Skip to content

Commit 606565c

Browse files
committed
fix(op-revm): reset BVM_ETH to cold after deposit mint to match op-geth
Deposit minting writes BVM_ETH via the journal (load_account/sload/sstore), which warms the BVM_ETH account + storage slots for the subsequent EVM execution. op-geth mints via StateDB.SetState(), which never touches the EVM access list, so it stays cold. This warm/cold divergence was patched over with a static BVM_ETH_MINT_GAS_COMPENSATION (4500) gated on `!tx.input().is_empty()`. That heuristic mis-fired for non-empty-calldata deposits to EOAs (hoodi-qa2 block 59294: reth 25628 vs geth 21320 -> receiptsRoot/blockHash fork), and over/under-compensated other access paths since the real cold-access cost is dynamic. Root-cause fix: after process_eth_deposit, reset BVM_ETH (account + touched storage slots) back to EIP-2929 cold via a new JournalColdExt, so the EVM observes it exactly like op-geth (cold then falls back to the tx access list / to / precompiles). The static compensation constant and the refund-stage hack are removed entirely. Scope: op-revm only, no core revm changes. The JournalColdExt bound is carried by OpContextTr so no per-call-site threading is needed. Tests: process_eth_deposit_leaves_bvm_eth_cold (mechanism); deposit_to_eoa_with_calldata_no_compensation_matches_geth (block 59294 replay asserts 21320, not 25628); existing mainnet fixture 89718944 (L2StandardBridge) still passes. cargo test -p op-revm: all green.
1 parent 56aee9a commit 606565c

4 files changed

Lines changed: 392 additions & 406 deletions

File tree

crates/op-revm/src/api/exec.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Implementation of the [`ExecuteEvm`] trait for the [`OpEvm`].
22
use crate::{
3-
evm::OpEvm, handler::OpHandler, transaction::OpTxTr, L1BlockInfo, OpHaltReason, OpSpecId,
4-
OpTransactionError,
3+
evm::OpEvm, handler::OpHandler, transaction::bvm_eth::JournalColdExt, transaction::OpTxTr,
4+
L1BlockInfo, OpHaltReason, OpSpecId, OpTransactionError,
55
};
66
use revm::{
77
context::{result::ExecResultAndState, ContextSetters},
@@ -25,7 +25,7 @@ use revm::{
2525
/// Type alias for Optimism context
2626
pub trait OpContextTr:
2727
ContextTr<
28-
Journal: JournalTr<State = EvmState>,
28+
Journal: JournalTr<State = EvmState> + JournalColdExt,
2929
Tx: OpTxTr,
3030
Cfg: Cfg<Spec = OpSpecId>,
3131
Chain = L1BlockInfo,
@@ -35,7 +35,7 @@ pub trait OpContextTr:
3535

3636
impl<T> OpContextTr for T where
3737
T: ContextTr<
38-
Journal: JournalTr<State = EvmState>,
38+
Journal: JournalTr<State = EvmState> + JournalColdExt,
3939
Tx: OpTxTr,
4040
Cfg: Cfg<Spec = OpSpecId>,
4141
Chain = L1BlockInfo,

crates/op-revm/src/constants.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,3 @@ pub const GAS_ORACLE_CONTRACT: Address = address!("42000000000000000000000000000
7474

7575
/// The address of the sequencer fee wallet, which is block coinbase.
7676
pub const SEQUENCER_FEE_VAULT_ADDRESS: Address = address!("4200000000000000000000000000000000000011");
77-
78-
/// Gas compensation for BVM_ETH mint operations to align with go-ethereum behavior.
79-
///
80-
/// This constant compensates for the gas calculation difference between REVM and go-ethereum
81-
/// when handling BVM_ETH state operations. The value of 4500 is derived from EIP-2929 access
82-
/// list gas costs:
83-
/// - Account access difference: 2500 (cold: 2600, warm: 100)
84-
/// - Storage slot access difference: 2000 (cold: 2100, warm: 100)
85-
///
86-
/// REVM marks BVM_ETH account and storage slots as warm during mint/transfer operations,
87-
/// while go-ethereum keeps them cold. When subsequent EVM execution accesses BVM_ETH,
88-
/// this compensation ensures consistent gas consumption.
89-
pub const BVM_ETH_MINT_GAS_COMPENSATION: u64 = 4500;

0 commit comments

Comments
 (0)