Skip to content

Commit 492c1c6

Browse files
committed
Use pre-computed data columns for testing and fix tests.
1 parent b3da74b commit 492c1c6

File tree

5 files changed

+91
-45
lines changed

5 files changed

+91
-45
lines changed

beacon_node/beacon_chain/src/kzg_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ pub fn blobs_to_data_column_sidecars<E: EthSpec>(
186186
.map_err(DataColumnSidecarError::BuildSidecarFailed)
187187
}
188188

189-
fn build_data_column_sidecars<E: EthSpec>(
189+
pub(crate) fn build_data_column_sidecars<E: EthSpec>(
190190
kzg_commitments: KzgCommitments<E>,
191191
kzg_commitments_inclusion_proof: FixedVector<Hash256, E::KzgCommitmentsInclusionProofDepth>,
192192
signed_block_header: SignedBeaconBlockHeader,

beacon_node/beacon_chain/src/test_utils.rs

Lines changed: 85 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::blob_verification::GossipVerifiedBlob;
22
use crate::block_verification_types::{AsBlock, RpcBlock};
33
use crate::data_column_verification::CustodyDataColumn;
4-
use crate::kzg_utils::blobs_to_data_column_sidecars;
4+
use crate::kzg_utils::build_data_column_sidecars;
55
use crate::observed_operations::ObservationOutcome;
66
pub use crate::persisted_beacon_chain::PersistedBeaconChain;
77
pub use crate::{
@@ -76,6 +76,11 @@ pub const FORK_NAME_ENV_VAR: &str = "FORK_NAME";
7676
// Environment variable to read if `ci_logger` feature is enabled.
7777
pub const CI_LOGGER_DIR_ENV_VAR: &str = "CI_LOGGER_DIR";
7878

79+
// Pre-computed data column sidecar using a single static blob from:
80+
// `beacon_node/execution_layer/src/test_utils/fixtures/mainnet/test_blobs_bundle.ssz`
81+
const TEST_DATA_COLUMN_SIDECARS_SSZ: &[u8] =
82+
include_bytes!("test_utils/fixtures/test_data_column_sidecars.ssz");
83+
7984
// Default target aggregators to set during testing, this ensures an aggregator at each slot.
8085
//
8186
// You should mutate the `ChainSpec` prior to initialising the harness if you would like to use
@@ -2357,26 +2362,19 @@ where
23572362
.data_availability_checker
23582363
.get_sampling_column_count();
23592364

2360-
let columns = blob_items
2361-
.map(|(_proofs, blobs)| {
2362-
blobs_to_data_column_sidecars(
2363-
&blobs.iter().collect::<Vec<_>>(),
2364-
&block,
2365-
&self.chain.kzg,
2366-
&self.spec,
2367-
)
2368-
.map(|column_sidecars| {
2369-
column_sidecars
2370-
.into_iter()
2371-
.take(sampling_column_count)
2372-
.map(CustodyDataColumn::from_asserted_custody)
2373-
.collect::<Vec<_>>()
2374-
})
2375-
})
2376-
.transpose()
2377-
.expect("should convert blobs to columns")
2378-
.unwrap_or_default();
2379-
RpcBlock::new_with_custody_columns(Some(block_root), block, columns, &self.spec)?
2365+
if blob_items.is_some_and(|(_, blobs)| !blobs.is_empty()) {
2366+
// Note: this method ignores the actual custody columns and just take the first
2367+
// `sampling_column_count` for testing purpose only, because the chain does not
2368+
// currently have any knowledge of the columns being custodied.
2369+
let columns = generate_data_column_sidecars_from_block(&block, &self.spec)
2370+
.into_iter()
2371+
.take(sampling_column_count)
2372+
.map(CustodyDataColumn::from_asserted_custody)
2373+
.collect::<Vec<_>>();
2374+
RpcBlock::new_with_custody_columns(Some(block_root), block, columns, &self.spec)?
2375+
} else {
2376+
RpcBlock::new_without_blobs(Some(block_root), block)
2377+
}
23802378
} else {
23812379
let blobs = blob_items
23822380
.map(|(proofs, blobs)| {
@@ -3073,21 +3071,15 @@ where
30733071
) {
30743072
let is_peerdas_enabled = self.chain.spec.is_peer_das_enabled_for_epoch(block.epoch());
30753073
if is_peerdas_enabled {
3076-
let sidecars = blobs_to_data_column_sidecars(
3077-
&blobs.collect::<Vec<_>>(),
3078-
block,
3079-
&self.chain.kzg,
3080-
&self.spec,
3081-
)
3082-
.unwrap();
3083-
30843074
let custody_columns = custody_columns_opt.unwrap_or_else(|| {
3085-
let spec = &self.chain.spec;
3086-
let sampling_size = spec.sampling_size(spec.custody_requirement).unwrap();
3087-
(0..sampling_size).collect()
3075+
let sampling_column_count = self
3076+
.chain
3077+
.data_availability_checker
3078+
.get_sampling_column_count() as u64;
3079+
(0..sampling_column_count).collect()
30883080
});
30893081

3090-
let verified_columns = sidecars
3082+
let verified_columns = generate_data_column_sidecars_from_block(block, &self.spec)
30913083
.into_iter()
30923084
.filter(|c| custody_columns.contains(&c.index))
30933085
.map(|sidecar| {
@@ -3098,10 +3090,12 @@ where
30983090
.collect::<Result<Vec<_>, _>>()
30993091
.unwrap();
31003092

3101-
self.chain
3102-
.process_gossip_data_columns(verified_columns, || Ok(()))
3103-
.await
3104-
.unwrap();
3093+
if !verified_columns.is_empty() {
3094+
self.chain
3095+
.process_gossip_data_columns(verified_columns, || Ok(()))
3096+
.await
3097+
.unwrap();
3098+
}
31053099
} else {
31063100
for (i, (kzg_proof, blob)) in proofs.into_iter().zip(blobs).enumerate() {
31073101
let sidecar =
@@ -3300,10 +3294,59 @@ pub fn generate_rand_block_and_data_columns<E: EthSpec>(
33003294
SignedBeaconBlock<E, FullPayload<E>>,
33013295
DataColumnSidecarList<E>,
33023296
) {
3303-
let kzg = get_kzg(spec);
3304-
let (block, blobs) = generate_rand_block_and_blobs(fork_name, num_blobs, rng, spec);
3305-
let blob_refs = blobs.iter().map(|b| &b.blob).collect::<Vec<_>>();
3306-
let data_columns = blobs_to_data_column_sidecars(&blob_refs, &block, &kzg, spec).unwrap();
3307-
3297+
let (block, _blobs) = generate_rand_block_and_blobs(fork_name, num_blobs, rng, spec);
3298+
let data_columns = generate_data_column_sidecars_from_block(&block, spec);
33083299
(block, data_columns)
33093300
}
3301+
3302+
/// Generate data column sidecars from pre-computed cells and proofs.
3303+
fn generate_data_column_sidecars_from_block<E: EthSpec>(
3304+
block: &SignedBeaconBlock<E>,
3305+
spec: &ChainSpec,
3306+
) -> DataColumnSidecarList<E> {
3307+
let kzg_commitments = block.message().body().blob_kzg_commitments().unwrap();
3308+
if kzg_commitments.is_empty() {
3309+
return vec![];
3310+
}
3311+
3312+
let kzg_commitments_inclusion_proof = block
3313+
.message()
3314+
.body()
3315+
.kzg_commitments_merkle_proof()
3316+
.unwrap();
3317+
let signed_block_header = block.signed_block_header();
3318+
3319+
// load the precomputed column sidecar to avoid computing them for every block in the tests.
3320+
let template_data_columns = RuntimeVariableList::<DataColumnSidecar<E>>::from_ssz_bytes(
3321+
TEST_DATA_COLUMN_SIDECARS_SSZ,
3322+
spec.number_of_columns as usize,
3323+
)
3324+
.unwrap();
3325+
3326+
let (cells, proofs) = template_data_columns
3327+
.into_iter()
3328+
.map(|sidecar| {
3329+
let DataColumnSidecar {
3330+
column, kzg_proofs, ..
3331+
} = sidecar;
3332+
// There's only one cell per column for a single blob
3333+
let cell_bytes: Vec<u8> = column.into_iter().next().unwrap().into();
3334+
let kzg_cell = cell_bytes.try_into().unwrap();
3335+
let kzg_proof = kzg_proofs.into_iter().next().unwrap();
3336+
(kzg_cell, kzg_proof)
3337+
})
3338+
.collect::<(Vec<_>, Vec<_>)>();
3339+
3340+
// Repeat the cells and proofs for every blob
3341+
let blob_cells_and_proofs_vec =
3342+
vec![(cells.try_into().unwrap(), proofs.try_into().unwrap()); kzg_commitments.len()];
3343+
3344+
build_data_column_sidecars(
3345+
kzg_commitments.clone(),
3346+
kzg_commitments_inclusion_proof,
3347+
signed_block_header,
3348+
blob_cells_and_proofs_vec,
3349+
spec,
3350+
)
3351+
.unwrap()
3352+
}
Binary file not shown.

beacon_node/network/src/sync/block_sidecar_coupling.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ mod tests {
321321
let blocks = (0..4)
322322
.map(|_| {
323323
generate_rand_block_and_data_columns::<E>(
324-
ForkName::Deneb,
324+
ForkName::Fulu,
325325
NumBlobs::Number(1),
326326
&mut rng,
327327
&spec,
@@ -384,7 +384,7 @@ mod tests {
384384
let blocks = (0..4)
385385
.map(|_| {
386386
generate_rand_block_and_data_columns::<E>(
387-
ForkName::Deneb,
387+
ForkName::Fulu,
388388
NumBlobs::Number(1),
389389
&mut rng,
390390
&spec,

crypto/kzg/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ pub use rust_eth_kzg::{
2121
Cell, CellIndex as CellID, CellRef, TrustedSetup as PeerDASTrustedSetup,
2222
};
2323

24+
// Note: `spec.number_of_columns` is a config and should match `CELLS_PER_EXT_BLOB` - however this
25+
// is a constant in the KZG library - be aware that overriding `number_of_columns` will break KZG
26+
// operations.
2427
pub type CellsAndKzgProofs = ([Cell; CELLS_PER_EXT_BLOB], [KzgProof; CELLS_PER_EXT_BLOB]);
2528

2629
pub type KzgBlobRef<'a> = &'a [u8; BYTES_PER_BLOB];

0 commit comments

Comments
 (0)