//! Loads chain metadata. use std::sync::Arc; use futures::Future; use reth_chainspec::{ChainInfo, ChainSpec}; use reth_errors::{RethError, RethResult}; use reth_network_api::NetworkInfo; use reth_primitives::{Address, U256, U64}; use reth_provider::{BlockNumReader, ChainSpecProvider, StageCheckpointReader}; use reth_rpc_types::{Stage, SyncInfo, SyncStatus}; use super::EthSigner; /// `Eth` API trait. /// /// Defines core functionality of the `eth` API implementation. #[auto_impl::auto_impl(&, Arc)] pub trait EthApiSpec: Send + Sync { /// Returns a handle for reading data from disk. fn provider(&self) -> impl ChainSpecProvider + BlockNumReader + StageCheckpointReader; /// Returns a handle for reading network data summary. fn network(&self) -> impl NetworkInfo; /// Returns the block node is started on. fn starting_block(&self) -> U256; /// Returns a handle to the signers owned by provider. fn signers(&self) -> &parking_lot::RwLock>>; /// Returns the current ethereum protocol version. fn protocol_version(&self) -> impl Future> + Send { async move { let status = self.network().network_status().await.map_err(RethError::other)?; Ok(U64::from(status.protocol_version)) } } /// Returns the chain id fn chain_id(&self) -> U64 { U64::from(self.network().chain_id()) } /// Returns provider chain info fn chain_info(&self) -> RethResult { Ok(self.provider().chain_info()?) } /// Returns a list of addresses owned by provider. fn accounts(&self) -> Vec
{ self.signers().read().iter().flat_map(|s| s.accounts()).collect() } /// Returns `true` if the network is undergoing sync. fn is_syncing(&self) -> bool { self.network().is_syncing() } /// Returns the [`SyncStatus`] of the network fn sync_status(&self) -> RethResult { let status = if self.is_syncing() { let current_block = U256::from( self.provider().chain_info().map(|info| info.best_number).unwrap_or_default(), ); let stages = self .provider() .get_all_checkpoints() .unwrap_or_default() .into_iter() .map(|(name, checkpoint)| Stage { name, block: checkpoint.block_number }) .collect(); SyncStatus::Info(Box::new(SyncInfo { starting_block: self.starting_block(), current_block, highest_block: current_block, warp_chunks_amount: None, warp_chunks_processed: None, stages: Some(stages), })) } else { SyncStatus::None }; Ok(status) } /// Returns the configured [`ChainSpec`]. fn chain_spec(&self) -> Arc { self.provider().chain_spec() } }