Deprecate gossip blobs (#9126)

#9124

Deprecate unneeded pre-Fulu blob features

- blob gossip
- blob lookup sync
- engine getBlobsV1

Also deprecates some tests and cleans up production code paths

I think this is blocked until gnosis forks to fulu?


  


Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>

Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>

Co-Authored-By: dapplion <35266934+dapplion@users.noreply.github.com>

Co-Authored-By: Pawan Dhananjay <pawandhananjay@gmail.com>

Co-Authored-By: Michael Sproul <michael@sigmaprime.io>

Co-Authored-By: Daniel Knopik <daniel@dknopik.de>

Co-Authored-By: Michael Sproul <michaelsproul@users.noreply.github.com>
This commit is contained in:
Eitan Seri-Levi
2026-05-28 19:59:23 -07:00
committed by GitHub
parent ba3abf943f
commit 8396dc87d0
48 changed files with 485 additions and 2346 deletions

View File

@@ -780,9 +780,11 @@ impl<T: BeaconChainTypes> DataAvailabilityCheckerInner<T> {
mod test {
use super::*;
use crate::test_utils::generate_data_column_indices_rand_order;
use crate::data_column_verification::{GossipVerifiedDataColumn, KzgVerifiedCustodyDataColumn};
use crate::test_utils::{
generate_data_column_indices_rand_order, generate_data_column_sidecars_from_block,
};
use crate::{
blob_verification::GossipVerifiedBlob,
block_verification::PayloadVerificationOutcome,
block_verification_types::{AsBlock, BlockImportData},
custody_context::NodeCustodyType,
@@ -794,8 +796,8 @@ mod test {
use store::{HotColdDB, ItemStore, StoreConfig, database::interface::BeaconNodeBackend};
use tempfile::{TempDir, tempdir};
use tracing::info;
use types::MinimalEthSpec;
use types::new_non_zero_usize;
use types::{DataColumnSubnetId, MinimalEthSpec};
const LOW_VALIDATOR_COUNT: usize = 32;
@@ -819,21 +821,25 @@ mod test {
.expect("disk store should initialize")
}
// get a beacon chain harness advanced to just before deneb fork
async fn get_deneb_chain<E: EthSpec>(
// get a beacon chain harness advanced to just before fulu fork
async fn get_fulu_chain<E: EthSpec>(
db_path: &TempDir,
) -> BeaconChainHarness<DiskHarnessType<E>> {
let altair_fork_epoch = Epoch::new(0);
let bellatrix_fork_epoch = Epoch::new(0);
let capella_fork_epoch = Epoch::new(3);
let deneb_fork_epoch = Epoch::new(4);
let deneb_fork_slot = deneb_fork_epoch.start_slot(E::slots_per_epoch());
let electra_fork_epoch = Epoch::new(5);
let fulu_fork_epoch = Epoch::new(6);
let fulu_fork_slot = fulu_fork_epoch.start_slot(E::slots_per_epoch());
let mut spec = E::default_spec();
spec.altair_fork_epoch = Some(altair_fork_epoch);
spec.bellatrix_fork_epoch = Some(bellatrix_fork_epoch);
spec.capella_fork_epoch = Some(capella_fork_epoch);
spec.deneb_fork_epoch = Some(deneb_fork_epoch);
spec.electra_fork_epoch = Some(electra_fork_epoch);
spec.fulu_fork_epoch = Some(fulu_fork_epoch);
let spec = Arc::new(spec);
let chain_store = get_store_with_spec::<E>(db_path, spec.clone());
@@ -846,8 +852,10 @@ mod test {
.mock_execution_layer()
.build();
// go right before deneb slot
harness.extend_to_slot(deneb_fork_slot - 1).await;
harness.execution_block_generator().set_min_blob_count(1);
// go right before fulu slot
harness.extend_to_slot(fulu_fork_slot - 1).await;
harness
}
@@ -856,7 +864,7 @@ mod test {
harness: &BeaconChainHarness<BaseHarnessType<E, Hot, Cold>>,
) -> (
AvailabilityPendingExecutedBlock<E>,
Vec<GossipVerifiedBlob<BaseHarnessType<E, Hot, Cold>>>,
Vec<GossipVerifiedDataColumn<BaseHarnessType<E, Hot, Cold>>>,
)
where
E: EthSpec,
@@ -874,7 +882,7 @@ mod test {
.expect("should get block")
.expect("should have block");
let (signed_beacon_block_hash, (block, maybe_blobs), state) = harness
let (signed_beacon_block_hash, (block, _maybe_blobs), state) = harness
.add_block_at_slot(target_slot, parent_state)
.await
.expect("should add block");
@@ -892,27 +900,25 @@ mod test {
.message()
.body()
.blob_kzg_commitments()
.expect("should be deneb fork")
.expect("should be fulu fork")
.clone(),
) {
info!(commitment = ?comm, "kzg commitment");
}
info!("done printing kzg commitments");
let gossip_verified_blobs = if let Some((kzg_proofs, blobs)) = maybe_blobs {
let sidecars =
BlobSidecar::build_sidecars(blobs, &block, kzg_proofs, &chain.spec).unwrap();
Vec::from(sidecars)
.into_iter()
.map(|sidecar| {
let subnet = sidecar.index;
GossipVerifiedBlob::new(sidecar, subnet, &harness.chain)
.expect("should validate blob")
})
.collect()
} else {
vec![]
};
// Generate data columns from the block
let data_columns = generate_data_column_sidecars_from_block(&block, &harness.spec);
let gossip_verified_columns: Vec<_> = data_columns
.into_iter()
.map(|sidecar| {
let subnet_id =
DataColumnSubnetId::from_column_index(*sidecar.index(), &harness.spec);
GossipVerifiedDataColumn::new(sidecar, subnet_id, &harness.chain)
.expect("should validate data column")
})
.collect();
let slot = block.slot();
let consensus_context = ConsensusContext::<E>::new(slot);
@@ -933,7 +939,7 @@ mod test {
payload_verification_outcome,
};
(availability_pending_block, gossip_verified_blobs)
(availability_pending_block, gossip_verified_columns)
}
async fn setup_harness_and_cache<E, T>(
@@ -953,7 +959,7 @@ mod test {
{
create_test_tracing_subscriber();
let chain_db_path = tempdir().expect("should get temp dir");
let harness = get_deneb_chain(&chain_db_path).await;
let harness = get_fulu_chain(&chain_db_path).await;
let spec = harness.spec.clone();
let capacity_non_zero = new_non_zero_usize(capacity);
let custody_context = Arc::new(CustodyContext::new(
@@ -979,20 +985,27 @@ mod test {
let capacity = 4;
let (harness, cache, _path) = setup_harness_and_cache::<E, T>(capacity).await;
let (pending_block, blobs) = availability_pending_block(&harness).await;
let (pending_block, columns) = availability_pending_block(&harness).await;
let root = pending_block.import_data.block_root;
let epoch = pending_block.block.epoch();
let blobs_expected = pending_block.num_blobs_expected();
let num_blobs_expected = pending_block.num_blobs_expected();
let columns_expected = cache
.custody_context
.num_of_data_columns_to_sample(epoch, &harness.spec);
// All columns are returned from availability_pending_block (E::number_of_columns())
// but we only need custody columns
assert_eq!(
blobs.len(),
blobs_expected,
"should have expected number of blobs"
columns.len(),
E::number_of_columns(),
"should have all data columns from block"
);
assert!(cache.critical.read().is_empty(), "cache should be empty");
let availability = cache
.put_executed_block(pending_block)
.expect("should put block");
if blobs_expected == 0 {
if num_blobs_expected == 0 {
assert!(
matches!(availability, Availability::Available(_)),
"block doesn't have blobs, should be available"
@@ -1005,7 +1018,7 @@ mod test {
} else {
assert!(
matches!(availability, Availability::MissingComponents(_)),
"should be pending blobs"
"should be pending columns"
);
assert_eq!(
cache.critical.read().len(),
@@ -1018,13 +1031,26 @@ mod test {
);
}
let mut kzg_verified_blobs = Vec::new();
for (blob_index, gossip_blob) in blobs.into_iter().enumerate() {
kzg_verified_blobs.push(gossip_blob.into_inner());
// Get sampling column indices for this epoch
let sampling_column_indices = cache
.custody_context
.sampling_columns_for_epoch(epoch, &harness.spec);
// Filter to only sampling columns
let sampling_columns: Vec<_> = columns
.into_iter()
.filter(|col| sampling_column_indices.contains(&col.index()))
.collect();
let mut kzg_verified_columns = Vec::new();
for (col_index, gossip_column) in sampling_columns.into_iter().enumerate() {
kzg_verified_columns.push(KzgVerifiedCustodyDataColumn::from_asserted_custody(
gossip_column.into_inner(),
));
let availability = cache
.put_kzg_verified_blobs(root, kzg_verified_blobs.clone())
.expect("should put blob");
if blob_index == blobs_expected - 1 {
.put_kzg_verified_data_columns(root, kzg_verified_columns.clone())
.expect("should put column");
if col_index == columns_expected - 1 {
assert!(matches!(availability, Availability::Available(_)));
} else {
assert!(matches!(availability, Availability::MissingComponents(_)));
@@ -1032,20 +1058,36 @@ mod test {
}
}
let (pending_block, blobs) = availability_pending_block(&harness).await;
let blobs_expected = pending_block.num_blobs_expected();
let (pending_block, columns) = availability_pending_block(&harness).await;
let _num_blobs_expected = pending_block.num_blobs_expected();
let epoch = pending_block.block.epoch();
// All columns returned
assert_eq!(
blobs.len(),
blobs_expected,
"should have expected number of blobs"
columns.len(),
E::number_of_columns(),
"should have all data columns"
);
let root = pending_block.import_data.block_root;
let mut kzg_verified_blobs = vec![];
for gossip_blob in blobs {
kzg_verified_blobs.push(gossip_blob.into_inner());
// Get sampling column indices for this epoch
let sampling_column_indices = cache
.custody_context
.sampling_columns_for_epoch(epoch, &harness.spec);
// Filter to only sampling columns
let sampling_columns: Vec<_> = columns
.into_iter()
.filter(|col| sampling_column_indices.contains(&col.index()))
.collect();
let mut kzg_verified_columns = vec![];
for gossip_column in sampling_columns {
kzg_verified_columns.push(KzgVerifiedCustodyDataColumn::from_asserted_custody(
gossip_column.into_inner(),
));
let availability = cache
.put_kzg_verified_blobs(root, kzg_verified_blobs.clone())
.expect("should put blob");
.put_kzg_verified_data_columns(root, kzg_verified_columns.clone())
.expect("should put column");
assert!(
matches!(availability, Availability::MissingComponents(_)),
"should be pending block"