reth_rpc_eth_api/helpers/
spec.rs1use 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#[auto_impl::auto_impl(&, Arc)]
18pub trait EthApiSpec: RpcNodeCore + EthApiTypes {
19 fn starting_block(&self) -> U256;
21
22 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 fn chain_id(&self) -> U64 {
32 U64::from(self.network().chain_id())
33 }
34
35 fn chain_info(&self) -> RethResult<ChainInfo> {
37 Ok(self.provider().chain_info()?)
38 }
39
40 fn is_syncing(&self) -> bool {
42 self.network().is_syncing()
43 }
44
45 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
75pub type SignersForRpc<Provider, Rpc> = parking_lot::RwLock<
78 Vec<Box<dyn EthSigner<<Provider as TransactionsProvider>::Transaction, RpcTxReq<Rpc>>>>,
79>;