Skip to main content

reth_rpc_eth_api/
core.rs

1//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`] trait. Handles RPC requests for
2//! the `eth_` namespace.
3use crate::{
4    helpers::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions, FullEthApi},
5    RpcBlock, RpcHeader, RpcReceipt, RpcTransaction,
6};
7use alloy_dyn_abi::TypedData;
8use alloy_eips::{eip2930::AccessListResult, BlockId, BlockNumberOrTag};
9use alloy_json_rpc::RpcObject;
10use alloy_primitives::{Address, Bytes, B256, B64, U256, U64};
11use alloy_rpc_types_eth::{
12    simulate::{SimulatePayload, SimulatedBlock},
13    state::{EvmOverrides, StateOverride},
14    BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, FeeHistory, Index,
15    StateContext, SyncStatus, Work,
16};
17use alloy_serde::JsonStorageKey;
18use jsonrpsee::{core::RpcResult, proc_macros::rpc};
19use reth_primitives_traits::TxTy;
20use reth_rpc_convert::RpcTxReq;
21use reth_rpc_eth_types::{EthApiError, EthCapabilities, FillTransaction};
22use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult};
23use serde_json::Value;
24use std::collections::HashMap;
25use tracing::trace;
26
27/// Helper trait, unifies functionality that must be supported to implement all RPC methods for
28/// server.
29pub trait FullEthApiServer:
30    EthApiServer<
31        RpcTxReq<Self::NetworkTypes>,
32        RpcTransaction<Self::NetworkTypes>,
33        RpcBlock<Self::NetworkTypes>,
34        RpcReceipt<Self::NetworkTypes>,
35        RpcHeader<Self::NetworkTypes>,
36        TxTy<Self::Primitives>,
37    > + FullEthApi
38    + Clone
39{
40}
41
42impl<T> FullEthApiServer for T where
43    T: EthApiServer<
44            RpcTxReq<T::NetworkTypes>,
45            RpcTransaction<T::NetworkTypes>,
46            RpcBlock<T::NetworkTypes>,
47            RpcReceipt<T::NetworkTypes>,
48            RpcHeader<T::NetworkTypes>,
49            TxTy<T::Primitives>,
50        > + FullEthApi
51        + Clone
52{
53}
54
55/// Eth rpc interface: <https://ethereum.github.io/execution-apis/api-documentation>
56#[cfg_attr(not(feature = "client"), rpc(server, namespace = "eth"))]
57#[cfg_attr(feature = "client", rpc(server, client, namespace = "eth"))]
58pub trait EthApi<
59    TxReq: RpcObject,
60    T: RpcObject,
61    B: RpcObject,
62    R: RpcObject,
63    H: RpcObject,
64    RawTx: RpcObject,
65>
66{
67    /// Returns the protocol version encoded as a string.
68    #[method(name = "protocolVersion")]
69    async fn protocol_version(&self) -> RpcResult<U64>;
70
71    /// Returns an object with data about the sync status or false.
72    #[method(name = "syncing")]
73    fn syncing(&self) -> RpcResult<SyncStatus>;
74
75    /// Returns the client coinbase address.
76    #[method(name = "coinbase")]
77    async fn author(&self) -> RpcResult<Address>;
78
79    /// Returns a list of addresses owned by client.
80    #[method(name = "accounts")]
81    fn accounts(&self) -> RpcResult<Vec<Address>>;
82
83    /// Returns the number of most recent block.
84    #[method(name = "blockNumber")]
85    fn block_number(&self) -> RpcResult<U256>;
86
87    /// Returns the chain ID of the current network.
88    #[method(name = "chainId")]
89    async fn chain_id(&self) -> RpcResult<Option<U64>>;
90
91    /// Returns effective routing capabilities for this node.
92    ///
93    /// See the `eth_capabilities` execution API proposal:
94    /// <https://github.com/ethereum/execution-apis/pull/755>.
95    #[method(name = "capabilities")]
96    fn capabilities(&self) -> RpcResult<EthCapabilities>;
97
98    /// Returns information about a block by hash.
99    #[method(name = "getBlockByHash")]
100    async fn block_by_hash(&self, hash: B256, full: bool) -> RpcResult<Option<B>>;
101
102    /// Returns information about a block by number.
103    #[method(name = "getBlockByNumber")]
104    async fn block_by_number(&self, number: BlockNumberOrTag, full: bool) -> RpcResult<Option<B>>;
105
106    /// Returns the number of transactions in a block from a block matching the given block hash.
107    #[method(name = "getBlockTransactionCountByHash")]
108    async fn block_transaction_count_by_hash(&self, hash: B256) -> RpcResult<Option<U256>>;
109
110    /// Returns the number of transactions in a block matching the given block number.
111    #[method(name = "getBlockTransactionCountByNumber")]
112    async fn block_transaction_count_by_number(
113        &self,
114        number: BlockNumberOrTag,
115    ) -> RpcResult<Option<U256>>;
116
117    /// Returns the number of uncles in a block from a block matching the given block hash.
118    #[method(name = "getUncleCountByBlockHash")]
119    async fn block_uncles_count_by_hash(&self, hash: B256) -> RpcResult<Option<U256>>;
120
121    /// Returns the number of uncles in a block with given block number.
122    #[method(name = "getUncleCountByBlockNumber")]
123    async fn block_uncles_count_by_number(
124        &self,
125        number: BlockNumberOrTag,
126    ) -> RpcResult<Option<U256>>;
127
128    /// Returns all transaction receipts for a given block.
129    #[method(name = "getBlockReceipts")]
130    async fn block_receipts(&self, block_id: BlockId) -> RpcResult<Option<Vec<R>>>;
131
132    /// Returns an uncle block of the given block and index.
133    #[method(name = "getUncleByBlockHashAndIndex")]
134    async fn uncle_by_block_hash_and_index(&self, hash: B256, index: Index)
135        -> RpcResult<Option<B>>;
136
137    /// Returns an uncle block of the given block and index.
138    #[method(name = "getUncleByBlockNumberAndIndex")]
139    async fn uncle_by_block_number_and_index(
140        &self,
141        number: BlockNumberOrTag,
142        index: Index,
143    ) -> RpcResult<Option<B>>;
144
145    /// Returns the EIP-2718 encoded transaction if it exists.
146    ///
147    /// If this is an EIP-4844 transaction that is in the pool, it will include the sidecar.
148    #[method(name = "getRawTransactionByHash")]
149    async fn raw_transaction_by_hash(&self, hash: B256) -> RpcResult<Option<Bytes>>;
150
151    /// Returns the information about a transaction requested by transaction hash.
152    #[method(name = "getTransactionByHash")]
153    async fn transaction_by_hash(&self, hash: B256) -> RpcResult<Option<T>>;
154
155    /// Returns information about a raw transaction by block hash and transaction index position.
156    #[method(name = "getRawTransactionByBlockHashAndIndex")]
157    async fn raw_transaction_by_block_hash_and_index(
158        &self,
159        hash: B256,
160        index: Index,
161    ) -> RpcResult<Option<Bytes>>;
162
163    /// Returns information about a transaction by block hash and transaction index position.
164    #[method(name = "getTransactionByBlockHashAndIndex")]
165    async fn transaction_by_block_hash_and_index(
166        &self,
167        hash: B256,
168        index: Index,
169    ) -> RpcResult<Option<T>>;
170
171    /// Returns information about a raw transaction by block number and transaction index
172    /// position.
173    #[method(name = "getRawTransactionByBlockNumberAndIndex")]
174    async fn raw_transaction_by_block_number_and_index(
175        &self,
176        number: BlockNumberOrTag,
177        index: Index,
178    ) -> RpcResult<Option<Bytes>>;
179
180    /// Returns information about a transaction by block number and transaction index position.
181    #[method(name = "getTransactionByBlockNumberAndIndex")]
182    async fn transaction_by_block_number_and_index(
183        &self,
184        number: BlockNumberOrTag,
185        index: Index,
186    ) -> RpcResult<Option<T>>;
187
188    /// Returns information about a transaction by sender and nonce.
189    #[method(name = "getTransactionBySenderAndNonce")]
190    async fn transaction_by_sender_and_nonce(
191        &self,
192        address: Address,
193        nonce: U64,
194    ) -> RpcResult<Option<T>>;
195
196    /// Returns all transactions in the local pending pool.
197    #[method(name = "pendingTransactions")]
198    fn pending_transactions(&self) -> RpcResult<Vec<T>>;
199
200    /// Returns the receipt of a transaction by transaction hash.
201    #[method(name = "getTransactionReceipt")]
202    async fn transaction_receipt(&self, hash: B256) -> RpcResult<Option<R>>;
203
204    /// Returns the balance of the account of given address.
205    #[method(name = "getBalance")]
206    async fn balance(&self, address: Address, block_number: Option<BlockId>) -> RpcResult<U256>;
207
208    /// Returns the value from a storage position at a given address
209    #[method(name = "getStorageAt")]
210    async fn storage_at(
211        &self,
212        address: Address,
213        index: JsonStorageKey,
214        block_number: Option<BlockId>,
215    ) -> RpcResult<B256>;
216
217    /// Returns values from multiple storage positions across multiple addresses.
218    #[method(name = "getStorageValues")]
219    async fn storage_values(
220        &self,
221        requests: HashMap<Address, Vec<JsonStorageKey>>,
222        block_number: Option<BlockId>,
223    ) -> RpcResult<HashMap<Address, Vec<B256>>>;
224
225    /// Returns the number of transactions sent from an address at given block number.
226    #[method(name = "getTransactionCount")]
227    async fn transaction_count(
228        &self,
229        address: Address,
230        block_number: Option<BlockId>,
231    ) -> RpcResult<U256>;
232
233    /// Returns code at a given address at given block number.
234    #[method(name = "getCode")]
235    async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> RpcResult<Bytes>;
236
237    /// Returns the block's header at given number.
238    #[method(name = "getHeaderByNumber")]
239    async fn header_by_number(&self, hash: BlockNumberOrTag) -> RpcResult<Option<H>>;
240
241    /// Returns the block's header at given hash.
242    #[method(name = "getHeaderByHash")]
243    async fn header_by_hash(&self, hash: B256) -> RpcResult<Option<H>>;
244
245    /// `eth_simulateV1` executes an arbitrary number of transactions on top of the requested state.
246    /// The transactions are packed into individual blocks. Overrides can be provided.
247    #[method(name = "simulateV1")]
248    async fn simulate_v1(
249        &self,
250        opts: SimulatePayload<TxReq>,
251        block_number: Option<BlockId>,
252    ) -> RpcResult<Vec<SimulatedBlock<B>>>;
253
254    /// Executes a new message call immediately without creating a transaction on the block chain.
255    #[method(name = "call")]
256    async fn call(
257        &self,
258        request: TxReq,
259        block_number: Option<BlockId>,
260        state_overrides: Option<StateOverride>,
261        block_overrides: Option<Box<BlockOverrides>>,
262    ) -> RpcResult<Bytes>;
263
264    /// Fills the defaults on a given unsigned transaction.
265    #[method(name = "fillTransaction")]
266    async fn fill_transaction(&self, request: TxReq) -> RpcResult<FillTransaction<RawTx>>;
267
268    /// Simulate arbitrary number of transactions at an arbitrary blockchain index, with the
269    /// optionality of state overrides
270    #[method(name = "callMany")]
271    async fn call_many(
272        &self,
273        bundles: Vec<Bundle<TxReq>>,
274        state_context: Option<StateContext>,
275        state_override: Option<StateOverride>,
276    ) -> RpcResult<Vec<Vec<EthCallResponse>>>;
277
278    /// Generates an access list for a transaction.
279    ///
280    /// This method creates an [EIP2930](https://eips.ethereum.org/EIPS/eip-2930) type accessList based on a given Transaction.
281    ///
282    /// An access list contains all storage slots and addresses touched by the transaction, except
283    /// for the sender account and the chain's precompiles.
284    ///
285    /// It returns list of addresses and storage keys used by the transaction, plus the gas
286    /// consumed when the access list is added. That is, it gives you the list of addresses and
287    /// storage keys that will be used by that transaction, plus the gas consumed if the access
288    /// list is included. Like `eth_estimateGas`, this is an estimation; the list could change
289    /// when the transaction is actually mined. Adding an accessList to your transaction does
290    /// not necessary result in lower gas usage compared to a transaction without an access
291    /// list.
292    #[method(name = "createAccessList")]
293    async fn create_access_list(
294        &self,
295        request: TxReq,
296        block_number: Option<BlockId>,
297        state_override: Option<StateOverride>,
298    ) -> RpcResult<AccessListResult>;
299
300    /// Generates and returns an estimate of how much gas is necessary to allow the transaction to
301    /// complete.
302    #[method(name = "estimateGas")]
303    async fn estimate_gas(
304        &self,
305        request: TxReq,
306        block_number: Option<BlockId>,
307        state_override: Option<StateOverride>,
308        block_overrides: Option<Box<BlockOverrides>>,
309    ) -> RpcResult<U256>;
310
311    /// Returns the current price per gas in wei.
312    #[method(name = "gasPrice")]
313    async fn gas_price(&self) -> RpcResult<U256>;
314
315    /// Returns the account details by specifying an address and a block number/tag
316    #[method(name = "getAccount")]
317    async fn get_account(
318        &self,
319        address: Address,
320        block: BlockId,
321    ) -> RpcResult<Option<alloy_rpc_types_eth::Account>>;
322
323    /// Introduced in EIP-1559, returns suggestion for the priority for dynamic fee transactions.
324    #[method(name = "maxPriorityFeePerGas")]
325    async fn max_priority_fee_per_gas(&self) -> RpcResult<U256>;
326
327    /// Returns the base fee for the next block, or `null` before London activation.
328    #[method(name = "baseFee")]
329    async fn base_fee(&self) -> RpcResult<Option<U256>>;
330
331    /// Introduced in EIP-4844, returns the current blob base fee in wei.
332    #[method(name = "blobBaseFee")]
333    async fn blob_base_fee(&self) -> RpcResult<U256>;
334
335    /// Returns the Transaction fee history
336    ///
337    /// Introduced in EIP-1559 for getting information on the appropriate priority fee to use.
338    ///
339    /// Returns transaction base fee per gas and effective priority fee per gas for the
340    /// requested/supported block range. The returned Fee history for the returned block range
341    /// can be a subsection of the requested range if not all blocks are available.
342    #[method(name = "feeHistory")]
343    async fn fee_history(
344        &self,
345        block_count: U64,
346        newest_block: BlockNumberOrTag,
347        reward_percentiles: Option<Vec<f64>>,
348    ) -> RpcResult<FeeHistory>;
349
350    /// Returns whether the client is actively mining new blocks.
351    #[method(name = "mining")]
352    async fn is_mining(&self) -> RpcResult<bool>;
353
354    /// Returns the number of hashes per second that the node is mining with.
355    #[method(name = "hashrate")]
356    async fn hashrate(&self) -> RpcResult<U256>;
357
358    /// Returns the hash of the current block, the seedHash, and the boundary condition to be met
359    /// (“target”)
360    #[method(name = "getWork")]
361    async fn get_work(&self) -> RpcResult<Work>;
362
363    /// Used for submitting mining hashrate.
364    ///
365    /// Can be used for remote miners to submit their hash rate.
366    /// It accepts the miner hash rate and an identifier which must be unique between nodes.
367    /// Returns `true` if the block was successfully submitted, `false` otherwise.
368    #[method(name = "submitHashrate")]
369    async fn submit_hashrate(&self, hashrate: U256, id: B256) -> RpcResult<bool>;
370
371    /// Used for submitting a proof-of-work solution.
372    #[method(name = "submitWork")]
373    async fn submit_work(&self, nonce: B64, pow_hash: B256, mix_digest: B256) -> RpcResult<bool>;
374
375    /// Sends transaction; will block waiting for signer to return the
376    /// transaction hash.
377    #[method(name = "sendTransaction")]
378    async fn send_transaction(&self, request: TxReq) -> RpcResult<B256>;
379
380    /// Sends signed transaction, returning its hash.
381    #[method(name = "sendRawTransaction")]
382    async fn send_raw_transaction(&self, bytes: Bytes) -> RpcResult<B256>;
383
384    /// Sends a signed transaction and awaits the transaction receipt.
385    ///
386    /// This will return a timeout error if the transaction isn't included within some time period.
387    #[method(name = "sendRawTransactionSync")]
388    async fn send_raw_transaction_sync(
389        &self,
390        bytes: Bytes,
391        timeout_ms: Option<u64>,
392    ) -> RpcResult<R>;
393
394    /// Returns an Ethereum specific signature with: sign(keccak256("\x19Ethereum Signed Message:\n"
395    /// + len(message) + message))).
396    #[method(name = "sign")]
397    async fn sign(&self, address: Address, message: Bytes) -> RpcResult<Bytes>;
398
399    /// Signs a transaction that can be submitted to the network at a later time using with
400    /// `sendRawTransaction.`
401    #[method(name = "signTransaction")]
402    async fn sign_transaction(&self, transaction: TxReq) -> RpcResult<Bytes>;
403
404    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
405    #[method(name = "signTypedData")]
406    async fn sign_typed_data(&self, address: Address, data: TypedData) -> RpcResult<Bytes>;
407
408    /// Returns the account and storage values of the specified account including the Merkle-proof.
409    /// This call can be used to verify that the data you are pulling from is not tampered with.
410    #[method(name = "getProof")]
411    async fn get_proof(
412        &self,
413        address: Address,
414        keys: Vec<JsonStorageKey>,
415        block_number: Option<BlockId>,
416    ) -> RpcResult<EIP1186AccountProofResponse>;
417
418    /// Returns the account and storage values of the specified targets including Merkle proofs.
419    #[method(name = "getMultiProof")]
420    async fn get_multi_proof(
421        &self,
422        targets: Vec<(Address, Vec<B256>)>,
423        block_number: Option<BlockId>,
424    ) -> RpcResult<Vec<EIP1186AccountProofResponse>>;
425
426    /// Returns the account's balance, nonce, and code.
427    ///
428    /// This is similar to `eth_getAccount` but does not return the storage root.
429    #[method(name = "getAccountInfo")]
430    async fn get_account_info(
431        &self,
432        address: Address,
433        block: BlockId,
434    ) -> RpcResult<alloy_rpc_types_eth::AccountInfo>;
435
436    /// Returns the EIP-7928 block access list for a block by hash.
437    #[method(name = "getBlockAccessListByBlockHash")]
438    async fn block_access_list_by_block_hash(&self, hash: B256) -> RpcResult<Option<Value>>;
439
440    /// Returns the EIP-7928 block access list for a block by number.
441    #[method(name = "getBlockAccessListByBlockNumber")]
442    async fn block_access_list_by_block_number(
443        &self,
444        number: BlockNumberOrTag,
445    ) -> RpcResult<Option<Value>>;
446
447    /// Returns the EIP-7928 block access list for a given block id.
448    #[method(name = "getBlockAccessList")]
449    async fn block_access_list(&self, block_id: BlockId) -> RpcResult<Option<Value>>;
450
451    /// Returns the EIP-7928 block access list bytes for a block by number.
452    #[method(name = "getBlockAccessListRaw")]
453    async fn block_access_list_raw(&self, block: BlockId) -> RpcResult<Option<Bytes>>;
454}
455
456#[async_trait::async_trait]
457impl<T>
458    EthApiServer<
459        RpcTxReq<T::NetworkTypes>,
460        RpcTransaction<T::NetworkTypes>,
461        RpcBlock<T::NetworkTypes>,
462        RpcReceipt<T::NetworkTypes>,
463        RpcHeader<T::NetworkTypes>,
464        TxTy<T::Primitives>,
465    > for T
466where
467    T: FullEthApi,
468    jsonrpsee_types::error::ErrorObject<'static>: From<T::Error>,
469{
470    /// Handler for: `eth_protocolVersion`
471    async fn protocol_version(&self) -> RpcResult<U64> {
472        trace!(target: "rpc::eth", "Serving eth_protocolVersion");
473        EthApiSpec::protocol_version(self).await.to_rpc_result()
474    }
475
476    /// Handler for: `eth_syncing`
477    fn syncing(&self) -> RpcResult<SyncStatus> {
478        trace!(target: "rpc::eth", "Serving eth_syncing");
479        EthApiSpec::sync_status(self).to_rpc_result()
480    }
481
482    /// Handler for: `eth_coinbase`
483    async fn author(&self) -> RpcResult<Address> {
484        Err(internal_rpc_err("unimplemented"))
485    }
486
487    /// Handler for: `eth_accounts`
488    fn accounts(&self) -> RpcResult<Vec<Address>> {
489        trace!(target: "rpc::eth", "Serving eth_accounts");
490        Ok(EthTransactions::accounts(self))
491    }
492
493    /// Handler for: `eth_blockNumber`
494    fn block_number(&self) -> RpcResult<U256> {
495        trace!(target: "rpc::eth", "Serving eth_blockNumber");
496        Ok(U256::from(
497            EthApiSpec::chain_info(self).with_message("failed to read chain info")?.best_number,
498        ))
499    }
500
501    /// Handler for: `eth_chainId`
502    async fn chain_id(&self) -> RpcResult<Option<U64>> {
503        trace!(target: "rpc::eth", "Serving eth_chainId");
504        Ok(Some(EthApiSpec::chain_id(self)))
505    }
506
507    /// Handler for: `eth_capabilities`
508    fn capabilities(&self) -> RpcResult<EthCapabilities> {
509        trace!(target: "rpc::eth", "Serving eth_capabilities");
510        EthApiSpec::capabilities(self).to_rpc_result()
511    }
512
513    /// Handler for: `eth_getBlockByHash`
514    async fn block_by_hash(
515        &self,
516        hash: B256,
517        full: bool,
518    ) -> RpcResult<Option<RpcBlock<T::NetworkTypes>>> {
519        trace!(target: "rpc::eth", ?hash, ?full, "Serving eth_getBlockByHash");
520        Ok(EthBlocks::rpc_block(self, hash.into(), full).await?)
521    }
522
523    /// Handler for: `eth_getBlockByNumber`
524    async fn block_by_number(
525        &self,
526        number: BlockNumberOrTag,
527        full: bool,
528    ) -> RpcResult<Option<RpcBlock<T::NetworkTypes>>> {
529        trace!(target: "rpc::eth", ?number, ?full, "Serving eth_getBlockByNumber");
530        Ok(EthBlocks::rpc_block(self, number.into(), full).await?)
531    }
532
533    /// Handler for: `eth_getBlockTransactionCountByHash`
534    async fn block_transaction_count_by_hash(&self, hash: B256) -> RpcResult<Option<U256>> {
535        trace!(target: "rpc::eth", ?hash, "Serving eth_getBlockTransactionCountByHash");
536        Ok(EthBlocks::block_transaction_count(self, hash.into()).await?.map(U256::from))
537    }
538
539    /// Handler for: `eth_getBlockTransactionCountByNumber`
540    async fn block_transaction_count_by_number(
541        &self,
542        number: BlockNumberOrTag,
543    ) -> RpcResult<Option<U256>> {
544        trace!(target: "rpc::eth", ?number, "Serving eth_getBlockTransactionCountByNumber");
545        Ok(EthBlocks::block_transaction_count(self, number.into()).await?.map(U256::from))
546    }
547
548    /// Handler for: `eth_getUncleCountByBlockHash`
549    async fn block_uncles_count_by_hash(&self, hash: B256) -> RpcResult<Option<U256>> {
550        trace!(target: "rpc::eth", ?hash, "Serving eth_getUncleCountByBlockHash");
551
552        if let Some(block) = self.block_by_hash(hash, false).await? {
553            Ok(Some(U256::from(block.uncles.len())))
554        } else {
555            Ok(None)
556        }
557    }
558
559    /// Handler for: `eth_getUncleCountByBlockNumber`
560    async fn block_uncles_count_by_number(
561        &self,
562        number: BlockNumberOrTag,
563    ) -> RpcResult<Option<U256>> {
564        trace!(target: "rpc::eth", ?number, "Serving eth_getUncleCountByBlockNumber");
565
566        if let Some(block) = self.block_by_number(number, false).await? {
567            Ok(Some(U256::from(block.uncles.len())))
568        } else {
569            Ok(None)
570        }
571    }
572
573    /// Handler for: `eth_getBlockReceipts`
574    async fn block_receipts(
575        &self,
576        block_id: BlockId,
577    ) -> RpcResult<Option<Vec<RpcReceipt<T::NetworkTypes>>>> {
578        trace!(target: "rpc::eth", ?block_id, "Serving eth_getBlockReceipts");
579        Ok(EthBlocks::block_receipts(self, block_id).await?)
580    }
581
582    /// Handler for: `eth_getUncleByBlockHashAndIndex`
583    async fn uncle_by_block_hash_and_index(
584        &self,
585        hash: B256,
586        index: Index,
587    ) -> RpcResult<Option<RpcBlock<T::NetworkTypes>>> {
588        trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getUncleByBlockHashAndIndex");
589        Ok(EthBlocks::ommer_by_block_and_index(self, hash.into(), index).await?)
590    }
591
592    /// Handler for: `eth_getUncleByBlockNumberAndIndex`
593    async fn uncle_by_block_number_and_index(
594        &self,
595        number: BlockNumberOrTag,
596        index: Index,
597    ) -> RpcResult<Option<RpcBlock<T::NetworkTypes>>> {
598        trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getUncleByBlockNumberAndIndex");
599        Ok(EthBlocks::ommer_by_block_and_index(self, number.into(), index).await?)
600    }
601
602    /// Handler for: `eth_getRawTransactionByHash`
603    async fn raw_transaction_by_hash(&self, hash: B256) -> RpcResult<Option<Bytes>> {
604        trace!(target: "rpc::eth", ?hash, "Serving eth_getRawTransactionByHash");
605        Ok(EthTransactions::raw_transaction_by_hash(self, hash).await?)
606    }
607
608    /// Handler for: `eth_getTransactionByHash`
609    async fn transaction_by_hash(
610        &self,
611        hash: B256,
612    ) -> RpcResult<Option<RpcTransaction<T::NetworkTypes>>> {
613        trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash");
614        Ok(EthTransactions::transaction_by_hash(self, hash)
615            .await?
616            .map(|tx| tx.into_transaction(self.converter()))
617            .transpose()
618            .map_err(T::Error::from)?)
619    }
620
621    /// Handler for: `eth_getRawTransactionByBlockHashAndIndex`
622    async fn raw_transaction_by_block_hash_and_index(
623        &self,
624        hash: B256,
625        index: Index,
626    ) -> RpcResult<Option<Bytes>> {
627        trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getRawTransactionByBlockHashAndIndex");
628        Ok(EthTransactions::raw_transaction_by_block_and_tx_index(self, hash.into(), index.into())
629            .await?)
630    }
631
632    /// Handler for: `eth_getTransactionByBlockHashAndIndex`
633    async fn transaction_by_block_hash_and_index(
634        &self,
635        hash: B256,
636        index: Index,
637    ) -> RpcResult<Option<RpcTransaction<T::NetworkTypes>>> {
638        trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getTransactionByBlockHashAndIndex");
639        Ok(EthTransactions::transaction_by_block_and_tx_index(self, hash.into(), index.into())
640            .await?)
641    }
642
643    /// Handler for: `eth_getRawTransactionByBlockNumberAndIndex`
644    async fn raw_transaction_by_block_number_and_index(
645        &self,
646        number: BlockNumberOrTag,
647        index: Index,
648    ) -> RpcResult<Option<Bytes>> {
649        trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getRawTransactionByBlockNumberAndIndex");
650        Ok(EthTransactions::raw_transaction_by_block_and_tx_index(
651            self,
652            number.into(),
653            index.into(),
654        )
655        .await?)
656    }
657
658    /// Handler for: `eth_getTransactionByBlockNumberAndIndex`
659    async fn transaction_by_block_number_and_index(
660        &self,
661        number: BlockNumberOrTag,
662        index: Index,
663    ) -> RpcResult<Option<RpcTransaction<T::NetworkTypes>>> {
664        trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getTransactionByBlockNumberAndIndex");
665        Ok(EthTransactions::transaction_by_block_and_tx_index(self, number.into(), index.into())
666            .await?)
667    }
668
669    /// Handler for: `eth_getTransactionBySenderAndNonce`
670    async fn transaction_by_sender_and_nonce(
671        &self,
672        sender: Address,
673        nonce: U64,
674    ) -> RpcResult<Option<RpcTransaction<T::NetworkTypes>>> {
675        trace!(target: "rpc::eth", ?sender, ?nonce, "Serving eth_getTransactionBySenderAndNonce");
676        Ok(EthTransactions::get_transaction_by_sender_and_nonce(self, sender, nonce.to(), true)
677            .await?)
678    }
679
680    /// Handler for: `eth_pendingTransactions`
681    fn pending_transactions(&self) -> RpcResult<Vec<RpcTransaction<T::NetworkTypes>>> {
682        trace!(target: "rpc::eth", "Serving eth_pendingTransactions");
683        Ok(EthTransactions::pending_transactions(self)?)
684    }
685
686    /// Handler for: `eth_getTransactionReceipt`
687    async fn transaction_receipt(
688        &self,
689        hash: B256,
690    ) -> RpcResult<Option<RpcReceipt<T::NetworkTypes>>> {
691        trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionReceipt");
692        Ok(EthTransactions::transaction_receipt(self, hash).await?)
693    }
694
695    /// Handler for: `eth_getBalance`
696    async fn balance(&self, address: Address, block_number: Option<BlockId>) -> RpcResult<U256> {
697        trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getBalance");
698        Ok(EthState::balance(self, address, block_number).await?)
699    }
700
701    /// Handler for: `eth_getStorageAt`
702    async fn storage_at(
703        &self,
704        address: Address,
705        index: JsonStorageKey,
706        block_number: Option<BlockId>,
707    ) -> RpcResult<B256> {
708        trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getStorageAt");
709        Ok(EthState::storage_at(self, address, index, block_number).await?)
710    }
711
712    /// Handler for: `eth_getStorageValues`
713    async fn storage_values(
714        &self,
715        requests: HashMap<Address, Vec<JsonStorageKey>>,
716        block_number: Option<BlockId>,
717    ) -> RpcResult<HashMap<Address, Vec<B256>>> {
718        trace!(target: "rpc::eth", ?block_number, "Serving eth_getStorageValues");
719        Ok(EthState::storage_values(self, requests, block_number).await?)
720    }
721
722    /// Handler for: `eth_getTransactionCount`
723    async fn transaction_count(
724        &self,
725        address: Address,
726        block_number: Option<BlockId>,
727    ) -> RpcResult<U256> {
728        trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getTransactionCount");
729        Ok(EthState::transaction_count(self, address, block_number).await?)
730    }
731
732    /// Handler for: `eth_getCode`
733    async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> RpcResult<Bytes> {
734        trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getCode");
735        Ok(EthState::get_code(self, address, block_number).await?)
736    }
737
738    /// Handler for: `eth_getHeaderByNumber`
739    async fn header_by_number(
740        &self,
741        block_number: BlockNumberOrTag,
742    ) -> RpcResult<Option<RpcHeader<T::NetworkTypes>>> {
743        trace!(target: "rpc::eth", ?block_number, "Serving eth_getHeaderByNumber");
744        Ok(EthBlocks::rpc_block_header(self, block_number.into()).await?)
745    }
746
747    /// Handler for: `eth_getHeaderByHash`
748    async fn header_by_hash(&self, hash: B256) -> RpcResult<Option<RpcHeader<T::NetworkTypes>>> {
749        trace!(target: "rpc::eth", ?hash, "Serving eth_getHeaderByHash");
750        Ok(EthBlocks::rpc_block_header(self, hash.into()).await?)
751    }
752
753    /// Handler for: `eth_simulateV1`
754    async fn simulate_v1(
755        &self,
756        payload: SimulatePayload<RpcTxReq<T::NetworkTypes>>,
757        block_number: Option<BlockId>,
758    ) -> RpcResult<Vec<SimulatedBlock<RpcBlock<T::NetworkTypes>>>> {
759        trace!(target: "rpc::eth", ?block_number, "Serving eth_simulateV1");
760        let _permit = self.tracing_task_guard().clone().acquire_owned().await;
761        Ok(EthCall::simulate_v1(self, payload, block_number).await?)
762    }
763
764    /// Handler for: `eth_call`
765    async fn call(
766        &self,
767        request: RpcTxReq<T::NetworkTypes>,
768        block_number: Option<BlockId>,
769        state_overrides: Option<StateOverride>,
770        block_overrides: Option<Box<BlockOverrides>>,
771    ) -> RpcResult<Bytes> {
772        trace!(target: "rpc::eth", ?request, ?block_number, ?state_overrides, ?block_overrides, "Serving eth_call");
773        Ok(EthCall::call(
774            self,
775            request,
776            block_number,
777            EvmOverrides::new(state_overrides, block_overrides),
778        )
779        .await?)
780    }
781
782    /// Handler for: `eth_fillTransaction`
783    async fn fill_transaction(
784        &self,
785        request: RpcTxReq<T::NetworkTypes>,
786    ) -> RpcResult<FillTransaction<TxTy<T::Primitives>>> {
787        trace!(target: "rpc::eth", ?request, "Serving eth_fillTransaction");
788        Ok(EthTransactions::fill_transaction(self, request).await?)
789    }
790
791    /// Handler for: `eth_callMany`
792    async fn call_many(
793        &self,
794        bundles: Vec<Bundle<RpcTxReq<T::NetworkTypes>>>,
795        state_context: Option<StateContext>,
796        state_override: Option<StateOverride>,
797    ) -> RpcResult<Vec<Vec<EthCallResponse>>> {
798        trace!(target: "rpc::eth", ?bundles, ?state_context, ?state_override, "Serving eth_callMany");
799        Ok(EthCall::call_many(self, bundles, state_context, state_override).await?)
800    }
801
802    /// Handler for: `eth_createAccessList`
803    async fn create_access_list(
804        &self,
805        request: RpcTxReq<T::NetworkTypes>,
806        block_number: Option<BlockId>,
807        state_override: Option<StateOverride>,
808    ) -> RpcResult<AccessListResult> {
809        trace!(target: "rpc::eth", ?request, ?block_number, ?state_override, "Serving eth_createAccessList");
810        Ok(EthCall::create_access_list_at(self, request, block_number, state_override).await?)
811    }
812
813    /// Handler for: `eth_estimateGas`
814    async fn estimate_gas(
815        &self,
816        request: RpcTxReq<T::NetworkTypes>,
817        block_number: Option<BlockId>,
818        state_override: Option<StateOverride>,
819        block_overrides: Option<Box<BlockOverrides>>,
820    ) -> RpcResult<U256> {
821        trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_estimateGas");
822        Ok(EthCall::estimate_gas_at(
823            self,
824            request,
825            block_number.unwrap_or_default(),
826            EvmOverrides::new(state_override, block_overrides),
827        )
828        .await?)
829    }
830
831    /// Handler for: `eth_gasPrice`
832    async fn gas_price(&self) -> RpcResult<U256> {
833        trace!(target: "rpc::eth", "Serving eth_gasPrice");
834        Ok(EthFees::gas_price(self).await?)
835    }
836
837    /// Handler for: `eth_getAccount`
838    async fn get_account(
839        &self,
840        address: Address,
841        block: BlockId,
842    ) -> RpcResult<Option<alloy_rpc_types_eth::Account>> {
843        trace!(target: "rpc::eth", "Serving eth_getAccount");
844        Ok(EthState::get_account(self, address, block).await?)
845    }
846
847    /// Handler for: `eth_maxPriorityFeePerGas`
848    async fn max_priority_fee_per_gas(&self) -> RpcResult<U256> {
849        trace!(target: "rpc::eth", "Serving eth_maxPriorityFeePerGas");
850        Ok(EthFees::suggested_priority_fee(self).await?)
851    }
852
853    /// Handler for: `eth_blobBaseFee`
854    async fn blob_base_fee(&self) -> RpcResult<U256> {
855        trace!(target: "rpc::eth", "Serving eth_blobBaseFee");
856        Ok(EthFees::blob_base_fee(self).await?)
857    }
858
859    /// Handler for: `eth_baseFee`
860    async fn base_fee(&self) -> RpcResult<Option<U256>> {
861        trace!(target: "rpc::eth", "Serving eth_baseFee");
862        Ok(EthFees::base_fee(self).await?)
863    }
864
865    // FeeHistory is calculated based on lazy evaluation of fees for historical blocks, and further
866    // caching of it in the LRU cache.
867    // When new RPC call is executed, the cache gets locked, we check it for the historical fees
868    // according to the requested block range, and fill any cache misses (in both RPC response
869    // and cache itself) with the actual data queried from the database.
870    // To minimize the number of database seeks required to query the missing data, we calculate the
871    // first non-cached block number and last non-cached block number. After that, we query this
872    // range of consecutive blocks from the database.
873    /// Handler for: `eth_feeHistory`
874    async fn fee_history(
875        &self,
876        block_count: U64,
877        newest_block: BlockNumberOrTag,
878        reward_percentiles: Option<Vec<f64>>,
879    ) -> RpcResult<FeeHistory> {
880        trace!(target: "rpc::eth", ?block_count, ?newest_block, ?reward_percentiles, "Serving eth_feeHistory");
881        Ok(EthFees::fee_history(self, block_count.to(), newest_block, reward_percentiles).await?)
882    }
883
884    /// Handler for: `eth_mining`
885    async fn is_mining(&self) -> RpcResult<bool> {
886        Err(internal_rpc_err("unimplemented"))
887    }
888
889    /// Handler for: `eth_hashrate`
890    async fn hashrate(&self) -> RpcResult<U256> {
891        Ok(U256::ZERO)
892    }
893
894    /// Handler for: `eth_getWork`
895    async fn get_work(&self) -> RpcResult<Work> {
896        Err(internal_rpc_err("unimplemented"))
897    }
898
899    /// Handler for: `eth_submitHashrate`
900    async fn submit_hashrate(&self, _hashrate: U256, _id: B256) -> RpcResult<bool> {
901        Ok(false)
902    }
903
904    /// Handler for: `eth_submitWork`
905    async fn submit_work(
906        &self,
907        _nonce: B64,
908        _pow_hash: B256,
909        _mix_digest: B256,
910    ) -> RpcResult<bool> {
911        Err(internal_rpc_err("unimplemented"))
912    }
913
914    /// Handler for: `eth_sendTransaction`
915    async fn send_transaction(&self, request: RpcTxReq<T::NetworkTypes>) -> RpcResult<B256> {
916        trace!(target: "rpc::eth", ?request, "Serving eth_sendTransaction");
917        Ok(EthTransactions::send_transaction_request(self, request).await?)
918    }
919
920    /// Handler for: `eth_sendRawTransaction`
921    async fn send_raw_transaction(&self, tx: Bytes) -> RpcResult<B256> {
922        trace!(target: "rpc::eth", ?tx, "Serving eth_sendRawTransaction");
923        Ok(EthTransactions::send_raw_transaction(self, tx).await?)
924    }
925
926    /// Handler for: `eth_sendRawTransactionSync`
927    async fn send_raw_transaction_sync(
928        &self,
929        tx: Bytes,
930        timeout_ms: Option<u64>,
931    ) -> RpcResult<RpcReceipt<T::NetworkTypes>> {
932        trace!(target: "rpc::eth", ?tx, ?timeout_ms, "Serving eth_sendRawTransactionSync");
933        Ok(EthTransactions::send_raw_transaction_sync(self, tx, timeout_ms).await?)
934    }
935
936    /// Handler for: `eth_sign`
937    async fn sign(&self, address: Address, message: Bytes) -> RpcResult<Bytes> {
938        trace!(target: "rpc::eth", ?address, ?message, "Serving eth_sign");
939        Ok(EthTransactions::sign(self, address, message).await?)
940    }
941
942    /// Handler for: `eth_signTransaction`
943    async fn sign_transaction(&self, request: RpcTxReq<T::NetworkTypes>) -> RpcResult<Bytes> {
944        trace!(target: "rpc::eth", ?request, "Serving eth_signTransaction");
945        Ok(EthTransactions::sign_transaction(self, request).await?)
946    }
947
948    /// Handler for: `eth_signTypedData`
949    async fn sign_typed_data(&self, address: Address, data: TypedData) -> RpcResult<Bytes> {
950        trace!(target: "rpc::eth", ?address, ?data, "Serving eth_signTypedData");
951        Ok(EthTransactions::sign_typed_data(self, &data, address)?)
952    }
953
954    /// Handler for: `eth_getProof`
955    async fn get_proof(
956        &self,
957        address: Address,
958        keys: Vec<JsonStorageKey>,
959        block_number: Option<BlockId>,
960    ) -> RpcResult<EIP1186AccountProofResponse> {
961        trace!(target: "rpc::eth", ?address, ?keys, ?block_number, "Serving eth_getProof");
962        Ok(EthState::get_proof(self, address, keys, block_number)?.await?)
963    }
964
965    /// Handler for: `eth_getMultiProof`
966    async fn get_multi_proof(
967        &self,
968        targets: Vec<(Address, Vec<B256>)>,
969        block_number: Option<BlockId>,
970    ) -> RpcResult<Vec<EIP1186AccountProofResponse>> {
971        trace!(target: "rpc::eth", ?targets, ?block_number, "Serving eth_getMultiProof");
972        Ok(EthState::get_multi_proof(self, targets, block_number)?.await?)
973    }
974
975    /// Handler for: `eth_getAccountInfo`
976    async fn get_account_info(
977        &self,
978        address: Address,
979        block: BlockId,
980    ) -> RpcResult<alloy_rpc_types_eth::AccountInfo> {
981        trace!(target: "rpc::eth", "Serving eth_getAccountInfo");
982        Ok(EthState::get_account_info(self, address, block).await?)
983    }
984
985    /// Handler for: `eth_getBlockAccessListByBlockHash`
986    async fn block_access_list_by_block_hash(&self, block_hash: B256) -> RpcResult<Option<Value>> {
987        trace!(target: "rpc::eth", ?block_hash, "Serving eth_getBlockAccessListByBlockHash");
988
989        let bal = self.get_block_access_list(block_hash.into()).await?;
990        let json = serde_json::to_value(&bal)
991            .map_err(|e| EthApiError::Internal(reth_errors::RethError::msg(e.to_string())))?;
992
993        Ok(Some(json))
994    }
995
996    /// Handler for: `eth_getBlockAccessListByBlockNumber`
997    async fn block_access_list_by_block_number(
998        &self,
999        number: BlockNumberOrTag,
1000    ) -> RpcResult<Option<Value>> {
1001        trace!(target: "rpc::eth", ?number, "Serving eth_getBlockAccessListByBlockNumber");
1002
1003        let bal = self.get_block_access_list(number.into()).await?;
1004        let json = serde_json::to_value(&bal)
1005            .map_err(|e| EthApiError::Internal(reth_errors::RethError::msg(e.to_string())))?;
1006
1007        Ok(Some(json))
1008    }
1009
1010    /// Handler for: `eth_getBlockAccessList`
1011    async fn block_access_list(&self, block_id: BlockId) -> RpcResult<Option<Value>> {
1012        trace!(target: "rpc::eth", ?block_id, "Serving eth_getBlockAccessList");
1013
1014        let bal = self.get_block_access_list(block_id).await?;
1015        let json = serde_json::to_value(&bal)
1016            .map_err(|e| EthApiError::Internal(reth_errors::RethError::msg(e.to_string())))?;
1017
1018        Ok(Some(json))
1019    }
1020
1021    /// Handler for: `eth_getBlockAccessListRaw`
1022    async fn block_access_list_raw(&self, block: BlockId) -> RpcResult<Option<Bytes>> {
1023        trace!(target: "rpc::eth", ?block, "Serving eth_getBlockAccessListRaw");
1024
1025        Ok(self.get_raw_block_access_list(block).await?)
1026    }
1027}