ethers_providers/rpc/
provider.rs

1use ethers_core::types::SyncingStatus;
2
3use crate::{
4    call_raw::CallBuilder,
5    errors::ProviderError,
6    ext::{ens, erc},
7    stream::{FilterWatcher, DEFAULT_LOCAL_POLL_INTERVAL, DEFAULT_POLL_INTERVAL},
8    utils::maybe,
9    Http as HttpProvider, JsonRpcClient, JsonRpcClientWrapper, LogQuery, MiddlewareError,
10    MockProvider, NodeInfo, PeerInfo, PendingTransaction, PubsubClient, QuorumProvider, RwClient,
11    SubscriptionStream,
12};
13
14#[cfg(not(target_arch = "wasm32"))]
15use crate::{HttpRateLimitRetryPolicy, RetryClient};
16use std::net::Ipv4Addr;
17
18pub use crate::Middleware;
19
20use async_trait::async_trait;
21
22use ethers_core::{
23    abi::{self, Detokenize, ParamType},
24    types::{
25        transaction::{eip2718::TypedTransaction, eip2930::AccessListWithGasUsed},
26        Address, Block, BlockId, BlockNumber, BlockTrace, Bytes, Chain, EIP1186ProofResponse,
27        FeeHistory, Filter, FilterBlockOption, GethDebugTracingCallOptions,
28        GethDebugTracingOptions, GethTrace, Log, NameOrAddress, Selector, Signature, Trace,
29        TraceFilter, TraceType, Transaction, TransactionReceipt, TransactionRequest, TxHash,
30        TxpoolContent, TxpoolInspect, TxpoolStatus, H256, U256, U64,
31    },
32    utils,
33};
34use futures_util::{lock::Mutex, try_join};
35use serde::{de::DeserializeOwned, Serialize};
36use std::{collections::VecDeque, fmt::Debug, str::FromStr, sync::Arc, time::Duration};
37use tracing::trace;
38use tracing_futures::Instrument;
39use url::{Host, ParseError, Url};
40
41/// Node Clients
42#[derive(Copy, Clone)]
43pub enum NodeClient {
44    /// Geth
45    Geth,
46    /// Erigon
47    Erigon,
48    /// OpenEthereum
49    OpenEthereum,
50    /// Nethermind
51    Nethermind,
52    /// Besu
53    Besu,
54}
55
56impl FromStr for NodeClient {
57    type Err = ProviderError;
58
59    fn from_str(s: &str) -> Result<Self, Self::Err> {
60        match s.split('/').next().unwrap().to_lowercase().as_str() {
61            "geth" => Ok(NodeClient::Geth),
62            "erigon" => Ok(NodeClient::Erigon),
63            "openethereum" => Ok(NodeClient::OpenEthereum),
64            "nethermind" => Ok(NodeClient::Nethermind),
65            "besu" => Ok(NodeClient::Besu),
66            _ => Err(ProviderError::UnsupportedNodeClient),
67        }
68    }
69}
70
71/// An abstract provider for interacting with the [Ethereum JSON RPC
72/// API](https://github.com/ethereum/wiki/wiki/JSON-RPC). Must be instantiated
73/// with a data transport which implements the [`JsonRpcClient`](trait@crate::JsonRpcClient) trait
74/// (e.g. [HTTP](crate::Http), Websockets etc.)
75///
76/// # Example
77///
78/// ```no_run
79/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
80/// use ethers_providers::{Middleware, Provider, Http};
81/// use std::convert::TryFrom;
82///
83/// let provider = Provider::<Http>::try_from(
84///     "https://eth.llamarpc.com"
85/// ).expect("could not instantiate HTTP Provider");
86///
87/// let block = provider.get_block(100u64).await?;
88/// println!("Got block: {}", serde_json::to_string(&block)?);
89/// # Ok(())
90/// # }
91/// ```
92#[derive(Clone, Debug)]
93pub struct Provider<P> {
94    inner: P,
95    ens: Option<Address>,
96    interval: Option<Duration>,
97    from: Option<Address>,
98    /// Node client hasn't been checked yet = `None`
99    /// Unsupported node client = `Some(None)`
100    /// Supported node client = `Some(Some(NodeClient))`
101    _node_client: Arc<Mutex<Option<NodeClient>>>,
102}
103
104impl<P> AsRef<P> for Provider<P> {
105    fn as_ref(&self) -> &P {
106        &self.inner
107    }
108}
109
110/// Types of filters supported by the JSON-RPC.
111#[derive(Clone, Debug)]
112pub enum FilterKind<'a> {
113    /// `eth_newBlockFilter`
114    Logs(&'a Filter),
115
116    /// `eth_newBlockFilter` filter
117    NewBlocks,
118
119    /// `eth_newPendingTransactionFilter` filter
120    PendingTransactions,
121}
122
123// JSON RPC bindings
124impl<P: JsonRpcClient> Provider<P> {
125    /// Instantiate a new provider with a backend.
126    pub fn new(provider: P) -> Self {
127        Self {
128            inner: provider,
129            ens: None,
130            interval: None,
131            from: None,
132            _node_client: Arc::new(Mutex::new(None)),
133        }
134    }
135
136    /// Returns the type of node we're connected to, while also caching the value for use
137    /// in other node-specific API calls, such as the get_block_receipts call.
138    pub async fn node_client(&self) -> Result<NodeClient, ProviderError> {
139        let mut node_client = self._node_client.lock().await;
140
141        if let Some(node_client) = *node_client {
142            Ok(node_client)
143        } else {
144            let client_version = self.client_version().await?;
145            let client_version = match client_version.parse::<NodeClient>() {
146                Ok(res) => res,
147                Err(_) => return Err(ProviderError::UnsupportedNodeClient),
148            };
149            *node_client = Some(client_version);
150            Ok(client_version)
151        }
152    }
153
154    #[must_use]
155    /// Set the default sender on the provider
156    pub fn with_sender(mut self, address: impl Into<Address>) -> Self {
157        self.from = Some(address.into());
158        self
159    }
160
161    /// Make an RPC request via the internal connection, and return the result.
162    pub async fn request<T, R>(&self, method: &str, params: T) -> Result<R, ProviderError>
163    where
164        T: Debug + Serialize + Send + Sync,
165        R: Serialize + DeserializeOwned + Debug + Send,
166    {
167        let span =
168            tracing::trace_span!("rpc", method = method, params = ?serde_json::to_string(&params)?);
169        // https://docs.rs/tracing/0.1.22/tracing/span/struct.Span.html#in-asynchronous-code
170        let res = async move {
171            trace!("tx");
172            let res: R = self.inner.request(method, params).await.map_err(Into::into)?;
173            trace!(rx = ?serde_json::to_string(&res)?);
174            Ok::<_, ProviderError>(res)
175        }
176        .instrument(span)
177        .await?;
178        Ok(res)
179    }
180
181    async fn get_block_gen<Tx: Default + Serialize + DeserializeOwned + Debug + Send>(
182        &self,
183        id: BlockId,
184        include_txs: bool,
185    ) -> Result<Option<Block<Tx>>, ProviderError> {
186        let include_txs = utils::serialize(&include_txs);
187
188        Ok(match id {
189            BlockId::Hash(hash) => {
190                let hash = utils::serialize(&hash);
191                self.request("eth_getBlockByHash", [hash, include_txs]).await?
192            }
193            BlockId::Number(num) => {
194                let num = utils::serialize(&num);
195                self.request("eth_getBlockByNumber", [num, include_txs]).await?
196            }
197        })
198    }
199
200    /// Analogous to [`Middleware::call`], but returns a [`CallBuilder`] that can either be
201    /// `.await`d or used to override the parameters sent to `eth_call`.
202    ///
203    /// See the [`ethers_core::types::spoof`] for functions to construct state override
204    /// parameters.
205    ///
206    /// Note: this method _does not_ send a transaction from your account
207    ///
208    /// [`ethers_core::types::spoof`]: ethers_core::types::spoof
209    ///
210    /// # Example
211    ///
212    /// ```no_run
213    /// # use ethers_core::{
214    /// #     types::{Address, TransactionRequest, H256, spoof},
215    /// #     utils::{parse_ether, Geth},
216    /// # };
217    /// # use ethers_providers::{Provider, Http, Middleware, call_raw::RawCall};
218    /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
219    /// let geth = Geth::new().spawn();
220    /// let provider = Provider::<Http>::try_from(geth.endpoint()).unwrap();
221    ///
222    /// let adr1: Address = "0x6fC21092DA55B392b045eD78F4732bff3C580e2c".parse()?;
223    /// let adr2: Address = "0x295a70b2de5e3953354a6a8344e616ed314d7251".parse()?;
224    /// let pay_amt = parse_ether(1u64)?;
225    ///
226    /// // Not enough ether to pay for the transaction
227    /// let tx = TransactionRequest::pay(adr2, pay_amt).from(adr1).into();
228    ///
229    /// // override the sender's balance for the call
230    /// let mut state = spoof::balance(adr1, pay_amt * 2);
231    /// provider.call_raw(&tx).state(&state).await?;
232    /// # Ok(()) }
233    /// ```
234    pub fn call_raw<'a>(&'a self, tx: &'a TypedTransaction) -> CallBuilder<'a, P> {
235        CallBuilder::new(self, tx)
236    }
237}
238
239#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
240#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
241impl<P: JsonRpcClient> Middleware for Provider<P> {
242    type Error = ProviderError;
243    type Provider = P;
244    type Inner = Self;
245
246    fn inner(&self) -> &Self::Inner {
247        unreachable!("There is no inner provider here")
248    }
249
250    fn provider(&self) -> &Provider<Self::Provider> {
251        self
252    }
253
254    fn convert_err(p: ProviderError) -> Self::Error {
255        // no conversion necessary
256        p
257    }
258
259    fn default_sender(&self) -> Option<Address> {
260        self.from
261    }
262
263    async fn client_version(&self) -> Result<String, Self::Error> {
264        self.request("web3_clientVersion", ()).await
265    }
266
267    async fn fill_transaction(
268        &self,
269        tx: &mut TypedTransaction,
270        block: Option<BlockId>,
271    ) -> Result<(), Self::Error> {
272        if let Some(default_sender) = self.default_sender() {
273            if tx.from().is_none() {
274                tx.set_from(default_sender);
275            }
276        }
277
278        // TODO: Join the name resolution and gas price future
279
280        // set the ENS name
281        if let Some(NameOrAddress::Name(ref ens_name)) = tx.to() {
282            let addr = self.resolve_name(ens_name).await?;
283            tx.set_to(addr);
284        }
285
286        // fill gas price
287        match tx {
288            TypedTransaction::Eip2930(_) | TypedTransaction::Legacy(_) => {
289                let gas_price = maybe(tx.gas_price(), self.get_gas_price()).await?;
290                tx.set_gas_price(gas_price);
291            }
292            TypedTransaction::Eip1559(ref mut inner) => {
293                if inner.max_fee_per_gas.is_none() || inner.max_priority_fee_per_gas.is_none() {
294                    let (max_fee_per_gas, max_priority_fee_per_gas) =
295                        self.estimate_eip1559_fees(None).await?;
296                    // we want to avoid overriding the user if either of these
297                    // are set. In order to do this, we refuse to override the
298                    // `max_fee_per_gas` if already set.
299                    // However, we must preserve the constraint that the tip
300                    // cannot be higher than max fee, so we override user
301                    // intent if that is so. We override by
302                    //   - first: if set, set to the min(current value, MFPG)
303                    //   - second, if still unset, use the RPC estimated amount
304                    let mfpg = inner.max_fee_per_gas.get_or_insert(max_fee_per_gas);
305                    inner.max_priority_fee_per_gas = inner
306                        .max_priority_fee_per_gas
307                        .map(|tip| std::cmp::min(tip, *mfpg))
308                        .or(Some(max_priority_fee_per_gas));
309                };
310            }
311            #[cfg(feature = "optimism")]
312            TypedTransaction::DepositTransaction(_) => {
313                let gas_price = maybe(tx.gas_price(), self.get_gas_price()).await?;
314                tx.set_gas_price(gas_price);
315            }
316        }
317
318        // Set gas to estimated value only if it was not set by the caller,
319        // even if the access list has been populated and saves gas
320        if tx.gas().is_none() {
321            let gas_estimate = self.estimate_gas(tx, block).await?;
322            tx.set_gas(gas_estimate);
323        }
324
325        Ok(())
326    }
327
328    async fn get_block_number(&self) -> Result<U64, ProviderError> {
329        self.request("eth_blockNumber", ()).await
330    }
331
332    async fn get_block<T: Into<BlockId> + Send + Sync>(
333        &self,
334        block_hash_or_number: T,
335    ) -> Result<Option<Block<TxHash>>, Self::Error> {
336        self.get_block_gen(block_hash_or_number.into(), false).await
337    }
338
339    async fn get_header<T: Into<BlockId> + Send + Sync>(
340        &self,
341        block_hash_or_number: T,
342    ) -> Result<Option<Block<Transaction>>, Self::Error> {
343        let id = block_hash_or_number.into();
344        Ok(match id {
345            BlockId::Number(num) => {
346                let num = utils::serialize(&num);
347                self.request("eth_getHeaderByNumber", [num]).await?
348            }
349            BlockId::Hash(hash) => {
350                let hash = utils::serialize(&hash);
351                self.request("eth_getHeaderByHash", [hash]).await?
352            }
353        })
354    }
355
356    async fn get_block_with_txs<T: Into<BlockId> + Send + Sync>(
357        &self,
358        block_hash_or_number: T,
359    ) -> Result<Option<Block<Transaction>>, ProviderError> {
360        self.get_block_gen(block_hash_or_number.into(), true).await
361    }
362
363    async fn get_uncle_count<T: Into<BlockId> + Send + Sync>(
364        &self,
365        block_hash_or_number: T,
366    ) -> Result<U256, Self::Error> {
367        let id = block_hash_or_number.into();
368        Ok(match id {
369            BlockId::Hash(hash) => {
370                let hash = utils::serialize(&hash);
371                self.request("eth_getUncleCountByBlockHash", [hash]).await?
372            }
373            BlockId::Number(num) => {
374                let num = utils::serialize(&num);
375                self.request("eth_getUncleCountByBlockNumber", [num]).await?
376            }
377        })
378    }
379
380    async fn get_uncle<T: Into<BlockId> + Send + Sync>(
381        &self,
382        block_hash_or_number: T,
383        idx: U64,
384    ) -> Result<Option<Block<H256>>, ProviderError> {
385        let blk_id = block_hash_or_number.into();
386        let idx = utils::serialize(&idx);
387        Ok(match blk_id {
388            BlockId::Hash(hash) => {
389                let hash = utils::serialize(&hash);
390                self.request("eth_getUncleByBlockHashAndIndex", [hash, idx]).await?
391            }
392            BlockId::Number(num) => {
393                let num = utils::serialize(&num);
394                self.request("eth_getUncleByBlockNumberAndIndex", [num, idx]).await?
395            }
396        })
397    }
398
399    async fn get_transaction<T: Send + Sync + Into<TxHash>>(
400        &self,
401        transaction_hash: T,
402    ) -> Result<Option<Transaction>, ProviderError> {
403        let hash = transaction_hash.into();
404        self.request("eth_getTransactionByHash", [hash]).await
405    }
406
407    async fn get_transaction_by_block_and_index<T: Into<BlockId> + Send + Sync>(
408        &self,
409        block_hash_or_number: T,
410        idx: U64,
411    ) -> Result<Option<Transaction>, ProviderError> {
412        let blk_id = block_hash_or_number.into();
413        let idx = ethers_core::utils::serialize(&idx);
414        Ok(match blk_id {
415            BlockId::Hash(hash) => {
416                let hash = ethers_core::utils::serialize(&hash);
417                self.request("eth_getTransactionByBlockHashAndIndex", [hash, idx]).await?
418            }
419            BlockId::Number(num) => {
420                let num = ethers_core::utils::serialize(&num);
421                self.request("eth_getTransactionByBlockNumberAndIndex", [num, idx]).await?
422            }
423        })
424    }
425
426    async fn get_transaction_receipt<T: Send + Sync + Into<TxHash>>(
427        &self,
428        transaction_hash: T,
429    ) -> Result<Option<TransactionReceipt>, ProviderError> {
430        let hash = transaction_hash.into();
431        self.request("eth_getTransactionReceipt", [hash]).await
432    }
433
434    async fn get_block_receipts<T: Into<BlockNumber> + Send + Sync>(
435        &self,
436        block: T,
437    ) -> Result<Vec<TransactionReceipt>, Self::Error> {
438        self.request("eth_getBlockReceipts", [block.into()]).await
439    }
440
441    async fn parity_block_receipts<T: Into<BlockNumber> + Send + Sync>(
442        &self,
443        block: T,
444    ) -> Result<Vec<TransactionReceipt>, Self::Error> {
445        self.request("parity_getBlockReceipts", vec![block.into()]).await
446    }
447
448    async fn get_gas_price(&self) -> Result<U256, ProviderError> {
449        self.request("eth_gasPrice", ()).await
450    }
451
452    async fn estimate_eip1559_fees(
453        &self,
454        estimator: Option<fn(U256, Vec<Vec<U256>>) -> (U256, U256)>,
455    ) -> Result<(U256, U256), Self::Error> {
456        let base_fee_per_gas = self
457            .get_block(BlockNumber::Latest)
458            .await?
459            .ok_or_else(|| ProviderError::CustomError("Latest block not found".into()))?
460            .base_fee_per_gas
461            .ok_or_else(|| ProviderError::CustomError("EIP-1559 not activated".into()))?;
462
463        let fee_history = self
464            .fee_history(
465                utils::EIP1559_FEE_ESTIMATION_PAST_BLOCKS,
466                BlockNumber::Latest,
467                &[utils::EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE],
468            )
469            .await?;
470
471        // use the provided fee estimator function, or fallback to the default implementation.
472        let (max_fee_per_gas, max_priority_fee_per_gas) = if let Some(es) = estimator {
473            es(base_fee_per_gas, fee_history.reward)
474        } else {
475            utils::eip1559_default_estimator(base_fee_per_gas, fee_history.reward)
476        };
477
478        Ok((max_fee_per_gas, max_priority_fee_per_gas))
479    }
480
481    async fn get_accounts(&self) -> Result<Vec<Address>, ProviderError> {
482        self.request("eth_accounts", ()).await
483    }
484
485    async fn get_transaction_count<T: Into<NameOrAddress> + Send + Sync>(
486        &self,
487        from: T,
488        block: Option<BlockId>,
489    ) -> Result<U256, ProviderError> {
490        let from = match from.into() {
491            NameOrAddress::Name(ens_name) => self.resolve_name(&ens_name).await?,
492            NameOrAddress::Address(addr) => addr,
493        };
494
495        let from = utils::serialize(&from);
496        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
497        self.request("eth_getTransactionCount", [from, block]).await
498    }
499
500    async fn get_balance<T: Into<NameOrAddress> + Send + Sync>(
501        &self,
502        from: T,
503        block: Option<BlockId>,
504    ) -> Result<U256, ProviderError> {
505        let from = match from.into() {
506            NameOrAddress::Name(ens_name) => self.resolve_name(&ens_name).await?,
507            NameOrAddress::Address(addr) => addr,
508        };
509
510        let from = utils::serialize(&from);
511        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
512        self.request("eth_getBalance", [from, block]).await
513    }
514
515    async fn get_chainid(&self) -> Result<U256, ProviderError> {
516        self.request("eth_chainId", ()).await
517    }
518
519    async fn syncing(&self) -> Result<SyncingStatus, Self::Error> {
520        self.request("eth_syncing", ()).await
521    }
522
523    async fn get_net_version(&self) -> Result<String, ProviderError> {
524        self.request("net_version", ()).await
525    }
526
527    async fn call(
528        &self,
529        tx: &TypedTransaction,
530        block: Option<BlockId>,
531    ) -> Result<Bytes, ProviderError> {
532        let tx = utils::serialize(tx);
533        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
534        self.request("eth_call", [tx, block]).await
535    }
536
537    async fn estimate_gas(
538        &self,
539        tx: &TypedTransaction,
540        block: Option<BlockId>,
541    ) -> Result<U256, ProviderError> {
542        let tx = utils::serialize(tx);
543        // Some nodes (e.g. old Optimism clients) don't support a block ID being passed as a param,
544        // so refrain from defaulting to BlockNumber::Latest.
545        let params = if let Some(block_id) = block {
546            vec![tx, utils::serialize(&block_id)]
547        } else {
548            vec![tx]
549        };
550        self.request("eth_estimateGas", params).await
551    }
552
553    async fn create_access_list(
554        &self,
555        tx: &TypedTransaction,
556        block: Option<BlockId>,
557    ) -> Result<AccessListWithGasUsed, ProviderError> {
558        let tx = utils::serialize(tx);
559        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
560        self.request("eth_createAccessList", [tx, block]).await
561    }
562
563    async fn send_transaction<T: Into<TypedTransaction> + Send + Sync>(
564        &self,
565        tx: T,
566        block: Option<BlockId>,
567    ) -> Result<PendingTransaction<'_, P>, ProviderError> {
568        let mut tx = tx.into();
569        self.fill_transaction(&mut tx, block).await?;
570        let tx_hash = self.request("eth_sendTransaction", [tx]).await?;
571
572        Ok(PendingTransaction::new(tx_hash, self))
573    }
574
575    async fn send_raw_transaction<'a>(
576        &'a self,
577        tx: Bytes,
578    ) -> Result<PendingTransaction<'a, P>, ProviderError> {
579        let rlp = utils::serialize(&tx);
580        let tx_hash = self.request("eth_sendRawTransaction", [rlp]).await?;
581        Ok(PendingTransaction::new(tx_hash, self))
582    }
583
584    async fn is_signer(&self) -> bool {
585        match self.from {
586            Some(sender) => self.sign(vec![], &sender).await.is_ok(),
587            None => false,
588        }
589    }
590
591    async fn sign<T: Into<Bytes> + Send + Sync>(
592        &self,
593        data: T,
594        from: &Address,
595    ) -> Result<Signature, ProviderError> {
596        let data = utils::serialize(&data.into());
597        let from = utils::serialize(from);
598
599        // get the response from `eth_sign` call
600        let sig: String = self.request("eth_sign", [from, data]).await?;
601
602        // decode the signature
603        let sig = hex::decode(sig)?;
604        Ok(Signature::try_from(sig.as_slice())
605            .map_err(|e| ProviderError::CustomError(e.to_string()))?)
606    }
607
608    /// Sign a transaction via RPC call
609    async fn sign_transaction(
610        &self,
611        _tx: &TypedTransaction,
612        _from: Address,
613    ) -> Result<Signature, Self::Error> {
614        Err(MiddlewareError::from_err(ProviderError::SignerUnavailable))
615    }
616
617    ////// Contract state
618
619    async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, ProviderError> {
620        self.request("eth_getLogs", [filter]).await
621    }
622
623    fn get_logs_paginated<'a>(&'a self, filter: &Filter, page_size: u64) -> LogQuery<'a, P> {
624        LogQuery::new(self, filter).with_page_size(page_size)
625    }
626
627    async fn watch<'a>(
628        &'a self,
629        filter: &Filter,
630    ) -> Result<FilterWatcher<'a, P, Log>, ProviderError> {
631        let id = self.new_filter(FilterKind::Logs(filter)).await?;
632        let filter = FilterWatcher::new(id, self).interval(self.get_interval());
633        Ok(filter)
634    }
635
636    async fn watch_blocks(&self) -> Result<FilterWatcher<'_, P, H256>, ProviderError> {
637        let id = self.new_filter(FilterKind::NewBlocks).await?;
638        let filter = FilterWatcher::new(id, self).interval(self.get_interval());
639        Ok(filter)
640    }
641
642    /// Streams pending transactions
643    async fn watch_pending_transactions(
644        &self,
645    ) -> Result<FilterWatcher<'_, P, H256>, ProviderError> {
646        let id = self.new_filter(FilterKind::PendingTransactions).await?;
647        let filter = FilterWatcher::new(id, self).interval(self.get_interval());
648        Ok(filter)
649    }
650
651    async fn new_filter(&self, filter: FilterKind<'_>) -> Result<U256, ProviderError> {
652        let (method, args) = match filter {
653            FilterKind::NewBlocks => ("eth_newBlockFilter", vec![]),
654            FilterKind::PendingTransactions => ("eth_newPendingTransactionFilter", vec![]),
655            FilterKind::Logs(filter) => ("eth_newFilter", vec![utils::serialize(&filter)]),
656        };
657
658        self.request(method, args).await
659    }
660
661    async fn uninstall_filter<T: Into<U256> + Send + Sync>(
662        &self,
663        id: T,
664    ) -> Result<bool, ProviderError> {
665        let id = utils::serialize(&id.into());
666        self.request("eth_uninstallFilter", [id]).await
667    }
668
669    async fn get_filter_changes<T, R>(&self, id: T) -> Result<Vec<R>, ProviderError>
670    where
671        T: Into<U256> + Send + Sync,
672        R: Serialize + DeserializeOwned + Send + Sync + Debug,
673    {
674        let id = utils::serialize(&id.into());
675        self.request("eth_getFilterChanges", [id]).await
676    }
677
678    async fn get_storage_at<T: Into<NameOrAddress> + Send + Sync>(
679        &self,
680        from: T,
681        location: H256,
682        block: Option<BlockId>,
683    ) -> Result<H256, ProviderError> {
684        let from = match from.into() {
685            NameOrAddress::Name(ens_name) => self.resolve_name(&ens_name).await?,
686            NameOrAddress::Address(addr) => addr,
687        };
688
689        // position is a QUANTITY according to the [spec](https://eth.wiki/json-rpc/API#eth_getstorageat): integer of the position in the storage, converting this to a U256
690        // will make sure the number is formatted correctly as [quantity](https://eips.ethereum.org/EIPS/eip-1474#quantity)
691        let position = U256::from_big_endian(location.as_bytes());
692        let position = utils::serialize(&position);
693        let from = utils::serialize(&from);
694        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
695
696        // get the hex encoded value
697        let value: String = self.request("eth_getStorageAt", [from, position, block]).await?;
698        // decode and left-pad to 32 bytes
699        let bytes = hex::decode(value)?;
700        if bytes.len() > 32 {
701            Err(hex::FromHexError::InvalidStringLength.into())
702        } else {
703            let mut buf = [0; 32];
704            buf[32 - bytes.len()..].copy_from_slice(&bytes);
705            Ok(H256(buf))
706        }
707    }
708
709    async fn get_code<T: Into<NameOrAddress> + Send + Sync>(
710        &self,
711        at: T,
712        block: Option<BlockId>,
713    ) -> Result<Bytes, ProviderError> {
714        let at = match at.into() {
715            NameOrAddress::Name(ens_name) => self.resolve_name(&ens_name).await?,
716            NameOrAddress::Address(addr) => addr,
717        };
718
719        let at = utils::serialize(&at);
720        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
721        self.request("eth_getCode", [at, block]).await
722    }
723
724    async fn get_proof<T: Into<NameOrAddress> + Send + Sync>(
725        &self,
726        from: T,
727        locations: Vec<H256>,
728        block: Option<BlockId>,
729    ) -> Result<EIP1186ProofResponse, ProviderError> {
730        let from = match from.into() {
731            NameOrAddress::Name(ens_name) => self.resolve_name(&ens_name).await?,
732            NameOrAddress::Address(addr) => addr,
733        };
734
735        let from = utils::serialize(&from);
736        let locations = locations.iter().map(|location| utils::serialize(&location)).collect();
737        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
738
739        self.request("eth_getProof", [from, locations, block]).await
740    }
741
742    /// Returns an indication if this node is currently mining.
743    async fn mining(&self) -> Result<bool, Self::Error> {
744        self.request("eth_mining", ()).await
745    }
746
747    async fn import_raw_key(
748        &self,
749        private_key: Bytes,
750        passphrase: String,
751    ) -> Result<Address, ProviderError> {
752        // private key should not be prefixed with 0x - it is also up to the user to pass in a key
753        // of the correct length
754
755        // the private key argument is supposed to be a string
756        let private_key_hex = hex::encode(private_key);
757        let private_key = utils::serialize(&private_key_hex);
758        let passphrase = utils::serialize(&passphrase);
759        self.request("personal_importRawKey", [private_key, passphrase]).await
760    }
761
762    async fn unlock_account<T: Into<Address> + Send + Sync>(
763        &self,
764        account: T,
765        passphrase: String,
766        duration: Option<u64>,
767    ) -> Result<bool, ProviderError> {
768        let account = utils::serialize(&account.into());
769        let duration = utils::serialize(&duration.unwrap_or(0));
770        let passphrase = utils::serialize(&passphrase);
771        self.request("personal_unlockAccount", [account, passphrase, duration]).await
772    }
773
774    async fn add_peer(&self, enode_url: String) -> Result<bool, Self::Error> {
775        let enode_url = utils::serialize(&enode_url);
776        self.request("admin_addPeer", [enode_url]).await
777    }
778
779    async fn add_trusted_peer(&self, enode_url: String) -> Result<bool, Self::Error> {
780        let enode_url = utils::serialize(&enode_url);
781        self.request("admin_addTrustedPeer", [enode_url]).await
782    }
783
784    async fn node_info(&self) -> Result<NodeInfo, Self::Error> {
785        self.request("admin_nodeInfo", ()).await
786    }
787
788    async fn peers(&self) -> Result<Vec<PeerInfo>, Self::Error> {
789        self.request("admin_peers", ()).await
790    }
791
792    async fn remove_peer(&self, enode_url: String) -> Result<bool, Self::Error> {
793        let enode_url = utils::serialize(&enode_url);
794        self.request("admin_removePeer", [enode_url]).await
795    }
796
797    async fn remove_trusted_peer(&self, enode_url: String) -> Result<bool, Self::Error> {
798        let enode_url = utils::serialize(&enode_url);
799        self.request("admin_removeTrustedPeer", [enode_url]).await
800    }
801
802    async fn start_mining(&self) -> Result<(), Self::Error> {
803        self.request("miner_start", ()).await
804    }
805
806    async fn stop_mining(&self) -> Result<(), Self::Error> {
807        self.request("miner_stop", ()).await
808    }
809
810    async fn resolve_name(&self, ens_name: &str) -> Result<Address, ProviderError> {
811        self.query_resolver(ParamType::Address, ens_name, ens::ADDR_SELECTOR).await
812    }
813
814    async fn lookup_address(&self, address: Address) -> Result<String, ProviderError> {
815        let ens_name = ens::reverse_address(address);
816        let domain: String =
817            self.query_resolver(ParamType::String, &ens_name, ens::NAME_SELECTOR).await?;
818        let reverse_address = self.resolve_name(&domain).await?;
819        if address != reverse_address {
820            Err(ProviderError::EnsNotOwned(domain))
821        } else {
822            Ok(domain)
823        }
824    }
825
826    async fn resolve_avatar(&self, ens_name: &str) -> Result<Url, ProviderError> {
827        let (field, owner) =
828            try_join!(self.resolve_field(ens_name, "avatar"), self.resolve_name(ens_name))?;
829        let url = Url::from_str(&field).map_err(|e| ProviderError::CustomError(e.to_string()))?;
830        match url.scheme() {
831            "https" | "data" => Ok(url),
832            "ipfs" => erc::http_link_ipfs(url).map_err(ProviderError::CustomError),
833            "eip155" => {
834                let token =
835                    erc::ERCNFT::from_str(url.path()).map_err(ProviderError::CustomError)?;
836                match token.type_ {
837                    erc::ERCNFTType::ERC721 => {
838                        let tx = TransactionRequest {
839                            data: Some(
840                                [&erc::ERC721_OWNER_SELECTOR[..], &token.id].concat().into(),
841                            ),
842                            to: Some(NameOrAddress::Address(token.contract)),
843                            ..Default::default()
844                        };
845                        let data = self.call(&tx.into(), None).await?;
846                        if decode_bytes::<Address>(ParamType::Address, data) != owner {
847                            return Err(ProviderError::CustomError("Incorrect owner.".to_string()))
848                        }
849                    }
850                    erc::ERCNFTType::ERC1155 => {
851                        let tx = TransactionRequest {
852                            data: Some(
853                                [
854                                    &erc::ERC1155_BALANCE_SELECTOR[..],
855                                    &[0x0; 12],
856                                    &owner.0,
857                                    &token.id,
858                                ]
859                                .concat()
860                                .into(),
861                            ),
862                            to: Some(NameOrAddress::Address(token.contract)),
863                            ..Default::default()
864                        };
865                        let data = self.call(&tx.into(), None).await?;
866                        if decode_bytes::<u64>(ParamType::Uint(64), data) == 0 {
867                            return Err(ProviderError::CustomError("Incorrect balance.".to_string()))
868                        }
869                    }
870                }
871
872                let image_url = self.resolve_nft(token).await?;
873                match image_url.scheme() {
874                    "https" | "data" => Ok(image_url),
875                    "ipfs" => erc::http_link_ipfs(image_url).map_err(ProviderError::CustomError),
876                    _ => Err(ProviderError::CustomError(
877                        "Unsupported scheme for the image".to_string(),
878                    )),
879                }
880            }
881            _ => Err(ProviderError::CustomError("Unsupported scheme".to_string())),
882        }
883    }
884
885    async fn resolve_nft(&self, token: erc::ERCNFT) -> Result<Url, ProviderError> {
886        let selector = token.type_.resolution_selector();
887        let tx = TransactionRequest {
888            data: Some([&selector[..], &token.id].concat().into()),
889            to: Some(NameOrAddress::Address(token.contract)),
890            ..Default::default()
891        };
892        let data = self.call(&tx.into(), None).await?;
893        let mut metadata_url = Url::parse(&decode_bytes::<String>(ParamType::String, data))
894            .map_err(|e| ProviderError::CustomError(format!("Invalid metadata url: {e}")))?;
895
896        if token.type_ == erc::ERCNFTType::ERC1155 {
897            metadata_url.set_path(&metadata_url.path().replace("%7Bid%7D", &hex::encode(token.id)));
898        }
899        if metadata_url.scheme() == "ipfs" {
900            metadata_url = erc::http_link_ipfs(metadata_url).map_err(ProviderError::CustomError)?;
901        }
902        let metadata: erc::Metadata = reqwest::get(metadata_url).await?.json().await?;
903        Url::parse(&metadata.image).map_err(|e| ProviderError::CustomError(e.to_string()))
904    }
905
906    async fn resolve_field(&self, ens_name: &str, field: &str) -> Result<String, ProviderError> {
907        let field: String = self
908            .query_resolver_parameters(
909                ParamType::String,
910                ens_name,
911                ens::FIELD_SELECTOR,
912                Some(&ens::parameterhash(field)),
913            )
914            .await?;
915        Ok(field)
916    }
917
918    async fn txpool_content(&self) -> Result<TxpoolContent, ProviderError> {
919        self.request("txpool_content", ()).await
920    }
921
922    async fn txpool_inspect(&self) -> Result<TxpoolInspect, ProviderError> {
923        self.request("txpool_inspect", ()).await
924    }
925
926    async fn txpool_status(&self) -> Result<TxpoolStatus, ProviderError> {
927        self.request("txpool_status", ()).await
928    }
929
930    async fn debug_trace_transaction(
931        &self,
932        tx_hash: TxHash,
933        trace_options: GethDebugTracingOptions,
934    ) -> Result<GethTrace, ProviderError> {
935        let tx_hash = utils::serialize(&tx_hash);
936        let trace_options = utils::serialize(&trace_options);
937        self.request("debug_traceTransaction", [tx_hash, trace_options]).await
938    }
939
940    async fn debug_trace_call<T: Into<TypedTransaction> + Send + Sync>(
941        &self,
942        req: T,
943        block: Option<BlockId>,
944        trace_options: GethDebugTracingCallOptions,
945    ) -> Result<GethTrace, ProviderError> {
946        let req = req.into();
947        let req = utils::serialize(&req);
948        let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));
949        let trace_options = utils::serialize(&trace_options);
950        self.request("debug_traceCall", [req, block, trace_options]).await
951    }
952
953    async fn debug_trace_block_by_number(
954        &self,
955        block: Option<BlockNumber>,
956        trace_options: GethDebugTracingOptions,
957    ) -> Result<Vec<GethTrace>, ProviderError> {
958        let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
959        let trace_options = utils::serialize(&trace_options);
960        self.request("debug_traceBlockByNumber", [block, trace_options]).await
961    }
962
963    async fn debug_trace_block_by_hash(
964        &self,
965        block: H256,
966        trace_options: GethDebugTracingOptions,
967    ) -> Result<Vec<GethTrace>, ProviderError> {
968        let block = utils::serialize(&block);
969        let trace_options = utils::serialize(&trace_options);
970        self.request("debug_traceBlockByHash", [block, trace_options]).await
971    }
972
973    async fn trace_call<T: Into<TypedTransaction> + Send + Sync>(
974        &self,
975        req: T,
976        trace_type: Vec<TraceType>,
977        block: Option<BlockNumber>,
978    ) -> Result<BlockTrace, ProviderError> {
979        let req = req.into();
980        let req = utils::serialize(&req);
981        let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
982        let trace_type = utils::serialize(&trace_type);
983        self.request("trace_call", [req, trace_type, block]).await
984    }
985
986    async fn trace_call_many<T: Into<TypedTransaction> + Send + Sync>(
987        &self,
988        req: Vec<(T, Vec<TraceType>)>,
989        block: Option<BlockNumber>,
990    ) -> Result<Vec<BlockTrace>, ProviderError> {
991        let req: Vec<(TypedTransaction, Vec<TraceType>)> =
992            req.into_iter().map(|(tx, trace_type)| (tx.into(), trace_type)).collect();
993        let req = utils::serialize(&req);
994        let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
995        self.request("trace_callMany", [req, block]).await
996    }
997
998    async fn trace_raw_transaction(
999        &self,
1000        data: Bytes,
1001        trace_type: Vec<TraceType>,
1002    ) -> Result<BlockTrace, ProviderError> {
1003        let data = utils::serialize(&data);
1004        let trace_type = utils::serialize(&trace_type);
1005        self.request("trace_rawTransaction", [data, trace_type]).await
1006    }
1007
1008    async fn trace_replay_transaction(
1009        &self,
1010        hash: H256,
1011        trace_type: Vec<TraceType>,
1012    ) -> Result<BlockTrace, ProviderError> {
1013        let hash = utils::serialize(&hash);
1014        let trace_type = utils::serialize(&trace_type);
1015        self.request("trace_replayTransaction", [hash, trace_type]).await
1016    }
1017
1018    async fn trace_replay_block_transactions(
1019        &self,
1020        block: BlockNumber,
1021        trace_type: Vec<TraceType>,
1022    ) -> Result<Vec<BlockTrace>, ProviderError> {
1023        let block = utils::serialize(&block);
1024        let trace_type = utils::serialize(&trace_type);
1025        self.request("trace_replayBlockTransactions", [block, trace_type]).await
1026    }
1027
1028    async fn trace_block(&self, block: BlockNumber) -> Result<Vec<Trace>, ProviderError> {
1029        let block = utils::serialize(&block);
1030        self.request("trace_block", [block]).await
1031    }
1032
1033    async fn trace_filter(&self, filter: TraceFilter) -> Result<Vec<Trace>, ProviderError> {
1034        let filter = utils::serialize(&filter);
1035        self.request("trace_filter", vec![filter]).await
1036    }
1037
1038    async fn trace_get<T: Into<U64> + Send + Sync>(
1039        &self,
1040        hash: H256,
1041        index: Vec<T>,
1042    ) -> Result<Trace, ProviderError> {
1043        let hash = utils::serialize(&hash);
1044        let index: Vec<U64> = index.into_iter().map(|i| i.into()).collect();
1045        let index = utils::serialize(&index);
1046        self.request("trace_get", vec![hash, index]).await
1047    }
1048
1049    async fn trace_transaction(&self, hash: H256) -> Result<Vec<Trace>, ProviderError> {
1050        let hash = utils::serialize(&hash);
1051        self.request("trace_transaction", vec![hash]).await
1052    }
1053
1054    async fn subscribe<T, R>(
1055        &self,
1056        params: T,
1057    ) -> Result<SubscriptionStream<'_, P, R>, ProviderError>
1058    where
1059        T: Debug + Serialize + Send + Sync,
1060        R: DeserializeOwned + Send + Sync,
1061        P: PubsubClient,
1062    {
1063        let id: U256 = self.request("eth_subscribe", params).await?;
1064        SubscriptionStream::new(id, self).map_err(Into::into)
1065    }
1066
1067    async fn unsubscribe<T>(&self, id: T) -> Result<bool, ProviderError>
1068    where
1069        T: Into<U256> + Send + Sync,
1070        P: PubsubClient,
1071    {
1072        self.request("eth_unsubscribe", [id.into()]).await
1073    }
1074
1075    async fn subscribe_blocks(
1076        &self,
1077    ) -> Result<SubscriptionStream<'_, P, Block<TxHash>>, ProviderError>
1078    where
1079        P: PubsubClient,
1080    {
1081        self.subscribe(["newHeads"]).await
1082    }
1083
1084    async fn subscribe_pending_txs(
1085        &self,
1086    ) -> Result<SubscriptionStream<'_, P, TxHash>, ProviderError>
1087    where
1088        P: PubsubClient,
1089    {
1090        self.subscribe(["newPendingTransactions"]).await
1091    }
1092
1093    async fn subscribe_full_pending_txs(
1094        &self,
1095    ) -> Result<SubscriptionStream<'_, P, Transaction>, ProviderError>
1096    where
1097        P: PubsubClient,
1098    {
1099        self.subscribe([utils::serialize(&"newPendingTransactions"), utils::serialize(&true)]).await
1100    }
1101
1102    async fn subscribe_logs<'a>(
1103        &'a self,
1104        filter: &Filter,
1105    ) -> Result<SubscriptionStream<'a, P, Log>, ProviderError>
1106    where
1107        P: PubsubClient,
1108    {
1109        let loaded_logs = match filter.block_option {
1110            FilterBlockOption::Range { from_block, to_block: _ } => {
1111                if from_block.is_none() {
1112                    vec![]
1113                } else {
1114                    self.get_logs(filter).await?
1115                }
1116            }
1117            FilterBlockOption::AtBlockHash(_block_hash) => self.get_logs(filter).await?,
1118        };
1119        let loaded_logs = VecDeque::from(loaded_logs);
1120
1121        let logs = utils::serialize(&"logs"); // TODO: Make this a static
1122        let filter = utils::serialize(filter);
1123        self.subscribe([logs, filter]).await.map(|mut stream| {
1124            stream.set_loaded_elements(loaded_logs);
1125            stream
1126        })
1127    }
1128
1129    async fn fee_history<T: Into<U256> + Send + Sync>(
1130        &self,
1131        block_count: T,
1132        last_block: BlockNumber,
1133        reward_percentiles: &[f64],
1134    ) -> Result<FeeHistory, Self::Error> {
1135        let block_count = block_count.into();
1136        let last_block = utils::serialize(&last_block);
1137        let reward_percentiles = utils::serialize(&reward_percentiles);
1138
1139        // The blockCount param is expected to be an unsigned integer up to geth v1.10.6.
1140        // Geth v1.10.7 onwards, this has been updated to a hex encoded form. Failure to
1141        // decode the param from client side would fallback to the old API spec.
1142        match self
1143            .request::<_, FeeHistory>(
1144                "eth_feeHistory",
1145                [utils::serialize(&block_count), last_block.clone(), reward_percentiles.clone()],
1146            )
1147            .await
1148        {
1149            success @ Ok(_) => success,
1150            err @ Err(_) => {
1151                let fallback = self
1152                    .request::<_, FeeHistory>(
1153                        "eth_feeHistory",
1154                        [utils::serialize(&block_count.as_u64()), last_block, reward_percentiles],
1155                    )
1156                    .await;
1157
1158                if fallback.is_err() {
1159                    // if the older fallback also resulted in an error, we return the error from the
1160                    // initial attempt
1161                    return err
1162                }
1163                fallback
1164            }
1165        }
1166    }
1167}
1168
1169impl<P: JsonRpcClient> Provider<P> {
1170    async fn query_resolver<T: Detokenize>(
1171        &self,
1172        param: ParamType,
1173        ens_name: &str,
1174        selector: Selector,
1175    ) -> Result<T, ProviderError> {
1176        self.query_resolver_parameters(param, ens_name, selector, None).await
1177    }
1178
1179    async fn query_resolver_parameters<T: Detokenize>(
1180        &self,
1181        param: ParamType,
1182        ens_name: &str,
1183        selector: Selector,
1184        parameters: Option<&[u8]>,
1185    ) -> Result<T, ProviderError> {
1186        // Get the ENS address, prioritize the local override variable
1187        let ens_addr = self.ens.unwrap_or(ens::ENS_ADDRESS);
1188
1189        // first get the resolver responsible for this name
1190        // the call will return a Bytes array which we convert to an address
1191        let data = self.call(&ens::get_resolver(ens_addr, ens_name).into(), None).await?;
1192
1193        // otherwise, decode_bytes panics
1194        if data.0.is_empty() {
1195            return Err(ProviderError::EnsError(ens_name.to_string()))
1196        }
1197
1198        let resolver_address: Address = decode_bytes(ParamType::Address, data);
1199        if resolver_address == Address::zero() {
1200            return Err(ProviderError::EnsError(ens_name.to_string()))
1201        }
1202
1203        if let ParamType::Address = param {
1204            // Reverse resolver reverts when calling `supportsInterface(bytes4)`
1205            self.validate_resolver(resolver_address, selector, ens_name).await?;
1206        }
1207
1208        // resolve
1209        let data = self
1210            .call(&ens::resolve(resolver_address, selector, ens_name, parameters).into(), None)
1211            .await?;
1212
1213        Ok(decode_bytes(param, data))
1214    }
1215
1216    /// Validates that the resolver supports `selector`.
1217    async fn validate_resolver(
1218        &self,
1219        resolver_address: Address,
1220        selector: Selector,
1221        ens_name: &str,
1222    ) -> Result<(), ProviderError> {
1223        let data =
1224            self.call(&ens::supports_interface(resolver_address, selector).into(), None).await?;
1225
1226        if data.is_empty() {
1227            return Err(ProviderError::EnsError(format!(
1228                "`{ens_name}` resolver ({resolver_address:?}) is invalid."
1229            )))
1230        }
1231
1232        let supports_selector = abi::decode(&[ParamType::Bool], data.as_ref())
1233            .map(|token| token[0].clone().into_bool().unwrap_or_default())
1234            .unwrap_or_default();
1235
1236        if !supports_selector {
1237            return Err(ProviderError::EnsError(format!(
1238                "`{}` resolver ({:?}) does not support selector {}.",
1239                ens_name,
1240                resolver_address,
1241                hex::encode(selector)
1242            )))
1243        }
1244
1245        Ok(())
1246    }
1247
1248    #[cfg(test)]
1249    /// Anvil and Ganache-only function for mining empty blocks
1250    pub async fn mine(&self, num_blocks: usize) -> Result<(), ProviderError> {
1251        for _ in 0..num_blocks {
1252            self.inner.request::<_, U256>("evm_mine", None::<()>).await.map_err(Into::into)?;
1253        }
1254        Ok(())
1255    }
1256
1257    /// Sets the ENS Address (default: mainnet)
1258    #[must_use]
1259    pub fn ens<T: Into<Address>>(mut self, ens: T) -> Self {
1260        self.ens = Some(ens.into());
1261        self
1262    }
1263
1264    /// Sets the default polling interval for event filters and pending transactions
1265    /// (default: 7 seconds)
1266    pub fn set_interval<T: Into<Duration>>(&mut self, interval: T) -> &mut Self {
1267        self.interval = Some(interval.into());
1268        self
1269    }
1270
1271    /// Sets the default polling interval for event filters and pending transactions
1272    /// (default: 7 seconds)
1273    #[must_use]
1274    pub fn interval<T: Into<Duration>>(mut self, interval: T) -> Self {
1275        self.set_interval(interval);
1276        self
1277    }
1278
1279    /// Gets the polling interval which the provider currently uses for event filters
1280    /// and pending transactions (default: 7 seconds)
1281    pub fn get_interval(&self) -> Duration {
1282        self.interval.unwrap_or(DEFAULT_POLL_INTERVAL)
1283    }
1284}
1285
1286#[cfg(all(feature = "ipc", any(unix, windows)))]
1287impl Provider<crate::Ipc> {
1288    #[cfg_attr(unix, doc = "Connects to the Unix socket at the provided path.")]
1289    #[cfg_attr(windows, doc = "Connects to the named pipe at the provided path.\n")]
1290    #[cfg_attr(
1291        windows,
1292        doc = r"Note: the path must be the fully qualified, like: `\\.\pipe\<name>`."
1293    )]
1294    pub async fn connect_ipc(path: impl AsRef<std::path::Path>) -> Result<Self, ProviderError> {
1295        let ipc = crate::Ipc::connect(path).await?;
1296        Ok(Self::new(ipc))
1297    }
1298}
1299
1300impl Provider<HttpProvider> {
1301    /// The Url to which requests are made
1302    pub fn url(&self) -> &Url {
1303        self.inner.url()
1304    }
1305
1306    /// Mutable access to the Url to which requests are made
1307    pub fn url_mut(&mut self) -> &mut Url {
1308        self.inner.url_mut()
1309    }
1310}
1311
1312impl<Read, Write> Provider<RwClient<Read, Write>>
1313where
1314    Read: JsonRpcClient + 'static,
1315    <Read as JsonRpcClient>::Error: Sync + Send + 'static,
1316    Write: JsonRpcClient + 'static,
1317    <Write as JsonRpcClient>::Error: Sync + Send + 'static,
1318{
1319    /// Creates a new [Provider] with a [RwClient]
1320    pub fn rw(r: Read, w: Write) -> Self {
1321        Self::new(RwClient::new(r, w))
1322    }
1323}
1324
1325impl<T: JsonRpcClientWrapper> Provider<QuorumProvider<T>> {
1326    /// Provider that uses a quorum
1327    pub fn quorum(inner: QuorumProvider<T>) -> Self {
1328        Self::new(inner)
1329    }
1330}
1331
1332impl Provider<MockProvider> {
1333    /// Returns a `Provider` instantiated with an internal "mock" transport.
1334    ///
1335    /// # Example
1336    ///
1337    /// ```
1338    /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
1339    /// use ethers_core::types::U64;
1340    /// use ethers_providers::{Middleware, Provider};
1341    /// // Instantiate the provider
1342    /// let (provider, mock) = Provider::mocked();
1343    /// // Push the mock response
1344    /// mock.push(U64::from(12))?;
1345    /// // Make the call
1346    /// let blk = provider.get_block_number().await.unwrap();
1347    /// // The response matches
1348    /// assert_eq!(blk.as_u64(), 12);
1349    /// // and the request as well!
1350    /// mock.assert_request("eth_blockNumber", ()).unwrap();
1351    /// # Ok(())
1352    /// # }
1353    /// ```
1354    pub fn mocked() -> (Self, MockProvider) {
1355        let mock = MockProvider::new();
1356        let mock_clone = mock.clone();
1357        (Self::new(mock), mock_clone)
1358    }
1359}
1360
1361/// infallible conversion of Bytes to Address/String
1362///
1363/// # Panics
1364///
1365/// If the provided bytes were not an interpretation of an address
1366fn decode_bytes<T: Detokenize>(param: ParamType, bytes: Bytes) -> T {
1367    let tokens = abi::decode(&[param], bytes.as_ref())
1368        .expect("could not abi-decode bytes to address tokens");
1369    T::from_tokens(tokens).expect("could not parse tokens as address")
1370}
1371
1372impl TryFrom<&str> for Provider<HttpProvider> {
1373    type Error = ParseError;
1374
1375    fn try_from(src: &str) -> Result<Self, Self::Error> {
1376        Ok(Provider::new(HttpProvider::new(Url::parse(src)?)))
1377    }
1378}
1379
1380impl TryFrom<String> for Provider<HttpProvider> {
1381    type Error = ParseError;
1382
1383    fn try_from(src: String) -> Result<Self, Self::Error> {
1384        Provider::try_from(src.as_str())
1385    }
1386}
1387
1388impl<'a> TryFrom<&'a String> for Provider<HttpProvider> {
1389    type Error = ParseError;
1390
1391    fn try_from(src: &'a String) -> Result<Self, Self::Error> {
1392        Provider::try_from(src.as_str())
1393    }
1394}
1395
1396#[cfg(not(target_arch = "wasm32"))]
1397impl Provider<RetryClient<HttpProvider>> {
1398    /// Create a new [`RetryClient`] by connecting to the provided URL. Errors
1399    /// if `src` is not a valid URL
1400    pub fn new_client(src: &str, max_retry: u32, initial_backoff: u64) -> Result<Self, ParseError> {
1401        Ok(Provider::new(RetryClient::new(
1402            HttpProvider::new(Url::parse(src)?),
1403            Box::new(HttpRateLimitRetryPolicy),
1404            max_retry,
1405            initial_backoff,
1406        )))
1407    }
1408}
1409
1410mod sealed {
1411    use crate::{Http, Provider};
1412    /// private trait to ensure extension trait is not implement outside of this crate
1413    pub trait Sealed {}
1414    impl Sealed for Provider<Http> {}
1415}
1416
1417/// Extension trait for `Provider`
1418///
1419/// **Note**: this is currently sealed until <https://github.com/gakonst/ethers-rs/pull/1267> is finalized
1420///
1421/// # Example
1422///
1423/// Automatically configure poll interval via `eth_getChainId`
1424///
1425/// Note that this will send an RPC to retrieve the chain id.
1426///
1427/// ```no_run
1428///  # use ethers_providers::{Http, Provider, ProviderExt};
1429///  # async fn t() {
1430/// let http_provider = Provider::<Http>::connect("https://eth.llamarpc.com").await;
1431/// # }
1432/// ```
1433///
1434/// This is essentially short for
1435///
1436/// ```no_run
1437/// use std::convert::TryFrom;
1438/// use ethers_core::types::Chain;
1439/// use ethers_providers::{Http, Provider, ProviderExt};
1440/// let http_provider = Provider::<Http>::try_from("https://eth.llamarpc.com").unwrap().set_chain(Chain::Mainnet);
1441/// ```
1442#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
1443#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
1444pub trait ProviderExt: sealed::Sealed {
1445    /// The error type that can occur when creating a provider
1446    type Error: Debug;
1447
1448    /// Creates a new instance connected to the given `url`, exit on error
1449    async fn connect(url: &str) -> Self
1450    where
1451        Self: Sized,
1452    {
1453        Self::try_connect(url).await.unwrap()
1454    }
1455
1456    /// Try to create a new `Provider`
1457    async fn try_connect(url: &str) -> Result<Self, Self::Error>
1458    where
1459        Self: Sized;
1460
1461    /// Customize `Provider` settings for chain.
1462    ///
1463    /// E.g. [`Chain::average_blocktime_hint()`] returns the average block time which can be used to
1464    /// tune the polling interval.
1465    ///
1466    /// Returns the customized `Provider`
1467    fn for_chain(mut self, chain: impl Into<Chain>) -> Self
1468    where
1469        Self: Sized,
1470    {
1471        self.set_chain(chain);
1472        self
1473    }
1474
1475    /// Customized `Provider` settings for chain
1476    fn set_chain(&mut self, chain: impl Into<Chain>) -> &mut Self;
1477}
1478
1479#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
1480#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
1481impl ProviderExt for Provider<HttpProvider> {
1482    type Error = ParseError;
1483
1484    async fn try_connect(url: &str) -> Result<Self, Self::Error>
1485    where
1486        Self: Sized,
1487    {
1488        let mut provider = Provider::try_from(url)?;
1489        if is_local_endpoint(url) {
1490            provider.set_interval(DEFAULT_LOCAL_POLL_INTERVAL);
1491        } else if let Some(chain) =
1492            provider.get_chainid().await.ok().and_then(|id| Chain::try_from(id).ok())
1493        {
1494            provider.set_chain(chain);
1495        }
1496
1497        Ok(provider)
1498    }
1499
1500    fn set_chain(&mut self, chain: impl Into<Chain>) -> &mut Self {
1501        let chain = chain.into();
1502        if let Some(blocktime) = chain.average_blocktime_hint() {
1503            // use half of the block time
1504            self.set_interval(blocktime / 2);
1505        }
1506        self
1507    }
1508}
1509
1510/// Returns true if the endpoint is local
1511///
1512/// # Example
1513///
1514/// ```
1515/// use ethers_providers::is_local_endpoint;
1516/// assert!(is_local_endpoint("http://localhost:8545"));
1517/// assert!(is_local_endpoint("http://test.localdev.me"));
1518/// assert!(is_local_endpoint("http://169.254.0.0:8545"));
1519/// assert!(is_local_endpoint("http://127.0.0.1:8545"));
1520/// assert!(!is_local_endpoint("http://206.71.50.230:8545"));
1521/// assert!(!is_local_endpoint("http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"));
1522/// assert!(is_local_endpoint("http://[::1]"));
1523/// assert!(!is_local_endpoint("havenofearlucishere"));
1524/// ```
1525#[inline]
1526pub fn is_local_endpoint(endpoint: &str) -> bool {
1527    if let Ok(url) = Url::parse(endpoint) {
1528        if let Some(host) = url.host() {
1529            match host {
1530                Host::Domain(domain) => {
1531                    return domain.contains("localhost") || domain.contains("localdev.me")
1532                }
1533                Host::Ipv4(ipv4) => {
1534                    return ipv4 == Ipv4Addr::LOCALHOST ||
1535                        ipv4.is_link_local() ||
1536                        ipv4.is_loopback() ||
1537                        ipv4.is_private()
1538                }
1539                Host::Ipv6(ipv6) => return ipv6.is_loopback(),
1540            }
1541        }
1542    }
1543    false
1544}
1545
1546#[cfg(test)]
1547mod tests {
1548    use super::*;
1549    use crate::Http;
1550    use ethers_core::{
1551        types::{
1552            transaction::eip2930::AccessList, Eip1559TransactionRequest,
1553            GethDebugBuiltInTracerConfig, GethDebugBuiltInTracerType, GethDebugTracerConfig,
1554            GethDebugTracerType, PreStateConfig,
1555        },
1556        utils::{Anvil, Genesis, Geth, GethInstance},
1557    };
1558    use futures_util::StreamExt;
1559    use std::path::PathBuf;
1560
1561    #[test]
1562    fn convert_h256_u256_quantity() {
1563        let hash: H256 = H256::zero();
1564        let quantity = U256::from_big_endian(hash.as_bytes());
1565        assert_eq!(format!("{quantity:#x}"), "0x0");
1566        assert_eq!(utils::serialize(&quantity).to_string(), "\"0x0\"");
1567
1568        let address: Address = "0x295a70b2de5e3953354a6a8344e616ed314d7251".parse().unwrap();
1569        let block = BlockNumber::Latest;
1570        let params =
1571            [utils::serialize(&address), utils::serialize(&quantity), utils::serialize(&block)];
1572
1573        let params = serde_json::to_string(&params).unwrap();
1574        assert_eq!(params, r#"["0x295a70b2de5e3953354a6a8344e616ed314d7251","0x0","latest"]"#);
1575    }
1576
1577    // Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
1578    #[tokio::test]
1579    async fn mainnet_resolve_name() {
1580        let provider = crate::test_provider::MAINNET.provider();
1581
1582        let addr = provider.resolve_name("registrar.firefly.eth").await.unwrap();
1583        assert_eq!(addr, "6fC21092DA55B392b045eD78F4732bff3C580e2c".parse().unwrap());
1584
1585        // registrar not found
1586        provider.resolve_name("asdfasdffads").await.unwrap_err();
1587
1588        // name not found
1589        provider.resolve_name("asdfasdf.registrar.firefly.eth").await.unwrap_err();
1590    }
1591
1592    // Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
1593    #[tokio::test]
1594    async fn mainnet_lookup_address() {
1595        let provider = crate::MAINNET.provider();
1596
1597        let name = provider
1598            .lookup_address("6fC21092DA55B392b045eD78F4732bff3C580e2c".parse().unwrap())
1599            .await
1600            .unwrap();
1601
1602        assert_eq!(name, "registrar.firefly.eth");
1603
1604        provider
1605            .lookup_address("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".parse().unwrap())
1606            .await
1607            .unwrap_err();
1608    }
1609
1610    #[tokio::test]
1611    #[ignore]
1612    async fn mainnet_resolve_avatar() {
1613        let provider = crate::MAINNET.provider();
1614
1615        for (ens_name, res) in &[
1616            // HTTPS
1617            ("alisha.eth", "https://ipfs.io/ipfs/QmeQm91kAdPGnUKsE74WvkqYKUeHvc2oHd2FW11V3TrqkQ"),
1618            // ERC-1155
1619            ("nick.eth", "https://img.seadn.io/files/3ae7be6c41ad4767bf3ecbc0493b4bfb.png"),
1620            // HTTPS
1621            ("parishilton.eth", "https://i.imgur.com/YW3Hzph.jpg"),
1622            // ERC-721 with IPFS link
1623            ("ikehaya-nft.eth", "https://ipfs.io/ipfs/QmdKkwCE8uVhgYd7tWBfhtHdQZDnbNukWJ8bvQmR6nZKsk"),
1624            // ERC-1155 with IPFS link
1625            ("vitalik.eth", "https://ipfs.io/ipfs/QmSP4nq9fnN9dAiCj42ug9Wa79rqmQerZXZch82VqpiH7U/image.gif"),
1626            // IPFS
1627            ("cdixon.eth", "https://ipfs.io/ipfs/QmYA6ZpEARgHvRHZQdFPynMMX8NtdL2JCadvyuyG2oA88u"),
1628            ("0age.eth", "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOmJsYWNrIiB2aWV3Qm94PSIwIDAgNTAwIDUwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSIxNTUiIHk9IjYwIiB3aWR0aD0iMTkwIiBoZWlnaHQ9IjM5MCIgZmlsbD0iIzY5ZmYzNyIvPjwvc3ZnPg==")
1629        ] {
1630        println!("Resolving: {ens_name}");
1631        assert_eq!(provider.resolve_avatar(ens_name).await.unwrap(), Url::parse(res).unwrap());
1632    }
1633    }
1634
1635    #[tokio::test]
1636    #[cfg_attr(feature = "celo", ignore)]
1637    async fn test_new_block_filter() {
1638        let num_blocks = 3;
1639        let geth = Anvil::new().block_time(2u64).spawn();
1640        let provider = Provider::<Http>::try_from(geth.endpoint())
1641            .unwrap()
1642            .interval(Duration::from_millis(1000));
1643
1644        let start_block = provider.get_block_number().await.unwrap();
1645
1646        let stream = provider.watch_blocks().await.unwrap().stream();
1647
1648        let hashes: Vec<H256> = stream.take(num_blocks).collect::<Vec<H256>>().await;
1649        for (i, hash) in hashes.iter().enumerate() {
1650            let block = provider.get_block(start_block + i as u64 + 1).await.unwrap().unwrap();
1651            assert_eq!(*hash, block.hash.unwrap());
1652        }
1653    }
1654
1655    #[tokio::test]
1656    async fn test_is_signer() {
1657        use ethers_core::utils::Anvil;
1658        use std::str::FromStr;
1659
1660        let anvil = Anvil::new().spawn();
1661        let provider =
1662            Provider::<Http>::try_from(anvil.endpoint()).unwrap().with_sender(anvil.addresses()[0]);
1663        assert!(provider.is_signer().await);
1664
1665        let provider = Provider::<Http>::try_from(anvil.endpoint()).unwrap();
1666        assert!(!provider.is_signer().await);
1667
1668        let sender = Address::from_str("635B4764D1939DfAcD3a8014726159abC277BecC")
1669            .expect("should be able to parse hex address");
1670        let provider = Provider::<Http>::try_from(
1671            "https://ropsten.infura.io/v3/fd8b88b56aa84f6da87b60f5441d6778",
1672        )
1673        .unwrap()
1674        .with_sender(sender);
1675        assert!(!provider.is_signer().await);
1676    }
1677
1678    #[tokio::test]
1679    async fn test_new_pending_txs_filter() {
1680        let num_txs = 5;
1681
1682        let geth = Anvil::new().block_time(2u64).spawn();
1683        let provider = Provider::<Http>::try_from(geth.endpoint())
1684            .unwrap()
1685            .interval(Duration::from_millis(1000));
1686        let accounts = provider.get_accounts().await.unwrap();
1687
1688        let stream = provider.watch_pending_transactions().await.unwrap().stream();
1689
1690        let mut tx_hashes = Vec::new();
1691        let tx = TransactionRequest::new().from(accounts[0]).to(accounts[0]).value(1e18 as u64);
1692
1693        for _ in 0..num_txs {
1694            tx_hashes.push(provider.send_transaction(tx.clone(), None).await.unwrap());
1695        }
1696
1697        let hashes: Vec<H256> = stream.take(num_txs).collect::<Vec<H256>>().await;
1698        assert_eq!(tx_hashes, hashes);
1699    }
1700
1701    #[tokio::test]
1702    async fn receipt_on_unmined_tx() {
1703        use ethers_core::{
1704            types::TransactionRequest,
1705            utils::{parse_ether, Anvil},
1706        };
1707        let anvil = Anvil::new().block_time(2u64).spawn();
1708        let provider = Provider::<Http>::try_from(anvil.endpoint()).unwrap();
1709
1710        let accounts = provider.get_accounts().await.unwrap();
1711        let tx = TransactionRequest::pay(accounts[0], parse_ether(1u64).unwrap()).from(accounts[0]);
1712        let pending_tx = provider.send_transaction(tx, None).await.unwrap();
1713
1714        assert!(provider.get_transaction_receipt(*pending_tx).await.unwrap().is_none());
1715
1716        let hash = *pending_tx;
1717        let receipt = pending_tx.await.unwrap().unwrap();
1718        assert_eq!(receipt.transaction_hash, hash);
1719    }
1720
1721    #[tokio::test]
1722    async fn parity_block_receipts() {
1723        let url = match std::env::var("PARITY") {
1724            Ok(inner) => inner,
1725            _ => return,
1726        };
1727        let provider = Provider::<Http>::try_from(url.as_str()).unwrap();
1728        let receipts = provider.parity_block_receipts(10657200).await.unwrap();
1729        assert!(!receipts.is_empty());
1730    }
1731
1732    #[tokio::test]
1733    #[ignore]
1734    async fn debug_trace_block() {
1735        let provider = Provider::<Http>::try_from("https://eth.llamarpc.com").unwrap();
1736
1737        let opts = GethDebugTracingOptions {
1738            disable_storage: Some(false),
1739            tracer: Some(GethDebugTracerType::BuiltInTracer(
1740                GethDebugBuiltInTracerType::PreStateTracer,
1741            )),
1742            tracer_config: Some(GethDebugTracerConfig::BuiltInTracer(
1743                GethDebugBuiltInTracerConfig::PreStateTracer(PreStateConfig {
1744                    diff_mode: Some(true),
1745                }),
1746            )),
1747            ..Default::default()
1748        };
1749
1750        let latest_block = provider
1751            .get_block(BlockNumber::Latest)
1752            .await
1753            .expect("Failed to fetch latest block.")
1754            .expect("Latest block is none.");
1755
1756        // debug_traceBlockByNumber
1757        let latest_block_num = BlockNumber::Number(latest_block.number.unwrap());
1758        let traces_by_num = provider
1759            .debug_trace_block_by_number(Some(latest_block_num), opts.clone())
1760            .await
1761            .unwrap();
1762        for trace in &traces_by_num {
1763            assert!(matches!(trace, GethTrace::Known(..)));
1764        }
1765
1766        // debug_traceBlockByHash
1767        let latest_block_hash = latest_block.hash.unwrap();
1768        let traces_by_hash =
1769            provider.debug_trace_block_by_hash(latest_block_hash, opts).await.unwrap();
1770        for trace in &traces_by_hash {
1771            assert!(matches!(trace, GethTrace::Known(..)));
1772        }
1773
1774        assert_eq!(traces_by_num, traces_by_hash);
1775    }
1776
1777    #[tokio::test]
1778    #[cfg_attr(feature = "celo", ignore)]
1779    async fn fee_history() {
1780        let provider = Provider::<Http>::try_from(
1781            "https://goerli.infura.io/v3/fd8b88b56aa84f6da87b60f5441d6778",
1782        )
1783        .unwrap();
1784
1785        provider.fee_history(10u64, BlockNumber::Latest, &[10.0, 40.0]).await.unwrap();
1786    }
1787
1788    #[tokio::test]
1789    #[ignore]
1790    #[cfg(feature = "ws")]
1791    async fn test_trace_call_many() {
1792        use ethers_core::types::H160;
1793
1794        // TODO: Implement ErigonInstance, so it'd be possible to test this.
1795        let provider = Provider::new(crate::Ws::connect("ws://127.0.0.1:8545").await.unwrap());
1796        provider
1797            .trace_call_many(
1798                vec![
1799                    (
1800                        TransactionRequest::new()
1801                            .from(Address::zero())
1802                            .to("0x0000000000000000000000000000000000000001"
1803                                .parse::<H160>()
1804                                .unwrap())
1805                            .value(U256::from(10000000000000000u128)),
1806                        vec![TraceType::StateDiff],
1807                    ),
1808                    (
1809                        TransactionRequest::new()
1810                            .from(
1811                                "0x0000000000000000000000000000000000000001"
1812                                    .parse::<H160>()
1813                                    .unwrap(),
1814                            )
1815                            .to("0x0000000000000000000000000000000000000002"
1816                                .parse::<H160>()
1817                                .unwrap())
1818                            .value(U256::from(10000000000000000u128)),
1819                        vec![TraceType::StateDiff],
1820                    ),
1821                ],
1822                None,
1823            )
1824            .await
1825            .unwrap();
1826    }
1827
1828    #[tokio::test]
1829    async fn test_fill_transaction_1559() {
1830        let (mut provider, mock) = Provider::mocked();
1831        provider.from = Some("0x6fC21092DA55B392b045eD78F4732bff3C580e2c".parse().unwrap());
1832
1833        let gas = U256::from(21000_usize);
1834        let max_fee = U256::from(25_usize);
1835        let prio_fee = U256::from(25_usize);
1836        let access_list: AccessList = vec![Default::default()].into();
1837
1838        // --- leaves a filled 1559 transaction unchanged, making no requests
1839        let from: Address = "0x0000000000000000000000000000000000000001".parse().unwrap();
1840        let to: Address = "0x0000000000000000000000000000000000000002".parse().unwrap();
1841        let mut tx = Eip1559TransactionRequest::new()
1842            .from(from)
1843            .to(to)
1844            .gas(gas)
1845            .max_fee_per_gas(max_fee)
1846            .max_priority_fee_per_gas(prio_fee)
1847            .access_list(access_list.clone())
1848            .into();
1849        provider.fill_transaction(&mut tx, None).await.unwrap();
1850
1851        assert_eq!(tx.from(), Some(&from));
1852        assert_eq!(tx.to(), Some(&to.into()));
1853        assert_eq!(tx.gas(), Some(&gas));
1854        assert_eq!(tx.gas_price(), Some(max_fee));
1855        assert_eq!(tx.access_list(), Some(&access_list));
1856
1857        // --- fills a 1559 transaction, leaving the existing gas limit unchanged,
1858        // without generating an access-list
1859        let mut tx = Eip1559TransactionRequest::new()
1860            .gas(gas)
1861            .max_fee_per_gas(max_fee)
1862            .max_priority_fee_per_gas(prio_fee)
1863            .into();
1864
1865        provider.fill_transaction(&mut tx, None).await.unwrap();
1866
1867        assert_eq!(tx.from(), provider.from.as_ref());
1868        assert!(tx.to().is_none());
1869        assert_eq!(tx.gas(), Some(&gas));
1870        assert_eq!(tx.access_list(), Some(&Default::default()));
1871
1872        // --- fills a 1559 transaction, using estimated gas
1873        let mut tx = Eip1559TransactionRequest::new()
1874            .max_fee_per_gas(max_fee)
1875            .max_priority_fee_per_gas(prio_fee)
1876            .into();
1877
1878        mock.push(gas).unwrap();
1879
1880        provider.fill_transaction(&mut tx, None).await.unwrap();
1881
1882        assert_eq!(tx.from(), provider.from.as_ref());
1883        assert!(tx.to().is_none());
1884        assert_eq!(tx.gas(), Some(&gas));
1885        assert_eq!(tx.access_list(), Some(&Default::default()));
1886
1887        // --- propogates estimate_gas() error
1888        let mut tx = Eip1559TransactionRequest::new()
1889            .max_fee_per_gas(max_fee)
1890            .max_priority_fee_per_gas(prio_fee)
1891            .into();
1892
1893        // bad mock value causes error response for eth_estimateGas
1894        mock.push(b'b').unwrap();
1895
1896        let res = provider.fill_transaction(&mut tx, None).await;
1897
1898        assert!(matches!(res, Err(ProviderError::JsonRpcClientError(_))));
1899    }
1900
1901    #[tokio::test]
1902    async fn test_fill_transaction_legacy() {
1903        let (mut provider, mock) = Provider::mocked();
1904        provider.from = Some("0x6fC21092DA55B392b045eD78F4732bff3C580e2c".parse().unwrap());
1905
1906        let gas = U256::from(21000_usize);
1907        let gas_price = U256::from(50_usize);
1908
1909        // --- leaves a filled legacy transaction unchanged, making no requests
1910        let from: Address = "0x0000000000000000000000000000000000000001".parse().unwrap();
1911        let to: Address = "0x0000000000000000000000000000000000000002".parse().unwrap();
1912        let mut tx =
1913            TransactionRequest::new().from(from).to(to).gas(gas).gas_price(gas_price).into();
1914        provider.fill_transaction(&mut tx, None).await.unwrap();
1915
1916        assert_eq!(tx.from(), Some(&from));
1917        assert_eq!(tx.to(), Some(&to.into()));
1918        assert_eq!(tx.gas(), Some(&gas));
1919        assert_eq!(tx.gas_price(), Some(gas_price));
1920        assert!(tx.access_list().is_none());
1921
1922        // --- fills an empty legacy transaction
1923        let mut tx = TransactionRequest::new().into();
1924        mock.push(gas).unwrap();
1925        mock.push(gas_price).unwrap();
1926        provider.fill_transaction(&mut tx, None).await.unwrap();
1927
1928        assert_eq!(tx.from(), provider.from.as_ref());
1929        assert!(tx.to().is_none());
1930        assert_eq!(tx.gas(), Some(&gas));
1931        assert_eq!(tx.gas_price(), Some(gas_price));
1932        assert!(tx.access_list().is_none());
1933    }
1934
1935    #[tokio::test]
1936    async fn mainnet_lookup_address_invalid_resolver() {
1937        let provider = crate::MAINNET.provider();
1938
1939        let err = provider
1940            .lookup_address("0x30c9223d9e3d23e0af1073a38e0834b055bf68ed".parse().unwrap())
1941            .await
1942            .unwrap_err();
1943
1944        assert_eq!(
1945            &err.to_string(),
1946            "ens name not found: `ox63616e.eth` resolver (0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) is invalid."
1947        );
1948    }
1949
1950    #[tokio::test]
1951    async fn geth_admin_nodeinfo() {
1952        // we can't use the test provider because infura does not expose admin endpoints
1953        let network = 1337u64;
1954        let dir = tempfile::tempdir().unwrap();
1955
1956        let (geth, provider) =
1957            spawn_geth_and_create_provider(network, Some(dir.path().into()), None);
1958
1959        let info = provider.node_info().await.unwrap();
1960        drop(geth);
1961
1962        // make sure it is running eth
1963        assert!(info.protocols.eth.is_some());
1964
1965        // check that the network id is correct
1966        assert_eq!(info.protocols.eth.unwrap().network, network);
1967
1968        #[cfg(not(windows))]
1969        dir.close().unwrap();
1970    }
1971
1972    /// Spawn a new `GethInstance` without discovery and create a `Provider` for it.
1973    ///
1974    /// These will all use the same genesis config.
1975    fn spawn_geth_and_create_provider(
1976        chain_id: u64,
1977        datadir: Option<PathBuf>,
1978        genesis: Option<Genesis>,
1979    ) -> (GethInstance, Provider<HttpProvider>) {
1980        let geth = Geth::new().chain_id(chain_id).disable_discovery();
1981
1982        let geth = match genesis {
1983            Some(genesis) => geth.genesis(genesis),
1984            None => geth,
1985        };
1986
1987        let geth = match datadir {
1988            Some(dir) => geth.data_dir(dir),
1989            None => geth,
1990        }
1991        .spawn();
1992
1993        let provider = Provider::try_from(geth.endpoint()).unwrap();
1994        (geth, provider)
1995    }
1996
1997    /// Spawn a set of [`GethInstance`]s with the list of given data directories and [`Provider`]s
1998    /// for those [`GethInstance`]s without discovery, setting sequential ports for their p2p, rpc,
1999    /// and authrpc ports.
2000    fn spawn_geth_instances<const N: usize>(
2001        datadirs: [PathBuf; N],
2002        chain_id: u64,
2003        genesis: Option<Genesis>,
2004    ) -> [(GethInstance, Provider<HttpProvider>); N] {
2005        datadirs.map(|dir| spawn_geth_and_create_provider(chain_id, Some(dir), genesis.clone()))
2006    }
2007
2008    #[tokio::test]
2009    #[cfg_attr(windows, ignore = "cannot spawn multiple geth instances")]
2010    async fn add_second_geth_peer() {
2011        // init each geth directory
2012        let dir1 = tempfile::tempdir().unwrap();
2013        let dir2 = tempfile::tempdir().unwrap();
2014
2015        // use the default genesis
2016        let genesis = utils::Genesis::default();
2017
2018        // spawn the geths
2019        let [(mut first_geth, first_peer), (second_geth, second_peer)] =
2020            spawn_geth_instances([dir1.path().into(), dir2.path().into()], 1337, Some(genesis));
2021
2022        // get nodeinfo for each geth instance
2023        let first_info = first_peer.node_info().await.unwrap();
2024        let second_info = second_peer.node_info().await.unwrap();
2025        let first_port = first_info.ports.listener;
2026
2027        // replace the ip in the enode by putting
2028        let first_prefix = first_info.enode.split('@').collect::<Vec<&str>>();
2029
2030        // create enodes for each geth instance using each id and port
2031        let first_enode = format!("{}@localhost:{}", first_prefix.first().unwrap(), first_port);
2032
2033        // add the first geth as a peer for the second
2034        let res = second_peer.add_peer(first_enode).await.unwrap();
2035        assert!(res);
2036
2037        // wait on the listening peer for an incoming connection
2038        first_geth.wait_to_add_peer(second_info.id).unwrap();
2039
2040        // check that second_geth exists in the first_geth peer list
2041        let peers = first_peer.peers().await.unwrap();
2042
2043        drop(first_geth);
2044        drop(second_geth);
2045
2046        // check that the second peer is in the list (it uses an enr so the enr should be Some)
2047        assert_eq!(peers.len(), 1);
2048
2049        let peer = peers.first().unwrap();
2050        assert_eq!(H256::from_str(&peer.id).unwrap(), second_info.id);
2051
2052        // remove directories
2053        #[cfg(not(windows))]
2054        {
2055            dir1.close().unwrap();
2056            dir2.close().unwrap();
2057        }
2058    }
2059}