mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 10:22:38 +00:00
spec: registry updates v0.6.1
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
use super::super::common::initiate_validator_exit;
|
||||
use super::Error;
|
||||
use itertools::{Either, Itertools};
|
||||
use types::*;
|
||||
|
||||
/// Peforms a validator registry update, if required.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
pub fn process_registry_updates(
|
||||
state: &mut BeaconState,
|
||||
current_total_balance: u64,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
// Process activation eligibility and ejections.
|
||||
// Collect eligible and exiting validators (we need to avoid mutating the state while iterating).
|
||||
// We assume it's safe to re-order the change in eligibility and `initiate_validator_exit`.
|
||||
// Rest assured exiting validators will still be exited in the same order as in the spec.
|
||||
let current_epoch = state.current_epoch(spec);
|
||||
let is_eligible = |validator: &Validator| {
|
||||
validator.activation_eligibility_epoch == spec.far_future_epoch
|
||||
&& validator.effective_balance >= spec.max_effective_balance
|
||||
};
|
||||
let is_exiting_validator = |validator: &Validator| {
|
||||
validator.is_active_at(current_epoch)
|
||||
&& validator.effective_balance <= spec.ejection_balance
|
||||
};
|
||||
let (eligible_validators, exiting_validators): (Vec<_>, Vec<_>) = state
|
||||
.validator_registry
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, validator)| is_eligible(validator) || is_exiting_validator(validator))
|
||||
.partition_map(|(index, validator)| {
|
||||
if is_eligible(validator) {
|
||||
Either::Left(index)
|
||||
} else {
|
||||
Either::Right(index)
|
||||
}
|
||||
});
|
||||
for index in eligible_validators {
|
||||
state.validator_registry[index].activation_eligibility_epoch = current_epoch;
|
||||
}
|
||||
for index in exiting_validators {
|
||||
initiate_validator_exit(state, index, spec)?;
|
||||
}
|
||||
|
||||
// Queue validators eligible for activation and not dequeued for activation prior to finalized epoch
|
||||
let activation_queue = state
|
||||
.validator_registry
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, validator)| {
|
||||
validator.activation_eligibility_epoch != spec.far_future_epoch
|
||||
&& validator.activation_epoch
|
||||
>= state.get_delayed_activation_exit_epoch(state.finalized_epoch, spec)
|
||||
})
|
||||
.sorted_by_key(|(_, validator)| validator.activation_eligibility_epoch)
|
||||
.map(|(index, _)| index)
|
||||
.collect_vec();
|
||||
|
||||
let churn_limit = state.get_churn_limit(spec)? as usize;
|
||||
let delayed_activation_epoch = state.get_delayed_activation_exit_epoch(current_epoch, spec);
|
||||
for index in activation_queue.into_iter().take(churn_limit) {
|
||||
let validator = &mut state.validator_registry[index];
|
||||
if validator.activation_epoch == spec.far_future_epoch {
|
||||
validator.activation_epoch = delayed_activation_epoch;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user