Skip to content

Dep: update revm to 20 #94

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 16 commits into from
Mar 27, 2025
20 changes: 8 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "trevm"
version = "0.19.12"
version = "0.20.0"
rust-version = "1.83.0"
edition = "2021"
authors = ["init4"]
Expand All @@ -27,21 +27,23 @@ option-if-let-else = "warn"
redundant-clone = "warn"

[dependencies]
alloy = { version = "=0.11.1", default-features = false, features = ["consensus", "rpc-types-mev", "eips", "k256", "std", "rlp", "sol-types"] }
alloy = { version = "0.12.6", default-features = false, features = ["consensus", "rpc-types-mev", "eips", "k256", "std", "rlp", "sol-types"] }

revm = { version = "19.5.0", default-features = false, features = ["std"] }
revm = { version = "20.0.0", default-features = false }

dashmap = { version = "6.1.0", optional = true }
tracing = { version = "0.1.41", optional = true}
thiserror = "2.0.11"

[dev-dependencies]
revm = { version = "19.5.0", features = [
"test-utils",
revm = { version = "20.0.0", features = [
"serde-json",
"std",
"alloydb",
] }
trevm = { path = ".", features = ["test-utils"] }

alloy = { version = "*", features = ["providers"]}

# misc
eyre = "0.6"
Expand All @@ -67,7 +69,7 @@ concurrent-db = ["dep:dashmap"]

estimate_gas = ["optional_eip3607", "optional_no_base_fee", "dep:tracing"]

test-utils = ["revm/test-utils", "revm/std", "revm/serde-json", "revm/alloydb"]
test-utils = ["revm/std", "revm/serde-json", "revm/alloydb"]

secp256k1 = ["revm/secp256k1"]
c-kzg = ["revm/c-kzg"]
Expand All @@ -80,23 +82,17 @@ dev = [
"optional_balance_check",
"optional_block_gas_limit",
"optional_eip3607",
"optional_gas_refund",
"optional_no_base_fee",
"optional_beneficiary_reward",
]

memory_limit = ["revm/memory_limit"]
optional_balance_check = ["revm/optional_balance_check"]
optional_beneficiary_reward = ["revm/optional_beneficiary_reward"]
optional_block_gas_limit = ["revm/optional_block_gas_limit"]
optional_eip3607 = ["revm/optional_eip3607"]
optional_gas_refund = ["revm/optional_gas_refund"]
optional_no_base_fee = ["revm/optional_no_base_fee"]
full_env_cfg = [
"optional_balance_check",
"optional_block_gas_limit",
"optional_eip3607",
"optional_gas_refund",
"optional_no_base_fee",
"optional_beneficiary_reward",
]
33 changes: 19 additions & 14 deletions examples/basic_transact.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//! Simple TREVM example that demonstrates how to execute a transaction on a contract.
//! It simply loads the contract bytecode and executes a transaction.

use revm::context::TransactTo;
use trevm::{
revm::{
inspector_handle_register,
inspectors::TracerEip3155,
primitives::{hex, AccountInfo, Address, Bytecode, TransactTo, U256},
EvmBuilder, InMemoryDB,
bytecode::Bytecode,
database::InMemoryDB,
inspector::inspectors::TracerEip3155,
primitives::{hex, Address, U256},
state::AccountInfo,
},
trevm_aliases, NoopBlock, NoopCfg, TrevmBuilder, Tx,
};
Expand All @@ -27,18 +29,18 @@ const CALLER_ADDR: Address = Address::with_last_byte(1);
struct SampleTx;

impl Tx for SampleTx {
fn fill_tx_env(&self, tx_env: &mut revm::primitives::TxEnv) {
fn fill_tx_env(&self, tx_env: &mut revm::context::TxEnv) {
tx_env.caller = CALLER_ADDR;
tx_env.transact_to = TransactTo::Call(CONTRACT_ADDR);
tx_env.kind = TransactTo::Call(CONTRACT_ADDR);
tx_env.data = hex::decode(PROGRAM_INPUT).unwrap().into();
}
}

// Produce aliases for the Trevm type
trevm_aliases!(TracerEip3155, InMemoryDB);

fn main() {
let mut db = revm::InMemoryDB::default();
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut db = revm::database::InMemoryDB::default();

let bytecode = Bytecode::new_raw(hex::decode(CONTRACT_BYTECODE).unwrap().into());
let acc_info = AccountInfo::new(U256::ZERO, 1, bytecode.hash_slow(), bytecode);
Expand All @@ -47,18 +49,19 @@ fn main() {
db.insert_contract(&mut acc_info.clone());
db.insert_account_info(CONTRACT_ADDR, acc_info);

let evm = EvmBuilder::default()
let insp = TracerEip3155::new(Box::new(std::io::stdout()));

let trevm = TrevmBuilder::new()
.with_db(db)
.with_external_context(TracerEip3155::new(Box::new(std::io::stdout())))
.append_handler_register(inspector_handle_register)
.build_trevm()
.with_insp(insp)
.build_trevm()?
.fill_cfg(&NoopCfg)
.fill_block(&NoopBlock);

let account = evm.read_account_ref(CONTRACT_ADDR).unwrap();
let account = trevm.read_account_ref(CONTRACT_ADDR).unwrap();
println!("account: {account:?}");

let evm = evm.fill_tx(&SampleTx).run();
let evm = trevm.fill_tx(&SampleTx).run();

match evm {
Ok(res) => {
Expand All @@ -69,4 +72,6 @@ fn main() {
println!("Execution error: {e:?}");
}
};

Ok(())
}
26 changes: 14 additions & 12 deletions examples/fork_ref_transact.rs.bak → examples/fork_ref_transact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

//! This example is currently disabled while waiting for revm @ 14.0.4

use alloy::{eips::BlockId, providers::ProviderBuilder};
use alloy_primitives::{address, Address, TxKind, U256};
use alloy_sol_types::{sol, SolCall};
use alloy::{
eips::BlockId,
primitives::{address, Address, TxKind, U256},
providers::ProviderBuilder,
sol,
sol_types::SolCall,
};
use revm::{context::TxEnv, database::WrapDatabaseAsync};
use trevm::{
revm::{
db::{AlloyDB, CacheDB},
Evm,
},
revm::database::{AlloyDB, CacheDB},
NoopBlock, NoopCfg, TrevmBuilder, Tx,
};

Expand All @@ -22,10 +24,10 @@ sol! {
struct GetReservesFiller;

impl Tx for GetReservesFiller {
fn fill_tx_env(&self, tx_env: &mut revm::primitives::TxEnv) {
fn fill_tx_env(&self, tx_env: &mut TxEnv) {
tx_env.caller = Address::with_last_byte(0);
// ETH/USDT pair on Uniswap V2
tx_env.transact_to = TxKind::Call(POOL_ADDRESS);
tx_env.kind = TxKind::Call(POOL_ADDRESS);
// calldata formed via alloy's abi encoder
tx_env.data = getReservesCall::new(()).abi_encode().into();
// transaction value in wei
Expand Down Expand Up @@ -55,15 +57,15 @@ async fn main() -> eyre::Result<()> {
// =========================================================== //

// initialize new AlloyDB
let alloydb = AlloyDB::new(client, BlockId::default()).unwrap();
let alloydb = WrapDatabaseAsync::new(AlloyDB::new(client, BlockId::default())).unwrap();

// initialise empty in-memory-db
let cache_db = CacheDB::new(alloydb);

// initialise an empty (default) EVM
let evm = Evm::builder()
let evm = TrevmBuilder::new()
.with_db(cache_db)
.build_trevm()
.build_trevm()?
.fill_cfg(&NoopCfg)
.fill_block(&NoopBlock)
.fill_tx(&GetReservesFiller)
Expand Down
61 changes: 61 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use crate::{evm::Trevm, helpers::Ctx, states::EvmNeedsCfg};
use revm::{
database::in_memory_db::InMemoryDB, primitives::hardfork::SpecId, Database, MainBuilder,
};

/// Error that can occur when building a Trevm instance.
#[derive(Debug, Clone, thiserror::Error)]
#[non_exhaustive]
pub enum TrevmBuilderError {
/// Database not set.
#[error("Database not set")]
DatabaseNotSet,
}

/// A builder for [`Trevm`] that allows configuring the EVM.
#[derive(Debug, Clone)]
pub struct TrevmBuilder<Db, Insp> {
pub(crate) db: Option<Db>,
pub(crate) insp: Insp,
pub(crate) spec: SpecId,
}

impl TrevmBuilder<InMemoryDB, ()> {
/// Create a new builder with the default database and inspector.
#[allow(clippy::new_without_default)] // default would make bad devex :(
pub const fn new() -> Self {
Self { db: None, insp: (), spec: SpecId::PRAGUE }
}
}

impl<Db, Insp> TrevmBuilder<Db, Insp> {
/// Set the database for the EVM.
pub fn with_db<Odb>(self, db: Odb) -> TrevmBuilder<Odb, Insp>
where
Db: Database,
{
TrevmBuilder { db: Some(db), insp: self.insp, spec: self.spec }
}

/// Set the inspector for the EVM.
pub fn with_insp<OInsp>(self, insp: OInsp) -> TrevmBuilder<Db, OInsp> {
TrevmBuilder { db: self.db, insp, spec: self.spec }
}

/// Set the spec id for the EVM.
pub const fn with_spec_id(mut self, spec: SpecId) -> Self {
self.spec = spec;
self
}

/// Build the Trevm instance.
pub fn build_trevm(self) -> Result<EvmNeedsCfg<Db, Insp>, TrevmBuilderError>
where
Db: Database,
{
let db = self.db.ok_or(TrevmBuilderError::DatabaseNotSet)?;
let ctx = Ctx::new(db, self.spec);
let evm = ctx.build_mainnet_with_inspector(self.insp);
Ok(Trevm::from(evm))
}
}
41 changes: 19 additions & 22 deletions src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
};
use core::convert::Infallible;
use revm::{
primitives::{EVMError, ResultAndState},
context::result::{EVMError, ResultAndState},
Database,
};
use std::format;
Expand All @@ -18,18 +18,18 @@ use std::format;
/// connector. E.g. the connector may contain some `Db` and the resulting Db may
/// contain `&Db`. This allows for (e.g.) shared caches between DBs on multiple
/// threads.
pub trait DbConnect<'a>: Sync {
pub trait DbConnect: Sync {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't exactly remember why we couldn't elide this lifetime before—what was the reason?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that it could appear in the return types of the functions without being a generic lifetime on the function

/// The database type returned when connecting.
type Database: Database;

/// The error type returned when connecting to the database.
type Error: core::error::Error;

/// Connect to the database.
fn connect(&'a self) -> Result<Self::Database, Self::Error>;
fn connect(&self) -> Result<Self::Database, Self::Error>;
}

impl<Db> DbConnect<'_> for Db
impl<Db> DbConnect for Db
where
Db: Database + Clone + Sync,
{
Expand All @@ -44,28 +44,28 @@ where

/// Trait for types that can create EVM instances.
///
/// Factories should contain configuration information like chain `EXT` types,
/// and database connections. They are intended to enable parallel instantiation
/// Factories should contain configuration information like `Insp` types, and
/// database connections. They are intended to enable parallel instantiation
/// of multiple EVMs in multiple threads sharing some configuration or backing
/// store.
///
/// The lifetime on this trait allows the resulting EVM to borrow from the
/// connector. E.g. the connector may contain some `Db` and the resulting EVM
/// may contain `&Db`. This allows for (e.g.) shared caches between EVMs on
/// multiple threads.
pub trait EvmFactory<'a>: DbConnect<'a> {
/// The `Ext` type used in the resulting EVM.
type Ext: Sync;
pub trait EvmFactory: DbConnect {
/// The `Insp` type used in the resulting EVM.
type Insp: Sync;

/// Create a new EVM instance with the given database connection and
/// extension.
fn create(&'a self) -> Result<EvmNeedsCfg<'a, Self::Ext, Self::Database>, Self::Error>;
fn create(&self) -> Result<EvmNeedsCfg<Self::Database, Self::Insp>, Self::Error>;

/// Create a new EVM instance and parameterize it with a [`Cfg`].
fn create_with_cfg<C>(
&'a self,
&self,
cfg: &C,
) -> Result<EvmNeedsBlock<'a, Self::Ext, Self::Database>, Self::Error>
) -> Result<EvmNeedsBlock<Self::Database, Self::Insp>, Self::Error>
where
C: Cfg,
{
Expand All @@ -75,10 +75,10 @@ pub trait EvmFactory<'a>: DbConnect<'a> {
/// Create a new EVM instance and parameterize it with a [`Cfg`] and a
/// [`Block`].
fn create_with_block<C, B>(
&'a self,
&self,
cfg: &C,
block: &B,
) -> Result<EvmNeedsTx<'a, Self::Ext, Self::Database>, Self::Error>
) -> Result<EvmNeedsTx<Self::Database, Self::Insp>, Self::Error>
where
C: Cfg,
B: Block,
Expand All @@ -89,11 +89,11 @@ pub trait EvmFactory<'a>: DbConnect<'a> {
/// Create a new EVM instance, and parameterize it with a [`Cfg`], a
/// [`Block`], and a [`Tx`], yielding an [`EvmReady`].
fn create_with_tx<C, B, T>(
&'a self,
&self,
cfg: &C,
block: &B,
tx: &T,
) -> Result<EvmReady<'a, Self::Ext, Self::Database>, Self::Error>
) -> Result<EvmReady<Self::Database, Self::Insp>, Self::Error>
where
C: Cfg,
B: Block,
Expand All @@ -107,15 +107,12 @@ pub trait EvmFactory<'a>: DbConnect<'a> {
/// [`EvmTransacted`] or [`EvmErrored`].
#[allow(clippy::type_complexity)]
fn transact<C, B, T>(
&'a self,
&self,
cfg: &C,
block: &B,
tx: &T,
) -> Result<
Result<
EvmTransacted<'a, Self::Ext, Self::Database>,
EvmErrored<'a, Self::Ext, Self::Database>,
>,
Result<EvmTransacted<Self::Database, Self::Insp>, EvmErrored<Self::Database, Self::Insp>>,
Self::Error,
>
where
Expand All @@ -130,7 +127,7 @@ pub trait EvmFactory<'a>: DbConnect<'a> {
/// Run a transaction, take the [`ResultAndState`], and discard the Evm.
/// This is a high-level shortcut function.
fn run<C, B, T>(
&'a self,
&self,
cfg: &C,
block: &B,
tx: &T,
Expand Down
2 changes: 1 addition & 1 deletion src/db/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/// Concurrent version of [`revm::db::State`]
/// Concurrent version of [`revm::database::State`]
#[cfg(feature = "concurrent-db")]
pub mod sync;

Expand Down
Loading
Loading