7
7
from ethereum .parse_genesis_declaration import mk_basic_state
8
8
from ethereum import abi
9
9
from ethereum .casper_utils import RandaoManager , generate_validation_code , call_casper , \
10
- get_skips_and_block_making_time , sign_block , get_casper_ct , make_casper_genesis , \
11
- validator_sizes , find_indices , get_timestamp , make_withdrawal_signature , \
12
- casper_config
10
+ get_skips_and_block_making_time , sign_block , get_contract_code , \
11
+ casper_config , get_casper_ct , get_casper_code , get_rlp_decoder_code , \
12
+ get_hash_without_ed_code , make_casper_genesis , get_timestamp , \
13
+ make_withdrawal_signature
13
14
from ethereum .block_creation import make_head_candidate
14
15
from ethereum .transaction_queue import TransactionQueue
15
16
from ethereum .slogging import LogRecorder , configure_logging , set_level
24
25
configure_logging (config_string = config_string )
25
26
26
27
NUM_PARTICIPANTS = 10
28
+ BLOCK_MAKING_PPB = 10
27
29
28
30
print 'Initializing privkeys, addresses and randaos for validators'
29
31
privkeys = [utils .sha3 (str (i )) for i in range (NUM_PARTICIPANTS )]
30
32
addrs = [utils .privtoaddr (k ) for k in privkeys ]
31
33
randaos = [RandaoManager (utils .sha3 (str (i ))) for i in range (NUM_PARTICIPANTS )]
32
- deposit_sizes = [256 ] * (NUM_PARTICIPANTS // 4 ) + [128 ] * (NUM_PARTICIPANTS - (NUM_PARTICIPANTS // 4 ))
33
- assert len (privkeys ) == len (addrs ) == len (randaos ) == len (deposit_sizes ) == NUM_PARTICIPANTS
34
+ deposit_sizes = [i * 500 + 500 for i in range (NUM_PARTICIPANTS )]
35
+ vcodes = [generate_validation_code (a ) for a in addrs ]
36
+ vchashes = [utils .sha3 (c ) for c in vcodes ]
37
+ assert len (privkeys ) == len (addrs ) == len (randaos ) == len (deposit_sizes ) == len (vcodes ) == len (vchashes ) == NUM_PARTICIPANTS
34
38
35
39
# Creating casper contract translator
36
40
ct = get_casper_ct ()
37
41
assert ct
38
42
print 'Constructing genesis'
39
- s = make_casper_genesis (validators = [(generate_validation_code (a ), ds * 10 ** 18 , r .get (9999 ))
43
+ s = make_casper_genesis (validators = [(generate_validation_code (a ), ds * 10 ** 18 , r .get (9999 ), a )
40
44
for a , ds , r in zip (addrs , deposit_sizes , randaos )][:- 1 ],
41
45
alloc = {a : {'balance' : 10 ** 18 } for a in addrs },
42
46
timestamp = int (time .time () - 99999 ),
43
47
epoch_length = 100 )
44
48
print 'Genesis constructed successfully'
45
49
chains = [Chain (s .to_snapshot (), env = s .env ) for i in range (NUM_PARTICIPANTS )]
50
+ withdrawal_time_1 = call_casper (chains [0 ].state , 'getLockDuration' , [vchashes [0 ]])
51
+
52
+ # List of validator IDs that created each block
53
+ vids = []
46
54
47
55
# Create and sign a block
48
- def make_block (chain , key , randao , indices , skips ):
56
+ def make_block (chain , key , randao , vchash , skips ):
49
57
h = make_head_candidate (chain , TransactionQueue (), timestamp = get_timestamp (chain , skips ))
50
- return sign_block (h , key , randao .get_parent (call_casper (chain .state , 'getRandao' , [indices [ 0 ], indices [ 1 ]] )), indices , skips )
58
+ return sign_block (h , key , randao .get_parent (call_casper (chain .state , 'getRandao' , [vchash ] )), vchash , skips )
51
59
52
60
next_validator = call_casper (s , 'getValidator' , [0 ])
53
- print 'Next validator:' , next_validator
54
- indices = [find_indices (s , generate_validation_code (addrs [i ]))[:2 ] for i in range (len (addrs ) - 1 )]
55
- print indices , next_validator
56
- next_validator_id = indices .index (next_validator )
57
-
58
- print 'Index in set:' , next_validator_id
61
+ print 'Next validator:' , next_validator .encode ('hex' )
62
+ next_validator_id = vchashes .index (next_validator )
63
+ print 'Next validator index:' , next_validator_id
59
64
60
- skip_count , timestamp = get_skips_and_block_making_time (chains [next_validator_id ], indices [ next_validator_id ] )
65
+ skip_count , timestamp = get_skips_and_block_making_time (chains [0 ]. state , next_validator )
61
66
assert skip_count == 0
62
67
b = make_block (chains [0 ], privkeys [next_validator_id ],
63
- randaos [next_validator_id ], indices [next_validator_id ], skip_count )
68
+ randaos [next_validator_id ], vchashes [next_validator_id ], skip_count )
64
69
# Validate it
65
70
print 'Block timestamp:' , b .header .timestamp
66
71
initialize (s , b )
67
72
print 'Validating block'
68
73
assert validate_block_header (s , b .header )
69
74
print 'Validation successful'
70
75
assert chains [0 ].add_block (b )
76
+ vids .append (next_validator_id )
71
77
print 'Block added to chain'
72
78
# Make another block
73
79
next_validator = call_casper (chains [0 ].state , 'getValidator' , [0 ])
74
- next_validator_id = indices .index (next_validator )
75
- skip_count , timestamp = get_skips_and_block_making_time (chains [0 ], next_validator )
80
+ next_validator_id = vchashes .index (next_validator )
81
+ skip_count , timestamp = get_skips_and_block_making_time (chains [0 ]. state , next_validator )
76
82
assert skip_count == 0
77
83
b2 = make_block (chains [0 ], privkeys [next_validator_id ],
78
- randaos [next_validator_id ], indices [next_validator_id ], skip_count )
84
+ randaos [next_validator_id ], vchashes [next_validator_id ], skip_count )
79
85
assert chains [0 ].add_block (b2 )
86
+ vids .append (next_validator_id )
80
87
print 'Second block added to chain'
81
88
# Make a dunkle and include it in a transaction
82
89
next_validator = call_casper (chains [1 ].state , 'getValidator' , [1 ])
83
- next_validator_id = indices .index (next_validator )
84
- skip_count , timestamp = get_skips_and_block_making_time (chains [next_validator_id ] , next_validator )
90
+ next_validator_id = vchashes .index (next_validator )
91
+ skip_count , timestamp = get_skips_and_block_making_time (chains [1 ]. state , next_validator )
85
92
assert skip_count == 1
86
93
b3 = make_block (chains [1 ], privkeys [next_validator_id ],
87
- randaos [next_validator_id ], indices [next_validator_id ], skip_count )
94
+ randaos [next_validator_id ], vchashes [next_validator_id ], skip_count )
88
95
print 'Dunkle produced'
89
96
t = Transaction (0 , 0 , 10 ** 6 , casper_config ['CASPER_ADDR' ], 0 , ct .encode ('includeDunkle' , [rlp .encode (b3 .header )])).sign (privkeys [0 ])
90
97
apply_transaction (chains [0 ].state , t )
@@ -104,51 +111,61 @@ def make_block(chain, key, randao, indices, skips):
104
111
t2 = Transaction (chains [0 ].state .get_nonce (a ), 0 , 1000000 , casper_config ['CASPER_ADDR' ],
105
112
ds * 10 ** 18 , ct .encode ('deposit' , [vc , r .get (9999 )])).sign (k )
106
113
apply_transaction (chains [0 ].state , t2 )
107
- indices .append (find_indices (chains [0 ].state , vc )[:2 ])
108
- assert indices [- 1 ]
109
- assert call_casper (chains [0 ].state , 'getStartEpoch' , indices [- 1 ]) == 2
114
+ assert call_casper (chains [0 ].state , 'getStartEpoch' , [vchashes [- 1 ]]) == 2
110
115
chains [0 ].state .commit ()
111
- print 'Added new validator "in-flight", indices:' , indices [- 1 ]
116
+ print 'Added new validator "in-flight", indices:' , vchashes [- 1 ]. encode ( 'hex' )
112
117
# Create some blocks
113
- vids = []
114
118
bn = call_casper (chains [0 ].state , 'getBlockNumber' )
115
119
for i in range (bn + 1 , 200 ):
116
120
next_validator = call_casper (chains [0 ].state , 'getValidator' , [0 ])
117
- next_validator_id = indices .index (next_validator )
121
+ next_validator_id = vchashes .index (next_validator )
118
122
b = make_block (chains [0 ], privkeys [next_validator_id ], randaos [next_validator_id ],
119
- indices [next_validator_id ], 0 )
123
+ vchashes [next_validator_id ], 0 )
120
124
assert chains [0 ].add_block (b )
121
125
vids .append (next_validator_id )
122
126
print 'Created 200 blocks before any deposits/widthdraws, created by validators:' , vids
123
- assert len (indices ) - 1 not in vids
127
+ assert len (vchashes ) - 1 not in vids
124
128
assert 0 in vids
125
129
# Remove a validator
126
130
sigdata = make_withdrawal_signature (privkeys [0 ])
127
- txdata = ct .encode ('startWithdrawal' , [indices [ 0 ][ 0 ], indices [ 0 ][ 1 ], sigdata ])
131
+ txdata = ct .encode ('startWithdrawal' , [vchashes [ 0 ], sigdata ])
128
132
t3 = Transaction (chains [0 ].state .get_nonce (addrs [0 ]), 0 , 1000000 , casper_config ['CASPER_ADDR' ], 0 , txdata ).sign (privkeys [0 ])
129
133
apply_transaction (chains [0 ].state , t3 )
130
- assert call_casper (chains [0 ].state , 'getEndEpoch' , indices [ 0 ]) == 4
134
+ assert call_casper (chains [0 ].state , 'getEndEpoch' , [ vchashes [ 0 ] ]) == 4
131
135
chains [0 ].state .commit ()
132
136
print 'Withdrew a validator'
137
+ print '%d blocks before ETH becomes available' % withdrawal_time_1
133
138
for i in range (200 , 400 ):
134
139
next_validator = call_casper (chains [0 ].state , 'getValidator' , [0 ])
135
- next_validator_id = indices .index (next_validator )
140
+ next_validator_id = vchashes .index (next_validator )
136
141
b = make_block (chains [0 ], privkeys [next_validator_id ], randaos [next_validator_id ],
137
- indices [next_validator_id ], 0 )
142
+ vchashes [next_validator_id ], 0 )
138
143
assert b .header .number == i
139
144
assert chains [0 ].add_block (b )
140
145
vids .append (next_validator_id )
141
146
print 'Created 200 blocks after the deposit, created by validators:' , vids [- 200 :]
142
- assert len (indices ) - 1 in vids
147
+ assert len (vchashes ) - 1 in vids
143
148
assert 0 in vids
144
- for i in range (400 , 600 ):
149
+ for i in range (400 , 400 + withdrawal_time_1 + 1 ):
145
150
next_validator = call_casper (chains [0 ].state , 'getValidator' , [0 ])
146
- next_validator_id = indices .index (next_validator )
151
+ next_validator_id = vchashes .index (next_validator )
147
152
b = make_block (chains [0 ], privkeys [next_validator_id ], randaos [next_validator_id ],
148
- indices [next_validator_id ], 0 )
153
+ vchashes [next_validator_id ], 0 )
149
154
assert chains [0 ].add_block (b )
150
155
vids .append (next_validator_id )
151
- print 'Created 200 blocks after the withdrawal, created by validators:' , vids [- 200 :]
152
- assert len (indices ) - 1 in vids
156
+ print 'Created %d blocks after the withdrawal, created by validators:' % ( withdrawal_time_1 + 1 ) , vids [- 200 :]
157
+ assert len (vchashes ) - 1 in vids
153
158
assert 0 not in vids [- 200 :]
159
+ pre_bal = chains [0 ].state .get_balance (addrs [0 ])
160
+ txdata = ct .encode ('withdraw' , [vchashes [0 ]])
161
+ t4 = Transaction (chains [0 ].state .get_nonce (addrs [0 ]), 0 , 1000000 , casper_config ['CASPER_ADDR' ], 0 , txdata ).sign (privkeys [0 ])
162
+ apply_transaction (chains [0 ].state , t4 )
163
+ post_bal = chains [0 ].state .get_balance (addrs [0 ])
164
+ print 'Wei withdrawn:' , post_bal - pre_bal
165
+ blocks_by_v0_in_stage1 = len ([x for x in vids [:200 ] if x == 0 ])
166
+ expected_revenue_in_stage1 = blocks_by_v0_in_stage1 * max (sum (deposit_sizes [:- 1 ]), 1000000 ) * 10 ** 18 * BLOCK_MAKING_PPB / 10 ** 9
167
+ blocks_by_v0_in_stage2 = len ([x for x in vids [200 :400 ] if x == 0 ])
168
+ expected_revenue_in_stage2 = blocks_by_v0_in_stage2 * max (sum (deposit_sizes ), 1000000 ) * 10 ** 18 * BLOCK_MAKING_PPB / 10 ** 9
169
+
170
+ assert post_bal - pre_bal == deposit_sizes [0 ] * 10 ** 18 + expected_revenue_in_stage1 + expected_revenue_in_stage2
154
171
print 'PoS test fully passed'
0 commit comments