mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 20:57:10 +00:00
Fix
This commit is contained in:
@@ -136,6 +136,10 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn custody_context(&self) -> &Arc<CustodyContext<T::EthSpec>> {
|
||||
&self.custody_context
|
||||
}
|
||||
|
||||
/// Checks if the block root is currently in the availability cache awaiting import because
|
||||
/// of missing components.
|
||||
///
|
||||
@@ -159,6 +163,30 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the set of cached custody column indexes for `block_root`. Returns None if there is
|
||||
/// no block component for `block_root`.
|
||||
pub fn cached_data_column_indexes(&self, block_root: &Hash256) -> Option<Vec<u64>> {
|
||||
self.availability_cache
|
||||
.peek_pending_components(block_root, |components| {
|
||||
components.map(|components| components.get_cached_data_columns_indices())
|
||||
})
|
||||
}
|
||||
|
||||
/// Check if the exact data column is in the availability cache.
|
||||
pub fn is_data_column_cached(
|
||||
&self,
|
||||
block_root: &Hash256,
|
||||
data_column: &DataColumnSidecar<T::EthSpec>,
|
||||
) -> bool {
|
||||
self.availability_cache
|
||||
.peek_pending_components(block_root, |components| {
|
||||
components.is_some_and(|components| {
|
||||
let cached_column_opt = components.get_cached_data_column(*data_column.index());
|
||||
cached_column_opt.is_some_and(|cached| *cached == *data_column)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a blob from the availability cache.
|
||||
pub fn get_blob(
|
||||
&self,
|
||||
@@ -167,6 +195,14 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
self.availability_cache.peek_blob(blob_id)
|
||||
}
|
||||
|
||||
/// Get data columns for a block from the availability cache.
|
||||
pub fn get_data_columns(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
) -> Option<DataColumnSidecarList<T::EthSpec>> {
|
||||
self.availability_cache.peek_data_columns(block_root)
|
||||
}
|
||||
|
||||
/// Put a list of blobs received via RPC into the availability cache. This performs KZG
|
||||
/// verification on the blobs in the list.
|
||||
#[instrument(skip_all, level = "trace")]
|
||||
@@ -194,6 +230,39 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
.put_kzg_verified_blobs(block_root, verified_blobs)
|
||||
}
|
||||
|
||||
/// Put a list of custody columns received via RPC into the availability cache. This performs KZG
|
||||
/// verification on the blobs in the list.
|
||||
#[allow(clippy::type_complexity)]
|
||||
#[instrument(skip_all, level = "trace")]
|
||||
pub fn put_rpc_custody_columns(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
slot: Slot,
|
||||
custody_columns: DataColumnSidecarList<T::EthSpec>,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
// Attributes fault to the specific peer that sent an invalid column
|
||||
let kzg_verified_columns =
|
||||
KzgVerifiedDataColumn::from_batch_with_scoring(custody_columns, &self.kzg)
|
||||
.map_err(AvailabilityCheckError::InvalidColumn)?;
|
||||
|
||||
// Filter out columns that aren't required for custody for this slot
|
||||
// This is required because `data_columns_by_root` requests the **latest** CGC that _may_
|
||||
// not be yet effective for data availability check, as CGC changes are only effecive from
|
||||
// a new epoch.
|
||||
let epoch = slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let sampling_columns = self
|
||||
.custody_context
|
||||
.sampling_columns_for_epoch(epoch, &self.spec);
|
||||
let verified_custody_columns = kzg_verified_columns
|
||||
.into_iter()
|
||||
.filter(|col| sampling_columns.contains(&col.index()))
|
||||
.map(KzgVerifiedCustodyDataColumn::from_asserted_custody)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.availability_cache
|
||||
.put_kzg_verified_data_columns(block_root, verified_custody_columns)
|
||||
}
|
||||
|
||||
/// Check if we've cached other blobs for this block. If it completes a set and we also
|
||||
/// have a block cached, return the `Availability` variant triggering block import.
|
||||
/// Otherwise cache the blob sidecar.
|
||||
@@ -222,6 +291,47 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
.put_kzg_verified_blobs(block_root, blobs)
|
||||
}
|
||||
|
||||
/// Check if we've cached other data columns for this block. If it satisfies the custody requirement and we also
|
||||
/// have a block cached, return the `Availability` variant triggering block import.
|
||||
/// Otherwise cache the data column sidecar.
|
||||
///
|
||||
/// This should only accept gossip verified data columns, so we should not have to worry about dupes.
|
||||
#[instrument(skip_all, level = "trace")]
|
||||
pub fn put_gossip_verified_data_columns<
|
||||
O: ObservationStrategy,
|
||||
I: IntoIterator<Item = GossipVerifiedDataColumn<T, O>>,
|
||||
>(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
slot: Slot,
|
||||
data_columns: I,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
let epoch = slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let sampling_columns = self
|
||||
.custody_context
|
||||
.sampling_columns_for_epoch(epoch, &self.spec);
|
||||
let custody_columns = data_columns
|
||||
.into_iter()
|
||||
.filter(|col| sampling_columns.contains(&col.index()))
|
||||
.map(|c| KzgVerifiedCustodyDataColumn::from_asserted_custody(c.into_inner()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.availability_cache
|
||||
.put_kzg_verified_data_columns(block_root, custody_columns)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, level = "trace")]
|
||||
pub fn put_kzg_verified_custody_data_columns<
|
||||
I: IntoIterator<Item = KzgVerifiedCustodyDataColumn<T::EthSpec>>,
|
||||
>(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
custody_columns: I,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
self.availability_cache
|
||||
.put_kzg_verified_data_columns(block_root, custody_columns)
|
||||
}
|
||||
|
||||
/// Check if we have all the blobs for a block. Returns `Availability` which has information
|
||||
/// about whether all components have been received or more are required.
|
||||
pub fn put_executed_block(
|
||||
@@ -356,113 +466,6 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
block_cache_size: self.availability_cache.block_cache_size(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
pub fn custody_context(&self) -> &Arc<CustodyContext<T::EthSpec>> {
|
||||
&self.custody_context
|
||||
}
|
||||
|
||||
/// Get data columns for a block from the availability cache.
|
||||
pub fn get_data_columns(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
) -> Option<DataColumnSidecarList<T::EthSpec>> {
|
||||
self.availability_cache.peek_data_columns(block_root)
|
||||
}
|
||||
|
||||
/// Return the set of cached custody column indices for `block_root`. Returns None if there is
|
||||
/// no block component for `block_root`.
|
||||
pub fn cached_data_column_indexes(&self, block_root: &Hash256) -> Option<Vec<u64>> {
|
||||
self.availability_cache
|
||||
.peek_pending_components(block_root, |components| {
|
||||
components.map(|components| components.get_cached_data_columns_indices())
|
||||
})
|
||||
}
|
||||
|
||||
/// Check if the exact data column is in the availability cache.
|
||||
pub fn is_data_column_cached(
|
||||
&self,
|
||||
block_root: &Hash256,
|
||||
data_column: &DataColumnSidecar<T::EthSpec>,
|
||||
) -> bool {
|
||||
self.availability_cache
|
||||
.peek_pending_components(block_root, |components| {
|
||||
components.is_some_and(|components| {
|
||||
let cached_column_opt = components.get_cached_data_column(*data_column.index());
|
||||
cached_column_opt.is_some_and(|cached| *cached == *data_column)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Put a list of custody columns received via RPC into the availability cache. This performs KZG
|
||||
/// verification on the blobs in the list.
|
||||
#[allow(clippy::type_complexity)]
|
||||
#[instrument(skip_all, level = "trace")]
|
||||
pub fn put_rpc_custody_columns(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
slot: Slot,
|
||||
custody_columns: DataColumnSidecarList<T::EthSpec>,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
// Attributes fault to the specific peer that sent an invalid column
|
||||
let kzg_verified_columns =
|
||||
KzgVerifiedDataColumn::from_batch_with_scoring(custody_columns, &self.kzg)
|
||||
.map_err(AvailabilityCheckError::InvalidColumn)?;
|
||||
|
||||
// Filter out columns that aren't required for custody for this slot
|
||||
// This is required because `data_columns_by_root` requests the **latest** CGC that _may_
|
||||
// not be yet effective for data availability check, as CGC changes are only effecive from
|
||||
// a new epoch.
|
||||
let epoch = slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let sampling_columns = self
|
||||
.custody_context
|
||||
.sampling_columns_for_epoch(epoch, &self.spec);
|
||||
let verified_custody_columns = kzg_verified_columns
|
||||
.into_iter()
|
||||
.filter(|col| sampling_columns.contains(&col.index()))
|
||||
.map(KzgVerifiedCustodyDataColumn::from_asserted_custody)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.availability_cache
|
||||
.put_kzg_verified_data_columns(block_root, verified_custody_columns)
|
||||
}
|
||||
|
||||
/// Check if we've cached other data columns for this block. If it satisfies the custody requirement and we also
|
||||
/// have a block cached, return the `Availability` variant triggering block import.
|
||||
/// Otherwise cache the data column sidecar.
|
||||
///
|
||||
/// This should only accept gossip verified data columns, so we should not have to worry about dupes.
|
||||
#[instrument(skip_all, level = "trace")]
|
||||
pub fn put_gossip_verified_data_columns<O: ObservationStrategy>(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
slot: Slot,
|
||||
data_columns: Vec<GossipVerifiedDataColumn<T, O>>,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
let epoch = slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let sampling_columns = self
|
||||
.custody_context
|
||||
.sampling_columns_for_epoch(epoch, &self.spec);
|
||||
let custody_columns = data_columns
|
||||
.into_iter()
|
||||
.filter(|col| sampling_columns.contains(&col.index()))
|
||||
.map(|c| KzgVerifiedCustodyDataColumn::from_asserted_custody(c.into_inner()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.availability_cache
|
||||
.put_kzg_verified_data_columns(block_root, custody_columns)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, level = "trace")]
|
||||
pub fn put_kzg_verified_custody_data_columns(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
custody_columns: Vec<KzgVerifiedCustodyDataColumn<T::EthSpec>>,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
self.availability_cache
|
||||
.put_kzg_verified_data_columns(block_root, custody_columns)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, level = "debug")]
|
||||
pub fn reconstruct_data_columns(
|
||||
@@ -551,18 +554,6 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
/// Verifies KZG commitments for data columns.
|
||||
pub fn verify_kzg_for_data_columns(
|
||||
&self,
|
||||
data_columns: &DataColumnSidecarList<T::EthSpec>,
|
||||
) -> Result<(), AvailabilityCheckError> {
|
||||
if !data_columns.is_empty() {
|
||||
verify_kzg_for_data_column_list(data_columns.iter(), &self.kzg)
|
||||
.map_err(AvailabilityCheckError::InvalidColumn)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper struct to group data availability checker metrics.
|
||||
@@ -590,7 +581,6 @@ pub fn start_availability_cache_maintenance_service<T: BeaconChainTypes>(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(gloas) we can shut down this service once we reach the gloas fork epoch
|
||||
async fn availability_cache_maintenance_service<T: BeaconChainTypes>(
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
overflow_cache: Arc<DataAvailabilityCheckerInner<T>>,
|
||||
|
||||
Reference in New Issue
Block a user