diff --git a/Cargo.lock b/Cargo.lock index 5cfa602ef5d..5fcba6b2643 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1408,6 +1408,7 @@ dependencies = [ "genesis", "http_api", "http_metrics", + "kzg", "lighthouse_metrics", "lighthouse_network", "monitoring_api", @@ -1415,6 +1416,7 @@ dependencies = [ "operation_pool", "sensitive_url", "serde", + "serde_json", "serde_yaml", "slasher", "slasher_service", @@ -2621,6 +2623,7 @@ dependencies = [ "discv5", "eth2_config", "ethereum_ssz", + "kzg", "logging", "pretty_reqwest_error", "reqwest", @@ -4413,7 +4416,6 @@ dependencies = [ "c-kzg", "criterion", "derivative", - "eth2_network_config", "ethereum_hashing", "ethereum_serde_utils", "ethereum_ssz", @@ -5641,6 +5643,7 @@ dependencies = [ "derivative", "error-chain", "eth2", + "eth2_network_config", "ethereum_ssz", "execution_layer", "fnv", @@ -5650,6 +5653,7 @@ dependencies = [ "hex", "igd-next", "itertools 0.10.5", + "kzg", "lighthouse_metrics", "lighthouse_network", "logging", @@ -5658,6 +5662,7 @@ dependencies = [ "operation_pool", "parking_lot 0.12.3", "rand", + "serde_json", "slog", "slog-async", "slog-term", @@ -7746,6 +7751,7 @@ dependencies = [ "eth2_network_config", "execution_layer", "futures", + "kzg", "node_test_rig", "parking_lot 0.12.3", "rayon", diff --git a/beacon_node/beacon_chain/benches/benches.rs b/beacon_node/beacon_chain/benches/benches.rs index 4a29be90251..b2f17062dce 100644 --- a/beacon_node/beacon_chain/benches/benches.rs +++ b/beacon_node/beacon_chain/benches/benches.rs @@ -1,11 +1,11 @@ use std::sync::Arc; use beacon_chain::kzg_utils::{blobs_to_data_column_sidecars, reconstruct_data_columns}; +use beacon_chain::test_utils::get_kzg; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use bls::Signature; -use eth2_network_config::TRUSTED_SETUP_BYTES; -use kzg::{Kzg, KzgCommitment, TrustedSetup}; +use kzg::KzgCommitment; use types::{ beacon_block_body::KzgCommitments, BeaconBlock, BeaconBlockDeneb, Blob, BlobsList, ChainSpec, EmptyBlock, EthSpec, MainnetEthSpec, SignedBeaconBlock, @@ -35,11 +35,7 @@ fn all_benches(c: &mut Criterion) { type E = MainnetEthSpec; let spec = Arc::new(E::default_spec()); - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) - .map_err(|e| format!("Unable to read trusted setup file: {}", e)) - .expect("should have trusted setup"); - let kzg = Arc::new(Kzg::new_from_trusted_setup(trusted_setup).expect("should create kzg")); - + let kzg = get_kzg(&spec); for blob_count in [1, 2, 3, 6] { let kzg = kzg.clone(); let (signed_block, blob_sidecars) = create_test_block_and_blobs::(blob_count, &spec); diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index d83955854d8..7094060b718 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -497,7 +497,7 @@ pub struct BeaconChain { /// they are collected and combined. pub data_availability_checker: Arc>, /// The KZG trusted setup used by this chain. - pub kzg: Option>, + pub kzg: Arc, } pub enum BeaconBlockResponseWrapper { @@ -5682,10 +5682,8 @@ impl BeaconChain { let kzg_proofs = Vec::from(proofs); - let kzg = self - .kzg - .as_ref() - .ok_or(BlockProductionError::TrustedSetupNotInitialized)?; + let kzg = self.kzg.as_ref(); + kzg_utils::validate_blobs::( kzg, expected_kzg_commitments, diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index e4646d62882..743748a76d9 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -115,13 +115,6 @@ pub enum GossipBlobError { index: u64, }, - /// `Kzg` struct hasn't been initialized. This is an internal error. - /// - /// ## Peer scoring - /// - /// The peer isn't faulty, This is an internal error. - KzgNotInitialized, - /// The kzg verification failed. /// /// ## Peer scoring @@ -559,11 +552,9 @@ pub fn validate_blob_sidecar_for_gossip( } // Kzg verification for gossip blob sidecar - let kzg = chain - .kzg - .as_ref() - .ok_or(GossipBlobError::KzgNotInitialized)?; - let kzg_verified_blob = KzgVerifiedBlob::new(blob_sidecar, kzg, seen_timestamp) + let kzg = chain.kzg.as_ref(); + + let kzg_verified_blob = KzgVerifiedBlob::new(blob_sidecar.clone(), kzg, seen_timestamp) .map_err(GossipBlobError::KzgError)?; let blob_sidecar = &kzg_verified_blob.blob; diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index 55547aaa18c..027c013a497 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -789,19 +789,11 @@ fn build_gossip_verified_data_columns( // Only attempt to build data columns if blobs is non empty to avoid skewing the metrics. .filter(|b| !b.is_empty()) .map(|blobs| { - // NOTE: we expect KZG to be initialized if the blobs are present - let kzg = chain - .kzg - .as_ref() - .ok_or(BlockContentsError::DataColumnError( - GossipDataColumnError::KzgNotInitialized, - ))?; - let mut timer = metrics::start_timer_vec( &metrics::DATA_COLUMN_SIDECAR_COMPUTATION, &[&blobs.len().to_string()], ); - let sidecars = blobs_to_data_column_sidecars(&blobs, block, kzg, &chain.spec) + let sidecars = blobs_to_data_column_sidecars(&blobs, block, &chain.kzg, &chain.spec) .discard_timer_on_break(&mut timer)?; drop(timer); let mut gossip_verified_data_columns = vec![]; diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index d38530b9049..c38101e274c 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -101,7 +101,7 @@ pub struct BeaconChainBuilder { // Pending I/O batch that is constructed during building and should be executed atomically // alongside `PersistedBeaconChain` storage when `BeaconChainBuilder::build` is called. pending_io_batch: Vec, - kzg: Option>, + kzg: Arc, task_executor: Option, validator_monitor_config: Option, import_all_data_columns: bool, @@ -120,7 +120,7 @@ where /// /// The `_eth_spec_instance` parameter is only supplied to make concrete the `E` trait. /// This should generally be either the `MinimalEthSpec` or `MainnetEthSpec` types. - pub fn new(_eth_spec_instance: E) -> Self { + pub fn new(_eth_spec_instance: E, kzg: Arc) -> Self { Self { store: None, store_migrator_config: None, @@ -143,7 +143,7 @@ where beacon_graffiti: GraffitiOrigin::default(), slasher: None, pending_io_batch: vec![], - kzg: None, + kzg, task_executor: None, validator_monitor_config: None, import_all_data_columns: false, @@ -694,11 +694,6 @@ where self } - pub fn kzg(mut self, kzg: Option>) -> Self { - self.kzg = kzg; - self - } - /// Consumes `self`, returning a `BeaconChain` if all required parameters have been supplied. /// /// An error will be returned at runtime if all required parameters have not been configured. @@ -1157,7 +1152,7 @@ fn descriptive_db_error(item: &str, error: &StoreError) -> String { #[cfg(test)] mod test { use super::*; - use crate::test_utils::EphemeralHarnessType; + use crate::test_utils::{get_kzg, EphemeralHarnessType}; use ethereum_hashing::hash; use genesis::{ generate_deterministic_keypairs, interop_genesis_state, DEFAULT_ETH1_BLOCK_HASH, @@ -1204,7 +1199,9 @@ mod test { let (shutdown_tx, _) = futures::channel::mpsc::channel(1); let runtime = TestRuntime::default(); - let chain = Builder::new(MinimalEthSpec) + let kzg = get_kzg(&spec); + + let chain = Builder::new(MinimalEthSpec, kzg) .logger(log.clone()) .store(Arc::new(store)) .task_executor(runtime.task_executor.clone()) diff --git a/beacon_node/beacon_chain/src/data_availability_checker.rs b/beacon_node/beacon_chain/src/data_availability_checker.rs index 470cee713fa..26fb46ef7f8 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker.rs @@ -69,7 +69,7 @@ pub const STATE_LRU_CAPACITY: usize = STATE_LRU_CAPACITY_NON_ZERO.get(); pub struct DataAvailabilityChecker { availability_cache: Arc>, slot_clock: T::SlotClock, - kzg: Option>, + kzg: Arc, spec: Arc, } @@ -97,7 +97,7 @@ impl Debug for Availability { impl DataAvailabilityChecker { pub fn new( slot_clock: T::SlotClock, - kzg: Option>, + kzg: Arc, store: BeaconStore, import_all_data_columns: bool, spec: ChainSpec, @@ -190,18 +190,17 @@ impl DataAvailabilityChecker { epoch: Epoch, blobs: FixedBlobSidecarList, ) -> Result, AvailabilityCheckError> { - let Some(kzg) = self.kzg.as_ref() else { - return Err(AvailabilityCheckError::KzgNotInitialized); - }; - let seen_timestamp = self .slot_clock .now_duration() .ok_or(AvailabilityCheckError::SlotClockError)?; - let verified_blobs = - KzgVerifiedBlobList::new(Vec::from(blobs).into_iter().flatten(), kzg, seen_timestamp) - .map_err(AvailabilityCheckError::Kzg)?; + let verified_blobs = KzgVerifiedBlobList::new( + Vec::from(blobs).into_iter().flatten(), + &self.kzg, + seen_timestamp, + ) + .map_err(AvailabilityCheckError::Kzg)?; self.availability_cache .put_kzg_verified_blobs(block_root, epoch, verified_blobs) @@ -217,23 +216,20 @@ impl DataAvailabilityChecker { custody_columns: DataColumnSidecarList, ) -> Result<(Availability, DataColumnsToPublish), AvailabilityCheckError> { - let Some(kzg) = self.kzg.as_ref() else { - return Err(AvailabilityCheckError::KzgNotInitialized); - }; - // TODO(das): report which column is invalid for proper peer scoring // TODO(das): batch KZG verification here let verified_custody_columns = custody_columns .into_iter() .map(|column| { Ok(KzgVerifiedCustodyDataColumn::from_asserted_custody( - KzgVerifiedDataColumn::new(column, kzg).map_err(AvailabilityCheckError::Kzg)?, + KzgVerifiedDataColumn::new(column, &self.kzg) + .map_err(AvailabilityCheckError::Kzg)?, )) }) .collect::, AvailabilityCheckError>>()?; self.availability_cache.put_kzg_verified_data_columns( - kzg, + &self.kzg, block_root, epoch, verified_custody_columns, @@ -269,9 +265,6 @@ impl DataAvailabilityChecker { gossip_data_columns: Vec>, ) -> Result<(Availability, DataColumnsToPublish), AvailabilityCheckError> { - let Some(kzg) = self.kzg.as_ref() else { - return Err(AvailabilityCheckError::KzgNotInitialized); - }; let epoch = slot.epoch(T::EthSpec::slots_per_epoch()); let custody_columns = gossip_data_columns @@ -280,7 +273,7 @@ impl DataAvailabilityChecker { .collect::>(); self.availability_cache.put_kzg_verified_data_columns( - kzg, + &self.kzg, block_root, epoch, custody_columns, @@ -314,11 +307,7 @@ impl DataAvailabilityChecker { let (block_root, block, blobs, data_columns) = block.deconstruct(); if self.blobs_required_for_block(&block) { return if let Some(blob_list) = blobs.as_ref() { - let kzg = self - .kzg - .as_ref() - .ok_or(AvailabilityCheckError::KzgNotInitialized)?; - verify_kzg_for_blob_list(blob_list.iter(), kzg) + verify_kzg_for_blob_list(blob_list.iter(), &self.kzg) .map_err(AvailabilityCheckError::Kzg)?; Ok(MaybeAvailableBlock::Available(AvailableBlock { block_root, @@ -334,15 +323,11 @@ impl DataAvailabilityChecker { } if self.data_columns_required_for_block(&block) { return if let Some(data_column_list) = data_columns.as_ref() { - let kzg = self - .kzg - .as_ref() - .ok_or(AvailabilityCheckError::KzgNotInitialized)?; verify_kzg_for_data_column_list( data_column_list .iter() .map(|custody_column| custody_column.as_data_column()), - kzg, + &self.kzg, ) .map_err(AvailabilityCheckError::Kzg)?; Ok(MaybeAvailableBlock::Available(AvailableBlock { @@ -395,11 +380,7 @@ impl DataAvailabilityChecker { // verify kzg for all blobs at once if !all_blobs.is_empty() { - let kzg = self - .kzg - .as_ref() - .ok_or(AvailabilityCheckError::KzgNotInitialized)?; - verify_kzg_for_blob_list(all_blobs.iter(), kzg)?; + verify_kzg_for_blob_list(all_blobs.iter(), &self.kzg)?; } let all_data_columns = blocks @@ -415,11 +396,7 @@ impl DataAvailabilityChecker { // verify kzg for all data columns at once if !all_data_columns.is_empty() { - let kzg = self - .kzg - .as_ref() - .ok_or(AvailabilityCheckError::KzgNotInitialized)?; - verify_kzg_for_data_column_list(all_data_columns.iter(), kzg)?; + verify_kzg_for_data_column_list(all_data_columns.iter(), &self.kzg)?; } for block in blocks { diff --git a/beacon_node/beacon_chain/src/data_availability_checker/error.rs b/beacon_node/beacon_chain/src/data_availability_checker/error.rs index 79793d6dc29..7f34cacefe3 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker/error.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker/error.rs @@ -4,7 +4,6 @@ use types::{BeaconStateError, Hash256}; #[derive(Debug)] pub enum Error { Kzg(KzgError), - KzgNotInitialized, KzgVerificationFailed, KzgCommitmentMismatch { blob_commitment: KzgCommitment, @@ -36,8 +35,7 @@ pub enum ErrorCategory { impl Error { pub fn category(&self) -> ErrorCategory { match self { - Error::KzgNotInitialized - | Error::SszTypes(_) + Error::SszTypes(_) | Error::MissingBlobs | Error::MissingCustodyColumns | Error::StoreError(_) diff --git a/beacon_node/beacon_chain/src/data_column_verification.rs b/beacon_node/beacon_chain/src/data_column_verification.rs index f4a5feaee2a..1647f190cfa 100644 --- a/beacon_node/beacon_chain/src/data_column_verification.rs +++ b/beacon_node/beacon_chain/src/data_column_verification.rs @@ -52,12 +52,6 @@ pub enum GossipDataColumnError { data_column_slot: Slot, parent_slot: Slot, }, - /// `Kzg` struct hasn't been initialized. This is an internal error. - /// - /// ## Peer scoring - /// - /// The peer isn't faulty, This is an internal error. - KzgNotInitialized, /// The kzg verification failed. /// /// ## Peer scoring @@ -382,12 +376,8 @@ pub fn validate_data_column_sidecar_for_gossip( let parent_block = verify_parent_block_and_finalized_descendant(data_column.clone(), chain)?; verify_slot_higher_than_parent(&parent_block, column_slot)?; verify_proposer_and_signature(&data_column, &parent_block, chain)?; - - let kzg = chain - .kzg - .clone() - .ok_or(GossipDataColumnError::KzgNotInitialized)?; - let kzg_verified_data_column = verify_kzg_for_data_column(data_column.clone(), &kzg) + let kzg = &chain.kzg; + let kzg_verified_data_column = verify_kzg_for_data_column(data_column.clone(), kzg) .map_err(GossipDataColumnError::InvalidKzgProof)?; chain diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 994ac79af7e..8a317ce7549 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -291,7 +291,6 @@ pub enum BlockProductionError { TokioJoin(JoinError), BeaconChain(BeaconChainError), InvalidPayloadFork, - TrustedSetupNotInitialized, InvalidBlockVariant(String), KzgError(kzg::Error), FailedToBuildBlobSidecars(String), diff --git a/beacon_node/beacon_chain/src/kzg_utils.rs b/beacon_node/beacon_chain/src/kzg_utils.rs index c2355e6f4f2..91c1098f81f 100644 --- a/beacon_node/beacon_chain/src/kzg_utils.rs +++ b/beacon_node/beacon_chain/src/kzg_utils.rs @@ -290,8 +290,7 @@ pub fn reconstruct_data_columns( mod test { use crate::kzg_utils::{blobs_to_data_column_sidecars, reconstruct_data_columns}; use bls::Signature; - use eth2_network_config::TRUSTED_SETUP_BYTES; - use kzg::{Kzg, KzgCommitment, TrustedSetup}; + use kzg::{trusted_setup::get_trusted_setup, Kzg, KzgCommitment, TrustedSetup}; use types::{ beacon_block_body::KzgCommitments, BeaconBlock, BeaconBlockDeneb, Blob, BlobsList, ChainSpec, EmptyBlock, EthSpec, MainnetEthSpec, SignedBeaconBlock, @@ -377,7 +376,7 @@ mod test { } fn get_kzg() -> Kzg { - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice()) .map_err(|e| format!("Unable to read trusted setup file: {}", e)) .expect("should have trusted setup"); Kzg::new_from_trusted_setup_das_enabled(trusted_setup).expect("should create kzg") diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 14028104914..8261500fba1 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -18,7 +18,6 @@ use crate::{ }; use bls::get_withdrawal_credentials; use eth2::types::SignedBlockContentsTuple; -use eth2_network_config::TRUSTED_SETUP_BYTES; use execution_layer::test_utils::generate_genesis_header; use execution_layer::{ auth::JwtKey, @@ -31,6 +30,7 @@ use execution_layer::{ use futures::channel::mpsc::Receiver; pub use genesis::{interop_genesis_state_with_eth1, DEFAULT_ETH1_BLOCK_HASH}; use int_to_bytes::int_to_bytes32; +use kzg::trusted_setup::get_trusted_setup; use kzg::{Kzg, TrustedSetup}; use merkle_proof::MerkleTree; use operation_pool::ReceivedPreCapella; @@ -75,22 +75,40 @@ pub const FORK_NAME_ENV_VAR: &str = "FORK_NAME"; // a different value. pub const DEFAULT_TARGET_AGGREGATORS: u64 = u64::MAX; -pub static KZG: LazyLock> = LazyLock::new(|| { - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) +static KZG: LazyLock> = LazyLock::new(|| { + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice()) .map_err(|e| format!("Unable to read trusted setup file: {}", e)) .expect("should have trusted setup"); let kzg = Kzg::new_from_trusted_setup(trusted_setup).expect("should create kzg"); Arc::new(kzg) }); -pub static KZG_PEERDAS: LazyLock> = LazyLock::new(|| { - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) +static KZG_PEERDAS: LazyLock> = LazyLock::new(|| { + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice()) .map_err(|e| format!("Unable to read trusted setup file: {}", e)) .expect("should have trusted setup"); let kzg = Kzg::new_from_trusted_setup_das_enabled(trusted_setup).expect("should create kzg"); Arc::new(kzg) }); +static KZG_NO_PRECOMP: LazyLock> = LazyLock::new(|| { + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice()) + .map_err(|e| format!("Unable to read trusted setup file: {}", e)) + .expect("should have trusted setup"); + let kzg = Kzg::new_from_trusted_setup_no_precomp(trusted_setup).expect("should create kzg"); + Arc::new(kzg) +}); + +pub fn get_kzg(spec: &ChainSpec) -> Arc { + if spec.eip7594_fork_epoch.is_some() { + KZG_PEERDAS.clone() + } else if spec.deneb_fork_epoch.is_some() { + KZG.clone() + } else { + KZG_NO_PRECOMP.clone() + } +} + pub type BaseHarnessType = Witness, E, THotStore, TColdStore>; @@ -522,12 +540,13 @@ where let validator_keypairs = self .validator_keypairs .expect("cannot build without validator keypairs"); - let kzg = spec.deneb_fork_epoch.map(|_| KZG.clone()); + + let kzg = get_kzg(&spec); let validator_monitor_config = self.validator_monitor_config.unwrap_or_default(); let chain_config = self.chain_config.unwrap_or_default(); - let mut builder = BeaconChainBuilder::new(self.eth_spec_instance) + let mut builder = BeaconChainBuilder::new(self.eth_spec_instance, kzg.clone()) .logger(log.clone()) .custom_spec(spec.clone()) .store(self.store.expect("cannot build without store")) @@ -546,8 +565,7 @@ where log.clone(), 5, ))) - .validator_monitor_config(validator_monitor_config) - .kzg(kzg); + .validator_monitor_config(validator_monitor_config); builder = if let Some(mutator) = self.initial_mutator { mutator(builder) @@ -602,7 +620,7 @@ pub fn mock_execution_layer_from_parts( HARNESS_GENESIS_TIME + spec.seconds_per_slot * E::slots_per_epoch() * epoch.as_u64() }); - let kzg_opt = spec.deneb_fork_epoch.map(|_| KZG.clone()); + let kzg = get_kzg(spec); MockExecutionLayer::new( task_executor, @@ -612,7 +630,7 @@ pub fn mock_execution_layer_from_parts( prague_time, Some(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap()), spec.clone(), - kzg_opt, + Some(kzg), ) } @@ -2842,9 +2860,10 @@ pub fn generate_rand_block_and_data_columns( SignedBeaconBlock>, Vec>>, ) { + let kzg = get_kzg(spec); let (block, blobs) = generate_rand_block_and_blobs(fork_name, num_blobs, rng); let blob: BlobsList = blobs.into_iter().map(|b| b.blob).collect::>().into(); - let data_columns = blobs_to_data_column_sidecars(&blob, &block, &KZG_PEERDAS, spec).unwrap(); + let data_columns = blobs_to_data_column_sidecars(&blob, &block, &kzg, spec).unwrap(); (block, data_columns) } diff --git a/beacon_node/beacon_chain/tests/events.rs b/beacon_node/beacon_chain/tests/events.rs index 1261e2d53ea..b8d4a7722a4 100644 --- a/beacon_node/beacon_chain/tests/events.rs +++ b/beacon_node/beacon_chain/tests/events.rs @@ -25,7 +25,7 @@ async fn blob_sidecar_event_on_process_gossip_blob() { let mut blob_event_receiver = event_handler.subscribe_blob_sidecar(); // build and process a gossip verified blob - let kzg = harness.chain.kzg.as_ref().unwrap(); + let kzg = harness.chain.kzg.as_ref(); let mut rng = StdRng::seed_from_u64(0xDEADBEEF0BAD5EEDu64); let sidecar = BlobSidecar::random_valid(&mut rng, kzg) .map(Arc::new) @@ -59,7 +59,7 @@ async fn blob_sidecar_event_on_process_rpc_blobs() { let mut blob_event_receiver = event_handler.subscribe_blob_sidecar(); // build and process multiple rpc blobs - let kzg = harness.chain.kzg.as_ref().unwrap(); + let kzg = harness.chain.kzg.as_ref(); let mut rng = StdRng::seed_from_u64(0xDEADBEEF0BAD5EEDu64); let mut blob_1 = BlobSidecar::random_valid(&mut rng, kzg).unwrap(); diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index 1b1e5ea5149..541abaa4247 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -7,8 +7,8 @@ use beacon_chain::data_availability_checker::AvailableBlock; use beacon_chain::schema_change::migrate_schema; use beacon_chain::test_utils::SyncCommitteeStrategy; use beacon_chain::test_utils::{ - mock_execution_layer_from_parts, test_spec, AttestationStrategy, BeaconChainHarness, - BlockStrategy, DiskHarnessType, KZG, + get_kzg, mock_execution_layer_from_parts, test_spec, AttestationStrategy, BeaconChainHarness, + BlockStrategy, DiskHarnessType, }; use beacon_chain::{ data_availability_checker::MaybeAvailableBlock, historical_blocks::HistoricalBlockError, @@ -164,7 +164,7 @@ async fn light_client_bootstrap_test() { .unwrap() .unwrap(); - let kzg = spec.deneb_fork_epoch.map(|_| KZG.clone()); + let kzg = get_kzg(&spec); let mock = mock_execution_layer_from_parts(&harness.spec, harness.runtime.task_executor.clone()); @@ -180,7 +180,7 @@ async fn light_client_bootstrap_test() { let (shutdown_tx, _shutdown_rx) = futures::channel::mpsc::channel(1); - let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec) + let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec, kzg) .store(store.clone()) .custom_spec(test_spec::()) .task_executor(harness.chain.task_executor.clone()) @@ -203,7 +203,6 @@ async fn light_client_bootstrap_test() { 1, ))) .execution_layer(Some(mock.el)) - .kzg(kzg) .build() .expect("should build"); @@ -299,7 +298,7 @@ async fn light_client_updates_test() { .unwrap() .unwrap(); - let kzg = spec.deneb_fork_epoch.map(|_| KZG.clone()); + let kzg = get_kzg(&spec); let mock = mock_execution_layer_from_parts(&harness.spec, harness.runtime.task_executor.clone()); @@ -324,7 +323,7 @@ async fn light_client_updates_test() { let (shutdown_tx, _shutdown_rx) = futures::channel::mpsc::channel(1); - let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec) + let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec, kzg) .store(store.clone()) .custom_spec(test_spec::()) .task_executor(harness.chain.task_executor.clone()) @@ -347,7 +346,6 @@ async fn light_client_updates_test() { 1, ))) .execution_layer(Some(mock.el)) - .kzg(kzg) .build() .expect("should build"); @@ -2680,7 +2678,8 @@ async fn weak_subjectivity_sync_test(slots: Vec, checkpoint_slot: Slot) { let store = get_store(&temp2); let spec = test_spec::(); let seconds_per_slot = spec.seconds_per_slot; - let kzg = spec.deneb_fork_epoch.map(|_| KZG.clone()); + + let kzg = get_kzg(&spec); let mock = mock_execution_layer_from_parts(&harness.spec, harness.runtime.task_executor.clone()); @@ -2694,7 +2693,7 @@ async fn weak_subjectivity_sync_test(slots: Vec, checkpoint_slot: Slot) { ); slot_clock.set_slot(harness.get_current_slot().as_u64()); - let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec) + let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec, kzg) .store(store.clone()) .custom_spec(test_spec::()) .task_executor(harness.chain.task_executor.clone()) @@ -2717,7 +2716,6 @@ async fn weak_subjectivity_sync_test(slots: Vec, checkpoint_slot: Slot) { 1, ))) .execution_layer(Some(mock.el)) - .kzg(kzg) .build() .expect("should build"); diff --git a/beacon_node/client/Cargo.toml b/beacon_node/client/Cargo.toml index 88ae650e729..06f7763c8a4 100644 --- a/beacon_node/client/Cargo.toml +++ b/beacon_node/client/Cargo.toml @@ -20,6 +20,7 @@ types = { workspace = true } eth2_config = { workspace = true } slot_clock = { workspace = true } serde = { workspace = true } +serde_json = { workspace = true } error-chain = { workspace = true } slog = { workspace = true } tokio = { workspace = true } @@ -27,6 +28,7 @@ futures = { workspace = true } dirs = { workspace = true } eth1 = { workspace = true } eth2 = { workspace = true } +kzg = { workspace = true } sensitive_url = { workspace = true } genesis = { workspace = true } task_executor = { workspace = true } diff --git a/beacon_node/client/src/builder.rs b/beacon_node/client/src/builder.rs index d299eebec8e..f64ab7200fd 100644 --- a/beacon_node/client/src/builder.rs +++ b/beacon_node/client/src/builder.rs @@ -195,7 +195,17 @@ where None }; - let builder = BeaconChainBuilder::new(eth_spec_instance) + let kzg_err_msg = |e| format!("Failed to load trusted setup: {:?}", e); + let trusted_setup = config.trusted_setup.clone(); + let kzg = if spec.is_peer_das_scheduled() { + Kzg::new_from_trusted_setup_das_enabled(trusted_setup).map_err(kzg_err_msg)? + } else if spec.deneb_fork_epoch.is_some() { + Kzg::new_from_trusted_setup(trusted_setup).map_err(kzg_err_msg)? + } else { + Kzg::new_from_trusted_setup_no_precomp(trusted_setup).map_err(kzg_err_msg)? + }; + + let builder = BeaconChainBuilder::new(eth_spec_instance, Arc::new(kzg)) .logger(context.log().clone()) .store(store) .task_executor(context.executor.clone()) @@ -623,20 +633,6 @@ where ClientGenesis::FromStore => builder.resume_from_db().map(|v| (v, None))?, }; - let beacon_chain_builder = if let Some(trusted_setup) = config.trusted_setup { - let kzg_err_msg = |e| format!("Failed to load trusted setup: {:?}", e); - - let kzg = if spec.is_peer_das_scheduled() { - Kzg::new_from_trusted_setup_das_enabled(trusted_setup).map_err(kzg_err_msg)? - } else { - Kzg::new_from_trusted_setup(trusted_setup).map_err(kzg_err_msg)? - }; - - beacon_chain_builder.kzg(Some(Arc::new(kzg))) - } else { - beacon_chain_builder - }; - if config.sync_eth1_chain { self.eth1_service = eth1_service_option; } diff --git a/beacon_node/client/src/config.rs b/beacon_node/client/src/config.rs index 16000374b22..a25216ff3ec 100644 --- a/beacon_node/client/src/config.rs +++ b/beacon_node/client/src/config.rs @@ -4,6 +4,7 @@ use beacon_chain::TrustedSetup; use beacon_processor::BeaconProcessorConfig; use directory::DEFAULT_ROOT_DIR; use environment::LoggerConfig; +use kzg::trusted_setup::get_trusted_setup; use network::NetworkConfig; use sensitive_url::SensitiveUrl; use serde::{Deserialize, Serialize}; @@ -75,7 +76,7 @@ pub struct Config { pub chain: beacon_chain::ChainConfig, pub eth1: eth1::Config, pub execution_layer: Option, - pub trusted_setup: Option, + pub trusted_setup: TrustedSetup, pub http_api: http_api::Config, pub http_metrics: http_metrics::Config, pub monitoring_api: Option, @@ -89,6 +90,9 @@ pub struct Config { impl Default for Config { fn default() -> Self { + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice()) + .expect("Unable to read trusted setup file"); + Self { data_dir: PathBuf::from(DEFAULT_ROOT_DIR), db_name: "chain_db".to_string(), @@ -103,7 +107,7 @@ impl Default for Config { sync_eth1_chain: false, eth1: <_>::default(), execution_layer: None, - trusted_setup: None, + trusted_setup, beacon_graffiti: GraffitiOrigin::default(), http_api: <_>::default(), http_metrics: <_>::default(), diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index 6094e0d6960..a5960744f5c 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -862,8 +862,7 @@ pub fn generate_pow_block( #[cfg(test)] mod test { use super::*; - use eth2_network_config::TRUSTED_SETUP_BYTES; - use kzg::TrustedSetup; + use kzg::{trusted_setup::get_trusted_setup, TrustedSetup}; use types::{MainnetEthSpec, MinimalEthSpec}; #[test] @@ -951,8 +950,9 @@ mod test { } fn load_kzg() -> Result { - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) - .map_err(|e| format!("Unable to read trusted setup file: {e:?}"))?; + let trusted_setup: TrustedSetup = + serde_json::from_reader(get_trusted_setup().as_slice()) + .map_err(|e| format!("Unable to read trusted setup file: {e:?}"))?; Kzg::new_from_trusted_setup(trusted_setup) .map_err(|e| format!("Failed to load trusted setup: {e:?}")) } diff --git a/beacon_node/network/Cargo.toml b/beacon_node/network/Cargo.toml index 6a81eb33f08..fed346127f0 100644 --- a/beacon_node/network/Cargo.toml +++ b/beacon_node/network/Cargo.toml @@ -8,10 +8,13 @@ edition = { workspace = true } sloggers = { workspace = true } genesis = { workspace = true } matches = "0.1.8" +serde_json = { workspace = true } slog-term = { workspace = true } slog-async = { workspace = true } eth2 = { workspace = true } gossipsub = { workspace = true } +eth2_network_config = { workspace = true } +kzg = { workspace = true } [dependencies] alloy-primitives = { workspace = true } diff --git a/beacon_node/network/src/network_beacon_processor/gossip_methods.rs b/beacon_node/network/src/network_beacon_processor/gossip_methods.rs index 62f1371c811..ddcd74d20b5 100644 --- a/beacon_node/network/src/network_beacon_processor/gossip_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/gossip_methods.rs @@ -696,8 +696,7 @@ impl NetworkBeaconProcessor { column_sidecar, )); } - GossipDataColumnError::KzgNotInitialized - | GossipDataColumnError::PubkeyCacheTimeout + GossipDataColumnError::PubkeyCacheTimeout | GossipDataColumnError::BeaconChainError(_) => { crit!( self.log, @@ -839,9 +838,7 @@ impl NetworkBeaconProcessor { blob_sidecar, )); } - GossipBlobError::KzgNotInitialized - | GossipBlobError::PubkeyCacheTimeout - | GossipBlobError::BeaconChainError(_) => { + GossipBlobError::PubkeyCacheTimeout | GossipBlobError::BeaconChainError(_) => { crit!( self.log, "Internal error when verifying blob sidecar"; diff --git a/beacon_node/network/src/network_beacon_processor/sync_methods.rs b/beacon_node/network/src/network_beacon_processor/sync_methods.rs index c21054dab50..50c7ee05a17 100644 --- a/beacon_node/network/src/network_beacon_processor/sync_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/sync_methods.rs @@ -385,8 +385,8 @@ impl NetworkBeaconProcessor { data_columns: Vec>>, _seen_timestamp: Duration, ) -> Result<(), String> { - let kzg = self.chain.kzg.as_ref().ok_or("Kzg not initialized")?; - verify_kzg_for_data_column_list(data_columns.iter(), kzg).map_err(|err| format!("{err:?}")) + verify_kzg_for_data_column_list(data_columns.iter(), &self.chain.kzg) + .map_err(|err| format!("{err:?}")) } /// Process a sampling completed event, inserting it into fork-choice @@ -561,8 +561,7 @@ impl NetworkBeaconProcessor { }) .collect::>(), Err(e) => match e { - AvailabilityCheckError::StoreError(_) - | AvailabilityCheckError::KzgNotInitialized => { + AvailabilityCheckError::StoreError(_) => { return ( 0, Err(ChainSegmentFailed { diff --git a/beacon_node/network/src/subnet_service/tests/mod.rs b/beacon_node/network/src/subnet_service/tests/mod.rs index e8d9218ec4c..3ee7c7f7680 100644 --- a/beacon_node/network/src/subnet_service/tests/mod.rs +++ b/beacon_node/network/src/subnet_service/tests/mod.rs @@ -2,6 +2,7 @@ use super::*; use beacon_chain::{ builder::{BeaconChainBuilder, Witness}, eth1_chain::CachingEth1Backend, + test_utils::get_kzg, BeaconChain, }; use futures::prelude::*; @@ -45,12 +46,14 @@ impl TestBeaconChain { let store = HotColdDB::open_ephemeral(StoreConfig::default(), spec.clone(), log.clone()).unwrap(); + let kzg = get_kzg(&spec); + let (shutdown_tx, _) = futures::channel::mpsc::channel(1); let test_runtime = TestRuntime::default(); let chain = Arc::new( - BeaconChainBuilder::new(MainnetEthSpec) + BeaconChainBuilder::new(MainnetEthSpec, kzg.clone()) .logger(log.clone()) .custom_spec(spec.clone()) .store(Arc::new(store)) diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index 6f61748a2d3..0eff8577c4a 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -396,13 +396,15 @@ pub fn get_config( } // 4844 params - client_config.trusted_setup = context + if let Some(trusted_setup) = context .eth2_network_config .as_ref() - .and_then(|config| config.kzg_trusted_setup.as_ref()) - .map(|trusted_setup_bytes| serde_json::from_slice(trusted_setup_bytes)) + .map(|config| serde_json::from_slice(&config.kzg_trusted_setup)) .transpose() - .map_err(|e| format!("Unable to read trusted setup file: {}", e))?; + .map_err(|e| format!("Unable to read trusted setup file: {}", e))? + { + client_config.trusted_setup = trusted_setup; + }; // Override default trusted setup file if required if let Some(trusted_setup_file_path) = cli_args.get_one::("trusted-setup-file-override") @@ -411,7 +413,7 @@ pub fn get_config( .map_err(|e| format!("Failed to open trusted setup file: {}", e))?; let trusted_setup: TrustedSetup = serde_json::from_reader(file) .map_err(|e| format!("Unable to read trusted setup file: {}", e))?; - client_config.trusted_setup = Some(trusted_setup); + client_config.trusted_setup = trusted_setup; } if let Some(freezer_dir) = cli_args.get_one::("freezer-dir") { diff --git a/common/eth2_network_config/Cargo.toml b/common/eth2_network_config/Cargo.toml index 4b34405e5b3..09cf2072d2f 100644 --- a/common/eth2_network_config/Cargo.toml +++ b/common/eth2_network_config/Cargo.toml @@ -28,3 +28,4 @@ sensitive_url = { workspace = true } slog = { workspace = true } logging = { workspace = true } bytes = { workspace = true } +kzg = { workspace = true } diff --git a/common/eth2_network_config/src/lib.rs b/common/eth2_network_config/src/lib.rs index 472ac55ca09..3d0ffc5b9e8 100644 --- a/common/eth2_network_config/src/lib.rs +++ b/common/eth2_network_config/src/lib.rs @@ -14,6 +14,7 @@ use bytes::Bytes; use discv5::enr::{CombinedKey, Enr}; use eth2_config::{instantiate_hardcoded_nets, HardcodedNet}; +use kzg::trusted_setup::get_trusted_setup; use pretty_reqwest_error::PrettyReqwestError; use reqwest::{Client, Error}; use sensitive_url::SensitiveUrl; @@ -24,7 +25,7 @@ use std::io::{Read, Write}; use std::path::PathBuf; use std::str::FromStr; use std::time::Duration; -use types::{BeaconState, ChainSpec, Config, Epoch, EthSpec, EthSpecId, Hash256}; +use types::{BeaconState, ChainSpec, Config, EthSpec, EthSpecId, Hash256}; use url::Url; pub use eth2_config::GenesisStateSource; @@ -43,26 +44,6 @@ instantiate_hardcoded_nets!(eth2_config); pub const DEFAULT_HARDCODED_NETWORK: &str = "mainnet"; -/// Contains the bytes from the trusted setup json. -/// The mainnet trusted setup is also reused in testnets. -/// -/// This is done to ensure that testnets also inherit the high security and -/// randomness of the mainnet kzg trusted setup ceremony. -/// -/// Note: The trusted setup for both mainnet and minimal presets are the same. -pub const TRUSTED_SETUP_BYTES: &[u8] = - include_bytes!("../built_in_network_configs/trusted_setup.json"); - -/// Returns `Some(TrustedSetup)` if the deneb fork epoch is set and `None` otherwise. -/// -/// Returns an error if the trusted setup parsing failed. -fn get_trusted_setup_from_config(config: &Config) -> Option> { - config - .deneb_fork_epoch - .filter(|epoch| epoch.value != Epoch::max_value()) - .map(|_| TRUSTED_SETUP_BYTES.to_vec()) -} - /// A simple slice-or-vec enum to avoid cloning the beacon state bytes in the /// binary whilst also supporting loading them from a file at runtime. #[derive(Clone, PartialEq, Debug)] @@ -104,7 +85,7 @@ pub struct Eth2NetworkConfig { pub genesis_state_source: GenesisStateSource, pub genesis_state_bytes: Option, pub config: Config, - pub kzg_trusted_setup: Option>, + pub kzg_trusted_setup: Vec, } impl Eth2NetworkConfig { @@ -122,7 +103,7 @@ impl Eth2NetworkConfig { fn from_hardcoded_net(net: &HardcodedNet) -> Result { let config: Config = serde_yaml::from_reader(net.config) .map_err(|e| format!("Unable to parse yaml config: {:?}", e))?; - let kzg_trusted_setup = get_trusted_setup_from_config(&config); + let kzg_trusted_setup = get_trusted_setup(); Ok(Self { deposit_contract_deploy_block: serde_yaml::from_reader(net.deploy_block) .map_err(|e| format!("Unable to parse deploy block: {:?}", e))?, @@ -359,7 +340,7 @@ impl Eth2NetworkConfig { (None, GenesisStateSource::Unknown) }; - let kzg_trusted_setup = get_trusted_setup_from_config(&config); + let kzg_trusted_setup = get_trusted_setup(); Ok(Self { deposit_contract_deploy_block, @@ -577,7 +558,7 @@ mod tests { GenesisStateSource::Unknown }; // With Deneb enabled by default we must set a trusted setup here. - let kzg_trusted_setup = get_trusted_setup_from_config(&config).unwrap(); + let kzg_trusted_setup = get_trusted_setup(); let testnet = Eth2NetworkConfig { deposit_contract_deploy_block, @@ -588,7 +569,7 @@ mod tests { .map(Encode::as_ssz_bytes) .map(Into::into), config, - kzg_trusted_setup: Some(kzg_trusted_setup), + kzg_trusted_setup, }; testnet diff --git a/crypto/kzg/Cargo.toml b/crypto/kzg/Cargo.toml index e940fe2e20c..ce55f83639b 100644 --- a/crypto/kzg/Cargo.toml +++ b/crypto/kzg/Cargo.toml @@ -18,11 +18,11 @@ hex = { workspace = true } ethereum_hashing = { workspace = true } c-kzg = { workspace = true } rust_eth_kzg = { workspace = true } +serde_json = { workspace = true } [dev-dependencies] criterion = { workspace = true } serde_json = { workspace = true } -eth2_network_config = { workspace = true } [[bench]] name = "benchmark" diff --git a/crypto/kzg/benches/benchmark.rs b/crypto/kzg/benches/benchmark.rs index 35e370cd0fd..50f5f4e7795 100644 --- a/crypto/kzg/benches/benchmark.rs +++ b/crypto/kzg/benches/benchmark.rs @@ -1,11 +1,10 @@ use c_kzg::KzgSettings; use criterion::{criterion_group, criterion_main, Criterion}; -use eth2_network_config::TRUSTED_SETUP_BYTES; -use kzg::TrustedSetup; +use kzg::{trusted_setup::get_trusted_setup, TrustedSetup}; use rust_eth_kzg::{DASContext, TrustedSetup as PeerDASTrustedSetup}; pub fn bench_init_context(c: &mut Criterion) { - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice()) .map_err(|e| format!("Unable to read trusted setup file: {}", e)) .expect("should have trusted setup"); @@ -22,9 +21,10 @@ pub fn bench_init_context(c: &mut Criterion) { }); c.bench_function(&format!("Initialize context c-kzg (4844)"), |b| { b.iter(|| { - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) - .map_err(|e| format!("Unable to read trusted setup file: {}", e)) - .expect("should have trusted setup"); + let trusted_setup: TrustedSetup = + serde_json::from_reader(get_trusted_setup().as_slice()) + .map_err(|e| format!("Unable to read trusted setup file: {}", e)) + .expect("should have trusted setup"); KzgSettings::load_trusted_setup(&trusted_setup.g1_points(), &trusted_setup.g2_points()) .unwrap() }) diff --git a/crypto/kzg/src/lib.rs b/crypto/kzg/src/lib.rs index ebe93934fd7..348ed785af0 100644 --- a/crypto/kzg/src/lib.rs +++ b/crypto/kzg/src/lib.rs @@ -1,6 +1,6 @@ mod kzg_commitment; mod kzg_proof; -mod trusted_setup; +pub mod trusted_setup; use rust_eth_kzg::{CellIndex, DASContext}; use std::fmt::Debug; @@ -51,18 +51,41 @@ impl From for Error { #[derive(Debug)] pub struct Kzg { trusted_setup: KzgSettings, - context: Option, + context: DASContext, } impl Kzg { + pub fn new_from_trusted_setup_no_precomp(trusted_setup: TrustedSetup) -> Result { + let peerdas_trusted_setup = PeerDASTrustedSetup::from(&trusted_setup); + + let context = DASContext::new(&peerdas_trusted_setup, rust_eth_kzg::UsePrecomp::No); + + Ok(Self { + trusted_setup: KzgSettings::load_trusted_setup( + &trusted_setup.g1_points(), + &trusted_setup.g2_points(), + )?, + context, + }) + } + /// Load the kzg trusted setup parameters from a vec of G1 and G2 points. pub fn new_from_trusted_setup(trusted_setup: TrustedSetup) -> Result { + let peerdas_trusted_setup = PeerDASTrustedSetup::from(&trusted_setup); + + let context = DASContext::new( + &peerdas_trusted_setup, + rust_eth_kzg::UsePrecomp::Yes { + width: rust_eth_kzg::constants::RECOMMENDED_PRECOMP_WIDTH, + }, + ); + Ok(Self { trusted_setup: KzgSettings::load_trusted_setup( &trusted_setup.g1_points(), &trusted_setup.g2_points(), )?, - context: None, + context, }) } @@ -88,12 +111,12 @@ impl Kzg { &trusted_setup.g1_points(), &trusted_setup.g2_points(), )?, - context: Some(context), + context, }) } - fn context(&self) -> Result<&DASContext, Error> { - self.context.as_ref().ok_or(Error::DASContextUninitialized) + fn context(&self) -> &DASContext { + &self.context } /// Compute the kzg proof given a blob and its kzg commitment. @@ -200,7 +223,7 @@ impl Kzg { blob: KzgBlobRef<'_>, ) -> Result { let (cells, proofs) = self - .context()? + .context() .compute_cells_and_kzg_proofs(blob) .map_err(Error::PeerDASKZG)?; @@ -226,7 +249,7 @@ impl Kzg { .iter() .map(|commitment| commitment.as_ref()) .collect(); - let verification_result = self.context()?.verify_cell_kzg_proof_batch( + let verification_result = self.context().verify_cell_kzg_proof_batch( commitments.to_vec(), columns, cells.to_vec(), @@ -247,7 +270,7 @@ impl Kzg { cells: &[CellRef<'_>], ) -> Result { let (cells, proofs) = self - .context()? + .context() .recover_cells_and_kzg_proofs(cell_ids.to_vec(), cells.to_vec()) .map_err(Error::PeerDASKZG)?; diff --git a/crypto/kzg/src/trusted_setup.rs b/crypto/kzg/src/trusted_setup.rs index 6ddc33df5ab..f788be265a9 100644 --- a/crypto/kzg/src/trusted_setup.rs +++ b/crypto/kzg/src/trusted_setup.rs @@ -5,6 +5,12 @@ use serde::{ Deserialize, Serialize, }; +pub const TRUSTED_SETUP_BYTES: &[u8] = include_bytes!("../trusted_setup.json"); + +pub fn get_trusted_setup() -> Vec { + TRUSTED_SETUP_BYTES.into() +} + /// Wrapper over a BLS G1 point's byte representation. #[derive(Debug, Clone, PartialEq)] struct G1Point([u8; BYTES_PER_G1_POINT]); diff --git a/common/eth2_network_config/built_in_network_configs/trusted_setup.json b/crypto/kzg/trusted_setup.json similarity index 100% rename from common/eth2_network_config/built_in_network_configs/trusted_setup.json rename to crypto/kzg/trusted_setup.json diff --git a/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs b/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs index f9b3009fded..3dc955bdcc8 100644 --- a/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs +++ b/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs @@ -1,7 +1,7 @@ use super::*; use crate::case_result::compare_result; use beacon_chain::kzg_utils::validate_blob; -use eth2_network_config::TRUSTED_SETUP_BYTES; +use kzg::trusted_setup::get_trusted_setup; use kzg::{Cell, Error as KzgError, Kzg, KzgCommitment, KzgProof, TrustedSetup}; use serde::Deserialize; use std::marker::PhantomData; @@ -10,7 +10,7 @@ use std::sync::LazyLock; use types::Blob; static KZG: LazyLock> = LazyLock::new(|| { - let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES) + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup().as_slice()) .map_err(|e| Error::InternalError(format!("Failed to initialize trusted setup: {:?}", e))) .expect("failed to initialize trusted setup"); let kzg = Kzg::new_from_trusted_setup_das_enabled(trusted_setup) diff --git a/testing/simulator/Cargo.toml b/testing/simulator/Cargo.toml index f8769b10e21..7772523284a 100644 --- a/testing/simulator/Cargo.toml +++ b/testing/simulator/Cargo.toml @@ -19,3 +19,4 @@ rayon = { workspace = true } sensitive_url = { path = "../../common/sensitive_url" } eth2_network_config = { workspace = true } serde_json = { workspace = true } +kzg = { workspace = true } diff --git a/testing/simulator/src/local_network.rs b/testing/simulator/src/local_network.rs index faf3246e0d7..7b9327a7aaa 100644 --- a/testing/simulator/src/local_network.rs +++ b/testing/simulator/src/local_network.rs @@ -1,5 +1,5 @@ use crate::checks::epoch_delay; -use eth2_network_config::TRUSTED_SETUP_BYTES; +use kzg::trusted_setup::get_trusted_setup; use node_test_rig::{ environment::RuntimeContext, eth2::{types::StateId, BeaconNodeHttpClient}, @@ -46,8 +46,8 @@ fn default_client_config(network_params: LocalNetworkParams, genesis_time: u64) beacon_config.chain.enable_light_client_server = true; beacon_config.http_api.enable_light_client_server = true; beacon_config.chain.optimistic_finalized_sync = false; - beacon_config.trusted_setup = - serde_json::from_reader(TRUSTED_SETUP_BYTES).expect("Trusted setup bytes should be valid"); + beacon_config.trusted_setup = serde_json::from_reader(get_trusted_setup().as_slice()) + .expect("Trusted setup bytes should be valid"); let el_config = execution_layer::Config { execution_endpoint: Some(