76 lines
2.5 KiB
Python
Executable File
76 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Simulate a maximal block attack on the Monero network
|
|
# This uses the scheme proposed by ArticMine
|
|
# Written by Sarang Nother
|
|
# Copyright (c) 2019 The Monero Project
|
|
from __future__ import print_function
|
|
import sys
|
|
import math
|
|
|
|
MEDIAN_WINDOW_SMALL = 100 # number of recent blocks for median computation
|
|
MEDIAN_WINDOW_BIG = 5000
|
|
MULTIPLIER_SMALL = 1.4 # multipliers for determining weights
|
|
MULTIPLIER_BIG = 50.0
|
|
MEDIAN_THRESHOLD = 300*1000 # initial value for median (scaled kB -> B)
|
|
lcg_seed = 0
|
|
embw = MEDIAN_THRESHOLD
|
|
ltembw = MEDIAN_THRESHOLD
|
|
|
|
weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_SMALL # weights of recent blocks (B), with index -1 most recent
|
|
lt_weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_BIG # long-term weights
|
|
|
|
# Compute the median of a list
|
|
def get_median(vec):
|
|
#temp = vec
|
|
temp = sorted(vec)
|
|
if len(temp) % 2 == 1:
|
|
return temp[len(temp)/2]
|
|
else:
|
|
return int((temp[len(temp)/2]+temp[len(temp)/2-1])/2)
|
|
|
|
def LCG():
|
|
global lcg_seed
|
|
lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff
|
|
return lcg_seed
|
|
|
|
def run(t, blocks):
|
|
global embw
|
|
global ltembw
|
|
|
|
weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_SMALL # weights of recent blocks (B), with index -1 most recent
|
|
lt_weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_BIG # long-term weights
|
|
|
|
for block in range(blocks):
|
|
# determine the long-term effective weight
|
|
ltmedian = get_median(lt_weights[-MEDIAN_WINDOW_BIG:])
|
|
ltembw = max(MEDIAN_THRESHOLD,ltmedian)
|
|
|
|
# determine the effective weight
|
|
stmedian = get_median(weights[-MEDIAN_WINDOW_SMALL:])
|
|
embw = min(max(MEDIAN_THRESHOLD,stmedian),int(MULTIPLIER_BIG*ltembw))
|
|
|
|
# drop the lowest values
|
|
weights = weights[1:]
|
|
lt_weights = lt_weights[1:]
|
|
|
|
# add a block of max weight
|
|
if t == 0:
|
|
max_weight = 2 * embw
|
|
elif t == 1:
|
|
r = LCG()
|
|
max_weight = int(90 + r % 500000 + 250000 + math.sin(block / 200.) * 350000)
|
|
if max_weight < 90: max_weight = 90
|
|
elif t == 2:
|
|
max_weight = 90
|
|
else:
|
|
sys.exit(1)
|
|
weights.append(max_weight)
|
|
lt_weights.append(min(max_weight,int(ltembw + int(ltembw * 2 / 5))))
|
|
|
|
#print "H %u, r %u, BW %u, EMBW %u, LTBW %u, LTEMBW %u, ltmedian %u" % (block, r, max_weight, embw, lt_weights[-1], ltembw, ltmedian)
|
|
print("H %u, BW %u, EMBW %u, LTBW %u" % (block, max_weight, embw, lt_weights[-1]))
|
|
|
|
run(0, 2 * MEDIAN_WINDOW_BIG)
|
|
run(1, 9 * MEDIAN_WINDOW_BIG)
|
|
run(2, 1 * MEDIAN_WINDOW_BIG)
|