From de844e6f3b8386b4e9c500b996d113fc521e81a1 Mon Sep 17 00:00:00 2001 From: anylots <22675649+anylots@users.noreply.github.com> Date: Tue, 27 Jan 2026 17:56:21 +0800 Subject: [PATCH 1/2] make altFeeGas state changes cold --- crates/revm/src/handler.rs | 13 +++++++++++- crates/revm/src/token_fee.rs | 39 +++++++++++++++--------------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/crates/revm/src/handler.rs b/crates/revm/src/handler.rs index 3fc54ac..eb3349f 100644 --- a/crates/revm/src/handler.rs +++ b/crates/revm/src/handler.rs @@ -2,7 +2,7 @@ use alloy_primitives::{Address, Bytes, U256}; use revm::{ - SystemCallEvm, + ExecuteEvm, SystemCallEvm, context::{ Cfg, ContextTr, JournalTr, Transaction, result::{EVMError, ExecutionResult, InvalidTransaction}, @@ -479,6 +479,17 @@ where token_fee_info.token_address, token_amount_required, )?; + + // State changs should be marked cold to avoid warm access in the main tx execution. + let mut state = evm.finalize(); + state.iter_mut().for_each(|(_, acc)| { + acc.mark_cold(); + acc.unmark_touch(); + acc.storage + .iter_mut() + .for_each(|(_, slot)| slot.mark_cold()); + }); + evm.ctx_mut().journal_mut().state.extend(state); } let (_, tx, cfg, journal, _, _) = evm.ctx().all_mut(); diff --git a/crates/revm/src/token_fee.rs b/crates/revm/src/token_fee.rs index 9ccd58c..7081b57 100644 --- a/crates/revm/src/token_fee.rs +++ b/crates/revm/src/token_fee.rs @@ -6,13 +6,10 @@ //! Reference: use alloy_evm::Database; -use alloy_primitives::{Address, Bytes, TxKind, U256, address, keccak256}; +use alloy_primitives::{Address, Bytes, U256, address, keccak256}; use morph_chainspec::hardfork::MorphHardfork; -use morph_primitives::L1_TX_TYPE_ID; -use revm::{ - ExecuteEvm, Inspector, context::TxEnv, context_interface::result::EVMError, - inspector::NoOpInspector, -}; +use revm::SystemCallEvm; +use revm::{Inspector, context_interface::result::EVMError, inspector::NoOpInspector}; use crate::evm::MorphContext; use crate::{MorphEvm, MorphInvalidTransaction}; @@ -193,9 +190,6 @@ fn load_mapping_value( Ok(storage_value) } -/// Gas limit for ERC20 balance query calls. -const BALANCE_OF_GAS_LIMIT: u64 = 200000; - /// Get ERC20 token balance for an account (storage-only version). /// /// First tries to read directly from storage if the balance slot is known. @@ -253,23 +247,22 @@ where let calldata = build_balance_of_calldata(account); // Create a minimal transaction environment for the call - let tx = TxEnv { - caller: Address::ZERO, - gas_limit: BALANCE_OF_GAS_LIMIT, - kind: TxKind::Call(token), - value: U256::ZERO, - data: calldata, - nonce: 0, - tx_type: L1_TX_TYPE_ID, // Mark as L1 message to skip gas validation - ..Default::default() - }; - - // Convert to MorphTxEnv - let morph_tx = crate::MorphTxEnv::new(tx); + // let tx = TxEnv { + // caller: Address::ZERO, + // gas_limit: BALANCE_OF_GAS_LIMIT, + // kind: TxKind::Call(token), + // value: U256::ZERO, + // data: calldata, + // nonce: 0, + // ..Default::default() + // }; + + // // Convert to MorphTxEnv + // let morph_tx = crate::MorphTxEnv::new(tx); // Execute using transact_one evm.cfg.disable_fee_charge = true; // Disable fee charge for system call - match evm.transact_one(morph_tx) { + match evm.system_call_one(token, calldata) { Ok(result) => { if result.is_success() { // Parse the returned balance (32 bytes) From 3c22c041187c832c1fc5a3d8bdc337076fa6edbf Mon Sep 17 00:00:00 2001 From: anylots <22675649+anylots@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:57:19 +0800 Subject: [PATCH 2/2] use system_call_one --- crates/revm/src/handler.rs | 21 +++++++-------------- crates/revm/src/token_fee.rs | 17 ----------------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/crates/revm/src/handler.rs b/crates/revm/src/handler.rs index eb3349f..1fa80ae 100644 --- a/crates/revm/src/handler.rs +++ b/crates/revm/src/handler.rs @@ -95,11 +95,8 @@ where &self, evm: &mut Self::Evm, ) -> Result<(), Self::Error> { - let (_, tx, cfg, journal, _, _) = evm.ctx().all_mut(); - // System transaction - skip all validation - if cfg.disable_fee_charge { - return Ok(()); - } + let (_, tx, _, journal, _, _) = evm.ctx().all_mut(); + // L1 message - skip fee validation if tx.is_l1_msg() { // Load caller's account @@ -128,10 +125,10 @@ where evm: &mut Self::Evm, exec_result: &mut <::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error> { - let (_, tx, cfg, _, _, _) = evm.ctx().all_mut(); + let (_, tx, _, _, _, _) = evm.ctx().all_mut(); // For L1 message transactions & system transactions, no reimbursement is needed - if tx.is_l1_msg() || cfg.disable_fee_charge { + if tx.is_l1_msg() { return Ok(()); } @@ -154,10 +151,7 @@ where exec_result: &mut <::Frame as FrameTr>::FrameResult, ) -> Result<(), Self::Error> { let (block, tx, cfg, journal, _, _) = evm.ctx().all_mut(); - // System transaction - skip all reward - if cfg.disable_fee_charge { - return Ok(()); - } + // L1 message transactions skip all reward. // MorphTransaction rewards are already applied when gasFee is deducted. if tx.is_l1_msg() || tx.is_morph_tx() { @@ -200,8 +194,8 @@ where #[inline] fn validate_env(&self, evm: &mut Self::Evm) -> Result<(), Self::Error> { - // For L1 message transactions & System transaction, skip certain validations - if evm.ctx_ref().tx().is_l1_msg() || evm.ctx_ref().cfg().disable_fee_charge { + // For L1 message transactions + if evm.ctx_ref().tx().is_l1_msg() { // L1 messages have zero gas price, so skip gas price validation return Ok(()); } @@ -484,7 +478,6 @@ where let mut state = evm.finalize(); state.iter_mut().for_each(|(_, acc)| { acc.mark_cold(); - acc.unmark_touch(); acc.storage .iter_mut() .for_each(|(_, slot)| slot.mark_cold()); diff --git a/crates/revm/src/token_fee.rs b/crates/revm/src/token_fee.rs index 7081b57..e6d9122 100644 --- a/crates/revm/src/token_fee.rs +++ b/crates/revm/src/token_fee.rs @@ -245,23 +245,6 @@ where { // Fallback: Execute EVM call to balanceOf(address) let calldata = build_balance_of_calldata(account); - - // Create a minimal transaction environment for the call - // let tx = TxEnv { - // caller: Address::ZERO, - // gas_limit: BALANCE_OF_GAS_LIMIT, - // kind: TxKind::Call(token), - // value: U256::ZERO, - // data: calldata, - // nonce: 0, - // ..Default::default() - // }; - - // // Convert to MorphTxEnv - // let morph_tx = crate::MorphTxEnv::new(tx); - - // Execute using transact_one - evm.cfg.disable_fee_charge = true; // Disable fee charge for system call match evm.system_call_one(token, calldata) { Ok(result) => { if result.is_success() {