Skip to content

migrate: anvil to revm 21 #10361

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 27 commits into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9f7b1f2
downgrade op-revm to 2.0.0 to resolve dep conflict
yash-atreya Apr 24, 2025
84d11f1
add `as_mut_dyn` to trait `MaybeFullDatabase` as we now require mut d…
yash-atreya Apr 24, 2025
6990086
Revert "add `as_mut_dyn` to trait `MaybeFullDatabase` as we now requi…
yash-atreya Apr 24, 2025
29600d7
fix: Inspector should be generic over CTX not DB
yash-atreya Apr 24, 2025
6a5d57b
fix: pass TxEnv to evm.transact
yash-atreya Apr 24, 2025
e4cc032
fix: inspector inference in TransactionExecutor and build_access_list…
yash-atreya Apr 24, 2025
213593b
workaround: dup LogCollector to use with AnvilEvmContext
yash-atreya Apr 24, 2025
fdb9239
fix tests
yash-atreya Apr 24, 2025
78e2f76
fix traces test
yash-atreya Apr 24, 2025
b7b9ddd
fix: use default kzg settings in blob validation
yash-atreya Apr 24, 2025
7fced07
reintroduce OptimismHardfork
yash-atreya Apr 24, 2025
af4e00a
fix: disable nonce check if nonce is None
yash-atreya Apr 24, 2025
f1cdd41
fix!: load state tests by addressing breaking changes in state files
yash-atreya Apr 24, 2025
673696a
fix: access_list test by using evm.inspect_with_tx
yash-atreya Apr 25, 2025
4d9b1bc
fix: replace evm.transact with evm.inspect_with_tx
yash-atreya Apr 25, 2025
298c535
fix: make impl Inspector for AnvilInspector generic over CTX
yash-atreya Apr 25, 2025
1abfdcf
fix: clone inspector in TransactionExecutor to enable evm.inspect_commit
yash-atreya Apr 25, 2025
0efb119
Merge branch 'zerosnacks/revm-bump-2' into yash/anvil-revm-21
yash-atreya Apr 25, 2025
4730007
fix: remove cloned inspector from TransactionExecutor
yash-atreya Apr 25, 2025
1afa5a2
feat(`anvil`): op support revm 21 (#10407)
yash-atreya Apr 29, 2025
57a0fec
docs EitherEvm
yash-atreya Apr 29, 2025
42ccf70
nit
yash-atreya Apr 29, 2025
f8ef782
refac: return TxEnv and Deposit parts separately
yash-atreya Apr 29, 2025
d02f5b8
nits
yash-atreya Apr 29, 2025
d1c2316
nit
yash-atreya Apr 29, 2025
0b8f251
make anvil result aliases more generic
yash-atreya Apr 29, 2025
7e46fad
nit
yash-atreya Apr 29, 2025
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
537 changes: 174 additions & 363 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ solar-sema = { version = "=0.1.2", default-features = false }
## revm
revm = { version = "21.0.0", default-features = false }
revm-inspectors = { version = "0.18.1", features = ["serde"] }
op-revm = { version = "3.0.2", default-features = false }
op-revm = { version = "2.0.0", default-features = false }

## alloy
alloy-consensus = { version = "0.13.0", default-features = false }
Expand Down 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
182 changes: 104 additions & 78 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) -> (TxEnv, Option<DepositTransactionParts>) {
fn transact_to(kind: &TxKind) -> TxKind {
match kind {
TxKind::Call(c) => TxKind::Call(*c),
Expand All @@ -394,19 +397,23 @@ 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 {
caller,
kind: transact_to(to),
data: input.clone(),
chain_id,
nonce: *nonce,
value: (*value),
gas_price: *gas_price,
gas_priority_fee: None,
gas_limit: *gas_limit,
access_list: vec![].into(),
..Default::default()
}
(
TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
chain_id,
nonce: *nonce,
value: (*value),
gas_price: *gas_price,
gas_priority_fee: None,
gas_limit: *gas_limit,
access_list: vec![].into(),
tx_type: 0,
..Default::default()
},
None,
)
}
TypedTransaction::EIP2930(tx) => {
let TxEip2930 {
Expand All @@ -420,19 +427,23 @@ impl PendingTransaction {
access_list,
..
} = tx.tx();
TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *gas_price,
gas_priority_fee: None,
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
..Default::default()
}
(
TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *gas_price,
gas_priority_fee: None,
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
tx_type: 1,
..Default::default()
},
None,
)
}
TypedTransaction::EIP1559(tx) => {
let TxEip1559 {
Expand All @@ -447,19 +458,23 @@ impl PendingTransaction {
access_list,
..
} = tx.tx();
TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *max_fee_per_gas,
gas_priority_fee: Some(*max_priority_fee_per_gas),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
..Default::default()
}
(
TxEnv {
caller,
kind: transact_to(to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *max_fee_per_gas,
gas_priority_fee: Some(*max_priority_fee_per_gas),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
tx_type: 2,
..Default::default()
},
None,
)
}
TypedTransaction::EIP4844(tx) => {
let TxEip4844 {
Expand All @@ -476,21 +491,25 @@ impl PendingTransaction {
blob_versioned_hashes,
..
} = tx.tx().tx();
TxEnv {
caller,
kind: TxKind::Call(*to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *max_fee_per_gas,
gas_priority_fee: Some(*max_priority_fee_per_gas),
max_fee_per_blob_gas: *max_fee_per_blob_gas,
blob_hashes: blob_versioned_hashes.clone(),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
..Default::default()
}
(
TxEnv {
caller,
kind: TxKind::Call(*to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *max_fee_per_gas,
gas_priority_fee: Some(*max_priority_fee_per_gas),
max_fee_per_blob_gas: *max_fee_per_blob_gas,
blob_hashes: blob_versioned_hashes.clone(),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
tx_type: 3,
..Default::default()
},
None,
)
}
TypedTransaction::EIP7702(tx) => {
let TxEip7702 {
Expand All @@ -505,20 +524,24 @@ impl PendingTransaction {
authorization_list,
input,
} = tx.tx();
TxEnv {
caller,
kind: TxKind::Call(*to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *max_fee_per_gas,
gas_priority_fee: Some(*max_priority_fee_per_gas),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
authorization_list: authorization_list.clone(),
..Default::default()
}
(
TxEnv {
caller,
kind: TxKind::Call(*to),
data: input.clone(),
chain_id: Some(*chain_id),
nonce: *nonce,
value: *value,
gas_price: *max_fee_per_gas,
gas_priority_fee: Some(*max_priority_fee_per_gas),
gas_limit: *gas_limit,
access_list: access_list.clone().into(),
authorization_list: authorization_list.clone(),
tx_type: 4,
..Default::default()
},
None,
)
}
TypedTransaction::Deposit(tx) => {
let chain_id = tx.chain_id();
Expand All @@ -533,7 +556,8 @@ impl PendingTransaction {
is_system_tx,
..
} = tx;
TxEnv {

let base = TxEnv {
caller,
kind: transact_to(kind),
data: input.clone(),
Expand All @@ -544,15 +568,17 @@ 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,
};

(base, Some(deposit))
}
}
}
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