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

Commit a7802e0

Browse files
committed
allow zero limb diff in state_circuit lexicoordering
1 parent 03d00ec commit a7802e0

File tree

10 files changed

+186
-222
lines changed

10 files changed

+186
-222
lines changed

bus-mapping/src/circuit_input_builder.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ impl CircuitInputBuilder<FixedCParams> {
666666
&mut self,
667667
eth_block: &EthBlock,
668668
geth_traces: &[eth_types::GethExecTrace],
669-
) -> Result<(ExecStep, Option<Call>), Error> {
669+
) -> Result<(Option<ExecStep>, Option<Call>), Error> {
670670
assert!(
671671
self.circuits_params.max_rws().unwrap_or_default() > self.rws_reserve(),
672672
"Fixed max_rws not enough for rws reserve"
@@ -687,13 +687,17 @@ impl CircuitInputBuilder<FixedCParams> {
687687
tx_id == eth_block.transactions.len(),
688688
tx_id as u64,
689689
)
690+
.map(|(exec_step, last_call)| (Some(exec_step), last_call))
690691
})
691-
.collect::<Result<Vec<(ExecStep, Option<Call>)>, _>>()?;
692-
let res = res.remove(res.len() - 1);
692+
.collect::<Result<Vec<(Option<ExecStep>, Option<Call>)>, _>>()?;
693693
// set eth_block
694694
self.block.eth_block = eth_block.clone();
695695
self.set_value_ops_call_context_rwc_eor();
696-
Ok(res)
696+
if !res.is_empty() {
697+
Ok(res.remove(res.len() - 1))
698+
} else {
699+
Ok((None, None))
700+
}
697701
}
698702

699703
/// Handle a block by handling each transaction to generate all the
@@ -706,6 +710,7 @@ impl CircuitInputBuilder<FixedCParams> {
706710
println!("--------------{:?}", self.circuits_params);
707711
// accumulates gas across all txs in the block
708712
let (last_step, last_call) = self.begin_handle_block(eth_block, geth_traces)?;
713+
let last_step = last_step.unwrap_or_default();
709714

710715
assert!(self.circuits_params.max_rws().is_some());
711716

@@ -748,10 +753,6 @@ impl CircuitInputBuilder<FixedCParams> {
748753
used_chunks <= self.circuits_params.total_chunks(),
749754
"Used more chunks than given total_chunks"
750755
);
751-
752-
self.chunks.iter().enumerate().for_each(|(id, chunk)| {
753-
println!("chunk {}th ctx {:?}", id, chunk.ctx);
754-
});
755756
assert!(
756757
self.chunks.len() == self.chunk_ctx.idx + 1,
757758
"number of chunks {} mis-match with chunk_ctx id {}",

zkevm-circuits/src/evm_circuit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ impl<F: Field> EvmCircuit<F> {
267267
}
268268

269269
/// Compute the public inputs for this circuit.
270-
fn instance_extend_chunk_ctx(&self) -> Vec<Vec<F>> {
270+
pub fn instance_extend_chunk_ctx(&self) -> Vec<Vec<F>> {
271271
let chunk = self.chunk.as_ref().unwrap();
272272

273273
let (rw_table_chunked_index, rw_table_total_chunks) =

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

+9-39
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ mod test {
117117
let builder = BlockData::new_from_geth_data_with_params(
118118
block.clone(),
119119
FixedCParams {
120-
total_chunks: 6,
120+
total_chunks: 4,
121121
max_rws: 64,
122122
max_txs: 2,
123123
..Default::default()
@@ -128,43 +128,13 @@ mod test {
128128
.unwrap();
129129
let block = block_convert::<Fr>(&builder).unwrap();
130130
let chunks = chunk_convert(&block, &builder).unwrap();
131-
println!("num of chunk {:?}", chunks.len());
132-
chunks.iter().enumerate().for_each(|(idx, chunk)| {
133-
println!(
134-
"{}th chunk by_address_rw_fingerprints {:?}, chrono_rw_fingerprints {:?} ",
135-
idx, chunk.by_address_rw_fingerprints, chunk.chrono_rw_fingerprints,
136-
);
137-
});
138-
}
139-
140-
#[test]
141-
fn test_all_chunks_ok() {
142-
let bytecode = bytecode! {
143-
PUSH1(0x0) // retLength
144-
PUSH1(0x0) // retOffset
145-
PUSH1(0x0) // argsLength
146-
PUSH1(0x0) // argsOffset
147-
PUSH1(0x0) // value
148-
PUSH32(0x10_0000) // addr
149-
PUSH32(0x10_0000) // gas
150-
CALL
151-
PUSH2(0xaa)
152-
};
153-
CircuitTestBuilder::new_from_test_ctx(
154-
TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(),
155-
)
156-
.block_modifier(Box::new(move |_block, chunk| {
157-
// TODO FIXME padding start as a workaround. The practical should be last chunk last row
158-
// rws
159-
// if let Some(a) = chunk.rws.0.get_mut(&Target::Start) {
160-
// a.push(Rw::Start { rw_counter: 1 });
161-
// }
162-
println!(
163-
"=> FIXME is fixed? {:?}",
164-
chunk.chrono_rws.0.get_mut(&Target::Start)
165-
);
166-
}))
167-
.run_dynamic_chunk(4, 2);
131+
// assert last fingerprint acc are equal
132+
if let Some(last_chunk) = chunks.last() {
133+
assert_eq!(
134+
last_chunk.by_address_rw_fingerprints.mul_acc,
135+
last_chunk.chrono_rw_fingerprints.mul_acc
136+
)
137+
}
168138
}
169139

170140
#[test]
@@ -202,7 +172,7 @@ mod test {
202172
.params({
203173
FixedCParams {
204174
total_chunks: 6,
205-
max_rws: 64,
175+
max_rws: 90,
206176
max_txs: 2,
207177
..Default::default()
208178
}

zkevm-circuits/src/state_circuit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ impl<F: Field> StateCircuit<F> {
484484
permu_alpha: chunk.permu_alpha,
485485
permu_gamma: chunk.permu_gamma,
486486
rw_fingerprints: chunk.by_address_rw_fingerprints.clone(),
487-
prev_chunk_last_rw: chunk.prev_chunk_last_chrono_rw,
487+
prev_chunk_last_rw: chunk.prev_chunk_last_by_address_rw,
488488
_marker: PhantomData::default(),
489489
}
490490
}

zkevm-circuits/src/state_circuit/lexicographic_ordering.rs

+13-22
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub struct Config {
9999
pub(crate) selector: Column<Fixed>,
100100
pub first_different_limb: BinaryNumberConfig<LimbIndex, 5>,
101101
limb_difference: Column<Advice>,
102-
limb_difference_inverse: Column<Advice>,
102+
// limb_difference_inverse: Column<Advice>,
103103
}
104104

105105
impl Config {
@@ -112,26 +112,26 @@ impl Config {
112112
let selector = meta.fixed_column();
113113
let first_different_limb = BinaryNumberChip::configure(meta, selector, None);
114114
let limb_difference = meta.advice_column();
115-
let limb_difference_inverse = meta.advice_column();
115+
// let limb_difference_inverse = meta.advice_column();
116116

117117
let config = Config {
118118
selector,
119119
first_different_limb,
120120
limb_difference,
121-
limb_difference_inverse,
121+
// limb_difference_inverse,
122122
};
123123

124124
lookup.range_check_u16(meta, "limb_difference fits into u16", |meta| {
125125
meta.query_advice(limb_difference, Rotation::cur())
126126
});
127127

128-
meta.create_gate("limb_difference is not zero", |meta| {
129-
let selector = meta.query_fixed(selector, Rotation::cur());
130-
let limb_difference = meta.query_advice(limb_difference, Rotation::cur());
131-
let limb_difference_inverse =
132-
meta.query_advice(limb_difference_inverse, Rotation::cur());
133-
vec![selector * (1.expr() - limb_difference * limb_difference_inverse)]
134-
});
128+
// meta.create_gate("limb_difference is not zero", |meta| {
129+
// let selector = meta.query_fixed(selector, Rotation::cur());
130+
// let limb_difference = meta.query_advice(limb_difference, Rotation::cur());
131+
// let limb_difference_inverse =
132+
// meta.query_advice(limb_difference_inverse, Rotation::cur());
133+
// vec![selector * (1.expr() - limb_difference * limb_difference_inverse)]
134+
// });
135135

136136
meta.create_gate(
137137
"limb differences before first_different_limb are all 0",
@@ -221,24 +221,15 @@ impl Config {
221221
offset,
222222
|| Value::known(limb_difference),
223223
)?;
224-
region.assign_advice(
225-
|| "limb_difference_inverse",
226-
self.limb_difference_inverse,
227-
offset,
228-
|| Value::known(limb_difference.invert().unwrap()),
229-
)?;
230224

231225
Ok(index)
232226
}
233227

234228
/// Annotates columns of this gadget embedded within a circuit region.
235229
pub fn annotate_columns_in_region<F: Field>(&self, region: &mut Region<F>, prefix: &str) {
236-
[
237-
(self.limb_difference, "LO_limb_difference"),
238-
(self.limb_difference_inverse, "LO_limb_difference_inverse"),
239-
]
240-
.iter()
241-
.for_each(|(col, ann)| region.name_column(|| format!("{}_{}", prefix, ann), *col));
230+
[(self.limb_difference, "LO_limb_difference")]
231+
.iter()
232+
.for_each(|(col, ann)| region.name_column(|| format!("{}_{}", prefix, ann), *col));
242233
// fixed column
243234
region.name_column(
244235
|| format!("{}_LO_upper_limb_difference", prefix),

zkevm-circuits/src/state_circuit/test.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,26 @@ fn state_circuit_unusable_rows() {
3434
)
3535
}
3636

37+
fn new_chunk_from_rw_map<F: Field>(rws: &RwMap, padding_start_rw: Option<Rw>) -> Chunk<F> {
38+
let (alpha, gamma) = get_permutation_randomness();
39+
let mut chunk = Chunk {
40+
by_address_rws: rws.clone(),
41+
..Default::default()
42+
};
43+
44+
let rw_fingerprints = get_permutation_fingerprint_of_rwmap(
45+
&chunk.by_address_rws,
46+
chunk.fixed_param.max_rws,
47+
alpha,
48+
gamma,
49+
F::from(1),
50+
false,
51+
padding_start_rw,
52+
);
53+
chunk.by_address_rw_fingerprints = rw_fingerprints;
54+
chunk
55+
}
56+
3757
fn test_state_circuit_ok(
3858
memory_ops: Vec<Operation<MemoryOp>>,
3959
stack_ops: Vec<Operation<StackOp>>,
@@ -45,7 +65,7 @@ fn test_state_circuit_ok(
4565
storage: storage_ops,
4666
..Default::default()
4767
});
48-
let chunk = Chunk::new_from_rw_map(&rw_map, None, None);
68+
let chunk = new_chunk_from_rw_map(&rw_map, None);
4969

5070
let circuit = StateCircuit::<Fr>::new(&chunk);
5171
let instance = circuit.instance();
@@ -69,7 +89,7 @@ fn verifying_key_independent_of_rw_length() {
6989

7090
let no_rows = StateCircuit::<Fr>::new(&chunk);
7191

72-
chunk = Chunk::new_from_rw_map(
92+
chunk = new_chunk_from_rw_map(
7393
&RwMap::from(&OperationContainer {
7494
memory: vec![Operation::new(
7595
RWCounter::from(1),
@@ -80,7 +100,6 @@ fn verifying_key_independent_of_rw_length() {
80100
..Default::default()
81101
}),
82102
None,
83-
None,
84103
);
85104
let one_row = StateCircuit::<Fr>::new(&chunk);
86105

@@ -948,11 +967,7 @@ fn variadic_size_check() {
948967
},
949968
];
950969
// let rw_map: RwMap = rows.clone().into();
951-
let circuit = StateCircuit::new(&Chunk::new_from_rw_map(
952-
&RwMap::from(rows.clone()),
953-
None,
954-
None,
955-
));
970+
let circuit = StateCircuit::new(&new_chunk_from_rw_map(&RwMap::from(rows.clone()), None));
956971
let power_of_randomness = circuit.instance();
957972
let prover1 = MockProver::<Fr>::run(17, &circuit, power_of_randomness).unwrap();
958973

@@ -973,7 +988,7 @@ fn variadic_size_check() {
973988
},
974989
]);
975990

976-
let circuit = StateCircuit::new(&Chunk::new_from_rw_map(&rows.into(), None, None));
991+
let circuit = StateCircuit::new(&new_chunk_from_rw_map(&rows.into(), None));
977992
let power_of_randomness = circuit.instance();
978993
let prover2 = MockProver::<Fr>::run(17, &circuit, power_of_randomness).unwrap();
979994

zkevm-circuits/src/test_util.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ const NUM_BLINDING_ROWS: usize = 64;
7979
///
8080
/// CircuitTestBuilder::new_from_test_ctx(ctx)
8181
/// .block_modifier(Box::new(|block, chunk| chunk.fixed_param.max_evm_rows = (1 << 18) - 100))
82-
/// .state_checks(Box::new(|prover, evm_rows, lookup_rows| assert!(prover.verify_at_rows_par(evm_rows.iter().cloned(), lookup_rows.iter().cloned()).is_err())))
8382
/// .run();
8483
/// ```
8584
pub struct CircuitTestBuilder<const NACC: usize, const NTX: usize> {
@@ -327,12 +326,14 @@ impl<const NACC: usize, const NTX: usize> CircuitTestBuilder<NACC, NTX> {
327326
"Total chunks unmatched with fixed param"
328327
);
329328
BlockData::new_from_geth_data_with_params(block.clone(), fixed_param)
330-
.new_circuit_input_builder()
329+
.new_circuit_input_builder_with_feature(
330+
self.feature_config.unwrap_or_default(),
331+
)
331332
.handle_block(&block.eth_block, &block.geth_traces)
332333
.unwrap()
333334
}
334335
None => BlockData::new_from_geth_data_chunked(block.clone(), total_chunk)
335-
.new_circuit_input_builder()
336+
.new_circuit_input_builder_with_feature(self.feature_config.unwrap_or_default())
336337
.handle_block(&block.eth_block, &block.geth_traces)
337338
.unwrap(),
338339
};
@@ -352,12 +353,11 @@ impl<const NACC: usize, const NTX: usize> CircuitTestBuilder<NACC, NTX> {
352353

353354
// Build a witness block from trace result.
354355
let mut block = crate::witness::block_convert(&builder).unwrap();
356+
355357
let mut chunk = crate::witness::chunk_convert(&block, &builder)
356358
.unwrap()
357359
.remove(chunk_index);
358360

359-
println!("fingerprints = {:?}", chunk.chrono_rw_fingerprints);
360-
361361
for modifier_fn in self.block_modifiers {
362362
modifier_fn.as_ref()(&mut block, &mut chunk);
363363
}
@@ -374,10 +374,16 @@ impl<const NACC: usize, const NTX: usize> CircuitTestBuilder<NACC, NTX> {
374374
let (_active_gate_rows, _active_lookup_rows) =
375375
EvmCircuit::<Fr>::get_active_rows(&block, &chunk);
376376

377-
let circuit =
378-
EvmCircuitCached::get_test_circuit_from_block(block.clone(), chunk.clone());
379-
let instance = circuit.instance();
380-
let _prover = MockProver::<Fr>::run(k, &circuit, instance).unwrap();
377+
let _prover = if block.feature_config.is_mainnet() {
378+
let circuit =
379+
EvmCircuitCached::get_test_circuit_from_block(block.clone(), chunk.clone());
380+
let instance = circuit.instance();
381+
MockProver::<Fr>::run(k, &circuit, instance)
382+
} else {
383+
let circuit = EvmCircuit::get_test_circuit_from_block(block.clone(), chunk.clone());
384+
let instance = circuit.instance_extend_chunk_ctx();
385+
MockProver::<Fr>::run(k, &circuit, instance)
386+
};
381387

382388
// self.evm_checks.as_ref()(prover, &active_gate_rows, &active_lookup_rows)
383389
}

zkevm-circuits/src/witness/block.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,14 @@ pub fn block_convert<F: Field>(
295295
.chunks
296296
.iter()
297297
.fold(BTreeMap::new(), |mut map, chunk| {
298-
assert!(chunk.ctx.rwc.0.saturating_sub(1) <= builder.circuits_params.max_rws);
299-
// [chunk.ctx.rwc.0, builder.circuits_params.max_rws + 1)
300-
(chunk.ctx.rwc.0..builder.circuits_params.max_rws + 1).for_each(|padding_rw_counter| {
298+
assert!(
299+
chunk.ctx.rwc.0.saturating_sub(1) <= builder.circuits_params.max_rws,
300+
"max_rws size {} must larger than chunk rws size {}",
301+
builder.circuits_params.max_rws,
302+
chunk.ctx.rwc.0.saturating_sub(1),
303+
);
304+
// [chunk.ctx.rwc.0, builder.circuits_params.max_rws)
305+
(chunk.ctx.rwc.0..builder.circuits_params.max_rws).for_each(|padding_rw_counter| {
301306
*map.entry(padding_rw_counter).or_insert(0) += 1;
302307
});
303308
map

0 commit comments

Comments
 (0)