Move committee tests to beacon state tests

They used to be in epoch_cache tests but they were really testing
BeaconState interfaces.
This commit is contained in:
Paul Hauner 2019-05-19 18:15:32 +10:00
parent 05b38cbb7b
commit 1565096008
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
2 changed files with 144 additions and 138 deletions

View File

@ -1,138 +1 @@
#![cfg(test)] #![cfg(test)]
use super::*;
use crate::beacon_state::FewValidatorsEthSpec;
use crate::test_utils::*;
use swap_or_not_shuffle::shuffle_list;
fn execute_sane_cache_test<T: EthSpec>(
state: BeaconState<T>,
epoch: Epoch,
validator_count: usize,
spec: &ChainSpec,
) {
let active_indices: Vec<usize> = (0..validator_count).collect();
let seed = state.generate_seed(epoch, spec).unwrap();
let start_shard = 0;
let relative_epoch = RelativeEpoch::from_epoch(state.current_epoch(), epoch).unwrap();
let mut ordered_indices = state
.get_cached_active_validator_indices(relative_epoch)
.unwrap()
.to_vec();
ordered_indices.sort_unstable();
assert_eq!(
active_indices, ordered_indices,
"Validator indices mismatch"
);
let shuffling =
shuffle_list(active_indices, spec.shuffle_round_count, &seed[..], false).unwrap();
let mut expected_indices_iter = shuffling.iter();
let mut expected_shards_iter = (start_shard..start_shard + T::shard_count() as u64).into_iter();
// Loop through all slots in the epoch being tested.
for slot in epoch.slot_iter(spec.slots_per_epoch) {
let crosslink_committees = state.get_crosslink_committees_at_slot(slot).unwrap();
// Assert that the number of committees in this slot is consistent with the reported number
// of committees in an epoch.
assert_eq!(
crosslink_committees.len() as u64,
state.get_epoch_committee_count(relative_epoch).unwrap() / T::slots_per_epoch()
);
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!(
state
.get_crosslink_committee_for_shard(cc.shard, relative_epoch)
.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>(
validator_count: usize,
state_epoch: Epoch,
cache_epoch: RelativeEpoch,
) {
let spec = &T::spec();
let mut builder =
TestingBeaconStateBuilder::from_single_keypair(validator_count, &Keypair::random(), spec);
let slot = state_epoch.start_slot(spec.slots_per_epoch);
builder.teleport_to_slot(slot, spec);
let (mut state, _keypairs): (BeaconState<T>, _) = builder.build();
state
.build_epoch_cache(RelativeEpoch::Previous, spec)
.unwrap();
state
.build_epoch_cache(RelativeEpoch::Current, spec)
.unwrap();
state.build_epoch_cache(RelativeEpoch::Next, spec).unwrap();
let cache_epoch = cache_epoch.into_epoch(state_epoch);
execute_sane_cache_test(state, cache_epoch, validator_count as usize, &spec);
}
fn sane_cache_test_suite<T: EthSpec>(cached_epoch: RelativeEpoch) {
let spec = T::spec();
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
sane_cache_test::<T>(validator_count as usize, Epoch::new(0), cached_epoch);
sane_cache_test::<T>(
validator_count as usize,
spec.genesis_epoch + 4,
cached_epoch,
);
sane_cache_test::<T>(
validator_count as usize,
spec.genesis_epoch + T::slots_per_historical_root() as u64 * T::slots_per_epoch() * 4,
cached_epoch,
);
}
#[test]
fn current_epoch_suite() {
sane_cache_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Current);
}
#[test]
fn previous_epoch_suite() {
sane_cache_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Previous);
}
#[test]
fn next_epoch_suite() {
sane_cache_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Next);
}

View File

@ -1,6 +1,5 @@
#![cfg(test)] #![cfg(test)]
use super::*; use super::*;
use crate::beacon_state::FewValidatorsEthSpec;
use crate::test_utils::*; use crate::test_utils::*;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
@ -149,3 +148,147 @@ fn tree_hash_cache() {
let root = state.update_tree_hash_cache().unwrap(); let root = state.update_tree_hash_cache().unwrap();
assert_eq!(root.as_bytes(), &state.tree_hash_root()[..]); assert_eq!(root.as_bytes(), &state.tree_hash_root()[..]);
} }
/// Tests committee-specific components
#[cfg(test)]
mod committees {
use super::*;
use crate::beacon_state::FewValidatorsEthSpec;
use swap_or_not_shuffle::shuffle_list;
fn execute_committee_consistency_test<T: EthSpec>(
state: BeaconState<T>,
epoch: Epoch,
validator_count: usize,
spec: &ChainSpec,
) {
let active_indices: Vec<usize> = (0..validator_count).collect();
let seed = state.generate_seed(epoch, spec).unwrap();
let start_shard = 0;
let relative_epoch = RelativeEpoch::from_epoch(state.current_epoch(), epoch).unwrap();
let mut ordered_indices = state
.get_cached_active_validator_indices(relative_epoch)
.unwrap()
.to_vec();
ordered_indices.sort_unstable();
assert_eq!(
active_indices, ordered_indices,
"Validator indices mismatch"
);
let shuffling =
shuffle_list(active_indices, spec.shuffle_round_count, &seed[..], false).unwrap();
let mut expected_indices_iter = shuffling.iter();
let mut expected_shards_iter =
(start_shard..start_shard + T::shard_count() as u64).into_iter();
// Loop through all slots in the epoch being tested.
for slot in epoch.slot_iter(spec.slots_per_epoch) {
let crosslink_committees = state.get_crosslink_committees_at_slot(slot).unwrap();
// Assert that the number of committees in this slot is consistent with the reported number
// of committees in an epoch.
assert_eq!(
crosslink_committees.len() as u64,
state.get_epoch_committee_count(relative_epoch).unwrap() / T::slots_per_epoch()
);
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!(
state
.get_crosslink_committee_for_shard(cc.shard, relative_epoch)
.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 committee_consistency_test<T: EthSpec>(
validator_count: usize,
state_epoch: Epoch,
cache_epoch: RelativeEpoch,
) {
let spec = &T::spec();
let mut builder = TestingBeaconStateBuilder::from_single_keypair(
validator_count,
&Keypair::random(),
spec,
);
let slot = state_epoch.start_slot(spec.slots_per_epoch);
builder.teleport_to_slot(slot, spec);
let (mut state, _keypairs): (BeaconState<T>, _) = builder.build();
state
.build_epoch_cache(RelativeEpoch::Previous, spec)
.unwrap();
state
.build_epoch_cache(RelativeEpoch::Current, spec)
.unwrap();
state.build_epoch_cache(RelativeEpoch::Next, spec).unwrap();
let cache_epoch = cache_epoch.into_epoch(state_epoch);
execute_committee_consistency_test(state, cache_epoch, validator_count as usize, &spec);
}
fn committee_consistency_test_suite<T: EthSpec>(cached_epoch: RelativeEpoch) {
let spec = T::spec();
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
committee_consistency_test::<T>(validator_count as usize, Epoch::new(0), cached_epoch);
committee_consistency_test::<T>(
validator_count as usize,
spec.genesis_epoch + 4,
cached_epoch,
);
committee_consistency_test::<T>(
validator_count as usize,
spec.genesis_epoch + T::slots_per_historical_root() as u64 * T::slots_per_epoch() * 4,
cached_epoch,
);
}
#[test]
fn current_epoch_committee_consistency() {
committee_consistency_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Current);
}
#[test]
fn previous_epoch_committee_consistency() {
committee_consistency_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Previous);
}
#[test]
fn next_epoch_committee_consistency() {
committee_consistency_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Next);
}
}