Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/rpc/src/ctx.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{
eth::{EthError, TxCacheForwarder},
eth::EthError,
interest::{ActiveFilter, FilterManager, FilterOutput, SubscriptionManager},
util::BlockRangeInclusiveIter,
Pnt,
Pnt, TxCacheForwarder,
};
use alloy::{
consensus::{BlockHeader, Header, Signed, Transaction, TxEnvelope},
Expand Down
58 changes: 1 addition & 57 deletions crates/rpc/src/eth/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
ctx::RpcCtx,
eth::{CallErrorData, EthError},
interest::{FilterOutput, InterestKind},
util::{await_jh_option, await_jh_option_response, response_tri},
Pnt,
};
use ajj::{HandlerCtx, ResponsePayload};
Expand Down Expand Up @@ -31,63 +32,6 @@ use std::borrow::Cow;
use tracing::{trace_span, Instrument};
use trevm::revm::context::result::ExecutionResult;

macro_rules! await_jh_option {
($h:expr) => {
match $h.await {
Ok(Some(res)) => res,
_ => return Err("task panicked or cancelled".to_string()),
}
};
}

macro_rules! await_jh_option_response {
($h:expr) => {
match $h.await {
Ok(Some(res)) => res,
_ => {
return ResponsePayload::internal_error_message(Cow::Borrowed(
"task panicked or cancelled",
))
}
}
};
}

macro_rules! response_tri {
($h:expr) => {
match $h {
Ok(res) => res,
Err(err) => return ResponsePayload::internal_error_message(err.to_string().into()),
}
};

($h:expr, $msg:literal) => {
match $h {
Ok(res) => res,
Err(_) => return ResponsePayload::internal_error_message($msg.into()),
}
};

($h:expr, $obj:expr) => {
match $h {
Ok(res) => res,
Err(err) => returnResponsePayload::internal_error_with_message_and_obj(
err.to_string().into(),
$obj,
),
}
};

($h:expr, $msg:literal, $obj:expr) => {
match $h {
Ok(res) => res,
Err(err) => {
return ResponsePayload::internal_error_with_message_and_obj($msg.into(), $obj)
}
}
};
}

/// Args for `eth_estimateGas` and `eth_call`.
#[derive(Debug, Deserialize)]
pub(super) struct TxParams(
Expand Down
3 changes: 0 additions & 3 deletions crates/rpc/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use endpoints::*;
mod error;
pub use error::EthError;

mod forwarder;
pub use forwarder::TxCacheForwarder;

mod helpers;
pub use helpers::CallErrorData;

Expand Down
File renamed without changes.
10 changes: 8 additions & 2 deletions crates/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ mod ctx;
pub use ctx::RpcCtx;

mod eth;
pub use eth::{eth, CallErrorData, EthError, TxCacheForwarder};
pub use eth::{eth, CallErrorData, EthError};

mod signet;
pub use signet::{error::SignetError, signet};

mod interest;

mod forwarder;
use forwarder::TxCacheForwarder;

pub(crate) mod util;
pub use util::Pnt;

Expand All @@ -76,7 +82,7 @@ where
Host: FullNodeComponents,
Signet: Pnt,
{
ajj::Router::new().nest("eth", eth::<Host, Signet>())
ajj::Router::new().nest("eth", eth::<Host, Signet>()).nest("signet", signet::<Host, Signet>())
}

/// Serve the router on the given addresses using axum.
Expand Down
23 changes: 23 additions & 0 deletions crates/rpc/src/signet/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! Signet RPC errors.

use reth::rpc::server_types::eth::EthApiError;

/// Errors that can occur when interacting with the `signet` namespace.
#[derive(Debug, thiserror::Error)]
pub enum SignetError {
/// The transaction cache URL was not provided.
#[error("transaction cache URL not provided")]
TxCacheUrlNotProvided,
/// An error coming from interacting with components
/// that could emit `EthApiError`s, such as the forwarder.
#[error(transparent)]
EthApiError(#[from] EthApiError),
}

impl SignetError {
/// Turn into a string by value, allows for `.map_err(SignetError::to_string)`
/// to be used.
pub fn into_string(self) -> String {
ToString::to_string(&self)
}
}
73 changes: 73 additions & 0 deletions crates/rpc/src/signet/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//! Signet RPC methods and related code.
pub(crate) mod error;

use crate::util::await_jh_option;
use crate::{ctx::RpcCtx, Pnt};
use ajj::HandlerCtx;
use error::SignetError;
use reth_node_api::FullNodeComponents;
use signet_bundle::SignetEthBundle;
use signet_zenith::SignedOrder;

/// Instantiate a `signet` API router.
pub fn signet<Host, Signet>() -> ajj::Router<RpcCtx<Host, Signet>>
where
Host: FullNodeComponents,
Signet: Pnt,
{
ajj::Router::new().route("sendBundle", send_bundle).route("sendOrder", send_order)
}

pub(super) async fn send_bundle<Host, Signet>(
hctx: HandlerCtx,
bundle: SignetEthBundle,
ctx: RpcCtx<Host, Signet>,
) -> Result<(), String>
where
Host: FullNodeComponents,
Signet: Pnt,
{
let task = |hctx: HandlerCtx| async move {
let Some(forwarder) = ctx.signet().forwarder() else {
return Err(SignetError::TxCacheUrlNotProvided.into_string());
};

hctx.spawn(async move {
forwarder
.forward_bundle(bundle)
.await
.map_err(|e| SignetError::EthApiError(e).into_string())
});

Ok(())
};

await_jh_option!(hctx.spawn_blocking_with_ctx(task))
}

pub(super) async fn send_order<Host, Signet>(
hctx: HandlerCtx,
order: SignedOrder,
ctx: RpcCtx<Host, Signet>,
) -> Result<(), String>
where
Host: FullNodeComponents,
Signet: Pnt,
{
let task = |hctx: HandlerCtx| async move {
let Some(forwarder) = ctx.signet().forwarder() else {
return Err(SignetError::TxCacheUrlNotProvided.into_string());
};

hctx.spawn(async move {
forwarder
.forward_order(order)
.await
.map_err(|e| SignetError::EthApiError(e).into_string())
});

Ok(())
};

await_jh_option!(hctx.spawn_blocking_with_ctx(task))
}
60 changes: 60 additions & 0 deletions crates/rpc/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,66 @@ use reth::{primitives::EthPrimitives, providers::providers::ProviderNodeTypes};
use reth_chainspec::ChainSpec;
use std::{iter::StepBy, ops::RangeInclusive};

macro_rules! await_jh_option {
($h:expr) => {
match $h.await {
Ok(Some(res)) => res,
_ => return Err("task panicked or cancelled".to_string()),
}
};
}
pub(crate) use await_jh_option;

macro_rules! await_jh_option_response {
($h:expr) => {
match $h.await {
Ok(Some(res)) => res,
_ => {
return ResponsePayload::internal_error_message(Cow::Borrowed(
"task panicked or cancelled",
))
}
}
};
}
pub(crate) use await_jh_option_response;

macro_rules! response_tri {
($h:expr) => {
match $h {
Ok(res) => res,
Err(err) => return ResponsePayload::internal_error_message(err.to_string().into()),
}
};

($h:expr, $msg:literal) => {
match $h {
Ok(res) => res,
Err(_) => return ResponsePayload::internal_error_message($msg.into()),
}
};

($h:expr, $obj:expr) => {
match $h {
Ok(res) => res,
Err(err) => returnResponsePayload::internal_error_with_message_and_obj(
err.to_string().into(),
$obj,
),
}
};

($h:expr, $msg:literal, $obj:expr) => {
match $h {
Ok(res) => res,
Err(err) => {
return ResponsePayload::internal_error_with_message_and_obj($msg.into(), $obj)
}
}
};
}
pub(crate) use response_tri;

/// Convenience trait for specifying the [`ProviderNodeTypes`] implementation
/// required for Signet RPC functionality.
pub trait Pnt: ProviderNodeTypes<ChainSpec = ChainSpec, Primitives = EthPrimitives> {}
Expand Down
Loading