Skip to content

Commit

Permalink
rename middleware to provider
Browse files Browse the repository at this point in the history
  • Loading branch information
prestwich committed Aug 21, 2023
1 parent 5770e67 commit 0c6b2c9
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 20 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# alloy-next

### Layout

- alloy-json-rpc
- Core data types for JSON-RPC 2.0
- alloy-transports
- Transports and RPC call futures.
- alloy-networks
- Network abstraction for RPC types. Allows capturing different RPC param and response types on a per-network basis.
- alloy-provider
- Based on ethers::middleware::Middleware, but abstract over <N>, and object-safe.
5 changes: 2 additions & 3 deletions crates/networks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use alloy_json_rpc::RpcObject;

/// Captures type info for network-specific RPC requests/responses
/// Captures type info for network-specific RPC requests/responses.
pub trait Network: Sized + Send + Sync + 'static {
#[doc(hidden)]
/// Asserts that this trait can only be implemented on a ZST.
const __ASSERT_ZST: bool = {
const __ASSERT_ZST: () = {
assert!(std::mem::size_of::<Self>() == 0, "Network must be a ZST");
true
};

/// The JSON body of a transaction request.
Expand Down
File renamed without changes.
112 changes: 112 additions & 0 deletions crates/provider/src/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use std::marker::PhantomData;

use alloy_networks::Network;
use alloy_transports::Transport;

use crate::Provider;

/// A layering abstraction in the vein of [`tower::Layer`]
///
/// [`tower::Layer`]: https://docs.rs/tower/latest/tower/trait.Layer.html
pub trait ProviderLayer<P: Provider<N, T>, N: Network, T: Transport> {
type Provider: Provider<N, T>;

fn layer(&self, inner: P) -> Self::Provider;
}

pub struct Stack<T, Inner, Outer> {
inner: Inner,
outer: Outer,
_pd: std::marker::PhantomData<fn() -> T>,
}

impl<T, Inner, Outer> Stack<T, Inner, Outer> {
/// Create a new `Stack`.
pub fn new(inner: Inner, outer: Outer) -> Self {
Stack {
inner,
outer,
_pd: std::marker::PhantomData,
}
}
}

impl<P, N, T, Inner, Outer> ProviderLayer<P, N, T> for Stack<T, Inner, Outer>
where
T: Transport,
N: Network,
P: Provider<N, T>,
Inner: ProviderLayer<P, N, T>,
Outer: ProviderLayer<Inner::Provider, N, T>,
{
type Provider = Outer::Provider;

fn layer(&self, provider: P) -> Self::Provider {
let inner = self.inner.layer(provider);

self.outer.layer(inner)
}
}

/// A builder for constructing a [`Provider`] from various layers.
pub struct ProviderBuilder<L, N = (), T = ()> {
layer: L,

transport: PhantomData<T>,
network: PhantomData<N>,
}

impl<L, N, T> ProviderBuilder<L, N, T> {
pub fn layer<Inner>(self, layer: Inner) -> ProviderBuilder<Stack<T, Inner, L>> {
ProviderBuilder {
layer: Stack::new(layer, self.layer),
transport: PhantomData,
network: PhantomData,
}
}

/// Change the network.
pub fn network<Net: Network>(self) -> ProviderBuilder<L, Net, T> {
ProviderBuilder {
layer: self.layer,
transport: self.transport,
network: PhantomData,
}
}

pub fn provider<P>(self, provider: P) -> L::Provider
where
L: ProviderLayer<P, N, T>,
P: Provider<N, T>,
T: Transport,
N: Network,
{
self.layer.layer(provider)
}
}

// Copyright (c) 2019 Tower Contributors

// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the
// Software without restriction, including without
// limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following
// conditions:

// The above copyright notice and this permission notice
// shall be included in all copies or substantial portions
// of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
27 changes: 10 additions & 17 deletions crates/middleware/src/lib.rs → crates/provider/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
mod builder;
pub use builder::{ProviderBuilder, ProviderLayer, Stack};

use alloy_json_rpc::RpcResult;
use alloy_networks::{Network, Transaction};
use alloy_primitives::Address;
Expand All @@ -9,13 +12,13 @@ pub type MwareFut<'a, T, E> = Pin<Box<dyn Future<Output = RpcResult<T, E>> + Sen

/// Middleware is parameterized with a network and a transport. The default
/// transport is type-erased, but you can do `Middleware<N, Http>`.
pub trait Middleware<N: Network, T: Transport = BoxTransport>: Send + Sync {
pub trait Provider<N: Network, T: Transport = BoxTransport>: Send + Sync {
fn client(&self) -> &RpcClient<T>;

/// Return a reference to the inner Middleware.
///
/// Middleware are object safe now :)
fn inner(&self) -> &dyn Middleware<N, T>;
fn inner(&self) -> &dyn Provider<N, T>;

fn estimate_gas<'s: 'fut, 'a: 'fut, 'fut>(
&'s self,
Expand Down Expand Up @@ -66,13 +69,13 @@ pub trait Middleware<N: Network, T: Transport = BoxTransport>: Send + Sync {
}
}

impl<N: Network, T: Transport + Clone> Middleware<N, T> for RpcClient<T> {
impl<N: Network, T: Transport + Clone> Provider<N, T> for RpcClient<T> {
fn client(&self) -> &RpcClient<T> {
self
}

fn inner(&self) -> &dyn Middleware<N, T> {
panic!("called inner on <RpcClient as Middleware>")
fn inner(&self) -> &dyn Provider<N, T> {
panic!("called inner on <RpcClient as Provider>")
}

fn estimate_gas<'s: 'fut, 'a: 'fut, 'fut>(
Expand Down Expand Up @@ -105,22 +108,12 @@ impl<N: Network, T: Transport + Clone> Middleware<N, T> for RpcClient<T> {
}
}

/// Middleware use a tower-like Layer abstraction
pub trait MwareLayer<N: Network> {
type Middleware<T: Transport>: Middleware<N, T>;

fn layer<M, T>(&self, inner: M) -> Self::Middleware<T>
where
M: Middleware<N, T>,
T: Transport;
}

#[cfg(test)]
mod test {
use crate::Middleware;
use crate::Provider;
use alloy_networks::Network;

fn __compile_check<N: Network>() -> Box<dyn Middleware<N>> {
fn __compile_check<N: Network>() -> Box<dyn Provider<N>> {
unimplemented!()
}
}

0 comments on commit 0c6b2c9

Please sign in to comment.