You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

81 lines
2.7 KiB

##this file calculates the success probability of a sybil attack on the
# orderbook with fidelity bonds used in joinmarket
# see https://gist.github.com/chris-belcher/87ebbcbb639686057a389acb9ab3e25b
#precomputed
#what sybil weight is required per-maker to sybil attack joinmarket with 95% success rate
#this is for when the honest weight (i.e. value of all fidelity bonds added up) equals 1
#however it is linear, so to calculate for another honest_weight just multiply
#see
#https://gist.github.com/chris-belcher/87ebbcbb639686057a389acb9ab3e25b#appendix-1---fit-to-unit-honest-weight-sybil-attack
successful_attack_95pc_sybil_weight = {
1: 19.2125,
2: 28.829523311823312,
3: 35.37299702466422,
4: 40.27618399827166,
5: 44.19631358837695,
6: 47.46160578701477,
7: 50.25944623742167,
8: 52.706868994753286,
9: 54.881852860047836,
10: 56.8389576639515,
11: 58.61784778500215,
12: 60.248261563672784,
13: 61.75306801,
14: 62.97189476,
15: 64.28155594,
16: 65.21832112385313,
17: 66.29765063354174,
18: 67.315269563541,
19: 68.27785449480159,
20: 69.19105386203657,
21: 70.05968878944397,
22: 70.88790716279642,
23: 71.67930342495613,
24: 72.43701285697972,
25: 73.16378660022
}
def descend_probability_tree(weights, remaining_descents, branch_probability):
if remaining_descents == 0:
return branch_probability
else:
total_weight = sum(weights)
result = 0
for i, w in enumerate(weights):
#honest makers are at index 0
if i == 0:
#an honest maker being chosen means the sybil attack failed
#so this branch contributes zero to the attack success prob
continue
if w == 0:
continue
weight_cache = weights[i]
weights[i] = 0
result += descend_probability_tree(weights,
remaining_descents-1, branch_probability*w/total_weight)
weights[i] = weight_cache
return result
def calculate_top_makers_sybil_attack_success_probability(weights, taker_peer_count):
honest_weight = sum(weights[taker_peer_count:])
weights = [honest_weight] + weights[:taker_peer_count]
return descend_probability_tree(weights, taker_peer_count, 1.0)
def weight_to_burned_coins(w):
#calculates how many coins need to be burned to produce a certain bond
return w**0.5
def weight_to_locked_coins(w, r, locktime_months):
#calculates how many coins need to be locked to produce a certain bond
return w**0.5 / r / locktime_months * 12
def coins_locked_to_weight(c, r, locktime_months):
return (c*r*locktime_months/12.0)**2
def coins_burned_to_weight(c):
return c*c