mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-17 12:58:31 +00:00
spec: initiate_validator_exit v0.6.1
Added a new field `exit_cache` to the BeaconState, which caches the number of validators exiting at each epoch.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use self::epoch_cache::{get_active_validator_indices, EpochCache, Error as EpochCacheError};
|
||||
use self::exit_cache::ExitCache;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use cached_tree_hash::{Error as TreeHashCacheError, TreeHashCache};
|
||||
@@ -13,6 +14,7 @@ use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
mod epoch_cache;
|
||||
mod exit_cache;
|
||||
mod pubkey_cache;
|
||||
mod tests;
|
||||
|
||||
@@ -126,6 +128,12 @@ pub struct BeaconState {
|
||||
#[tree_hash(skip_hashing)]
|
||||
#[test_random(default)]
|
||||
pub tree_hash_cache: TreeHashCache,
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
#[ssz(skip_serializing)]
|
||||
#[ssz(skip_deserializing)]
|
||||
#[tree_hash(skip_hashing)]
|
||||
#[test_random(default)]
|
||||
pub exit_cache: ExitCache,
|
||||
}
|
||||
|
||||
impl BeaconState {
|
||||
@@ -198,6 +206,7 @@ impl BeaconState {
|
||||
],
|
||||
pubkey_cache: PubkeyCache::default(),
|
||||
tree_hash_cache: TreeHashCache::default(),
|
||||
exit_cache: ExitCache::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,6 +643,21 @@ impl BeaconState {
|
||||
epoch + 1 + spec.activation_exit_delay
|
||||
}
|
||||
|
||||
/// Return the churn limit for the current epoch (number of validators who can leave per epoch).
|
||||
///
|
||||
/// Uses the epoch cache, and will error if it isn't initialized.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
pub fn get_churn_limit(&self, spec: &ChainSpec) -> Result<u64, Error> {
|
||||
Ok(std::cmp::max(
|
||||
spec.min_per_epoch_churn_limit,
|
||||
self.cache(RelativeEpoch::Current, spec)?
|
||||
.active_validator_indices
|
||||
.len() as u64
|
||||
/ spec.churn_limit_quotient,
|
||||
))
|
||||
}
|
||||
|
||||
/// Initiate an exit for the validator of the given `index`.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
@@ -685,6 +709,8 @@ impl BeaconState {
|
||||
self.build_epoch_cache(RelativeEpoch::NextWithRegistryChange, spec)?;
|
||||
self.update_pubkey_cache()?;
|
||||
self.update_tree_hash_cache()?;
|
||||
self.exit_cache
|
||||
.build_from_registry(&self.validator_registry, spec);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
35
eth2/types/src/beacon_state/exit_cache.rs
Normal file
35
eth2/types/src/beacon_state/exit_cache.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use super::{ChainSpec, Epoch, Validator};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Map from exit epoch to the number of validators known to be exiting/exited at that epoch.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ExitCache(HashMap<Epoch, u64>);
|
||||
|
||||
impl ExitCache {
|
||||
/// Add all validators with a non-trivial exit epoch to the cache.
|
||||
pub fn build_from_registry(&mut self, validator_registry: &[Validator], spec: &ChainSpec) {
|
||||
validator_registry
|
||||
.iter()
|
||||
.filter(|validator| validator.exit_epoch != spec.far_future_epoch)
|
||||
.for_each(|validator| self.record_validator_exit(validator.exit_epoch));
|
||||
}
|
||||
|
||||
/// Record the exit of a single validator in the cache.
|
||||
///
|
||||
/// Must only be called once per exiting validator.
|
||||
pub fn record_validator_exit(&mut self, exit_epoch: Epoch) {
|
||||
*self.0.entry(exit_epoch).or_insert(0) += 1;
|
||||
}
|
||||
|
||||
/// Get the greatest epoch for which validator exits are known.
|
||||
pub fn max_epoch(&self) -> Option<Epoch> {
|
||||
// This could probably be made even faster by caching the maximum.
|
||||
self.0.keys().max().cloned()
|
||||
}
|
||||
|
||||
/// Get the number of validators exiting/exited at a given epoch, or zero if not known.
|
||||
pub fn get_churn_at(&self, epoch: Epoch) -> u64 {
|
||||
self.0.get(&epoch).cloned().unwrap_or(0)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user