Merge pull request #2083 from ethereum/init-tests
additional genesis init tests
This commit is contained in:
commit
122d34a41e
|
@ -1,3 +1,5 @@
|
|||
from random import Random
|
||||
|
||||
from eth2spec.test.helpers.keys import pubkeys, privkeys
|
||||
from eth2spec.utils import bls
|
||||
from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merkle_proof
|
||||
|
@ -62,29 +64,69 @@ def deposit_from_context(spec, deposit_data_list, index):
|
|||
return deposit, root, deposit_data_list
|
||||
|
||||
|
||||
def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False, deposit_data_list=None):
|
||||
def prepare_full_genesis_deposits(spec,
|
||||
amount,
|
||||
deposit_count,
|
||||
min_pubkey_index=0,
|
||||
signed=False,
|
||||
deposit_data_list=None):
|
||||
if deposit_data_list is None:
|
||||
deposit_data_list = []
|
||||
genesis_deposits = []
|
||||
for validator_index in range(genesis_validator_count):
|
||||
pubkey = pubkeys[validator_index]
|
||||
privkey = privkeys[validator_index]
|
||||
for pubkey_index in range(min_pubkey_index, min_pubkey_index + deposit_count):
|
||||
pubkey = pubkeys[pubkey_index]
|
||||
privkey = privkeys[pubkey_index]
|
||||
# insecurely use pubkey as withdrawal key if no credentials provided
|
||||
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
|
||||
deposit, root, deposit_data_list = build_deposit(
|
||||
spec,
|
||||
deposit_data_list,
|
||||
pubkey,
|
||||
privkey,
|
||||
amount,
|
||||
withdrawal_credentials,
|
||||
signed,
|
||||
deposit_data_list=deposit_data_list,
|
||||
pubkey=pubkey,
|
||||
privkey=privkey,
|
||||
amount=amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=signed,
|
||||
)
|
||||
genesis_deposits.append(deposit)
|
||||
|
||||
return genesis_deposits, root, deposit_data_list
|
||||
|
||||
|
||||
def prepare_random_genesis_deposits(spec,
|
||||
deposit_count,
|
||||
max_pubkey_index,
|
||||
min_pubkey_index=0,
|
||||
max_amount=None,
|
||||
min_amount=None,
|
||||
deposit_data_list=None,
|
||||
rng=Random(3131)):
|
||||
if max_amount is None:
|
||||
max_amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
if min_amount is None:
|
||||
min_amount = spec.MIN_DEPOSIT_AMOUNT
|
||||
if deposit_data_list is None:
|
||||
deposit_data_list = []
|
||||
deposits = []
|
||||
for _ in range(deposit_count):
|
||||
pubkey_index = rng.randint(min_pubkey_index, max_pubkey_index)
|
||||
pubkey = pubkeys[pubkey_index]
|
||||
privkey = privkeys[pubkey_index]
|
||||
amount = rng.randint(min_amount, max_amount)
|
||||
random_byte = bytes([rng.randint(0, 255)])
|
||||
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(random_byte)[1:]
|
||||
deposit, root, deposit_data_list = build_deposit(
|
||||
spec,
|
||||
deposit_data_list=deposit_data_list,
|
||||
pubkey=pubkey,
|
||||
privkey=privkey,
|
||||
amount=amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
deposits.append(deposit)
|
||||
return deposits, root, deposit_data_list
|
||||
|
||||
|
||||
def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False):
|
||||
"""
|
||||
Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from eth2spec.test.context import PHASE0, spec_test, with_phases, single_phase
|
||||
from eth2spec.test.helpers.deposits import (
|
||||
prepare_genesis_deposits,
|
||||
prepare_full_genesis_deposits,
|
||||
prepare_random_genesis_deposits,
|
||||
)
|
||||
|
||||
|
||||
|
@ -9,7 +10,12 @@ from eth2spec.test.helpers.deposits import (
|
|||
@single_phase
|
||||
def test_initialize_beacon_state_from_eth1(spec):
|
||||
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
deposits, deposit_root, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True)
|
||||
deposits, deposit_root, _ = prepare_full_genesis_deposits(
|
||||
spec,
|
||||
spec.MAX_EFFECTIVE_BALANCE,
|
||||
deposit_count,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
eth1_block_hash = b'\x12' * 32
|
||||
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||
|
@ -37,14 +43,18 @@ def test_initialize_beacon_state_from_eth1(spec):
|
|||
@single_phase
|
||||
def test_initialize_beacon_state_some_small_balances(spec):
|
||||
main_deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
main_deposits, _, deposit_data_list = prepare_genesis_deposits(spec, main_deposit_count,
|
||||
spec.MAX_EFFECTIVE_BALANCE, signed=True)
|
||||
main_deposits, _, deposit_data_list = prepare_full_genesis_deposits(
|
||||
spec, spec.MAX_EFFECTIVE_BALANCE,
|
||||
deposit_count=main_deposit_count, signed=True,
|
||||
)
|
||||
# For deposits above, and for another deposit_count, add a balance of EFFECTIVE_BALANCE_INCREMENT
|
||||
small_deposit_count = main_deposit_count * 2
|
||||
small_deposits, deposit_root, _ = prepare_genesis_deposits(spec, small_deposit_count,
|
||||
spec.MIN_DEPOSIT_AMOUNT,
|
||||
signed=True,
|
||||
deposit_data_list=deposit_data_list)
|
||||
small_deposits, deposit_root, _ = prepare_full_genesis_deposits(
|
||||
spec, spec.MIN_DEPOSIT_AMOUNT,
|
||||
deposit_count=small_deposit_count,
|
||||
signed=True,
|
||||
deposit_data_list=deposit_data_list,
|
||||
)
|
||||
deposits = main_deposits + small_deposits
|
||||
|
||||
eth1_block_hash = b'\x12' * 32
|
||||
|
@ -67,3 +77,109 @@ def test_initialize_beacon_state_some_small_balances(spec):
|
|||
|
||||
# yield state
|
||||
yield 'state', state
|
||||
|
||||
|
||||
@with_phases([PHASE0])
|
||||
@spec_test
|
||||
@single_phase
|
||||
def test_initialize_beacon_state_one_topup_activation(spec):
|
||||
# Submit all but one deposit as MAX_EFFECTIVE_BALANCE
|
||||
main_deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - 1
|
||||
main_deposits, _, deposit_data_list = prepare_full_genesis_deposits(
|
||||
spec, spec.MAX_EFFECTIVE_BALANCE,
|
||||
deposit_count=main_deposit_count, signed=True,
|
||||
)
|
||||
|
||||
# Submit last pubkey deposit as MAX_EFFECTIVE_BALANCE - MIN_DEPOSIT_AMOUNT
|
||||
partial_deposits, _, deposit_data_list = prepare_full_genesis_deposits(
|
||||
spec, spec.MAX_EFFECTIVE_BALANCE - spec.MIN_DEPOSIT_AMOUNT,
|
||||
deposit_count=1,
|
||||
min_pubkey_index=main_deposit_count,
|
||||
signed=True,
|
||||
deposit_data_list=deposit_data_list,
|
||||
)
|
||||
|
||||
# Top up thelast pubkey deposit as MIN_DEPOSIT_AMOUNT to complete the deposit
|
||||
top_up_deposits, _, _ = prepare_full_genesis_deposits(
|
||||
spec, spec.MIN_DEPOSIT_AMOUNT,
|
||||
deposit_count=1,
|
||||
min_pubkey_index=main_deposit_count,
|
||||
signed=True,
|
||||
deposit_data_list=deposit_data_list,
|
||||
)
|
||||
|
||||
deposits = main_deposits + partial_deposits + top_up_deposits
|
||||
|
||||
eth1_block_hash = b'\x13' * 32
|
||||
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||
|
||||
yield 'eth1_block_hash', eth1_block_hash
|
||||
yield 'eth1_timestamp', eth1_timestamp
|
||||
yield 'deposits', deposits
|
||||
|
||||
# initialize beacon_state
|
||||
state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||
assert spec.is_valid_genesis_state(state)
|
||||
|
||||
# yield state
|
||||
yield 'state', state
|
||||
|
||||
|
||||
@with_phases([PHASE0])
|
||||
@spec_test
|
||||
@single_phase
|
||||
def test_initialize_beacon_state_random_invalid_genesis(spec):
|
||||
# Make a bunch of random deposits
|
||||
deposits, _, deposit_data_list = prepare_random_genesis_deposits(
|
||||
spec,
|
||||
deposit_count=20,
|
||||
max_pubkey_index=10,
|
||||
)
|
||||
eth1_block_hash = b'\x14' * 32
|
||||
eth1_timestamp = spec.MIN_GENESIS_TIME + 1
|
||||
|
||||
yield 'eth1_block_hash', eth1_block_hash
|
||||
yield 'eth1_timestamp', eth1_timestamp
|
||||
yield 'deposits', deposits
|
||||
|
||||
# initialize beacon_state
|
||||
state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||
assert not spec.is_valid_genesis_state(state)
|
||||
|
||||
yield 'state', state
|
||||
|
||||
|
||||
@with_phases([PHASE0])
|
||||
@spec_test
|
||||
@single_phase
|
||||
def test_initialize_beacon_state_random_valid_genesis(spec):
|
||||
# Make a bunch of random deposits
|
||||
random_deposits, _, deposit_data_list = prepare_random_genesis_deposits(
|
||||
spec,
|
||||
deposit_count=20,
|
||||
min_pubkey_index=spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - 5,
|
||||
max_pubkey_index=spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + 5,
|
||||
)
|
||||
|
||||
# Then make spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT full deposits
|
||||
full_deposits, _, _ = prepare_full_genesis_deposits(
|
||||
spec,
|
||||
spec.MAX_EFFECTIVE_BALANCE,
|
||||
deposit_count=spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT,
|
||||
signed=True,
|
||||
deposit_data_list=deposit_data_list
|
||||
)
|
||||
|
||||
deposits = random_deposits + full_deposits
|
||||
eth1_block_hash = b'\x15' * 32
|
||||
eth1_timestamp = spec.MIN_GENESIS_TIME + 2
|
||||
|
||||
yield 'eth1_block_hash', eth1_block_hash
|
||||
yield 'eth1_timestamp', eth1_timestamp
|
||||
yield 'deposits', deposits
|
||||
|
||||
# initialize beacon_state
|
||||
state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||
assert spec.is_valid_genesis_state(state)
|
||||
|
||||
yield 'state', state
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
from eth2spec.test.context import PHASE0, spec_test, with_phases, single_phase
|
||||
from eth2spec.test.helpers.deposits import (
|
||||
prepare_genesis_deposits,
|
||||
prepare_full_genesis_deposits,
|
||||
)
|
||||
|
||||
|
||||
def create_valid_beacon_state(spec):
|
||||
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
deposits, _, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True)
|
||||
deposits, _, _ = prepare_full_genesis_deposits(
|
||||
spec,
|
||||
amount=spec.MAX_EFFECTIVE_BALANCE,
|
||||
deposit_count=deposit_count,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
eth1_block_hash = b'\x12' * 32
|
||||
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||
|
@ -69,7 +74,12 @@ def test_is_valid_genesis_state_true_more_balance(spec):
|
|||
@single_phase
|
||||
def test_is_valid_genesis_state_true_one_more_validator(spec):
|
||||
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + 1
|
||||
deposits, _, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True)
|
||||
deposits, _, _ = prepare_full_genesis_deposits(
|
||||
spec,
|
||||
amount=spec.MAX_EFFECTIVE_BALANCE,
|
||||
deposit_count=deposit_count,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
eth1_block_hash = b'\x12' * 32
|
||||
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||
|
@ -83,7 +93,12 @@ def test_is_valid_genesis_state_true_one_more_validator(spec):
|
|||
@single_phase
|
||||
def test_is_valid_genesis_state_false_not_enough_validator(spec):
|
||||
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - 1
|
||||
deposits, _, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE, signed=True)
|
||||
deposits, _, _ = prepare_full_genesis_deposits(
|
||||
spec,
|
||||
amount=spec.MAX_EFFECTIVE_BALANCE,
|
||||
deposit_count=deposit_count,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
eth1_block_hash = b'\x12' * 32
|
||||
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||
|
|
Loading…
Reference in New Issue