Skip to main content

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, Index, 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, RpcLog, RpcReceipt,
15    RpcTransaction,
16};
17use serde_json::Value;
18use tracing_futures::Instrument;
19
20macro_rules! engine_span {
21    () => {
22        tracing::info_span!(target: "rpc", "engine")
23    };
24}
25
26/// A wrapper type for the `EthApi` and `EthFilter` implementations that only expose the required
27/// subset for the `eth_` namespace used in auth server alongside the `engine_` namespace.
28#[derive(Debug, Clone)]
29pub struct EngineEthApi<Eth, EthFilter> {
30    eth: Eth,
31    eth_filter: EthFilter,
32}
33
34impl<Eth, EthFilter> EngineEthApi<Eth, EthFilter> {
35    /// Create a new `EngineEthApi` instance.
36    pub const fn new(eth: Eth, eth_filter: EthFilter) -> Self {
37        Self { eth, eth_filter }
38    }
39}
40
41#[async_trait::async_trait]
42impl<Eth, EthFilter>
43    EngineEthApiServer<
44        RpcTxReq<Eth::NetworkTypes>,
45        RpcBlock<Eth::NetworkTypes>,
46        RpcReceipt<Eth::NetworkTypes>,
47        RpcLog<Eth::NetworkTypes>,
48    > for EngineEthApi<Eth, EthFilter>
49where
50    Eth: EthApiServer<
51            RpcTxReq<Eth::NetworkTypes>,
52            RpcTransaction<Eth::NetworkTypes>,
53            RpcBlock<Eth::NetworkTypes>,
54            RpcReceipt<Eth::NetworkTypes>,
55            RpcHeader<Eth::NetworkTypes>,
56            TxTy<Eth::Primitives>,
57        > + FullEthApiTypes,
58    EthFilter: EngineEthFilter<RpcLog<Eth::NetworkTypes>>,
59{
60    /// Handler for: `eth_syncing`
61    fn syncing(&self) -> Result<SyncStatus> {
62        let span = engine_span!();
63        let _enter = span.enter();
64        self.eth.syncing()
65    }
66
67    /// Handler for: `eth_chainId`
68    async fn chain_id(&self) -> Result<Option<U64>> {
69        let span = engine_span!();
70        let _enter = span.enter();
71        self.eth.chain_id().await
72    }
73
74    /// Handler for: `eth_blockNumber`
75    fn block_number(&self) -> Result<U256> {
76        let span = engine_span!();
77        let _enter = span.enter();
78        self.eth.block_number()
79    }
80
81    /// Handler for: `eth_call`
82    async fn call(
83        &self,
84        request: RpcTxReq<Eth::NetworkTypes>,
85        block_id: Option<BlockId>,
86        state_overrides: Option<StateOverride>,
87        block_overrides: Option<Box<BlockOverrides>>,
88    ) -> Result<Bytes> {
89        self.eth
90            .call(request, block_id, state_overrides, block_overrides)
91            .instrument(engine_span!())
92            .await
93    }
94
95    /// Handler for: `eth_getCode`
96    async fn get_code(&self, address: Address, block_id: Option<BlockId>) -> Result<Bytes> {
97        self.eth.get_code(address, block_id).instrument(engine_span!()).await
98    }
99
100    /// Handler for: `eth_getBlockByHash`
101    async fn block_by_hash(
102        &self,
103        hash: B256,
104        full: bool,
105    ) -> Result<Option<RpcBlock<Eth::NetworkTypes>>> {
106        self.eth.block_by_hash(hash, full).instrument(engine_span!()).await
107    }
108
109    /// Handler for: `eth_getBlockByNumber`
110    async fn block_by_number(
111        &self,
112        number: BlockNumberOrTag,
113        full: bool,
114    ) -> Result<Option<RpcBlock<Eth::NetworkTypes>>> {
115        self.eth.block_by_number(number, full).instrument(engine_span!()).await
116    }
117
118    async fn block_receipts(
119        &self,
120        block_id: BlockId,
121    ) -> Result<Option<Vec<RpcReceipt<Eth::NetworkTypes>>>> {
122        self.eth.block_receipts(block_id).instrument(engine_span!()).await
123    }
124
125    /// Handler for: `eth_getRawTransactionByBlockHashAndIndex`
126    async fn raw_transaction_by_block_hash_and_index(
127        &self,
128        hash: B256,
129        index: Index,
130    ) -> Result<Option<Bytes>> {
131        self.eth
132            .raw_transaction_by_block_hash_and_index(hash, index)
133            .instrument(engine_span!())
134            .await
135    }
136
137    /// Handler for: `eth_getRawTransactionByBlockNumberAndIndex`
138    async fn raw_transaction_by_block_number_and_index(
139        &self,
140        number: BlockNumberOrTag,
141        index: Index,
142    ) -> Result<Option<Bytes>> {
143        self.eth
144            .raw_transaction_by_block_number_and_index(number, index)
145            .instrument(engine_span!())
146            .await
147    }
148
149    /// Handler for: `eth_sendRawTransaction`
150    async fn send_raw_transaction(&self, bytes: Bytes) -> Result<B256> {
151        self.eth.send_raw_transaction(bytes).instrument(engine_span!()).await
152    }
153
154    async fn transaction_receipt(
155        &self,
156        hash: B256,
157    ) -> Result<Option<RpcReceipt<Eth::NetworkTypes>>> {
158        self.eth.transaction_receipt(hash).instrument(engine_span!()).await
159    }
160
161    /// Handler for `eth_getLogs`
162    async fn logs(&self, filter: Filter) -> Result<Vec<RpcLog<Eth::NetworkTypes>>> {
163        self.eth_filter.logs(filter, QueryLimits::no_limits()).instrument(engine_span!()).await
164    }
165
166    /// Handler for `eth_getProof`
167    async fn get_proof(
168        &self,
169        address: Address,
170        keys: Vec<JsonStorageKey>,
171        block_number: Option<BlockId>,
172    ) -> Result<EIP1186AccountProofResponse> {
173        self.eth.get_proof(address, keys, block_number).instrument(engine_span!()).await
174    }
175
176    /// Handler for `eth_getMultiProof`
177    async fn get_multi_proof(
178        &self,
179        targets: Vec<(Address, Vec<B256>)>,
180        block_number: Option<BlockId>,
181    ) -> Result<Vec<EIP1186AccountProofResponse>> {
182        self.eth.get_multi_proof(targets, block_number).instrument(engine_span!()).await
183    }
184
185    /// Handler for `eth_getBlockAccessListByBlockHash`
186    async fn block_access_list_by_block_hash(&self, hash: B256) -> Result<Option<Value>> {
187        self.eth.block_access_list_by_block_hash(hash).instrument(engine_span!()).await
188    }
189
190    /// Handler for `eth_getBlockAccessListByBlockNumber`
191    async fn block_access_list_by_block_number(
192        &self,
193        block_number: BlockNumberOrTag,
194    ) -> Result<Option<Value>> {
195        self.eth.block_access_list_by_block_number(block_number).instrument(engine_span!()).await
196    }
197
198    /// Handler for `eth_getBlockAccessList`
199    async fn block_access_list(&self, block_id: BlockId) -> Result<Option<Value>> {
200        self.eth.block_access_list(block_id).instrument(engine_span!()).await
201    }
202
203    /// Handler for `getBlockAccessListRaw`
204    async fn block_access_list_raw(&self, block: BlockId) -> Result<Option<Bytes>> {
205        self.eth.block_access_list_raw(block).instrument(engine_span!()).await
206    }
207}