Created
April 11, 2018 09:30
-
-
Save tomasvdw/73504065c3baa7e8c9701f7893e43290 to your computer and use it in GitHub Desktop.
Selfish mining simulator
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
# Simulation of Selfish mining with gamma=0 | |
# gamma=0 assumes a nearly full connected topology. | |
# We simulate a selfish pool p and h who mines honest | |
# As Gamma=0, we do not need to simulate more then two miners | |
# Tomas van der Wansem | |
import random; | |
ROUNDS = 10000000 | |
# size of pool relative to total | |
ALPHA = 0.39 | |
# difficulty factor; reduces blocks found at the same time | |
DIFF = 0.01 | |
class State: | |
def __init__(self, selfish): | |
# pool gains and honest gains | |
self.p_gains = 0 | |
self.h_gains = 0 | |
# blockcount of pool and honest chains | |
self.p_len = 0 | |
self.h_len = 0 | |
# the number of blocks shared between the two chains | |
self.shared_len = 0 | |
self.selfish = selfish | |
# Execute a single round | |
# where both h and p attempt to find a block | |
# and try to propagate | |
def find_hash(self, r_h, r_p): | |
# update both chains and assume gains until blocks are staled | |
if r_p < ALPHA * DIFF: | |
self.p_gains += 1 | |
self.p_len += 1 | |
if r_h < (1 - ALPHA) * DIFF: | |
self.h_gains += 1 | |
self.h_len += 1 | |
if self.selfish: | |
self.propagate_selfish() | |
else: | |
self.propagate_honest() | |
# p and h are both honest. | |
# Used for comparison | |
def propagate_honest(self): | |
if self.p_len > self.h_len: | |
# publish | |
# stale blocks reduce gain | |
self.h_gains -= (self.h_len - self.shared_len) | |
self.h_len = self.p_len | |
self.shared_len = self.p_len | |
elif self.h_len > self.p_len: | |
# publish | |
# stale blocks reduce gain | |
self.p_gains -= (self.p_len - self.shared_len) | |
self.p_len = self.h_len | |
self.shared_len = self.h_len | |
else: | |
# two chains competing | |
pass | |
# Selfish mining; from algorithm 1 of the paper | |
def propagate_selfish(self): | |
if self.p_len > self.h_len: | |
if self.shared_len < self.h_len: | |
# we had two competing chains which we now overtook | |
# publish | |
# stale blocks reduce gain | |
self.h_gains -= (self.h_len - self.shared_len) | |
self.h_len = self.p_len | |
self.shared_len = self.p_len | |
else: | |
# Don't publish our block as we are selfish | |
pass | |
elif self.h_len > self.p_len: | |
# honest miners win | |
# orphaned blocks reduce gain | |
self.p_gains -= (self.p_len - self.shared_len) | |
self.p_len = self.h_len | |
self.shared_len = self.h_len | |
else: | |
# two chains competing | |
pass | |
s_h = State(False) | |
s_s = State(True) | |
for i in range(0,ROUNDS): | |
r_h = random.random() | |
r_p = random.random() | |
s_s.find_hash(r_h,r_p) | |
s_h.find_hash(r_h,r_p) | |
print "Selfish" | |
print "p_gain = " + str(s_s.p_gains) | |
print "h_gain = " + str(s_s.h_gains) | |
print "p_gain = " + str(s_s.p_gains/float(s_s.p_gains+s_s.h_gains)) | |
print "Honest" | |
print "p_gain = " + str(s_h.p_gains) | |
print "h_gain = " + str(s_h.h_gains) | |
print "p_gain = " + str(s_h.p_gains/float(s_h.p_gains+s_h.h_gains)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment