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

Commit 70ccef7

Browse files
authored
fix sender_nonce vs tx_nonce handling inside begin tx (#731)
1 parent 8b29f74 commit 70ccef7

File tree

3 files changed

+69
-27
lines changed

3 files changed

+69
-27
lines changed

bus-mapping/src/evm/opcodes.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -547,13 +547,13 @@ pub fn gen_begin_tx_ops(
547547
}
548548

549549
// Increase caller's nonce
550-
let mut nonce_prev = state.sdb.get_nonce(&caller_address);
551-
debug_assert!(nonce_prev <= state.tx.nonce);
552-
while nonce_prev < state.tx.nonce {
553-
state.sdb.increase_nonce(&caller_address);
554-
nonce_prev = state.sdb.get_nonce(&caller_address);
555-
log::warn!("[debug] increase nonce to {}", nonce_prev);
556-
}
550+
let nonce_prev = state.sdb.get_nonce(&caller_address);
551+
//debug_assert!(nonce_prev <= state.tx.nonce);
552+
//while nonce_prev < state.tx.nonce {
553+
// state.sdb.increase_nonce(&caller_address);
554+
// nonce_prev = state.sdb.get_nonce(&caller_address);
555+
// log::warn!("[debug] increase nonce to {}", nonce_prev);
556+
//}
557557
state.account_write(
558558
&mut exec_step,
559559
caller_address,

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

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use crate::{
2020
witness::{Block, Call, ExecStep, Transaction},
2121
},
2222
table::{
23-
AccountFieldTag, BlockContextFieldTag, CallContextFieldTag, TxFieldTag as TxContextFieldTag,
23+
AccountFieldTag, BlockContextFieldTag, CallContextFieldTag, RwTableTag,
24+
TxFieldTag as TxContextFieldTag,
2425
},
2526
};
2627
use bus_mapping::circuit_input_builder::CopyDataType;
@@ -42,6 +43,7 @@ use gadgets::util::select;
4243
#[derive(Clone, Debug)]
4344
pub(crate) struct BeginTxGadget<F> {
4445
tx_id: Cell<F>,
46+
sender_nonce: Cell<F>,
4547
tx_nonce: Cell<F>,
4648
tx_gas: Cell<F>,
4749
tx_gas_price: Word<F>,
@@ -100,6 +102,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
100102

101103
let tx_id = cb.query_cell();
102104

105+
let sender_nonce = cb.query_cell();
103106
let [tx_nonce, tx_gas, tx_caller_address, tx_callee_address, tx_is_create, tx_call_data_length, tx_call_data_gas_cost, tx_data_gas_cost] =
104107
[
105108
TxContextFieldTag::Nonce,
@@ -115,6 +118,11 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
115118

116119
let tx_l1_msg = TxL1MsgGadget::construct(cb, tx_id.expr(), tx_caller_address.expr());
117120
let tx_l1_fee = cb.condition(not::expr(tx_l1_msg.is_l1_msg()), |cb| {
121+
cb.require_equal(
122+
"tx.nonce == sender.nonce",
123+
tx_nonce.expr(),
124+
sender_nonce.expr(),
125+
);
118126
TxL1FeeGadget::construct(cb, tx_id.expr(), tx_data_gas_cost.expr())
119127
});
120128
cb.condition(tx_l1_msg.is_l1_msg(), |cb| {
@@ -181,8 +189,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
181189
cb.account_write(
182190
tx_caller_address.expr(),
183191
AccountFieldTag::Nonce,
184-
tx_nonce.expr() + 1.expr(),
185-
tx_nonce.expr(),
192+
sender_nonce.expr() + 1.expr(),
193+
sender_nonce.expr(),
186194
None,
187195
); // rwc_delta += 1
188196

@@ -654,6 +662,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
654662
Self {
655663
tx_id,
656664
tx_nonce,
665+
sender_nonce,
657666
tx_gas,
658667
tx_gas_price,
659668
mul_gas_fee_by_gas,
@@ -720,26 +729,53 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
720729
self.tx_l1_msg
721730
.assign(region, offset, tx.tx_type, caller_code_hash)?;
722731

723-
rws.offset_add(
724-
if tx.tx_type.is_l1_msg() {
725-
if caller_code_hash.is_zero() {
726-
assert_eq!(
727-
tx.nonce, 0,
728-
"unexpected nonce {} when caller is not existed (must be 0)",
729-
tx.nonce
730-
);
731-
if cfg!(feature = "scroll") {
732-
10
733-
} else {
734-
9
735-
}
732+
////////////// RWS ////////////////
733+
// if L1:
734+
// CodeHash
735+
// if empty:
736+
// CodeHash
737+
// if scroll:
738+
// KeccakCodeHash
739+
// else:
740+
// 3 l1 fee rw
741+
// TxId
742+
// RwCounterEndOfReversion
743+
// IsPersistent
744+
// IsSuccess
745+
// Nonce
746+
// Precompiles
747+
// caller addr
748+
// callee addr
749+
// coinbase
750+
rws.offset_add(if tx.tx_type.is_l1_msg() {
751+
if caller_code_hash.is_zero() {
752+
assert_eq!(
753+
tx.nonce, 0,
754+
"unexpected nonce {} when caller is not existed (must be 0)",
755+
tx.nonce
756+
);
757+
if cfg!(feature = "scroll") {
758+
2
736759
} else {
737-
8
760+
1
738761
}
739762
} else {
740-
10
741-
} + PRECOMPILE_COUNT,
742-
);
763+
0
764+
}
765+
} else {
766+
3
767+
});
768+
let rw = rws.next();
769+
debug_assert_eq!(rw.tag(), RwTableTag::CallContext);
770+
debug_assert_eq!(rw.field_tag(), Some(CallContextFieldTag::TxId as u64));
771+
rws.offset_add(3);
772+
773+
let rw = rws.next();
774+
debug_assert_eq!(rw.tag(), RwTableTag::Account);
775+
debug_assert_eq!(rw.field_tag(), Some(AccountFieldTag::Nonce as u64));
776+
let nonce_rw = rw.account_nonce_pair();
777+
778+
rws.offset_add(PRECOMPILE_COUNT + 2);
743779

744780
#[cfg(feature = "shanghai")]
745781
let is_coinbase_warm = rws.next().tx_access_list_value_pair().1;
@@ -778,6 +814,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
778814
.assign(region, offset, Value::known(F::from(tx.id as u64)))?;
779815
self.tx_nonce
780816
.assign(region, offset, Value::known(F::from(tx.nonce)))?;
817+
self.sender_nonce
818+
.assign(region, offset, Value::known(F::from(nonce_rw.1.as_u64())))?;
781819
self.tx_gas
782820
.assign(region, offset, Value::known(F::from(tx.gas)))?;
783821
self.tx_gas_price

zkevm-circuits/src/evm_circuit/util.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,10 @@ impl<'a> StepRws<'a> {
723723
}
724724
/// Increment the step rw operation offset by `offset`.
725725
pub(crate) fn offset_add(&mut self, offset: usize) {
726+
self.offset += offset
727+
}
728+
/// Set the step rw operation offset by `offset`.
729+
pub(crate) fn offset_set(&mut self, offset: usize) {
726730
self.offset = offset
727731
}
728732
/// Return the next rw operation from the step.

0 commit comments

Comments
 (0)