Custom Python Consensus Simulator
From TeachMeBitcoin, the free encyclopedia
⏱️ 3 min read
Building a Nakamoto Consensus Simulator in Pure Python
To visualize how the "Most Work" rule protects the network from double-spending, we can build a Consensus Race Simulator. This script simulates two competing entities: an Honest Network and an Attacker, each with a defined percentage of the total hashrate.
💻 1. The Consensus Race Source Code
Save the following Python script as consensus_race_sim.py.
import random
class ConsensusRaceSim:
def __init__(self, attacker_hashrate_pct: float, confirm_threshold: int):
self.q = attacker_hashrate_pct / 100.0 # Attacker power
self.p = 1.0 - self.q # Honest power
self.z = confirm_threshold # Number of blocks to catch up
def simulate_race(self):
"""
Simulates a single race. Returns True if attacker catches up,
False if they fail after a reasonable number of blocks.
"""
# Attacker starts z blocks behind
attacker_blocks = 0
honest_blocks = self.z
# We cap the simulation at a high number to avoid infinite loops
# though math says p > q will eventually converge to 0 probability.
max_blocks = 1000
while honest_blocks < max_blocks:
# Roll for who finds the next block
if random.random() < self.q:
attacker_blocks += 1
else:
honest_blocks += 1
# If attacker catches up or overtakes
if attacker_blocks >= honest_blocks:
return True
return False
def run_monte_carlo(self, trials: int = 10000):
print(f"[*] Starting Monte Carlo Simulation...")
print(f"[*] Attacker Hashrate: {self.q*100:.1f}%")
print(f"[*] Honest Hashrate: {self.p*100:.1f}%")
print(f"[*] Confirmations: {self.z}")
successes = 0
for _ in range(trials):
if self.simulate_race():
successes += 1
prob = (successes / trials) * 100
print(f"\n[✔] Results after {trials:,} trials:")
print(f" └─ Attacker Successes: {successes}")
print(f" └─ Success Probability: {prob:.4f}%")
if __name__ == "__main__":
# Example 1: Attacker with 10% hashrate vs 6 confirmations
sim1 = ConsensusRaceSim(attacker_hashrate_pct=10, confirm_threshold=6)
sim1.run_monte_carlo()
print("\n" + "="*40 + "\n")
# Example 2: Attacker with 35% hashrate vs 6 confirmations
sim2 = ConsensusRaceSim(attacker_hashrate_pct=35, confirm_threshold=6)
sim2.run_monte_carlo()
🛠️ 2. Interpreting the Results
When you run this script, you will see how sensitive the network is to the confirmation threshold:
- Low Hashrate Attacker (10%): Even with 10,000 trials, an attacker with only 10% hashrate will almost never catch up after 6 blocks. The probability is typically $<0.1\%$.
- High Hashrate Attacker (35%): An attacker with 35% hashrate has a much better chance. You will likely see a success probability around 10-15%. This is why for extremely high-value transactions, waiting for 10 or 20 confirmations is recommended.
🧩 Key Takeaways
- Hashpower is King: The rule of thumb is that if an attacker has $>50\%$ hashrate ($q > 0.5$), the success probability is 100% given enough time.
- Time is Security: Each additional block added to the chain increases the "cost" and "luck" required for an attacker to reorganize the ledger.
☕ Help support TeachMeBitcoin
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:
Ethereum:
0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin:
bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana:
4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J