Update to spec v1.1.8 (#2893)

## Proposed Changes

Change the canonical fork name for the merge to Bellatrix. Keep other merge naming the same to avoid churn.

I've also fixed and enabled the `fork` and `transition` tests for Bellatrix, and the v1.1.7 fork choice tests.

Additionally, the `BellatrixPreset` has been added with tests. It gets served via the `/config/spec` API endpoint along with the other presets.
This commit is contained in:
Michael Sproul
2022-01-19 00:24:19 +00:00
parent 9ed92d6e78
commit ef7351ddfe
29 changed files with 214 additions and 172 deletions

View File

@@ -3,7 +3,7 @@ use crate::case_result::compare_beacon_state_results_without_caches;
use crate::cases::common::previous_fork;
use crate::decode::{ssz_decode_state, yaml_decode_file};
use serde_derive::Deserialize;
use state_processing::upgrade::upgrade_to_altair;
use state_processing::upgrade::{upgrade_to_altair, upgrade_to_bellatrix};
use types::{BeaconState, ForkName};
#[derive(Debug, Clone, Default, Deserialize)]
@@ -49,10 +49,7 @@ impl<E: EthSpec> Case for ForkTest<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
// Upgrades exist targeting all forks except phase0/base.
// Fork tests also need BLS.
// FIXME(merge): enable merge tests once available
cfg!(not(feature = "fake_crypto"))
&& fork_name != ForkName::Base
&& fork_name != ForkName::Merge
cfg!(not(feature = "fake_crypto")) && fork_name != ForkName::Base
}
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
@@ -61,8 +58,9 @@ impl<E: EthSpec> Case for ForkTest<E> {
let spec = &E::default_spec();
let mut result = match fork_name {
ForkName::Base => panic!("phase0 not supported"),
ForkName::Altair => upgrade_to_altair(&mut result_state, spec).map(|_| result_state),
_ => panic!("unknown fork: {:?}", fork_name),
ForkName::Merge => upgrade_to_bellatrix(&mut result_state, spec).map(|_| result_state),
};
compare_beacon_state_results_without_caches(&mut result, &mut expected)

View File

@@ -154,15 +154,10 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
let tester = Tester::new(self, fork_choice_spec::<E>(fork_name))?;
// TODO(merge): enable these tests before production.
// This test will fail until this PR is merged and released:
//
// https://github.com/ethereum/consensus-specs/pull/2760
if self.description == "shorter_chain_but_heavier_weight"
// This test is skipped until we can do retrospective confirmations of the terminal
// block after an optimistic sync.
|| self.description == "block_lookup_failed"
{
// TODO(merge): re-enable this test before production.
// This test is skipped until we can do retrospective confirmations of the terminal
// block after an optimistic sync.
if self.description == "block_lookup_failed" {
return Err(Error::SkippedKnownFailure);
};

View File

@@ -239,7 +239,6 @@ impl<E: EthSpec> Operation<E> for ExecutionPayload<E> {
spec: &ChainSpec,
extra: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
// FIXME(merge): we may want to plumb the validity bool into state processing
let valid = extra
.execution_metadata
.as_ref()

View File

@@ -39,7 +39,8 @@ impl<E: EthSpec> LoadCase for TransitionTest<E> {
spec.altair_fork_epoch = Some(metadata.fork_epoch);
}
ForkName::Merge => {
spec.merge_fork_epoch = Some(metadata.fork_epoch);
spec.altair_fork_epoch = Some(Epoch::new(0));
spec.bellatrix_fork_epoch = Some(metadata.fork_epoch);
}
}
@@ -73,10 +74,7 @@ impl<E: EthSpec> Case for TransitionTest<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
// Upgrades exist targeting all forks except phase0/base.
// Transition tests also need BLS.
// FIXME(merge): Merge transition tests are now available but not yet passing
cfg!(not(feature = "fake_crypto"))
&& fork_name != ForkName::Base
&& fork_name != ForkName::Merge
cfg!(not(feature = "fake_crypto")) && fork_name != ForkName::Base
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {

View File

@@ -2,7 +2,7 @@ use crate::cases::{self, Case, Cases, EpochTransition, LoadCase, Operation};
use crate::type_name;
use crate::type_name::TypeName;
use derivative::Derivative;
use std::fs;
use std::fs::{self, DirEntry};
use std::marker::PhantomData;
use std::path::PathBuf;
use types::{BeaconState, EthSpec, ForkName};
@@ -31,30 +31,27 @@ pub trait Handler {
}
fn run_for_fork(&self, fork_name: ForkName) {
let fork_name_str = match fork_name {
ForkName::Base => "phase0",
ForkName::Altair => "altair",
ForkName::Merge => "merge",
};
let fork_name_str = fork_name.to_string();
let handler_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("consensus-spec-tests")
.join("tests")
.join(Self::config_name())
.join(fork_name_str)
.join(&fork_name_str)
.join(Self::runner_name())
.join(self.handler_name());
// Iterate through test suites
let as_directory = |entry: Result<DirEntry, std::io::Error>| -> Option<DirEntry> {
entry
.ok()
.filter(|e| e.file_type().map(|ty| ty.is_dir()).unwrap_or(false))
};
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))
})
.filter_map(as_directory)
.flat_map(|suite| fs::read_dir(suite.path()).expect("suite dir exists"))
.flat_map(Result::ok)
.filter_map(as_directory)
.map(|test_case_dir| {
let path = test_case_dir.path();
let case = Self::Case::load_from_dir(&path, fork_name).expect("test should load");
@@ -439,37 +436,21 @@ impl<E: EthSpec + TypeName> Handler for FinalityHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct ForkChoiceGetHeadHandler<E>(PhantomData<E>);
pub struct ForkChoiceHandler<E> {
handler_name: String,
_phantom: PhantomData<E>,
}
impl<E: EthSpec + TypeName> Handler for ForkChoiceGetHeadHandler<E> {
type Case = cases::ForkChoiceTest<E>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"fork_choice"
}
fn handler_name(&self) -> String {
"get_head".into()
}
fn is_enabled_for_fork(&self, _fork_name: ForkName) -> bool {
// These tests check block validity (which may include signatures) and there is no need to
// run them with fake crypto.
cfg!(not(feature = "fake_crypto"))
impl<E: EthSpec> ForkChoiceHandler<E> {
pub fn new(handler_name: &str) -> Self {
Self {
handler_name: handler_name.into(),
_phantom: PhantomData,
}
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct ForkChoiceOnBlockHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for ForkChoiceOnBlockHandler<E> {
impl<E: EthSpec + TypeName> Handler for ForkChoiceHandler<E> {
type Case = cases::ForkChoiceTest<E>;
fn config_name() -> &'static str {
@@ -481,41 +462,20 @@ impl<E: EthSpec + TypeName> Handler for ForkChoiceOnBlockHandler<E> {
}
fn handler_name(&self) -> String {
"on_block".into()
}
fn is_enabled_for_fork(&self, _fork_name: ForkName) -> bool {
// These tests check block validity (which may include signatures) and there is no need to
// run them with fake crypto.
cfg!(not(feature = "fake_crypto"))
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
pub struct ForkChoiceOnMergeBlockHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for ForkChoiceOnMergeBlockHandler<E> {
type Case = cases::ForkChoiceTest<E>;
fn config_name() -> &'static str {
E::name()
}
fn runner_name() -> &'static str {
"fork_choice"
}
fn handler_name(&self) -> String {
"on_merge_block".into()
self.handler_name.clone()
}
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
// Merge block tests are only enabled for Bellatrix or later.
if self.handler_name == "on_merge_block"
&& (fork_name == ForkName::Base || fork_name == ForkName::Altair)
{
return false;
}
// These tests check block validity (which may include signatures) and there is no need to
// run them with fake crypto.
cfg!(not(feature = "fake_crypto"))
// These tests only exist for the merge.
&& fork_name == ForkName::Merge
}
}