Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit f5577c6

Browse files
committed
root/super circuit multiple chunk mock test
1 parent 1ca62a0 commit f5577c6

File tree

8 files changed

+177
-79
lines changed

8 files changed

+177
-79
lines changed

.github/workflows/main-tests.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,16 @@ jobs:
133133
sudo chmod +x /usr/bin/solc
134134
- name: Update ERC20 git submodule
135135
run: git submodule update --init --recursive --checkout integration-tests/contracts/vendor/openzeppelin-contracts
136+
- name: Run root test
137+
uses: actions-rs/cargo@v1
138+
with:
139+
command: test
140+
args: --package zkevm-circuits --lib -- root_circuit::test::test_root_circuit_multiple_chunk --exact --ignored
136141
- name: Run heavy tests # heavy tests are run serially to avoid OOM
137142
uses: actions-rs/cargo@v1
138143
with:
139144
command: test
140145
args: --verbose --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks serial_ -- --ignored --test-threads 1
141-
142146
build:
143147
needs: [skip_check]
144148
if: |

bus-mapping/src/circuit_input_builder.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl FeatureConfig {
8888
const RW_BUFFER_SIZE: usize = 30;
8989

9090
/// Circuit Setup Parameters
91-
#[derive(Debug, Clone, Copy)]
91+
#[derive(Debug, Clone, Copy, PartialEq)]
9292
pub struct FixedCParams {
9393
///
9494
pub total_chunks: usize,
@@ -557,13 +557,9 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
557557
self.chunk_ctx.end_copy_index = next_copy_index;
558558
self.cur_chunk_mut().ctx = self.chunk_ctx.clone();
559559
if to_next {
560-
// here use `-1` to include previous set
560+
// add `-1` to include previous set and deal with transaction cross-chunk case
561561
self.chunk_ctx
562562
.bump(self.block_ctx.rwc.0, next_tx_index - 1, next_copy_index);
563-
// println!("bump last_call {:?}", last_call);
564-
if last_call.is_none() {
565-
panic!("??")
566-
}
567563
self.cur_chunk_mut().prev_last_call = last_call;
568564
}
569565
}
@@ -577,12 +573,10 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
577573
..ExecStep::default()
578574
};
579575
self.gen_chunk_associated_steps(&mut begin_chunk, RW::READ, tx);
580-
println!("in set begin chunk {:?}", begin_chunk);
581576
self.chunks[self.chunk_ctx.idx].begin_chunk = Some(begin_chunk);
582577
}
583578

584579
fn set_end_chunk(&mut self, next_step: &ExecStep, tx: Option<&Transaction>) {
585-
println!("before self.block_ctx.rwc.0 {}", self.block_ctx.rwc.0);
586580
// println!("next step {:?}", next_step);
587581
let mut end_chunk = ExecStep {
588582
exec_state: ExecState::EndChunk,
@@ -594,7 +588,6 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
594588
};
595589
self.gen_chunk_associated_steps(&mut end_chunk, RW::WRITE, tx);
596590
self.gen_chunk_padding(&mut end_chunk);
597-
println!("after self.block_ctx.rwc.0 {}", self.block_ctx.rwc.0);
598591
self.chunks[self.chunk_ctx.idx].end_chunk = Some(end_chunk);
599592
}
600593

zkevm-circuits/src/evm_circuit/execution/end_chunk.rs

+1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ mod test {
190190
.params({
191191
FixedCParams {
192192
total_chunks,
193+
max_evm_rows: 1 << 12,
193194
max_rws: total_rws / total_chunks,
194195
max_txs: 2,
195196
..Default::default()

zkevm-circuits/src/root_circuit/test.rs

+47-30
Original file line numberDiff line numberDiff line change
@@ -20,70 +20,87 @@ use rand::rngs::OsRng;
2020

2121
#[ignore = "Due to high memory requirement"]
2222
#[test]
23-
fn test_root_circuit() {
24-
let (params, protocol, proof, instance, rwtable_columns) = {
23+
fn test_root_circuit_multiple_chunk() {
24+
let (params, protocol, proofs, instances, rwtable_columns) = {
2525
// Preprocess
2626
const TEST_MOCK_RANDOMNESS: u64 = 0x100;
2727
let circuits_params = FixedCParams {
28-
total_chunks: 1,
28+
total_chunks: 3,
2929
max_txs: 1,
3030
max_withdrawals: 5,
3131
max_calldata: 32,
32-
max_rws: 256,
32+
max_rws: 100,
3333
max_copy_rows: 256,
3434
max_exp_steps: 256,
3535
max_bytecode: 512,
36-
max_evm_rows: 0,
36+
max_evm_rows: 1 << 12,
3737
max_keccak_rows: 0,
3838
};
39-
let (k, circuit, instance, _) =
39+
let (k, circuits, instances, _) =
4040
SuperCircuit::<_>::build(block_1tx(), circuits_params, TEST_MOCK_RANDOMNESS.into())
4141
.unwrap();
42+
assert!(circuits.len() > 0);
43+
assert!(circuits.len() == instances.len());
4244

4345
// get chronological_rwtable and byaddr_rwtable columns index
4446
let mut cs = ConstraintSystem::default();
45-
let config = SuperCircuit::configure_with_params(&mut cs, circuit.params());
47+
let config = SuperCircuit::configure_with_params(&mut cs, circuits[0].params());
4648
let rwtable_columns = config.get_rwtable_columns();
4749

4850
let params = ParamsKZG::<Bn256>::setup(k, OsRng);
49-
let pk = keygen_pk(&params, keygen_vk(&params, &circuit).unwrap(), &circuit).unwrap();
51+
let pk = keygen_pk(
52+
&params,
53+
keygen_vk(&params, &circuits[0]).unwrap(),
54+
&circuits[0],
55+
)
56+
.unwrap();
5057
let protocol = compile(
5158
&params,
5259
pk.get_vk(),
5360
Config::kzg()
54-
.with_num_instance(instance.iter().map(|instance| instance.len()).collect()),
61+
.with_num_instance(instances[0].iter().map(|instance| instance.len()).collect()),
5562
);
5663

57-
// Create proof
58-
let proof = {
59-
let mut transcript = PoseidonTranscript::new(Vec::new());
60-
create_proof::<KZGCommitmentScheme<_>, ProverGWC<_>, _, _, _, _>(
61-
&params,
62-
&pk,
63-
&[circuit],
64-
&[&instance.iter().map(Vec::as_slice).collect_vec()],
65-
OsRng,
66-
&mut transcript,
67-
)
68-
.unwrap();
69-
transcript.finalize()
70-
};
71-
72-
(params, protocol, proof, instance, rwtable_columns)
64+
let proofs: Vec<Vec<u8>> = circuits
65+
.into_iter()
66+
.zip(instances.iter())
67+
.map(|(circuit, instance)| {
68+
// Create proof
69+
let proof = {
70+
let mut transcript = PoseidonTranscript::new(Vec::new());
71+
create_proof::<KZGCommitmentScheme<_>, ProverGWC<_>, _, _, _, _>(
72+
&params,
73+
&pk,
74+
&[circuit],
75+
&[&instance.iter().map(Vec::as_slice).collect_vec()],
76+
OsRng,
77+
&mut transcript,
78+
)
79+
.unwrap();
80+
transcript.finalize()
81+
};
82+
proof
83+
})
84+
.collect();
85+
(params, protocol, proofs, instances, rwtable_columns)
7386
};
7487

7588
let user_challenge = UserChallenge {
7689
column_indexes: rwtable_columns,
7790
num_challenges: 2, // alpha, gamma
7891
};
92+
let snark_witnesses: Vec<_> = proofs
93+
.iter()
94+
.zip(instances.iter())
95+
.map(|(proof, instance)| {
96+
SnarkWitness::new(&protocol, Value::known(&instance), Value::known(&proof))
97+
})
98+
.collect();
99+
79100
let root_circuit = RootCircuit::<Bn256, Gwc<_>>::new(
80101
&params,
81102
&protocol,
82-
vec![SnarkWitness::new(
83-
&protocol,
84-
Value::known(&instance),
85-
Value::known(&proof),
86-
)],
103+
snark_witnesses,
87104
Some(&user_challenge),
88105
)
89106
.unwrap();

zkevm-circuits/src/state_circuit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ impl<F: Field> SubCircuit<F> for StateCircuit<F> {
506506
/// Return the minimum number of rows required to prove the block
507507
fn min_num_rows_block(_block: &witness::Block<F>, chunk: &Chunk<F>) -> (usize, usize) {
508508
(
509-
chunk.chrono_rws.0.values().flatten().count() + 1,
509+
chunk.by_address_rws.0.values().flatten().count() + 1,
510510
chunk.fixed_param.max_rws,
511511
)
512512
}

zkevm-circuits/src/super_circuit.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ use halo2_proofs::{
7979
circuit::{Layouter, SimpleFloorPlanner, Value},
8080
plonk::{Any, Circuit, Column, ConstraintSystem, Error, Expression},
8181
};
82+
use itertools::Itertools;
8283

8384
use std::array;
8485

@@ -560,8 +561,15 @@ impl<F: Field> SuperCircuit<F> {
560561
geth_data: GethData,
561562
circuits_params: FixedCParams,
562563
mock_randomness: F,
563-
) -> Result<(u32, Self, Vec<Vec<F>>, CircuitInputBuilder<FixedCParams>), bus_mapping::Error>
564-
{
564+
) -> Result<
565+
(
566+
u32,
567+
Vec<Self>,
568+
Vec<Vec<Vec<F>>>,
569+
CircuitInputBuilder<FixedCParams>,
570+
),
571+
bus_mapping::Error,
572+
> {
565573
let block_data =
566574
BlockData::new_from_geth_data_with_params(geth_data.clone(), circuits_params);
567575
let builder = block_data
@@ -581,18 +589,39 @@ impl<F: Field> SuperCircuit<F> {
581589
pub fn build_from_circuit_input_builder(
582590
builder: &CircuitInputBuilder<FixedCParams>,
583591
mock_randomness: F,
584-
) -> Result<(u32, Self, Vec<Vec<F>>), bus_mapping::Error> {
592+
) -> Result<(u32, Vec<Self>, Vec<Vec<Vec<F>>>), bus_mapping::Error> {
585593
let mut block = block_convert(builder).unwrap();
586-
let chunk = chunk_convert(&block, builder).unwrap().remove(0);
594+
let chunks = chunk_convert(&block, builder).unwrap();
587595
block.randomness = mock_randomness;
588596

589-
let (_, rows_needed) = Self::min_num_rows_block(&block, &chunk);
590-
let k = log2_ceil(Self::unusable_rows() + rows_needed);
597+
let (rows_needed, circuit_instance_pairs): (Vec<usize>, Vec<(_, _)>) = chunks
598+
.iter()
599+
.map(|chunk| {
600+
let (_, rows_needed) = Self::min_num_rows_block(&block, &chunk);
601+
602+
let circuit = SuperCircuit::new_from_block(&block, &chunk);
603+
let instance = circuit.instance();
604+
(rows_needed, (circuit, instance))
605+
})
606+
.unzip();
607+
608+
// assert all rows needed are equal
609+
rows_needed
610+
.iter()
611+
.tuple_windows()
612+
.for_each(|rows_needed: (&usize, &usize)| {
613+
assert!(
614+
rows_needed.0 == rows_needed.1,
615+
"mismatched super_circuit rows_needed {:?} != {:?}",
616+
rows_needed.0,
617+
rows_needed.1
618+
)
619+
});
620+
621+
let k = log2_ceil(Self::unusable_rows() + rows_needed[0]);
591622
log::debug!("super circuit uses k = {}", k);
592623

593-
let circuit = SuperCircuit::new_from_block(&block, &chunk);
594-
595-
let instance = circuit.instance();
596-
Ok((k, circuit, instance))
624+
let (circuits, instances) = circuit_instance_pairs.into_iter().unzip();
625+
Ok((k, circuits, instances))
597626
}
598627
}

zkevm-circuits/src/super_circuit/test.rs

+32-7
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ fn super_circuit_degree() {
3838
}
3939

4040
fn test_super_circuit(block: GethData, circuits_params: FixedCParams, mock_randomness: Fr) {
41-
let (k, circuit, instance, _) =
41+
let (k, circuits, instances, _) =
4242
SuperCircuit::<Fr>::build(block, circuits_params, mock_randomness).unwrap();
43-
let prover = MockProver::run(k, &circuit, instance).unwrap();
44-
let res = prover.verify();
45-
if let Err(err) = res {
46-
error!("Verification failures: {:#?}", err);
47-
panic!("Failed verification");
48-
}
43+
circuits
44+
.into_iter()
45+
.zip(instances.into_iter())
46+
.enumerate()
47+
.for_each(|(i, (circuit, instance))| {
48+
let prover = MockProver::run(k, &circuit, instance).unwrap();
49+
let res = prover.verify();
50+
if let Err(err) = res {
51+
error!("{}th supercircuit Verification failures: {:#?}", i, err);
52+
panic!("Failed verification");
53+
}
54+
});
4955
}
5056

5157
pub(crate) fn block_1tx() -> GethData {
@@ -193,6 +199,25 @@ fn serial_test_super_circuit_2tx_2max_tx() {
193199
test_super_circuit(block, circuits_params, Fr::from(TEST_MOCK_RANDOMNESS));
194200
}
195201

202+
#[ignore]
203+
#[test]
204+
fn serial_test_multi_chunk_super_circuit_2tx_2max_tx() {
205+
let block = block_2tx();
206+
let circuits_params = FixedCParams {
207+
total_chunks: 4,
208+
max_txs: 2,
209+
max_withdrawals: 5,
210+
max_calldata: 32,
211+
max_rws: 90,
212+
max_copy_rows: 256,
213+
max_exp_steps: 256,
214+
max_bytecode: 512,
215+
max_evm_rows: 0,
216+
max_keccak_rows: 0,
217+
};
218+
test_super_circuit(block, circuits_params, Fr::from(TEST_MOCK_RANDOMNESS));
219+
}
220+
196221
#[ignore]
197222
#[test]
198223
fn test_rw_table_commitment() {

0 commit comments

Comments
 (0)