add deposit size check in state transiton. add deposit tests

This commit is contained in:
Danny Ryan 2019-03-19 17:10:36 -06:00
parent a8e2b8cd1d
commit cf4f3463a9
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
5 changed files with 180 additions and 1 deletions

View File

@ -0,0 +1,132 @@
from copy import deepcopy
import pytest
import build.phase0.spec as spec
from build.phase0.spec import (
Deposit,
process_deposit,
)
from tests.phase0.helpers import (
build_deposit,
)
# mark entire file as 'voluntary_exits'
pytestmark = pytest.mark.voluntary_exits
def test_success(state, deposit_data_leaves, pubkeys, privkeys):
pre_state = deepcopy(state)
index = len(deposit_data_leaves)
pubkey = pubkeys[index]
privkey = privkeys[index]
deposit, root, deposit_data_leaves = build_deposit(
pre_state,
deposit_data_leaves,
pubkey,
privkey,
spec.MAX_DEPOSIT_AMOUNT,
)
pre_state.latest_eth1_data.deposit_root = root
pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves)
post_state = deepcopy(pre_state)
process_deposit(post_state, deposit)
assert len(post_state.validator_registry) == len(state.validator_registry) + 1
assert len(post_state.validator_balances) == len(state.validator_balances) + 1
assert post_state.validator_registry[index].pubkey == pubkeys[index]
assert post_state.deposit_index == post_state.latest_eth1_data.deposit_count
return pre_state, deposit, post_state
def test_success_top_up(state, deposit_data_leaves, pubkeys, privkeys):
pre_state = deepcopy(state)
validator_index = 0
amount = spec.MAX_DEPOSIT_AMOUNT // 4
pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
deposit, root, deposit_data_leaves = build_deposit(
pre_state,
deposit_data_leaves,
pubkey,
privkey,
amount,
)
pre_state.latest_eth1_data.deposit_root = root
pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves)
pre_balance = pre_state.validator_balances[validator_index]
post_state = deepcopy(pre_state)
process_deposit(post_state, deposit)
assert len(post_state.validator_registry) == len(state.validator_registry)
assert len(post_state.validator_balances) == len(state.validator_balances)
assert post_state.deposit_index == post_state.latest_eth1_data.deposit_count
assert post_state.validator_balances[validator_index] == pre_balance + amount
return pre_state, deposit, post_state
def test_wrong_index(state, deposit_data_leaves, pubkeys, privkeys):
pre_state = deepcopy(state)
index = len(deposit_data_leaves)
pubkey = pubkeys[index]
privkey = privkeys[index]
deposit, root, deposit_data_leaves = build_deposit(
pre_state,
deposit_data_leaves,
pubkey,
privkey,
spec.MAX_DEPOSIT_AMOUNT,
)
# mess up deposit_index
deposit.index = pre_state.deposit_index + 1
pre_state.latest_eth1_data.deposit_root = root
pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves)
post_state = deepcopy(pre_state)
with pytest.raises(AssertionError):
process_deposit(post_state, deposit)
return pre_state, deposit, None
def test_bad_merkle_proof(state, deposit_data_leaves, pubkeys, privkeys):
pre_state = deepcopy(state)
index = len(deposit_data_leaves)
pubkey = pubkeys[index]
privkey = privkeys[index]
deposit, root, deposit_data_leaves = build_deposit(
pre_state,
deposit_data_leaves,
pubkey,
privkey,
spec.MAX_DEPOSIT_AMOUNT,
)
# mess up merkle branch
deposit.proof[-1] = spec.ZERO_HASH
pre_state.latest_eth1_data.deposit_root = root
pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves)
post_state = deepcopy(pre_state)
with pytest.raises(AssertionError):
process_deposit(post_state, deposit)
return pre_state, deposit, None

View File

@ -13,6 +13,10 @@ from tests.phase0.helpers import (
) )
# mark entire file as 'voluntary_exits'
pytestmark = pytest.mark.voluntary_exits
def test_success(state, pub_to_priv): def test_success(state, pub_to_priv):
pre_state = deepcopy(state) pre_state = deepcopy(state)
# #

View File

@ -72,12 +72,16 @@ def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves):
def create_genesis_state(num_validators, deposit_data_leaves): def create_genesis_state(num_validators, deposit_data_leaves):
initial_deposits, deposit_root = create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves) initial_deposits, deposit_root = create_mock_genesis_validator_deposits(
num_validators,
deposit_data_leaves,
)
return get_genesis_beacon_state( return get_genesis_beacon_state(
initial_deposits, initial_deposits,
genesis_time=0, genesis_time=0,
genesis_eth1_data=Eth1Data( genesis_eth1_data=Eth1Data(
deposit_root=deposit_root, deposit_root=deposit_root,
deposit_count=len(initial_deposits),
block_hash=spec.ZERO_HASH, block_hash=spec.ZERO_HASH,
), ),
) )
@ -171,3 +175,27 @@ def build_voluntary_exit(state, epoch, validator_index, privkey):
) )
return voluntary_exit return voluntary_exit
def build_deposit(state,
deposit_data_leaves,
pubkey,
privkey,
amount):
deposit_data = build_deposit_data(state, pubkey, privkey, amount)
item = hash(deposit_data.serialize())
index = len(deposit_data_leaves)
deposit_data_leaves.append(item)
tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves))
root = get_merkle_root((tuple(deposit_data_leaves)))
proof = list(get_merkle_proof(tree, item_index=index))
assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root)
deposit = Deposit(
proof=list(proof),
index=index,
deposit_data=deposit_data,
)
return deposit, root, deposit_data_leaves

View File

@ -196,6 +196,7 @@ def test_deposit_in_block(state, deposit_data_leaves, pubkeys, privkeys):
) )
pre_state.latest_eth1_data.deposit_root = root pre_state.latest_eth1_data.deposit_root = root
pre_state.latest_eth1_data.deposit_count = len(test_deposit_data_leaves)
post_state = deepcopy(pre_state) post_state = deepcopy(pre_state)
block = build_empty_block_for_next_slot(post_state) block = build_empty_block_for_next_slot(post_state)
block.body.deposits.append(deposit) block.body.deposits.append(deposit)
@ -233,6 +234,7 @@ def test_deposit_top_up(state, pubkeys, privkeys, deposit_data_leaves):
) )
pre_state.latest_eth1_data.deposit_root = root pre_state.latest_eth1_data.deposit_root = root
pre_state.latest_eth1_data.deposit_count = len(test_deposit_data_leaves)
block = build_empty_block_for_next_slot(pre_state) block = build_empty_block_for_next_slot(pre_state)
block.body.deposits.append(deposit) block.body.deposits.append(deposit)

View File

@ -15,6 +15,13 @@ from .spec import (
) )
def expected_deposit_count(state: BeaconState) -> int:
return min(
spec.MAX_DEPOSITS,
state.latest_eth1_data.deposit_count - state.deposit_index
)
def process_transaction_type(state: BeaconState, def process_transaction_type(state: BeaconState,
transactions: List[Any], transactions: List[Any],
max_transactions: int, max_transactions: int,
@ -31,30 +38,36 @@ def process_transactions(state: BeaconState, block: BeaconBlock) -> None:
spec.MAX_PROPOSER_SLASHINGS, spec.MAX_PROPOSER_SLASHINGS,
spec.process_proposer_slashing, spec.process_proposer_slashing,
) )
process_transaction_type( process_transaction_type(
state, state,
block.body.attester_slashings, block.body.attester_slashings,
spec.MAX_ATTESTER_SLASHINGS, spec.MAX_ATTESTER_SLASHINGS,
spec.process_attester_slashing, spec.process_attester_slashing,
) )
process_transaction_type( process_transaction_type(
state, state,
block.body.attestations, block.body.attestations,
spec.MAX_ATTESTATIONS, spec.MAX_ATTESTATIONS,
spec.process_attestation, spec.process_attestation,
) )
assert len(block.body.deposits) == expected_deposit_count(state)
process_transaction_type( process_transaction_type(
state, state,
block.body.deposits, block.body.deposits,
spec.MAX_DEPOSITS, spec.MAX_DEPOSITS,
spec.process_deposit, spec.process_deposit,
) )
process_transaction_type( process_transaction_type(
state, state,
block.body.voluntary_exits, block.body.voluntary_exits,
spec.MAX_VOLUNTARY_EXITS, spec.MAX_VOLUNTARY_EXITS,
spec.process_voluntary_exit, spec.process_voluntary_exit,
) )
assert len(block.body.transfers) == len(set(block.body.transfers)) assert len(block.body.transfers) == len(set(block.body.transfers))
process_transaction_type( process_transaction_type(
state, state,