Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Commit 0b9e24f

Browse files
committedApr 19, 2024
wip
1 parent 2325e9a commit 0b9e24f

File tree

11 files changed

+488
-990
lines changed

11 files changed

+488
-990
lines changed
 

‎Cargo.lock

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

‎Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ serde_json = "1.0"
2727
tokio = { version = "1.32", features = ["full"] }
2828

2929
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "v1.1" }
30-
prover = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.10.0rc3", default-features = false, features = ["parallel_syn", "scroll", "shanghai"] }
31-
zkevm-circuits = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.10.0rc3", default-features = false, features = ["parallel_syn", "scroll", "shanghai"] }
30+
prover = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.10.3", default-features = false, features = ["parallel_syn", "scroll", "shanghai"] }
31+
zkevm-circuits = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.10.3", default-features = false, features = ["parallel_syn", "scroll", "shanghai"] }
3232

3333
integration = { path = "integration" }
3434

‎Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ CURRENTDATE=`date +"%Y-%m-%d"`
22

33
CHAIN_ID ?= 534352
44
export CHAIN_ID
5+
RUST_MIN_STACK ?= 100000000
6+
export RUST_MIN_STACK
57

68
help: ## Display this help screen
79
@grep -h \
@@ -44,8 +46,8 @@ test-inner-prove:
4446
test-chunk-prove:
4547
@cargo test --features prove_verify --release test_chunk_prove_verify
4648

47-
test-agg-prove:
48-
@cargo test --features prove_verify --release test_agg_prove_verify
49+
test-e2e-prove:
50+
@cargo test --features prove_verify --release test_e2e_prove_verify
4951

5052
test-batch-prove:
5153
@cargo test --features prove_verify --release test_batch_prove_verify

‎integration/src/test_util.rs

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,51 +20,28 @@ pub use proof::{
2020
pub const ASSETS_DIR: &str = "./test_assets";
2121
pub const PARAMS_DIR: &str = "./test_params";
2222

23-
pub fn parse_trace_path_from_mode(mode: &str) -> &'static str {
24-
let trace_path = match mode {
25-
"empty" => "./tests/traces/bridge/01.json",
26-
"greeter" => "./tests/traces/greeter/setValue.json",
27-
"single" => "./tests/traces/erc20/1_transfer.json",
28-
"multiple" => "./tests/extra_traces/batch_495/chunk_495/block_8802.json",
29-
"multiswap" => "./tests/traces/multi_uniswapv2/router-swapExactTokensForTokens_34.json",
30-
"native" => "./tests/traces/native/transfer.json",
31-
"dao" => "./tests/traces/dao/dao-propose.json",
32-
"nft" => "./tests/traces/nft/mint.json",
33-
"sushi" => "./tests/traces/sushi/chef-withdraw.json",
34-
_ => "./tests/extra_traces/batch_495/chunk_495/block_8802.json",
35-
};
36-
log::info!("using mode {:?}, testing with {:?}", mode, trace_path);
37-
trace_path
38-
}
39-
4023
pub fn load_block_traces_for_test() -> (Vec<String>, Vec<BlockTrace>) {
41-
let trace_path: String = read_env_var("TRACE_PATH", "".to_string());
42-
let paths: Vec<String> = if trace_path.is_empty() {
43-
// use mode
44-
let mode = read_env_var("MODE", "default".to_string());
45-
if mode.to_lowercase() == "batch" || mode.to_lowercase() == "pack" {
46-
(1..=20)
47-
.map(|i| format!("tests/traces/bridge/{i:02}.json"))
48-
.collect()
49-
} else {
50-
vec![parse_trace_path_from_mode(&mode).to_string()]
51-
}
52-
} else if !std::fs::metadata(&trace_path).unwrap().is_dir() {
24+
let trace_path: String = read_env_var(
25+
"TRACE_PATH",
26+
"./tests/extra_traces/batch_495/chunk_495/block_8802.json".to_string(),
27+
);
28+
let paths: Vec<String> = if !std::fs::metadata(&trace_path).unwrap().is_dir() {
5329
vec![trace_path]
5430
} else {
55-
load_batch_traces(&trace_path).0
31+
load_chunk_traces(&trace_path).0
5632
};
5733
log::info!("test cases traces: {:?}", paths);
5834
let traces: Vec<_> = paths.iter().map(get_block_trace_from_file).collect();
5935
(paths, traces)
6036
}
6137

62-
fn load_batch_traces(batch_dir: &str) -> (Vec<String>, Vec<BlockTrace>) {
63-
let file_names: Vec<String> = glob(&format!("{batch_dir}/**/*.json"))
38+
fn load_chunk_traces(chunk_dir: &str) -> (Vec<String>, Vec<BlockTrace>) {
39+
// Nested dirs are not allowed
40+
let file_names: Vec<String> = glob(&format!("{chunk_dir}/*.json"))
6441
.unwrap()
6542
.map(|p| p.unwrap().to_str().unwrap().to_string())
6643
.collect();
67-
log::info!("test batch with {:?}", file_names);
44+
log::info!("test chunk with {:?}", file_names);
6845
let mut names_and_traces = file_names
6946
.into_iter()
7047
.map(|trace_path| {
@@ -86,3 +63,16 @@ fn load_batch_traces(batch_dir: &str) -> (Vec<String>, Vec<BlockTrace>) {
8663
);
8764
names_and_traces.into_iter().map(|(f, t, _)| (f, t)).unzip()
8865
}
66+
67+
pub fn load_batch() -> anyhow::Result<Vec<String>> {
68+
let batch_dir = read_env_var("TRACE_PATH", "./tests/extra_traces/batch_24".to_string());
69+
let mut sorted_dirs: Vec<String> = std::fs::read_dir(batch_dir)?
70+
.filter_map(|entry| entry.ok())
71+
.map(|entry| entry.path())
72+
.filter(|path| path.is_dir())
73+
.map(|path| path.to_string_lossy().into_owned())
74+
.collect::<Vec<String>>();
75+
sorted_dirs.sort();
76+
log::info!("batch content: {:?}", sorted_dirs);
77+
Ok(sorted_dirs)
78+
}

‎integration/src/test_util/proof.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,34 @@ use prover::{
77
};
88
use std::env;
99

10-
pub fn gen_and_verify_batch_proofs(agg_prover: &mut Prover, layer3_snark: Snark, output_dir: &str) {
11-
let evm_proof = gen_and_verify_normal_and_evm_proofs(
10+
pub fn gen_and_verify_batch_proofs(
11+
agg_prover: &mut Prover,
12+
layer3_snark: Snark,
13+
output_dir: &str,
14+
assets_dir: &str,
15+
) {
16+
let (_normal_proof, evm_proof) = gen_and_verify_normal_and_evm_proofs(
1217
&mut agg_prover.inner,
1318
LayerId::Layer4,
1419
layer3_snark,
1520
Some(output_dir),
16-
)
17-
.1;
18-
verify_batch_proof(evm_proof, output_dir);
21+
);
22+
verify_batch_proof(evm_proof, output_dir, assets_dir);
1923
}
2024

25+
// So here even for chunk, we generate and verify a evm proof
26+
// TODO: remove this?
2127
pub fn gen_and_verify_chunk_proofs(
2228
zkevm_prover: &mut zkevm::Prover,
2329
layer1_snark: Snark,
2430
output_dir: &str,
2531
) {
26-
let normal_proof = gen_and_verify_normal_and_evm_proofs(
32+
let (normal_proof, _evm_proof) = gen_and_verify_normal_and_evm_proofs(
2733
&mut zkevm_prover.inner,
2834
LayerId::Layer2,
2935
layer1_snark,
3036
Some(output_dir),
31-
)
32-
.0;
37+
);
3338
verify_chunk_proof(&zkevm_prover.inner, normal_proof, output_dir);
3439
}
3540

@@ -99,12 +104,12 @@ fn gen_normal_proof(
99104
snark
100105
}
101106

102-
fn verify_batch_proof(evm_proof: EvmProof, output_dir: &str) {
107+
fn verify_batch_proof(evm_proof: EvmProof, output_dir: &str, assets_dir: &str) {
103108
let batch_proof = BatchProof::from(evm_proof.proof);
104109
batch_proof.dump(output_dir, "agg").unwrap();
105110
batch_proof.clone().assert_calldata();
106111

107-
let verifier = Verifier::from_dirs(PARAMS_DIR, output_dir);
112+
let verifier = Verifier::from_dirs(PARAMS_DIR, assets_dir);
108113
log::info!("Constructed aggregator verifier");
109114

110115
assert!(verifier.verify_agg_evm_proof(batch_proof));

‎integration/tests/aggregation_tests.rs

Lines changed: 0 additions & 140 deletions
This file was deleted.

‎integration/tests/batch_tests.rs

Lines changed: 122 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,100 @@
1-
use integration::test_util::{gen_and_verify_batch_proofs, PARAMS_DIR};
1+
use integration::test_util::{
2+
gen_and_verify_batch_proofs, load_batch, load_block_traces_for_test, PARAMS_DIR,
3+
};
24
use prover::{
3-
aggregator::Prover, proof::from_json_file, utils::init_env_and_log, ChunkHash, ChunkProof,
5+
aggregator::Prover,
6+
config::LayerId,
7+
proof::from_json_file,
8+
utils::{chunk_trace_to_witness_block, init_env_and_log},
9+
BatchHash, BatchProof, ChunkHash, ChunkProof, CompressionCircuit,
410
};
511
use serde_derive::{Deserialize, Serialize};
612
use std::{env, fs, path::PathBuf};
713

8-
#[cfg(feature = "prove_verify")]
14+
//#[cfg(feature = "prove_verify")]
915
#[test]
1016
fn test_batch_prove_verify() {
1117
let output_dir = init_env_and_log("batch_tests");
1218
log::info!("Initialized ENV and created output-dir {output_dir}");
1319

14-
let chunk_hashes_proofs = load_chunk_hashes_and_proofs("tests/test_data", "1", &output_dir);
15-
let mut batch_prover = new_batch_prover(&output_dir);
16-
prove_and_verify_batch(&output_dir, &mut batch_prover, chunk_hashes_proofs);
17-
}
20+
// let batch_task = "tests/test_data/full_proof_1.json";
21+
let batch_task = "tests/test_data/batch_task_69776.json";
22+
let assets_dir = "assets";
23+
let chunk_hashes_proofs = load_batch_proving_task(batch_task, &output_dir);
1824

19-
#[cfg(feature = "prove_verify")]
20-
#[test]
21-
fn test_batches_with_each_chunk_num_prove_verify() {
22-
let output_dir = init_env_and_log("batches_with_each_chunk_num_tests");
23-
log::info!("Initialized ENV and created output-dir {output_dir}");
25+
env::set_var("AGG_VK_FILENAME", "agg_vk.vkey");
26+
env::set_var("CHUNK_PROTOCOL_FILENAME", "chunk.protocol");
27+
let mut batch_prover = Prover::from_dirs(PARAMS_DIR, assets_dir);
28+
log::info!("Constructed batch prover");
2429

25-
let chunk_hashes_proofs = load_chunk_hashes_and_proofs("tests/test_data", "2", &output_dir);
26-
let mut batch_prover = new_batch_prover(&output_dir);
30+
let chunk_num = chunk_hashes_proofs.len();
31+
log::info!("Prove batch BEGIN: chunk_num = {chunk_num}");
2732

28-
// Iterate over chunk proofs to test with 1 - 15 chunks (in a batch).
29-
for i in 0..chunk_hashes_proofs.len() {
30-
let mut output_dir = PathBuf::from(&output_dir);
31-
output_dir.push(format!("batch_{}", i + 1));
32-
fs::create_dir_all(&output_dir).unwrap();
33+
// Load or generate aggregation snark (layer-3).
34+
let layer3_snark = batch_prover
35+
.load_or_gen_last_agg_snark("agg", chunk_hashes_proofs, Some(&output_dir))
36+
.unwrap();
3337

34-
prove_and_verify_batch(
35-
&output_dir.to_string_lossy(),
36-
&mut batch_prover,
37-
chunk_hashes_proofs[..=i].to_vec(),
38-
);
39-
}
38+
let layer_id = LayerId::Layer4;
39+
40+
let id = layer_id.id();
41+
let degree = layer_id.degree();
42+
// Load or generate compression snark.
43+
let normal_proof = batch_prover
44+
.inner
45+
.load_or_gen_comp_snark(
46+
"normal",
47+
id,
48+
true,
49+
degree,
50+
layer3_snark.clone(),
51+
Some(&output_dir),
52+
)
53+
.unwrap();
54+
log::info!("Generated compression snark: {id}");
55+
56+
let evm_proof = batch_prover
57+
.inner
58+
.load_or_gen_comp_evm_proof("evm", id, true, degree, layer3_snark, Some(&output_dir))
59+
.unwrap();
60+
log::info!("Generated EVM proof: {id}");
61+
62+
let config_path = layer_id.config_path();
63+
64+
env::set_var("COMPRESSION_CONFIG", config_path);
65+
let vk = evm_proof.proof.vk::<CompressionCircuit>();
66+
67+
let params = batch_prover.inner.params(degree).clone();
68+
let verifier = prover::common::Verifier::<CompressionCircuit>::new(params, vk);
69+
log::info!("Constructed common verifier");
70+
71+
assert!(verifier.verify_snark(normal_proof));
72+
log::info!("Verified normal proof: {id}");
73+
74+
verifier.evm_verify(&evm_proof, Some(&output_dir));
75+
log::info!("Verified EVM proof: {id}");
76+
77+
let batch_proof = BatchProof::from(evm_proof.proof);
78+
batch_proof.dump(&output_dir, "agg").unwrap();
79+
batch_proof.clone().assert_calldata();
80+
81+
let verifier = prover::aggregator::Verifier::from_dirs(PARAMS_DIR, assets_dir);
82+
log::info!("Constructed aggregator verifier");
83+
84+
assert!(verifier.verify_agg_evm_proof(batch_proof));
85+
log::info!("Verified batch proof");
86+
87+
log::info!("Prove batch END: chunk_num = {chunk_num}");
4088
}
89+
4190
#[derive(Debug, Deserialize, Serialize)]
4291
struct BatchTaskDetail {
4392
chunk_infos: Vec<ChunkHash>,
4493
chunk_proofs: Vec<ChunkProof>,
4594
}
4695

47-
fn load_chunk_hashes_and_proofs(
48-
dir: &str,
49-
filename: &str,
50-
output_dir: &str,
51-
) -> Vec<(ChunkHash, ChunkProof)> {
52-
let batch_task_detail: BatchTaskDetail = from_json_file(dir, filename).unwrap();
96+
fn load_batch_proving_task(filename: &str, output_dir: &str) -> Vec<(ChunkHash, ChunkProof)> {
97+
let batch_task_detail: BatchTaskDetail = from_json_file(filename).unwrap();
5398
let chunk_hashes = batch_task_detail.chunk_infos;
5499
let chunk_proofs = batch_task_detail.chunk_proofs;
55100

@@ -59,13 +104,13 @@ fn load_chunk_hashes_and_proofs(
59104
.zip(chunk_proofs[..].iter().cloned())
60105
.collect();
61106

62-
// Dump chunk-procotol for further batch-proving.
63-
chunk_hashes_proofs
64-
.first()
65-
.unwrap()
66-
.1
67-
.dump(output_dir, "0")
68-
.unwrap();
107+
let dump_protocol = false;
108+
if dump_protocol {
109+
log::info!("dumping first chunk protocol to {output_dir}/chunk_protocol");
110+
let chunk_protocol = &chunk_hashes_proofs.first().unwrap().1.protocol;
111+
// Dump chunk-procotol for further batch-proving.
112+
prover::proof::dump_data(output_dir, "chunk.protocol", &chunk_protocol);
113+
}
69114

70115
log::info!(
71116
"Loaded chunk-hashes and chunk-proofs: total = {}",
@@ -74,29 +119,48 @@ fn load_chunk_hashes_and_proofs(
74119
chunk_hashes_proofs
75120
}
76121

77-
fn new_batch_prover(assets_dir: &str) -> Prover {
78-
env::set_var("AGG_VK_FILENAME", "vk_batch_agg.vkey");
79-
env::set_var("CHUNK_PROTOCOL_FILENAME", "chunk_chunk_0.protocol");
80-
let prover = Prover::from_dirs(PARAMS_DIR, assets_dir);
81-
log::info!("Constructed batch prover");
122+
#[test]
123+
fn test_batch_pi_consistency() {
124+
let output_dir = init_env_and_log("batch_pi");
125+
log::info!("Initialized ENV and created output-dir {output_dir}");
126+
let trace_paths = load_batch().unwrap();
82127

83-
prover
84-
}
128+
let max_num_snarks = 15;
129+
let chunk_traces: Vec<_> = trace_paths
130+
.iter()
131+
.map(|trace_path| {
132+
env::set_var("TRACE_PATH", trace_path);
133+
load_block_traces_for_test().1
134+
})
135+
.collect();
85136

86-
fn prove_and_verify_batch(
87-
output_dir: &str,
88-
batch_prover: &mut Prover,
89-
chunk_hashes_proofs: Vec<(ChunkHash, ChunkProof)>,
90-
) {
91-
let chunk_num = chunk_hashes_proofs.len();
92-
log::info!("Prove batch BEGIN: chunk_num = {chunk_num}");
137+
let mut chunk_hashes: Vec<ChunkHash> = chunk_traces
138+
.into_iter()
139+
.enumerate()
140+
.map(|(_i, chunk_trace)| {
141+
let witness_block = chunk_trace_to_witness_block(chunk_trace.clone()).unwrap();
142+
ChunkHash::from_witness_block(&witness_block, false)
143+
})
144+
.collect();
93145

94-
// Load or generate aggregation snark (layer-3).
95-
let layer3_snark = batch_prover
96-
.load_or_gen_last_agg_snark("agg", chunk_hashes_proofs, Some(output_dir))
97-
.unwrap();
146+
let real_chunk_count = chunk_hashes.len();
147+
if real_chunk_count < max_num_snarks {
148+
let mut padding_chunk_hash = chunk_hashes.last().unwrap().clone();
149+
padding_chunk_hash.is_padding = true;
98150

99-
gen_and_verify_batch_proofs(batch_prover, layer3_snark, output_dir);
151+
// Extend to MAX_AGG_SNARKS for both chunk hashes and layer-2 snarks.
152+
chunk_hashes
153+
.extend(std::iter::repeat(padding_chunk_hash).take(max_num_snarks - real_chunk_count));
154+
}
100155

101-
log::info!("Prove batch END: chunk_num = {chunk_num}");
156+
let batch_hash = BatchHash::construct(&chunk_hashes);
157+
let blob = batch_hash.blob_assignments();
158+
159+
let challenge = blob.challenge;
160+
let evaluation = blob.evaluation;
161+
println!("blob.challenge: {challenge:x}");
162+
println!("blob.evaluation: {evaluation:x}");
163+
for (i, elem) in blob.coefficients.iter().enumerate() {
164+
println!("blob.coeffs[{}]: {elem:x}", i);
165+
}
102166
}

‎integration/tests/e2e_tests.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use integration::test_util::{
2+
gen_and_verify_batch_proofs, load_batch, load_block_traces_for_test, ASSETS_DIR, PARAMS_DIR,
3+
};
4+
use prover::{
5+
aggregator::Prover,
6+
utils::{chunk_trace_to_witness_block, init_env_and_log, read_env_var},
7+
zkevm, BatchHash, BlockTrace, ChunkHash, ChunkProof,
8+
};
9+
use std::env;
10+
11+
#[cfg(feature = "prove_verify")]
12+
#[test]
13+
fn test_e2e_prove_verify() {
14+
let output_dir = init_env_and_log("e2e_tests");
15+
log::info!("Initialized ENV and created output-dir {output_dir}");
16+
17+
let chunk_paths = load_batch().unwrap();
18+
let chunk_hashes_proofs = gen_chunk_hashes_and_proofs(&output_dir, &chunk_paths);
19+
20+
let mut batch_prover = new_batch_prover(&output_dir);
21+
prove_and_verify_batch(&output_dir, &mut batch_prover, chunk_hashes_proofs);
22+
}
23+
24+
fn gen_chunk_hashes_and_proofs(
25+
output_dir: &str,
26+
chunk_paths: &[String],
27+
) -> Vec<(ChunkHash, ChunkProof)> {
28+
let mut zkevm_prover = zkevm::Prover::from_dirs(PARAMS_DIR, ASSETS_DIR);
29+
log::info!("Constructed zkevm prover");
30+
31+
let chunk_traces: Vec<Vec<BlockTrace>> = chunk_paths
32+
.iter()
33+
.map(|chunk_path| {
34+
env::set_var("TRACE_PATH", chunk_path);
35+
load_block_traces_for_test().1
36+
})
37+
.collect();
38+
39+
let chunk_hashes_proofs = chunk_traces
40+
.into_iter()
41+
.enumerate()
42+
.map(|(i, chunk_trace)| {
43+
let witness_block = chunk_trace_to_witness_block(chunk_trace.clone()).unwrap();
44+
let chunk_hash = ChunkHash::from_witness_block(&witness_block, false);
45+
46+
let proof = zkevm_prover
47+
.gen_chunk_proof(chunk_trace, Some(&i.to_string()), None, Some(output_dir))
48+
.unwrap();
49+
50+
(chunk_hash, proof)
51+
})
52+
.collect();
53+
54+
log::info!("Generated chunk hashes and proofs");
55+
chunk_hashes_proofs
56+
}
57+
58+
fn new_batch_prover(assets_dir: &str) -> Prover {
59+
env::set_var("AGG_VK_FILENAME", "vk_batch_agg.vkey");
60+
env::set_var("CHUNK_PROTOCOL_FILENAME", "chunk_chunk_0.protocol");
61+
let prover = Prover::from_dirs(PARAMS_DIR, assets_dir);
62+
log::info!("Constructed batch prover");
63+
64+
prover
65+
}
66+
67+
fn prove_and_verify_batch(
68+
output_dir: &str,
69+
batch_prover: &mut Prover,
70+
chunk_hashes_proofs: Vec<(ChunkHash, ChunkProof)>,
71+
) {
72+
// Load or generate aggregation snark (layer-3).
73+
let layer3_snark = batch_prover
74+
.load_or_gen_last_agg_snark("agg", chunk_hashes_proofs, Some(output_dir))
75+
.unwrap();
76+
77+
gen_and_verify_batch_proofs(batch_prover, layer3_snark, output_dir, output_dir);
78+
}

‎integration/tests/test_data/batch_task_69776.json

Lines changed: 231 additions & 0 deletions
Large diffs are not rendered by default.

‎integration/tests/test_data/full_proof_1.json

Lines changed: 0 additions & 366 deletions
This file was deleted.

‎integration/tests/test_data/full_proof_2.json

Lines changed: 0 additions & 366 deletions
This file was deleted.

0 commit comments

Comments
 (0)
This repository has been archived.