Skip to content

Commit

Permalink
update to ethereum/consensus-specs#750. add deposit top up test
Browse files Browse the repository at this point in the history
  • Loading branch information
djrtwo committed Mar 12, 2019
1 parent b986cb7 commit b9ec207
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 21 deletions.
48 changes: 48 additions & 0 deletions spec_pythonizer/sanity_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
38 changes: 17 additions & 21 deletions spec_pythonizer/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -1298,34 +1298,33 @@ 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
amount = deposit.deposit_data.amount
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,
Expand All @@ -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
Expand Down

0 comments on commit b9ec207

Please sign in to comment.