owned this note
owned this note
Published
Linked with GitHub
# A note on Ethereum 2.0 phase 0 validator lifecycle
###### tags: `eth2` `v0.10.1`
[TOC]
:::info
By @hwwhww 20200115
Special thanks to @djrtwo for the review.
:::
:::warning
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](https://github.com/ethereum/eth2.0-specs/pull/1581)
:::
# 1. Introduction
The validator status is defined in the [beacon chain spec](https://github.com/ethereum/eth2.0-specs/blob/v0.10.0/specs/phase0/beacon-chain.md) 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](https://notes.ethereum.org/@vbuterin/rkhCgQteN#The-validator-lifecycle) to understand the deep meaning of some constants configuration.
# 2. Validator status
## 2.1. Statuses in phase 0
The validator may be in the following statuses:
1. **Deposited**: the validator has made a deposit and has registered in `BeaconState`.
2. **Eligible to be activated (Pending)**: the validator is eligible to be activated.
3. **Activated**: the validator is activated
:::info
Note that the validator may be "eligible to be activated, but has not been activated yet".
:::
4. **Slashed**: the validator has been slashed
5. **Exited**: the validator is exited
6. **Withdrawable**: the validator is withdrawable
:::info
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".
## 2.2. Validator status epoch
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.
![](https://storage.googleapis.com/ethereum-hackmd/upload_eca5ac48a840054374280d7c0ffbd556.png)
These fields define that a validator is in $status_x$ status when $v.status\_epoch_x \geq current\_status$. The default value of the status epoch fields is $FAR\_FUTURE\_EPOCH$, where $FAR\_FUTURE\_EPOCH := 2^{64} - 1$ epochs.
For example, if a validator $v_1$, where $v_1.activation\_eligibility\_epoch$ is $100$ and
$v_1.activation\_epoch$ is $200$.
- When current epoch is $150$, the validator is "eligibile" to be activated, but has not been *activated* yet.
![](https://storage.googleapis.com/ethereum-hackmd/upload_4ce9f0a6553c0974b0f9d54c3db7e386.png)
- When current epoch is $250$, the validator is activated.
![](https://storage.googleapis.com/ethereum-hackmd/upload_d77aae8a701f1d89d5f2ab8786709639.png)
\
By updating these fields, we can determine the validator statuses. Basically, the status epoch setting should follow:
$$
activation\_eligibility\_epoch \leq acitivation\_epoch \leq exit\_epoch \leq withdrawable\_epoch
\\
$$
## 2.3. `validator.slashed` boolean flag
We use a `slashed` flag field in `Validator` to describe if the validator has been slashed.
![](https://storage.googleapis.com/ethereum-hackmd/upload_4c1db5447b54f929c2fa6e5364e3bc22.png)
You can find more information on slashing from the [validator guide doc](https://github.com/ethereum/eth2.0-specs/blob/v0.10.0/specs/phase0/validator.md). Note that a slashed validator will be forced to exit (we will discuss the details in Chapter 4).
# 3. Rate-limiting activation/exits queues
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](https://ethresear.ch/t/weak-subjectivity-under-the-exit-queue-model/5187)), we limit the activation/exit queues dynamically.
:::info
Some rationale is described in [Serenity Design Rationale - Exiting](https://notes.ethereum.org/@vbuterin/rkhCgQteN?type=view#Exiting).
:::
## 3.1. Churn limit function
The churn limit computation algorithm is describe in [get_validator_churn_limit](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#get_validator_churn_limit).
$$
\begin{split}
|S| &:= \text{the size of set } S
\\
V_{active} &:= \text{the active validators}
\\
churn\_limit(state) &:= max(MIN\_PER\_EPOCH\_CHURN\_LIMIT,\ \Big\lfloor{\frac{|V_{active}|}{CHURN\_LIMIT\_QUOTIENT}}\Big\rfloor
)
\end{split}
$$
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.
# 4. Validator lifecycle
This section, we will explain each validator status transition step-by-step. The following is the state transition diagram:
[![Diagram](https://storage.googleapis.com/ethereum-hackmd/upload_f76a1c2499efcaabcf2aa167986a06d3.png)](https://storage.googleapis.com/ethereum-hackmd/upload_f76a1c2499efcaabcf2aa167986a06d3.png)
:::info
💡 Hint: click the image to see the full-size diagram.
:::
## 4.1. Step 1. Deposited
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](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue):
- Check if
1. the validator has made enough deposit: $v.effective\_balance = MAX\_EFFECTIVE\_BALANCE$
2. the validator's activation eligibility epoch has **not** been set (i.e. not previously added to the activition queue): $v.activation\_eligibility\_epoch = FAR\_FUTURE\_EPOCH$.
- If yes, set $v.activation\_eligibility\_epoch$ to $current\_epoch + 1$ (thus entering the queue at the next epoch).
- Else, go back to step $1.a$ at the next epoch.
## 4.2. Step 2. Eligible to be activated (Pending)
In epoch-processing, step $2.a$ checks if the validator [is eligible for activation ](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#is_eligible_for_activation) and is **within churn limit**:
- Select the activation queue -- the validators such that:
1. the validator's activation eligibility has been finalized: $v.activation\_eligibility\_epoch \leq state.finalized\_checkpoint.epoch$
2. the validator’s activation epoch has **not** been set: $v.activation\_epoch = FAR\_FUTURE\_EPOCH$
- **Dequeue** validators for activation up to churn limit for the current epoch
- If the validator gets dequeued, set $v.activation\_epoch$ to $current\_epoch + 1 + MAX\_SEED\_LOOKAHEAD$.
- Else, go back to step $2.a$ at the next epoch.
:::info
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$](#43-Step-3-Activated).
## 4.3. Step 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.
### 4.3.1. Step 3.a Get slashed
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*.
#### 4.3.1.1. Initiate exit
To [initiate exit](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#initiate_validator_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:
$$
\begin{split}
exit\_epochs(state)\ &:= \{v.exit\_epoch\ \forall v\in V\ |\ v.exit\_epoch \not= FAR\_FUTURE\_EPOCH\big\}
\\
exit\_queue\_epoch(state)\ &:= max\big\{exit\_epochs(state) \cup \{current\_epoch + 1 + MAX\_SEED\_LOOKAHEAD\}\big\}
\\
v.exit\_epoch &:= exit\_queue\_epoch(state)
\\
v.withdrawable\_epoch &:= v.exit\_epoch + MIN\_VALIDATOR\_WITHDRAWABILITY\_DELAY
\end{split}
$$
#### 4.3.1.2. Extra penal delay
The slashed and exited validators suffer from a lock-in period of $2^{13}$ 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)
$$
:::info
The reason why we set the penal delay twice is simply to reuse the helper function in spec.
:::
:::success
The validator's `exit_epoch` and `withdrawable_epoch` are set, which will trigger the status transitions for exit and withdrawable.
:::
### 4.3.2. Step 3.b Insufficient balance (ejection)
If a validator gets [*penalized*](https://notes.ethereum.org/@djrtwo/Bkn3zpwxB?type=view#Rewards-and-Penalties), they lose portions of their balance. If the balance is too low, i.e., $v.effective\_balance \leq EJECTION\_BALANCE$, this validator is forcefully exited.
#### 4.3.2.1. Initiate exit
As same as [4.3.1.1. Initiate exit](#4311-Initiate-exit).
:::success
The validator's `exit_epoch` and `withdrawable_epoch` are set, which will trigger the status transitions for exit and withdrawable.
:::
### 4.3.3. Step 3.c Voluntary exit path
The validator can [initiate exit voluntarily](https://notes.ethereum.org/@djrtwo/Bkn3zpwxB?type=view#Voluntary-Exits) by sending `VoluntaryExit` operation.
#### 4.3.3.1. Minimum service time
For added validator set stability, the validator can only initiate exit if $v.activation\_epoch + PERSISTENT\_COMMITTEE\_PERIOD \geq current\_state$, i.e., $2^{11}$ epochs (**~9 days**) after activation.
#### 4.3.3.2. Initiate exit
As same as [4.3.1.1. Initiate exit](#4311-Initiate-exit).
:::success
The validator's `exit_epoch` and `withdrawable_epoch` are set, which will trigger the status transitions for exit and withdrawable.
:::
## 4.4. Step 4. Slashed and Exited
The slashed and exited validators will suffer from a long lock-in period of $2^{13}$ epochs (~36 days) before they become [$6.\ \text{Withdrawable}$](#46-Step-6-Withdrawable).
## 4.5. Step 5. Unslashed and Exited
The unslashed and exited validators need to wait for $2^8$ epochs (**~27 hours**) to become [$6.\ \text{Withdrawable}$](#46-Step-6-Withdrawable).
:::info
This 27-hour waiting time is for:
1. Ensuring that if a validator misbehaved, there is a period of time within which the error can be caught, and the validator **can be slashed** even if the exit queue is nearly empty. If so, their withdrawalability will be delayed as [4.3.1.2. Extra penal delay](#4312-Extra-penal-delay).
2. Providing time for the last period of shard **rewards** to be included in phase 1.
3. Providing time for **proof of custody challenges** to be made in phase 1.
:::
## 4.6. Step 6. Withdrawable
The withdrawable status is the end status in phase 0. Validators will be able to perform withdrawal in phase 2.