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_rpc_api::{EngineEthApiServer, EthApiServer};
9use reth_rpc_convert::RpcTxReq;
10pub use reth_rpc_engine_api::EngineApi;
12use reth_rpc_eth_api::{
13 EngineEthFilter, FullEthApiTypes, QueryLimits, RpcBlock, RpcHeader, RpcReceipt, RpcTransaction,
14};
15use tracing_futures::Instrument;
16
17macro_rules! engine_span {
18 () => {
19 tracing::trace_span!(target: "rpc", "engine")
20 };
21}
22
23#[derive(Debug, Clone)]
26pub struct EngineEthApi<Eth, EthFilter> {
27 eth: Eth,
28 eth_filter: EthFilter,
29}
30
31impl<Eth, EthFilter> EngineEthApi<Eth, EthFilter> {
32 pub const fn new(eth: Eth, eth_filter: EthFilter) -> Self {
34 Self { eth, eth_filter }
35 }
36}
37
38#[async_trait::async_trait]
39impl<Eth, EthFilter>
40 EngineEthApiServer<
41 RpcTxReq<Eth::NetworkTypes>,
42 RpcBlock<Eth::NetworkTypes>,
43 RpcReceipt<Eth::NetworkTypes>,
44 > for EngineEthApi<Eth, EthFilter>
45where
46 Eth: EthApiServer<
47 RpcTxReq<Eth::NetworkTypes>,
48 RpcTransaction<Eth::NetworkTypes>,
49 RpcBlock<Eth::NetworkTypes>,
50 RpcReceipt<Eth::NetworkTypes>,
51 RpcHeader<Eth::NetworkTypes>,
52 > + FullEthApiTypes,
53 EthFilter: EngineEthFilter,
54{
55 fn syncing(&self) -> Result<SyncStatus> {
57 let span = engine_span!();
58 let _enter = span.enter();
59 self.eth.syncing()
60 }
61
62 async fn chain_id(&self) -> Result<Option<U64>> {
64 let span = engine_span!();
65 let _enter = span.enter();
66 self.eth.chain_id().await
67 }
68
69 fn block_number(&self) -> Result<U256> {
71 let span = engine_span!();
72 let _enter = span.enter();
73 self.eth.block_number()
74 }
75
76 async fn call(
78 &self,
79 request: RpcTxReq<Eth::NetworkTypes>,
80 block_id: Option<BlockId>,
81 state_overrides: Option<StateOverride>,
82 block_overrides: Option<Box<BlockOverrides>>,
83 ) -> Result<Bytes> {
84 self.eth
85 .call(request, block_id, state_overrides, block_overrides)
86 .instrument(engine_span!())
87 .await
88 }
89
90 async fn get_code(&self, address: Address, block_id: Option<BlockId>) -> Result<Bytes> {
92 self.eth.get_code(address, block_id).instrument(engine_span!()).await
93 }
94
95 async fn block_by_hash(
97 &self,
98 hash: B256,
99 full: bool,
100 ) -> Result<Option<RpcBlock<Eth::NetworkTypes>>> {
101 self.eth.block_by_hash(hash, full).instrument(engine_span!()).await
102 }
103
104 async fn block_by_number(
106 &self,
107 number: BlockNumberOrTag,
108 full: bool,
109 ) -> Result<Option<RpcBlock<Eth::NetworkTypes>>> {
110 self.eth.block_by_number(number, full).instrument(engine_span!()).await
111 }
112
113 async fn block_receipts(
114 &self,
115 block_id: BlockId,
116 ) -> Result<Option<Vec<RpcReceipt<Eth::NetworkTypes>>>> {
117 self.eth.block_receipts(block_id).instrument(engine_span!()).await
118 }
119
120 async fn send_raw_transaction(&self, bytes: Bytes) -> Result<B256> {
122 self.eth.send_raw_transaction(bytes).instrument(engine_span!()).await
123 }
124
125 async fn transaction_receipt(
126 &self,
127 hash: B256,
128 ) -> Result<Option<RpcReceipt<Eth::NetworkTypes>>> {
129 self.eth.transaction_receipt(hash).instrument(engine_span!()).await
130 }
131
132 async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
134 self.eth_filter.logs(filter, QueryLimits::no_limits()).instrument(engine_span!()).await
135 }
136
137 async fn get_proof(
139 &self,
140 address: Address,
141 keys: Vec<JsonStorageKey>,
142 block_number: Option<BlockId>,
143 ) -> Result<EIP1186AccountProofResponse> {
144 self.eth.get_proof(address, keys, block_number).instrument(engine_span!()).await
145 }
146}