From 2015433fa1c7c95867d796eacf1a14ee5ce14b49 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 20 Jan 2020 20:03:38 -0700 Subject: [PATCH] revert exit queue epoch issue introduced in v0.10.0. add test to catch subtlety --- specs/phase0/beacon-chain.md | 2 +- .../test_process_voluntary_exit.py | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/specs/phase0/beacon-chain.md b/specs/phase0/beacon-chain.md index 503286e48..dcc03fc47 100644 --- a/specs/phase0/beacon-chain.md +++ b/specs/phase0/beacon-chain.md @@ -1036,7 +1036,7 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: # Compute exit queue epoch exit_epochs = [v.exit_epoch for v in state.validators if v.exit_epoch != FAR_FUTURE_EPOCH] - exit_queue_epoch = max(exit_epochs, default=compute_activation_exit_epoch(get_current_epoch(state))) + exit_queue_epoch = max(exit_epochs + [compute_activation_exit_epoch(get_current_epoch(state))]) exit_queue_churn = len([v for v in state.validators if v.exit_epoch == exit_queue_epoch]) if exit_queue_churn >= get_validator_churn_limit(state): exit_queue_epoch += Epoch(1) diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py b/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py index 461c38b73..19915750f 100644 --- a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py +++ b/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py @@ -46,6 +46,8 @@ def test_success(spec, state): yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit) + assert state.validators[validator_index].exit_epoch == spec.compute_activation_exit_epoch(current_epoch) + @with_all_phases @spec_state_test @@ -110,6 +112,28 @@ def test_success_exit_queue(spec, state): ) +@with_all_phases +@spec_state_test +def test_default_exit_epoch_subsequent_exit(spec, state): + # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit + state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH + + current_epoch = spec.get_current_epoch(state) + validator_index = spec.get_active_validator_indices(state, current_epoch)[0] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] + + signed_voluntary_exit = sign_voluntary_exit( + spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey) + + # Exit one validator prior to this new one + exited_index = spec.get_active_validator_indices(state, current_epoch)[-1] + state.validators[exited_index].exit_epoch = current_epoch - 1 + + yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit) + + assert state.validators[validator_index].exit_epoch == spec.compute_activation_exit_epoch(current_epoch) + + @with_all_phases @spec_state_test def test_validator_exit_in_future(spec, state):