From 9742f1d88a010aed343c6c71ca2b6e2541336a66 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 09:31:33 -0700 Subject: [PATCH 1/8] feature: wasm-compatability --- crates/providers/src/lib.rs | 6 ++- crates/transports/Cargo.toml | 2 +- crates/transports/src/batch.rs | 4 +- crates/transports/src/call.rs | 12 +----- crates/transports/src/client.rs | 34 ++++++++++++----- crates/transports/src/lib.rs | 32 ++++++++++++++++ .../transports/src/transports/http/hyper.rs | 8 ++-- crates/transports/src/transports/http/mod.rs | 33 ++++++++++++++--- .../transports/src/transports/http/reqwest.rs | 15 +++----- crates/transports/src/transports/mod.rs | 37 ++++++++++++++----- 10 files changed, 129 insertions(+), 54 deletions(-) diff --git a/crates/providers/src/lib.rs b/crates/providers/src/lib.rs index d6bc55c9119..045923096c4 100644 --- a/crates/providers/src/lib.rs +++ b/crates/providers/src/lib.rs @@ -54,7 +54,8 @@ where } } -#[async_trait::async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] /// Provider is parameterized with a network and a transport. The default /// transport is type-erased, but you can do `Provider`. pub trait Provider: Send + Sync { @@ -105,7 +106,8 @@ pub trait Provider: Send + Sync { } } -#[async_trait::async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] impl Provider for NetworkRpcClient { fn client(&self) -> &NetworkRpcClient { self diff --git a/crates/transports/Cargo.toml b/crates/transports/Cargo.toml index 0adfd4b2565..d60382d8296 100644 --- a/crates/transports/Cargo.toml +++ b/crates/transports/Cargo.toml @@ -30,6 +30,6 @@ reqwest = { version = "0.11.18", features = ["serde_json", "json"], optional = t hyper = { version = "0.14.27", optional = true, features = ["full"] } [features] -default = ["reqwest", "hyper"] +default = ["reqwest"] reqwest = ["dep:reqwest"] hyper = ["dep:hyper", "hyper/client"] \ No newline at end of file diff --git a/crates/transports/src/batch.rs b/crates/transports/src/batch.rs index 3215cebfb00..6fbf46cb6f0 100644 --- a/crates/transports/src/batch.rs +++ b/crates/transports/src/batch.rs @@ -63,7 +63,7 @@ where pub enum BatchFuture where Conn: Transport + Clone, - Conn::Future: Send, + // Conn::Future: Send, { Prepared { transport: Conn, @@ -250,7 +250,7 @@ where impl Future for BatchFuture where T: Transport + Clone, - T::Future: Send, + // T::Future: Send, { type Output = Result<(), TransportError>; diff --git a/crates/transports/src/call.rs b/crates/transports/src/call.rs index 854e2f420af..d21d45f63e0 100644 --- a/crates/transports/src/call.rs +++ b/crates/transports/src/call.rs @@ -1,6 +1,7 @@ use crate::{ error::TransportError, transports::{JsonRpcLayer, JsonRpcService, Transport}, + RpcFut, }; use alloy_json_rpc::{Request, RpcParam, RpcResult, RpcReturn}; @@ -15,7 +16,6 @@ use tower::{Layer, Service}; enum CallState where Conn: Transport + Clone, - Conn::Future: Send, Params: RpcParam, { Prepared { @@ -32,7 +32,6 @@ where impl CallState where Conn: Transport + Clone, - Conn::Future: Send, Params: RpcParam, { fn poll_prepared( @@ -79,7 +78,6 @@ where impl Future for CallState where Conn: Transport + Clone, - Conn::Future: Send, Params: RpcParam, { type Output = RpcResult, TransportError>; @@ -120,7 +118,6 @@ where pub struct RpcCall where Conn: Transport + Clone, - Conn::Future: Send, Params: RpcParam, { #[pin] @@ -131,7 +128,6 @@ where impl RpcCall where Conn: Transport + Clone, - Conn::Future: Send, Params: RpcParam, { #[doc(hidden)] @@ -164,14 +160,11 @@ where impl<'a, Conn, Params, Resp> RpcCall where Conn: Transport + Clone, - Conn::Future: Send, Params: RpcParam + 'a, Resp: RpcReturn, { /// Convert this future into a boxed, pinned future, erasing its type. - pub fn boxed( - self, - ) -> Pin> + Send + 'a>> { + pub fn boxed(self) -> RpcFut<'a, Resp> { Box::pin(self) } } @@ -179,7 +172,6 @@ where impl Future for RpcCall where Conn: Transport + Clone, - Conn::Future: Send, Params: RpcParam, Resp: RpcReturn, { diff --git a/crates/transports/src/client.rs b/crates/transports/src/client.rs index 39a949a2364..cecb00dcd1c 100644 --- a/crates/transports/src/client.rs +++ b/crates/transports/src/client.rs @@ -1,6 +1,8 @@ use alloy_json_rpc::{Id, Request, RpcParam, RpcReturn}; -use serde_json::value::RawValue; -use tower::{layer::util::Stack, Layer, ServiceBuilder}; +use tower::{ + layer::util::{Identity, Stack}, + Layer, ServiceBuilder, +}; use std::{ borrow::Cow, @@ -31,6 +33,14 @@ pub struct RpcClient { pub(crate) id: AtomicU64, } +impl RpcClient { + pub fn builder() -> ClientBuilder { + ClientBuilder { + builder: ServiceBuilder::new(), + } + } +} + impl RpcClient { /// Create a new [`RpcClient`] with the given transport. pub fn new(t: T, is_local: bool) -> Self { @@ -73,7 +83,6 @@ impl RpcClient { impl RpcClient where T: Transport + Clone, - T::Future: Send, { /// Create a new [`BatchRequest`] builder. #[inline] @@ -144,6 +153,14 @@ pub struct ClientBuilder { builder: ServiceBuilder, } +impl Default for ClientBuilder { + fn default() -> Self { + Self { + builder: ServiceBuilder::new(), + } + } +} + impl ClientBuilder { /// Add a middleware layer to the stack. /// @@ -162,37 +179,34 @@ impl ClientBuilder { L: Layer, T: Transport, L::Service: Transport, - >>::Future: Send, { RpcClient::new(self.builder.service(transport), is_local) } - #[cfg(feature = "reqwest")] /// Create a new [`RpcClient`] with a [`reqwest`] HTTP transport connecting /// to the given URL and the configured layers. + #[cfg(feature = "reqwest")] pub fn reqwest_http(self, url: reqwest::Url) -> RpcClient where L: Layer>, L::Service: Transport, - >>::Future: Send, { let transport = Http::new(url); - let is_local = transport.is_local(); + let is_local = transport.guess_local(); self.transport(transport, is_local) } - #[cfg(feature = "hyper")] /// Create a new [`RpcClient`] with a [`hyper`] HTTP transport connecting /// to the given URL and the configured layers. + #[cfg(feature = "hyper")] pub fn hyper_http(self, url: url::Url) -> RpcClient where L: Layer>>, L::Service: Transport, - >>::Future: Send, { let transport = Http::new(url); - let is_local = transport.is_local(); + let is_local = transport.guess_local(); self.transport(transport, is_local) } diff --git a/crates/transports/src/lib.rs b/crates/transports/src/lib.rs index b489f06999a..e011e6ccb66 100644 --- a/crates/transports/src/lib.rs +++ b/crates/transports/src/lib.rs @@ -20,3 +20,35 @@ pub use transports::{BoxTransport, Http, Transport}; pub use alloy_json_rpc::RpcResult; pub(crate) mod utils; + +pub use type_aliases::*; + +#[cfg(not(target_arch = "wasm32"))] +mod type_aliases { + use alloy_json_rpc::RpcResult; + + use crate::TransportError; + + /// Future for Transport-level requests. + pub type TransportFut<'a, T = Box, E = TransportError> = + std::pin::Pin> + Send + 'a>>; + + /// Future for RPC-level requests. + pub type RpcFut<'a, T, E = TransportError> = + std::pin::Pin> + Send + 'a>>; +} + +#[cfg(target_arch = "wasm32")] +mod type_aliases { + use alloy_json_rpc::RpcResult; + + use crate::TransportError; + + /// Future for Transport-level requests. + pub type TransportFut<'a, T = Box, E = TransportError> = + std::pin::Pin> + 'a>>; + + /// Future for RPC-level requests. + pub type RpcFut<'a, T, E = TransportError> = + std::pin::Pin> + 'a>>; +} diff --git a/crates/transports/src/transports/http/hyper.rs b/crates/transports/src/transports/http/hyper.rs index 219ee985cf1..443e7ab5f3f 100644 --- a/crates/transports/src/transports/http/hyper.rs +++ b/crates/transports/src/transports/http/hyper.rs @@ -3,7 +3,7 @@ use serde_json::value::RawValue; use std::{future::Future, pin::Pin, task}; use tower::Service; -use crate::{Http, TransportError}; +use crate::{Http, TransportError, TransportFut}; impl Http> where @@ -44,8 +44,7 @@ where { type Response = Box; type Error = TransportError; - type Future = - Pin> + Send + 'static>>; + type Future = TransportFut; #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { @@ -65,8 +64,7 @@ where { type Response = Box; type Error = TransportError; - type Future = - Pin> + Send + 'static>>; + type Future = TransportFut; #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { diff --git a/crates/transports/src/transports/http/mod.rs b/crates/transports/src/transports/http/mod.rs index a79b2edc1a0..0b20c42576b 100644 --- a/crates/transports/src/transports/http/mod.rs +++ b/crates/transports/src/transports/http/mod.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "hyper")] +#[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] mod hyper; #[cfg(feature = "reqwest")] @@ -41,13 +41,36 @@ impl Http { Self { client, url } } - /// True if the connection has no hostname, or the hostname is `localhost` - /// or `127.0.0.1`. - pub fn is_local(&self) -> bool { + /// Set the URL. + pub fn set_url(&mut self, url: Url) { + self.url = url; + } + + /// Set the client. + pub fn set_client(&mut self, client: T) { + self.client = client; + } + + /// Guess whether the URL is local, based on the hostname. + /// + /// The ouput of this function is best-efforts, and should be checked if + /// possible. It simply returns `true` if the connection has no hostname, + /// or the hostname is `localhost` or `127.0.0.1`. + pub fn guess_local(&self) -> bool { self.url .host_str() .map_or(true, |host| host == "localhost" || host == "127.0.0.1") } + + /// Get a reference to the client. + pub fn client(&self) -> &T { + &self.client + } + + /// Get a reference to the URL. + pub fn url(&self) -> &str { + self.url.as_ref() + } } impl RpcClient> @@ -57,7 +80,7 @@ where /// Create a new [`RpcClient`] from a URL. pub fn new_http(url: Url) -> Self { let transport = Http::new(url); - let is_local = transport.is_local(); + let is_local = transport.guess_local(); Self { transport, is_local, diff --git a/crates/transports/src/transports/http/reqwest.rs b/crates/transports/src/transports/http/reqwest.rs index f0c306ad227..78f56dbb767 100644 --- a/crates/transports/src/transports/http/reqwest.rs +++ b/crates/transports/src/transports/http/reqwest.rs @@ -1,14 +1,11 @@ use serde_json::value::RawValue; -use std::{future::Future, pin::Pin, task}; +use std::task; use tower::Service; -use crate::{Http, TransportError}; +use crate::{Http, TransportError, TransportFut}; impl Http { - fn request( - &self, - req: Box, - ) -> Pin, TransportError>> + Send + 'static>> { + fn request(&self, req: Box) -> TransportFut<'static> { let this = self.clone(); Box::pin(async move { let resp = this.client.post(this.url).json(&req).send().await?; @@ -22,8 +19,7 @@ impl Http { impl Service> for Http { type Response = Box; type Error = TransportError; - type Future = - Pin> + Send + 'static>>; + type Future = TransportFut<'static>; #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { @@ -40,8 +36,7 @@ impl Service> for Http { impl Service> for &Http { type Response = Box; type Error = TransportError; - type Future = - Pin> + Send + 'static>>; + type Future = TransportFut<'static>; #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { diff --git a/crates/transports/src/transports/mod.rs b/crates/transports/src/transports/mod.rs index a92f9fa2601..07c10ebe120 100644 --- a/crates/transports/src/transports/mod.rs +++ b/crates/transports/src/transports/mod.rs @@ -5,27 +5,30 @@ mod json_service; pub(crate) use json_service::{JsonRpcLayer, JsonRpcService}; use serde_json::value::RawValue; -use std::{future::Future, pin::Pin}; +use std::fmt::Debug; use tower::Service; -use crate::TransportError; +use crate::{TransportError, TransportFut}; /// A marker trait for transports. /// +/// # Implementing `Transport` +/// /// This trait is blanket implemented for all appropriate types. To implement /// this trait, you must implement the [`tower::Service`] trait with the -/// appropriate associated types. +/// appropriate associated types. It cannot be implemented directly. pub trait Transport: private::Sealed + Service< Box, Response = Box, Error = TransportError, - Future = Pin, TransportError>> + Send>>, + Future = TransportFut<'static>, > + Send + Sync + 'static { + /// Convert this transport into a boxed trait object. fn boxed(self) -> BoxTransport where Self: Sized + Clone + Send + Sync + 'static, @@ -42,17 +45,34 @@ impl Transport for T where Box, Response = Box, Error = TransportError, - Future = Pin, TransportError>> + Send>>, + Future = TransportFut<'static>, > + Send + Sync + 'static { } +/// A boxed, Clone-able [`Transport`] trait object. +/// +/// This type allows [`RpcClient`] to use a type-erased transport. It is +/// [`Clone`] and [`Send`] + [`Sync`], and implementes [`Transport`]. This +/// allows for complex behavior abstracting across several different clients +/// with different transport types. +/// +/// Most higher-level types will be generic over `T: Transport = BoxTransport`. +/// This allows paramterization with a concrete type, while hiding this +/// complexity from the library consumer. +#[repr(transparent)] pub struct BoxTransport { inner: Box, } +impl Debug for BoxTransport { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("BoxTransport").finish() + } +} + impl Clone for BoxTransport { fn clone(&self) -> Self { Self { @@ -61,6 +81,7 @@ impl Clone for BoxTransport { } } +/// Helper trait for constructing [`BoxTransport`]. trait CloneTransport: Transport { fn clone_box(&self) -> Box; } @@ -79,7 +100,7 @@ impl Service> for BoxTransport { type Error = TransportError; - type Future = Pin, TransportError>> + Send>>; + type Future = TransportFut<'static>; fn poll_ready( &mut self, @@ -110,9 +131,7 @@ mod private { Box, Response = Box, Error = TransportError, - Future = Pin< - Box, TransportError>> + Send>, - >, + Future = TransportFut<'static>, > + Send + Sync + 'static From 0f0633d962e57a5bd33f27380ac14f5290412b31 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 09:39:33 -0700 Subject: [PATCH 2/8] feature: wasm-compatability --- .github/workflows/ci.yml | 24 ++++++++++++------------ crates/transports/Cargo.toml | 6 +++++- crates/transports/README.md | 2 +- crates/transports/src/client.rs | 2 +- crates/transports/src/error.rs | 2 +- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 301528791f2..f0e64cd59ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,18 +27,18 @@ jobs: - name: test run: cargo test --workspace ${{ matrix.flags }} - # wasm: - # name: check WASM - # runs-on: ubuntu-latest - # timeout-minutes: 30 - # steps: - # - uses: actions/checkout@v3 - # - uses: dtolnay/rust-toolchain@stable - # with: - # targets: wasm32-unknown-unknown - # - uses: Swatinem/rust-cache@v2 - # - name: check - # run: cargo check --workspace --target wasm32-unknown-unknown + wasm: + name: check WASM + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown + - uses: Swatinem/rust-cache@v2 + - name: check + run: cargo check --workspace --target wasm32-unknown-unknown feature-checks: name: feature checks diff --git a/crates/transports/Cargo.toml b/crates/transports/Cargo.toml index d60382d8296..97bcc7309b4 100644 --- a/crates/transports/Cargo.toml +++ b/crates/transports/Cargo.toml @@ -27,7 +27,11 @@ pin-project.workspace = true # feature deps reqwest = { version = "0.11.18", features = ["serde_json", "json"], optional = true } -hyper = { version = "0.14.27", optional = true, features = ["full"] } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.hyper] +version = "0.14.27" +optional = true +features = ["full"] [features] default = ["reqwest"] diff --git a/crates/transports/README.md b/crates/transports/README.md index f2554df12c5..6de5e3b0c88 100644 --- a/crates/transports/README.md +++ b/crates/transports/README.md @@ -58,4 +58,4 @@ let balance = balance_fut.await.unwrap(); ### Features - `reqwest`: Enables the `reqwest` transport implementation. -- `hyper`: Enables the `hyper` transport implementation. +- `hyper`: Enables the `hyper` transport implementation (not available in WASM). diff --git a/crates/transports/src/client.rs b/crates/transports/src/client.rs index cecb00dcd1c..6ffe4f5daf8 100644 --- a/crates/transports/src/client.rs +++ b/crates/transports/src/client.rs @@ -199,7 +199,7 @@ impl ClientBuilder { /// Create a new [`RpcClient`] with a [`hyper`] HTTP transport connecting /// to the given URL and the configured layers. - #[cfg(feature = "hyper")] + #[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] pub fn hyper_http(self, url: url::Url) -> RpcClient where L: Layer>>, diff --git a/crates/transports/src/error.rs b/crates/transports/src/error.rs index 313570d5bbc..b08545781ef 100644 --- a/crates/transports/src/error.rs +++ b/crates/transports/src/error.rs @@ -28,7 +28,7 @@ pub enum TransportError { /// Hyper http transport #[error(transparent)] - #[cfg(feature = "hyper")] + #[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] Hyper(#[from] hyper::Error), } From b733870a29e1d6a121212f0918c3c27f7232b123 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 10:02:40 -0700 Subject: [PATCH 3/8] fix: hyper --- crates/transports/Cargo.toml | 2 +- crates/transports/src/transports/http/hyper.rs | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/crates/transports/Cargo.toml b/crates/transports/Cargo.toml index 97bcc7309b4..b6586121ba5 100644 --- a/crates/transports/Cargo.toml +++ b/crates/transports/Cargo.toml @@ -34,6 +34,6 @@ optional = true features = ["full"] [features] -default = ["reqwest"] +default = ["reqwest", "hyper"] reqwest = ["dep:reqwest"] hyper = ["dep:hyper", "hyper/client"] \ No newline at end of file diff --git a/crates/transports/src/transports/http/hyper.rs b/crates/transports/src/transports/http/hyper.rs index 443e7ab5f3f..8053b0f7b9b 100644 --- a/crates/transports/src/transports/http/hyper.rs +++ b/crates/transports/src/transports/http/hyper.rs @@ -1,6 +1,6 @@ use hyper::client::{connect::Connect, Client}; use serde_json::value::RawValue; -use std::{future::Future, pin::Pin, task}; +use std::task; use tower::Service; use crate::{Http, TransportError, TransportFut}; @@ -9,10 +9,7 @@ impl Http> where C: Connect + Clone + Send + Sync + 'static, { - pub fn request( - &self, - req: Box, - ) -> Pin, TransportError>> + Send + 'static>> { + pub fn request(&self, req: Box) -> TransportFut<'static> { let this = self.clone(); Box::pin(async move { // convert the Box into a hyper request @@ -44,7 +41,7 @@ where { type Response = Box; type Error = TransportError; - type Future = TransportFut; + type Future = TransportFut<'static>; #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { @@ -64,7 +61,7 @@ where { type Response = Box; type Error = TransportError; - type Future = TransportFut; + type Future = TransportFut<'static>; #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { From 153541790c7d3b0acae4f590ba5e2b49524d00f4 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 10:03:52 -0700 Subject: [PATCH 4/8] docs: a couple lines --- crates/transports/src/transports/http/hyper.rs | 3 ++- crates/transports/src/transports/http/reqwest.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/transports/src/transports/http/hyper.rs b/crates/transports/src/transports/http/hyper.rs index 8053b0f7b9b..72032801eda 100644 --- a/crates/transports/src/transports/http/hyper.rs +++ b/crates/transports/src/transports/http/hyper.rs @@ -9,7 +9,8 @@ impl Http> where C: Connect + Clone + Send + Sync + 'static, { - pub fn request(&self, req: Box) -> TransportFut<'static> { + /// Make a request. + fn request(&self, req: Box) -> TransportFut<'static> { let this = self.clone(); Box::pin(async move { // convert the Box into a hyper request diff --git a/crates/transports/src/transports/http/reqwest.rs b/crates/transports/src/transports/http/reqwest.rs index 78f56dbb767..49286c4627e 100644 --- a/crates/transports/src/transports/http/reqwest.rs +++ b/crates/transports/src/transports/http/reqwest.rs @@ -5,6 +5,7 @@ use tower::Service; use crate::{Http, TransportError, TransportFut}; impl Http { + /// Make a request. fn request(&self, req: Box) -> TransportFut<'static> { let this = self.clone(); Box::pin(async move { From 2c4f6dc28ff739d065d3082275923ac879399286 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 10:04:47 -0700 Subject: [PATCH 5/8] doc: fix link --- crates/transports/src/transports/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/transports/src/transports/mod.rs b/crates/transports/src/transports/mod.rs index 07c10ebe120..7262fb5b117 100644 --- a/crates/transports/src/transports/mod.rs +++ b/crates/transports/src/transports/mod.rs @@ -62,6 +62,8 @@ impl Transport for T where /// Most higher-level types will be generic over `T: Transport = BoxTransport`. /// This allows paramterization with a concrete type, while hiding this /// complexity from the library consumer. +/// +/// [`RpcClient`]: crate::client::RpcClient #[repr(transparent)] pub struct BoxTransport { inner: Box, From fb5540158536b951da951a4dcecedbf967ab483f Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 10:07:26 -0700 Subject: [PATCH 6/8] fix: remove commented bounds --- crates/transports/src/batch.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/transports/src/batch.rs b/crates/transports/src/batch.rs index 6fbf46cb6f0..d165c607b60 100644 --- a/crates/transports/src/batch.rs +++ b/crates/transports/src/batch.rs @@ -63,7 +63,6 @@ where pub enum BatchFuture where Conn: Transport + Clone, - // Conn::Future: Send, { Prepared { transport: Conn, @@ -250,7 +249,6 @@ where impl Future for BatchFuture where T: Transport + Clone, - // T::Future: Send, { type Output = Result<(), TransportError>; From 4fbe8716d51e4814b3a950355d7dae51bb63c3e3 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 10:38:06 -0700 Subject: [PATCH 7/8] chore: some batch request cleanup --- crates/transports/src/batch.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/transports/src/batch.rs b/crates/transports/src/batch.rs index d165c607b60..2d0aae22b87 100644 --- a/crates/transports/src/batch.rs +++ b/crates/transports/src/batch.rs @@ -21,14 +21,18 @@ type ChannelMap = HashMap; /// call. #[derive(Debug)] pub struct BatchRequest<'a, T> { + /// The transport via which the batch will be sent. transport: &'a RpcClient, + /// The requests to be sent. requests: Vec>, + /// The channels to send the responses through. channels: ChannelMap, } /// Awaits a single response for a request that has been included in a batch. +#[must_use = "A Waiter does nothing unless the corresponding BatchRequest is sent via `send_batch` and `.await`, AND the Waiter is awaited."] pub struct Waiter { rx: oneshot::Receiver, TransportError>>, _resp: PhantomData, @@ -62,7 +66,7 @@ where #[pin_project::pin_project(project = CallStateProj)] pub enum BatchFuture where - Conn: Transport + Clone, + Conn: Transport, { Prepared { transport: Conn, From b5eb3c166b1cd0c999fa874e0c15c1aee05e7e7f Mon Sep 17 00:00:00 2001 From: James Date: Tue, 5 Sep 2023 10:41:46 -0700 Subject: [PATCH 8/8] refactor: relax a bound --- crates/transports/src/client.rs | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/crates/transports/src/client.rs b/crates/transports/src/client.rs index 6ffe4f5daf8..67f821e88d0 100644 --- a/crates/transports/src/client.rs +++ b/crates/transports/src/client.rs @@ -51,6 +51,23 @@ impl RpcClient { } } + /// Build a `JsonRpcRequest` with the given method and params. + /// + /// This function reserves an ID for the request, however the request + /// is not sent. To send a request, use [`RpcClient::prepare`] and await + /// the returned [`RpcCall`]. + pub fn make_request<'a, Params: RpcParam>( + &self, + method: &'static str, + params: Cow<'a, Params>, + ) -> Request> { + Request { + method, + params, + id: self.next_id(), + } + } + /// `true` if the client believes the transport is local. /// /// This can be used to optimize remote API usage, or to change program @@ -90,23 +107,6 @@ where BatchRequest::new(self) } - /// Build a `JsonRpcRequest` with the given method and params. - /// - /// This function reserves an ID for the request, however the request - /// is not sent. To send a request, use [`RpcClient::prepare`] and await - /// the returned [`RpcCall`]. - pub fn make_request<'a, Params: RpcParam>( - &self, - method: &'static str, - params: Cow<'a, Params>, - ) -> Request> { - Request { - method, - params, - id: self.next_id(), - } - } - /// Prepare an [`RpcCall`]. /// /// This function reserves an ID for the request, however the request