eth2
v0.10.1
By @hwwhww 20200115
Special thanks to @djrtwo for the review.
Changelog
20200212: Fix PERSISTENT_COMMITTEE_PERIOD
value mistake. Thanks to
Joseph Chow for finding out this mistake.
20200127: Update to v0.10.1 - fix exit queue
The validator status is defined in the beacon chain spec with “beacon state transition” functions. This document describes the concept of validator status epochs and the cases of validator lifecycle in the view of “validator status transition” in phase 0. We also recommend you to read Serenity Design Rationale - The validator lifecycle to understand the deep meaning of some constants configuration.
The validator may be in the following statuses:
BeaconState
.Note that the validator may be “eligible to be activated, but has not been activated yet”.
Note that the validator will be able to withdraw to EEs in phase 2
Note that in some cases, a validator can be in multiple statuses at the same time, e.g., an active validator may be “activated and slashed”.
To determine the status of validator, we maintain the status epoch fields for each validator in BeaconState
. The fields include activation eligibility, activation, exit, and withdrawable.
These fields define that a validator is in statusx status when v.status_epochx≥current_status. The default value of the status epoch fields is FAR_FUTURE_EPOCH, where FAR_FUTURE_EPOCH:=264−1 epochs.
For example, if a validator v1, where v1.activation_eligibility_epoch is 100 and
v1.activation_epoch is 200.
By updating these fields, we can determine the validator statuses. Basically, the status epoch setting should follow:
activation_eligibility_epoch≤acitivation_epoch≤exit_epoch≤withdrawable_epoch
validator.slashed
boolean flagWe use a slashed
flag field in Validator
to describe if the validator has been slashed.
You can find more information on slashing from the validator guide doc. Note that a slashed validator will be forced to exit (we will discuss the details in Chapter 4).
To (i) ensure the validator set is stable enough between two points and (ii) ensure that finality guarantees still remain between two chains as long as a validator logs on often enough (weak subjectivity), we limit the activation/exit queues dynamically.
Some rationale is described in Serenity Design Rationale - Exiting.
The churn limit computation algorithm is describe in get_validator_churn_limit.
|S|:=the size of set SVactive:=the active validatorschurn_limit(state):=max(MIN_PER_EPOCH_CHURN_LIMIT, ⌊|Vactive|CHURN_LIMIT_QUOTIENT⌋)
For example, if the churn_limit(state)
is 10, that means at the current epoch, only the first 10 validators in the activation queue could be initiated activation.
In normal operation with sufficient validators, CHURN_LIMIT_QUOTIENT
dictates the maximum fraction of validators that can churn in a given epoch.
To ensure that validators can always activate/exit even when a low total validator count, MIN_PER_EPOCH_CHURN_LIMIT
is in place.
This section, we will explain each validator status transition step-by-step. The following is the state transition diagram:
💡 Hint: click the image to see the full-size diagram.
The validator has deposited the deposit contract, and the corresponding Deposit
operation has been processed.
In epoch-processing, step 1.a checks if the validator is eligible for activation queue:
In epoch-processing, step 2.a checks if the validator is eligible for activation and is within churn limit:
Note that since we process epoch transition right after processing the last slot of epoch n. That’s why we have to add +1 to the status epoch.
After MAX_SEED_LOOKAHEAD epochs (:=4 epochs, ~25.6 minutes), the validator will be 3. Activated.
The active validator will now be assigned duties each epoch (perform attesting, proposing, etc.) and gain rewards. Normally, we expect most validators will stay at the activated status for a long time.
If a validator misbehaves (i.e., double voting or surround voting), the other validator can create a slashing operation to catch it on-chain, and the misbehaved validator will get slashed.
Once the validator gets slashed when processing slashing operations, they will be forced to initiate exit, plus extra ~36 days delay before being withdrawable.
To initiate exit, first, we check if the validator has not initiated exit before, i.e., v.exit_epoch=FAR_FUTURE_EPOCH. If so, we compute the exit queue epoch (see below), and then set validator exit epoch and withdrawable epoch.
Like the activation queue, The exit queue dequeue process is also based on the current churn rate:
exit_epochs(state) :={v.exit_epoch ∀v∈V | v.exit_epoch≠FAR_FUTURE_EPOCH}exit_queue_epoch(state) :=max{exit_epochs(state)∪{current_epoch+1+MAX_SEED_LOOKAHEAD}}v.exit_epoch:=exit_queue_epoch(state)v.withdrawable_epoch:=v.exit_epoch+MIN_VALIDATOR_WITHDRAWABILITY_DELAY
The slashed and exited validators suffer from a lock-in period of 213 epochs (~36 days) before they become withdrawable. We have to delay withdrawalability by setting:
v.withdrawable_epoch:=max(v.withdrawable_epoch,current_epoch+EPOCHS_PER_SLASHINGS_VECTOR)
The reason why we set the penal delay twice is simply to reuse the helper function in spec.
The validator’s exit_epoch
and withdrawable_epoch
are set, which will trigger the status transitions for exit and withdrawable.
If a validator gets penalized, they lose portions of their balance. If the balance is too low, i.e., v.effective_balance≤EJECTION_BALANCE, this validator is forcefully exited.
As same as 4.3.1.1. Initiate exit.
The validator’s exit_epoch
and withdrawable_epoch
are set, which will trigger the status transitions for exit and withdrawable.
The validator can initiate exit voluntarily by sending VoluntaryExit
operation.
For added validator set stability, the validator can only initiate exit if v.activation_epoch+PERSISTENT_COMMITTEE_PERIOD≥current_state, i.e., 211 epochs (~9 days) after activation.
As same as 4.3.1.1. Initiate exit.
The validator’s exit_epoch
and withdrawable_epoch
are set, which will trigger the status transitions for exit and withdrawable.
The slashed and exited validators will suffer from a long lock-in period of 213 epochs (~36 days) before they become 6. Withdrawable.
The unslashed and exited validators need to wait for 28 epochs (~27 hours) to become 6. Withdrawable.
This 27-hour waiting time is for:
The withdrawable status is the end status in phase 0. Validators will be able to perform withdrawal in phase 2.