diff --git a/consensus/state_processing/src/per_epoch_processing/altair.rs b/consensus/state_processing/src/per_epoch_processing/altair.rs index 085da9abc1f..79208b83596 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair.rs @@ -34,10 +34,10 @@ pub fn process_epoch( // Justification and finalization. process_justification_and_finalization(state, &participation_cache, spec)?; - process_inactivity_updates(state, spec)?; + process_inactivity_updates(state, &participation_cache, spec)?; // Rewards and Penalties. - process_rewards_and_penalties(state, spec)?; + process_rewards_and_penalties(state, &participation_cache, spec)?; // Registry Updates. process_registry_updates(state, spec)?; diff --git a/consensus/state_processing/src/per_epoch_processing/altair/inactivity_updates.rs b/consensus/state_processing/src/per_epoch_processing/altair/inactivity_updates.rs index cc629c1ef09..469bd49a3c6 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair/inactivity_updates.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair/inactivity_updates.rs @@ -1,3 +1,4 @@ +use super::ParticipationCache; use crate::EpochProcessingError; use core::result::Result; use core::result::Result::Ok; @@ -10,6 +11,7 @@ use types::eth_spec::EthSpec; pub fn process_inactivity_updates( state: &mut BeaconState, + participation_cache: &ParticipationCache, spec: &ChainSpec, ) -> Result<(), EpochProcessingError> { // Score updates based on previous epoch participation, skip genesis epoch @@ -17,15 +19,12 @@ pub fn process_inactivity_updates( return Ok(()); } - let unslashed_indices = state.get_unslashed_participating_indices( - TIMELY_TARGET_FLAG_INDEX, - state.previous_epoch(), - spec, - )?; + let unslashed_indices = participation_cache + .get_unslashed_participating_indices(TIMELY_TARGET_FLAG_INDEX, state.previous_epoch())?; for index in state.get_eligible_validator_indices()? { // Increase inactivity score of inactive validators - if unslashed_indices.contains(&index) { + if unslashed_indices.contains(index)? { let inactivity_score = state.get_inactivity_score_mut(index)?; inactivity_score.safe_sub_assign(min(1, *inactivity_score))?; } else { diff --git a/consensus/state_processing/src/per_epoch_processing/altair/justification_and_finalization.rs b/consensus/state_processing/src/per_epoch_processing/altair/justification_and_finalization.rs index 3f5eae0b12d..59e9ef94c0e 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair/justification_and_finalization.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair/justification_and_finalization.rs @@ -1,5 +1,6 @@ +use super::ParticipationCache; use crate::per_epoch_processing::weigh_justification_and_finalization; -use crate::per_epoch_processing::{altair::ParticipationCache, Error}; +use crate::per_epoch_processing::Error; use safe_arith::SafeArith; use types::consts::altair::TIMELY_TARGET_FLAG_INDEX; use types::{BeaconState, ChainSpec, EthSpec}; diff --git a/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs b/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs index 6e1475d06d0..5ad4585379e 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs @@ -1,3 +1,4 @@ +use super::ParticipationCache; use safe_arith::SafeArith; use types::consts::altair::{ PARTICIPATION_FLAG_WEIGHTS, TIMELY_HEAD_FLAG_INDEX, TIMELY_TARGET_FLAG_INDEX, @@ -13,6 +14,7 @@ use crate::per_epoch_processing::{Delta, Error}; /// Spec v1.1.0 pub fn process_rewards_and_penalties( state: &mut BeaconState, + participation_cache: &ParticipationCache, spec: &ChainSpec, ) -> Result<(), Error> { if state.current_epoch() == T::genesis_epoch() { @@ -24,10 +26,17 @@ pub fn process_rewards_and_penalties( let total_active_balance = state.get_total_active_balance(spec)?; for flag_index in 0..PARTICIPATION_FLAG_WEIGHTS.len() { - get_flag_index_deltas(&mut deltas, state, flag_index, total_active_balance, spec)?; + get_flag_index_deltas( + &mut deltas, + state, + flag_index, + total_active_balance, + participation_cache, + spec, + )?; } - get_inactivity_penalty_deltas(&mut deltas, state, spec)?; + get_inactivity_penalty_deltas(&mut deltas, state, participation_cache, spec)?; // Apply the deltas, erroring on overflow above but not on overflow below (saturating at 0 // instead). @@ -47,11 +56,12 @@ pub fn get_flag_index_deltas( state: &BeaconState, flag_index: usize, total_active_balance: u64, + participation_cache: &ParticipationCache, spec: &ChainSpec, ) -> Result<(), Error> { let previous_epoch = state.previous_epoch(); let unslashed_participating_indices = - state.get_unslashed_participating_indices(flag_index, previous_epoch, spec)?; + participation_cache.get_unslashed_participating_indices(flag_index, previous_epoch)?; let weight = get_flag_weight(flag_index)?; let unslashed_participating_balance = state.get_total_balance(&unslashed_participating_indices, spec)?; @@ -63,7 +73,7 @@ pub fn get_flag_index_deltas( let base_reward = get_base_reward(state, index, total_active_balance, spec)?; let mut delta = Delta::default(); - if unslashed_participating_indices.contains(&(index as usize)) { + if unslashed_participating_indices.contains(index as usize)? { if !state.is_in_inactivity_leak(spec) { let reward_numerator = base_reward .safe_mul(weight)? @@ -94,18 +104,16 @@ pub fn get_flag_weight(flag_index: usize) -> Result { pub fn get_inactivity_penalty_deltas( deltas: &mut Vec, state: &BeaconState, + participation_cache: &ParticipationCache, spec: &ChainSpec, ) -> Result<(), Error> { let previous_epoch = state.previous_epoch(); - let matching_target_indices = state.get_unslashed_participating_indices( - TIMELY_TARGET_FLAG_INDEX, - previous_epoch, - spec, - )?; + let matching_target_indices = participation_cache + .get_unslashed_participating_indices(TIMELY_TARGET_FLAG_INDEX, previous_epoch)?; for index in state.get_eligible_validator_indices()? { let mut delta = Delta::default(); - if !matching_target_indices.contains(&index) { + if !matching_target_indices.contains(index)? { let penalty_numerator = state .get_validator(index)? .effective_balance diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index dcdaf059c39..8773d5ae099 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -13,7 +13,6 @@ use serde_derive::{Deserialize, Serialize}; use ssz::{ssz_encode, Decode, DecodeError, Encode}; use ssz_derive::{Decode, Encode}; use ssz_types::{typenum::Unsigned, BitVector, FixedVector}; -use std::collections::HashSet; use std::convert::TryInto; use std::{fmt, mem}; use superstruct::superstruct; @@ -1452,40 +1451,6 @@ impl BeaconState { self.clone_with(CloneConfig::committee_caches_only()) } - /// Get the unslashed participating indices for a given `flag_index`. - /// - /// The `self` state must be Altair or later. - pub fn get_unslashed_participating_indices( - &self, - flag_index: usize, - epoch: Epoch, - spec: &ChainSpec, - ) -> Result, Error> { - let epoch_participation = if epoch == self.current_epoch() { - self.current_epoch_participation()? - } else if epoch == self.previous_epoch() { - self.previous_epoch_participation()? - } else { - return Err(Error::EpochOutOfBounds); - }; - let active_validator_indices = self.get_active_validator_indices(epoch, spec)?; - itertools::process_results( - active_validator_indices.into_iter().map(|val_index| { - let has_flag = epoch_participation - .get(val_index) - .ok_or(Error::ParticipationOutOfBounds(val_index))? - .has_flag(flag_index)?; - let not_slashed = !self.get_validator(val_index)?.slashed; - Ok((val_index, has_flag && not_slashed)) - }), - |iter| { - iter.filter(|(_, eligible)| *eligible) - .map(|(validator_index, _)| validator_index) - .collect() - }, - ) - } - pub fn get_eligible_validator_indices(&self) -> Result, Error> { match self { BeaconState::Base(_) => Err(Error::IncorrectStateVariant),