mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-19 21:04:41 +00:00
Altair consensus changes and refactors (#2279)
## Proposed Changes Implement the consensus changes necessary for the upcoming Altair hard fork. ## Additional Info This is quite a heavy refactor, with pivotal types like the `BeaconState` and `BeaconBlock` changing from structs to enums. This ripples through the whole codebase with field accesses changing to methods, e.g. `state.slot` => `state.slot()`. Co-authored-by: realbigsean <seananderson33@gmail.com>
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
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 derivative::Derivative;
|
||||
use std::fs;
|
||||
use std::marker::PhantomData;
|
||||
use std::path::PathBuf;
|
||||
use types::EthSpec;
|
||||
use types::{BeaconState, EthSpec, ForkName};
|
||||
|
||||
pub trait Handler {
|
||||
type Case: Case + LoadCase;
|
||||
@@ -15,22 +14,35 @@ pub trait Handler {
|
||||
"general"
|
||||
}
|
||||
|
||||
fn fork_name() -> &'static str {
|
||||
"phase0"
|
||||
}
|
||||
|
||||
fn runner_name() -> &'static str;
|
||||
|
||||
fn handler_name() -> String;
|
||||
fn handler_name(&self) -> String;
|
||||
|
||||
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
||||
Self::Case::is_enabled_for_fork(fork_name)
|
||||
}
|
||||
|
||||
fn run(&self) {
|
||||
for fork_name in ForkName::list_all() {
|
||||
if self.is_enabled_for_fork(fork_name) {
|
||||
self.run_for_fork(fork_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_for_fork(&self, fork_name: ForkName) {
|
||||
let fork_name_str = match fork_name {
|
||||
ForkName::Base => "phase0",
|
||||
ForkName::Altair => "altair",
|
||||
};
|
||||
|
||||
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(fork_name_str)
|
||||
.join(Self::runner_name())
|
||||
.join(Self::handler_name());
|
||||
.join(self.handler_name());
|
||||
|
||||
// Iterate through test suites
|
||||
let test_cases = fs::read_dir(&handler_path)
|
||||
@@ -44,30 +56,41 @@ pub trait Handler {
|
||||
.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");
|
||||
let case = Self::Case::load_from_dir(&path, fork_name).expect("test should load");
|
||||
(path, case)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let results = Cases { test_cases }.test_results();
|
||||
let results = Cases { test_cases }.test_results(fork_name);
|
||||
|
||||
let name = format!("{}/{}", Self::runner_name(), Self::handler_name());
|
||||
let name = format!(
|
||||
"{}/{}/{}",
|
||||
fork_name_str,
|
||||
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) => {
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct $runner_name;
|
||||
|
||||
impl Handler for $runner_name {
|
||||
type Case = cases::$case_name;
|
||||
|
||||
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
||||
fork_name == ForkName::Base
|
||||
}
|
||||
|
||||
fn runner_name() -> &'static str {
|
||||
"bls"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
$handler_name.into()
|
||||
}
|
||||
}
|
||||
@@ -89,14 +112,47 @@ bls_handler!(
|
||||
);
|
||||
|
||||
/// Handler for SSZ types.
|
||||
pub struct SszStaticHandler<T, E>(PhantomData<(T, E)>);
|
||||
pub struct SszStaticHandler<T, E> {
|
||||
supported_forks: Vec<ForkName>,
|
||||
_phantom: PhantomData<(T, E)>,
|
||||
}
|
||||
|
||||
impl<T, E> Default for SszStaticHandler<T, E> {
|
||||
fn default() -> Self {
|
||||
Self::for_forks(ForkName::list_all())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> SszStaticHandler<T, E> {
|
||||
pub fn for_forks(supported_forks: Vec<ForkName>) -> Self {
|
||||
SszStaticHandler {
|
||||
supported_forks,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn base_only() -> Self {
|
||||
Self::for_forks(vec![ForkName::Base])
|
||||
}
|
||||
|
||||
pub fn altair_only() -> Self {
|
||||
Self::for_forks(vec![ForkName::Altair])
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for SSZ types that implement `CachedTreeHash`.
|
||||
pub struct SszStaticTHCHandler<T, C, E>(PhantomData<(T, C, E)>);
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct SszStaticTHCHandler<T, E>(PhantomData<(T, E)>);
|
||||
|
||||
/// Handler for SSZ types that don't implement `ssz::Decode`.
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct SszStaticWithSpecHandler<T, E>(PhantomData<(T, E)>);
|
||||
|
||||
impl<T, E> Handler for SszStaticHandler<T, E>
|
||||
where
|
||||
T: cases::SszStaticType + TypeName,
|
||||
T: cases::SszStaticType + ssz::Decode + TypeName,
|
||||
E: TypeName,
|
||||
{
|
||||
type Case = cases::SszStatic<T>;
|
||||
@@ -109,18 +165,20 @@ where
|
||||
"ssz_static"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
T::name().into()
|
||||
}
|
||||
|
||||
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
||||
self.supported_forks.contains(&fork_name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C, E> Handler for SszStaticTHCHandler<T, C, E>
|
||||
impl<E> Handler for SszStaticTHCHandler<BeaconState<E>, E>
|
||||
where
|
||||
T: cases::SszStaticType + CachedTreeHash<C> + TypeName,
|
||||
C: Debug + Sync,
|
||||
E: TypeName,
|
||||
E: EthSpec + TypeName,
|
||||
{
|
||||
type Case = cases::SszStaticTHC<T, C>;
|
||||
type Case = cases::SszStaticTHC<BeaconState<E>>;
|
||||
|
||||
fn config_name() -> &'static str {
|
||||
E::name()
|
||||
@@ -130,11 +188,34 @@ where
|
||||
"ssz_static"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
BeaconState::<E>::name().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Handler for SszStaticWithSpecHandler<T, E>
|
||||
where
|
||||
T: TypeName,
|
||||
E: EthSpec + TypeName,
|
||||
cases::SszStaticWithSpec<T>: Case + LoadCase,
|
||||
{
|
||||
type Case = cases::SszStaticWithSpec<T>;
|
||||
|
||||
fn config_name() -> &'static str {
|
||||
E::name()
|
||||
}
|
||||
|
||||
fn runner_name() -> &'static str {
|
||||
"ssz_static"
|
||||
}
|
||||
|
||||
fn handler_name(&self) -> String {
|
||||
T::name().into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct ShufflingHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for ShufflingHandler<E> {
|
||||
@@ -148,11 +229,17 @@ impl<E: EthSpec + TypeName> Handler for ShufflingHandler<E> {
|
||||
"shuffling"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
"core".into()
|
||||
}
|
||||
|
||||
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
||||
fork_name == ForkName::Base
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct SanityBlocksHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for SanityBlocksHandler<E> {
|
||||
@@ -166,11 +253,19 @@ impl<E: EthSpec + TypeName> Handler for SanityBlocksHandler<E> {
|
||||
"sanity"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
"blocks".into()
|
||||
}
|
||||
|
||||
fn is_enabled_for_fork(&self, _fork_name: ForkName) -> bool {
|
||||
// FIXME(altair): v1.1.0-alpha.3 doesn't mark the historical blocks test as
|
||||
// requiring real crypto, so only run these tests with real crypto for now.
|
||||
cfg!(not(feature = "fake_crypto"))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct SanitySlotsHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for SanitySlotsHandler<E> {
|
||||
@@ -184,11 +279,13 @@ impl<E: EthSpec + TypeName> Handler for SanitySlotsHandler<E> {
|
||||
"sanity"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
"slots".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct EpochProcessingHandler<E, T>(PhantomData<(E, T)>);
|
||||
|
||||
impl<E: EthSpec + TypeName, T: EpochTransition<E>> Handler for EpochProcessingHandler<E, T> {
|
||||
@@ -202,11 +299,83 @@ impl<E: EthSpec + TypeName, T: EpochTransition<E>> Handler for EpochProcessingHa
|
||||
"epoch_processing"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
T::name().into()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RewardsHandler<E: EthSpec> {
|
||||
handler_name: &'static str,
|
||||
_phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> RewardsHandler<E> {
|
||||
pub fn new(handler_name: &'static str) -> Self {
|
||||
Self {
|
||||
handler_name,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for RewardsHandler<E> {
|
||||
type Case = cases::RewardsTest<E>;
|
||||
|
||||
fn config_name() -> &'static str {
|
||||
E::name()
|
||||
}
|
||||
|
||||
fn runner_name() -> &'static str {
|
||||
"rewards"
|
||||
}
|
||||
|
||||
fn handler_name(&self) -> String {
|
||||
self.handler_name.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct ForkHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for ForkHandler<E> {
|
||||
type Case = cases::ForkTest<E>;
|
||||
|
||||
fn config_name() -> &'static str {
|
||||
E::name()
|
||||
}
|
||||
|
||||
fn runner_name() -> &'static str {
|
||||
"fork"
|
||||
}
|
||||
|
||||
fn handler_name(&self) -> String {
|
||||
"fork".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct TransitionHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for TransitionHandler<E> {
|
||||
type Case = cases::TransitionTest<E>;
|
||||
|
||||
fn config_name() -> &'static str {
|
||||
E::name()
|
||||
}
|
||||
|
||||
fn runner_name() -> &'static str {
|
||||
"transition"
|
||||
}
|
||||
|
||||
fn handler_name(&self) -> String {
|
||||
"core".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct FinalityHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for FinalityHandler<E> {
|
||||
@@ -221,11 +390,13 @@ impl<E: EthSpec + TypeName> Handler for FinalityHandler<E> {
|
||||
"finality"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
"finality".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct GenesisValidityHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for GenesisValidityHandler<E> {
|
||||
@@ -239,11 +410,13 @@ impl<E: EthSpec + TypeName> Handler for GenesisValidityHandler<E> {
|
||||
"genesis"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
"validity".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct GenesisInitializationHandler<E>(PhantomData<E>);
|
||||
|
||||
impl<E: EthSpec + TypeName> Handler for GenesisInitializationHandler<E> {
|
||||
@@ -257,11 +430,13 @@ impl<E: EthSpec + TypeName> Handler for GenesisInitializationHandler<E> {
|
||||
"genesis"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
"initialization".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct OperationsHandler<E, O>(PhantomData<(E, O)>);
|
||||
|
||||
impl<E: EthSpec + TypeName, O: Operation<E>> Handler for OperationsHandler<E, O> {
|
||||
@@ -275,11 +450,13 @@ impl<E: EthSpec + TypeName, O: Operation<E>> Handler for OperationsHandler<E, O>
|
||||
"operations"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn handler_name(&self) -> String {
|
||||
O::handler_name()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
pub struct SszGenericHandler<H>(PhantomData<H>);
|
||||
|
||||
impl<H: TypeName> Handler for SszGenericHandler<H> {
|
||||
@@ -293,7 +470,12 @@ impl<H: TypeName> Handler for SszGenericHandler<H> {
|
||||
"ssz_generic"
|
||||
}
|
||||
|
||||
fn handler_name() -> String {
|
||||
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
||||
// SSZ generic tests are genesis only
|
||||
fork_name == ForkName::Base
|
||||
}
|
||||
|
||||
fn handler_name(&self) -> String {
|
||||
H::name().into()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user