From b9ec2076fc9934561c4508c38bafdbf3656465d0 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Tue, 12 Mar 2019 11:21:55 -0600 Subject: [PATCH] update to https://github.com/ethereum/eth2.0-specs/pull/750. add deposit top up test --- spec_pythonizer/sanity_check.py | 48 +++++++++++++++++++++++++++++++++ spec_pythonizer/spec.md | 38 ++++++++++++-------------- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/spec_pythonizer/sanity_check.py b/spec_pythonizer/sanity_check.py index 46c08825..8fe73349 100644 --- a/spec_pythonizer/sanity_check.py +++ b/spec_pythonizer/sanity_check.py @@ -347,6 +347,52 @@ def test_deposit_in_block(state): return state, [block], test_state +@timeit +def test_deposit_top_up(state): + test_state = deepcopy(state) + test_deposit_data_leaves = deepcopy(all_deposit_data_leaves) + withdrawal_credentials = b'\x42' * 32 + deposit_timestamp = 1 + proof_of_possession = b'\x44' * 96 + amount = MAX_DEPOSIT_AMOUNT // 4 + validator_index = 0 + + merkle_index = len(test_deposit_data_leaves) + deposit_data = DepositData( + amount=amount, + timestamp=deposit_timestamp, + deposit_input=DepositInput( + pubkey=test_state.validator_registry[validator_index].pubkey, + withdrawal_credentials=withdrawal_credentials, + proof_of_possession=proof_of_possession, + ), + ) + item = hash(deposit_data.serialize()) + test_deposit_data_leaves.append(item) + tree = calc_merkle_tree_from_leaves(tuple(test_deposit_data_leaves)) + root = get_merkle_root((tuple(test_deposit_data_leaves))) + proof = list(get_merkle_proof(tree, item_index=merkle_index)) + assert verify_merkle_branch(item, proof, DEPOSIT_CONTRACT_TREE_DEPTH, merkle_index, root) + + deposit = Deposit( + proof=list(proof), + index=merkle_index, + deposit_data=deposit_data, + ) + + test_state.latest_eth1_data.deposit_root = root + block = construct_empty_block_for_next_slot(test_state) + block.body.deposits.append(deposit) + + pre_balance = test_state.validator_balances[validator_index] + state_transition(test_state, block) + assert len(test_state.validator_registry) == len(state.validator_registry) + assert len(test_state.validator_balances) == len(state.validator_balances) + assert test_state.validator_balances[validator_index] == pre_balance + amount + + return state, [block], test_state + + @timeit def test_attestation(state): test_state = deepcopy(state) @@ -543,6 +589,8 @@ def sanity_tests(): print("Passed attestation test\n") test_cases.append(test_deposit_in_block(genesis_state)) print("Passed deposit test\n") + test_cases.append(test_deposit_top_up(genesis_state)) + print("Passed deposit top up test\n") test_cases.append(test_voluntary_exit(genesis_state)) print("Passed voluntary exit test\n") test_cases.append(test_transfer(genesis_state)) diff --git a/spec_pythonizer/spec.md b/spec_pythonizer/spec.md index 9571c23d..b4554e0f 100644 --- a/spec_pythonizer/spec.md +++ b/spec_pythonizer/spec.md @@ -1288,7 +1288,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: serialized_deposit_data = serialize(deposit.deposit_data) # Deposits must be processed in order assert deposit.index == state.deposit_index - + # Verify the Merkle branch merkle_branch_is_valid = verify_merkle_branch( leaf=hash(serialized_deposit_data), @@ -1298,27 +1298,12 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: root=state.latest_eth1_data.deposit_root, ) assert merkle_branch_is_valid - + # Increment the next deposit index we are expecting. Note that this # needs to be done here because while the deposit contract will never # create an invalid Merkle branch, it may admit an invalid deposit # object, and we need to be able to skip over it state.deposit_index += 1 - - # Verify the proof of possession - proof_is_valid = bls_verify( - pubkey=deposit_input.pubkey, - message_hash=signed_root(deposit_input), - signature=deposit_input.proof_of_possession, - domain=get_domain( - state.fork, - get_current_epoch(state), - DOMAIN_DEPOSIT, - ) - ) - - if not proof_is_valid: - return validator_pubkeys = [v.pubkey for v in state.validator_registry] pubkey = deposit_input.pubkey @@ -1326,6 +1311,20 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: withdrawal_credentials = deposit_input.withdrawal_credentials if pubkey not in validator_pubkeys: + # Verify the proof of possession + proof_is_valid = bls_verify( + pubkey=deposit_input.pubkey, + message_hash=signed_root(deposit_input), + signature=deposit_input.proof_of_possession, + domain=get_domain( + state.fork, + get_current_epoch(state), + DOMAIN_DEPOSIT, + ) + ) + if not proof_is_valid: + return + # Add new validator validator = Validator( pubkey=pubkey, @@ -1342,10 +1341,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: state.validator_balances.append(amount) else: # Increase balance by deposit amount - index = validator_pubkeys.index(pubkey) - assert state.validator_registry[index].withdrawal_credentials == withdrawal_credentials - - state.validator_balances[index] += amount + state.validator_balances[validator_pubkeys.index(pubkey)] += amount ``` ### Routines for updating validator status