Files
lighthouse/consensus/state_processing/src/common/initiate_validator_exit.rs
Michael Sproul 61962898e2 In-memory tree states (#5533)
* Consensus changes

* EF tests

* lcli

* common and watch

* account manager

* cargo

* fork choice

* promise cache

* beacon chain

* interop genesis

* http api

* lighthouse

* op pool

* beacon chain misc

* parallel state cache

* store

* fix issues in store

* IT COMPILES

* Remove some unnecessary module qualification

* Revert Arced pubkey optimization (#5536)

* Merge remote-tracking branch 'origin/unstable' into tree-states-memory

* Fix caching, rebasing and some tests

* Remove unused deps

* Merge remote-tracking branch 'origin/unstable' into tree-states-memory

* Small cleanups

* Revert shuffling cache/promise cache changes

* Fix state advance bugs

* Fix shuffling tests

* Remove some resolved FIXMEs

* Remove StateProcessingStrategy

* Optimise withdrawals calculation

* Don't reorg if state cache is missed

* Remove inconsistent state func

* Fix beta compiler

* Rebase early, rebase often

* Fix state caching behaviour

* Update to milhouse release

* Fix on-disk consensus context format

* Merge remote-tracking branch 'origin/unstable' into tree-states-memory

* Squashed commit of the following:

commit 3a16649023
Author: Michael Sproul <michael@sigmaprime.io>
Date:   Thu Apr 18 14:26:09 2024 +1000

    Fix on-disk consensus context format

* Keep indexed attestations, thanks Sean

* Merge branch 'on-disk-consensus-context' into tree-states-memory

* Merge branch 'unstable' into tree-states-memory

* Address half of Sean's review

* More simplifications from Sean's review

* Cache state after get_advanced_hot_state
2024-04-24 01:22:36 +00:00

51 lines
1.8 KiB
Rust

use safe_arith::SafeArith;
use std::cmp::max;
use types::{BeaconStateError as Error, *};
/// Initiate the exit of the validator of the given `index`.
pub fn initiate_validator_exit<E: EthSpec>(
state: &mut BeaconState<E>,
index: usize,
spec: &ChainSpec,
) -> Result<(), Error> {
// We do things in a slightly different order to the spec here. Instead of immediately checking
// whether the validator has already exited, we instead prepare the exit cache and compute the
// cheap-to-calculate values from that. *Then* we look up the validator a single time in the
// validator tree (expensive), make the check and mutate as appropriate. Compared to the spec
// ordering, this saves us from looking up the validator in the validator registry multiple
// times.
// Ensure the exit cache is built.
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)?;
if exit_queue_churn >= state.get_validator_churn_limit(spec)? {
exit_queue_epoch.safe_add_assign(1)?;
}
let validator = state.get_validator_cow(index)?;
// Return if the validator already initiated exit
if validator.exit_epoch != spec.far_future_epoch {
return Ok(());
}
let validator = validator.into_mut()?;
validator.exit_epoch = exit_queue_epoch;
validator.withdrawable_epoch =
exit_queue_epoch.safe_add(spec.min_validator_withdrawability_delay)?;
state
.exit_cache_mut()
.record_validator_exit(exit_queue_epoch)?;
Ok(())
}