TeachMeBitcoin

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:

  1. 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\%$.
  2. 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

☕ 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
Address copied to clipboard!