Skip to main content

reth_rpc/
engine.rs

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