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;
11pub 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#[derive(Debug, Clone)]
28pub struct EngineEthApi<Eth, EthFilter> {
29 eth: Eth,
30 eth_filter: EthFilter,
31}
32
33impl<Eth, EthFilter> EngineEthApi<Eth, EthFilter> {
34 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 fn syncing(&self) -> Result<SyncStatus> {
60 let span = engine_span!();
61 let _enter = span.enter();
62 self.eth.syncing()
63 }
64
65 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 fn block_number(&self) -> Result<U256> {
74 let span = engine_span!();
75 let _enter = span.enter();
76 self.eth.block_number()
77 }
78
79 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 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 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 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 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 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 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 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 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 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 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 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 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 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}