mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: tx forwarder
eth_sendRawTransaction will forward transactions into --upstream-rpc-url, if specified in cli args.
This commit is contained in:
@ -5,10 +5,10 @@ Heavily inspired by [reth-bsc](https://github.com/loocapro/reth-bsc).
|
|||||||
|
|
||||||
## TODOs
|
## TODOs
|
||||||
|
|
||||||
- [ ] Make it compilable
|
- [x] Make it compilable
|
||||||
- [x] EVM
|
- [x] EVM
|
||||||
- [x] Storage
|
- [x] Storage
|
||||||
- [ ] TX forwarder API
|
- [x] TX forwarder API
|
||||||
- [x] Decide whether to include system txs, receipts in block or not
|
- [x] Decide whether to include system txs, receipts in block or not
|
||||||
- [x] Downloader
|
- [x] Downloader
|
||||||
- [x] S3 format (file)
|
- [x] S3 format (file)
|
||||||
|
|||||||
@ -4,5 +4,6 @@ mod evm;
|
|||||||
mod hardforks;
|
mod hardforks;
|
||||||
pub mod node;
|
pub mod node;
|
||||||
pub mod pseudo_peer;
|
pub mod pseudo_peer;
|
||||||
|
pub mod tx_forwarder;
|
||||||
|
|
||||||
pub use node::primitives::{HlBlock, HlBlockBody, HlPrimitives};
|
pub use node::primitives::{HlBlock, HlBlockBody, HlPrimitives};
|
||||||
|
|||||||
25
src/main.rs
25
src/main.rs
@ -1,9 +1,15 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use reth::builder::NodeHandle;
|
use reth::builder::NodeHandle;
|
||||||
|
use reth_hl::tx_forwarder::{self, EthForwarderApiServer};
|
||||||
use reth_hl::{
|
use reth_hl::{
|
||||||
chainspec::parser::HlChainSpecParser,
|
chainspec::parser::HlChainSpecParser,
|
||||||
node::{cli::{Cli, HlNodeArgs}, storage::tables::Tables, HlNode},
|
node::{
|
||||||
|
cli::{Cli, HlNodeArgs},
|
||||||
|
storage::tables::Tables,
|
||||||
|
HlNode,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
// We use jemalloc for performance reasons
|
// We use jemalloc for performance reasons
|
||||||
#[cfg(all(feature = "jemalloc", unix))]
|
#[cfg(all(feature = "jemalloc", unix))]
|
||||||
@ -21,8 +27,21 @@ fn main() -> eyre::Result<()> {
|
|||||||
Cli::<HlChainSpecParser, HlNodeArgs>::parse().run(|builder, ext| async move {
|
Cli::<HlChainSpecParser, HlNodeArgs>::parse().run(|builder, ext| async move {
|
||||||
builder.builder.database.create_tables_for::<Tables>()?;
|
builder.builder.database.create_tables_for::<Tables>()?;
|
||||||
let (node, engine_handle_tx) = HlNode::new(ext.block_source_args.parse().await?);
|
let (node, engine_handle_tx) = HlNode::new(ext.block_source_args.parse().await?);
|
||||||
let NodeHandle { node, node_exit_future: exit_future } =
|
let NodeHandle { node, node_exit_future: exit_future } = builder
|
||||||
builder.node(node).launch().await?;
|
.node(node)
|
||||||
|
.extend_rpc_modules(|ctx| {
|
||||||
|
let upstream_rpc_url = ext.upstream_rpc_url;
|
||||||
|
if let Some(upstream_rpc_url) = upstream_rpc_url {
|
||||||
|
ctx.modules.replace_configured(
|
||||||
|
tx_forwarder::EthForwarderExt::new(upstream_rpc_url.clone()).into_rpc(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
info!("Transaction forwarding enabled");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.launch()
|
||||||
|
.await?;
|
||||||
|
|
||||||
engine_handle_tx.send(node.beacon_engine_handle.clone()).unwrap();
|
engine_handle_tx.send(node.beacon_engine_handle.clone()).unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,9 @@ use tracing::info;
|
|||||||
pub struct HlNodeArgs {
|
pub struct HlNodeArgs {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
pub block_source_args: BlockSourceArgs,
|
pub block_source_args: BlockSourceArgs,
|
||||||
|
|
||||||
|
#[arg(long, env = "UPSTREAM_RPC_URL")]
|
||||||
|
pub upstream_rpc_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The main reth_hl cli interface.
|
/// The main reth_hl cli interface.
|
||||||
|
|||||||
44
src/tx_forwarder.rs
Normal file
44
src/tx_forwarder.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use alloy_primitives::{Bytes, B256};
|
||||||
|
use jsonrpsee::{
|
||||||
|
http_client::{HttpClient, HttpClientBuilder},
|
||||||
|
proc_macros::rpc,
|
||||||
|
types::{error::INTERNAL_ERROR_CODE, ErrorObject},
|
||||||
|
};
|
||||||
|
use jsonrpsee_core::{async_trait, client::ClientT, ClientError, RpcResult};
|
||||||
|
|
||||||
|
#[rpc(server, namespace = "eth")]
|
||||||
|
pub trait EthForwarderApi {
|
||||||
|
#[method(name = "sendRawTransaction")]
|
||||||
|
async fn send_raw_transaction(&self, tx: Bytes) -> RpcResult<B256>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EthForwarderExt {
|
||||||
|
client: HttpClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EthForwarderExt {
|
||||||
|
pub fn new(upstream_rpc_url: String) -> Self {
|
||||||
|
let client =
|
||||||
|
HttpClientBuilder::default().build(upstream_rpc_url).expect("Failed to build client");
|
||||||
|
|
||||||
|
Self { client }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl EthForwarderApiServer for EthForwarderExt {
|
||||||
|
async fn send_raw_transaction(&self, tx: Bytes) -> RpcResult<B256> {
|
||||||
|
let txhash =
|
||||||
|
self.client.clone().request("eth_sendRawTransaction", vec![tx]).await.map_err(|e| {
|
||||||
|
match e {
|
||||||
|
ClientError::Call(e) => e,
|
||||||
|
_ => ErrorObject::owned(
|
||||||
|
INTERNAL_ERROR_CODE,
|
||||||
|
format!("Failed to send transaction: {e:?}"),
|
||||||
|
Some(()),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
Ok(txhash)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user