From 9fd084948ba036c932a2389ec39832575f4d1617 Mon Sep 17 00:00:00 2001 From: Enrique Ortiz Date: Mon, 20 Nov 2023 23:21:25 -0400 Subject: [PATCH 1/9] wip --- crates/anvil/src/lib.rs | 13 +++++ crates/anvil/tests/it/anvil.rs | 13 ++--- crates/anvil/tests/it/logs.rs | 10 ++-- crates/anvil/tests/it/main.rs | 8 +-- crates/anvil/tests/it/transaction.rs | 81 ++++++++++++++-------------- crates/anvil/tests/it/txpool.rs | 2 +- crates/utils/src/types.rs | 27 +++++++++- 7 files changed, 96 insertions(+), 58 deletions(-) diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index 3e5d91b8f177..e3aa1cf87634 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -24,6 +24,7 @@ use ethers::{ types::{Address, U256}, }; use foundry_common::provider::alloy::{ProviderBuilder, RetryProvider}; +use foundry_common::provider::ethers::{ProviderBuilder as EthersProviderBuilder, RetryProvider as EthersRetryProvider}; use foundry_evm::revm; use futures::{FutureExt, TryFutureExt}; use parking_lot::Mutex; @@ -275,16 +276,28 @@ impl NodeHandle { // .interval(Duration::from_millis(500)) } + pub fn ethers_http_provider(&self) -> EthersRetryProvider { + EthersProviderBuilder::new(&self.http_endpoint()).build().expect("failed to build ethers HTTP provider") + } + /// Constructs a [`RetryProvider`] for this handle's WS endpoint. pub fn ws_provider(&self) -> RetryProvider { ProviderBuilder::new(&self.ws_endpoint()).build().expect("failed to build WS provider") } + pub fn ethers_ws_provider(&self) -> EthersRetryProvider { + EthersProviderBuilder::new(&self.ws_endpoint()).build().expect("failed to build ethers WS provider") + } + /// Constructs a [`RetryProvider`] for this handle's IPC endpoint, if any. pub fn ipc_provider(&self) -> Option { ProviderBuilder::new(&self.config.get_ipc_path()?).build().ok() } + pub fn ethers_ipc_provider(&self) -> Option { + EthersProviderBuilder::new(&self.config.get_ipc_path()?).build().ok() + } + /// Signer accounts that can sign messages/transactions from the EVM node pub fn dev_accounts(&self) -> impl Iterator + '_ { self.config.signer_accounts.iter().map(|wallet| wallet.address()) diff --git a/crates/anvil/tests/it/anvil.rs b/crates/anvil/tests/it/anvil.rs index 07d8e3f96712..de4b382cf21e 100644 --- a/crates/anvil/tests/it/anvil.rs +++ b/crates/anvil/tests/it/anvil.rs @@ -2,11 +2,12 @@ use anvil::{spawn, NodeConfig}; use ethers::{prelude::Middleware, types::Address}; +use foundry_utils::types::ToAlloy; #[tokio::test(flavor = "multi_thread")] async fn test_can_change_mining_mode() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); assert!(api.anvil_get_auto_mine().unwrap()); @@ -35,7 +36,7 @@ async fn test_can_change_mining_mode() { #[tokio::test(flavor = "multi_thread")] async fn can_get_default_dev_keys() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let dev_accounts = handle.dev_accounts().collect::>(); let accounts = provider.get_accounts().await.unwrap(); @@ -46,8 +47,8 @@ async fn can_get_default_dev_keys() { async fn can_set_empty_code() { let (api, _handle) = spawn(NodeConfig::test()).await; let addr = Address::random(); - api.anvil_set_code(addr, Vec::new().into()).await.unwrap(); - let code = api.get_code(addr, None).await.unwrap(); + api.anvil_set_code(addr.to_alloy(), Vec::new().into()).await.unwrap(); + let code = api.get_code(addr.to_alloy(), None).await.unwrap(); assert!(code.as_ref().is_empty()); } @@ -56,7 +57,7 @@ async fn test_can_set_genesis_timestamp() { let genesis_timestamp = 1000u64; let (_api, handle) = spawn(NodeConfig::test().with_genesis_timestamp(genesis_timestamp.into())).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); assert_eq!(genesis_timestamp, provider.get_block(0).await.unwrap().unwrap().timestamp.as_u64()); } @@ -64,7 +65,7 @@ async fn test_can_set_genesis_timestamp() { #[tokio::test(flavor = "multi_thread")] async fn test_can_use_default_genesis_timestamp() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); assert_ne!(0u64, provider.get_block(0).await.unwrap().unwrap().timestamp.as_u64()); } diff --git a/crates/anvil/tests/it/logs.rs b/crates/anvil/tests/it/logs.rs index 913015de5edf..307eabf27ed3 100644 --- a/crates/anvil/tests/it/logs.rs +++ b/crates/anvil/tests/it/logs.rs @@ -13,7 +13,7 @@ use std::sync::Arc; #[tokio::test(flavor = "multi_thread")] async fn get_past_events() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let address = wallet.address(); @@ -50,7 +50,7 @@ async fn get_past_events() { #[tokio::test(flavor = "multi_thread")] async fn get_all_events() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -87,7 +87,7 @@ async fn get_all_events() { #[tokio::test(flavor = "multi_thread")] async fn can_install_filter() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -130,7 +130,7 @@ async fn can_install_filter() { async fn watch_events() { let (_api, handle) = spawn(NodeConfig::test()).await; let wallet = handle.dev_wallets().next().unwrap(); - let client = Arc::new(SignerMiddleware::new(handle.http_provider(), wallet)); + let client = Arc::new(SignerMiddleware::new(handle.ethers_http_provider(), wallet)); let contract = SimpleStorage::deploy(Arc::clone(&client), "initial value".to_string()) .unwrap() @@ -143,7 +143,7 @@ async fn watch_events() { let mut stream = event.stream().await.unwrap(); // Also set up a subscription for the same thing - let ws = Arc::new(handle.ws_provider()); + let ws = Arc::new(handle.ethers_ws_provider()); let contract2 = SimpleStorage::new(contract.address(), ws); let event2 = contract2.event::(); let mut subscription = event2.subscribe().await.unwrap(); diff --git a/crates/anvil/tests/it/main.rs b/crates/anvil/tests/it/main.rs index 902e2e504887..a546ff9e3acc 100644 --- a/crates/anvil/tests/it/main.rs +++ b/crates/anvil/tests/it/main.rs @@ -1,5 +1,5 @@ -// mod abi; -// mod anvil; +mod abi; +mod anvil; // mod anvil_api; // mod api; // mod fork; @@ -15,8 +15,8 @@ mod genesis; // mod otterscan; // mod sign; // mod traces; -// mod transaction; -// mod txpool; +mod transaction; +mod txpool; // pub mod utils; // mod wsapi; diff --git a/crates/anvil/tests/it/transaction.rs b/crates/anvil/tests/it/transaction.rs index 7cb5c4bc6e5a..b269fd3c66d7 100644 --- a/crates/anvil/tests/it/transaction.rs +++ b/crates/anvil/tests/it/transaction.rs @@ -11,6 +11,7 @@ use ethers::{ Address, BlockNumber, Transaction, TransactionReceipt, H256, U256, }, }; +use foundry_utils::types::{ToAlloy, ToEthers, to_call_request_from_tx_request}; use futures::{future::join_all, FutureExt, StreamExt}; use std::{collections::HashSet, sync::Arc, time::Duration}; use tokio::time::timeout; @@ -18,7 +19,7 @@ use tokio::time::timeout; #[tokio::test(flavor = "multi_thread")] async fn can_transfer_eth() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -53,7 +54,7 @@ async fn can_transfer_eth() { #[tokio::test(flavor = "multi_thread")] async fn can_order_transactions() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); // disable automine api.anvil_set_auto_mine(false).await.unwrap(); @@ -87,7 +88,7 @@ async fn can_order_transactions() { #[tokio::test(flavor = "multi_thread")] async fn can_respect_nonces() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -126,7 +127,7 @@ async fn can_replace_transaction() { // disable auto mining api.anvil_set_auto_mine(false).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -164,7 +165,7 @@ async fn can_replace_transaction() { #[tokio::test(flavor = "multi_thread")] async fn can_reject_too_high_gas_limits() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -176,20 +177,20 @@ async fn can_reject_too_high_gas_limits() { let tx = TransactionRequest::new().to(to).value(amount).from(from); // send transaction with the exact gas limit - let pending = provider.send_transaction(tx.clone().gas(gas_limit), None).await; + let pending = provider.send_transaction(tx.clone().gas(gas_limit.to_ethers()), None).await; pending.unwrap(); // send transaction with higher gas limit - let pending = provider.send_transaction(tx.clone().gas(gas_limit + 1u64), None).await; + let pending = provider.send_transaction(tx.clone().gas(gas_limit.to_ethers() + 1u64), None).await; assert!(pending.is_err()); let err = pending.unwrap_err(); assert!(err.to_string().contains("gas too high")); - api.anvil_set_balance(from, U256::MAX).await.unwrap(); + api.anvil_set_balance(from.to_alloy(), U256::MAX.to_alloy()).await.unwrap(); - let pending = provider.send_transaction(tx.gas(gas_limit), None).await; + let pending = provider.send_transaction(tx.gas(gas_limit.to_ethers()), None).await; pending.unwrap(); } @@ -200,7 +201,7 @@ async fn can_reject_underpriced_replacement() { // disable auto mining api.anvil_set_auto_mine(false).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -235,7 +236,7 @@ async fn can_reject_underpriced_replacement() { #[tokio::test(flavor = "multi_thread")] async fn can_deploy_greeter_http() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -268,7 +269,7 @@ async fn can_deploy_and_mine_manually() { // can mine in manual mode api.evm_mine(None).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -301,7 +302,7 @@ async fn can_deploy_and_mine_manually() { #[tokio::test(flavor = "multi_thread")] async fn can_mine_automatically() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); // disable auto mine api.anvil_set_auto_mine(false).await.unwrap(); @@ -322,7 +323,7 @@ async fn can_mine_automatically() { #[tokio::test(flavor = "multi_thread")] async fn can_call_greeter_historic() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -357,7 +358,7 @@ async fn can_call_greeter_historic() { #[tokio::test(flavor = "multi_thread")] async fn can_deploy_greeter_ws() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -382,7 +383,7 @@ async fn can_deploy_greeter_ws() { #[tokio::test(flavor = "multi_thread")] async fn can_deploy_get_code() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -401,7 +402,7 @@ async fn can_deploy_get_code() { #[tokio::test(flavor = "multi_thread")] async fn get_blocktimestamp_works() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -413,14 +414,14 @@ async fn get_blocktimestamp_works() { assert!(timestamp > U256::one()); - let latest_block = api.block_by_number(BlockNumber::Latest).await.unwrap().unwrap(); + let latest_block = api.block_by_number(alloy_rpc_types::BlockNumberOrTag::Latest).await.unwrap().unwrap(); let timestamp = contract.get_current_block_timestamp().call().await.unwrap(); - assert_eq!(timestamp, latest_block.timestamp); + assert_eq!(timestamp, latest_block.header.timestamp.to_ethers()); // repeat call same result let timestamp = contract.get_current_block_timestamp().call().await.unwrap(); - assert_eq!(timestamp, latest_block.timestamp); + assert_eq!(timestamp, latest_block.header.timestamp.to_ethers()); // mock timestamp let next_timestamp = timestamp.as_u64() + 1337; @@ -439,7 +440,7 @@ async fn get_blocktimestamp_works() { #[tokio::test(flavor = "multi_thread")] async fn call_past_state() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -496,7 +497,7 @@ async fn call_past_state() { async fn can_handle_multiple_concurrent_transfers_with_same_nonce() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -526,7 +527,7 @@ async fn can_handle_multiple_concurrent_transfers_with_same_nonce() { #[tokio::test(flavor = "multi_thread")] async fn can_handle_multiple_concurrent_deploys_with_same_nonce() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallet = handle.dev_wallets().next().unwrap(); let from = wallet.address(); @@ -560,7 +561,7 @@ async fn can_handle_multiple_concurrent_deploys_with_same_nonce() { #[tokio::test(flavor = "multi_thread")] async fn can_handle_multiple_concurrent_transactions_with_same_nonce() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallet = handle.dev_wallets().next().unwrap(); let from = wallet.address(); @@ -619,7 +620,7 @@ async fn can_get_pending_transaction() { // disable auto mining so we can check if we can return pending tx from the mempool api.anvil_set_auto_mine(false).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let from = handle.dev_wallets().next().unwrap().address(); let tx = TransactionRequest::new().from(from).value(1337u64).to(Address::random()); @@ -640,7 +641,7 @@ async fn test_first_noce_is_zero() { api.anvil_set_auto_mine(false).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let from = handle.dev_wallets().next().unwrap().address(); let nonce = provider @@ -657,7 +658,7 @@ async fn can_handle_different_sender_nonce_calculation() { api.anvil_set_auto_mine(false).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from_first = accounts[0].address(); let from_second = accounts[1].address(); @@ -692,7 +693,7 @@ async fn includes_pending_tx_for_transaction_count() { api.anvil_set_auto_mine(false).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let from = handle.dev_wallets().next().unwrap().address(); let tx_count = 10u64; @@ -719,7 +720,7 @@ async fn includes_pending_tx_for_transaction_count() { #[tokio::test(flavor = "multi_thread")] async fn can_get_historic_info() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -756,7 +757,7 @@ async fn test_tx_receipt() { let (_api, handle) = spawn(NodeConfig::test()).await; let wallet = handle.dev_wallets().next().unwrap(); - let client = Arc::new(SignerMiddleware::new(handle.http_provider(), wallet)); + let client = Arc::new(SignerMiddleware::new(handle.ethers_http_provider(), wallet)); let tx = TransactionRequest::new().to(Address::random()).value(1337u64); @@ -777,8 +778,8 @@ async fn can_stream_pending_transactions() { let (_api, handle) = spawn(NodeConfig::test().with_blocktime(Some(Duration::from_secs(2)))).await; let num_txs = 5; - let provider = handle.http_provider(); - let ws_provider = handle.ws_provider(); + let provider = handle.ethers_http_provider(); + let ws_provider = handle.ethers_ws_provider(); let accounts = provider.get_accounts().await.unwrap(); let tx = TransactionRequest::new().from(accounts[0]).to(accounts[0]).value(1e18 as u64); @@ -861,7 +862,7 @@ async fn test_tx_access_list() { let (_api, handle) = spawn(NodeConfig::test()).await; let wallet = handle.dev_wallets().next().unwrap(); - let client = Arc::new(SignerMiddleware::new(handle.http_provider(), wallet)); + let client = Arc::new(SignerMiddleware::new(handle.ethers_http_provider(), wallet)); let sender = Address::random(); let other_acc = Address::random(); @@ -930,7 +931,7 @@ async fn estimates_gas_on_pending_by_default() { // disable auto mine api.anvil_set_auto_mine(false).await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let sender = wallet.address(); @@ -943,13 +944,13 @@ async fn estimates_gas_on_pending_by_default() { let tx = TransactionRequest::new().from(recipient).to(sender).value(1e10 as u64).data(vec![0x42]); - api.estimate_gas(tx.into(), None).await.unwrap(); + api.estimate_gas(to_call_request_from_tx_request(tx), None).await.unwrap(); } #[tokio::test(flavor = "multi_thread")] async fn test_reject_gas_too_low() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let account = handle.dev_accounts().next().unwrap(); @@ -971,7 +972,7 @@ async fn test_reject_gas_too_low() { async fn can_call_with_high_gas_limit() { let (_api, handle) = spawn(NodeConfig::test().with_gas_limit(Some(U256::from(100_000_000)))).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -989,7 +990,7 @@ async fn can_call_with_high_gas_limit() { #[tokio::test(flavor = "multi_thread")] async fn test_reject_eip1559_pre_london() { let (api, handle) = spawn(NodeConfig::test().with_hardfork(Some(Hardfork::Berlin))).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -998,8 +999,8 @@ async fn test_reject_eip1559_pre_london() { let gas_price = api.gas_price().unwrap(); let unsupported = Greeter::deploy(Arc::clone(&client), "Hello World!".to_string()) .unwrap() - .gas(gas_limit) - .gas_price(gas_price) + .gas(gas_limit.to_ethers()) + .gas_price(gas_price.to_ethers()) .send() .await .unwrap_err() diff --git a/crates/anvil/tests/it/txpool.rs b/crates/anvil/tests/it/txpool.rs index ea0f6b4d246a..3f17e5beeaac 100644 --- a/crates/anvil/tests/it/txpool.rs +++ b/crates/anvil/tests/it/txpool.rs @@ -9,7 +9,7 @@ use ethers::{ #[tokio::test(flavor = "multi_thread")] async fn geth_txpool() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); api.anvil_set_auto_mine(false).await.unwrap(); let account = provider.get_accounts().await.unwrap()[0]; diff --git a/crates/utils/src/types.rs b/crates/utils/src/types.rs index c481d375203e..38d4584eb405 100644 --- a/crates/utils/src/types.rs +++ b/crates/utils/src/types.rs @@ -2,10 +2,10 @@ use alloy_json_abi::{Event, EventParam, Function, InternalType, Param, StateMutability}; use alloy_primitives::{Address, B256, I256, U128, U256, U64}; -use alloy_rpc_types::{Signature, Transaction, AccessList, AccessListItem}; +use alloy_rpc_types::{Signature, Transaction, AccessList, AccessListItem, CallRequest, CallInput}; use ethers_core::{ abi as ethabi, - types::{H160, H256, I256 as EthersI256, U256 as EthersU256, U64 as EthersU64, transaction::eip2930::{AccessList as EthersAccessList, AccessListItem as EthersAccessListItem}}, + types::{H160, H256, I256 as EthersI256, U256 as EthersU256, U64 as EthersU64, transaction::eip2930::{AccessList as EthersAccessList, AccessListItem as EthersAccessListItem}, TransactionRequest}, }; /// Conversion trait to easily convert from Ethers types to Alloy types. @@ -103,6 +103,29 @@ impl ToAlloy for ethers_core::types::Transaction { } } +pub fn to_call_request_from_tx_request(tx: TransactionRequest) -> CallRequest { + CallRequest { + from: tx.from.map(|f| f.to_alloy()), + to: match tx.to { + Some(to) => match to { + ethers_core::types::NameOrAddress::Address(addr) => Some(addr.to_alloy()), + ethers_core::types::NameOrAddress::Name(_) => None + }, + None => None + }, + gas_price: tx.gas_price.map(|g| g.to_alloy()), + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + gas: tx.gas.map(|g| g.to_alloy()), + value: tx.value.map(|v| v.to_alloy()), + input: CallInput::maybe_input(tx.data.map(|b| b.0.into())), + nonce: tx.nonce.map(|n| U64::from(n.as_u64())), + chain_id: tx.chain_id.map(|c| c.to_alloy()), + access_list: None, max_fee_per_blob_gas: None, blob_versioned_hashes: None, + transaction_type: None + } +} + impl ToAlloy for EthersAccessList { type To = AccessList; fn to_alloy(self) -> Self::To { From e6220104781bbc084f777ffb6cb57b1f49235526 Mon Sep 17 00:00:00 2001 From: Enrique Ortiz Date: Mon, 20 Nov 2023 23:33:17 -0400 Subject: [PATCH 2/9] chore: fix u64 --- crates/anvil/src/config.rs | 6 +++--- crates/anvil/src/eth/api.rs | 8 ++++---- crates/anvil/src/eth/backend/fork.rs | 8 ++++---- crates/anvil/src/eth/backend/mem/mod.rs | 8 ++++---- crates/anvil/src/pubsub.rs | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/crates/anvil/src/config.rs b/crates/anvil/src/config.rs index 35d404cbb6e7..587a76d056e8 100644 --- a/crates/anvil/src/config.rs +++ b/crates/anvil/src/config.rs @@ -954,7 +954,7 @@ impl NodeConfig { }; let block = provider - .get_block(BlockNumberOrTag::Number(U64::from(fork_block_number)).into(), false) + .get_block(BlockNumberOrTag::Number(fork_block_number).into(), false) .await .expect("Failed to get fork block"); @@ -969,7 +969,7 @@ latest block number: {latest_block}" // If the `eth_getBlockByNumber` call succeeds, but returns null instead of // the block, and the block number is less than equal the latest block, then // the user is forking from a non-archive node with an older block number. - if fork_block_number <= latest_block.to::() { + if fork_block_number <= latest_block { message.push_str(&format!("\n{}", NON_ARCHIVE_NODE_WARNING)); } panic!("{}", message); @@ -1189,7 +1189,7 @@ pub fn anvil_tmp_dir() -> Option { /// This fetches the "latest" block and checks whether the `Block` is fully populated (`hash` field /// is present). This prevents edge cases where anvil forks the "latest" block but `eth_getBlockByNumber` still returns a pending block, async fn find_latest_fork_block(provider: P) -> Result { - let mut num = provider.get_block_number().await?.to::(); + let mut num = provider.get_block_number().await?; // walk back from the head of the chain, but at most 2 blocks, which should be more than enough // leeway diff --git a/crates/anvil/src/eth/api.rs b/crates/anvil/src/eth/api.rs index 1aa2288d818c..49df2957b186 100644 --- a/crates/anvil/src/eth/api.rs +++ b/crates/anvil/src/eth/api.rs @@ -637,7 +637,7 @@ impl EthApi { fork.storage_at( address, B256::from(index), - Some(BlockNumber::Number(*number)), + Some(BlockNumber::Number(number.to::())), ) .await .map_err(|_| BlockchainError::DataUnavailable)?, @@ -1260,7 +1260,7 @@ impl EthApi { let number = match newest_block { BlockNumber::Latest | BlockNumber::Pending => current, BlockNumber::Earliest => 0, - BlockNumber::Number(n) => n.to::(), + BlockNumber::Number(n) => n, BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch), BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2), }; @@ -1273,7 +1273,7 @@ impl EthApi { return Ok(fork .fee_history( block_count, - BlockNumber::Number(U64::from(number)), + BlockNumber::Number(number), &reward_percentiles, ) .await @@ -1906,7 +1906,7 @@ impl EthApi { for offset in (0..mined_blocks).rev() { let block_num = latest - offset; if let Some(mut block) = - self.backend.block_by_number_full(BlockNumber::Number(U64::from(block_num))).await? + self.backend.block_by_number_full(BlockNumber::Number(block_num)).await? { let mut block_txs = match block.transactions { BlockTransactions::Full(txs) => txs, diff --git a/crates/anvil/src/eth/backend/fork.rs b/crates/anvil/src/eth/backend/fork.rs index b52d87531e36..38e04323c5b4 100644 --- a/crates/anvil/src/eth/backend/fork.rs +++ b/crates/anvil/src/eth/backend/fork.rs @@ -178,7 +178,7 @@ impl ClientFork { if let BlockNumber::Number(num) = block { // check if this request was already been sent - let key = (request.clone(), num.to::()); + let key = (request.clone(), num); if let Some(res) = self.storage_read().eth_call.get(&key).cloned() { return Ok(res); } @@ -191,7 +191,7 @@ impl ClientFork { if let BlockNumber::Number(num) = block { // cache result let mut storage = self.storage_write(); - storage.eth_call.insert((request, num.to::()), res.clone()); + storage.eth_call.insert((request, num), res.clone()); } Ok(res) @@ -208,7 +208,7 @@ impl ClientFork { if let BlockNumber::Number(num) = block { // check if this request was already been sent - let key = (request.clone(), num.to::()); + let key = (request.clone(), num); if let Some(res) = self.storage_read().eth_gas_estimations.get(&key).cloned() { return Ok(res); } @@ -221,7 +221,7 @@ impl ClientFork { if let BlockNumber::Number(num) = block { // cache result let mut storage = self.storage_write(); - storage.eth_gas_estimations.insert((request, num.to::()), res); + storage.eth_gas_estimations.insert((request, num), res); } Ok(res) diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs index 9cc02c6eb54c..19d663f6077e 100644 --- a/crates/anvil/src/eth/backend/mem/mod.rs +++ b/crates/anvil/src/eth/backend/mem/mod.rs @@ -128,7 +128,7 @@ impl BlockRequest { pub fn block_number(&self) -> BlockNumber { match self { BlockRequest::Pending(_) => BlockNumber::Pending, - BlockRequest::Number(n) => BlockNumber::Number(*n), + BlockRequest::Number(n) => BlockNumber::Number(n.to::()), } } } @@ -1602,7 +1602,7 @@ impl Backend { BlockId::Number(num) => match num { BlockNumber::Latest | BlockNumber::Pending => self.best_number().to::(), BlockNumber::Earliest => U64::ZERO.to::(), - BlockNumber::Number(num) => num.to::(), + BlockNumber::Number(num) => num, BlockNumber::Safe => { U64::from(current).saturating_sub(U64::from(slots_in_an_epoch)).to::() } @@ -1625,7 +1625,7 @@ impl Backend { match block.unwrap_or(BlockNumber::Latest) { BlockNumber::Latest | BlockNumber::Pending => current, BlockNumber::Earliest => 0, - BlockNumber::Number(num) => num.to::(), + BlockNumber::Number(num) => num, BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch), BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2), } @@ -1660,7 +1660,7 @@ impl Backend { .await; return Ok(result); } - Some(BlockRequest::Number(bn)) => Some(BlockNumber::Number(bn)), + Some(BlockRequest::Number(bn)) => Some(BlockNumber::Number(bn.to::())), None => None, }; let block_number: U256 = U256::from(self.convert_block_number(block_number)); diff --git a/crates/anvil/src/pubsub.rs b/crates/anvil/src/pubsub.rs index e9543e6e6b0b..a8e0f0b0416a 100644 --- a/crates/anvil/src/pubsub.rs +++ b/crates/anvil/src/pubsub.rs @@ -168,7 +168,7 @@ pub fn filter_logs( }; if params.filter.is_some() { let block_number = block.header.number.as_u64(); - if !params.filter_block_range(U64::from(block_number)) + if !params.filter_block_range(block_number) || !params.filter_block_hash(block_hash) || !params.filter_address(&log) || !params.filter_topics(&log) From cdc88723a761aaa84761c3ba6377a8e0074b9c51 Mon Sep 17 00:00:00 2001 From: Oliver Nordbjerg Date: Tue, 21 Nov 2023 05:18:41 +0100 Subject: [PATCH 3/9] fix: access lists --- .../core/src/eth/transaction/ethers_compat.rs | 19 ++------ crates/evm/core/src/utils.rs | 10 +++- crates/utils/src/types.rs | 47 ++++++++++--------- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/crates/anvil/core/src/eth/transaction/ethers_compat.rs b/crates/anvil/core/src/eth/transaction/ethers_compat.rs index 8cf073e8cb19..232056c0ac1e 100644 --- a/crates/anvil/core/src/eth/transaction/ethers_compat.rs +++ b/crates/anvil/core/src/eth/transaction/ethers_compat.rs @@ -98,7 +98,9 @@ pub fn to_ethers_access_list(access_list: AlloyAccessList) -> AccessList { storage_keys: item .storage_keys .into_iter() - .map(|k| BigEndianHash::from_uint(&k.to_ethers())) + .map(|k| { + BigEndianHash::from_uint(&U256::from_big_endian(k.to_ethers().as_bytes())) + }) .collect(), }) .collect(), @@ -106,20 +108,7 @@ pub fn to_ethers_access_list(access_list: AlloyAccessList) -> AccessList { } pub fn from_ethers_access_list(access_list: AccessList) -> AlloyAccessList { - AlloyAccessList( - access_list - .0 - .into_iter() - .map(|item| AlloyAccessListItem { - address: item.address.to_alloy(), - storage_keys: item - .storage_keys - .into_iter() - .map(|k| rU256::from_be_bytes(k.to_alloy().0)) - .collect(), - }) - .collect(), - ) + AlloyAccessList(access_list.0.into_iter().map(ToAlloy::to_alloy).collect()) } impl From for EthersTypedTransactionRequest { diff --git a/crates/evm/core/src/utils.rs b/crates/evm/core/src/utils.rs index 0699b8ad1aac..87446f80deea 100644 --- a/crates/evm/core/src/utils.rs +++ b/crates/evm/core/src/utils.rs @@ -250,7 +250,15 @@ pub fn configure_tx_env(env: &mut revm::primitives::Env, tx: &Transaction) { .clone() .unwrap_or_default() .into_iter() - .map(|item| (item.address, item.storage_keys)) + .map(|item| { + ( + item.address, + item.storage_keys + .into_iter() + .map(|key| alloy_primitives::U256::from_be_bytes(key.0)) + .collect(), + ) + }) .collect(); env.tx.value = tx.value.to(); env.tx.data = alloy_primitives::Bytes(tx.input.0.clone()); diff --git a/crates/utils/src/types.rs b/crates/utils/src/types.rs index 38d4584eb405..54e2b08e92b1 100644 --- a/crates/utils/src/types.rs +++ b/crates/utils/src/types.rs @@ -2,10 +2,15 @@ use alloy_json_abi::{Event, EventParam, Function, InternalType, Param, StateMutability}; use alloy_primitives::{Address, B256, I256, U128, U256, U64}; -use alloy_rpc_types::{Signature, Transaction, AccessList, AccessListItem, CallRequest, CallInput}; +use alloy_rpc_types::{AccessList, AccessListItem, CallInput, CallRequest, Signature, Transaction}; use ethers_core::{ abi as ethabi, - types::{H160, H256, I256 as EthersI256, U256 as EthersU256, U64 as EthersU64, transaction::eip2930::{AccessList as EthersAccessList, AccessListItem as EthersAccessListItem}, TransactionRequest}, + types::{ + transaction::eip2930::{ + AccessList as EthersAccessList, AccessListItem as EthersAccessListItem, + }, + TransactionRequest, H160, H256, I256 as EthersI256, U256 as EthersU256, U64 as EthersU64, + }, }; /// Conversion trait to easily convert from Ethers types to Alloy types. @@ -86,7 +91,9 @@ impl ToAlloy for ethers_core::types::Transaction { gas_price: self.gas_price.map(|a| U128::from(a.as_u128())), gas: self.gas.to_alloy(), max_fee_per_gas: self.max_fee_per_gas.map(|f| U128::from(f.as_u128())), - max_priority_fee_per_gas: self.max_priority_fee_per_gas.map(|f| U128::from(f.as_u128())), + max_priority_fee_per_gas: self + .max_priority_fee_per_gas + .map(|f| U128::from(f.as_u128())), max_fee_per_blob_gas: None, input: self.input.0.into(), signature: Some(Signature { @@ -104,25 +111,27 @@ impl ToAlloy for ethers_core::types::Transaction { } pub fn to_call_request_from_tx_request(tx: TransactionRequest) -> CallRequest { - CallRequest { + CallRequest { from: tx.from.map(|f| f.to_alloy()), to: match tx.to { Some(to) => match to { ethers_core::types::NameOrAddress::Address(addr) => Some(addr.to_alloy()), - ethers_core::types::NameOrAddress::Name(_) => None + ethers_core::types::NameOrAddress::Name(_) => None, }, - None => None + None => None, }, - gas_price: tx.gas_price.map(|g| g.to_alloy()), - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - gas: tx.gas.map(|g| g.to_alloy()), - value: tx.value.map(|v| v.to_alloy()), - input: CallInput::maybe_input(tx.data.map(|b| b.0.into())), - nonce: tx.nonce.map(|n| U64::from(n.as_u64())), - chain_id: tx.chain_id.map(|c| c.to_alloy()), - access_list: None, max_fee_per_blob_gas: None, blob_versioned_hashes: None, - transaction_type: None + gas_price: tx.gas_price.map(|g| g.to_alloy()), + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + gas: tx.gas.map(|g| g.to_alloy()), + value: tx.value.map(|v| v.to_alloy()), + input: CallInput::maybe_input(tx.data.map(|b| b.0.into())), + nonce: tx.nonce.map(|n| U64::from(n.as_u64())), + chain_id: tx.chain_id.map(|c| c.to_alloy()), + access_list: None, + max_fee_per_blob_gas: None, + blob_versioned_hashes: None, + transaction_type: None, } } @@ -139,11 +148,7 @@ impl ToAlloy for EthersAccessListItem { fn to_alloy(self) -> Self::To { AccessListItem { address: self.address.to_alloy(), - storage_keys: self - .storage_keys - .into_iter() - .map(|k| U256::from_be_bytes(k.to_alloy().0)) - .collect(), + storage_keys: self.storage_keys.into_iter().map(ToAlloy::to_alloy).collect(), } } } From dd9f3e0fd29d0462f6142ad852dc8bee93e8f199 Mon Sep 17 00:00:00 2001 From: Oliver Nordbjerg Date: Tue, 21 Nov 2023 05:21:31 +0100 Subject: [PATCH 4/9] chore: use latest ethers --- Cargo.lock | 44 ++++++++++++++++++++++---------------------- Cargo.toml | 20 ++++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2961167107b..75ed9c259bfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2213,8 +2213,8 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -2228,8 +2228,8 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "ethers-core", "once_cell", @@ -2239,8 +2239,8 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -2257,8 +2257,8 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "Inflector", "const-hex", @@ -2280,8 +2280,8 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "Inflector", "const-hex", @@ -2295,8 +2295,8 @@ dependencies = [ [[package]] name = "ethers-core" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "arrayvec", "bytes", @@ -2324,8 +2324,8 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "chrono", "ethers-core", @@ -2340,8 +2340,8 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "async-trait", "auto_impl", @@ -2365,8 +2365,8 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "async-trait", "auto_impl", @@ -2403,8 +2403,8 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "async-trait", "coins-bip32", @@ -2431,8 +2431,8 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.10" -source = "git+https://github.com/gakonst/ethers-rs?rev=b4c366c964106b274e2eb528ac44eebc9bb49551#b4c366c964106b274e2eb528ac44eebc9bb49551" +version = "2.0.11" +source = "git+https://github.com/gakonst/ethers-rs?rev=546ea029362a7502365667c6f99fac92ad0aeb9f#546ea029362a7502365667c6f99fac92ad0aeb9f" dependencies = [ "cfg-if", "const-hex", diff --git a/Cargo.toml b/Cargo.toml index ca6196464bed..1e76da5c8060 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -200,16 +200,16 @@ tower-http = "0.4" #ethers-solc = { path = "../ethers-rs/ethers-solc" } [patch.crates-io] -ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-addressbook = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-core = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-contract = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-contract-abigen = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-providers = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-signers = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-middleware = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-etherscan = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } -ethers-solc = { git = "https://github.com/gakonst/ethers-rs", rev = "b4c366c964106b274e2eb528ac44eebc9bb49551" } +ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-addressbook = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-core = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-contract = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-contract-abigen = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-providers = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-signers = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-middleware = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-etherscan = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } +ethers-solc = { git = "https://github.com/gakonst/ethers-rs", rev = "546ea029362a7502365667c6f99fac92ad0aeb9f" } alloy-dyn-abi = { git = "https://github.com/alloy-rs/core/" } alloy-primitives = { git = "https://github.com/alloy-rs/core/" } From 9e2436e7b7151ac9ddbbe22615f240f5008b12c8 Mon Sep 17 00:00:00 2001 From: Enrique Ortiz Date: Tue, 21 Nov 2023 01:14:25 -0400 Subject: [PATCH 5/9] silly ahhh otterscan test failing --- crates/anvil/core/src/eth/state.rs | 16 +++ crates/anvil/src/eth/otterscan/types.rs | 4 +- crates/anvil/tests/it/gas.rs | 10 +- crates/anvil/tests/it/main.rs | 10 +- crates/anvil/tests/it/otterscan.rs | 175 +++++++++++++----------- 5 files changed, 125 insertions(+), 90 deletions(-) create mode 100644 crates/anvil/core/src/eth/state.rs diff --git a/crates/anvil/core/src/eth/state.rs b/crates/anvil/core/src/eth/state.rs new file mode 100644 index 000000000000..128941f34771 --- /dev/null +++ b/crates/anvil/core/src/eth/state.rs @@ -0,0 +1,16 @@ +use ethers_core::types::{Address, Bytes, H256, U256}; +use std::collections::HashMap; + +#[derive(Clone, Debug, PartialEq, Eq, Default)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] +pub struct AccountOverride { + pub nonce: Option, + pub code: Option, + pub balance: Option, + pub state: Option>, + pub state_diff: Option>, +} + +pub type StateOverride = HashMap; \ No newline at end of file diff --git a/crates/anvil/src/eth/otterscan/types.rs b/crates/anvil/src/eth/otterscan/types.rs index 1529a8ca1650..643bcc33e70c 100644 --- a/crates/anvil/src/eth/otterscan/types.rs +++ b/crates/anvil/src/eth/otterscan/types.rs @@ -12,7 +12,7 @@ use serde::Serialize; use serde_repr::Serialize_repr; /// Patched Block struct, to include the additional `transactionCount` field expected by Otterscan -#[derive(Debug, Serialize)] +#[derive(Clone, Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct OtsBlock { #[serde(flatten)] @@ -38,7 +38,7 @@ pub struct Issuance { } /// Holds both transactions and receipts for a block -#[derive(Serialize, Debug)] +#[derive(Clone, Serialize, Debug)] pub struct OtsBlockTransactions { pub fullblock: OtsBlock, pub receipts: Vec, diff --git a/crates/anvil/tests/it/gas.rs b/crates/anvil/tests/it/gas.rs index 27c6055be3ee..b7052014b8ac 100644 --- a/crates/anvil/tests/it/gas.rs +++ b/crates/anvil/tests/it/gas.rs @@ -17,7 +17,7 @@ async fn test_basefee_full_block() { NodeConfig::test().with_base_fee(Some(INITIAL_BASE_FEE)).with_gas_limit(Some(GAS_TRANSFER)), ) .await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let tx = TransactionRequest::new().to(Address::random()).value(1337u64); provider.send_transaction(tx.clone(), None).await.unwrap().await.unwrap().unwrap(); let base_fee = @@ -40,7 +40,7 @@ async fn test_basefee_half_block() { .with_gas_limit(Some(GAS_TRANSFER * 2)), ) .await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let tx = TransactionRequest::new().to(Address::random()).value(1337u64); provider.send_transaction(tx.clone(), None).await.unwrap().await.unwrap().unwrap(); let tx = TransactionRequest::new().to(Address::random()).value(1337u64); @@ -55,7 +55,7 @@ async fn test_basefee_half_block() { async fn test_basefee_empty_block() { let (api, handle) = spawn(NodeConfig::test().with_base_fee(Some(INITIAL_BASE_FEE))).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let tx = TransactionRequest::new().to(Address::random()).value(1337u64); provider.send_transaction(tx, None).await.unwrap().await.unwrap().unwrap(); let base_fee = @@ -75,7 +75,7 @@ async fn test_basefee_empty_block() { async fn test_respect_base_fee() { let base_fee = 50u64; let (_api, handle) = spawn(NodeConfig::test().with_base_fee(Some(base_fee))).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let mut tx = TypedTransaction::default(); tx.set_value(100u64); tx.set_to(Address::random()); @@ -95,7 +95,7 @@ async fn test_respect_base_fee() { async fn test_tip_above_fee_cap() { let base_fee = 50u64; let (_api, handle) = spawn(NodeConfig::test().with_base_fee(Some(base_fee))).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let tx = TypedTransaction::Eip1559( Eip1559TransactionRequest::new() .max_fee_per_gas(base_fee) diff --git a/crates/anvil/tests/it/main.rs b/crates/anvil/tests/it/main.rs index a546ff9e3acc..d454bf82ad43 100644 --- a/crates/anvil/tests/it/main.rs +++ b/crates/anvil/tests/it/main.rs @@ -4,20 +4,20 @@ mod anvil; // mod api; // mod fork; // mod ganache; -// mod gas; +mod gas; mod genesis; -// mod geth; +mod geth; // mod ipc; -// mod logs; +mod logs; // mod proof; // mod pubsub; // // mod revert; // TODO uncomment -// mod otterscan; +mod otterscan; // mod sign; // mod traces; mod transaction; mod txpool; -// pub mod utils; +pub mod utils; // mod wsapi; #[allow(unused)] diff --git a/crates/anvil/tests/it/otterscan.rs b/crates/anvil/tests/it/otterscan.rs index 3c460424ccbf..1ce062617ca4 100644 --- a/crates/anvil/tests/it/otterscan.rs +++ b/crates/anvil/tests/it/otterscan.rs @@ -13,6 +13,9 @@ use ethers::{ types::{BlockNumber, Bytes, TransactionRequest, U256}, utils::get_contract_address, }; +use alloy_primitives::{U256 as rU256, Address as rAddress, B256}; +use alloy_rpc_types::{BlockNumberOrTag, BlockTransactions, Block}; +use foundry_utils::types::{ToAlloy, ToEthers}; use ethers_solc::{project_util::TempProject, Artifact}; use std::{collections::VecDeque, str::FromStr, sync::Arc}; @@ -24,8 +27,8 @@ async fn can_call_erigon_get_header_by_number() { let res0 = api.erigon_get_header_by_number(0.into()).await.unwrap().unwrap(); let res1 = api.erigon_get_header_by_number(1.into()).await.unwrap().unwrap(); - assert_eq!(res0.number, Some(0.into())); - assert_eq!(res1.number, Some(1.into())); + assert_eq!(res0.header.number, Some(rU256::from(0))); + assert_eq!(res1.header.number, Some(rU256::from(1))); } #[tokio::test(flavor = "multi_thread")] @@ -38,7 +41,7 @@ async fn can_call_ots_get_api_level() { #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_get_internal_operations_contract_deploy() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let sender = wallet.address(); @@ -50,16 +53,16 @@ async fn can_call_ots_get_internal_operations_contract_deploy() { let receipt = client.send_transaction(deploy_tx, None).await.unwrap().await.unwrap().unwrap(); - let res = api.ots_get_internal_operations(receipt.transaction_hash).await.unwrap(); + let res = api.ots_get_internal_operations(receipt.transaction_hash.to_alloy()).await.unwrap(); assert_eq!(res.len(), 1); assert_eq!( res[0], OtsInternalOperation { r#type: OtsInternalOperationType::Create, - from: sender, - to: contract_address, - value: 0.into() + from: sender.to_alloy(), + to: contract_address.to_alloy(), + value: rU256::from(0) } ); } @@ -67,7 +70,7 @@ async fn can_call_ots_get_internal_operations_contract_deploy() { #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_get_internal_operations_contract_trasfer() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); @@ -80,16 +83,16 @@ async fn can_call_ots_get_internal_operations_contract_trasfer() { let receipt = provider.send_transaction(tx, None).await.unwrap().await.unwrap().unwrap(); - let res = api.ots_get_internal_operations(receipt.transaction_hash).await.unwrap(); + let res = api.ots_get_internal_operations(receipt.transaction_hash.to_alloy()).await.unwrap(); assert_eq!(res.len(), 1); assert_eq!( res[0], OtsInternalOperation { r#type: OtsInternalOperationType::Transfer, - from, - to, - value: amount + from: from.to_alloy(), + to: to.to_alloy(), + value: amount.to_alloy() } ); } @@ -122,7 +125,7 @@ contract Contract { let (abi, bytecode, _) = contract.into_contract_bytecode().into_parts(); let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallets = handle.dev_wallets().collect::>(); let client = Arc::new(SignerMiddleware::new(provider, wallets[0].clone())); @@ -133,21 +136,21 @@ contract Contract { let contract = ContractInstance::new( contract.address(), abi.unwrap(), - SignerMiddleware::new(handle.http_provider(), wallets[1].clone()), + SignerMiddleware::new(handle.ethers_http_provider(), wallets[1].clone()), ); let call = contract.method::<_, ()>("deploy", ()).unwrap(); let receipt = call.send().await.unwrap().await.unwrap().unwrap(); - let res = api.ots_get_internal_operations(receipt.transaction_hash).await.unwrap(); + let res = api.ots_get_internal_operations(receipt.transaction_hash.to_alloy()).await.unwrap(); assert_eq!(res.len(), 1); assert_eq!( res[0], OtsInternalOperation { r#type: OtsInternalOperationType::Create2, - from: Address::from_str("0x4e59b44847b379578588920cA78FbF26c0B4956C").unwrap(), - to: Address::from_str("0x347bcdad821abc09b8c275881b368de36476b62c").unwrap(), - value: 0.into() + from: Address::from_str("0x4e59b44847b379578588920cA78FbF26c0B4956C").unwrap().to_alloy(), + to: Address::from_str("0x347bcdad821abc09b8c275881b368de36476b62c").unwrap().to_alloy(), + value: rU256::from(0) } ); } @@ -178,7 +181,7 @@ contract Contract { let (abi, bytecode, _) = contract.into_contract_bytecode().into_parts(); let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallets = handle.dev_wallets().collect::>(); let client = Arc::new(SignerMiddleware::new(provider, wallets[0].clone())); @@ -189,22 +192,22 @@ contract Contract { let contract = ContractInstance::new( contract.address(), abi.unwrap(), - SignerMiddleware::new(handle.http_provider(), wallets[1].clone()), + SignerMiddleware::new(handle.ethers_http_provider(), wallets[1].clone()), ); let call = contract.method::<_, ()>("goodbye", ()).unwrap(); let receipt = call.send().await.unwrap().await.unwrap().unwrap(); - let res = api.ots_get_internal_operations(receipt.transaction_hash).await.unwrap(); + let res = api.ots_get_internal_operations(receipt.transaction_hash.to_alloy()).await.unwrap(); assert_eq!(res.len(), 1); assert_eq!( res[0], OtsInternalOperation { r#type: OtsInternalOperationType::SelfDestruct, - from: contract.address(), + from: contract.address().to_alloy(), to: Default::default(), - value: 0.into() + value: rU256::from(0) } ); } @@ -212,7 +215,7 @@ contract Contract { #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_has_code() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let sender = wallet.address(); @@ -226,7 +229,7 @@ async fn can_call_ots_has_code() { // no code in the address before deploying assert!(!api - .ots_has_code(pending_contract_address, BlockNumber::Number(1.into())) + .ots_has_code(pending_contract_address.to_alloy(), BlockNumberOrTag::Number(1)) .await .unwrap()); @@ -237,11 +240,11 @@ async fn can_call_ots_has_code() { assert_eq!(num, receipt.block_number.unwrap()); // code is detected after deploying - assert!(api.ots_has_code(pending_contract_address, BlockNumber::Number(num)).await.unwrap()); + assert!(api.ots_has_code(pending_contract_address.to_alloy(), BlockNumberOrTag::Number(num.as_u64())).await.unwrap()); // code is not detected for the previous block assert!(!api - .ots_has_code(pending_contract_address, BlockNumber::Number(num - 1)) + .ots_has_code(pending_contract_address.to_alloy(), BlockNumberOrTag::Number(num.as_u64() - 1)) .await .unwrap()); } @@ -285,7 +288,7 @@ contract Contract { let (abi, bytecode, _) = contract.into_contract_bytecode().into_parts(); let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallets = handle.dev_wallets().collect::>(); let client = Arc::new(SignerMiddleware::new(provider, wallets[0].clone())); @@ -296,12 +299,12 @@ contract Contract { let contract = ContractInstance::new( contract.address(), abi.unwrap(), - SignerMiddleware::new(handle.http_provider(), wallets[1].clone()), + SignerMiddleware::new(handle.ethers_http_provider(), wallets[1].clone()), ); let call = contract.method::<_, ()>("run", ()).unwrap().value(1337); let receipt = call.send().await.unwrap().await.unwrap().unwrap(); - let res = api.ots_trace_transaction(receipt.transaction_hash).await.unwrap(); + let res = api.ots_trace_transaction(receipt.transaction_hash.to_alloy()).await.unwrap(); assert_eq!( res, @@ -309,42 +312,42 @@ contract Contract { OtsTrace { r#type: OtsTraceType::Call, depth: 0, - from: wallets[1].address(), - to: contract.address(), - value: 1337.into(), - input: Bytes::from_str("0xc0406226").unwrap() + from: wallets[1].address().to_alloy(), + to: contract.address().to_alloy(), + value: rU256::from(1337), + input: Bytes::from_str("0xc0406226").unwrap().0.into() }, OtsTrace { r#type: OtsTraceType::StaticCall, depth: 1, - from: contract.address(), - to: contract.address(), - value: U256::zero(), - input: Bytes::from_str("0x6a6758fe").unwrap() + from: contract.address().to_alloy(), + to: contract.address().to_alloy(), + value: U256::zero().to_alloy(), + input: Bytes::from_str("0x6a6758fe").unwrap().0.into() }, OtsTrace { r#type: OtsTraceType::Call, depth: 1, - from: contract.address(), - to: contract.address(), - value: U256::zero(), - input: Bytes::from_str("0x96385e39").unwrap() + from: contract.address().to_alloy(), + to: contract.address().to_alloy(), + value: U256::zero().to_alloy(), + input: Bytes::from_str("0x96385e39").unwrap().0.into() }, OtsTrace { r#type: OtsTraceType::Call, depth: 2, - from: contract.address(), - to: wallets[0].address(), - value: 1337.into(), - input: Bytes::from_str("0x").unwrap() + from: contract.address().to_alloy(), + to: wallets[0].address().to_alloy(), + value: U256::from(1337).to_alloy(), + input: Bytes::from_str("0x").unwrap().0.into() }, OtsTrace { r#type: OtsTraceType::DelegateCall, depth: 2, - from: contract.address(), - to: contract.address(), - value: U256::zero(), - input: Bytes::from_str("0xa1325397").unwrap() + from: contract.address().to_alloy(), + to: contract.address().to_alloy(), + value: U256::zero().to_alloy(), + input: Bytes::from_str("0xa1325397").unwrap().0.into() }, ] ); @@ -374,7 +377,7 @@ contract Contract { let (abi, bytecode, _) = contract.into_contract_bytecode().into_parts(); let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -386,14 +389,15 @@ contract Contract { let call = contract.method::<_, ()>("trigger_revert", ()).unwrap().gas(150_000u64); let receipt = call.send().await.unwrap().await.unwrap().unwrap(); - let res = api.ots_get_transaction_error(receipt.transaction_hash).await.unwrap().unwrap(); + let res = api.ots_get_transaction_error(receipt.transaction_hash.to_alloy()).await.unwrap().unwrap(); + let res: Bytes = res.0.into(); assert_eq!(res, Bytes::from_str("0x8d6ea8be00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000012526576657274537472696e67466f6f4261720000000000000000000000000000").unwrap()); } #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_get_block_details() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -404,13 +408,18 @@ async fn can_call_ots_get_block_details() { let result = api.ots_get_block_details(1.into()).await.unwrap(); assert_eq!(result.block.transaction_count, 1); - assert_eq!(result.block.block.transactions[0], receipt.transaction_hash); + let hash = match result.block.block.transactions { + BlockTransactions::Full(txs) => txs[0].hash, + BlockTransactions::Hashes(hashes) => hashes[0], + BlockTransactions::Uncle => unreachable!() + }; + assert_eq!(hash, receipt.transaction_hash.to_alloy()); } #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_get_block_details_by_hash() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -419,16 +428,21 @@ async fn can_call_ots_get_block_details_by_hash() { let receipt = client.send_transaction(tx, None).await.unwrap().await.unwrap().unwrap(); let block_hash = receipt.block_hash.unwrap(); - let result = api.ots_get_block_details_by_hash(block_hash).await.unwrap(); + let result = api.ots_get_block_details_by_hash(block_hash.to_alloy()).await.unwrap(); assert_eq!(result.block.transaction_count, 1); - assert_eq!(result.block.block.transactions[0], receipt.transaction_hash); + let hash = match result.block.block.transactions { + BlockTransactions::Full(txs) => txs[0].hash, + BlockTransactions::Hashes(hashes) => hashes[0], + BlockTransactions::Uncle => unreachable!() + }; + assert_eq!(hash.to_ethers(), receipt.transaction_hash); } #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_get_block_transactions() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -450,13 +464,18 @@ async fn can_call_ots_get_block_transactions() { let result = api.ots_get_block_transactions(1, page, page_size).await.unwrap(); assert!(result.receipts.len() <= page_size); - assert!(result.fullblock.block.transactions.len() <= page_size); + let len = match result.fullblock.block.transactions { + BlockTransactions::Full(ref txs) => txs.len(), + BlockTransactions::Hashes(ref hashes) => hashes.len(), + BlockTransactions::Uncle => 0 + }; + assert!(len <= page_size); assert!(result.fullblock.transaction_count == result.receipts.len()); result.receipts.iter().enumerate().for_each(|(i, receipt)| { let expected = hashes.pop_front(); - assert_eq!(expected, Some(receipt.transaction_hash)); - assert_eq!(expected, Some(result.fullblock.block.transactions[i].hash)); + assert_eq!(Some(expected), Some(receipt.transaction_hash.map(|h| h.to_ethers()))); + assert_eq!(Some(expected.map(|h| h.to_alloy())), Some(result.clone().fullblock.block.clone().transactions.iter().nth(i))); }); } @@ -466,7 +485,7 @@ async fn can_call_ots_get_block_transactions() { #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_search_transactions_before() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let sender = wallet.address(); @@ -483,16 +502,16 @@ async fn can_call_ots_search_transactions_before() { let page_size = 2; let mut block = 0; for _ in 0..4 { - let result = api.ots_search_transactions_before(sender, block, page_size).await.unwrap(); + let result = api.ots_search_transactions_before(sender.to_alloy(), block, page_size).await.unwrap(); assert!(result.txs.len() <= page_size); // check each individual hash result.txs.iter().for_each(|tx| { - assert_eq!(hashes.pop(), Some(tx.hash)); + assert_eq!(hashes.pop(), Some(tx.hash.to_ethers())); }); - block = result.txs.last().unwrap().block_number.unwrap().as_u64() - 1; + block = result.txs.last().unwrap().block_number.unwrap().to::() - 1; } assert!(hashes.is_empty()); @@ -501,7 +520,7 @@ async fn can_call_ots_search_transactions_before() { #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_search_transactions_after() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let sender = wallet.address(); @@ -518,16 +537,16 @@ async fn can_call_ots_search_transactions_after() { let page_size = 2; let mut block = 0; for _ in 0..4 { - let result = api.ots_search_transactions_after(sender, block, page_size).await.unwrap(); + let result = api.ots_search_transactions_after(sender.to_alloy(), block, page_size).await.unwrap(); assert!(result.txs.len() <= page_size); // check each individual hash result.txs.iter().for_each(|tx| { - assert_eq!(hashes.pop_back(), Some(tx.hash)); + assert_eq!(hashes.pop_back(), Some(tx.hash.to_ethers())); }); - block = result.txs.last().unwrap().block_number.unwrap().as_u64() + 1; + block = result.txs.last().unwrap().block_number.unwrap().to::() + 1; } assert!(hashes.is_empty()); @@ -536,7 +555,7 @@ async fn can_call_ots_search_transactions_after() { #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_get_transaction_by_sender_and_nonce() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); api.mine_one().await; let wallet = handle.dev_wallets().next().unwrap(); @@ -549,17 +568,17 @@ async fn can_call_ots_get_transaction_by_sender_and_nonce() { let receipt1 = client.send_transaction(tx1, None).await.unwrap().await.unwrap().unwrap(); let receipt2 = client.send_transaction(tx2, None).await.unwrap().await.unwrap().unwrap(); - let result1 = api.ots_get_transaction_by_sender_and_nonce(sender, 0.into()).await.unwrap(); - let result2 = api.ots_get_transaction_by_sender_and_nonce(sender, 1.into()).await.unwrap(); + let result1 = api.ots_get_transaction_by_sender_and_nonce(sender.to_alloy(), rU256::from(0)).await.unwrap(); + let result2 = api.ots_get_transaction_by_sender_and_nonce(sender.to_alloy(), rU256::from(1)).await.unwrap(); - assert_eq!(result1.unwrap().hash, receipt1.transaction_hash); - assert_eq!(result2.unwrap().hash, receipt2.transaction_hash); + assert_eq!(result1.unwrap().hash, receipt1.transaction_hash.to_alloy()); + assert_eq!(result2.unwrap().hash, receipt2.transaction_hash.to_alloy()); } #[tokio::test(flavor = "multi_thread")] async fn can_call_ots_get_contract_creator() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); api.mine_one().await; let wallet = handle.dev_wallets().next().unwrap(); @@ -573,8 +592,8 @@ async fn can_call_ots_get_contract_creator() { let receipt = client.send_transaction(deploy_tx, None).await.unwrap().await.unwrap().unwrap(); - let creator = api.ots_get_contract_creator(pending_contract_address).await.unwrap().unwrap(); + let creator = api.ots_get_contract_creator(pending_contract_address.to_alloy()).await.unwrap().unwrap(); - assert_eq!(creator.creator, sender); - assert_eq!(creator.hash, receipt.transaction_hash); + assert_eq!(creator.creator, sender.to_alloy()); + assert_eq!(creator.hash, receipt.transaction_hash.to_alloy()); } From 4697912633806224370c713f08b7e9c667172cf5 Mon Sep 17 00:00:00 2001 From: Enrique Ortiz Date: Tue, 21 Nov 2023 13:11:51 -0400 Subject: [PATCH 6/9] more fixdy --- crates/anvil/core/src/eth/mod.rs | 1 + .../core/src/eth/transaction/ethers_compat.rs | 26 +++++++- crates/anvil/core/src/eth/transaction/mod.rs | 2 +- crates/anvil/tests/it/api.rs | 64 ++++++++++--------- crates/anvil/tests/it/main.rs | 10 +-- crates/anvil/tests/it/proof/mod.rs | 15 +++-- crates/anvil/tests/it/sign.rs | 4 +- 7 files changed, 75 insertions(+), 47 deletions(-) diff --git a/crates/anvil/core/src/eth/mod.rs b/crates/anvil/core/src/eth/mod.rs index b3ff591db85d..63a9c676b107 100644 --- a/crates/anvil/core/src/eth/mod.rs +++ b/crates/anvil/core/src/eth/mod.rs @@ -17,6 +17,7 @@ pub mod subscription; pub mod transaction; pub mod trie; pub mod utils; +pub mod state; #[cfg(feature = "serde")] pub mod serde_helpers; diff --git a/crates/anvil/core/src/eth/transaction/ethers_compat.rs b/crates/anvil/core/src/eth/transaction/ethers_compat.rs index 232056c0ac1e..ee4802443e05 100644 --- a/crates/anvil/core/src/eth/transaction/ethers_compat.rs +++ b/crates/anvil/core/src/eth/transaction/ethers_compat.rs @@ -6,13 +6,13 @@ use crate::eth::{ transaction::{ EIP1559TransactionRequest, EIP2930TransactionRequest, LegacyTransactionRequest, MaybeImpersonatedTransaction, TypedTransaction, TypedTransactionRequest, - }, + }, state::{StateOverride as EthStateOverride, AccountOverride}, }; use alloy_primitives::{U128 as rU128, U256 as rU256, U64 as rU64}; use alloy_rpc_types::{ AccessList as AlloyAccessList, AccessListItem as AlloyAccessListItem, CallRequest, EIP1186StorageProof, Signature, Transaction as AlloyTransaction, - TransactionRequest as AlloyTransactionRequest, + TransactionRequest as AlloyTransactionRequest, state::{StateOverride, AccountOverride as AlloyAccountOverride}, }; use ethers_core::types::{ transaction::{ @@ -111,6 +111,28 @@ pub fn from_ethers_access_list(access_list: AccessList) -> AlloyAccessList { AlloyAccessList(access_list.0.into_iter().map(ToAlloy::to_alloy).collect()) } +pub fn to_ethers_state_override(ov: StateOverride) -> EthStateOverride { + ov.into_iter() + .map(|(addr, o)| (addr.to_ethers(), AccountOverride { + nonce: o.nonce.map(|n| n.to::()), + balance: o.balance.map(|b| b.to_ethers()), + code: o.code.map(|c| c.0.into()), + state_diff: o.state_diff.map(|s| s.into_iter().map(|(k, v)| (k.to_ethers(), H256::from_uint(&v.to_ethers()))).collect()), + state: o.state.map(|s| s.into_iter().map(|(k, v)| (k.to_ethers(), H256::from_uint(&v.to_ethers()))).collect()), + })).collect() +} + +pub fn to_alloy_state_override(ov: EthStateOverride) -> StateOverride { + ov.into_iter() + .map(|(addr, o)| (addr.to_alloy(), AlloyAccountOverride { + nonce: o.nonce.map(|n| rU64::from(n)), + balance: o.balance.map(|b| b.to_alloy()), + code: o.code.map(|c| c.0.into()), + state_diff: o.state_diff.map(|s| s.into_iter().map(|(k, v)| (k.to_alloy(), rU256::from_be_bytes(v.to_alloy().0))).collect()), + state: o.state.map(|s| s.into_iter().map(|(k, v)| (k.to_alloy(), rU256::from_be_bytes(v.to_alloy().0))).collect()), + })).collect() +} + impl From for EthersTypedTransactionRequest { fn from(tx: TypedTransactionRequest) -> Self { match tx { diff --git a/crates/anvil/core/src/eth/transaction/mod.rs b/crates/anvil/core/src/eth/transaction/mod.rs index 4d319a5c59d9..c1a1675f223a 100644 --- a/crates/anvil/core/src/eth/transaction/mod.rs +++ b/crates/anvil/core/src/eth/transaction/mod.rs @@ -27,7 +27,7 @@ mod ethers_compat; pub use ethers_compat::{ call_to_internal_tx_request, from_ethers_access_list, to_alloy_proof, to_ethers_access_list, - to_internal_tx_request, + to_internal_tx_request, to_ethers_state_override, to_alloy_state_override }; /// The signature used to bypass signing via the `eth_sendUnsignedTransaction` cheat RPC diff --git a/crates/anvil/tests/it/api.rs b/crates/anvil/tests/it/api.rs index 32c6fcf2ba6c..27180ab7b192 100644 --- a/crates/anvil/tests/it/api.rs +++ b/crates/anvil/tests/it/api.rs @@ -1,11 +1,12 @@ //! general eth api tests use crate::abi::{MulticallContract, SimpleStorage}; +use alloy_rpc_types::{CallRequest, CallInput}; use anvil::{ eth::{api::CLIENT_VERSION, EthApi}, spawn, NodeConfig, CHAIN_ID, }; -use anvil_core::eth::{state::AccountOverride, transaction::EthTransactionRequest}; +use anvil_core::eth::{state::AccountOverride, transaction::{EthTransactionRequest, to_ethers_state_override, to_alloy_state_override}}; use ethers::{ abi::{Address, Tokenizable}, prelude::{builders::ContractCall, decode_function_data, Middleware, SignerMiddleware}, @@ -13,6 +14,8 @@ use ethers::{ types::{Block, BlockNumber, Chain, Transaction, TransactionRequest, H256, U256}, utils::get_contract_address, }; +use alloy_primitives::{U256 as rU256}; +use foundry_utils::types::ToAlloy; use std::{collections::HashMap, sync::Arc, time::Duration}; #[tokio::test(flavor = "multi_thread")] @@ -20,18 +23,18 @@ async fn can_get_block_number() { let (api, handle) = spawn(NodeConfig::test()).await; let block_num = api.block_number().unwrap(); - assert_eq!(block_num, U256::zero()); + assert_eq!(block_num, U256::zero().to_alloy()); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let num = provider.get_block_number().await.unwrap(); - assert_eq!(num, block_num.as_u64().into()); + assert_eq!(num, block_num.to::().into()); } #[tokio::test(flavor = "multi_thread")] async fn can_dev_get_balance() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let genesis_balance = handle.genesis_balance(); for acc in handle.genesis_accounts() { @@ -43,7 +46,7 @@ async fn can_dev_get_balance() { #[tokio::test(flavor = "multi_thread")] async fn can_get_price() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let _ = provider.get_gas_price().await.unwrap(); } @@ -51,7 +54,7 @@ async fn can_get_price() { #[tokio::test(flavor = "multi_thread")] async fn can_get_accounts() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let _ = provider.get_accounts().await.unwrap(); } @@ -59,7 +62,7 @@ async fn can_get_accounts() { #[tokio::test(flavor = "multi_thread")] async fn can_get_client_version() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let version = provider.client_version().await.unwrap(); assert_eq!(CLIENT_VERSION, version); @@ -68,7 +71,7 @@ async fn can_get_client_version() { #[tokio::test(flavor = "multi_thread")] async fn can_get_chain_id() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let chain_id = provider.get_chainid().await.unwrap(); assert_eq!(chain_id, CHAIN_ID.into()); @@ -77,7 +80,7 @@ async fn can_get_chain_id() { #[tokio::test(flavor = "multi_thread")] async fn can_modify_chain_id() { let (_api, handle) = spawn(NodeConfig::test().with_chain_id(Some(Chain::Goerli))).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let chain_id = provider.get_chainid().await.unwrap(); assert_eq!(chain_id, Chain::Goerli.into()); @@ -97,7 +100,7 @@ async fn can_get_network_id() { #[tokio::test(flavor = "multi_thread")] async fn can_get_block_by_number() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let from = accounts[0].address(); let to = accounts[1].address(); @@ -119,7 +122,7 @@ async fn can_get_block_by_number() { #[tokio::test(flavor = "multi_thread")] async fn can_get_pending_block() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let accounts: Vec<_> = handle.dev_wallets().collect(); let block = provider.get_block(BlockNumber::Pending).await.unwrap().unwrap(); @@ -153,7 +156,7 @@ async fn can_get_pending_block() { #[tokio::test(flavor = "multi_thread")] async fn can_call_on_pending_block() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let num = provider.get_block_number().await.unwrap(); assert_eq!(num.as_u64(), 0u64); @@ -182,36 +185,37 @@ async fn can_call_on_pending_block() { let accounts: Vec
= handle.dev_wallets().map(|w| w.address()).collect(); for i in 1..10 { - api.anvil_set_coinbase(accounts[i % accounts.len()]).await.unwrap(); - api.evm_set_block_gas_limit((30_000_000 + i).into()).unwrap(); + api.anvil_set_coinbase(accounts[i % accounts.len()].to_alloy()).await.unwrap(); + api.evm_set_block_gas_limit(rU256::from((30_000_000 + i))).unwrap(); - api.anvil_mine(Some(1.into()), None).await.unwrap(); + api.anvil_mine(Some(rU256::from(1)), None).await.unwrap(); tokio::time::sleep(Duration::from_secs(1)).await; } // Ensure that the right header values are set when calling a past block - for block_number in 1..(api.block_number().unwrap().as_usize() + 1) { - let block_number = BlockNumber::Number(block_number.into()); - let block = api.block_by_number(block_number).await.unwrap().unwrap(); + for block_number in 1..(api.block_number().unwrap().to::() + 1) { + let block_number_alloy = alloy_rpc_types::BlockNumberOrTag::Number(block_number as u64); + let block_number_ethers = BlockNumber::Number((block_number as u64).into()); + let block = api.block_by_number(block_number_alloy).await.unwrap().unwrap(); let block_timestamp = pending_contract .get_current_block_timestamp() - .block(block_number) + .block(block_number_ethers) .call() .await .unwrap(); - assert_eq!(block.timestamp, block_timestamp); + assert_eq!(block.header.timestamp, block_timestamp.to_alloy()); let block_gas_limit = pending_contract .get_current_block_gas_limit() - .block(block_number) + .block(block_number_ethers) .call() .await .unwrap(); - assert_eq!(block.gas_limit, block_gas_limit); + assert_eq!(block.header.gas_limit, block_gas_limit.to_alloy()); let block_coinbase = - pending_contract.get_current_block_coinbase().block(block_number).call().await.unwrap(); - assert_eq!(block.author.unwrap(), block_coinbase); + pending_contract.get_current_block_coinbase().block(block_number_ethers).call().await.unwrap(); + assert_eq!(block.header.miner, block_coinbase.to_alloy()); } } @@ -226,13 +230,13 @@ where { let result = api .call( - EthTransactionRequest { - data: call.tx.data().cloned(), - to: Some(to), + CallRequest { + input: CallInput::maybe_input(call.tx.data().cloned().map(|b| b.0.into())), + to: Some(to.to_alloy()), ..Default::default() }, None, - Some(overrides), + Some(to_alloy_state_override(overrides)), ) .await .unwrap(); @@ -242,7 +246,7 @@ where #[tokio::test(flavor = "multi_thread")] async fn can_call_with_state_override() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); api.anvil_set_auto_mine(true).await.unwrap(); diff --git a/crates/anvil/tests/it/main.rs b/crates/anvil/tests/it/main.rs index d454bf82ad43..368ae9eed8df 100644 --- a/crates/anvil/tests/it/main.rs +++ b/crates/anvil/tests/it/main.rs @@ -1,19 +1,19 @@ mod abi; mod anvil; // mod anvil_api; -// mod api; +mod api; // mod fork; -// mod ganache; +mod ganache; mod gas; mod genesis; mod geth; // mod ipc; mod logs; -// mod proof; +mod proof; // mod pubsub; -// // mod revert; // TODO uncomment +// mod revert; // TODO uncomment mod otterscan; -// mod sign; +mod sign; // mod traces; mod transaction; mod txpool; diff --git a/crates/anvil/tests/it/proof/mod.rs b/crates/anvil/tests/it/proof/mod.rs index 4b6f25569c97..6d9386750323 100644 --- a/crates/anvil/tests/it/proof/mod.rs +++ b/crates/anvil/tests/it/proof/mod.rs @@ -1,6 +1,7 @@ //! tests for `eth_getProof` use crate::proof::eip1186::verify_proof; +use alloy_rpc_types::EIP1186AccountProofResponse; use anvil::{spawn, NodeConfig}; use anvil_core::eth::{ proof::{AccountProof, BasicAccount}, @@ -12,7 +13,7 @@ use ethers::{ utils::{keccak256, rlp}, }; use foundry_evm::revm::primitives::KECCAK_EMPTY; -use foundry_utils::types::ToEthers; +use foundry_utils::types::{ToEthers, ToAlloy}; mod eip1186; @@ -25,20 +26,20 @@ async fn can_get_proof() { let key = U256::zero(); let value = U256::one(); - api.anvil_set_storage_at(acc, key, H256::from_uint(&value)).await.unwrap(); + api.anvil_set_storage_at(acc.to_alloy(), key.to_alloy(), H256::from_uint(&value).to_alloy()).await.unwrap(); - let proof: AccountProof = api.get_proof(acc, vec![H256::from_uint(&key)], None).await.unwrap(); + let proof: EIP1186AccountProofResponse = api.get_proof(acc.to_alloy(), vec![H256::from_uint(&key).to_alloy()], None).await.unwrap(); let account = BasicAccount { nonce: 0.into(), balance: 0.into(), - storage_root: proof.storage_hash, + storage_root: proof.storage_hash.to_ethers(), code_hash: KECCAK_EMPTY.to_ethers(), }; let rlp_account = rlp::encode(&account); - let root: H256 = api.state_root().await.unwrap(); + let root: H256 = api.state_root().await.unwrap().to_ethers(); let acc_proof: Vec> = proof .account_proof .into_iter() @@ -58,7 +59,7 @@ async fn can_get_proof() { let proof = proof.storage_proof[0].clone(); let storage_proof: Vec> = proof.proof.into_iter().map(|node| rlp::decode::>(&node).unwrap()).collect(); - let key = H256::from(keccak256(proof.key.as_bytes())); + let key = H256::from(keccak256(proof.key.0.0)); verify_proof::( &account.storage_root.0, &storage_proof, @@ -74,7 +75,7 @@ async fn can_get_random_account_proofs() { for acc in std::iter::repeat_with(Address::random).take(10) { let _ = api - .get_proof(acc, Vec::new(), None) + .get_proof(acc.to_alloy(), Vec::new(), None) .await .unwrap_or_else(|_| panic!("Failed to get proof for {acc:?}")); } diff --git a/crates/anvil/tests/it/sign.rs b/crates/anvil/tests/it/sign.rs index 368a34da1763..c802c0ff6e67 100644 --- a/crates/anvil/tests/it/sign.rs +++ b/crates/anvil/tests/it/sign.rs @@ -283,7 +283,7 @@ async fn can_sign_typed_data_os() { #[tokio::test(flavor = "multi_thread")] async fn rejects_different_chain_id() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = SignerMiddleware::new(provider, wallet.with_chain_id(Chain::Mainnet)); @@ -299,7 +299,7 @@ async fn rejects_different_chain_id() { async fn rejects_invalid_chain_id() { let (_api, handle) = spawn(NodeConfig::test()).await; let wallet = handle.dev_wallets().next().unwrap().with_chain_id(99u64); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let client = SignerMiddleware::new(provider, wallet); let tx = TransactionRequest::new().to(Address::random()).value(100u64); let res = client.send_transaction(tx, None).await; From 3b56936bb787b07cb323abad6a8c2c5b3356e076 Mon Sep 17 00:00:00 2001 From: Enrique Ortiz Date: Tue, 21 Nov 2023 13:17:14 -0400 Subject: [PATCH 7/9] almost done lesgo --- crates/anvil/tests/it/anvil_api.rs | 38 +++++++++++++++--------------- crates/anvil/tests/it/main.rs | 2 +- crates/anvil/tests/it/wsapi.rs | 9 +++---- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/crates/anvil/tests/it/anvil_api.rs b/crates/anvil/tests/it/anvil_api.rs index 272f6b2824c7..6e339727c946 100644 --- a/crates/anvil/tests/it/anvil_api.rs +++ b/crates/anvil/tests/it/anvil_api.rs @@ -24,7 +24,7 @@ use std::{ #[tokio::test(flavor = "multi_thread")] async fn can_set_gas_price() { let (api, handle) = spawn(NodeConfig::test().with_hardfork(Some(Hardfork::Berlin))).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let gas_price = 1337u64.into(); api.anvil_set_min_gas_price(gas_price).await.unwrap(); @@ -64,7 +64,7 @@ async fn can_set_storage() { #[tokio::test(flavor = "multi_thread")] async fn can_impersonate_account() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let impersonate = Address::random(); let to = Address::random(); @@ -101,7 +101,7 @@ async fn can_impersonate_account() { #[tokio::test(flavor = "multi_thread")] async fn can_auto_impersonate_account() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let impersonate = Address::random(); let to = Address::random(); @@ -141,7 +141,7 @@ async fn can_auto_impersonate_account() { #[tokio::test(flavor = "multi_thread")] async fn can_impersonate_contract() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let provider = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -153,7 +153,7 @@ async fn can_impersonate_contract() { let to = Address::random(); let val = 1337u64; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); // fund the impersonated account api.anvil_set_balance(impersonate, U256::from(1e18 as u64)).await.unwrap(); @@ -185,7 +185,7 @@ async fn can_impersonate_contract() { #[tokio::test(flavor = "multi_thread")] async fn can_impersonate_gnosis_safe() { let (api, handle) = spawn(fork_config()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); // let safe: Address = "0xA063Cb7CFd8E57c30c788A0572CBbf2129ae56B6".parse().unwrap(); @@ -215,7 +215,7 @@ async fn can_impersonate_gnosis_safe() { #[tokio::test(flavor = "multi_thread")] async fn can_impersonate_multiple_account() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let impersonate0 = Address::random(); let impersonate1 = Address::random(); @@ -262,7 +262,7 @@ async fn can_impersonate_multiple_account() { #[tokio::test(flavor = "multi_thread")] async fn can_mine_manually() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let start_num = provider.get_block_number().await.unwrap(); @@ -276,7 +276,7 @@ async fn can_mine_manually() { #[tokio::test(flavor = "multi_thread")] async fn test_set_next_timestamp() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); @@ -303,7 +303,7 @@ async fn test_set_next_timestamp() { #[tokio::test(flavor = "multi_thread")] async fn test_evm_set_time() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); @@ -327,7 +327,7 @@ async fn test_evm_set_time() { #[tokio::test(flavor = "multi_thread")] async fn test_evm_set_time_in_past() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); @@ -347,7 +347,7 @@ async fn test_evm_set_time_in_past() { #[tokio::test(flavor = "multi_thread")] async fn test_timestamp_interval() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); api.evm_mine(None).await.unwrap(); let interval = 10; @@ -398,7 +398,7 @@ async fn test_timestamp_interval() { async fn test_can_set_storage_bsc_fork() { let (api, handle) = spawn(NodeConfig::test().with_eth_rpc_url(Some("https://bsc-dataseed.binance.org/"))).await; - let provider = Arc::new(handle.http_provider()); + let provider = Arc::new(handle.ethers_http_provider()); let busd_addr: Address = "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56".parse().unwrap(); let idx: U256 = @@ -427,7 +427,7 @@ async fn can_get_node_info() { let node_info = api.anvil_node_info().await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let block_number = provider.get_block_number().await.unwrap(); let block = provider.get_block(block_number).await.unwrap().unwrap(); @@ -460,7 +460,7 @@ async fn can_get_metadata() { let metadata = api.anvil_metadata().await.unwrap(); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let block_number = provider.get_block_number().await.unwrap(); let chain_id = provider.get_chainid().await.unwrap(); @@ -482,7 +482,7 @@ async fn can_get_metadata() { async fn can_get_metadata_on_fork() { let (api, handle) = spawn(NodeConfig::test().with_eth_rpc_url(Some("https://bsc-dataseed.binance.org/"))).await; - let provider = Arc::new(handle.http_provider()); + let provider = Arc::new(handle.ethers_http_provider()); let metadata = api.anvil_metadata().await.unwrap(); @@ -525,7 +525,7 @@ async fn metadata_changes_on_reset() { #[tokio::test(flavor = "multi_thread")] async fn test_get_transaction_receipt() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); // set the base fee let new_base_fee = U256::from(1_000); @@ -556,7 +556,7 @@ async fn test_get_transaction_receipt() { #[tokio::test(flavor = "multi_thread")] async fn test_set_chain_id() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let chain_id = provider.get_chainid().await.unwrap(); assert_eq!(chain_id, U256::from(31337)); @@ -592,7 +592,7 @@ async fn test_fork_revert_next_block_timestamp() { #[tokio::test(flavor = "multi_thread")] async fn test_fork_revert_call_latest_block_timestamp() { let (api, handle) = spawn(fork_config()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); // Mine a new block, and check the new block gas limit api.mine_one().await; diff --git a/crates/anvil/tests/it/main.rs b/crates/anvil/tests/it/main.rs index 368ae9eed8df..73c58d96f8ff 100644 --- a/crates/anvil/tests/it/main.rs +++ b/crates/anvil/tests/it/main.rs @@ -18,7 +18,7 @@ mod sign; mod transaction; mod txpool; pub mod utils; -// mod wsapi; +mod wsapi; #[allow(unused)] pub(crate) fn init_tracing() { diff --git a/crates/anvil/tests/it/wsapi.rs b/crates/anvil/tests/it/wsapi.rs index f185c6b8ee24..349cdb48f569 100644 --- a/crates/anvil/tests/it/wsapi.rs +++ b/crates/anvil/tests/it/wsapi.rs @@ -2,23 +2,24 @@ use anvil::{spawn, NodeConfig}; use ethers::{prelude::Middleware, types::U256}; +use foundry_utils::types::ToAlloy; #[tokio::test(flavor = "multi_thread")] async fn can_get_block_number_ws() { let (api, handle) = spawn(NodeConfig::test()).await; let block_num = api.block_number().unwrap(); - assert_eq!(block_num, U256::zero()); + assert_eq!(block_num, U256::zero().to_alloy()); - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let num = provider.get_block_number().await.unwrap(); - assert_eq!(num, block_num.as_u64().into()); + assert_eq!(num, block_num.to::().into()); } #[tokio::test(flavor = "multi_thread")] async fn can_dev_get_balance_ws() { let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let genesis_balance = handle.genesis_balance(); for acc in handle.genesis_accounts() { From c29921fbfec1c787f98e50ee5905844fd62c697f Mon Sep 17 00:00:00 2001 From: Enrique Ortiz Date: Tue, 21 Nov 2023 17:01:30 -0400 Subject: [PATCH 8/9] pub sob --- crates/anvil/tests/it/main.rs | 2 +- crates/anvil/tests/it/pubsub.rs | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/crates/anvil/tests/it/main.rs b/crates/anvil/tests/it/main.rs index 73c58d96f8ff..1eaa1c3601f7 100644 --- a/crates/anvil/tests/it/main.rs +++ b/crates/anvil/tests/it/main.rs @@ -10,7 +10,7 @@ mod geth; // mod ipc; mod logs; mod proof; -// mod pubsub; +mod pubsub; // mod revert; // TODO uncomment mod otterscan; mod sign; diff --git a/crates/anvil/tests/it/pubsub.rs b/crates/anvil/tests/it/pubsub.rs index 22df53c96825..e52ba490a4f1 100644 --- a/crates/anvil/tests/it/pubsub.rs +++ b/crates/anvil/tests/it/pubsub.rs @@ -9,6 +9,7 @@ use ethers::{ signers::Signer, types::{Address, Block, Filter, TransactionRequest, TxHash, ValueOrArray, U256}, }; +use foundry_utils::types::ToAlloy; use futures::StreamExt; use std::sync::Arc; @@ -16,7 +17,7 @@ use std::sync::Arc; async fn test_sub_new_heads() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let blocks = provider.subscribe_blocks().await.unwrap(); @@ -34,7 +35,7 @@ async fn test_sub_logs_legacy() { abigen!(EmitLogs, "test-data/emit_logs.json"); let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -73,7 +74,7 @@ async fn test_sub_logs() { abigen!(EmitLogs, "test-data/emit_logs.json"); let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -111,13 +112,13 @@ async fn test_sub_logs_impersonated() { abigen!(EmitLogs, "test-data/emit_logs.json"); let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); // impersonate account let impersonate = Address::random(); let funding = U256::from(1e18 as u64); - api.anvil_set_balance(impersonate, funding).await.unwrap(); - api.anvil_impersonate_account(impersonate).await.unwrap(); + api.anvil_set_balance(impersonate.to_alloy(), funding.to_alloy()).await.unwrap(); + api.anvil_impersonate_account(impersonate.to_alloy()).await.unwrap(); let wallet = handle.dev_wallets().next().unwrap(); let client = Arc::new(SignerMiddleware::new(provider, wallet)); @@ -137,7 +138,7 @@ async fn test_sub_logs_impersonated() { let tx = TransactionRequest::new().from(impersonate).to(contract.address()).data(data); - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let receipt = provider.send_transaction(tx, None).await.unwrap().await.unwrap().unwrap(); @@ -152,7 +153,7 @@ async fn test_filters_legacy() { abigen!(EmitLogs, "test-data/emit_logs.json"); let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let from = wallet.address(); @@ -193,7 +194,7 @@ async fn test_filters() { abigen!(EmitLogs, "test-data/emit_logs.json"); let (_api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.http_provider(); + let provider = handle.ethers_http_provider(); let wallet = handle.dev_wallets().next().unwrap(); let from = wallet.address(); @@ -253,7 +254,7 @@ async fn test_subscriptions() { async fn test_sub_new_heads_fast() { let (api, handle) = spawn(NodeConfig::test()).await; - let provider = handle.ws_provider(); + let provider = handle.ethers_ws_provider(); let blocks = provider.subscribe_blocks().await.unwrap(); From 69a385973005d79172abce02f232ea25a5776f74 Mon Sep 17 00:00:00 2001 From: Enrique Ortiz Date: Tue, 21 Nov 2023 18:13:02 -0400 Subject: [PATCH 9/9] chre: fix otterscan test --- crates/anvil/src/eth/otterscan/types.rs | 13 ++++++++++--- crates/anvil/tests/it/otterscan.rs | 6 +----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/anvil/src/eth/otterscan/types.rs b/crates/anvil/src/eth/otterscan/types.rs index 643bcc33e70c..f273ddcb5ab4 100644 --- a/crates/anvil/src/eth/otterscan/types.rs +++ b/crates/anvil/src/eth/otterscan/types.rs @@ -172,7 +172,7 @@ impl From for OtsBlock { impl OtsBlockTransactions { /// Fetches all receipts for the blocks's transactions, as required by the [`ots_getBlockTransactions`](https://github.com/otterscan/otterscan/blob/develop/docs/custom-jsonrpc.md#ots_getblockdetails) endpoint spec, and returns the final response object. pub async fn build( - block: Block, + mut block: Block, backend: &Backend, page: usize, page_size: usize, @@ -182,10 +182,17 @@ impl OtsBlockTransactions { BlockTransactions::Hashes(txs) => txs, BlockTransactions::Uncle => return Err(BlockchainError::DataUnavailable), }; - let block_txs = block_txs.iter().skip(page * page_size).take(page_size).collect::>(); + + let block_txs = block_txs.into_iter().skip(page * page_size).take(page_size).collect::>(); + + block.transactions = match block.transactions { + BlockTransactions::Full(txs) => BlockTransactions::Full(txs.into_iter().skip(page * page_size).take(page_size).collect()), + BlockTransactions::Hashes(txs) => BlockTransactions::Hashes(txs.into_iter().skip(page * page_size).take(page_size).collect()), + BlockTransactions::Uncle => return Err(BlockchainError::DataUnavailable), + }; let receipt_futs = - block_txs.iter().map(|tx| async { backend.transaction_receipt(*tx.clone()).await }); + block_txs.iter().map(|tx| async { backend.transaction_receipt(tx.clone()).await }); let receipts: Vec = join_all(receipt_futs) .await diff --git a/crates/anvil/tests/it/otterscan.rs b/crates/anvil/tests/it/otterscan.rs index 1ce062617ca4..1b68869aa9b8 100644 --- a/crates/anvil/tests/it/otterscan.rs +++ b/crates/anvil/tests/it/otterscan.rs @@ -464,11 +464,7 @@ async fn can_call_ots_get_block_transactions() { let result = api.ots_get_block_transactions(1, page, page_size).await.unwrap(); assert!(result.receipts.len() <= page_size); - let len = match result.fullblock.block.transactions { - BlockTransactions::Full(ref txs) => txs.len(), - BlockTransactions::Hashes(ref hashes) => hashes.len(), - BlockTransactions::Uncle => 0 - }; + let len = result.receipts.len(); assert!(len <= page_size); assert!(result.fullblock.transaction_count == result.receipts.len());