From 9c257c62c057d3e2c84e8778c34532952453e178 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 14 Jan 2025 17:01:31 -0500 Subject: [PATCH 1/2] chore: delete eth for now --- Cargo.toml | 1 - crates/eth/Cargo.toml | 19 ----- crates/eth/src/lib.rs | 122 ----------------------------- crates/router/src/ctx.rs | 10 ++- crates/router/src/error.rs | 1 + crates/router/src/lib.rs | 12 ++- crates/router/src/router.rs | 6 +- crates/router/src/routes/erased.rs | 4 +- crates/router/src/routes/future.rs | 6 +- crates/router/src/routes/method.rs | 9 ++- crates/router/src/routes/mod.rs | 1 + 11 files changed, 35 insertions(+), 156 deletions(-) delete mode 100644 crates/eth/Cargo.toml delete mode 100644 crates/eth/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 0c82ae3..4e63cbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ incremental = false [workspace.dependencies] router = { path = "./crates/router" } -eth = { path = "./crates/eth" } pubsub = { path = "./crates/pubsub" } # alloy = { version = "0.9.2", features = ["json-rpc", "rpc-types"] } diff --git a/crates/eth/Cargo.toml b/crates/eth/Cargo.toml deleted file mode 100644 index d746bac..0000000 --- a/crates/eth/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "eth" -version.workspace = true -edition.workspace = true -rust-version.workspace = true -authors.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true - -[dependencies] -reth-provider = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.5" } -reth-rpc = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.5" } -reth-rpc-eth-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.5" } - -alloy.workspace = true -tracing.workspace = true -router.workspace = true -axum = "0.8.1" diff --git a/crates/eth/src/lib.rs b/crates/eth/src/lib.rs deleted file mode 100644 index 3485f56..0000000 --- a/crates/eth/src/lib.rs +++ /dev/null @@ -1,122 +0,0 @@ -// use alloy::{ -// primitives::{Address, U256}, -// rpc::types::BlockId, -// }; -// use axum::routing::post; -// use reth_rpc_eth_api::helpers::{EthState, FullEthApi}; -// use std::{borrow::Borrow, sync::Arc}; -// use tracing::{debug_span, Instrument}; - -// #[derive(Clone)] -// pub struct EthRpcContext { -// inner: Arc, -// } - -// impl AsRef for EthRpcContext { -// fn as_ref(&self) -> &T { -// &self.inner -// } -// } - -// impl Borrow for EthRpcContext { -// fn borrow(&self) -> &T { -// &self.inner -// } -// } - -// impl core::ops::Deref for EthRpcContext { -// type Target = T; - -// fn deref(&self) -> &T { -// &self.inner -// } -// } - -// impl From for EthRpcContext -// where -// T: FullEthApi, -// { -// fn from(inner: T) -> Self { -// Self { -// inner: Arc::new(inner), -// } -// } -// } - -// macro_rules! convert_route { -// ($call:expr) => { -// convert_route!($call,) -// }; - -// ($call:expr,) => { -// convert_route!(finish @ $call.in_current_span()) - -// }; - -// ($call:expr, $name:literal) => { -// convert_route!($call, $name,) -// }; - -// ($call:expr, $name:literal,) => { -// let span = tracing::info_span!("rpc", method = $name); -// convert_route!($call, span) -// }; - -// ($call:expr, $span:expr) => { -// convert_route!($call,$span,) -// }; - -// ($call:expr, $span:expr,) => { -// { -// convert_route!(finish @ $call.instrument($span)) -// } -// }; - -// (finish @ $fut:expr) => { -// { -// $fut -// .await -// .inspect_err(|err| tracing::warn!(%err, "rpc error")) -// .map_err(drop) -// } -// }; -// } - -// /// [`Handler`] for the `eth_getTransactionCount` RPC method. -// /// -// /// [`Handler`]: router::Handler -// #[allow(non_snake_case)] -// pub async fn eth_getTransactionCount( -// params: (Address, Option), -// state: EthRpcContext, -// ) -> Result -// where -// T: FullEthApi, -// { -// let span = debug_span!("rpc", method = "getTransactionCount", address = %params.0, block_id = ?params.1); - -// convert_route!( -// EthState::transaction_count(state.as_ref(), params.0, params.1), -// span -// ) -// } - -// pub fn eth_router(t: T) -> axum::Router<()> { -// let t = t.into(); - -// let router = router::Router::>::new() -// .route("getTransactionCount", eth_getTransactionCount) -// .route("getCode", |(address, block), state: EthRpcContext| { -// async move { convert_route!(EthState::get_code(&*state, address, block)) } -// .instrument(debug_span!("rpc", method = "getCode")) -// }) -// .route("getBalance", |(address, block), state: EthRpcContext| { -// async move { convert_route!(EthState::balance(&*state, address, block)) } -// .instrument(debug_span!("rpc", method = "getBalance")) -// }) -// .with_state(t); - -// let router = router::Router::new().nest("eth", router); - -// axum::Router::new().route("/rpc", post(router)) -// } diff --git a/crates/router/src/ctx.rs b/crates/router/src/ctx.rs index 7d2ab62..1ae6fb2 100644 --- a/crates/router/src/ctx.rs +++ b/crates/router/src/ctx.rs @@ -22,12 +22,14 @@ impl From>> for HandlerCtx { impl HandlerCtx { /// Instantiate a new handler context. - pub fn new() -> Self { - Default::default() + pub const fn new() -> Self { + Self { + notifications: None, + } } /// Instantiation a new handler context with notifications enabled. - pub fn with_notifications(notifications: mpsc::Sender>) -> Self { + pub const fn with_notifications(notifications: mpsc::Sender>) -> Self { Self { notifications: Some(notifications), } @@ -35,7 +37,7 @@ impl HandlerCtx { /// Get a reference to the notification sender. This is used to /// send notifications over pubsub transports. - pub fn notifications(&self) -> Option<&mpsc::Sender>> { + pub const fn notifications(&self) -> Option<&mpsc::Sender>> { self.notifications.as_ref() } } diff --git a/crates/router/src/error.rs b/crates/router/src/error.rs index fa6c989..4af04fa 100644 --- a/crates/router/src/error.rs +++ b/crates/router/src/error.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; /// Errors that can occur when registering a method. #[derive(Debug, Clone, thiserror::Error)] pub enum RegistrationError { + /// Method name is already in use. #[error("Method already registered: {0}")] MethodAlreadyRegistered(Cow<'static, str>), } diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs index 6485fad..e47c7f2 100644 --- a/crates/router/src/lib.rs +++ b/crates/router/src/lib.rs @@ -12,7 +12,17 @@ //! //! [`axum`]: https://docs.rs/axum/latest/axum/index.html //! [`axum::Router`]: https://docs.rs/axum/latest/axum/routing/struct.Router.html + +#![warn( + missing_copy_implementations, + missing_debug_implementations, + missing_docs, + unreachable_pub, + clippy::missing_const_for_fn, + rustdoc::all +)] #![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![deny(unused_must_use, rust_2018_idioms)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #[macro_use] @@ -32,7 +42,7 @@ pub use primitives::MethodId; mod routes; pub(crate) use routes::{BoxedIntoRoute, ErasedIntoRoute, Method}; -pub use routes::{Handler, HandlerService, Route}; +pub use routes::{Handler, HandlerArgs, HandlerService, MethodFuture, Route}; mod router; pub use router::Router; diff --git a/crates/router/src/router.rs b/crates/router/src/router.rs index 5bf40a3..adbe2c6 100644 --- a/crates/router/src/router.rs +++ b/crates/router/src/router.rs @@ -393,7 +393,7 @@ impl fmt::Debug for RouterInner { impl RouterInner { /// Create a new, empty router. - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { routes: BTreeMap::new(), @@ -410,7 +410,7 @@ impl RouterInner { /// /// Note that the type parameter `S2` is NOT the state you are adding to the /// router. It is additional state that must be added AFTER the state `S`. - pub fn with_state(self, state: &S) -> RouterInner + pub(crate) fn with_state(self, state: &S) -> RouterInner where S: Clone, { @@ -527,7 +527,7 @@ impl RouterInner { /// /// Panic if the method name already exists in the router. #[track_caller] - pub fn route_service(self, method: impl Into>, service: T) -> Self + pub(crate) fn route_service(self, method: impl Into>, service: T) -> Self where T: Service< (HandlerCtx, Box), diff --git a/crates/router/src/routes/erased.rs b/crates/router/src/routes/erased.rs index b039658..7d24a84 100644 --- a/crates/router/src/routes/erased.rs +++ b/crates/router/src/routes/erased.rs @@ -41,7 +41,7 @@ pub(crate) struct BoxedIntoRoute(pub(crate) Box>); #[allow(dead_code)] impl BoxedIntoRoute { /// Convert this into a [`Route`] with the given state. - pub fn into_route(self, state: S) -> Route { + pub(crate) fn into_route(self, state: S) -> Route { self.0.into_route(state) } } @@ -85,7 +85,7 @@ where impl MakeErasedHandler { /// Create a new [`MakeErasedHandler`] with the given handler and conversion /// function. - pub fn from_handler(handler: H) -> Self + pub(crate) fn from_handler(handler: H) -> Self where H: Handler, T: Send + 'static, diff --git a/crates/router/src/routes/future.rs b/crates/router/src/routes/future.rs index 839d9a4..06ac7b0 100644 --- a/crates/router/src/routes/future.rs +++ b/crates/router/src/routes/future.rs @@ -23,7 +23,7 @@ pub struct RouteFuture { impl RouteFuture { /// Create a new route future. - pub fn new( + pub const fn new( inner: Oneshot, HandlerArgs>, ) -> Self { Self { inner } @@ -44,6 +44,8 @@ impl Future for RouteFuture { } } +/// A future for a method, containing the request ID, and the inner future +/// which resolves to the response. #[pin_project] pub struct MethodFuture { /// The request ID. Guaranteed to be `Some` until the future is completed. @@ -55,7 +57,7 @@ pub struct MethodFuture { impl MethodFuture { /// Create a new method future. - pub fn new(id: Id, fut: RouteFuture) -> Self { + pub const fn new(id: Id, fut: RouteFuture) -> Self { Self { inner: fut, id: Some(id), diff --git a/crates/router/src/routes/method.rs b/crates/router/src/routes/method.rs index 219b555..621e43e 100644 --- a/crates/router/src/routes/method.rs +++ b/crates/router/src/routes/method.rs @@ -23,7 +23,12 @@ impl Clone for Method { impl Method { /// Call the method with the given state and request. - pub fn call_with_state(&self, ctx: HandlerCtx, req: Box, state: S) -> RouteFuture { + pub(crate) fn call_with_state( + &self, + ctx: HandlerCtx, + req: Box, + state: S, + ) -> RouteFuture { match self { Self::Ready(route) => route.clone().oneshot_inner_owned(ctx, req), Self::Needs(handler) => handler @@ -40,7 +45,7 @@ where S: Clone, { /// Add state to a method, converting - pub fn with_state(self, state: &S) -> Method { + pub(crate) fn with_state(self, state: &S) -> Method { match self { Self::Ready(route) => Method::Ready(route), Self::Needs(handler) => Method::Ready(handler.0.into_route(state.clone())), diff --git a/crates/router/src/routes/mod.rs b/crates/router/src/routes/mod.rs index 0e88f68..09b21b7 100644 --- a/crates/router/src/routes/mod.rs +++ b/crates/router/src/routes/mod.rs @@ -29,6 +29,7 @@ pub type HandlerArgs = (HandlerCtx, Box); /// a JSON-RPC [`ResponsePayload`]. Routes SHOULD be infallible. I.e. any error /// that occurs during the handling of a request should be represented as a /// JSON-RPC error response, rather than having the service return an `Err`. +#[derive(Debug)] pub struct Route(tower::util::BoxCloneSyncService); impl Route { From ae54ee0395db77d31c53010d7df1c9351961d8be Mon Sep 17 00:00:00 2001 From: James Date: Wed, 15 Jan 2025 11:02:35 -0500 Subject: [PATCH 2/2] feat: into_axum --- crates/router/src/router.rs | 6 ++++++ crates/router/src/routes/erased.rs | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/router/src/router.rs b/crates/router/src/router.rs index adbe2c6..3453b0d 100644 --- a/crates/router/src/router.rs +++ b/crates/router/src/router.rs @@ -318,6 +318,12 @@ where MethodFuture::new(id, fut) } + + /// Nest this router into a new Axum router, with the specified path. + #[cfg(feature = "axum")] + pub fn into_axum(self, path: &str) -> axum::Router { + axum::Router::new().route(path, axum::routing::post(self)) + } } impl Router<()> { diff --git a/crates/router/src/routes/erased.rs b/crates/router/src/routes/erased.rs index 7d24a84..d97ee8f 100644 --- a/crates/router/src/routes/erased.rs +++ b/crates/router/src/routes/erased.rs @@ -33,8 +33,6 @@ pub(crate) trait ErasedIntoRoute: Send + Sync { /// /// Similar to axum's [`BoxedIntoRoute`] /// -/// Currently this is a placeholder to enable future convenience functions. -/// /// [`BoxedIntoRoute`]: https://github.com/tokio-rs/axum/blob/18a99da0b0baf9eeef326b34525826ae0b5a1370/axum/src/boxed.rs#L12 pub(crate) struct BoxedIntoRoute(pub(crate) Box>);