Skip to content

Commit 0d7ea70

Browse files
committed
Remove KZG verification from local block production and blobs fetched from local EL.
1 parent 3e6b0bd commit 0d7ea70

File tree

6 files changed

+29
-79
lines changed

6 files changed

+29
-79
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ use crate::validator_monitor::{
7070
};
7171
use crate::validator_pubkey_cache::ValidatorPubkeyCache;
7272
use crate::{
73-
kzg_utils, metrics, AvailabilityPendingExecutedBlock, BeaconChainError, BeaconForkChoiceStore,
73+
metrics, AvailabilityPendingExecutedBlock, BeaconChainError, BeaconForkChoiceStore,
7474
BeaconSnapshot, CachedHead,
7575
};
7676
use eth2::types::{
@@ -5748,8 +5748,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
57485748
let (mut block, _) = block.deconstruct();
57495749
*block.state_root_mut() = state_root;
57505750

5751-
let blobs_verification_timer =
5752-
metrics::start_timer(&metrics::BLOCK_PRODUCTION_BLOBS_VERIFICATION_TIMES);
57535751
let blob_items = match maybe_blobs_and_proofs {
57545752
Some((blobs, proofs)) => {
57555753
let expected_kzg_commitments =
@@ -5768,37 +5766,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
57685766
)));
57695767
}
57705768

5771-
let kzg_proofs = Vec::from(proofs);
5772-
5773-
let kzg = self.kzg.as_ref();
5774-
if self
5775-
.spec
5776-
.is_peer_das_enabled_for_epoch(slot.epoch(T::EthSpec::slots_per_epoch()))
5777-
{
5778-
kzg_utils::validate_blobs_and_cell_proofs::<T::EthSpec>(
5779-
kzg,
5780-
blobs.iter().collect(),
5781-
&kzg_proofs,
5782-
expected_kzg_commitments,
5783-
)
5784-
.map_err(BlockProductionError::KzgError)?;
5785-
} else {
5786-
kzg_utils::validate_blobs::<T::EthSpec>(
5787-
kzg,
5788-
expected_kzg_commitments,
5789-
blobs.iter().collect(),
5790-
&kzg_proofs,
5791-
)
5792-
.map_err(BlockProductionError::KzgError)?;
5793-
}
5794-
5795-
Some((kzg_proofs.into(), blobs))
5769+
Some((proofs, blobs))
57965770
}
57975771
None => None,
57985772
};
57995773

5800-
drop(blobs_verification_timer);
5801-
58025774
metrics::inc_counter(&metrics::BLOCK_PRODUCTION_SUCCESSES);
58035775

58045776
trace!(

beacon_node/beacon_chain/src/data_column_verification.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,12 @@ impl<E: EthSpec> KzgVerifiedDataColumn<E> {
266266
verify_kzg_for_data_column(data_column, kzg)
267267
}
268268

269+
/// Mark a data column as KZG verified. Caller must ONLY use this on columns constructed
270+
/// from EL blobs.
271+
pub fn from_execution_verified(data_column: Arc<DataColumnSidecar<E>>) -> Self {
272+
Self { data: data_column }
273+
}
274+
269275
/// Create a `KzgVerifiedDataColumn` from `DataColumnSidecar` for testing ONLY.
270276
pub(crate) fn __new_for_testing(data_column: Arc<DataColumnSidecar<E>>) -> Self {
271277
Self { data: data_column }

beacon_node/beacon_chain/src/fetch_blobs/fetch_blobs_beacon_adapter.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
use crate::blob_verification::{GossipBlobError, GossipVerifiedBlob};
2-
use crate::data_column_verification::KzgVerifiedDataColumn;
32
use crate::fetch_blobs::{EngineGetBlobsOutput, FetchEngineBlobError};
43
use crate::observed_block_producers::ProposalKey;
54
use crate::observed_data_sidecars::DoNotObserve;
65
use crate::{AvailabilityProcessingStatus, BeaconChain, BeaconChainTypes};
76
use execution_layer::json_structures::{BlobAndProofV1, BlobAndProofV2};
8-
use kzg::{Error as KzgError, Kzg};
7+
use kzg::Kzg;
98
#[cfg(test)]
109
use mockall::automock;
1110
use std::collections::HashSet;
1211
use std::sync::Arc;
1312
use task_executor::TaskExecutor;
14-
use types::{BlobSidecar, ChainSpec, ColumnIndex, DataColumnSidecar, Hash256, Slot};
13+
use types::{BlobSidecar, ChainSpec, ColumnIndex, Hash256, Slot};
1514

1615
/// An adapter to the `BeaconChain` functionalities to remove `BeaconChain` from direct dependency to enable testing fetch blobs logic.
1716
pub(crate) struct FetchBlobsBeaconAdapter<T: BeaconChainTypes> {
@@ -77,14 +76,7 @@ impl<T: BeaconChainTypes> FetchBlobsBeaconAdapter<T> {
7776
GossipVerifiedBlob::<T, DoNotObserve>::new(blob.clone(), blob.index, &self.chain)
7877
}
7978

80-
pub(crate) fn verify_data_columns_kzg(
81-
&self,
82-
data_columns: Vec<Arc<DataColumnSidecar<T::EthSpec>>>,
83-
) -> Result<Vec<KzgVerifiedDataColumn<T::EthSpec>>, KzgError> {
84-
KzgVerifiedDataColumn::from_batch(data_columns, &self.chain.kzg)
85-
}
86-
87-
pub(crate) fn known_for_proposal(
79+
pub(crate) fn data_column_known_for_proposal(
8880
&self,
8981
proposal_key: ProposalKey,
9082
) -> Option<HashSet<ColumnIndex>> {

beacon_node/beacon_chain/src/fetch_blobs/mod.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod tests;
1414

1515
use crate::blob_verification::{GossipBlobError, GossipVerifiedBlob};
1616
use crate::block_verification_types::AsBlock;
17-
use crate::data_column_verification::KzgVerifiedCustodyDataColumn;
17+
use crate::data_column_verification::{KzgVerifiedCustodyDataColumn, KzgVerifiedDataColumn};
1818
#[cfg_attr(test, double)]
1919
use crate::fetch_blobs::fetch_blobs_beacon_adapter::FetchBlobsBeaconAdapter;
2020
use crate::kzg_utils::blobs_to_data_column_sidecars;
@@ -358,17 +358,24 @@ async fn compute_custody_columns_to_import<T: BeaconChainTypes>(
358358
// `DataAvailabilityChecker` requires a strict match on custody columns count to
359359
// consider a block available.
360360
let mut custody_columns = data_columns_result
361-
.map(|mut data_columns| {
362-
data_columns.retain(|col| custody_columns_indices.contains(&col.index));
361+
.map(|data_columns| {
363362
data_columns
363+
.into_iter()
364+
.filter(|col| custody_columns_indices.contains(&col.index))
365+
.map(|col| {
366+
KzgVerifiedCustodyDataColumn::from_asserted_custody(
367+
KzgVerifiedDataColumn::from_execution_verified(col),
368+
)
369+
})
370+
.collect::<Vec<_>>()
364371
})
365372
.map_err(FetchEngineBlobError::DataColumnSidecarError)?;
366373

367374
// Only consider columns that are not already observed on gossip.
368-
if let Some(observed_columns) = chain_adapter_cloned.known_for_proposal(
375+
if let Some(observed_columns) = chain_adapter_cloned.data_column_known_for_proposal(
369376
ProposalKey::new(block.message().proposer_index(), block.slot()),
370377
) {
371-
custody_columns.retain(|col| !observed_columns.contains(&col.index));
378+
custody_columns.retain(|col| !observed_columns.contains(&col.index()));
372379
if custody_columns.is_empty() {
373380
return Ok(vec![]);
374381
}
@@ -378,26 +385,13 @@ async fn compute_custody_columns_to_import<T: BeaconChainTypes>(
378385
if let Some(known_columns) =
379386
chain_adapter_cloned.cached_data_column_indexes(&block_root)
380387
{
381-
custody_columns.retain(|col| !known_columns.contains(&col.index));
388+
custody_columns.retain(|col| !known_columns.contains(&col.index()));
382389
if custody_columns.is_empty() {
383390
return Ok(vec![]);
384391
}
385392
}
386393

387-
// KZG verify data columns before publishing. This prevents blobs with invalid
388-
// KZG proofs from the EL making it into the data availability checker. We do not
389-
// immediately add these blobs to the observed blobs/columns cache because we want
390-
// to allow blobs/columns to arrive on gossip and be accepted (and propagated) while
391-
// we are waiting to publish. Just before publishing we will observe the blobs/columns
392-
// and only proceed with publishing if they are not yet seen.
393-
let verified = chain_adapter_cloned
394-
.verify_data_columns_kzg(custody_columns)
395-
.map_err(FetchEngineBlobError::KzgError)?;
396-
397-
Ok(verified
398-
.into_iter()
399-
.map(KzgVerifiedCustodyDataColumn::from_asserted_custody)
400-
.collect())
394+
Ok(custody_columns)
401395
},
402396
"compute_custody_columns_to_import",
403397
)

beacon_node/beacon_chain/src/fetch_blobs/tests.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ mod get_blobs_v2 {
156156
mock_fork_choice_contains_block(&mut mock_adapter, vec![]);
157157
// All data columns already seen on gossip
158158
mock_adapter
159-
.expect_known_for_proposal()
159+
.expect_data_column_known_for_proposal()
160160
.returning(|_| Some(hashset![0, 1, 2]));
161161
// No blobs should be processed
162162
mock_adapter.expect_process_engine_blobs().times(0);
@@ -192,17 +192,12 @@ mod get_blobs_v2 {
192192
// All blobs returned, fork choice doesn't contain block
193193
mock_get_blobs_v2_response(&mut mock_adapter, Some(blobs_and_proofs));
194194
mock_fork_choice_contains_block(&mut mock_adapter, vec![]);
195-
mock_adapter.expect_known_for_proposal().returning(|_| None);
196195
mock_adapter
197-
.expect_cached_data_column_indexes()
196+
.expect_data_column_known_for_proposal()
198197
.returning(|_| None);
199198
mock_adapter
200-
.expect_verify_data_columns_kzg()
201-
.returning(|c| {
202-
Ok(c.into_iter()
203-
.map(KzgVerifiedDataColumn::__new_for_testing)
204-
.collect())
205-
});
199+
.expect_cached_data_column_indexes()
200+
.returning(|_| None);
206201
mock_process_engine_blobs_result(
207202
&mut mock_adapter,
208203
Ok(AvailabilityProcessingStatus::Imported(block_root)),

beacon_node/beacon_chain/src/metrics.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,15 +1824,6 @@ pub static KZG_VERIFICATION_DATA_COLUMN_BATCH_TIMES: LazyLock<Result<Histogram>>
18241824
)
18251825
});
18261826

1827-
pub static BLOCK_PRODUCTION_BLOBS_VERIFICATION_TIMES: LazyLock<Result<Histogram>> = LazyLock::new(
1828-
|| {
1829-
try_create_histogram(
1830-
"beacon_block_production_blobs_verification_seconds",
1831-
"Time taken to verify blobs against commitments and creating BlobSidecar objects in block production"
1832-
)
1833-
},
1834-
);
1835-
18361827
/*
18371828
* Data Availability cache metrics
18381829
*/

0 commit comments

Comments
 (0)