From 83bb0ef4cfc7d050b8affd37fb1e565e59a7e689 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 8 Jan 2025 17:49:51 +0530 Subject: [PATCH 1/9] feat(`provider`): make recommended fillers the default --- crates/contract/src/call.rs | 11 +++-- crates/contract/src/instance.rs | 2 +- crates/provider/src/builder.rs | 66 ++++++++++++++++++-------- crates/provider/src/ext/debug.rs | 5 +- crates/provider/src/fillers/gas.rs | 8 ++-- crates/provider/src/fillers/nonce.rs | 10 +++- crates/provider/src/layers/cache.rs | 3 +- crates/provider/src/provider/trait.rs | 7 ++- crates/provider/src/provider/wallet.rs | 4 +- crates/provider/src/utils.rs | 12 +++++ 10 files changed, 85 insertions(+), 43 deletions(-) diff --git a/crates/contract/src/call.rs b/crates/contract/src/call.rs index fc33ee306c8..2b4161bd12f 100644 --- a/crates/contract/src/call.rs +++ b/crates/contract/src/call.rs @@ -570,7 +570,8 @@ mod tests { use alloy_consensus::Transaction; use alloy_primitives::{address, b256, bytes, hex, utils::parse_units, B256}; use alloy_provider::{ - layers::AnvilProvider, Provider, ProviderBuilder, RootProvider, WalletProvider, + fillers::FillProvider, layers::AnvilProvider, utils::JoinedRecommendedFillers, Provider, + ProviderBuilder, RootProvider, WalletProvider, }; use alloy_rpc_types_eth::AccessListItem; use alloy_sol_types::sol; @@ -619,10 +620,12 @@ mod tests { } } + type AnvilFillProvider = + FillProvider, Ethereum>; /// Creates a new call_builder to test field modifications, taken from [call_encoding] #[allow(clippy::type_complexity)] fn build_call_builder( - ) -> CallBuilder<(), AnvilProvider, PhantomData> { + ) -> CallBuilder<(), AnvilFillProvider, PhantomData> { let provider = ProviderBuilder::new().on_anvil(); let contract = MyContract::new(Address::ZERO, provider); let call_builder = contract.doStuff(U256::ZERO, true).with_cloned_provider(); @@ -730,7 +733,7 @@ mod tests { #[tokio::test(flavor = "multi_thread")] async fn deploy_and_call() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let expected_address = provider.default_signer_address().create(0); let my_contract = MyContract::deploy(provider, true).await.unwrap(); @@ -756,7 +759,7 @@ mod tests { #[tokio::test(flavor = "multi_thread")] async fn deploy_and_call_with_priority() { - let provider = ProviderBuilder::new().on_anvil(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let counter_contract = Counter::deploy(provider.clone()).await.unwrap(); let max_fee_per_gas: U256 = parse_units("50", "gwei").unwrap().into(); let max_priority_fee_per_gas: U256 = parse_units("0.1", "gwei").unwrap().into(); diff --git a/crates/contract/src/instance.rs b/crates/contract/src/instance.rs index 97484fedba8..814429cce2b 100644 --- a/crates/contract/src/instance.rs +++ b/crates/contract/src/instance.rs @@ -127,7 +127,7 @@ mod tests { #[tokio::test] async fn contract_interface() { - let provider = ProviderBuilder::new().on_anvil(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let abi_str = r#"[{"inputs":[],"name":"counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"increment","outputs":[],"stateMutability":"nonpayable","type":"function"}]"#; let abi = serde_json::from_str::(abi_str).unwrap(); diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 901db43be51..749a67442f1 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -112,10 +112,43 @@ pub struct ProviderBuilder { network: PhantomData N>, } -impl ProviderBuilder { - /// Create a new [`ProviderBuilder`]. - pub const fn new() -> Self { - Self { layer: Identity, filler: Identity, network: PhantomData } +// impl ProviderBuilder { +// /// Create a new [`ProviderBuilder`] with recommended fillers enabled. +// pub const fn new() -> Self { +// let p: ProviderBuilder< +// Identity, +// JoinFill< +// Identity, +// JoinFill< +// GasFiller, +// JoinFill>, >, +// >, +// > = Self { layer: Identity, filler: Identity, network: PhantomData } +// > .with_recommended_fillers(); + +// p +// } +// } + +impl + ProviderBuilder< + Identity, + JoinFill::RecommendedFillers>, + Ethereum, + > +{ + /// Create a new [`ProviderBuilder`] with the recommended filler enabled. + /// + /// Recommended fillers are preconfigured set of fillers that handle gas estimation, nonce + /// management, and chain-id fetching. + /// + /// Building a provider with this setting enabled will return a [`crate::fillers::FillProvider`] + /// with [`crate::utils::JoinedRecommendedFillers`]. + /// + /// You can opt-out of using these fillers by using the `.disable_recommended_fillers()` method. + pub fn new() -> Self { + ProviderBuilder::default().with_recommended_fillers() } } @@ -125,6 +158,13 @@ impl Default for ProviderBuilder { } } +impl ProviderBuilder { + /// Opt-out of the recommended fillers by reseting the fillers stack in the [`ProviderBuilder`]. + pub fn disable_recommended_fillers(self) -> ProviderBuilder { + ProviderBuilder { layer: self.layer, filler: Identity, network: self.network } + } +} + impl ProviderBuilder { /// Add preconfigured set of layers handling gas estimation, nonce /// management, and chain-id fetching. @@ -384,6 +424,7 @@ impl ProviderBuilder { >, { self.on_anvil_with_wallet_and_config(std::convert::identity) + .expect("failed to build provider") } /// Build this provider with anvil, using the BoxTransport. The @@ -411,23 +452,6 @@ impl ProviderBuilder { pub fn on_anvil_with_wallet_and_config( self, f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil, - ) -> as ProviderLayer>::Provider - where - F: TxFiller + ProviderLayer, - L: crate::builder::ProviderLayer< - crate::layers::AnvilProvider, - >, - { - self.try_on_anvil_with_wallet_and_config(f).unwrap() - } - - /// Build this provider with anvil, using the BoxTransport. The - /// given function is used to configure the anvil instance. This - /// function configures a wallet backed by anvil keys, and is intended for - /// use in tests. - pub fn try_on_anvil_with_wallet_and_config( - self, - f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil, ) -> AnvilProviderResult< as ProviderLayer>::Provider> where F: TxFiller + ProviderLayer, diff --git a/crates/provider/src/ext/debug.rs b/crates/provider/src/ext/debug.rs index dfeb1bc0884..137f53a8b47 100644 --- a/crates/provider/src/ext/debug.rs +++ b/crates/provider/src/ext/debug.rs @@ -413,7 +413,7 @@ mod test { #[tokio::test] async fn test_debug_trace_transaction() { async_ci_only(|| async move { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let from = provider.default_signer_address(); let gas_price = provider.get_gas_price().await.unwrap(); @@ -542,8 +542,7 @@ mod test { async_ci_only(|| async move { run_with_tempdir("reth-test-", |temp_dir| async move { let reth = Reth::new().dev().disable_discovery().data_dir(temp_dir).spawn(); - let provider = - ProviderBuilder::new().with_recommended_fillers().on_http(reth.endpoint_url()); + let provider = ProviderBuilder::new().on_http(reth.endpoint_url()); let tx1 = TransactionRequest::default() .with_from(address!("0000000000000000000000000000000000000123")) diff --git a/crates/provider/src/fillers/gas.rs b/crates/provider/src/fillers/gas.rs index ab66fb29513..7f06747618c 100644 --- a/crates/provider/src/fillers/gas.rs +++ b/crates/provider/src/fillers/gas.rs @@ -253,7 +253,7 @@ mod tests { #[tokio::test] async fn no_gas_price_or_limit() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); // GasEstimationLayer requires chain_id to be set to handle EIP-1559 tx let tx = TransactionRequest { @@ -273,7 +273,7 @@ mod tests { #[tokio::test] async fn no_gas_limit() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let gas_price = provider.get_gas_price().await.unwrap(); let tx = TransactionRequest { @@ -292,7 +292,7 @@ mod tests { #[tokio::test] async fn no_max_fee_per_blob_gas() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let sidecar: SidecarBuilder = SidecarBuilder::from_slice(b"Hello World"); let sidecar = sidecar.build().unwrap(); @@ -319,7 +319,7 @@ mod tests { #[tokio::test] async fn zero_max_fee_per_blob_gas() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let sidecar: SidecarBuilder = SidecarBuilder::from_slice(b"Hello World"); let sidecar = sidecar.build().unwrap(); diff --git a/crates/provider/src/fillers/nonce.rs b/crates/provider/src/fillers/nonce.rs index 82bd4488f00..2f44e464833 100644 --- a/crates/provider/src/fillers/nonce.rs +++ b/crates/provider/src/fillers/nonce.rs @@ -232,7 +232,10 @@ mod tests { #[tokio::test] async fn no_nonce_if_sender_unset() { - let provider = ProviderBuilder::new().with_cached_nonce_management().on_anvil(); + let provider = ProviderBuilder::new() + .disable_recommended_fillers() + .with_cached_nonce_management() + .on_anvil(); let tx = TransactionRequest { value: Some(U256::from(100)), @@ -248,7 +251,10 @@ mod tests { #[tokio::test] async fn increments_nonce() { - let provider = ProviderBuilder::new().with_cached_nonce_management().on_anvil_with_wallet(); + let provider = ProviderBuilder::new() + .disable_recommended_fillers() + .with_cached_nonce_management() + .on_anvil_with_wallet(); let from = provider.default_signer_address(); let tx = TransactionRequest { diff --git a/crates/provider/src/layers/cache.rs b/crates/provider/src/layers/cache.rs index d0813f1c4cf..6399b395c41 100644 --- a/crates/provider/src/layers/cache.rs +++ b/crates/provider/src/layers/cache.rs @@ -724,8 +724,7 @@ mod tests { run_with_tempdir("get-code", |dir| async move { let cache_layer = CacheLayer::new(100); let shared_cache = cache_layer.cache(); - let anvil = Anvil::new().spawn(); - let provider = ProviderBuilder::new().layer(cache_layer).on_http(anvil.endpoint_url()); + let provider = ProviderBuilder::new().layer(cache_layer).on_anvil_with_wallet(); let path = dir.join("rpc-cache-code.txt"); shared_cache.load_cache(path.clone()).unwrap(); diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 46b419b379a..57eba4afb17 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -1407,7 +1407,7 @@ mod tests { #[tokio::test] async fn test_send_tx() { - let provider = ProviderBuilder::new().on_anvil(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let tx = TransactionRequest { value: Some(U256::from(100)), to: Some(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()), @@ -1430,7 +1430,7 @@ mod tests { #[tokio::test] async fn test_watch_confirmed_tx() { - let provider = ProviderBuilder::new().on_anvil(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let tx = TransactionRequest { value: Some(U256::from(100)), to: Some(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()), @@ -1622,7 +1622,7 @@ mod tests { #[tokio::test] async fn gets_transaction_by_hash() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); let req = TransactionRequest::default() .from(provider.default_signer_address()) @@ -1767,7 +1767,6 @@ mod tests { let wallet = EthereumWallet::from(signer); let provider = ProviderBuilder::new() - .with_recommended_fillers() .network::() .wallet(wallet) .on_http(anvil.endpoint_url()); diff --git a/crates/provider/src/provider/wallet.rs b/crates/provider/src/provider/wallet.rs index cc204b90af3..f01f961b0f5 100644 --- a/crates/provider/src/provider/wallet.rs +++ b/crates/provider/src/provider/wallet.rs @@ -97,14 +97,14 @@ mod test { #[test] fn basic_usage() { - let provider = ProviderBuilder::new().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().disable_recommended_fillers().on_anvil_with_wallet(); assert!(provider.signer_addresses().contains(&provider.default_signer_address())); } #[test] fn bubbles_through_fillers() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); assert!(provider.signer_addresses().contains(&provider.default_signer_address())); } diff --git a/crates/provider/src/utils.rs b/crates/provider/src/utils.rs index ba2d1960723..021f3ed453c 100644 --- a/crates/provider/src/utils.rs +++ b/crates/provider/src/utils.rs @@ -2,6 +2,11 @@ use alloy_primitives::{U128, U64}; +use crate::{ + fillers::{BlobGasFiller, ChainIdFiller, GasFiller, JoinFill, NonceFiller}, + Identity, +}; + /// The number of blocks from the past for which the fee rewards are fetched for fee estimation. pub const EIP1559_FEE_ESTIMATION_PAST_BLOCKS: u64 = 10; /// Multiplier for the current base fee to estimate max base fee for the next block. @@ -66,6 +71,13 @@ pub(crate) fn convert_u64(r: U64) -> u64 { r.to::() } +/// Helper type representing the joined recommended fillers i.e [`GasFiller`], +/// [`BlobGasFiller`], [`NonceFiller`], and [`ChainIdFiller`]. +pub type JoinedRecommendedFillers = JoinFill< + Identity, + JoinFill>>, +>; + #[cfg(test)] mod tests { use super::*; From c9ece7b524ce52d6a21f963a603dff733d469bdb Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 8 Jan 2025 18:18:48 +0530 Subject: [PATCH 2/9] fix: event filter tests --- crates/contract/src/event.rs | 60 ++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/crates/contract/src/event.rs b/crates/contract/src/event.rs index 0263eae6f27..82a1d296661 100644 --- a/crates/contract/src/event.rs +++ b/crates/contract/src/event.rs @@ -280,8 +280,9 @@ pub(crate) mod subscription { #[cfg(test)] mod tests { use super::*; - use alloy_primitives::U256; + use alloy_primitives::{address, U256}; use alloy_sol_types::sol; + use MyContract::MyContractInstance; sol! { // solc v0.8.24; solc a.sol --via-ir --optimize --bin @@ -309,9 +310,13 @@ mod tests { let _ = tracing_subscriber::fmt::try_init(); let anvil = alloy_node_bindings::Anvil::new().spawn(); + let provider = alloy_provider::ProviderBuilder::new().on_http(anvil.endpoint_url()); - let contract = MyContract::deploy(&provider).await.unwrap(); + let from = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); + let contract_addr = + MyContract::deploy_builder(&provider).from(from).deploy().await.unwrap(); + let contract = MyContractInstance::new(contract_addr, &provider); let event: Event<(), _, MyContract::MyEvent, _> = Event::new(&provider, Filter::new()); let all = event.query().await.unwrap(); @@ -322,8 +327,15 @@ mod tests { let poller = event.watch().await.unwrap(); - let _receipt = - contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); + let _receipt = contract + .doEmit() + .from(from) + .send() + .await + .unwrap() + .get_receipt() + .await + .expect("no receipt"); let expected_event = MyContract::MyEvent { _0: 42, @@ -350,6 +362,7 @@ mod tests { // send the wrong event and make sure it is NOT picked up by the event filter let _wrong_receipt = contract .doEmitWrongEvent() + .from(from) .send() .await .unwrap() @@ -374,7 +387,15 @@ mod tests { let sub = event.subscribe().await.unwrap(); - contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); + contract + .doEmit() + .from(from) + .send() + .await + .unwrap() + .get_receipt() + .await + .expect("no receipt"); let mut stream = sub.into_stream(); @@ -390,6 +411,7 @@ mod tests { // send the request to emit the wrong event contract .doEmitWrongEvent() + .from(from) .send() .await .unwrap() @@ -412,7 +434,10 @@ mod tests { let anvil = alloy_node_bindings::Anvil::new().spawn(); let provider = alloy_provider::ProviderBuilder::new().on_http(anvil.endpoint_url()); - let contract = MyContract::deploy(&provider).await.unwrap(); + let from = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); + let contract_addr = + MyContract::deploy_builder(&provider).from(from).deploy().await.unwrap(); + let contract = MyContractInstance::new(contract_addr, &provider); let event: Event<(), _, MyContract::MyEvent, _> = Event::new(&provider, Filter::new()) .address(*contract.address()) @@ -422,8 +447,15 @@ mod tests { let poller = event.watch().await.unwrap(); - let _receipt = - contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); + let _receipt = contract + .doEmit() + .from(from) + .send() + .await + .unwrap() + .get_receipt() + .await + .expect("no receipt"); let expected_event = MyContract::MyEvent { _0: 42, @@ -450,6 +482,7 @@ mod tests { // send the wrong event and make sure it is NOT picked up by the event filter let _wrong_receipt = contract .doEmitWrongEvent() + .from(from) .send() .await .unwrap() @@ -476,7 +509,15 @@ mod tests { let sub = event.subscribe().await.unwrap(); - contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); + contract + .doEmit() + .from(from) + .send() + .await + .unwrap() + .get_receipt() + .await + .expect("no receipt"); let mut stream = sub.into_stream(); @@ -492,6 +533,7 @@ mod tests { // send the request to emit the wrong event contract .doEmitWrongEvent() + .from(from) .send() .await .unwrap() From e8fd3298115ca2a7e6998fb04e0c809d1d792354 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:46:45 +0530 Subject: [PATCH 3/9] fix --- crates/provider/src/layers/cache.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/provider/src/layers/cache.rs b/crates/provider/src/layers/cache.rs index 6399b395c41..17d4afdc9a5 100644 --- a/crates/provider/src/layers/cache.rs +++ b/crates/provider/src/layers/cache.rs @@ -656,7 +656,10 @@ mod tests { let cache_layer = CacheLayer::new(100); let shared_cache = cache_layer.cache(); let anvil = Anvil::new().block_time_f64(0.3).spawn(); - let provider = ProviderBuilder::new().layer(cache_layer).on_http(anvil.endpoint_url()); + let provider = ProviderBuilder::new() + .disable_recommended_fillers() + .layer(cache_layer) + .on_http(anvil.endpoint_url()); let path = dir.join("rpc-cache-tx.txt"); shared_cache.load_cache(path.clone()).unwrap(); @@ -724,7 +727,7 @@ mod tests { run_with_tempdir("get-code", |dir| async move { let cache_layer = CacheLayer::new(100); let shared_cache = cache_layer.cache(); - let provider = ProviderBuilder::new().layer(cache_layer).on_anvil_with_wallet(); + let provider = ProviderBuilder::default().with_gas_estimation().layer(cache_layer).on_anvil_with_wallet(); let path = dir.join("rpc-cache-code.txt"); shared_cache.load_cache(path.clone()).unwrap(); @@ -733,7 +736,7 @@ mod tests { // solc v0.8.26; solc Counter.sol --via-ir --optimize --bin "6080806040523460135760df908160198239f35b600080fdfe6080806040526004361015601257600080fd5b60003560e01c9081633fb5c1cb1460925781638381f58a146079575063d09de08a14603c57600080fd5b3460745760003660031901126074576000546000198114605e57600101600055005b634e487b7160e01b600052601160045260246000fd5b600080fd5b3460745760003660031901126074576020906000548152f35b34607457602036600319011260745760043560005500fea2646970667358221220e978270883b7baed10810c4079c941512e93a7ba1cd1108c781d4bc738d9090564736f6c634300081a0033" ).unwrap(); - let tx = TransactionRequest::default().with_deploy_code(bytecode); + let tx = TransactionRequest::default().with_nonce(0).with_deploy_code(bytecode).with_chain_id(31337); let receipt = provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap(); From 7267ce4ce3bea0c5b6de74161f65fbd065337ba5 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:05:18 +0530 Subject: [PATCH 4/9] test --- crates/provider/src/provider/trait.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 57eba4afb17..adee3d13544 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -1106,7 +1106,7 @@ impl Provider for RootProvider { #[cfg(test)] mod tests { - use std::time::Duration; + use std::{str::FromStr, time::Duration}; use super::*; use crate::{builder, ProviderBuilder, WalletProvider}; @@ -1839,4 +1839,20 @@ mod tests { .unwrap(); assert!(block.transactions.is_hashes()); } + + #[tokio::test] + async fn disable_test() { + let provider = ProviderBuilder::new() + .disable_recommended_fillers() + .with_cached_nonce_management() + .on_anvil(); + + let tx = TransactionRequest::default() + .with_kind(alloy_primitives::TxKind::Create) + .value(U256::from(1235)) + .with_input(Bytes::from_str("ffffffffffffff").unwrap()); + + let err = provider.send_transaction(tx).await.unwrap_err().to_string(); + assert!(err.contains("missing properties: [(\"NonceManager\", [\"from\"])]")); + } } From d3694c81f8ae8b9ad31beffd7919f21ef1fc3c02 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:07:39 +0530 Subject: [PATCH 5/9] nit --- crates/provider/src/builder.rs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 749a67442f1..ec78a6e8177 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -112,25 +112,6 @@ pub struct ProviderBuilder { network: PhantomData N>, } -// impl ProviderBuilder { -// /// Create a new [`ProviderBuilder`] with recommended fillers enabled. -// pub const fn new() -> Self { -// let p: ProviderBuilder< -// Identity, -// JoinFill< -// Identity, -// JoinFill< -// GasFiller, -// JoinFill>, >, -// >, -// > = Self { layer: Identity, filler: Identity, network: PhantomData } -// > .with_recommended_fillers(); - -// p -// } -// } - impl ProviderBuilder< Identity, From 2d9c488fc8312094505f3703a06e24da9bb6704b Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 8 Jan 2025 22:32:08 +0530 Subject: [PATCH 6/9] fix: doc tests + event_filter tests + return impl Provider --- crates/contract/Cargo.toml | 1 + crates/contract/README.md | 2 +- crates/contract/src/call.rs | 11 +--- crates/contract/src/event.rs | 78 +++++++++---------------- crates/provider/src/fillers/chain_id.rs | 2 +- crates/provider/src/fillers/gas.rs | 2 +- crates/provider/src/fillers/nonce.rs | 2 +- 7 files changed, 34 insertions(+), 64 deletions(-) diff --git a/crates/contract/Cargo.toml b/crates/contract/Cargo.toml index a65be56b6d6..0d57e964d9f 100644 --- a/crates/contract/Cargo.toml +++ b/crates/contract/Cargo.toml @@ -46,6 +46,7 @@ alloy-rpc-client = { workspace = true, features = ["pubsub", "ws"] } alloy-transport-http.workspace = true alloy-node-bindings.workspace = true alloy-provider = { workspace = true, features = ["anvil-node"] } +alloy-signer-local.workspace = true reqwest.workspace = true tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/crates/contract/README.md b/crates/contract/README.md index dd830b68f2f..b1a468584c2 100644 --- a/crates/contract/README.md +++ b/crates/contract/README.md @@ -32,7 +32,7 @@ sol! { } // Build a provider. -let provider = ProviderBuilder::new().with_recommended_fillers().on_builtin("http://localhost:8545").await?; +let provider = ProviderBuilder::new().on_builtin("http://localhost:8545").await?; // If `#[sol(bytecode = "0x...")]` is provided, the contract can be deployed with `MyContract::deploy`, // and a new instance will be created. diff --git a/crates/contract/src/call.rs b/crates/contract/src/call.rs index 2b4161bd12f..a043dc6f665 100644 --- a/crates/contract/src/call.rs +++ b/crates/contract/src/call.rs @@ -569,10 +569,7 @@ mod tests { use super::*; use alloy_consensus::Transaction; use alloy_primitives::{address, b256, bytes, hex, utils::parse_units, B256}; - use alloy_provider::{ - fillers::FillProvider, layers::AnvilProvider, utils::JoinedRecommendedFillers, Provider, - ProviderBuilder, RootProvider, WalletProvider, - }; + use alloy_provider::{Provider, ProviderBuilder, WalletProvider}; use alloy_rpc_types_eth::AccessListItem; use alloy_sol_types::sol; @@ -620,12 +617,10 @@ mod tests { } } - type AnvilFillProvider = - FillProvider, Ethereum>; /// Creates a new call_builder to test field modifications, taken from [call_encoding] #[allow(clippy::type_complexity)] - fn build_call_builder( - ) -> CallBuilder<(), AnvilFillProvider, PhantomData> { + fn build_call_builder() -> CallBuilder<(), impl Provider, PhantomData> + { let provider = ProviderBuilder::new().on_anvil(); let contract = MyContract::new(Address::ZERO, provider); let call_builder = contract.doStuff(U256::ZERO, true).with_cloned_provider(); diff --git a/crates/contract/src/event.rs b/crates/contract/src/event.rs index 82a1d296661..7ddd21e2502 100644 --- a/crates/contract/src/event.rs +++ b/crates/contract/src/event.rs @@ -280,9 +280,10 @@ pub(crate) mod subscription { #[cfg(test)] mod tests { use super::*; - use alloy_primitives::{address, U256}; + use alloy_network::EthereumWallet; + use alloy_primitives::U256; + use alloy_signer_local::PrivateKeySigner; use alloy_sol_types::sol; - use MyContract::MyContractInstance; sol! { // solc v0.8.24; solc a.sol --via-ir --optimize --bin @@ -311,12 +312,15 @@ mod tests { let anvil = alloy_node_bindings::Anvil::new().spawn(); - let provider = alloy_provider::ProviderBuilder::new().on_http(anvil.endpoint_url()); + let pk: PrivateKeySigner = + "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".parse().unwrap(); + let wallet = EthereumWallet::from(pk); + let provider = alloy_provider::ProviderBuilder::new() + .wallet(wallet.clone()) + .on_http(anvil.endpoint_url()); - let from = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); - let contract_addr = - MyContract::deploy_builder(&provider).from(from).deploy().await.unwrap(); - let contract = MyContractInstance::new(contract_addr, &provider); + // let from = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); + let contract = MyContract::deploy(&provider).await.unwrap(); let event: Event<(), _, MyContract::MyEvent, _> = Event::new(&provider, Filter::new()); let all = event.query().await.unwrap(); @@ -327,15 +331,8 @@ mod tests { let poller = event.watch().await.unwrap(); - let _receipt = contract - .doEmit() - .from(from) - .send() - .await - .unwrap() - .get_receipt() - .await - .expect("no receipt"); + let _receipt = + contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); let expected_event = MyContract::MyEvent { _0: 42, @@ -362,7 +359,6 @@ mod tests { // send the wrong event and make sure it is NOT picked up by the event filter let _wrong_receipt = contract .doEmitWrongEvent() - .from(from) .send() .await .unwrap() @@ -378,6 +374,7 @@ mod tests { #[cfg(feature = "pubsub")] { let provider = alloy_provider::ProviderBuilder::new() + .wallet(wallet) .on_builtin(&anvil.ws_endpoint()) .await .unwrap(); @@ -387,15 +384,7 @@ mod tests { let sub = event.subscribe().await.unwrap(); - contract - .doEmit() - .from(from) - .send() - .await - .unwrap() - .get_receipt() - .await - .expect("no receipt"); + contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); let mut stream = sub.into_stream(); @@ -411,7 +400,6 @@ mod tests { // send the request to emit the wrong event contract .doEmitWrongEvent() - .from(from) .send() .await .unwrap() @@ -432,12 +420,14 @@ mod tests { let _ = tracing_subscriber::fmt::try_init(); let anvil = alloy_node_bindings::Anvil::new().spawn(); - let provider = alloy_provider::ProviderBuilder::new().on_http(anvil.endpoint_url()); + let pk: PrivateKeySigner = + "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".parse().unwrap(); + let wallet = EthereumWallet::from(pk); + let provider = alloy_provider::ProviderBuilder::new() + .wallet(wallet.clone()) + .on_http(anvil.endpoint_url()); - let from = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); - let contract_addr = - MyContract::deploy_builder(&provider).from(from).deploy().await.unwrap(); - let contract = MyContractInstance::new(contract_addr, &provider); + let contract = MyContract::deploy(&provider).await.unwrap(); let event: Event<(), _, MyContract::MyEvent, _> = Event::new(&provider, Filter::new()) .address(*contract.address()) @@ -447,15 +437,8 @@ mod tests { let poller = event.watch().await.unwrap(); - let _receipt = contract - .doEmit() - .from(from) - .send() - .await - .unwrap() - .get_receipt() - .await - .expect("no receipt"); + let _receipt = + contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); let expected_event = MyContract::MyEvent { _0: 42, @@ -482,7 +465,6 @@ mod tests { // send the wrong event and make sure it is NOT picked up by the event filter let _wrong_receipt = contract .doEmitWrongEvent() - .from(from) .send() .await .unwrap() @@ -498,6 +480,7 @@ mod tests { #[cfg(feature = "pubsub")] { let provider = alloy_provider::ProviderBuilder::new() + .wallet(wallet) .on_builtin(&anvil.ws_endpoint()) .await .unwrap(); @@ -509,15 +492,7 @@ mod tests { let sub = event.subscribe().await.unwrap(); - contract - .doEmit() - .from(from) - .send() - .await - .unwrap() - .get_receipt() - .await - .expect("no receipt"); + contract.doEmit().send().await.unwrap().get_receipt().await.expect("no receipt"); let mut stream = sub.into_stream(); @@ -533,7 +508,6 @@ mod tests { // send the request to emit the wrong event contract .doEmitWrongEvent() - .from(from) .send() .await .unwrap() diff --git a/crates/provider/src/fillers/chain_id.rs b/crates/provider/src/fillers/chain_id.rs index 583228cbeeb..296a059f763 100644 --- a/crates/provider/src/fillers/chain_id.rs +++ b/crates/provider/src/fillers/chain_id.rs @@ -26,7 +26,7 @@ use crate::{ /// # use alloy_rpc_types_eth::TransactionRequest; /// # use alloy_provider::{ProviderBuilder, RootProvider, Provider}; /// # async fn test + Clone>(url: url::Url, wallet: W) -> Result<(), Box> { -/// let provider = ProviderBuilder::new() +/// let provider = ProviderBuilder::default() /// .with_chain_id(1) /// .wallet(wallet) /// .on_http(url); diff --git a/crates/provider/src/fillers/gas.rs b/crates/provider/src/fillers/gas.rs index 7f06747618c..006cb048230 100644 --- a/crates/provider/src/fillers/gas.rs +++ b/crates/provider/src/fillers/gas.rs @@ -52,7 +52,7 @@ pub enum GasFillable { /// # use alloy_rpc_types_eth::TransactionRequest; /// # use alloy_provider::{ProviderBuilder, RootProvider, Provider}; /// # async fn test + Clone>(url: url::Url, wallet: W) -> Result<(), Box> { -/// let provider = ProviderBuilder::new() +/// let provider = ProviderBuilder::default() /// .with_gas_estimation() /// .wallet(wallet) /// .on_http(url); diff --git a/crates/provider/src/fillers/nonce.rs b/crates/provider/src/fillers/nonce.rs index 2f44e464833..fcd7fffb063 100644 --- a/crates/provider/src/fillers/nonce.rs +++ b/crates/provider/src/fillers/nonce.rs @@ -104,7 +104,7 @@ impl NonceManager for CachedNonceManager { /// # use alloy_rpc_types_eth::TransactionRequest; /// # use alloy_provider::{ProviderBuilder, RootProvider, Provider}; /// # async fn test + Clone>(url: url::Url, wallet: W) -> Result<(), Box> { -/// let provider = ProviderBuilder::new() +/// let provider = ProviderBuilder::default() /// .with_simple_nonce_management() /// .wallet(wallet) /// .on_http(url); From 23246d4206cf28abc007ef24e09965a269ea7bb0 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:31:04 +0530 Subject: [PATCH 7/9] fix --- crates/provider/src/builder.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index ec78a6e8177..d32da2d9035 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -131,6 +131,11 @@ impl pub fn new() -> Self { ProviderBuilder::default().with_recommended_fillers() } + + /// Opt-out of the recommended fillers by reseting the fillers stack in the [`ProviderBuilder`]. + pub fn disable_recommended_fillers(self) -> ProviderBuilder { + ProviderBuilder { layer: self.layer, filler: Identity, network: self.network } + } } impl Default for ProviderBuilder { @@ -139,13 +144,6 @@ impl Default for ProviderBuilder { } } -impl ProviderBuilder { - /// Opt-out of the recommended fillers by reseting the fillers stack in the [`ProviderBuilder`]. - pub fn disable_recommended_fillers(self) -> ProviderBuilder { - ProviderBuilder { layer: self.layer, filler: Identity, network: self.network } - } -} - impl ProviderBuilder { /// Add preconfigured set of layers handling gas estimation, nonce /// management, and chain-id fetching. From 8e098a8eba3244259c703c9b10cea62baba8c349 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:49:26 +0530 Subject: [PATCH 8/9] docs --- crates/provider/src/builder.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index d32da2d9035..8f28034202d 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -104,6 +104,13 @@ where /// This type is similar to [`tower::ServiceBuilder`], with extra complication /// around maintaining the network and transport types. /// +/// The [`ProviderBuilder`] can be instantiated in two ways, using `ProviderBuilder::new()` or +/// `ProviderBuilder::default()`. +/// +/// `ProviderBuilder::new()` will create a new [`ProviderBuilder`] with the [`RecommendedFillers`] +/// enabled, whereas `ProviderBuilder::default()` will instantiate it in its vanilla +/// [`ProviderBuilder`] form i.e with no fillers enabled. +/// /// [`tower::ServiceBuilder`]: https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html #[derive(Debug)] pub struct ProviderBuilder { From e294f3877e8aed1442154c0584af8269183a8f45 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Fri, 10 Jan 2025 13:08:13 +0530 Subject: [PATCH 9/9] doc nit --- crates/provider/src/builder.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 8f28034202d..e9b224a6449 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -140,6 +140,8 @@ impl } /// Opt-out of the recommended fillers by reseting the fillers stack in the [`ProviderBuilder`]. + /// + /// This is equivalent to creating the builder using `ProviderBuilder::default()`. pub fn disable_recommended_fillers(self) -> ProviderBuilder { ProviderBuilder { layer: self.layer, filler: Identity, network: self.network } }