Skip to content

Commit c4db809

Browse files
authored
Fix: sig circuit's capacity checker does not take account of ecrecover precompile (#725)
* sig circuit capacity checker does not take account of ecrecover precompile * fmt * clippy
1 parent 76989b3 commit c4db809

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

zkevm-circuits/src/sig_circuit.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,10 @@ impl<F: Field> SubCircuit<F> for SigCircuit<F> {
220220
type Config = SigCircuitConfig<F>;
221221

222222
fn new_from_block(block: &crate::witness::Block<F>) -> Self {
223+
assert!(block.circuits_params.max_txs <= MAX_NUM_SIG);
224+
223225
SigCircuit {
224-
// TODO: seperate max_verif with max_txs?
225-
max_verif: block.circuits_params.max_txs,
226+
max_verif: MAX_NUM_SIG,
226227
signatures: block.get_sign_data(true),
227228
_marker: Default::default(),
228229
}
@@ -257,13 +258,22 @@ impl<F: Field> SubCircuit<F> for SigCircuit<F> {
257258
fn min_num_rows_block(block: &crate::witness::Block<F>) -> (usize, usize) {
258259
let row_num = Self::min_num_rows();
259260

260-
let tx_count = block.txs.len();
261-
let max_tx_count = block.circuits_params.max_txs;
261+
let ecdsa_verif_count = block
262+
.txs
263+
.iter()
264+
.filter(|tx| !tx.tx_type.is_l1_msg())
265+
.count()
266+
+ block.precompile_events.get_ecrecover_events().len();
267+
// Reserve one ecdsa verification for padding tx such that the bad case in which some tx
268+
// calls MAX_NUM_SIG - 1 ecrecover precompile won't happen. If that case happens, the sig
269+
// circuit won't have more space for the padding tx's ECDSA verification. Then the
270+
// prover won't be able to produce any valid proof.
271+
let max_num_verif = MAX_NUM_SIG - 1;
262272

263273
// Instead of showing actual minimum row usage,
264274
// halo2-lib based circuits use min_row_num to represent a percentage of total-used capacity
265275
// This functionality allows l2geth to decide if additional ops can be added.
266-
let min_row_num = (row_num / max_tx_count) * tx_count;
276+
let min_row_num = (row_num / max_num_verif) * ecdsa_verif_count;
267277

268278
(min_row_num, row_num)
269279
}

zkevm-circuits/src/witness/block.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,15 @@ impl<F: Field> Block<F> {
9696
let mut signatures: Vec<SignData> = self
9797
.txs
9898
.iter()
99-
.map(|tx| {
100-
if tx.tx_type.is_l1_msg() {
101-
// dummy signature
102-
Ok(SignData::default())
103-
} else {
104-
tx.sign_data()
105-
}
106-
})
99+
// Since L1Msg tx does not have signature, it do not need to do lookup into sig table
100+
.filter(|tx| !tx.tx_type.is_l1_msg())
101+
.map(|tx| tx.sign_data())
107102
.filter_map(|res| res.ok())
108103
.collect::<Vec<SignData>>();
109104
signatures.extend_from_slice(&self.precompile_events.get_ecrecover_events());
110-
if padding {
111-
let max_verif = self.circuits_params.max_txs;
112-
signatures.resize(
113-
max_verif,
114-
Transaction::dummy(self.chain_id).sign_data().unwrap(),
115-
)
105+
if padding && self.txs.len() < self.circuits_params.max_txs {
106+
// padding tx's sign data
107+
signatures.push(Transaction::dummy(self.chain_id).sign_data().unwrap());
116108
}
117109
signatures
118110
}

0 commit comments

Comments
 (0)