Merge pull request #785 from ethereum/JustinDrake-patch-13
Include recently slashed churn in exit churn queue
This commit is contained in:
commit
571439bb6f
|
@ -2089,16 +2089,21 @@ def update_validator_registry(state: BeaconState) -> None:
|
||||||
activate_validator(state, index, is_genesis=False)
|
activate_validator(state, index, is_genesis=False)
|
||||||
|
|
||||||
# Exit validators within the allowable balance churn
|
# Exit validators within the allowable balance churn
|
||||||
balance_churn = 0
|
if current_epoch < state.validator_registry_update_epoch + LATEST_SLASHED_EXIT_LENGTH:
|
||||||
for index, validator in enumerate(state.validator_registry):
|
balance_churn = (
|
||||||
if validator.exit_epoch == FAR_FUTURE_EPOCH and validator.initiated_exit:
|
state.latest_slashed_balances[state.validator_registry_update_epoch % LATEST_SLASHED_EXIT_LENGTH] -
|
||||||
# Check the balance churn would be within the allowance
|
state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH]
|
||||||
balance_churn += get_effective_balance(state, index)
|
)
|
||||||
if balance_churn > max_balance_churn:
|
|
||||||
break
|
|
||||||
|
|
||||||
# Exit validator
|
for index, validator in enumerate(state.validator_registry):
|
||||||
exit_validator(state, index)
|
if validator.exit_epoch == FAR_FUTURE_EPOCH and validator.initiated_exit:
|
||||||
|
# Check the balance churn would be within the allowance
|
||||||
|
balance_churn += get_effective_balance(state, index)
|
||||||
|
if balance_churn > max_balance_churn:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Exit validator
|
||||||
|
exit_validator(state, index)
|
||||||
|
|
||||||
state.validator_registry_update_epoch = current_epoch
|
state.validator_registry_update_epoch = current_epoch
|
||||||
```
|
```
|
||||||
|
|
|
@ -316,12 +316,18 @@ def test_attestation(state, pubkeys, privkeys):
|
||||||
|
|
||||||
def test_voluntary_exit(state, pubkeys, privkeys):
|
def test_voluntary_exit(state, pubkeys, privkeys):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
validator_index = get_active_validator_indices(pre_state.validator_registry, get_current_epoch(pre_state))[-1]
|
validator_index = get_active_validator_indices(
|
||||||
|
pre_state.validator_registry,
|
||||||
|
get_current_epoch(pre_state)
|
||||||
|
)[-1]
|
||||||
|
|
||||||
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
|
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
|
||||||
pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
|
pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
|
||||||
# artificially trigger registry update at next epoch transition
|
# artificially trigger registry update at next epoch transition
|
||||||
pre_state.validator_registry_update_epoch -= 1
|
pre_state.finalized_epoch = get_current_epoch(pre_state) - 1
|
||||||
|
for crosslink in pre_state.latest_crosslinks:
|
||||||
|
crosslink.epoch = pre_state.finalized_epoch
|
||||||
|
pre_state.validator_registry_update_epoch = pre_state.finalized_epoch - 1
|
||||||
|
|
||||||
post_state = deepcopy(pre_state)
|
post_state = deepcopy(pre_state)
|
||||||
|
|
||||||
|
@ -363,6 +369,44 @@ def test_voluntary_exit(state, pubkeys, privkeys):
|
||||||
return pre_state, [initiate_exit_block, exit_block], post_state
|
return pre_state, [initiate_exit_block, exit_block], post_state
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_exit_too_long_since_change(state):
|
||||||
|
pre_state = deepcopy(state)
|
||||||
|
validator_index = get_active_validator_indices(
|
||||||
|
pre_state.validator_registry,
|
||||||
|
get_current_epoch(pre_state)
|
||||||
|
)[-1]
|
||||||
|
|
||||||
|
#
|
||||||
|
# setup pre_state
|
||||||
|
#
|
||||||
|
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
|
||||||
|
pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
|
||||||
|
# artificially trigger registry update at next epoch transition
|
||||||
|
pre_state.finalized_epoch = get_current_epoch(pre_state) - 1
|
||||||
|
for crosslink in pre_state.latest_crosslinks:
|
||||||
|
crosslink.epoch = pre_state.finalized_epoch
|
||||||
|
# make epochs since registry update greater than LATEST_SLASHED_EXIT_LENGTH
|
||||||
|
pre_state.validator_registry_update_epoch = (
|
||||||
|
get_current_epoch(pre_state) - spec.LATEST_SLASHED_EXIT_LENGTH
|
||||||
|
)
|
||||||
|
# set validator to have previously initiated exit
|
||||||
|
pre_state.validator_registry[validator_index].initiated_exit = True
|
||||||
|
|
||||||
|
post_state = deepcopy(pre_state)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Process registry change but ensure no exit
|
||||||
|
#
|
||||||
|
block = build_empty_block_for_next_slot(post_state)
|
||||||
|
block.slot += spec.SLOTS_PER_EPOCH
|
||||||
|
state_transition(post_state, block)
|
||||||
|
|
||||||
|
assert post_state.validator_registry_update_epoch == get_current_epoch(post_state) - 1
|
||||||
|
assert post_state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH
|
||||||
|
|
||||||
|
return pre_state, [block], post_state
|
||||||
|
|
||||||
|
|
||||||
def test_transfer(state, pubkeys, privkeys):
|
def test_transfer(state, pubkeys, privkeys):
|
||||||
pre_state = deepcopy(state)
|
pre_state = deepcopy(state)
|
||||||
current_epoch = get_current_epoch(pre_state)
|
current_epoch = get_current_epoch(pre_state)
|
||||||
|
|
Loading…
Reference in New Issue