Skip to content

Commit 82c39dc

Browse files
committed
Fix column sidecars incorrectly produced when there are no blobs.
1 parent 5b4f9de commit 82c39dc

File tree

7 files changed

+150
-8
lines changed

7 files changed

+150
-8
lines changed

Cargo.lock

Lines changed: 92 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ libsecp256k1 = "0.7"
119119
log = "0.4"
120120
lru = "0.12"
121121
maplit = "1"
122+
mockall = "0.12"
123+
mockall_double = "0.3"
122124
num_cpus = "1"
123125
parking_lot = "0.12"
124126
paste = "1"

beacon_node/beacon_chain/src/block_verification.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,8 @@ fn build_gossip_verified_data_columns<T: BeaconChainTypes>(
773773
gossip_verified_blobs: Option<&GossipVerifiedBlobList<T>>,
774774
) -> Result<Option<GossipVerifiedDataColumnList<T>>, BlockContentsError<T::EthSpec>> {
775775
gossip_verified_blobs
776+
// Only attempt to build data columns if blobs is non empty to avoid skewing the metrics.
777+
.filter(|b| !b.is_empty())
776778
.map(|blobs| {
777779
// NOTE: we expect KZG to be initialized if the blobs are present
778780
let kzg = chain
@@ -786,7 +788,7 @@ fn build_gossip_verified_data_columns<T: BeaconChainTypes>(
786788
let blob_sidecar_list = BlobSidecarList::new(blob_sidecar_list)
787789
.map_err(DataColumnSidecarError::SszError)?;
788790
let timer = metrics::start_timer(&metrics::DATA_COLUMN_SIDECAR_COMPUTATION);
789-
let sidecars = DataColumnSidecar::build_sidecars(&blob_sidecar_list, &block, kzg)?;
791+
let sidecars = DataColumnSidecar::build_sidecars(&blob_sidecar_list, block, kzg)?;
790792
drop(timer);
791793
let mut gossip_verified_data_columns = vec![];
792794
for sidecar in sidecars {

consensus/types/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ eth2_network_config = { workspace = true }
6060
state_processing = { workspace = true }
6161
tokio = { workspace = true }
6262
paste = { workspace = true }
63+
mockall_double = { workspace = true }
6364

6465
[features]
6566
default = ["sqlite", "legacy-arith"]

consensus/types/src/data_column_sidecar.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ use crate::{
77
};
88
use bls::Signature;
99
use derivative::Derivative;
10-
use kzg::{Blob as KzgBlob, Error as KzgError, Kzg};
10+
#[cfg_attr(test, double)]
11+
use kzg::Kzg;
12+
use kzg::{Blob as KzgBlob, Error as KzgError};
1113
use kzg::{KzgCommitment, KzgProof};
14+
#[cfg(test)]
15+
use mockall_double::double;
1216
use safe_arith::ArithError;
1317
use serde::{Deserialize, Serialize};
1418
use ssz::Encode;
@@ -76,6 +80,9 @@ impl<E: EthSpec> DataColumnSidecar<E> {
7680
block: &SignedBeaconBlock<E>,
7781
kzg: &Kzg,
7882
) -> Result<DataColumnSidecarList<E>, DataColumnSidecarError> {
83+
if blobs.is_empty() {
84+
return Ok(DataColumnSidecarList::empty());
85+
}
7986
let kzg_commitments = block
8087
.message()
8188
.body()
@@ -239,6 +246,7 @@ pub type FixedDataColumnSidecarList<E> =
239246

240247
#[cfg(test)]
241248
mod test {
249+
use super::*;
242250
use crate::beacon_block::EmptyBlock;
243251
use crate::beacon_block_body::KzgCommitments;
244252
use crate::eth_spec::EthSpec;
@@ -247,10 +255,24 @@ mod test {
247255
DataColumnSidecar, MainnetEthSpec, SignedBeaconBlock,
248256
};
249257
use bls::Signature;
250-
use eth2_network_config::TRUSTED_SETUP_BYTES;
251-
use kzg::{Kzg, KzgCommitment, KzgProof, TrustedSetup};
258+
use kzg::{KzgCommitment, KzgProof};
252259
use std::sync::Arc;
253260

261+
#[test]
262+
fn test_build_sidecars_empty() {
263+
type E = MainnetEthSpec;
264+
let num_of_blobs = 0;
265+
let spec = E::default_spec();
266+
let (signed_block, blob_sidecars) =
267+
create_test_block_and_blob_sidecars::<E>(num_of_blobs, &spec);
268+
269+
let mock_kzg = Arc::new(Kzg::default());
270+
let column_sidecars =
271+
DataColumnSidecar::build_sidecars(&blob_sidecars, &signed_block, &mock_kzg).unwrap();
272+
273+
assert!(column_sidecars.is_empty());
274+
}
275+
254276
#[test]
255277
fn test_build_sidecars() {
256278
type E = MainnetEthSpec;
@@ -259,11 +281,13 @@ mod test {
259281
let (signed_block, blob_sidecars) =
260282
create_test_block_and_blob_sidecars::<E>(num_of_blobs, &spec);
261283

262-
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES).unwrap();
263-
let kzg = Arc::new(Kzg::new_from_trusted_setup(trusted_setup).unwrap());
284+
let mut mock_kzg = Kzg::default();
285+
mock_kzg
286+
.expect_compute_cells_and_proofs()
287+
.returning(kzg::mock::compute_cells_and_proofs);
264288

265289
let column_sidecars =
266-
DataColumnSidecar::build_sidecars(&blob_sidecars, &signed_block, &kzg).unwrap();
290+
DataColumnSidecar::build_sidecars(&blob_sidecars, &signed_block, &mock_kzg).unwrap();
267291

268292
let block_kzg_commitments = signed_block
269293
.message()

crypto/kzg/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ ethereum_serde_utils = { workspace = true }
1717
hex = { workspace = true }
1818
ethereum_hashing = { workspace = true }
1919
c-kzg = { workspace = true }
20+
mockall = { workspace = true }

crypto/kzg/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub use c_kzg::{
1414
BYTES_PER_FIELD_ELEMENT, BYTES_PER_PROOF, FIELD_ELEMENTS_PER_BLOB,
1515
};
1616
use c_kzg::{Cell, CELLS_PER_BLOB};
17+
use mockall::automock;
18+
1719
#[derive(Debug)]
1820
pub enum Error {
1921
/// An error from the underlying kzg library.
@@ -34,6 +36,7 @@ pub struct Kzg {
3436
trusted_setup: KzgSettings,
3537
}
3638

39+
#[automock]
3740
impl Kzg {
3841
/// Load the kzg trusted setup parameters from a vec of G1 and G2 points.
3942
pub fn new_from_trusted_setup(trusted_setup: TrustedSetup) -> Result<Self, Error> {
@@ -191,6 +194,24 @@ impl Kzg {
191194
}
192195
}
193196

197+
pub mod mock {
198+
use crate::{Error, KzgProof};
199+
use c_kzg::{Blob, Cell, CELLS_PER_BLOB};
200+
201+
pub const MOCK_KZG_BYTES_PER_CELL: usize = 2048;
202+
203+
#[allow(clippy::type_complexity)]
204+
pub fn compute_cells_and_proofs(
205+
_blob: &Blob,
206+
) -> Result<(Box<[Cell; CELLS_PER_BLOB]>, Box<[KzgProof; CELLS_PER_BLOB]>), Error> {
207+
let empty_cell = Cell::new([0; MOCK_KZG_BYTES_PER_CELL]);
208+
Ok((
209+
Box::new([empty_cell; CELLS_PER_BLOB]),
210+
Box::new([KzgProof::empty(); CELLS_PER_BLOB]),
211+
))
212+
}
213+
}
214+
194215
impl TryFrom<TrustedSetup> for Kzg {
195216
type Error = Error;
196217

0 commit comments

Comments
 (0)