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

Commit 69f4fe1

Browse files
authored
[fix] add precompile to access list (#676)
* add precompile address to access list * update constraint * update circuit begin_tx offset * Revert "update circuit begin_tx offset" This reverts commit 9eaf56c. * fix circuit constraint * apply review * assume precompile address pre_warm always false * fmt * Revert "fmt" This reverts commit 369e1f1. * Revert "assume precompile address pre_warm always false" This reverts commit a8b3ceb. * fix begin_tx with precompile
1 parent e9261c6 commit 69f4fe1

File tree

3 files changed

+40
-22
lines changed

3 files changed

+40
-22
lines changed

bus-mapping/src/evm/opcodes.rs

+13
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,19 @@ pub fn gen_begin_tx_ops(
511511
nonce_prev,
512512
)?;
513513

514+
// Add precompile contract address to access list
515+
for address in 1..=9 {
516+
let address = eth_types::Address::from_low_u64_be(address);
517+
let is_warm_prev = !state.sdb.add_account_to_access_list(address);
518+
state.tx_accesslist_account_write(
519+
&mut exec_step,
520+
state.tx_ctx.id(),
521+
address,
522+
true,
523+
is_warm_prev,
524+
)?;
525+
}
526+
514527
// Add caller, callee and coinbase (only for Shanghai) to access list.
515528
#[cfg(feature = "shanghai")]
516529
let accessed_addresses = [

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

+23-5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ const SHANGHAI_RW_DELTA: u8 = 1;
3535
#[cfg(not(feature = "shanghai"))]
3636
const SHANGHAI_RW_DELTA: u8 = 0;
3737

38+
const PRECOMPILE_COUNT: usize = 9;
39+
3840
use gadgets::util::select;
3941

4042
#[derive(Clone, Debug)]
@@ -224,6 +226,10 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
224226
let gas_left = tx_gas.expr() - intrinsic_gas_cost.expr();
225227
let sufficient_gas_left = RangeCheckGadget::construct(cb, gas_left.clone());
226228

229+
for addr in 1..=PRECOMPILE_COUNT {
230+
cb.account_access_list_write(tx_id.expr(), addr.expr(), 1.expr(), 0.expr(), None);
231+
} // rwc_delta += PRECOMPILE_COUNT
232+
227233
// Prepare access list of caller and callee
228234
cb.account_access_list_write(
229235
tx_id.expr(),
@@ -239,7 +245,11 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
239245
1.expr(),
240246
// No extra constraint being used here.
241247
// Correctness will be enforced in build_tx_access_list_account_constraints
242-
is_caller_callee_equal.expr(),
248+
select::expr(
249+
is_precompile.expr(),
250+
1.expr(),
251+
is_caller_callee_equal.expr(),
252+
),
243253
None,
244254
); // rwc_delta += 1
245255

@@ -406,6 +416,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
406416
// - Write CallContext IsPersistent
407417
// - Write CallContext IsSuccess
408418
// - Write Account (Caller) Nonce
419+
// - Write TxAccessListAccount (Precompile) x PRECOMPILE_COUNT
409420
// - Write TxAccessListAccount (Caller)
410421
// - Write TxAccessListAccount (Callee)
411422
// - Write TxAccessListAccount (Coinbase) only for Shanghai
@@ -429,7 +440,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
429440
22.expr()
430441
+ tx_l1_fee.rw_delta()
431442
+ transfer_with_gas_fee.rw_delta()
432-
+ SHANGHAI_RW_DELTA.expr(),
443+
+ SHANGHAI_RW_DELTA.expr()
444+
+ PRECOMPILE_COUNT.expr(),
433445
),
434446
call_id: To(call_id.expr()),
435447
is_root: To(true.expr()),
@@ -474,6 +486,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
474486
// - Write CallContext IsPersistent
475487
// - Write CallContext IsSuccess
476488
// - Write Account (Caller) Nonce
489+
// - Write TxAccessListAccount (Precompile) x PRECOMPILE_COUNT
477490
// - Write TxAccessListAccount (Caller)
478491
// - Write TxAccessListAccount (Callee)
479492
// - Write TxAccessListAccount (Coinbase) only for Shanghai
@@ -484,6 +497,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
484497
+ tx_l1_fee.rw_delta()
485498
+ transfer_with_gas_fee.rw_delta()
486499
+ SHANGHAI_RW_DELTA.expr()
500+
+ PRECOMPILE_COUNT.expr()
487501
// TRICKY:
488502
// Process the reversion only for Precompile in begin TX. Since no
489503
// associated opcodes could process reversion afterwards
@@ -524,6 +538,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
524538
// - Write CallContext IsPersistent
525539
// - Write CallContext IsSuccess
526540
// - Write Account Nonce
541+
// - Write TxAccessListAccount (Precompile) x PRECOMPILE_COUNT
527542
// - Write TxAccessListAccount (Caller)
528543
// - Write TxAccessListAccount (Callee)
529544
// - Write TxAccessListAccount (Coinbase) only for Shanghai
@@ -534,7 +549,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
534549
8.expr()
535550
+ tx_l1_fee.rw_delta()
536551
+ transfer_with_gas_fee.rw_delta()
537-
+ SHANGHAI_RW_DELTA.expr(),
552+
+ SHANGHAI_RW_DELTA.expr()
553+
+ PRECOMPILE_COUNT.expr(),
538554
),
539555
call_id: To(call_id.expr()),
540556
..StepStateTransition::any()
@@ -582,6 +598,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
582598
// - Write CallContext IsPersistent
583599
// - Write CallContext IsSuccess
584600
// - Write Account Nonce
601+
// - Write TxAccessListAccount (Precompile) x PRECOMPILE_COUNT
585602
// - Write TxAccessListAccount (Caller)
586603
// - Write TxAccessListAccount (Callee)
587604
// - Write TxAccessListAccount (Coinbase) only for Shanghai
@@ -604,7 +621,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
604621
21.expr()
605622
+ tx_l1_fee.rw_delta()
606623
+ transfer_with_gas_fee.rw_delta()
607-
+ SHANGHAI_RW_DELTA.expr(),
624+
+ SHANGHAI_RW_DELTA.expr()
625+
+ PRECOMPILE_COUNT.expr(),
608626
),
609627
call_id: To(call_id.expr()),
610628
is_root: To(true.expr()),
@@ -672,7 +690,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
672690
let zero = eth_types::Word::zero();
673691

674692
let mut rws = StepRws::new(block, step);
675-
rws.offset_add(10);
693+
rws.offset_add(10 + PRECOMPILE_COUNT);
676694

677695
#[cfg(feature = "shanghai")]
678696
let is_coinbase_warm = rws.next().tx_access_list_value_pair().1;

zkevm-circuits/src/state_circuit/constraint_builder.rs

+4-17
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,10 @@ impl<F: Field> ConstraintBuilder<F> {
154154
"first access reads don't change value",
155155
q.is_read() * (q.rw_table.value.clone() - q.initial_value()),
156156
);
157-
// FIXME
158-
// precompile should be warm
159-
// https://github.com/scroll-tech/zkevm-circuits/issues/343
160-
// If we decide to implement optional access list of tx later,
161-
// we need to revist this constraint.
162-
cb.condition(
163-
not::expr(
164-
q.tag_matches(RwTableTag::TxAccessListAccount)
165-
+ q.tag_matches(RwTableTag::TxAccessListAccountStorage),
166-
),
167-
|cb| {
168-
cb.require_equal(
169-
"value_prev column is initial_value for first access",
170-
q.value_prev_column(),
171-
q.initial_value.clone(),
172-
);
173-
},
157+
cb.require_equal(
158+
"value_prev column is initial_value for first access",
159+
q.value_prev_column(),
160+
q.initial_value.clone(),
174161
);
175162
});
176163

0 commit comments

Comments
 (0)