Skip to content

Instantly share code, notes, and snippets.

@sgbett
Created April 6, 2018 17:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgbett/4dabc83cfc0603439fead83f0f9862e8 to your computer and use it in GitHub Desktop.
Save sgbett/4dabc83cfc0603439fead83f0f9862e8 to your computer and use it in GitHub Desktop.
Selfish Mining Sim
#!/usr/bin/env ruby
i = 0
iterations = 1000
sm_hash_pct = 33
public_chain = []
hm_fork = []
sm_fork = []
while i < iterations do
print "Iteration #{i}: "
i = i + 1
solution = rand(0..99)
print "[#{solution}] "
if solution < sm_hash_pct
print "SM solved"
sm_fork.push 'S'
else
print "HM solved"
hm_fork.push 'H'
end
if hm_fork.count > sm_fork.count
#hm is ahead so SM rebase
public_chain = hm_fork.clone
sm_fork = hm_fork.clone
end
if sm_fork.count > hm_fork.count
#sm is ahead so the game is on
print " - SM #{sm_fork.count - hm_fork.count} ahead"
if sm_fork.count > public_chain.count + 1
#if 2+ blocks ahead of main chain then we have a chance to orphan
if sm_fork.count == hm_fork.count+1 #only 1 block ahead of HM so publish
print ', HM only 1 behind - publishing...'
public_chain = sm_fork.clone
hm_fork = sm_fork.clone
else
end
else
print ", withholding..."
end
end
puts
puts "PUB:" + public_chain.join
# puts "HM :" + hm_fork.join
# puts "SM :" + sm_fork.join
# STDIN.getc
end
if sm_fork.count > hm_fork.count
public_chain = sm_fork
else
public_chain = hm_fork
end
puts "SM expected blocks = #{iterations * sm_hash_pct / 100} actual blocks = #{public_chain.join.count('S')}"
puts "HM expected blocks = #{iterations * (100-sm_hash_pct) / 100} actual blocks = #{public_chain.join.count('H')}"
puts "Orphans: #{orphans = (iterations - public_chain.count)}, rate #{"%.1f" % (100.0 * orphans/public_chain.count)}% "
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment