-
Notifications
You must be signed in to change notification settings - Fork 253
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
alloy_transport::BoxTransport, | ||
AnvilProvider<RootProvider<alloy_transport::BoxTransport>, alloy_transport::BoxTransport>, | ||
PhantomData<MyContract::doStuffCall>, |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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
// 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 () {} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
pub trait Transport {} | ||
impl Transport for () {} |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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
// SAFETY: `self` is `BoxTransport`. This is a no-op. | ||
let this = std::mem::ManuallyDrop::new(self); | ||
return unsafe { std::mem::transmute_copy(&this) }; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
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.
T: Transport (+ Clone)
generic parameters from almost every public API by always boxing the transport internally.IntoBoxTransport
for where this generic is still needed, mainly the builder/layer types.BoxTransportConnect
and rename (with deprecation)connect_boxed
methods to simpler names.connect_builtin
and similar to justconnect
.boxed()
methods, as they just returnself
nowBreaking changes have been adjusted to not require any changes in alloy-core (
sol!
macro); mainly,CallBuilder
andEvent
will keep theT
generic, but the trait bounds are replaced with a fakeTransport
trait only exposed tosol!
, so that the compiler is able to infer the type to be()
, the only implementer of that fake trait.