diff --git a/Cargo.lock b/Cargo.lock index 2d84107c2..e6a42384b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ dependencies = [ [[package]] name = "aggregator" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "ark-std", "env_logger 0.10.0", @@ -418,7 +418,7 @@ checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "bus-mapping" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "eth-types", "ethers-core 0.17.0", @@ -1118,7 +1118,7 @@ dependencies = [ [[package]] name = "eth-types" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "ethers-core 0.17.0", "ethers-signers", @@ -1384,7 +1384,7 @@ dependencies = [ [[package]] name = "external-tracer" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "eth-types", "geth-utils", @@ -1437,7 +1437,7 @@ dependencies = [ [[package]] name = "ffi" -version = "0.4.0" +version = "0.5.0" dependencies = [ "libc", "log", @@ -1613,7 +1613,7 @@ dependencies = [ [[package]] name = "gadgets" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "digest 0.7.6", "eth-types", @@ -1653,7 +1653,7 @@ dependencies = [ [[package]] name = "geth-utils" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "env_logger 0.9.3", "gobuild 0.1.0-alpha.2 (git+https://github.com/scroll-tech/gobuild.git)", @@ -1807,7 +1807,7 @@ dependencies = [ [[package]] name = "halo2_proofs" version = "0.2.0" -source = "git+https://github.com/scroll-tech/halo2.git?branch=develop#9bf3562083dd9bed8a19f651b52bc810f5e2235f" +source = "git+https://github.com/scroll-tech/halo2.git?branch=feat/disable_selector_compression#031495f62172c144f392848043da2064261c13dc" dependencies = [ "ark-std", "blake2b_simd", @@ -2243,7 +2243,7 @@ dependencies = [ [[package]] name = "keccak256" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "env_logger 0.9.3", "eth-types", @@ -2443,7 +2443,7 @@ dependencies = [ [[package]] name = "mock" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "eth-types", "ethers-core 0.17.0", @@ -2458,7 +2458,7 @@ dependencies = [ [[package]] name = "mpt-zktrie" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "bus-mapping", "eth-types", @@ -4683,7 +4683,7 @@ checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" [[package]] name = "zkevm-circuits" version = "0.1.0" -source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#ba4f7fe610e920c173e2acf3c276e8d048b97854" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=integrate-dynamic-proof-agg#53bfb3e95f526fbe13ac78b73075dad30df18931" dependencies = [ "array-init", "bus-mapping", diff --git a/Cargo.toml b/Cargo.toml index d14d3648a..73db3297b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = [ ] [patch."https://github.com/privacy-scaling-explorations/halo2.git"] -halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "develop" } +halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "feat/disable_selector_compression" } [patch."https://github.com/privacy-scaling-explorations/poseidon.git"] poseidon = { git = "https://github.com/scroll-tech/poseidon.git", branch = "scroll-dev-0220" } [patch."https://github.com/privacy-scaling-explorations/halo2wrong.git"] diff --git a/README.md b/README.md index 052e4ca0e..4eb43a466 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ make download-setup -e degree=DEGREE params_dir=PARAMS_DIR ### Testing -`make test-chunk-prove` is the main testing entry point for the multi-level circuit constraint system of scroll-zkevm. Developers could understand how the system works by reading the codes of this test. +`make test-chunk-prove` and `make test-agg-prove` are the main testing entries for multi-level circuit constraint system of scroll-prover. Developers could understand how the system works by reading the codes of these tests. Besides it, `make test-inner-prove` could be used to test the first-level circuit, and `make-comp-prove` could be used to test two-layers compression circuits. diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index b8de7144a..35f2282ad 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ffi" -version = "0.4.0" +version = "0.5.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/ffi/src/prove.rs b/ffi/src/prove.rs index 3f8a5819b..801ab7e94 100644 --- a/ffi/src/prove.rs +++ b/ffi/src/prove.rs @@ -1,19 +1,32 @@ use crate::utils::{c_char_to_str, c_char_to_vec, vec_to_c_char}; use libc::c_char; -use prover::{utils::init_env_and_log, zkevm}; +use prover::{aggregator, config::ALL_AGG_DEGREES, utils::init_env_and_log, zkevm}; use std::cell::OnceCell; use types::eth::BlockTrace; -static mut PROVER: OnceCell = OnceCell::new(); +static mut CHUNK_PROVER: OnceCell = OnceCell::new(); +static mut AGG_PROVER: OnceCell = OnceCell::new(); +static mut AGG_CHUNK_TRACES: OnceCell>> = OnceCell::new(); /// # Safety #[no_mangle] -pub unsafe extern "C" fn init_prover(params_path: *const c_char, _seed_path: *const c_char) { - init_env_and_log("ffi_prove"); +pub unsafe extern "C" fn init_chunk_prover(params_dir: *const c_char) { + init_env_and_log("ffi_chunk_prove"); - let params_path = c_char_to_str(params_path); - let p = zkevm::Prover::from_params_dir(params_path); - PROVER.set(p).unwrap(); + let params_dir = c_char_to_str(params_dir); + let prover = zkevm::Prover::from_params_dir(params_dir); + CHUNK_PROVER.set(prover).unwrap(); +} + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn init_agg_prover(params_dir: *const c_char) { + init_env_and_log("ffi_agg_prove"); + + let params_dir = c_char_to_str(params_dir); + + let prover = aggregator::Prover::from_params_dir(params_dir, &ALL_AGG_DEGREES); + AGG_PROVER.set(prover).unwrap(); } /// # Safety @@ -21,7 +34,11 @@ pub unsafe extern "C" fn init_prover(params_path: *const c_char, _seed_path: *co pub unsafe extern "C" fn create_block_proof(trace_char: *const c_char) -> *const c_char { let trace_vec = c_char_to_vec(trace_char); let trace = serde_json::from_slice::(&trace_vec).unwrap(); - let proof = PROVER.get_mut().unwrap().gen_chunk_proof(&[trace]).unwrap(); + let proof = CHUNK_PROVER + .get_mut() + .unwrap() + .gen_chunk_proof(&[trace]) + .unwrap(); let proof_bytes = serde_json::to_vec(&proof).unwrap(); vec_to_c_char(proof_bytes) } @@ -31,7 +48,7 @@ pub unsafe extern "C" fn create_block_proof(trace_char: *const c_char) -> *const pub unsafe extern "C" fn create_chunk_proof(trace_char: *const c_char) -> *const c_char { let trace_vec = c_char_to_vec(trace_char); let traces = serde_json::from_slice::>(&trace_vec).unwrap(); - let proof = PROVER + let proof = CHUNK_PROVER .get_mut() .unwrap() .gen_chunk_proof(traces.as_slice()) @@ -39,3 +56,43 @@ pub unsafe extern "C" fn create_chunk_proof(trace_char: *const c_char) -> *const let proof_bytes = serde_json::to_vec(&proof).unwrap(); vec_to_c_char(proof_bytes) } + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn add_agg_chunk_trace(trace_char: *const c_char) { + let trace_vec = c_char_to_vec(trace_char); + let trace = serde_json::from_slice::>(&trace_vec).unwrap(); + + AGG_CHUNK_TRACES + .get_mut() + .or_else(|| { + AGG_CHUNK_TRACES.set(vec![]).unwrap(); + AGG_CHUNK_TRACES.get_mut() + }) + .unwrap() + .push(trace); +} + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn clear_agg_chunk_traces() { + if let Some(chunk_traces) = AGG_CHUNK_TRACES.get_mut() { + chunk_traces.clear(); + } +} + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn create_agg_proof() -> *const c_char { + // Consume the chunk traces (take and clear). + let chunk_traces = AGG_CHUNK_TRACES.take().unwrap(); + + let proof = AGG_PROVER + .get_mut() + .unwrap() + .gen_agg_proof(chunk_traces) + .unwrap(); + + let proof_bytes = serde_json::to_vec(&proof).unwrap(); + vec_to_c_char(proof_bytes) +} diff --git a/ffi/src/verify.rs b/ffi/src/verify.rs index 30b3f149b..ab919dd8f 100644 --- a/ffi/src/verify.rs +++ b/ffi/src/verify.rs @@ -1,30 +1,64 @@ use crate::utils::{c_char_to_str, c_char_to_vec}; use libc::c_char; -use prover::{utils::init_env_and_log, zkevm, Proof}; +use prover::{aggregator, config::AGG_LAYER4_DEGREE, utils::init_env_and_log, zkevm, Proof}; use std::{fs::File, io::Read}; -static mut VERIFIER: Option<&zkevm::Verifier> = None; +static mut CHUNK_VERIFIER: Option<&zkevm::Verifier> = None; +static mut AGG_VERIFIER: Option<&aggregator::Verifier> = None; /// # Safety #[no_mangle] -pub unsafe extern "C" fn init_verifier(params_path: *const c_char, agg_vk_path: *const c_char) { - init_env_and_log("ffi_verify"); +pub unsafe extern "C" fn init_chunk_verifier(params_dir: *const c_char, vk_path: *const c_char) { + init_env_and_log("ffi_chunk_verify"); - let params_path = c_char_to_str(params_path); - let agg_vk_path = c_char_to_str(agg_vk_path); - let mut f = File::open(agg_vk_path).unwrap(); - let mut agg_vk = vec![]; - f.read_to_end(&mut agg_vk).unwrap(); + let vk_path = c_char_to_str(vk_path); + let mut f = File::open(vk_path).unwrap(); + let mut vk = vec![]; + f.read_to_end(&mut vk).unwrap(); - let v = Box::new(zkevm::Verifier::from_params_dir(params_path, Some(agg_vk))); - VERIFIER = Some(Box::leak(v)) + let params_dir = c_char_to_str(params_dir); + let verifier = Box::new(zkevm::Verifier::from_params_dir(params_dir, Some(vk))); + + CHUNK_VERIFIER = Some(Box::leak(verifier)); +} + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn init_agg_verifier(params_dir: *const c_char, vk_path: *const c_char) { + init_env_and_log("ffi_agg_verify"); + + let vk_path = c_char_to_str(vk_path); + let mut f = File::open(vk_path).unwrap(); + let mut vk = vec![]; + f.read_to_end(&mut vk).unwrap(); + + let params_dir = c_char_to_str(params_dir); + let verifier = Box::new(aggregator::Verifier::from_params_dir( + params_dir, + *AGG_LAYER4_DEGREE, + Some(vk), + )); + + AGG_VERIFIER = Some(Box::leak(verifier)); } /// # Safety #[no_mangle] pub unsafe extern "C" fn verify_chunk_proof(proof: *const c_char) -> c_char { let proof_vec = c_char_to_vec(proof); - let chunk_proof = serde_json::from_slice::(proof_vec.as_slice()).unwrap(); - let verified = VERIFIER.unwrap().verify_chunk_proof(chunk_proof).is_ok(); + let proof = serde_json::from_slice::(proof_vec.as_slice()).unwrap(); + let verified = CHUNK_VERIFIER.unwrap().verify_chunk_proof(proof).is_ok(); + + verified as c_char +} + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn verify_agg_proof(proof: *const c_char) -> c_char { + let proof_vec = c_char_to_vec(proof); + let proof = serde_json::from_slice::(proof_vec.as_slice()).unwrap(); + + let verified = AGG_VERIFIER.unwrap().verify_agg_proof(proof).is_ok(); + verified as c_char } diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 8b19125f2..acd73705d 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -8,12 +8,12 @@ edition = "2021" [dependencies] halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" } -aggregator = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop" } -bus-mapping = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop" } -eth-types = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop" } -zkevm-circuits = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop", default-features = false, features = ["test","scroll","scroll-trace","shanghai"] } -mpt-zktrie = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop" } -mock = { git = "https://github.com/scroll-tech/zkevm-circuits", branch = "develop" } +aggregator = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "integrate-dynamic-proof-agg" } +bus-mapping = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "integrate-dynamic-proof-agg" } +eth-types = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "integrate-dynamic-proof-agg" } +zkevm-circuits = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "integrate-dynamic-proof-agg", default-features = false, features = ["test","scroll","scroll-trace","shanghai"] } +mpt-zktrie = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "integrate-dynamic-proof-agg" } +mock = { git = "https://github.com/scroll-tech/zkevm-circuits", branch = "integrate-dynamic-proof-agg" } snark-verifier = { git = "https://github.com/scroll-tech/snark-verifier", branch = "develop" } snark-verifier-sdk = { git = "https://github.com/scroll-tech/snark-verifier", branch = "develop" } diff --git a/prover/src/aggregator/prover.rs b/prover/src/aggregator/prover.rs index 023e5c0f4..274eaf120 100644 --- a/prover/src/aggregator/prover.rs +++ b/prover/src/aggregator/prover.rs @@ -1,11 +1,22 @@ -use crate::utils::{load_params, param_path_for_degree}; +use crate::{ + config::{AGG_LAYER1_DEGREE, AGG_LAYER2_DEGREE, AGG_LAYER3_DEGREE, AGG_LAYER4_DEGREE}, + utils::{chunk_trace_to_witness_block, gen_rng, load_params, param_path_for_degree}, + zkevm::circuit::SuperCircuit, + Proof, +}; +use anyhow::Result; use halo2_proofs::{ halo2curves::bn256::{Bn256, G1Affine}, plonk::ProvingKey, poly::{commitment::Params, kzg::commitment::ParamsKZG}, }; -use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::{ + collections::{BTreeMap, BTreeSet, HashMap}, + env::set_var, +}; +use types::eth::BlockTrace; +mod aggregation; mod chunk; mod common; mod compression; @@ -63,4 +74,60 @@ impl Prover { pk_map: HashMap::new(), } } + + pub fn gen_agg_proof(&mut self, chunk_traces: Vec>) -> Result { + // Convert chunk traces to witness blocks. + let witness_blocks = chunk_traces + .into_iter() + .map(chunk_trace_to_witness_block) + .collect::>>()?; + + // Convert witness blocks to chunk hashes. + let chunk_hashes: Vec<_> = witness_blocks.iter().map(Into::into).collect(); + + // Generate chunk snarks. + let chunk_snarks = witness_blocks + .into_iter() + .map(|block| self.gen_chunk_snark::(&block)) + .collect::>>()?; + + // Generate compression wide snarks (layer-1). + set_var("VERIFY_CONFIG", "./configs/agg_layer1.config"); + let layer1_snarks = chunk_snarks + .into_iter() + .map(|snark| { + let rng = gen_rng(); + self.gen_comp_snark("agg_layer1", true, *AGG_LAYER1_DEGREE, rng, snark) + }) + .collect::>>()?; + + // Generate compression thin snarks (layer-2). + set_var("VERIFY_CONFIG", "./configs/agg_layer2.config"); + let layer2_snarks: Vec<_> = layer1_snarks + .into_iter() + .map(|snark| { + let rng = gen_rng(); + self.gen_comp_snark("agg_layer2", false, *AGG_LAYER2_DEGREE, rng, snark) + }) + .collect::>>()?; + + // Generate aggregation snark (layer-3). + set_var("VERIFY_CONFIG", "./configs/agg_layer3.config"); + let rng = gen_rng(); + let layer3_snark = self.gen_agg_snark( + "agg_layer3", + *AGG_LAYER3_DEGREE, + rng, + &chunk_hashes, + &layer2_snarks, + ); + + // Generate final compression snarks (layer-4). + set_var("VERIFY_CONFIG", "./configs/agg_layer4.config"); + let rng = gen_rng(); + let layer4_snark = + self.gen_comp_snark("agg_layer4", false, *AGG_LAYER4_DEGREE, rng, layer3_snark)?; + + Proof::from_snark(&self.pk_map["agg_layer4"], &layer4_snark) + } } diff --git a/prover/src/aggregator/prover/aggregation.rs b/prover/src/aggregator/prover/aggregation.rs new file mode 100644 index 000000000..54465d613 --- /dev/null +++ b/prover/src/aggregator/prover/aggregation.rs @@ -0,0 +1,24 @@ +use super::Prover; +use aggregator::{AggregationCircuit, ChunkHash}; +use rand::Rng; +use snark_verifier_sdk::Snark; + +impl Prover { + pub fn gen_agg_snark( + &mut self, + id: &str, + degree: u32, + mut rng: impl Rng + Send, + chunk_hashes: &[ChunkHash], + prev_snarks: &[Snark], + ) -> Snark { + todo!() + +/* + let circuit = + AggregationCircuit::new(self.params(degree), prev_snarks, &mut rng, chunk_hashes); + + self.gen_snark(id, degree, &mut rng, circuit) +*/ + } +} diff --git a/prover/src/aggregator/prover/common.rs b/prover/src/aggregator/prover/common.rs index 139a2ae85..bb5fcf260 100644 --- a/prover/src/aggregator/prover/common.rs +++ b/prover/src/aggregator/prover/common.rs @@ -96,7 +96,8 @@ impl Prover { } tick(&format!("Before generate outer pk of {}", &id)); - let pk = gen_pk(self.params(degree), circuit, None); + // let pk = gen_pk(self.params(degree), circuit, None); + let pk = keygen_pk2(self.params(degree), circuit).unwrap(); tick(&format!("After generate outer pk of {}", &id)); self.pk_map.insert(id.to_string(), pk); diff --git a/prover/src/aggregator/prover/compression.rs b/prover/src/aggregator/prover/compression.rs index 868475634..b990e2361 100644 --- a/prover/src/aggregator/prover/compression.rs +++ b/prover/src/aggregator/prover/compression.rs @@ -15,7 +15,7 @@ impl Prover { prev_snark: Snark, ) -> Result { let circuit = CompressionCircuit::new(self.params(degree), prev_snark, is_fresh, &mut rng) - .map_err(|err| anyhow!("Failed to construct compression circuit: {err:?}"))?; + .map_err(|err| anyhow!("Failed to construct compression circuit: {err:?}"))?; Ok(self.gen_snark(id, degree, &mut rng, circuit)) } @@ -29,7 +29,7 @@ impl Prover { prev_snark: Snark, ) -> Result { let circuit = CompressionCircuit::new(self.params(degree), prev_snark, is_fresh, &mut rng) - .map_err(|err| anyhow!("Failed to construct compression circuit: {err:?}"))?; + .map_err(|err| anyhow!("Failed to construct compression circuit: {err:?}"))?; self.gen_evm_proof(id, degree, &mut rng, circuit) } diff --git a/prover/src/test_util/aggregator.rs b/prover/src/test_util/aggregator.rs index 8f58b7588..ae91f52fd 100644 --- a/prover/src/test_util/aggregator.rs +++ b/prover/src/test_util/aggregator.rs @@ -5,11 +5,32 @@ use crate::{ zkevm::circuit::SuperCircuit, Proof, }; +use aggregator::ChunkHash; use halo2_proofs::halo2curves::bn256::Fr; use snark_verifier_sdk::Snark; use std::{env::set_var, path::PathBuf}; use zkevm_circuits::evm_circuit::witness::Block; +pub fn load_or_gen_agg_snark( + output_dir: &str, + id: &str, + degree: u32, + prover: &mut Prover, + chunk_hashes: &[ChunkHash], + prev_snarks: &[Snark], +) -> Snark { + set_var("VERIFY_CONFIG", format!("./configs/{id}.config")); + let file_path = format!("{output_dir}/{id}_snark.json"); + + load_snark(&file_path).unwrap().unwrap_or_else(|| { + let rng = gen_rng(); + let snark = prover.gen_agg_snark(id, degree, rng, chunk_hashes, prev_snarks); + write_snark(&file_path, &snark); + + snark + }) +} + pub fn gen_comp_evm_proof( output_dir: &str, id: &str, @@ -18,6 +39,8 @@ pub fn gen_comp_evm_proof( prover: &mut Prover, prev_snark: Snark, ) -> Proof { + // gupeng + set_var("VERIFY_CONFIG", format!("./configs/{id}.config")); set_var("COMPRESSION_CONFIG", format!("./configs/{id}.config")); let rng = gen_rng(); @@ -55,6 +78,8 @@ pub fn load_or_gen_comp_snark( prover: &mut Prover, prev_snark: Snark, ) -> Snark { + // gupeng + set_var("VERIFY_CONFIG", format!("./configs/{id}.config")); set_var("COMPRESSION_CONFIG", format!("./configs/{id}.config")); let file_path = format!("{output_dir}/{id}_snark.json"); diff --git a/prover/tests/aggregation_tests.rs b/prover/tests/aggregation_tests.rs new file mode 100644 index 000000000..92ca03397 --- /dev/null +++ b/prover/tests/aggregation_tests.rs @@ -0,0 +1,116 @@ +use aggregator::CompressionCircuit; +use prover::{ + aggregator::{Prover, Verifier}, + config::{ + AGG_LAYER1_DEGREE, AGG_LAYER2_DEGREE, AGG_LAYER3_DEGREE, AGG_LAYER4_DEGREE, ALL_AGG_DEGREES, + }, + test_util::{ + aggregator::{ + gen_comp_evm_proof, load_or_gen_agg_snark, load_or_gen_chunk_snark, + load_or_gen_comp_snark, + }, + load_block_traces_for_test, PARAMS_DIR, + }, + utils::{chunk_trace_to_witness_block, init_env_and_log}, +}; +use std::{env::set_var, path::Path}; + +#[cfg(feature = "prove_verify")] +#[test] +fn test_agg_prove_verify() { + // Init, load block traces and construct prover. + + let output_dir = init_env_and_log("agg_tests"); + log::info!("Initialized ENV and created output-dir {output_dir}"); + + let mut chunk_traces = vec![]; + set_var("TRACE_PATH", "./tests/traces/erc20/1_transfer.json"); + chunk_traces.push(load_block_traces_for_test().1); + set_var("TRACE_PATH", "./tests/traces/erc20/10_transfer.json"); + chunk_traces.push(load_block_traces_for_test().1); + log::info!("Loaded chunk-traces"); + + // Convert chunk traces to witness blocks. + let witness_blocks: Vec<_> = chunk_traces + .into_iter() + .map(|trace| chunk_trace_to_witness_block(trace).unwrap()) + .collect(); + log::info!("Got witness-blocks"); + + // Convert witness blocks to chunk hashes. + let chunk_hashes: Vec<_> = witness_blocks.iter().map(Into::into).collect(); + log::info!("Got chunk-hashes"); + + let mut prover = Prover::from_params_dir(PARAMS_DIR, &*ALL_AGG_DEGREES); + log::info!("Constructed prover"); + + // Load or generate chunk snarks. + let chunk_snarks: Vec<_> = witness_blocks + .into_iter() + .enumerate() + .map(|(i, block)| load_or_gen_chunk_snark(&output_dir, &i.to_string(), &mut prover, block)) + .collect(); + log::info!("Got chunk-snarks"); + + // Load or generate compression wide snarks (layer-1). + let layer1_snarks: Vec<_> = chunk_snarks + .into_iter() + .map(|snark| { + load_or_gen_comp_snark( + &output_dir, + "agg_layer1", + true, + *AGG_LAYER1_DEGREE, + &mut prover, + snark, + ) + }) + .collect(); + log::info!("Got compression wide snarks (layer-1)"); + + // Load or generate compression thin snarks (layer-2). + let layer2_snarks: Vec<_> = layer1_snarks + .into_iter() + .map(|snark| { + load_or_gen_comp_snark( + &output_dir, + "agg_layer2", + false, + *AGG_LAYER2_DEGREE, + &mut prover, + snark, + ) + }) + .collect(); + log::info!("Got compression thin snarks (layer-2)"); + + // Load or generate aggregation snark (layer-3). + let layer3_snark = load_or_gen_agg_snark( + &output_dir, + "agg_layer3", + *AGG_LAYER3_DEGREE, + &mut prover, + &chunk_hashes, + &layer2_snarks, + ); + log::info!("Got aggregation snark (layer-3)"); + + // Load or generate compression EVM proof (layer-4). + let proof = gen_comp_evm_proof( + &output_dir, + "agg_layer4", + false, + *AGG_LAYER4_DEGREE, + &mut prover, + layer3_snark, + ); + log::info!("Got compression EVM proof (layer-4)"); + + // Construct verifier and EVM verify. + let params = prover.params(*AGG_LAYER4_DEGREE).clone(); + let vk = prover.pk("agg_layer4").unwrap().get_vk().clone(); + let verifier = Verifier::new(params, Some(vk)); + let yul_file_path = format!("{output_dir}/agg_verifier.yul"); + verifier.evm_verify::(&proof, Some(Path::new(&yul_file_path))); + log::info!("Finish EVM verify"); +} diff --git a/prover/tests/compression_tests.rs b/prover/tests/compression_tests.rs index 6258e616a..e3c007635 100644 --- a/prover/tests/compression_tests.rs +++ b/prover/tests/compression_tests.rs @@ -1,14 +1,18 @@ use aggregator::CompressionCircuit; +use halo2_proofs::{halo2curves::bn256::G1Affine, plonk::VerifyingKey, SerdeFormat}; use prover::{ aggregator::{Prover, Verifier}, config::{AGG_LAYER1_DEGREE, AGG_LAYER2_DEGREE, INNER_DEGREE}, + io::serialize_vk, test_util::{ aggregator::{gen_comp_evm_proof, load_or_gen_chunk_snark, load_or_gen_comp_snark}, load_block_traces_for_test, PARAMS_DIR, }, utils::{chunk_trace_to_witness_block, init_env_and_log}, }; -use std::path::Path; +use snark_verifier::pcs::kzg::{Bdfg21, Kzg}; +use snark_verifier_sdk::{evm_verify, gen_evm_verifier, verify_snark_shplonk, CircuitExt}; +use std::{io::Cursor, path::Path}; #[cfg(feature = "prove_verify")] #[test] @@ -56,10 +60,23 @@ fn test_comp_prove_verify() { ); log::info!("Got compression EVM proof (layer-2)"); + // Test vk deserialization. + let vk1 = prover.pk("agg_layer2").unwrap().get_vk().clone(); + let raw_vk1 = serialize_vk(&vk1); + let mut vk2 = VerifyingKey::::read::<_, CompressionCircuit>( + &mut Cursor::new(&raw_vk1), + SerdeFormat::Processed, + ) + .unwrap(); + let raw_vk2 = serialize_vk(&vk2); + assert_eq!(raw_vk1, raw_vk2); + log::error!("test - vk1 = {:#?}", vk1); + log::error!("test - vk2 = {:#?}", vk2); + // Construct verifier and EVM verify. let params = prover.params(*AGG_LAYER2_DEGREE).clone(); - let vk = prover.pk("agg_layer2").unwrap().get_vk().clone(); - let verifier = Verifier::new(params, Some(vk)); + // let vk = prover.pk("agg_layer2").unwrap().get_vk().clone(); + let verifier = Verifier::new(params, Some(vk2)); let yul_file_path = format!("{output_dir}/comp_verifier.yul"); verifier.evm_verify::(&proof, Some(Path::new(&yul_file_path))); log::info!("Finish EVM verify"); diff --git a/types/Cargo.toml b/types/Cargo.toml index ab73ebe5b..6e8fa53c3 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -4,7 +4,7 @@ version = "0.4.0" edition = "2021" [dependencies] -eth-types = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop" } +eth-types = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "integrate-dynamic-proof-agg" } base64 = "0.13.0" blake2 = "0.10.3" ethers-core = "0.17.0"