Skip to content

Commit c57fd1b

Browse files
authored
feat(rpc): signet_* specific methods (#22)
* signet methods * chore: move stuff around for the new endpoints * chore: add new methods * feat(rpc): nest signet on the main router * feat: SIgnetError, use it * chore: move macros
1 parent cb457b6 commit c57fd1b

File tree

8 files changed

+167
-64
lines changed

8 files changed

+167
-64
lines changed

crates/rpc/src/ctx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::{
2-
eth::{EthError, TxCacheForwarder},
2+
eth::EthError,
33
interest::{ActiveFilter, FilterManager, FilterOutput, SubscriptionManager},
44
util::BlockRangeInclusiveIter,
5-
Pnt,
5+
Pnt, TxCacheForwarder,
66
};
77
use alloy::{
88
consensus::{BlockHeader, Header, Signed, Transaction, TxEnvelope},

crates/rpc/src/eth/endpoints.rs

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::{
22
ctx::RpcCtx,
33
eth::{CallErrorData, EthError},
44
interest::{FilterOutput, InterestKind},
5+
util::{await_jh_option, await_jh_option_response, response_tri},
56
Pnt,
67
};
78
use ajj::{HandlerCtx, ResponsePayload};
@@ -31,63 +32,6 @@ use std::borrow::Cow;
3132
use tracing::{trace_span, Instrument};
3233
use trevm::revm::context::result::ExecutionResult;
3334

34-
macro_rules! await_jh_option {
35-
($h:expr) => {
36-
match $h.await {
37-
Ok(Some(res)) => res,
38-
_ => return Err("task panicked or cancelled".to_string()),
39-
}
40-
};
41-
}
42-
43-
macro_rules! await_jh_option_response {
44-
($h:expr) => {
45-
match $h.await {
46-
Ok(Some(res)) => res,
47-
_ => {
48-
return ResponsePayload::internal_error_message(Cow::Borrowed(
49-
"task panicked or cancelled",
50-
))
51-
}
52-
}
53-
};
54-
}
55-
56-
macro_rules! response_tri {
57-
($h:expr) => {
58-
match $h {
59-
Ok(res) => res,
60-
Err(err) => return ResponsePayload::internal_error_message(err.to_string().into()),
61-
}
62-
};
63-
64-
($h:expr, $msg:literal) => {
65-
match $h {
66-
Ok(res) => res,
67-
Err(_) => return ResponsePayload::internal_error_message($msg.into()),
68-
}
69-
};
70-
71-
($h:expr, $obj:expr) => {
72-
match $h {
73-
Ok(res) => res,
74-
Err(err) => returnResponsePayload::internal_error_with_message_and_obj(
75-
err.to_string().into(),
76-
$obj,
77-
),
78-
}
79-
};
80-
81-
($h:expr, $msg:literal, $obj:expr) => {
82-
match $h {
83-
Ok(res) => res,
84-
Err(err) => {
85-
return ResponsePayload::internal_error_with_message_and_obj($msg.into(), $obj)
86-
}
87-
}
88-
};
89-
}
90-
9135
/// Args for `eth_estimateGas` and `eth_call`.
9236
#[derive(Debug, Deserialize)]
9337
pub(super) struct TxParams(

crates/rpc/src/eth/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ use endpoints::*;
44
mod error;
55
pub use error::EthError;
66

7-
mod forwarder;
8-
pub use forwarder::TxCacheForwarder;
9-
107
mod helpers;
118
pub use helpers::CallErrorData;
129

crates/rpc/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,16 @@ mod ctx;
4747
pub use ctx::RpcCtx;
4848

4949
mod eth;
50-
pub use eth::{eth, CallErrorData, EthError, TxCacheForwarder};
50+
pub use eth::{eth, CallErrorData, EthError};
51+
52+
mod signet;
53+
pub use signet::{error::SignetError, signet};
5154

5255
mod interest;
5356

57+
mod forwarder;
58+
use forwarder::TxCacheForwarder;
59+
5460
pub(crate) mod util;
5561
pub use util::Pnt;
5662

@@ -76,7 +82,7 @@ where
7682
Host: FullNodeComponents,
7783
Signet: Pnt,
7884
{
79-
ajj::Router::new().nest("eth", eth::<Host, Signet>())
85+
ajj::Router::new().nest("eth", eth::<Host, Signet>()).nest("signet", signet::<Host, Signet>())
8086
}
8187

8288
/// Serve the router on the given addresses using axum.

crates/rpc/src/signet/error.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//! Signet RPC errors.
2+
3+
use reth::rpc::server_types::eth::EthApiError;
4+
5+
/// Errors that can occur when interacting with the `signet` namespace.
6+
#[derive(Debug, thiserror::Error)]
7+
pub enum SignetError {
8+
/// The transaction cache URL was not provided.
9+
#[error("transaction cache URL not provided")]
10+
TxCacheUrlNotProvided,
11+
/// An error coming from interacting with components
12+
/// that could emit `EthApiError`s, such as the forwarder.
13+
#[error(transparent)]
14+
EthApiError(#[from] EthApiError),
15+
}
16+
17+
impl SignetError {
18+
/// Turn into a string by value, allows for `.map_err(SignetError::to_string)`
19+
/// to be used.
20+
pub fn into_string(self) -> String {
21+
ToString::to_string(&self)
22+
}
23+
}

crates/rpc/src/signet/mod.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//! Signet RPC methods and related code.
2+
pub(crate) mod error;
3+
4+
use crate::util::await_jh_option;
5+
use crate::{ctx::RpcCtx, Pnt};
6+
use ajj::HandlerCtx;
7+
use error::SignetError;
8+
use reth_node_api::FullNodeComponents;
9+
use signet_bundle::SignetEthBundle;
10+
use signet_zenith::SignedOrder;
11+
12+
/// Instantiate a `signet` API router.
13+
pub fn signet<Host, Signet>() -> ajj::Router<RpcCtx<Host, Signet>>
14+
where
15+
Host: FullNodeComponents,
16+
Signet: Pnt,
17+
{
18+
ajj::Router::new().route("sendBundle", send_bundle).route("sendOrder", send_order)
19+
}
20+
21+
pub(super) async fn send_bundle<Host, Signet>(
22+
hctx: HandlerCtx,
23+
bundle: SignetEthBundle,
24+
ctx: RpcCtx<Host, Signet>,
25+
) -> Result<(), String>
26+
where
27+
Host: FullNodeComponents,
28+
Signet: Pnt,
29+
{
30+
let task = |hctx: HandlerCtx| async move {
31+
let Some(forwarder) = ctx.signet().forwarder() else {
32+
return Err(SignetError::TxCacheUrlNotProvided.into_string());
33+
};
34+
35+
hctx.spawn(async move {
36+
forwarder
37+
.forward_bundle(bundle)
38+
.await
39+
.map_err(|e| SignetError::EthApiError(e).into_string())
40+
});
41+
42+
Ok(())
43+
};
44+
45+
await_jh_option!(hctx.spawn_blocking_with_ctx(task))
46+
}
47+
48+
pub(super) async fn send_order<Host, Signet>(
49+
hctx: HandlerCtx,
50+
order: SignedOrder,
51+
ctx: RpcCtx<Host, Signet>,
52+
) -> Result<(), String>
53+
where
54+
Host: FullNodeComponents,
55+
Signet: Pnt,
56+
{
57+
let task = |hctx: HandlerCtx| async move {
58+
let Some(forwarder) = ctx.signet().forwarder() else {
59+
return Err(SignetError::TxCacheUrlNotProvided.into_string());
60+
};
61+
62+
hctx.spawn(async move {
63+
forwarder
64+
.forward_order(order)
65+
.await
66+
.map_err(|e| SignetError::EthApiError(e).into_string())
67+
});
68+
69+
Ok(())
70+
};
71+
72+
await_jh_option!(hctx.spawn_blocking_with_ctx(task))
73+
}

crates/rpc/src/util.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,66 @@ use reth::{primitives::EthPrimitives, providers::providers::ProviderNodeTypes};
22
use reth_chainspec::ChainSpec;
33
use std::{iter::StepBy, ops::RangeInclusive};
44

5+
macro_rules! await_jh_option {
6+
($h:expr) => {
7+
match $h.await {
8+
Ok(Some(res)) => res,
9+
_ => return Err("task panicked or cancelled".to_string()),
10+
}
11+
};
12+
}
13+
pub(crate) use await_jh_option;
14+
15+
macro_rules! await_jh_option_response {
16+
($h:expr) => {
17+
match $h.await {
18+
Ok(Some(res)) => res,
19+
_ => {
20+
return ResponsePayload::internal_error_message(Cow::Borrowed(
21+
"task panicked or cancelled",
22+
))
23+
}
24+
}
25+
};
26+
}
27+
pub(crate) use await_jh_option_response;
28+
29+
macro_rules! response_tri {
30+
($h:expr) => {
31+
match $h {
32+
Ok(res) => res,
33+
Err(err) => return ResponsePayload::internal_error_message(err.to_string().into()),
34+
}
35+
};
36+
37+
($h:expr, $msg:literal) => {
38+
match $h {
39+
Ok(res) => res,
40+
Err(_) => return ResponsePayload::internal_error_message($msg.into()),
41+
}
42+
};
43+
44+
($h:expr, $obj:expr) => {
45+
match $h {
46+
Ok(res) => res,
47+
Err(err) => returnResponsePayload::internal_error_with_message_and_obj(
48+
err.to_string().into(),
49+
$obj,
50+
),
51+
}
52+
};
53+
54+
($h:expr, $msg:literal, $obj:expr) => {
55+
match $h {
56+
Ok(res) => res,
57+
Err(err) => {
58+
return ResponsePayload::internal_error_with_message_and_obj($msg.into(), $obj)
59+
}
60+
}
61+
};
62+
}
63+
pub(crate) use response_tri;
64+
565
/// Convenience trait for specifying the [`ProviderNodeTypes`] implementation
666
/// required for Signet RPC functionality.
767
pub trait Pnt: ProviderNodeTypes<ChainSpec = ChainSpec, Primitives = EthPrimitives> {}

0 commit comments

Comments
 (0)