Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions bus-mapping/src/circuit_input_builder/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ pub enum CopyDataType {
/// scenario where we wish to accumulate the value (RLC) over all rows.
/// This is used for Copy Lookup from SHA3 opcode verification.
RlcAcc,
/// When copy event is access-list addresses (EIP-2930), source is tx-table
/// and destination is rw-table.
AccessListAddresses,
/// When copy event is access-list storage keys (EIP-2930), source is
/// tx-table and destination is rw-table.
AccessListStorageKeys,
}
impl CopyDataType {
/// How many bits are necessary to represent a copy data type.
Expand Down Expand Up @@ -307,6 +313,8 @@ impl From<CopyDataType> for usize {
CopyDataType::TxCalldata => 3,
CopyDataType::TxLog => 4,
CopyDataType::RlcAcc => 5,
CopyDataType::AccessListAddresses => 6,
CopyDataType::AccessListStorageKeys => 7,
}
}
}
Expand All @@ -320,6 +328,8 @@ impl From<&CopyDataType> for u64 {
CopyDataType::TxCalldata => 3,
CopyDataType::TxLog => 4,
CopyDataType::RlcAcc => 5,
CopyDataType::AccessListAddresses => 6,
CopyDataType::AccessListStorageKeys => 7,
}
}
}
Expand Down
60 changes: 58 additions & 2 deletions bus-mapping/src/evm/opcodes/begin_end_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use eth_types::{
gas_utils::{tx_access_list_gas_cost, tx_data_gas_cost},
GasCost, MAX_REFUND_QUOTIENT_OF_GAS_USED,
},
geth_types::access_list_size,
Bytecode, ToWord, Word,
};
use ethers_core::utils::get_contract_address;
Expand All @@ -42,10 +43,12 @@ impl TxExecSteps for BeginEndTx {

pub fn gen_begin_tx_steps(state: &mut CircuitInputStateRef) -> Result<ExecStep, Error> {
let mut exec_step = state.new_begin_tx_step();
let call = state.call()?.clone();

let caller_address = call.caller_address;
// Add two copy-events for tx access-list addresses and storage keys if EIP-2930.
gen_tx_eip2930_ops(state, &mut exec_step)?;

let call = state.call()?.clone();
let caller_address = call.caller_address;
if state.tx.tx_type.is_l1_msg() {
// for l1 message, no need to add rw op, but we must check
// caller for its existent status
Expand Down Expand Up @@ -615,3 +618,56 @@ fn gen_tx_l1_fee_ops(
)?;
Ok(())
}

// Add two copy-events for tx access-list addresses and storage keys if EIP-2930.
fn gen_tx_eip2930_ops(
state: &mut CircuitInputStateRef,
exec_step: &mut ExecStep,
) -> Result<(), Error> {
if !state.tx.tx_type.is_eip2930_tx() {
return Ok(());
}

let tx_id = NumberOrHash::Number(state.tx_ctx.id());
let (address_size, storage_key_size) = access_list_size(&state.tx.access_list);

// Add copy event for access-list addresses.
let rw_counter_start = state.block_ctx.rwc;
state.push_copy(
Comment thread
roynalnaruto marked this conversation as resolved.
exec_step,
CopyEvent {
src_addr: 0,
src_addr_end: address_size,
src_type: CopyDataType::AccessListAddresses,
src_id: tx_id.clone(),
dst_addr: 0,
dst_type: CopyDataType::AccessListAddresses,
dst_id: tx_id.clone(),
log_id: None,
rw_counter_start,
// TODO
copy_bytes: CopyBytes::new(vec![], None, None),
Comment thread
roynalnaruto marked this conversation as resolved.
},
);

// Add copy event for access-list storage keys.
let rw_counter_start = state.block_ctx.rwc;
state.push_copy(
exec_step,
CopyEvent {
src_addr: 0,
src_addr_end: storage_key_size,
src_type: CopyDataType::AccessListStorageKeys,
src_id: tx_id.clone(),
Comment thread
roynalnaruto marked this conversation as resolved.
dst_addr: 0,
dst_type: CopyDataType::AccessListStorageKeys,
dst_id: tx_id,
log_id: None,
rw_counter_start,
// TODO
copy_bytes: CopyBytes::new(vec![], None, None),
},
);

Ok(())
}
27 changes: 24 additions & 3 deletions eth-types/src/geth_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,17 @@ impl From<TxType> for u64 {
impl TxType {
/// If this type is L1Msg or not
pub fn is_l1_msg(&self) -> bool {
matches!(*self, TxType::L1Msg)
matches!(*self, Self::L1Msg)
}

/// If this type is Eip155 or not
/// If this type is EIP-155 or not
pub fn is_eip155_tx(&self) -> bool {
matches!(*self, TxType::Eip155)
matches!(*self, Self::Eip155)
}

/// If this type is EIP-2930 or not
pub fn is_eip2930_tx(&self) -> bool {
matches!(*self, Self::Eip2930)
}

/// Get the type of transaction
Expand Down Expand Up @@ -402,3 +407,19 @@ impl GethData {
}
}
*/

/// Returns the number of addresses and the cumulative number of storage keys in
/// the entire access list.
pub fn access_list_size(access_list: &Option<AccessList>) -> (u64, u64) {
access_list.as_ref().map_or_else(
|| (0, 0),
|list| {
(
list.0.len() as u64,
list.0
.iter()
.fold(0, |acc, item| acc + item.storage_keys.len()) as u64,
)
},
)
}
39 changes: 21 additions & 18 deletions zkevm-circuits/src/evm_circuit/execution/begin_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use crate::{
util::{
and,
common_gadget::{
TransferGadgetInfo, TransferWithGasFeeGadget, TxL1FeeGadget, TxL1MsgGadget,
TransferGadgetInfo, TransferWithGasFeeGadget, TxEip2930Gadget, TxL1FeeGadget,
TxL1MsgGadget,
},
constraint_builder::{
ConstrainBuilderCommon, EVMConstraintBuilder, ReversionInfo, StepStateTransition,
Expand Down Expand Up @@ -43,6 +44,7 @@ const PRECOMPILE_COUNT: usize = 9;
#[derive(Clone, Debug)]
pub(crate) struct BeginTxGadget<F> {
tx_id: Cell<F>,
tx_type: Cell<F>,
sender_nonce: Cell<F>,
tx_nonce: Cell<F>,
tx_gas: Cell<F>,
Expand All @@ -60,8 +62,6 @@ pub(crate) struct BeginTxGadget<F> {
is_call_data_empty: IsZeroGadget<F>,
tx_call_data_word_length: ConstantDivisionGadget<F, N_BYTES_U64>,
tx_call_data_gas_cost: Cell<F>,
// The gas cost for access list (EIP 2930)
access_list_gas_cost: Cell<F>,
// The gas cost for rlp-encoded bytes of unsigned tx
tx_data_gas_cost: Cell<F>,
reversion_info: ReversionInfo<F>,
Expand Down Expand Up @@ -92,6 +92,7 @@ pub(crate) struct BeginTxGadget<F> {
is_coinbase_warm: Cell<F>,
tx_l1_fee: TxL1FeeGadget<F>,
tx_l1_msg: TxL1MsgGadget<F>,
tx_eip2930: TxEip2930Gadget<F>,
}

impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
Expand All @@ -104,25 +105,26 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
let call_id = cb.curr.state.rw_counter.clone();

let tx_id = cb.query_cell();

let sender_nonce = cb.query_cell();
let [tx_nonce, tx_gas, tx_caller_address, tx_callee_address, tx_is_create, tx_call_data_length, tx_call_data_gas_cost, access_list_gas_cost, tx_data_gas_cost] =

let [tx_type, 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] =
[
TxContextFieldTag::TxType,
TxContextFieldTag::Nonce,
TxContextFieldTag::Gas,
TxContextFieldTag::CallerAddress,
TxContextFieldTag::CalleeAddress,
TxContextFieldTag::IsCreate,
TxContextFieldTag::CallDataLength,
TxContextFieldTag::CallDataGasCost,
TxContextFieldTag::AccessListGasCost,
TxContextFieldTag::TxDataGasCost,
]
.map(|field_tag| cb.tx_context(tx_id.expr(), field_tag, None));

let tx_eip2930 = TxEip2930Gadget::construct(cb, tx_id.expr(), tx_type.expr());
let is_call_data_empty = IsZeroGadget::construct(cb, tx_call_data_length.expr());

let tx_l1_msg = TxL1MsgGadget::construct(cb, tx_id.expr(), tx_caller_address.expr());
let tx_l1_msg = TxL1MsgGadget::construct(cb, tx_type.expr(), tx_caller_address.expr());
let tx_l1_fee = cb.condition(not::expr(tx_l1_msg.is_l1_msg()), |cb| {
cb.require_equal(
"tx.nonce == sender.nonce",
Expand Down Expand Up @@ -258,7 +260,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
eth_types::evm_types::GasCost::CREATION_TX.expr(),
eth_types::evm_types::GasCost::TX.expr(),
) + tx_call_data_gas_cost.expr()
+ access_list_gas_cost.expr()
+ tx_eip2930.gas_cost()
+ init_code_gas_cost,
)
});
Expand Down Expand Up @@ -676,6 +678,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {

Self {
tx_id,
tx_type,
tx_nonce,
sender_nonce,
tx_gas,
Expand All @@ -693,7 +696,6 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
is_call_data_empty,
tx_call_data_word_length,
tx_call_data_gas_cost,
access_list_gas_cost,
tx_data_gas_cost,
reversion_info,
sufficient_gas_left,
Expand All @@ -717,6 +719,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
is_coinbase_warm,
tx_l1_fee,
tx_l1_msg,
tx_eip2930,
}
}

Expand All @@ -737,7 +740,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {

let mut rws = StepRws::new(block, step);

let caller_code_hash = if tx.tx_type.is_l1_msg() {
let tx_type = tx.tx_type;
let caller_code_hash = if tx_type.is_l1_msg() {
let caller_code_hash_pair = rws.next().account_codehash_pair();
assert_eq!(
caller_code_hash_pair.0, caller_code_hash_pair.1,
Expand All @@ -748,7 +752,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
U256::zero()
};
self.tx_l1_msg
.assign(region, offset, tx.tx_type, caller_code_hash)?;
.assign(region, offset, tx_type, caller_code_hash)?;

////////////// RWS ////////////////
// if L1:
Expand All @@ -768,7 +772,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
// caller addr
// callee addr
// coinbase
rws.offset_add(if tx.tx_type.is_l1_msg() {
rws.offset_add(if tx_type.is_l1_msg() {
if caller_code_hash.is_zero() {
assert_eq!(
tx.nonce, 0,
Expand Down Expand Up @@ -851,6 +855,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {

self.tx_id
.assign(region, offset, Value::known(F::from(tx.id as u64)))?;
self.tx_type
.assign(region, offset, Value::known(F::from(tx_type as u64)))?;
self.tx_nonce
.assign(region, offset, Value::known(F::from(tx.nonce)))?;
self.sender_nonce
Expand Down Expand Up @@ -921,11 +927,6 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
offset,
Value::known(F::from(tx.call_data_gas_cost)),
)?;
self.access_list_gas_cost.assign(
region,
offset,
Value::known(F::from(tx.access_list_gas_cost)),
)?;
self.tx_data_gas_cost
.assign(region, offset, Value::known(F::from(tx.tx_data_gas_cost)))?;
self.reversion_info.assign(
Expand Down Expand Up @@ -1054,7 +1055,9 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
tx.l1_fee,
tx.l1_fee_committed,
tx.tx_data_gas_cost,
)
)?;

self.tx_eip2930.assign(region, offset, tx)
}
}

Expand Down
2 changes: 2 additions & 0 deletions zkevm-circuits/src/evm_circuit/util/common_gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ use halo2_proofs::{
plonk::{Error, Expression},
};

mod tx_eip2930;
mod tx_l1_fee;
mod tx_l1_msg;

pub(crate) use tx_eip2930::TxEip2930Gadget;
pub(crate) use tx_l1_fee::TxL1FeeGadget;
pub(crate) use tx_l1_msg::TxL1MsgGadget;

Expand Down
Loading