Skip to content

Commit

Permalink
feat: convert EthCall to ProviderCall
Browse files Browse the repository at this point in the history
* use `ClientRef` in EthCall instead of `WeakClient`

* change lifetimes

* add *_internal methods that return `EthCall`
  • Loading branch information
yash-atreya committed Jun 27, 2024
1 parent 478ac23 commit 1cb1579
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 25 deletions.
4 changes: 2 additions & 2 deletions crates/contract/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBu
/// Returns the estimated gas cost for the underlying transaction to be executed
/// If [`state overrides`](Self::state) are set, they will be applied to the gas estimation.
pub async fn estimate_gas(&self) -> Result<u128> {
let mut estimate = self.provider.estimate_gas(&self.request);
let mut estimate = self.provider.estimate_gas_internal(&self.request);
if let Some(state) = &self.state {
estimate = estimate.overrides(state);
}
Expand All @@ -444,7 +444,7 @@ impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBu
///
/// See [`call`](Self::call) for more information.
pub fn call_raw(&self) -> EthCall<'_, '_, '_, (), T, N> {
let call = self.provider.call(&self.request).block(self.block);
let call = self.provider.call_internal(&self.request).block(self.block);
let call = match &self.state {
Some(state) => call.overrides(state),
None => call,
Expand Down
4 changes: 2 additions & 2 deletions crates/provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ pub mod layers;

mod provider;
pub use provider::{
builder, EthCall, FilterPollerBuilder, Provider, ProviderCall, RootProvider, RpcWithBlock,
SendableTx, WalletProvider,
builder, EthCall, EthCallParams, FilterPollerBuilder, Provider, ProviderCall, RootProvider,
RpcWithBlock, SendableTx, WalletProvider,
};

pub mod utils;
Expand Down
44 changes: 31 additions & 13 deletions crates/provider/src/provider/eth_call.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::ProviderCall;
use alloy_eips::BlockId;
use alloy_json_rpc::RpcReturn;
use alloy_network::Network;
use alloy_rpc_client::{RpcCall, WeakClient};
use alloy_rpc_client::{ClientRef, RpcCall};
use alloy_rpc_types_eth::state::StateOverride;
use alloy_transport::{Transport, TransportErrorKind, TransportResult};
use alloy_transport::{Transport, TransportResult};
use futures::FutureExt;
use serde::ser::SerializeSeq;
use std::{future::Future, marker::PhantomData, task::Poll};
Expand All @@ -12,7 +13,8 @@ type RunningFut<'req, 'state, T, N, Resp, Output, Map> =
RpcCall<T, EthCallParams<'req, 'state, N>, Resp, Output, Map>;

#[derive(Clone, Debug)]
struct EthCallParams<'req, 'state, N: Network> {
#[doc(hidden)] // Not public API.
pub struct EthCallParams<'req, 'state, N: Network> {
data: &'req N::TransactionRequest,
block: Option<BlockId>,
overrides: Option<&'state StateOverride>,
Expand Down Expand Up @@ -58,7 +60,7 @@ where
Map: Fn(Resp) -> Output,
{
Preparing {
client: WeakClient<T>,
client: ClientRef<'req, T>,
data: &'req N::TransactionRequest,
overrides: Option<&'state StateOverride>,
block: Option<BlockId>,
Expand Down Expand Up @@ -94,11 +96,6 @@ where
unreachable!("bad state")
};

let client = match client.upgrade().ok_or_else(TransportErrorKind::backend_gone) {
Ok(client) => client,
Err(e) => return Poll::Ready(Err(e)),
};

let params = EthCallParams { data, block, overrides };

let fut = client.request(method, params).map_resp(map);
Expand Down Expand Up @@ -153,8 +150,7 @@ where
Resp: RpcReturn,
Map: Fn(Resp) -> Output,
{
client: WeakClient<T>,

client: ClientRef<'req, T>,
data: &'req N::TransactionRequest,
overrides: Option<&'state StateOverride>,
block: Option<BlockId>,
Expand All @@ -170,7 +166,7 @@ where
Resp: RpcReturn,
{
/// Create a new CallBuilder.
pub const fn new(client: WeakClient<T>, data: &'req N::TransactionRequest) -> Self {
pub const fn new(client: ClientRef<'req, T>, data: &'req N::TransactionRequest) -> Self {
Self {
client,
data,
Expand All @@ -183,7 +179,10 @@ where
}

/// Create new EthCall for gas estimates.
pub const fn gas_estimate(client: WeakClient<T>, data: &'req N::TransactionRequest) -> Self {
pub const fn gas_estimate(
client: ClientRef<'req, T>,
data: &'req N::TransactionRequest,
) -> Self {
Self {
client,
data,
Expand Down Expand Up @@ -245,6 +244,25 @@ where
}
}

impl<'req, T, N, Resp, Output, Map> EthCall<'req, 'req, T, N, Resp, Output, Map>
where
T: Transport + Clone,
N: Network,
Resp: RpcReturn,
Map: Fn(Resp) -> Output,
{
/// Convert EthCall into a ProviderCall
pub(crate) fn into_provider_call(
self,
) -> ProviderCall<T, EthCallParams<'req, 'req, N>, Resp, Output, Map> {
let EthCall { client, data, overrides, block, method, map, .. } = self;
let params = EthCallParams { data, overrides, block };

let fut = client.request(method, params).map_resp(map);
fut.into()
}
}

impl<'req, 'state, T, N, Resp, Output, Map> std::future::IntoFuture
for EthCall<'req, 'state, T, N, Resp, Output, Map>
where
Expand Down
2 changes: 1 addition & 1 deletion crates/provider/src/provider/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod eth_call;
pub use eth_call::EthCall;
pub use eth_call::{EthCall, EthCallParams};

mod prov_call;
pub use prov_call::ProviderCall;
Expand Down
43 changes: 36 additions & 7 deletions crates/provider/src/provider/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

use crate::{
utils::{self, Eip1559Estimation, EstimatorFunction},
EthCall, Identity, PendingTransaction, PendingTransactionBuilder, PendingTransactionConfig,
ProviderBuilder, ProviderCall, RootProvider, RpcWithBlock, SendableTx,
EthCall, EthCallParams, Identity, PendingTransaction, PendingTransactionBuilder,
PendingTransactionConfig, ProviderBuilder, ProviderCall, RootProvider, RpcWithBlock,
SendableTx,
};
use alloy_eips::eip2718::Encodable2718;
use alloy_json_rpc::{RpcError, RpcParam, RpcReturn};
Expand Down Expand Up @@ -150,8 +151,21 @@ pub trait Provider<T: Transport + Clone = BoxTransport, N: Network = Ethereum>:
/// Not all client implementations support state overrides.
#[doc(alias = "eth_call")]
#[doc(alias = "call_with_overrides")]
fn call<'req>(&self, tx: &'req N::TransactionRequest) -> EthCall<'req, 'static, T, N, Bytes> {
EthCall::new(self.weak_client(), tx)
fn call<'req>(
&'req self,
tx: &'req N::TransactionRequest,
) -> ProviderCall<T, EthCallParams<'req, 'req, N>, Bytes, Bytes> {
let call = self.call_internal(tx);
call.into_provider_call()
}

/// This method returns `EthCall` struct.
/// It is useful when we have to set the block or state overrides after generating the struct.
fn call_internal<'req>(
&'req self,
tx: &'req N::TransactionRequest,
) -> EthCall<'req, 'req, T, N, Bytes, Bytes> {
EthCall::new(self.client(), tx)
}

/// Gets the chain ID.
Expand Down Expand Up @@ -183,10 +197,21 @@ pub trait Provider<T: Transport + Clone = BoxTransport, N: Network = Ethereum>:
///
/// Not all client implementations support state overrides for eth_estimateGas.
fn estimate_gas<'req>(
&self,
&'req self,
tx: &'req N::TransactionRequest,
) -> ProviderCall<T, EthCallParams<'req, 'req, N>, U128, u128> {
let call = self.estimate_gas_internal(tx);
call.into_provider_call()
}

/// This method returns `EthCall` struct.
/// It is useful when we have to set the block or state overrides after generating the struct.
fn estimate_gas_internal<'req>(
&'req self,
tx: &'req N::TransactionRequest,
) -> EthCall<'req, 'static, T, N, U128, u128> {
EthCall::gas_estimate(self.weak_client(), tx).map_resp(crate::utils::convert_u128)
EthCall::gas_estimate(self.client(), tx)
.map_resp(crate::utils::convert_u128 as fn(U128) -> u128)
}

/// Estimates the EIP1559 `maxFeePerGas` and `maxPriorityFeePerGas` fields.
Expand Down Expand Up @@ -1426,7 +1451,11 @@ mod tests {
let req = TransactionRequest::default()
.with_to(address!("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")) // WETH
.with_input(bytes!("06fdde03")); // `name()`
let result = provider.call(&req).await.unwrap();
let provider_call = provider.call(&req);

assert!(matches!(provider_call, ProviderCall::RpcCall(_)));

let result = provider_call.await.unwrap();
assert_eq!(String::abi_decode(&result, true).unwrap(), "Wrapped Ether");
}

Expand Down

0 comments on commit 1cb1579

Please sign in to comment.