-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsketch.py
More file actions
90 lines (69 loc) · 3.39 KB
/
sketch.py
File metadata and controls
90 lines (69 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import logging
from queue import Queue
from Structures import Block, Blockchain
from utils import get_block_time
### Pseudocode for the simulation class:
valid_chain = Blockchain()
attack_queue = Queue()
gamma = 0.4
# in honest miner agent class
total_mining_time: float = 0
# FIXME: We should be checking if blockchain has had 2016 blocks appended to it before restarting the count from 0
# FIXME: this while loop is incorrect.
while(len(valid_chain) <= 2016):
h_mine_time = get_block_time(honest_agent)
s_mine_time = get_block_time(selfish_agent)
winner = 'H' if h_mine_time < s_mine_time else 'S'
# TODO: FIGURE OUT A WAY TO CHECK THE QUEUES OF OTHER MINERS
# TODO: TLDR; WE DON'T ALWAYS HAVE TO GENERATE NEW BLOCK TIMES FOR EVERYONE ON EVERY TIMESTEP
# TODO: FIGURE OUT HOW TO DO THIS
if winner == 'H':
# if selfish miners found no blocks so far.
if attack_queue.qsize() == 0:
# append honest block to the blockchain
new_timestamp = valid_chain.get_global_time_of_chain() + h_mine_time
valid_chain.add_block(Block(mining_time=h_mine_time, timestamp=new_timestamp))
# selfish miners and honest miners have matching chain lengths
# selfish miners fork and pray to Satoshi for a victory
elif attack_queue.qsize() == 1:
# Some honest miners will defect. Create these two new mining groups
defector_agent = Agent(alpha = honest_agent.alpha*gamma) # Effectively (1 - alpha)*gamma
new_honest_agent = Agent(alpha = honest_agent.alpha*(1-gamma))
# TODO: COMPUTE MINING TIME FOR ALL 3 AGENTS AND WINNER HAS THE LOWEST
#
# Decides who wins the fork contest
# If selfish miners win, they keep to themselves
# If defector miners win, selfish miners gain +1 block but have to restart mining from scratch
# If honest miners win, rip
results = get_winner(defector_agent, new_honest_agent, selfish_agent)
if results["selfish"] == True:
attack_queue.put(results["block"])
elif results["defector"] == True:
selfish_agent.blocks_won += 1
elif results["honest"] == True:
# empty attack queue
attack_queue.empty()
else:
logging.error("winner at fork not found")
raise Exception
# Selfish miner must publish all blocks to ensure victory
elif attack_queue.qsize() == 2:
selfish_agent.blocks_won += 2
valid_chain.add_block()
valid_chain.add_block()
# Selfish miner will only match the block posted but will continue mining on their longer chain
elif attack_queue.qsize() > 2:
# We just push one block to fork on the valid chain
attack_queue.get()
# # We push the TWO earliest blocks in the attack chain to the valid chain.
# block1 = attack_queue.get()
# block1.timestamp = valid_chain.get_global_time_of_chain() + h_mine_time
#
# block2 = attack_queue.get()
# block2.timestamp = valid_chain.get_global_time_of_chain() + h_mine_time
#
# valid_chain.add_block(block1)
# valid_chain.add_block(block2)
# If the selfish miners win
else:
attack_queue.put(Block(mining_time=s_mine_time))