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

Commit f7941c1

Browse files
authored
constrain rw_counter_end_of_reversion for failed step (#1030)
* try to constrain rw_counter_end_of_reversion * fix by minus one for rw_counter_end_of_reversion * verify rwcounter end of reversion both for root and internal call * make all errors with rw_counter_end_of_reversion check * apply review suggestion * fix typing
1 parent d6937c1 commit f7941c1

File tree

5 files changed

+118
-8
lines changed

5 files changed

+118
-8
lines changed

bus-mapping/src/circuit_input_builder/input_state_ref.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,18 @@ impl<'a> CircuitInputStateRef<'a> {
11901190
CallContextField::IsSuccess,
11911191
0u64.into(),
11921192
);
1193+
1194+
//Even call.rw_counter_end_of_reversion is zero for now, it will set in
1195+
//set_value_ops_call_context_rwc_eor later
1196+
// if call fails, no matter root or internal, read RwCounterEndOfReversion for
1197+
// circuit constraint.
1198+
self.call_context_read(
1199+
exec_step,
1200+
call.call_id,
1201+
CallContextField::RwCounterEndOfReversion,
1202+
call.rw_counter_end_of_reversion.into(),
1203+
);
1204+
11931205
if call.is_root {
11941206
return Ok(());
11951207
}

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub(crate) struct ErrorInvalidJumpGadget<F> {
3434
is_jumpi: IsEqualGadget<F>,
3535
phase2_condition: Cell<F>,
3636
is_condition_zero: IsZeroGadget<F>,
37+
rw_counter_end_of_reversion: Cell<F>,
3738
restore_context: RestoreContextGadget<F>,
3839
}
3940

@@ -47,6 +48,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorInvalidJumpGadget<F> {
4748
let opcode = cb.query_cell();
4849
let value = cb.query_cell();
4950
let is_code = cb.query_cell();
51+
let rw_counter_end_of_reversion = cb.query_cell();
5052
let phase2_condition = cb.query_cell_with_type(CellType::StoragePhase2);
5153

5254
cb.require_in_set(
@@ -96,6 +98,13 @@ impl<F: Field> ExecutionGadget<F> for ErrorInvalidJumpGadget<F> {
9698

9799
cb.call_context_lookup(false.expr(), None, CallContextFieldTag::IsSuccess, 0.expr());
98100

101+
cb.call_context_lookup(
102+
false.expr(),
103+
None,
104+
CallContextFieldTag::RwCounterEndOfReversion,
105+
rw_counter_end_of_reversion.expr(),
106+
);
107+
99108
// Go to EndTx only when is_root
100109
let is_to_end_tx = cb.next.execution_state_selector([ExecutionState::EndTx]);
101110
cb.require_equal(
@@ -110,7 +119,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorInvalidJumpGadget<F> {
110119
cb.require_step_state_transition(StepStateTransition {
111120
call_id: Same,
112121
rw_counter: Delta(
113-
2.expr() + is_jumpi.expr() + cb.curr.state.reversible_write_counter.expr(),
122+
3.expr() + is_jumpi.expr() + cb.curr.state.reversible_write_counter.expr(),
114123
),
115124

116125
..StepStateTransition::any()
@@ -131,6 +140,15 @@ impl<F: Field> ExecutionGadget<F> for ErrorInvalidJumpGadget<F> {
131140
)
132141
});
133142

143+
// constrain RwCounterEndOfReversion
144+
let rw_counter_end_of_step =
145+
cb.curr.state.rw_counter.expr() + cb.rw_counter_offset() - 1.expr();
146+
cb.require_equal(
147+
"rw_counter_end_of_reversion = rw_counter_end_of_step + reversible_counter",
148+
rw_counter_end_of_reversion.expr(),
149+
rw_counter_end_of_step + cb.curr.state.reversible_write_counter.expr(),
150+
);
151+
134152
Self {
135153
opcode,
136154
destination,
@@ -142,6 +160,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorInvalidJumpGadget<F> {
142160
is_jumpi,
143161
phase2_condition,
144162
is_condition_zero,
163+
rw_counter_end_of_reversion,
145164
restore_context,
146165
}
147166
}
@@ -222,8 +241,13 @@ impl<F: Field> ExecutionGadget<F> for ErrorInvalidJumpGadget<F> {
222241
self.is_condition_zero
223242
.assign_value(region, offset, condition_rlc)?;
224243

244+
self.rw_counter_end_of_reversion.assign(
245+
region,
246+
offset,
247+
Value::known(F::from(call.rw_counter_end_of_reversion as u64)),
248+
)?;
225249
self.restore_context
226-
.assign(region, offset, block, call, step, 2 + is_jumpi as usize)?;
250+
.assign(region, offset, block, call, step, 3 + is_jumpi as usize)?;
227251
Ok(())
228252
}
229253
}

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub(crate) struct ErrorOOGCallGadget<F> {
3232
is_warm: Cell<F>,
3333
balance: Word<F>,
3434
insufficient_gas: LtGadget<F, N_BYTES_GAS>,
35+
rw_counter_end_of_reversion: Cell<F>,
3536
restore_context: RestoreContextGadget<F>,
3637
}
3738

@@ -51,6 +52,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
5152
OpcodeId::CALL.expr(),
5253
);
5354

55+
let rw_counter_end_of_reversion = cb.query_cell();
5456
let tx_id = cb.call_context(None, CallContextFieldTag::TxId);
5557
let is_static = cb.call_context(None, CallContextFieldTag::IsStatic);
5658
let call_gadget = CommonCallGadget::construct(cb, 1.expr(), 0.expr(), 0.expr());
@@ -84,6 +86,13 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
8486
// current call must be failed.
8587
cb.call_context_lookup(false.expr(), None, CallContextFieldTag::IsSuccess, 0.expr());
8688

89+
cb.call_context_lookup(
90+
false.expr(),
91+
None,
92+
CallContextFieldTag::RwCounterEndOfReversion,
93+
rw_counter_end_of_reversion.expr(),
94+
);
95+
8796
// Go to EndTx only when is_root
8897
let is_to_end_tx = cb.next.execution_state_selector([ExecutionState::EndTx]);
8998
cb.require_equal(
@@ -97,7 +106,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
97106
// Do step state transition
98107
cb.require_step_state_transition(StepStateTransition {
99108
call_id: Same,
100-
rw_counter: Delta(14.expr() + cb.curr.state.reversible_write_counter.expr()),
109+
rw_counter: Delta(15.expr() + cb.curr.state.reversible_write_counter.expr()),
101110

102111
..StepStateTransition::any()
103112
});
@@ -117,6 +126,15 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
117126
)
118127
});
119128

129+
// constrain RwCounterEndOfReversion
130+
let rw_counter_end_of_step =
131+
cb.curr.state.rw_counter.expr() + cb.rw_counter_offset() - 1.expr();
132+
cb.require_equal(
133+
"rw_counter_end_of_reversion = rw_counter_end_of_step + reversible_counter",
134+
rw_counter_end_of_reversion.expr(),
135+
rw_counter_end_of_step + cb.curr.state.reversible_write_counter.expr(),
136+
);
137+
120138
Self {
121139
opcode,
122140
tx_id,
@@ -125,6 +143,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
125143
is_warm,
126144
balance,
127145
insufficient_gas,
146+
rw_counter_end_of_reversion,
128147
restore_context,
129148
}
130149
}
@@ -214,8 +233,14 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
214233
Value::known(F::from(gas_cost)),
215234
)?;
216235

236+
self.rw_counter_end_of_reversion.assign(
237+
region,
238+
offset,
239+
Value::known(F::from(call.rw_counter_end_of_reversion as u64)),
240+
)?;
241+
217242
self.restore_context
218-
.assign(region, offset, block, call, step, 14)?;
243+
.assign(region, offset, block, call, step, 15)?;
219244
Ok(())
220245
}
221246
}

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub(crate) struct ErrorOOGConstantGadget<F> {
2424
// constrain gas left is less than required
2525
gas_required: Cell<F>,
2626
insufficient_gas: LtGadget<F, N_BYTES_GAS>,
27+
rw_counter_end_of_reversion: Cell<F>,
2728
restore_context: RestoreContextGadget<F>,
2829
}
2930

@@ -37,6 +38,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGConstantGadget<F> {
3738
cb.opcode_lookup(opcode.expr(), 1.expr());
3839

3940
let gas_required = cb.query_cell();
41+
let rw_counter_end_of_reversion = cb.query_cell();
4042

4143
cb.constant_gas_lookup(opcode.expr(), gas_required.expr());
4244
// Check if the amount of gas available is less than the amount of gas
@@ -52,6 +54,13 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGConstantGadget<F> {
5254
// current call must be failed.
5355
cb.call_context_lookup(false.expr(), None, CallContextFieldTag::IsSuccess, 0.expr());
5456

57+
cb.call_context_lookup(
58+
false.expr(),
59+
None,
60+
CallContextFieldTag::RwCounterEndOfReversion,
61+
rw_counter_end_of_reversion.expr(),
62+
);
63+
5564
// Go to EndTx only when is_root
5665
let is_to_end_tx = cb.next.execution_state_selector([ExecutionState::EndTx]);
5766
cb.require_equal(
@@ -65,7 +74,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGConstantGadget<F> {
6574
// Do step state transition
6675
cb.require_step_state_transition(StepStateTransition {
6776
call_id: Same,
68-
rw_counter: Delta(1.expr() + cb.curr.state.reversible_write_counter.expr()),
77+
rw_counter: Delta(2.expr() + cb.curr.state.reversible_write_counter.expr()),
6978
..StepStateTransition::any()
7079
});
7180
});
@@ -85,10 +94,20 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGConstantGadget<F> {
8594
)
8695
});
8796

97+
// constrain RwCounterEndOfReversion
98+
let rw_counter_end_of_step =
99+
cb.curr.state.rw_counter.expr() + cb.rw_counter_offset() - 1.expr();
100+
cb.require_equal(
101+
"rw_counter_end_of_reversion = rw_counter_end_of_step + reversible_counter",
102+
rw_counter_end_of_reversion.expr(),
103+
rw_counter_end_of_step + cb.curr.state.reversible_write_counter.expr(),
104+
);
105+
88106
Self {
89107
opcode,
90108
gas_required,
91109
insufficient_gas,
110+
rw_counter_end_of_reversion,
92111
restore_context,
93112
}
94113
}
@@ -118,8 +137,14 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGConstantGadget<F> {
118137
F::from(step.gas_cost),
119138
)?;
120139

140+
self.rw_counter_end_of_reversion.assign(
141+
region,
142+
offset,
143+
Value::known(F::from(call.rw_counter_end_of_reversion as u64)),
144+
)?;
145+
121146
self.restore_context
122-
.assign(region, offset, block, call, step, 1)?;
147+
.assign(region, offset, block, call, step, 2)?;
123148

124149
Ok(())
125150
}

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub(crate) struct ErrorStackGadget<F> {
2626
max_stack_pointer: Cell<F>,
2727
is_overflow: LtGadget<F, N_BYTES_STACK>,
2828
is_underflow: LtGadget<F, N_BYTES_STACK>,
29+
rw_counter_end_of_reversion: Cell<F>,
2930
restore_context: RestoreContextGadget<F>,
3031
}
3132

@@ -40,6 +41,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorStackGadget<F> {
4041

4142
let min_stack_pointer = cb.query_cell();
4243
let max_stack_pointer = cb.query_cell();
44+
let rw_counter_end_of_reversion = cb.query_cell();
4345

4446
cb.opcode_stack_lookup(
4547
opcode.expr(),
@@ -71,6 +73,13 @@ impl<F: Field> ExecutionGadget<F> for ErrorStackGadget<F> {
7173
// current call must be failed.
7274
cb.call_context_lookup(false.expr(), None, CallContextFieldTag::IsSuccess, 0.expr());
7375

76+
cb.call_context_lookup(
77+
false.expr(),
78+
None,
79+
CallContextFieldTag::RwCounterEndOfReversion,
80+
rw_counter_end_of_reversion.expr(),
81+
);
82+
7483
// Go to EndTx only when is_root
7584
let is_to_end_tx = cb.next.execution_state_selector([ExecutionState::EndTx]);
7685
cb.require_equal(
@@ -84,7 +93,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorStackGadget<F> {
8493
// Do step state transition
8594
cb.require_step_state_transition(StepStateTransition {
8695
call_id: Same,
87-
rw_counter: Delta(1.expr() + cb.curr.state.reversible_write_counter.expr()),
96+
rw_counter: Delta(2.expr() + cb.curr.state.reversible_write_counter.expr()),
8897
..StepStateTransition::any()
8998
});
9099
});
@@ -104,12 +113,22 @@ impl<F: Field> ExecutionGadget<F> for ErrorStackGadget<F> {
104113
)
105114
});
106115

116+
// constrain RwCounterEndOfReversion
117+
let rw_counter_end_of_step =
118+
cb.curr.state.rw_counter.expr() + cb.rw_counter_offset() - 1.expr();
119+
cb.require_equal(
120+
"rw_counter_end_of_reversion = rw_counter_end_of_step + reversible_counter",
121+
rw_counter_end_of_reversion.expr(),
122+
rw_counter_end_of_step + cb.curr.state.reversible_write_counter.expr(),
123+
);
124+
107125
Self {
108126
opcode,
109127
min_stack_pointer,
110128
max_stack_pointer,
111129
is_overflow,
112130
is_underflow,
131+
rw_counter_end_of_reversion,
113132
restore_context,
114133
}
115134
}
@@ -148,8 +167,13 @@ impl<F: Field> ExecutionGadget<F> for ErrorStackGadget<F> {
148167
F::from(step.stack_pointer as u64),
149168
)?;
150169

170+
self.rw_counter_end_of_reversion.assign(
171+
region,
172+
offset,
173+
Value::known(F::from(call.rw_counter_end_of_reversion as u64)),
174+
)?;
151175
self.restore_context
152-
.assign(region, offset, block, call, step, 1)?;
176+
.assign(region, offset, block, call, step, 2)?;
153177

154178
Ok(())
155179
}

0 commit comments

Comments
 (0)