From c05cf6c25629ded0643623dc1b81a527ade6a142 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Tue, 4 Jun 2019 16:35:33 +1000 Subject: [PATCH] ef_tests: sanity slot tests + block headers --- tests/ef_tests/src/cases.rs | 4 ++ .../src/cases/operations_block_header.rs | 40 ++++++++++++++++++ tests/ef_tests/src/cases/sanity_slots.rs | 42 +++++++++++++++++++ tests/ef_tests/src/doc.rs | 8 ++++ tests/ef_tests/src/eth_specs.rs | 4 +- tests/ef_tests/tests/tests.rs | 27 ++++++++++++ 6 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 tests/ef_tests/src/cases/operations_block_header.rs create mode 100644 tests/ef_tests/src/cases/sanity_slots.rs diff --git a/tests/ef_tests/src/cases.rs b/tests/ef_tests/src/cases.rs index 8bff0cdf8..8e57e6f87 100644 --- a/tests/ef_tests/src/cases.rs +++ b/tests/ef_tests/src/cases.rs @@ -11,10 +11,12 @@ mod epoch_processing_crosslinks; mod epoch_processing_registry_updates; mod operations_attestation; mod operations_attester_slashing; +mod operations_block_header; mod operations_deposit; mod operations_exit; mod operations_proposer_slashing; mod operations_transfer; +mod sanity_slots; mod shuffling; mod ssz_generic; mod ssz_static; @@ -29,10 +31,12 @@ pub use epoch_processing_crosslinks::*; pub use epoch_processing_registry_updates::*; pub use operations_attestation::*; pub use operations_attester_slashing::*; +pub use operations_block_header::*; pub use operations_deposit::*; pub use operations_exit::*; pub use operations_proposer_slashing::*; pub use operations_transfer::*; +pub use sanity_slots::*; pub use shuffling::*; pub use ssz_generic::*; pub use ssz_static::*; diff --git a/tests/ef_tests/src/cases/operations_block_header.rs b/tests/ef_tests/src/cases/operations_block_header.rs new file mode 100644 index 000000000..8fb91a551 --- /dev/null +++ b/tests/ef_tests/src/cases/operations_block_header.rs @@ -0,0 +1,40 @@ +use super::*; +use crate::case_result::compare_beacon_state_results_without_caches; +use serde_derive::Deserialize; +use state_processing::per_block_processing::process_block_header; +use types::{BeaconBlock, BeaconState, EthSpec}; + +#[derive(Debug, Clone, Deserialize)] +pub struct OperationsBlockHeader { + pub description: String, + #[serde(bound = "E: EthSpec")] + pub pre: BeaconState, + pub block: BeaconBlock, + #[serde(bound = "E: EthSpec")] + pub post: Option>, +} + +impl YamlDecode for OperationsBlockHeader { + fn yaml_decode(yaml: &String) -> Result { + Ok(serde_yaml::from_str(&yaml.as_str()).unwrap()) + } +} + +impl Case for OperationsBlockHeader { + fn description(&self) -> String { + self.description.clone() + } + + fn result(&self, _case_index: usize) -> Result<(), Error> { + let mut state = self.pre.clone(); + let mut expected = self.post.clone(); + + // Processing requires the epoch cache. + state.build_all_caches(&E::spec()).unwrap(); + + let mut result = + process_block_header(&mut state, &self.block, &E::spec(), true).map(|_| state); + + compare_beacon_state_results_without_caches(&mut result, &mut expected) + } +} diff --git a/tests/ef_tests/src/cases/sanity_slots.rs b/tests/ef_tests/src/cases/sanity_slots.rs new file mode 100644 index 000000000..9b02428c2 --- /dev/null +++ b/tests/ef_tests/src/cases/sanity_slots.rs @@ -0,0 +1,42 @@ +use super::*; +use crate::case_result::compare_beacon_state_results_without_caches; +use serde_derive::Deserialize; +use state_processing::per_slot_processing; +use types::{BeaconState, EthSpec}; + +#[derive(Debug, Clone, Deserialize)] +pub struct SanitySlots { + pub description: String, + #[serde(bound = "E: EthSpec")] + pub pre: BeaconState, + pub slots: usize, + #[serde(bound = "E: EthSpec")] + pub post: Option>, +} + +impl YamlDecode for SanitySlots { + fn yaml_decode(yaml: &String) -> Result { + Ok(serde_yaml::from_str(&yaml.as_str()).unwrap()) + } +} + +impl Case for SanitySlots { + fn description(&self) -> String { + self.description.clone() + } + + fn result(&self, _case_index: usize) -> Result<(), Error> { + let mut state = self.pre.clone(); + let mut expected = self.post.clone(); + let spec = &E::spec(); + + // Processing requires the epoch cache. + state.build_all_caches(&E::spec()).unwrap(); + + let mut result = (0..self.slots) + .try_for_each(|_| per_slot_processing(&mut state, spec)) + .map(|_| state); + + compare_beacon_state_results_without_caches(&mut result, &mut expected) + } +} diff --git a/tests/ef_tests/src/doc.rs b/tests/ef_tests/src/doc.rs index 38f5e3cb3..522b094d5 100644 --- a/tests/ef_tests/src/doc.rs +++ b/tests/ef_tests/src/doc.rs @@ -41,6 +41,8 @@ impl Doc { ("ssz", "uint", _) => run_test::(self), ("ssz", "static", "minimal") => run_test::>(self), ("ssz", "static", "mainnet") => run_test::>(self), + ("sanity", "slots", "minimal") => run_test::>(self), + ("sanity", "slots", "mainnet") => run_test::>(self), ("shuffling", "core", "minimal") => run_test::>(self), ("shuffling", "core", "mainnet") => run_test::>(self), ("bls", "aggregate_pubkeys", "mainnet") => run_test::(self), @@ -89,6 +91,12 @@ impl Doc { ("operations", "attestation", "minimal") => { run_test::>(self) } + ("operations", "block_header", "mainnet") => { + run_test::>(self) + } + ("operations", "block_header", "minimal") => { + run_test::>(self) + } ("epoch_processing", "crosslinks", "minimal") => { run_test::>(self) } diff --git a/tests/ef_tests/src/eth_specs.rs b/tests/ef_tests/src/eth_specs.rs index 1e3f57d41..e6ac4e5fc 100644 --- a/tests/ef_tests/src/eth_specs.rs +++ b/tests/ef_tests/src/eth_specs.rs @@ -20,10 +20,12 @@ impl EthSpec for MinimalEthSpec { type LatestSlashedExitLength = U64; fn spec() -> ChainSpec { - // TODO: this spec is likely incorrect! let mut spec = FewValidatorsEthSpec::spec(); + spec.target_committee_size = 4; spec.shuffle_round_count = 10; spec.min_attestation_inclusion_delay = 2; + spec.slots_per_epoch = 8; + spec.slots_per_eth1_voting_period = 16; spec } } diff --git a/tests/ef_tests/tests/tests.rs b/tests/ef_tests/tests/tests.rs index 4a1618541..06e8f223d 100644 --- a/tests/ef_tests/tests/tests.rs +++ b/tests/ef_tests/tests/tests.rs @@ -124,6 +124,33 @@ fn operations_attestation() { }); } +#[test] +fn operations_block_header() { + yaml_files_in_test_dir(&Path::new("operations").join("block_header")) + .into_par_iter() + .for_each(|file| { + Doc::assert_tests_pass(file); + }); +} + +#[test] +fn sanity_blocks() { + yaml_files_in_test_dir(&Path::new("sanity").join("blocks")) + .into_par_iter() + .for_each(|file| { + Doc::assert_tests_pass(file); + }); +} + +#[test] +fn sanity_slots() { + yaml_files_in_test_dir(&Path::new("sanity").join("slots")) + .into_par_iter() + .for_each(|file| { + Doc::assert_tests_pass(file); + }); +} + #[test] #[cfg(not(feature = "fake_crypto"))] fn bls() {