Tidy epoch processing, improve testing

This commit is contained in:
Paul Hauner 2019-05-19 18:07:18 +10:00
parent 94a39c3cb6
commit 05b38cbb7b
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
5 changed files with 40 additions and 24 deletions

View File

@ -348,7 +348,6 @@ impl<T: EthSpec> BeaconState<T> {
pub fn get_crosslink_committees_at_slot( pub fn get_crosslink_committees_at_slot(
&self, &self,
slot: Slot, slot: Slot,
spec: &ChainSpec,
) -> Result<Vec<CrosslinkCommittee>, Error> { ) -> Result<Vec<CrosslinkCommittee>, Error> {
let relative_epoch = RelativeEpoch::from_slot(self.slot, slot, T::slots_per_epoch())?; let relative_epoch = RelativeEpoch::from_slot(self.slot, slot, T::slots_per_epoch())?;
let cache = self.cache(relative_epoch)?; let cache = self.cache(relative_epoch)?;

View File

@ -178,17 +178,9 @@ impl EpochCache {
} }
pub fn first_committee_at_slot(&self, slot: Slot) -> Option<&[usize]> { pub fn first_committee_at_slot(&self, slot: Slot) -> Option<&[usize]> {
let position = self self.get_crosslink_committees_for_slot(slot)?
.initialized_epoch? .first()
.position(slot, self.slots_per_epoch)?; .and_then(|cc| Some(cc.committee))
let committees_per_slot = self.committee_count / self.slots_per_epoch as usize;
let position = position * committees_per_slot;
if position >= self.committee_count {
None
} else {
self.compute_committee(position)
}
} }
fn compute_committee(&self, index: usize) -> Option<&[usize]> { fn compute_committee(&self, index: usize) -> Option<&[usize]> {

View File

@ -30,23 +30,48 @@ fn execute_sane_cache_test<T: EthSpec>(
shuffle_list(active_indices, spec.shuffle_round_count, &seed[..], false).unwrap(); shuffle_list(active_indices, spec.shuffle_round_count, &seed[..], false).unwrap();
let mut expected_indices_iter = shuffling.iter(); let mut expected_indices_iter = shuffling.iter();
let mut expected_shards_iter = (start_shard..start_shard + T::shard_count() as u64).into_iter();
for i in 0..T::shard_count() { // Loop through all slots in the epoch being tested.
let shard = (i + start_shard as usize) % T::shard_count(); for slot in epoch.slot_iter(spec.slots_per_epoch) {
let crosslink_committees = state.get_crosslink_committees_at_slot(slot).unwrap();
let c = state // Assert that the number of committees in this slot is consistent with the reported number
.get_crosslink_committee_for_shard(shard as u64, relative_epoch) // of committees in an epoch.
.unwrap() assert_eq!(
.unwrap(); crosslink_committees.len() as u64,
state.get_epoch_committee_count(relative_epoch).unwrap() / T::slots_per_epoch()
);
for &i in c.committee { for cc in crosslink_committees {
// Assert that shards are assigned contiguously across committees.
assert_eq!(expected_shards_iter.next().unwrap(), cc.shard);
// Assert that a committee lookup via slot is identical to a committee lookup via
// shard.
assert_eq!( assert_eq!(
i, state
*expected_indices_iter.next().unwrap(), .get_crosslink_committee_for_shard(cc.shard, relative_epoch)
"Non-sequential validators." .unwrap(),
cc
); );
// Loop through each validator in the committee.
for &i in cc.committee {
// Assert the validators are assigned contiguously across committees.
assert_eq!(
i,
*expected_indices_iter.next().unwrap(),
"Non-sequential validators."
);
}
} }
} }
// Assert that all validators were assigned to a committee.
assert!(expected_indices_iter.next().is_none());
// Assert that all shards were assigned to a committee.
assert!(expected_shards_iter.next().is_none());
} }
fn sane_cache_test<T: EthSpec>( fn sane_cache_test<T: EthSpec>(

View File

@ -109,7 +109,7 @@ impl TestingBeaconBlockBuilder {
break; break;
} }
for crosslink_committee in state.get_crosslink_committees_at_slot(slot, spec)? { for crosslink_committee in state.get_crosslink_committees_at_slot(slot)? {
if attestations_added >= num_attestations { if attestations_added >= num_attestations {
break; break;
} }

View File

@ -223,7 +223,7 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
let slot = Slot::from(slot); let slot = Slot::from(slot);
let committees: Vec<OwnedCrosslinkCommittee> = state let committees: Vec<OwnedCrosslinkCommittee> = state
.get_crosslink_committees_at_slot(slot, spec) .get_crosslink_committees_at_slot(slot)
.unwrap() .unwrap()
.into_iter() .into_iter()
.map(|c| c.clone().into_owned()) .map(|c| c.clone().into_owned())