diff --git a/beacon_node/beacon_chain/src/data_availability_router.rs b/beacon_node/beacon_chain/src/data_availability_router.rs index 0e45a847d3..3b46771146 100644 --- a/beacon_node/beacon_chain/src/data_availability_router.rs +++ b/beacon_node/beacon_chain/src/data_availability_router.rs @@ -344,15 +344,21 @@ impl DataAvailabilityRouter { self.pending_block_cache.get_cached_block(block_root) } - /// Inserts a pre-execution block into the cache (v1). + /// Inserts a pre-execution block into the cache. pub fn put_pre_execution_block( &self, block_root: Hash256, block: Arc>, source: BlockImportSource, ) -> Result<(), AvailabilityCheckError> { - self.pending_block_cache - .put_pre_execution_block(block_root, block, source) + if let ForkName::Gloas = block.fork_name_unchecked() { + self.pending_payload_cache + .init_pending_block(block_root, block); + Ok(()) + } else { + self.pending_block_cache + .put_pre_execution_block(block_root, block, source) + } } /// Insert an executed block and check availability (v1). diff --git a/beacon_node/beacon_chain/src/payload_envelope_verification/mod.rs b/beacon_node/beacon_chain/src/payload_envelope_verification/mod.rs index bfd459ed2e..fdce30ecb8 100644 --- a/beacon_node/beacon_chain/src/payload_envelope_verification/mod.rs +++ b/beacon_node/beacon_chain/src/payload_envelope_verification/mod.rs @@ -25,7 +25,7 @@ use state_processing::{BlockProcessingError, envelope_processing::EnvelopeProces use store::Error as DBError; use tracing::instrument; use types::{ - BeaconState, BeaconStateError, ChainSpec, DataColumnSidecarList, EthSpec, ExecutionBlockHash, + BeaconState, BeaconStateError, DataColumnSidecarList, EthSpec, ExecutionBlockHash, ExecutionPayloadEnvelope, Hash256, SignedExecutionPayloadEnvelope, Slot, }; @@ -57,7 +57,6 @@ pub struct AvailableEnvelope { pub columns: DataColumnSidecarList, /// Timestamp at which this envelope first became available (UNIX timestamp, time since 1970). pub columns_available_timestamp: Option, - pub spec: Arc, } impl AvailableEnvelope { @@ -66,14 +65,12 @@ impl AvailableEnvelope { envelope: Arc>, columns: DataColumnSidecarList, columns_available_timestamp: Option, - spec: Arc, ) -> Self { Self { execution_block_hash, envelope, columns, columns_available_timestamp, - spec, } } diff --git a/beacon_node/beacon_chain/src/pending_payload_cache/mod.rs b/beacon_node/beacon_chain/src/pending_payload_cache/mod.rs index 616e3ead32..a2cd393a14 100644 --- a/beacon_node/beacon_chain/src/pending_payload_cache/mod.rs +++ b/beacon_node/beacon_chain/src/pending_payload_cache/mod.rs @@ -55,12 +55,13 @@ use task_executor::TaskExecutor; use tracing::{Span, debug, error, instrument, trace}; use types::{ ChainSpec, ColumnIndex, DataColumnSidecar, DataColumnSidecarList, Epoch, EthSpec, Hash256, - PartialDataColumnSidecarRef, Slot, + PartialDataColumnSidecarRef, SignedBeaconBlock, Slot, }; mod pending_column; mod pending_components; +use crate::block_verification_types::AsBlock; use crate::data_column_verification::{ GossipVerifiedDataColumn, KzgVerifiedCustodyDataColumn, KzgVerifiedDataColumn, }; @@ -159,7 +160,12 @@ impl PendingPayloadCache { c.verified_data_columns .iter() .filter_map(|(col_idx, col)| { - col.try_to_sidecar(*col_idx, c.slot, block_root, c.num_blobs_expected) + col.try_to_sidecar( + *col_idx, + c.block.slot(), + block_root, + c.num_blobs_expected(), + ) }) .collect() }) @@ -229,11 +235,13 @@ impl PendingPayloadCache { /// Initialize pending components for a block. Called when the beacon block (containing the /// bid) arrives. Sets up the slot and expected blob count so that subsequent column insertions /// know how many cells to expect per column. - pub fn init_pending_block(&self, block_root: Hash256, slot: Slot, num_blobs_expected: usize) { + pub fn init_pending_block( + &self, + block_root: Hash256, + block: Arc>, + ) { let mut write_lock = self.availability_cache.write(); - write_lock.get_or_insert_mut(block_root, || { - PendingComponents::empty(block_root, slot, num_blobs_expected, self.spec.clone()) - }); + write_lock.get_or_insert_mut(block_root, || PendingComponents::empty(block_root, block)); } /// Perform KZG verification on RPC custody columns and insert them into the cache. @@ -761,17 +769,6 @@ mod data_availability_checker_tests { // once the Gloas harness can produce KZG-valid columns. These wrappers add KZG verification // and custody column filtering on top of `put_kzg_verified_custody_data_columns`. - fn num_blobs_in_block(block: &SignedBeaconBlock>) -> usize { - block - .message() - .body() - .signed_execution_payload_bid() - .expect("gloas block should have bid") - .message - .blob_kzg_commitments - .len() - } - fn make_test_signed_envelope(block_root: Hash256) -> Arc> { Arc::new(SignedExecutionPayloadEnvelope { message: ExecutionPayloadEnvelope { @@ -817,7 +814,7 @@ mod data_availability_checker_tests { ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let verified_columns: Vec<_> = data_columns .into_iter() @@ -861,7 +858,7 @@ mod data_availability_checker_tests { ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let first_column = data_columns.first().cloned().expect("should have column"); let column_index = *first_column.index(); @@ -907,7 +904,7 @@ mod data_availability_checker_tests { ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let verified_columns: Vec<_> = data_columns .into_iter() @@ -946,7 +943,7 @@ mod data_availability_checker_tests { ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let verified_columns: Vec<_> = data_columns .into_iter() @@ -982,10 +979,20 @@ mod data_availability_checker_tests { } type T = DiskHarnessType; - let (_harness, cache, _path) = setup_harness_and_cache::().await; + let (harness, cache, _path) = setup_harness_and_cache::().await; + + let mut rng = StdRng::seed_from_u64(0xDEADBEEF); + let spec = harness.spec.clone(); + + let (block, _) = generate_rand_block_and_data_columns::( + ForkName::Gloas, + NumBlobs::Number(0), + &mut rng, + &spec, + ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), 0); + cache.init_pending_block(block_root, Arc::new(block)); let executed_envelope = make_test_executed_envelope(block_root); let result = cache @@ -1019,7 +1026,7 @@ mod data_availability_checker_tests { ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let verified_columns: Vec<_> = data_columns .into_iter() @@ -1088,7 +1095,7 @@ mod data_availability_checker_tests { assert!(cache.get_data_columns(block_root).is_none()); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let verified_columns: Vec<_> = data_columns .into_iter() @@ -1128,13 +1135,13 @@ mod data_availability_checker_tests { &spec, ); - let num_blobs = num_blobs_in_block(&block); + let block = Arc::new(block); let mut roots = Vec::new(); for _ in 0..33 { let block_root = Hash256::random(); roots.push(block_root); - cache.init_pending_block(block_root, Slot::new(0), num_blobs); + cache.init_pending_block(block_root, block.clone()); let col = data_columns.first().cloned().expect("should have column"); let verified = vec![KzgVerifiedCustodyDataColumn::from_asserted_custody( KzgVerifiedDataColumn::__new_for_testing(col), @@ -1169,7 +1176,7 @@ mod data_availability_checker_tests { ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let col = data_columns.first().cloned().expect("should have column"); let verified = vec![KzgVerifiedCustodyDataColumn::from_asserted_custody( @@ -1209,7 +1216,7 @@ mod data_availability_checker_tests { ); let block_root = Hash256::random(); - cache.init_pending_block(block_root, Slot::new(0), num_blobs_in_block(&block)); + cache.init_pending_block(block_root, Arc::new(block)); let executed_envelope = make_test_executed_envelope(block_root); cache diff --git a/beacon_node/beacon_chain/src/pending_payload_cache/pending_components.rs b/beacon_node/beacon_chain/src/pending_payload_cache/pending_components.rs index 9d16ecbdf6..b88a602772 100644 --- a/beacon_node/beacon_chain/src/pending_payload_cache/pending_components.rs +++ b/beacon_node/beacon_chain/src/pending_payload_cache/pending_components.rs @@ -8,31 +8,38 @@ use std::cmp::Ordering; use std::collections::HashMap; use std::sync::Arc; use tracing::{Span, debug, debug_span}; -use types::{ChainSpec, ColumnIndex, Epoch, EthSpec, Hash256}; -use types::{DataColumnSidecar, Slot}; +use types::DataColumnSidecar; +use types::{ColumnIndex, Epoch, EthSpec, Hash256, SignedBeaconBlock}; /// This represents the components of a payload pending data availability. /// /// The columns are all gossip and kzg verified. /// The payload is considered "available" when all required columns are received. pub struct PendingComponents { - pub slot: Slot, - pub num_blobs_expected: usize, + pub block: Arc>, /// a cached post executed payload envelope pub envelope: Option>, pub verified_data_columns: HashMap>, pub reconstruction_started: bool, pub(crate) span: Span, - spec: Arc, } impl PendingComponents { + pub fn num_blobs_expected(&self) -> usize { + self.block.num_expected_blobs() + } + /// Returns the completed custody columns pub fn get_cached_data_columns(&self, block_root: Hash256) -> Vec>> { self.verified_data_columns .iter() .filter_map(|(col_idx, col)| { - col.try_to_sidecar(*col_idx, self.slot, block_root, self.num_blobs_expected) + col.try_to_sidecar( + *col_idx, + self.block.slot(), + block_root, + self.num_blobs_expected(), + ) }) .collect() } @@ -42,7 +49,8 @@ impl PendingComponents { self.verified_data_columns .iter() .filter_map(|(col_idx, col)| { - col.is_complete(self.num_blobs_expected).then_some(*col_idx) + col.is_complete(self.num_blobs_expected()) + .then_some(*col_idx) }) .collect() } @@ -52,12 +60,13 @@ impl PendingComponents { &mut self, kzg_verified_data_columns: I, ) -> Result<(), AvailabilityCheckError> { + let num_blobs_expected = self.num_blobs_expected(); for data_column in kzg_verified_data_columns { let data_column = data_column.as_data_column(); let col = self .verified_data_columns .entry(*data_column.index()) - .or_insert_with(|| PendingColumn::new_with_capacity(self.num_blobs_expected)); + .or_insert_with(|| PendingColumn::new_with_capacity(num_blobs_expected)); for (cell_idx, (cell, proof)) in data_column .column() .iter() @@ -84,7 +93,7 @@ impl PendingComponents { pub fn num_completed_columns(&self) -> usize { self.verified_data_columns .values() - .filter_map(|col| col.is_complete(self.num_blobs_expected).then_some(())) + .filter_map(|col| col.is_complete(self.num_blobs_expected()).then_some(())) .count() } @@ -105,7 +114,7 @@ impl PendingComponents { payload_verification_outcome, } = envelope; - let columns = if self.num_blobs_expected == 0 { + let columns = if self.num_blobs_expected() == 0 { self.span.in_scope(|| { debug!("Bid has no blobs, data is available"); }); @@ -129,9 +138,9 @@ impl PendingComponents { .filter_map(|(col_idx, col)| { col.try_to_sidecar( *col_idx, - self.slot, + self.block.slot(), block_hash, - self.num_blobs_expected, + self.num_blobs_expected(), ) }) .collect() @@ -148,7 +157,6 @@ impl PendingComponents { envelope: envelope.clone(), columns, columns_available_timestamp: None, - spec: self.spec.clone(), }; Ok(Some(AvailableExecutedEnvelope { @@ -159,28 +167,21 @@ impl PendingComponents { } /// Returns an empty `PendingComponents` object with the given block root. - pub fn empty( - block_root: Hash256, - slot: Slot, - num_blobs_expected: usize, - spec: Arc, - ) -> Self { - let span = debug_span!(parent: None, "lh_pending_components", %block_root, %slot); + pub fn empty(block_root: Hash256, block: Arc>) -> Self { + let span = debug_span!(parent: None, "lh_pending_components", %block_root); let _guard = span.clone().entered(); Self { - slot, - num_blobs_expected, + block, envelope: None, verified_data_columns: HashMap::new(), reconstruction_started: false, span, - spec, } } /// Returns the epoch of the bid or first data column, if available. pub fn epoch(&self) -> Epoch { - self.slot.epoch(E::slots_per_epoch()) + self.block.slot().epoch(E::slots_per_epoch()) } pub fn status_str(&self, num_expected_columns: usize) -> String { diff --git a/consensus/types/src/block/signed_beacon_block.rs b/consensus/types/src/block/signed_beacon_block.rs index 23b01415c8..e901901599 100644 --- a/consensus/types/src/block/signed_beacon_block.rs +++ b/consensus/types/src/block/signed_beacon_block.rs @@ -354,6 +354,12 @@ impl> SignedBeaconBlock self.message() .body() .blob_kzg_commitments() + .or_else(|_| { + self.message() + .body() + .signed_execution_payload_bid() + .map(|bid| &bid.message.blob_kzg_commitments) + }) .map(|c| c.len()) .unwrap_or(0) }