reth_rpc_eth_api/helpers/
spec.rs

1//! Loads chain metadata.
2
3use alloy_primitives::{U256, U64};
4use alloy_rpc_types_eth::{Stage, SyncInfo, SyncStatus};
5use futures::Future;
6use reth_chainspec::ChainInfo;
7use reth_errors::{RethError, RethResult};
8use reth_network_api::NetworkInfo;
9use reth_rpc_convert::RpcTxReq;
10use reth_storage_api::{BlockNumReader, StageCheckpointReader, TransactionsProvider};
11
12use crate::{helpers::EthSigner, EthApiTypes, RpcNodeCore};
13
14/// `Eth` API trait.
15///
16/// Defines core functionality of the `eth` API implementation.
17#[auto_impl::auto_impl(&, Arc)]
18pub trait EthApiSpec: RpcNodeCore + EthApiTypes {
19    /// Returns the block node is started on.
20    fn starting_block(&self) -> U256;
21
22    /// Returns the current ethereum protocol version.
23    fn protocol_version(&self) -> impl Future<Output = RethResult<U64>> + Send {
24        async move {
25            let status = self.network().network_status().await.map_err(RethError::other)?;
26            Ok(U64::from(status.protocol_version))
27        }
28    }
29
30    /// Returns the chain id
31    fn chain_id(&self) -> U64 {
32        U64::from(self.network().chain_id())
33    }
34
35    /// Returns provider chain info
36    fn chain_info(&self) -> RethResult<ChainInfo> {
37        Ok(self.provider().chain_info()?)
38    }
39
40    /// Returns `true` if the network is undergoing sync.
41    fn is_syncing(&self) -> bool {
42        self.network().is_syncing()
43    }
44
45    /// Returns the [`SyncStatus`] of the network
46    fn sync_status(&self) -> RethResult<SyncStatus> {
47        let status = if self.is_syncing() {
48            let current_block = U256::from(
49                self.provider().chain_info().map(|info| info.best_number).unwrap_or_default(),
50            );
51
52            let stages = self
53                .provider()
54                .get_all_checkpoints()
55                .unwrap_or_default()
56                .into_iter()
57                .map(|(name, checkpoint)| Stage { name, block: checkpoint.block_number })
58                .collect();
59
60            SyncStatus::Info(Box::new(SyncInfo {
61                starting_block: self.starting_block(),
62                current_block,
63                highest_block: current_block,
64                warp_chunks_amount: None,
65                warp_chunks_processed: None,
66                stages: Some(stages),
67            }))
68        } else {
69            SyncStatus::None
70        };
71        Ok(status)
72    }
73}
74
75/// A handle to [`EthSigner`]s with its generics set from [`TransactionsProvider`] and
76/// [`reth_rpc_convert::RpcTypes`].
77pub type SignersForRpc<Provider, Rpc> = parking_lot::RwLock<
78    Vec<Box<dyn EthSigner<<Provider as TransactionsProvider>::Transaction, RpcTxReq<Rpc>>>>,
79>;