lighthouse/tests/ef_tests/src/handler.rs
Michael Sproul 371e5adcf8
Update to Spec v0.10 (#817)
* Start updating types

* WIP

* Signature hacking

* Existing EF tests passing with fake_crypto

* Updates

* Delete outdated API spec

* The refactor continues

* It compiles

* WIP test fixes

* All release tests passing bar genesis state parsing

* Update and test YamlConfig

* Update to spec v0.10 compatible BLS

* Updates to BLS EF tests

* Add EF test for AggregateVerify

And delete unused hash2curve tests for uncompressed points

* Update EF tests to v0.10.1

* Use optional block root correctly in block proc

* Use genesis fork in deposit domain. All tests pass

* Cargo fmt

* Fast aggregate verify test

* Update REST API docs

* Cargo fmt

* Fix unused import

* Bump spec tags to v0.10.1

* Add `seconds_per_eth1_block` to chainspec

* Update to timestamp based eth1 voting scheme

* Return None from `get_votes_to_consider` if block cache is empty

* Handle overflows in `is_candidate_block`

* Revert to failing tests

* Fix eth1 data sets test

* Choose default vote according to spec

* Fix collect_valid_votes tests

* Fix `get_votes_to_consider` to choose all eligible blocks

* Uncomment winning_vote tests

* Add comments; remove unused code

* Reduce seconds_per_eth1_block for simulation

* Addressed review comments

* Add test for default vote case

* Fix logs

* Remove unused functions

* Meter default eth1 votes

* Fix comments

* Address review comments; remove unused dependency

* Disable/delete two outdated tests

* Bump eth1 default vote warn to error

* Delete outdated eth1 test

Co-authored-by: Pawan Dhananjay <pawandhananjay@gmail.com>
2020-02-11 10:19:36 +11:00

295 lines
6.6 KiB
Rust

use crate::cases::{self, Case, Cases, EpochTransition, LoadCase, Operation};
use crate::type_name;
use crate::type_name::TypeName;
use cached_tree_hash::CachedTreeHash;
use std::fmt::Debug;
use std::fs;
use std::marker::PhantomData;
use std::path::PathBuf;
use types::EthSpec;
pub trait Handler {
type Case: Case + LoadCase;
fn config_name() -> &'static str {
"general"
}
fn fork_name() -> &'static str {
"phase0"
}
fn runner_name() -> &'static str;
fn handler_name() -> String;
fn run() {
let handler_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("eth2.0-spec-tests")
.join("tests")
.join(Self::config_name())
.join(Self::fork_name())
.join(Self::runner_name())
.join(Self::handler_name());
// Iterate through test suites
let test_cases = fs::read_dir(&handler_path)
.expect("handler dir exists")
.flat_map(|entry| {
entry
.ok()
.filter(|e| e.file_type().map(|ty| ty.is_dir()).unwrap_or(false))
})
.flat_map(|suite| fs::read_dir(suite.path()).expect("suite dir exists"))
.flat_map(Result::ok)
.map(|test_case_dir| {
let path = test_case_dir.path();
let case = Self::Case::load_from_dir(&path).expect("test should load");
(path, case)
})
.collect();
let results = Cases { test_cases }.test_results();
let name = format!("{}/{}", Self::runner_name(), Self::handler_name());
crate::results::assert_tests_pass(&name, &handler_path, &results);
}
}
macro_rules! bls_handler {
($runner_name: ident, $case_name:ident, $handler_name:expr) => {
pub struct $runner_name;
impl Handler for $runner_name {
type Case = cases::$case_name;
fn runner_name() -> &'static str {
"bls"
}
fn handler_name() -> String {
$handler_name.into()
}
}
};
}
bls_handler!(BlsAggregateSigsHandler, BlsAggregateSigs, "aggregate");
bls_handler!(BlsSignMsgHandler, BlsSign, "sign");
bls_handler!(BlsVerifyMsgHandler, BlsVerify, "verify");
bls_handler!(
BlsAggregateVerifyHandler,
BlsAggregateVerify,
"aggregate_verify"
);
bls_handler!(
BlsFastAggregateVerifyHandler,
BlsFastAggregateVerify,
"fast_aggregate_verify"
);
/// Handler for SSZ types.
pub struct SszStaticHandler<T, E>(PhantomData<(T, E)>);
/// Handler for SSZ types that implement `CachedTreeHash`.
pub struct SszStaticTHCHandler<T, C, E>(PhantomData<(T, C, E)>);
impl<T, E> Handler for SszStaticHandler<T, E>
where
T: cases::SszStaticType + TypeName,
E: TypeName,
{
type Case = cases::SszStatic<T>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"ssz_static"
}
fn handler_name() -> String {
T::name().into()
}
}
impl<T, C, E> Handler for SszStaticTHCHandler<T, C, E>
where
T: cases::SszStaticType + CachedTreeHash<C> + TypeName,
C: Debug + Sync,
E: TypeName,
{
type Case = cases::SszStaticTHC<T, C>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"ssz_static"
}
fn handler_name() -> String {
T::name().into()
}
}
pub struct ShufflingHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for ShufflingHandler<E> {
type Case = cases::Shuffling<E>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"shuffling"
}
fn handler_name() -> String {
"core".into()
}
}
pub struct SanityBlocksHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for SanityBlocksHandler<E> {
type Case = cases::SanityBlocks<E>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"sanity"
}
fn handler_name() -> String {
"blocks".into()
}
}
pub struct SanitySlotsHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for SanitySlotsHandler<E> {
type Case = cases::SanitySlots<E>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"sanity"
}
fn handler_name() -> String {
"slots".into()
}
}
pub struct EpochProcessingHandler<E, T>(PhantomData<(E, T)>);
impl<E: EthSpec + TypeName, T: EpochTransition<E>> Handler for EpochProcessingHandler<E, T> {
type Case = cases::EpochProcessing<E, T>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"epoch_processing"
}
fn handler_name() -> String {
T::name().into()
}
}
pub struct GenesisValidityHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for GenesisValidityHandler<E> {
type Case = cases::GenesisValidity<E>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"genesis"
}
fn handler_name() -> String {
"validity".into()
}
}
pub struct GenesisInitializationHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for GenesisInitializationHandler<E> {
type Case = cases::GenesisInitialization<E>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"genesis"
}
fn handler_name() -> String {
"initialization".into()
}
}
pub struct OperationsHandler<E, O>(PhantomData<(E, O)>);
impl<E: EthSpec + TypeName, O: Operation<E>> Handler for OperationsHandler<E, O> {
type Case = cases::Operations<E, O>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"operations"
}
fn handler_name() -> String {
O::handler_name()
}
}
pub struct SszGenericHandler<H>(PhantomData<H>);
impl<H: TypeName> Handler for SszGenericHandler<H> {
type Case = cases::SszGeneric;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"ssz_generic"
}
fn handler_name() -> String {
H::name().into()
}
}
// Supported SSZ generic handlers
pub struct BasicVector;
type_name!(BasicVector, "basic_vector");
pub struct Bitlist;
type_name!(Bitlist, "bitlist");
pub struct Bitvector;
type_name!(Bitvector, "bitvector");
pub struct Boolean;
type_name!(Boolean, "boolean");
pub struct Uints;
type_name!(Uints, "uints");
pub struct Containers;
type_name!(Containers, "containers");