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

feat!: remove T: Transport from public APIs #1859

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions crates/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

extern crate alloc;

#[cfg(feature = "arbitrary")]
use rand as _;

pub use alloy_trie::TrieAccount;

#[deprecated(since = "0.7.3", note = "use TrieAccount instead")]
Expand Down
61 changes: 29 additions & 32 deletions crates/contract/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ use alloy_primitives::{Address, Bytes, ChainId, TxKind, U256};
use alloy_provider::{PendingTransactionBuilder, Provider};
use alloy_rpc_types_eth::{state::StateOverride, AccessList, BlobTransactionSidecar, BlockId};
use alloy_sol_types::SolCall;
use alloy_transport::Transport;
use std::{
future::{Future, IntoFuture},
marker::PhantomData,
pin::Pin,
};

// NOTE: The `T` generic here is kept to mitigate breakage with the `sol!` macro.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the breakage here?
unclear to me what the relationship with the macro is

EDIT: so the macro in alloy/core generates code for alloy/alloy
this makes upgrading a bit weird, but manageable I assume

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

// It should always be `()` and has no effect on the implementation.

/// [`CallBuilder`] using a [`SolCall`] type as the call decoder.
// NOTE: please avoid changing this type due to its use in the `sol!` macro.
pub type SolCallBuilder<T, P, C, N = Ethereum> = CallBuilder<T, P, PhantomData<C>, N>;
Expand Down Expand Up @@ -51,7 +53,7 @@ pub type RawCallBuilder<T, P, N = Ethereum> = CallBuilder<T, P, (), N>;
/// Using [`sol!`][sol]:
///
/// ```no_run
/// # async fn test<P: alloy_contract::private::Provider>(provider: P) -> Result<(), Box<dyn std::error::Error>> {
/// # async fn test<P: alloy_provider::Provider>(provider: P) -> Result<(), Box<dyn std::error::Error>> {
/// use alloy_contract::SolCallBuilder;
/// use alloy_primitives::{Address, U256};
/// use alloy_sol_types::sol;
Expand Down Expand Up @@ -87,7 +89,7 @@ pub type RawCallBuilder<T, P, N = Ethereum> = CallBuilder<T, P, (), N>;
/// Using [`ContractInstance`](crate::ContractInstance):
///
/// ```no_run
/// # async fn test<P: alloy_contract::private::Provider>(provider: P, dynamic_abi: alloy_json_abi::JsonAbi) -> Result<(), Box<dyn std::error::Error>> {
/// # async fn test<P: alloy_provider::Provider>(provider: P, dynamic_abi: alloy_json_abi::JsonAbi) -> Result<(), Box<dyn std::error::Error>> {
/// use alloy_primitives::{Address, Bytes, U256};
/// use alloy_dyn_abi::DynSolValue;
/// use alloy_contract::{CallBuilder, ContractInstance, DynCallBuilder, Interface, RawCallBuilder};
Expand All @@ -101,16 +103,16 @@ pub type RawCallBuilder<T, P, N = Ethereum> = CallBuilder<T, P, (), N>;
/// let provider = ...;
/// # );
/// let address = Address::ZERO;
/// let contract: ContractInstance<_, _, _> = interface.connect(address, &provider);
/// let contract: ContractInstance<_, _> = interface.connect(address, &provider);
///
/// // Build and call the function:
/// let call_builder: DynCallBuilder<_, _, _> = contract.function("doStuff", &[U256::ZERO.into(), true.into()])?;
/// let call_builder: DynCallBuilder<(), _, _> = contract.function("doStuff", &[U256::ZERO.into(), true.into()])?;
/// let result: Vec<DynSolValue> = call_builder.call().await?;
///
/// // You can also decode the output manually. Get the raw bytes:
/// let raw_result: Bytes = call_builder.call_raw().await?;
/// // Or, equivalently:
/// let raw_builder: RawCallBuilder<_, _, _> = call_builder.clone().clear_decoder();
/// let raw_builder: RawCallBuilder<(), _, _> = call_builder.clone().clear_decoder();
/// let raw_result: Bytes = raw_builder.call().await?;
/// // Decode the raw bytes:
/// let decoded_result: Vec<DynSolValue> = call_builder.decode_output(raw_result, false)?;
Expand All @@ -129,7 +131,7 @@ pub struct CallBuilder<T, P, D, N: Network = Ethereum> {
// NOTE: This is public due to usage in `sol!`, please avoid changing it.
pub provider: P,
decoder: D,
transport: PhantomData<T>,
fake_transport: PhantomData<T>,
}

impl<T, P, D, N: Network> CallBuilder<T, P, D, N> {
Expand All @@ -146,7 +148,7 @@ impl<T, P, D, N: Network> AsRef<N::TransactionRequest> for CallBuilder<T, P, D,
}

// See [`ContractInstance`].
impl<T: Transport + Clone, P: Provider<T, N>, N: Network> DynCallBuilder<T, P, N> {
impl<T, P: Provider<N>, N: Network> DynCallBuilder<T, P, N> {
pub(crate) fn new_dyn(
provider: P,
address: &Address,
Expand All @@ -170,23 +172,21 @@ impl<T: Transport + Clone, P: Provider<T, N>, N: Network> DynCallBuilder<T, P, N
state: self.state,
provider: self.provider,
decoder: (),
transport: PhantomData,
fake_transport: PhantomData,
}
}
}

#[doc(hidden)]
impl<'a, T: Transport + Clone, P: Provider<T, N>, C: SolCall, N: Network>
SolCallBuilder<T, &'a P, C, N>
{
impl<'a, T, P: Provider<N>, C: SolCall, N: Network> SolCallBuilder<T, &'a P, C, N> {
// `sol!` macro constructor, see `#[sol(rpc)]`. Not public API.
// NOTE: please avoid changing this function due to its use in the `sol!` macro.
pub fn new_sol(provider: &'a P, address: &Address, call: &C) -> Self {
Self::new_inner_call(provider, call.abi_encode().into(), PhantomData::<C>).to(*address)
}
}

impl<T: Transport + Clone, P: Provider<T, N>, C: SolCall, N: Network> SolCallBuilder<T, P, C, N> {
impl<T, P: Provider<N>, C: SolCall, N: Network> SolCallBuilder<T, P, C, N> {
/// Clears the decoder, returning a raw call builder.
#[inline]
pub fn clear_decoder(self) -> RawCallBuilder<T, P, N> {
Expand All @@ -196,12 +196,12 @@ impl<T: Transport + Clone, P: Provider<T, N>, C: SolCall, N: Network> SolCallBui
state: self.state,
provider: self.provider,
decoder: (),
transport: PhantomData,
fake_transport: PhantomData,
}
}
}

impl<T: Transport + Clone, P: Provider<T, N>, N: Network> RawCallBuilder<T, P, N> {
impl<T, P: Provider<N>, N: Network> RawCallBuilder<T, P, N> {
/// Sets the decoder to the provided [`SolCall`].
///
/// Converts the raw call builder into a sol call builder.
Expand Down Expand Up @@ -261,12 +261,12 @@ impl<T: Transport + Clone, P: Provider<T, N>, N: Network> RawCallBuilder<T, P, N
state: self.state,
provider: self.provider,
decoder: PhantomData::<C>,
transport: PhantomData,
fake_transport: PhantomData,
}
}
}

impl<T: Transport + Clone, P: Provider<T, N>, N: Network> RawCallBuilder<T, P, N> {
impl<T, P: Provider<N>, N: Network> RawCallBuilder<T, P, N> {
/// Creates a new call builder with the provided provider and ABI encoded input.
///
/// Will not decode the output of the call, meaning that [`call`](Self::call) will behave the
Expand All @@ -286,15 +286,15 @@ impl<T: Transport + Clone, P: Provider<T, N>, N: Network> RawCallBuilder<T, P, N
}
}

impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBuilder<T, P, D, N> {
impl<T, P: Provider<N>, D: CallDecoder, N: Network> CallBuilder<T, P, D, N> {
fn new_inner_deploy(provider: P, input: Bytes, decoder: D) -> Self {
Self {
request: <N::TransactionRequest>::default().with_deploy_code(input),
decoder,
provider,
block: BlockId::default(),
state: None,
transport: PhantomData,
fake_transport: PhantomData,
}
}

Expand All @@ -305,7 +305,7 @@ impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBu
provider,
block: BlockId::default(),
state: None,
transport: PhantomData,
fake_transport: PhantomData,
}
}

Expand Down Expand Up @@ -447,7 +447,7 @@ impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBu
/// If this is not desired, use [`call_raw`](Self::call_raw) to get the raw output data.
#[doc(alias = "eth_call")]
#[doc(alias = "call_with_overrides")]
pub fn call(&self) -> EthCall<'_, '_, D, T, N> {
pub fn call(&self) -> EthCall<'_, '_, D, N> {
self.call_raw().with_decoder(&self.decoder)
}

Expand All @@ -457,7 +457,7 @@ impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBu
/// Does not decode the output of the call, returning the raw output data instead.
///
/// See [`call`](Self::call) for more information.
pub fn call_raw(&self) -> EthCall<'_, '_, (), T, N> {
pub fn call_raw(&self) -> EthCall<'_, '_, (), N> {
let call = self.provider.call(&self.request).block(self.block);
let call = match &self.state {
Some(state) => call.overrides(state),
Expand Down Expand Up @@ -495,7 +495,7 @@ impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBu
///
/// Returns a builder for configuring the pending transaction watcher.
/// See [`Provider::send_transaction`] for more information.
pub async fn send(&self) -> Result<PendingTransactionBuilder<T, N>> {
pub async fn send(&self) -> Result<PendingTransactionBuilder<N>> {
Ok(self.provider.send_transaction(self.request.clone()).await?)
}

Expand All @@ -508,7 +508,7 @@ impl<T: Transport + Clone, P: Provider<T, N>, D: CallDecoder, N: Network> CallBu
}
}

impl<T: Transport, P: Clone, D, N: Network> CallBuilder<T, &P, D, N> {
impl<T, P: Clone, D, N: Network> CallBuilder<T, &P, D, N> {
/// Clones the provider and returns a new builder with the cloned provider.
pub fn with_cloned_provider(self) -> CallBuilder<T, P, D, N> {
CallBuilder {
Expand All @@ -517,7 +517,7 @@ impl<T: Transport, P: Clone, D, N: Network> CallBuilder<T, &P, D, N> {
state: self.state,
provider: self.provider.clone(),
decoder: self.decoder,
transport: PhantomData,
fake_transport: PhantomData,
}
}
}
Expand All @@ -534,8 +534,8 @@ impl<T: Transport, P: Clone, D, N: Network> CallBuilder<T, &P, D, N> {
/// stable yet. See [rust-lang/rust#63063](https://github.com/rust-lang/rust/issues/63063).
impl<T, P, D, N> IntoFuture for CallBuilder<T, P, D, N>
where
T: Transport + Clone,
P: Provider<T, N>,
T: Send + Sync,
P: Provider<N>,
D: CallDecoder + Send + Sync + Unpin,
N: Network,
Self: 'static,
Expand Down Expand Up @@ -621,11 +621,8 @@ mod tests {

/// Creates a new call_builder to test field modifications, taken from [call_encoding]
#[allow(clippy::type_complexity)]
fn build_call_builder() -> CallBuilder<
alloy_transport::BoxTransport,
AnvilProvider<RootProvider<alloy_transport::BoxTransport>, alloy_transport::BoxTransport>,
PhantomData<MyContract::doStuffCall>,
Comment on lines -625 to -627
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah this was kinda horrible

> {
fn build_call_builder(
) -> CallBuilder<(), AnvilProvider<RootProvider>, PhantomData<MyContract::doStuffCall>> {
let provider = ProviderBuilder::new().on_anvil();
let contract = MyContract::new(Address::ZERO, provider);
let call_builder = contract.doStuff(U256::ZERO, true).with_cloned_provider();
Expand Down
43 changes: 15 additions & 28 deletions crates/contract/src/eth_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use alloy_network::Network;
use alloy_primitives::Bytes;
use alloy_rpc_types_eth::{state::StateOverride, BlockId};
use alloy_sol_types::SolCall;
use alloy_transport::Transport;

use crate::{Error, Result};

Expand All @@ -24,54 +23,47 @@ mod private {
/// An [`alloy_provider::EthCall`] with an abi decoder.
#[must_use = "EthCall must be awaited to execute the call"]
#[derive(Clone, Debug)]
pub struct EthCall<'req, 'coder, D, T, N>
pub struct EthCall<'req, 'coder, D, N>
where
T: Transport + Clone,
N: Network,
D: CallDecoder,
{
inner: alloy_provider::EthCall<'req, T, N, Bytes>,
inner: alloy_provider::EthCall<'req, N, Bytes>,

decoder: &'coder D,
}

impl<'req, 'coder, D, T, N> EthCall<'req, 'coder, D, T, N>
impl<'req, 'coder, D, N> EthCall<'req, 'coder, D, N>
where
T: Transport + Clone,
N: Network,
D: CallDecoder,
{
/// Create a new [`EthCall`].
pub const fn new(
inner: alloy_provider::EthCall<'req, T, N, Bytes>,
decoder: &'coder D,
) -> Self {
pub const fn new(inner: alloy_provider::EthCall<'req, N, Bytes>, decoder: &'coder D) -> Self {
Self { inner, decoder }
}
}

impl<'req, T, N> EthCall<'req, 'static, (), T, N>
impl<'req, N> EthCall<'req, 'static, (), N>
where
T: Transport + Clone,
N: Network,
{
/// Create a new [`EthCall`].
pub const fn new_raw(inner: alloy_provider::EthCall<'req, T, N, Bytes>) -> Self {
pub const fn new_raw(inner: alloy_provider::EthCall<'req, N, Bytes>) -> Self {
Self::new(inner, &RAW_CODER)
}
}

impl<'req, D, T, N> EthCall<'req, '_, D, T, N>
impl<'req, D, N> EthCall<'req, '_, D, N>
where
T: Transport + Clone,
N: Network,
D: CallDecoder,
{
/// Swap the decoder for this call.
pub fn with_decoder<'new_coder, E>(
self,
decoder: &'new_coder E,
) -> EthCall<'req, 'new_coder, E, T, N>
) -> EthCall<'req, 'new_coder, E, N>
where
E: CallDecoder,
{
Expand All @@ -91,26 +83,23 @@ where
}
}

impl<'req, T, N> From<alloy_provider::EthCall<'req, T, N, Bytes>>
for EthCall<'req, 'static, (), T, N>
impl<'req, N> From<alloy_provider::EthCall<'req, N, Bytes>> for EthCall<'req, 'static, (), N>
where
T: Transport + Clone,
N: Network,
{
fn from(inner: alloy_provider::EthCall<'req, T, N, Bytes>) -> Self {
fn from(inner: alloy_provider::EthCall<'req, N, Bytes>) -> Self {
Self { inner, decoder: &RAW_CODER }
}
}

impl<'req, 'coder, D, T, N> std::future::IntoFuture for EthCall<'req, 'coder, D, T, N>
impl<'req, 'coder, D, N> std::future::IntoFuture for EthCall<'req, 'coder, D, N>
where
D: CallDecoder + Unpin,
T: Transport + Clone,
N: Network,
{
type Output = Result<D::CallOutput>;

type IntoFuture = EthCallFut<'req, 'coder, D, T, N>;
type IntoFuture = EthCallFut<'req, 'coder, D, N>;

fn into_future(self) -> Self::IntoFuture {
EthCallFut { inner: self.inner.into_future(), decoder: self.decoder }
Expand All @@ -122,20 +111,18 @@ where
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
#[allow(unnameable_types)]
pub struct EthCallFut<'req, 'coder, D, T, N>
pub struct EthCallFut<'req, 'coder, D, N>
where
T: Transport + Clone,
N: Network,
D: CallDecoder,
{
inner: <alloy_provider::EthCall<'req, T, N, Bytes> as IntoFuture>::IntoFuture,
inner: <alloy_provider::EthCall<'req, N, Bytes> as IntoFuture>::IntoFuture,
decoder: &'coder D,
}

impl<D, T, N> std::future::Future for EthCallFut<'_, '_, D, T, N>
impl<D, N> std::future::Future for EthCallFut<'_, '_, D, N>
where
D: CallDecoder + Unpin,
T: Transport + Clone,
N: Network,
{
type Output = Result<D::CallOutput>;
Expand Down
Loading
Loading