Add test_genesis

This commit is contained in:
Hsiao-Wei Wang 2019-06-21 15:59:18 -06:00
parent 0031eaa96a
commit 7a16db144c
No known key found for this signature in database
GPG Key ID: 95B070122902DEA4
4 changed files with 84 additions and 12 deletions

View File

@ -16,6 +16,7 @@ PHASE0_IMPORTS = '''from typing import (
Callable, Callable,
Dict, Dict,
List, List,
Optional,
Set, Set,
Tuple, Tuple,
) )

View File

@ -1176,8 +1176,12 @@ def get_genesis_beacon_state(deposits: List[Deposit], genesis_time: int, genesis
) )
# Process genesis deposits # Process genesis deposits
for deposit in deposits: for deposit_index, deposit in enumerate(deposits):
process_deposit(state, deposit) process_deposit(
state,
deposit,
deposit_index=deposit_index,
)
# Process genesis activations # Process genesis activations
for validator in state.validators: for validator in state.validators:
@ -1726,16 +1730,18 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
##### Deposits ##### Deposits
```python ```python
def process_deposit(state: BeaconState, deposit: Deposit) -> None: def process_deposit(state: BeaconState, deposit: Deposit, deposit_index: Optional[uint64]) -> None:
""" """
Process an Eth1 deposit, registering a validator or increasing its balance. Process an Eth1 deposit, registering a validator or increasing its balance.
""" """
if deposit_index is None:
deposit_index = state.eth1_deposit_index
# Verify the Merkle branch # Verify the Merkle branch
assert verify_merkle_branch( assert verify_merkle_branch(
leaf=hash_tree_root(deposit.data), leaf=hash_tree_root(deposit.data),
proof=deposit.proof, proof=deposit.proof,
depth=DEPOSIT_CONTRACT_TREE_DEPTH, depth=DEPOSIT_CONTRACT_TREE_DEPTH,
index=state.eth1_deposit_index, index=deposit_index,
root=state.eth1_data.deposit_root, root=state.eth1_data.deposit_root,
) )

View File

@ -4,25 +4,31 @@ from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merk
from eth2spec.utils.ssz.ssz_impl import signing_root from eth2spec.utils.ssz.ssz_impl import signing_root
def build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed=False): def build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=None, signed=False):
deposit_data = spec.DepositData( deposit_data = spec.DepositData(
pubkey=pubkey, pubkey=pubkey,
withdrawal_credentials=withdrawal_credentials, withdrawal_credentials=withdrawal_credentials,
amount=amount, amount=amount,
) )
if signed: if signed:
sign_deposit_data(spec, state, deposit_data, privkey) sign_deposit_data(spec, deposit_data, privkey, state)
return deposit_data return deposit_data
def sign_deposit_data(spec, state, deposit_data, privkey): def sign_deposit_data(spec, deposit_data, privkey, state=None):
signature = bls_sign( if state is None:
message_hash=signing_root(deposit_data), # Genesis
privkey=privkey, domain = spec.bls_domain(spec.DOMAIN_DEPOSIT)
domain=spec.get_domain( else:
domain = spec.get_domain(
state, state,
spec.DOMAIN_DEPOSIT, spec.DOMAIN_DEPOSIT,
) )
signature = bls_sign(
message_hash=signing_root(deposit_data),
privkey=privkey,
domain=domain,
) )
deposit_data.signature = signature deposit_data.signature = signature
@ -35,7 +41,7 @@ def build_deposit(spec,
amount, amount,
withdrawal_credentials, withdrawal_credentials,
signed): signed):
deposit_data = build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed) deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed)
item = deposit_data.hash_tree_root() item = deposit_data.hash_tree_root()
index = len(deposit_data_leaves) index = len(deposit_data_leaves)
@ -54,6 +60,36 @@ def build_deposit(spec,
return deposit, root, deposit_data_leaves return deposit, root, deposit_data_leaves
def prepare_genesis_deposits(spec, genesis_validator_count, signed=False):
genesis_deposit_data_list = []
deposit_data_leaves = []
for validator_index in range(genesis_validator_count):
pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
# insecurely use pubkey as withdrawal key if no credentials provided
withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(pubkey)[1:]
deposit_data = spec.DepositData(
pubkey=pubkey,
withdrawal_credentials=withdrawal_credentials,
amount=spec.MAX_EFFECTIVE_BALANCE,
)
if signed:
sign_deposit_data(spec, deposit_data, privkey) # state=None
item = deposit_data.hash_tree_root()
deposit_data_leaves.append(item)
genesis_deposit_data_list.append(deposit_data)
tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves))
root = get_merkle_root((tuple(deposit_data_leaves)))
genesis_deposits = (
spec.Deposit(proof=list(get_merkle_proof(tree, item_index=index)), data=deposit_data)
for index, deposit_data in enumerate(genesis_deposit_data_list)
)
return genesis_deposits, root
def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False): 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. Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount.

View File

@ -0,0 +1,29 @@
from eth2spec.test.context import spec_state_test, with_phases
from eth2spec.test.helpers.deposits import (
prepare_genesis_deposits,
)
@with_phases(['phase0'])
@spec_state_test
def test_genesis(spec, state):
deposit_count = 2
genesis_deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count)
genesis_time = 1234
yield genesis_deposits
yield genesis_time
genesis_eth1_data = spec.Eth1Data(
deposit_root=deposit_root,
deposit_count=deposit_count,
block_hash=b'\x12' * 32,
)
yield genesis_eth1_data
genesis_state = spec.get_genesis_beacon_state(
genesis_deposits,
genesis_time,
genesis_eth1_data,
)
yield genesis_state