mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-31 13:17:09 +00:00
starting to cell-ize
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
//! Abstraction layer for data availability operations across different DA checkers.
|
||||
//!
|
||||
//! This module provides a unified interface for availability operations that are shared
|
||||
//! between the legacy `DataAvailabilityChecker` (v1, for blocks) and
|
||||
//! `DataAvailabilityChecker` v2 (for payload envelopes after Gloas).
|
||||
//! between the legacy `DataAvailabilityChecker` (for blocks) and
|
||||
//! `DataAvailabilityCache` (for payload envelopes after Gloas).
|
||||
//!
|
||||
//! ## Design
|
||||
//!
|
||||
@@ -21,20 +21,20 @@ use crate::custody_context::CustodyContext;
|
||||
use crate::data_availability_checker::{
|
||||
Availability as BlockAvailability, AvailabilityCheckError, AvailableBlock,
|
||||
DataAvailabilityChecker, DataAvailabilityCheckerMetrics as BlockMetrics,
|
||||
DataColumnReconstructionResult as BlockReconstructionResult,
|
||||
};
|
||||
use crate::data_availability_checker_v2::{
|
||||
Availability as PayloadAvailability, DataAvailabilityChecker as DataAvailabilityCheckerV2,
|
||||
DataAvailabilityCheckerMetrics as PayloadMetrics,
|
||||
DataColumnReconstructionResult as PayloadReconstructionResult,
|
||||
DataColumnReconstructionResult as BlockReconstructionResult, MissingCellsError,
|
||||
};
|
||||
use crate::data_column_verification::{GossipVerifiedDataColumn, KzgVerifiedCustodyDataColumn};
|
||||
use crate::observed_data_sidecars::ObservationStrategy;
|
||||
use crate::pending_payload_cache::{
|
||||
Availability as PayloadAvailability, DataAvailabilityCheckerMetrics as PayloadMetrics,
|
||||
DataColumnReconstructionResult as PayloadReconstructionResult, PendingPayloadCache,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use types::data::{BlobIdentifier, FixedBlobSidecarList};
|
||||
use types::{
|
||||
BlobSidecar, BlockImportSource, ChainSpec, ColumnIndex, DataColumnSidecar,
|
||||
DataColumnSidecarList, Epoch, EthSpec, ForkName, Hash256, SignedBeaconBlock, Slot,
|
||||
DataColumnSidecarList, Epoch, EthSpec, ForkName, Hash256, PartialDataColumnSidecarRef,
|
||||
SignedBeaconBlock, Slot,
|
||||
};
|
||||
|
||||
/// Unified result from operations that can come from either DA checker.
|
||||
@@ -65,7 +65,6 @@ impl<E: EthSpec> AvailabilityOutcome<E> {
|
||||
match self {
|
||||
Self::Block(BlockAvailability::Available(block)) => block.import_data.block_root,
|
||||
Self::Block(BlockAvailability::MissingComponents(root)) => *root,
|
||||
// For payload availability, the first element of the tuple is the block root
|
||||
Self::Payload(PayloadAvailability::Available(available_data)) => {
|
||||
available_data.envelope.message().beacon_block_root
|
||||
}
|
||||
@@ -139,19 +138,23 @@ impl<E: EthSpec> ReconstructionOutcome<E> {
|
||||
/// we can use the V2 DA checker directly.
|
||||
pub struct DataAvailabilityRouter<T: BeaconChainTypes> {
|
||||
/// Legacy DA checker for pre-Gloas blocks
|
||||
v1: Arc<DataAvailabilityChecker<T>>,
|
||||
pending_block_cache: Arc<DataAvailabilityChecker<T>>,
|
||||
/// Gloas DA checker for payload envelopes
|
||||
v2: Arc<DataAvailabilityCheckerV2<T>>,
|
||||
pending_payload_cache: Arc<PendingPayloadCache<T>>,
|
||||
spec: Arc<ChainSpec>,
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
pub fn new(
|
||||
v1: Arc<DataAvailabilityChecker<T>>,
|
||||
v2: Arc<DataAvailabilityCheckerV2<T>>,
|
||||
pending_block_cache: Arc<DataAvailabilityChecker<T>>,
|
||||
pending_payload_cache: Arc<PendingPayloadCache<T>>,
|
||||
spec: Arc<ChainSpec>,
|
||||
) -> Self {
|
||||
Self { v1, v2, spec }
|
||||
Self {
|
||||
pending_block_cache,
|
||||
pending_payload_cache,
|
||||
spec,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the given slot is in the Gloas fork or later.
|
||||
@@ -166,7 +169,7 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
/// Returns the custody context (same for both checkers).
|
||||
pub fn custody_context(&self) -> &Arc<CustodyContext<T::EthSpec>> {
|
||||
// Both checkers share the same custody context
|
||||
self.v1.custody_context()
|
||||
self.pending_block_cache.custody_context()
|
||||
}
|
||||
|
||||
/// Query data columns from the appropriate checker based on fork.
|
||||
@@ -176,22 +179,23 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
fork_name: ForkName,
|
||||
) -> Option<DataColumnSidecarList<T::EthSpec>> {
|
||||
if fork_name.gloas_enabled() {
|
||||
self.v2.get_data_columns(block_root)
|
||||
self.pending_payload_cache.get_data_columns(block_root)
|
||||
} else {
|
||||
self.v1.get_data_columns(block_root)
|
||||
self.pending_block_cache.get_data_columns(block_root)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_data_column_cached(
|
||||
&self,
|
||||
pub fn missing_cells_for_column_sidecar<'a>(
|
||||
&'_ self,
|
||||
slot: Slot,
|
||||
block_root: &Hash256,
|
||||
data_column: &DataColumnSidecar<T::EthSpec>,
|
||||
) -> bool {
|
||||
data_column: &'a DataColumnSidecar<T::EthSpec>,
|
||||
) -> Result<Option<PartialDataColumnSidecarRef<'a, T::EthSpec>>, MissingCellsError> {
|
||||
if self.is_gloas(slot) {
|
||||
self.v2.is_data_column_cached(block_root, data_column)
|
||||
self.pending_payload_cache
|
||||
.missing_cells_for_column_sidecar(data_column)
|
||||
} else {
|
||||
self.v1.is_data_column_cached(block_root, data_column)
|
||||
self.pending_block_cache
|
||||
.missing_cells_for_column_sidecar(data_column)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,9 +206,11 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
slot: Slot,
|
||||
) -> Option<Vec<ColumnIndex>> {
|
||||
if self.is_gloas(slot) {
|
||||
self.v2.cached_data_column_indexes(block_root)
|
||||
self.pending_payload_cache
|
||||
.cached_data_column_indexes(block_root)
|
||||
} else {
|
||||
self.v1.cached_data_column_indexes(block_root)
|
||||
self.pending_block_cache
|
||||
.cached_data_column_indexes(block_root)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,11 +222,11 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
custody_columns: DataColumnSidecarList<T::EthSpec>,
|
||||
) -> Result<AvailabilityOutcome<T::EthSpec>, AvailabilityCheckError> {
|
||||
if self.is_gloas(slot) {
|
||||
self.v2
|
||||
self.pending_payload_cache
|
||||
.put_rpc_custody_columns(block_root, slot, custody_columns)
|
||||
.map(AvailabilityOutcome::Payload)
|
||||
} else {
|
||||
self.v1
|
||||
self.pending_block_cache
|
||||
.put_rpc_custody_columns(block_root, slot, custody_columns)
|
||||
.map(AvailabilityOutcome::Block)
|
||||
}
|
||||
@@ -234,11 +240,11 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
data_columns: Vec<GossipVerifiedDataColumn<T, O>>,
|
||||
) -> Result<AvailabilityOutcome<T::EthSpec>, AvailabilityCheckError> {
|
||||
if self.is_gloas(slot) {
|
||||
self.v2
|
||||
self.pending_payload_cache
|
||||
.put_gossip_verified_data_columns(block_root, slot, data_columns)
|
||||
.map(AvailabilityOutcome::Payload)
|
||||
} else {
|
||||
self.v1
|
||||
self.pending_block_cache
|
||||
.put_gossip_verified_data_columns(block_root, slot, data_columns)
|
||||
.map(AvailabilityOutcome::Block)
|
||||
}
|
||||
@@ -252,11 +258,11 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
custody_columns: Vec<KzgVerifiedCustodyDataColumn<T::EthSpec>>,
|
||||
) -> Result<AvailabilityOutcome<T::EthSpec>, AvailabilityCheckError> {
|
||||
if self.is_gloas(slot) {
|
||||
self.v2
|
||||
self.pending_payload_cache
|
||||
.put_kzg_verified_custody_data_columns(block_root, custody_columns)
|
||||
.map(AvailabilityOutcome::Payload)
|
||||
} else {
|
||||
self.v1
|
||||
self.pending_block_cache
|
||||
.put_kzg_verified_custody_data_columns(block_root, custody_columns)
|
||||
.map(AvailabilityOutcome::Block)
|
||||
}
|
||||
@@ -269,11 +275,11 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
slot: Slot,
|
||||
) -> Result<ReconstructionOutcome<T::EthSpec>, AvailabilityCheckError> {
|
||||
if self.is_gloas(slot) {
|
||||
self.v2
|
||||
self.pending_payload_cache
|
||||
.reconstruct_data_columns(block_root)
|
||||
.map(ReconstructionOutcome::Payload)
|
||||
} else {
|
||||
self.v1
|
||||
self.pending_block_cache
|
||||
.reconstruct_data_columns(block_root)
|
||||
.map(ReconstructionOutcome::Block)
|
||||
}
|
||||
@@ -283,22 +289,23 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
|
||||
/// Returns the data availability boundary epoch (v1).
|
||||
pub fn data_availability_boundary(&self) -> Option<Epoch> {
|
||||
self.v1.data_availability_boundary()
|
||||
self.pending_block_cache.data_availability_boundary()
|
||||
}
|
||||
|
||||
/// Returns whether a DA check is required for the given epoch (v1).
|
||||
pub fn da_check_required_for_epoch(&self, epoch: Epoch) -> bool {
|
||||
self.v1.da_check_required_for_epoch(epoch)
|
||||
self.pending_block_cache.da_check_required_for_epoch(epoch)
|
||||
}
|
||||
|
||||
/// Returns whether blobs are required for the given epoch (v1).
|
||||
pub fn blobs_required_for_epoch(&self, epoch: Epoch) -> bool {
|
||||
self.v1.blobs_required_for_epoch(epoch)
|
||||
self.pending_block_cache.blobs_required_for_epoch(epoch)
|
||||
}
|
||||
|
||||
/// Returns whether data columns are required for the given epoch (v1).
|
||||
pub fn data_columns_required_for_epoch(&self, epoch: Epoch) -> bool {
|
||||
self.v1.data_columns_required_for_epoch(epoch)
|
||||
self.pending_block_cache
|
||||
.data_columns_required_for_epoch(epoch)
|
||||
}
|
||||
|
||||
/// Verifies KZG commitments for a single available block (v1).
|
||||
@@ -306,7 +313,8 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
&self,
|
||||
available_block: &AvailableBlock<T::EthSpec>,
|
||||
) -> Result<(), AvailabilityCheckError> {
|
||||
self.v1.verify_kzg_for_available_block(available_block)
|
||||
self.pending_block_cache
|
||||
.verify_kzg_for_available_block(available_block)
|
||||
}
|
||||
|
||||
/// Batch verifies KZG commitments for multiple available blocks (v1).
|
||||
@@ -314,7 +322,7 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
&self,
|
||||
available_blocks: &[AvailableBlock<T::EthSpec>],
|
||||
) -> Result<(), AvailabilityCheckError> {
|
||||
self.v1
|
||||
self.pending_block_cache
|
||||
.batch_verify_kzg_for_available_blocks(available_blocks)
|
||||
}
|
||||
|
||||
@@ -323,17 +331,17 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
&self,
|
||||
blob_id: &BlobIdentifier,
|
||||
) -> Result<Option<Arc<BlobSidecar<T::EthSpec>>>, AvailabilityCheckError> {
|
||||
self.v1.get_blob(blob_id)
|
||||
self.pending_block_cache.get_blob(blob_id)
|
||||
}
|
||||
|
||||
/// Returns the cached blob indexes for a given block root (v1).
|
||||
pub fn cached_blob_indexes(&self, block_root: &Hash256) -> Option<Vec<u64>> {
|
||||
self.v1.cached_blob_indexes(block_root)
|
||||
self.pending_block_cache.cached_blob_indexes(block_root)
|
||||
}
|
||||
|
||||
/// Returns the cached block for a given block root (v1).
|
||||
pub fn get_cached_block(&self, block_root: &Hash256) -> Option<BlockProcessStatus<T::EthSpec>> {
|
||||
self.v1.get_cached_block(block_root)
|
||||
self.pending_block_cache.get_cached_block(block_root)
|
||||
}
|
||||
|
||||
/// Inserts a pre-execution block into the cache (v1).
|
||||
@@ -343,7 +351,8 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
source: BlockImportSource,
|
||||
) -> Result<(), AvailabilityCheckError> {
|
||||
self.v1.put_pre_execution_block(block_root, block, source)
|
||||
self.pending_block_cache
|
||||
.put_pre_execution_block(block_root, block, source)
|
||||
}
|
||||
|
||||
/// Insert an executed block and check availability (v1).
|
||||
@@ -351,12 +360,13 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
&self,
|
||||
executed_block: AvailabilityPendingExecutedBlock<T::EthSpec>,
|
||||
) -> Result<BlockAvailability<T::EthSpec>, AvailabilityCheckError> {
|
||||
self.v1.put_executed_block(executed_block)
|
||||
self.pending_block_cache.put_executed_block(executed_block)
|
||||
}
|
||||
|
||||
/// Removes a pre-execution block from the cache on execution error (v1).
|
||||
pub fn remove_block_on_execution_error(&self, block_root: &Hash256) {
|
||||
self.v1.remove_block_on_execution_error(block_root)
|
||||
self.pending_block_cache
|
||||
.remove_block_on_execution_error(block_root)
|
||||
}
|
||||
|
||||
/// Insert blobs received via RPC and check availability (v1).
|
||||
@@ -365,7 +375,7 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
block_root: Hash256,
|
||||
blobs: FixedBlobSidecarList<T::EthSpec>,
|
||||
) -> Result<BlockAvailability<T::EthSpec>, AvailabilityCheckError> {
|
||||
self.v1.put_rpc_blobs(block_root, blobs)
|
||||
self.pending_block_cache.put_rpc_blobs(block_root, blobs)
|
||||
}
|
||||
|
||||
/// Insert KZG-verified blobs and check availability (v1).
|
||||
@@ -374,7 +384,8 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
block_root: Hash256,
|
||||
blobs: I,
|
||||
) -> Result<BlockAvailability<T::EthSpec>, AvailabilityCheckError> {
|
||||
self.v1.put_kzg_verified_blobs(block_root, blobs)
|
||||
self.pending_block_cache
|
||||
.put_kzg_verified_blobs(block_root, blobs)
|
||||
}
|
||||
|
||||
/// Insert gossip-verified blobs into the v1 checker.
|
||||
@@ -386,15 +397,16 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
block_root: Hash256,
|
||||
blobs: I,
|
||||
) -> Result<BlockAvailability<T::EthSpec>, AvailabilityCheckError> {
|
||||
self.v1.put_gossip_verified_blobs(block_root, blobs)
|
||||
self.pending_block_cache
|
||||
.put_gossip_verified_blobs(block_root, blobs)
|
||||
}
|
||||
|
||||
// ── Metrics ──
|
||||
|
||||
pub fn metrics(&self) -> DataAvailabilityRouterMetrics {
|
||||
DataAvailabilityRouterMetrics {
|
||||
block: self.v1.metrics(),
|
||||
payload: self.v2.metrics(),
|
||||
block: self.pending_block_cache.metrics(),
|
||||
payload: self.pending_payload_cache.metrics(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,14 +414,14 @@ impl<T: BeaconChainTypes> DataAvailabilityRouter<T> {
|
||||
|
||||
/// Direct access to the block-level DA checker (pre-Gloas).
|
||||
/// Used for block availability checks, range sync, and blob verification.
|
||||
pub fn v1(&self) -> &Arc<DataAvailabilityChecker<T>> {
|
||||
&self.v1
|
||||
pub fn pending_block_cache(&self) -> &Arc<DataAvailabilityChecker<T>> {
|
||||
&self.pending_block_cache
|
||||
}
|
||||
|
||||
/// Direct access to the envelope-level DA checker (Gloas).
|
||||
/// Used for payload envelope availability checks and column verification.
|
||||
pub fn v2(&self) -> &Arc<DataAvailabilityCheckerV2<T>> {
|
||||
&self.v2
|
||||
pub fn pending_payload_cache(&self) -> &Arc<PendingPayloadCache<T>> {
|
||||
&self.pending_payload_cache
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +438,5 @@ pub fn start_availability_cache_maintenance_service<T: BeaconChainTypes>(
|
||||
executor.clone(),
|
||||
chain.clone(),
|
||||
);
|
||||
crate::data_availability_checker_v2::start_availability_cache_maintenance_service(
|
||||
executor, chain,
|
||||
);
|
||||
crate::pending_payload_cache::start_availability_cache_maintenance_service(executor, chain);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user