Fix activation queue bug

Fix bug [flagged by @NIC619 and @hwwhww](https://github.com/ethereum/eth2.0-specs/pull/850#issuecomment-485275575) whereby the `activation_epoch` of validators dequeued since the finalized epoch was overwritten.

Cosmetic changes:

1) Remove `activate_validator` (there is no overlap between genesis and non-genesis activations)
2) Improve comments related to activation queue
This commit is contained in:
Justin 2019-04-22 15:12:30 +10:00 committed by GitHub
parent 3ea4620eb2
commit 0da60ba90d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 7 additions and 21 deletions

View File

@ -94,7 +94,6 @@
- [`bls_verify_multiple`](#bls_verify_multiple) - [`bls_verify_multiple`](#bls_verify_multiple)
- [`bls_aggregate_pubkeys`](#bls_aggregate_pubkeys) - [`bls_aggregate_pubkeys`](#bls_aggregate_pubkeys)
- [Routines for updating validator status](#routines-for-updating-validator-status) - [Routines for updating validator status](#routines-for-updating-validator-status)
- [`activate_validator`](#activate_validator)
- [`initiate_validator_exit`](#initiate_validator_exit) - [`initiate_validator_exit`](#initiate_validator_exit)
- [`slash_validator`](#slash_validator) - [`slash_validator`](#slash_validator)
- [Ethereum 1.0 deposit contract](#ethereum-10-deposit-contract) - [Ethereum 1.0 deposit contract](#ethereum-10-deposit-contract)
@ -1205,22 +1204,6 @@ def get_churn_limit(state: BeaconState) -> int:
Note: All functions in this section mutate `state`. Note: All functions in this section mutate `state`.
#### `activate_validator`
```python
def activate_validator(state: BeaconState, index: ValidatorIndex) -> None:
"""
Activate the validator of the given ``index``.
Note that this function mutates ``state``.
"""
validator = state.validator_registry[index]
if state.slot == GENESIS_SLOT:
validator.activation_eligibility_epoch = GENESIS_EPOCH
validator.activation_epoch = GENESIS_EPOCH
else:
validator.activation_epoch = get_delayed_activation_exit_epoch(get_current_epoch(state))
```
#### `initiate_validator_exit` #### `initiate_validator_exit`
```python ```python
@ -1340,9 +1323,10 @@ def get_genesis_beacon_state(genesis_validator_deposits: List[Deposit],
process_deposit(state, deposit) process_deposit(state, deposit)
# Process genesis activations # Process genesis activations
for index in range(len(state.validator_registry)): for index, validator in enumerate(state.validator_registry):
if get_effective_balance(state, index) >= MAX_DEPOSIT_AMOUNT: if get_effective_balance(state, index) >= MAX_DEPOSIT_AMOUNT:
activate_validator(state, index) validator.activation_eligibility_epoch = GENESIS_EPOCH
validator.activation_epoch = GENESIS_EPOCH
genesis_active_index_root = hash_tree_root(get_active_validator_indices(state, GENESIS_EPOCH)) genesis_active_index_root = hash_tree_root(get_active_validator_indices(state, GENESIS_EPOCH))
for index in range(LATEST_ACTIVE_INDEX_ROOTS_LENGTH): for index in range(LATEST_ACTIVE_INDEX_ROOTS_LENGTH):
@ -1745,14 +1729,16 @@ def process_registry_updates(state: BeaconState) -> None:
if is_active_validator(validator, get_current_epoch(state)) and balance < EJECTION_BALANCE: if is_active_validator(validator, get_current_epoch(state)) and balance < EJECTION_BALANCE:
initiate_validator_exit(state, index) initiate_validator_exit(state, index)
# Process activations # Queue validators are eligible for activation and not dequeued prior to finalized epoch
activation_queue = sorted([ activation_queue = sorted([
index for index, validator in enumerate(state.validator_registry) if index for index, validator in enumerate(state.validator_registry) if
validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and
validator.activation_epoch >= get_delayed_activation_exit_epoch(state.finalized_epoch) validator.activation_epoch >= get_delayed_activation_exit_epoch(state.finalized_epoch)
], key=lambda index: state.validator_registry[index].activation_eligibility_epoch) ], key=lambda index: state.validator_registry[index].activation_eligibility_epoch)
# Dequeued validators for activation up to churn limit (without resetting activation epoch)
for index in activation_queue[:get_churn_limit(state)]: for index in activation_queue[:get_churn_limit(state)]:
activate_validator(state, index) if validator.activation_epoch != FAR_FUTURE_EPOCH:
validator.activation_epoch = get_delayed_activation_exit_epoch(get_current_epoch(state))
``` ```
#### Slashings #### Slashings