Created
February 12, 2021 21:05
-
-
Save JeremyRubin/9c25b3a947661ea297824dbf18decac5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
TRIALS = 10000 | |
MARS_DIST_LIGHT_MINUTES_MAX = 22 | |
RTT = MARS_DIST_LIGHT_MINUTES_MAX*60*2 | |
gen = lambda mins: list(np.round(np.random.exponential(mins*60, TRIALS))) | |
# Assume miner_1 has 50% hashrate and miner_2 has 50%... find blocks every 20 mins each | |
# alternative: Assume miner_1 has 90% and miner_2 has 10%... find blocks 10/0.9 and 10/0.1 | |
miner_1 = gen(10/0.5) | |
miner_2 = gen(10/0.5) | |
SECONDS = int(60*10*TRIALS*2) | |
log = [[(None, None), (None, None)] for x in range(SECONDS)] | |
height_1 = 0 | |
height_2 = 0 | |
time = list(range(SECONDS)) | |
height_at_time_1 = [0]*SECONDS | |
height_at_time_2 = [0]*SECONDS | |
blocks_1 = [None]*TRIALS | |
blocks_2 = [None]*TRIALS | |
m_1_streak = 0 | |
m_2_streak = 0 | |
orphans_1 = 0 | |
orphans_2 = 0 | |
orphans_1_t = [0]*SECONDS | |
orphans_2_t = [0]*SECONDS | |
try: | |
for i in range(len(log)): | |
(m_1_transmitted_height, m_1_n_blocks), (m_2_transmitted_height, m_2_n_blocks) = log[i] | |
update_1 = None | |
# Check to see if the transmitted height from miner 2 exceeds that at miner 1 | |
# If it does, take the best height. | |
if m_2_transmitted_height: | |
if m_2_transmitted_height > height_1: | |
# give up this block (otherwise non-memoryless process) | |
miner_1.pop() | |
m_1_streak = 0 | |
update_1 = m_2_transmitted_height | |
for k in range(m_2_transmitted_height - m_2_n_blocks, m_2_transmitted_height+1): | |
if blocks_1[k] == 1: | |
orphans_1 += 1 | |
blocks_1[k] = 2 | |
# Check to see if the transmitted height from miner 1 exceeds that at miner 2 | |
# If it does, take the best height. | |
if m_1_transmitted_height: | |
if m_1_transmitted_height > height_2: | |
# give up this block (otherwise non-memoryless process) | |
miner_2.pop() | |
height_2 = m_1_transmitted_height | |
m_2_streak = 0 | |
for k in range(m_1_transmitted_height - m_1_n_blocks, m_1_transmitted_height+1): | |
if blocks_2[k] == 2: | |
orphans_2 += 1 | |
blocks_2[k] = 1 | |
if update_1 is not None: | |
height_1 = update_1 | |
if miner_1[-1] <= 0: | |
# Miner 1 has found a block | |
height_1 += 1 | |
# send message to miner 2, arrives later | |
log[i+RTT//2][0] = (height_1, m_1_streak) | |
blocks_1[height_1] = 1 | |
miner_1.pop() | |
m_1_streak += 1 | |
else: | |
miner_1[-1] -= 1 | |
if miner_2[-1] <= 0: | |
# Miner 2 has found a block | |
height_2 += 1 | |
# send message to miner 1, arrives later | |
log[i+RTT//2][1] = (height_2, m_2_streak) | |
blocks_2[height_2] = 2 | |
miner_2.pop() | |
m_2_streak += 1 | |
else: | |
miner_2[-1] -= 1 | |
height_at_time_1[i] = height_1 | |
height_at_time_2[i] = height_2 | |
orphans_1_t[i] = orphans_1 | |
orphans_2_t[i] = orphans_2 | |
except Exception as e: | |
print(e) | |
print("Consensus Worked: ", blocks_1 == blocks_2) | |
from matplotlib import pyplot as plt | |
#plt.plot(time, height_at_time_1) | |
#plt.plot(time, height_at_time_2) | |
rel_time = np.array(time) / 10 / 60 | |
plt.plot(rel_time, orphans_1_t, label="orphans 1") | |
plt.plot(rel_time, orphans_2_t, label="orphans 2") | |
plt.plot(range(TRIALS), np.cumsum(list(map(lambda x: x == 1, blocks_1))), label="blocks 1") | |
plt.plot(range(TRIALS), np.cumsum(list(map(lambda x: x == 2, blocks_1))), label="blocks 2") | |
plt.legend() | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment