Resolve merge conflicts

This commit is contained in:
Eitan Seri-Levi
2026-01-02 08:52:14 -06:00
918 changed files with 49304 additions and 37273 deletions

View File

@@ -22,6 +22,7 @@ mod genesis_validity;
mod get_custody_groups;
mod kzg_blob_to_kzg_commitment;
mod kzg_compute_blob_kzg_proof;
mod kzg_compute_cells;
mod kzg_compute_cells_and_kzg_proofs;
mod kzg_compute_kzg_proof;
mod kzg_recover_cells_and_kzg_proofs;
@@ -58,6 +59,7 @@ pub use genesis_validity::*;
pub use get_custody_groups::*;
pub use kzg_blob_to_kzg_commitment::*;
pub use kzg_compute_blob_kzg_proof::*;
pub use kzg_compute_cells::*;
pub use kzg_compute_cells_and_kzg_proofs::*;
pub use kzg_compute_kzg_proof::*;
pub use kzg_recover_cells_and_kzg_proofs::*;
@@ -91,29 +93,29 @@ pub use transition::TransitionTest;
/// to return `true` for the feature in order for the feature test vector to be tested.
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FeatureName {
// TODO(fulu): to be removed once we start using Fulu types for test vectors.
// Existing SSZ types for PeerDAS (Fulu) are the same as Electra, so the test vectors get
// loaded as Electra types (default serde behaviour for untagged enums).
Fulu,
// Placeholder for future feature-gated forks
// Add new feature-gated forks here before they are incorporated into a main fork
#[doc(hidden)]
__Placeholder,
}
impl FeatureName {
pub fn list_all() -> Vec<FeatureName> {
vec![FeatureName::Fulu]
vec![]
}
/// `ForkName` to use when running the feature tests.
pub fn fork_name(&self) -> ForkName {
match self {
FeatureName::Fulu => ForkName::Electra,
FeatureName::__Placeholder => unreachable!("Placeholder variant should never be used"),
}
}
}
impl Display for FeatureName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
FeatureName::Fulu => f.write_str("fulu"),
FeatureName::__Placeholder => unreachable!("Placeholder variant should never be used"),
}
}
}
@@ -165,17 +167,13 @@ impl<T: Case> Cases<T> {
self.test_cases
.into_par_iter()
.enumerate()
.map(|(i, (ref path, ref tc))| {
CaseResult::new(i, path, tc, tc.result(i, fork_name))
})
.map(|(i, (path, 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))
})
.map(|(i, (path, tc))| CaseResult::new(i, path, tc, tc.result(i, fork_name)))
.collect()
}
}

View File

@@ -1,7 +1,7 @@
use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{verify_signature_sets, BlsWrappedSignature, PublicKeyBytes, Signature, SignatureSet};
use bls::{BlsWrappedSignature, PublicKeyBytes, Signature, SignatureSet, verify_signature_sets};
use serde::Deserialize;
use std::borrow::Cow;
use std::str::FromStr;

View File

@@ -1,8 +1,8 @@
use serde::Deserialize;
use context_deserialize::ContextDeserialize;
use serde::{Deserialize, Deserializer};
use ssz::Encode;
use ssz_derive::{Decode, Encode};
use std::fmt::Debug;
use types::ForkName;
/// Macro to wrap U128 and U256 so they deserialize correctly.
macro_rules! uint_wrapper {
@@ -40,6 +40,15 @@ macro_rules! uint_wrapper {
self.x.tree_hash_root()
}
}
impl<'de, T> ContextDeserialize<'de, T> for $wrapper_name {
fn context_deserialize<D>(deserializer: D, _context: T) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
<$wrapper_name>::deserialize(deserializer)
}
}
};
}
@@ -47,29 +56,9 @@ uint_wrapper!(DecimalU128, alloy_primitives::U128);
uint_wrapper!(DecimalU256, alloy_primitives::U256);
/// Trait for types that can be used in SSZ static tests.
pub trait SszStaticType:
serde::de::DeserializeOwned + Encode + Clone + PartialEq + Debug + Sync
{
}
pub trait SszStaticType: Encode + Clone + PartialEq + Debug + Sync {}
impl<T> SszStaticType for T where
T: serde::de::DeserializeOwned + Encode + Clone + PartialEq + Debug + Sync
{
}
/// Return the fork immediately prior to a fork.
pub fn previous_fork(fork_name: ForkName) -> ForkName {
match fork_name {
ForkName::Base => ForkName::Base,
ForkName::Altair => ForkName::Base,
ForkName::Bellatrix => ForkName::Altair,
ForkName::Capella => ForkName::Bellatrix,
ForkName::Deneb => ForkName::Capella,
ForkName::Electra => ForkName::Deneb,
ForkName::Eip7805 => ForkName::Electra,
ForkName::Fulu => ForkName::Eip7805,
}
}
impl<T> SszStaticType for T where T: Encode + Clone + PartialEq + Debug + Sync {}
#[macro_export]
macro_rules! impl_bls_load_case {

View File

@@ -1,7 +1,7 @@
use super::*;
use serde::Deserialize;
use std::marker::PhantomData;
use types::data_column_custody_group::{compute_columns_for_custody_group, CustodyIndex};
use types::data_column_custody_group::{CustodyIndex, compute_columns_for_custody_group};
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
@@ -27,7 +27,7 @@ impl<E: EthSpec> Case for ComputeColumnsForCustodyGroups<E> {
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let spec = E::default_spec();
let computed_columns = compute_columns_for_custody_group(self.custody_group, &spec)
let computed_columns = compute_columns_for_custody_group::<E>(self.custody_group, &spec)
.expect("should compute custody columns from group")
.collect::<Vec<_>>();

View File

@@ -4,6 +4,7 @@ use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_state, yaml_decode_file};
use crate::type_name;
use serde::Deserialize;
use state_processing::EpochProcessingError;
use state_processing::common::update_progressive_balances_cache::initialize_progressive_balances_cache;
use state_processing::epoch_cache::initialize_epoch_cache;
use state_processing::per_epoch_processing::capella::process_historical_summaries_update;
@@ -11,7 +12,7 @@ use state_processing::per_epoch_processing::effective_balance_updates::{
process_effective_balance_updates, process_effective_balance_updates_slow,
};
use state_processing::per_epoch_processing::single_pass::{
process_epoch_single_pass, SinglePassConfig,
SinglePassConfig, process_epoch_single_pass, process_proposer_lookahead,
};
use state_processing::per_epoch_processing::{
altair, base,
@@ -20,7 +21,6 @@ use state_processing::per_epoch_processing::{
process_slashings_slow,
resets::{process_eth1_data_reset, process_randao_mixes_reset, process_slashings_reset},
};
use state_processing::EpochProcessingError;
use std::marker::PhantomData;
use types::BeaconState;
@@ -77,6 +77,8 @@ pub struct SyncCommitteeUpdates;
pub struct InactivityUpdates;
#[derive(Debug)]
pub struct ParticipationFlagUpdates;
#[derive(Debug)]
pub struct ProposerLookahead;
type_name!(
JustificationAndFinalization,
@@ -97,6 +99,7 @@ type_name!(ParticipationRecordUpdates, "participation_record_updates");
type_name!(SyncCommitteeUpdates, "sync_committee_updates");
type_name!(InactivityUpdates, "inactivity_updates");
type_name!(ParticipationFlagUpdates, "participation_flag_updates");
type_name!(ProposerLookahead, "proposer_lookahead");
impl<E: EthSpec> EpochTransition<E> for JustificationAndFinalization {
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
@@ -280,6 +283,16 @@ impl<E: EthSpec> EpochTransition<E> for ParticipationFlagUpdates {
}
}
impl<E: EthSpec> EpochTransition<E> for ProposerLookahead {
fn run(state: &mut BeaconState<E>, spec: &ChainSpec) -> Result<(), EpochProcessingError> {
if state.fork_name_unchecked().fulu_enabled() {
process_proposer_lookahead(state, spec)
} else {
Ok(())
}
}
}
impl<E: EthSpec, T: EpochTransition<E>> LoadCase for EpochProcessing<E, T> {
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
let spec = &testing_spec::<E>(fork_name);
@@ -338,6 +351,11 @@ impl<E: EthSpec, T: EpochTransition<E>> Case for EpochProcessing<E, T> {
{
return false;
}
if !fork_name.fulu_enabled() && T::name() == "proposer_lookahead" {
return false;
}
true
}

View File

@@ -1,11 +1,10 @@
use super::*;
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::Deserialize;
use state_processing::upgrade::{
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
upgrade_to_eip7805, upgrade_to_electra, upgrade_to_fulu,
upgrade_to_eip7805, upgrade_to_electra, upgrade_to_fulu, upgrade_to_gloas,
};
use types::BeaconState;
@@ -33,7 +32,10 @@ impl<E: EthSpec> LoadCase for ForkTest<E> {
assert_eq!(metadata.fork_name(), fork_name);
// Decode pre-state with previous fork.
let pre_spec = &previous_fork(fork_name).make_genesis_spec(E::default_spec());
let pre_spec = &fork_name
.previous_fork()
.unwrap_or(ForkName::Base)
.make_genesis_spec(E::default_spec());
let pre = ssz_decode_state(&path.join("pre.ssz_snappy"), pre_spec)?;
// Decode post-state with target fork.
@@ -58,7 +60,7 @@ impl<E: EthSpec> Case for ForkTest<E> {
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
let mut result_state = self.pre.clone();
let mut expected = Some(self.post.clone());
let spec = &E::default_spec();
let spec = &fork_name.make_genesis_spec(E::default_spec());
let mut result = match fork_name {
ForkName::Base => panic!("phase0 not supported"),
@@ -71,6 +73,7 @@ impl<E: EthSpec> Case for ForkTest<E> {
ForkName::Electra => upgrade_to_electra(&mut result_state, spec).map(|_| result_state),
ForkName::Eip7805 => upgrade_to_eip7805(&mut result_state, spec).map(|_| result_state),
ForkName::Fulu => upgrade_to_fulu(&mut result_state, spec).map(|_| result_state),
ForkName::Gloas => upgrade_to_gloas(&mut result_state, spec).map(|_| result_state),
};
compare_beacon_state_results_without_caches(&mut result, &mut expected)

View File

@@ -5,19 +5,21 @@ use beacon_chain::beacon_proposer_cache::compute_proposer_duties_from_head;
use beacon_chain::blob_verification::GossipBlobError;
use beacon_chain::block_verification_types::RpcBlock;
use beacon_chain::chain_config::{
DisallowedReOrgOffsets, DEFAULT_RE_ORG_HEAD_THRESHOLD,
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION, DEFAULT_RE_ORG_PARENT_THRESHOLD,
DEFAULT_RE_ORG_HEAD_THRESHOLD, DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION,
DEFAULT_RE_ORG_PARENT_THRESHOLD, DisallowedReOrgOffsets,
};
use beacon_chain::data_column_verification::GossipVerifiedDataColumn;
use beacon_chain::slot_clock::SlotClock;
use beacon_chain::{
AvailabilityProcessingStatus, BeaconChainTypes, CachedHead, ChainConfig, NotifyExecutionLayer,
attestation_verification::{
obtain_indexed_attestation_and_committees_per_slot, VerifiedAttestation,
VerifiedAttestation, obtain_indexed_attestation_and_committees_per_slot,
},
blob_verification::GossipVerifiedBlob,
custody_context::NodeCustodyType,
test_utils::{BeaconChainHarness, EphemeralHarnessType},
AvailabilityProcessingStatus, BeaconChainTypes, CachedHead, ChainConfig, NotifyExecutionLayer,
};
use execution_layer::{json_structures::JsonPayloadStatusV1Status, PayloadStatusV1};
use execution_layer::{PayloadStatusV1, json_structures::JsonPayloadStatusV1Status};
use serde::Deserialize;
use ssz_derive::Decode;
use state_processing::state_advance::complete_state_advance;
@@ -26,8 +28,9 @@ use std::sync::Arc;
use std::time::Duration;
use types::{
Attestation, AttestationRef, AttesterSlashing, AttesterSlashingRef, BeaconBlock, BeaconState,
BlobSidecar, BlobsList, BlockImportSource, Checkpoint, ExecutionBlockHash, Hash256,
IndexedAttestation, KzgProof, ProposerPreparationData, SignedBeaconBlock, Slot, Uint256,
BlobSidecar, BlobsList, BlockImportSource, Checkpoint, DataColumnSidecarList,
DataColumnSubnetId, ExecutionBlockHash, Hash256, IndexedAttestation, KzgProof,
ProposerPreparationData, SignedBeaconBlock, Slot, Uint256,
};
// When set to true, cache any states fetched from the db.
@@ -91,14 +94,14 @@ impl From<PayloadStatus> for PayloadStatusV1 {
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged, deny_unknown_fields)]
pub enum Step<TBlock, TBlobs, TAttestation, TAttesterSlashing, TPowBlock> {
pub enum Step<TBlock, TBlobs, TColumns, TAttestation, TAttesterSlashing, TPowBlock> {
Tick {
tick: u64,
},
ValidBlock {
block: TBlock,
},
MaybeValidBlock {
MaybeValidBlockAndBlobs {
block: TBlock,
blobs: Option<TBlobs>,
proofs: Option<Vec<KzgProof>>,
@@ -120,6 +123,11 @@ pub enum Step<TBlock, TBlobs, TAttestation, TAttesterSlashing, TPowBlock> {
Checks {
checks: Box<Checks>,
},
MaybeValidBlockAndColumns {
block: TBlock,
columns: Option<TColumns>,
valid: bool,
},
}
#[derive(Debug, Clone, Deserialize)]
@@ -136,7 +144,14 @@ pub struct ForkChoiceTest<E: EthSpec> {
pub anchor_block: BeaconBlock<E>,
#[allow(clippy::type_complexity)]
pub steps: Vec<
Step<SignedBeaconBlock<E>, BlobsList<E>, Attestation<E>, AttesterSlashing<E>, PowBlock>,
Step<
SignedBeaconBlock<E>,
BlobsList<E>,
DataColumnSidecarList<E>,
Attestation<E>,
AttesterSlashing<E>,
PowBlock,
>,
>,
}
@@ -150,7 +165,7 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
.expect("path must be valid OsStr")
.to_string();
let spec = &testing_spec::<E>(fork_name);
let steps: Vec<Step<String, String, String, String, String>> =
let steps: Vec<Step<String, String, Vec<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
@@ -163,7 +178,7 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
})
.map(|block| Step::ValidBlock { block })
}
Step::MaybeValidBlock {
Step::MaybeValidBlockAndBlobs {
block,
blobs,
proofs,
@@ -176,7 +191,7 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
let blobs = blobs
.map(|blobs| ssz_decode_file(&path.join(format!("{blobs}.ssz_snappy"))))
.transpose()?;
Ok(Step::MaybeValidBlock {
Ok(Step::MaybeValidBlockAndBlobs {
block,
blobs,
proofs,
@@ -223,6 +238,31 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
payload_status,
}),
Step::Checks { checks } => Ok(Step::Checks { checks }),
Step::MaybeValidBlockAndColumns {
block,
columns,
valid,
} => {
let block =
ssz_decode_file_with(&path.join(format!("{block}.ssz_snappy")), |bytes| {
SignedBeaconBlock::from_ssz_bytes(bytes, spec)
})?;
let columns = columns
.map(|columns_vec| {
columns_vec
.into_iter()
.map(|column| {
ssz_decode_file(&path.join(format!("{column}.ssz_snappy")))
})
.collect::<Result<Vec<_>, _>>()
})
.transpose()?;
Ok(Step::MaybeValidBlockAndColumns {
block,
columns,
valid,
})
}
})
.collect::<Result<_, _>>()?;
let anchor_state = ssz_decode_state(&path.join("anchor_state.ssz_snappy"), spec)?;
@@ -263,14 +303,19 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
match step {
Step::Tick { tick } => tester.set_tick(*tick),
Step::ValidBlock { block } => {
tester.process_block(block.clone(), None, None, true)?
tester.process_block_and_blobs(block.clone(), None, None, true)?
}
Step::MaybeValidBlock {
Step::MaybeValidBlockAndBlobs {
block,
blobs,
proofs,
valid,
} => tester.process_block(block.clone(), blobs.clone(), proofs.clone(), *valid)?,
} => tester.process_block_and_blobs(
block.clone(),
blobs.clone(),
proofs.clone(),
*valid,
)?,
Step::Attestation { attestation } => tester.process_attestation(attestation)?,
Step::AttesterSlashing { attester_slashing } => {
tester.process_attester_slashing(attester_slashing.to_ref())
@@ -344,6 +389,14 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
tester.check_expected_proposer_head(*expected_proposer_head)?;
}
}
Step::MaybeValidBlockAndColumns {
block,
columns,
valid,
} => {
tester.process_block_and_columns(block.clone(), columns.clone(), *valid)?;
}
}
}
@@ -384,6 +437,7 @@ impl<E: EthSpec> Tester<E> {
.genesis_state_ephemeral_store(case.anchor_state.clone())
.mock_execution_layer()
.recalculate_fork_times_with_genesis(0)
.node_custody_type(NodeCustodyType::Supernode)
.mock_execution_layer_all_payloads_valid()
.build();
@@ -454,7 +508,67 @@ impl<E: EthSpec> Tester<E> {
.unwrap();
}
pub fn process_block(
pub fn process_block_and_columns(
&self,
block: SignedBeaconBlock<E>,
columns: Option<DataColumnSidecarList<E>>,
valid: bool,
) -> Result<(), Error> {
let block_root = block.canonical_root();
let mut data_column_success = true;
if let Some(columns) = columns.clone() {
let gossip_verified_data_columns = columns
.into_iter()
.map(|column| {
let subnet_id = DataColumnSubnetId::from_column_index(column.index, &self.spec);
GossipVerifiedDataColumn::new(column.clone(), subnet_id, &self.harness.chain)
.unwrap_or_else(|_| {
data_column_success = false;
GossipVerifiedDataColumn::__new_for_testing(column)
})
})
.collect();
let result = self.block_on_dangerous(
self.harness
.chain
.process_gossip_data_columns(gossip_verified_data_columns, || Ok(())),
)?;
if valid {
assert!(result.is_ok());
}
};
let block = Arc::new(block);
let result: Result<Result<Hash256, ()>, _> = self
.block_on_dangerous(self.harness.chain.process_block(
block_root,
RpcBlock::new_without_blobs(Some(block_root), block.clone()),
NotifyExecutionLayer::Yes,
BlockImportSource::Lookup,
|| Ok(()),
))?
.map(|avail: AvailabilityProcessingStatus| avail.try_into());
let success = data_column_success && result.as_ref().is_ok_and(|inner| inner.is_ok());
if success != valid {
return Err(Error::DidntFail(format!(
"block with root {} was valid={} whilst test expects valid={}. result: {:?}",
block_root,
result.is_ok(),
valid,
result
)));
}
if !valid && columns.is_none() {
self.apply_invalid_block(&block)?;
}
Ok(())
}
pub fn process_block_and_blobs(
&self,
block: SignedBeaconBlock<E>,
blobs: Option<BlobsList<E>>,
@@ -520,7 +634,7 @@ impl<E: EthSpec> Tester<E> {
let result: Result<Result<Hash256, ()>, _> = self
.block_on_dangerous(self.harness.chain.process_block(
block_root,
RpcBlock::new_without_blobs(Some(block_root), block.clone(), 0),
RpcBlock::new_without_blobs(Some(block_root), block.clone()),
NotifyExecutionLayer::Yes,
BlockImportSource::Lookup,
|| Ok(()),
@@ -537,66 +651,73 @@ impl<E: EthSpec> Tester<E> {
)));
}
// Apply invalid blocks directly against the fork choice `on_block` function. This ensures
// that the block is being rejected by `on_block`, not just some upstream block processing
// function. When blobs exist, we don't do this.
if !valid && blobs.is_none() {
// A missing parent block whilst `valid == false` means the test should pass.
if let Some(parent_block) = self
self.apply_invalid_block(&block)?;
}
Ok(())
}
// Apply invalid blocks directly against the fork choice `on_block` function. This ensures
// that the block is being rejected by `on_block`, not just some upstream block processing
// function. When data columns or blobs exist, we don't do this.
fn apply_invalid_block(&self, block: &Arc<SignedBeaconBlock<E>>) -> Result<(), Error> {
let block_root = block.canonical_root();
// A missing parent block whilst `valid == false` means the test should pass.
if let Some(parent_block) = self
.harness
.chain
.get_blinded_block(&block.parent_root())
.unwrap()
{
let parent_state_root = parent_block.state_root();
let mut state = self
.harness
.chain
.get_blinded_block(&block.parent_root())
.unwrap()
{
let parent_state_root = parent_block.state_root();
let mut state = self
.harness
.chain
.get_state(
&parent_state_root,
Some(parent_block.slot()),
CACHE_STATE_IN_TESTS,
)
.unwrap()
.unwrap();
complete_state_advance(
&mut state,
Some(parent_state_root),
block.slot(),
&self.harness.chain.spec,
.get_state(
&parent_state_root,
Some(parent_block.slot()),
CACHE_STATE_IN_TESTS,
)
.unwrap()
.unwrap();
let block_delay = self
.harness
.chain
.slot_clock
.seconds_from_current_slot_start()
.unwrap();
complete_state_advance(
&mut state,
Some(parent_state_root),
block.slot(),
&self.harness.chain.spec,
)
.unwrap();
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,
);
let block_delay = self
.harness
.chain
.slot_clock
.seconds_from_current_slot_start()
.unwrap();
if result.is_ok() {
return Err(Error::DidntFail(format!(
"block with root {} should fail on_block",
block_root,
)));
}
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,
);
if result.is_ok() {
return Err(Error::DidntFail(format!(
"block with root {} should fail on_block",
block_root,
)));
}
}
@@ -799,7 +920,7 @@ impl<E: EthSpec> Tester<E> {
let cached_head = self.harness.chain.canonical_head.cached_head();
let next_slot = cached_head.snapshot.beacon_block.slot() + 1;
let next_slot_epoch = next_slot.epoch(E::slots_per_epoch());
let (proposer_indices, decision_root, _, fork) =
let (proposer_indices, decision_root, _, _, fork) =
compute_proposer_duties_from_head(next_slot_epoch, &self.harness.chain).unwrap();
let proposer_index = proposer_indices[next_slot.as_usize() % E::slots_per_epoch() as usize];
@@ -883,7 +1004,7 @@ pub struct ManuallyVerifiedAttestation<'a, T: BeaconChainTypes> {
}
impl<T: BeaconChainTypes> VerifiedAttestation<T> for ManuallyVerifiedAttestation<'_, T> {
fn attestation(&self) -> AttestationRef<T::EthSpec> {
fn attestation(&self) -> AttestationRef<'_, T::EthSpec> {
self.attestation.to_ref()
}

View File

@@ -0,0 +1,54 @@
use super::*;
use crate::case_result::compare_result;
use kzg::Cell;
use serde::Deserialize;
use std::marker::PhantomData;
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KZGComputeCellsInput {
pub blob: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
pub struct KZGComputeCells<E: EthSpec> {
pub input: KZGComputeCellsInput,
pub output: Option<Vec<String>>,
#[serde(skip)]
_phantom: PhantomData<E>,
}
impl<E: EthSpec> LoadCase for KZGComputeCells<E> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
decode::yaml_decode_file(path.join("data.yaml").as_path())
}
}
impl<E: EthSpec> Case for KZGComputeCells<E> {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name.fulu_enabled()
}
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let cells = parse_blob::<E>(&self.input.blob)
.and_then(|blob| {
let blob = blob.as_ref().try_into().map_err(|e| {
Error::InternalError(format!("Failed to convert blob to kzg blob: {e:?}"))
})?;
let kzg = get_kzg();
kzg.compute_cells(blob).map_err(|e| {
Error::InternalError(format!("Failed to compute cells and kzg proofs: {e:?}"))
})
})
.map(|cells| cells.to_vec());
let expected = self.output.as_ref().map(|cells| {
parse_cells_and_proofs(cells, &[])
.map(|(cells, _)| cells)
.expect("Valid cells")
});
compare_result::<Vec<Cell>, _>(&cells, &expected)
}
}

View File

@@ -2,7 +2,7 @@ use super::*;
use crate::case_result::compare_result;
use beacon_chain::kzg_utils::validate_blob;
use kzg::trusted_setup::get_trusted_setup;
use kzg::{Cell, Error as KzgError, Kzg, KzgCommitment, KzgProof, TrustedSetup};
use kzg::{Cell, Error as KzgError, Kzg, KzgCommitment, KzgProof};
use serde::Deserialize;
use std::marker::PhantomData;
use std::sync::Arc;
@@ -10,10 +10,7 @@ use std::sync::LazyLock;
use types::Blob;
static KZG: LazyLock<Arc<Kzg>> = LazyLock::new(|| {
let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice())
.map_err(|e| Error::InternalError(format!("Failed to initialize trusted setup: {:?}", e)))
.expect("failed to initialize trusted setup");
let kzg = Kzg::new_from_trusted_setup_das_enabled(trusted_setup)
let kzg = Kzg::new_from_trusted_setup(&get_trusted_setup())
.map_err(|e| Error::InternalError(format!("Failed to initialize kzg: {:?}", e)))
.expect("failed to initialize kzg");
Arc::new(kzg)

View File

@@ -53,7 +53,7 @@ impl<E: EthSpec> Case for KZGVerifyCellKZGProofBatch<E> {
let kzg = get_kzg();
match kzg.verify_cell_proof_batch(&cells, &proofs, cell_indices, &commitments) {
Ok(_) => Ok(true),
Err(KzgError::KzgVerificationFailed) => Ok(false),
Err((_, KzgError::KzgVerificationFailed)) => Ok(false),
Err(e) => Err(Error::InternalError(format!(
"Failed to validate cells: {:?}",
e

View File

@@ -1,11 +1,13 @@
use super::*;
use crate::decode::{ssz_decode_file, ssz_decode_state, yaml_decode_file};
use serde::Deserialize;
use ssz_types::FixedVector;
use tree_hash::Hash256;
use typenum::Unsigned;
use types::{
light_client_update, BeaconBlockBody, BeaconBlockBodyCapella, BeaconBlockBodyDeneb,
BeaconBlockBodyEip7805, BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconState, FixedVector,
FullPayload, Unsigned,
BeaconBlockBody, BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyEip7805,
BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockBodyGloas, BeaconState, FullPayload,
light_client_update,
};
#[derive(Debug, Clone, Deserialize)]
@@ -161,7 +163,7 @@ impl<E: EthSpec> LoadCase for KzgInclusionMerkleProofValidity<E> {
return Err(Error::InternalError(format!(
"KZG inclusion merkle proof validity test skipped for {:?}",
fork_name
)))
)));
}
ForkName::Deneb => {
ssz_decode_file::<BeaconBlockBodyDeneb<E>>(&path.join("object.ssz_snappy"))?.into()
@@ -177,6 +179,9 @@ impl<E: EthSpec> LoadCase for KzgInclusionMerkleProofValidity<E> {
ForkName::Fulu => {
ssz_decode_file::<BeaconBlockBodyFulu<E>>(&path.join("object.ssz_snappy"))?.into()
}
ForkName::Gloas => {
ssz_decode_file::<BeaconBlockBodyGloas<E>>(&path.join("object.ssz_snappy"))?.into()
}
};
let merkle_proof = yaml_decode_file(&path.join("proof.yaml"))?;
// Metadata does not exist in these tests but it is left like this just in case.
@@ -279,7 +284,7 @@ impl<E: EthSpec> LoadCase for BeaconBlockBodyMerkleProofValidity<E> {
return Err(Error::InternalError(format!(
"Beacon block body merkle proof validity test skipped for {:?}",
fork_name
)))
)));
}
ForkName::Capella => {
ssz_decode_file::<BeaconBlockBodyCapella<E>>(&path.join("object.ssz_snappy"))?
@@ -299,6 +304,9 @@ impl<E: EthSpec> LoadCase for BeaconBlockBodyMerkleProofValidity<E> {
ForkName::Fulu => {
ssz_decode_file::<BeaconBlockBodyFulu<E>>(&path.join("object.ssz_snappy"))?.into()
}
ForkName::Gloas => {
ssz_decode_file::<BeaconBlockBodyGloas<E>>(&path.join("object.ssz_snappy"))?.into()
}
};
let merkle_proof = yaml_decode_file(&path.join("proof.yaml"))?;
// Metadata does not exist in these tests but it is left like this just in case.

View File

@@ -10,22 +10,23 @@ use state_processing::per_block_processing::process_operations::{
process_consolidation_requests, process_deposit_requests, process_withdrawal_requests,
};
use state_processing::{
ConsensusContext,
per_block_processing::{
VerifyBlockRoot, VerifySignatures,
errors::BlockProcessingError,
process_block_header, process_execution_payload,
process_operations::{
altair_deneb, base, process_attester_slashings, process_bls_to_execution_changes,
process_deposits, process_exits, process_proposer_slashings,
},
process_sync_aggregate, process_withdrawals, VerifyBlockRoot, VerifySignatures,
process_sync_aggregate, process_withdrawals,
},
ConsensusContext,
};
use std::fmt::Debug;
use types::{
Attestation, AttesterSlashing, BeaconBlock, BeaconBlockBody, BeaconBlockBodyBellatrix,
BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconState,
BlindedPayload, ConsolidationRequest, Deposit, DepositRequest, ExecutionPayload,
BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu,
BeaconState, BlindedPayload, ConsolidationRequest, Deposit, DepositRequest, ExecutionPayload,
ForkVersionDecode, FullPayload, ProposerSlashing, SignedBlsToExecutionChange,
SignedVoluntaryExit, SyncAggregate, WithdrawalRequest,
};
@@ -171,7 +172,7 @@ impl<E: EthSpec> Operation<E> for Deposit {
spec: &ChainSpec,
_: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
process_deposits(state, &[self.clone()], spec)
process_deposits(state, std::slice::from_ref(self), spec)
}
}
@@ -194,7 +195,7 @@ impl<E: EthSpec> Operation<E> for ProposerSlashing {
initialize_progressive_balances_cache(state, spec)?;
process_proposer_slashings(
state,
&[self.clone()],
std::slice::from_ref(self),
VerifySignatures::True,
&mut ctxt,
spec,
@@ -217,7 +218,12 @@ impl<E: EthSpec> Operation<E> for SignedVoluntaryExit {
spec: &ChainSpec,
_: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
process_exits(state, &[self.clone()], VerifySignatures::True, spec)
process_exits(
state,
std::slice::from_ref(self),
VerifySignatures::True,
spec,
)
}
}
@@ -301,6 +307,7 @@ impl<E: EthSpec> Operation<E> for BeaconBlockBody<E, FullPayload<E>> {
ForkName::Deneb => BeaconBlockBody::Deneb(<_>::from_ssz_bytes(bytes)?),
ForkName::Electra => BeaconBlockBody::Electra(<_>::from_ssz_bytes(bytes)?),
ForkName::Fulu => BeaconBlockBody::Fulu(<_>::from_ssz_bytes(bytes)?),
// TODO(EIP-7732): See if we need to handle Gloas here
_ => panic!(),
})
})
@@ -357,9 +364,10 @@ impl<E: EthSpec> Operation<E> for BeaconBlockBody<E, BlindedPayload<E>> {
BeaconBlockBody::Electra(inner.clone_as_blinded())
}
ForkName::Fulu => {
let inner = <BeaconBlockBodyElectra<E, FullPayload<E>>>::from_ssz_bytes(bytes)?;
BeaconBlockBody::Electra(inner.clone_as_blinded())
let inner = <BeaconBlockBodyFulu<E, FullPayload<E>>>::from_ssz_bytes(bytes)?;
BeaconBlockBody::Fulu(inner.clone_as_blinded())
}
// TODO(EIP-7732): See if we need to handle Gloas here
_ => panic!(),
})
})
@@ -411,6 +419,7 @@ impl<E: EthSpec> Operation<E> for WithdrawalsPayload<E> {
spec: &ChainSpec,
_: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
// TODO(EIP-7732): implement separate gloas and non-gloas variants of process_withdrawals
process_withdrawals::<_, FullPayload<_>>(state, self.payload.to_ref(), spec)
}
}
@@ -438,7 +447,12 @@ impl<E: EthSpec> Operation<E> for SignedBlsToExecutionChange {
spec: &ChainSpec,
_extra: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
process_bls_to_execution_changes(state, &[self.clone()], VerifySignatures::True, spec)
process_bls_to_execution_changes(
state,
std::slice::from_ref(self),
VerifySignatures::True,
spec,
)
}
}
@@ -462,7 +476,7 @@ impl<E: EthSpec> Operation<E> for WithdrawalRequest {
_extra: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
state.update_pubkey_cache()?;
process_withdrawal_requests(state, &[self.clone()], spec)
process_withdrawal_requests(state, std::slice::from_ref(self), spec)
}
}
@@ -485,7 +499,7 @@ impl<E: EthSpec> Operation<E> for DepositRequest {
spec: &ChainSpec,
_extra: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
process_deposit_requests(state, &[self.clone()], spec)
process_deposit_requests(state, std::slice::from_ref(self), spec)
}
}
@@ -509,7 +523,7 @@ impl<E: EthSpec> Operation<E> for ConsolidationRequest {
_extra: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
state.update_pubkey_cache()?;
process_consolidation_requests(state, &[self.clone()], spec)
process_consolidation_requests(state, std::slice::from_ref(self), spec)
}
}
@@ -587,10 +601,10 @@ impl<E: EthSpec, O: Operation<E>> Case for Operations<E, O> {
let mut state = pre_state.clone();
let mut expected = self.post.clone();
if O::handler_name() != "withdrawals" {
if let Some(post_state) = expected.as_mut() {
post_state.build_all_committee_caches(spec).unwrap();
}
if O::handler_name() != "withdrawals"
&& let Some(post_state) = expected.as_mut()
{
post_state.build_all_committee_caches(spec).unwrap();
}
let mut result = self

View File

@@ -1,18 +1,17 @@
use super::*;
use crate::case_result::compare_result_detailed;
use crate::decode::{ssz_decode_file, ssz_decode_state, yaml_decode_file};
use compare_fields_derive::CompareFields;
use compare_fields::CompareFields;
use serde::Deserialize;
use ssz::four_byte_option_impl;
use ssz_derive::{Decode, Encode};
use state_processing::per_epoch_processing::base::rewards_and_penalties::ProposerRewardCalculation;
use state_processing::{
per_epoch_processing::{
altair,
base::{self, rewards_and_penalties::AttestationDelta, ValidatorStatuses},
Delta,
},
EpochProcessingError,
per_epoch_processing::{
Delta, altair,
base::{self, ValidatorStatuses, rewards_and_penalties::AttestationDelta},
},
};
use types::BeaconState;

View File

@@ -4,8 +4,8 @@ use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_file_with, ssz_decode_state, yaml_decode_file};
use serde::Deserialize;
use state_processing::{
per_block_processing, per_slot_processing, BlockProcessingError, BlockSignatureStrategy,
ConsensusContext, VerifyBlockRoot,
BlockProcessingError, BlockSignatureStrategy, ConsensusContext, VerifyBlockRoot,
per_block_processing, per_slot_processing,
};
use types::{BeaconState, RelativeEpoch, SignedBeaconBlock};

View File

@@ -3,15 +3,19 @@
use super::*;
use crate::cases::common::{DecimalU128, DecimalU256, SszStaticType};
use crate::cases::ssz_static::{check_serialization, check_tree_hash};
use crate::decode::{log_file_access, snappy_decode_file, yaml_decode_file};
use serde::{de::Error as SerdeError, Deserialize, Deserializer};
use crate::decode::{context_yaml_decode_file, log_file_access, snappy_decode_file};
use context_deserialize::{ContextDeserialize, context_deserialize};
use milhouse::Vector;
use serde::{Deserialize, Deserializer, de::Error as SerdeError};
use ssz_derive::{Decode, Encode};
use ssz_types::{BitList, BitVector, FixedVector, VariableList};
use tree_hash::TreeHash;
use tree_hash_derive::TreeHash;
use types::typenum::*;
use types::{BitList, BitVector, FixedVector, ForkName, VariableList, Vector};
use typenum::*;
use types::ForkName;
#[derive(Debug, Clone, Deserialize)]
#[context_deserialize(ForkName)]
struct Metadata {
root: String,
#[serde(rename(deserialize = "signing_root"))]
@@ -78,12 +82,16 @@ macro_rules! type_dispatch {
"7" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U7>, $($rest)*),
"8" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U8>, $($rest)*),
"9" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U9>, $($rest)*),
"15" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U15>, $($rest)*),
"16" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U16>, $($rest)*),
"17" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U17>, $($rest)*),
"31" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U31>, $($rest)*),
"32" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U32>, $($rest)*),
"33" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U33>, $($rest)*),
"64" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U64>, $($rest)*),
"128" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U128>, $($rest)*),
"256" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U256>, $($rest)*),
"511" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U511>, $($rest)*),
"512" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U512>, $($rest)*),
"513" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U513>, $($rest)*),
"1024" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* U1024>, $($rest)*),
@@ -105,6 +113,8 @@ macro_rules! type_dispatch {
"VarTestStruct" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* VarTestStruct>, $($rest)*),
"ComplexTestStruct" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* ComplexTestStruct>, $($rest)*),
"BitsStruct" => type_dispatch!($function, ($($arg),*), $base_ty, <$($param_ty,)* BitsStruct>, $($rest)*),
// EIP-7916 is still in draft and hasn't been implemented yet https://eips.ethereum.org/EIPS/eip-7916
"ProgressiveTestStruct" | "ProgressiveBitsStruct" => Err(Error::SkippedKnownFailure),
_ => Err(Error::FailedToParseTest(format!("unsupported: {}", $value))),
}
};
@@ -118,7 +128,7 @@ macro_rules! type_dispatch {
}
impl Case for SszGeneric {
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
let parts = self.case_name.split('_').collect::<Vec<_>>();
match self.handler_name.as_str() {
@@ -134,7 +144,7 @@ impl Case for SszGeneric {
type_dispatch!(
ssz_generic_test,
(&self.path),
(&self.path, fork_name),
Vector,
<>,
[elem_ty => primitive_type]
@@ -142,7 +152,7 @@ impl Case for SszGeneric {
)?;
type_dispatch!(
ssz_generic_test,
(&self.path),
(&self.path, fork_name),
FixedVector,
<>,
[elem_ty => primitive_type]
@@ -159,7 +169,7 @@ impl Case for SszGeneric {
type_dispatch!(
ssz_generic_test,
(&self.path),
(&self.path, fork_name),
BitList,
<>,
[limit => typenum]
@@ -170,21 +180,21 @@ impl Case for SszGeneric {
type_dispatch!(
ssz_generic_test,
(&self.path),
(&self.path, fork_name),
BitVector,
<>,
[length => typenum]
)?;
}
"boolean" => {
ssz_generic_test::<bool>(&self.path)?;
ssz_generic_test::<bool>(&self.path, fork_name)?;
}
"uints" => {
let type_name = "uint".to_owned() + parts[1];
type_dispatch!(
ssz_generic_test,
(&self.path),
(&self.path, fork_name),
_,
<>,
[type_name.as_str() => primitive_type]
@@ -195,7 +205,7 @@ impl Case for SszGeneric {
type_dispatch!(
ssz_generic_test,
(&self.path),
(&self.path, fork_name),
_,
<>,
[type_name => test_container]
@@ -207,10 +217,15 @@ impl Case for SszGeneric {
}
}
fn ssz_generic_test<T: SszStaticType + TreeHash + ssz::Decode>(path: &Path) -> Result<(), Error> {
fn ssz_generic_test<
T: SszStaticType + for<'de> ContextDeserialize<'de, ForkName> + TreeHash + ssz::Decode,
>(
path: &Path,
fork_name: ForkName,
) -> Result<(), Error> {
let meta_path = path.join("meta.yaml");
let meta: Option<Metadata> = if meta_path.is_file() {
Some(yaml_decode_file(&meta_path)?)
Some(context_yaml_decode_file(&meta_path, fork_name)?)
} else {
None
};
@@ -220,7 +235,7 @@ fn ssz_generic_test<T: SszStaticType + TreeHash + ssz::Decode>(path: &Path) -> R
let value_path = path.join("value.yaml");
let value: Option<T> = if value_path.is_file() {
Some(yaml_decode_file(&value_path)?)
Some(context_yaml_decode_file(&value_path, fork_name)?)
} else {
None
};
@@ -246,17 +261,20 @@ fn ssz_generic_test<T: SszStaticType + TreeHash + ssz::Decode>(path: &Path) -> R
// Containers for SSZ generic tests
#[derive(Debug, Clone, Default, PartialEq, Decode, Encode, TreeHash, Deserialize)]
#[context_deserialize(ForkName)]
struct SingleFieldTestStruct {
A: u8,
}
#[derive(Debug, Clone, Default, PartialEq, Decode, Encode, TreeHash, Deserialize)]
#[context_deserialize(ForkName)]
struct SmallTestStruct {
A: u16,
B: u16,
}
#[derive(Debug, Clone, Default, PartialEq, Decode, Encode, TreeHash, Deserialize)]
#[context_deserialize(ForkName)]
struct FixedTestStruct {
A: u8,
B: u64,
@@ -264,6 +282,7 @@ struct FixedTestStruct {
}
#[derive(Debug, Clone, Default, PartialEq, Decode, Encode, TreeHash, Deserialize)]
#[context_deserialize(ForkName)]
struct VarTestStruct {
A: u16,
B: VariableList<u16, U1024>,
@@ -271,6 +290,7 @@ struct VarTestStruct {
}
#[derive(Debug, Clone, Default, PartialEq, Decode, Encode, TreeHash, Deserialize)]
#[context_deserialize(ForkName)]
struct ComplexTestStruct {
A: u16,
B: VariableList<u16, U128>,
@@ -283,6 +303,7 @@ struct ComplexTestStruct {
}
#[derive(Debug, Clone, PartialEq, Decode, Encode, TreeHash, Deserialize)]
#[context_deserialize(ForkName)]
struct BitsStruct {
A: BitList<U5>,
B: BitVector<U2>,
@@ -299,14 +320,13 @@ where
{
let s: String = serde::de::Deserialize::deserialize(deserializer)?;
let decoded: Vec<u8> = hex::decode(&s.as_str()[2..]).map_err(D::Error::custom)?;
let decoded_len = decoded.len();
if decoded.len() > N::to_usize() {
Err(D::Error::custom(format!(
decoded.try_into().map_err(|_| {
D::Error::custom(format!(
"Too many values for list, got: {}, limit: {}",
decoded.len(),
decoded_len,
N::to_usize()
)))
} else {
Ok(decoded.into())
}
))
})
}

View File

@@ -1,10 +1,11 @@
use super::*;
use crate::case_result::compare_result;
use crate::decode::{snappy_decode_file, yaml_decode_file};
use crate::decode::{context_yaml_decode_file, snappy_decode_file, yaml_decode_file};
use context_deserialize::ContextDeserialize;
use serde::Deserialize;
use ssz::Decode;
use tree_hash::TreeHash;
use types::{BeaconBlock, BeaconState, Hash256, SignedBeaconBlock};
use types::{BeaconBlock, BeaconState, DataColumnsByRootIdentifier, Hash256, SignedBeaconBlock};
#[derive(Debug, Clone, Deserialize)]
struct SszStaticRoots {
@@ -37,18 +38,28 @@ pub struct SszStaticWithSpec<T> {
value: T,
}
fn load_from_dir<T: SszStaticType>(path: &Path) -> Result<(SszStaticRoots, Vec<u8>, T), Error> {
fn load_from_dir<T: SszStaticType + for<'de> ContextDeserialize<'de, ForkName>>(
path: &Path,
fork_name: ForkName,
) -> Result<(SszStaticRoots, Vec<u8>, T), Error> {
load_from_dir_with_context(path, fork_name)
}
fn load_from_dir_with_context<T: SszStaticType + for<'de> ContextDeserialize<'de, C>, C>(
path: &Path,
context: C,
) -> Result<(SszStaticRoots, Vec<u8>, T), Error> {
let roots = yaml_decode_file(&path.join("roots.yaml"))?;
let serialized = snappy_decode_file(&path.join("serialized.ssz_snappy"))
.expect("serialized.ssz_snappy exists");
let value = yaml_decode_file(&path.join("value.yaml"))?;
let value = context_yaml_decode_file(&path.join("value.yaml"), context)?;
Ok((roots, serialized, value))
}
impl<T: SszStaticType> LoadCase for SszStatic<T> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path).map(|(roots, serialized, value)| Self {
impl<T: SszStaticType + for<'de> ContextDeserialize<'de, ForkName>> LoadCase for SszStatic<T> {
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path, fork_name).map(|(roots, serialized, value)| Self {
roots,
serialized,
value,
@@ -56,19 +67,9 @@ impl<T: SszStaticType> LoadCase for SszStatic<T> {
}
}
impl<T: SszStaticType> LoadCase for SszStaticTHC<T> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path).map(|(roots, serialized, value)| Self {
roots,
serialized,
value,
})
}
}
impl<T: SszStaticType> LoadCase for SszStaticWithSpec<T> {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path).map(|(roots, serialized, value)| Self {
impl<T: SszStaticType + for<'de> ContextDeserialize<'de, ForkName>> LoadCase for SszStaticTHC<T> {
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path, fork_name).map(|(roots, serialized, value)| Self {
roots,
serialized,
value,
@@ -124,6 +125,16 @@ impl<E: EthSpec> Case for SszStaticTHC<BeaconState<E>> {
}
}
impl<E: EthSpec> LoadCase for SszStaticWithSpec<BeaconBlock<E>> {
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path, fork_name).map(|(roots, serialized, value)| Self {
roots,
serialized,
value,
})
}
}
impl<E: EthSpec> Case for SszStaticWithSpec<BeaconBlock<E>> {
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
let spec = &testing_spec::<E>(fork_name);
@@ -135,6 +146,16 @@ impl<E: EthSpec> Case for SszStaticWithSpec<BeaconBlock<E>> {
}
}
impl<E: EthSpec> LoadCase for SszStaticWithSpec<SignedBeaconBlock<E>> {
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path, fork_name).map(|(roots, serialized, value)| Self {
roots,
serialized,
value,
})
}
}
impl<E: EthSpec> Case for SszStaticWithSpec<SignedBeaconBlock<E>> {
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
let spec = &testing_spec::<E>(fork_name);
@@ -145,3 +166,23 @@ impl<E: EthSpec> Case for SszStaticWithSpec<SignedBeaconBlock<E>> {
Ok(())
}
}
impl<E: EthSpec> LoadCase for SszStaticWithSpec<DataColumnsByRootIdentifier<E>> {
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
load_from_dir(path, fork_name).map(|(roots, serialized, value)| Self {
roots,
serialized,
value,
})
}
}
impl<E: EthSpec> Case for SszStaticWithSpec<DataColumnsByRootIdentifier<E>> {
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
check_serialization(&self.value, &self.serialized, |bytes| {
DataColumnsByRootIdentifier::from_ssz_bytes(bytes)
})?;
check_tree_hash(&self.roots.root, self.value.tree_hash_root().as_slice())?;
Ok(())
}
}

View File

@@ -3,8 +3,8 @@ use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_file_with, ssz_decode_state, yaml_decode_file};
use serde::Deserialize;
use state_processing::{
per_block_processing, state_advance::complete_state_advance, BlockSignatureStrategy,
ConsensusContext, VerifyBlockRoot,
BlockSignatureStrategy, ConsensusContext, VerifyBlockRoot, per_block_processing,
state_advance::complete_state_advance,
};
use std::str::FromStr;
use types::{BeaconState, Epoch, SignedBeaconBlock};
@@ -76,6 +76,15 @@ impl<E: EthSpec> LoadCase for TransitionTest<E> {
spec.electra_fork_epoch = Some(Epoch::new(0));
spec.fulu_fork_epoch = Some(metadata.fork_epoch);
}
ForkName::Gloas => {
spec.altair_fork_epoch = Some(Epoch::new(0));
spec.bellatrix_fork_epoch = Some(Epoch::new(0));
spec.capella_fork_epoch = Some(Epoch::new(0));
spec.deneb_fork_epoch = Some(Epoch::new(0));
spec.electra_fork_epoch = Some(Epoch::new(0));
spec.fulu_fork_epoch = Some(Epoch::new(0));
spec.gloas_fork_epoch = Some(metadata.fork_epoch);
}
}
// Load blocks

View File

@@ -1,4 +1,5 @@
use super::*;
use context_deserialize::ContextDeserialize;
use fs2::FileExt;
use snap::raw::Decoder;
use std::fs::{self};
@@ -35,6 +36,27 @@ pub fn yaml_decode<T: serde::de::DeserializeOwned>(string: &str) -> Result<T, Er
serde_yaml::from_str(string).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))
}
pub fn context_yaml_decode<'de, T, C>(string: &'de str, context: C) -> Result<T, Error>
where
T: ContextDeserialize<'de, C>,
{
let deserializer = serde_yaml::Deserializer::from_str(string);
T::context_deserialize(deserializer, context)
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))
}
pub fn context_yaml_decode_file<T, C>(path: &Path, context: C) -> Result<T, Error>
where
T: for<'de> ContextDeserialize<'de, C>,
{
log_file_access(path);
fs::read_to_string(path)
.map_err(|e| {
Error::FailedToParseTest(format!("Unable to load {}: {:?}", path.display(), e))
})
.and_then(|s| context_yaml_decode(&s, context))
}
pub fn yaml_decode_file<T: serde::de::DeserializeOwned>(path: &Path) -> Result<T, Error> {
log_file_access(path);
fs::read_to_string(path)

View File

@@ -1,7 +1,8 @@
use crate::cases::{self, Case, Cases, EpochTransition, LoadCase, Operation};
use crate::type_name::TypeName;
use crate::{type_name, FeatureName};
use derivative::Derivative;
use crate::{FeatureName, type_name};
use context_deserialize::ContextDeserialize;
use educe::Educe;
use std::fs::{self, DirEntry};
use std::marker::PhantomData;
use std::path::PathBuf;
@@ -21,7 +22,7 @@ pub trait Handler {
// Add forks here to exclude them from EF spec testing. Helpful for adding future or
// unspecified forks.
fn disabled_forks(&self) -> Vec<ForkName> {
vec![ForkName::Fulu]
vec![ForkName::Gloas]
}
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
@@ -50,6 +51,19 @@ pub trait Handler {
}
}
// Do NOT override this function.
// TODO: use default keyword when stable.
fn rayon_enabled() -> bool {
#[cfg(feature = "disable_rayon")]
{
false
}
#[cfg(not(feature = "disable_rayon"))]
{
Self::use_rayon()
}
}
fn use_rayon() -> bool {
true
}
@@ -79,13 +93,12 @@ pub trait Handler {
.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");
(path, case)
})
.collect();
let results = Cases { test_cases }.test_results(fork_name, Self::use_rayon());
let results = Cases { test_cases }.test_results(fork_name, Self::rayon_enabled());
let name = format!(
"{}/{}/{}",
@@ -127,7 +140,7 @@ pub trait Handler {
})
.collect();
let results = Cases { test_cases }.test_results(fork_name, Self::use_rayon());
let results = Cases { test_cases }.test_results(fork_name, Self::rayon_enabled());
let name = format!(
"{}/{}/{}",
@@ -141,8 +154,8 @@ pub trait Handler {
macro_rules! bls_eth_handler {
($runner_name: ident, $case_name:ident, $handler_name:expr) => {
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct $runner_name;
impl Handler for $runner_name {
@@ -161,8 +174,8 @@ macro_rules! bls_eth_handler {
macro_rules! bls_handler {
($runner_name: ident, $case_name:ident, $handler_name:expr) => {
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct $runner_name;
impl Handler for $runner_name {
@@ -205,7 +218,7 @@ macro_rules! bls_handler {
})
.collect();
let results = Cases { test_cases }.test_results(fork_name, Self::use_rayon());
let results = Cases { test_cases }.test_results(fork_name, Self::rayon_enabled());
let name = format!(
"{}/{}/{}",
@@ -322,18 +335,42 @@ impl<T, E> SszStaticHandler<T, E> {
}
/// Handler for SSZ types that implement `CachedTreeHash`.
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
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)>);
pub struct SszStaticWithSpecHandler<T, E> {
supported_forks: Vec<ForkName>,
_phantom: PhantomData<(T, E)>,
}
impl<T, E> Default for SszStaticWithSpecHandler<T, E> {
fn default() -> Self {
Self::for_forks(ForkName::list_all())
}
}
impl<T, E> SszStaticWithSpecHandler<T, E> {
pub fn for_forks(supported_forks: Vec<ForkName>) -> Self {
SszStaticWithSpecHandler {
supported_forks,
_phantom: PhantomData,
}
}
pub fn fulu_and_later() -> Self {
Self::for_forks(ForkName::list_all()[6..].to_vec())
}
}
impl<T, E> Handler for SszStaticHandler<T, E>
where
T: cases::SszStaticType + tree_hash::TreeHash + ssz::Decode + TypeName,
T: cases::SszStaticType
+ for<'de> ContextDeserialize<'de, ForkName>
+ tree_hash::TreeHash
+ ssz::Decode
+ TypeName,
E: TypeName,
{
type Case = cases::SszStatic<T>;
@@ -353,25 +390,6 @@ where
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
self.supported_forks.contains(&fork_name)
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
// TODO(fulu): to be removed once Fulu types start differing from Electra. We currently run Fulu tests as a
// "feature" - this means we use Electra types for Fulu SSZ tests (except for PeerDAS types, e.g. `DataColumnSidecar`).
//
// This ensures we only run the tests **once** for `Fulu`, using the types matching the
// correct fork, e.g. `Fulu` uses SSZ types from `Electra` as of spec test version
// `v1.5.0-beta.0`, therefore the `Fulu` tests should get included when testing Deneb types.
//
// e.g. Fulu test vectors are executed in the 2nd line below, but excluded in the 1st
// line when testing the type `AttestationElectra`:
//
// ```
// SszStaticHandler::<AttestationBase<MainnetEthSpec>, MainnetEthSpec>::pre_electra().run();
// SszStaticHandler::<AttestationElectra<MainnetEthSpec>, MainnetEthSpec>::electra_only().run();
// ```
feature_name == FeatureName::Fulu
&& self.supported_forks.contains(&feature_name.fork_name())
}
}
impl<E> Handler for SszStaticTHCHandler<BeaconState<E>, E>
@@ -391,10 +409,6 @@ where
fn handler_name(&self) -> String {
BeaconState::<E>::name().into()
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
}
}
impl<T, E> Handler for SszStaticWithSpecHandler<T, E>
@@ -417,13 +431,13 @@ where
T::name().into()
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
self.supported_forks.contains(&fork_name)
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct ShufflingHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for ShufflingHandler<E> {
@@ -446,8 +460,8 @@ impl<E: EthSpec + TypeName> Handler for ShufflingHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct SanityBlocksHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for SanityBlocksHandler<E> {
@@ -472,8 +486,8 @@ impl<E: EthSpec + TypeName> Handler for SanityBlocksHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct SanitySlotsHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for SanitySlotsHandler<E> {
@@ -497,8 +511,8 @@ impl<E: EthSpec + TypeName> Handler for SanitySlotsHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct RandomHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for RandomHandler<E> {
@@ -517,8 +531,8 @@ impl<E: EthSpec + TypeName> Handler for RandomHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct EpochProcessingHandler<E, T>(PhantomData<(E, T)>);
impl<E: EthSpec + TypeName, T: EpochTransition<E>> Handler for EpochProcessingHandler<E, T> {
@@ -567,8 +581,8 @@ impl<E: EthSpec + TypeName> Handler for RewardsHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct ForkHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for ForkHandler<E> {
@@ -587,8 +601,8 @@ impl<E: EthSpec + TypeName> Handler for ForkHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct TransitionHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for TransitionHandler<E> {
@@ -607,8 +621,8 @@ impl<E: EthSpec + TypeName> Handler for TransitionHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct FinalityHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for FinalityHandler<E> {
@@ -691,8 +705,8 @@ impl<E: EthSpec + TypeName> Handler for ForkChoiceHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct OptimisticSyncHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for OptimisticSyncHandler<E> {
@@ -720,8 +734,8 @@ impl<E: EthSpec + TypeName> Handler for OptimisticSyncHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct GenesisValidityHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for GenesisValidityHandler<E> {
@@ -740,8 +754,8 @@ impl<E: EthSpec + TypeName> Handler for GenesisValidityHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct GenesisInitializationHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for GenesisInitializationHandler<E> {
@@ -760,8 +774,8 @@ impl<E: EthSpec + TypeName> Handler for GenesisInitializationHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGBlobToKZGCommitmentHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGBlobToKZGCommitmentHandler<E> {
@@ -780,8 +794,8 @@ impl<E: EthSpec> Handler for KZGBlobToKZGCommitmentHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGComputeBlobKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGComputeBlobKZGProofHandler<E> {
@@ -800,8 +814,8 @@ impl<E: EthSpec> Handler for KZGComputeBlobKZGProofHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGComputeKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGComputeKZGProofHandler<E> {
@@ -820,8 +834,8 @@ impl<E: EthSpec> Handler for KZGComputeKZGProofHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGVerifyBlobKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofHandler<E> {
@@ -840,8 +854,8 @@ impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGVerifyBlobKZGProofBatchHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofBatchHandler<E> {
@@ -860,8 +874,8 @@ impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofBatchHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGVerifyKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGVerifyKZGProofHandler<E> {
@@ -880,8 +894,8 @@ impl<E: EthSpec> Handler for KZGVerifyKZGProofHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct GetCustodyGroupsHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for GetCustodyGroupsHandler<E> {
@@ -898,14 +912,10 @@ impl<E: EthSpec + TypeName> Handler for GetCustodyGroupsHandler<E> {
fn handler_name(&self) -> String {
"get_custody_groups".into()
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct ComputeColumnsForCustodyGroupHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for ComputeColumnsForCustodyGroupHandler<E> {
@@ -922,14 +932,30 @@ impl<E: EthSpec + TypeName> Handler for ComputeColumnsForCustodyGroupHandler<E>
fn handler_name(&self) -> String {
"compute_columns_for_custody_group".into()
}
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
#[derive(Educe)]
#[educe(Default)]
pub struct KZGComputeCellsHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGComputeCellsHandler<E> {
type Case = cases::KZGComputeCells<E>;
fn config_name() -> &'static str {
"general"
}
fn runner_name() -> &'static str {
"kzg"
}
fn handler_name(&self) -> String {
"compute_cells".into()
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGComputeCellsAndKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGComputeCellsAndKZGProofHandler<E> {
@@ -946,14 +972,10 @@ impl<E: EthSpec> Handler for KZGComputeCellsAndKZGProofHandler<E> {
fn handler_name(&self) -> String {
"compute_cells_and_kzg_proofs".into()
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGVerifyCellKZGProofBatchHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGVerifyCellKZGProofBatchHandler<E> {
@@ -970,14 +992,10 @@ impl<E: EthSpec> Handler for KZGVerifyCellKZGProofBatchHandler<E> {
fn handler_name(&self) -> String {
"verify_cell_kzg_proof_batch".into()
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KZGRecoverCellsAndKZGProofHandler<E>(PhantomData<E>);
impl<E: EthSpec> Handler for KZGRecoverCellsAndKZGProofHandler<E> {
@@ -994,14 +1012,10 @@ impl<E: EthSpec> Handler for KZGRecoverCellsAndKZGProofHandler<E> {
fn handler_name(&self) -> String {
"recover_cells_and_kzg_proofs".into()
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct KzgInclusionMerkleProofValidityHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for KzgInclusionMerkleProofValidityHandler<E> {
@@ -1022,14 +1036,10 @@ impl<E: EthSpec + TypeName> Handler for KzgInclusionMerkleProofValidityHandler<E
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
fork_name.deneb_enabled()
}
fn is_enabled_for_feature(&self, feature_name: FeatureName) -> bool {
feature_name == FeatureName::Fulu
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct MerkleProofValidityHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for MerkleProofValidityHandler<E> {
@@ -1052,8 +1062,8 @@ impl<E: EthSpec + TypeName> Handler for MerkleProofValidityHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct LightClientUpdateHandler<E>(PhantomData<E>);
impl<E: EthSpec + TypeName> Handler for LightClientUpdateHandler<E> {
@@ -1077,8 +1087,8 @@ impl<E: EthSpec + TypeName> Handler for LightClientUpdateHandler<E> {
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct OperationsHandler<E, O>(PhantomData<(E, O)>);
impl<E: EthSpec + TypeName, O: Operation<E>> Handler for OperationsHandler<E, O> {
@@ -1097,8 +1107,8 @@ impl<E: EthSpec + TypeName, O: Operation<E>> Handler for OperationsHandler<E, O>
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derive(Educe)]
#[educe(Default)]
pub struct SszGenericHandler<H>(PhantomData<H>);
impl<H: TypeName> Handler for SszGenericHandler<H> {

View File

@@ -4,8 +4,8 @@ pub use cases::{
Case, EffectiveBalanceUpdates, Eth1DataReset, FeatureName, HistoricalRootsUpdate,
HistoricalSummariesUpdate, InactivityUpdates, JustificationAndFinalization,
ParticipationFlagUpdates, ParticipationRecordUpdates, PendingBalanceDeposits,
PendingConsolidations, RandaoMixesReset, RegistryUpdates, RewardsAndPenalties, Slashings,
SlashingsReset, SyncCommitteeUpdates,
PendingConsolidations, ProposerLookahead, RandaoMixesReset, RegistryUpdates,
RewardsAndPenalties, Slashings, SlashingsReset, SyncCommitteeUpdates,
};
pub use decode::log_file_access;
pub use error::Error;

View File

@@ -58,7 +58,7 @@ type_name_generic!(BeaconBlockBodyFulu, "BeaconBlockBody");
type_name!(BeaconBlockHeader);
type_name_generic!(BeaconState);
type_name!(BlobIdentifier);
type_name!(DataColumnsByRootIdentifier);
type_name_generic!(DataColumnsByRootIdentifier, "DataColumnsByRootIdentifier");
type_name_generic!(BlobSidecar);
type_name_generic!(DataColumnSidecar);
type_name!(Checkpoint);
@@ -76,6 +76,7 @@ type_name_generic!(ExecutionPayloadCapella, "ExecutionPayload");
type_name_generic!(ExecutionPayloadDeneb, "ExecutionPayload");
type_name_generic!(ExecutionPayloadElectra, "ExecutionPayload");
type_name_generic!(ExecutionPayloadFulu, "ExecutionPayload");
type_name_generic!(ExecutionPayloadEip7805, "ExecutionPayload");
type_name_generic!(FullPayload, "ExecutionPayload");
type_name_generic!(ExecutionPayloadHeader);
type_name_generic!(ExecutionPayloadHeaderBellatrix, "ExecutionPayloadHeader");
@@ -83,6 +84,7 @@ type_name_generic!(ExecutionPayloadHeaderCapella, "ExecutionPayloadHeader");
type_name_generic!(ExecutionPayloadHeaderDeneb, "ExecutionPayloadHeader");
type_name_generic!(ExecutionPayloadHeaderElectra, "ExecutionPayloadHeader");
type_name_generic!(ExecutionPayloadHeaderFulu, "ExecutionPayloadHeader");
type_name_generic!(ExecutionPayloadHeaderEip7805, "ExecutionPayloadHeader");
type_name_generic!(ExecutionRequests);
type_name_generic!(BlindedPayload, "ExecutionPayloadHeader");
type_name!(Fork);