CHURN_LIMIT_QUOTIENT
Current CHURN_LIMIT_QUOTIENT
in Gnosis is low such that the network's validator set can change significantly in short periods of time posing unnecessary risks to the network. The original value was chosen without a great deal of care to facilitate staker onboarding UX. Even that argument will no longer apply with eip6110
(in-protocol deposits).
CHURN_LIMIT_QUOTIENT
dictates the validator_churn_limit
which is constant through an epoch variable only to active validator count.
def get_validator_churn_limit(state: BeaconState) -> uint64:
"""
Return the validator churn limit for the current epoch.
"""
active_validator_indices = get_active_validator_indices(state, get_current_epoch(state))
return max(MIN_PER_EPOCH_CHURN_LIMIT, uint64(len(active_validator_indices)) // CHURN_LIMIT_QUOTIENT)
(specs/phase0/beacon-chain.md)
Higher CHURN_LIMIT_QUOTIENT
results in less validators dequeued from that epoch's activation_epoch
.
def process_registry_updates(state: BeaconState) -> None:
...
# Dequeued validators for activation up to churn limit
for index in activation_queue[:get_validator_churn_limit(state)]:
validator = state.validators[index]
validator.activation_epoch = compute_activation_exit_epoch(get_current_epoch(state))
The result of computing the validator churn limit is persisted in the state for outflows. Below initiate_validator_exit
exit_epoch
, and count how many validators will exit at the epochdef initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
...
# Compute exit queue epoch
exit_epochs = [v.exit_epoch for v in state.validators if v.exit_epoch != FAR_FUTURE_EPOCH]
exit_queue_epoch = max(exit_epochs + [compute_activation_exit_epoch(get_current_epoch(state))])
exit_queue_churn = len([v for v in state.validators if v.exit_epoch == exit_queue_epoch])
if exit_queue_churn >= get_validator_churn_limit(state):
exit_queue_epoch += Epoch(1)
# Set validator exit epoch and withdrawable epoch
validator.exit_epoch = exit_queue_epoch
validator.withdrawable_epoch = Epoch(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
Irrespective of the current status of the exit churn, the chrun decrease is well handled with the spec as is.
Implementations must make sure to invalidate any exit churn cache and recompute that fork boundary.
CHURN_LIMIT_QUOTIENT
TBD pending research. Current tentative value Ethereum's 65536
Consensus layer config differences to Ethereum
Config value | Ethereum | Gnosis |
---|---|---|
CHURN_LIMIT_QUOTIENT |
65536 | 4096 |
CHURN_LIMIT_QUOTIENT
: The churn to enter and exit the validator set is greater. For 100_000 validators, 100000 / 4096 = 24 validators can activate and exit per epoch.Churn out | Churn in |
---|---|