From d44d401a5dfe4a0f641a626c59ef102ff655289b Mon Sep 17 00:00:00 2001 From: evalir Date: Mon, 5 May 2025 19:28:05 +0200 Subject: [PATCH 01/17] chore(deps): upgrade to revm22/alloy0.14 --- Cargo.toml | 8 ++++---- examples/fork_ref_transact.rs | 2 +- src/evm.rs | 3 +-- src/system/eip6110.rs | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0ea830c..a7e2ca5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,23 +27,23 @@ option-if-let-else = "warn" redundant-clone = "warn" [dependencies] -alloy = { version = "0.12.6", default-features = false, features = ["consensus", "rpc-types-mev", "eips", "k256", "std", "rlp", "sol-types"] } +alloy = { version = "0.14.0", default-features = false, features = ["consensus", "rpc-types-mev", "eips", "k256", "std", "rlp", "sol-types"] } -revm = { version = "20.0.0", default-features = false } +revm = { version = "22.0.1", 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 = "20.0.0", features = [ +revm = { version = "22.0.1", features = [ "serde-json", "std", "alloydb", ] } trevm = { path = ".", features = ["test-utils"] } -alloy = { version = "0.12.6", features = ["providers"]} +alloy = { version = "0.14.0", features = ["providers"]} # misc eyre = "0.6" diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 3687950..2b5e85a 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -78,7 +78,7 @@ async fn main() -> eyre::Result<()> { let output = evm.output().expect("Execution halted"); // decode bytes to reserves + ts via alloy's abi decode - let return_vals = getReservesCall::abi_decode_returns(output, true)?; + let return_vals = getReservesCall::abi_decode_returns(output)?; // Print emulated getReserves() call output println!("Reserve0: {:#?}", return_vals.reserve0); diff --git a/src/evm.rs b/src/evm.rs index a44ff07..c5c8576 100644 --- a/src/evm.rs +++ b/src/evm.rs @@ -1978,12 +1978,11 @@ where /// [`SolCall`]: alloy::sol_types::SolCall pub fn output_sol( &self, - validate: bool, ) -> Option> where T::Return: alloy::sol_types::SolType, { - self.output().map(|output| T::abi_decode_returns(output, validate)) + self.output().map(|output| T::abi_decode_returns(output)) } /// Get the gas used by the transaction. diff --git a/src/system/eip6110.rs b/src/system/eip6110.rs index 2c26917..d92a9a3 100644 --- a/src/system/eip6110.rs +++ b/src/system/eip6110.rs @@ -60,7 +60,7 @@ where logs.into_iter().filter(|log| log.address == MAINNET_DEPOSIT_CONTRACT_ADDRESS).map(|log| { // We assume that the log is valid because it was emitted by the // deposit contract. - let decoded_log = DepositEvent::decode_log(log, false).expect("invalid log"); + let decoded_log = DepositEvent::decode_log(log).expect("invalid log"); parse_deposit_from_log(&decoded_log) }) } @@ -74,7 +74,7 @@ pub fn accumulate_deposits_from_logs<'a>( |log| { // We assume that the log is valid because it was emitted by the // deposit contract. - let decoded_log = DepositEvent::decode_log(log, false).expect("invalid log"); + let decoded_log = DepositEvent::decode_log(log).expect("invalid log"); accumulate_deposit_from_log(&decoded_log, out); }, ); From 09c767c2af902e51825702766f915a96cff99145 Mon Sep 17 00:00:00 2001 From: evalir Date: Wed, 21 May 2025 13:15:08 +0200 Subject: [PATCH 02/17] chore: alloy1.0.5/revm23 fixes --- Cargo.toml | 24 ++++++++++++--------- examples/fork_ref_transact.rs | 2 +- src/driver/alloy.rs | 15 ++++++++++--- src/evm.rs | 40 +++++++++++++++++------------------ src/ext.rs | 2 +- src/fill/alloy.rs | 8 ++++++- src/fill/fillers.rs | 12 +++++------ src/fill/traits.rs | 6 +++--- src/inspectors/spanning.rs | 16 ++++++++------ src/system/mod.rs | 8 +++---- 10 files changed, 78 insertions(+), 55 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a7e2ca5..4b131f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trevm" -version = "0.20.10" +version = "0.20.11" rust-version = "1.83.0" edition = "2021" authors = ["init4"] @@ -27,23 +27,27 @@ option-if-let-else = "warn" redundant-clone = "warn" [dependencies] -alloy = { version = "0.14.0", default-features = false, features = ["consensus", "rpc-types-mev", "eips", "k256", "std", "rlp", "sol-types"] } +alloy = { version = "1.0.5", default-features = false, features = [ + "consensus", + "rpc-types-mev", + "eips", + "k256", + "std", + "rlp", + "sol-types", +] } -revm = { version = "22.0.1", default-features = false } +revm = { version = "23.1.0", default-features = false } dashmap = { version = "6.1.0", optional = true } -tracing = { version = "0.1.41", optional = true} +tracing = { version = "0.1.41", optional = true } thiserror = "2.0.11" [dev-dependencies] -revm = { version = "22.0.1", features = [ - "serde-json", - "std", - "alloydb", -] } +revm = { version = "23.1.0", features = ["serde-json", "std", "alloydb"] } trevm = { path = ".", features = ["test-utils"] } -alloy = { version = "0.14.0", features = ["providers"]} +alloy = { version = "1.0.5", features = ["providers"] } # misc eyre = "0.6" diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 2b5e85a..7065061 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -42,7 +42,7 @@ async fn main() -> eyre::Result<()> { // create ethers client and wrap it in Arc let rpc_url = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"; - let client = ProviderBuilder::new().on_http(rpc_url.parse()?); + let client = ProviderBuilder::new().connect_http(rpc_url.parse()?); // ----------------------------------------------------------- // // Storage slots of UniV2Pair contract // diff --git a/src/driver/alloy.rs b/src/driver/alloy.rs index dcd6fa3..565f754 100644 --- a/src/driver/alloy.rs +++ b/src/driver/alloy.rs @@ -4,7 +4,10 @@ use crate::{ trevm_bail, trevm_ensure, trevm_try, Block, BundleDriver, DriveBundleResult, }; use alloy::{ - consensus::{Transaction, TxEip4844Variant, TxEnvelope}, + consensus::{ + crypto::RecoveryError, transaction::SignerRecoverable, Transaction, TxEip4844Variant, + TxEnvelope, + }, eips::{eip2718::Decodable2718, BlockNumberOrTag}, primitives::{bytes::Buf, keccak256, Address, Bytes, TxKind, U256}, rpc::types::mev::{ @@ -35,7 +38,7 @@ pub enum BundleError { /// An error occurred while decoding a transaction contained in the bundle. TransactionDecodingError(alloy::eips::eip2718::Eip2718Error), /// An error occurred while recovering the sender of a transaction. - TransactionSenderRecoveryError(alloy::primitives::SignatureError), + TransactionSenderRecoveryError(alloy::consensus::crypto::RecoveryError), /// An error occurred while running the EVM. EVMError { /// The error that occurred while running the EVM. @@ -71,7 +74,7 @@ impl From for BundleError impl From for BundleError { fn from(err: alloy::primitives::SignatureError) -> Self { - Self::TransactionSenderRecoveryError(err) + Self::TransactionSenderRecoveryError(err.into()) } } @@ -91,6 +94,12 @@ impl std::error::Error for BundleError { } } +impl From for BundleError { + fn from(err: RecoveryError) -> Self { + Self::TransactionSenderRecoveryError(err) + } +} + impl core::fmt::Debug for BundleError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { diff --git a/src/evm.rs b/src/evm.rs index c5c8576..d0bd8d6 100644 --- a/src/evm.rs +++ b/src/evm.rs @@ -96,12 +96,12 @@ where /// Deconstruct the [`Trevm`] into the backing DB, dropping all other types. pub fn into_db(self) -> Db { - self.inner.data.ctx.journaled_state.database + self.inner.ctx.journaled_state.database } /// Get the id of the currently running hardfork spec. pub fn spec_id(&self) -> SpecId { - self.inner.data.ctx.cfg().spec() + self.inner.ctx.cfg().spec() } /// Set the [SpecId], modifying the EVM handlers accordingly. This function @@ -712,7 +712,7 @@ where /// [`Eip-170`]: https://eips.ethereum.org/EIPS/eip-170 pub fn set_code_size_limit(&mut self, limit: usize) -> Option { let mut csl = None; - self.inner.data.ctx.modify_cfg(|cfg| { + self.inner.ctx.modify_cfg(|cfg| { csl = cfg.limit_contract_code_size.replace(limit); }); csl @@ -724,7 +724,7 @@ where /// [`Eip-170`]: https://eips.ethereum.org/EIPS/eip-170 pub fn disable_code_size_limit(&mut self) -> Option { let mut csl = None; - self.inner.data.ctx.modify_cfg(|cfg| csl = cfg.limit_contract_code_size.take()); + self.inner.ctx.modify_cfg(|cfg| csl = cfg.limit_contract_code_size.take()); csl } @@ -766,7 +766,7 @@ where cfg.fill_cfg(&mut self.inner); let mut this = f(self); - this.inner.data.ctx.modify_cfg(|cfg| *cfg = previous); + this.inner.ctx.modify_cfg(|cfg| *cfg = previous); this } @@ -879,7 +879,7 @@ where /// [EIP-3607]: https://eips.ethereum.org/EIPS/eip-3607 #[cfg(feature = "optional_eip3607")] pub fn disable_eip3607(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_eip3607 = true); + self.inner.ctx.modify_cfg(|cfg| cfg.disable_eip3607 = true); } /// Enable [EIP-3607]. See [`Self::disable_eip3607`]. @@ -887,7 +887,7 @@ where /// [EIP-3607]: https://eips.ethereum.org/EIPS/eip-3607 #[cfg(feature = "optional_eip3607")] pub fn enable_eip3607(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_eip3607 = false); + self.inner.ctx.modify_cfg(|cfg| cfg.disable_eip3607 = false); } /// Run a closure with [EIP-3607] disabled, then restore the previous @@ -901,7 +901,7 @@ where self.disable_eip3607(); let mut new = f(self); - new.inner.data.ctx.modify_cfg(|cfg| cfg.disable_eip3607 = previous); + new.inner.ctx.modify_cfg(|cfg| cfg.disable_eip3607 = previous); new } @@ -911,7 +911,7 @@ where /// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559 #[cfg(feature = "optional_no_base_fee")] pub fn disable_base_fee(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_base_fee = true) + self.inner.ctx.modify_cfg(|cfg| cfg.disable_base_fee = true) } /// Enable [EIP-1559] base fee checks. See [`Self::disable_base_fee`]. @@ -919,7 +919,7 @@ where /// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559 #[cfg(feature = "optional_no_base_fee")] pub fn enable_base_fee(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_base_fee = false) + self.inner.ctx.modify_cfg(|cfg| cfg.disable_base_fee = false) } /// Run a closure with [EIP-1559] base fee checks disabled, then restore the @@ -935,19 +935,19 @@ where self.disable_base_fee(); let mut new = f(self); - new.inner.data.ctx.modify_cfg(|cfg| cfg.disable_base_fee = previous); + new.inner.ctx.modify_cfg(|cfg| cfg.disable_base_fee = previous); new } /// Disable nonce checks. This allows transactions to be sent with /// incorrect nonces, and is useful for things like system transactions. pub fn disable_nonce_check(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = true) + self.inner.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = true) } /// Enable nonce checks. See [`Self::disable_nonce_check`]. pub fn enable_nonce_check(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = false) + self.inner.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = false) } /// Run a closure with nonce checks disabled, then restore the previous @@ -961,7 +961,7 @@ where self.disable_nonce_check(); let mut new = f(self); - new.inner.data.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = previous); + new.inner.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = previous); new } } @@ -1080,7 +1080,7 @@ where b.fill_block(&mut self.inner); let mut this = f(self); - this.inner.data.ctx.set_block(previous); + this.inner.ctx.set_block(previous); this } @@ -1100,11 +1100,11 @@ where match f(self) { Ok(mut evm) => { - evm.inner.data.ctx.set_block(previous); + evm.inner.ctx.set_block(previous); Ok(evm) } Err(mut evm) => { - evm.inner.data.ctx.set_block(previous); + evm.inner.ctx.set_block(previous); Err(evm) } } @@ -1363,7 +1363,7 @@ where let previous = self.inner.tx().clone(); t.fill_tx(&mut self.inner); let mut this = f(self); - this.inner.data.ctx.set_tx(previous); + this.inner.ctx.set_tx(previous); this } @@ -1383,11 +1383,11 @@ where t.fill_tx(&mut self.inner); match f(self) { Ok(mut evm) => { - evm.inner.data.ctx.set_tx(previous); + evm.inner.ctx.set_tx(previous); Ok(evm) } Err(mut evm) => { - evm.inner.data.ctx.set_tx(previous); + evm.inner.ctx.set_tx(previous); Err(evm) } } diff --git a/src/ext.rs b/src/ext.rs index 34613db..8e3e304 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -176,6 +176,6 @@ where Ctx: ContextTr, { fn db_mut_ext(&mut self) -> &mut Ctx::Db { - self.data.ctx.db() + self.ctx.db() } } diff --git a/src/fill/alloy.rs b/src/fill/alloy.rs index 8d8d9ff..75cfbf6 100644 --- a/src/fill/alloy.rs +++ b/src/fill/alloy.rs @@ -1,5 +1,6 @@ use alloy::{ consensus::{Signed, TxType}, + eips::eip7702::{RecoveredAuthorization, SignedAuthorization}, primitives::U256, }; use revm::{ @@ -323,6 +324,11 @@ impl Tx for alloy::rpc::types::TransactionRequest { *caller = self.from.unwrap_or_default(); + let auth_list = self.authorization_list.clone().unwrap_or_default(); + let auth_list: Vec< + revm::context::either::Either, + > = auth_list.into_iter().map(revm::context::either::Either::Left).collect(); + // NB: this is set to max if not provided, as users will typically // intend that to mean "as much as possible" *tx_type = self.transaction_type.unwrap_or(TxType::Eip1559 as u8); @@ -337,7 +343,7 @@ impl Tx for alloy::rpc::types::TransactionRequest { *gas_priority_fee = self.max_priority_fee_per_gas; *blob_hashes = self.blob_versioned_hashes.clone().unwrap_or_default(); *max_fee_per_blob_gas = self.max_fee_per_blob_gas.unwrap_or_default(); - *authorization_list = self.authorization_list.clone().unwrap_or_default(); + authorization_list.extend(auth_list); } } diff --git a/src/fill/fillers.rs b/src/fill/fillers.rs index 3474911..f917a85 100644 --- a/src/fill/fillers.rs +++ b/src/fill/fillers.rs @@ -73,11 +73,11 @@ impl Cfg for GasEstimationFiller { &self, evm: &mut revm::context::Evm, Insp, Inst, Prec>, ) { - evm.data.ctx.modify_cfg(|cfg_env| self.fill_cfg_env(cfg_env)); + evm.ctx.modify_cfg(|cfg_env| self.fill_cfg_env(cfg_env)); - let chain_id = evm.data.ctx.cfg.chain_id; + let chain_id = evm.ctx.cfg.chain_id; - evm.data.ctx.modify_tx(|tx_env| { + evm.ctx.modify_tx(|tx_env| { tx_env.chain_id = Some(chain_id); }); } @@ -107,11 +107,11 @@ impl Cfg for CallFiller { &self, evm: &mut revm::context::Evm, Insp, Inst, Prec>, ) { - evm.data.ctx.modify_cfg(|cfg_env| self.fill_cfg_env(cfg_env)); + evm.ctx.modify_cfg(|cfg_env| self.fill_cfg_env(cfg_env)); - let chain_id = evm.data.ctx.cfg.chain_id; + let chain_id = evm.ctx.cfg.chain_id; - evm.data.ctx.modify_tx(|tx_env| { + evm.ctx.modify_tx(|tx_env| { tx_env.chain_id = Some(chain_id); }); } diff --git a/src/fill/traits.rs b/src/fill/traits.rs index 2592a4b..f8c4150 100644 --- a/src/fill/traits.rs +++ b/src/fill/traits.rs @@ -23,7 +23,7 @@ pub trait Tx: Send + Sync { where Self: Sized, { - evm.data.ctx.modify_tx(|tx_env| self.fill_tx_env(tx_env)); + evm.ctx.modify_tx(|tx_env| self.fill_tx_env(tx_env)); } } @@ -65,7 +65,7 @@ pub trait Block: Send + Sync { where Self: Sized, { - evm.data.ctx.modify_block(|block_env| self.fill_block_env(block_env)); + evm.ctx.modify_block(|block_env| self.fill_block_env(block_env)); } /// Get the transaction count hint from the filler. This can be used for @@ -122,7 +122,7 @@ pub trait Cfg: Send + Sync { where Self: Sized, { - evm.data.ctx.modify_cfg(|cfg_env| self.fill_cfg_env(cfg_env)); + evm.ctx.modify_cfg(|cfg_env| self.fill_cfg_env(cfg_env)); } } diff --git a/src/inspectors/spanning.rs b/src/inspectors/spanning.rs index b39f06a..8db2fc3 100644 --- a/src/inspectors/spanning.rs +++ b/src/inspectors/spanning.rs @@ -1,8 +1,8 @@ -use alloy::hex; +use alloy::{consensus::constants::SELECTOR_LEN, hex}; use revm::{ interpreter::{ - CallInputs, CallOutcome, CreateInputs, CreateOutcome, EOFCreateInputs, Interpreter, - InterpreterTypes, + CallInput, CallInputs, CallOutcome, CreateInputs, CreateOutcome, EOFCreateInputs, + Interpreter, InterpreterTypes, }, Inspector, }; @@ -113,13 +113,17 @@ impl SpanningInspector { /// Create a span for a `CALL`-family opcode. fn span_call(&self, _context: &Ctx, inputs: &CallInputs) -> Span { - let mut selector = inputs.input.clone(); - selector.truncate(4); + let selector = if let CallInput::Bytes(ref input) = inputs.input { + input[..SELECTOR_LEN].try_into().unwrap_or([0; 4]) + } else { + [0; 4] + }; + runtime_level_span!( self.level, "call", input_len = inputs.input.len(), - selector = hex::encode(&selector), + selector = hex::encode(selector), gas_limit = inputs.gas_limit, bytecode_address = %inputs.bytecode_address, target_addrses = %inputs.target_address, diff --git a/src/system/mod.rs b/src/system/mod.rs index 721cf33..e996655 100644 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -108,7 +108,7 @@ fn cleanup_syscall( }); // Restore the nonce check - evm.data.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = previous_nonce_check); + evm.ctx.modify_cfg(|cfg| cfg.disable_nonce_check = previous_nonce_check); // Remove the system caller and fees from the state let state = &mut result.state; @@ -136,18 +136,18 @@ where let limit = evm.tx().gas_limit(); - let block = &mut evm.data.ctx.block; + let block = &mut evm.ctx.block; let old_gas_limit = core::mem::replace(&mut block.gas_limit, limit); let old_base_fee = core::mem::take(&mut block.basefee); - let previous_nonce_check = std::mem::replace(&mut evm.data.ctx.cfg.disable_nonce_check, true); + let previous_nonce_check = std::mem::replace(&mut evm.ctx.cfg.disable_nonce_check, true); let mut result = evm.inspect_replay()?; // Cleanup the syscall. cleanup_syscall(evm, &mut result, syscall, old_gas_limit, old_base_fee, previous_nonce_check); - evm.data.ctx.db().commit(result.state); + evm.ctx.db().commit(result.state); // apply result, remove receipt from block outputs. Ok(result.result) From cfcd66b0489619ebc0f8a02e3488f9b06e36ec6f Mon Sep 17 00:00:00 2001 From: evalir Date: Wed, 21 May 2025 13:21:19 +0200 Subject: [PATCH 03/17] chore: more fixes --- src/evm.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/evm.rs b/src/evm.rs index d0bd8d6..c6387c8 100644 --- a/src/evm.rs +++ b/src/evm.rs @@ -810,10 +810,7 @@ where #[cfg(feature = "memory_limit")] pub fn set_memory_limit(&mut self, new_limit: u64) -> u64 { let mut ml = 0; - self.inner - .data - .ctx - .modify_cfg(|cfg| ml = core::mem::replace(&mut cfg.memory_limit, new_limit)); + self.inner.ctx.modify_cfg(|cfg| ml = core::mem::replace(&mut cfg.memory_limit, new_limit)); ml } @@ -822,13 +819,13 @@ where /// execution doesn't fail. #[cfg(feature = "optional_balance_check")] pub fn disable_balance_check(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_balance_check = true) + self.inner.ctx.modify_cfg(|cfg| cfg.disable_balance_check = true) } /// Enable balance checks. See [`Self::disable_balance_check`]. #[cfg(feature = "optional_balance_check")] pub fn enable_balance_check(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_balance_check = false) + self.inner.ctx.modify_cfg(|cfg| cfg.disable_balance_check = false) } /// Run a closure with balance checks disabled, then restore the previous @@ -841,7 +838,7 @@ where let previous = self.inner.cfg().disable_balance_check; self.disable_balance_check(); let mut new = f(self); - new.inner.data.ctx.modify_cfg(|cfg| cfg.disable_balance_check = previous); + new.inner.ctx.modify_cfg(|cfg| cfg.disable_balance_check = previous); new } @@ -850,13 +847,13 @@ where /// simulating large transactions like forge scripts. #[cfg(feature = "optional_block_gas_limit")] pub fn disable_block_gas_limit(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_block_gas_limit = true); + self.inner.ctx.modify_cfg(|cfg| cfg.disable_block_gas_limit = true); } /// Enable block gas limits. See [`Self::disable_block_gas_limit`]. #[cfg(feature = "optional_block_gas_limit")] pub fn enable_block_gas_limit(&mut self) { - self.inner.data.ctx.modify_cfg(|cfg| cfg.disable_block_gas_limit = false); + self.inner.ctx.modify_cfg(|cfg| cfg.disable_block_gas_limit = false); } /// Run a closure with block gas limits disabled, then restore the previous @@ -869,7 +866,7 @@ where let previous = self.inner.cfg().disable_block_gas_limit; self.disable_block_gas_limit(); let mut new = f(self); - new.inner.data.ctx.modify_cfg(|cfg| cfg.disable_block_gas_limit = previous); + new.inner.ctx.modify_cfg(|cfg| cfg.disable_block_gas_limit = previous); new } From bb5e53cf16af699719846007fd6beb5e9eb02b9a Mon Sep 17 00:00:00 2001 From: evalir Date: Wed, 21 May 2025 17:26:54 +0200 Subject: [PATCH 04/17] chore: keep optional validation --- src/evm.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/evm.rs b/src/evm.rs index c6387c8..50a7ebd 100644 --- a/src/evm.rs +++ b/src/evm.rs @@ -1975,10 +1975,15 @@ where /// [`SolCall`]: alloy::sol_types::SolCall pub fn output_sol( &self, + validate: bool, ) -> Option> where T::Return: alloy::sol_types::SolType, { + if validate { + return self.output().map(|output| T::abi_decode_returns_validate(output)); + } + self.output().map(|output| T::abi_decode_returns(output)) } From e81f9569d30743fb854a0bc497cd84d3e9ea2289 Mon Sep 17 00:00:00 2001 From: evalir Date: Wed, 21 May 2025 17:29:42 +0200 Subject: [PATCH 05/17] chore: nicer auth list wrangling --- src/fill/alloy.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/fill/alloy.rs b/src/fill/alloy.rs index 75cfbf6..723b67d 100644 --- a/src/fill/alloy.rs +++ b/src/fill/alloy.rs @@ -1,6 +1,5 @@ use alloy::{ consensus::{Signed, TxType}, - eips::eip7702::{RecoveredAuthorization, SignedAuthorization}, primitives::U256, }; use revm::{ @@ -324,11 +323,6 @@ impl Tx for alloy::rpc::types::TransactionRequest { *caller = self.from.unwrap_or_default(); - let auth_list = self.authorization_list.clone().unwrap_or_default(); - let auth_list: Vec< - revm::context::either::Either, - > = auth_list.into_iter().map(revm::context::either::Either::Left).collect(); - // NB: this is set to max if not provided, as users will typically // intend that to mean "as much as possible" *tx_type = self.transaction_type.unwrap_or(TxType::Eip1559 as u8); @@ -343,7 +337,13 @@ impl Tx for alloy::rpc::types::TransactionRequest { *gas_priority_fee = self.max_priority_fee_per_gas; *blob_hashes = self.blob_versioned_hashes.clone().unwrap_or_default(); *max_fee_per_blob_gas = self.max_fee_per_blob_gas.unwrap_or_default(); - authorization_list.extend(auth_list); + *authorization_list = self + .authorization_list + .iter() + .flatten() + .cloned() + .map(revm::context::either::Either::Left) + .collect(); } } From 3d3467193c53f375a00b770b0cab600e38aca896 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 10:53:49 +0200 Subject: [PATCH 06/17] fix: proper selector parsing --- src/inspectors/spanning.rs | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/inspectors/spanning.rs b/src/inspectors/spanning.rs index 8db2fc3..9d9baf8 100644 --- a/src/inspectors/spanning.rs +++ b/src/inspectors/spanning.rs @@ -1,5 +1,6 @@ use alloy::{consensus::constants::SELECTOR_LEN, hex}; use revm::{ + context::{ContextTr, LocalContextTr}, interpreter::{ CallInput, CallInputs, CallOutcome, CreateInputs, CreateOutcome, EOFCreateInputs, Interpreter, InterpreterTypes, @@ -112,12 +113,11 @@ impl SpanningInspector { } /// Create a span for a `CALL`-family opcode. - fn span_call(&self, _context: &Ctx, inputs: &CallInputs) -> Span { - let selector = if let CallInput::Bytes(ref input) = inputs.input { - input[..SELECTOR_LEN].try_into().unwrap_or([0; 4]) - } else { - [0; 4] - }; + fn span_call(&self, _context: &mut Ctx, inputs: &CallInputs) -> Span + where + Ctx: ContextTr, + { + let selector = resolve_selector(inputs, _context).unwrap_or_default(); runtime_level_span!( self.level, @@ -134,7 +134,10 @@ impl SpanningInspector { } /// Create, enter, and store a span for a `CALL`-family opcode. - fn enter_call(&mut self, context: &Ctx, inputs: &CallInputs) { + fn enter_call(&mut self, context: &mut Ctx, inputs: &CallInputs) + where + Ctx: ContextTr, + { self.active.push(self.span_call(context, inputs).entered()) } @@ -176,6 +179,7 @@ impl SpanningInspector { impl Inspector for SpanningInspector where Int: InterpreterTypes, + Ctx: ContextTr, { fn initialize_interp(&mut self, interp: &mut Interpreter, context: &mut Ctx) { self.init(interp, context); @@ -222,3 +226,17 @@ where self.exit_span(); } } + +/// Resolve a selector from the [CallInputs]. +fn resolve_selector(inputs: &CallInputs, ctx: &mut impl ContextTr) -> Option<[u8; SELECTOR_LEN]> { + match &inputs.input { + CallInput::SharedBuffer(range) => { + let raw = ctx.local().shared_memory_buffer_slice(range.clone()); + + raw?.get(..SELECTOR_LEN).map(TryInto::try_into).and_then(Result::ok) + } + CallInput::Bytes(bytes) => { + bytes.as_ref().get(..SELECTOR_LEN).map(TryInto::try_into).and_then(Result::ok) + } + } +} From 54452771accef7c4e9f0953cd3baf4b3c02309d0 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 14:11:58 +0200 Subject: [PATCH 07/17] chore: no underscore --- src/inspectors/spanning.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/inspectors/spanning.rs b/src/inspectors/spanning.rs index 9d9baf8..3ea9eaf 100644 --- a/src/inspectors/spanning.rs +++ b/src/inspectors/spanning.rs @@ -113,11 +113,11 @@ impl SpanningInspector { } /// Create a span for a `CALL`-family opcode. - fn span_call(&self, _context: &mut Ctx, inputs: &CallInputs) -> Span + fn span_call(&self, context: &mut Ctx, inputs: &CallInputs) -> Span where Ctx: ContextTr, { - let selector = resolve_selector(inputs, _context).unwrap_or_default(); + let selector = resolve_selector(inputs, context).unwrap_or_default(); runtime_level_span!( self.level, From fc9c93a3bab6860eda958d0d4ca2cd0ed0572d74 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 14:14:12 +0200 Subject: [PATCH 08/17] chore: validate on example --- examples/fork_ref_transact.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 7065061..7ce0fb6 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -78,7 +78,7 @@ async fn main() -> eyre::Result<()> { let output = evm.output().expect("Execution halted"); // decode bytes to reserves + ts via alloy's abi decode - let return_vals = getReservesCall::abi_decode_returns(output)?; + let return_vals = getReservesCall::abi_decode_returns_validate(output)?; // Print emulated getReserves() call output println!("Reserve0: {:#?}", return_vals.reserve0); From fdf3458872f23bc5a814ef36c002b52415a9d34d Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 15:08:53 +0200 Subject: [PATCH 09/17] chore: keep selector as option --- src/inspectors/spanning.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/inspectors/spanning.rs b/src/inspectors/spanning.rs index 3ea9eaf..18fe1d8 100644 --- a/src/inspectors/spanning.rs +++ b/src/inspectors/spanning.rs @@ -117,13 +117,13 @@ impl SpanningInspector { where Ctx: ContextTr, { - let selector = resolve_selector(inputs, context).unwrap_or_default(); + let selector = resolve_selector(inputs, context).map(hex::encode); runtime_level_span!( self.level, "call", input_len = inputs.input.len(), - selector = hex::encode(selector), + selector, gas_limit = inputs.gas_limit, bytecode_address = %inputs.bytecode_address, target_addrses = %inputs.target_address, From bc0dde50a5bbc2cd6a3b23f61e25dd08d40e7e83 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 15:10:57 +0200 Subject: [PATCH 10/17] feat: version bump --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4b131f2..f622739 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trevm" -version = "0.20.11" +version = "0.23.0" rust-version = "1.83.0" edition = "2021" authors = ["init4"] From 70c6723a1a2c475d0dcadc7e7337c6da4647f3c8 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 16:43:05 +0200 Subject: [PATCH 11/17] chore: vendor alloydb, fix example --- Cargo.toml | 14 ++- examples/fork_ref_transact.rs | 5 +- src/db/alloy.rs | 173 ++++++++++++++++++++++++++++++++++ src/db/mod.rs | 4 + 4 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 src/db/alloy.rs diff --git a/Cargo.toml b/Cargo.toml index f622739..f9756af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,13 @@ use-self = "warn" option-if-let-else = "warn" redundant-clone = "warn" +[[example]] +name = "basic_transact" + +[[example]] +name = "fork_ref_transact" +required-features = ["alloydb"] + [dependencies] alloy = { version = "1.0.5", default-features = false, features = [ "consensus", @@ -43,11 +50,13 @@ dashmap = { version = "6.1.0", optional = true } tracing = { version = "0.1.41", optional = true } thiserror = "2.0.11" +tokio = { version = "1.44", optional = true } + [dev-dependencies] revm = { version = "23.1.0", features = ["serde-json", "std", "alloydb"] } trevm = { path = ".", features = ["test-utils"] } -alloy = { version = "1.0.5", features = ["providers"] } +alloy = { version = "1.0.5", features = ["providers", "transports"] } # misc eyre = "0.6" @@ -67,6 +76,9 @@ default = [ "revm/secp256k1", ] +alloydb = ["dep:tokio"] + + call = ["optional_eip3607", "optional_no_base_fee"] concurrent-db = ["dep:dashmap"] diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 7ce0fb6..8416223 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -1,8 +1,6 @@ //! This example demonstrates how to query storage slots of a contract, using //! [`AlloyDB`]. -//! This example is currently disabled while waiting for revm @ 14.0.4 - use alloy::{ eips::BlockId, primitives::{address, Address, TxKind, U256}, @@ -12,7 +10,8 @@ use alloy::{ }; use revm::{context::TxEnv, database::WrapDatabaseAsync}; use trevm::{ - revm::database::{AlloyDB, CacheDB}, + db::alloy::AlloyDB, + revm::database::CacheDB, NoopBlock, NoopCfg, TrevmBuilder, Tx, }; diff --git a/src/db/alloy.rs b/src/db/alloy.rs new file mode 100644 index 0000000..bf01e70 --- /dev/null +++ b/src/db/alloy.rs @@ -0,0 +1,173 @@ +#![cfg(feature = "alloydb")] + +pub use alloy::eips::BlockId; +use alloy::{primitives::{StorageValue, U256}, providers::{ + network::{primitives::HeaderResponse, BlockResponse}, + Network, Provider, +}}; +use alloy::transports::TransportError; +use core::error::Error; +use revm::database_interface::{async_db::DatabaseAsyncRef, DBErrorMarker}; +use revm::primitives::{Address, B256}; + +use revm::state::{AccountInfo, Bytecode}; +use std::fmt::Display; + +/// A type alias for the storage key used in the database. +/// We use this instead of alloy's [alloy::primitives::StorageKey] as Revm requires +/// the actual type to be an [U256] instead of a [B256]. +pub type StorageKey = U256; + +/// An error that can occur when using [AlloyDB]. +#[derive(Debug)] +pub struct DBTransportError(pub TransportError); + +impl DBErrorMarker for DBTransportError {} + +impl Display for DBTransportError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "Transport error: {}", self.0) + } +} + +impl Error for DBTransportError {} + +impl From for DBTransportError { + fn from(e: TransportError) -> Self { + Self(e) + } +} + +/// An alloy-powered REVM [Database][database_interface::Database]. +/// +/// When accessing the database, it'll use the given provider to fetch the corresponding account's data. +#[derive(Debug)] +pub struct AlloyDB> { + /// The provider to fetch the data from. + provider: P, + /// The block number on which the queries will be based on. + block_number: BlockId, + _marker: core::marker::PhantomData N>, +} + +impl> AlloyDB { + /// Creates a new AlloyDB instance, with a [Provider] and a block. + pub fn new(provider: P, block_number: BlockId) -> Self { + Self { + provider, + block_number, + _marker: core::marker::PhantomData, + } + } + + /// Sets the block number on which the queries will be based on. + pub fn set_block_number(&mut self, block_number: BlockId) { + self.block_number = block_number; + } +} + +impl> DatabaseAsyncRef for AlloyDB { + type Error = DBTransportError; + + async fn basic_async_ref(&self, address: Address) -> Result, Self::Error> { + let nonce = self + .provider + .get_transaction_count(address) + .block_id(self.block_number); + let balance = self + .provider + .get_balance(address) + .block_id(self.block_number); + let code = self + .provider + .get_code_at(address) + .block_id(self.block_number); + + let (nonce, balance, code) = tokio::join!(nonce, balance, code,); + + let balance = balance?; + let code = Bytecode::new_raw(code?.0.into()); + let code_hash = code.hash_slow(); + let nonce = nonce?; + + Ok(Some(AccountInfo::new(balance, nonce, code_hash, code))) + } + + async fn block_hash_async_ref(&self, number: u64) -> Result { + let block = self + .provider + // SAFETY: We know number <= u64::MAX, so we can safely convert it to u64 + .get_block_by_number(number.into()) + .await?; + // SAFETY: If the number is given, the block is supposed to be finalized, so unwrapping is safe. + Ok(B256::new(*block.unwrap().header().hash())) + } + + async fn code_by_hash_async_ref(&self, _code_hash: B256) -> Result { + panic!("This should not be called, as the code is already loaded"); + // This is not needed, as the code is already loaded with basic_ref + } + + async fn storage_async_ref( + &self, + address: Address, + index: StorageKey, + ) -> Result { + Ok(self + .provider + .get_storage_at(address, index) + .block_id(self.block_number) + .await?) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy::providers::ProviderBuilder; + use revm::database_interface::{DatabaseRef, WrapDatabaseAsync}; + + #[test] + #[ignore = "flaky RPC"] + fn can_get_basic() { + let client = ProviderBuilder::new().connect_http( + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" + .parse() + .unwrap(), + ); + let alloydb = AlloyDB::new(client, BlockId::from(16148323)); + let wrapped_alloydb = WrapDatabaseAsync::new(alloydb).unwrap(); + + // ETH/USDT pair on Uniswap V2 + let address: Address = "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852" + .parse() + .unwrap(); + + let acc_info = wrapped_alloydb.basic_ref(address).unwrap().unwrap(); + assert!(acc_info.exists()); + } +} + +// This code has been reproduced from the original AlloyDB implementation +// contained in revm. +// +// The original license is included below: +// +// MIT License +// Copyright (c) 2021-2025 draganrakita +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. \ No newline at end of file diff --git a/src/db/mod.rs b/src/db/mod.rs index f6e07b8..50c59fb 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -9,3 +9,7 @@ pub use traits::{ArcUpgradeError, CachingDb, StateAcc, TryCachingDb, TryStateAcc /// Cache-on-write database. A memory cache that caches only on write, not on /// read. Intended to wrap some other caching database. pub mod cow; + +#[cfg(feature = "alloydb")] +/// Alloy-powered revm Database implementation that fetches data over the network. +pub mod alloy; \ No newline at end of file From c36660f05df8ff2564dad7dc8e7e780dd31035dc Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 16:46:23 +0200 Subject: [PATCH 12/17] chore: clippy --- examples/fork_ref_transact.rs | 6 +--- src/db/alloy.rs | 54 +++++++++++------------------------ src/db/mod.rs | 2 +- 3 files changed, 19 insertions(+), 43 deletions(-) diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 8416223..57298b8 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -9,11 +9,7 @@ use alloy::{ sol_types::SolCall, }; use revm::{context::TxEnv, database::WrapDatabaseAsync}; -use trevm::{ - db::alloy::AlloyDB, - revm::database::CacheDB, - NoopBlock, NoopCfg, TrevmBuilder, Tx, -}; +use trevm::{db::alloy::AlloyDB, revm::database::CacheDB, NoopBlock, NoopCfg, TrevmBuilder, Tx}; sol! { #[allow(missing_docs)] diff --git a/src/db/alloy.rs b/src/db/alloy.rs index bf01e70..4a55511 100644 --- a/src/db/alloy.rs +++ b/src/db/alloy.rs @@ -1,11 +1,12 @@ -#![cfg(feature = "alloydb")] - pub use alloy::eips::BlockId; -use alloy::{primitives::{StorageValue, U256}, providers::{ - network::{primitives::HeaderResponse, BlockResponse}, - Network, Provider, -}}; use alloy::transports::TransportError; +use alloy::{ + primitives::{StorageValue, U256}, + providers::{ + network::{primitives::HeaderResponse, BlockResponse}, + Network, Provider, + }, +}; use core::error::Error; use revm::database_interface::{async_db::DatabaseAsyncRef, DBErrorMarker}; use revm::primitives::{Address, B256}; @@ -53,15 +54,11 @@ pub struct AlloyDB> { impl> AlloyDB { /// Creates a new AlloyDB instance, with a [Provider] and a block. pub fn new(provider: P, block_number: BlockId) -> Self { - Self { - provider, - block_number, - _marker: core::marker::PhantomData, - } + Self { provider, block_number, _marker: core::marker::PhantomData } } /// Sets the block number on which the queries will be based on. - pub fn set_block_number(&mut self, block_number: BlockId) { + pub const fn set_block_number(&mut self, block_number: BlockId) { self.block_number = block_number; } } @@ -70,18 +67,9 @@ impl> DatabaseAsyncRef for AlloyDB { type Error = DBTransportError; async fn basic_async_ref(&self, address: Address) -> Result, Self::Error> { - let nonce = self - .provider - .get_transaction_count(address) - .block_id(self.block_number); - let balance = self - .provider - .get_balance(address) - .block_id(self.block_number); - let code = self - .provider - .get_code_at(address) - .block_id(self.block_number); + let nonce = self.provider.get_transaction_count(address).block_id(self.block_number); + let balance = self.provider.get_balance(address).block_id(self.block_number); + let code = self.provider.get_code_at(address).block_id(self.block_number); let (nonce, balance, code) = tokio::join!(nonce, balance, code,); @@ -113,11 +101,7 @@ impl> DatabaseAsyncRef for AlloyDB { address: Address, index: StorageKey, ) -> Result { - Ok(self - .provider - .get_storage_at(address, index) - .block_id(self.block_number) - .await?) + Ok(self.provider.get_storage_at(address, index).block_id(self.block_number).await?) } } @@ -131,17 +115,13 @@ mod tests { #[ignore = "flaky RPC"] fn can_get_basic() { let client = ProviderBuilder::new().connect_http( - "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" - .parse() - .unwrap(), + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27".parse().unwrap(), ); let alloydb = AlloyDB::new(client, BlockId::from(16148323)); let wrapped_alloydb = WrapDatabaseAsync::new(alloydb).unwrap(); // ETH/USDT pair on Uniswap V2 - let address: Address = "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852" - .parse() - .unwrap(); + let address: Address = "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852".parse().unwrap(); let acc_info = wrapped_alloydb.basic_ref(address).unwrap().unwrap(); assert!(acc_info.exists()); @@ -152,7 +132,7 @@ mod tests { // contained in revm. // // The original license is included below: -// +// // MIT License // Copyright (c) 2021-2025 draganrakita // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -170,4 +150,4 @@ mod tests { // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. \ No newline at end of file +// SOFTWARE. diff --git a/src/db/mod.rs b/src/db/mod.rs index 50c59fb..b30ad93 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -12,4 +12,4 @@ pub mod cow; #[cfg(feature = "alloydb")] /// Alloy-powered revm Database implementation that fetches data over the network. -pub mod alloy; \ No newline at end of file +pub mod alloy; From 5339e92b0ab6b6d644e2431d5029dba454c29518 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 16:47:46 +0200 Subject: [PATCH 13/17] chore: docs --- src/db/alloy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/alloy.rs b/src/db/alloy.rs index 4a55511..5d8588c 100644 --- a/src/db/alloy.rs +++ b/src/db/alloy.rs @@ -39,7 +39,7 @@ impl From for DBTransportError { } } -/// An alloy-powered REVM [Database][database_interface::Database]. +/// An alloy-powered REVM [Database][revm::database_interface::Database]. /// /// When accessing the database, it'll use the given provider to fetch the corresponding account's data. #[derive(Debug)] From efb61931e7af205460353d2bf24c42b295994af8 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 17:11:07 +0200 Subject: [PATCH 14/17] chore: improve code style --- Cargo.toml | 5 ++--- examples/fork_ref_transact.rs | 4 ++-- src/db/alloy.rs | 21 +++++++++++---------- src/db/mod.rs | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f9756af..7faa65b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ name = "basic_transact" [[example]] name = "fork_ref_transact" -required-features = ["alloydb"] +required-features = ["alloy-db"] [dependencies] alloy = { version = "1.0.5", default-features = false, features = [ @@ -76,8 +76,7 @@ default = [ "revm/secp256k1", ] -alloydb = ["dep:tokio"] - +alloy-db = ["dep:tokio"] call = ["optional_eip3607", "optional_no_base_fee"] diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 57298b8..cdc150d 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -9,7 +9,7 @@ use alloy::{ sol_types::SolCall, }; use revm::{context::TxEnv, database::WrapDatabaseAsync}; -use trevm::{db::alloy::AlloyDB, revm::database::CacheDB, NoopBlock, NoopCfg, TrevmBuilder, Tx}; +use trevm::{db::alloy::AlloyDb, revm::database::CacheDB, NoopBlock, NoopCfg, TrevmBuilder, Tx}; sol! { #[allow(missing_docs)] @@ -52,7 +52,7 @@ async fn main() -> eyre::Result<()> { // =========================================================== // // initialize new AlloyDB - let alloydb = WrapDatabaseAsync::new(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); diff --git a/src/db/alloy.rs b/src/db/alloy.rs index 5d8588c..b8cc52b 100644 --- a/src/db/alloy.rs +++ b/src/db/alloy.rs @@ -1,17 +1,18 @@ -pub use alloy::eips::BlockId; -use alloy::transports::TransportError; use alloy::{ + eips::BlockId, primitives::{StorageValue, U256}, providers::{ network::{primitives::HeaderResponse, BlockResponse}, Network, Provider, }, + transports::TransportError, }; use core::error::Error; -use revm::database_interface::{async_db::DatabaseAsyncRef, DBErrorMarker}; -use revm::primitives::{Address, B256}; - -use revm::state::{AccountInfo, Bytecode}; +use revm::{ + database_interface::{async_db::DatabaseAsyncRef, DBErrorMarker}, + primitives::{Address, B256}, + state::{AccountInfo, Bytecode}, +}; use std::fmt::Display; /// A type alias for the storage key used in the database. @@ -43,7 +44,7 @@ impl From for DBTransportError { /// /// When accessing the database, it'll use the given provider to fetch the corresponding account's data. #[derive(Debug)] -pub struct AlloyDB> { +pub struct AlloyDb> { /// The provider to fetch the data from. provider: P, /// The block number on which the queries will be based on. @@ -51,7 +52,7 @@ pub struct AlloyDB> { _marker: core::marker::PhantomData N>, } -impl> AlloyDB { +impl> AlloyDb { /// Creates a new AlloyDB instance, with a [Provider] and a block. pub fn new(provider: P, block_number: BlockId) -> Self { Self { provider, block_number, _marker: core::marker::PhantomData } @@ -63,7 +64,7 @@ impl> AlloyDB { } } -impl> DatabaseAsyncRef for AlloyDB { +impl> DatabaseAsyncRef for AlloyDb { type Error = DBTransportError; async fn basic_async_ref(&self, address: Address) -> Result, Self::Error> { @@ -117,7 +118,7 @@ mod tests { let client = ProviderBuilder::new().connect_http( "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27".parse().unwrap(), ); - let alloydb = AlloyDB::new(client, BlockId::from(16148323)); + let alloydb = AlloyDb::new(client, BlockId::from(16148323)); let wrapped_alloydb = WrapDatabaseAsync::new(alloydb).unwrap(); // ETH/USDT pair on Uniswap V2 diff --git a/src/db/mod.rs b/src/db/mod.rs index b30ad93..aad4c92 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -10,6 +10,6 @@ pub use traits::{ArcUpgradeError, CachingDb, StateAcc, TryCachingDb, TryStateAcc /// read. Intended to wrap some other caching database. pub mod cow; -#[cfg(feature = "alloydb")] +#[cfg(feature = "alloy-db")] /// Alloy-powered revm Database implementation that fetches data over the network. pub mod alloy; From f40768c8d84529a36d8f17b1641812caa7f003f5 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 17:11:54 +0200 Subject: [PATCH 15/17] chore: backticks --- src/db/alloy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/db/alloy.rs b/src/db/alloy.rs index b8cc52b..ba6e9d0 100644 --- a/src/db/alloy.rs +++ b/src/db/alloy.rs @@ -16,8 +16,8 @@ use revm::{ use std::fmt::Display; /// A type alias for the storage key used in the database. -/// We use this instead of alloy's [alloy::primitives::StorageKey] as Revm requires -/// the actual type to be an [U256] instead of a [B256]. +/// We use this instead of alloy's [`alloy::primitives::StorageKey`] as Revm requires +/// the actual type to be an [`U256`] instead of a [`B256`]. pub type StorageKey = U256; /// An error that can occur when using [AlloyDB]. From d513b4d728973beaf198e1d95645ffd7080cf540 Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 17:15:59 +0200 Subject: [PATCH 16/17] chore: more docs --- src/db/alloy.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/db/alloy.rs b/src/db/alloy.rs index ba6e9d0..f8b51aa 100644 --- a/src/db/alloy.rs +++ b/src/db/alloy.rs @@ -20,7 +20,7 @@ use std::fmt::Display; /// the actual type to be an [`U256`] instead of a [`B256`]. pub type StorageKey = U256; -/// An error that can occur when using [AlloyDB]. +/// An error that can occur when using [`AlloyDb`]. #[derive(Debug)] pub struct DBTransportError(pub TransportError); @@ -40,7 +40,7 @@ impl From for DBTransportError { } } -/// An alloy-powered REVM [Database][revm::database_interface::Database]. +/// An alloy-powered REVM [`Database`][revm::database_interface::Database]. /// /// When accessing the database, it'll use the given provider to fetch the corresponding account's data. #[derive(Debug)] @@ -53,7 +53,7 @@ pub struct AlloyDb> { } impl> AlloyDb { - /// Creates a new AlloyDB instance, with a [Provider] and a block. + /// Creates a new AlloyDB instance, with a [`Provider`] and a block. pub fn new(provider: P, block_number: BlockId) -> Self { Self { provider, block_number, _marker: core::marker::PhantomData } } From fa6c1871217e4dca86bb064658b0ed6fb5e79eeb Mon Sep 17 00:00:00 2001 From: evalir Date: Thu, 22 May 2025 17:17:57 +0200 Subject: [PATCH 17/17] chore: do not use SAFETY disclaimers, as its not unsafe code --- examples/fork_ref_transact.rs | 2 +- src/db/alloy.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index cdc150d..b0cfcfb 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -1,5 +1,5 @@ //! This example demonstrates how to query storage slots of a contract, using -//! [`AlloyDB`]. +//! [`AlloyDb`]. use alloy::{ eips::BlockId, diff --git a/src/db/alloy.rs b/src/db/alloy.rs index f8b51aa..8de2d14 100644 --- a/src/db/alloy.rs +++ b/src/db/alloy.rs @@ -85,10 +85,10 @@ impl> DatabaseAsyncRef for AlloyDb { async fn block_hash_async_ref(&self, number: u64) -> Result { let block = self .provider - // SAFETY: We know number <= u64::MAX, so we can safely convert it to u64 + // We know number <= u64::MAX, so we can safely convert it to u64 .get_block_by_number(number.into()) .await?; - // SAFETY: If the number is given, the block is supposed to be finalized, so unwrapping is safe. + // If the number is given, the block is supposed to be finalized, so unwrapping is safe. Ok(B256::new(*block.unwrap().header().hash())) }