EIP-7922: Dynamic exit queue rate limit
Update the validator exit process by dynamically adjusting the churn limit based on historical validator exits.
Abstract
This EIP proposes updating Ethereum's validator exit churn calculation by dynamically adjusting the churn limit at the start of each 256-epoch period ("generation") based on historical validator exits. Specifically, the maximum churn allowed in each generation will adjust according to the unused churn from the past 16 generations. This approach reduces validator wait times during periods of high exit demand without sacrificing network safety.
Motivation
Ethereum currently implements a fixed, rate-limited queue for validator exits to ensure the security and stability of the network. The exit queue ensures the economic security of transactions finalized by the validator set. Suppose a malicious validator could immediately exit the set without any delay. In that case, they may attempt to execute a double spend attack by publishing a block while withholding a conflicting block, which they release after their stake has exited the protocol. The slashing mechanism can no longer hold the malicious validator accountable, and two conflicting finalized transactions may exist (if the attacker has 1/3 of the total stake and successfully splits the 2/3 honest majority in half).
The CHURN_LIMIT_QUOTIENT=2^16
was selected according to the rough heuristic that it should take approximately one month for 10% of the stake to exit. With 1,053,742 validators, we have a churn limit of 16 exits per epoch. 225 epochs per day $\implies$ 3600 exits per day $\implies$ 108,000 exits per 30 days. Then 108,000/1,053,742 $\approx$ 0.10. We can interpret this as "the economic security of a finalized transaction decreases by no more than 10% within one month."
Another way of understanding the 16 exits per epoch security model is that it encodes the following constraints around validator exits:
- at most 16 validators exit in the next one epoch, and
- at most 32 validators exit in the next two epochs, and
- at most 48 validators exit in the next three epochs, and ...
- at most 16 $\cdot$ n validators exit in the next n epochs.
While these constraints are simple to understand, the fixed per-epoch churn limit can result in unnecessarily long validator withdrawal delays during periods of higher-than-average exit demand, such as during institutional liquidations or market events. We argue that we should choose a single constraint from the above set and implement that flexibly.
We illustrate this with an example. With one million validators, the current protocol specifies that 16 validators may exit per epoch. Over two weeks, this corresponds to 50,400 exits. This translates directly to "no more than 5.04% of the validators (equiv. stake) can exit within two weeks." Now imagine that in the past 13 days, no validators have exited the protocol, and thus, none of the two-week churn limit has been used. If a large staking operator with 3% of the validator set (30,000 validators) seeks to withdraw immediately, they should be able to -- this doesn't violate the two-week limit of 5.04%. However, since only 16 exits can be processed per epoch moving forward, they are forced to wait 1875 epochs (equiv. 8.33 days).
Key observation: If we enable the protocol to look backward at the exit history, we no longer need the per-epoch limit looking forward.
For example, say we chose the following constraint explicitly:
Proposed weak subjectivity constraint: No more than 50,400 exits in two weeks.
Then, we only need to ensure that the constraint is honored over every rolling two-week window without setting a hard cap on exits during every epoch. A dynamically adjusted churn limit based on historical validator exit data allows Ethereum to flexibly accommodate spikes in exit demand while preserving the same security over every two-week window. By tracking the unused churn capacity of recent generations (periods), we can safely increase the churn limit when the network consistently operates below capacity, significantly improving the validator exit experience.
Specification
Since the validator exit process is complex, we start with the stack trace and a verbal description of the end-to-end process in Electra.
initiate_validator_exit
– a validator signals their intent to exit, which is actuated by settingvalidator.exit_epoch
andvalidator.withdrawable_epoch
based on the output ofcompute_exit_epoch_and_update_churn
.compute_exit_epoch_and_update_churn
– is used to determine the exit epoch of a validator. This function implements the exit queue in the following way:get_balance_churn_limit
- returns the amount of withdrawable ETH per epoch by dividing the total active balance by 2**16.- set
exit_balance_to_consume
to the churn available in the current furthest epoch where some exits will be processed. - if
exit_balance > exit_balance_to_consume
, then we calculate the number of extra epochs the exit consumes to set the finalexit_epoch
.
This EIP changes how the churn limit and exit epochs are calculated by examining the number of exits in the previous 14 generations.
get_exit_churn_limit
– implements the new churn limit calculation by summing over historical generations.per_epoch_exit_churn
is set usingget_activation_exit_churn_limit
as today by dividing the total stake by 2**16 and capping the result at 256 ETH. With today's numbers, this returns 256 ETH that can churn per epoch.per_generation_exit_churn
is set by multiplying the per epoch exit churn by 256 (the number of epochs in a generation). With today's numbers, this is 256 $\cdot$ 256 = 65536 ETH that can churn per generation.total_unused_exit_churn
is calculated by looping through the past generations and summing the amount of unused capacity,per_generation_exit_churn - churn_usage
.- The final returned value is capped at
per_epoch_exit_churn * 8
. With today's numbers, this max is 256 $\cdot$ 8 = 2048 ETH per epoch.
compute_exit_epoch_and_update_churn
– is modified to useget_exit_churn_limit
and account for any churn consumed in the generation where the exit will be processed.
Definitions
- Generation: A period consisting of 256 epochs.
- Historical Churn Vector: A fixed-size array (
exit_churn_vector
) that records the total amount of churned ETH in the previous 16 generations. - Unused Churn: The difference between the maximum possible churn and the actual churn that occurred within a generation.
Preset
Name | Value | Comment |
---|---|---|
EPOCHS_PER_CHURN_GENERATION | uint64(2**8) (= 256) | ~27 hours |
GENERATIONS_PER_EXIT_CHURN_VECTOR | uint64(2**4) (= 16) | ~18 days |
GENERATIONS_PER_EXIT_CHURN_LOOKAHEAD | uint(2**1) (= 2) | |
EXIT_CHURN_SLACK_MULTIPLIER | uint(2**3) (= 8) |
New State Variables
Add the following to the state:
Initialization
Upon activation of this EIP, initialize new variables:
Design note: Max out churn usage for the past generations as it is unknown; update the current and lookahead generations according to the state.earliest_exit_epoch
generation.
New Functions
Epoch Processing
Design note: This function resets the lookahead generation churn upon switching to the next generation. If state.earliest_exit_epoch
falls into the generation earlier than the lookahead, the lookahead generation churn usage is reset. Otherwise, it is marked as fully used.
get_exit_churn_limit
Design note: Given churn usage for past generations and current epoch churn size estimates the churn leftover from past generations. Caps the returned churn at per_epoch_exit_churn * EXIT_CHURN_SLACK_MULTIPLIER
.
Modified Functions
Replace the existing compute_exit_epoch_and_update_churn
function with this simplified MINSLACK-inspired version:
Rationale
As we described earlier, by computing unused churn from the previous 14 generations, the churn limit dynamically responds to actual validator behavior. This mechanism:
- Reduces validator waiting times during periods of congestion.
- Ensures security by restricting maximum churn limit increases.
- Simplifies implementation compared to more complex dynamic mechanisms.
A generation length of 256 epochs (~27 hours) and a history of 14 generations (~16 days) balances responsiveness and stability, enabling Ethereum to adapt smoothly to sustained changes in validator exit behavior.
Backwards Compatibility
This EIP requires a hard fork.
Security Considerations
- Validator exit constraints remain crucial for Ethereum's accountable safety. This proposal maintains the core safety guarantee by strictly limiting the increase of the churn limit.
- The maximum churn limit is capped at eight times the current fixed churn, ensuring safety assumptions hold even in worst-case scenarios.
Copyright
Copyright and related rights waived via CC0.