Skip to content

Commit 2d9fc34

Browse files
authored
Fulu EF tests v1.6.0-alpha.0 (#7540)
Update to EF tests v1.6.0-alpha.0
1 parent 357a8cc commit 2d9fc34

File tree

21 files changed

+494
-167
lines changed

21 files changed

+494
-167
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

consensus/types/presets/minimal/electra.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ MAX_ATTESTATIONS_ELECTRA: 8
3232

3333
# Execution
3434
# ---------------------------------------------------------------
35-
# [customized] 2**2 (= 4) deposit requests
36-
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 4
37-
# [customized] 2**1 (= 2) withdrawal requests
38-
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2
35+
# 2**13 (= 8,192) deposit requests
36+
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 8192
37+
# 2**4 (= 16) withdrawal requests
38+
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 16
3939
# 2**1 (= 2) consolidation requests
4040
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 2
4141

consensus/types/src/data_column_sidecar.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ use crate::{
66
SignedBeaconBlockHeader, Slot,
77
};
88
use bls::Signature;
9+
use context_deserialize::ContextDeserialize;
910
use derivative::Derivative;
1011
use kzg::Error as KzgError;
1112
use kzg::{KzgCommitment, KzgProof};
1213
use merkle_proof::verify_merkle_proof;
1314
use safe_arith::ArithError;
14-
use serde::{Deserialize, Serialize};
15+
use serde::de::Error;
16+
use serde::{Deserialize, Deserializer, Serialize};
1517
use ssz::{DecodeError, Encode};
1618
use ssz_derive::{Decode, Encode};
1719
use ssz_types::Error as SszError;
@@ -26,12 +28,49 @@ pub type Cell<E> = FixedVector<u8, <E as EthSpec>::BytesPerCell>;
2628
pub type DataColumn<E> = VariableList<Cell<E>, <E as EthSpec>::MaxBlobCommitmentsPerBlock>;
2729

2830
/// Identifies a set of data columns associated with a specific beacon block.
29-
#[derive(Encode, Clone, Debug, PartialEq)]
31+
#[derive(Encode, Clone, Debug, PartialEq, TreeHash)]
3032
pub struct DataColumnsByRootIdentifier {
3133
pub block_root: Hash256,
3234
pub columns: RuntimeVariableList<ColumnIndex>,
3335
}
3436

37+
impl<'de> ContextDeserialize<'de, (ForkName, usize)> for DataColumnsByRootIdentifier {
38+
fn context_deserialize<D>(deserializer: D, context: (ForkName, usize)) -> Result<Self, D::Error>
39+
where
40+
D: Deserializer<'de>,
41+
{
42+
#[derive(Deserialize)]
43+
struct Helper {
44+
block_root: Hash256,
45+
columns: serde_json::Value,
46+
}
47+
48+
let helper = Helper::deserialize(deserializer)?;
49+
Ok(Self {
50+
block_root: helper.block_root,
51+
columns: RuntimeVariableList::context_deserialize(helper.columns, context)
52+
.map_err(Error::custom)?,
53+
})
54+
}
55+
}
56+
57+
impl DataColumnsByRootIdentifier {
58+
pub fn from_ssz_bytes(bytes: &[u8], num_columns: usize) -> Result<Self, DecodeError> {
59+
let mut builder = ssz::SszDecoderBuilder::new(bytes);
60+
builder.register_type::<Hash256>()?;
61+
builder.register_anonymous_variable_length_item()?;
62+
63+
let mut decoder = builder.build()?;
64+
let block_root = decoder.decode_next()?;
65+
let columns = decoder
66+
.decode_next_with(|bytes| RuntimeVariableList::from_ssz_bytes(bytes, num_columns))?;
67+
Ok(DataColumnsByRootIdentifier {
68+
block_root,
69+
columns,
70+
})
71+
}
72+
}
73+
3574
impl RuntimeVariableList<DataColumnsByRootIdentifier> {
3675
pub fn from_ssz_bytes_with_nested(
3776
bytes: &[u8],
@@ -47,21 +86,7 @@ impl RuntimeVariableList<DataColumnsByRootIdentifier> {
4786
Some(max_len),
4887
)?
4988
.into_iter()
50-
.map(|bytes| {
51-
let mut builder = ssz::SszDecoderBuilder::new(&bytes);
52-
builder.register_type::<Hash256>()?;
53-
builder.register_anonymous_variable_length_item()?;
54-
55-
let mut decoder = builder.build()?;
56-
let block_root = decoder.decode_next()?;
57-
let columns = decoder.decode_next_with(|bytes| {
58-
RuntimeVariableList::from_ssz_bytes(bytes, num_columns)
59-
})?;
60-
Ok(DataColumnsByRootIdentifier {
61-
block_root,
62-
columns,
63-
})
64-
})
89+
.map(|bytes| DataColumnsByRootIdentifier::from_ssz_bytes(&bytes, num_columns))
6590
.collect::<Result<Vec<_>, _>>()?;
6691

6792
Ok(RuntimeVariableList::from_vec(vec, max_len))

consensus/types/src/eth_spec.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,6 @@ impl EthSpec for MinimalEthSpec {
476476
type KzgCommitmentInclusionProofDepth = U10;
477477
type PendingPartialWithdrawalsLimit = U64;
478478
type PendingConsolidationsLimit = U64;
479-
type MaxDepositRequestsPerPayload = U4;
480-
type MaxWithdrawalRequestsPerPayload = U2;
481479
type FieldElementsPerCell = U64;
482480
type FieldElementsPerExtBlob = U8192;
483481
type MaxCellsPerBlock = U33554432;
@@ -509,7 +507,9 @@ impl EthSpec for MinimalEthSpec {
509507
MaxPendingDepositsPerEpoch,
510508
MaxConsolidationRequestsPerPayload,
511509
MaxAttesterSlashingsElectra,
512-
MaxAttestationsElectra
510+
MaxAttestationsElectra,
511+
MaxDepositRequestsPerPayload,
512+
MaxWithdrawalRequestsPerPayload
513513
});
514514

515515
fn default_spec() -> ChainSpec {

consensus/types/src/runtime_var_list.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use ssz::Decode;
66
use ssz_types::Error;
77
use std::ops::{Deref, Index, IndexMut};
88
use std::slice::SliceIndex;
9+
use tree_hash::{Hash256, MerkleHasher, PackedEncoding, TreeHash, TreeHashType};
910

1011
/// Emulates a SSZ `List`.
1112
///
@@ -241,6 +242,62 @@ where
241242
}
242243
}
243244

245+
impl<T: TreeHash> TreeHash for RuntimeVariableList<T> {
246+
fn tree_hash_type() -> tree_hash::TreeHashType {
247+
tree_hash::TreeHashType::List
248+
}
249+
250+
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
251+
unreachable!("List should never be packed.")
252+
}
253+
254+
fn tree_hash_packing_factor() -> usize {
255+
unreachable!("List should never be packed.")
256+
}
257+
258+
fn tree_hash_root(&self) -> Hash256 {
259+
let root = runtime_vec_tree_hash_root::<T>(&self.vec, self.max_len);
260+
261+
tree_hash::mix_in_length(&root, self.len())
262+
}
263+
}
264+
265+
// We can delete this once the upstream `vec_tree_hash_root` is modified to use a runtime max len.
266+
pub fn runtime_vec_tree_hash_root<T>(vec: &[T], max_len: usize) -> Hash256
267+
where
268+
T: TreeHash,
269+
{
270+
match T::tree_hash_type() {
271+
TreeHashType::Basic => {
272+
let mut hasher =
273+
MerkleHasher::with_leaves(max_len.div_ceil(T::tree_hash_packing_factor()));
274+
275+
for item in vec {
276+
hasher
277+
.write(&item.tree_hash_packed_encoding())
278+
.expect("ssz_types variable vec should not contain more elements than max");
279+
}
280+
281+
hasher
282+
.finish()
283+
.expect("ssz_types variable vec should not have a remaining buffer")
284+
}
285+
TreeHashType::Container | TreeHashType::List | TreeHashType::Vector => {
286+
let mut hasher = MerkleHasher::with_leaves(max_len);
287+
288+
for item in vec {
289+
hasher
290+
.write(item.tree_hash_root().as_slice())
291+
.expect("ssz_types vec should not contain more elements than max");
292+
}
293+
294+
hasher
295+
.finish()
296+
.expect("ssz_types vec should not have a remaining buffer")
297+
}
298+
}
299+
}
300+
244301
#[cfg(test)]
245302
mod test {
246303
use super::*;

testing/ef_tests/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = { workspace = true }
77
[features]
88
# `ef_tests` feature must be enabled to actually run the tests
99
ef_tests = []
10+
disable_rayon = []
1011
fake_crypto = ["bls/fake_crypto"]
1112
portable = ["beacon_chain/portable"]
1213

@@ -16,6 +17,8 @@ beacon_chain = { workspace = true }
1617
bls = { workspace = true }
1718
compare_fields = { workspace = true }
1819
compare_fields_derive = { workspace = true }
20+
context_deserialize = { workspace = true }
21+
context_deserialize_derive = { workspace = true }
1922
derivative = { workspace = true }
2023
eth2_network_config = { workspace = true }
2124
ethereum_ssz = { workspace = true }

testing/ef_tests/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
TESTS_TAG := v1.5.0-beta.4
1+
TESTS_TAG := v1.6.0-alpha.0
22
TESTS = general minimal mainnet
33
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))
44

testing/ef_tests/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ $ cargo test --features ef_tests
2828
The tests won't run without the `ef_tests` feature enabled (this is to ensure that a top-level
2929
`cargo test --all` won't fail on missing files).
3030

31+
The following is sometimes necessary to avoid stack overflow issues when running on MacOS:
32+
```
33+
$ export RUST_MIN_STACK=8388608
34+
```
35+
36+
When debugging failing tests, it's often useful to disable parallization and output suppression:
37+
```
38+
$ cargo test --features ef_tests,disable_rayon -- --nocapture
39+
```
40+
3141
## Saving Space
3242

3343
When you download the tests, the downloaded archives will be kept in addition to the extracted

testing/ef_tests/check_all_files_accessed.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@
4545
"bls12-381-tests/deserialization_G1",
4646
"bls12-381-tests/deserialization_G2",
4747
"bls12-381-tests/hash_to_G2",
48-
"tests/.*/eip6110",
49-
"tests/.*/whisk",
50-
# TODO(das): Fulu tests are ignored for now
51-
"tests/.*/fulu",
52-
"tests/.*/fulu/ssz_static/MatrixEntry",
53-
"tests/.*/eip7441",
5448
"tests/.*/eip7732",
49+
"tests/.*/eip7805",
50+
# Ignore MatrixEntry SSZ tests for now.
51+
"tests/.*/fulu/ssz_static/MatrixEntry/.*",
52+
# Ignore full epoch tests for now (just test the sub-transitions).
53+
"tests/.*/.*/epoch_processing/.*/pre_epoch.ssz_snappy",
54+
"tests/.*/.*/epoch_processing/.*/post_epoch.ssz_snappy",
5555
]
5656

5757

testing/ef_tests/src/cases.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ mod genesis_validity;
2222
mod get_custody_groups;
2323
mod kzg_blob_to_kzg_commitment;
2424
mod kzg_compute_blob_kzg_proof;
25+
mod kzg_compute_cells;
2526
mod kzg_compute_cells_and_kzg_proofs;
2627
mod kzg_compute_kzg_proof;
2728
mod kzg_recover_cells_and_kzg_proofs;
@@ -49,7 +50,7 @@ pub use bls_eth_fast_aggregate_verify::*;
4950
pub use bls_fast_aggregate_verify::*;
5051
pub use bls_sign_msg::*;
5152
pub use bls_verify_msg::*;
52-
pub use common::SszStaticType;
53+
pub use common::{DataColumnsByRootIdentifierWrapper, SszStaticType};
5354
pub use compute_columns_for_custody_groups::*;
5455
pub use epoch_processing::*;
5556
pub use fork::ForkTest;
@@ -58,6 +59,7 @@ pub use genesis_validity::*;
5859
pub use get_custody_groups::*;
5960
pub use kzg_blob_to_kzg_commitment::*;
6061
pub use kzg_compute_blob_kzg_proof::*;
62+
pub use kzg_compute_cells::*;
6163
pub use kzg_compute_cells_and_kzg_proofs::*;
6264
pub use kzg_compute_kzg_proof::*;
6365
pub use kzg_recover_cells_and_kzg_proofs::*;
@@ -91,29 +93,29 @@ pub use transition::TransitionTest;
9193
/// to return `true` for the feature in order for the feature test vector to be tested.
9294
#[derive(Debug, PartialEq, Clone, Copy)]
9395
pub enum FeatureName {
94-
// TODO(fulu): to be removed once we start using Fulu types for test vectors.
95-
// Existing SSZ types for PeerDAS (Fulu) are the same as Electra, so the test vectors get
96-
// loaded as Electra types (default serde behaviour for untagged enums).
97-
Fulu,
96+
// Placeholder for future feature-gated forks
97+
// Add new feature-gated forks here before they are incorporated into a main fork
98+
#[doc(hidden)]
99+
__Placeholder,
98100
}
99101

100102
impl FeatureName {
101103
pub fn list_all() -> Vec<FeatureName> {
102-
vec![FeatureName::Fulu]
104+
vec![]
103105
}
104106

105107
/// `ForkName` to use when running the feature tests.
106108
pub fn fork_name(&self) -> ForkName {
107109
match self {
108-
FeatureName::Fulu => ForkName::Electra,
110+
FeatureName::__Placeholder => unreachable!("Placeholder variant should never be used"),
109111
}
110112
}
111113
}
112114

113115
impl Display for FeatureName {
114-
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
116+
fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result {
115117
match self {
116-
FeatureName::Fulu => f.write_str("fulu"),
118+
FeatureName::__Placeholder => unreachable!("Placeholder variant should never be used"),
117119
}
118120
}
119121
}

0 commit comments

Comments
 (0)