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