From f75998ac06ded267b15d37c673b1f74859da350d Mon Sep 17 00:00:00 2001 From: rakita Date: Fri, 20 Sep 2024 18:28:20 +0200 Subject: [PATCH] feat: restructure part3 fix examples (#1792) * fix contract deployment example * database component example * fix examples * fix uniswap usdc swap * fmt * docs * rm comment --- Cargo.lock | 69 ++++++ Cargo.toml | 12 +- bins/revme/Cargo.toml | 2 +- crates/database/src/ethersdb.rs | 213 ------------------ examples/block_traces/Cargo.toml | 16 +- examples/block_traces/src/main.rs | 5 +- examples/contract_deployment/Cargo.toml | 5 +- examples/contract_deployment/src/main.rs | 2 +- examples/database_components/Cargo.toml | 5 +- .../database_components/src/block_hash.rs | 44 ++++ examples/database_components/src/lib.rs | 133 +---------- examples/database_components/src/state.rs | 75 ++++++ examples/database_ref/Cargo.toml | 7 +- examples/database_ref/src/main.rs | 6 +- examples/uniswap_get_reserves/Cargo.toml | 16 +- examples/uniswap_get_reserves/src/main.rs | 2 +- examples/uniswap_v2_usdc_swap/Cargo.toml | 15 +- examples/uniswap_v2_usdc_swap/src/main.rs | 50 ++-- 18 files changed, 295 insertions(+), 382 deletions(-) delete mode 100644 crates/database/src/ethersdb.rs create mode 100644 examples/database_components/src/block_hash.rs create mode 100644 examples/database_components/src/state.rs diff --git a/Cargo.lock b/Cargo.lock index 06710be8e8..806c3dff72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1374,6 +1374,75 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "example-block-traces" +version = "0.0.0" +dependencies = [ + "alloy-eips", + "alloy-provider", + "anyhow", + "indicatif", + "revm", + "revm-database", + "revm-inspector", + "tokio", +] + +[[package]] +name = "example-contract-deployment" +version = "0.0.0" +dependencies = [ + "anyhow", + "revm", + "revm-database", +] + +[[package]] +name = "example-database-components" +version = "0.0.0" +dependencies = [ + "auto_impl", + "revm", +] + +[[package]] +name = "example-database-ref" +version = "0.0.0" +dependencies = [ + "anyhow", + "revm", + "revm-database", + "revm-inspector", +] + +[[package]] +name = "example-uniswap-get-reserves" +version = "0.0.0" +dependencies = [ + "alloy-eips", + "alloy-provider", + "alloy-sol-types", + "anyhow", + "revm", + "revm-database", + "tokio", +] + +[[package]] +name = "example-uniswap-v2-usdc-swap" +version = "0.0.0" +dependencies = [ + "alloy-eips", + "alloy-provider", + "alloy-sol-types", + "alloy-transport-http", + "anyhow", + "reqwest", + "revm", + "revm-database", + "tokio", +] + [[package]] name = "eyre" version = "0.6.12" diff --git a/Cargo.toml b/Cargo.toml index 884d8d16cc..d3adb3e832 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,13 +20,13 @@ members = [ "crates/specification", # examples - #"examples/block_traces", - #"examples/contract_deployment", + "examples/block_traces", + "examples/contract_deployment", + "examples/database_components", + "examples/database_ref", + "examples/uniswap_get_reserves", + "examples/uniswap_v2_usdc_swap", #"examples/custom_opcodes", - #"examples/database_components", - #"examples/database_ref", - #"examples/uniswap_get_reserves", - #"examples/uniswap_v2_usdc_swap", ] [workspace.dependencies] diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index 0bda112fd6..4032a8ae09 100644 --- a/bins/revme/Cargo.toml +++ b/bins/revme/Cargo.toml @@ -12,7 +12,7 @@ repository.workspace = true # revm database.workspace = true revm = { workspace = true, features = ["std", "hashbrown", "c-kzg", "blst"] } -inspector = { workspace = true, features = ["std", "serde", "serde-json"] } +inspector = { workspace = true, features = ["std", "serde-json"] } hash-db = "0.15" hex = "0.4" diff --git a/crates/database/src/ethersdb.rs b/crates/database/src/ethersdb.rs deleted file mode 100644 index 7918dfe792..0000000000 --- a/crates/database/src/ethersdb.rs +++ /dev/null @@ -1,213 +0,0 @@ -use std::sync::Arc; - -use ethers_core::types::{Block, BlockId, TxHash, H160 as eH160, H256, U64 as eU64}; -use ethers_providers::Middleware; -use tokio::runtime::{Handle, Runtime}; - -use crate::{Database, DatabaseRef}; -use bytecode::Bytecode; -use primitives::{Address, B256, U256}; -use state::AccountInfo; - -use super::utils::HandleOrRuntime; - -#[derive(Debug)] -pub struct EthersDB { - client: Arc, - block_number: Option, - rt: HandleOrRuntime, -} - -impl EthersDB { - /// Create ethers db connector inputs are url and block on what we are basing our database (None for latest). - /// - /// Returns `None` if no tokio runtime is available or if the current runtime is a current-thread runtime. - pub fn new(client: Arc, block_number: Option) -> Option { - let rt = match Handle::try_current() { - Ok(handle) => match handle.runtime_flavor() { - tokio::runtime::RuntimeFlavor::CurrentThread => return None, - _ => HandleOrRuntime::Handle(handle), - }, - Err(_) => return None, - }; - - if block_number.is_some() { - Some(Self { - client, - block_number, - rt, - }) - } else { - let mut instance = Self { - client, - block_number: None, - rt, - }; - instance.block_number = Some(BlockId::from( - instance.block_on(instance.client.get_block_number()).ok()?, - )); - Some(instance) - } - } - - /// Create a new EthersDB instance, with a provider and a block (None for latest) and a runtime. - /// - /// Refer to [tokio::runtime::Builder] how to create a runtime if you are in synchronous world. - /// If you are already using something like [tokio::main], call EthersDB::new instead. - pub fn with_runtime( - client: Arc, - block_number: Option, - runtime: Runtime, - ) -> Option { - let rt = HandleOrRuntime::Runtime(runtime); - let mut instance = Self { - client, - block_number, - rt, - }; - - instance.block_number = Some(BlockId::from( - instance.block_on(instance.client.get_block_number()).ok()?, - )); - Some(instance) - } - - /// Create a new EthersDB instance, with a provider and a block (None for latest) and a handle. - /// - /// This generally allows you to pass any valid runtime handle, refer to [tokio::runtime::Handle] on how - /// to obtain a handle. If you are already in asynchronous world, like [tokio::main], use EthersDB::new instead. - pub fn with_handle( - client: Arc, - block_number: Option, - handle: Handle, - ) -> Option { - let rt = HandleOrRuntime::Handle(handle); - let mut instance = Self { - client, - block_number, - rt, - }; - - instance.block_number = Some(BlockId::from( - instance.block_on(instance.client.get_block_number()).ok()?, - )); - Some(instance) - } - - /// Internal utility function to call tokio feature and wait for output - #[inline] - fn block_on(&self, f: F) -> F::Output - where - F: core::future::Future + Send, - F::Output: Send, - { - self.rt.block_on(f) - } - - /// set block number on which upcoming queries will be based - #[inline] - pub fn set_block_number(&mut self, block_number: BlockId) { - self.block_number = Some(block_number); - } -} - -impl DatabaseRef for EthersDB { - type Error = M::Error; - - fn basic_ref(&self, address: Address) -> Result, Self::Error> { - let add = eH160::from(address.0 .0); - - let f = async { - let nonce = self.client.get_transaction_count(add, self.block_number); - let balance = self.client.get_balance(add, self.block_number); - let code = self.client.get_code(add, self.block_number); - tokio::join!(nonce, balance, code) - }; - let (nonce, balance, code) = self.block_on(f); - - let balance = U256::from_limbs(balance?.0); - let nonce = nonce?.as_u64(); - let bytecode = Bytecode::new_raw(code?.0.into()); - let code_hash = bytecode.hash_slow(); - Ok(Some(AccountInfo::new(balance, nonce, code_hash, bytecode))) - } - - fn code_by_hash_ref(&self, _code_hash: B256) -> Result { - panic!("Should not be called. Code is already loaded"); - // not needed because we already load code with basic info - } - - fn storage_ref(&self, address: Address, index: U256) -> Result { - let add = eH160::from(address.0 .0); - let index = H256::from(index.to_be_bytes()); - let slot_value: H256 = - self.block_on(self.client.get_storage_at(add, index, self.block_number))?; - Ok(U256::from_be_bytes(slot_value.to_fixed_bytes())) - } - - fn block_hash_ref(&self, number: u64) -> Result { - let number = eU64::from(number); - let block: Option> = - self.block_on(self.client.get_block(BlockId::from(number)))?; - // If number is given, the block is supposed to be finalized so unwrap is safe too. - Ok(B256::new(block.unwrap().hash.unwrap().0)) - } -} - -impl Database for EthersDB { - type Error = M::Error; - - #[inline] - fn basic(&mut self, address: Address) -> Result, Self::Error> { - ::basic_ref(self, address) - } - - #[inline] - fn code_by_hash(&mut self, code_hash: B256) -> Result { - ::code_by_hash_ref(self, code_hash) - } - - #[inline] - fn storage(&mut self, address: Address, index: U256) -> Result { - ::storage_ref(self, address, index) - } - - #[inline] - fn block_hash(&mut self, number: u64) -> Result { - ::block_hash_ref(self, number) - } -} - -// Run tests with `cargo test -- --nocapture` to see print statements -#[cfg(test)] -mod tests { - use super::*; - use ethers_providers::{Http, Provider}; - - #[test] - #[ignore = "flaky RPC"] - fn can_get_basic() { - let client = Provider::::try_from( - "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27", - ) - .unwrap(); - let client = Arc::new(client); - - let ethersdb = EthersDB::new( - Arc::clone(&client), // public infura mainnet - Some(BlockId::from(16148323)), - ) - .unwrap(); - - // ETH/USDT pair on Uniswap V2 - let address = "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852" - .parse::() - .unwrap(); - let address = address.as_fixed_bytes().into(); - - let acc_info = ethersdb.basic_ref(address).unwrap().unwrap(); - - // check if not empty - assert!(acc_info.exists()); - } -} diff --git a/examples/block_traces/Cargo.toml b/examples/block_traces/Cargo.toml index 466edfbf77..326107482d 100644 --- a/examples/block_traces/Cargo.toml +++ b/examples/block_traces/Cargo.toml @@ -23,4 +23,18 @@ all = "warn" [dependencies] revm.workspace = true -database.workspace = true +database = { workspace = true, features = ["std", "alloydb"] } +inspector = { workspace = true, features = ["std", "serde-json"] } + +# tokio +tokio = { version = "1.40", features = ["rt-multi-thread", "macros"] } + +# alloy +alloy-eips = "0.3.6" +alloy-provider = "0.3" + +# progress bar +indicatif = "0.17" + +# mics +anyhow = "1.0.89" diff --git a/examples/block_traces/src/main.rs b/examples/block_traces/src/main.rs index 88baf830e7..22143bc6ff 100644 --- a/examples/block_traces/src/main.rs +++ b/examples/block_traces/src/main.rs @@ -3,11 +3,10 @@ use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_provider::{network::primitives::BlockTransactions, Provider, ProviderBuilder}; +use database::{AlloyDB, CacheDB, StateBuilder}; use indicatif::ProgressBar; +use inspector::{inspector_handle_register, inspectors::TracerEip3155}; use revm::{ - db::{AlloyDB, CacheDB, StateBuilder}, - inspector_handle_register, - inspectors::TracerEip3155, primitives::{TxKind, B256, U256}, specification::eip2930::AccessListItem, wiring::EthereumWiring, diff --git a/examples/contract_deployment/Cargo.toml b/examples/contract_deployment/Cargo.toml index 0d482a26dc..85ae1dc76c 100644 --- a/examples/contract_deployment/Cargo.toml +++ b/examples/contract_deployment/Cargo.toml @@ -22,5 +22,8 @@ rust_2018_idioms = "deny" all = "warn" [dependencies] -revm.workspace = true +revm = { workspace = true, features = ["std"] } database.workspace = true + +# mics +anyhow = "1.0.89" diff --git a/examples/contract_deployment/src/main.rs b/examples/contract_deployment/src/main.rs index d025ecb62b..7dba23307f 100644 --- a/examples/contract_deployment/src/main.rs +++ b/examples/contract_deployment/src/main.rs @@ -89,7 +89,7 @@ fn main() -> anyhow::Result<()> { bail!("Failed to write storage in the init code: {result:#?}"); }; - println!("storage U256(0) at{address}: {storage0:#?}"); + println!("storage U256(0) at {address}: {storage0:#?}"); assert_eq!(storage0.present_value(), param.try_into()?, "{result:#?}"); Ok(()) } diff --git a/examples/database_components/Cargo.toml b/examples/database_components/Cargo.toml index 666c1633a0..03139b79ab 100644 --- a/examples/database_components/Cargo.toml +++ b/examples/database_components/Cargo.toml @@ -22,5 +22,8 @@ rust_2018_idioms = "deny" all = "warn" [dependencies] +# srevm revm.workspace = true -database.workspace = true + +# mics +auto_impl = "1.2" diff --git a/examples/database_components/src/block_hash.rs b/examples/database_components/src/block_hash.rs new file mode 100644 index 0000000000..9741706d87 --- /dev/null +++ b/examples/database_components/src/block_hash.rs @@ -0,0 +1,44 @@ +//! BlockHash database component from [`revm::Database`] + +use auto_impl::auto_impl; +use core::ops::Deref; +use revm::primitives::B256; +use std::sync::Arc; + +#[auto_impl(&mut, Box)] +pub trait BlockHash { + type Error; + + /// Get block hash by block number + fn block_hash(&mut self, number: u64) -> Result; +} + +#[auto_impl(&, &mut, Box, Rc, Arc)] +pub trait BlockHashRef { + type Error; + + /// Get block hash by block number + fn block_hash(&self, number: u64) -> Result; +} + +impl BlockHash for &T +where + T: BlockHashRef, +{ + type Error = ::Error; + + fn block_hash(&mut self, number: u64) -> Result { + BlockHashRef::block_hash(*self, number) + } +} + +impl BlockHash for Arc +where + T: BlockHashRef, +{ + type Error = ::Error; + + fn block_hash(&mut self, number: u64) -> Result { + self.deref().block_hash(number) + } +} diff --git a/examples/database_components/src/lib.rs b/examples/database_components/src/lib.rs index 095a737956..982882ddc3 100644 --- a/examples/database_components/src/lib.rs +++ b/examples/database_components/src/lib.rs @@ -1,8 +1,6 @@ //! Optimism-specific constants, types, and helpers. #![cfg_attr(not(test), warn(unused_crate_dependencies))] - - //! Database that is split on State and BlockHash traits. pub mod block_hash; pub mod state; @@ -10,13 +8,12 @@ pub mod state; pub use block_hash::{BlockHash, BlockHashRef}; pub use state::{State, StateRef}; -use crate::{ - db::{Database, DatabaseRef}, - Account, AccountInfo, Address, Bytecode, HashMap, B256, U256, +use revm::{ + database_interface::{Database, DatabaseCommit, DatabaseRef}, + primitives::{Address, HashMap, B256, U256}, + state::{Account, AccountInfo, Bytecode}, }; -use super::DatabaseCommit; - #[derive(Debug)] pub struct DatabaseComponents { pub state: S, @@ -86,125 +83,3 @@ impl DatabaseCommit for DatabaseComponents< self.state.commit(changes); } } - - -//! BlockHash database component from [`database::Database`] -//! it is used inside [`database::DatabaseComponents`] - -use crate::B256; -use auto_impl::auto_impl; -use core::ops::Deref; -use std::sync::Arc; - -#[auto_impl(&mut, Box)] -pub trait BlockHash { - type Error; - - /// Get block hash by block number - fn block_hash(&mut self, number: u64) -> Result; -} - -#[auto_impl(&, &mut, Box, Rc, Arc)] -pub trait BlockHashRef { - type Error; - - /// Get block hash by block number - fn block_hash(&self, number: u64) -> Result; -} - -impl BlockHash for &T -where - T: BlockHashRef, -{ - type Error = ::Error; - - fn block_hash(&mut self, number: u64) -> Result { - BlockHashRef::block_hash(*self, number) - } -} - -impl BlockHash for Arc -where - T: BlockHashRef, -{ - type Error = ::Error; - - fn block_hash(&mut self, number: u64) -> Result { - self.deref().block_hash(number) - } -} - - -//! State database component from [`crate::db::Database`] -//! it is used inside [`crate::db::DatabaseComponents`] - -use crate::{AccountInfo, Address, Bytecode, B256, U256}; -use auto_impl::auto_impl; -use core::ops::Deref; -use std::sync::Arc; - -#[auto_impl(&mut, Box)] -pub trait State { - type Error; - - /// Get basic account information. - fn basic(&mut self, address: Address) -> Result, Self::Error>; - - /// Get account code by its hash - fn code_by_hash(&mut self, code_hash: B256) -> Result; - - /// Get storage value of address at index. - fn storage(&mut self, address: Address, index: U256) -> Result; -} - -#[auto_impl(&, &mut, Box, Rc, Arc)] -pub trait StateRef { - type Error; - - /// Get basic account information. - fn basic(&self, address: Address) -> Result, Self::Error>; - - /// Get account code by its hash - fn code_by_hash(&self, code_hash: B256) -> Result; - - /// Get storage value of address at index. - fn storage(&self, address: Address, index: U256) -> Result; -} - -impl State for &T -where - T: StateRef, -{ - type Error = ::Error; - - fn basic(&mut self, address: Address) -> Result, Self::Error> { - StateRef::basic(*self, address) - } - - fn code_by_hash(&mut self, code_hash: B256) -> Result { - StateRef::code_by_hash(*self, code_hash) - } - - fn storage(&mut self, address: Address, index: U256) -> Result { - StateRef::storage(*self, address, index) - } -} - -impl State for Arc -where - T: StateRef, -{ - type Error = ::Error; - - fn basic(&mut self, address: Address) -> Result, Self::Error> { - self.deref().basic(address) - } - - fn code_by_hash(&mut self, code_hash: B256) -> Result { - self.deref().code_by_hash(code_hash) - } - - fn storage(&mut self, address: Address, index: U256) -> Result { - self.deref().storage(address, index) - } -} diff --git a/examples/database_components/src/state.rs b/examples/database_components/src/state.rs new file mode 100644 index 0000000000..e295fe9601 --- /dev/null +++ b/examples/database_components/src/state.rs @@ -0,0 +1,75 @@ +//! State database component from [`crate::Database`] + +use auto_impl::auto_impl; +use core::ops::Deref; +use revm::{ + primitives::{Address, B256, U256}, + state::{AccountInfo, Bytecode}, +}; +use std::sync::Arc; + +#[auto_impl(&mut, Box)] +pub trait State { + type Error; + + /// Get basic account information. + fn basic(&mut self, address: Address) -> Result, Self::Error>; + + /// Get account code by its hash + fn code_by_hash(&mut self, code_hash: B256) -> Result; + + /// Get storage value of address at index. + fn storage(&mut self, address: Address, index: U256) -> Result; +} + +#[auto_impl(&, &mut, Box, Rc, Arc)] +pub trait StateRef { + type Error; + + /// Get basic account information. + fn basic(&self, address: Address) -> Result, Self::Error>; + + /// Get account code by its hash + fn code_by_hash(&self, code_hash: B256) -> Result; + + /// Get storage value of address at index. + fn storage(&self, address: Address, index: U256) -> Result; +} + +impl State for &T +where + T: StateRef, +{ + type Error = ::Error; + + fn basic(&mut self, address: Address) -> Result, Self::Error> { + StateRef::basic(*self, address) + } + + fn code_by_hash(&mut self, code_hash: B256) -> Result { + StateRef::code_by_hash(*self, code_hash) + } + + fn storage(&mut self, address: Address, index: U256) -> Result { + StateRef::storage(*self, address, index) + } +} + +impl State for Arc +where + T: StateRef, +{ + type Error = ::Error; + + fn basic(&mut self, address: Address) -> Result, Self::Error> { + self.deref().basic(address) + } + + fn code_by_hash(&mut self, code_hash: B256) -> Result { + self.deref().code_by_hash(code_hash) + } + + fn storage(&mut self, address: Address, index: U256) -> Result { + self.deref().storage(address, index) + } +} diff --git a/examples/database_ref/Cargo.toml b/examples/database_ref/Cargo.toml index 10250d758d..508b00add8 100644 --- a/examples/database_ref/Cargo.toml +++ b/examples/database_ref/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "example-db-by-ref" +name = "example-database-ref" version = "0.0.0" publish = false authors.workspace = true @@ -23,3 +23,8 @@ all = "warn" [dependencies] revm.workspace = true +database.workspace = true +inspector = { workspace = true, features = ["std", "serde-json"] } + +# mics +anyhow = "1.0.89" diff --git a/examples/database_ref/src/main.rs b/examples/database_ref/src/main.rs index 36f335639a..e540da7e02 100644 --- a/examples/database_ref/src/main.rs +++ b/examples/database_ref/src/main.rs @@ -4,11 +4,13 @@ use core::error::Error; use core::fmt::Debug; use database::CacheDB; +use inspector::{ + inspector_handle_register, + inspectors::{NoOpInspector, TracerEip3155}, +}; use revm::{ database_interface::{EmptyDB, WrapDatabaseRef}, handler::register::HandleRegister, - inspector_handle_register, - inspectors::{NoOpInspector, TracerEip3155}, wiring::{ result::{HaltReason, ResultAndState}, EthereumWiring, diff --git a/examples/uniswap_get_reserves/Cargo.toml b/examples/uniswap_get_reserves/Cargo.toml index e275f58bcc..e6335b2d12 100644 --- a/examples/uniswap_get_reserves/Cargo.toml +++ b/examples/uniswap_get_reserves/Cargo.toml @@ -22,5 +22,19 @@ rust_2018_idioms = "deny" all = "warn" [dependencies] +# revm revm.workspace = true -database.workspace = true +database = { workspace = true, features = ["std", "alloydb"] } + +# tokio +tokio = { version = "1.40", features = ["rt-multi-thread", "macros"] } + +# alloy +alloy-sol-types = { version = "0.8.2", default-features = false, features = [ + "std", +] } +alloy-eips = "0.3.6" +alloy-provider = "0.3" + +# mics +anyhow = "1.0.89" diff --git a/examples/uniswap_get_reserves/src/main.rs b/examples/uniswap_get_reserves/src/main.rs index 8004bf8b07..ff9144ff14 100644 --- a/examples/uniswap_get_reserves/src/main.rs +++ b/examples/uniswap_get_reserves/src/main.rs @@ -5,10 +5,10 @@ use alloy_eips::BlockId; use alloy_provider::ProviderBuilder; use alloy_sol_types::sol; use alloy_sol_types::SolCall; +use database::{AlloyDB, CacheDB}; use revm::{ database_interface::Database, database_interface::EmptyDB, - db::{AlloyDB, CacheDB}, primitives::{address, TxKind, U256}, wiring::{ result::{ExecutionResult, Output}, diff --git a/examples/uniswap_v2_usdc_swap/Cargo.toml b/examples/uniswap_v2_usdc_swap/Cargo.toml index 6275283a17..3aba647e5c 100644 --- a/examples/uniswap_v2_usdc_swap/Cargo.toml +++ b/examples/uniswap_v2_usdc_swap/Cargo.toml @@ -23,4 +23,17 @@ all = "warn" [dependencies] revm.workspace = true -database.workspace = true +database = { workspace = true, features = ["std", "alloydb"] } + +# tokio +tokio = { version = "1.40", features = ["rt-multi-thread", "macros"] } + +# alloy +alloy-sol-types = { version = "0.8.2", default-features = false, features = [ + "std", +] } +alloy-eips = "0.3.6" +alloy-transport-http = "0.3" +alloy-provider = "0.3" +reqwest = { version = "0.12" } +anyhow = "1.0.89" diff --git a/examples/uniswap_v2_usdc_swap/src/main.rs b/examples/uniswap_v2_usdc_swap/src/main.rs index c6922d98dc..012899b9bb 100644 --- a/examples/uniswap_v2_usdc_swap/src/main.rs +++ b/examples/uniswap_v2_usdc_swap/src/main.rs @@ -1,33 +1,36 @@ //! Example of uniswap getReserves() call emulation. #![cfg_attr(not(test), warn(unused_crate_dependencies))] +use alloy_eips::BlockId; use alloy_provider::{network::Ethereum, ProviderBuilder, RootProvider}; -use alloy_rpc_types::BlockId; use alloy_sol_types::{sol, SolCall, SolValue}; use alloy_transport_http::Http; use anyhow::{anyhow, Result}; +use database::{AlloyDB, CacheDB}; use reqwest::Client; use revm::{ - db::{AlloyDB, CacheDB}, - primitives::{ - address, keccak256, AccountInfo, Address, Bytes, ExecutionResult, Output, TxKind, U256, + primitives::{address, keccak256, Address, Bytes, TxKind, U256}, + state::AccountInfo, + wiring::{ + result::{ExecutionResult, Output}, + EthereumWiring, }, Evm, }; use std::ops::Div; -use std::sync::Arc; -type AlloyCacheDB = CacheDB, Ethereum, Arc>>>>; +type AlloyCacheDB = CacheDB, Ethereum, RootProvider>>>; #[tokio::main] async fn main() -> Result<()> { - let client = ProviderBuilder::new().on_http( - "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" - .parse() - .unwrap(), - ); - let client = Arc::new(client); - let mut cache_db = CacheDB::new(AlloyDB::new(client, BlockId::default())); + // Set up the HTTP transport which is consumed by the RPC client. + let rpc_url = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27".parse()?; + + // create ethers client and wrap it in Arc + let client = ProviderBuilder::new().on_http(rpc_url); + + let alloy = AlloyDB::new(client, BlockId::latest()).unwrap(); + let mut cache_db = CacheDB::new(alloy); // Random empty account let account = address!("18B06aaF27d44B756FCF16Ca20C1f183EB49111f"); @@ -83,18 +86,20 @@ async fn main() -> Result<()> { let acc_usdc_balance_after = balance_of(usdc, account, &mut cache_db)?; println!("USDC balance after swap: {}", acc_usdc_balance_after); + println!("OK"); Ok(()) } -fn balance_of(token: Address, address: Address, cache_db: &mut AlloyCacheDB) -> Result { +fn balance_of(token: Address, address: Address, alloy_db: &mut AlloyCacheDB) -> Result { sol! { function balanceOf(address account) public returns (uint256); } let encoded = balanceOfCall { account: address }.abi_encode(); - let mut evm = Evm::builder() - .with_db(cache_db) + let mut evm = Evm::>::builder() + .with_db(alloy_db) + .with_default_ext_ctx() .modify_tx_env(|tx| { // 0x1 because calling USDC proxy from zero address fails tx.caller = address!("0000000000000000000000000000000000000001"); @@ -138,8 +143,9 @@ async fn get_amount_out( } .abi_encode(); - let mut evm = Evm::builder() + let mut evm = Evm::>::builder() .with_db(cache_db) + .with_default_ext_ctx() .modify_tx_env(|tx| { tx.caller = address!("0000000000000000000000000000000000000000"); tx.transact_to = TxKind::Call(uniswap_v2_router); @@ -171,8 +177,9 @@ fn get_reserves(pair_address: Address, cache_db: &mut AlloyCacheDB) -> Result<(U let encoded = getReservesCall {}.abi_encode(); - let mut evm = Evm::builder() + let mut evm = Evm::>::builder() .with_db(cache_db) + .with_default_ext_ctx() .modify_tx_env(|tx| { tx.caller = address!("0000000000000000000000000000000000000000"); tx.transact_to = TxKind::Call(pair_address); @@ -220,13 +227,15 @@ fn swap( } .abi_encode(); - let mut evm = Evm::builder() + let mut evm = Evm::>::builder() .with_db(cache_db) + .with_default_ext_ctx() .modify_tx_env(|tx| { tx.caller = from; tx.transact_to = TxKind::Call(pool_address); tx.data = encoded.into(); tx.value = U256::from(0); + tx.nonce = 1; }) .build(); @@ -253,8 +262,9 @@ fn transfer( let encoded = transferCall { to, amount }.abi_encode(); - let mut evm = Evm::builder() + let mut evm = Evm::>::builder() .with_db(cache_db) + .with_default_ext_ctx() .modify_tx_env(|tx| { tx.caller = from; tx.transact_to = TxKind::Call(token);