mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-02 16:21:42 +00:00
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2576,6 +2576,8 @@ dependencies = [
|
||||
"bls",
|
||||
"compare_fields",
|
||||
"compare_fields_derive",
|
||||
"context_deserialize",
|
||||
"context_deserialize_derive",
|
||||
"derivative",
|
||||
"eth2_network_config",
|
||||
"ethereum_ssz",
|
||||
|
||||
@@ -32,10 +32,10 @@ MAX_ATTESTATIONS_ELECTRA: 8
|
||||
|
||||
# Execution
|
||||
# ---------------------------------------------------------------
|
||||
# [customized] 2**2 (= 4) deposit requests
|
||||
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 4
|
||||
# [customized] 2**1 (= 2) withdrawal requests
|
||||
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2
|
||||
# 2**13 (= 8,192) deposit requests
|
||||
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 8192
|
||||
# 2**4 (= 16) withdrawal requests
|
||||
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 16
|
||||
# 2**1 (= 2) consolidation requests
|
||||
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 2
|
||||
|
||||
|
||||
@@ -6,12 +6,14 @@ use crate::{
|
||||
SignedBeaconBlockHeader, Slot,
|
||||
};
|
||||
use bls::Signature;
|
||||
use context_deserialize::ContextDeserialize;
|
||||
use derivative::Derivative;
|
||||
use kzg::Error as KzgError;
|
||||
use kzg::{KzgCommitment, KzgProof};
|
||||
use merkle_proof::verify_merkle_proof;
|
||||
use safe_arith::ArithError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{DecodeError, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::Error as SszError;
|
||||
@@ -26,12 +28,49 @@ pub type Cell<E> = FixedVector<u8, <E as EthSpec>::BytesPerCell>;
|
||||
pub type DataColumn<E> = VariableList<Cell<E>, <E as EthSpec>::MaxBlobCommitmentsPerBlock>;
|
||||
|
||||
/// Identifies a set of data columns associated with a specific beacon block.
|
||||
#[derive(Encode, Clone, Debug, PartialEq)]
|
||||
#[derive(Encode, Clone, Debug, PartialEq, TreeHash)]
|
||||
pub struct DataColumnsByRootIdentifier {
|
||||
pub block_root: Hash256,
|
||||
pub columns: RuntimeVariableList<ColumnIndex>,
|
||||
}
|
||||
|
||||
impl<'de> ContextDeserialize<'de, (ForkName, usize)> for DataColumnsByRootIdentifier {
|
||||
fn context_deserialize<D>(deserializer: D, context: (ForkName, usize)) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
struct Helper {
|
||||
block_root: Hash256,
|
||||
columns: serde_json::Value,
|
||||
}
|
||||
|
||||
let helper = Helper::deserialize(deserializer)?;
|
||||
Ok(Self {
|
||||
block_root: helper.block_root,
|
||||
columns: RuntimeVariableList::context_deserialize(helper.columns, context)
|
||||
.map_err(Error::custom)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DataColumnsByRootIdentifier {
|
||||
pub fn from_ssz_bytes(bytes: &[u8], num_columns: usize) -> Result<Self, DecodeError> {
|
||||
let mut builder = ssz::SszDecoderBuilder::new(bytes);
|
||||
builder.register_type::<Hash256>()?;
|
||||
builder.register_anonymous_variable_length_item()?;
|
||||
|
||||
let mut decoder = builder.build()?;
|
||||
let block_root = decoder.decode_next()?;
|
||||
let columns = decoder
|
||||
.decode_next_with(|bytes| RuntimeVariableList::from_ssz_bytes(bytes, num_columns))?;
|
||||
Ok(DataColumnsByRootIdentifier {
|
||||
block_root,
|
||||
columns,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl RuntimeVariableList<DataColumnsByRootIdentifier> {
|
||||
pub fn from_ssz_bytes_with_nested(
|
||||
bytes: &[u8],
|
||||
@@ -47,21 +86,7 @@ impl RuntimeVariableList<DataColumnsByRootIdentifier> {
|
||||
Some(max_len),
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|bytes| {
|
||||
let mut builder = ssz::SszDecoderBuilder::new(&bytes);
|
||||
builder.register_type::<Hash256>()?;
|
||||
builder.register_anonymous_variable_length_item()?;
|
||||
|
||||
let mut decoder = builder.build()?;
|
||||
let block_root = decoder.decode_next()?;
|
||||
let columns = decoder.decode_next_with(|bytes| {
|
||||
RuntimeVariableList::from_ssz_bytes(bytes, num_columns)
|
||||
})?;
|
||||
Ok(DataColumnsByRootIdentifier {
|
||||
block_root,
|
||||
columns,
|
||||
})
|
||||
})
|
||||
.map(|bytes| DataColumnsByRootIdentifier::from_ssz_bytes(&bytes, num_columns))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(RuntimeVariableList::from_vec(vec, max_len))
|
||||
|
||||
@@ -476,8 +476,6 @@ impl EthSpec for MinimalEthSpec {
|
||||
type KzgCommitmentInclusionProofDepth = U10;
|
||||
type PendingPartialWithdrawalsLimit = U64;
|
||||
type PendingConsolidationsLimit = U64;
|
||||
type MaxDepositRequestsPerPayload = U4;
|
||||
type MaxWithdrawalRequestsPerPayload = U2;
|
||||
type FieldElementsPerCell = U64;
|
||||
type FieldElementsPerExtBlob = U8192;
|
||||
type MaxCellsPerBlock = U33554432;
|
||||
@@ -509,7 +507,9 @@ impl EthSpec for MinimalEthSpec {
|
||||
MaxPendingDepositsPerEpoch,
|
||||
MaxConsolidationRequestsPerPayload,
|
||||
MaxAttesterSlashingsElectra,
|
||||
MaxAttestationsElectra
|
||||
MaxAttestationsElectra,
|
||||
MaxDepositRequestsPerPayload,
|
||||
MaxWithdrawalRequestsPerPayload
|
||||
});
|
||||
|
||||
fn default_spec() -> ChainSpec {
|
||||
|
||||
@@ -6,6 +6,7 @@ use ssz::Decode;
|
||||
use ssz_types::Error;
|
||||
use std::ops::{Deref, Index, IndexMut};
|
||||
use std::slice::SliceIndex;
|
||||
use tree_hash::{Hash256, MerkleHasher, PackedEncoding, TreeHash, TreeHashType};
|
||||
|
||||
/// Emulates a SSZ `List`.
|
||||
///
|
||||
@@ -241,6 +242,62 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TreeHash> TreeHash for RuntimeVariableList<T> {
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
tree_hash::TreeHashType::List
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Hash256 {
|
||||
let root = runtime_vec_tree_hash_root::<T>(&self.vec, self.max_len);
|
||||
|
||||
tree_hash::mix_in_length(&root, self.len())
|
||||
}
|
||||
}
|
||||
|
||||
// We can delete this once the upstream `vec_tree_hash_root` is modified to use a runtime max len.
|
||||
pub fn runtime_vec_tree_hash_root<T>(vec: &[T], max_len: usize) -> Hash256
|
||||
where
|
||||
T: TreeHash,
|
||||
{
|
||||
match T::tree_hash_type() {
|
||||
TreeHashType::Basic => {
|
||||
let mut hasher =
|
||||
MerkleHasher::with_leaves(max_len.div_ceil(T::tree_hash_packing_factor()));
|
||||
|
||||
for item in vec {
|
||||
hasher
|
||||
.write(&item.tree_hash_packed_encoding())
|
||||
.expect("ssz_types variable vec should not contain more elements than max");
|
||||
}
|
||||
|
||||
hasher
|
||||
.finish()
|
||||
.expect("ssz_types variable vec should not have a remaining buffer")
|
||||
}
|
||||
TreeHashType::Container | TreeHashType::List | TreeHashType::Vector => {
|
||||
let mut hasher = MerkleHasher::with_leaves(max_len);
|
||||
|
||||
for item in vec {
|
||||
hasher
|
||||
.write(item.tree_hash_root().as_slice())
|
||||
.expect("ssz_types vec should not contain more elements than max");
|
||||
}
|
||||
|
||||
hasher
|
||||
.finish()
|
||||
.expect("ssz_types vec should not have a remaining buffer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = { workspace = true }
|
||||
[features]
|
||||
# `ef_tests` feature must be enabled to actually run the tests
|
||||
ef_tests = []
|
||||
disable_rayon = []
|
||||
fake_crypto = ["bls/fake_crypto"]
|
||||
portable = ["beacon_chain/portable"]
|
||||
|
||||
@@ -16,6 +17,8 @@ beacon_chain = { workspace = true }
|
||||
bls = { workspace = true }
|
||||
compare_fields = { workspace = true }
|
||||
compare_fields_derive = { workspace = true }
|
||||
context_deserialize = { workspace = true }
|
||||
context_deserialize_derive = { workspace = true }
|
||||
derivative = { workspace = true }
|
||||
eth2_network_config = { workspace = true }
|
||||
ethereum_ssz = { workspace = true }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
TESTS_TAG := v1.5.0-beta.4
|
||||
TESTS_TAG := v1.6.0-alpha.0
|
||||
TESTS = general minimal mainnet
|
||||
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))
|
||||
|
||||
|
||||
@@ -28,6 +28,16 @@ $ cargo test --features ef_tests
|
||||
The tests won't run without the `ef_tests` feature enabled (this is to ensure that a top-level
|
||||
`cargo test --all` won't fail on missing files).
|
||||
|
||||
The following is sometimes necessary to avoid stack overflow issues when running on MacOS:
|
||||
```
|
||||
$ export RUST_MIN_STACK=8388608
|
||||
```
|
||||
|
||||
When debugging failing tests, it's often useful to disable parallization and output suppression:
|
||||
```
|
||||
$ cargo test --features ef_tests,disable_rayon -- --nocapture
|
||||
```
|
||||
|
||||
## Saving Space
|
||||
|
||||
When you download the tests, the downloaded archives will be kept in addition to the extracted
|
||||
|
||||
@@ -45,13 +45,13 @@ excluded_paths = [
|
||||
"bls12-381-tests/deserialization_G1",
|
||||
"bls12-381-tests/deserialization_G2",
|
||||
"bls12-381-tests/hash_to_G2",
|
||||
"tests/.*/eip6110",
|
||||
"tests/.*/whisk",
|
||||
# TODO(das): Fulu tests are ignored for now
|
||||
"tests/.*/fulu",
|
||||
"tests/.*/fulu/ssz_static/MatrixEntry",
|
||||
"tests/.*/eip7441",
|
||||
"tests/.*/eip7732",
|
||||
"tests/.*/eip7805",
|
||||
# Ignore MatrixEntry SSZ tests for now.
|
||||
"tests/.*/fulu/ssz_static/MatrixEntry/.*",
|
||||
# Ignore full epoch tests for now (just test the sub-transitions).
|
||||
"tests/.*/.*/epoch_processing/.*/pre_epoch.ssz_snappy",
|
||||
"tests/.*/.*/epoch_processing/.*/post_epoch.ssz_snappy",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -49,7 +50,7 @@ pub use bls_eth_fast_aggregate_verify::*;
|
||||
pub use bls_fast_aggregate_verify::*;
|
||||
pub use bls_sign_msg::*;
|
||||
pub use bls_verify_msg::*;
|
||||
pub use common::SszStaticType;
|
||||
pub use common::{DataColumnsByRootIdentifierWrapper, SszStaticType};
|
||||
pub use compute_columns_for_custody_groups::*;
|
||||
pub use epoch_processing::*;
|
||||
pub use fork::ForkTest;
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
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;
|
||||
use std::marker::PhantomData;
|
||||
use tree_hash::TreeHash;
|
||||
use types::{DataColumnsByRootIdentifier, EthSpec, ForkName, Hash256};
|
||||
|
||||
/// Macro to wrap U128 and U256 so they deserialize correctly.
|
||||
macro_rules! uint_wrapper {
|
||||
@@ -40,6 +43,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,26 +59,63 @@ 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: Encode + Clone + PartialEq + Debug + Sync {}
|
||||
|
||||
/// We need the `EthSpec` to implement `LoadCase` for this type, in order to work out the
|
||||
/// ChainSpec.
|
||||
///
|
||||
/// No other type currently requires this kind of context.
|
||||
#[derive(Debug, Encode, Clone, PartialEq)]
|
||||
#[ssz(struct_behaviour = "transparent")]
|
||||
pub struct DataColumnsByRootIdentifierWrapper<E: EthSpec> {
|
||||
pub value: DataColumnsByRootIdentifier,
|
||||
// SSZ derive is a bit buggy and requires skip_deserializing for transparent to work.
|
||||
#[ssz(skip_serializing, skip_deserializing)]
|
||||
pub _phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<T> SszStaticType for T where
|
||||
T: serde::de::DeserializeOwned + Encode + Clone + PartialEq + Debug + Sync
|
||||
impl<'de, E: EthSpec> ContextDeserialize<'de, (ForkName, usize)>
|
||||
for DataColumnsByRootIdentifierWrapper<E>
|
||||
{
|
||||
fn context_deserialize<D>(deserializer: D, context: (ForkName, usize)) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let value = DataColumnsByRootIdentifier::context_deserialize(deserializer, context)?;
|
||||
Ok(DataColumnsByRootIdentifierWrapper {
|
||||
value,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// 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::Fulu => ForkName::Electra,
|
||||
// We can delete this if we ever get `tree_hash(struct_behaviour = "transparent")`.
|
||||
impl<E: EthSpec> TreeHash for DataColumnsByRootIdentifierWrapper<E> {
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
DataColumnsByRootIdentifier::tree_hash_type()
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> tree_hash::PackedEncoding {
|
||||
self.value.tree_hash_packed_encoding()
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
DataColumnsByRootIdentifier::tree_hash_packing_factor()
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Hash256 {
|
||||
self.value.tree_hash_root()
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> From<DataColumnsByRootIdentifier> for DataColumnsByRootIdentifierWrapper<E> {
|
||||
fn from(value: DataColumnsByRootIdentifier) -> Self {
|
||||
Self {
|
||||
value,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
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::{
|
||||
@@ -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.
|
||||
|
||||
54
testing/ef_tests/src/cases/kzg_compute_cells.rs
Normal file
54
testing/ef_tests/src/cases/kzg_compute_cells.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,11 @@ use state_processing::{
|
||||
ConsensusContext,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
use std::path::PathBuf;
|
||||
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,
|
||||
};
|
||||
@@ -49,6 +50,7 @@ pub struct WithdrawalsPayload<E: EthSpec> {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Operations<E: EthSpec, O: Operation<E>> {
|
||||
path: PathBuf,
|
||||
metadata: Metadata,
|
||||
execution_metadata: Option<ExecutionMetadata>,
|
||||
pub pre: BeaconState<E>,
|
||||
@@ -357,8 +359,8 @@ 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())
|
||||
}
|
||||
_ => panic!(),
|
||||
})
|
||||
@@ -555,6 +557,7 @@ impl<E: EthSpec, O: Operation<E>> LoadCase for Operations<E, O> {
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
path: path.into(),
|
||||
metadata,
|
||||
execution_metadata,
|
||||
pre,
|
||||
@@ -574,6 +577,17 @@ impl<E: EthSpec, O: Operation<E>> Case for Operations<E, O> {
|
||||
}
|
||||
|
||||
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
|
||||
// FIXME(das): remove this once v1.6.0-alpha.1 is released
|
||||
// We are ahead of the v1.6.0-alpha.0 spec in our implementation of
|
||||
// `get_max_blobs_per_block`, so we fail the execution payload test which expects the
|
||||
// empty blob schedule to generate an error.
|
||||
if O::handler_name() == "execution_payload"
|
||||
&& fork_name == ForkName::Fulu
|
||||
&& self.path.ends_with("invalid_exceed_max_blobs_per_block")
|
||||
{
|
||||
return Err(Error::SkippedKnownFailure);
|
||||
}
|
||||
|
||||
let spec = &testing_spec::<E>(fork_name);
|
||||
|
||||
let mut pre_state = self.pre.clone();
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
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 crate::decode::{context_yaml_decode_file, log_file_access, snappy_decode_file};
|
||||
use context_deserialize::ContextDeserialize;
|
||||
use context_deserialize_derive::context_deserialize;
|
||||
use serde::{de::Error as SerdeError, Deserialize, Deserializer};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use tree_hash::TreeHash;
|
||||
@@ -12,6 +14,7 @@ use types::typenum::*;
|
||||
use types::{BitList, BitVector, FixedVector, ForkName, VariableList, Vector};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[context_deserialize(ForkName)]
|
||||
struct Metadata {
|
||||
root: String,
|
||||
#[serde(rename(deserialize = "signing_root"))]
|
||||
@@ -118,7 +121,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 +137,7 @@ impl Case for SszGeneric {
|
||||
|
||||
type_dispatch!(
|
||||
ssz_generic_test,
|
||||
(&self.path),
|
||||
(&self.path, fork_name),
|
||||
Vector,
|
||||
<>,
|
||||
[elem_ty => primitive_type]
|
||||
@@ -142,7 +145,7 @@ impl Case for SszGeneric {
|
||||
)?;
|
||||
type_dispatch!(
|
||||
ssz_generic_test,
|
||||
(&self.path),
|
||||
(&self.path, fork_name),
|
||||
FixedVector,
|
||||
<>,
|
||||
[elem_ty => primitive_type]
|
||||
@@ -159,7 +162,7 @@ impl Case for SszGeneric {
|
||||
|
||||
type_dispatch!(
|
||||
ssz_generic_test,
|
||||
(&self.path),
|
||||
(&self.path, fork_name),
|
||||
BitList,
|
||||
<>,
|
||||
[limit => typenum]
|
||||
@@ -170,21 +173,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 +198,7 @@ impl Case for SszGeneric {
|
||||
|
||||
type_dispatch!(
|
||||
ssz_generic_test,
|
||||
(&self.path),
|
||||
(&self.path, fork_name),
|
||||
_,
|
||||
<>,
|
||||
[type_name => test_container]
|
||||
@@ -207,10 +210,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 +228,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 +254,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 +275,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 +283,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 +296,7 @@ struct ComplexTestStruct {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Decode, Encode, TreeHash, Deserialize)]
|
||||
#[context_deserialize(ForkName)]
|
||||
struct BitsStruct {
|
||||
A: BitList<U5>,
|
||||
B: BitVector<U2>,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use super::*;
|
||||
use crate::case_result::compare_result;
|
||||
use crate::decode::{snappy_decode_file, yaml_decode_file};
|
||||
use crate::cases::common::DataColumnsByRootIdentifierWrapper;
|
||||
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 +39,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 +68,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 +126,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 +147,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 +167,27 @@ impl<E: EthSpec> Case for SszStaticWithSpec<SignedBeaconBlock<E>> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> LoadCase for SszStaticWithSpec<DataColumnsByRootIdentifierWrapper<E>> {
|
||||
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
|
||||
let spec = &testing_spec::<E>(fork_name);
|
||||
let context = (fork_name, spec.number_of_columns as usize);
|
||||
load_from_dir_with_context(path, context).map(|(roots, serialized, value)| Self {
|
||||
roots,
|
||||
serialized,
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Case for SszStaticWithSpec<DataColumnsByRootIdentifierWrapper<E>> {
|
||||
fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> {
|
||||
let spec = &testing_spec::<E>(fork_name);
|
||||
check_serialization(&self.value, &self.serialized, |bytes| {
|
||||
DataColumnsByRootIdentifier::from_ssz_bytes(bytes, spec.number_of_columns as usize)
|
||||
.map(Into::into)
|
||||
})?;
|
||||
check_tree_hash(&self.roots.root, self.value.tree_hash_root().as_slice())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::cases::{self, Case, Cases, EpochTransition, LoadCase, Operation};
|
||||
use crate::type_name::TypeName;
|
||||
use crate::{type_name, FeatureName};
|
||||
use context_deserialize::ContextDeserialize;
|
||||
use derivative::Derivative;
|
||||
use std::fs::{self, DirEntry};
|
||||
use std::marker::PhantomData;
|
||||
@@ -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![]
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -85,7 +99,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!(
|
||||
"{}/{}/{}",
|
||||
@@ -127,7 +141,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!(
|
||||
"{}/{}/{}",
|
||||
@@ -205,7 +219,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!(
|
||||
"{}/{}/{}",
|
||||
@@ -327,13 +341,37 @@ impl<T, E> SszStaticHandler<T, E> {
|
||||
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 +391,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 +410,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,8 +432,8 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -898,10 +913,6 @@ 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)]
|
||||
@@ -922,9 +933,25 @@ 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(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -946,10 +973,6 @@ 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)]
|
||||
@@ -970,10 +993,6 @@ 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)]
|
||||
@@ -994,10 +1013,6 @@ 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)]
|
||||
@@ -1022,10 +1037,6 @@ 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)]
|
||||
@@ -1073,7 +1084,8 @@ impl<E: EthSpec + TypeName> Handler for LightClientUpdateHandler<E> {
|
||||
|
||||
fn is_enabled_for_fork(&self, fork_name: ForkName) -> bool {
|
||||
// Enabled in Altair
|
||||
fork_name.altair_enabled()
|
||||
// No test in Fulu yet.
|
||||
fork_name.altair_enabled() && fork_name != ForkName::Fulu
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
pub use case_result::CaseResult;
|
||||
pub use cases::WithdrawalsPayload;
|
||||
pub use cases::{
|
||||
Case, EffectiveBalanceUpdates, Eth1DataReset, FeatureName, HistoricalRootsUpdate,
|
||||
HistoricalSummariesUpdate, InactivityUpdates, JustificationAndFinalization,
|
||||
ParticipationFlagUpdates, ParticipationRecordUpdates, PendingBalanceDeposits,
|
||||
PendingConsolidations, RandaoMixesReset, RegistryUpdates, RewardsAndPenalties, Slashings,
|
||||
SlashingsReset, SyncCommitteeUpdates,
|
||||
Case, DataColumnsByRootIdentifierWrapper, EffectiveBalanceUpdates, Eth1DataReset, FeatureName,
|
||||
HistoricalRootsUpdate, HistoricalSummariesUpdate, InactivityUpdates,
|
||||
JustificationAndFinalization, ParticipationFlagUpdates, ParticipationRecordUpdates,
|
||||
PendingBalanceDeposits, PendingConsolidations, RandaoMixesReset, RegistryUpdates,
|
||||
RewardsAndPenalties, Slashings, SlashingsReset, SyncCommitteeUpdates,
|
||||
};
|
||||
pub use decode::log_file_access;
|
||||
pub use error::Error;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//! Mapping from types to canonical string identifiers used in testing.
|
||||
use crate::DataColumnsByRootIdentifierWrapper;
|
||||
use types::historical_summary::HistoricalSummary;
|
||||
use types::*;
|
||||
|
||||
@@ -59,6 +60,10 @@ type_name!(BeaconBlockHeader);
|
||||
type_name_generic!(BeaconState);
|
||||
type_name!(BlobIdentifier);
|
||||
type_name!(DataColumnsByRootIdentifier);
|
||||
type_name_generic!(
|
||||
DataColumnsByRootIdentifierWrapper,
|
||||
"DataColumnsByRootIdentifier"
|
||||
);
|
||||
type_name_generic!(BlobSidecar);
|
||||
type_name_generic!(DataColumnSidecar);
|
||||
type_name!(Checkpoint);
|
||||
|
||||
@@ -238,7 +238,8 @@ macro_rules! ssz_static_test_no_run {
|
||||
#[cfg(feature = "fake_crypto")]
|
||||
mod ssz_static {
|
||||
use ef_tests::{
|
||||
FeatureName, Handler, SszStaticHandler, SszStaticTHCHandler, SszStaticWithSpecHandler,
|
||||
DataColumnsByRootIdentifierWrapper, Handler, SszStaticHandler, SszStaticTHCHandler,
|
||||
SszStaticWithSpecHandler,
|
||||
};
|
||||
use types::historical_summary::HistoricalSummary;
|
||||
use types::{
|
||||
@@ -660,20 +661,24 @@ mod ssz_static {
|
||||
|
||||
#[test]
|
||||
fn data_column_sidecar() {
|
||||
SszStaticHandler::<DataColumnSidecar<MinimalEthSpec>, MinimalEthSpec>::default()
|
||||
.run_for_feature(FeatureName::Fulu);
|
||||
SszStaticHandler::<DataColumnSidecar<MainnetEthSpec>, MainnetEthSpec>::default()
|
||||
.run_for_feature(FeatureName::Fulu);
|
||||
SszStaticHandler::<DataColumnSidecar<MinimalEthSpec>, MinimalEthSpec>::fulu_and_later()
|
||||
.run();
|
||||
SszStaticHandler::<DataColumnSidecar<MainnetEthSpec>, MainnetEthSpec>::fulu_and_later()
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
// TODO(das): enable once EF tests are updated to latest release.
|
||||
fn data_column_by_root_identifier() {
|
||||
// SszStaticHandler::<DataColumnsByRootIdentifier, MinimalEthSpec>::default()
|
||||
// .run_for_feature(FeatureName::Fulu);
|
||||
// SszStaticHandler::<DataColumnsByRootIdentifier, MainnetEthSpec>::default()
|
||||
// .run_for_feature(FeatureName::Fulu);
|
||||
SszStaticWithSpecHandler::<
|
||||
DataColumnsByRootIdentifierWrapper<MinimalEthSpec>,
|
||||
MinimalEthSpec,
|
||||
>::fulu_and_later()
|
||||
.run();
|
||||
SszStaticWithSpecHandler::<
|
||||
DataColumnsByRootIdentifierWrapper<MainnetEthSpec>,
|
||||
MainnetEthSpec,
|
||||
>::fulu_and_later()
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -941,6 +946,11 @@ fn kzg_verify_kzg_proof() {
|
||||
KZGVerifyKZGProofHandler::<MainnetEthSpec>::default().run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kzg_compute_cells() {
|
||||
KZGComputeCellsHandler::<MainnetEthSpec>::default().run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kzg_compute_cells_and_proofs() {
|
||||
KZGComputeCellsAndKZGProofHandler::<MainnetEthSpec>::default().run();
|
||||
|
||||
Reference in New Issue
Block a user