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

@@ -80,7 +80,6 @@ const MAX_LOOKUPS: usize = 200;
/// The values for `Blob`, `DataColumn` and `PartialDataColumn` is the parent root of the column.
pub enum BlockComponent<E: EthSpec> {
Block(DownloadResult<Arc<SignedBeaconBlock<E>>>),
Blob(DownloadResult<Hash256>),
DataColumn(DownloadResult<Hash256>),
PartialDataColumn(DownloadResult<Hash256>),
}
@@ -89,15 +88,13 @@ impl<E: EthSpec> BlockComponent<E> {
fn parent_root(&self) -> Hash256 {
match self {
BlockComponent::Block(block) => block.value.parent_root(),
BlockComponent::Blob(parent_root)
| BlockComponent::DataColumn(parent_root)
BlockComponent::DataColumn(parent_root)
| BlockComponent::PartialDataColumn(parent_root) => parent_root.value,
}
}
fn get_type(&self) -> &'static str {
match self {
BlockComponent::Block(_) => "block",
BlockComponent::Blob(_) => "blob",
BlockComponent::DataColumn(_) => "data_column",
BlockComponent::PartialDataColumn(_) => "partial_data_column",
}
@@ -214,9 +211,9 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
block_root,
Some(block_component),
Some(parent_root),
// On a `UnknownParentBlock` or `UnknownParentBlob` event the peer is not required
// to have the rest of the block components (refer to decoupled blob gossip). Create
// the lookup with zero peers to house the block components.
// On a `UnknownParentBlock` or `UnknownParentDataColumn` event the peer is not
// required to have the rest of the block components. Create the lookup with zero
// peers to house the block components.
&[],
cx,
)

View File

@@ -156,9 +156,7 @@ impl<T: BeaconChainTypes> SingleBlockLookup<T> {
.block_request_state
.state
.insert_verified_response(block),
BlockComponent::Blob(_)
| BlockComponent::DataColumn(_)
| BlockComponent::PartialDataColumn(_) => {
BlockComponent::DataColumn(_) | BlockComponent::PartialDataColumn(_) => {
// For now ignore single blobs and columns, as the blob request state assumes all blobs are
// attributed to the same peer = the peer serving the remaining blobs. Ignoring this
// block component has a minor effect, causing the node to re-request this blob

View File

@@ -144,9 +144,6 @@ pub enum SyncMessage<E: EthSpec> {
/// A block with an unknown parent has been received.
UnknownParentBlock(PeerId, Arc<SignedBeaconBlock<E>>, Hash256),
/// A blob with an unknown parent has been received.
UnknownParentBlob(PeerId, Arc<BlobSidecar<E>>),
/// A data column with an unknown parent has been received.
UnknownParentDataColumn(PeerId, Arc<DataColumnSidecar<E>>),
@@ -890,24 +887,6 @@ impl<T: BeaconChainTypes> SyncManager<T> {
}),
);
}
SyncMessage::UnknownParentBlob(peer_id, blob) => {
let blob_slot = blob.slot();
let block_root = blob.block_root();
let parent_root = blob.block_parent_root();
debug!(%block_root, %parent_root, "Received unknown parent blob message");
self.handle_unknown_parent(
peer_id,
block_root,
parent_root,
blob_slot,
BlockComponent::Blob(DownloadResult {
value: parent_root,
block_root,
seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(),
peer_group: PeerGroup::from_single(peer_id),
}),
);
}
SyncMessage::UnknownParentDataColumn(peer_id, data_column) => {
let data_column_slot = data_column.slot();
let block_root = data_column.block_root();

View File

@@ -33,6 +33,7 @@ impl<E: EthSpec> ActiveRequestItems for BlobsByRangeRequestItems<E> {
if blob.index >= self.max_blobs_per_block {
return Err(LookupVerifyError::UnrequestedIndex(blob.index));
}
if !blob.verify_blob_sidecar_inclusion_proof() {
return Err(LookupVerifyError::InvalidInclusionProof);
}

View File

@@ -50,9 +50,11 @@ impl<E: EthSpec> ActiveRequestItems for BlobsByRootRequestItems<E> {
if self.request.block_root != block_root {
return Err(LookupVerifyError::UnrequestedBlockRoot(block_root));
}
if !blob.verify_blob_sidecar_inclusion_proof() {
return Err(LookupVerifyError::InvalidInclusionProof);
}
if !self.request.indices.contains(&blob.index) {
return Err(LookupVerifyError::UnrequestedIndex(blob.index));
}

View File

@@ -1205,17 +1205,6 @@ impl TestRig {
self.trigger_unknown_parent_block(peer_id, last_block);
}
fn trigger_with_last_unknown_blob_parent(&mut self) {
let peer_id = self.new_connected_supernode_peer();
let blobs = self
.get_last_block()
.block_data()
.blobs()
.expect("no blobs");
let blob = blobs.first().expect("empty blobs");
self.trigger_unknown_parent_blob(peer_id, blob.clone());
}
fn trigger_with_last_unknown_data_column_parent(&mut self) {
let peer_id = self.new_connected_supernode_peer();
let columns = self
@@ -1224,7 +1213,7 @@ impl TestRig {
.data_columns()
.expect("No data columns");
let column = columns.first().expect("empty columns");
self.trigger_unknown_parent_column(peer_id, column.clone());
self.trigger_unknown_parent_data_column(peer_id, column.clone());
}
// Post-test assertions
@@ -1428,6 +1417,10 @@ impl TestRig {
genesis_fork().deneb_enabled().then(Self::default)
}
fn new_after_fulu() -> Option<Self> {
genesis_fork().fulu_enabled().then(Self::default)
}
fn new_after_deneb_before_fulu() -> Option<Self> {
let fork = genesis_fork();
if fork.deneb_enabled() && !fork.fulu_enabled() {
@@ -1463,16 +1456,12 @@ impl TestRig {
self.send_sync_message(SyncMessage::UnknownParentBlock(peer_id, block, block_root))
}
fn trigger_unknown_parent_blob(&mut self, peer_id: PeerId, blob: Arc<BlobSidecar<E>>) {
self.send_sync_message(SyncMessage::UnknownParentBlob(peer_id, blob));
}
fn trigger_unknown_parent_column(
fn trigger_unknown_parent_data_column(
&mut self,
peer_id: PeerId,
column: Arc<DataColumnSidecar<E>>,
data_column: Arc<DataColumnSidecar<E>>,
) {
self.send_sync_message(SyncMessage::UnknownParentDataColumn(peer_id, column));
self.send_sync_message(SyncMessage::UnknownParentDataColumn(peer_id, data_column));
}
fn trigger_unknown_block_from_attestation(&mut self, block_root: Hash256, peer_id: PeerId) {
@@ -1757,9 +1746,9 @@ impl TestRig {
)
.unwrap()
{
Availability::Available(_) => panic!("blob removed from da_checker, available"),
Availability::Available(_) => panic!("column removed from da_checker, available"),
Availability::MissingComponents(block_root) => {
self.log(&format!("inserted blob to da_checker {block_root:?}"))
self.log(&format!("inserted column to da_checker {block_root:?}"))
}
};
}
@@ -1944,35 +1933,29 @@ async fn happy_path_unknown_block_parent(depth: usize) {
}
}
/// Assert that sync completes from a GossipUnknownParentBlob / UnknownDataColumnParent
/// Assert that sync completes from an UnknownDataColumnParent
async fn happy_path_unknown_data_parent(depth: usize) {
let Some(mut r) = TestRig::new_after_deneb() else {
let Some(mut r) = TestRig::new_after_fulu() else {
return;
};
r.build_chain(depth).await;
if r.is_after_fulu() {
r.trigger_with_last_unknown_data_column_parent();
} else if r.is_after_deneb() {
r.trigger_with_last_unknown_blob_parent();
}
r.trigger_with_last_unknown_data_column_parent();
r.simulate(SimulateConfig::happy_path()).await;
r.assert_successful_lookup_sync_parent_trigger();
}
/// Assert that multiple trigger types don't create extra lookups
async fn happy_path_multiple_triggers(depth: usize) {
let mut r = TestRig::default();
let Some(mut r) = TestRig::new_after_fulu() else {
return;
};
// + 1, because the unknown parent trigger needs two new blocks
r.build_chain(depth + 1).await;
r.trigger_with_last_block();
r.trigger_with_last_block();
r.trigger_with_last_unknown_block_parent();
r.trigger_with_last_unknown_block_parent();
if r.is_after_fulu() {
r.trigger_with_last_unknown_data_column_parent();
} else if r.is_after_deneb() {
r.trigger_with_last_unknown_blob_parent();
}
r.trigger_with_last_unknown_data_column_parent();
r.simulate(SimulateConfig::happy_path()).await;
assert_eq!(r.created_lookups(), depth + 1, "Don't create extra lookups");
r.assert_successful_lookup_sync();
@@ -2105,18 +2088,14 @@ async fn too_many_processing_failures(depth: usize) {
#[tokio::test]
/// Assert that multiple trigger types don't create extra lookups
async fn unknown_parent_does_not_add_peers_to_itself() {
let Some(mut r) = TestRig::new_after_deneb() else {
let Some(mut r) = TestRig::new_after_fulu() else {
return;
};
// 2, because the unknown parent trigger needs two new blocks
r.build_chain(2).await;
r.trigger_with_last_unknown_block_parent();
r.trigger_with_last_unknown_block_parent();
if r.is_after_fulu() {
r.trigger_with_last_unknown_data_column_parent();
} else if r.is_after_deneb() {
r.trigger_with_last_unknown_blob_parent();
}
r.trigger_with_last_unknown_data_column_parent();
r.simulate(SimulateConfig::happy_path()).await;
r.assert_peers_at_lookup_of_slot(2, 0);
r.assert_peers_at_lookup_of_slot(1, 3);