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

Commit e3615ee

Browse files
committed
Add AccessListGasCost to TxContextFieldTag.
1 parent b02de5d commit e3615ee

File tree

7 files changed

+60
-8
lines changed

7 files changed

+60
-8
lines changed

bus-mapping/src/evm/opcodes/begin_end_tx.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use crate::{
1212
};
1313
use core::fmt::Debug;
1414
use eth_types::{
15-
evm_types::{gas_utils::tx_data_gas_cost, GasCost, MAX_REFUND_QUOTIENT_OF_GAS_USED},
15+
evm_types::{
16+
gas_utils::{tx_access_list_gas_cost, tx_data_gas_cost},
17+
GasCost, MAX_REFUND_QUOTIENT_OF_GAS_USED,
18+
},
1619
Bytecode, ToWord, Word,
1720
};
1821
use ethers_core::utils::get_contract_address;
@@ -186,13 +189,15 @@ pub fn gen_begin_tx_steps(state: &mut CircuitInputStateRef) -> Result<ExecStep,
186189

187190
// Calculate intrinsic gas cost
188191
let call_data_gas_cost = tx_data_gas_cost(&state.tx.input);
192+
let access_list_gas_cost = tx_access_list_gas_cost(&state.tx.access_list);
189193
let intrinsic_gas_cost = if state.tx.is_create() {
190194
GasCost::CREATION_TX.as_u64()
191195
} else {
192196
GasCost::TX.as_u64()
193197
} + call_data_gas_cost
198+
+ access_list_gas_cost
194199
+ init_code_gas_cost;
195-
log::trace!("intrinsic_gas_cost {intrinsic_gas_cost}, call_data_gas_cost {call_data_gas_cost}, init_code_gas_cost {init_code_gas_cost}, exec_step.gas_cost {:?}", exec_step.gas_cost);
200+
log::trace!("intrinsic_gas_cost {intrinsic_gas_cost}, call_data_gas_cost {call_data_gas_cost}, access_list_gas_cost {access_list_gas_cost}, init_code_gas_cost {init_code_gas_cost}, exec_step.gas_cost {:?}", exec_step.gas_cost);
196201
exec_step.gas_cost = GasCost(intrinsic_gas_cost);
197202

198203
// Get code_hash of callee account

eth-types/src/evm_types.rs

+4
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ impl GasCost {
205205
pub const PRECOMPILE_MODEXP_MIN: Self = Self(200);
206206
/// Base gas cost for precompile call: BLAKE2F
207207
pub const PRECOMPILE_BLAKE2F: Self = Self(0);
208+
/// Gas cost per address in tx access list (EIP 2930)
209+
pub const ACCESS_LIST_PER_ADDRESS: Self = Self(2400);
210+
/// Gas cost per storage key in tx access list (EIP 2930)
211+
pub const ACCESS_LIST_PER_STORAGE_KEY: Self = Self(1900);
208212
}
209213

210214
impl GasCost {

eth-types/src/evm_types/gas_utils.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Utility functions to help calculate gas
22
33
use super::GasCost;
4-
use crate::Word;
4+
use crate::{AccessList, Word};
55

66
/// Calculate memory expansion gas cost by current and next memory word size.
77
pub fn memory_expansion_gas_cost(curr_memory_word_size: u64, next_memory_word_size: u64) -> u64 {
@@ -49,6 +49,18 @@ pub fn eip150_gas(gas_left: u64, gas_specified: Word) -> u64 {
4949
capped_gas
5050
}
5151

52+
/// Calculate gas cost for access list (EIP 2930).
53+
pub fn tx_access_list_gas_cost(access_list: &Option<AccessList>) -> u64 {
54+
access_list.as_ref().map_or(0, |access_list| {
55+
access_list.0.len() as u64 * GasCost::ACCESS_LIST_PER_ADDRESS.as_u64()
56+
+ access_list
57+
.0
58+
.iter()
59+
.fold(0, |acc, item| acc + item.storage_keys.len() as u64)
60+
* GasCost::ACCESS_LIST_PER_STORAGE_KEY.as_u64()
61+
})
62+
}
63+
5264
/// Calculate gas cost for transaction data.
5365
pub fn tx_data_gas_cost(data: &[u8]) -> u64 {
5466
data.iter()

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

+11-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ pub(crate) struct BeginTxGadget<F> {
6060
is_call_data_empty: IsZeroGadget<F>,
6161
tx_call_data_word_length: ConstantDivisionGadget<F, N_BYTES_U64>,
6262
tx_call_data_gas_cost: Cell<F>,
63+
// The gas cost for access list (EIP 2930)
64+
access_list_gas_cost: Cell<F>,
6365
// The gas cost for rlp-encoded bytes of unsigned tx
6466
tx_data_gas_cost: Cell<F>,
6567
reversion_info: ReversionInfo<F>,
@@ -104,7 +106,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
104106
let tx_id = cb.query_cell();
105107

106108
let sender_nonce = cb.query_cell();
107-
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] =
109+
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] =
108110
[
109111
TxContextFieldTag::Nonce,
110112
TxContextFieldTag::Gas,
@@ -113,6 +115,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
113115
TxContextFieldTag::IsCreate,
114116
TxContextFieldTag::CallDataLength,
115117
TxContextFieldTag::CallDataGasCost,
118+
TxContextFieldTag::AccessListGasCost,
116119
TxContextFieldTag::TxDataGasCost,
117120
]
118121
.map(|field_tag| cb.tx_context(tx_id.expr(), field_tag, None));
@@ -255,6 +258,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
255258
eth_types::evm_types::GasCost::CREATION_TX.expr(),
256259
eth_types::evm_types::GasCost::TX.expr(),
257260
) + tx_call_data_gas_cost.expr()
261+
+ access_list_gas_cost.expr()
258262
+ init_code_gas_cost,
259263
)
260264
});
@@ -689,6 +693,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
689693
is_call_data_empty,
690694
tx_call_data_word_length,
691695
tx_call_data_gas_cost,
696+
access_list_gas_cost,
692697
tx_data_gas_cost,
693698
reversion_info,
694699
sufficient_gas_left,
@@ -916,6 +921,11 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
916921
offset,
917922
Value::known(F::from(tx.call_data_gas_cost)),
918923
)?;
924+
self.access_list_gas_cost.assign(
925+
region,
926+
offset,
927+
Value::known(F::from(tx.access_list_gas_cost)),
928+
)?;
919929
self.tx_data_gas_cost
920930
.assign(region, offset, Value::known(F::from(tx.tx_data_gas_cost)))?;
921931
self.reversion_info.assign(

zkevm-circuits/src/table.rs

+2
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ pub enum TxFieldTag {
146146
CallDataLength,
147147
/// Gas cost for transaction call data (4 for byte == 0, 16 otherwise)
148148
CallDataGasCost,
149+
/// Gas cost for access list (EIP 2930)
150+
AccessListGasCost,
149151
/// Gas cost of the transaction data charged in L1
150152
TxDataGasCost,
151153
/// Chain ID

zkevm-circuits/src/tx_circuit.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ use crate::{
1919
BlockContextFieldTag::{CumNumTxs, NumAllTxs, NumTxs},
2020
BlockTable, KeccakTable, LookupTable, RlpFsmRlpTable as RlpTable, SigTable, TxFieldTag,
2121
TxFieldTag::{
22-
BlockNumber, CallData, CallDataGasCost, CallDataLength, CallDataRLC, CalleeAddress,
23-
CallerAddress, ChainID, Gas, GasPrice, IsCreate, Nonce, SigR, SigS, SigV,
24-
TxDataGasCost, TxHashLength, TxHashRLC, TxSignHash, TxSignLength, TxSignRLC,
22+
AccessListGasCost, BlockNumber, CallData, CallDataGasCost, CallDataLength, CallDataRLC,
23+
CalleeAddress, CallerAddress, ChainID, Gas, GasPrice, IsCreate, Nonce, SigR, SigS,
24+
SigV, TxDataGasCost, TxHashLength, TxHashRLC, TxSignHash, TxSignLength, TxSignRLC,
2525
},
2626
TxTable, U16Table, U8Table,
2727
},
@@ -331,6 +331,7 @@ impl<F: Field> SubCircuitConfig<F> for TxCircuitConfig<F> {
331331
is_tx_tag!(is_data, CallData);
332332
is_tx_tag!(is_data_length, CallDataLength);
333333
is_tx_tag!(is_data_gas_cost, CallDataGasCost);
334+
is_tx_tag!(is_access_list_gas_cost, AccessListGasCost);
334335
is_tx_tag!(is_tx_gas_cost, TxDataGasCost);
335336
is_tx_tag!(is_data_rlc, CallDataRLC);
336337
is_tx_tag!(is_chain_id_expr, ChainID);
@@ -466,6 +467,7 @@ impl<F: Field> SubCircuitConfig<F> for TxCircuitConfig<F> {
466467
(is_create(meta), Null),
467468
(is_data_length(meta), Null),
468469
(is_data_gas_cost(meta), Null),
470+
(is_access_list_gas_cost(meta), Null),
469471
(is_sign_hash(meta), Null),
470472
(is_hash(meta), Null),
471473
(is_data(meta), Null),
@@ -554,6 +556,8 @@ impl<F: Field> SubCircuitConfig<F> for TxCircuitConfig<F> {
554556
},
555557
);
556558

559+
// TODO: add basic constraints for AccessListGasCost.
560+
557561
cb.gate(meta.query_fixed(q_enable, Rotation::cur()))
558562
});
559563

@@ -1835,6 +1839,11 @@ impl<F: Field> TxCircuitConfig<F> {
18351839
None,
18361840
Value::known(F::from(tx.call_data_gas_cost)),
18371841
),
1842+
(
1843+
AccessListGasCost,
1844+
None,
1845+
Value::known(F::from(tx.access_list_gas_cost)),
1846+
),
18381847
(
18391848
TxDataGasCost,
18401849
Some(RlpTableInputValue {

zkevm-circuits/src/witness/tx.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
};
1818
use bus_mapping::circuit_input_builder::{self, get_dummy_tx_hash, TxL1Fee};
1919
use eth_types::{
20-
evm_types::gas_utils::tx_data_gas_cost,
20+
evm_types::gas_utils::{tx_access_list_gas_cost, tx_data_gas_cost},
2121
geth_types::{TxType, TxType::PreEip155},
2222
sign_types::{
2323
biguint_to_32bytes_le, ct_option_ok_or, get_dummy_tx, recover_pk2, SignData, SECP256K1_Q,
@@ -67,6 +67,8 @@ pub struct Transaction {
6767
pub call_data_length: usize,
6868
/// The gas cost for transaction call data
6969
pub call_data_gas_cost: u64,
70+
/// The gas cost for access list (EIP 2930)
71+
pub access_list_gas_cost: u64,
7072
/// The gas cost for rlp-encoded bytes of unsigned tx
7173
pub tx_data_gas_cost: u64,
7274
/// Chain ID as per EIP-155.
@@ -226,6 +228,12 @@ impl Transaction {
226228
Value::known(F::zero()),
227229
Value::known(F::from(self.call_data_gas_cost)),
228230
],
231+
[
232+
Value::known(F::from(self.id as u64)),
233+
Value::known(F::from(TxContextFieldTag::AccessListGasCost as u64)),
234+
Value::known(F::zero()),
235+
Value::known(F::from(self.access_list_gas_cost)),
236+
],
229237
[
230238
Value::known(F::from(self.id as u64)),
231239
Value::known(F::from(TxContextFieldTag::TxDataGasCost as u64)),
@@ -858,6 +866,7 @@ impl From<MockTransaction> for Transaction {
858866
call_data: mock_tx.input.to_vec(),
859867
call_data_length: mock_tx.input.len(),
860868
call_data_gas_cost: tx_data_gas_cost(&mock_tx.input),
869+
access_list_gas_cost: tx_access_list_gas_cost(&Some(mock_tx.access_list)),
861870
tx_data_gas_cost: tx_data_gas_cost(&rlp_signed),
862871
chain_id: mock_tx.chain_id,
863872
rlp_unsigned,
@@ -909,6 +918,7 @@ pub(super) fn tx_convert(
909918
call_data: tx.input.clone(),
910919
call_data_length: tx.input.len(),
911920
call_data_gas_cost: tx_data_gas_cost(&tx.input),
921+
access_list_gas_cost: tx_access_list_gas_cost(&tx.access_list),
912922
tx_data_gas_cost: tx_gas_cost,
913923
chain_id,
914924
rlp_unsigned: tx.rlp_unsigned_bytes.clone(),

0 commit comments

Comments
 (0)