add deposit size check in state transiton. add deposit tests
This commit is contained in:
parent
a8e2b8cd1d
commit
cf4f3463a9
|
@ -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
|
|
@ -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)
|
||||||
#
|
#
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue