research/casper/voting_strategy.py

69 lines
2.2 KiB
Python
Raw Normal View History

2015-07-19 19:01:20 +00:00
# The voting strategy. Validators see what every other validator's most
# recent vote for very particular block, in the format
#
# {
# blockhash1: [vote1, vote2, vote3...],
# blockhash2: [vote1, vote2, vote3...],
# ...
# }
#
# Where the votes are probabilities with 0 < p < 1 (see
# http://lesswrong.com/lw/mp/0_and_1_are_not_probabilities/ !), and the
# strategy should itself return an object of the format
# {
# blockhash1: vote,
# blockhash2: vote,
# ...
# }
def vote(probs, db, num_validators):
pass1 = {k: get_vote_from_scores(v, num_validators)
for k, v in probs.items() if k in db}
pass2 = normalize(pass1, num_validators)
return pass2
# Get the list of scores from other users and come up with
# your own base score
def get_vote_from_scores(probs, num_validators):
if len(probs) <= num_validators * 2 / 3:
o1 = 0
else:
o1 = sorted(probs)[::-1][num_validators * 2 / 3]
return 0.8 + 0.2 * o1
# Given a set of independently computed block probabilities, "normalize" the
# probabilities (ie. make sure they sum to at most 1; less than 1 is fine
# because the difference reflects the probability that some as-yet-unknown
# block will ultimately be finalized)
def normalize(block_results, num_validators):
# Trivial base cases
if len(block_results) == 1:
return {k: v for k, v in block_results.items()}
elif len(block_results) == 0:
return {}
a = {k: v for k, v in block_results.items()}
for v in a.values():
assert v <= 1, a
# Artificially privilege the maximum value at the expense of the
# others; this ensures more rapid convergence toward one equilibrium
maxkey, maxval = None, 0
for v in a:
if a[v] > maxval:
maxkey, maxval = v, a[v]
for v in a:
if v == maxkey:
a[v] = a[v] * 0.8 + 0.2
else:
a[v] *= 0.8
# If probabilities sum to more than 1, keep reducing them via a
# transform that preserves proportional probability of non-inclusion
while 1:
for v in a.values():
assert v <= 1, a
if sum(a.values()) < 1:
return a
a = {k: v * 1.05 - 0.050001 for k, v in a.items() if v > 0.050001}