feat: integrate chain_id and protocol_version in NetworkInfo (#1029)

This commit is contained in:
Aurélien
2023-01-25 13:08:40 +01:00
committed by GitHub
parent 6c37b0aa1b
commit e493720f64
7 changed files with 53 additions and 19 deletions

View File

@@ -16,4 +16,7 @@ pub enum Error {
#[error(transparent)]
Provider(#[from] crate::provider::Error),
#[error(transparent)]
Network(#[from] reth_network_api::NetworkError),
}

View File

@@ -26,6 +26,9 @@ pub trait NetworkInfo: Send + Sync {
/// Returns the current status of the network being ran by the local node.
async fn network_status(&self) -> Result<NetworkStatus, NetworkError>;
/// Returns the chain id
fn chain_id(&self) -> u64;
}
/// Provides general purpose information about Peers in the network.
@@ -44,6 +47,8 @@ pub trait PeersInfo: Send + Sync {
pub struct NetworkStatus {
/// The local node client version.
pub client_version: String,
/// The current ethereum protocol version
pub protocol_version: u64,
/// Information about the Ethereum Wire Protocol.
pub eth_protocol_info: EthProtocolInfo,
}

View File

@@ -46,7 +46,7 @@ use std::{
net::SocketAddr,
pin::Pin,
sync::{
atomic::{AtomicUsize, Ordering},
atomic::{AtomicU64, AtomicUsize, Ordering},
Arc,
},
task::{Context, Poll},
@@ -218,6 +218,7 @@ where
peers_handle,
network_mode,
bandwidth_meter,
Arc::new(AtomicU64::new(chain_spec.chain.id())),
);
Ok(Self {
@@ -312,9 +313,11 @@ where
pub fn status(&self) -> NetworkStatus {
let sessions = self.swarm.sessions();
let status = sessions.status();
let hello_message = sessions.hello_message();
NetworkStatus {
client_version: sessions.hello_message().client_version,
client_version: hello_message.client_version,
protocol_version: hello_message.protocol_version as u64,
eth_protocol_info: EthProtocolInfo {
difficulty: status.total_difficulty,
head: status.blockhash,

View File

@@ -19,7 +19,7 @@ use reth_primitives::{NodeRecord, PeerId, TransactionSigned, TxHash, H256, U256}
use std::{
net::SocketAddr,
sync::{
atomic::{AtomicBool, AtomicUsize, Ordering},
atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering},
Arc,
},
};
@@ -39,6 +39,7 @@ pub struct NetworkHandle {
impl NetworkHandle {
/// Creates a single new instance.
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
num_active_peers: Arc<AtomicUsize>,
listener_address: Arc<Mutex<SocketAddr>>,
@@ -47,6 +48,7 @@ impl NetworkHandle {
peers: PeersHandle,
network_mode: NetworkMode,
bandwidth_meter: BandwidthMeter,
chain_id: Arc<AtomicU64>,
) -> Self {
let inner = NetworkInner {
num_active_peers,
@@ -57,6 +59,7 @@ impl NetworkHandle {
network_mode,
bandwidth_meter,
is_syncing: Arc::new(Default::default()),
chain_id,
};
Self { inner: Arc::new(inner) }
}
@@ -227,6 +230,10 @@ impl NetworkInfo for NetworkHandle {
let _ = self.manager().send(NetworkHandleMessage::GetStatus(tx));
rx.await.map_err(Into::into)
}
fn chain_id(&self) -> u64 {
self.inner.chain_id.load(Ordering::Relaxed)
}
}
impl StatusUpdater for NetworkHandle {
@@ -267,6 +274,8 @@ struct NetworkInner {
bandwidth_meter: BandwidthMeter,
/// Represents if the network is currently syncing.
is_syncing: Arc<AtomicBool>,
/// The chain id
chain_id: Arc<AtomicU64>,
}
/// Internal messages that can be passed to the [`NetworkManager`](crate::NetworkManager).

View File

@@ -15,7 +15,7 @@ use reth_rpc_types::{
pub trait EthApi {
/// Returns the protocol version encoded as a string.
#[method(name = "eth_protocolVersion")]
fn protocol_version(&self) -> Result<U64>;
async fn protocol_version(&self) -> Result<U64>;
/// Returns an object with data about the sync status or false.
#[method(name = "eth_syncing")]

View File

@@ -1,6 +1,8 @@
//! Provides everything related to `eth_` namespace
use async_trait::async_trait;
use reth_interfaces::Result;
use reth_network_api::NetworkInfo;
use reth_primitives::U64;
use reth_provider::{BlockProvider, ChainInfo, StateProviderFactory};
use reth_rpc_types::Transaction;
@@ -12,9 +14,10 @@ mod server;
/// `Eth` API trait.
///
/// Defines core functionality of the `eth` API implementation.
#[async_trait]
pub trait EthApiSpec: Send + Sync {
/// Returns the current ethereum protocol version.
fn protocol_version(&self) -> U64;
async fn protocol_version(&self) -> Result<U64>;
/// Returns the chain id
fn chain_id(&self) -> U64;
@@ -32,19 +35,20 @@ pub trait EthApiSpec: Send + Sync {
/// the main impls. This way [`EthApi`] is not limited to [`jsonrpsee`] and can be used standalone
/// or in other network handlers (for example ipc).
#[derive(Debug, Clone)]
pub struct EthApi<Pool, Client> {
pub struct EthApi<Pool, Client, Network> {
/// All nested fields bundled together.
inner: Arc<EthApiInner<Pool, Client>>,
inner: Arc<EthApiInner<Pool, Client, Network>>,
}
impl<Pool, Client> EthApi<Pool, Client>
impl<Pool, Client, Network> EthApi<Pool, Client, Network>
where
Pool: TransactionPool + 'static,
Client: BlockProvider + StateProviderFactory + 'static,
Network: NetworkInfo,
{
/// Creates a new, shareable instance.
pub fn new(client: Arc<Client>, pool: Pool) -> Self {
let inner = EthApiInner { client, pool };
pub fn new(client: Arc<Client>, pool: Pool, network: Network) -> Self {
let inner = EthApiInner { client, pool, network };
Self { inner: Arc::new(inner) }
}
@@ -52,23 +56,31 @@ where
fn client(&self) -> &Arc<Client> {
&self.inner.client
}
/// Returns the inner `Network`
fn network(&self) -> &Network {
&self.inner.network
}
}
impl<Pool, Client> EthApiSpec for EthApi<Pool, Client>
#[async_trait]
impl<Pool, Client, Network> EthApiSpec for EthApi<Pool, Client, Network>
where
Pool: TransactionPool<Transaction = Transaction> + Clone + 'static,
Client: BlockProvider + StateProviderFactory + 'static,
Network: NetworkInfo + 'static,
{
/// Returns the current ethereum protocol version.
///
/// Note: This returns an `U64`, since this should return as hex string.
fn protocol_version(&self) -> U64 {
1u64.into()
async fn protocol_version(&self) -> Result<U64> {
let status = self.network().network_status().await?;
Ok(U64::from(status.protocol_version))
}
/// Returns the chain id
fn chain_id(&self) -> U64 {
todo!()
U64::from(self.network().chain_id())
}
/// Returns the current info for the chain
@@ -79,10 +91,11 @@ where
/// Container type `EthApi`
#[derive(Debug)]
struct EthApiInner<Pool, Client> {
struct EthApiInner<Pool, Client, Network> {
/// The transaction pool.
pool: Pool,
/// The client that can interact with the chain.
client: Arc<Client>,
// TODO needs network access to handle things like `eth_syncing`
/// An interface to interact with the network
network: Network,
}

View File

@@ -19,14 +19,15 @@ use serde_json::Value;
use super::EthApiSpec;
#[async_trait::async_trait]
impl<Pool, Client> EthApiServer for EthApi<Pool, Client>
impl<Pool, Client, Network> EthApiServer for EthApi<Pool, Client, Network>
where
Self: EthApiSpec,
Pool: TransactionPool + 'static,
Client: BlockProvider + StateProviderFactory + 'static,
Network: 'static,
{
fn protocol_version(&self) -> Result<U64> {
Ok(EthApiSpec::protocol_version(self))
async fn protocol_version(&self) -> Result<U64> {
EthApiSpec::protocol_version(self).await.to_rpc_result()
}
fn syncing(&self) -> Result<SyncStatus> {