reth_rpc/
engine.rs

1use alloy_eips::{BlockId, BlockNumberOrTag};
2use alloy_primitives::{Address, Bytes, B256, U256, U64};
3use alloy_rpc_types_eth::{
4    state::StateOverride, BlockOverrides, EIP1186AccountProofResponse, Filter, Log, SyncStatus,
5};
6use alloy_serde::JsonStorageKey;
7use jsonrpsee::core::RpcResult as Result;
8use reth_primitives_traits::TxTy;
9use reth_rpc_api::{EngineEthApiServer, EthApiServer};
10use reth_rpc_convert::RpcTxReq;
11/// Re-export for convenience
12pub use reth_rpc_engine_api::EngineApi;
13use reth_rpc_eth_api::{
14    EngineEthFilter, FullEthApiTypes, QueryLimits, RpcBlock, RpcHeader, RpcReceipt, RpcTransaction,
15};
16use tracing_futures::Instrument;
17
18macro_rules! engine_span {
19    () => {
20        tracing::info_span!(target: "rpc", "engine")
21    };
22}
23
24/// A wrapper type for the `EthApi` and `EthFilter` implementations that only expose the required
25/// subset for the `eth_` namespace used in auth server alongside the `engine_` namespace.
26#[derive(Debug, Clone)]
27pub struct EngineEthApi<Eth, EthFilter> {
28    eth: Eth,
29    eth_filter: EthFilter,
30}
31
32impl<Eth, EthFilter> EngineEthApi<Eth, EthFilter> {
33    /// Create a new `EngineEthApi` instance.
34    pub const fn new(eth: Eth, eth_filter: EthFilter) -> Self {
35        Self { eth, eth_filter }
36    }
37}
38
39#[async_trait::async_trait]
40impl<Eth, EthFilter>
41    EngineEthApiServer<
42        RpcTxReq<Eth::NetworkTypes>,
43        RpcBlock<Eth::NetworkTypes>,
44        RpcReceipt<Eth::NetworkTypes>,
45    > for EngineEthApi<Eth, EthFilter>
46where
47    Eth: EthApiServer<
48            RpcTxReq<Eth::NetworkTypes>,
49            RpcTransaction<Eth::NetworkTypes>,
50            RpcBlock<Eth::NetworkTypes>,
51            RpcReceipt<Eth::NetworkTypes>,
52            RpcHeader<Eth::NetworkTypes>,
53            TxTy<Eth::Primitives>,
54        > + FullEthApiTypes,
55    EthFilter: EngineEthFilter,
56{
57    /// Handler for: `eth_syncing`
58    fn syncing(&self) -> Result<SyncStatus> {
59        let span = engine_span!();
60        let _enter = span.enter();
61        self.eth.syncing()
62    }
63
64    /// Handler for: `eth_chainId`
65    async fn chain_id(&self) -> Result<Option<U64>> {
66        let span = engine_span!();
67        let _enter = span.enter();
68        self.eth.chain_id().await
69    }
70
71    /// Handler for: `eth_blockNumber`
72    fn block_number(&self) -> Result<U256> {
73        let span = engine_span!();
74        let _enter = span.enter();
75        self.eth.block_number()
76    }
77
78    /// Handler for: `eth_call`
79    async fn call(
80        &self,
81        request: RpcTxReq<Eth::NetworkTypes>,
82        block_id: Option<BlockId>,
83        state_overrides: Option<StateOverride>,
84        block_overrides: Option<Box<BlockOverrides>>,
85    ) -> Result<Bytes> {
86        self.eth
87            .call(request, block_id, state_overrides, block_overrides)
88            .instrument(engine_span!())
89            .await
90    }
91
92    /// Handler for: `eth_getCode`
93    async fn get_code(&self, address: Address, block_id: Option<BlockId>) -> Result<Bytes> {
94        self.eth.get_code(address, block_id).instrument(engine_span!()).await
95    }
96
97    /// Handler for: `eth_getBlockByHash`
98    async fn block_by_hash(
99        &self,
100        hash: B256,
101        full: bool,
102    ) -> Result<Option<RpcBlock<Eth::NetworkTypes>>> {
103        self.eth.block_by_hash(hash, full).instrument(engine_span!()).await
104    }
105
106    /// Handler for: `eth_getBlockByNumber`
107    async fn block_by_number(
108        &self,
109        number: BlockNumberOrTag,
110        full: bool,
111    ) -> Result<Option<RpcBlock<Eth::NetworkTypes>>> {
112        self.eth.block_by_number(number, full).instrument(engine_span!()).await
113    }
114
115    async fn block_receipts(
116        &self,
117        block_id: BlockId,
118    ) -> Result<Option<Vec<RpcReceipt<Eth::NetworkTypes>>>> {
119        self.eth.block_receipts(block_id).instrument(engine_span!()).await
120    }
121
122    /// Handler for: `eth_sendRawTransaction`
123    async fn send_raw_transaction(&self, bytes: Bytes) -> Result<B256> {
124        self.eth.send_raw_transaction(bytes).instrument(engine_span!()).await
125    }
126
127    async fn transaction_receipt(
128        &self,
129        hash: B256,
130    ) -> Result<Option<RpcReceipt<Eth::NetworkTypes>>> {
131        self.eth.transaction_receipt(hash).instrument(engine_span!()).await
132    }
133
134    /// Handler for `eth_getLogs`
135    async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
136        self.eth_filter.logs(filter, QueryLimits::no_limits()).instrument(engine_span!()).await
137    }
138
139    /// Handler for `eth_getProof`
140    async fn get_proof(
141        &self,
142        address: Address,
143        keys: Vec<JsonStorageKey>,
144        block_number: Option<BlockId>,
145    ) -> Result<EIP1186AccountProofResponse> {
146        self.eth.get_proof(address, keys, block_number).instrument(engine_span!()).await
147    }
148}