diff --git a/beacon_node/beacon_chain/benches/benches.rs b/beacon_node/beacon_chain/benches/benches.rs index c005ebb91a..5c56594317 100644 --- a/beacon_node/beacon_chain/benches/benches.rs +++ b/beacon_node/beacon_chain/benches/benches.rs @@ -7,7 +7,7 @@ use criterion::{Criterion, black_box, criterion_group, criterion_main}; use bls::Signature; use kzg::{KzgCommitment, KzgProof}; use types::{ - BeaconBlock, BeaconBlockDeneb, Blob, BlobsList, ChainSpec, EmptyBlock, EthSpec, KzgProofs, + BeaconBlock, BeaconBlockFulu, Blob, BlobsList, ChainSpec, EmptyBlock, EthSpec, KzgProofs, MainnetEthSpec, SignedBeaconBlock, beacon_block_body::KzgCommitments, }; @@ -15,7 +15,7 @@ fn create_test_block_and_blobs( num_of_blobs: usize, spec: &ChainSpec, ) -> (SignedBeaconBlock, BlobsList, KzgProofs) { - let mut block = BeaconBlock::Deneb(BeaconBlockDeneb::empty(spec)); + let mut block = BeaconBlock::Fulu(BeaconBlockFulu::empty(spec)); let mut body = block.body_mut(); let blob_kzg_commitments = body.blob_kzg_commitments_mut().unwrap(); *blob_kzg_commitments = @@ -27,7 +27,7 @@ fn create_test_block_and_blobs( .map(|_| Blob::::default()) .collect::>() .into(); - let proofs = vec![KzgProof::empty(); num_of_blobs * spec.number_of_columns as usize].into(); + let proofs = vec![KzgProof::empty(); num_of_blobs * E::number_of_columns()].into(); (signed_block, blobs, proofs) } diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 14ddc021b8..47d47314f3 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -1247,8 +1247,8 @@ impl BeaconChain { if self.spec.is_peer_das_enabled_for_epoch(block.epoch()) { if let Some(columns) = self.store.get_data_columns(block_root)? { - let num_required_columns = self.spec.number_of_columns / 2; - let reconstruction_possible = columns.len() >= num_required_columns as usize; + let num_required_columns = T::EthSpec::number_of_columns() / 2; + let reconstruction_possible = columns.len() >= num_required_columns; if reconstruction_possible { reconstruct_blobs(&self.kzg, &columns, None, &block, &self.spec) .map(Some) diff --git a/beacon_node/beacon_chain/src/block_verification_types.rs b/beacon_node/beacon_chain/src/block_verification_types.rs index 5841eacf58..1a0b188fdc 100644 --- a/beacon_node/beacon_chain/src/block_verification_types.rs +++ b/beacon_node/beacon_chain/src/block_verification_types.rs @@ -3,13 +3,14 @@ pub use crate::data_availability_checker::{AvailableBlock, MaybeAvailableBlock}; use crate::data_column_verification::{CustodyDataColumn, CustodyDataColumnList}; use crate::{PayloadVerificationOutcome, get_block_root}; use derivative::Derivative; +use ssz_types::VariableList; use state_processing::ConsensusContext; use std::fmt::{Debug, Formatter}; use std::sync::Arc; use types::blob_sidecar::BlobIdentifier; use types::{ - BeaconBlockRef, BeaconState, BlindedPayload, BlobSidecarList, ChainSpec, Epoch, EthSpec, - Hash256, RuntimeVariableList, SignedBeaconBlock, SignedBeaconBlockHeader, Slot, + BeaconBlockRef, BeaconState, BlindedPayload, BlobSidecarList, Epoch, EthSpec, Hash256, + SignedBeaconBlock, SignedBeaconBlockHeader, Slot, }; /// A block that has been received over RPC. It has 2 internal variants: @@ -151,7 +152,6 @@ impl RpcBlock { block_root: Option, block: Arc>, custody_columns: Vec>, - spec: &ChainSpec, ) -> Result { let block_root = block_root.unwrap_or_else(|| get_block_root(&block)); @@ -161,10 +161,7 @@ impl RpcBlock { } // Treat empty data column lists as if they are missing. let inner = if !custody_columns.is_empty() { - RpcBlockInner::BlockAndCustodyColumns( - block, - RuntimeVariableList::new(custody_columns, spec.number_of_columns as usize)?, - ) + RpcBlockInner::BlockAndCustodyColumns(block, VariableList::new(custody_columns)?) } else { RpcBlockInner::Block(block) }; diff --git a/beacon_node/beacon_chain/src/data_availability_checker.rs b/beacon_node/beacon_chain/src/data_availability_checker.rs index 9918ec585a..37c408f9f1 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker.rs @@ -446,7 +446,7 @@ impl DataAvailabilityChecker { .map(CustodyDataColumn::into_inner) .collect::>(); let all_data_columns = - RuntimeVariableList::from_vec(all_data_columns, self.spec.number_of_columns as usize); + RuntimeVariableList::from_vec(all_data_columns, T::EthSpec::number_of_columns()); // verify kzg for all data columns at once if !all_data_columns.is_empty() { diff --git a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs index bc2b217535..019849e724 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs @@ -591,7 +591,7 @@ impl DataAvailabilityCheckerInner { }; // If we're sampling all columns, it means we must be custodying all columns. - let total_column_count = self.spec.number_of_columns as usize; + let total_column_count = T::EthSpec::number_of_columns(); let received_column_count = pending_components.verified_data_columns.len(); if pending_components.reconstruction_started { diff --git a/beacon_node/beacon_chain/src/data_column_verification.rs b/beacon_node/beacon_chain/src/data_column_verification.rs index 3b444860e0..873627abea 100644 --- a/beacon_node/beacon_chain/src/data_column_verification.rs +++ b/beacon_node/beacon_chain/src/data_column_verification.rs @@ -12,6 +12,7 @@ use kzg::{Error as KzgError, Kzg}; use proto_array::Block; use slot_clock::SlotClock; use ssz_derive::{Decode, Encode}; +use ssz_types::VariableList; use std::iter; use std::marker::PhantomData; use std::sync::Arc; @@ -19,7 +20,7 @@ use tracing::{debug, instrument}; use types::data_column_sidecar::ColumnIndex; use types::{ BeaconStateError, ChainSpec, DataColumnSidecar, DataColumnSubnetId, EthSpec, Hash256, - RuntimeVariableList, SignedBeaconBlockHeader, Slot, + SignedBeaconBlockHeader, Slot, }; /// An error occurred while validating a gossip data column. @@ -315,7 +316,8 @@ impl KzgVerifiedDataColumn { } } -pub type CustodyDataColumnList = RuntimeVariableList>; +pub type CustodyDataColumnList = + VariableList, ::NumberOfColumns>; /// Data column that we must custody #[derive(Debug, Derivative, Clone, Encode, Decode)] @@ -479,7 +481,7 @@ pub fn validate_data_column_sidecar_for_gossip, ) -> Result, GossipDataColumnError> { let column_slot = data_column.slot(); - verify_data_column_sidecar(&data_column, &chain.spec)?; + verify_data_column_sidecar(&data_column)?; verify_index_matches_subnet(&data_column, subnet, &chain.spec)?; verify_sidecar_not_from_future_slot(chain, column_slot)?; verify_slot_greater_than_latest_finalized_slot(chain, column_slot)?; @@ -533,9 +535,8 @@ pub fn validate_data_column_sidecar_for_gossip( data_column: &DataColumnSidecar, - spec: &ChainSpec, ) -> Result<(), GossipDataColumnError> { - if data_column.index >= spec.number_of_columns { + if data_column.index >= E::number_of_columns() as u64 { return Err(GossipDataColumnError::InvalidColumnIndex(data_column.index)); } if data_column.kzg_commitments.is_empty() { diff --git a/beacon_node/beacon_chain/src/kzg_utils.rs b/beacon_node/beacon_chain/src/kzg_utils.rs index 02c2f320dc..2c99ca4b07 100644 --- a/beacon_node/beacon_chain/src/kzg_utils.rs +++ b/beacon_node/beacon_chain/src/kzg_utils.rs @@ -185,7 +185,7 @@ pub fn blobs_to_data_column_sidecars( let signed_block_header = block.signed_block_header(); let proof_chunks = cell_proofs - .chunks_exact(spec.number_of_columns as usize) + .chunks_exact(E::number_of_columns()) .collect::>(); // NOTE: assumes blob sidecars are ordered by index @@ -243,7 +243,7 @@ pub(crate) fn build_data_column_sidecars( blob_cells_and_proofs_vec: Vec, spec: &ChainSpec, ) -> Result, String> { - let number_of_columns = spec.number_of_columns as usize; + let number_of_columns = E::number_of_columns(); let max_blobs_per_block = spec .max_blobs_per_block(signed_block_header.message.slot.epoch(E::slots_per_epoch())) as usize; @@ -495,7 +495,7 @@ mod test { .kzg_commitments_merkle_proof() .unwrap(); - assert_eq!(column_sidecars.len(), spec.number_of_columns as usize); + assert_eq!(column_sidecars.len(), E::number_of_columns()); for (idx, col_sidecar) in column_sidecars.iter().enumerate() { assert_eq!(col_sidecar.index, idx as u64); @@ -530,7 +530,7 @@ mod test { ) .unwrap(); - for i in 0..spec.number_of_columns as usize { + for i in 0..E::number_of_columns() { assert_eq!(reconstructed_columns.get(i), column_sidecars.get(i), "{i}"); } } diff --git a/beacon_node/beacon_chain/src/observed_data_sidecars.rs b/beacon_node/beacon_chain/src/observed_data_sidecars.rs index a2141a1697..46a3678f16 100644 --- a/beacon_node/beacon_chain/src/observed_data_sidecars.rs +++ b/beacon_node/beacon_chain/src/observed_data_sidecars.rs @@ -58,8 +58,8 @@ impl ObservableDataSidecar for DataColumnSidecar { self.index } - fn max_num_of_items(spec: &ChainSpec, _slot: Slot) -> usize { - spec.number_of_columns as usize + fn max_num_of_items(_spec: &ChainSpec, _slot: Slot) -> usize { + E::number_of_columns() } } diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 569dd72954..8e45ec88b4 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -2358,8 +2358,7 @@ where .into_iter() .map(CustodyDataColumn::from_asserted_custody) .collect::>(); - RpcBlock::new_with_custody_columns(Some(block_root), block, custody_columns, &self.spec) - .unwrap() + RpcBlock::new_with_custody_columns(Some(block_root), block, custody_columns).unwrap() } else { let blobs = self.chain.get_blobs(&block_root).unwrap().blobs(); RpcBlock::new(Some(block_root), block, blobs).unwrap() @@ -2386,7 +2385,7 @@ where .filter(|d| sampling_columns.contains(&d.index)) .map(CustodyDataColumn::from_asserted_custody) .collect::>(); - RpcBlock::new_with_custody_columns(Some(block_root), block, columns, &self.spec)? + RpcBlock::new_with_custody_columns(Some(block_root), block, columns)? } else { RpcBlock::new_without_blobs(Some(block_root), block) } @@ -3310,7 +3309,7 @@ fn generate_data_column_sidecars_from_block( // load the precomputed column sidecar to avoid computing them for every block in the tests. let template_data_columns = RuntimeVariableList::>::from_ssz_bytes( TEST_DATA_COLUMN_SIDECARS_SSZ, - spec.number_of_columns as usize, + E::number_of_columns(), ) .unwrap(); diff --git a/beacon_node/beacon_chain/src/validator_custody.rs b/beacon_node/beacon_chain/src/validator_custody.rs index 3531fc33c1..b8853362b8 100644 --- a/beacon_node/beacon_chain/src/validator_custody.rs +++ b/beacon_node/beacon_chain/src/validator_custody.rs @@ -197,7 +197,7 @@ impl CustodyContext { ) -> Result<(), String> { let mut ordered_custody_columns = vec![]; for custody_index in all_custody_groups_ordered { - let columns = compute_columns_for_custody_group(custody_index, spec) + let columns = compute_columns_for_custody_group::(custody_index, spec) .map_err(|e| format!("Failed to compute columns for custody group {e:?}"))?; ordered_custody_columns.extend(columns); } @@ -303,7 +303,7 @@ impl CustodyContext { /// Returns the count of columns this node must _sample_ for a block at `epoch` to import. pub fn num_of_data_columns_to_sample(&self, epoch: Epoch, spec: &ChainSpec) -> usize { let custody_group_count = self.custody_group_count_at_epoch(epoch, spec); - spec.sampling_size_columns(custody_group_count) + spec.sampling_size_columns::(custody_group_count) .expect("should compute node sampling size from valid chain spec") } @@ -641,7 +641,7 @@ mod tests { let expected_sampling_columns = &all_custody_groups_ordered .iter() .flat_map(|custody_index| { - compute_columns_for_custody_group(*custody_index, &spec) + compute_columns_for_custody_group::(*custody_index, &spec) .expect("should compute columns for custody group") }) .collect::>()[0..sampling_size]; diff --git a/beacon_node/beacon_chain/tests/block_verification.rs b/beacon_node/beacon_chain/tests/block_verification.rs index 2afae10e96..a93dda1080 100644 --- a/beacon_node/beacon_chain/tests/block_verification.rs +++ b/beacon_node/beacon_chain/tests/block_verification.rs @@ -121,14 +121,13 @@ fn get_harness(validator_count: usize) -> BeaconChainHarness], chain_segment_sidecars: &[Option>], - spec: &ChainSpec, ) -> Vec> { chain_segment .iter() .zip(chain_segment_sidecars.iter()) .map(|(snapshot, data_sidecars)| { let block = snapshot.beacon_block.clone(); - build_rpc_block(block, data_sidecars, spec) + build_rpc_block(block, data_sidecars) }) .collect() } @@ -136,14 +135,13 @@ fn chain_segment_blocks( fn build_rpc_block( block: Arc>, data_sidecars: &Option>, - spec: &ChainSpec, ) -> RpcBlock { match data_sidecars { Some(DataSidecars::Blobs(blobs)) => { RpcBlock::new(None, block, Some(blobs.clone())).unwrap() } Some(DataSidecars::DataColumns(columns)) => { - RpcBlock::new_with_custody_columns(None, block, columns.clone(), spec).unwrap() + RpcBlock::new_with_custody_columns(None, block, columns.clone()).unwrap() } None => RpcBlock::new_without_blobs(None, block), } @@ -256,10 +254,9 @@ fn update_data_column_signed_header( async fn chain_segment_full_segment() { let harness = get_harness(VALIDATOR_COUNT); let (chain_segment, chain_segment_blobs) = get_chain_segment().await; - let blocks: Vec> = - chain_segment_blocks(&chain_segment, &chain_segment_blobs, &harness.spec) - .into_iter() - .collect(); + let blocks: Vec> = chain_segment_blocks(&chain_segment, &chain_segment_blobs) + .into_iter() + .collect(); harness .chain @@ -295,10 +292,9 @@ async fn chain_segment_varying_chunk_size() { for chunk_size in &[1, 2, 3, 5, 31, 32, 33, 42] { let harness = get_harness(VALIDATOR_COUNT); let (chain_segment, chain_segment_blobs) = get_chain_segment().await; - let blocks: Vec> = - chain_segment_blocks(&chain_segment, &chain_segment_blobs, &harness.spec) - .into_iter() - .collect(); + let blocks: Vec> = chain_segment_blocks(&chain_segment, &chain_segment_blobs) + .into_iter() + .collect(); harness .chain @@ -337,10 +333,9 @@ async fn chain_segment_non_linear_parent_roots() { /* * Test with a block removed. */ - let mut blocks: Vec> = - chain_segment_blocks(&chain_segment, &chain_segment_blobs, &harness.spec) - .into_iter() - .collect(); + let mut blocks: Vec> = chain_segment_blocks(&chain_segment, &chain_segment_blobs) + .into_iter() + .collect(); blocks.remove(2); assert!( @@ -358,10 +353,9 @@ async fn chain_segment_non_linear_parent_roots() { /* * Test with a modified parent root. */ - let mut blocks: Vec> = - chain_segment_blocks(&chain_segment, &chain_segment_blobs, &harness.spec) - .into_iter() - .collect(); + let mut blocks: Vec> = chain_segment_blocks(&chain_segment, &chain_segment_blobs) + .into_iter() + .collect(); let (mut block, signature) = blocks[3].as_block().clone().deconstruct(); *block.parent_root_mut() = Hash256::zero(); @@ -396,10 +390,9 @@ async fn chain_segment_non_linear_slots() { * Test where a child is lower than the parent. */ - let mut blocks: Vec> = - chain_segment_blocks(&chain_segment, &chain_segment_blobs, &harness.spec) - .into_iter() - .collect(); + let mut blocks: Vec> = chain_segment_blocks(&chain_segment, &chain_segment_blobs) + .into_iter() + .collect(); let (mut block, signature) = blocks[3].as_block().clone().deconstruct(); *block.slot_mut() = Slot::new(0); blocks[3] = RpcBlock::new_without_blobs( @@ -423,10 +416,9 @@ async fn chain_segment_non_linear_slots() { * Test where a child is equal to the parent. */ - let mut blocks: Vec> = - chain_segment_blocks(&chain_segment, &chain_segment_blobs, &harness.spec) - .into_iter() - .collect(); + let mut blocks: Vec> = chain_segment_blocks(&chain_segment, &chain_segment_blobs) + .into_iter() + .collect(); let (mut block, signature) = blocks[3].as_block().clone().deconstruct(); *block.slot_mut() = blocks[2].slot(); blocks[3] = RpcBlock::new_without_blobs( @@ -458,9 +450,7 @@ async fn assert_invalid_signature( let blocks: Vec> = snapshots .iter() .zip(chain_segment_blobs.iter()) - .map(|(snapshot, blobs)| { - build_rpc_block(snapshot.beacon_block.clone(), blobs, &harness.spec) - }) + .map(|(snapshot, blobs)| build_rpc_block(snapshot.beacon_block.clone(), blobs)) .collect(); // Ensure the block will be rejected if imported in a chain segment. @@ -485,9 +475,7 @@ async fn assert_invalid_signature( .iter() .take(block_index) .zip(chain_segment_blobs.iter()) - .map(|(snapshot, blobs)| { - build_rpc_block(snapshot.beacon_block.clone(), blobs, &harness.spec) - }) + .map(|(snapshot, blobs)| build_rpc_block(snapshot.beacon_block.clone(), blobs)) .collect(); // We don't care if this fails, we just call this to ensure that all prior blocks have been // imported prior to this test. @@ -504,7 +492,6 @@ async fn assert_invalid_signature( build_rpc_block( snapshots[block_index].beacon_block.clone(), &chain_segment_blobs[block_index], - &harness.spec, ), NotifyExecutionLayer::Yes, BlockImportSource::Lookup, @@ -562,9 +549,7 @@ async fn invalid_signature_gossip_block() { .iter() .take(block_index) .zip(chain_segment_blobs.iter()) - .map(|(snapshot, blobs)| { - build_rpc_block(snapshot.beacon_block.clone(), blobs, &harness.spec) - }) + .map(|(snapshot, blobs)| build_rpc_block(snapshot.beacon_block.clone(), blobs)) .collect(); harness .chain @@ -615,9 +600,7 @@ async fn invalid_signature_block_proposal() { let blocks: Vec> = snapshots .iter() .zip(chain_segment_blobs.iter()) - .map(|(snapshot, blobs)| { - build_rpc_block(snapshot.beacon_block.clone(), blobs, &harness.spec) - }) + .map(|(snapshot, blobs)| build_rpc_block(snapshot.beacon_block.clone(), blobs)) .collect::>(); // Ensure the block will be rejected if imported in a chain segment. let process_res = harness @@ -923,9 +906,7 @@ async fn invalid_signature_deposit() { let blocks: Vec> = snapshots .iter() .zip(chain_segment_blobs.iter()) - .map(|(snapshot, blobs)| { - build_rpc_block(snapshot.beacon_block.clone(), blobs, &harness.spec) - }) + .map(|(snapshot, blobs)| build_rpc_block(snapshot.beacon_block.clone(), blobs)) .collect(); assert!( !matches!( diff --git a/beacon_node/beacon_chain/tests/events.rs b/beacon_node/beacon_chain/tests/events.rs index f8b3d33a20..0fc097ae8f 100644 --- a/beacon_node/beacon_chain/tests/events.rs +++ b/beacon_node/beacon_chain/tests/events.rs @@ -162,7 +162,7 @@ async fn data_column_sidecar_event_on_process_rpc_columns() { // load the precomputed column sidecar to avoid computing them for every block in the tests. let mut sidecar = RuntimeVariableList::>::from_ssz_bytes( TEST_DATA_COLUMN_SIDECARS_SSZ, - spec.number_of_columns as usize, + E::number_of_columns(), ) .unwrap()[0] .clone(); diff --git a/beacon_node/http_api/src/block_id.rs b/beacon_node/http_api/src/block_id.rs index 2ecc1dd615..e527e466f6 100644 --- a/beacon_node/http_api/src/block_id.rs +++ b/beacon_node/http_api/src/block_id.rs @@ -396,8 +396,8 @@ impl BlockId { })?; let num_found_column_keys = column_indices.len(); - let num_required_columns = chain.spec.number_of_columns / 2; - let is_blob_available = num_found_column_keys >= num_required_columns as usize; + let num_required_columns = T::EthSpec::number_of_columns() / 2; + let is_blob_available = num_found_column_keys >= num_required_columns; if is_blob_available { let data_columns = column_indices diff --git a/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs b/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs index 30f42f4162..6e841c25a5 100644 --- a/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs +++ b/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs @@ -35,7 +35,7 @@ where .is_ok_and(|b| b.get(*s.deref() as usize).unwrap_or(false)), Subnet::DataColumn(s) => { if let Ok(custody_group_count) = enr.custody_group_count::(&spec) { - compute_subnets_for_node(enr.node_id().raw(), custody_group_count, &spec) + compute_subnets_for_node::(enr.node_id().raw(), custody_group_count, &spec) .is_ok_and(|subnets| subnets.contains(s)) } else { false diff --git a/beacon_node/lighthouse_network/src/peer_manager/mod.rs b/beacon_node/lighthouse_network/src/peer_manager/mod.rs index 13367a3e99..93515ed5f6 100644 --- a/beacon_node/lighthouse_network/src/peer_manager/mod.rs +++ b/beacon_node/lighthouse_network/src/peer_manager/mod.rs @@ -167,10 +167,12 @@ impl PeerManager { let subnets_by_custody_group = if network_globals.spec.is_peer_das_scheduled() { (0..network_globals.spec.number_of_custody_groups) .map(|custody_index| { - let subnets = - compute_subnets_from_custody_group(custody_index, &network_globals.spec) - .expect("Should compute subnets for all custody groups") - .collect(); + let subnets = compute_subnets_from_custody_group::( + custody_index, + &network_globals.spec, + ) + .expect("Should compute subnets for all custody groups") + .collect(); (custody_index, subnets) }) .collect::>>() diff --git a/beacon_node/lighthouse_network/src/peer_manager/peerdb.rs b/beacon_node/lighthouse_network/src/peer_manager/peerdb.rs index 430ad2f6da..974b41230e 100644 --- a/beacon_node/lighthouse_network/src/peer_manager/peerdb.rs +++ b/beacon_node/lighthouse_network/src/peer_manager/peerdb.rs @@ -822,8 +822,9 @@ impl PeerDB { } else { let peer_info = self.peers.get_mut(&peer_id).expect("peer exists"); let node_id = peer_id_to_node_id(&peer_id).expect("convert peer_id to node_id"); - let subnets = compute_subnets_for_node(node_id.raw(), spec.custody_requirement, spec) - .expect("should compute custody subnets"); + let subnets = + compute_subnets_for_node::(node_id.raw(), spec.custody_requirement, spec) + .expect("should compute custody subnets"); peer_info.set_custody_subnets(subnets); } diff --git a/beacon_node/lighthouse_network/src/rpc/codec.rs b/beacon_node/lighthouse_network/src/rpc/codec.rs index 0a468d1ca6..e10b8c4ecc 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec.rs @@ -169,7 +169,9 @@ impl Decoder for SSZSnappyInboundCodec { // Should not attempt to decode rpc chunks with `length > max_packet_size` or not within bounds of // packet size for ssz container corresponding to `self.protocol`. - let ssz_limits = self.protocol.rpc_request_limits(&self.fork_context.spec); + let ssz_limits = self + .protocol + .rpc_request_limits::(&self.fork_context.spec); if ssz_limits.is_out_of_bounds(length, self.max_packet_size) { return Err(RPCError::InvalidData(format!( "RPC request length for protocol {:?} is out of bounds, length {}", @@ -560,10 +562,9 @@ fn handle_rpc_request( SupportedProtocol::DataColumnsByRootV1 => Ok(Some(RequestType::DataColumnsByRoot( DataColumnsByRootRequest { data_column_ids: - >::from_ssz_bytes_with_nested( + >>::from_ssz_bytes( decoded_buffer, spec.max_request_blocks(current_fork), - spec.number_of_columns as usize, )?, }, ))), @@ -1066,13 +1067,12 @@ mod tests { } } - fn dcbroot_request(fork_name: ForkName, spec: &ChainSpec) -> DataColumnsByRootRequest { - let number_of_columns = spec.number_of_columns as usize; + fn dcbroot_request(fork_name: ForkName, spec: &ChainSpec) -> DataColumnsByRootRequest { DataColumnsByRootRequest { data_column_ids: RuntimeVariableList::new( vec![DataColumnsByRootIdentifier { block_root: Hash256::zero(), - columns: RuntimeVariableList::from_vec(vec![0, 1, 2], number_of_columns), + columns: VariableList::from(vec![0, 1, 2]), }], spec.max_request_blocks(fork_name), ) @@ -2283,7 +2283,7 @@ mod tests { )); // Request limits - let limit = protocol_id.rpc_request_limits(&fork_context.spec); + let limit = protocol_id.rpc_request_limits::(&fork_context.spec); let mut max = encode_len(limit.max + 1); let mut codec = SSZSnappyOutboundCodec::::new( protocol_id.clone(), diff --git a/beacon_node/lighthouse_network/src/rpc/methods.rs b/beacon_node/lighthouse_network/src/rpc/methods.rs index 180130a2bf..39078e8d9e 100644 --- a/beacon_node/lighthouse_network/src/rpc/methods.rs +++ b/beacon_node/lighthouse_network/src/rpc/methods.rs @@ -400,11 +400,11 @@ impl DataColumnsByRangeRequest { .len() } - pub fn ssz_max_len(spec: &ChainSpec) -> usize { + pub fn ssz_max_len() -> usize { DataColumnsByRangeRequest { start_slot: 0, count: 0, - columns: vec![0; spec.number_of_columns as usize], + columns: vec![0; E::number_of_columns()], } .as_ssz_bytes() .len() @@ -517,14 +517,14 @@ impl BlobsByRootRequest { /// Request a number of data columns from a peer. #[derive(Clone, Debug, PartialEq)] -pub struct DataColumnsByRootRequest { +pub struct DataColumnsByRootRequest { /// The list of beacon block roots and column indices being requested. - pub data_column_ids: RuntimeVariableList, + pub data_column_ids: RuntimeVariableList>, } -impl DataColumnsByRootRequest { +impl DataColumnsByRootRequest { pub fn new( - data_column_ids: Vec, + data_column_ids: Vec>, max_request_blocks: usize, ) -> Self { let data_column_ids = RuntimeVariableList::from_vec(data_column_ids, max_request_blocks); @@ -924,7 +924,7 @@ impl std::fmt::Display for BlobsByRangeRequest { } } -impl std::fmt::Display for DataColumnsByRootRequest { +impl std::fmt::Display for DataColumnsByRootRequest { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index 388dbe63ef..48c356fb29 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -493,7 +493,7 @@ impl AsRef for ProtocolId { impl ProtocolId { /// Returns min and max size for messages of given protocol id requests. - pub fn rpc_request_limits(&self, spec: &ChainSpec) -> RpcLimits { + pub fn rpc_request_limits(&self, spec: &ChainSpec) -> RpcLimits { match self.versioned_protocol.protocol() { Protocol::Status => RpcLimits::new( ::ssz_fixed_len(), @@ -517,7 +517,7 @@ impl ProtocolId { Protocol::DataColumnsByRoot => RpcLimits::new(0, spec.max_data_columns_by_root_request), Protocol::DataColumnsByRange => RpcLimits::new( DataColumnsByRangeRequest::ssz_min_len(), - DataColumnsByRangeRequest::ssz_max_len(spec), + DataColumnsByRangeRequest::ssz_max_len::(), ), Protocol::Ping => RpcLimits::new( ::ssz_fixed_len(), @@ -725,7 +725,7 @@ pub enum RequestType { BlocksByRoot(BlocksByRootRequest), BlobsByRange(BlobsByRangeRequest), BlobsByRoot(BlobsByRootRequest), - DataColumnsByRoot(DataColumnsByRootRequest), + DataColumnsByRoot(DataColumnsByRootRequest), DataColumnsByRange(DataColumnsByRangeRequest), LightClientBootstrap(LightClientBootstrapRequest), LightClientOptimisticUpdate, diff --git a/beacon_node/lighthouse_network/src/types/globals.rs b/beacon_node/lighthouse_network/src/types/globals.rs index 082097f926..bcb4758386 100644 --- a/beacon_node/lighthouse_network/src/types/globals.rs +++ b/beacon_node/lighthouse_network/src/types/globals.rs @@ -70,7 +70,7 @@ impl NetworkGlobals { let mut sampling_subnets = HashSet::new(); for custody_index in &custody_groups { - let subnets = compute_subnets_from_custody_group(*custody_index, &spec) + let subnets = compute_subnets_from_custody_group::(*custody_index, &spec) .expect("should compute custody subnets for node"); sampling_subnets.extend(subnets); } @@ -106,7 +106,7 @@ impl NetworkGlobals { let mut sampling_subnets = self.sampling_subnets.write(); for custody_index in &custody_groups { - let subnets = compute_subnets_from_custody_group(*custody_index, &self.spec) + let subnets = compute_subnets_from_custody_group::(*custody_index, &self.spec) .expect("should compute custody subnets for node"); sampling_subnets.extend(subnets); } diff --git a/beacon_node/network/src/network_beacon_processor/mod.rs b/beacon_node/network/src/network_beacon_processor/mod.rs index ccf002e7e5..73349cd431 100644 --- a/beacon_node/network/src/network_beacon_processor/mod.rs +++ b/beacon_node/network/src/network_beacon_processor/mod.rs @@ -629,7 +629,7 @@ impl NetworkBeaconProcessor { self: &Arc, peer_id: PeerId, inbound_request_id: InboundRequestId, - request: DataColumnsByRootRequest, + request: DataColumnsByRootRequest, ) -> Result<(), Error> { let processor = self.clone(); let process_fn = move || { @@ -1008,7 +1008,7 @@ impl NetworkBeaconProcessor { let blob_publication_batch_interval = chain.config.blob_publication_batch_interval; let blob_publication_batches = chain.config.blob_publication_batches; - let number_of_columns = chain.spec.number_of_columns as usize; + let number_of_columns = T::EthSpec::number_of_columns(); let batch_size = number_of_columns / blob_publication_batches; let mut publish_count = 0usize; diff --git a/beacon_node/network/src/network_beacon_processor/rpc_methods.rs b/beacon_node/network/src/network_beacon_processor/rpc_methods.rs index 117377c924..7d686d375d 100644 --- a/beacon_node/network/src/network_beacon_processor/rpc_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/rpc_methods.rs @@ -346,7 +346,7 @@ impl NetworkBeaconProcessor { self: Arc, peer_id: PeerId, inbound_request_id: InboundRequestId, - request: DataColumnsByRootRequest, + request: DataColumnsByRootRequest, ) { self.terminate_response_stream( peer_id, @@ -361,14 +361,14 @@ impl NetworkBeaconProcessor { &self, peer_id: PeerId, inbound_request_id: InboundRequestId, - request: DataColumnsByRootRequest, + request: DataColumnsByRootRequest, ) -> Result<(), (RpcErrorResponse, &'static str)> { let mut send_data_column_count = 0; for data_column_ids_by_root in request.data_column_ids.as_slice() { match self.chain.get_data_columns_checking_all_caches( data_column_ids_by_root.block_root, - data_column_ids_by_root.columns.as_slice(), + data_column_ids_by_root.columns.iter().as_slice(), ) { Ok(data_columns) => { send_data_column_count += data_columns.len(); diff --git a/beacon_node/network/src/router.rs b/beacon_node/network/src/router.rs index d534c354d9..60fe094bb7 100644 --- a/beacon_node/network/src/router.rs +++ b/beacon_node/network/src/router.rs @@ -186,11 +186,11 @@ impl Router { /* RPC - Related functionality */ /// A new RPC request has been received from the network. - fn handle_rpc_request( + fn handle_rpc_request( &mut self, peer_id: PeerId, inbound_request_id: InboundRequestId, // Use ResponseId here - request_type: RequestType, + request_type: RequestType, ) { if !self.network_globals.peers.read().is_connected(&peer_id) { debug!(%peer_id, request = ?request_type, "Dropping request of disconnected peer"); diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index 605da3b4bd..23598cdd91 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -243,7 +243,6 @@ impl RangeBlockComponentsRequest { column_to_peer_id, expected_custody_columns, *attempt, - spec, ); if let Err(CouplingError::DataColumnPeerFailure { @@ -336,7 +335,6 @@ impl RangeBlockComponentsRequest { column_to_peer: HashMap, expects_custody_columns: &[ColumnIndex], attempt: usize, - spec: &ChainSpec, ) -> Result>, CouplingError> { // Group data columns by block_root and index let mut data_columns_by_block = @@ -415,7 +413,7 @@ impl RangeBlockComponentsRequest { ); } - RpcBlock::new_with_custody_columns(Some(block_root), block, custody_columns, spec) + RpcBlock::new_with_custody_columns(Some(block_root), block, custody_columns) .map_err(|e| CouplingError::InternalError(format!("{:?}", e)))? } else { // Block has no data, expects zero columns diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 76e5ed3f5d..c4f58c1f6e 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -948,9 +948,10 @@ impl SyncNetworkContext { self.send_network_msg(NetworkMessage::SendRequest { peer_id, request: RequestType::DataColumnsByRoot( - request - .clone() - .try_into_request(self.fork_context.current_fork_name(), &self.chain.spec)?, + request.clone().try_into_request::( + self.fork_context.current_fork_name(), + &self.chain.spec, + )?, ), app_request_id: AppRequestId::Sync(SyncRequestId::DataColumnsByRoot(id)), })?; diff --git a/beacon_node/network/src/sync/network_context/custody.rs b/beacon_node/network/src/sync/network_context/custody.rs index 51958ddad1..023d98daa6 100644 --- a/beacon_node/network/src/sync/network_context/custody.rs +++ b/beacon_node/network/src/sync/network_context/custody.rs @@ -13,16 +13,14 @@ use std::collections::HashSet; use std::time::{Duration, Instant}; use std::{collections::HashMap, marker::PhantomData, sync::Arc}; use tracing::{debug, warn}; -use types::EthSpec; use types::{DataColumnSidecar, Hash256, data_column_sidecar::ColumnIndex}; +use types::{DataColumnSidecarList, EthSpec}; use super::{LookupRequestResult, PeerGroup, RpcResponseResult, SyncNetworkContext}; const FAILED_PEERS_CACHE_EXPIRY_SECONDS: u64 = 5; const MAX_STALE_NO_PEERS_DURATION: Duration = Duration::from_secs(30); -type DataColumnSidecarList = Vec>>; - pub struct ActiveCustodyRequest { block_root: Hash256, custody_id: CustodyId, diff --git a/beacon_node/network/src/sync/network_context/requests/data_columns_by_root.rs b/beacon_node/network/src/sync/network_context/requests/data_columns_by_root.rs index 09d7f4b3b7..253e8940b2 100644 --- a/beacon_node/network/src/sync/network_context/requests/data_columns_by_root.rs +++ b/beacon_node/network/src/sync/network_context/requests/data_columns_by_root.rs @@ -1,8 +1,8 @@ use lighthouse_network::rpc::methods::DataColumnsByRootRequest; +use ssz_types::VariableList; use std::sync::Arc; use types::{ ChainSpec, DataColumnSidecar, DataColumnsByRootIdentifier, EthSpec, ForkName, Hash256, - RuntimeVariableList, }; use super::{ActiveRequestItems, LookupVerifyError}; @@ -14,13 +14,12 @@ pub struct DataColumnsByRootSingleBlockRequest { } impl DataColumnsByRootSingleBlockRequest { - pub fn try_into_request( + pub fn try_into_request( self, fork_name: ForkName, spec: &ChainSpec, - ) -> Result { - let number_of_columns = spec.number_of_columns as usize; - let columns = RuntimeVariableList::new(self.indices, number_of_columns) + ) -> Result, &'static str> { + let columns = VariableList::new(self.indices) .map_err(|_| "Number of indices exceeds total number of columns")?; Ok(DataColumnsByRootRequest::new( vec![DataColumnsByRootIdentifier { diff --git a/beacon_node/network/src/sync/tests/lookups.rs b/beacon_node/network/src/sync/tests/lookups.rs index 6cfe7a82a7..4180025096 100644 --- a/beacon_node/network/src/sync/tests/lookups.rs +++ b/beacon_node/network/src/sync/tests/lookups.rs @@ -1922,7 +1922,7 @@ fn custody_lookup_happy_path() { let id = r.expect_block_lookup_request(block.canonical_root()); r.complete_valid_block_request(id, block.into(), true); // for each slot we download `samples_per_slot` columns - let sample_column_count = spec.samples_per_slot * spec.data_columns_per_group(); + let sample_column_count = spec.samples_per_slot * spec.data_columns_per_group::(); let custody_ids = r.expect_only_data_columns_by_root_requests(block_root, sample_column_count as usize); r.complete_valid_custody_request(custody_ids, data_columns, false); diff --git a/beacon_node/network/src/sync/tests/range.rs b/beacon_node/network/src/sync/tests/range.rs index 718ddf1c1d..cb728a90c1 100644 --- a/beacon_node/network/src/sync/tests/range.rs +++ b/beacon_node/network/src/sync/tests/range.rs @@ -427,7 +427,7 @@ impl TestRig { .chain .process_block( block_root, - build_rpc_block(block.into(), &data_sidecars, &self.spec), + build_rpc_block(block.into(), &data_sidecars), NotifyExecutionLayer::Yes, BlockImportSource::RangeSync, || Ok(()), @@ -443,14 +443,13 @@ impl TestRig { fn build_rpc_block( block: Arc>, data_sidecars: &Option>, - spec: &ChainSpec, ) -> RpcBlock { match data_sidecars { Some(DataSidecars::Blobs(blobs)) => { RpcBlock::new(None, block, Some(blobs.clone())).unwrap() } Some(DataSidecars::DataColumns(columns)) => { - RpcBlock::new_with_custody_columns(None, block, columns.clone(), spec).unwrap() + RpcBlock::new_with_custody_columns(None, block, columns.clone()).unwrap() } // Block has no data, expects zero columns None => RpcBlock::new_without_blobs(None, block), diff --git a/common/eth2_network_config/built_in_network_configs/chiado/config.yaml b/common/eth2_network_config/built_in_network_configs/chiado/config.yaml index 4d4ccdf717..f0c833612d 100644 --- a/common/eth2_network_config/built_in_network_configs/chiado/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/chiado/config.yaml @@ -149,7 +149,6 @@ MAX_BLOBS_PER_BLOCK_ELECTRA: 2 MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 256 # Fulu -NUMBER_OF_COLUMNS: 128 NUMBER_OF_CUSTODY_GROUPS: 128 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 SAMPLES_PER_SLOT: 8 diff --git a/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml b/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml index eece34b89c..62c6d0db1b 100644 --- a/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/gnosis/config.yaml @@ -133,7 +133,6 @@ MAX_BLOBS_PER_BLOCK_ELECTRA: 2 MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 256 # Fulu -NUMBER_OF_COLUMNS: 128 NUMBER_OF_CUSTODY_GROUPS: 128 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 SAMPLES_PER_SLOT: 8 diff --git a/common/eth2_network_config/built_in_network_configs/holesky/config.yaml b/common/eth2_network_config/built_in_network_configs/holesky/config.yaml index 76d8d482c2..654689fdf1 100644 --- a/common/eth2_network_config/built_in_network_configs/holesky/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/holesky/config.yaml @@ -138,7 +138,6 @@ MAX_BLOBS_PER_BLOCK_ELECTRA: 9 MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152 # Fulu -NUMBER_OF_COLUMNS: 128 NUMBER_OF_CUSTODY_GROUPS: 128 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 diff --git a/common/eth2_network_config/built_in_network_configs/hoodi/config.yaml b/common/eth2_network_config/built_in_network_configs/hoodi/config.yaml index a1365e3464..ba4501ccfb 100644 --- a/common/eth2_network_config/built_in_network_configs/hoodi/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/hoodi/config.yaml @@ -150,7 +150,6 @@ WHISK_EPOCHS_PER_SHUFFLING_PHASE: 256 WHISK_PROPOSER_SELECTION_GAP: 2 # Fulu -NUMBER_OF_COLUMNS: 128 NUMBER_OF_CUSTODY_GROUPS: 128 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 diff --git a/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml b/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml index 0b68a27f4d..72ace023d7 100644 --- a/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml @@ -153,7 +153,6 @@ MAX_BLOBS_PER_BLOCK_ELECTRA: 9 MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152 # Fulu -NUMBER_OF_COLUMNS: 128 NUMBER_OF_CUSTODY_GROUPS: 128 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 diff --git a/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml b/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml index ccd71cdce9..013cddebe2 100644 --- a/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/sepolia/config.yaml @@ -139,7 +139,6 @@ MAX_BLOBS_PER_BLOCK_ELECTRA: 9 MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152 # Fulu -NUMBER_OF_COLUMNS: 128 NUMBER_OF_CUSTODY_GROUPS: 128 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 diff --git a/consensus/types/presets/gnosis/fulu.yaml b/consensus/types/presets/gnosis/fulu.yaml index e5f3ce0212..b25d88f191 100644 --- a/consensus/types/presets/gnosis/fulu.yaml +++ b/consensus/types/presets/gnosis/fulu.yaml @@ -8,3 +8,7 @@ FIELD_ELEMENTS_PER_CELL: 64 FIELD_ELEMENTS_PER_EXT_BLOB: 8192 # uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments')) KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH: 4 +# FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL (= 128) +CELLS_PER_EXT_BLOB: 128 +# CELLS_PER_EXT_BLOB (= 128) +NUMBER_OF_COLUMNS: 128 \ No newline at end of file diff --git a/consensus/types/presets/mainnet/fulu.yaml b/consensus/types/presets/mainnet/fulu.yaml index 394f335f90..b7cad6239e 100644 --- a/consensus/types/presets/mainnet/fulu.yaml +++ b/consensus/types/presets/mainnet/fulu.yaml @@ -8,3 +8,7 @@ FIELD_ELEMENTS_PER_CELL: 64 FIELD_ELEMENTS_PER_EXT_BLOB: 8192 # uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments')) KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH: 4 +# FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL (= 128) +CELLS_PER_EXT_BLOB: 128 +# CELLS_PER_EXT_BLOB (= 128) +NUMBER_OF_COLUMNS: 128 \ No newline at end of file diff --git a/consensus/types/presets/minimal/fulu.yaml b/consensus/types/presets/minimal/fulu.yaml index c961eb7f3c..d4b32eb876 100644 --- a/consensus/types/presets/minimal/fulu.yaml +++ b/consensus/types/presets/minimal/fulu.yaml @@ -8,3 +8,7 @@ FIELD_ELEMENTS_PER_CELL: 64 FIELD_ELEMENTS_PER_EXT_BLOB: 8192 # uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments')) KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH: 4 +# FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL (= 128) +CELLS_PER_EXT_BLOB: 128 +# CELLS_PER_EXT_BLOB (= 128) +NUMBER_OF_COLUMNS: 128 \ No newline at end of file diff --git a/consensus/types/src/beacon_block.rs b/consensus/types/src/beacon_block.rs index 297bd38d8a..9494838c00 100644 --- a/consensus/types/src/beacon_block.rs +++ b/consensus/types/src/beacon_block.rs @@ -1094,22 +1094,12 @@ mod tests { slot: fulu_slot, ..<_>::random_for_test(rng) }); - // It's invalid to have a Fulu block with a epoch lower than the fork epoch. - let _bad_block = { - let mut bad = good_block.clone(); - *bad.slot_mut() = electra_slot; - bad - }; assert_eq!( BeaconBlock::from_ssz_bytes(&good_block.as_ssz_bytes(), &spec) .expect("good fulu block can be decoded"), good_block ); - // TODO(fulu): Uncomment once Fulu has features since without features - // and with an Electra slot it decodes successfully to Electra. - //BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec) - // .expect_err("bad fulu block cannot be decoded"); } } } diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index 659bd1d23f..f42159252a 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -201,7 +201,6 @@ pub struct ChainSpec { pub fulu_fork_version: [u8; 4], /// The Fulu fork epoch is optional, with `None` representing "Fulu never happens". pub fulu_fork_epoch: Option, - pub number_of_columns: u64, pub number_of_custody_groups: u64, pub data_column_sidecar_subnet_count: u64, pub samples_per_slot: u64, @@ -773,20 +772,19 @@ impl ChainSpec { } /// Returns the number of data columns per custody group. - pub fn data_columns_per_group(&self) -> u64 { - self.number_of_columns + pub fn data_columns_per_group(&self) -> u64 { + (E::number_of_columns() as u64) .safe_div(self.number_of_custody_groups) .expect("Custody group count must be greater than 0") } /// Returns the number of column sidecars to sample per slot. - pub fn sampling_size_columns(&self, custody_group_count: u64) -> Result { + pub fn sampling_size_columns( + &self, + custody_group_count: u64, + ) -> Result { let sampling_size_groups = self.sampling_size_custody_groups(custody_group_count)?; - - let columns_per_custody_group = self - .number_of_columns - .safe_div(self.number_of_custody_groups) - .map_err(|_| "number_of_custody_groups must be greater than 0")?; + let columns_per_custody_group = self.data_columns_per_group::(); let sampling_size_columns = columns_per_custody_group .safe_mul(sampling_size_groups) @@ -1048,7 +1046,6 @@ impl ChainSpec { custody_requirement: 4, number_of_custody_groups: 128, data_column_sidecar_subnet_count: 128, - number_of_columns: 128, samples_per_slot: 8, validator_custody_requirement: 8, balance_per_additional_custody_group: 32000000000, @@ -1088,7 +1085,6 @@ impl ChainSpec { max_blocks_by_root_request: default_max_blocks_by_root_request(), max_blocks_by_root_request_deneb: default_max_blocks_by_root_request_deneb(), max_blobs_by_root_request: default_max_blobs_by_root_request(), - max_data_columns_by_root_request: default_data_columns_by_root_request(), /* * Networking Electra specific @@ -1103,6 +1099,7 @@ impl ChainSpec { blob_schedule: BlobSchedule::default(), min_epochs_for_data_column_sidecars_requests: default_min_epochs_for_data_column_sidecars_requests(), + max_data_columns_by_root_request: default_data_columns_by_root_request(), /* * Application specific @@ -1386,7 +1383,6 @@ impl ChainSpec { custody_requirement: 4, number_of_custody_groups: 128, data_column_sidecar_subnet_count: 128, - number_of_columns: 128, samples_per_slot: 8, validator_custody_requirement: 8, balance_per_additional_custody_group: 32000000000, @@ -1426,7 +1422,6 @@ impl ChainSpec { max_blocks_by_root_request: default_max_blocks_by_root_request(), max_blocks_by_root_request_deneb: default_max_blocks_by_root_request_deneb(), max_blobs_by_root_request: default_max_blobs_by_root_request(), - max_data_columns_by_root_request: default_data_columns_by_root_request(), /* * Networking Electra specific @@ -1441,6 +1436,7 @@ impl ChainSpec { blob_schedule: BlobSchedule::default(), min_epochs_for_data_column_sidecars_requests: default_min_epochs_for_data_column_sidecars_requests(), + max_data_columns_by_root_request: default_data_columns_by_root_request(), /* * Application specific @@ -1759,9 +1755,6 @@ pub struct Config { #[serde(with = "serde_utils::quoted_u64")] max_request_blob_sidecars_electra: u64, - #[serde(default = "default_number_of_columns")] - #[serde(with = "serde_utils::quoted_u64")] - number_of_columns: u64, #[serde(default = "default_number_of_custody_groups")] #[serde(with = "serde_utils::quoted_u64")] number_of_custody_groups: u64, @@ -1938,10 +1931,6 @@ const fn default_data_column_sidecar_subnet_count() -> u64 { 128 } -const fn default_number_of_columns() -> u64 { - 128 -} - const fn default_number_of_custody_groups() -> u64 { 128 } @@ -1987,19 +1976,15 @@ fn max_blobs_by_root_request_common(max_request_blob_sidecars: u64) -> usize { .len() } -fn max_data_columns_by_root_request_common( - max_request_blocks: u64, - number_of_columns: u64, -) -> usize { +fn max_data_columns_by_root_request_common(max_request_blocks: u64) -> usize { let max_request_blocks = max_request_blocks as usize; - let number_of_columns = number_of_columns as usize; let empty_data_columns_by_root_id = DataColumnsByRootIdentifier { block_root: Hash256::zero(), - columns: RuntimeVariableList::from_vec(vec![0; number_of_columns], number_of_columns), + columns: VariableList::from(vec![0]), }; - RuntimeVariableList::::from_vec( + RuntimeVariableList::>::from_vec( vec![empty_data_columns_by_root_id; max_request_blocks], max_request_blocks, ) @@ -2020,10 +2005,7 @@ fn default_max_blobs_by_root_request() -> usize { } fn default_data_columns_by_root_request() -> usize { - max_data_columns_by_root_request_common( - default_max_request_blocks_deneb(), - default_number_of_columns(), - ) + max_data_columns_by_root_request_common::(default_max_request_blocks_deneb()) } impl Default for Config { @@ -2165,7 +2147,6 @@ impl Config { blob_sidecar_subnet_count_electra: spec.blob_sidecar_subnet_count_electra, max_request_blob_sidecars_electra: spec.max_request_blob_sidecars_electra, - number_of_columns: spec.number_of_columns, number_of_custody_groups: spec.number_of_custody_groups, data_column_sidecar_subnet_count: spec.data_column_sidecar_subnet_count, samples_per_slot: spec.samples_per_slot, @@ -2248,7 +2229,6 @@ impl Config { max_blobs_per_block_electra, blob_sidecar_subnet_count_electra, max_request_blob_sidecars_electra, - number_of_columns, number_of_custody_groups, data_column_sidecar_subnet_count, samples_per_slot, @@ -2330,12 +2310,10 @@ impl Config { max_request_blocks_deneb, ), max_blobs_by_root_request: max_blobs_by_root_request_common(max_request_blob_sidecars), - max_data_columns_by_root_request: max_data_columns_by_root_request_common( + max_data_columns_by_root_request: max_data_columns_by_root_request_common::( max_request_blocks_deneb, - number_of_columns, ), - number_of_columns, number_of_custody_groups, data_column_sidecar_subnet_count, samples_per_slot, @@ -2815,7 +2793,6 @@ mod yaml_tests { DEPOSIT_CONTRACT_ADDRESS: 0x00000000219ab540356cBB839Cbe05303d7705Fa CUSTODY_REQUIREMENT: 1 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 - NUMBER_OF_COLUMNS: 128 SAMPLES_PER_SLOT: 8 "#; diff --git a/consensus/types/src/data_column_custody_group.rs b/consensus/types/src/data_column_custody_group.rs index 3e88ef210a..0c44608e46 100644 --- a/consensus/types/src/data_column_custody_group.rs +++ b/consensus/types/src/data_column_custody_group.rs @@ -1,4 +1,4 @@ -use crate::{ChainSpec, ColumnIndex, DataColumnSubnetId}; +use crate::{ChainSpec, ColumnIndex, DataColumnSubnetId, EthSpec}; use alloy_primitives::U256; use itertools::Itertools; use safe_arith::{ArithError, SafeArith}; @@ -24,8 +24,12 @@ pub fn get_custody_groups( custody_group_count: u64, spec: &ChainSpec, ) -> Result, DataColumnCustodyGroupError> { - get_custody_groups_ordered(raw_node_id, custody_group_count, spec) - .map(|custody_groups| custody_groups.into_iter().collect()) + if custody_group_count == spec.number_of_custody_groups { + Ok(HashSet::from_iter(0..spec.number_of_custody_groups)) + } else { + get_custody_groups_ordered(raw_node_id, custody_group_count, spec) + .map(|custody_groups| custody_groups.into_iter().collect()) + } } /// Returns a deterministically ordered list of custody groups assigned to a node, @@ -75,7 +79,7 @@ pub fn get_custody_groups_ordered( /// Returns the columns that are associated with a given custody group. /// /// spec: https://github.com/ethereum/consensus-specs/blob/8e0d0d48e81d6c7c5a8253ab61340f5ea5bac66a/specs/fulu/das-core.md#compute_columns_for_custody_group -pub fn compute_columns_for_custody_group( +pub fn compute_columns_for_custody_group( custody_group: CustodyIndex, spec: &ChainSpec, ) -> Result, DataColumnCustodyGroupError> { @@ -87,7 +91,7 @@ pub fn compute_columns_for_custody_group( } let mut columns = Vec::new(); - for i in 0..spec.data_columns_per_group() { + for i in 0..spec.data_columns_per_group::() { let column = number_of_custody_groups .safe_mul(i) .and_then(|v| v.safe_add(custody_group)) @@ -98,7 +102,7 @@ pub fn compute_columns_for_custody_group( Ok(columns.into_iter()) } -pub fn compute_subnets_for_node( +pub fn compute_subnets_for_node( raw_node_id: [u8; 32], custody_group_count: u64, spec: &ChainSpec, @@ -107,7 +111,7 @@ pub fn compute_subnets_for_node( let mut subnets = HashSet::new(); for custody_group in custody_groups { - let custody_group_subnets = compute_subnets_from_custody_group(custody_group, spec)?; + let custody_group_subnets = compute_subnets_from_custody_group::(custody_group, spec)?; subnets.extend(custody_group_subnets); } @@ -115,11 +119,11 @@ pub fn compute_subnets_for_node( } /// Returns the subnets that are associated with a given custody group. -pub fn compute_subnets_from_custody_group( +pub fn compute_subnets_from_custody_group( custody_group: CustodyIndex, spec: &ChainSpec, ) -> Result + '_, DataColumnCustodyGroupError> { - let result = compute_columns_for_custody_group(custody_group, spec)? + let result = compute_columns_for_custody_group::(custody_group, spec)? .map(|column_index| DataColumnSubnetId::from_column_index(column_index, spec)) .unique(); Ok(result) @@ -128,19 +132,23 @@ pub fn compute_subnets_from_custody_group( #[cfg(test)] mod test { use super::*; + use crate::MainnetEthSpec; + + type E = MainnetEthSpec; #[test] fn test_compute_columns_for_custody_group() { let mut spec = ChainSpec::mainnet(); spec.number_of_custody_groups = 64; - spec.number_of_columns = 128; - let columns_per_custody_group = spec.number_of_columns / spec.number_of_custody_groups; + + let columns_per_custody_group = + E::number_of_columns() / (spec.number_of_custody_groups as usize); for custody_group in 0..spec.number_of_custody_groups { - let columns = compute_columns_for_custody_group(custody_group, &spec) + let columns = compute_columns_for_custody_group::(custody_group, &spec) .unwrap() .collect::>(); - assert_eq!(columns.len(), columns_per_custody_group as usize); + assert_eq!(columns.len(), columns_per_custody_group); } } @@ -148,14 +156,13 @@ mod test { fn test_compute_subnets_from_custody_group() { let mut spec = ChainSpec::mainnet(); spec.number_of_custody_groups = 64; - spec.number_of_columns = 256; spec.data_column_sidecar_subnet_count = 128; let subnets_per_custody_group = spec.data_column_sidecar_subnet_count / spec.number_of_custody_groups; for custody_group in 0..spec.number_of_custody_groups { - let subnets = compute_subnets_from_custody_group(custody_group, &spec) + let subnets = compute_subnets_from_custody_group::(custody_group, &spec) .unwrap() .collect::>(); assert_eq!(subnets.len(), subnets_per_custody_group as usize); diff --git a/consensus/types/src/data_column_sidecar.rs b/consensus/types/src/data_column_sidecar.rs index 192540c596..57f7a88e19 100644 --- a/consensus/types/src/data_column_sidecar.rs +++ b/consensus/types/src/data_column_sidecar.rs @@ -2,19 +2,17 @@ use crate::beacon_block_body::{BLOB_KZG_COMMITMENTS_INDEX, KzgCommitments}; use crate::context_deserialize; use crate::test_utils::TestRandom; use crate::{ - BeaconBlockHeader, BeaconStateError, Epoch, EthSpec, ForkName, Hash256, RuntimeVariableList, + BeaconBlockHeader, BeaconStateError, Epoch, EthSpec, ForkName, Hash256, 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::de::Error; -use serde::{Deserialize, Deserializer, Serialize}; -use ssz::{DecodeError, Encode}; +use serde::{Deserialize, Serialize}; +use ssz::Encode; use ssz_derive::{Decode, Encode}; use ssz_types::Error as SszError; use ssz_types::{FixedVector, VariableList}; @@ -28,69 +26,11 @@ pub type Cell = FixedVector::BytesPerCell>; pub type DataColumn = VariableList, ::MaxBlobCommitmentsPerBlock>; /// Identifies a set of data columns associated with a specific beacon block. -#[derive(Encode, Clone, Debug, PartialEq, TreeHash)] -pub struct DataColumnsByRootIdentifier { +#[derive(Encode, Decode, Clone, Debug, PartialEq, TreeHash, Deserialize)] +#[context_deserialize(ForkName)] +pub struct DataColumnsByRootIdentifier { pub block_root: Hash256, - pub columns: RuntimeVariableList, -} - -impl<'de> ContextDeserialize<'de, (ForkName, usize)> for DataColumnsByRootIdentifier { - fn context_deserialize(deserializer: D, context: (ForkName, usize)) -> Result - 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 { - let mut builder = ssz::SszDecoderBuilder::new(bytes); - builder.register_type::()?; - 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 { - pub fn from_ssz_bytes_with_nested( - bytes: &[u8], - max_len: usize, - num_columns: usize, - ) -> Result { - if bytes.is_empty() { - return Ok(RuntimeVariableList::empty(max_len)); - } - - let vec = ssz::decode_list_of_variable_length_items::, Vec>>( - bytes, - Some(max_len), - )? - .into_iter() - .map(|bytes| DataColumnsByRootIdentifier::from_ssz_bytes(&bytes, num_columns)) - .collect::, _>>()?; - - Ok(RuntimeVariableList::from_vec(vec, max_len)) - } + pub columns: VariableList, } pub type DataColumnSidecarList = Vec>>; @@ -228,45 +168,3 @@ impl From for DataColumnSidecarError { Self::SszError(e) } } - -#[cfg(test)] -mod test { - use super::*; - use bls::FixedBytesExtended; - - #[test] - fn round_trip_dcbroot_list() { - let max_outer = 5; - let max_inner = 10; - - let data = vec![ - DataColumnsByRootIdentifier { - block_root: Hash256::from_low_u64_be(10), - columns: RuntimeVariableList::::from_vec(vec![1u64, 2, 3], max_inner), - }, - DataColumnsByRootIdentifier { - block_root: Hash256::from_low_u64_be(20), - columns: RuntimeVariableList::::from_vec(vec![4u64, 5], max_inner), - }, - ]; - - let list = RuntimeVariableList::from_vec(data.clone(), max_outer); - - let ssz_bytes = list.as_ssz_bytes(); - - let decoded = - RuntimeVariableList::::from_ssz_bytes_with_nested( - &ssz_bytes, max_outer, max_inner, - ) - .expect("should decode list of DataColumnsByRootIdentifier"); - - assert_eq!(decoded.len(), data.len()); - for (original, decoded) in data.iter().zip(decoded.iter()) { - assert_eq!(decoded.block_root, original.block_root); - assert_eq!( - decoded.columns.iter().copied().collect::>(), - original.columns.iter().copied().collect::>() - ); - } - } -} diff --git a/consensus/types/src/eth_spec.rs b/consensus/types/src/eth_spec.rs index 2dc4515998..e9a291f6c7 100644 --- a/consensus/types/src/eth_spec.rs +++ b/consensus/types/src/eth_spec.rs @@ -111,11 +111,13 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + type BytesPerFieldElement: Unsigned + Clone + Sync + Send + Debug + PartialEq; type KzgCommitmentInclusionProofDepth: Unsigned + Clone + Sync + Send + Debug + PartialEq; /* - * New in PeerDAS + * New in Fulu */ type FieldElementsPerCell: Unsigned + Clone + Sync + Send + Debug + PartialEq; type FieldElementsPerExtBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq; type KzgCommitmentsInclusionProofDepth: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type CellsPerExtBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type NumberOfColumns: Unsigned + Clone + Sync + Send + Debug + PartialEq; type ProposerLookaheadSlots: Unsigned + Clone + Sync + Send + Debug + PartialEq; /* * Derived values (set these CAREFULLY) @@ -378,6 +380,14 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + Self::KzgCommitmentsInclusionProofDepth::to_usize() } + fn cells_per_ext_blob() -> usize { + Self::CellsPerExtBlob::to_usize() + } + + fn number_of_columns() -> usize { + Self::NumberOfColumns::to_usize() + } + fn proposer_lookahead_slots() -> usize { Self::ProposerLookaheadSlots::to_usize() } @@ -433,6 +443,8 @@ impl EthSpec for MainnetEthSpec { type MaxCellsPerBlock = U33554432; type KzgCommitmentInclusionProofDepth = U17; type KzgCommitmentsInclusionProofDepth = U4; // inclusion of the whole list of commitments + type CellsPerExtBlob = U128; + type NumberOfColumns = U128; type ProposerLookaheadSlots = U64; // Derived from (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch @@ -487,6 +499,8 @@ impl EthSpec for MinimalEthSpec { type MaxCellsPerBlock = U33554432; type BytesPerCell = U2048; type KzgCommitmentsInclusionProofDepth = U4; + type CellsPerExtBlob = U128; + type NumberOfColumns = U128; type ProposerLookaheadSlots = U16; // Derived from (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH params_from_eth_spec!(MainnetEthSpec { @@ -584,6 +598,8 @@ impl EthSpec for GnosisEthSpec { type MaxCellsPerBlock = U33554432; type BytesPerCell = U2048; type KzgCommitmentsInclusionProofDepth = U4; + type CellsPerExtBlob = U128; + type NumberOfColumns = U128; type ProposerLookaheadSlots = U32; // Derived from (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH fn default_spec() -> ChainSpec { diff --git a/consensus/types/src/preset.rs b/consensus/types/src/preset.rs index d025c72eac..b776cf5873 100644 --- a/consensus/types/src/preset.rs +++ b/consensus/types/src/preset.rs @@ -297,6 +297,10 @@ pub struct FuluPreset { pub field_elements_per_ext_blob: u64, #[serde(with = "serde_utils::quoted_u64")] pub kzg_commitments_inclusion_proof_depth: u64, + #[serde(with = "serde_utils::quoted_u64")] + pub cells_per_ext_blob: u64, + #[serde(with = "serde_utils::quoted_u64")] + pub number_of_columns: u64, } impl FuluPreset { @@ -306,6 +310,8 @@ impl FuluPreset { field_elements_per_ext_blob: E::field_elements_per_ext_blob() as u64, kzg_commitments_inclusion_proof_depth: E::kzg_commitments_inclusion_proof_depth() as u64, + cells_per_ext_blob: E::cells_per_ext_blob() as u64, + number_of_columns: E::number_of_columns() as u64, } } } diff --git a/crypto/kzg/src/lib.rs b/crypto/kzg/src/lib.rs index f3735418b6..ddaddd1ada 100644 --- a/crypto/kzg/src/lib.rs +++ b/crypto/kzg/src/lib.rs @@ -29,8 +29,8 @@ pub use rust_eth_kzg::{ /// pub const NO_PRECOMPUTE: u64 = 0; -// Note: `spec.number_of_columns` is a config and should match `CELLS_PER_EXT_BLOB` - however this -// is a constant in the KZG library - be aware that overriding `number_of_columns` will break KZG +// Note: Both `NUMBER_OF_COLUMNS` and `CELLS_PER_EXT_BLOB` are preset values - however this +// is a constant in the KZG library - be aware that overriding `NUMBER_OF_COLUMNS` will break KZG // operations. pub type CellsAndKzgProofs = ([Cell; CELLS_PER_EXT_BLOB], [KzgProof; CELLS_PER_EXT_BLOB]); diff --git a/lighthouse/environment/tests/testnet_dir/config.yaml b/lighthouse/environment/tests/testnet_dir/config.yaml index 3f72e2ea6c..24c4a67225 100644 --- a/lighthouse/environment/tests/testnet_dir/config.yaml +++ b/lighthouse/environment/tests/testnet_dir/config.yaml @@ -101,5 +101,4 @@ ATTESTATION_SUBNET_SHUFFLING_PREFIX_BITS: 3 # DAS CUSTODY_REQUIREMENT: 4 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128 -NUMBER_OF_COLUMNS: 128 SAMPLES_PER_SLOT: 8 \ No newline at end of file diff --git a/testing/ef_tests/Makefile b/testing/ef_tests/Makefile index 333a443889..eb3631aa91 100644 --- a/testing/ef_tests/Makefile +++ b/testing/ef_tests/Makefile @@ -1,6 +1,6 @@ # To download/extract nightly tests, run: # CONSENSUS_SPECS_TEST_VERSION=nightly make -CONSENSUS_SPECS_TEST_VERSION ?= v1.6.0-alpha.3 +CONSENSUS_SPECS_TEST_VERSION ?= v1.6.0-alpha.4 REPO_NAME := consensus-spec-tests OUTPUT_DIR := ./$(REPO_NAME) diff --git a/testing/ef_tests/check_all_files_accessed.py b/testing/ef_tests/check_all_files_accessed.py index d7568d854f..9c168b6fa2 100755 --- a/testing/ef_tests/check_all_files_accessed.py +++ b/testing/ef_tests/check_all_files_accessed.py @@ -49,6 +49,11 @@ excluded_paths = [ "tests/.*/eip7805", # Ignore MatrixEntry SSZ tests for now. "tests/.*/fulu/ssz_static/MatrixEntry/.*", + # EIP-7916 is still in draft and hasn't been implemented yet https://eips.ethereum.org/EIPS/eip-7916 + "tests/general/phase0/ssz_generic/progressive_bitlist", + "tests/general/phase0/ssz_generic/basic_progressive_list", + "tests/general/phase0/ssz_generic/containers/.*/ProgressiveBitsStruct.*", + "tests/general/phase0/ssz_generic/containers/.*/ProgressiveTestStruct.*", # 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", diff --git a/testing/ef_tests/src/cases.rs b/testing/ef_tests/src/cases.rs index 17b9c90ba7..b2e0276353 100644 --- a/testing/ef_tests/src/cases.rs +++ b/testing/ef_tests/src/cases.rs @@ -50,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::{DataColumnsByRootIdentifierWrapper, SszStaticType}; +pub use common::SszStaticType; pub use compute_columns_for_custody_groups::*; pub use epoch_processing::*; pub use fork::ForkTest; diff --git a/testing/ef_tests/src/cases/common.rs b/testing/ef_tests/src/cases/common.rs index f63380cc33..d58f6dbb10 100644 --- a/testing/ef_tests/src/cases/common.rs +++ b/testing/ef_tests/src/cases/common.rs @@ -3,9 +3,6 @@ use serde::{Deserialize, Deserializer}; use ssz::Encode; use ssz_derive::{Decode, Encode}; use std::fmt::Debug; -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 { @@ -63,62 +60,6 @@ pub trait SszStaticType: Encode + Clone + PartialEq + Debug + Sync {} impl 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 { - 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, -} - -impl<'de, E: EthSpec> ContextDeserialize<'de, (ForkName, usize)> - for DataColumnsByRootIdentifierWrapper -{ - fn context_deserialize(deserializer: D, context: (ForkName, usize)) -> Result - where - D: Deserializer<'de>, - { - let value = DataColumnsByRootIdentifier::context_deserialize(deserializer, context)?; - Ok(DataColumnsByRootIdentifierWrapper { - value, - _phantom: PhantomData, - }) - } -} - -// We can delete this if we ever get `tree_hash(struct_behaviour = "transparent")`. -impl TreeHash for DataColumnsByRootIdentifierWrapper { - 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 From for DataColumnsByRootIdentifierWrapper { - fn from(value: DataColumnsByRootIdentifier) -> Self { - Self { - value, - _phantom: PhantomData, - } - } -} - #[macro_export] macro_rules! impl_bls_load_case { ($case_name:ident) => { diff --git a/testing/ef_tests/src/cases/compute_columns_for_custody_groups.rs b/testing/ef_tests/src/cases/compute_columns_for_custody_groups.rs index 2da72916cf..16d3eaf7af 100644 --- a/testing/ef_tests/src/cases/compute_columns_for_custody_groups.rs +++ b/testing/ef_tests/src/cases/compute_columns_for_custody_groups.rs @@ -27,7 +27,7 @@ impl Case for ComputeColumnsForCustodyGroups { 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::(self.custody_group, &spec) .expect("should compute custody columns from group") .collect::>(); diff --git a/testing/ef_tests/src/cases/ssz_generic.rs b/testing/ef_tests/src/cases/ssz_generic.rs index 1155aacb27..4152711aee 100644 --- a/testing/ef_tests/src/cases/ssz_generic.rs +++ b/testing/ef_tests/src/cases/ssz_generic.rs @@ -80,12 +80,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)*), @@ -107,6 +111,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))), } }; diff --git a/testing/ef_tests/src/cases/ssz_static.rs b/testing/ef_tests/src/cases/ssz_static.rs index b02b9597bb..3f066c2fe3 100644 --- a/testing/ef_tests/src/cases/ssz_static.rs +++ b/testing/ef_tests/src/cases/ssz_static.rs @@ -1,6 +1,5 @@ use super::*; use crate::case_result::compare_result; -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; @@ -168,11 +167,9 @@ impl Case for SszStaticWithSpec> { } } -impl LoadCase for SszStaticWithSpec> { +impl LoadCase for SszStaticWithSpec> { fn load_from_dir(path: &Path, fork_name: ForkName) -> Result { - let spec = &testing_spec::(fork_name); - let context = (fork_name, spec.number_of_columns as usize); - load_from_dir_with_context(path, context).map(|(roots, serialized, value)| Self { + load_from_dir(path, fork_name).map(|(roots, serialized, value)| Self { roots, serialized, value, @@ -180,12 +177,10 @@ impl LoadCase for SszStaticWithSpec Case for SszStaticWithSpec> { - fn result(&self, _case_index: usize, fork_name: ForkName) -> Result<(), Error> { - let spec = &testing_spec::(fork_name); +impl Case for SszStaticWithSpec> { + fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> { check_serialization(&self.value, &self.serialized, |bytes| { - DataColumnsByRootIdentifier::from_ssz_bytes(bytes, spec.number_of_columns as usize) - .map(Into::into) + DataColumnsByRootIdentifier::from_ssz_bytes(bytes) })?; check_tree_hash(&self.roots.root, self.value.tree_hash_root().as_slice())?; Ok(()) diff --git a/testing/ef_tests/src/lib.rs b/testing/ef_tests/src/lib.rs index a2d905738e..8ec4860cab 100644 --- a/testing/ef_tests/src/lib.rs +++ b/testing/ef_tests/src/lib.rs @@ -1,11 +1,11 @@ pub use case_result::CaseResult; pub use cases::WithdrawalsPayload; pub use cases::{ - Case, DataColumnsByRootIdentifierWrapper, EffectiveBalanceUpdates, Eth1DataReset, FeatureName, - HistoricalRootsUpdate, HistoricalSummariesUpdate, InactivityUpdates, - JustificationAndFinalization, ParticipationFlagUpdates, ParticipationRecordUpdates, - PendingBalanceDeposits, PendingConsolidations, ProposerLookahead, RandaoMixesReset, - RegistryUpdates, RewardsAndPenalties, Slashings, SlashingsReset, SyncCommitteeUpdates, + Case, EffectiveBalanceUpdates, Eth1DataReset, FeatureName, HistoricalRootsUpdate, + HistoricalSummariesUpdate, InactivityUpdates, JustificationAndFinalization, + ParticipationFlagUpdates, ParticipationRecordUpdates, PendingBalanceDeposits, + PendingConsolidations, ProposerLookahead, RandaoMixesReset, RegistryUpdates, + RewardsAndPenalties, Slashings, SlashingsReset, SyncCommitteeUpdates, }; pub use decode::log_file_access; pub use error::Error; diff --git a/testing/ef_tests/src/type_name.rs b/testing/ef_tests/src/type_name.rs index b5b2c424d8..2d13a6daa1 100644 --- a/testing/ef_tests/src/type_name.rs +++ b/testing/ef_tests/src/type_name.rs @@ -1,5 +1,4 @@ //! Mapping from types to canonical string identifiers used in testing. -use crate::DataColumnsByRootIdentifierWrapper; use types::historical_summary::HistoricalSummary; use types::*; @@ -59,11 +58,7 @@ type_name_generic!(BeaconBlockBodyFulu, "BeaconBlockBody"); type_name!(BeaconBlockHeader); type_name_generic!(BeaconState); type_name!(BlobIdentifier); -type_name!(DataColumnsByRootIdentifier); -type_name_generic!( - DataColumnsByRootIdentifierWrapper, - "DataColumnsByRootIdentifier" -); +type_name_generic!(DataColumnsByRootIdentifier, "DataColumnsByRootIdentifier"); type_name_generic!(BlobSidecar); type_name_generic!(DataColumnSidecar); type_name!(Checkpoint); diff --git a/testing/ef_tests/tests/tests.rs b/testing/ef_tests/tests/tests.rs index b6264f2e08..089e4464cd 100644 --- a/testing/ef_tests/tests/tests.rs +++ b/testing/ef_tests/tests/tests.rs @@ -237,10 +237,7 @@ macro_rules! ssz_static_test_no_run { #[cfg(feature = "fake_crypto")] mod ssz_static { - use ef_tests::{ - DataColumnsByRootIdentifierWrapper, Handler, SszStaticHandler, SszStaticTHCHandler, - SszStaticWithSpecHandler, - }; + use ef_tests::{Handler, SszStaticHandler, SszStaticTHCHandler, SszStaticWithSpecHandler}; use types::historical_summary::HistoricalSummary; use types::{ AttesterSlashingBase, AttesterSlashingElectra, ConsolidationRequest, DepositRequest, @@ -670,12 +667,12 @@ mod ssz_static { #[test] fn data_column_by_root_identifier() { SszStaticWithSpecHandler::< - DataColumnsByRootIdentifierWrapper, + DataColumnsByRootIdentifier, MinimalEthSpec, >::fulu_and_later() .run(); SszStaticWithSpecHandler::< - DataColumnsByRootIdentifierWrapper, + DataColumnsByRootIdentifier, MainnetEthSpec, >::fulu_and_later() .run();