diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index 81ff8e5fc9..e5ac442551 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -511,9 +511,7 @@ impl TryInto> for MaybeAvailableBlock { fn try_into(self) -> Result, Self::Error> { match self { Self::Available(block) => Ok(block), - Self::AvailabilityPending(block) => Err(AvailabilityCheckError::MissingBlobs( - block.as_block().canonical_root(), - )), + Self::AvailabilityPending(block) => Err(AvailabilityCheckError::MissingBlobs), } } } diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index 5b8ad5c7bf..8650372355 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -861,12 +861,10 @@ where slasher: self.slasher.clone(), validator_monitor: RwLock::new(validator_monitor), //TODO(sean) should we move kzg solely to the da checker? - data_availability_checker: Arc::new(DataAvailabilityChecker::new( - slot_clock, - kzg.clone(), - store, - self.spec, - ).map_err(|e| format!("Error initializing DataAvailabiltyChecker: {:?}", e))?), + data_availability_checker: Arc::new( + DataAvailabilityChecker::new(slot_clock, kzg.clone(), store, self.spec) + .map_err(|e| format!("Error initializing DataAvailabiltyChecker: {:?}", e))?, + ), proposal_blob_cache: BlobCache::default(), kzg, }; diff --git a/beacon_node/beacon_chain/src/data_availability_checker.rs b/beacon_node/beacon_chain/src/data_availability_checker.rs index 64ee2663fc..72700947ca 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker.rs @@ -10,13 +10,12 @@ use kzg::Error as KzgError; use kzg::Kzg; use slog::{debug, error}; use slot_clock::SlotClock; -use ssz_types::{Error, VariableList}; +use ssz_types::{Error, FixedVector, VariableList}; use state_processing::per_block_processing::deneb::deneb::verify_kzg_commitments_against_transactions; -use std::collections::hash_map::{Entry, OccupiedEntry}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::sync::Arc; -use task_executor::TaskExecutor; use strum::IntoStaticStr; +use task_executor::TaskExecutor; use types::beacon_block_body::KzgCommitments; use types::blob_sidecar::{BlobIdentifier, BlobSidecar, FixedBlobSidecarList}; use types::consts::deneb::MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS; @@ -36,7 +35,7 @@ pub enum AvailabilityCheckError { KzgVerificationFailed, KzgNotInitialized, SszTypes(ssz_types::Error), - MissingBlobs(Hash256), + MissingBlobs, NumBlobsMismatch { num_kzg_commitments: usize, num_blobs: usize, @@ -89,56 +88,6 @@ pub struct DataAvailabilityChecker { spec: ChainSpec, } -/// Caches partially available blobs and execution verified blocks corresponding -/// to a given `block_hash` that are received over gossip. -/// -/// The blobs are all gossip and kzg verified. -/// The block has completed all verifications except the availability check. -struct ReceivedComponents { - verified_blobs: FixedVector>, T::MaxBlobsPerBlock>, - executed_block: Option>, -} - -impl ReceivedComponents { - fn new_from_blobs(blobs: &[KzgVerifiedBlob]) -> Self { - let mut verified_blobs = FixedVector::<_, _>::default(); - for blob in blobs { - // TODO: verify that we've already ensured the blob index < T::MaxBlobsPerBlock - if let Some(mut_maybe_blob) = verified_blobs.get_mut(blob.blob_index() as usize) { - *mut_maybe_blob = Some(blob.clone()); - } - } - - Self { - verified_blobs, - executed_block: None, - } - } - - fn new_from_block(block: AvailabilityPendingExecutedBlock) -> Self { - Self { - verified_blobs: <_>::default(), - executed_block: Some(block), - } - } - - /// Returns `true` if the cache has all blobs corresponding to the - /// kzg commitments in the block. - fn has_all_blobs(&self, block: &AvailabilityPendingExecutedBlock) -> bool { - for i in 0..block.num_blobs_expected() { - if self - .verified_blobs - .get(i) - .map(|maybe_blob| maybe_blob.is_none()) - .unwrap_or(true) - { - return false; - } - } - true - } -} - /// This type is returned after adding a block / blob to the `DataAvailabilityChecker`. /// /// Indicates if the block is fully `Available` or if we need blobs or blocks @@ -178,34 +127,17 @@ impl DataAvailabilityChecker { } pub fn has_block(&self, block_root: &Hash256) -> bool { - self.availability_cache - .read() - .get(block_root) - .map_or(false, |cache| cache.executed_block.is_some()) + self.availability_cache.has_block(block_root) } pub fn get_missing_blob_ids_checking_cache( &self, block_root: Hash256, ) -> Option> { - let guard = self.availability_cache.read(); - let (block, blob_indices) = guard - .get(&block_root) - .map(|cache| { - let block_opt = cache - .executed_block - .as_ref() - .map(|block| &block.block.block); - let blobs = cache - .verified_blobs - .iter() - .enumerate() - .filter_map(|(i, maybe_blob)| maybe_blob.as_ref().map(|_| i)) - .collect::>(); - (block_opt, blobs) - }) - .unwrap_or_default(); - self.get_missing_blob_ids(block_root, block, Some(blob_indices)) + let (block, blob_indices) = self + .availability_cache + .get_missing_blob_ids_checking_cache(block_root); + self.get_missing_blob_ids(block_root, block.as_ref(), Some(blob_indices)) } /// A `None` indicates blobs are not required. @@ -215,10 +147,10 @@ impl DataAvailabilityChecker { pub fn get_missing_blob_ids( &self, block_root: Hash256, - block_opt: Option<&Arc>>, + block_opt: Option<&Arc>>, blobs_opt: Option>, ) -> Option> { - let epoch = self.slot_clock.now()?.epoch(T::slots_per_epoch()); + let epoch = self.slot_clock.now()?.epoch(T::EthSpec::slots_per_epoch()); self.da_check_required(epoch).then(|| { block_opt @@ -228,8 +160,8 @@ impl DataAvailabilityChecker { }) }) .unwrap_or_else(|| { - let mut blob_ids = Vec::with_capacity(T::max_blobs_per_block()); - for i in 0..T::max_blobs_per_block() { + let mut blob_ids = Vec::with_capacity(T::EthSpec::max_blobs_per_block()); + for i in 0..T::EthSpec::max_blobs_per_block() { if blobs_opt.as_ref().map_or(true, |blobs| !blobs.contains(&i)) { blob_ids.push(BlobIdentifier { block_root, @@ -253,8 +185,8 @@ impl DataAvailabilityChecker { pub fn put_rpc_blobs( &self, block_root: Hash256, - blobs: FixedBlobSidecarList, - ) -> Result, AvailabilityCheckError> { + blobs: FixedBlobSidecarList, + ) -> Result, AvailabilityCheckError> { // TODO(sean) we may duplicated kzg verification on some blobs we already have cached so we could optimize this let mut verified_blobs = vec![]; @@ -265,8 +197,8 @@ impl DataAvailabilityChecker { } else { return Err(AvailabilityCheckError::KzgNotInitialized); }; - - self.put_kzg_verified_blobs(block_root, &verified_blobs) + self.availability_cache + .put_kzg_verified_blobs(block_root, &verified_blobs) } /// This first validates the KZG commitments included in the blob sidecar. @@ -287,53 +219,7 @@ impl DataAvailabilityChecker { }; self.availability_cache - .put_kzg_verified_blob(kzg_verified_blob) - self.put_kzg_verified_blobs(kzg_verified_blob.block_root(), &[kzg_verified_blob]) - } - - fn put_kzg_verified_blobs( - &self, - block_root: Hash256, - kzg_verified_blobs: &[KzgVerifiedBlob], - ) -> Result, AvailabilityCheckError> { - for blob in kzg_verified_blobs { - let blob_block_root = blob.block_root(); - if blob_block_root != block_root { - return Err(AvailabilityCheckError::BlockBlobRootMismatch { - block_root, - blob_block_root, - }); - } - } - - let availability = match self.availability_cache.write().entry(block_root) { - Entry::Occupied(mut occupied_entry) => { - // All blobs reaching this cache should be gossip verified and gossip verification - // should filter duplicates, as well as validate indices. - let received_components = occupied_entry.get_mut(); - - for kzg_verified_blob in kzg_verified_blobs { - if let Some(maybe_verified_blob) = received_components - .verified_blobs - .get_mut(kzg_verified_blob.blob_index() as usize) - { - *maybe_verified_blob = Some(kzg_verified_blob.clone()) - } - } - - if let Some(executed_block) = received_components.executed_block.take() { - self.check_block_availability_maybe_cache(occupied_entry, executed_block)? - } else { - Availability::MissingComponents(block_root) - } - } - Entry::Vacant(vacant_entry) => { - vacant_entry.insert(ReceivedComponents::new_from_blobs(kzg_verified_blobs)); - Availability::MissingComponents(block_root) - } - }; - - Ok(availability) + .put_kzg_verified_blobs(kzg_verified_blob.block_root(), &[kzg_verified_blob]) } /// Check if we have all the blobs for a block. If we do, return the Availability variant that @@ -346,59 +232,6 @@ impl DataAvailabilityChecker { .put_pending_executed_block(executed_block) } - /// Checks if the provided `executed_block` contains all required blobs to be considered an - /// `AvailableBlock` based on blobs that are cached. - /// - /// Returns an error if there was an error when matching the block commitments against blob commitments. - /// - /// Returns `Ok(Availability::Available(_))` if all blobs for the block are present in cache. - /// Returns `Ok(Availability::PendingBlobs(_))` if all corresponding blobs have not been received in the cache. - fn check_block_availability_maybe_cache( - &self, - mut occupied_entry: OccupiedEntry>, - executed_block: AvailabilityPendingExecutedBlock, - ) -> Result, AvailabilityCheckError> { - if occupied_entry.get().has_all_blobs(&executed_block) { - let num_blobs_expected = executed_block.num_blobs_expected(); - let block_root = executed_block.import_data.block_root; - let AvailabilityPendingExecutedBlock { - block, - import_data, - payload_verification_outcome, - } = executed_block; - - let ReceivedComponents { - verified_blobs, - executed_block: _, - } = occupied_entry.remove(); - - let verified_blobs = Vec::from(verified_blobs) - .into_iter() - .take(num_blobs_expected) - .map(|maybe_blob| { - maybe_blob.ok_or(AvailabilityCheckError::MissingBlobs(block_root)) - }) - .collect::, _>>()?; - - let available_block = self.make_available(block, verified_blobs)?; - Ok(Availability::Available(Box::new( - AvailableExecutedBlock::new( - available_block, - import_data, - payload_verification_outcome, - ), - ))) - } else { - let received_components = occupied_entry.get_mut(); - - let block_root = executed_block.import_data.block_root; - - let _ = received_components.executed_block.insert(executed_block); - - Ok(Availability::MissingComponents(block_root)) - } - } - /// Checks if a block is available, returns a `MaybeAvailableBlock` that may include the fully /// available block. pub fn check_availability( @@ -422,27 +255,6 @@ impl DataAvailabilityChecker { } } - /// Checks if a block is available, returning an error if the block is not immediately available. - /// Does not access the gossip cache. - pub fn try_check_availability( - &self, - block: BlockWrapper, - ) -> Result, AvailabilityCheckError> { - match block { - BlockWrapper::Block(block) => { - let blob_requirements = self.get_blob_requirements(&block)?; - let blobs = match blob_requirements { - BlobRequirements::EmptyBlobs => VerifiedBlobs::EmptyBlobs, - BlobRequirements::NotRequired => VerifiedBlobs::NotRequired, - BlobRequirements::PreDeneb => VerifiedBlobs::PreDeneb, - BlobRequirements::Required => return Err(AvailabilityCheckError::MissingBlobs), - }; - Ok(AvailableBlock { block, blobs }) - } - BlockWrapper::BlockAndBlobs(_, _) => Err(AvailabilityCheckError::Pending), - } - } - /// Verifies a block against a set of KZG verified blobs. Returns an AvailableBlock if block's /// commitments are consistent with the provided verified blob commitments. pub fn check_availability_with_blobs( 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 4ad5f57eb6..384ff9a667 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 @@ -11,7 +11,7 @@ use ssz_derive::{Decode, Encode}; use ssz_types::FixedVector; use std::{collections::HashSet, sync::Arc}; use types::blob_sidecar::BlobIdentifier; -use types::{BlobSidecar, Epoch, EthSpec, Hash256}; +use types::{BlobSidecar, Epoch, EthSpec, Hash256, SignedBeaconBlock}; /// Caches partially available blobs and execution verified blocks corresponding /// to a given `block_hash` that are received over gossip. @@ -25,10 +25,12 @@ pub struct PendingComponents { } impl PendingComponents { - pub fn new_from_blob(blob: KzgVerifiedBlob) -> Self { + pub fn new_from_blobs(blobs: &[KzgVerifiedBlob]) -> Self { let mut verified_blobs = FixedVector::<_, _>::default(); - if let Some(mut_maybe_blob) = verified_blobs.get_mut(blob.blob_index() as usize) { - *mut_maybe_blob = Some(blob); + for blob in blobs { + if let Some(mut_maybe_blob) = verified_blobs.get_mut(blob.blob_index() as usize) { + *mut_maybe_blob = Some(blob.clone()); + } } Self { @@ -240,6 +242,12 @@ impl Critical { Ok(()) } + pub fn has_block(&self, block_root: &Hash256) -> bool { + self.in_memory + .peek(block_root) + .map_or(false, |cache| cache.executed_block.is_some()) + } + /// This only checks for the blobs in memory pub fn peek_blob( &self, @@ -320,6 +328,34 @@ impl OverflowLRUCache { }) } + pub fn has_block(&self, block_root: &Hash256) -> bool { + self.critical.read().has_block(block_root) + } + + pub fn get_missing_blob_ids_checking_cache( + &self, + block_root: Hash256, + ) -> (Option>>, HashSet) { + self.critical + .read() + .in_memory + .peek(&block_root) + .map(|cache| { + let block_opt = cache + .executed_block + .as_ref() + .map(|block| block.block.block.clone()); + let blobs = cache + .verified_blobs + .iter() + .enumerate() + .filter_map(|(i, maybe_blob)| maybe_blob.as_ref().map(|_| i)) + .collect::>(); + (block_opt, blobs) + }) + .unwrap_or_default() + } + pub fn peek_blob( &self, blob_id: &BlobIdentifier, @@ -335,27 +371,39 @@ impl OverflowLRUCache { } } - pub fn put_kzg_verified_blob( + pub fn put_kzg_verified_blobs( &self, - kzg_verified_blob: KzgVerifiedBlob, + block_root: Hash256, + kzg_verified_blobs: &[KzgVerifiedBlob], ) -> Result, AvailabilityCheckError> { + for blob in kzg_verified_blobs { + let blob_block_root = blob.block_root(); + if blob_block_root != block_root { + return Err(AvailabilityCheckError::BlockBlobRootMismatch { + block_root, + blob_block_root, + }); + } + } let mut write_lock = self.critical.write(); - let block_root = kzg_verified_blob.block_root(); let availability = if let Some(mut pending_components) = write_lock.pop_pending_components(block_root, &self.overflow_store)? { - let blob_index = kzg_verified_blob.blob_index(); - *pending_components - .verified_blobs - .get_mut(blob_index as usize) - .ok_or(AvailabilityCheckError::BlobIndexInvalid(blob_index))? = - Some(kzg_verified_blob); + for kzg_verified_blob in kzg_verified_blobs { + let blob_index = kzg_verified_blob.blob_index() as usize; + if let Some(maybe_verified_blob) = + pending_components.verified_blobs.get_mut(blob_index) + { + *maybe_verified_blob = Some(kzg_verified_blob.clone()) + } else { + return Err(AvailabilityCheckError::BlobIndexInvalid(blob_index as u64)); + } + } if let Some(executed_block) = pending_components.executed_block.take() { self.check_block_availability_maybe_cache( write_lock, - block_root, pending_components, executed_block, )? @@ -365,17 +413,17 @@ impl OverflowLRUCache { pending_components, &self.overflow_store, )?; - Availability::PendingBlock(block_root) + Availability::MissingComponents(block_root) } } else { // not in memory or store -> put new in memory - let new_pending_components = PendingComponents::new_from_blob(kzg_verified_blob); + let new_pending_components = PendingComponents::new_from_blobs(kzg_verified_blobs); write_lock.put_pending_components( block_root, new_pending_components, &self.overflow_store, )?; - Availability::PendingBlock(block_root) + Availability::MissingComponents(block_root) }; Ok(availability) @@ -394,7 +442,6 @@ impl OverflowLRUCache { match write_lock.pop_pending_components(block_root, &self.overflow_store)? { Some(pending_components) => self.check_block_availability_maybe_cache( write_lock, - block_root, pending_components, executed_block, )?, @@ -422,7 +469,7 @@ impl OverflowLRUCache { new_pending_components, &self.overflow_store, )?; - Availability::PendingBlobs(all_blob_ids) + Availability::MissingComponents(block_root) } }; @@ -435,11 +482,10 @@ impl OverflowLRUCache { /// Returns an error if there was an error when matching the block commitments against blob commitments. /// /// Returns `Ok(Availability::Available(_))` if all blobs for the block are present in cache. - /// Returns `Ok(Availability::PendingBlobs(_))` if all corresponding blobs have not been received in the cache. + /// Returns `Ok(Availability::MissingComponents(_))` if all corresponding blobs have not been received in the cache. fn check_block_availability_maybe_cache( &self, mut write_lock: RwLockWriteGuard>, - block_root: Hash256, mut pending_components: PendingComponents, executed_block: AvailabilityPendingExecutedBlock, ) -> Result, AvailabilityCheckError> { @@ -466,14 +512,7 @@ impl OverflowLRUCache { ), ))) } else { - let missing_blob_ids = executed_block.get_filtered_blob_ids(|index| { - pending_components - .verified_blobs - .get(index as usize) - .map(|maybe_blob| maybe_blob.is_none()) - .unwrap_or(true) - }); - + let block_root = executed_block.import_data.block_root; let _ = pending_components.executed_block.insert(executed_block); write_lock.put_pending_components( block_root, @@ -481,7 +520,7 @@ impl OverflowLRUCache { &self.overflow_store, )?; - Ok(Availability::PendingBlobs(missing_blob_ids)) + Ok(Availability::MissingComponents(block_root)) } } @@ -1080,7 +1119,7 @@ mod test { ); } else { assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "should be pending blobs" ); assert_eq!( @@ -1109,7 +1148,7 @@ mod test { if blob_index == blobs_expected - 1 { assert!(matches!(availability, Availability::Available(_))); } else { - assert!(matches!(availability, Availability::PendingBlobs(_))); + assert!(matches!(availability, Availability::MissingComponents(_))); assert_eq!(cache.critical.read().in_memory.len(), 1); } } @@ -1134,7 +1173,7 @@ mod test { .expect("should put blob"); assert_eq!( availability, - Availability::PendingBlock(root), + Availability::MissingComponents(root), "should be pending block" ); assert_eq!(cache.critical.read().in_memory.len(), 1); @@ -1284,7 +1323,7 @@ mod test { cache.critical.read().in_memory.peek(&roots[0]).is_some(), "first block should be in memory" ); - assert!(matches!(availability, Availability::PendingBlobs(_))); + assert!(matches!(availability, Availability::MissingComponents(_))); } } assert_eq!( @@ -1374,14 +1413,14 @@ mod test { .put_pending_executed_block(pending_block) .expect("should put block"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "should have pending blobs" ); let availability = cache .put_kzg_verified_blob(kzg_verified_blob) .expect("should put blob"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "availabilty should be pending blobs: {:?}", availability ); @@ -1392,14 +1431,14 @@ mod test { let root = pending_block.block.as_block().canonical_root(); assert_eq!( availability, - Availability::PendingBlock(root), + Availability::MissingComponents(root), "should be pending block" ); let availability = cache .put_pending_executed_block(pending_block) .expect("should put block"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "should have pending blobs" ); } @@ -1410,7 +1449,7 @@ mod test { .put_pending_executed_block(pending_block) .expect("should put block"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "should be pending blobs" ); } @@ -1527,14 +1566,14 @@ mod test { .put_pending_executed_block(pending_block) .expect("should put block"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "should have pending blobs" ); let availability = cache .put_kzg_verified_blob(kzg_verified_blob) .expect("should put blob"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "availabilty should be pending blobs: {:?}", availability ); @@ -1545,14 +1584,14 @@ mod test { let root = pending_block.block.as_block().canonical_root(); assert_eq!( availability, - Availability::PendingBlock(root), + Availability::MissingComponents(root), "should be pending block" ); let availability = cache .put_pending_executed_block(pending_block) .expect("should put block"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "should have pending blobs" ); } @@ -1564,7 +1603,7 @@ mod test { .put_pending_executed_block(pending_block) .expect("should put block"); assert!( - matches!(availability, Availability::PendingBlobs(_)), + matches!(availability, Availability::MissingComponents(_)), "should be pending blobs" ); } @@ -1637,7 +1676,7 @@ mod test { if i == additional_blobs - 1 { assert!(matches!(availability, Availability::Available(_))) } else { - assert!(matches!(availability, Availability::PendingBlobs(_))); + assert!(matches!(availability, Availability::MissingComponents(_))); } } } diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index 78d0675ea1..f20808b896 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -658,34 +658,34 @@ pub fn generate_random_blobs( let versioned_hash = commitment.calculate_versioned_hash(); - let blob_transaction = BlobTransaction { - chain_id: Default::default(), - nonce: 0, - max_priority_fee_per_gas: Default::default(), - max_fee_per_gas: Default::default(), - gas: 100000, - to: None, - value: Default::default(), - data: Default::default(), - access_list: Default::default(), - max_fee_per_data_gas: Default::default(), - versioned_hashes: vec![versioned_hash].into(), - }; - let bad_signature = EcdsaSignature { - y_parity: false, - r: Uint256::from(0), - s: Uint256::from(0), - }; - let signed_blob_transaction = SignedBlobTransaction { - message: blob_transaction, - signature: bad_signature, - }; - // calculate transaction bytes - let tx_bytes = [BLOB_TX_TYPE] - .into_iter() - .chain(signed_blob_transaction.as_ssz_bytes().into_iter()) - .collect::>(); - let tx = Transaction::::from(tx_bytes); + let blob_transaction = BlobTransaction { + chain_id: Default::default(), + nonce: 0, + max_priority_fee_per_gas: Default::default(), + max_fee_per_gas: Default::default(), + gas: 100000, + to: None, + value: Default::default(), + data: Default::default(), + access_list: Default::default(), + max_fee_per_data_gas: Default::default(), + versioned_hashes: vec![versioned_hash].into(), + }; + let bad_signature = EcdsaSignature { + y_parity: false, + r: Uint256::from(0), + s: Uint256::from(0), + }; + let signed_blob_transaction = SignedBlobTransaction { + message: blob_transaction, + signature: bad_signature, + }; + // calculate transaction bytes + let tx_bytes = [BLOB_TX_TYPE] + .into_iter() + .chain(signed_blob_transaction.as_ssz_bytes().into_iter()) + .collect::>(); + let tx = Transaction::::from(tx_bytes); transactions.push(tx); bundle diff --git a/beacon_node/network/src/sync/block_lookups/mod.rs b/beacon_node/network/src/sync/block_lookups/mod.rs index 595d5dbbfd..40a81e38c3 100644 --- a/beacon_node/network/src/sync/block_lookups/mod.rs +++ b/beacon_node/network/src/sync/block_lookups/mod.rs @@ -1,5 +1,5 @@ use beacon_chain::blob_verification::{AsBlock, BlockWrapper}; -use beacon_chain::data_availability_checker::{DataAvailabilityChecker}; +use beacon_chain::data_availability_checker::DataAvailabilityChecker; use beacon_chain::{AvailabilityProcessingStatus, BeaconChainTypes, BlockError}; use lighthouse_network::rpc::RPCError; use lighthouse_network::{PeerAction, PeerId}; @@ -60,7 +60,7 @@ pub(crate) struct BlockLookups { SingleBlockLookup, )>, - da_checker: Arc>, + da_checker: Arc>, /// The logger for the import manager. log: Logger, @@ -121,10 +121,7 @@ pub enum ShouldRemoveLookup { } impl BlockLookups { - pub fn new( - da_checker: Arc>, - log: Logger, - ) -> Self { + pub fn new(da_checker: Arc>, log: Logger) -> Self { Self { parent_lookups: Default::default(), processing_parent_lookups: Default::default(), @@ -540,7 +537,8 @@ impl BlockLookups { if !outstanding_blobs_req { if let Ok(peer_id) = parent_lookup .current_parent_request - .downloading_peer(ResponseType::Blob) { + .downloading_peer(ResponseType::Blob) + { cx.report_peer( peer_id.to_peer_id(), PeerAction::MidToleranceError, @@ -622,9 +620,11 @@ impl BlockLookups { seen_timestamp: Duration, cx: &mut SyncNetworkContext, ) { - let mut parent_lookup = if let Some(pos) = self.parent_lookups.iter().position(|request| { - request.pending_blob_response(id) - }) { + let mut parent_lookup = if let Some(pos) = self + .parent_lookups + .iter() + .position(|request| request.pending_blob_response(id)) + { self.parent_lookups.remove(pos) } else { if blob.is_some() { @@ -1055,7 +1055,7 @@ impl BlockLookups { cx, &self.log, ) - } else if let Some(block_id_ref) = block_id_ref { + } else if let Some(block_id_ref) = block_id_ref { // Try it again if possible. retry_request_after_failure( block_id_ref, @@ -1488,8 +1488,6 @@ impl BlockLookups { } } - - fn handle_block_lookup_verify_error( request_id_ref: &mut u32, request_ref: &mut SingleBlockLookup, diff --git a/beacon_node/network/src/sync/block_lookups/parent_lookup.rs b/beacon_node/network/src/sync/block_lookups/parent_lookup.rs index 996d7561f6..e56436bef1 100644 --- a/beacon_node/network/src/sync/block_lookups/parent_lookup.rs +++ b/beacon_node/network/src/sync/block_lookups/parent_lookup.rs @@ -63,25 +63,6 @@ pub enum RequestError { NoPeers, } -#[derive(Debug)] -pub enum LookupDownloadStatus { - Process(BlockWrapper), - SearchBlock(Hash256), - AvailabilityCheck(AvailabilityCheckError), -} - -impl From, AvailabilityCheckError>> for LookupDownloadStatus { - fn from(value: Result, AvailabilityCheckError>) -> Self { - match value { - Ok(wrapper) => LookupDownloadStatus::Process(wrapper), - Err(AvailabilityCheckError::MissingBlobs(block_root)) => { - LookupDownloadStatus::SearchBlock(block_root) - } - Err(e) => LookupDownloadStatus::AvailabilityCheck(e), - } - } -} - impl ParentLookup { pub fn contains_block(&self, block_root: &Hash256) -> bool { self.downloaded_blocks @@ -93,7 +74,7 @@ impl ParentLookup { block_root: Hash256, parent_root: Hash256, peer_id: PeerShouldHave, - da_checker: Arc>, + da_checker: Arc>, ) -> Self { let current_parent_request = SingleBlockLookup::new(parent_root, Some(<_>::default()), peer_id, da_checker); @@ -189,10 +170,7 @@ impl ParentLookup { Some(UnknownParentComponents::default()); } - pub fn add_current_request_block( - &mut self, - block: Arc>, - ) { + pub fn add_current_request_block(&mut self, block: Arc>) { // Cache the block. self.current_parent_request.add_unknown_parent_block(block); diff --git a/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs b/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs index e68a7e7f81..3ee9f51987 100644 --- a/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs +++ b/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs @@ -23,7 +23,7 @@ pub struct SingleBlockLookup { pub blob_download_queue: FixedBlobSidecarList, pub block_request_state: SingleLookupRequestState, pub blob_request_state: SingleLookupRequestState, - pub da_checker: Arc>, + pub da_checker: Arc>, /// Only necessary for requests triggered by an `UnkownParent` because any /// blocks or blobs without parents won't hit the data availability cache. pub unknown_parent_components: Option>, @@ -110,7 +110,7 @@ impl SingleBlockLookup>, peer_source: PeerShouldHave, - da_checker: Arc>, + da_checker: Arc>, ) -> Self { Self { requested_block_root,