mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(rpc): add engine eth subset rpc handler (#2317)
This commit is contained in:
@ -1,8 +1,14 @@
|
||||
use jsonrpsee::{core::RpcResult as Result, proc_macros::rpc};
|
||||
use reth_primitives::{BlockHash, U64};
|
||||
use reth_rpc_types::engine::{
|
||||
ExecutionPayload, ExecutionPayloadBodies, ExecutionPayloadEnvelope, ForkchoiceState,
|
||||
ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration,
|
||||
use reth_primitives::{
|
||||
filter::Filter, Address, BlockHash, BlockId, BlockNumberOrTag, Bytes, H256, U256, U64,
|
||||
};
|
||||
use reth_rpc_types::{
|
||||
engine::{
|
||||
ExecutionPayload, ExecutionPayloadBodies, ExecutionPayloadEnvelope, ForkchoiceState,
|
||||
ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration,
|
||||
},
|
||||
state::StateOverride,
|
||||
CallRequest, Log, RichBlock, SyncStatus,
|
||||
};
|
||||
|
||||
#[cfg_attr(not(feature = "client"), rpc(server))]
|
||||
@ -81,3 +87,56 @@ pub trait EngineApi {
|
||||
#[method(name = "engine_exchangeCapabilities")]
|
||||
async fn exchange_capabilities(&self, capabilities: Vec<String>) -> Result<Vec<String>>;
|
||||
}
|
||||
|
||||
/// A subset of the ETH rpc interface: <https://ethereum.github.io/execution-apis/api-documentation/>
|
||||
///
|
||||
/// Specifically for the engine auth server: <https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md#underlying-protocol>
|
||||
#[cfg_attr(not(feature = "client"), rpc(server))]
|
||||
#[cfg_attr(feature = "client", rpc(server, client))]
|
||||
#[async_trait]
|
||||
pub trait EngineEthApi {
|
||||
/// Returns an object with data about the sync status or false.
|
||||
#[method(name = "eth_syncing")]
|
||||
fn syncing(&self) -> Result<SyncStatus>;
|
||||
|
||||
/// Returns the chain ID of the current network.
|
||||
#[method(name = "eth_chainId")]
|
||||
async fn chain_id(&self) -> Result<Option<U64>>;
|
||||
|
||||
/// Returns the number of most recent block.
|
||||
#[method(name = "eth_blockNumber")]
|
||||
fn block_number(&self) -> Result<U256>;
|
||||
|
||||
/// Executes a new message call immediately without creating a transaction on the block chain.
|
||||
#[method(name = "eth_call")]
|
||||
async fn call(
|
||||
&self,
|
||||
request: CallRequest,
|
||||
block_number: Option<BlockId>,
|
||||
state_overrides: Option<StateOverride>,
|
||||
) -> Result<Bytes>;
|
||||
|
||||
/// Returns code at a given address at given block number.
|
||||
#[method(name = "eth_getCode")]
|
||||
async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes>;
|
||||
|
||||
/// Returns information about a block by hash.
|
||||
#[method(name = "eth_getBlockByHash")]
|
||||
async fn block_by_hash(&self, hash: H256, full: bool) -> Result<Option<RichBlock>>;
|
||||
|
||||
/// Returns information about a block by number.
|
||||
#[method(name = "eth_getBlockByNumber")]
|
||||
async fn block_by_number(
|
||||
&self,
|
||||
number: BlockNumberOrTag,
|
||||
full: bool,
|
||||
) -> Result<Option<RichBlock>>;
|
||||
|
||||
/// Sends signed transaction, returning its hash.
|
||||
#[method(name = "eth_sendRawTransaction")]
|
||||
async fn send_raw_transaction(&self, bytes: Bytes) -> Result<H256>;
|
||||
|
||||
/// Returns logs matching given filter object.
|
||||
#[method(name = "eth_getLogs")]
|
||||
async fn logs(&self, filter: Filter) -> Result<Vec<Log>>;
|
||||
}
|
||||
|
||||
@ -25,9 +25,15 @@ pub use servers::*;
|
||||
/// Aggregates all server traits.
|
||||
pub mod servers {
|
||||
pub use crate::{
|
||||
admin::AdminApiServer, debug::DebugApiServer, engine::EngineApiServer, eth::EthApiServer,
|
||||
eth_filter::EthFilterApiServer, eth_pubsub::EthPubSubApiServer, net::NetApiServer,
|
||||
trace::TraceApiServer, web3::Web3ApiServer,
|
||||
admin::AdminApiServer,
|
||||
debug::DebugApiServer,
|
||||
engine::{EngineApiServer, EngineEthApiServer},
|
||||
eth::EthApiServer,
|
||||
eth_filter::EthFilterApiServer,
|
||||
eth_pubsub::EthPubSubApiServer,
|
||||
net::NetApiServer,
|
||||
trace::TraceApiServer,
|
||||
web3::Web3ApiServer,
|
||||
};
|
||||
}
|
||||
|
||||
@ -39,7 +45,12 @@ pub use clients::*;
|
||||
#[cfg(feature = "client")]
|
||||
pub mod clients {
|
||||
pub use crate::{
|
||||
admin::AdminApiClient, debug::DebugApiClient, engine::EngineApiClient, eth::EthApiClient,
|
||||
net::NetApiClient, trace::TraceApiClient, web3::Web3ApiClient,
|
||||
admin::AdminApiClient,
|
||||
debug::DebugApiClient,
|
||||
engine::{EngineApiClient, EngineEthApiClient},
|
||||
eth::EthApiClient,
|
||||
net::NetApiClient,
|
||||
trace::TraceApiClient,
|
||||
web3::Web3ApiClient,
|
||||
};
|
||||
}
|
||||
|
||||
@ -11,7 +11,8 @@ use jsonrpsee::{
|
||||
use reth_network_api::{NetworkInfo, Peers};
|
||||
use reth_provider::{BlockProvider, EvmEnvProvider, HeaderProvider, StateProviderFactory};
|
||||
use reth_rpc::{
|
||||
eth::cache::EthStateCache, AuthLayer, Claims, EthApi, EthFilter, JwtAuthValidator, JwtSecret,
|
||||
eth::cache::EthStateCache, AuthLayer, Claims, EngineEthApi, EthApi, EthFilter,
|
||||
JwtAuthValidator, JwtSecret,
|
||||
};
|
||||
use reth_rpc_api::{servers::*, EngineApiServer};
|
||||
use reth_tasks::TaskSpawner;
|
||||
@ -75,8 +76,8 @@ where
|
||||
// Configure the module and start the server.
|
||||
let mut module = RpcModule::new(());
|
||||
module.merge(engine_api.into_rpc()).expect("No conflicting methods");
|
||||
module.merge(eth_api.into_rpc()).expect("No conflicting methods");
|
||||
module.merge(eth_filter.into_rpc()).expect("No conflicting methods");
|
||||
let engine_eth = EngineEthApi::new(eth_api, eth_filter);
|
||||
module.merge(engine_eth.into_rpc()).expect("No conflicting methods");
|
||||
|
||||
// Create auth middleware.
|
||||
let middleware =
|
||||
|
||||
@ -108,7 +108,7 @@ use reth_ipc::server::IpcServer;
|
||||
use reth_network_api::{NetworkInfo, Peers};
|
||||
use reth_provider::{BlockProvider, CanonStateSubscriptions, EvmEnvProvider, StateProviderFactory};
|
||||
use reth_rpc::{
|
||||
eth::cache::EthStateCache, AdminApi, DebugApi, EthApi, EthFilter, EthPubSub,
|
||||
eth::cache::EthStateCache, AdminApi, DebugApi, EngineEthApi, EthApi, EthFilter, EthPubSub,
|
||||
EthSubscriptionIdProvider, NetApi, TraceApi, TracingCallGuard, Web3Api,
|
||||
};
|
||||
use reth_rpc_api::{servers::*, EngineApiServer};
|
||||
@ -643,10 +643,9 @@ where
|
||||
|
||||
module.merge(engine_api.into_rpc()).expect("No conflicting methods");
|
||||
|
||||
// also merge all `eth_` handlers
|
||||
module.merge(eth_handlers.api.into_rpc()).expect("No conflicting methods");
|
||||
module.merge(eth_handlers.filter.into_rpc()).expect("No conflicting methods");
|
||||
module.merge(eth_handlers.pubsub.into_rpc()).expect("No conflicting methods");
|
||||
// also merge a subset of `eth_` handlers
|
||||
let engine_eth = EngineEthApi::new(eth_handlers.api.clone(), eth_handlers.filter);
|
||||
module.merge(engine_eth.into_rpc()).expect("No conflicting methods");
|
||||
|
||||
AuthRpcModule { inner: module }
|
||||
}
|
||||
|
||||
@ -1,2 +1,92 @@
|
||||
use jsonrpsee::core::RpcResult as Result;
|
||||
use reth_primitives::{filter::Filter, Address, BlockId, BlockNumberOrTag, Bytes, H256, U256, U64};
|
||||
use reth_rpc_api::{EngineEthApiServer, EthApiServer, EthFilterApiServer};
|
||||
/// Re-export for convenience
|
||||
pub use reth_rpc_engine_api::EngineApi;
|
||||
use reth_rpc_types::{state::StateOverride, CallRequest, Log, RichBlock, SyncStatus};
|
||||
use tracing::trace;
|
||||
|
||||
/// A wrapper type for the `EthApi` and `EthFilter` implementations that only expose the required
|
||||
/// subset for the `eth_` namespace used in auth server alongside the `engine_` namespace.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EngineEthApi<Eth, EthFilter> {
|
||||
eth: Eth,
|
||||
eth_filter: EthFilter,
|
||||
}
|
||||
|
||||
impl<Eth, EthFilter> EngineEthApi<Eth, EthFilter> {
|
||||
/// Create a new `EngineEthApi` instance.
|
||||
pub fn new(eth: Eth, eth_filter: EthFilter) -> Self {
|
||||
Self { eth, eth_filter }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<Eth, EthFilter> EngineEthApiServer for EngineEthApi<Eth, EthFilter>
|
||||
where
|
||||
Eth: EthApiServer,
|
||||
EthFilter: EthFilterApiServer,
|
||||
{
|
||||
/// Handler for: `eth_syncing`
|
||||
fn syncing(&self) -> Result<SyncStatus> {
|
||||
trace!(target: "rpc::eth", "Serving eth_syncing [engine]");
|
||||
self.eth.syncing()
|
||||
}
|
||||
|
||||
/// Handler for: `eth_chainId`
|
||||
async fn chain_id(&self) -> Result<Option<U64>> {
|
||||
trace!(target: "rpc::eth", "Serving eth_chainId [engine]");
|
||||
self.eth.chain_id().await
|
||||
}
|
||||
|
||||
/// Handler for: `eth_blockNumber`
|
||||
fn block_number(&self) -> Result<U256> {
|
||||
trace!(target: "rpc::eth", "Serving eth_blockNumber [engine]");
|
||||
self.eth.block_number()
|
||||
}
|
||||
|
||||
/// Handler for: `eth_call`
|
||||
async fn call(
|
||||
&self,
|
||||
request: CallRequest,
|
||||
block_number: Option<BlockId>,
|
||||
state_overrides: Option<StateOverride>,
|
||||
) -> Result<Bytes> {
|
||||
trace!(target: "rpc::eth", "Serving eth_call [engine]");
|
||||
self.eth.call(request, block_number, state_overrides).await
|
||||
}
|
||||
|
||||
/// Handler for: `eth_getCode`
|
||||
async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
|
||||
trace!(target: "rpc::eth", "Serving eth_getCode [engine]");
|
||||
self.eth.get_code(address, block_number).await
|
||||
}
|
||||
|
||||
/// Handler for: `eth_getBlockByHash`
|
||||
async fn block_by_hash(&self, hash: H256, full: bool) -> Result<Option<RichBlock>> {
|
||||
trace!(target: "rpc::eth", "Serving eth_getBlockByHash [engine]");
|
||||
self.eth.block_by_hash(hash, full).await
|
||||
}
|
||||
|
||||
/// Handler for: `eth_getBlockByNumber`
|
||||
async fn block_by_number(
|
||||
&self,
|
||||
number: BlockNumberOrTag,
|
||||
full: bool,
|
||||
) -> Result<Option<RichBlock>> {
|
||||
trace!(target: "rpc::eth", "Serving eth_getBlockByNumber [engine]");
|
||||
self.eth.block_by_number(number, full).await
|
||||
}
|
||||
|
||||
/// Handler for: `eth_sendRawTransaction`
|
||||
async fn send_raw_transaction(&self, bytes: Bytes) -> Result<H256> {
|
||||
trace!(target: "rpc::eth", "Serving eth_sendRawTransaction [engine]");
|
||||
self.eth.send_raw_transaction(bytes).await
|
||||
}
|
||||
|
||||
/// Handler for `eth_getLogs`
|
||||
async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
|
||||
trace!(target: "rpc::eth", "Serving eth_getLogs [engine]");
|
||||
self.eth_filter.logs(filter).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ mod web3;
|
||||
pub use admin::AdminApi;
|
||||
pub use call_guard::TracingCallGuard;
|
||||
pub use debug::DebugApi;
|
||||
pub use engine::EngineApi;
|
||||
pub use engine::{EngineApi, EngineEthApi};
|
||||
pub use eth::{EthApi, EthApiSpec, EthFilter, EthPubSub, EthSubscriptionIdProvider};
|
||||
pub use layers::{AuthLayer, AuthValidator, Claims, JwtAuthValidator, JwtError, JwtSecret};
|
||||
pub use net::NetApi;
|
||||
|
||||
Reference in New Issue
Block a user