merge eip4844

This commit is contained in:
realbigsean 2023-01-19 08:46:38 -05:00
commit acbbdd8b9e
No known key found for this signature in database
GPG Key ID: B372B64D866BF8CC
7 changed files with 33 additions and 52 deletions

3
Cargo.lock generated
View File

@ -896,7 +896,7 @@ dependencies = [
[[package]] [[package]]
name = "c-kzg" name = "c-kzg"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pawanjay176/c-kzg-4844?rev=c9e4fa0dabdd000738b7fcdf85a72880a5da8748#c9e4fa0dabdd000738b7fcdf85a72880a5da8748" source = "git+https://github.com/ethereum/c-kzg-4844?rev=69f6155d7524247be9d3f54ab3bfbe33a0345622#69f6155d7524247be9d3f54ab3bfbe33a0345622"
dependencies = [ dependencies = [
"hex", "hex",
"libc", "libc",
@ -3735,6 +3735,7 @@ dependencies = [
"eth2_wallet", "eth2_wallet",
"genesis", "genesis",
"int_to_bytes", "int_to_bytes",
"kzg",
"lighthouse_network", "lighthouse_network",
"lighthouse_version", "lighthouse_version",
"log", "log",

View File

@ -136,13 +136,6 @@ pub fn validate_blob_for_gossip<T: BeaconChainTypes>(
}); });
} }
// Verify that kzg commitments in the block are valid BLS g1 points
for commitment in kzg_commitments {
if kzg::bytes_to_g1(&commitment.0).is_err() {
return Err(BlobError::InvalidKZGCommitment);
}
}
// Validate commitments agains transactions in the block. // Validate commitments agains transactions in the block.
if verify_kzg_commitments_against_transactions::<T::EthSpec>(transactions, kzg_commitments) if verify_kzg_commitments_against_transactions::<T::EthSpec>(transactions, kzg_commitments)
.is_err() .is_err()
@ -150,16 +143,6 @@ pub fn validate_blob_for_gossip<T: BeaconChainTypes>(
return Err(BlobError::TransactionCommitmentMismatch); return Err(BlobError::TransactionCommitmentMismatch);
} }
// Check that blobs are < BLS_MODULUS
// TODO(pawan): Add this check after there's some resolution of this
// issue https://github.com/ethereum/c-kzg-4844/issues/11
// As of now, `bytes_to_bls_field` does not fail in the c-kzg library if blob >= BLS_MODULUS
// Validate that kzg proof is a valid g1 point
if kzg::bytes_to_g1(&blob_sidecar.kzg_aggregated_proof.0).is_err() {
return Err(BlobError::InvalidKzgProof);
}
// Validatate that the kzg proof is valid against the commitments and blobs // Validatate that the kzg proof is valid against the commitments and blobs
let kzg = chain let kzg = chain
.kzg .kzg

View File

@ -1,14 +1,11 @@
use kzg::{Error as KzgError, Kzg, BYTES_PER_BLOB}; use kzg::{Error as KzgError, Kzg, BYTES_PER_BLOB};
use types::{Blob, BlobsSidecar, EthSpec, Hash256, KzgCommitment, KzgProof, Slot}; use types::{Blob, BlobsSidecar, EthSpec, Hash256, KzgCommitment, KzgProof, Slot};
fn ssz_blob_to_crypto_blob<T: EthSpec>(blob: Blob<T>) -> Option<[u8; BYTES_PER_BLOB]> { fn ssz_blob_to_crypto_blob<T: EthSpec>(blob: Blob<T>) -> kzg::Blob {
if blob.len() != BYTES_PER_BLOB {
return None;
}
let blob_vec: Vec<u8> = blob.into(); let blob_vec: Vec<u8> = blob.into();
let mut arr = [0; BYTES_PER_BLOB]; let mut arr = [0; BYTES_PER_BLOB];
arr.copy_from_slice(&blob_vec); arr.copy_from_slice(&blob_vec);
Some(arr) arr.into()
} }
pub fn validate_blobs_sidecar<T: EthSpec>( pub fn validate_blobs_sidecar<T: EthSpec>(
@ -29,8 +26,7 @@ pub fn validate_blobs_sidecar<T: EthSpec>(
.blobs .blobs
.into_iter() .into_iter()
.map(|blob| ssz_blob_to_crypto_blob::<T>(blob.clone())) // TODO(pawan): avoid this clone .map(|blob| ssz_blob_to_crypto_blob::<T>(blob.clone())) // TODO(pawan): avoid this clone
.collect::<Option<Vec<_>>>() .collect::<Vec<_>>();
.ok_or_else(|| KzgError::InvalidBlob("Invalid blobs in sidecar".to_string()))?;
kzg.verify_aggregate_kzg_proof( kzg.verify_aggregate_kzg_proof(
&blobs, &blobs,
@ -46,13 +42,12 @@ pub fn compute_aggregate_kzg_proof<T: EthSpec>(
let blobs = blobs let blobs = blobs
.into_iter() .into_iter()
.map(|blob| ssz_blob_to_crypto_blob::<T>(blob.clone())) // TODO(pawan): avoid this clone .map(|blob| ssz_blob_to_crypto_blob::<T>(blob.clone())) // TODO(pawan): avoid this clone
.collect::<Option<Vec<_>>>() .collect::<Vec<_>>();
.ok_or_else(|| KzgError::InvalidBlob("Invalid blobs".to_string()))?;
kzg.compute_aggregate_kzg_proof(&blobs) kzg.compute_aggregate_kzg_proof(&blobs)
} }
pub fn blob_to_kzg_commitment<T: EthSpec>(kzg: &Kzg, blob: Blob<T>) -> Option<KzgCommitment> { pub fn blob_to_kzg_commitment<T: EthSpec>(kzg: &Kzg, blob: Blob<T>) -> KzgCommitment {
let blob = ssz_blob_to_crypto_blob::<T>(blob)?; let blob = ssz_blob_to_crypto_blob::<T>(blob);
Some(kzg.blob_to_kzg_commitment(blob)) kzg.blob_to_kzg_commitment(blob)
} }

View File

@ -18,7 +18,7 @@ eth2_serde_utils = "0.1.1"
hex = "0.4.2" hex = "0.4.2"
eth2_hashing = "0.3.0" eth2_hashing = "0.3.0"
ethereum-types = "0.12.1" ethereum-types = "0.12.1"
c-kzg = {git = "https://github.com/pawanjay176/c-kzg-4844", rev = "c9e4fa0dabdd000738b7fcdf85a72880a5da8748" } c-kzg = {git = "https://github.com/ethereum/c-kzg-4844", rev = "69f6155d7524247be9d3f54ab3bfbe33a0345622" }
arbitrary = { version = "1.0", features = ["derive"], optional = true } arbitrary = { version = "1.0", features = ["derive"], optional = true }
[features] [features]

View File

@ -3,20 +3,16 @@ mod kzg_proof;
mod trusted_setup; mod trusted_setup;
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof, trusted_setup::TrustedSetup}; pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof, trusted_setup::TrustedSetup};
pub use c_kzg::bytes_to_g1;
pub use c_kzg::{ pub use c_kzg::{
Blob, Error as CKzgError, KzgSettings, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT, Blob, Error as CKzgError, KZGSettings, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT,
FIELD_ELEMENTS_PER_BLOB, FIELD_ELEMENTS_PER_BLOB,
}; };
use std::path::PathBuf; use std::path::PathBuf;
#[derive(Debug)] #[derive(Debug)]
/// TODO(pawan): add docs after the c_kzg interface changes to bytes only.
pub enum Error { pub enum Error {
InvalidTrustedSetup(CKzgError), InvalidTrustedSetup(CKzgError),
InvalidKzgCommitment(CKzgError),
InvalidKzgProof(CKzgError), InvalidKzgProof(CKzgError),
KzgVerificationFailed(CKzgError),
InvalidLength(String), InvalidLength(String),
KzgProofComputationFailed(CKzgError), KzgProofComputationFailed(CKzgError),
InvalidBlob(String), InvalidBlob(String),
@ -24,7 +20,7 @@ pub enum Error {
/// A wrapper over a kzg library that holds the trusted setup parameters. /// A wrapper over a kzg library that holds the trusted setup parameters.
pub struct Kzg { pub struct Kzg {
trusted_setup: KzgSettings, trusted_setup: KZGSettings,
} }
impl Kzg { impl Kzg {
@ -35,7 +31,7 @@ impl Kzg {
/// The number of G2 points should be equal to 65. /// The number of G2 points should be equal to 65.
pub fn new_from_trusted_setup(trusted_setup: TrustedSetup) -> Result<Self, Error> { pub fn new_from_trusted_setup(trusted_setup: TrustedSetup) -> Result<Self, Error> {
Ok(Self { Ok(Self {
trusted_setup: KzgSettings::load_trusted_setup( trusted_setup: KZGSettings::load_trusted_setup(
trusted_setup.g1_points(), trusted_setup.g1_points(),
trusted_setup.g2_points(), trusted_setup.g2_points(),
) )
@ -50,14 +46,14 @@ impl Kzg {
#[deprecated] #[deprecated]
pub fn new_from_file(file_path: PathBuf) -> Result<Self, Error> { pub fn new_from_file(file_path: PathBuf) -> Result<Self, Error> {
Ok(Self { Ok(Self {
trusted_setup: KzgSettings::load_trusted_setup_file(file_path) trusted_setup: KZGSettings::load_trusted_setup_file(file_path)
.map_err(Error::InvalidTrustedSetup)?, .map_err(Error::InvalidTrustedSetup)?,
}) })
} }
/// Compute the aggregated kzg proof given an array of blobs. /// Compute the aggregated kzg proof given an array of blobs.
pub fn compute_aggregate_kzg_proof(&self, blobs: &[Blob]) -> Result<KzgProof, Error> { pub fn compute_aggregate_kzg_proof(&self, blobs: &[Blob]) -> Result<KzgProof, Error> {
c_kzg::KzgProof::compute_aggregate_kzg_proof(blobs, &self.trusted_setup) c_kzg::KZGProof::compute_aggregate_kzg_proof(blobs, &self.trusted_setup)
.map_err(Error::KzgProofComputationFailed) .map_err(Error::KzgProofComputationFailed)
.map(|proof| KzgProof(proof.to_bytes())) .map(|proof| KzgProof(proof.to_bytes()))
} }
@ -77,12 +73,9 @@ impl Kzg {
} }
let commitments = expected_kzg_commitments let commitments = expected_kzg_commitments
.into_iter() .into_iter()
.map(|comm| { .map(|comm| comm.0.into())
c_kzg::KzgCommitment::from_bytes(&comm.0).map_err(Error::InvalidKzgCommitment) .collect::<Vec<c_kzg::KZGCommitment>>();
}) let proof: c_kzg::KZGProof = kzg_aggregated_proof.0.into();
.collect::<Result<Vec<c_kzg::KzgCommitment>, Error>>()?;
let proof =
c_kzg::KzgProof::from_bytes(&kzg_aggregated_proof.0).map_err(Error::InvalidKzgProof)?;
proof proof
.verify_aggregate_kzg_proof(blobs, &commitments, &self.trusted_setup) .verify_aggregate_kzg_proof(blobs, &commitments, &self.trusted_setup)
.map_err(Error::InvalidKzgProof) .map_err(Error::InvalidKzgProof)
@ -91,7 +84,7 @@ impl Kzg {
/// Converts a blob to a kzg commitment. /// Converts a blob to a kzg commitment.
pub fn blob_to_kzg_commitment(&self, blob: Blob) -> KzgCommitment { pub fn blob_to_kzg_commitment(&self, blob: Blob) -> KzgCommitment {
KzgCommitment( KzgCommitment(
c_kzg::KzgCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup).to_bytes(), c_kzg::KZGCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup).to_bytes(),
) )
} }
} }

View File

@ -11,6 +11,7 @@ fake_crypto = ['bls/fake_crypto']
[dependencies] [dependencies]
bls = { path = "../crypto/bls" } bls = { path = "../crypto/bls" }
kzg = { path = "../crypto/kzg" }
clap = "2.33.3" clap = "2.33.3"
log = "0.4.11" log = "0.4.11"
serde = "1.0.116" serde = "1.0.116"

View File

@ -2,6 +2,7 @@ use clap::ArgMatches;
use clap_utils::{parse_optional, parse_required, parse_ssz_optional}; use clap_utils::{parse_optional, parse_required, parse_ssz_optional};
use eth2_hashing::hash; use eth2_hashing::hash;
use eth2_network_config::{Eth2NetworkConfig, TRUSTED_SETUP}; use eth2_network_config::{Eth2NetworkConfig, TRUSTED_SETUP};
use kzg::TrustedSetup;
use ssz::Decode; use ssz::Decode;
use ssz::Encode; use ssz::Encode;
use state_processing::process_activations; use state_processing::process_activations;
@ -81,13 +82,8 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
spec.capella_fork_epoch = Some(fork_epoch); spec.capella_fork_epoch = Some(fork_epoch);
} }
let mut kzg_trusted_setup = None;
if let Some(fork_epoch) = parse_optional(matches, "eip4844-fork-epoch")? { if let Some(fork_epoch) = parse_optional(matches, "eip4844-fork-epoch")? {
spec.eip4844_fork_epoch = Some(fork_epoch); spec.eip4844_fork_epoch = Some(fork_epoch);
kzg_trusted_setup = Some(
serde_json::from_reader(TRUSTED_SETUP)
.map_err(|e| format!("Unable to read trusted setup file: {}", e))?,
)
} }
if let Some(ttd) = parse_optional(matches, "ttd")? { if let Some(ttd) = parse_optional(matches, "ttd")? {
@ -163,6 +159,18 @@ pub fn run<T: EthSpec>(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul
None None
}; };
let kzg_trusted_setup = if let Some(epoch) = spec.eip4844_fork_epoch {
// Only load the trusted setup if the eip4844 fork epoch is set
if epoch != Epoch::max_value() {
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP)
.map_err(|e| format!("Unable to read trusted setup file: {}", e))?;
Some(trusted_setup)
} else {
None
}
} else {
None
};
let testnet = Eth2NetworkConfig { let testnet = Eth2NetworkConfig {
deposit_contract_deploy_block, deposit_contract_deploy_block,
boot_enr: Some(vec![]), boot_enr: Some(vec![]),