2020-06-20 13:55:07 +00:00
#![ cfg_attr(docsrs, feature(doc_cfg)) ]
2020-12-17 11:26:01 +00:00
#![ deny(broken_intra_doc_links) ]
2021-04-05 07:44:58 +00:00
#![ allow(clippy::type_complexity) ]
2020-06-20 13:55:07 +00:00
//! # Clients for interacting with Ethereum nodes
//!
//! This crate provides asynchronous [Ethereum JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC)
//! compliant clients.
//!
//! For more documentation on the available calls, refer to the [`Provider`](crate::Provider)
//! struct.
//!
//! # Examples
//!
//! ```no_run
2021-08-28 21:06:29 +00:00
//! use ethers_providers::{Provider, Http, Middleware};
2020-06-20 13:55:07 +00:00
//! use std::convert::TryFrom;
//!
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! let provider = Provider::<Http>::try_from(
//! "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"
//! )?;
//!
//! let block = provider.get_block(100u64).await?;
//! println!("Got block: {}", serde_json::to_string(&block)?);
//!
//! let code = provider.get_code("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", None).await?;
//! println!("Got code: {}", serde_json::to_string(&code)?);
//! # Ok(())
//! # }
//! ```
//!
2020-06-21 07:17:11 +00:00
//! # Websockets
//!
2020-12-31 17:19:14 +00:00
//! The crate has support for WebSockets via Tokio.
2020-06-21 07:17:11 +00:00
//!
//! ```
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
2021-08-28 21:06:29 +00:00
//! # use ethers_providers::Ws;
2020-06-21 07:17:11 +00:00
//! let ws = Ws::connect("ws://localhost:8545").await?;
//! # Ok(())
//! # }
//! ```
//!
2020-06-20 13:55:07 +00:00
//! # Ethereum Name Service
//!
//! The provider may also be used to resolve [Ethereum Name Service](https://ens.domains) (ENS) names
//! to addresses (and vice versa). The default ENS address is [mainnet](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) and can be overriden by calling the [`ens`](method@crate::Provider::ens) method on the provider.
//!
//! ```no_run
2021-08-28 21:06:29 +00:00
//! # use ethers_providers::{Provider, Http, Middleware};
2020-06-20 13:55:07 +00:00
//! # use std::convert::TryFrom;
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! # let provider = Provider::<Http>::try_from(
//! # "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"
//! # )?;
//! // Resolve ENS name to Address
//! let name = "vitalik.eth";
//! let address = provider.resolve_name(name).await?;
//!
//! // Lookup ENS name given Address
//! let resolved_name = provider.lookup_address(address).await?;
//! assert_eq!(name, resolved_name);
//! # Ok(())
//! # }
//! ```
2020-06-21 07:17:11 +00:00
mod transports ;
2021-11-12 01:23:46 +00:00
use futures_util ::future ::join_all ;
2020-07-02 15:33:16 +00:00
pub use transports ::* ;
2020-06-10 08:58:27 +00:00
2020-05-26 10:24:19 +00:00
mod provider ;
2020-05-26 09:52:15 +00:00
2020-05-28 16:34:06 +00:00
// ENS support
2021-09-06 08:52:44 +00:00
pub mod ens ;
2020-05-27 11:32:44 +00:00
2020-06-15 12:40:06 +00:00
mod pending_transaction ;
pub use pending_transaction ::PendingTransaction ;
2021-11-12 01:23:46 +00:00
mod pending_escalator ;
pub use pending_escalator ::EscalatingPending ;
2020-06-15 08:46:07 +00:00
mod stream ;
pub use futures_util ::StreamExt ;
2021-06-05 17:08:33 +00:00
pub use stream ::{ interval , FilterWatcher , TransactionStream , DEFAULT_POLL_INTERVAL } ;
2020-06-15 08:46:07 +00:00
2020-11-30 09:33:06 +00:00
mod pubsub ;
pub use pubsub ::{ PubsubClient , SubscriptionStream } ;
2020-05-26 09:52:15 +00:00
use async_trait ::async_trait ;
2020-12-18 11:15:19 +00:00
use auto_impl ::auto_impl ;
2021-08-09 00:31:11 +00:00
use ethers_core ::types ::transaction ::{ eip2718 ::TypedTransaction , eip2930 ::AccessListWithGasUsed } ;
2021-08-19 16:44:15 +00:00
use serde ::{ de ::DeserializeOwned , Deserialize , Deserializer , Serialize } ;
use std ::{ error ::Error , fmt ::Debug , future ::Future , pin ::Pin , str ::FromStr } ;
2020-05-26 09:52:15 +00:00
2020-09-24 21:33:09 +00:00
pub use provider ::{ FilterKind , Provider , ProviderError } ;
2020-05-26 10:24:19 +00:00
2021-11-12 01:23:46 +00:00
/// A simple gas escalation policy
pub type EscalationPolicy = Box < dyn Fn ( U256 , usize ) -> U256 + Send + Sync > ;
2020-09-23 08:04:54 +00:00
// Helper type alias
2021-08-23 09:56:44 +00:00
#[ cfg(target_arch = " wasm32 " ) ]
pub ( crate ) type PinBoxFut < ' a , T > = Pin < Box < dyn Future < Output = Result < T , ProviderError > > + ' a > > ;
#[ cfg(not(target_arch = " wasm32 " )) ]
2020-10-08 15:56:36 +00:00
pub ( crate ) type PinBoxFut < ' a , T > =
Pin < Box < dyn Future < Output = Result < T , ProviderError > > + Send + ' a > > ;
2020-09-23 08:04:54 +00:00
2021-08-23 09:56:44 +00:00
#[ cfg_attr(target_arch = " wasm32 " , async_trait(?Send)) ]
#[ cfg_attr(not(target_arch = " wasm32 " ), async_trait) ]
2020-12-18 11:15:19 +00:00
#[ auto_impl(&, Box, Arc) ]
2020-05-28 16:34:06 +00:00
/// Trait which must be implemented by data transports to be used with the Ethereum
/// JSON-RPC provider.
2020-09-24 21:33:09 +00:00
pub trait JsonRpcClient : Debug + Send + Sync {
2020-05-28 16:34:06 +00:00
/// A JSON-RPC Error
2020-06-01 23:00:58 +00:00
type Error : Error + Into < ProviderError > ;
2020-05-26 09:52:15 +00:00
2020-05-28 16:34:06 +00:00
/// Sends a request with the provided JSON-RPC and parameters serialized as JSON
2020-06-15 10:53:40 +00:00
async fn request < T , R > ( & self , method : & str , params : T ) -> Result < R , Self ::Error >
2020-06-10 07:10:33 +00:00
where
2020-06-15 12:40:06 +00:00
T : Debug + Serialize + Send + Sync ,
2020-12-24 20:23:05 +00:00
R : Serialize + DeserializeOwned ;
2020-05-26 09:37:31 +00:00
}
2020-09-24 21:33:09 +00:00
use ethers_core ::types ::* ;
pub trait FromErr < T > {
fn from ( src : T ) -> Self ;
}
2021-08-09 00:31:11 +00:00
/// Calls the future if `item` is None, otherwise returns a `futures::ok`
pub async fn maybe < F , T , E > ( item : Option < T > , f : F ) -> Result < T , E >
where
F : Future < Output = Result < T , E > > ,
{
if let Some ( item ) = item {
futures_util ::future ::ok ( item ) . await
} else {
f . await
}
}
2020-12-31 19:08:12 +00:00
/// A middleware allows customizing requests send and received from an ethereum node.
///
/// Writing a middleware is as simple as:
2021-10-29 12:29:35 +00:00
/// 1. implementing the [`inner`](crate::Middleware::inner) method to point to the next layer in the
/// "middleware onion", 2. implementing the [`FromErr`](crate::FromErr) trait on your middleware's
/// error type 3. implementing any of the methods you want to override
2020-12-31 19:08:12 +00:00
///
/// ```rust
2021-08-28 21:06:29 +00:00
/// use ethers_providers::{Middleware, FromErr};
/// use ethers_core::types::{U64, TransactionRequest, U256, transaction::eip2718::TypedTransaction};
2020-12-31 19:08:12 +00:00
/// use thiserror::Error;
/// use async_trait::async_trait;
///
/// #[derive(Debug)]
/// struct MyMiddleware<M>(M);
///
/// #[derive(Error, Debug)]
/// pub enum MyError<M: Middleware> {
/// #[error("{0}")]
/// MiddlewareError(M::Error),
///
/// // Add your middleware's specific errors here
/// }
///
/// impl<M: Middleware> FromErr<M::Error> for MyError<M> {
/// fn from(src: M::Error) -> MyError<M> {
/// MyError::MiddlewareError(src)
/// }
/// }
///
/// #[async_trait]
/// impl<M> Middleware for MyMiddleware<M>
/// where
/// M: Middleware,
/// {
/// type Error = MyError<M>;
/// type Provider = M::Provider;
/// type Inner = M;
///
/// fn inner(&self) -> &M {
/// &self.0
/// }
///
/// /// Overrides the default `get_block_number` method to always return 0
/// async fn get_block_number(&self) -> Result<U64, Self::Error> {
/// Ok(U64::zero())
/// }
///
/// /// Overrides the default `estimate_gas` method to log that it was called,
/// /// before forwarding the call to the next layer.
2021-08-09 00:31:11 +00:00
/// async fn estimate_gas(&self, tx: &TypedTransaction) -> Result<U256, Self::Error> {
2020-12-31 19:08:12 +00:00
/// println!("Estimating gas...");
/// self.inner().estimate_gas(tx).await.map_err(FromErr::from)
/// }
/// }
/// ```
2021-08-23 09:56:44 +00:00
#[ cfg_attr(target_arch = " wasm32 " , async_trait(?Send)) ]
#[ cfg_attr(not(target_arch = " wasm32 " ), async_trait) ]
#[ auto_impl(&, Box, Arc) ]
2020-09-24 21:33:09 +00:00
pub trait Middleware : Sync + Send + Debug {
2020-10-31 10:39:03 +00:00
type Error : Sync + Send + Error + FromErr < < Self ::Inner as Middleware > ::Error > ;
2020-09-24 21:33:09 +00:00
type Provider : JsonRpcClient ;
type Inner : Middleware < Provider = Self ::Provider > ;
2020-12-31 19:08:12 +00:00
/// The next middleware in the stack
2020-09-24 21:33:09 +00:00
fn inner ( & self ) -> & Self ::Inner ;
2020-12-31 19:08:12 +00:00
/// The HTTP or Websocket provider.
2020-12-17 11:26:01 +00:00
fn provider ( & self ) -> & Provider < Self ::Provider > {
self . inner ( ) . provider ( )
}
2021-08-09 00:31:11 +00:00
fn default_sender ( & self ) -> Option < Address > {
self . inner ( ) . default_sender ( )
}
2021-08-08 21:10:40 +00:00
async fn client_version ( & self ) -> Result < String , Self ::Error > {
self . inner ( ) . client_version ( ) . await . map_err ( FromErr ::from )
}
2021-08-09 00:31:11 +00:00
/// Helper for filling a transaction
async fn fill_transaction (
& self ,
tx : & mut TypedTransaction ,
block : Option < BlockId > ,
) -> Result < ( ) , Self ::Error > {
2021-10-20 20:18:58 +00:00
if let Some ( default_sender ) = self . default_sender ( ) {
if tx . from ( ) . is_none ( ) {
tx . set_from ( default_sender ) ;
2021-08-09 00:31:11 +00:00
}
2021-10-20 20:18:58 +00:00
}
// TODO: Can we poll the futures below at the same time?
// Access List + Name resolution and then Gas price + Gas
// set the ENS name
if let Some ( NameOrAddress ::Name ( ref ens_name ) ) = tx . to ( ) {
let addr = self . resolve_name ( ens_name ) . await ? ;
tx . set_to ( addr ) ;
}
// estimate the gas without the access list
let gas = maybe ( tx . gas ( ) . cloned ( ) , self . estimate_gas ( tx ) ) . await ? ;
let mut al_used = false ;
// set the access lists
if let Some ( access_list ) = tx . access_list ( ) {
if access_list . 0. is_empty ( ) {
if let Ok ( al_with_gas ) = self . create_access_list ( tx , block ) . await {
// only set the access list if the used gas is less than the
// normally estimated gas
if al_with_gas . gas_used < gas {
tx . set_access_list ( al_with_gas . access_list ) ;
tx . set_gas ( al_with_gas . gas_used ) ;
al_used = true ;
}
2021-08-09 00:50:38 +00:00
}
2021-08-09 00:31:11 +00:00
}
2021-10-20 20:18:58 +00:00
}
2021-08-09 00:31:11 +00:00
2021-10-20 20:18:58 +00:00
if ! al_used {
tx . set_gas ( gas ) ;
}
2021-08-19 14:01:40 +00:00
2021-10-20 20:18:58 +00:00
match tx {
TypedTransaction ::Eip2930 ( _ ) | TypedTransaction ::Legacy ( _ ) = > {
let gas_price = maybe ( tx . gas_price ( ) , self . get_gas_price ( ) ) . await ? ;
tx . set_gas_price ( gas_price ) ;
}
TypedTransaction ::Eip1559 ( ref mut inner ) = > {
2021-08-19 14:01:40 +00:00
if inner . max_fee_per_gas . is_none ( ) | | inner . max_priority_fee_per_gas . is_none ( ) {
let ( max_fee_per_gas , max_priority_fee_per_gas ) =
self . estimate_eip1559_fees ( None ) . await ? ;
2021-10-20 20:18:58 +00:00
inner . max_fee_per_gas = Some ( max_fee_per_gas ) ;
inner . max_priority_fee_per_gas = Some ( max_priority_fee_per_gas ) ;
} ;
2021-08-09 00:31:11 +00:00
}
2021-10-20 20:18:58 +00:00
}
2021-08-09 00:31:11 +00:00
Ok ( ( ) )
}
2020-09-24 21:33:09 +00:00
async fn get_block_number ( & self ) -> Result < U64 , Self ::Error > {
self . inner ( ) . get_block_number ( ) . await . map_err ( FromErr ::from )
}
2021-08-09 00:31:11 +00:00
async fn send_transaction < T : Into < TypedTransaction > + Send + Sync > (
2020-09-24 21:33:09 +00:00
& self ,
2021-08-09 00:31:11 +00:00
tx : T ,
2021-03-16 19:46:07 +00:00
block : Option < BlockId > ,
2020-12-17 11:26:01 +00:00
) -> Result < PendingTransaction < '_ , Self ::Provider > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . send_transaction ( tx , block ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
2021-11-12 01:23:46 +00:00
/// Send a transaction with a simple escalation policy.
///
/// `policy` should be a boxed function that maps `original_gas_price`
/// and `number_of_previous_escalations` -> `new_gas_price`.
///
/// e.g. `Box::new(|start, escalation_index| start * 1250.pow(escalations) /
/// 1000.pow(escalations))`
async fn send_escalating < ' a > (
& ' a self ,
tx : & TypedTransaction ,
escalations : usize ,
policy : EscalationPolicy ,
) -> Result < EscalatingPending < ' a , Self ::Provider > , Self ::Error > {
let mut original = tx . clone ( ) ;
self . fill_transaction ( & mut original , None ) . await ? ;
let gas_price = original . gas_price ( ) . expect ( " filled " ) ;
let chain_id = self . get_chainid ( ) . await ? . low_u64 ( ) ;
let sign_futs : Vec < _ > = ( 0 .. escalations )
. map ( | i | {
let new_price = policy ( gas_price , i ) ;
let mut r = original . clone ( ) ;
r . set_gas_price ( new_price ) ;
r
} )
. map ( | req | async move {
self . sign ( req . rlp ( chain_id ) , & self . default_sender ( ) . unwrap_or_default ( ) )
. await
. map ( | sig | req . rlp_signed ( chain_id , & sig ) )
} )
. collect ( ) ;
// we reverse for convenience. Ensuring that we can always just
// `pop()` the next tx off the back later
let mut signed = join_all ( sign_futs ) . await . into_iter ( ) . collect ::< Result < Vec < _ > , _ > > ( ) ? ;
signed . reverse ( ) ;
Ok ( EscalatingPending ::new ( self . provider ( ) , signed ) )
}
2020-09-24 21:33:09 +00:00
async fn resolve_name ( & self , ens_name : & str ) -> Result < Address , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . resolve_name ( ens_name ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn lookup_address ( & self , address : Address ) -> Result < String , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . lookup_address ( address ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn get_block < T : Into < BlockId > + Send + Sync > (
& self ,
block_hash_or_number : T ,
) -> Result < Option < Block < TxHash > > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_block ( block_hash_or_number ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn get_block_with_txs < T : Into < BlockId > + Send + Sync > (
& self ,
block_hash_or_number : T ,
) -> Result < Option < Block < Transaction > > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_block_with_txs ( block_hash_or_number ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
2021-08-19 14:04:11 +00:00
async fn get_uncle_count < T : Into < BlockId > + Send + Sync > (
& self ,
block_hash_or_number : T ,
) -> Result < U256 , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_uncle_count ( block_hash_or_number ) . await . map_err ( FromErr ::from )
2021-08-19 14:04:11 +00:00
}
async fn get_uncle < T : Into < BlockId > + Send + Sync > (
& self ,
block_hash_or_number : T ,
idx : U64 ,
) -> Result < Option < Block < H256 > > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_uncle ( block_hash_or_number , idx ) . await . map_err ( FromErr ::from )
2021-08-19 14:04:11 +00:00
}
2020-09-24 21:33:09 +00:00
async fn get_transaction_count < T : Into < NameOrAddress > + Send + Sync > (
& self ,
from : T ,
2021-03-16 19:46:07 +00:00
block : Option < BlockId > ,
2020-09-24 21:33:09 +00:00
) -> Result < U256 , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_transaction_count ( from , block ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
2021-08-09 00:31:11 +00:00
async fn estimate_gas ( & self , tx : & TypedTransaction ) -> Result < U256 , Self ::Error > {
2020-09-24 21:33:09 +00:00
self . inner ( ) . estimate_gas ( tx ) . await . map_err ( FromErr ::from )
}
async fn call (
& self ,
2021-08-09 00:31:11 +00:00
tx : & TypedTransaction ,
2021-03-16 19:46:07 +00:00
block : Option < BlockId > ,
2020-09-24 21:33:09 +00:00
) -> Result < Bytes , Self ::Error > {
self . inner ( ) . call ( tx , block ) . await . map_err ( FromErr ::from )
}
async fn get_chainid ( & self ) -> Result < U256 , Self ::Error > {
self . inner ( ) . get_chainid ( ) . await . map_err ( FromErr ::from )
}
async fn get_balance < T : Into < NameOrAddress > + Send + Sync > (
& self ,
from : T ,
2021-03-16 19:46:07 +00:00
block : Option < BlockId > ,
2020-09-24 21:33:09 +00:00
) -> Result < U256 , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_balance ( from , block ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn get_transaction < T : Send + Sync + Into < TxHash > > (
& self ,
transaction_hash : T ,
) -> Result < Option < Transaction > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_transaction ( transaction_hash ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn get_transaction_receipt < T : Send + Sync + Into < TxHash > > (
& self ,
transaction_hash : T ,
) -> Result < Option < TransactionReceipt > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_transaction_receipt ( transaction_hash ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
2021-08-08 21:10:40 +00:00
async fn get_block_receipts < T : Into < BlockNumber > + Send + Sync > (
& self ,
block : T ,
) -> Result < Vec < TransactionReceipt > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_block_receipts ( block ) . await . map_err ( FromErr ::from )
2021-08-08 21:10:40 +00:00
}
2020-09-24 21:33:09 +00:00
async fn get_gas_price ( & self ) -> Result < U256 , Self ::Error > {
self . inner ( ) . get_gas_price ( ) . await . map_err ( FromErr ::from )
}
2021-08-19 14:01:40 +00:00
async fn estimate_eip1559_fees (
& self ,
estimator : Option < fn ( U256 , Vec < Vec < U256 > > ) -> ( U256 , U256 ) > ,
) -> Result < ( U256 , U256 ) , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . estimate_eip1559_fees ( estimator ) . await . map_err ( FromErr ::from )
2021-08-19 14:01:40 +00:00
}
2020-09-24 21:33:09 +00:00
async fn get_accounts ( & self ) -> Result < Vec < Address > , Self ::Error > {
self . inner ( ) . get_accounts ( ) . await . map_err ( FromErr ::from )
}
2020-12-17 11:26:01 +00:00
async fn send_raw_transaction < ' a > (
& ' a self ,
2021-08-08 22:49:23 +00:00
tx : Bytes ,
2020-12-17 11:26:01 +00:00
) -> Result < PendingTransaction < ' a , Self ::Provider > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . send_raw_transaction ( tx ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
2021-01-28 06:51:53 +00:00
/// This returns true if either the middleware stack contains a `SignerMiddleware`, or the
/// JSON-RPC provider has an unlocked key that can sign using the `eth_sign` call. If none of
/// the above conditions are met, then the middleware stack is not capable of signing data.
async fn is_signer ( & self ) -> bool {
self . inner ( ) . is_signer ( ) . await
}
2020-09-24 21:33:09 +00:00
async fn sign < T : Into < Bytes > + Send + Sync > (
& self ,
data : T ,
from : & Address ,
) -> Result < Signature , Self ::Error > {
self . inner ( ) . sign ( data , from ) . await . map_err ( FromErr ::from )
}
////// Contract state
async fn get_logs ( & self , filter : & Filter ) -> Result < Vec < Log > , Self ::Error > {
self . inner ( ) . get_logs ( filter ) . await . map_err ( FromErr ::from )
}
async fn new_filter ( & self , filter : FilterKind < '_ > ) -> Result < U256 , Self ::Error > {
self . inner ( ) . new_filter ( filter ) . await . map_err ( FromErr ::from )
}
async fn uninstall_filter < T : Into < U256 > + Send + Sync > (
& self ,
id : T ,
) -> Result < bool , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . uninstall_filter ( id ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn watch < ' a > (
& ' a self ,
filter : & Filter ,
) -> Result < FilterWatcher < ' a , Self ::Provider , Log > , Self ::Error > {
self . inner ( ) . watch ( filter ) . await . map_err ( FromErr ::from )
}
async fn watch_pending_transactions (
& self ,
) -> Result < FilterWatcher < '_ , Self ::Provider , H256 > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . watch_pending_transactions ( ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn get_filter_changes < T , R > ( & self , id : T ) -> Result < Vec < R > , Self ::Error >
where
T : Into < U256 > + Send + Sync ,
2020-12-24 20:23:05 +00:00
R : Serialize + DeserializeOwned + Send + Sync + Debug ,
2020-09-24 21:33:09 +00:00
{
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_filter_changes ( id ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn watch_blocks ( & self ) -> Result < FilterWatcher < '_ , Self ::Provider , H256 > , Self ::Error > {
self . inner ( ) . watch_blocks ( ) . await . map_err ( FromErr ::from )
}
async fn get_code < T : Into < NameOrAddress > + Send + Sync > (
& self ,
at : T ,
2021-03-16 19:46:07 +00:00
block : Option < BlockId > ,
2020-09-24 21:33:09 +00:00
) -> Result < Bytes , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_code ( at , block ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
async fn get_storage_at < T : Into < NameOrAddress > + Send + Sync > (
& self ,
from : T ,
location : H256 ,
2021-03-16 19:46:07 +00:00
block : Option < BlockId > ,
2020-09-24 21:33:09 +00:00
) -> Result < H256 , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_storage_at ( from , location , block ) . await . map_err ( FromErr ::from )
2020-09-24 21:33:09 +00:00
}
2021-09-18 06:01:02 +00:00
async fn get_proof < T : Into < NameOrAddress > + Send + Sync > (
& self ,
from : T ,
locations : Vec < H256 > ,
block : Option < BlockId > ,
) -> Result < EIP1186ProofResponse , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . get_proof ( from , locations , block ) . await . map_err ( FromErr ::from )
2021-09-18 06:01:02 +00:00
}
2020-10-31 10:44:08 +00:00
// Mempool inspection for Geth's API
2020-10-24 08:13:13 +00:00
async fn txpool_content ( & self ) -> Result < TxpoolContent , Self ::Error > {
self . inner ( ) . txpool_content ( ) . await . map_err ( FromErr ::from )
}
async fn txpool_inspect ( & self ) -> Result < TxpoolInspect , Self ::Error > {
self . inner ( ) . txpool_inspect ( ) . await . map_err ( FromErr ::from )
}
async fn txpool_status ( & self ) -> Result < TxpoolStatus , Self ::Error > {
self . inner ( ) . txpool_status ( ) . await . map_err ( FromErr ::from )
}
2020-10-31 10:44:08 +00:00
// Parity `trace` support
/// Executes the given call and returns a number of possible traces for it
2021-08-09 00:31:11 +00:00
async fn trace_call < T : Into < TypedTransaction > + Send + Sync > (
2020-10-31 10:44:08 +00:00
& self ,
2021-08-09 00:31:11 +00:00
req : T ,
2020-10-31 10:44:08 +00:00
trace_type : Vec < TraceType > ,
block : Option < BlockNumber > ,
2020-11-12 10:08:20 +00:00
) -> Result < BlockTrace , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . trace_call ( req , trace_type , block ) . await . map_err ( FromErr ::from )
2020-10-31 10:44:08 +00:00
}
/// Traces a call to `eth_sendRawTransaction` without making the call, returning the traces
async fn trace_raw_transaction (
& self ,
data : Bytes ,
trace_type : Vec < TraceType > ,
2020-11-12 10:08:20 +00:00
) -> Result < BlockTrace , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . trace_raw_transaction ( data , trace_type ) . await . map_err ( FromErr ::from )
2020-10-31 10:44:08 +00:00
}
/// Replays a transaction, returning the traces
async fn trace_replay_transaction (
& self ,
hash : H256 ,
trace_type : Vec < TraceType > ,
2020-11-12 10:08:20 +00:00
) -> Result < BlockTrace , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . trace_replay_transaction ( hash , trace_type ) . await . map_err ( FromErr ::from )
2020-10-31 10:44:08 +00:00
}
/// Replays all transactions in a block returning the requested traces for each transaction
async fn trace_replay_block_transactions (
& self ,
block : BlockNumber ,
trace_type : Vec < TraceType > ,
2020-11-12 10:08:20 +00:00
) -> Result < Vec < BlockTrace > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . trace_replay_block_transactions ( block , trace_type ) . await . map_err ( FromErr ::from )
2020-10-31 10:44:08 +00:00
}
/// Returns traces created at given block
2020-11-12 10:08:20 +00:00
async fn trace_block ( & self , block : BlockNumber ) -> Result < Vec < Trace > , Self ::Error > {
2020-10-31 10:44:08 +00:00
self . inner ( ) . trace_block ( block ) . await . map_err ( FromErr ::from )
}
/// Return traces matching the given filter
2020-11-12 10:08:20 +00:00
async fn trace_filter ( & self , filter : TraceFilter ) -> Result < Vec < Trace > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . trace_filter ( filter ) . await . map_err ( FromErr ::from )
2020-10-31 10:44:08 +00:00
}
/// Returns trace at the given position
async fn trace_get < T : Into < U64 > + Send + Sync > (
& self ,
hash : H256 ,
index : Vec < T > ,
2020-11-12 10:08:20 +00:00
) -> Result < Trace , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . trace_get ( hash , index ) . await . map_err ( FromErr ::from )
2020-10-31 10:44:08 +00:00
}
/// Returns all traces of a given transaction
2020-11-12 10:08:20 +00:00
async fn trace_transaction ( & self , hash : H256 ) -> Result < Vec < Trace > , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . trace_transaction ( hash ) . await . map_err ( FromErr ::from )
2020-10-31 10:44:08 +00:00
}
2020-11-19 17:30:10 +00:00
// Parity namespace
2020-11-30 09:33:06 +00:00
async fn subscribe < T , R > (
& self ,
params : T ,
) -> Result < SubscriptionStream < '_ , Self ::Provider , R > , Self ::Error >
where
T : Debug + Serialize + Send + Sync ,
R : DeserializeOwned + Send + Sync ,
< Self as Middleware > ::Provider : PubsubClient ,
{
self . inner ( ) . subscribe ( params ) . await . map_err ( FromErr ::from )
}
async fn unsubscribe < T > ( & self , id : T ) -> Result < bool , Self ::Error >
where
T : Into < U256 > + Send + Sync ,
< Self as Middleware > ::Provider : PubsubClient ,
{
self . inner ( ) . unsubscribe ( id ) . await . map_err ( FromErr ::from )
}
async fn subscribe_blocks (
& self ,
) -> Result < SubscriptionStream < '_ , Self ::Provider , Block < TxHash > > , Self ::Error >
where
< Self as Middleware > ::Provider : PubsubClient ,
{
self . inner ( ) . subscribe_blocks ( ) . await . map_err ( FromErr ::from )
}
async fn subscribe_pending_txs (
& self ,
) -> Result < SubscriptionStream < '_ , Self ::Provider , TxHash > , Self ::Error >
where
< Self as Middleware > ::Provider : PubsubClient ,
{
2021-10-29 12:29:35 +00:00
self . inner ( ) . subscribe_pending_txs ( ) . await . map_err ( FromErr ::from )
2020-11-30 09:33:06 +00:00
}
async fn subscribe_logs < ' a > (
& ' a self ,
filter : & Filter ,
) -> Result < SubscriptionStream < ' a , Self ::Provider , Log > , Self ::Error >
where
< Self as Middleware > ::Provider : PubsubClient ,
{
2021-10-29 12:29:35 +00:00
self . inner ( ) . subscribe_logs ( filter ) . await . map_err ( FromErr ::from )
2020-11-30 09:33:06 +00:00
}
2021-08-09 00:31:11 +00:00
2021-08-19 16:44:15 +00:00
async fn fee_history < T : Into < U256 > + serde ::Serialize + Send + Sync > (
2021-08-09 00:31:11 +00:00
& self ,
2021-08-19 16:44:15 +00:00
block_count : T ,
2021-08-09 00:31:11 +00:00
last_block : BlockNumber ,
reward_percentiles : & [ f64 ] ,
) -> Result < FeeHistory , Self ::Error > {
self . inner ( )
. fee_history ( block_count , last_block , reward_percentiles )
. await
. map_err ( FromErr ::from )
}
async fn create_access_list (
& self ,
tx : & TypedTransaction ,
block : Option < BlockId > ,
) -> Result < AccessListWithGasUsed , Self ::Error > {
2021-10-29 12:29:35 +00:00
self . inner ( ) . create_access_list ( tx , block ) . await . map_err ( FromErr ::from )
2021-08-09 00:31:11 +00:00
}
}
#[ derive(Deserialize, Serialize, Debug, Clone) ]
#[ serde(rename_all = " camelCase " ) ]
pub struct FeeHistory {
pub base_fee_per_gas : Vec < U256 > ,
pub gas_used_ratio : Vec < f64 > ,
2021-08-19 16:44:15 +00:00
#[ serde(deserialize_with = " from_int_or_hex " ) ]
/// oldestBlock is returned as an unsigned integer up to geth v1.10.6. From
/// geth v1.10.7, this has been updated to return in the hex encoded form.
/// The custom deserializer allows backward compatibility for those clients
/// not running v1.10.7 yet.
pub oldest_block : U256 ,
2021-08-09 00:31:11 +00:00
pub reward : Vec < Vec < U256 > > ,
2020-09-24 21:33:09 +00:00
}
2021-06-15 12:22:53 +00:00
2021-08-19 16:44:15 +00:00
fn from_int_or_hex < ' de , D > ( deserializer : D ) -> Result < U256 , D ::Error >
where
D : Deserializer < ' de > ,
{
#[ derive(Deserialize) ]
#[ serde(untagged) ]
enum IntOrHex {
Int ( u64 ) ,
Hex ( String ) ,
}
match IntOrHex ::deserialize ( deserializer ) ? {
IntOrHex ::Int ( n ) = > Ok ( U256 ::from ( n ) ) ,
IntOrHex ::Hex ( s ) = > U256 ::from_str ( s . as_str ( ) ) . map_err ( serde ::de ::Error ::custom ) ,
}
}
2021-06-15 12:22:53 +00:00
#[ cfg(feature = " celo " ) ]
2021-08-23 09:56:44 +00:00
#[ cfg_attr(target_arch = " wasm32 " , async_trait(?Send)) ]
#[ cfg_attr(not(target_arch = " wasm32 " ), async_trait) ]
2021-06-15 12:22:53 +00:00
pub trait CeloMiddleware : Middleware {
2021-06-22 11:56:10 +00:00
async fn get_validators_bls_public_keys < T : Into < BlockId > + Send + Sync > (
2021-06-15 12:22:53 +00:00
& self ,
2021-06-22 11:56:10 +00:00
block_id : T ,
) -> Result < Vec < String > , ProviderError > {
2021-10-29 12:29:35 +00:00
self . provider ( ) . get_validators_bls_public_keys ( block_id ) . await . map_err ( FromErr ::from )
2021-06-15 12:22:53 +00:00
}
}