Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: dedupe CallRequest/TransactionRequest #178

Merged
merged 12 commits into from
Feb 9, 2024
16 changes: 11 additions & 5 deletions crates/contract/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use alloy_dyn_abi::{DynSolValue, FunctionExt, JsonAbiExt};
use alloy_json_abi::Function;
use alloy_primitives::{Address, Bytes, U256, U64};
use alloy_providers::provider::TempProvider;
use alloy_rpc_types::{state::StateOverride, BlockId, CallInput, CallRequest, TransactionReceipt};
use alloy_rpc_types::{
request::{TransactionInput, TransactionRequest},
state::StateOverride,
BlockId, TransactionReceipt,
};
use alloy_sol_types::SolCall;
use std::{
future::{Future, IntoFuture},
Expand Down Expand Up @@ -189,7 +193,7 @@ impl CallDecoder for () {
pub struct CallBuilder<P, D> {
// TODO: this will not work with `send_transaction` and does not differentiate between EIP-1559
// and legacy tx
request: CallRequest,
request: TransactionRequest,
block: Option<BlockId>,
state: Option<StateOverride>,
provider: P,
Expand Down Expand Up @@ -249,7 +253,8 @@ impl<P: TempProvider> RawCallBuilder<P> {

impl<P: TempProvider, D: CallDecoder> CallBuilder<P, D> {
fn new_inner(provider: P, input: Bytes, decoder: D) -> Self {
let request = CallRequest { input: CallInput::new(input), ..Default::default() };
let request =
TransactionRequest { input: TransactionInput::new(input), ..Default::default() };
Self { request, decoder, provider, block: None, state: None }
}

Expand All @@ -272,15 +277,16 @@ impl<P: TempProvider, D: CallDecoder> CallBuilder<P, D> {

/// Sets the `gas` field in the transaction to the provided value
pub fn gas(mut self, gas: U256) -> Self {
self.request = self.request.gas(gas);
self.request = self.request.gas_limit(gas);
self
}

/// Sets the `gas_price` field in the transaction to the provided value
/// If the internal transaction is an EIP-1559 one, then it sets both
/// `max_fee_per_gas` and `max_priority_fee_per_gas` to the same value
pub fn gas_price(mut self, gas_price: U256) -> Self {
self.request = self.request.gas_price(gas_price);
self.request = self.request.max_fee_per_gas(gas_price);
self.request = self.request.max_priority_fee_per_gas(gas_price);
self
}

Expand Down
42 changes: 25 additions & 17 deletions crates/providers/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use alloy_rpc_trace_types::{
parity::LocalizedTransactionTrace,
};
use alloy_rpc_types::{
state::StateOverride, AccessListWithGasUsed, Block, BlockId, BlockNumberOrTag, CallRequest,
EIP1186AccountProofResponse, FeeHistory, Filter, Log, SyncStatus, Transaction,
TransactionReceipt,
request::TransactionRequest, state::StateOverride, AccessListWithGasUsed, Block, BlockId,
BlockNumberOrTag, EIP1186AccountProofResponse, FeeHistory, Filter, Log, SyncStatus,
Transaction, TransactionReceipt,
};
use alloy_transport::{BoxTransport, Transport, TransportErrorKind, TransportResult};
use alloy_transport_http::Http;
Expand Down Expand Up @@ -141,24 +141,28 @@ pub trait TempProvider: Send + Sync {
/// Gets syncing info.
async fn syncing(&self) -> TransportResult<SyncStatus>;

/// Execute a smart contract call with [CallRequest] without publishing a transaction.
async fn call(&self, tx: CallRequest, block: Option<BlockId>) -> TransportResult<Bytes>;
/// Execute a smart contract call with [TransactionRequest] without publishing a transaction.
async fn call(&self, tx: TransactionRequest, block: Option<BlockId>) -> TransportResult<Bytes>;

/// Execute a smart contract call with [CallRequest] and state overrides, without publishing a
/// transaction.
/// Execute a smart contract call with [TransactionRequest] and state overrides, without
/// publishing a transaction.
///
/// # Note
///
/// Not all client implementations support state overrides.
async fn call_with_overrides(
&self,
tx: CallRequest,
tx: TransactionRequest,
block: Option<BlockId>,
state: StateOverride,
) -> TransportResult<Bytes>;

/// Estimate the gas needed for a transaction.
async fn estimate_gas(&self, tx: CallRequest, block: Option<BlockId>) -> TransportResult<U256>;
async fn estimate_gas(
&self,
tx: TransactionRequest,
block: Option<BlockId>,
) -> TransportResult<U256>;

/// Sends an already-signed transaction.
async fn send_raw_transaction(&self, tx: Bytes) -> TransportResult<TxHash>;
Expand All @@ -183,7 +187,7 @@ pub trait TempProvider: Send + Sync {

async fn create_access_list(
&self,
request: CallRequest,
request: TransactionRequest,
block: Option<BlockId>,
) -> TransportResult<AccessListWithGasUsed>;

Expand Down Expand Up @@ -379,28 +383,32 @@ impl<T: Transport + Clone + Send + Sync> TempProvider for Provider<T> {
self.inner.prepare("eth_syncing", ()).await
}

/// Execute a smart contract call with [CallRequest] without publishing a transaction.
async fn call(&self, tx: CallRequest, block: Option<BlockId>) -> TransportResult<Bytes> {
/// Execute a smart contract call with [TransactionRequest] without publishing a transaction.
async fn call(&self, tx: TransactionRequest, block: Option<BlockId>) -> TransportResult<Bytes> {
self.inner.prepare("eth_call", (tx, block.unwrap_or_default())).await
}

/// Execute a smart contract call with [CallRequest] and state overrides, without publishing a
/// transaction.
/// Execute a smart contract call with [TransactionRequest] and state overrides, without
/// publishing a transaction.
///
/// # Note
///
/// Not all client implementations support state overrides.
async fn call_with_overrides(
&self,
tx: CallRequest,
tx: TransactionRequest,
block: Option<BlockId>,
state: StateOverride,
) -> TransportResult<Bytes> {
self.inner.prepare("eth_call", (tx, block.unwrap_or_default(), state)).await
}

/// Estimate the gas needed for a transaction.
async fn estimate_gas(&self, tx: CallRequest, block: Option<BlockId>) -> TransportResult<U256> {
async fn estimate_gas(
&self,
tx: TransactionRequest,
block: Option<BlockId>,
) -> TransportResult<U256> {
if let Some(block_id) = block {
self.inner.prepare("eth_estimateGas", (tx, block_id)).await
} else {
Expand Down Expand Up @@ -468,7 +476,7 @@ impl<T: Transport + Clone + Send + Sync> TempProvider for Provider<T> {

async fn create_access_list(
&self,
request: CallRequest,
request: TransactionRequest,
block: Option<BlockId>,
) -> TransportResult<AccessListWithGasUsed> {
self.inner.prepare("eth_createAccessList", (request, block.unwrap_or_default())).await
Expand Down
8 changes: 4 additions & 4 deletions crates/rpc-trace-types/src/tracerequest.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//! Builder style functions for `trace_call`

use crate::parity::TraceType;
use alloy_rpc_types::{state::StateOverride, BlockId, BlockOverrides, CallRequest};
use alloy_rpc_types::{request::TransactionRequest, state::StateOverride, BlockId, BlockOverrides};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;

/// Container type for `trace_call` arguments
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct TraceCallRequest {
/// call request object
pub call: CallRequest,
pub call: TransactionRequest,
/// trace types
pub trace_types: HashSet<TraceType>,
/// Optional: blockId
Expand All @@ -21,8 +21,8 @@ pub struct TraceCallRequest {
}

impl TraceCallRequest {
/// Returns a new [`TraceCallRequest`] given a [`CallRequest`] and [`HashSet<TraceType>`]
pub fn new(call: CallRequest) -> Self {
/// Returns a new [`TraceCallRequest`] given a [`TransactionRequest`] and [`HashSet<TraceType>`]
pub fn new(call: TransactionRequest) -> Self {
Self {
call,
trace_types: HashSet::new(),
Expand Down
Loading
Loading