Skip to content

Commit

Permalink
[wip] feat: provider alloy migration (#7106)
Browse files Browse the repository at this point in the history
* chore: make cast use an alloy provider

* move initial methods to alloy

* feat(`foundry-common`): NameOrAddress ENS util (#7122)

* feat(foundry-common): NameOrAddress ENS util

* chore: rename err

* chore: remove from impl for str

* chore: unrelated fix from alloy upgrade

* nit

* feat(`cast`): Move non `tx` methods to alloy (#7129)

* chore: add alloy contract

* feat(cast): migrate most methods to alloy

* chore: leave todo for converting a tx envelope into an rpc tx

* fix: use proper type for storage

* readd decodetx for now

* chore: extend txbuilder to build an alloy tx request

* feat: migrate most methods bar send/decode raw tx

* fix: include tx data

* simplify txbuilder

* chore: simplify back access_list

* chore: remove unnecesary conversion

* fmt

* doctests

* fmt

* do not use trait

* Update crates/cast/bin/main.rs

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>

* cleanup builder

* clippy

* fix doc comments

---------

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>

* DocumentMut

* wip

* wip

* wip: bump alloy

* wip

* wip

* wip

* [wip] migrate to alloy providers and signers (#7425)

wip

* fix wallets after alloy bump

* clean up deps

* use serde on consensus types

* update TypedTransaction for anvil

* make anvil compile

* wip: make script compile

* fix script

* make forge compile

* fix: anvil tests

* bump alloy

* fix tests

* fix tx builder

* fix cargo.toml

* fix cargo.toml

* fix script gas price logic

* remove ethers from anvil

* clippy

* rm all_derives

* deps

* fmt

* fix tests

* configure clippy

* clippy

* add feature

* fix cargo deny

* fix persist

* fix doctests

* fmt

* fix clap

* review fixes

* fmt

* bump alloy

* Update cargo.toml

* fmt

* fixes

* ethers clean-up

* fix(fmt): fix indent closing parenthesis enclosed in { } (#7557)

* fix(fmt): fix indent closing parenthesis enclosed in { }

* Fix testdata bad formatting

* feat(test): only compile files needed for tests (#7334)

* feat(forge test): only compile files needed for tests

* remove comment

* clippy

* update fixtures

* getCode + getDeployedCode updates

* fixes

* fix path matching

* clippy

* add config flag

* fix

* docs

* fmt

* patch compilers

* fix Cargo.toml

* update patch

* update patch

* doc

* rm space

* cargo cheats

* new output selection fn

* log compiler errors on failure

* fixes

* fix: do not flood dictionary with data dependent on fuzz inputs (#7552)

* fix dictionary

* clippy + fmt

* fix

* Feat: Index cheatcode for Strings (#7539)

* feat: index cheatcode

* some nits to make it work

* nit: use as_str()

* final changes

* chore: reviewed changes

* chore: reduce logs in tests (#7566)

* fix(script): decode custom error in script fail message (#7563)

* clippy

* bump alloy

* AnyNetwork

* bump alloy

* add comment

* clippy

* bump alloy

* fixes

* refactor cast logs to use alloy (#7594)

* refactor cast logs to use alloy

* fmt

* make clippy happy

* cleanup

* doc nits

---------

Co-authored-by: evalir <hi@enriqueortiz.dev>

---------

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com>
Co-authored-by: Krishang <93703995+kamuik16@users.noreply.github.com>
Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
Co-authored-by: bernard-wagner <bernard-wagner@users.noreply.github.com>
  • Loading branch information
7 people authored Apr 9, 2024
1 parent a6d6a3a commit f840dbd
Show file tree
Hide file tree
Showing 118 changed files with 3,842 additions and 4,081 deletions.
1,108 changes: 721 additions & 387 deletions Cargo.lock

Large diffs are not rendered by default.

65 changes: 33 additions & 32 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ codegen-units = 1
[profile.release.package]
mdbook.opt-level = 1
protobuf.opt-level = 1
rusoto_core.opt-level = 1
rusoto_credential.opt-level = 1
rusoto_kms.opt-level = 1
toml_edit.opt-level = 1
trezor-client.opt-level = 1

Expand Down Expand Up @@ -140,16 +137,16 @@ foundry-wallets = { path = "crates/wallets" }
foundry-linking = { path = "crates/linking" }

# solc & compilation utilities
foundry-block-explorers = { version = "0.2.4", default-features = false }
foundry-compilers = { version = "0.3.13", default-features = false }
foundry-block-explorers = { version = "0.2.5", default-features = false }
foundry-compilers = { version = "0.3.14", default-features = false }

## revm
# no default features to avoid c-kzg
revm = { version = "7.1", default-features = false, features = ["std"] }
revm-primitives = { version = "3", default-features = false, features = ["std"] }
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "ba0b6ab", features = [
revm = { version = "8", default-features = false }
revm-primitives = { version = "3", default-features = false }
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "510d4d0", features = [
"serde",
] }
] }

## ethers
ethers = { version = "2.0.14", default-features = false }
Expand All @@ -161,30 +158,34 @@ 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 = "9ac2c90", default-features = false }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-providers = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "9ac2c90", default-features = false }
alloy-primitives = { version = "0.6.3", features = ["getrandom"] }
alloy-dyn-abi = "0.6.3"
alloy-json-abi = "0.6.3"
alloy-sol-types = "0.6.3"
syn-solidity = "0.6.3"
alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-signer-wallet = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-signer-aws = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-signer-ledger = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-signer-trezor = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "5f74d4e", default-features = false }
alloy-primitives = { version = "0.7.0", features = ["getrandom"] }
alloy-dyn-abi = "0.7.0"
alloy-json-abi = "0.7.0"
alloy-sol-types = "0.7.0"
syn-solidity = "0.7.0"
alloy-chains = "0.1"
alloy-trie = "0.3"

alloy-trie = "0.3.1"
alloy-rlp = "0.3.3"
solang-parser = "=0.3.3"

Expand Down
3 changes: 3 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
msrv = "1.76"
# bytes::Bytes is included by default and alloy_primitives::Bytes is a wrapper around it,
# so it is safe to ignore it as well
ignore-interior-mutability = ["bytes::Bytes", "alloy_primitives::Bytes"]
21 changes: 15 additions & 6 deletions crates/anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ path = "src/anvil.rs"
required-features = ["cli"]

[build-dependencies]
vergen = { workspace = true, default-features = false, features = ["build", "git", "gitcl"] }
vergen = { workspace = true, default-features = false, features = [
"build",
"git",
"gitcl",
] }

[dependencies]
# foundry internal
Expand All @@ -36,12 +40,13 @@ alloy-primitives = { workspace = true, features = ["serde"] }
alloy-consensus = { workspace = true, features = ["k256", "kzg"] }
alloy-network.workspace = true
alloy-rlp.workspace = true
alloy-signer = { workspace = true, features = ["eip712", "mnemonic"] }
alloy-signer = { workspace = true, features = ["eip712"] }
alloy-signer-wallet = { workspace = true, features = ["mnemonic"] }
alloy-sol-types = { workspace = true, features = ["std"] }
alloy-dyn-abi = { workspace = true, features = ["std", "eip712"] }
alloy-rpc-types.workspace = true
alloy-rpc-trace-types.workspace = true
alloy-providers.workspace = true
alloy-rpc-types-trace.workspace = true
alloy-provider = { workspace = true, features = ["pubsub"] }
alloy-transport.workspace = true
alloy-chains.workspace = true
alloy-genesis.workspace = true
Expand Down Expand Up @@ -75,7 +80,11 @@ rand = "0.8"
eyre.workspace = true

# cli
clap = { version = "4", features = ["derive", "env", "wrap_help"], optional = true }
clap = { version = "4", features = [
"derive",
"env",
"wrap_help",
], optional = true }
clap_complete = { version = "4", optional = true }
chrono.workspace = true
auto_impl = "1"
Expand All @@ -89,7 +98,7 @@ tikv-jemallocator = { workspace = true, optional = true }

[dev-dependencies]
alloy-json-abi.workspace = true
ethers = { workspace = true, features = ["abigen"] }
ethers = { workspace = true, features = ["abigen", "optimism"] }
ethers-core = { workspace = true, features = ["optimism"] }
foundry-compilers = { workspace = true, features = ["project-util", "full"] }

Expand Down
10 changes: 7 additions & 3 deletions crates/anvil/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ repository.workspace = true
[dependencies]
foundry-common.workspace = true
foundry-evm.workspace = true
revm = { workspace = true, default-features = false, features = ["std", "serde", "memory_limit"] }
revm = { workspace = true, default-features = false, features = [
"std",
"serde",
"memory_limit",
] }

alloy-primitives = { workspace = true, features = ["serde"] }
alloy-rpc-types = { workspace = true }
alloy-rpc-trace-types.workspace = true
alloy-rpc-types-trace.workspace = true
alloy-rlp.workspace = true
alloy-eips.workspace = true
alloy-network = { workspace = true, features = ["k256"] }
Expand All @@ -27,7 +31,7 @@ alloy-trie.workspace = true
serde = { workspace = true, optional = true }
serde_json.workspace = true
bytes = "1.4"
c-kzg = { version = "0.4.2", features = ["serde"] }
c-kzg = { version = "1", features = ["serde"] }

# misc
rand = "0.8"
Expand Down
37 changes: 18 additions & 19 deletions crates/anvil/core/src/eth/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{
trie,
};
use alloy_consensus::Header;
use alloy_primitives::{Address, Bloom, Bytes, B256, U256};
use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256};
use alloy_rlp::{RlpDecodable, RlpEncodable};

// Type alias to optionally support impersonated transactions
Expand Down Expand Up @@ -88,13 +88,13 @@ pub struct PartialHeader {
pub logs_bloom: Bloom,
pub difficulty: U256,
pub number: u64,
pub gas_limit: u64,
pub gas_used: u64,
pub gas_limit: u128,
pub gas_used: u128,
pub timestamp: u64,
pub extra_data: Bytes,
pub mix_hash: B256,
pub nonce: u64,
pub base_fee: Option<u64>,
pub nonce: B64,
pub base_fee: Option<u128>,
}

impl From<Header> for PartialHeader {
Expand All @@ -120,7 +120,6 @@ impl From<Header> for PartialHeader {

#[cfg(test)]
mod tests {
use alloy_network::Sealable;
use alloy_primitives::{
b256,
hex::{self, FromHex},
Expand All @@ -143,11 +142,11 @@ mod tests {
difficulty: Default::default(),
number: 124u64,
gas_limit: Default::default(),
gas_used: 1337u64,
gas_used: 1337u128,
timestamp: 0,
extra_data: Default::default(),
mix_hash: Default::default(),
nonce: 99u64,
nonce: B64::with_last_byte(99),
withdrawals_root: Default::default(),
blob_gas_used: Default::default(),
excess_blob_gas: Default::default(),
Expand All @@ -159,7 +158,7 @@ mod tests {
let decoded: Header = Header::decode(&mut encoded.as_ref()).unwrap();
assert_eq!(header, decoded);

header.base_fee_per_gas = Some(12345u64);
header.base_fee_per_gas = Some(12345u128);

let encoded = alloy_rlp::encode(&header);
let decoded: Header = Header::decode(&mut encoded.as_ref()).unwrap();
Expand All @@ -182,16 +181,16 @@ mod tests {
logs_bloom: Bloom::from_hex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(),
difficulty: U256::from(2222),
number: 0xd05u64,
gas_limit: 0x115cu64,
gas_used: 0x15b3u64,
gas_limit: 0x115cu128,
gas_used: 0x15b3u128,
timestamp: 0x1a0au64,
extra_data: hex::decode("7788").unwrap().into(),
mix_hash: B256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap(),
withdrawals_root: None,
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
nonce: 0,
nonce: B64::ZERO,
base_fee_per_gas: None,
};

Expand All @@ -214,12 +213,12 @@ mod tests {
logs_bloom: <[u8; 256]>::from_hex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap().into(),
difficulty: U256::from(2222),
number: 0xd05u64,
gas_limit: 0x115cu64,
gas_used: 0x15b3u64,
gas_limit: 0x115cu128,
gas_used: 0x15b3u128,
timestamp: 0x1a0au64,
extra_data: hex::decode("7788").unwrap().into(),
mix_hash: B256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap(),
nonce: 0,
nonce: B64::ZERO,
withdrawals_root: None,
blob_gas_used: None,
excess_blob_gas: None,
Expand All @@ -245,19 +244,19 @@ mod tests {
logs_bloom: Bloom::from_hex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(),
difficulty: U256::from(0x020000),
number: 1u64,
gas_limit: U256::from(0x016345785d8a0000u128).to::<u64>(),
gas_used: U256::from(0x015534).to::<u64>(),
gas_limit: U256::from(0x016345785d8a0000u128).to::<u128>(),
gas_used: U256::from(0x015534).to::<u128>(),
timestamp: 0x079e,
extra_data: hex::decode("42").unwrap().into(),
mix_hash: B256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap(),
nonce: 0,
nonce: B64::ZERO,
base_fee_per_gas: Some(875),
withdrawals_root: None,
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
};
assert_eq!(header.hash(), expected_hash);
assert_eq!(header.hash_slow(), expected_hash);
}

#[test]
Expand Down
18 changes: 9 additions & 9 deletions crates/anvil/core/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use crate::{
types::{EvmMineOptions, Forking, Index},
};
use alloy_primitives::{Address, Bytes, TxHash, B256, B64, U256};
use alloy_rpc_trace_types::geth::{GethDebugTracingOptions, GethDefaultTracingOptions};
use alloy_rpc_types::{
pubsub::{Params as SubscriptionParams, SubscriptionKind},
request::TransactionRequest,
state::StateOverride,
BlockId, BlockNumberOrTag as BlockNumber, Filter,
BlockId, BlockNumberOrTag as BlockNumber, Filter, WithOtherFields,
};
use alloy_rpc_types_trace::geth::{GethDebugTracingOptions, GethDefaultTracingOptions};

pub mod block;
pub mod proof;
Expand Down Expand Up @@ -143,7 +143,7 @@ pub enum EthRequest {
EthSign(Address, Bytes),

#[cfg_attr(feature = "serde", serde(rename = "eth_signTransaction"))]
EthSignTransaction(Box<TransactionRequest>),
EthSignTransaction(Box<WithOtherFields<TransactionRequest>>),

/// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
#[cfg_attr(feature = "serde", serde(rename = "eth_signTypedData"))]
Expand All @@ -158,27 +158,27 @@ pub enum EthRequest {
EthSignTypedDataV4(Address, alloy_dyn_abi::TypedData),

#[cfg_attr(feature = "serde", serde(rename = "eth_sendTransaction", with = "sequence"))]
EthSendTransaction(Box<TransactionRequest>),
EthSendTransaction(Box<WithOtherFields<TransactionRequest>>),

#[cfg_attr(feature = "serde", serde(rename = "eth_sendRawTransaction", with = "sequence"))]
EthSendRawTransaction(Bytes),

#[cfg_attr(feature = "serde", serde(rename = "eth_call"))]
EthCall(
TransactionRequest,
WithOtherFields<TransactionRequest>,
#[cfg_attr(feature = "serde", serde(default))] Option<BlockId>,
#[cfg_attr(feature = "serde", serde(default))] Option<StateOverride>,
),

#[cfg_attr(feature = "serde", serde(rename = "eth_createAccessList"))]
EthCreateAccessList(
TransactionRequest,
WithOtherFields<TransactionRequest>,
#[cfg_attr(feature = "serde", serde(default))] Option<BlockId>,
),

#[cfg_attr(feature = "serde", serde(rename = "eth_estimateGas"))]
EthEstimateGas(
TransactionRequest,
WithOtherFields<TransactionRequest>,
#[cfg_attr(feature = "serde", serde(default))] Option<BlockId>,
#[cfg_attr(feature = "serde", serde(default))] Option<StateOverride>,
),
Expand Down Expand Up @@ -272,7 +272,7 @@ pub enum EthRequest {
/// geth's `debug_traceCall` endpoint
#[cfg_attr(feature = "serde", serde(rename = "debug_traceCall"))]
DebugTraceCall(
TransactionRequest,
WithOtherFields<TransactionRequest>,
#[cfg_attr(feature = "serde", serde(default))] Option<BlockId>,
#[cfg_attr(feature = "serde", serde(default))] GethDefaultTracingOptions,
),
Expand Down Expand Up @@ -597,7 +597,7 @@ pub enum EthRequest {
feature = "serde",
serde(rename = "eth_sendUnsignedTransaction", with = "sequence")
)]
EthSendUnsignedTransaction(Box<TransactionRequest>),
EthSendUnsignedTransaction(Box<WithOtherFields<TransactionRequest>>),

/// Turn on call traces for transactions that are returned to the user when they execute a
/// transaction (instead of just txhash/receipt)
Expand Down
Loading

0 comments on commit f840dbd

Please sign in to comment.