mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2024-12-22 03:30:38 +00:00
Upgrade to v1.4.0-beta.3 (#4862)
## Issue Addressed Makes lighthouse compliant with new kzg changes in https://github.com/ethereum/consensus-specs/releases/tag/v1.4.0-beta.3 ## Proposed Changes 1. Adds new official trusted setup 2. Refactors kzg to match upstream changes in https://github.com/ethereum/c-kzg-4844/pull/377 3. Updates pre-generated `BlobBundle` to work with official trusted setup. ~~Using json here instead of ssz to account for different value of `MaxBlobCommitmentsPerBlock` in minimal and mainnet. By using json, we can just use one pre generated bundle for both minimal and mainnet. Size of 2 separate ssz bundles is approximately equal to one json bundle cc @jimmygchen~~ Dunno what I was doing, ssz works without any issues 4. Stores trusted_setup as just bytes in eth2_network_config so that we don't have kzg dependency in that lib and in lcli. Co-authored-by: realbigsean <seananderson33@gmail.com> Co-authored-by: realbigsean <seananderson33@GMAIL.com>
This commit is contained in:
parent
074c4951fc
commit
6315a81260
21
Cargo.lock
generated
21
Cargo.lock
generated
@ -874,21 +874,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "c-kzg"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/ethereum//c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d#f5f6f863d475847876a2bd5ee252058d37c3a15d"
|
||||
dependencies = [
|
||||
"bindgen 0.66.1",
|
||||
"blst",
|
||||
"cc",
|
||||
"glob",
|
||||
"hex",
|
||||
"libc",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "c-kzg"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/ethereum/c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d#f5f6f863d475847876a2bd5ee252058d37c3a15d"
|
||||
source = "git+https://github.com/ethereum/c-kzg-4844?rev=748283cced543c486145d5f3f38684becdfe3e1b#748283cced543c486145d5f3f38684becdfe3e1b"
|
||||
dependencies = [
|
||||
"bindgen 0.66.1",
|
||||
"blst",
|
||||
@ -2203,7 +2189,6 @@ dependencies = [
|
||||
"discv5",
|
||||
"eth2_config",
|
||||
"ethereum_ssz",
|
||||
"kzg",
|
||||
"logging",
|
||||
"pretty_reqwest_error",
|
||||
"reqwest",
|
||||
@ -3844,8 +3829,7 @@ name = "kzg"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"c-kzg 0.1.0 (git+https://github.com/ethereum//c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d)",
|
||||
"c-kzg 0.1.0 (git+https://github.com/ethereum/c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d)",
|
||||
"c-kzg",
|
||||
"derivative",
|
||||
"ethereum_hashing",
|
||||
"ethereum_serde_utils",
|
||||
@ -3892,7 +3876,6 @@ dependencies = [
|
||||
"ethereum_ssz",
|
||||
"genesis",
|
||||
"int_to_bytes",
|
||||
"kzg",
|
||||
"lighthouse_network",
|
||||
"lighthouse_version",
|
||||
"log",
|
||||
|
@ -481,7 +481,7 @@ pub struct BeaconChain<T: BeaconChainTypes> {
|
||||
/// they are collected and combined.
|
||||
pub data_availability_checker: Arc<DataAvailabilityChecker<T>>,
|
||||
/// The KZG trusted setup used by this chain.
|
||||
pub kzg: Option<Arc<Kzg<<T::EthSpec as EthSpec>::Kzg>>>,
|
||||
pub kzg: Option<Arc<Kzg>>,
|
||||
}
|
||||
|
||||
type BeaconBlockAndState<T, Payload> = (
|
||||
|
@ -499,7 +499,7 @@ impl<T: EthSpec> KzgVerifiedBlob<T> {
|
||||
/// Returns an error if the kzg verification check fails.
|
||||
pub fn verify_kzg_for_blob<T: EthSpec>(
|
||||
blob: Arc<BlobSidecar<T>>,
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
) -> Result<KzgVerifiedBlob<T>, AvailabilityCheckError> {
|
||||
let _timer = crate::metrics::start_timer(&crate::metrics::KZG_VERIFICATION_SINGLE_TIMES);
|
||||
if validate_blob::<T>(kzg, &blob.blob, blob.kzg_commitment, blob.kzg_proof)
|
||||
@ -518,7 +518,7 @@ pub fn verify_kzg_for_blob<T: EthSpec>(
|
||||
/// in a loop since this function kzg verifies a list of blobs more efficiently.
|
||||
pub fn verify_kzg_for_blob_list<T: EthSpec>(
|
||||
blob_list: &BlobSidecarList<T>,
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
) -> Result<(), AvailabilityCheckError> {
|
||||
let _timer = crate::metrics::start_timer(&crate::metrics::KZG_VERIFICATION_BATCH_TIMES);
|
||||
let (blobs, (commitments, proofs)): (Vec<_>, (Vec<_>, Vec<_>)) = blob_list
|
||||
|
@ -50,7 +50,7 @@ pub struct DataAvailabilityChecker<T: BeaconChainTypes> {
|
||||
processing_cache: RwLock<ProcessingCache<T::EthSpec>>,
|
||||
availability_cache: Arc<OverflowLRUCache<T>>,
|
||||
slot_clock: T::SlotClock,
|
||||
kzg: Option<Arc<Kzg<<T::EthSpec as EthSpec>::Kzg>>>,
|
||||
kzg: Option<Arc<Kzg>>,
|
||||
log: Logger,
|
||||
spec: ChainSpec,
|
||||
}
|
||||
@ -79,7 +79,7 @@ impl<T: EthSpec> Debug for Availability<T> {
|
||||
impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
pub fn new(
|
||||
slot_clock: T::SlotClock,
|
||||
kzg: Option<Arc<Kzg<<T::EthSpec as EthSpec>::Kzg>>>,
|
||||
kzg: Option<Arc<Kzg>>,
|
||||
store: BeaconStore<T>,
|
||||
log: &Logger,
|
||||
spec: ChainSpec,
|
||||
|
@ -970,6 +970,7 @@ mod test {
|
||||
) -> (
|
||||
BeaconChainHarness<DiskHarnessType<E>>,
|
||||
Arc<OverflowLRUCache<T>>,
|
||||
TempDir,
|
||||
)
|
||||
where
|
||||
E: EthSpec,
|
||||
@ -984,7 +985,7 @@ mod test {
|
||||
OverflowLRUCache::<T>::new(capacity, test_store, spec.clone())
|
||||
.expect("should create cache"),
|
||||
);
|
||||
(harness, cache)
|
||||
(harness, cache, chain_db_path)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -992,7 +993,7 @@ mod test {
|
||||
type E = MinimalEthSpec;
|
||||
type T = DiskHarnessType<E>;
|
||||
let capacity = 4;
|
||||
let (harness, cache) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
let (harness, cache, _path) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
|
||||
let (pending_block, blobs) = availability_pending_block(&harness).await;
|
||||
let root = pending_block.import_data.block_root;
|
||||
@ -1104,7 +1105,7 @@ mod test {
|
||||
type E = MinimalEthSpec;
|
||||
type T = DiskHarnessType<E>;
|
||||
let capacity = 4;
|
||||
let (harness, cache) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
let (harness, cache, _path) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
|
||||
let mut pending_blocks = VecDeque::new();
|
||||
let mut pending_blobs = VecDeque::new();
|
||||
@ -1255,7 +1256,7 @@ mod test {
|
||||
type E = MinimalEthSpec;
|
||||
type T = DiskHarnessType<E>;
|
||||
let capacity = E::slots_per_epoch() as usize;
|
||||
let (harness, cache) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
let (harness, cache, _path) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
|
||||
let n_epochs = 4;
|
||||
let mut pending_blocks = VecDeque::new();
|
||||
@ -1395,7 +1396,7 @@ mod test {
|
||||
type E = MinimalEthSpec;
|
||||
type T = DiskHarnessType<E>;
|
||||
let capacity = E::slots_per_epoch() as usize;
|
||||
let (harness, cache) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
let (harness, cache, _path) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
|
||||
let n_epochs = 4;
|
||||
let mut pending_blocks = VecDeque::new();
|
||||
@ -1573,7 +1574,7 @@ mod test {
|
||||
type E = MinimalEthSpec;
|
||||
type T = DiskHarnessType<E>;
|
||||
let capacity = STATE_LRU_CAPACITY * 2;
|
||||
let (harness, cache) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
let (harness, cache, _path) = setup_harness_and_cache::<E, T>(capacity).await;
|
||||
|
||||
let mut pending_blocks = VecDeque::new();
|
||||
let mut states = Vec::new();
|
||||
|
@ -1,31 +1,26 @@
|
||||
use kzg::{Error as KzgError, Kzg, KzgPreset};
|
||||
use kzg::{Blob as KzgBlob, Error as KzgError, Kzg};
|
||||
use types::{Blob, EthSpec, Hash256, KzgCommitment, KzgProof};
|
||||
|
||||
/// Converts a blob ssz List object to an array to be used with the kzg
|
||||
/// crypto library.
|
||||
fn ssz_blob_to_crypto_blob<T: EthSpec>(
|
||||
blob: &Blob<T>,
|
||||
) -> Result<<<T as EthSpec>::Kzg as KzgPreset>::Blob, KzgError> {
|
||||
T::blob_from_bytes(blob.as_ref())
|
||||
fn ssz_blob_to_crypto_blob<T: EthSpec>(blob: &Blob<T>) -> Result<KzgBlob, KzgError> {
|
||||
KzgBlob::from_bytes(blob.as_ref())
|
||||
}
|
||||
|
||||
/// Validate a single blob-commitment-proof triplet from a `BlobSidecar`.
|
||||
pub fn validate_blob<T: EthSpec>(
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
blob: &Blob<T>,
|
||||
kzg_commitment: KzgCommitment,
|
||||
kzg_proof: KzgProof,
|
||||
) -> Result<bool, KzgError> {
|
||||
kzg.verify_blob_kzg_proof(
|
||||
&ssz_blob_to_crypto_blob::<T>(blob)?,
|
||||
kzg_commitment,
|
||||
kzg_proof,
|
||||
)
|
||||
let kzg_blob = ssz_blob_to_crypto_blob::<T>(blob)?;
|
||||
kzg.verify_blob_kzg_proof(&kzg_blob, kzg_commitment, kzg_proof)
|
||||
}
|
||||
|
||||
/// Validate a batch of blob-commitment-proof triplets from multiple `BlobSidecars`.
|
||||
pub fn validate_blobs<T: EthSpec>(
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
expected_kzg_commitments: &[KzgCommitment],
|
||||
blobs: Vec<&Blob<T>>,
|
||||
kzg_proofs: &[KzgProof],
|
||||
@ -40,36 +35,38 @@ pub fn validate_blobs<T: EthSpec>(
|
||||
|
||||
/// Compute the kzg proof given an ssz blob and its kzg commitment.
|
||||
pub fn compute_blob_kzg_proof<T: EthSpec>(
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
blob: &Blob<T>,
|
||||
kzg_commitment: KzgCommitment,
|
||||
) -> Result<KzgProof, KzgError> {
|
||||
// Avoid this blob clone
|
||||
kzg.compute_blob_kzg_proof(&ssz_blob_to_crypto_blob::<T>(blob)?, kzg_commitment)
|
||||
let kzg_blob = ssz_blob_to_crypto_blob::<T>(blob)?;
|
||||
kzg.compute_blob_kzg_proof(&kzg_blob, kzg_commitment)
|
||||
}
|
||||
|
||||
/// Compute the kzg commitment for a given blob.
|
||||
pub fn blob_to_kzg_commitment<T: EthSpec>(
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
blob: &Blob<T>,
|
||||
) -> Result<KzgCommitment, KzgError> {
|
||||
kzg.blob_to_kzg_commitment(&ssz_blob_to_crypto_blob::<T>(blob)?)
|
||||
let kzg_blob = ssz_blob_to_crypto_blob::<T>(blob)?;
|
||||
kzg.blob_to_kzg_commitment(&kzg_blob)
|
||||
}
|
||||
|
||||
/// Compute the kzg proof for a given blob and an evaluation point z.
|
||||
pub fn compute_kzg_proof<T: EthSpec>(
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
blob: &Blob<T>,
|
||||
z: Hash256,
|
||||
) -> Result<(KzgProof, Hash256), KzgError> {
|
||||
let z = z.0.into();
|
||||
kzg.compute_kzg_proof(&ssz_blob_to_crypto_blob::<T>(blob)?, &z)
|
||||
let kzg_blob = ssz_blob_to_crypto_blob::<T>(blob)?;
|
||||
kzg.compute_kzg_proof(&kzg_blob, &z)
|
||||
.map(|(proof, z)| (proof, Hash256::from_slice(&z.to_vec())))
|
||||
}
|
||||
|
||||
/// Verify a `kzg_proof` for a `kzg_commitment` that evaluating a polynomial at `z` results in `y`
|
||||
pub fn verify_kzg_proof<T: EthSpec>(
|
||||
kzg: &Kzg<T::Kzg>,
|
||||
kzg: &Kzg,
|
||||
kzg_commitment: KzgCommitment,
|
||||
kzg_proof: KzgProof,
|
||||
z: Hash256,
|
||||
|
@ -16,6 +16,7 @@ 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,
|
||||
@ -492,10 +493,9 @@ where
|
||||
.validator_keypairs
|
||||
.expect("cannot build without validator keypairs");
|
||||
let chain_config = self.chain_config.unwrap_or_default();
|
||||
let trusted_setup: TrustedSetup =
|
||||
serde_json::from_reader(eth2_network_config::get_trusted_setup::<E::Kzg>())
|
||||
.map_err(|e| format!("Unable to read trusted setup file: {}", e))
|
||||
.unwrap();
|
||||
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES)
|
||||
.map_err(|e| format!("Unable to read trusted setup file: {}", e))
|
||||
.unwrap();
|
||||
|
||||
let mut builder = BeaconChainBuilder::new(self.eth_spec_instance)
|
||||
.logger(log.clone())
|
||||
@ -571,10 +571,9 @@ pub fn mock_execution_layer_from_parts<T: EthSpec>(
|
||||
HARNESS_GENESIS_TIME + spec.seconds_per_slot * T::slots_per_epoch() * epoch.as_u64()
|
||||
});
|
||||
|
||||
let trusted_setup: TrustedSetup =
|
||||
serde_json::from_reader(eth2_network_config::get_trusted_setup::<T::Kzg>())
|
||||
.map_err(|e| format!("Unable to read trusted setup file: {}", e))
|
||||
.expect("should have trusted setup");
|
||||
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 = Kzg::new_from_trusted_setup(trusted_setup).expect("should create kzg");
|
||||
|
||||
MockExecutionLayer::new(
|
||||
|
@ -14,7 +14,7 @@ use beacon_chain::{
|
||||
migrate::MigratorConfig, BeaconChain, BeaconChainError, BeaconChainTypes, BeaconSnapshot,
|
||||
BlockError, ChainConfig, NotifyExecutionLayer, ServerSentEventHandler, WhenSlotSkipped,
|
||||
};
|
||||
use eth2_network_config::get_trusted_setup;
|
||||
use eth2_network_config::TRUSTED_SETUP_BYTES;
|
||||
use kzg::TrustedSetup;
|
||||
use lazy_static::lazy_static;
|
||||
use logging::test_logger;
|
||||
@ -2154,10 +2154,9 @@ async fn weak_subjectivity_sync_test(slots: Vec<Slot>, checkpoint_slot: Slot) {
|
||||
let store = get_store(&temp2);
|
||||
let spec = test_spec::<E>();
|
||||
let seconds_per_slot = spec.seconds_per_slot;
|
||||
let trusted_setup: TrustedSetup =
|
||||
serde_json::from_reader(get_trusted_setup::<<E as EthSpec>::Kzg>())
|
||||
.map_err(|e| println!("Unable to read trusted setup file: {}", e))
|
||||
.unwrap();
|
||||
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES)
|
||||
.map_err(|e| println!("Unable to read trusted setup file: {}", e))
|
||||
.unwrap();
|
||||
|
||||
let mock =
|
||||
mock_execution_layer_from_parts(&harness.spec, harness.runtime.task_executor.clone(), None);
|
||||
|
@ -14,22 +14,21 @@ use kzg::{Kzg, KzgCommitment, KzgProof};
|
||||
use parking_lot::Mutex;
|
||||
use rand::{rngs::StdRng, Rng, SeedableRng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Decode;
|
||||
use ssz_types::VariableList;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
use types::{
|
||||
Blob, ChainSpec, EthSpec, EthSpecId, ExecutionBlockHash, ExecutionPayload,
|
||||
ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadHeader, ExecutionPayloadMerge,
|
||||
ForkName, Hash256, Transaction, Transactions, Uint256,
|
||||
Blob, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadCapella,
|
||||
ExecutionPayloadDeneb, ExecutionPayloadHeader, ExecutionPayloadMerge, ForkName, Hash256,
|
||||
Transaction, Transactions, Uint256,
|
||||
};
|
||||
|
||||
use super::DEFAULT_TERMINAL_BLOCK;
|
||||
use ssz::Decode;
|
||||
|
||||
const TEST_BLOB_BUNDLE_MAINNET: &[u8] = include_bytes!("fixtures/mainnet/test_blobs_bundle.ssz");
|
||||
const TEST_BLOB_BUNDLE_MINIMAL: &[u8] = include_bytes!("fixtures/minimal/test_blobs_bundle.ssz");
|
||||
const TEST_BLOB_BUNDLE: &[u8] = include_bytes!("fixtures/mainnet/test_blobs_bundle.ssz");
|
||||
|
||||
const GAS_LIMIT: u64 = 16384;
|
||||
const GAS_USED: u64 = GAS_LIMIT - 1;
|
||||
@ -137,7 +136,7 @@ pub struct ExecutionBlockGenerator<T: EthSpec> {
|
||||
* deneb stuff
|
||||
*/
|
||||
pub blobs_bundles: HashMap<PayloadId, BlobsBundle<T>>,
|
||||
pub kzg: Option<Arc<Kzg<T::Kzg>>>,
|
||||
pub kzg: Option<Arc<Kzg>>,
|
||||
rng: Arc<Mutex<StdRng>>,
|
||||
}
|
||||
|
||||
@ -154,7 +153,7 @@ impl<T: EthSpec> ExecutionBlockGenerator<T> {
|
||||
terminal_block_hash: ExecutionBlockHash,
|
||||
shanghai_time: Option<u64>,
|
||||
cancun_time: Option<u64>,
|
||||
kzg: Option<Kzg<T::Kzg>>,
|
||||
kzg: Option<Kzg>,
|
||||
) -> Self {
|
||||
let mut gen = Self {
|
||||
head_block: <_>::default(),
|
||||
@ -649,20 +648,12 @@ impl<T: EthSpec> ExecutionBlockGenerator<T> {
|
||||
}
|
||||
|
||||
pub fn load_test_blobs_bundle<E: EthSpec>() -> Result<(KzgCommitment, KzgProof, Blob<E>), String> {
|
||||
let blob_bundle_bytes = match E::spec_name() {
|
||||
EthSpecId::Mainnet => TEST_BLOB_BUNDLE_MAINNET,
|
||||
EthSpecId::Minimal => TEST_BLOB_BUNDLE_MINIMAL,
|
||||
EthSpecId::Gnosis => {
|
||||
return Err("Test blobs bundle not available for Gnosis preset".to_string())
|
||||
}
|
||||
};
|
||||
|
||||
let BlobsBundle {
|
||||
let BlobsBundle::<E> {
|
||||
commitments,
|
||||
proofs,
|
||||
blobs,
|
||||
} = BlobsBundle::<E>::from_ssz_bytes(blob_bundle_bytes)
|
||||
.map_err(|e| format!("Unable to decode SSZ: {:?}", e))?;
|
||||
} = BlobsBundle::from_ssz_bytes(TEST_BLOB_BUNDLE)
|
||||
.map_err(|e| format!("Unable to decode ssz: {:?}", e))?;
|
||||
|
||||
Ok((
|
||||
commitments
|
||||
@ -821,6 +812,7 @@ pub fn generate_pow_block(
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use eth2_network_config::TRUSTED_SETUP_BYTES;
|
||||
use kzg::TrustedSetup;
|
||||
use types::{MainnetEthSpec, MinimalEthSpec};
|
||||
|
||||
@ -898,18 +890,17 @@ mod test {
|
||||
}
|
||||
|
||||
fn validate_blob<E: EthSpec>() -> Result<bool, String> {
|
||||
let kzg = load_kzg::<E>()?;
|
||||
let kzg = load_kzg()?;
|
||||
let (kzg_commitment, kzg_proof, blob) = load_test_blobs_bundle::<E>()?;
|
||||
let kzg_blob = E::blob_from_bytes(blob.as_ref())
|
||||
let kzg_blob = kzg::Blob::from_bytes(blob.as_ref())
|
||||
.map_err(|e| format!("Error converting blob to kzg blob: {e:?}"))?;
|
||||
kzg.verify_blob_kzg_proof(&kzg_blob, kzg_commitment, kzg_proof)
|
||||
.map_err(|e| format!("Invalid blobs bundle: {e:?}"))
|
||||
}
|
||||
|
||||
fn load_kzg<E: EthSpec>() -> Result<Kzg<E::Kzg>, String> {
|
||||
let trusted_setup: TrustedSetup =
|
||||
serde_json::from_reader(eth2_network_config::get_trusted_setup::<E::Kzg>())
|
||||
.map_err(|e| format!("Unable to read trusted setup file: {e:?}"))?;
|
||||
fn load_kzg() -> Result<Kzg, String> {
|
||||
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES)
|
||||
.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:?}"))
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
@ -46,7 +46,7 @@ impl<T: EthSpec> MockExecutionLayer<T> {
|
||||
builder_threshold: Option<u128>,
|
||||
jwt_key: Option<JwtKey>,
|
||||
spec: ChainSpec,
|
||||
kzg: Option<Kzg<T::Kzg>>,
|
||||
kzg: Option<Kzg>,
|
||||
) -> Self {
|
||||
let handle = executor.handle().unwrap();
|
||||
|
||||
|
@ -107,7 +107,7 @@ impl<T: EthSpec> MockServer<T> {
|
||||
pub fn new_with_config(
|
||||
handle: &runtime::Handle,
|
||||
config: MockExecutionConfig,
|
||||
kzg: Option<Kzg<T::Kzg>>,
|
||||
kzg: Option<Kzg>,
|
||||
) -> Self {
|
||||
let MockExecutionConfig {
|
||||
jwt_key,
|
||||
@ -188,7 +188,7 @@ impl<T: EthSpec> MockServer<T> {
|
||||
terminal_block_hash: ExecutionBlockHash,
|
||||
shanghai_time: Option<u64>,
|
||||
cancun_time: Option<u64>,
|
||||
kzg: Option<Kzg<T::Kzg>>,
|
||||
kzg: Option<Kzg>,
|
||||
) -> Self {
|
||||
Self::new_with_config(
|
||||
handle,
|
||||
|
@ -389,10 +389,12 @@ pub fn get_config<E: EthSpec>(
|
||||
client_config.trusted_setup = context
|
||||
.eth2_network_config
|
||||
.as_ref()
|
||||
.and_then(|config| config.kzg_trusted_setup.clone());
|
||||
.and_then(|config| config.kzg_trusted_setup.as_ref())
|
||||
.map(|trusted_setup_bytes| serde_json::from_slice(trusted_setup_bytes))
|
||||
.transpose()
|
||||
.map_err(|e| format!("Unable to read trusted setup file: {}", e))?;
|
||||
|
||||
// Override default trusted setup file if required
|
||||
// TODO: consider removing this when we get closer to launch
|
||||
if let Some(trusted_setup_file_path) = cli_args.value_of("trusted-setup-file-override") {
|
||||
let file = std::fs::File::open(trusted_setup_file_path)
|
||||
.map_err(|e| format!("Failed to open trusted setup file: {}", e))?;
|
||||
|
@ -18,7 +18,6 @@ tokio = { workspace = true }
|
||||
serde_yaml = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
types = { workspace = true }
|
||||
kzg = { workspace = true }
|
||||
ethereum_ssz = { workspace = true }
|
||||
eth2_config = { workspace = true }
|
||||
discv5 = { workspace = true }
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -14,7 +14,6 @@
|
||||
use bytes::Bytes;
|
||||
use discv5::enr::{CombinedKey, Enr};
|
||||
use eth2_config::{instantiate_hardcoded_nets, HardcodedNet};
|
||||
use kzg::{KzgPreset, KzgPresetId, TrustedSetup};
|
||||
use pretty_reqwest_error::PrettyReqwestError;
|
||||
use reqwest::{Client, Error};
|
||||
use sensitive_url::SensitiveUrl;
|
||||
@ -49,35 +48,19 @@ pub const DEFAULT_HARDCODED_NETWORK: &str = "mainnet";
|
||||
///
|
||||
/// This is done to ensure that testnets also inherit the high security and
|
||||
/// randomness of the mainnet kzg trusted setup ceremony.
|
||||
const TRUSTED_SETUP: &[u8] =
|
||||
include_bytes!("../built_in_network_configs/testing_trusted_setups.json");
|
||||
///
|
||||
/// 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");
|
||||
|
||||
const TRUSTED_SETUP_MINIMAL: &[u8] =
|
||||
include_bytes!("../built_in_network_configs/minimal_testing_trusted_setups.json");
|
||||
|
||||
pub fn get_trusted_setup<P: KzgPreset>() -> &'static [u8] {
|
||||
get_trusted_setup_from_id(P::spec_name())
|
||||
}
|
||||
|
||||
pub fn get_trusted_setup_from_id(id: KzgPresetId) -> &'static [u8] {
|
||||
match id {
|
||||
KzgPresetId::Mainnet => TRUSTED_SETUP,
|
||||
KzgPresetId::Minimal => TRUSTED_SETUP_MINIMAL,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_trusted_setup_from_config(config: &Config) -> Result<Option<TrustedSetup>, String> {
|
||||
/// 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<Vec<u8>> {
|
||||
config
|
||||
.deneb_fork_epoch
|
||||
.filter(|epoch| epoch.value != Epoch::max_value())
|
||||
.map(|_| {
|
||||
let id = KzgPresetId::from_str(&config.preset_base)
|
||||
.map_err(|e| format!("Unable to parse preset_base as KZG preset: {:?}", e))?;
|
||||
let trusted_setup_bytes = get_trusted_setup_from_id(id);
|
||||
serde_json::from_reader(trusted_setup_bytes)
|
||||
.map_err(|e| format!("Unable to read trusted setup file: {}", e))
|
||||
})
|
||||
.transpose()
|
||||
.map(|_| TRUSTED_SETUP_BYTES.to_vec())
|
||||
}
|
||||
|
||||
/// A simple slice-or-vec enum to avoid cloning the beacon state bytes in the
|
||||
@ -121,7 +104,7 @@ pub struct Eth2NetworkConfig {
|
||||
pub genesis_state_source: GenesisStateSource,
|
||||
pub genesis_state_bytes: Option<GenesisStateBytes>,
|
||||
pub config: Config,
|
||||
pub kzg_trusted_setup: Option<TrustedSetup>,
|
||||
pub kzg_trusted_setup: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl Eth2NetworkConfig {
|
||||
@ -139,7 +122,7 @@ impl Eth2NetworkConfig {
|
||||
fn from_hardcoded_net(net: &HardcodedNet) -> Result<Self, String> {
|
||||
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_from_config(&config);
|
||||
Ok(Self {
|
||||
deposit_contract_deploy_block: serde_yaml::from_reader(net.deploy_block)
|
||||
.map_err(|e| format!("Unable to parse deploy block: {:?}", e))?,
|
||||
@ -376,7 +359,7 @@ impl Eth2NetworkConfig {
|
||||
(None, GenesisStateSource::Unknown)
|
||||
};
|
||||
|
||||
let kzg_trusted_setup = get_trusted_setup_from_config(&config)?;
|
||||
let kzg_trusted_setup = get_trusted_setup_from_config(&config);
|
||||
|
||||
Ok(Self {
|
||||
deposit_contract_deploy_block,
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Misc
|
||||
# ---------------------------------------------------------------
|
||||
# [customized]
|
||||
FIELD_ELEMENTS_PER_BLOB: 4
|
||||
FIELD_ELEMENTS_PER_BLOB: 4096
|
||||
# [customized]
|
||||
MAX_BLOB_COMMITMENTS_PER_BLOCK: 16
|
||||
# `uint64(6)`
|
||||
|
@ -1,7 +1,10 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Blob, EthSpec, Hash256, SignedRoot, Slot};
|
||||
use derivative::Derivative;
|
||||
use kzg::{Kzg, KzgCommitment, KzgPreset, KzgProof, BYTES_PER_FIELD_ELEMENT};
|
||||
use kzg::{
|
||||
Blob as KzgBlob, Kzg, KzgCommitment, KzgProof, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT,
|
||||
FIELD_ELEMENTS_PER_BLOB,
|
||||
};
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
@ -142,12 +145,12 @@ impl<T: EthSpec> BlobSidecar<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random_valid<R: Rng>(rng: &mut R, kzg: &Kzg<T::Kzg>) -> Result<Self, String> {
|
||||
let mut blob_bytes = vec![0u8; T::Kzg::BYTES_PER_BLOB];
|
||||
pub fn random_valid<R: Rng>(rng: &mut R, kzg: &Kzg) -> Result<Self, String> {
|
||||
let mut blob_bytes = vec![0u8; BYTES_PER_BLOB];
|
||||
rng.fill_bytes(&mut blob_bytes);
|
||||
// Ensure that the blob is canonical by ensuring that
|
||||
// each field element contained in the blob is < BLS_MODULUS
|
||||
for i in 0..T::Kzg::FIELD_ELEMENTS_PER_BLOB {
|
||||
for i in 0..FIELD_ELEMENTS_PER_BLOB {
|
||||
let Some(byte) = blob_bytes.get_mut(
|
||||
i.checked_mul(BYTES_PER_FIELD_ELEMENT)
|
||||
.ok_or("overflow".to_string())?,
|
||||
@ -159,7 +162,7 @@ impl<T: EthSpec> BlobSidecar<T> {
|
||||
|
||||
let blob = Blob::<T>::new(blob_bytes)
|
||||
.map_err(|e| format!("error constructing random blob: {:?}", e))?;
|
||||
let kzg_blob = T::blob_from_bytes(&blob).unwrap();
|
||||
let kzg_blob = KzgBlob::from_bytes(&blob).unwrap();
|
||||
|
||||
let commitment = kzg
|
||||
.blob_to_kzg_commitment(&kzg_blob)
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::*;
|
||||
|
||||
use kzg::{BlobTrait, KzgPreset, MainnetKzgPreset, MinimalKzgPreset};
|
||||
use safe_arith::SafeArith;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_types::typenum::{
|
||||
@ -52,8 +51,6 @@ impl fmt::Display for EthSpecId {
|
||||
pub trait EthSpec:
|
||||
'static + Default + Sync + Send + Clone + Debug + PartialEq + Eq + for<'a> arbitrary::Arbitrary<'a>
|
||||
{
|
||||
type Kzg: KzgPreset;
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
@ -270,10 +267,6 @@ pub trait EthSpec:
|
||||
Self::FieldElementsPerBlob::to_usize()
|
||||
}
|
||||
|
||||
fn blob_from_bytes(bytes: &[u8]) -> Result<<Self::Kzg as KzgPreset>::Blob, kzg::Error> {
|
||||
<Self::Kzg as KzgPreset>::Blob::from_bytes(bytes)
|
||||
}
|
||||
|
||||
/// Returns the `BYTES_PER_BLOB` constant for this specification.
|
||||
fn bytes_per_blob() -> usize {
|
||||
Self::BytesPerBlob::to_usize()
|
||||
@ -293,8 +286,6 @@ macro_rules! params_from_eth_spec {
|
||||
pub struct MainnetEthSpec;
|
||||
|
||||
impl EthSpec for MainnetEthSpec {
|
||||
type Kzg = MainnetKzgPreset;
|
||||
|
||||
type JustificationBitsLength = U4;
|
||||
type SubnetBitfieldLength = U64;
|
||||
type MaxValidatorsPerCommittee = U2048;
|
||||
@ -344,8 +335,6 @@ impl EthSpec for MainnetEthSpec {
|
||||
pub struct MinimalEthSpec;
|
||||
|
||||
impl EthSpec for MinimalEthSpec {
|
||||
type Kzg = MinimalKzgPreset;
|
||||
|
||||
type SlotsPerEpoch = U8;
|
||||
type EpochsPerEth1VotingPeriod = U4;
|
||||
type SlotsPerHistoricalRoot = U64;
|
||||
@ -356,8 +345,8 @@ impl EthSpec for MinimalEthSpec {
|
||||
type MaxPendingAttestations = U1024; // 128 max attestations * 8 slots per epoch
|
||||
type SlotsPerEth1VotingPeriod = U32; // 4 epochs * 8 slots per epoch
|
||||
type MaxWithdrawalsPerPayload = U4;
|
||||
type FieldElementsPerBlob = U4;
|
||||
type BytesPerBlob = U128;
|
||||
type FieldElementsPerBlob = U4096;
|
||||
type BytesPerBlob = U131072;
|
||||
type MaxBlobCommitmentsPerBlock = U16;
|
||||
|
||||
params_from_eth_spec!(MainnetEthSpec {
|
||||
@ -398,8 +387,6 @@ impl EthSpec for MinimalEthSpec {
|
||||
pub struct GnosisEthSpec;
|
||||
|
||||
impl EthSpec for GnosisEthSpec {
|
||||
type Kzg = MainnetKzgPreset;
|
||||
|
||||
type JustificationBitsLength = U4;
|
||||
type SubnetBitfieldLength = U64;
|
||||
type MaxValidatorsPerCommittee = U2048;
|
||||
|
@ -16,10 +16,4 @@ serde = { workspace = true }
|
||||
ethereum_serde_utils = { workspace = true }
|
||||
hex = { workspace = true }
|
||||
ethereum_hashing = { workspace = true }
|
||||
c-kzg = { git = "https://github.com/ethereum/c-kzg-4844", rev = "f5f6f863d475847876a2bd5ee252058d37c3a15d" , features = ["mainnet-spec", "serde"]}
|
||||
c_kzg_min = { package = "c-kzg", git = "https://github.com/ethereum//c-kzg-4844", rev = "f5f6f863d475847876a2bd5ee252058d37c3a15d", features = ["minimal-spec", "serde"], optional = true }
|
||||
|
||||
[features]
|
||||
# TODO(deneb): enabled by default for convenience, would need more cfg magic to disable
|
||||
default = ["c_kzg_min"]
|
||||
minimal-spec = ["c_kzg_min"]
|
||||
c-kzg = { git = "https://github.com/ethereum/c-kzg-4844", rev = "748283cced543c486145d5f3f38684becdfe3e1b"}
|
@ -34,12 +34,6 @@ impl From<KzgCommitment> for c_kzg::Bytes48 {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KzgCommitment> for c_kzg_min::Bytes48 {
|
||||
fn from(value: KzgCommitment) -> Self {
|
||||
value.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for KzgCommitment {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", serde_utils::hex::encode(self.0))
|
||||
|
@ -17,12 +17,6 @@ impl From<KzgProof> for c_kzg::Bytes48 {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KzgProof> for c_kzg_min::Bytes48 {
|
||||
fn from(value: KzgProof) -> Self {
|
||||
value.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl KzgProof {
|
||||
/// Creates a valid proof using `G1_POINT_AT_INFINITY`.
|
||||
pub fn empty() -> Self {
|
||||
|
@ -2,297 +2,54 @@ mod kzg_commitment;
|
||||
mod kzg_proof;
|
||||
mod trusted_setup;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof, trusted_setup::TrustedSetup};
|
||||
pub use c_kzg::{Bytes32, Bytes48, BYTES_PER_COMMITMENT, BYTES_PER_FIELD_ELEMENT, BYTES_PER_PROOF};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
InvalidTrustedSetup(CryptoError),
|
||||
InvalidKzgProof(CryptoError),
|
||||
InvalidBytes(CryptoError),
|
||||
KzgProofComputationFailed(CryptoError),
|
||||
InvalidBlob(CryptoError),
|
||||
InvalidBytesForBlob(CryptoError),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CryptoError {
|
||||
CKzg(c_kzg::Error),
|
||||
CKzgMin(c_kzg_min::Error),
|
||||
/// Trusted setup is for the incorrect kzg preset.
|
||||
InconsistentTrustedSetup,
|
||||
}
|
||||
|
||||
impl From<c_kzg::Error> for CryptoError {
|
||||
fn from(e: c_kzg::Error) -> Self {
|
||||
Self::CKzg(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<c_kzg_min::Error> for CryptoError {
|
||||
fn from(e: c_kzg_min::Error) -> Self {
|
||||
Self::CKzgMin(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait BlobTrait: Sized + Clone {
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
pub enum KzgPresetId {
|
||||
Mainnet,
|
||||
Minimal,
|
||||
}
|
||||
|
||||
impl FromStr for KzgPresetId {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"mainnet" => Ok(KzgPresetId::Mainnet),
|
||||
"minimal" => Ok(KzgPresetId::Minimal),
|
||||
_ => Err(format!("Unknown eth spec: {}", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait KzgPreset:
|
||||
'static + Default + Sync + Send + Clone + Debug + PartialEq + Eq + for<'a> arbitrary::Arbitrary<'a>
|
||||
{
|
||||
type KzgSettings: Debug + Sync + Send;
|
||||
type Blob: BlobTrait;
|
||||
type Bytes32: From<[u8; 32]> + Deref<Target = [u8; 32]>;
|
||||
type Bytes48: From<KzgCommitment> + From<KzgProof>;
|
||||
type Error: Into<CryptoError>;
|
||||
|
||||
const BYTES_PER_BLOB: usize;
|
||||
const FIELD_ELEMENTS_PER_BLOB: usize;
|
||||
|
||||
fn spec_name() -> KzgPresetId;
|
||||
|
||||
fn bytes32_in(bytes: Bytes32) -> Self::Bytes32 {
|
||||
let bytes: [u8; 32] = *bytes;
|
||||
Self::Bytes32::from(bytes)
|
||||
}
|
||||
|
||||
fn bytes32_out(bytes: Self::Bytes32) -> Bytes32 {
|
||||
let bytes: [u8; 32] = *bytes;
|
||||
Bytes32::from(bytes)
|
||||
}
|
||||
|
||||
fn load_trusted_setup(trusted_setup: TrustedSetup) -> Result<Self::KzgSettings, CryptoError>;
|
||||
|
||||
fn compute_blob_kzg_proof(
|
||||
blob: &Self::Blob,
|
||||
kzg_commitment: KzgCommitment,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<KzgProof, CryptoError>;
|
||||
|
||||
fn verify_blob_kzg_proof(
|
||||
blob: &Self::Blob,
|
||||
kzg_commitment: KzgCommitment,
|
||||
kzg_proof: KzgProof,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<bool, CryptoError>;
|
||||
|
||||
fn verify_blob_kzg_proof_batch(
|
||||
blobs: &[Self::Blob],
|
||||
commitments_bytes: &[Self::Bytes48],
|
||||
proofs_bytes: &[Self::Bytes48],
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<bool, CryptoError>;
|
||||
|
||||
fn blob_to_kzg_commitment(
|
||||
blob: &Self::Blob,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<KzgCommitment, CryptoError>;
|
||||
|
||||
fn compute_kzg_proof(
|
||||
blob: &Self::Blob,
|
||||
z: &Self::Bytes32,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<(KzgProof, Self::Bytes32), CryptoError>;
|
||||
|
||||
fn verify_kzg_proof(
|
||||
kzg_commitment: KzgCommitment,
|
||||
z: &Self::Bytes32,
|
||||
y: &Self::Bytes32,
|
||||
kzg_proof: KzgProof,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<bool, CryptoError>;
|
||||
}
|
||||
|
||||
macro_rules! implement_kzg_preset {
|
||||
($preset_type:ident, $module_name:ident, $preset_id:ident) => {
|
||||
impl KzgPreset for $preset_type {
|
||||
type KzgSettings = $module_name::KzgSettings;
|
||||
type Blob = $module_name::Blob;
|
||||
type Bytes32 = $module_name::Bytes32;
|
||||
type Bytes48 = $module_name::Bytes48;
|
||||
type Error = $module_name::Error;
|
||||
|
||||
const BYTES_PER_BLOB: usize = $module_name::BYTES_PER_BLOB;
|
||||
const FIELD_ELEMENTS_PER_BLOB: usize = $module_name::FIELD_ELEMENTS_PER_BLOB;
|
||||
|
||||
fn spec_name() -> KzgPresetId {
|
||||
KzgPresetId::$preset_id
|
||||
}
|
||||
|
||||
fn load_trusted_setup(
|
||||
trusted_setup: TrustedSetup,
|
||||
) -> Result<Self::KzgSettings, CryptoError> {
|
||||
if trusted_setup.g1_len() != Self::FIELD_ELEMENTS_PER_BLOB {
|
||||
return Err(CryptoError::InconsistentTrustedSetup);
|
||||
}
|
||||
$module_name::KzgSettings::load_trusted_setup(
|
||||
&trusted_setup.g1_points(),
|
||||
&trusted_setup.g2_points(),
|
||||
)
|
||||
.map_err(CryptoError::from)
|
||||
}
|
||||
|
||||
fn compute_blob_kzg_proof(
|
||||
blob: &Self::Blob,
|
||||
kzg_commitment: KzgCommitment,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<KzgProof, CryptoError> {
|
||||
$module_name::KzgProof::compute_blob_kzg_proof(
|
||||
blob,
|
||||
&kzg_commitment.into(),
|
||||
trusted_setup,
|
||||
)
|
||||
.map(|proof| KzgProof(proof.to_bytes().into_inner()))
|
||||
.map_err(CryptoError::from)
|
||||
}
|
||||
|
||||
fn verify_blob_kzg_proof(
|
||||
blob: &Self::Blob,
|
||||
kzg_commitment: KzgCommitment,
|
||||
kzg_proof: KzgProof,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<bool, CryptoError> {
|
||||
$module_name::KzgProof::verify_blob_kzg_proof(
|
||||
blob,
|
||||
&kzg_commitment.into(),
|
||||
&kzg_proof.into(),
|
||||
trusted_setup,
|
||||
)
|
||||
.map_err(CryptoError::from)
|
||||
}
|
||||
|
||||
fn verify_blob_kzg_proof_batch(
|
||||
blobs: &[Self::Blob],
|
||||
commitments_bytes: &[Self::Bytes48],
|
||||
proofs_bytes: &[Self::Bytes48],
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<bool, CryptoError> {
|
||||
$module_name::KzgProof::verify_blob_kzg_proof_batch(
|
||||
blobs,
|
||||
commitments_bytes,
|
||||
proofs_bytes,
|
||||
trusted_setup,
|
||||
)
|
||||
.map_err(CryptoError::from)
|
||||
}
|
||||
|
||||
fn blob_to_kzg_commitment(
|
||||
blob: &Self::Blob,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<KzgCommitment, CryptoError> {
|
||||
$module_name::KzgCommitment::blob_to_kzg_commitment(blob, trusted_setup)
|
||||
.map(|com| KzgCommitment(com.to_bytes().into_inner()))
|
||||
.map_err(CryptoError::from)
|
||||
}
|
||||
|
||||
fn compute_kzg_proof(
|
||||
blob: &Self::Blob,
|
||||
z: &Self::Bytes32,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<(KzgProof, Self::Bytes32), CryptoError> {
|
||||
$module_name::KzgProof::compute_kzg_proof(blob, z, trusted_setup)
|
||||
.map(|(proof, y)| (KzgProof(proof.to_bytes().into_inner()), y))
|
||||
.map_err(CryptoError::from)
|
||||
}
|
||||
|
||||
fn verify_kzg_proof(
|
||||
kzg_commitment: KzgCommitment,
|
||||
z: &Self::Bytes32,
|
||||
y: &Self::Bytes32,
|
||||
kzg_proof: KzgProof,
|
||||
trusted_setup: &Self::KzgSettings,
|
||||
) -> Result<bool, CryptoError> {
|
||||
$module_name::KzgProof::verify_kzg_proof(
|
||||
&kzg_commitment.into(),
|
||||
z,
|
||||
y,
|
||||
&kzg_proof.into(),
|
||||
trusted_setup,
|
||||
)
|
||||
.map_err(CryptoError::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl BlobTrait for $module_name::Blob {
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
|
||||
Self::from_bytes(bytes)
|
||||
.map_err(CryptoError::from)
|
||||
.map_err(Error::InvalidBlob)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize, arbitrary::Arbitrary)]
|
||||
pub struct MainnetKzgPreset;
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize, arbitrary::Arbitrary)]
|
||||
pub struct MinimalKzgPreset;
|
||||
|
||||
implement_kzg_preset!(MainnetKzgPreset, c_kzg, Mainnet);
|
||||
implement_kzg_preset!(MinimalKzgPreset, c_kzg_min, Minimal);
|
||||
pub use c_kzg::{
|
||||
Blob, Bytes32, Bytes48, Error, KzgSettings, BYTES_PER_BLOB, BYTES_PER_COMMITMENT,
|
||||
BYTES_PER_FIELD_ELEMENT, BYTES_PER_PROOF, FIELD_ELEMENTS_PER_BLOB,
|
||||
};
|
||||
|
||||
/// A wrapper over a kzg library that holds the trusted setup parameters.
|
||||
#[derive(Debug)]
|
||||
pub struct Kzg<P: KzgPreset> {
|
||||
trusted_setup: P::KzgSettings,
|
||||
pub struct Kzg {
|
||||
trusted_setup: KzgSettings,
|
||||
}
|
||||
|
||||
impl<P: KzgPreset> Kzg<P> {
|
||||
impl Kzg {
|
||||
/// Load the kzg trusted setup parameters from a vec of G1 and G2 points.
|
||||
///
|
||||
/// The number of G1 points should be equal to FIELD_ELEMENTS_PER_BLOB
|
||||
/// Note: this number changes based on the preset values.
|
||||
/// The number of G2 points should be equal to 65.
|
||||
pub fn new_from_trusted_setup(trusted_setup: TrustedSetup) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
trusted_setup: P::load_trusted_setup(trusted_setup)
|
||||
.map_err(Error::InvalidTrustedSetup)?,
|
||||
trusted_setup: KzgSettings::load_trusted_setup(
|
||||
&trusted_setup.g1_points(),
|
||||
&trusted_setup.g2_points(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Compute the kzg proof given a blob and its kzg commitment.
|
||||
pub fn compute_blob_kzg_proof(
|
||||
&self,
|
||||
blob: &P::Blob,
|
||||
blob: &Blob,
|
||||
kzg_commitment: KzgCommitment,
|
||||
) -> Result<KzgProof, Error> {
|
||||
P::compute_blob_kzg_proof(blob, kzg_commitment, &self.trusted_setup)
|
||||
.map_err(Error::KzgProofComputationFailed)
|
||||
c_kzg::KzgProof::compute_blob_kzg_proof(blob, &kzg_commitment.into(), &self.trusted_setup)
|
||||
.map(|proof| KzgProof(proof.to_bytes().into_inner()))
|
||||
}
|
||||
|
||||
/// Verify a kzg proof given the blob, kzg commitment and kzg proof.
|
||||
pub fn verify_blob_kzg_proof(
|
||||
&self,
|
||||
blob: &P::Blob,
|
||||
blob: &Blob,
|
||||
kzg_commitment: KzgCommitment,
|
||||
kzg_proof: KzgProof,
|
||||
) -> Result<bool, Error> {
|
||||
P::verify_blob_kzg_proof(blob, kzg_commitment, kzg_proof, &self.trusted_setup)
|
||||
.map_err(Error::InvalidKzgProof)
|
||||
c_kzg::KzgProof::verify_blob_kzg_proof(
|
||||
blob,
|
||||
&kzg_commitment.into(),
|
||||
&kzg_proof.into(),
|
||||
&self.trusted_setup,
|
||||
)
|
||||
}
|
||||
|
||||
/// Verify a batch of blob commitment proof triplets.
|
||||
@ -301,43 +58,42 @@ impl<P: KzgPreset> Kzg<P> {
|
||||
/// TODO(pawan): test performance against a parallelized rayon impl.
|
||||
pub fn verify_blob_kzg_proof_batch(
|
||||
&self,
|
||||
blobs: &[P::Blob],
|
||||
blobs: &[Blob],
|
||||
kzg_commitments: &[KzgCommitment],
|
||||
kzg_proofs: &[KzgProof],
|
||||
) -> Result<bool, Error> {
|
||||
let commitments_bytes = kzg_commitments
|
||||
.iter()
|
||||
.map(|comm| P::Bytes48::from(*comm))
|
||||
.map(|comm| Bytes48::from(*comm))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let proofs_bytes = kzg_proofs
|
||||
.iter()
|
||||
.map(|proof| P::Bytes48::from(*proof))
|
||||
.map(|proof| Bytes48::from(*proof))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
P::verify_blob_kzg_proof_batch(
|
||||
c_kzg::KzgProof::verify_blob_kzg_proof_batch(
|
||||
blobs,
|
||||
&commitments_bytes,
|
||||
&proofs_bytes,
|
||||
&self.trusted_setup,
|
||||
)
|
||||
.map_err(Error::InvalidKzgProof)
|
||||
}
|
||||
|
||||
/// Converts a blob to a kzg commitment.
|
||||
pub fn blob_to_kzg_commitment(&self, blob: &P::Blob) -> Result<KzgCommitment, Error> {
|
||||
P::blob_to_kzg_commitment(blob, &self.trusted_setup).map_err(Error::InvalidBlob)
|
||||
pub fn blob_to_kzg_commitment(&self, blob: &Blob) -> Result<KzgCommitment, Error> {
|
||||
c_kzg::KzgCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup)
|
||||
.map(|commitment| KzgCommitment(commitment.to_bytes().into_inner()))
|
||||
}
|
||||
|
||||
/// Computes the kzg proof for a given `blob` and an evaluation point `z`
|
||||
pub fn compute_kzg_proof(
|
||||
&self,
|
||||
blob: &P::Blob,
|
||||
blob: &Blob,
|
||||
z: &Bytes32,
|
||||
) -> Result<(KzgProof, Bytes32), Error> {
|
||||
P::compute_kzg_proof(blob, &P::bytes32_in(*z), &self.trusted_setup)
|
||||
.map_err(Error::KzgProofComputationFailed)
|
||||
.map(|(proof, y)| (proof, P::bytes32_out(y)))
|
||||
c_kzg::KzgProof::compute_kzg_proof(blob, z, &self.trusted_setup)
|
||||
.map(|(proof, y)| (KzgProof(proof.to_bytes().into_inner()), y))
|
||||
}
|
||||
|
||||
/// Verifies a `kzg_proof` for a `kzg_commitment` that evaluating a polynomial at `z` results in `y`
|
||||
@ -348,13 +104,12 @@ impl<P: KzgPreset> Kzg<P> {
|
||||
y: &Bytes32,
|
||||
kzg_proof: KzgProof,
|
||||
) -> Result<bool, Error> {
|
||||
P::verify_kzg_proof(
|
||||
kzg_commitment,
|
||||
&P::bytes32_in(*z),
|
||||
&P::bytes32_in(*y),
|
||||
kzg_proof,
|
||||
c_kzg::KzgProof::verify_kzg_proof(
|
||||
&kzg_commitment.into(),
|
||||
z,
|
||||
y,
|
||||
&kzg_proof.into(),
|
||||
&self.trusted_setup,
|
||||
)
|
||||
.map_err(Error::InvalidKzgProof)
|
||||
}
|
||||
}
|
||||
|
@ -18,12 +18,12 @@ struct G2Point([u8; BYTES_PER_G2_POINT]);
|
||||
/// The serialize/deserialize implementations are written according to
|
||||
/// the format specified in the the ethereum consensus specs trusted setup files.
|
||||
///
|
||||
/// See https://github.com/ethereum/consensus-specs/blob/dev/presets/mainnet/trusted_setups/testing_trusted_setups.json
|
||||
/// See https://github.com/ethereum/consensus-specs/blob/dev/presets/mainnet/trusted_setups/trusted_setup_4096.json
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct TrustedSetup {
|
||||
#[serde(rename = "setup_G1_lagrange")]
|
||||
#[serde(rename = "g1_lagrange")]
|
||||
g1_points: Vec<G1Point>,
|
||||
#[serde(rename = "setup_G2")]
|
||||
#[serde(rename = "g2_monomial")]
|
||||
g2_points: Vec<G2Point>,
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ jemalloc = ["malloc_utils/jemalloc"]
|
||||
|
||||
[dependencies]
|
||||
bls = { workspace = true }
|
||||
kzg = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
log = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
|
@ -1,12 +1,11 @@
|
||||
use account_utils::eth2_keystore::keypair_from_secret;
|
||||
use clap::ArgMatches;
|
||||
use clap_utils::{parse_optional, parse_required, parse_ssz_optional};
|
||||
use eth2_network_config::{get_trusted_setup, Eth2NetworkConfig, GenesisStateSource};
|
||||
use eth2_network_config::{Eth2NetworkConfig, GenesisStateSource, TRUSTED_SETUP_BYTES};
|
||||
use eth2_wallet::bip39::Seed;
|
||||
use eth2_wallet::bip39::{Language, Mnemonic};
|
||||
use eth2_wallet::{recover_validator_secret_from_mnemonic, KeyType};
|
||||
use ethereum_hashing::hash;
|
||||
use kzg::TrustedSetup;
|
||||
use ssz::Decode;
|
||||
use ssz::Encode;
|
||||
use state_processing::process_activations;
|
||||
@ -199,10 +198,7 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
|
||||
let kzg_trusted_setup = if let Some(epoch) = spec.deneb_fork_epoch {
|
||||
// Only load the trusted setup if the deneb fork epoch is set
|
||||
if epoch != Epoch::max_value() {
|
||||
let trusted_setup: TrustedSetup =
|
||||
serde_json::from_reader(get_trusted_setup::<T::Kzg>())
|
||||
.map_err(|e| format!("Unable to read trusted setup file: {}", e))?;
|
||||
Some(trusted_setup)
|
||||
Some(TRUSTED_SETUP_BYTES.to_vec())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
TESTS_TAG := v1.4.0-beta.2-hotfix
|
||||
TESTS_TAG := v1.4.0-beta.3
|
||||
TESTS = general minimal mainnet
|
||||
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))
|
||||
|
||||
|
@ -32,7 +32,7 @@ impl<E: EthSpec> Case for KZGBlobToKZGCommitment<E> {
|
||||
}
|
||||
|
||||
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
|
||||
let kzg = get_kzg::<E::Kzg>()?;
|
||||
let kzg = get_kzg()?;
|
||||
|
||||
let commitment = parse_blob::<E>(&self.input.blob).and_then(|blob| {
|
||||
blob_to_kzg_commitment::<E>(&kzg, &blob).map_err(|e| {
|
||||
|
@ -39,7 +39,7 @@ impl<E: EthSpec> Case for KZGComputeBlobKZGProof<E> {
|
||||
Ok((blob, commitment))
|
||||
};
|
||||
|
||||
let kzg = get_kzg::<E::Kzg>()?;
|
||||
let kzg = get_kzg()?;
|
||||
let proof = parse_input(&self.input).and_then(|(blob, commitment)| {
|
||||
compute_blob_kzg_proof::<E>(&kzg, &blob, commitment)
|
||||
.map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e)))
|
||||
|
@ -46,7 +46,7 @@ impl<E: EthSpec> Case for KZGComputeKZGProof<E> {
|
||||
Ok((blob, z))
|
||||
};
|
||||
|
||||
let kzg = get_kzg::<E::Kzg>()?;
|
||||
let kzg = get_kzg()?;
|
||||
let proof = parse_input(&self.input).and_then(|(blob, z)| {
|
||||
compute_kzg_proof::<E>(&kzg, &blob, z)
|
||||
.map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e)))
|
||||
|
@ -1,15 +1,15 @@
|
||||
use super::*;
|
||||
use crate::case_result::compare_result;
|
||||
use beacon_chain::kzg_utils::validate_blob;
|
||||
use eth2_network_config::get_trusted_setup;
|
||||
use kzg::{Kzg, KzgCommitment, KzgPreset, KzgProof, TrustedSetup};
|
||||
use eth2_network_config::TRUSTED_SETUP_BYTES;
|
||||
use kzg::{Kzg, KzgCommitment, KzgProof, TrustedSetup};
|
||||
use serde::Deserialize;
|
||||
use std::convert::TryInto;
|
||||
use std::marker::PhantomData;
|
||||
use types::Blob;
|
||||
|
||||
pub fn get_kzg<P: KzgPreset>() -> Result<Kzg<P>, Error> {
|
||||
let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup::<P>())
|
||||
pub fn get_kzg() -> Result<Kzg, Error> {
|
||||
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP_BYTES)
|
||||
.map_err(|e| Error::InternalError(format!("Failed to initialize kzg: {:?}", e)))?;
|
||||
Kzg::new_from_trusted_setup(trusted_setup)
|
||||
.map_err(|e| Error::InternalError(format!("Failed to initialize kzg: {:?}", e)))
|
||||
@ -89,7 +89,7 @@ impl<E: EthSpec> Case for KZGVerifyBlobKZGProof<E> {
|
||||
Ok((blob, commitment, proof))
|
||||
};
|
||||
|
||||
let kzg = get_kzg::<E::Kzg>()?;
|
||||
let kzg = get_kzg()?;
|
||||
let result = parse_input(&self.input).and_then(|(blob, commitment, proof)| {
|
||||
validate_blob::<E>(&kzg, &blob, commitment, proof)
|
||||
.map_err(|e| Error::InternalError(format!("Failed to validate blob: {:?}", e)))
|
||||
|
@ -52,7 +52,7 @@ impl<E: EthSpec> Case for KZGVerifyBlobKZGProofBatch<E> {
|
||||
Ok((commitments, blobs, proofs))
|
||||
};
|
||||
|
||||
let kzg = get_kzg::<E::Kzg>()?;
|
||||
let kzg = get_kzg()?;
|
||||
let result = parse_input(&self.input).and_then(|(commitments, blobs, proofs)| {
|
||||
validate_blobs::<E>(&kzg, &commitments, blobs.iter().collect(), &proofs)
|
||||
.map_err(|e| Error::InternalError(format!("Failed to validate blobs: {:?}", e)))
|
||||
|
@ -42,7 +42,7 @@ impl<E: EthSpec> Case for KZGVerifyKZGProof<E> {
|
||||
Ok((commitment, z, y, proof))
|
||||
};
|
||||
|
||||
let kzg = get_kzg::<E::Kzg>()?;
|
||||
let kzg = get_kzg()?;
|
||||
let result = parse_input(&self.input).and_then(|(commitment, z, y, proof)| {
|
||||
verify_kzg_proof::<E>(&kzg, commitment, proof, z, y)
|
||||
.map_err(|e| Error::InternalError(format!("Failed to validate proof: {:?}", e)))
|
||||
|
Loading…
Reference in New Issue
Block a user