Skip to content

Commit

Permalink
Swap hashmap to vec
Browse files Browse the repository at this point in the history
  • Loading branch information
paulhauner committed Jun 9, 2022
1 parent cfd26d2 commit 3870406
Showing 1 changed file with 21 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
//! to get useful summaries about the validator participation in an epoch.
use safe_arith::{ArithError, SafeArith};
use std::collections::HashMap;
use types::{
consts::altair::{
NUM_FLAG_INDICES, TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_FLAG_INDEX,
Expand All @@ -24,6 +23,7 @@ use types::{
#[derive(Debug, PartialEq)]
pub enum Error {
InvalidFlagIndex(usize),
InvalidValidatorIndex(usize),
}

/// A balance which will never be below the specified `minimum`.
Expand Down Expand Up @@ -64,7 +64,7 @@ struct SingleEpochParticipationCache {
/// It would be ideal to maintain a reference to the `BeaconState` here rather than copying the
/// `ParticipationFlags`, however that would cause us to run into mutable reference limitations
/// upstream.
unslashed_participating_indices: HashMap<usize, ParticipationFlags>,
unslashed_participating_indices: Vec<Option<ParticipationFlags>>,
/// Stores the sum of the balances for all validators in `self.unslashed_participating_indices`
/// for all flags in `NUM_FLAG_INDICES`.
///
Expand All @@ -76,11 +76,11 @@ struct SingleEpochParticipationCache {
}

impl SingleEpochParticipationCache {
fn new(hashmap_len: usize, spec: &ChainSpec) -> Self {
fn instantiate(num_validators: usize, spec: &ChainSpec) -> Self {
let zero_balance = Balance::zero(spec.effective_balance_increment);

Self {
unslashed_participating_indices: HashMap::with_capacity(hashmap_len),
unslashed_participating_indices: vec![None; num_validators],
total_flag_balances: [zero_balance; NUM_FLAG_INDICES],
total_active_balance: zero_balance,
}
Expand All @@ -100,7 +100,11 @@ impl SingleEpochParticipationCache {
///
/// May return an error if `flag_index` is out-of-bounds.
fn has_flag(&self, val_index: usize, flag_index: usize) -> Result<bool, Error> {
if let Some(participation_flags) = self.unslashed_participating_indices.get(&val_index) {
let participation_flags = self
.unslashed_participating_indices
.get(val_index)
.ok_or(Error::InvalidValidatorIndex(val_index))?;
if let Some(participation_flags) = participation_flags {
participation_flags
.has_flag(flag_index)
.map_err(|_| Error::InvalidFlagIndex(flag_index))
Expand Down Expand Up @@ -149,8 +153,10 @@ impl SingleEpochParticipationCache {
}

// Add their `ParticipationFlags` to the map.
self.unslashed_participating_indices
.insert(val_index, *epoch_participation);
*self
.unslashed_participating_indices
.get_mut(val_index)
.ok_or(BeaconStateError::UnknownValidator(val_index))? = Some(*epoch_participation);

// Iterate through all the flags and increment the total flag balances for whichever flags
// are set for `val_index`.
Expand Down Expand Up @@ -190,19 +196,12 @@ impl ParticipationCache {
let current_epoch = state.current_epoch();
let previous_epoch = state.previous_epoch();

let num_previous_epoch_active_vals = state
.get_cached_active_validator_indices(RelativeEpoch::Previous)?
.len();
let num_current_epoch_active_vals = state
.get_cached_active_validator_indices(RelativeEpoch::Current)?
.len();

// Both the current/previous epoch participations are set to a capacity that is slightly
// larger than required. The difference will be due slashed-but-active validators.
let mut current_epoch_participation =
SingleEpochParticipationCache::new(num_current_epoch_active_vals, spec);
SingleEpochParticipationCache::instantiate(state.validators().len(), spec);
let mut previous_epoch_participation =
SingleEpochParticipationCache::new(num_previous_epoch_active_vals, spec);
SingleEpochParticipationCache::instantiate(state.validators().len(), spec);
// Contains the set of validators which are either:
//
// - Active in the previous epoch.
Expand Down Expand Up @@ -316,13 +315,17 @@ impl ParticipationCache {
pub fn is_active_unslashed_in_previous_epoch(&self, val_index: usize) -> bool {
self.previous_epoch_participation
.unslashed_participating_indices
.contains_key(&val_index)
.get(val_index)
// TODO(paul): map_or should be an Err.
.map_or(false, |flags| flags.is_some())
}

pub fn is_active_unslashed_in_current_epoch(&self, val_index: usize) -> bool {
self.current_epoch_participation
.unslashed_participating_indices
.contains_key(&val_index)
.get(val_index)
// TODO(paul): map_or should be an Err.
.map_or(false, |flags| flags.is_some())
}

/*
Expand Down

0 comments on commit 3870406

Please sign in to comment.