mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-19 22:08:30 +00:00
Merge remote-tracking branch 'origin/unstable' into tree-states
This commit is contained in:
@@ -2,20 +2,15 @@ use self::BlsSetting::*;
|
||||
use crate::error::Error;
|
||||
use serde_repr::Deserialize_repr;
|
||||
|
||||
#[derive(Deserialize_repr, Debug, Clone, Copy)]
|
||||
#[derive(Deserialize_repr, Debug, Clone, Copy, Default)]
|
||||
#[repr(u8)]
|
||||
pub enum BlsSetting {
|
||||
#[default]
|
||||
Flexible = 0,
|
||||
Required = 1,
|
||||
Ignored = 2,
|
||||
}
|
||||
|
||||
impl Default for BlsSetting {
|
||||
fn default() -> Self {
|
||||
Flexible
|
||||
}
|
||||
}
|
||||
|
||||
impl BlsSetting {
|
||||
/// Check the BLS setting and skip the test if it isn't compatible with the crypto config.
|
||||
pub fn check(self) -> Result<(), Error> {
|
||||
|
||||
@@ -81,11 +81,23 @@ pub struct Cases<T> {
|
||||
}
|
||||
|
||||
impl<T: Case> Cases<T> {
|
||||
pub fn test_results(&self, fork_name: ForkName) -> Vec<CaseResult> {
|
||||
self.test_cases
|
||||
.into_par_iter()
|
||||
.enumerate()
|
||||
.map(|(i, (ref path, ref tc))| CaseResult::new(i, path, tc, tc.result(i, fork_name)))
|
||||
.collect()
|
||||
pub fn test_results(&self, fork_name: ForkName, use_rayon: bool) -> Vec<CaseResult> {
|
||||
if use_rayon {
|
||||
self.test_cases
|
||||
.into_par_iter()
|
||||
.enumerate()
|
||||
.map(|(i, (ref path, ref tc))| {
|
||||
CaseResult::new(i, path, tc, tc.result(i, fork_name))
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
self.test_cases
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (ref path, ref tc))| {
|
||||
CaseResult::new(i, path, tc, tc.result(i, fork_name))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,17 +88,23 @@ impl<E: EthSpec> EpochTransition<E> for JustificationAndFinalization {
|
||||
BeaconState::Base(_) => {
|
||||
let mut validator_statuses = base::ValidatorStatuses::new(state, spec)?;
|
||||
validator_statuses.process_attestations(state)?;
|
||||
base::process_justification_and_finalization(
|
||||
state,
|
||||
&validator_statuses.total_balances,
|
||||
spec,
|
||||
)
|
||||
let justification_and_finalization_state =
|
||||
base::process_justification_and_finalization(
|
||||
state,
|
||||
&validator_statuses.total_balances,
|
||||
spec,
|
||||
)?;
|
||||
justification_and_finalization_state.apply_changes_to_state(state);
|
||||
Ok(())
|
||||
}
|
||||
BeaconState::Altair(_) | BeaconState::Merge(_) => {
|
||||
altair::process_justification_and_finalization(
|
||||
state,
|
||||
&altair::ParticipationCache::new(state, spec).unwrap(),
|
||||
)
|
||||
let justification_and_finalization_state =
|
||||
altair::process_justification_and_finalization(
|
||||
state,
|
||||
&altair::ParticipationCache::new(state, spec).unwrap(),
|
||||
)?;
|
||||
justification_and_finalization_state.apply_changes_to_state(state);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,7 +277,8 @@ impl<E: EthSpec, T: EpochTransition<E>> Case for EpochProcessing<E, T> {
|
||||
&& T::name() != "inactivity_updates"
|
||||
&& T::name() != "participation_flag_updates"
|
||||
}
|
||||
ForkName::Altair | ForkName::Merge => true,
|
||||
// No phase0 tests for Altair and later.
|
||||
ForkName::Altair | ForkName::Merge => T::name() != "participation_record_updates",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,15 +7,17 @@ use beacon_chain::{
|
||||
obtain_indexed_attestation_and_committees_per_slot, VerifiedAttestation,
|
||||
},
|
||||
test_utils::{BeaconChainHarness, EphemeralHarnessType},
|
||||
BeaconChainTypes, HeadInfo,
|
||||
BeaconChainTypes, CachedHead, CountUnrealized,
|
||||
};
|
||||
use serde_derive::Deserialize;
|
||||
use ssz_derive::Decode;
|
||||
use state_processing::state_advance::complete_state_advance;
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use types::{
|
||||
Attestation, BeaconBlock, BeaconState, Checkpoint, Epoch, EthSpec, ExecutionBlockHash,
|
||||
ForkName, Hash256, IndexedAttestation, SignedBeaconBlock, Slot, Uint256,
|
||||
Attestation, AttesterSlashing, BeaconBlock, BeaconState, Checkpoint, EthSpec,
|
||||
ExecutionBlockHash, ForkName, Hash256, IndexedAttestation, SignedBeaconBlock, Slot, Uint256,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, PartialEq, Clone, Deserialize, Decode)]
|
||||
@@ -43,16 +45,19 @@ pub struct Checks {
|
||||
justified_checkpoint_root: Option<Hash256>,
|
||||
finalized_checkpoint: Option<Checkpoint>,
|
||||
best_justified_checkpoint: Option<Checkpoint>,
|
||||
u_justified_checkpoint: Option<Checkpoint>,
|
||||
u_finalized_checkpoint: Option<Checkpoint>,
|
||||
proposer_boost_root: Option<Hash256>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(untagged, deny_unknown_fields)]
|
||||
pub enum Step<B, A, P> {
|
||||
pub enum Step<B, A, AS, P> {
|
||||
Tick { tick: u64 },
|
||||
ValidBlock { block: B },
|
||||
MaybeValidBlock { block: B, valid: bool },
|
||||
Attestation { attestation: A },
|
||||
AttesterSlashing { attester_slashing: AS },
|
||||
PowBlock { pow_block: P },
|
||||
Checks { checks: Box<Checks> },
|
||||
}
|
||||
@@ -69,16 +74,8 @@ pub struct ForkChoiceTest<E: EthSpec> {
|
||||
pub description: String,
|
||||
pub anchor_state: BeaconState<E>,
|
||||
pub anchor_block: BeaconBlock<E>,
|
||||
pub steps: Vec<Step<SignedBeaconBlock<E>, Attestation<E>, PowBlock>>,
|
||||
}
|
||||
|
||||
/// Spec for fork choice tests, with proposer boosting enabled.
|
||||
///
|
||||
/// This function can be deleted once `ChainSpec::mainnet` enables proposer boosting by default.
|
||||
pub fn fork_choice_spec<E: EthSpec>(fork_name: ForkName) -> ChainSpec {
|
||||
let mut spec = testing_spec::<E>(fork_name);
|
||||
spec.proposer_score_boost = Some(70);
|
||||
spec
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub steps: Vec<Step<SignedBeaconBlock<E>, Attestation<E>, AttesterSlashing<E>, PowBlock>>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
|
||||
@@ -90,8 +87,9 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
|
||||
.to_str()
|
||||
.expect("path must be valid OsStr")
|
||||
.to_string();
|
||||
let spec = &fork_choice_spec::<E>(fork_name);
|
||||
let steps: Vec<Step<String, String, String>> = yaml_decode_file(&path.join("steps.yaml"))?;
|
||||
let spec = &testing_spec::<E>(fork_name);
|
||||
let steps: Vec<Step<String, String, String, String>> =
|
||||
yaml_decode_file(&path.join("steps.yaml"))?;
|
||||
// Resolve the object names in `steps.yaml` into actual decoded block/attestation objects.
|
||||
let steps = steps
|
||||
.into_iter()
|
||||
@@ -113,6 +111,10 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", attestation)))
|
||||
.map(|attestation| Step::Attestation { attestation })
|
||||
}
|
||||
Step::AttesterSlashing { attester_slashing } => {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", attester_slashing)))
|
||||
.map(|attester_slashing| Step::AttesterSlashing { attester_slashing })
|
||||
}
|
||||
Step::PowBlock { pow_block } => {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", pow_block)))
|
||||
.map(|pow_block| Step::PowBlock { pow_block })
|
||||
@@ -152,14 +154,7 @@ 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): 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);
|
||||
};
|
||||
let tester = Tester::new(self, testing_spec::<E>(fork_name))?;
|
||||
|
||||
for step in &self.steps {
|
||||
match step {
|
||||
@@ -169,6 +164,9 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
|
||||
tester.process_block(block.clone(), *valid)?
|
||||
}
|
||||
Step::Attestation { attestation } => tester.process_attestation(attestation)?,
|
||||
Step::AttesterSlashing { attester_slashing } => {
|
||||
tester.process_attester_slashing(attester_slashing)
|
||||
}
|
||||
Step::PowBlock { pow_block } => tester.process_pow_block(pow_block),
|
||||
Step::Checks { checks } => {
|
||||
let Checks {
|
||||
@@ -179,6 +177,8 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
|
||||
justified_checkpoint_root,
|
||||
finalized_checkpoint,
|
||||
best_justified_checkpoint,
|
||||
u_justified_checkpoint,
|
||||
u_finalized_checkpoint,
|
||||
proposer_boost_root,
|
||||
} = checks.as_ref();
|
||||
|
||||
@@ -212,6 +212,14 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
|
||||
.check_best_justified_checkpoint(*expected_best_justified_checkpoint)?;
|
||||
}
|
||||
|
||||
if let Some(expected_u_justified_checkpoint) = u_justified_checkpoint {
|
||||
tester.check_u_justified_checkpoint(*expected_u_justified_checkpoint)?;
|
||||
}
|
||||
|
||||
if let Some(expected_u_finalized_checkpoint) = u_finalized_checkpoint {
|
||||
tester.check_u_finalized_checkpoint(*expected_u_finalized_checkpoint)?;
|
||||
}
|
||||
|
||||
if let Some(expected_proposer_boost_root) = proposer_boost_root {
|
||||
tester.check_expected_proposer_boost_root(*expected_proposer_boost_root)?;
|
||||
}
|
||||
@@ -287,19 +295,19 @@ impl<E: EthSpec> Tester<E> {
|
||||
Ok(self.spec.genesis_slot + slots_since_genesis)
|
||||
}
|
||||
|
||||
fn find_head(&self) -> Result<HeadInfo, Error> {
|
||||
fn block_on_dangerous<F: Future>(&self, future: F) -> Result<F::Output, Error> {
|
||||
self.harness
|
||||
.chain
|
||||
.fork_choice()
|
||||
.map_err(|e| Error::InternalError(format!("failed to find head with {:?}", e)))?;
|
||||
self.harness
|
||||
.chain
|
||||
.head_info()
|
||||
.map_err(|e| Error::InternalError(format!("failed to read head with {:?}", e)))
|
||||
.task_executor
|
||||
.clone()
|
||||
.block_on_dangerous(future, "ef_tests_block_on")
|
||||
.ok_or_else(|| Error::InternalError("runtime shutdown".into()))
|
||||
}
|
||||
|
||||
fn genesis_epoch(&self) -> Epoch {
|
||||
self.spec.genesis_slot.epoch(E::slots_per_epoch())
|
||||
fn find_head(&self) -> Result<CachedHead<E>, Error> {
|
||||
let chain = self.harness.chain.clone();
|
||||
self.block_on_dangerous(chain.recompute_head_at_current_slot())?;
|
||||
Ok(self.harness.chain.canonical_head.cached_head())
|
||||
}
|
||||
|
||||
pub fn set_tick(&self, tick: u64) {
|
||||
@@ -314,15 +322,20 @@ impl<E: EthSpec> Tester<E> {
|
||||
|
||||
self.harness
|
||||
.chain
|
||||
.fork_choice
|
||||
.write()
|
||||
.update_time(slot)
|
||||
.canonical_head
|
||||
.fork_choice_write_lock()
|
||||
.update_time(slot, &self.spec)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn process_block(&self, block: SignedBeaconBlock<E>, valid: bool) -> Result<(), Error> {
|
||||
let result = self.harness.chain.process_block(block.clone());
|
||||
let block_root = block.canonical_root();
|
||||
let block = Arc::new(block);
|
||||
let result = self.block_on_dangerous(
|
||||
self.harness
|
||||
.chain
|
||||
.process_block(block.clone(), CountUnrealized::False),
|
||||
)?;
|
||||
if result.is_ok() != valid {
|
||||
return Err(Error::DidntFail(format!(
|
||||
"block with root {} was valid={} whilst test expects valid={}. result: {:?}",
|
||||
@@ -367,16 +380,21 @@ impl<E: EthSpec> Tester<E> {
|
||||
.seconds_from_current_slot_start(self.spec.seconds_per_slot)
|
||||
.unwrap();
|
||||
|
||||
let (block, _) = block.deconstruct();
|
||||
let result = self.harness.chain.fork_choice.write().on_block(
|
||||
self.harness.chain.slot().unwrap(),
|
||||
&block,
|
||||
block_root,
|
||||
block_delay,
|
||||
&state,
|
||||
PayloadVerificationStatus::Irrelevant,
|
||||
&self.harness.chain.spec,
|
||||
);
|
||||
let result = self
|
||||
.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_write_lock()
|
||||
.on_block(
|
||||
self.harness.chain.slot().unwrap(),
|
||||
block.message(),
|
||||
block_root,
|
||||
block_delay,
|
||||
&state,
|
||||
PayloadVerificationStatus::Irrelevant,
|
||||
&self.harness.chain.spec,
|
||||
self.harness.chain.config.count_unrealized.into(),
|
||||
);
|
||||
|
||||
if result.is_ok() {
|
||||
return Err(Error::DidntFail(format!(
|
||||
@@ -408,6 +426,14 @@ impl<E: EthSpec> Tester<E> {
|
||||
.map_err(|e| Error::InternalError(format!("attestation import failed with {:?}", e)))
|
||||
}
|
||||
|
||||
pub fn process_attester_slashing(&self, attester_slashing: &AttesterSlashing<E>) {
|
||||
self.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_write_lock()
|
||||
.on_attester_slashing(attester_slashing)
|
||||
}
|
||||
|
||||
pub fn process_pow_block(&self, pow_block: &PowBlock) {
|
||||
let el = self.harness.mock_execution_layer.as_ref().unwrap();
|
||||
|
||||
@@ -424,10 +450,11 @@ impl<E: EthSpec> Tester<E> {
|
||||
}
|
||||
|
||||
pub fn check_head(&self, expected_head: Head) -> Result<(), Error> {
|
||||
let chain_head = self.find_head().map(|head| Head {
|
||||
slot: head.slot,
|
||||
root: head.block_root,
|
||||
})?;
|
||||
let head = self.find_head()?;
|
||||
let chain_head = Head {
|
||||
slot: head.head_slot(),
|
||||
root: head.head_block_root(),
|
||||
};
|
||||
|
||||
check_equal("head", chain_head, expected_head)
|
||||
}
|
||||
@@ -446,15 +473,15 @@ impl<E: EthSpec> Tester<E> {
|
||||
}
|
||||
|
||||
pub fn check_justified_checkpoint(&self, expected_checkpoint: Checkpoint) -> Result<(), Error> {
|
||||
let head_checkpoint = self.find_head()?.current_justified_checkpoint;
|
||||
let fc_checkpoint = self.harness.chain.fork_choice.read().justified_checkpoint();
|
||||
let head_checkpoint = self.find_head()?.justified_checkpoint();
|
||||
let fc_checkpoint = self
|
||||
.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.justified_checkpoint();
|
||||
|
||||
assert_checkpoints_eq(
|
||||
"justified_checkpoint",
|
||||
self.genesis_epoch(),
|
||||
head_checkpoint,
|
||||
fc_checkpoint,
|
||||
);
|
||||
assert_checkpoints_eq("justified_checkpoint", head_checkpoint, fc_checkpoint);
|
||||
|
||||
check_equal("justified_checkpoint", fc_checkpoint, expected_checkpoint)
|
||||
}
|
||||
@@ -463,15 +490,15 @@ impl<E: EthSpec> Tester<E> {
|
||||
&self,
|
||||
expected_checkpoint_root: Hash256,
|
||||
) -> Result<(), Error> {
|
||||
let head_checkpoint = self.find_head()?.current_justified_checkpoint;
|
||||
let fc_checkpoint = self.harness.chain.fork_choice.read().justified_checkpoint();
|
||||
let head_checkpoint = self.find_head()?.justified_checkpoint();
|
||||
let fc_checkpoint = self
|
||||
.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.justified_checkpoint();
|
||||
|
||||
assert_checkpoints_eq(
|
||||
"justified_checkpoint_root",
|
||||
self.genesis_epoch(),
|
||||
head_checkpoint,
|
||||
fc_checkpoint,
|
||||
);
|
||||
assert_checkpoints_eq("justified_checkpoint_root", head_checkpoint, fc_checkpoint);
|
||||
|
||||
check_equal(
|
||||
"justified_checkpoint_root",
|
||||
@@ -481,15 +508,15 @@ impl<E: EthSpec> Tester<E> {
|
||||
}
|
||||
|
||||
pub fn check_finalized_checkpoint(&self, expected_checkpoint: Checkpoint) -> Result<(), Error> {
|
||||
let head_checkpoint = self.find_head()?.finalized_checkpoint;
|
||||
let fc_checkpoint = self.harness.chain.fork_choice.read().finalized_checkpoint();
|
||||
let head_checkpoint = self.find_head()?.finalized_checkpoint();
|
||||
let fc_checkpoint = self
|
||||
.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.finalized_checkpoint();
|
||||
|
||||
assert_checkpoints_eq(
|
||||
"finalized_checkpoint",
|
||||
self.genesis_epoch(),
|
||||
head_checkpoint,
|
||||
fc_checkpoint,
|
||||
);
|
||||
assert_checkpoints_eq("finalized_checkpoint", head_checkpoint, fc_checkpoint);
|
||||
|
||||
check_equal("finalized_checkpoint", fc_checkpoint, expected_checkpoint)
|
||||
}
|
||||
@@ -501,8 +528,8 @@ impl<E: EthSpec> Tester<E> {
|
||||
let best_justified_checkpoint = self
|
||||
.harness
|
||||
.chain
|
||||
.fork_choice
|
||||
.read()
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.best_justified_checkpoint();
|
||||
check_equal(
|
||||
"best_justified_checkpoint",
|
||||
@@ -511,11 +538,50 @@ impl<E: EthSpec> Tester<E> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn check_u_justified_checkpoint(
|
||||
&self,
|
||||
expected_checkpoint: Checkpoint,
|
||||
) -> Result<(), Error> {
|
||||
let u_justified_checkpoint = self
|
||||
.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.unrealized_justified_checkpoint();
|
||||
check_equal(
|
||||
"u_justified_checkpoint",
|
||||
u_justified_checkpoint,
|
||||
expected_checkpoint,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn check_u_finalized_checkpoint(
|
||||
&self,
|
||||
expected_checkpoint: Checkpoint,
|
||||
) -> Result<(), Error> {
|
||||
let u_finalized_checkpoint = self
|
||||
.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.unrealized_finalized_checkpoint();
|
||||
check_equal(
|
||||
"u_finalized_checkpoint",
|
||||
u_finalized_checkpoint,
|
||||
expected_checkpoint,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn check_expected_proposer_boost_root(
|
||||
&self,
|
||||
expected_proposer_boost_root: Hash256,
|
||||
) -> Result<(), Error> {
|
||||
let proposer_boost_root = self.harness.chain.fork_choice.read().proposer_boost_root();
|
||||
let proposer_boost_root = self
|
||||
.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.proposer_boost_root();
|
||||
check_equal(
|
||||
"proposer_boost_root",
|
||||
proposer_boost_root,
|
||||
@@ -530,20 +596,8 @@ impl<E: EthSpec> Tester<E> {
|
||||
/// This function is necessary due to a quirk documented in this issue:
|
||||
///
|
||||
/// https://github.com/ethereum/consensus-specs/issues/2566
|
||||
fn assert_checkpoints_eq(name: &str, genesis_epoch: Epoch, head: Checkpoint, fc: Checkpoint) {
|
||||
if fc.epoch == genesis_epoch {
|
||||
assert_eq!(
|
||||
head,
|
||||
Checkpoint {
|
||||
epoch: genesis_epoch,
|
||||
root: Hash256::zero()
|
||||
},
|
||||
"{} (genesis)",
|
||||
name
|
||||
)
|
||||
} else {
|
||||
assert_eq!(head, fc, "{} (non-genesis)", name)
|
||||
}
|
||||
fn assert_checkpoints_eq(name: &str, head: Checkpoint, fc: Checkpoint) {
|
||||
assert_eq!(head, fc, "{}", name)
|
||||
}
|
||||
|
||||
/// Convenience function to create `Error` messages.
|
||||
|
||||
@@ -20,8 +20,9 @@ use state_processing::{
|
||||
use std::fmt::Debug;
|
||||
use std::path::Path;
|
||||
use types::{
|
||||
Attestation, AttesterSlashing, BeaconBlock, BeaconState, ChainSpec, Deposit, EthSpec, ForkName,
|
||||
FullPayload, ProposerSlashing, SignedVoluntaryExit, SyncAggregate,
|
||||
Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit,
|
||||
EthSpec, ExecutionPayload, ForkName, FullPayload, ProposerSlashing, SignedVoluntaryExit,
|
||||
SyncAggregate,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Default, Deserialize)]
|
||||
@@ -260,6 +261,40 @@ impl<E: EthSpec> Operation<E> for FullPayload<E> {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<E: EthSpec> Operation<E> for BlindedPayload<E> {
|
||||
fn handler_name() -> String {
|
||||
"execution_payload".into()
|
||||
}
|
||||
|
||||
fn filename() -> String {
|
||||
"execution_payload.ssz_snappy".into()
|
||||
}
|
||||
|
||||
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||
fork_name != ForkName::Base && fork_name != ForkName::Altair
|
||||
}
|
||||
|
||||
fn decode(path: &Path, _spec: &ChainSpec) -> Result<Self, Error> {
|
||||
ssz_decode_file::<ExecutionPayload<E>>(path).map(Into::into)
|
||||
}
|
||||
|
||||
fn apply_to(
|
||||
&self,
|
||||
state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
extra: &Operations<E, Self>,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
let valid = extra
|
||||
.execution_metadata
|
||||
.as_ref()
|
||||
.map_or(false, |e| e.execution_valid);
|
||||
if valid {
|
||||
process_execution_payload(state, self, spec)
|
||||
} else {
|
||||
Err(BlockProcessingError::ExecutionInvalid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec, O: Operation<E>> LoadCase for Operations<E, O> {
|
||||
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
|
||||
|
||||
@@ -30,6 +30,10 @@ pub trait Handler {
|
||||
}
|
||||
}
|
||||
|
||||
fn use_rayon() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run_for_fork(&self, fork_name: ForkName) {
|
||||
let fork_name_str = fork_name.to_string();
|
||||
|
||||
@@ -48,7 +52,7 @@ pub trait Handler {
|
||||
.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")
|
||||
.unwrap_or_else(|e| panic!("handler dir {} exists: {:?}", handler_path.display(), e))
|
||||
.filter_map(as_directory)
|
||||
.flat_map(|suite| fs::read_dir(suite.path()).expect("suite dir exists"))
|
||||
.filter_map(as_directory)
|
||||
@@ -59,7 +63,7 @@ pub trait Handler {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let results = Cases { test_cases }.test_results(fork_name);
|
||||
let results = Cases { test_cases }.test_results(fork_name, Self::use_rayon());
|
||||
|
||||
let name = format!(
|
||||
"{}/{}/{}",
|
||||
@@ -460,6 +464,11 @@ impl<E: EthSpec + TypeName> Handler for ForkChoiceHandler<E> {
|
||||
self.handler_name.clone()
|
||||
}
|
||||
|
||||
fn use_rayon() -> bool {
|
||||
// The fork choice tests use `block_on` which can cause panics with rayon.
|
||||
false
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
@@ -56,6 +56,7 @@ type_name!(Eth1Data);
|
||||
type_name_generic!(ExecutionPayload);
|
||||
type_name_generic!(FullPayload, "ExecutionPayload");
|
||||
type_name_generic!(ExecutionPayloadHeader);
|
||||
type_name_generic!(BlindedPayload, "ExecutionPayloadHeader");
|
||||
type_name!(Fork);
|
||||
type_name!(ForkData);
|
||||
type_name_generic!(HistoricalBatch);
|
||||
|
||||
Reference in New Issue
Block a user