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

Conversation

DaniPopes
Copy link
Member

Currently, every high-level type derived from RPC client contains a T: Transport + Clone = BoxTransport generic parameter.

However, there is, AFAICT, no benefit to exposing this generic in high-level types. The dynamic dispatch performance impact is negligible compared to what a transport actually does (many syscalls, network calls, etc.), and it only complicates generic bounds where any of those types are used.

  • Remove T: Transport (+ Clone) generic parameters from almost every public API by always boxing the transport internally.
  • Add a public IntoBoxTransport for where this generic is still needed, mainly the builder/layer types.
  • Remove BoxTransportConnect and rename (with deprecation) connect_boxed methods to simpler names.
    • driveby: Rename (with deprecation) connect_builtin and similar to just connect
  • Deprecate .boxed() methods, as they just return self now

Breaking changes have been adjusted to not require any changes in alloy-core (sol! macro); mainly, CallBuilder and Event will keep the T generic, but the trait bounds are replaced with a fake Transport trait only exposed to sol!, so that the compiler is able to infer the type to be (), the only implementer of that fake trait.

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

removing the (useless) transport generic is long overdue.

only have some questions and a smol ask to describe the alloy-provider <-> sol! macro relationship

we also need to migrate https://github.com/alloy-rs/examples should we do this against this branch or later?

this requires a minor release, I'm fine with doing that whenever but would prefer if we had the examples migrated already

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

crates/contract/src/call.rs Outdated Show resolved Hide resolved
Comment on lines -625 to -627
alloy_transport::BoxTransport,
AnvilProvider<RootProvider<alloy_transport::BoxTransport>, alloy_transport::BoxTransport>,
PhantomData<MyContract::doStuffCall>,
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

use std::marker::PhantomData;

/// A handle to an Ethereum contract at a specific address.
///
/// A contract is an abstraction of an executable program on Ethereum. Every deployed contract has
/// an address, which is used to connect to it so that it may receive messages (transactions).
#[derive(Clone)]
pub struct ContractInstance<T, P, N = Ethereum> {
pub struct ContractInstance<P, N = Ethereum> {
Copy link
Member

Choose a reason for hiding this comment

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

great, this was annoying af

Comment on lines +39 to +46
// Fake traits to mitigate `sol!` macro breaking changes.
pub trait Provider<T, N: Network>: alloy_provider::Provider<N> {}
impl<N: Network, P: alloy_provider::Provider<N>> Provider<(), N> for P {}

// This is done so that the compiler can infer the `T` type to be `()`, which is the only type
// that implements this fake `Transport` trait.
pub trait Transport {}
impl Transport for () {}
Copy link
Member

Choose a reason for hiding this comment

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

could we perhaps add some docs to the release checklist that covers alloy-provider <-> sol! and what we need to keep in mind

Copy link
Member Author

Choose a reason for hiding this comment

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

the docs is don't do it, if you have to, message me

Comment on lines +45 to +46
pub trait Transport {}
impl Transport for () {}
Copy link
Member

Choose a reason for hiding this comment

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

I see, now I get it


/// Admin namespace rpc interface that gives access to several non-standard RPC methods.
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
pub trait AdminApi<N, T>: Send + Sync {
pub trait AdminApi<N>: Send + Sync {
Copy link
Member

@mattsse mattsse Dec 31, 2024

Choose a reason for hiding this comment

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

this network generic is also kinda pointless, and only necessary because the send_request function is part of the Provider trait, we could potentially split these off, but not in this pr

Comment on lines +25 to +27
// SAFETY: `self` is `BoxTransport`. This is a no-op.
let this = std::mem::ManuallyDrop::new(self);
return unsafe { std::mem::transmute_copy(&this) };
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 difference between this and just a regular transmute?

Copy link
Member Author

Choose a reason for hiding this comment

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

transmute doesn't allow size mismatch, T has generic size so it never works

Copy link
Member

Choose a reason for hiding this comment

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

I see, so we effectively just copy the pointer here? hence the manual drop

Copy link
Member Author

@DaniPopes DaniPopes Dec 31, 2024

Choose a reason for hiding this comment

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

yeah, would be just return self

@DaniPopes
Copy link
Member Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants