Running a simulation
1. Introduction
A simulation can help visualise the security of PoW + PoS hybrid mining in comparison to pure PoW mining blockchains. To help understand the security provided by PoW + PoS mechanism, InvalidationGame simulates an attack on a (simulated) version of pure PoW blockchain mining mechanisms like Bitcoin and also of a PoW + PoS hybrid mining blockchains like the one introduced by Decred Project
InvalidationGame simulates a blockchain creating processing cycles that simulate multiple adversaries mining blocks on different sidechains (PoW). The script also simulates a pool of tickets that validates the previously mined blocks (PoW + PoS).
Assumptions and caveats are available at the README file.
2. Software
The source code is available on my Github repository.
Sample stdout output:
PoW + PoS simulation:
_____________________
Number of simulations: 1
Adversary Hashpower Stake Simulations won Simulations won Avg Invalidated Blocks Avg Validated Blocks
A0 60.00% 67.00% 1 100.0% 1 6
A1 40.00% 33.00% 0 0.0% 5 0
Total time for the batch of simulations: 0:00:00.121588
Average duration of simulations: 0.053931 seconds
2-block difference for 1 simulation: 3 blocks
6-block difference for 1 simulation: 7 blocks
Sample JSON output:
{'sims': {'0': {'2-block-diff': 3,
'2-block-diff_winner': 'A0',
'2-block-diff_winner_score': '2',
'6-block-diff': 7,
'6-block-diff_winner': 'A0',
'6-block-diff_winner_score': '6',
'adversaries': {'A0': {'chain': {'0': {'block_hash': 2920,
'online_tickets': 5,
'owned_tickets': [36743,
5137,
24754,
39151]},
'1': {'block_hash': 1541,
'online_tickets': 5,
'owned_tickets': [26326,
29914,
930]},
'2': {'block_hash': 2731,
'online_tickets': 5,
'owned_tickets': [5967,
15094,
27675,
6]},
'3': {'block_hash': 3476,
'online_tickets': 5,
'owned_tickets': [36483,
10914,
33651]},
'4': {'block_hash': 7997,
'online_tickets': 5,
'owned_tickets': [39281,
15886,
7925,
4721]},
'5': {'block_hash': 8611,
'online_tickets': 5,
'owned_tickets': [2523,
17438,
24681,
9662,
34060]}},
'hashpower': 60.0,
'invalidated_blocks': 1,
'pos_stakesize': '67.00%',
'pow_hashpower': '60.00%',
'stakesize': 67.0,
'sum_blocks': 6,
'validated_blocks': 6},
'A1': {'chain': {},
'hashpower': 40.0,
'invalidated_blocks': 5,
'pos_stakesize': '33.00%',
'pow_hashpower': '40.00%',
'stakesize': 33.0,
'sum_blocks': 0,
'validated_blocks': 0}},
'cycles': {'0': {'drawn_block_hash': 2920,
'pos_winners': ['A0'],
'pow_winners': ['A0', 'A1']},
'1': {'drawn_block_hash': 1541,
'pos_winners': ['A0'],
'pow_winners': ['A0', 'A1']},
'2': {'drawn_block_hash': 2731,
'pos_winners': ['A0'],
'pow_winners': ['A0']},
'3': {'drawn_block_hash': 3476,
'pos_winners': ['A0'],
'pow_winners': ['A0']},
'4': {'drawn_block_hash': 7997,
'pos_winners': ['A0'],
'pow_winners': ['A0']},
'5': {'drawn_block_hash': 8611,
'pos_winners': ['A0'],
'pow_winners': ['A0', 'A1']},
'6': {'distance_before_this_cycle': 6,
'probability_before_this_cycle': '0.0012620916488757833'}}}},
'summary': {'batch_end': '2020-05-11 22:23:07.280245',
'batch_start': '2020-05-11 22:23:07.158657',
'perc_wins': {'A0': '100.0%', 'A1': '0.0%'},
'pos': {'A0': {'invalidated_blocks': [1],
'invalidated_blocks-average': 1,
'validated_blocks': [6],
'validated_blocks-average': 6},
'A1': {'invalidated_blocks': [5],
'invalidated_blocks-average': 5,
'validated_blocks': [0],
'validated_blocks-average': 0}},
'pow': {'2-block-diff-average': 3, '6-block-diff-average': 7},
'rewind_adv': 'A0',
'rewind_blocks': 0,
'sim_mean_time': 0.053931,
'sum_blocks': {'A0': {'average': 6}, 'A1': {'average': 0}},
'total': 1,
'total_wins': {'A0': 1, 'A1': 0}}}