Skip to content

Commit d012d39

Browse files
committed
Proxy eth_sendRawTransaction to builder
1 parent 981dda2 commit d012d39

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

src/proxy.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use std::{future::Future, pin::Pin};
99
use tower::{Layer, Service};
1010
use tracing::debug;
1111

12+
const PROXY_METHODS: [&str; 2] = ["engine_", "eth_sendRawTransaction"];
13+
1214
#[derive(Debug, Clone)]
1315
pub struct ProxyLayer {
1416
target_url: Uri,
@@ -84,7 +86,7 @@ where
8486
message = "received json rpc request for",
8587
method = method.method
8688
);
87-
if method.method.starts_with("engine_") {
89+
if PROXY_METHODS.iter().any(|&m| method.method.starts_with(m)) {
8890
// let rpc server handle engine rpc requests
8991
let res = inner.call(req).await.map_err(|e| e.into())?;
9092
Ok(res)

src/server.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use alloy::primitives::B256;
2+
use alloy_primitives::Bytes;
23
use alloy_rpc_types_engine::{
34
ExecutionPayload, ExecutionPayloadV3, ForkchoiceState, ForkchoiceUpdated, PayloadId,
45
PayloadStatus,
@@ -15,7 +16,7 @@ use op_alloy_rpc_types_engine::{
1516
};
1617
use reth_rpc_layer::AuthClientService;
1718
use std::sync::Arc;
18-
use tracing::{error, info};
19+
use tracing::{debug, error, info};
1920

2021
use crate::selector::{DefaultPayloadSelector, PayloadSelector};
2122

@@ -43,6 +44,12 @@ pub trait EngineApi {
4344
) -> RpcResult<PayloadStatus>;
4445
}
4546

47+
#[rpc(server, client, namespace = "eth")]
48+
pub trait EthApi {
49+
#[method(name = "sendRawTransaction")]
50+
async fn send_raw_transaction(&self, bytes: Bytes) -> RpcResult<B256>;
51+
}
52+
4653
pub struct EthEngineApi<S = AuthClientService<HttpBackend>> {
4754
l2_client: Arc<HttpClient<S>>,
4855
builder_clients: Vec<Arc<HttpClient<S>>>,
@@ -65,6 +72,36 @@ impl<S> EthEngineApi<S> {
6572
}
6673
}
6774

75+
#[async_trait]
76+
impl EthApiServer for EthEngineApi {
77+
async fn send_raw_transaction(&self, bytes: Bytes) -> RpcResult<B256> {
78+
debug!(
79+
message = "received send_raw_transaction",
80+
"bytes_len" = bytes.len()
81+
);
82+
let builder = self.builder_client.clone();
83+
let tx_bytes = bytes.clone();
84+
tokio::spawn(async move {
85+
builder.send_raw_transaction(tx_bytes).await.map_err(|e| {
86+
error!(message = "error calling send_raw_transaction for builder", "error" = %e);
87+
})
88+
});
89+
self.l2_client
90+
.send_raw_transaction(bytes)
91+
.await
92+
.map_err(|e| match e {
93+
ClientError::Call(err) => err, // Already an ErrorObjectOwned, so just return it
94+
other_error => {
95+
error!(
96+
message = "error calling send_raw_transaction for l2 client",
97+
"error" = %other_error,
98+
);
99+
ErrorCode::InternalError.into()
100+
}
101+
})
102+
}
103+
}
104+
68105
#[async_trait]
69106
impl EngineApiServer for EthEngineApi {
70107
async fn fork_choice_updated_v3(

0 commit comments

Comments
 (0)