Tidy, add comments to CommitteeCache
				
					
				
			This commit is contained in:
		
							parent
							
								
									6660311b2b
								
							
						
					
					
						commit
						aa01808a00
					
				| @ -1,6 +1,4 @@ | ||||
| use self::committee_cache::{ | ||||
|     get_active_validator_indices, CommitteeCache, Error as CommitteeCacheError, | ||||
| }; | ||||
| use self::committee_cache::{get_active_validator_indices, CommitteeCache}; | ||||
| use self::exit_cache::ExitCache; | ||||
| use crate::test_utils::TestRandom; | ||||
| use crate::*; | ||||
| @ -37,6 +35,7 @@ pub enum Error { | ||||
|     UnableToDetermineProducer, | ||||
|     InvalidBitfield, | ||||
|     ValidatorIsWithdrawable, | ||||
|     UnableToShuffle, | ||||
|     InsufficientValidators, | ||||
|     InsufficientRandaoMixes, | ||||
|     InsufficientBlockRoots, | ||||
| @ -47,6 +46,7 @@ pub enum Error { | ||||
|     InsufficientStateRoots, | ||||
|     NoCommitteeForShard, | ||||
|     NoCommitteeForSlot, | ||||
|     ZeroSlotsPerEpoch, | ||||
|     PubkeyCacheInconsistent, | ||||
|     PubkeyCacheIncomplete { | ||||
|         cache_len: usize, | ||||
| @ -56,7 +56,6 @@ pub enum Error { | ||||
|     CurrentCommitteeCacheUninitialized, | ||||
|     RelativeEpochError(RelativeEpochError), | ||||
|     CommitteeCacheUninitialized(RelativeEpoch), | ||||
|     CommitteeCacheError(CommitteeCacheError), | ||||
|     TreeHashCacheError(TreeHashCacheError), | ||||
| } | ||||
| 
 | ||||
| @ -872,12 +871,6 @@ impl<T: EthSpec> BeaconState<T> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<CommitteeCacheError> for Error { | ||||
|     fn from(e: CommitteeCacheError) -> Error { | ||||
|         Error::CommitteeCacheError(e) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<RelativeEpochError> for Error { | ||||
|     fn from(e: RelativeEpochError) -> Error { | ||||
|         Error::RelativeEpochError(e) | ||||
|  | ||||
| @ -4,18 +4,13 @@ use honey_badger_split::SplitExt; | ||||
| use serde_derive::{Deserialize, Serialize}; | ||||
| use swap_or_not_shuffle::shuffle_list; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub enum Error { | ||||
|     EpochOutOfBounds, | ||||
|     UnableToShuffle, | ||||
|     UnableToGenerateSeed, | ||||
| } | ||||
| 
 | ||||
| mod tests; | ||||
| 
 | ||||
| /// Computes and stores the shuffling for an epoch. Provides various getters to allow callers to
 | ||||
| /// read the committees for the given epoch.
 | ||||
| #[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)] | ||||
| pub struct CommitteeCache { | ||||
|     /// `Some(epoch)` if the cache is initialized, where `epoch` is the cache it holds.
 | ||||
|     /// `Some(epoch)` if the cache is initialized where `epoch` is the cache it holds.
 | ||||
|     initialized_epoch: Option<Epoch>, | ||||
|     shuffling_start_shard: u64, | ||||
|     shuffling: Vec<usize>, | ||||
| @ -28,19 +23,26 @@ pub struct CommitteeCache { | ||||
| 
 | ||||
| impl CommitteeCache { | ||||
|     /// Return a new, fully initialized cache.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     pub fn initialized<T: EthSpec>( | ||||
|         state: &BeaconState<T>, | ||||
|         epoch: Epoch, | ||||
|         spec: &ChainSpec, | ||||
|     ) -> Result<CommitteeCache, BeaconStateError> { | ||||
|     ) -> Result<CommitteeCache, Error> { | ||||
|         let relative_epoch = RelativeEpoch::from_epoch(state.current_epoch(), epoch) | ||||
|             .map_err(|_| BeaconStateError::EpochOutOfBounds)?; | ||||
|             .map_err(|_| Error::EpochOutOfBounds)?; | ||||
| 
 | ||||
|         // May cause divide-by-zero errors.
 | ||||
|         if T::slots_per_epoch() == 0 { | ||||
|             return Err(Error::ZeroSlotsPerEpoch); | ||||
|         } | ||||
| 
 | ||||
|         let active_validator_indices = | ||||
|             get_active_validator_indices(&state.validator_registry, epoch); | ||||
| 
 | ||||
|         if active_validator_indices.is_empty() { | ||||
|             return Err(BeaconStateError::InsufficientValidators); | ||||
|             return Err(Error::InsufficientValidators); | ||||
|         } | ||||
| 
 | ||||
|         let committee_count = T::get_epoch_committee_count(active_validator_indices.len()) as usize; | ||||
| @ -89,6 +91,7 @@ impl CommitteeCache { | ||||
|         Ok(cache) | ||||
|     } | ||||
| 
 | ||||
|     /// Scans the shuffling and stores the attestation duties required for each active validator.
 | ||||
|     fn build_attestation_duties(&mut self) { | ||||
|         for (i, committee) in self | ||||
|             .shuffling | ||||
| @ -110,16 +113,30 @@ impl CommitteeCache { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Returns `true` if the cache has been initialized at the supplied `epoch`.
 | ||||
|     ///
 | ||||
|     /// An non-initialized cache does not provide any useful information.
 | ||||
|     pub fn is_initialized_at(&self, epoch: Epoch) -> bool { | ||||
|         Some(epoch) == self.initialized_epoch | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the **shuffled** list of active validator indices for the initialized epoch.
 | ||||
|     ///
 | ||||
|     /// These indices are not in ascending order.
 | ||||
|     ///
 | ||||
|     /// Always returns `&[]` for a non-initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     pub fn active_validator_indices(&self) -> &[usize] { | ||||
|         &self.shuffling | ||||
|     } | ||||
| 
 | ||||
|     /// Return `Some(CrosslinkCommittee)` if the given shard has a committee during the given
 | ||||
|     /// `epoch`.
 | ||||
|     ///
 | ||||
|     /// Always returns `None` for a non-initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     pub fn get_crosslink_committee_for_shard(&self, shard: Shard) -> Option<CrosslinkCommittee> { | ||||
|         if shard >= self.shard_count || self.initialized_epoch.is_none() { | ||||
|             return None; | ||||
| @ -137,18 +154,36 @@ impl CommitteeCache { | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the number of active validators in the initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Always returns `usize::default()` for a non-initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     pub fn active_validator_count(&self) -> usize { | ||||
|         self.shuffling.len() | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the total number of committees in the initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Always returns `usize::default()` for a non-initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     pub fn epoch_committee_count(&self) -> usize { | ||||
|         self.committee_count | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the shard assigned to the first committee in the initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Always returns `u64::default()` for a non-initialized epoch.
 | ||||
|     pub fn epoch_start_shard(&self) -> u64 { | ||||
|         self.shuffling_start_shard | ||||
|     } | ||||
| 
 | ||||
|     /// Returns all crosslink committees, if any, for the given slot in the initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Returns `None` if `slot` is not in the initialized epoch, or if `Self` is not initialized.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     pub fn get_crosslink_committees_for_slot(&self, slot: Slot) -> Option<Vec<CrosslinkCommittee>> { | ||||
|         let position = self | ||||
|             .initialized_epoch? | ||||
| @ -176,14 +211,24 @@ impl CommitteeCache { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the first committee of the first slot of the initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Always returns `None` for a non-initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     pub fn first_committee_at_slot(&self, slot: Slot) -> Option<&[usize]> { | ||||
|         self.get_crosslink_committees_for_slot(slot)? | ||||
|             .first() | ||||
|             .and_then(|cc| Some(cc.committee)) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns a slice of `self.shuffling` that represents the `index`'th committee in the epoch.
 | ||||
|     ///
 | ||||
|     /// To avoid a divide-by-zero, returns `None` if `self.committee_count` is zero.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     fn compute_committee(&self, index: usize) -> Option<&[usize]> { | ||||
|         if self.initialized_epoch.is_none() { | ||||
|         if self.committee_count == 0 { | ||||
|             return None; | ||||
|         } | ||||
| 
 | ||||
| @ -197,6 +242,11 @@ impl CommitteeCache { | ||||
|         Some(&self.shuffling[start..end]) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the `slot` that `shard` will be crosslink-ed in during the initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Always returns `None` for a non-initialized epoch.
 | ||||
|     ///
 | ||||
|     /// Spec v0.6.1
 | ||||
|     fn crosslink_slot_for_shard(&self, shard: u64) -> Option<Slot> { | ||||
|         let offset = (shard + self.shard_count - self.shuffling_start_shard) % self.shard_count; | ||||
|         Some( | ||||
| @ -224,6 +274,10 @@ pub fn get_active_validator_indices(validators: &[Validator], epoch: Epoch) -> V | ||||
|     active | ||||
| } | ||||
| 
 | ||||
| pub fn get_active_validator_count(validators: &[Validator], epoch: Epoch) -> usize { | ||||
| /// Returns the count of all `validator_registry` indices where the validator is active at the given
 | ||||
| /// `epoch`.
 | ||||
| ///
 | ||||
| /// Spec v0.6.1
 | ||||
| fn get_active_validator_count(validators: &[Validator], epoch: Epoch) -> usize { | ||||
|     validators.iter().filter(|v| v.is_active_at(epoch)).count() | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,21 @@ use crate::{test_utils::*, *}; | ||||
| use fixed_len_vec::typenum::*; | ||||
| use serde_derive::{Deserialize, Serialize}; | ||||
| 
 | ||||
| #[test] | ||||
| fn default_values() { | ||||
|     let cache = CommitteeCache::default(); | ||||
| 
 | ||||
|     assert_eq!(cache.attestation_duties, vec![]); | ||||
|     assert_eq!(cache.is_initialized_at(Epoch::new(0)), false); | ||||
|     assert_eq!(cache.active_validator_indices(), &[]); | ||||
|     assert_eq!(cache.get_crosslink_committee_for_shard(0), None); | ||||
|     assert_eq!(cache.active_validator_count(), 0); | ||||
|     assert_eq!(cache.epoch_committee_count(), 0); | ||||
|     assert_eq!(cache.epoch_start_shard(), 0); | ||||
|     assert_eq!(cache.get_crosslink_committees_for_slot(Slot::new(0)), None); | ||||
|     assert_eq!(cache.first_committee_at_slot(Slot::new(0)), None); | ||||
| } | ||||
| 
 | ||||
| fn new_state<T: EthSpec>(validator_count: usize, slot: Slot) -> BeaconState<T> { | ||||
|     let spec = &T::spec(); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user