Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anvil tests alloy migration #7619

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
635 changes: 407 additions & 228 deletions Cargo.lock

Large diffs are not rendered by default.

51 changes: 27 additions & 24 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ foundry-compilers = { version = "0.3.14", default-features = false }
# no default features to avoid c-kzg
revm = { version = "8", default-features = false }
revm-primitives = { version = "3", default-features = false }
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "21f8f3d", features = [
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "735f67c", features = [
"serde",
] }
] }

## ethers
ethers = { version = "2.0.14", default-features = false }
Expand All @@ -158,27 +158,27 @@ ethers-signers = { version = "2.0.14", default-features = false }
ethers-middleware = { version = "2.0.14", default-features = false }

## alloy
alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-signer-wallet = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-signer-aws = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-signer-ledger = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-signer-trezor = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "987b393", default-features = false }
alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-signer-wallet = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-signer-aws = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-signer-ledger = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-signer-trezor = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "188c4f8", default-features = false }
alloy-primitives = { version = "0.7.0", features = ["getrandom"] }
alloy-dyn-abi = "0.7.0"
alloy-json-abi = "0.7.0"
Expand All @@ -192,7 +192,10 @@ solang-parser = "=0.3.3"
## misc
arrayvec = "0.7"
base64 = "0.22"
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
chrono = { version = "0.4", default-features = false, features = [
"clock",
"std",
] }
color-eyre = "0.6"
derive_more = "0.99"
evm-disassembler = "0.5"
Expand Down
8 changes: 7 additions & 1 deletion crates/anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ k256.workspace = true
ethers = { workspace = true, features = ["rustls", "ws", "ipc", "optimism"] }
alloy-primitives = { workspace = true, features = ["serde"] }
alloy-consensus = { workspace = true, features = ["k256", "kzg"] }
alloy-contract = { workspace = true }
alloy-network.workspace = true
alloy-eips.workspace = true
alloy-rlp.workspace = true
Expand All @@ -47,7 +48,12 @@ alloy-sol-types = { workspace = true, features = ["std"] }
alloy-dyn-abi = { workspace = true, features = ["std", "eip712"] }
alloy-rpc-types.workspace = true
alloy-rpc-types-trace.workspace = true
alloy-provider = { workspace = true, features = ["pubsub"] }
alloy-provider = { workspace = true, features = [
"pubsub",
"ws",
"ipc",
"reqwest",
] }
alloy-transport.workspace = true
alloy-chains.workspace = true
alloy-genesis.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions crates/anvil/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2013,9 +2013,9 @@ impl EthApi {
fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
let tx = &tx.pending_transaction.transaction;
let to = tx.to();
let gas_price = U256::from(tx.gas_price());
let gas_price = tx.gas_price();
let value = tx.value();
let gas = U256::from(tx.gas_limit());
let gas = tx.gas_limit();
TxpoolInspectSummary { to, value, gas, gas_price }
}

Expand Down
19 changes: 11 additions & 8 deletions crates/anvil/src/eth/backend/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::eth::{backend::db::Db, error::BlockchainError};
use alloy_primitives::{Address, Bytes, StorageValue, B256, U256, U64};
use alloy_provider::Provider;
use alloy_provider::{debug::DebugApi, Provider};
use alloy_rpc_types::{
request::TransactionRequest, AccessListWithGasUsed, Block, BlockId,
BlockNumberOrTag as BlockNumber, BlockTransactions, EIP1186AccountProofResponse, FeeHistory,
Expand Down Expand Up @@ -162,7 +162,7 @@ impl ClientFork {
keys: Vec<B256>,
block_number: Option<BlockId>,
) -> Result<EIP1186AccountProofResponse, TransportError> {
self.provider().get_proof(address, keys, block_number).await
self.provider().get_proof(address, keys, block_number.unwrap_or(BlockId::latest())).await
}

/// Sends `eth_call`
Expand All @@ -172,7 +172,7 @@ impl ClientFork {
block: Option<BlockNumber>,
) -> Result<Bytes, TransportError> {
let block = block.unwrap_or(BlockNumber::Latest);
let res = self.provider().call(request, Some(block.into())).await?;
let res = self.provider().call(request, block.into()).await?;

Ok(res)
}
Expand All @@ -184,7 +184,7 @@ impl ClientFork {
block: Option<BlockNumber>,
) -> Result<u128, TransportError> {
let block = block.unwrap_or(BlockNumber::Latest);
let res = self.provider().estimate_gas(request, Some(block.into())).await?;
let res = self.provider().estimate_gas(request, block.into()).await?;

Ok(res)
}
Expand All @@ -195,7 +195,8 @@ impl ClientFork {
request: &WithOtherFields<TransactionRequest>,
block: Option<BlockNumber>,
) -> Result<AccessListWithGasUsed, TransportError> {
self.provider().create_access_list(request, block.map(|b| b.into())).await
let block = block.unwrap_or(BlockNumber::Latest);
self.provider().create_access_list(request, block.into()).await
}

pub async fn storage_at(
Expand All @@ -204,7 +205,9 @@ impl ClientFork {
index: U256,
number: Option<BlockNumber>,
) -> Result<StorageValue, TransportError> {
self.provider().get_storage_at(address, index, number.map(Into::into)).await
self.provider()
.get_storage_at(address, index, number.unwrap_or(BlockNumber::Latest).into())
.await
}

pub async fn logs(&self, filter: &Filter) -> Result<Vec<Log>, TransportError> {
Expand Down Expand Up @@ -245,12 +248,12 @@ impl ClientFork {
blocknumber: u64,
) -> Result<U256, TransportError> {
trace!(target: "backend::fork", "get_balance={:?}", address);
self.provider().get_balance(address, Some(blocknumber.into())).await
self.provider().get_balance(address, blocknumber.into()).await
}

pub async fn get_nonce(&self, address: Address, block: u64) -> Result<u64, TransportError> {
trace!(target: "backend::fork", "get_nonce={:?}", address);
self.provider().get_transaction_count(address, Some(block.into())).await
self.provider().get_transaction_count(address, block.into()).await
}

pub async fn transaction_by_block_number_and_index(
Expand Down
2 changes: 1 addition & 1 deletion crates/anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2030,7 +2030,7 @@ impl Backend {
let inner = TransactionReceipt {
inner,
transaction_hash: info.transaction_hash,
transaction_index: info.transaction_index,
transaction_index: Some(info.transaction_index),
block_number: Some(block.header.number),
gas_used: info.gas_used,
contract_address: info.contract_address,
Expand Down
4 changes: 2 additions & 2 deletions crates/anvil/src/eth/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ impl Pool {
/// Returns the number of tx that are ready and queued for further execution
pub fn txpool_status(&self) -> TxpoolStatus {
// Note: naming differs here compared to geth's `TxpoolStatus`
let pending = U64::from(self.ready_transactions().count());
let queued = U64::from(self.inner.read().pending_transactions.len());
let pending: u64 = self.ready_transactions().count().try_into().unwrap_or(0);
let queued: u64 = self.inner.read().pending_transactions.len().try_into().unwrap_or(0);
TxpoolStatus { pending, queued }
}

Expand Down
43 changes: 43 additions & 0 deletions crates/anvil/tests/it/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use ethers::{
types::Address,
};

// use alloy_contract;
use alloy_sol_types::sol;
#[derive(Clone, Debug, EthEvent)]
pub struct ValueChanged {
#[ethevent(indexed)]
Expand All @@ -15,6 +17,47 @@ pub struct ValueChanged {
pub new_value: String,
}

// TODO: Rename to Greeter before merging
sol!(
#[sol(rpc)]
AlloyGreeter,
"test-data/greeter.json"
);

sol!(
#[derive(Debug)]
#[sol(rpc)]
AlloySimpleStorage,
"test-data/SimpleStorage.json"
);

sol!(
#[sol(rpc)]
AlloyMulticallContract,
"test-data/multicall.json"
);
sol!(
#[sol(rpc)]
interface AlloyErc721 {
function balanceOf(address owner) public view virtual returns (uint256);
function ownerOf(uint256 tokenId) public view virtual returns (address);
function name() public view virtual returns (string memory);
function symbol() public view virtual returns (string memory);
function tokenURI(uint256 tokenId) public view virtual returns (string memory);
function getApproved(uint256 tokenId) public view virtual returns (address);
function setApprovalForAll(address operator, bool approved) public virtual;
function isApprovedForAll(address owner, address operator) public view virtual returns (bool);
function transferFrom(address from, address to, uint256 tokenId) public virtual;
function safeTransferFrom(address from, address to, uint256 tokenId) public;
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual;
function _mint(address to, uint256 tokenId) internal;
function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual;
function _burn(uint256 tokenId) internal;
function _transfer(address from, address to, uint256 tokenId) internal;
function _approve(address to, uint256 tokenId, address auth) internal;
}
);

abigen!(Greeter, "test-data/greeter.json");
abigen!(SimpleStorage, "test-data/SimpleStorage.json");
abigen!(MulticallContract, "test-data/multicall.json");
Expand Down
42 changes: 20 additions & 22 deletions crates/anvil/tests/it/anvil.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,56 @@
//! tests for anvil specific logic

use crate::utils::ethers_http_provider;
use crate::utils::http_provider;
use alloy_primitives::Address;
use alloy_provider::Provider;
use anvil::{spawn, NodeConfig};
use ethers::{prelude::Middleware, types::Address};
use foundry_common::types::ToAlloy;

#[tokio::test(flavor = "multi_thread")]
async fn test_can_change_mining_mode() {
let (api, handle) = spawn(NodeConfig::test()).await;
let provider = ethers_http_provider(&handle.http_endpoint());
let provider = http_provider(&handle.http_endpoint());

assert!(api.anvil_get_auto_mine().unwrap());

let num = provider.get_block_number().await.unwrap();
assert_eq!(num.as_u64(), 0);
assert_eq!(num, 0);

api.anvil_set_interval_mining(1).unwrap();
assert!(!api.anvil_get_auto_mine().unwrap());
// changing the mining mode will instantly mine a new block
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
let num = provider.get_block_number().await.unwrap();
assert_eq!(num.as_u64(), 0);
assert_eq!(num, 0);

tokio::time::sleep(std::time::Duration::from_millis(700)).await;
let num = provider.get_block_number().await.unwrap();
assert_eq!(num.as_u64(), 1);
assert_eq!(num, 1);

// assert that no block is mined when the interval is set to 0
api.anvil_set_interval_mining(0).unwrap();
assert!(!api.anvil_get_auto_mine().unwrap());
tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
let num = provider.get_block_number().await.unwrap();
assert_eq!(num.as_u64(), 1);
assert_eq!(num, 1);
}

#[tokio::test(flavor = "multi_thread")]
async fn can_get_default_dev_keys() {
let (_api, handle) = spawn(NodeConfig::test()).await;
let provider = ethers_http_provider(&handle.http_endpoint());
let provider = http_provider(&handle.http_endpoint());

let dev_accounts = handle.dev_accounts().collect::<Vec<_>>();
let accounts = provider
.get_accounts()
.await
.unwrap()
.into_iter()
.map(ToAlloy::to_alloy)
.collect::<Vec<_>>();
let accounts = provider.get_accounts().await.unwrap();

assert_eq!(dev_accounts, accounts);
}

#[tokio::test(flavor = "multi_thread")]
async fn can_set_empty_code() {
let (api, _handle) = spawn(NodeConfig::test()).await;
let addr = Address::random();
api.anvil_set_code(addr.to_alloy(), Vec::new().into()).await.unwrap();
let code = api.get_code(addr.to_alloy(), None).await.unwrap();
api.anvil_set_code(addr, Vec::new().into()).await.unwrap();
let code = api.get_code(addr, None).await.unwrap();
assert!(code.as_ref().is_empty());
}

Expand All @@ -64,15 +59,18 @@ 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 = ethers_http_provider(&handle.http_endpoint());
let provider = http_provider(&handle.http_endpoint());

assert_eq!(genesis_timestamp, provider.get_block(0).await.unwrap().unwrap().timestamp.as_u64());
assert_eq!(
genesis_timestamp,
provider.get_block(0.into(), false).await.unwrap().unwrap().header.timestamp
);
}

#[tokio::test(flavor = "multi_thread")]
async fn test_can_use_default_genesis_timestamp() {
let (_api, handle) = spawn(NodeConfig::test()).await;
let provider = ethers_http_provider(&handle.http_endpoint());
let provider = http_provider(&handle.http_endpoint());

assert_ne!(0u64, provider.get_block(0).await.unwrap().unwrap().timestamp.as_u64());
assert_ne!(0u64, provider.get_block(0.into(), false).await.unwrap().unwrap().header.timestamp);
}
4 changes: 2 additions & 2 deletions crates/anvil/tests/it/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use alloy_provider::Provider;
use alloy_rpc_types::{
request::{TransactionInput as CallInput, TransactionRequest as CallRequest},
state::{AccountOverride, StateOverride},
WithOtherFields,
BlockId, WithOtherFields,
};
use anvil::{
eth::{api::CLIENT_VERSION, EthApi},
Expand Down Expand Up @@ -45,7 +45,7 @@ async fn can_dev_get_balance() {

let genesis_balance = handle.genesis_balance();
for acc in handle.genesis_accounts() {
let balance = provider.get_balance(acc, None).await.unwrap();
let balance = provider.get_balance(acc, BlockId::latest()).await.unwrap();
assert_eq!(balance, genesis_balance);
}
}
Expand Down
Loading