Skip to content

feat(anvil): op support revm 21 #10407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 29, 2025
29 changes: 29 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ alloy-sol-types = "0.8.22"

alloy-chains = "0.1"
alloy-evm = "0.3.2"
alloy-op-evm = "0.3.2"
alloy-rlp = "0.3"
alloy-trie = "0.7.0"

Expand Down
1 change: 1 addition & 0 deletions crates/anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ foundry-evm-core.workspace = true

# alloy
alloy-evm.workspace = true
alloy-op-evm.workspace = true
alloy-primitives = { workspace = true, features = ["serde"] }
alloy-consensus = { workspace = true, features = ["k256", "kzg"] }
alloy-contract = { workspace = true, features = ["pubsub"] }
Expand Down
52 changes: 32 additions & 20 deletions crates/anvil/core/src/eth/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use alloy_serde::{OtherFields, WithOtherFields};
use bytes::BufMut;
use foundry_evm::traces::CallTraceNode;
use op_alloy_consensus::{TxDeposit, DEPOSIT_TX_TYPE_ID};
use op_revm::{transaction::deposit::DepositTransactionParts, OpTransaction};
use revm::{context::TxEnv, interpreter::InstructionResult};
use serde::{Deserialize, Serialize};
use std::ops::{Deref, Mul};
Expand Down Expand Up @@ -381,7 +382,9 @@ impl PendingTransaction {

/// Converts the [PendingTransaction] into the [TxEnv] context that [`revm`](foundry_evm)
/// expects.
pub fn to_revm_tx_env(&self) -> TxEnv {
///
/// Base [`TxEnv`] is encapsulated in the [`OpTransaction`]
pub fn to_revm_tx_env(&self) -> OpTransaction<TxEnv> {
fn transact_to(kind: &TxKind) -> TxKind {
match kind {
TxKind::Call(c) => TxKind::Call(*c),
Expand All @@ -394,7 +397,7 @@ impl PendingTransaction {
TypedTransaction::Legacy(tx) => {
let chain_id = tx.tx().chain_id;
let TxLegacy { nonce, gas_price, gas_limit, value, to, input, .. } = tx.tx();
TxEnv {
OpTransaction::new(TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
Expand All @@ -405,8 +408,9 @@ impl PendingTransaction {
gas_priority_fee: None,
gas_limit: *gas_limit,
access_list: vec![].into(),
tx_type: 0,
..Default::default()
}
})
}
TypedTransaction::EIP2930(tx) => {
let TxEip2930 {
Expand All @@ -420,7 +424,7 @@ impl PendingTransaction {
access_list,
..
} = tx.tx();
TxEnv {
OpTransaction::new(TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
Expand All @@ -431,8 +435,9 @@ impl PendingTransaction {
gas_priority_fee: None,
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
tx_type: 1,
..Default::default()
}
})
}
TypedTransaction::EIP1559(tx) => {
let TxEip1559 {
Expand All @@ -447,7 +452,7 @@ impl PendingTransaction {
access_list,
..
} = tx.tx();
TxEnv {
OpTransaction::new(TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
Expand All @@ -458,8 +463,9 @@ impl PendingTransaction {
gas_priority_fee: Some(*max_priority_fee_per_gas),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
tx_type: 2,
..Default::default()
}
})
}
TypedTransaction::EIP4844(tx) => {
let TxEip4844 {
Expand All @@ -476,7 +482,7 @@ impl PendingTransaction {
blob_versioned_hashes,
..
} = tx.tx().tx();
TxEnv {
OpTransaction::new(TxEnv {
caller,
kind: TxKind::Call(*to),
data: input.clone(),
Expand All @@ -489,8 +495,9 @@ impl PendingTransaction {
blob_hashes: blob_versioned_hashes.clone(),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
tx_type: 3,
..Default::default()
}
})
}
TypedTransaction::EIP7702(tx) => {
let TxEip7702 {
Expand All @@ -505,7 +512,7 @@ impl PendingTransaction {
authorization_list,
input,
} = tx.tx();
TxEnv {
OpTransaction::new(TxEnv {
caller,
kind: TxKind::Call(*to),
data: input.clone(),
Expand All @@ -517,8 +524,9 @@ impl PendingTransaction {
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
authorization_list: authorization_list.clone(),
tx_type: 4,
..Default::default()
}
})
}
TypedTransaction::Deposit(tx) => {
let chain_id = tx.chain_id();
Expand All @@ -533,7 +541,7 @@ impl PendingTransaction {
is_system_tx,
..
} = tx;
TxEnv {
let base = TxEnv {
caller,
kind: transact_to(kind),
data: input.clone(),
Expand All @@ -544,15 +552,19 @@ impl PendingTransaction {
gas_priority_fee: None,
gas_limit: { *gas_limit },
access_list: vec![].into(),
// TODO: add Optimism support
// optimism: OptimismFields {
// source_hash: Some(*source_hash),
// mint: Some(mint.to::<u128>()),
// is_system_transaction: Some(*is_system_tx),
// enveloped_tx: None,
// },
tx_type: DEPOSIT_TX_TYPE_ID,
..Default::default()
}
};

let deposit = DepositTransactionParts {
source_hash: *source_hash,
mint: Some(mint.to::<u128>()),
is_system_transaction: *is_system_tx,
};

let mut encoded = Vec::new();
tx.encode_2718(&mut encoded);
OpTransaction { base, deposit, enveloped_tx: Some(encoded.into()) }
}
}
}
Expand Down
29 changes: 14 additions & 15 deletions crates/anvil/src/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
config::{ForkChoice, DEFAULT_MNEMONIC},
eth::{backend::db::SerializableState, pool::transactions::TransactionOrder, EthApi},
AccountGenerator, EthereumHardfork, NodeConfig, CHAIN_ID,
AccountGenerator, EthereumHardfork, NodeConfig, OptimismHardfork, CHAIN_ID,
};
use alloy_genesis::Genesis;
use alloy_primitives::{utils::Unit, B256, U256};
Expand Down Expand Up @@ -217,11 +217,11 @@ impl NodeArgs {

let hardfork = match &self.hardfork {
Some(hf) => {
// if self.evm.optimism {
// Some(OptimismHardfork::from_str(hf)?.into())
// } else {
Some(EthereumHardfork::from_str(hf)?.into())
// }
if self.evm.optimism {
Some(OptimismHardfork::from_str(hf)?.into())
} else {
Some(EthereumHardfork::from_str(hf)?.into())
}
}
None => None,
};
Expand Down Expand Up @@ -791,9 +791,8 @@ fn duration_from_secs_f64(s: &str) -> Result<Duration, String> {

#[cfg(test)]
mod tests {
use crate::EthereumHardfork;

use super::*;
use crate::{EthereumHardfork, OptimismHardfork};
use std::{env, net::Ipv4Addr};

#[test]
Expand Down Expand Up @@ -833,13 +832,13 @@ mod tests {
assert_eq!(config.hardfork, Some(EthereumHardfork::Berlin.into()));
}

// #[test]
// fn can_parse_optimism_hardfork() {
// let args: NodeArgs =
// NodeArgs::parse_from(["anvil", "--optimism", "--hardfork", "Regolith"]);
// let config = args.into_node_config().unwrap();
// assert_eq!(config.hardfork, Some(OptimismHardfork::Regolith.into()));
// }
#[test]
fn can_parse_optimism_hardfork() {
let args: NodeArgs =
NodeArgs::parse_from(["anvil", "--optimism", "--hardfork", "Regolith"]);
let config = args.into_node_config().unwrap();
assert_eq!(config.hardfork, Some(OptimismHardfork::Regolith.into()));
}

#[test]
fn cant_parse_invalid_hardfork() {
Expand Down
10 changes: 6 additions & 4 deletions crates/anvil/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
},
hardfork::ChainHardfork,
mem::{self, in_memory_db::MemDb},
EthereumHardfork, FeeManager, PrecompileFactory,
EthereumHardfork, FeeManager, OptimismHardfork, PrecompileFactory,
};
use alloy_consensus::BlockHeader;
use alloy_genesis::Genesis;
Expand Down Expand Up @@ -527,9 +527,9 @@ impl NodeConfig {
if let Some(hardfork) = self.hardfork {
return hardfork;
}
// if self.enable_optimism {
// return OptimismHardfork::default().into();
// }
if self.enable_optimism {
return OptimismHardfork::default().into();
}
EthereumHardfork::default().into()
}

Expand Down Expand Up @@ -1048,6 +1048,8 @@ impl NodeConfig {
TxEnv { chain_id: Some(self.get_chain_id()), ..Default::default() },
);

env.is_optimism = self.enable_optimism;

let fees = FeeManager::new(
spec_id,
self.get_base_fee(),
Expand Down
Loading
Loading