use the processing cache instead

This commit is contained in:
realbigsean
2024-01-29 18:25:15 -05:00
parent 66b911fd80
commit 0512420385
8 changed files with 56 additions and 66 deletions

View File

@@ -2940,18 +2940,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
unverified_block: B, unverified_block: B,
notify_execution_layer: NotifyExecutionLayer, notify_execution_layer: NotifyExecutionLayer,
) -> Result<AvailabilityProcessingStatus, BlockError<T::EthSpec>> { ) -> Result<AvailabilityProcessingStatus, BlockError<T::EthSpec>> {
if let Ok(commitments) = unverified_block self.data_availability_checker
.block() .notify_block(block_root, unverified_block.block_cloned());
.message()
.body()
.blob_kzg_commitments()
{
self.data_availability_checker.notify_block_commitments(
unverified_block.block().slot(),
block_root,
commitments.clone(),
);
};
let r = self let r = self
.process_block(block_root, unverified_block, notify_execution_layer, || { .process_block(block_root, unverified_block, notify_execution_layer, || {
Ok(()) Ok(())

View File

@@ -764,6 +764,7 @@ pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>>; ) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>>;
fn block(&self) -> &SignedBeaconBlock<T::EthSpec>; fn block(&self) -> &SignedBeaconBlock<T::EthSpec>;
fn block_cloned(&self) -> Arc<SignedBeaconBlock<T::EthSpec>>;
} }
impl<T: BeaconChainTypes> GossipVerifiedBlock<T> { impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
@@ -1017,6 +1018,10 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for GossipVerifiedBlock<T
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> { fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
self.block.as_block() self.block.as_block()
} }
fn block_cloned(&self) -> Arc<SignedBeaconBlock<T::EthSpec>> {
self.block.clone()
}
} }
impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> { impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
@@ -1168,6 +1173,10 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> { fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
self.block.as_block() self.block.as_block()
} }
fn block_cloned(&self) -> Arc<SignedBeaconBlock<T::EthSpec>> {
self.block.block_cloned()
}
} }
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock<T::EthSpec>> { impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock<T::EthSpec>> {
@@ -1198,6 +1207,10 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> { fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
self self
} }
fn block_cloned(&self) -> Arc<SignedBeaconBlock<T::EthSpec>> {
self.clone()
}
} }
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for RpcBlock<T::EthSpec> { impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for RpcBlock<T::EthSpec> {
@@ -1228,6 +1241,10 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for RpcBlock<T::EthSpec>
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> { fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
self.as_block() self.as_block()
} }
fn block_cloned(&self) -> Arc<SignedBeaconBlock<T::EthSpec>> {
self.block_cloned()
}
} }
impl<T: BeaconChainTypes> ExecutionPendingBlock<T> { impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {

View File

@@ -46,6 +46,13 @@ impl<E: EthSpec> RpcBlock<E> {
} }
} }
pub fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> {
match &self.block {
RpcBlockInner::Block(block) => block.clone(),
RpcBlockInner::BlockAndBlobs(block, _) => block.clone(),
}
}
pub fn blobs(&self) -> Option<&BlobSidecarList<E>> { pub fn blobs(&self) -> Option<&BlobSidecarList<E>> {
match &self.block { match &self.block {
RpcBlockInner::Block(_) => None, RpcBlockInner::Block(_) => None,

View File

@@ -20,7 +20,7 @@ use std::fmt::Debug;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::sync::Arc; use std::sync::Arc;
use task_executor::TaskExecutor; use task_executor::TaskExecutor;
use types::beacon_block_body::{KzgCommitmentOpts, KzgCommitments}; use types::beacon_block_body::KzgCommitmentOpts;
use types::blob_sidecar::{BlobIdentifier, BlobSidecar, FixedBlobSidecarList}; use types::blob_sidecar::{BlobIdentifier, BlobSidecar, FixedBlobSidecarList};
use types::{BlobSidecarList, ChainSpec, Epoch, EthSpec, Hash256, SignedBeaconBlock, Slot}; use types::{BlobSidecarList, ChainSpec, Epoch, EthSpec, Hash256, SignedBeaconBlock, Slot};
@@ -195,7 +195,10 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
/// Get a block from the availability cache. Only checks for blocks stored in memory. Useful /// Get a block from the availability cache. Only checks for blocks stored in memory. Useful
/// for serving RPC requests. /// for serving RPC requests.
pub fn get_block(&self, block_root: &Hash256) -> Option<Arc<SignedBeaconBlock<T::EthSpec>>> { pub fn get_block(&self, block_root: &Hash256) -> Option<Arc<SignedBeaconBlock<T::EthSpec>>> {
self.availability_cache.peek_block(block_root) self.processing_cache
.read()
.get(block_root)
.and_then(|cached| cached.block.clone())
} }
/// Put a list of blobs received via RPC into the availability cache. This performs KZG /// Put a list of blobs received via RPC into the availability cache. This performs KZG
@@ -350,20 +353,16 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
block.num_expected_blobs() > 0 && self.da_check_required_for_epoch(block.epoch()) block.num_expected_blobs() > 0 && self.da_check_required_for_epoch(block.epoch())
} }
/// Adds block commitments to the processing cache. These commitments are unverified but caching /// Adds a block to the processing cache. This block's commitments are unverified but caching
/// them here is useful to avoid duplicate downloads of blocks, as well as understanding /// them here is useful to avoid duplicate downloads of blocks, as well as understanding
/// our blob download requirements. /// our blob download requirements. We will also serve this over RPC.
pub fn notify_block_commitments( pub fn notify_block(&self, block_root: Hash256, block: Arc<SignedBeaconBlock<T::EthSpec>>) {
&self, let slot = block.slot();
slot: Slot,
block_root: Hash256,
commitments: KzgCommitments<T::EthSpec>,
) {
self.processing_cache self.processing_cache
.write() .write()
.entry(block_root) .entry(block_root)
.or_insert_with(|| ProcessingComponents::new(slot)) .or_insert_with(|| ProcessingComponents::new(slot))
.merge_block(commitments); .merge_block(block);
} }
/// Add a single blob commitment to the processing cache. This commitment is unverified but caching /// Add a single blob commitment to the processing cache. This commitment is unverified but caching
@@ -591,6 +590,15 @@ pub enum MaybeAvailableBlock<E: EthSpec> {
}, },
} }
impl<E: EthSpec> MaybeAvailableBlock<E> {
pub fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> {
match self {
Self::Available(block) => block.block_cloned(),
Self::AvailabilityPending { block, .. } => block.clone(),
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum MissingBlobs { pub enum MissingBlobs {
/// We know for certain these blobs are missing. /// We know for certain these blobs are missing.

View File

@@ -182,9 +182,9 @@ macro_rules! impl_availability_view {
impl_availability_view!( impl_availability_view!(
ProcessingComponents, ProcessingComponents,
KzgCommitments<E>, Arc<SignedBeaconBlock<E>>,
KzgCommitment, KzgCommitment,
block_commitments, block,
blob_commitments blob_commitments
); );
@@ -212,12 +212,6 @@ pub trait GetCommitment<E: EthSpec> {
fn get_commitment(&self) -> &KzgCommitment; fn get_commitment(&self) -> &KzgCommitment;
} }
// These implementations are required to implement `AvailabilityView` for `ProcessingView`.
impl<E: EthSpec> GetCommitments<E> for KzgCommitments<E> {
fn get_commitments(&self) -> KzgCommitments<E> {
self.clone()
}
}
impl<E: EthSpec> GetCommitment<E> for KzgCommitment { impl<E: EthSpec> GetCommitment<E> for KzgCommitment {
fn get_commitment(&self) -> &KzgCommitment { fn get_commitment(&self) -> &KzgCommitment {
self self
@@ -310,7 +304,7 @@ pub mod tests {
} }
type ProcessingViewSetup<E> = ( type ProcessingViewSetup<E> = (
KzgCommitments<E>, Arc<SignedBeaconBlock<E>>,
FixedVector<Option<KzgCommitment>, <E as EthSpec>::MaxBlobsPerBlock>, FixedVector<Option<KzgCommitment>, <E as EthSpec>::MaxBlobsPerBlock>,
FixedVector<Option<KzgCommitment>, <E as EthSpec>::MaxBlobsPerBlock>, FixedVector<Option<KzgCommitment>, <E as EthSpec>::MaxBlobsPerBlock>,
); );
@@ -320,12 +314,6 @@ pub mod tests {
valid_blobs: FixedVector<Option<Arc<BlobSidecar<E>>>, <E as EthSpec>::MaxBlobsPerBlock>, valid_blobs: FixedVector<Option<Arc<BlobSidecar<E>>>, <E as EthSpec>::MaxBlobsPerBlock>,
invalid_blobs: FixedVector<Option<Arc<BlobSidecar<E>>>, <E as EthSpec>::MaxBlobsPerBlock>, invalid_blobs: FixedVector<Option<Arc<BlobSidecar<E>>>, <E as EthSpec>::MaxBlobsPerBlock>,
) -> ProcessingViewSetup<E> { ) -> ProcessingViewSetup<E> {
let commitments = block
.message()
.body()
.blob_kzg_commitments()
.unwrap()
.clone();
let blobs = FixedVector::from( let blobs = FixedVector::from(
valid_blobs valid_blobs
.iter() .iter()
@@ -338,7 +326,7 @@ pub mod tests {
.map(|blob_opt| blob_opt.as_ref().map(|blob| blob.kzg_commitment)) .map(|blob_opt| blob_opt.as_ref().map(|blob| blob.kzg_commitment))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
); );
(commitments, blobs, invalid_blobs) (Arc::new(block), blobs, invalid_blobs)
} }
type PendingComponentsSetup<E> = ( type PendingComponentsSetup<E> = (

View File

@@ -45,7 +45,7 @@ use ssz_types::{FixedVector, VariableList};
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::{collections::HashSet, sync::Arc}; use std::{collections::HashSet, sync::Arc};
use types::blob_sidecar::BlobIdentifier; use types::blob_sidecar::BlobIdentifier;
use types::{BlobSidecar, ChainSpec, Epoch, EthSpec, Hash256, SignedBeaconBlock}; use types::{BlobSidecar, ChainSpec, Epoch, EthSpec, Hash256};
/// This represents the components of a partially available block /// This represents the components of a partially available block
/// ///
@@ -322,18 +322,6 @@ impl<T: BeaconChainTypes> Critical<T> {
} }
} }
/// This only checks for the blocks in memory
pub fn peek_block(&self, block_root: &Hash256) -> Option<Arc<SignedBeaconBlock<T::EthSpec>>> {
self.in_memory
.peek(block_root)
.and_then(|pending_components| {
pending_components
.executed_block
.as_ref()
.map(|block| block.block_cloned())
})
}
/// Puts the pending components in the LRU cache. If the cache /// Puts the pending components in the LRU cache. If the cache
/// is at capacity, the LRU entry is written to the store first /// is at capacity, the LRU entry is written to the store first
pub fn put_pending_components( pub fn put_pending_components(
@@ -411,11 +399,6 @@ impl<T: BeaconChainTypes> OverflowLRUCache<T> {
}) })
} }
/// Just checks for blocks stored in memory
pub fn peek_block(&self, block_root: &Hash256) -> Option<Arc<SignedBeaconBlock<T::EthSpec>>> {
self.critical.read().peek_block(block_root)
}
/// Fetch a blob from the cache without affecting the LRU ordering /// Fetch a blob from the cache without affecting the LRU ordering
pub fn peek_blob( pub fn peek_blob(
&self, &self,

View File

@@ -1,8 +1,9 @@
use crate::data_availability_checker::AvailabilityView; use crate::data_availability_checker::AvailabilityView;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::HashMap; use std::collections::HashMap;
use types::beacon_block_body::{KzgCommitmentOpts, KzgCommitments}; use std::sync::Arc;
use types::{EthSpec, Hash256, Slot}; use types::beacon_block_body::KzgCommitmentOpts;
use types::{EthSpec, Hash256, SignedBeaconBlock, Slot};
/// This cache is used only for gossip blocks/blobs and single block/blob lookups, to give req/resp /// This cache is used only for gossip blocks/blobs and single block/blob lookups, to give req/resp
/// a view of what we have and what we require. This cache serves a slightly different purpose than /// a view of what we have and what we require. This cache serves a slightly different purpose than
@@ -45,7 +46,7 @@ pub struct ProcessingComponents<E: EthSpec> {
/// Blobs required for a block can only be known if we have seen the block. So `Some` here /// Blobs required for a block can only be known if we have seen the block. So `Some` here
/// means we've seen it, a `None` means we haven't. The `kzg_commitments` value helps us figure /// means we've seen it, a `None` means we haven't. The `kzg_commitments` value helps us figure
/// out whether incoming blobs actually match the block. /// out whether incoming blobs actually match the block.
pub block_commitments: Option<KzgCommitments<E>>, pub block: Option<Arc<SignedBeaconBlock<E>>>,
/// `KzgCommitments` for blobs are always known, even if we haven't seen the block. See /// `KzgCommitments` for blobs are always known, even if we haven't seen the block. See
/// `AvailabilityView`'s trait definition for more details. /// `AvailabilityView`'s trait definition for more details.
pub blob_commitments: KzgCommitmentOpts<E>, pub blob_commitments: KzgCommitmentOpts<E>,
@@ -55,7 +56,7 @@ impl<E: EthSpec> ProcessingComponents<E> {
pub fn new(slot: Slot) -> Self { pub fn new(slot: Slot) -> Self {
Self { Self {
slot, slot,
block_commitments: None, block: None,
blob_commitments: KzgCommitmentOpts::<E>::default(), blob_commitments: KzgCommitmentOpts::<E>::default(),
} }
} }
@@ -67,7 +68,7 @@ impl<E: EthSpec> ProcessingComponents<E> {
pub fn empty(_block_root: Hash256) -> Self { pub fn empty(_block_root: Hash256) -> Self {
Self { Self {
slot: Slot::new(0), slot: Slot::new(0),
block_commitments: None, block: None,
blob_commitments: KzgCommitmentOpts::<E>::default(), blob_commitments: KzgCommitmentOpts::<E>::default(),
} }
} }

View File

@@ -35,10 +35,6 @@ impl<E: EthSpec> DietAvailabilityPendingExecutedBlock<E> {
&self.block &self.block
} }
pub fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> {
self.block.clone()
}
pub fn num_blobs_expected(&self) -> usize { pub fn num_blobs_expected(&self) -> usize {
self.block self.block
.message() .message()