eth2.0-specs/py_tests/phase0/block_processing/test_voluntary_exit.py

164 lines
5.1 KiB
Python
Raw Normal View History

2019-03-19 21:49:01 +00:00
from copy import deepcopy
import pytest
2019-04-03 03:18:17 +00:00
import eth2spec.phase0.spec as spec
2019-03-19 21:49:01 +00:00
2019-04-03 03:18:17 +00:00
from eth2spec.phase0.spec import (
2019-03-19 21:49:01 +00:00
get_active_validator_indices,
2019-04-14 07:52:50 +00:00
get_churn_limit,
2019-03-19 21:49:01 +00:00
get_current_epoch,
process_voluntary_exit,
)
from phase0.helpers import (
2019-03-19 21:49:01 +00:00
build_voluntary_exit,
2019-03-25 17:25:33 +00:00
pubkey_to_privkey,
2019-03-19 21:49:01 +00:00
)
# mark entire file as 'voluntary_exits'
pytestmark = pytest.mark.voluntary_exits
2019-04-13 23:13:53 +00:00
def run_voluntary_exit_processing(state, voluntary_exit, valid=True):
"""
Run ``process_voluntary_exit`` returning the pre and post state.
If ``valid == False``, run expecting ``AssertionError``
"""
post_state = deepcopy(state)
if not valid:
with pytest.raises(AssertionError):
process_voluntary_exit(post_state, voluntary_exit)
return state, None
process_voluntary_exit(post_state, voluntary_exit)
validator_index = voluntary_exit.validator_index
assert state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH
assert post_state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
return state, post_state
2019-03-25 17:25:33 +00:00
def test_success(state):
2019-03-19 21:49:01 +00:00
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
2019-04-13 23:13:53 +00:00
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
2019-03-19 21:49:01 +00:00
2019-04-13 23:13:53 +00:00
current_epoch = get_current_epoch(state)
2019-04-14 07:52:50 +00:00
validator_index = get_active_validator_indices(state, current_epoch)[0]
2019-04-13 23:13:53 +00:00
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
2019-03-19 21:49:01 +00:00
voluntary_exit = build_voluntary_exit(
2019-04-13 23:13:53 +00:00
state,
2019-03-19 21:49:01 +00:00
current_epoch,
validator_index,
privkey,
)
2019-04-13 23:13:53 +00:00
pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit)
2019-03-19 21:49:01 +00:00
return pre_state, voluntary_exit, post_state
2019-04-13 23:13:53 +00:00
def test_success_exit_queue(state):
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = get_current_epoch(state)
# exit `MAX_EXITS_PER_EPOCH`
2019-04-14 07:52:50 +00:00
initial_indices = get_active_validator_indices(state, current_epoch)[:get_churn_limit(state)]
2019-04-13 23:13:53 +00:00
post_state = state
for index in initial_indices:
privkey = pubkey_to_privkey[state.validator_registry[index].pubkey]
voluntary_exit = build_voluntary_exit(
state,
current_epoch,
index,
privkey,
)
2019-04-13 23:21:29 +00:00
pre_state, post_state = run_voluntary_exit_processing(post_state, voluntary_exit)
2019-04-13 23:13:53 +00:00
# exit an additional validator
2019-04-14 07:52:50 +00:00
validator_index = get_active_validator_indices(state, current_epoch)[-1]
2019-04-13 23:13:53 +00:00
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
2019-03-19 21:49:01 +00:00
voluntary_exit = build_voluntary_exit(
2019-04-13 23:13:53 +00:00
state,
2019-03-19 21:49:01 +00:00
current_epoch,
validator_index,
privkey,
)
2019-04-13 23:13:53 +00:00
pre_state, post_state = run_voluntary_exit_processing(post_state, voluntary_exit)
2019-03-19 21:49:01 +00:00
2019-04-13 23:13:53 +00:00
assert (
post_state.validator_registry[validator_index].exit_epoch ==
post_state.validator_registry[initial_indices[0]].exit_epoch + 1
)
2019-03-19 21:49:01 +00:00
return pre_state, voluntary_exit, post_state
2019-03-25 17:25:33 +00:00
def test_validator_not_active(state):
2019-04-13 23:13:53 +00:00
current_epoch = get_current_epoch(state)
2019-04-14 07:52:50 +00:00
validator_index = get_active_validator_indices(state, current_epoch)[0]
2019-04-13 23:13:53 +00:00
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
2019-03-19 21:49:01 +00:00
2019-04-13 23:13:53 +00:00
state.validator_registry[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH
2019-03-19 21:49:01 +00:00
#
# build and test voluntary exit
#
voluntary_exit = build_voluntary_exit(
2019-04-13 23:13:53 +00:00
state,
2019-03-19 21:49:01 +00:00
current_epoch,
validator_index,
privkey,
)
2019-04-13 23:13:53 +00:00
pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False)
return pre_state, voluntary_exit, post_state
2019-03-19 21:49:01 +00:00
2019-03-25 17:25:33 +00:00
def test_validator_already_exited(state):
2019-03-19 21:49:01 +00:00
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow validator able to exit
2019-04-13 23:13:53 +00:00
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
2019-03-19 21:49:01 +00:00
2019-04-13 23:13:53 +00:00
current_epoch = get_current_epoch(state)
2019-04-14 07:52:50 +00:00
validator_index = get_active_validator_indices(state, current_epoch)[0]
2019-04-13 23:13:53 +00:00
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
2019-03-19 21:49:01 +00:00
# but validator already has exited
2019-04-13 23:13:53 +00:00
state.validator_registry[validator_index].exit_epoch = current_epoch + 2
2019-03-19 21:49:01 +00:00
voluntary_exit = build_voluntary_exit(
2019-04-13 23:13:53 +00:00
state,
2019-03-19 21:49:01 +00:00
current_epoch,
validator_index,
privkey,
)
2019-04-13 23:13:53 +00:00
pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False)
return pre_state, voluntary_exit, post_state
2019-03-19 21:49:01 +00:00
2019-03-25 17:25:33 +00:00
def test_validator_not_active_long_enough(state):
2019-04-13 23:13:53 +00:00
current_epoch = get_current_epoch(state)
2019-04-14 07:52:50 +00:00
validator_index = get_active_validator_indices(state, current_epoch)[0]
2019-04-13 23:13:53 +00:00
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
2019-03-19 21:49:01 +00:00
voluntary_exit = build_voluntary_exit(
2019-04-13 23:13:53 +00:00
state,
2019-03-19 21:49:01 +00:00
current_epoch,
validator_index,
privkey,
)
assert (
2019-04-13 23:13:53 +00:00
current_epoch - state.validator_registry[validator_index].activation_epoch <
2019-03-19 21:49:01 +00:00
spec.PERSISTENT_COMMITTEE_PERIOD
)
2019-04-13 23:13:53 +00:00
pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False)
return pre_state, voluntary_exit, post_state