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

@ -30,11 +30,11 @@ fn verify_execution_payload_chain<T: EthSpec>(chain: &[ExecutionPayload<T>]) {
#[should_panic]
fn merge_with_terminal_block_hash_override() {
let altair_fork_epoch = Epoch::new(0);
let merge_fork_epoch = Epoch::new(0);
let bellatrix_fork_epoch = Epoch::new(0);
let mut spec = E::default_spec();
spec.altair_fork_epoch = Some(altair_fork_epoch);
spec.merge_fork_epoch = Some(merge_fork_epoch);
spec.bellatrix_fork_epoch = Some(bellatrix_fork_epoch);
let genesis_pow_block_hash = generate_pow_block(
spec.terminal_total_difficulty,
@ -95,12 +95,12 @@ fn merge_with_terminal_block_hash_override() {
fn base_altair_merge_with_terminal_block_after_fork() {
let altair_fork_epoch = Epoch::new(4);
let altair_fork_slot = altair_fork_epoch.start_slot(E::slots_per_epoch());
let merge_fork_epoch = Epoch::new(8);
let merge_fork_slot = merge_fork_epoch.start_slot(E::slots_per_epoch());
let bellatrix_fork_epoch = Epoch::new(8);
let merge_fork_slot = bellatrix_fork_epoch.start_slot(E::slots_per_epoch());
let mut spec = E::default_spec();
spec.altair_fork_epoch = Some(altair_fork_epoch);
spec.merge_fork_epoch = Some(merge_fork_epoch);
spec.bellatrix_fork_epoch = Some(bellatrix_fork_epoch);
let mut execution_payloads = vec![];

View File

@ -29,7 +29,7 @@ pub fn fork_context() -> ForkContext {
// Set fork_epoch to `Some` to ensure that the `ForkContext` object
// includes altair in the list of forks
chain_spec.altair_fork_epoch = Some(types::Epoch::new(42));
chain_spec.merge_fork_epoch = Some(types::Epoch::new(84));
chain_spec.bellatrix_fork_epoch = Some(types::Epoch::new(84));
ForkContext::new::<E>(types::Slot::new(0), Hash256::zero(), &chain_spec)
}

View File

@ -469,7 +469,7 @@ pub fn get_config<E: EthSpec>(
}
client_config.chain.max_network_size =
lighthouse_network::gossip_max_size(spec.merge_fork_epoch.is_some());
lighthouse_network::gossip_max_size(spec.bellatrix_fork_epoch.is_some());
if cli_args.is_present("slasher") {
let slasher_dir = if let Some(slasher_dir) = cli_args.value_of("slasher-dir") {

View File

@ -33,8 +33,8 @@ GENESIS_DELAY: 604800
ALTAIR_FORK_VERSION: 0x01000000
ALTAIR_FORK_EPOCH: 74240
# Merge
MERGE_FORK_VERSION: 0x02000000
MERGE_FORK_EPOCH: 18446744073709551615
BELLATRIX_FORK_VERSION: 0x02000000
BELLATRIX_FORK_EPOCH: 18446744073709551615
# Sharding
SHARDING_FORK_VERSION: 0x03000000
SHARDING_FORK_EPOCH: 18446744073709551615

View File

@ -33,8 +33,8 @@ GENESIS_DELAY: 1919188
ALTAIR_FORK_VERSION: 0x01001020
ALTAIR_FORK_EPOCH: 36660
# Merge
MERGE_FORK_VERSION: 0x02001020
MERGE_FORK_EPOCH: 18446744073709551615
BELLATRIX_FORK_VERSION: 0x02001020
BELLATRIX_FORK_EPOCH: 18446744073709551615
# Sharding
SHARDING_FORK_VERSION: 0x03001020
SHARDING_FORK_EPOCH: 18446744073709551615

View File

@ -33,8 +33,8 @@ GENESIS_DELAY: 432000
ALTAIR_FORK_VERSION: 0x01002009
ALTAIR_FORK_EPOCH: 61650
# Merge
MERGE_FORK_VERSION: 0x02002009
MERGE_FORK_EPOCH: 18446744073709551615
BELLATRIX_FORK_VERSION: 0x02002009
BELLATRIX_FORK_EPOCH: 18446744073709551615
# Sharding
SHARDING_FORK_VERSION: 0x03002009
SHARDING_FORK_EPOCH: 18446744073709551615

View File

@ -2,7 +2,7 @@ use super::per_block_processing::{
errors::BlockProcessingError, process_operations::process_deposit,
};
use crate::common::DepositDataTree;
use crate::upgrade::{upgrade_to_altair, upgrade_to_merge};
use crate::upgrade::{upgrade_to_altair, upgrade_to_bellatrix};
use safe_arith::{ArithError, SafeArith};
use tree_hash::TreeHash;
use types::DEPOSIT_TREE_DEPTH;
@ -58,13 +58,13 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
// Similarly, perform an upgrade to the merge if configured from genesis.
if spec
.merge_fork_epoch
.bellatrix_fork_epoch
.map_or(false, |fork_epoch| fork_epoch == T::genesis_epoch())
{
upgrade_to_merge(&mut state, spec)?;
upgrade_to_bellatrix(&mut state, spec)?;
// Remove intermediate Altair fork from `state.fork`.
state.fork_mut().previous_version = spec.merge_fork_version;
state.fork_mut().previous_version = spec.bellatrix_fork_version;
// Override latest execution payload header.
// See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/beacon-chain.md#testing

View File

@ -1,4 +1,4 @@
use crate::upgrade::{upgrade_to_altair, upgrade_to_merge};
use crate::upgrade::{upgrade_to_altair, upgrade_to_bellatrix};
use crate::{per_epoch_processing::EpochProcessingSummary, *};
use safe_arith::{ArithError, SafeArith};
use types::*;
@ -52,8 +52,8 @@ pub fn per_slot_processing<T: EthSpec>(
upgrade_to_altair(state, spec)?;
}
// If the Merge fork epoch is reached, perform an irregular state upgrade.
if spec.merge_fork_epoch == Some(state.current_epoch()) {
upgrade_to_merge(state, spec)?;
if spec.bellatrix_fork_epoch == Some(state.current_epoch()) {
upgrade_to_bellatrix(state, spec)?;
}
}

View File

@ -2,4 +2,4 @@ pub mod altair;
pub mod merge;
pub use altair::upgrade_to_altair;
pub use merge::upgrade_to_merge;
pub use merge::upgrade_to_bellatrix;

View File

@ -5,7 +5,7 @@ use types::{
};
/// Transform a `Altair` state into an `Merge` state.
pub fn upgrade_to_merge<E: EthSpec>(
pub fn upgrade_to_bellatrix<E: EthSpec>(
pre_state: &mut BeaconState<E>,
spec: &ChainSpec,
) -> Result<(), Error> {
@ -24,7 +24,7 @@ pub fn upgrade_to_merge<E: EthSpec>(
slot: pre.slot,
fork: Fork {
previous_version: pre.fork.current_version,
current_version: spec.merge_fork_version,
current_version: spec.bellatrix_fork_version,
epoch,
},
// History

View File

@ -0,0 +1,21 @@
# Mainnet preset - Bellatrix
# Updated penalty values
# ---------------------------------------------------------------
# 2**24 (= 16,777,216)
INACTIVITY_PENALTY_QUOTIENT_BELLATRIX: 16777216
# 2**5 (= 32)
MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX: 32
# 3
PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX: 3
# Execution
# ---------------------------------------------------------------
# 2**30 (= 1,073,741,824)
MAX_BYTES_PER_TRANSACTION: 1073741824
# 2**20 (= 1,048,576)
MAX_TRANSACTIONS_PER_PAYLOAD: 1048576
# 2**8 (= 256)
BYTES_PER_LOGS_BLOOM: 256
# 2**5 (= 32)
MAX_EXTRA_DATA_BYTES: 32

View File

@ -0,0 +1,21 @@
# Minimal preset - Bellatrix
# Updated penalty values
# ---------------------------------------------------------------
# 2**24 (= 16,777,216)
INACTIVITY_PENALTY_QUOTIENT_BELLATRIX: 16777216
# 2**5 (= 32)
MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX: 32
# 3
PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX: 3
# Execution
# ---------------------------------------------------------------
# 2**30 (= 1,073,741,824)
MAX_BYTES_PER_TRANSACTION: 1073741824
# 2**20 (= 1,048,576)
MAX_TRANSACTIONS_PER_PAYLOAD: 1048576
# 2**8 (= 256)
BYTES_PER_LOGS_BLOOM: 256
# 2**5 (= 32)
MAX_EXTRA_DATA_BYTES: 32

View File

@ -69,7 +69,7 @@ impl<'a, T: EthSpec> SignedRoot for BeaconBlockRef<'a, T> {}
impl<T: EthSpec> BeaconBlock<T> {
/// Returns an empty block to be used during genesis.
pub fn empty(spec: &ChainSpec) -> Self {
if spec.merge_fork_epoch == Some(T::genesis_epoch()) {
if spec.bellatrix_fork_epoch == Some(T::genesis_epoch()) {
Self::Merge(BeaconBlockMerge::empty(spec))
} else if spec.altair_fork_epoch == Some(T::genesis_epoch()) {
Self::Altair(BeaconBlockAltair::empty(spec))

View File

@ -132,12 +132,12 @@ pub struct ChainSpec {
/*
* Merge hard fork params
*/
pub inactivity_penalty_quotient_merge: u64,
pub min_slashing_penalty_quotient_merge: u64,
pub proportional_slashing_multiplier_merge: u64,
pub merge_fork_version: [u8; 4],
pub inactivity_penalty_quotient_bellatrix: u64,
pub min_slashing_penalty_quotient_bellatrix: u64,
pub proportional_slashing_multiplier_bellatrix: u64,
pub bellatrix_fork_version: [u8; 4],
/// The Merge fork epoch is optional, with `None` representing "Merge never happens".
pub merge_fork_epoch: Option<Epoch>,
pub bellatrix_fork_epoch: Option<Epoch>,
pub terminal_total_difficulty: Uint256,
pub terminal_block_hash: Hash256,
pub terminal_block_hash_activation_epoch: Epoch,
@ -217,7 +217,7 @@ impl ChainSpec {
/// Returns the name of the fork which is active at `epoch`.
pub fn fork_name_at_epoch(&self, epoch: Epoch) -> ForkName {
match self.merge_fork_epoch {
match self.bellatrix_fork_epoch {
Some(fork_epoch) if epoch >= fork_epoch => ForkName::Merge,
_ => match self.altair_fork_epoch {
Some(fork_epoch) if epoch >= fork_epoch => ForkName::Altair,
@ -231,7 +231,7 @@ impl ChainSpec {
match fork_name {
ForkName::Base => self.genesis_fork_version,
ForkName::Altair => self.altair_fork_version,
ForkName::Merge => self.merge_fork_version,
ForkName::Merge => self.bellatrix_fork_version,
}
}
@ -240,7 +240,7 @@ impl ChainSpec {
match fork_name {
ForkName::Base => Some(Epoch::new(0)),
ForkName::Altair => self.altair_fork_epoch,
ForkName::Merge => self.merge_fork_epoch,
ForkName::Merge => self.bellatrix_fork_epoch,
}
}
@ -249,7 +249,7 @@ impl ChainSpec {
match state {
BeaconState::Base(_) => self.inactivity_penalty_quotient,
BeaconState::Altair(_) => self.inactivity_penalty_quotient_altair,
BeaconState::Merge(_) => self.inactivity_penalty_quotient_merge,
BeaconState::Merge(_) => self.inactivity_penalty_quotient_bellatrix,
}
}
@ -261,7 +261,7 @@ impl ChainSpec {
match state {
BeaconState::Base(_) => self.proportional_slashing_multiplier,
BeaconState::Altair(_) => self.proportional_slashing_multiplier_altair,
BeaconState::Merge(_) => self.proportional_slashing_multiplier_merge,
BeaconState::Merge(_) => self.proportional_slashing_multiplier_bellatrix,
}
}
@ -273,7 +273,7 @@ impl ChainSpec {
match state {
BeaconState::Base(_) => self.min_slashing_penalty_quotient,
BeaconState::Altair(_) => self.min_slashing_penalty_quotient_altair,
BeaconState::Merge(_) => self.min_slashing_penalty_quotient_merge,
BeaconState::Merge(_) => self.min_slashing_penalty_quotient_bellatrix,
}
}
@ -526,13 +526,13 @@ impl ChainSpec {
/*
* Merge hard fork params
*/
inactivity_penalty_quotient_merge: u64::checked_pow(2, 24)
inactivity_penalty_quotient_bellatrix: u64::checked_pow(2, 24)
.expect("pow does not overflow"),
min_slashing_penalty_quotient_merge: u64::checked_pow(2, 5)
min_slashing_penalty_quotient_bellatrix: u64::checked_pow(2, 5)
.expect("pow does not overflow"),
proportional_slashing_multiplier_merge: 3,
merge_fork_version: [0x02, 0x00, 0x00, 0x00],
merge_fork_epoch: None,
proportional_slashing_multiplier_bellatrix: 3,
bellatrix_fork_version: [0x02, 0x00, 0x00, 0x00],
bellatrix_fork_epoch: None,
terminal_total_difficulty: Uint256::MAX
.checked_sub(Uint256::from(2u64.pow(10)))
.expect("subtraction does not overflow")
@ -583,8 +583,8 @@ impl ChainSpec {
altair_fork_version: [0x01, 0x00, 0x00, 0x01],
altair_fork_epoch: None,
// Merge
merge_fork_version: [0x02, 0x00, 0x00, 0x01],
merge_fork_epoch: None,
bellatrix_fork_version: [0x02, 0x00, 0x00, 0x01],
bellatrix_fork_epoch: None,
// Other
network_id: 2, // lighthouse testnet network id
deposit_chain_id: 5,
@ -632,10 +632,10 @@ pub struct Config {
pub altair_fork_epoch: Option<MaybeQuoted<Epoch>>,
#[serde(with = "eth2_serde_utils::bytes_4_hex")]
merge_fork_version: [u8; 4],
bellatrix_fork_version: [u8; 4],
#[serde(serialize_with = "serialize_fork_epoch")]
#[serde(deserialize_with = "deserialize_fork_epoch")]
pub merge_fork_epoch: Option<MaybeQuoted<Epoch>>,
pub bellatrix_fork_epoch: Option<MaybeQuoted<Epoch>>,
#[serde(with = "eth2_serde_utils::quoted_u64")]
seconds_per_slot: u64,
@ -734,9 +734,9 @@ impl Config {
altair_fork_epoch: spec
.altair_fork_epoch
.map(|epoch| MaybeQuoted { value: epoch }),
merge_fork_version: spec.merge_fork_version,
merge_fork_epoch: spec
.merge_fork_epoch
bellatrix_fork_version: spec.bellatrix_fork_version,
bellatrix_fork_epoch: spec
.bellatrix_fork_epoch
.map(|epoch| MaybeQuoted { value: epoch }),
seconds_per_slot: spec.seconds_per_slot,
@ -779,8 +779,8 @@ impl Config {
genesis_delay,
altair_fork_version,
altair_fork_epoch,
merge_fork_epoch,
merge_fork_version,
bellatrix_fork_epoch,
bellatrix_fork_version,
seconds_per_slot,
seconds_per_eth1_block,
min_validator_withdrawability_delay,
@ -808,8 +808,8 @@ impl Config {
genesis_delay,
altair_fork_version,
altair_fork_epoch: altair_fork_epoch.map(|q| q.value),
merge_fork_epoch: merge_fork_epoch.map(|q| q.value),
merge_fork_version,
bellatrix_fork_epoch: bellatrix_fork_epoch.map(|q| q.value),
bellatrix_fork_version,
seconds_per_slot,
seconds_per_eth1_block,
min_validator_withdrawability_delay,

View File

@ -1,4 +1,4 @@
use crate::{AltairPreset, BasePreset, ChainSpec, Config, EthSpec};
use crate::{AltairPreset, BasePreset, BellatrixPreset, ChainSpec, Config, EthSpec};
use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap;
@ -14,6 +14,8 @@ pub struct ConfigAndPreset {
pub base_preset: BasePreset,
#[serde(flatten)]
pub altair_preset: AltairPreset,
#[serde(flatten)]
pub bellatrix_preset: BellatrixPreset,
/// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks.
#[serde(flatten)]
@ -25,12 +27,14 @@ impl ConfigAndPreset {
let config = Config::from_chain_spec::<T>(spec);
let base_preset = BasePreset::from_chain_spec::<T>(spec);
let altair_preset = AltairPreset::from_chain_spec::<T>(spec);
let bellatrix_preset = BellatrixPreset::from_chain_spec::<T>(spec);
let extra_fields = HashMap::new();
Self {
config,
base_preset,
altair_preset,
bellatrix_preset,
extra_fields,
}
}

View File

@ -36,11 +36,14 @@ impl ForkContext {
}
// Only add Merge to list of forks if it's enabled
// Note: `merge_fork_epoch == None` implies merge hasn't been activated yet on the config.
if spec.merge_fork_epoch.is_some() {
// Note: `bellatrix_fork_epoch == None` implies merge hasn't been activated yet on the config.
if spec.bellatrix_fork_epoch.is_some() {
fork_to_digest.push((
ForkName::Merge,
ChainSpec::compute_fork_digest(spec.merge_fork_version, genesis_validators_root),
ChainSpec::compute_fork_digest(
spec.bellatrix_fork_version,
genesis_validators_root,
),
));
}

View File

@ -25,17 +25,17 @@ impl ForkName {
match self {
ForkName::Base => {
spec.altair_fork_epoch = None;
spec.merge_fork_epoch = None;
spec.bellatrix_fork_epoch = None;
spec
}
ForkName::Altair => {
spec.altair_fork_epoch = Some(Epoch::new(0));
spec.merge_fork_epoch = None;
spec.bellatrix_fork_epoch = None;
spec
}
ForkName::Merge => {
spec.altair_fork_epoch = Some(Epoch::new(0));
spec.merge_fork_epoch = Some(Epoch::new(0));
spec.bellatrix_fork_epoch = Some(Epoch::new(0));
spec
}
}
@ -112,7 +112,7 @@ impl FromStr for ForkName {
Ok(match fork_name.to_lowercase().as_ref() {
"phase0" | "base" => ForkName::Base,
"altair" => ForkName::Altair,
"merge" => ForkName::Merge,
"bellatrix" | "merge" => ForkName::Merge,
_ => return Err(()),
})
}
@ -123,7 +123,7 @@ impl Display for ForkName {
match self {
ForkName::Base => "phase0".fmt(f),
ForkName::Altair => "altair".fmt(f),
ForkName::Merge => "merge".fmt(f),
ForkName::Merge => "bellatrix".fmt(f),
}
}
}
@ -181,4 +181,11 @@ mod test {
assert_eq!(ForkName::from_str("NO_NAME"), Err(()));
assert_eq!(ForkName::from_str("no_name"), Err(()));
}
#[test]
fn fork_name_bellatrix_or_merge() {
assert_eq!(ForkName::from_str("bellatrix"), Ok(ForkName::Merge));
assert_eq!(ForkName::from_str("merge"), Ok(ForkName::Merge));
assert_eq!(ForkName::Merge.to_string(), "bellatrix");
}
}

View File

@ -125,7 +125,7 @@ pub use crate::indexed_attestation::IndexedAttestation;
pub use crate::participation_flags::ParticipationFlags;
pub use crate::participation_list::ParticipationList;
pub use crate::pending_attestation::PendingAttestation;
pub use crate::preset::{AltairPreset, BasePreset};
pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset};
pub use crate::proposer_slashing::ProposerSlashing;
pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch};
pub use crate::selection_proof::SelectionProof;

View File

@ -150,6 +150,40 @@ impl AltairPreset {
}
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub struct BellatrixPreset {
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub inactivity_penalty_quotient_bellatrix: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub min_slashing_penalty_quotient_bellatrix: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub proportional_slashing_multiplier_bellatrix: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub max_bytes_per_transaction: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub max_transactions_per_payload: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub bytes_per_logs_bloom: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub max_extra_data_bytes: u64,
}
impl BellatrixPreset {
pub fn from_chain_spec<T: EthSpec>(spec: &ChainSpec) -> Self {
Self {
inactivity_penalty_quotient_bellatrix: spec.inactivity_penalty_quotient_bellatrix,
min_slashing_penalty_quotient_bellatrix: spec.min_slashing_penalty_quotient_bellatrix,
proportional_slashing_multiplier_bellatrix: spec
.proportional_slashing_multiplier_bellatrix,
max_bytes_per_transaction: T::max_bytes_per_transaction() as u64,
max_transactions_per_payload: T::max_transactions_per_payload() as u64,
bytes_per_logs_bloom: T::bytes_per_logs_bloom() as u64,
max_extra_data_bytes: T::max_extra_data_bytes() as u64,
}
}
}
#[cfg(test)]
mod test {
use super::*;
@ -182,6 +216,9 @@ mod test {
let altair: AltairPreset = preset_from_file(&preset_name, "altair.yaml");
assert_eq!(altair, AltairPreset::from_chain_spec::<E>(&spec));
let bellatrix: BellatrixPreset = preset_from_file(&preset_name, "bellatrix.yaml");
assert_eq!(bellatrix, BellatrixPreset::from_chain_spec::<E>(&spec));
}
#[test]

View File

@ -63,7 +63,7 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
}
if let Some(fork_epoch) = parse_optional(matches, "merge-fork-epoch")? {
spec.merge_fork_epoch = Some(fork_epoch);
spec.bellatrix_fork_epoch = Some(fork_epoch);
}
let genesis_state_bytes = if matches.is_present("interop-genesis-state") {

View File

@ -33,8 +33,8 @@ GENESIS_DELAY: 604800
ALTAIR_FORK_VERSION: 0x01000000
ALTAIR_FORK_EPOCH: 18446744073709551615
# Merge
MERGE_FORK_VERSION: 0x02000000
MERGE_FORK_EPOCH: 18446744073709551615
BELLATRIX_FORK_VERSION: 0x02000000
BELLATRIX_FORK_EPOCH: 18446744073709551615
# Sharding
SHARDING_FORK_VERSION: 0x03000000
SHARDING_FORK_EPOCH: 18446744073709551615

View File

@ -1,4 +1,4 @@
TESTS_TAG := v1.1.6
TESTS_TAG := v1.1.8
TESTS = general minimal mainnet
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))

View File

@ -30,18 +30,11 @@ excluded_paths = [
# LightClientUpdate
"tests/.*/.*/ssz_static/LightClientUpdate",
# LightClientSnapshot
"tests/minimal/altair/ssz_static/LightClientSnapshot",
"tests/mainnet/altair/ssz_static/LightClientSnapshot",
"tests/minimal/merge/ssz_static/LightClientSnapshot",
"tests/mainnet/merge/ssz_static/LightClientSnapshot",
"tests/.*/.*/ssz_static/LightClientSnapshot",
# Merkle-proof tests for light clients
"tests/mainnet/altair/merkle/single_proof",
"tests/minimal/altair/merkle/single_proof",
"tests/mainnet/merge/merkle/single_proof",
"tests/minimal/merge/merkle/single_proof",
# FIXME(merge): Merge transition tests are now available but not yet passing
"tests/mainnet/merge/transition/",
"tests/minimal/merge/transition/",
"tests/.*/.*/merkle/single_proof",
# One of the EF researchers likes to pack the tarballs on a Mac
".*\.DS_Store.*"
]
def normalize_path(path):

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
}
}

View File

@ -413,20 +413,26 @@ fn finality() {
#[test]
fn fork_choice_get_head() {
ForkChoiceGetHeadHandler::<MinimalEthSpec>::default().run();
ForkChoiceGetHeadHandler::<MainnetEthSpec>::default().run();
ForkChoiceHandler::<MinimalEthSpec>::new("get_head").run();
ForkChoiceHandler::<MainnetEthSpec>::new("get_head").run();
}
#[test]
fn fork_choice_on_block() {
ForkChoiceOnBlockHandler::<MinimalEthSpec>::default().run();
ForkChoiceOnBlockHandler::<MainnetEthSpec>::default().run();
ForkChoiceHandler::<MinimalEthSpec>::new("on_block").run();
ForkChoiceHandler::<MainnetEthSpec>::new("on_block").run();
}
#[test]
fn fork_choice_on_merge_block() {
ForkChoiceOnMergeBlockHandler::<MinimalEthSpec>::default().run();
ForkChoiceOnMergeBlockHandler::<MainnetEthSpec>::default().run();
ForkChoiceHandler::<MinimalEthSpec>::new("on_merge_block").run();
ForkChoiceHandler::<MainnetEthSpec>::new("on_merge_block").run();
}
#[test]
fn fork_choice_ex_ante() {
ForkChoiceHandler::<MinimalEthSpec>::new("ex_ante").run();
ForkChoiceHandler::<MainnetEthSpec>::new("ex_ante").run();
}
#[test]