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
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 |
|
|
|
|