From 9f42d4d764bb270886953977edf23a925f9fc915 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 15 May 2019 09:50:05 +1000 Subject: [PATCH] Extend ssz-static testing --- eth2/types/src/lib.rs | 2 +- tests/ef_tests/Cargo.toml | 1 + tests/ef_tests/src/eth_specs.rs | 23 +++++++++++++++++ tests/ef_tests/src/lib.rs | 2 ++ tests/ef_tests/src/test_case_result.rs | 4 +-- tests/ef_tests/src/test_doc.rs | 4 +-- .../src/test_doc_cases/ssz_generic.rs | 2 +- .../ef_tests/src/test_doc_cases/ssz_static.rs | 25 +++++++++++-------- 8 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 tests/ef_tests/src/eth_specs.rs diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index bb40106d1..43af62245 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -81,7 +81,7 @@ pub type AttesterMap = HashMap<(u64, u64), Vec>; pub type ProposerMap = HashMap; pub use bls::{AggregatePublicKey, AggregateSignature, Keypair, PublicKey, SecretKey, Signature}; -pub use fixed_len_vec::{typenum::Unsigned, FixedLenVec}; +pub use fixed_len_vec::{typenum, typenum::Unsigned, FixedLenVec}; pub use libp2p::floodsub::{Topic, TopicBuilder, TopicHash}; pub use libp2p::multiaddr; pub use libp2p::Multiaddr; diff --git a/tests/ef_tests/Cargo.toml b/tests/ef_tests/Cargo.toml index fee9f07cd..08cf279b5 100644 --- a/tests/ef_tests/Cargo.toml +++ b/tests/ef_tests/Cargo.toml @@ -15,5 +15,6 @@ serde = "1.0" serde_derive = "1.0" serde_yaml = "0.8" ssz = { path = "../../eth2/utils/ssz" } +tree_hash = { path = "../../eth2/utils/tree_hash" } types = { path = "../../eth2/types" } yaml-rust = { git = "https://github.com/sigp/yaml-rust", branch = "escape_all_str"} diff --git a/tests/ef_tests/src/eth_specs.rs b/tests/ef_tests/src/eth_specs.rs new file mode 100644 index 000000000..81a6e1731 --- /dev/null +++ b/tests/ef_tests/src/eth_specs.rs @@ -0,0 +1,23 @@ +use types::{EthSpec, typenum::{U64, U8}, ChainSpec, FewValidatorsEthSpec}; +use serde_derive::{Serialize, Deserialize}; + +/// "Minimal" testing specification, as defined here: +/// +/// https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/configs/constant_presets/minimal.yaml +/// +/// Spec v0.6.1 +#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] +pub struct MinimalEthSpec; + +impl EthSpec for MinimalEthSpec { + type ShardCount = U8; + type SlotsPerHistoricalRoot = U64; + type LatestRandaoMixesLength = U64; + type LatestActiveIndexRootsLength = U64; + type LatestSlashedExitLength = U64; + + fn spec() -> ChainSpec { + // TODO: this spec is likely incorrect! + FewValidatorsEthSpec::spec() + } +} diff --git a/tests/ef_tests/src/lib.rs b/tests/ef_tests/src/lib.rs index 56aaaec92..ecfcae3cc 100644 --- a/tests/ef_tests/src/lib.rs +++ b/tests/ef_tests/src/lib.rs @@ -6,6 +6,7 @@ use std::fmt::Debug; use test_decode::TestDecode; pub use crate::error::*; +pub use crate::eth_specs::*; pub use crate::test_case_result::*; pub use crate::test_doc::*; pub use crate::test_doc_cases::*; @@ -13,6 +14,7 @@ pub use crate::test_doc_header::*; pub use crate::yaml_utils::*; mod error; +mod eth_specs; mod test_case_result; mod test_decode; mod test_doc; diff --git a/tests/ef_tests/src/test_case_result.rs b/tests/ef_tests/src/test_case_result.rs index 9e3a97613..98e872564 100644 --- a/tests/ef_tests/src/test_case_result.rs +++ b/tests/ef_tests/src/test_case_result.rs @@ -26,7 +26,7 @@ pub trait Test { /// /// If `expected.is_none()` then `result` is expected to be `Err`. Otherwise, `T` in `result` and /// `expected` must be equal. -pub fn compare_result(result: Result, expected: Option) -> Result<(), Error> +pub fn compare_result(result: &Result, expected: &Option) -> Result<(), Error> where T: PartialEq + Debug, E: Debug, @@ -36,7 +36,7 @@ where (Err(_), None) => Ok(()), // Fail: The test failed when it should have produced a result (fail). (Err(e), Some(expected)) => Err(Error::NotEqual(format!( - "Got {:?} expected {:?}", + "Got {:?} Expected {:?}", e, expected ))), // Fail: The test produced a result when it should have failed (fail). diff --git a/tests/ef_tests/src/test_doc.rs b/tests/ef_tests/src/test_doc.rs index 87382b989..316404cfa 100644 --- a/tests/ef_tests/src/test_doc.rs +++ b/tests/ef_tests/src/test_doc.rs @@ -1,6 +1,6 @@ use super::*; use std::{fs::File, io::prelude::*, path::PathBuf}; -use types::{EthSpec, FewValidatorsEthSpec, FoundationEthSpec}; +use types::{EthSpec, FoundationEthSpec}; #[derive(Debug, Deserialize)] pub struct TestDoc { @@ -28,7 +28,7 @@ impl TestDoc { header.config.as_ref(), ) { ("ssz", "uint", _) => run_test::(&doc.yaml), - ("ssz", "static", "minimal") => run_test::(&doc.yaml), + ("ssz", "static", "minimal") => run_test::(&doc.yaml), (runner, handler, config) => panic!( "No implementation for runner: \"{}\", handler: \"{}\", config: \"{}\"", runner, handler, config diff --git a/tests/ef_tests/src/test_doc_cases/ssz_generic.rs b/tests/ef_tests/src/test_doc_cases/ssz_generic.rs index 48fdd0b58..a0ed7da22 100644 --- a/tests/ef_tests/src/test_doc_cases/ssz_generic.rs +++ b/tests/ef_tests/src/test_doc_cases/ssz_generic.rs @@ -72,5 +72,5 @@ where let decoded = T::from_ssz_bytes(&ssz); - compare_result(decoded, expected) + compare_result(&decoded, &expected) } diff --git a/tests/ef_tests/src/test_doc_cases/ssz_static.rs b/tests/ef_tests/src/test_doc_cases/ssz_static.rs index 5948fdb25..789b5f17f 100644 --- a/tests/ef_tests/src/test_doc_cases/ssz_static.rs +++ b/tests/ef_tests/src/test_doc_cases/ssz_static.rs @@ -1,10 +1,10 @@ use super::*; -use serde::de::{Deserialize, Deserializer}; +use tree_hash::TreeHash; use types::{ Attestation, AttestationData, AttestationDataAndCustodyBit, AttesterSlashing, BeaconBlock, BeaconBlockBody, BeaconBlockHeader, BeaconState, Crosslink, Deposit, DepositData, Eth1Data, - EthSpec, Fork, HistoricalBatch, IndexedAttestation, PendingAttestation, ProposerSlashing, - Transfer, Validator, VoluntaryExit, + EthSpec, Fork, Hash256, HistoricalBatch, IndexedAttestation, PendingAttestation, + ProposerSlashing, Transfer, Validator, VoluntaryExit, }; #[derive(Debug, Clone, Deserialize)] @@ -84,18 +84,21 @@ impl Test for TestDocCases { fn ssz_static_test(tc: &SszStatic) -> Result<(), Error> where - T: Decode + Debug + PartialEq + serde::de::DeserializeOwned, + T: Decode + Debug + PartialEq + serde::de::DeserializeOwned + TreeHash, { + // Verify we can decode SSZ in the same way we can decode YAML. let ssz = hex::decode(&tc.serialized[2..]) .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?; - let expected = tc.value::()?; + let decode_result = T::from_ssz_bytes(&ssz); + compare_result(&decode_result, &Some(expected))?; + + // Verify the tree hash root is identical to the decoded struct. + let root_bytes = + &hex::decode(&tc.root[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?; + let expected_root = Hash256::from_slice(&root_bytes); + let root = Hash256::from_slice(&decode_result.unwrap().tree_hash_root()); + compare_result::(&Ok(root), &Some(expected_root))?; Ok(()) - - /* - let decoded = T::from_ssz_bytes(&ssz); - - compare_result(decoded, Some(expected)) - */ }