Skip to content

Commit

Permalink
feat!: remove T: Transport from public APIs (#1859)
Browse files Browse the repository at this point in the history
* feat: remove T: Transport from public APIs

* fix: keep T for sol macro APIs, fix doctests

* fix: warning in consensus

* docs

* feat: subsume BoxTransportConnect into TransportConnect, rename methods

* nits

* chore: more deprecations

* fix: specialize BoxTransport::new(BoxTransport)

* chore: clippy

* docs

* msrv

* com
  • Loading branch information
DaniPopes authored Jan 6, 2025
1 parent 69f7631 commit 46ec4b1
Show file tree
Hide file tree
Showing 53 changed files with 745 additions and 920 deletions.
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.
// 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>,
> {
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

0 comments on commit 46ec4b1

Please sign in to comment.