From 75ab913a3a9db0f332a7bec2eb8778b9452498de Mon Sep 17 00:00:00 2001 From: realbigsean Date: Tue, 7 May 2024 15:32:07 -0400 Subject: [PATCH] exit updates --- .../src/common/initiate_validator_exit.rs | 24 ++++++++++++------- .../src/per_block_processing/errors.rs | 6 ++++- .../src/per_block_processing/verify_exit.rs | 11 +++++++++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/consensus/state_processing/src/common/initiate_validator_exit.rs b/consensus/state_processing/src/common/initiate_validator_exit.rs index a40a9dfd39..8874e9ed4b 100644 --- a/consensus/state_processing/src/common/initiate_validator_exit.rs +++ b/consensus/state_processing/src/common/initiate_validator_exit.rs @@ -19,16 +19,22 @@ pub fn initiate_validator_exit( state.build_exit_cache(spec)?; // Compute exit queue epoch - let delayed_epoch = state.compute_activation_exit_epoch(state.current_epoch(), spec)?; - let mut exit_queue_epoch = state - .exit_cache() - .max_epoch()? - .map_or(delayed_epoch, |epoch| max(epoch, delayed_epoch)); - let exit_queue_churn = state.exit_cache().get_churn_at(exit_queue_epoch)?; + let exit_queue_epoch = if state.fork_name_unchecked() >= ForkName::Electra { + let effective_balance = state.get_validator(index)?.effective_balance; + state.compute_exit_epoch_and_update_churn(effective_balance, spec)? + } else { + let delayed_epoch = state.compute_activation_exit_epoch(state.current_epoch(), spec)?; + let mut exit_queue_epoch = state + .exit_cache() + .max_epoch()? + .map_or(delayed_epoch, |epoch| max(epoch, delayed_epoch)); + let exit_queue_churn = state.exit_cache().get_churn_at(exit_queue_epoch)?; - if exit_queue_churn >= state.get_validator_churn_limit(spec)? { - exit_queue_epoch.safe_add_assign(1)?; - } + if exit_queue_churn >= state.get_validator_churn_limit(spec)? { + exit_queue_epoch.safe_add_assign(1)?; + } + exit_queue_epoch + }; let validator = state.get_validator_cow(index)?; diff --git a/consensus/state_processing/src/per_block_processing/errors.rs b/consensus/state_processing/src/per_block_processing/errors.rs index e3e15303f8..46665a8839 100644 --- a/consensus/state_processing/src/per_block_processing/errors.rs +++ b/consensus/state_processing/src/per_block_processing/errors.rs @@ -451,7 +451,10 @@ pub enum ExitInvalid { /// The specified validator has already initiated exit. AlreadyInitiatedExit(u64), /// The exit is for a future epoch. - FutureEpoch { state: Epoch, exit: Epoch }, + FutureEpoch { + state: Epoch, + exit: Epoch, + }, /// The validator has not been active for long enough. TooYoungToExit { current_epoch: Epoch, @@ -462,6 +465,7 @@ pub enum ExitInvalid { /// There was an error whilst attempting to get a set of signatures. The signatures may have /// been invalid or an internal error occurred. SignatureSetError(SignatureSetError), + PendingWithdrawalInQueue(u64), } #[derive(Debug, PartialEq, Clone)] diff --git a/consensus/state_processing/src/per_block_processing/verify_exit.rs b/consensus/state_processing/src/per_block_processing/verify_exit.rs index fc258d3829..dea17dbc0c 100644 --- a/consensus/state_processing/src/per_block_processing/verify_exit.rs +++ b/consensus/state_processing/src/per_block_processing/verify_exit.rs @@ -79,5 +79,16 @@ pub fn verify_exit( ); } + // [New in Electra:EIP7251] + // Only exit validator if it has no pending withdrawals in the queue + if let Ok(pending_balance_to_withdraw) = + state.get_pending_balance_to_withdraw(exit.validator_index as usize) + { + verify!( + pending_balance_to_withdraw == 0, + ExitInvalid::PendingWithdrawalInQueue(exit.validator_index) + ); + } + Ok(()) }