Registration and Withdrawal Process
How a Validator can join and leave the proof of stake protocol
We take this time to consider how messages are sent between the deposit contract and the consensus layer including:
Registration process. A candidate can stake ETH and become an active Validator.
Withdrawal process. An active Validator can signal their desire to exit and withdraw their final balance.
In both cases, there is a time delay before a registration or withdrawal is processed. The former is due to previous unreliable confirmation/finality issues inherit with proof of work while the latter is to enable slashing actions to be caught before the Validator exits the system.
Registration Process
There are two stages of the registration process:
Recognising a deposit event in the consensus layer,
Activating the Validator in the consensus layer,
It all begins with the execution layer as a user deposits ETH to a smart contract and the deposit contract signals a new registration attempt should eventually be recognised on the consensus layer. Once picked up by the Validators — it’ll trigger the process to eventually activate the Validator and enable them to participate in the proof of stake protocol.
Deposit event. In regards to the deposit, a user must deposit ETH into the deposit contract and it must be denominated in whole ETH (i.e., not gwei) alongside:
Validating key. A BLS public key to sign all actions in the proof of stake protocol.
Withdrawal key. Remaining balance will be sent to this Ethereum address when the Validator decides to leave the proof of stake protocol.
Deposit signature. A digital signature from the BLS public key over the deposit message — prove ownership of validating key before joining.
The deposit contract does not check the validity of the validating key, withdrawal key, or the deposit signature. It is up to the consensus layer to check its validity — so be sure to double-check all signatures/keys before registering for the proof of stake protocol.
The Validating key represents the user’s identity as a Validator in the proof of stake protocol. It is not linked to their real-world identity and there is no gate-keeper. A candidate can register one or several Validators as long as they satisfy the 32 ETH deposit for each registration.
Surface to consensus layer. The deposit contract only has two roles:
Emit a deposit event to notify all active Validators that a new registration is underway,
Lock up the staked ETH.
All Validators watch for deposit events on the execution layer. A deposit event can only be included in a beacon block after:
64 epochs on the consensus layer (~14 hours)
Final epoch for consensus layer must be finalised.
The waiting period is very long.
It was implemented when the execution layer relied on proof of work and it was completely separate to the consensus layer. The motivation was to provide enough time to ensure the deposit event has achieved significant depth in the execution layer via proof of work and it was essentially impossible for a large block re-organisation to occur that may reverse the deposit event.
Since the merge, a new EIP-6110 has been proposed to reduce the waiting period and recognise a deposit event after the checkpoint is finalised.
Once the waiting period is complete, the deposit events will be recognised by all Validators and they must be immediately included in beacon blocks. A beacon block can include up to 16 deposit events per block. If a beacon block is missing deposit events, then it will be rejected by the network.
Activating Validator. A Validator is placed in an activation queue when the deposit event is recognised by the consensus layer and their total deposit is equal to (or greater than) 32 ETH.
The consensus layer restricts the rate of activation for new Validators with a churn limit per epoch. The churn limit requires a minimum of 4 Validators and it is currently set to 7 Validators. This implies that up to 7 Validators will be removed from the activation queue per epoch. Finally, a Validator must wait an additional 4 epochs before they are added to the shuffle protocol and allocated a slot. c
As a side note, the exceedingly slow rate-limit mechanism appears to have been implemented as it is mostly an intuitively good idea. There is no rigorous study on whether it helps to prevent such an attack.
Withdrawal Process
The upcoming Shanghai upgrade to proof of stake Ethereum will include a new withdrawal process.
Before we continue — there are three key features to highlight:
Most Validators will need to upgrade their withdrawal key to an Ethereum address,
Ethereum will issue new coins to process withdrawals and the funds in the deposit contract are locked forever.
Any balance >32 ETH will periodically be swept and sent to the Validator on the execution layer — only activated when withdrawal key is updated).
Upgrade withdrawal key. All Validators has already registered a BLS withdrawal key upon joining the proof of stake protocol.
Unfortunately, they will need to change the withdrawal key to an Ethereum address. To upgrade, they must sign a new message using the already registered BLS withdrawal key (SignedBLSToExecutionChange)
.
An upgrade can only be done once and it will automatically enable periodic partial withdrawals.
Request to exit. A Validator must request to exit the proof of stake protocol before they can withdraw their full balance. Just like registrations, there are two stages to consider:
Exit the proof of stake protocol and stop active participation,
Withdraw their funds on the execution layer.
To signal an exit, they must sign a VoluntaryExit message that is propagated on the consensus layer. The exit message will be picked up in a new beacon block and only 16 exit requests can be processed per block. It is a voluntary action for block proposers to include exit messages.
The next step is computing when a Validator will be deactivated and they are no longer required to participate in the proof of stake protocol. This depends on the churn limit (similar to registrations) as only ~7 Validators can be deactivated per epoch.
It works as follows:
Fetch all current exit requests,
Find last epoch to process a voluntary exit (exit_queue_epoch),
If there are no current exit requests, set exit_queue_epoch as 5 epochs in the future.
Check if exit_queue_epoch can process another exit request (churn limit is minimum 4, but currently 7 exits per epoch)
If yes, set exit_epoch as as exit_queue_epoch.
If no, set exit_epoch as this exit_queue_epoch+1.
Set withdrawable_epoch as exit_epoch + 256 epochs.
To summarise the time to wait. In the best case, a Validator can exit after 5 epochs. In the worst case, the exit epoch depends on the churn limit and the total number of Validators trying to exit. If we assume that all 508,000 Validators want to exit at the same time, then it will take ~72,571 epochs (~300 days).
Finally — after they have exited the proof of stake protocol — all Validators will need to wait at least an additional 256 epochs before they can withdraw their funds on the execution layer. The actual withdrawal depends on a loop of all Validators to process withdrawals.
Withdrawal process. There are two types of withdrawals to consider:
Full withdrawal. A Validator requests to exit the proof of stake protocol and withdraw their full balance.
Partial sweep withdrawal. A Validator’s excess balance (above 32 ETH) is periodically swept and sent to them on the execution layer.
In both cases, the withdrawal is processed using the same mechanism as outlined in the code snippet. Briefly, the sweep repeatedly loops over all Validator indexes (0-N-1) from start to finish.
In every beacon block:
Start from the last Validator Index from the previous beacon block.
Fetch the next 16,384 Validators.
Loop through each Validator one by one.
Does this Validator need a withdrawal process?
Yes — Add to the withdrawal payload of the execution block.
No — Continue to the next Validator
The process halts when the withdrawal payload is full at 16 withdrawals or the list of Validators is exhausted.
It saves the Validator index for the last one checked.
The withdrawal payload is in the execution block’s header and it resembles a system operation as it issues new coins to the Validator. It can only perform the transfer and the coins are only recorded on the execution layer after the entire block is executed. All coins held in the deposit contract are effectively burnt or inaccessible.
Validating withdrawals. All Validators need to double-check any withdrawals processed by the execution layer. Each Validator will repeat the above process and compute which withdrawals should be processed in the next execution block. It will fetch the withdrawal payload from the execution block and simply compare it with its own local list. If they both match, then it passes the validity check.
A small disclaimer — the Shanghai upgrade and withdrawals are in the process of testing by the consensus client developers. There may be small upgrades that I am not aware off / reflected here. If so, do let me know!
super interesting. The churn limit sounds like a policy parameter that could affect collective behavior?