feat(rpc): Add admin_nodeInfo to get the local node record (#880)

Co-authored-by: Enrique Ortiz <evalir@users.noreply.github.com>
This commit is contained in:
Enrique Ortiz
2023-01-17 21:50:09 -04:00
committed by GitHub
parent 5d45325e43
commit dba3b30a42
5 changed files with 99 additions and 1 deletions

View File

@ -1,5 +1,6 @@
use jsonrpsee::{core::RpcResult as Result, proc_macros::rpc};
use reth_primitives::NodeRecord;
use reth_rpc_types::NodeInfo;
/// Admin namespace rpc interface that gives access to several non-standard RPC methods.
#[rpc(server)]
@ -33,4 +34,8 @@ pub trait AdminApi {
item = String
)]
fn subscribe(&self);
/// Returns the ENR of the node.
#[method(name = "admin_nodeInfo")]
fn node_info(&self) -> Result<NodeInfo>;
}

View File

@ -0,0 +1,76 @@
use reth_primitives::{NodeRecord, PeerId, H256, U256};
use serde::{Deserialize, Serialize};
use std::{
collections::BTreeMap,
net::{IpAddr, SocketAddr},
};
/// Represents the `admin_nodeInfo` response, which can be queried for all the information
/// known about the running node at the networking granularity.
///
/// Note: this format is not standardized. Reth follows geth's format,
/// see: https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-admin
#[derive(Serialize, Deserialize, Debug)]
pub struct NodeInfo {
/// Enode in URL format.
pub enode: NodeRecord,
/// ID of the local node.
pub id: PeerId,
/// IP of the local node.
pub ip: IpAddr,
/// Address exposed for listening for the local node.
#[serde(rename = "listenAddr")]
pub listen_addr: SocketAddr,
/// Local node client name.
pub name: String,
/// Ports exposed by the node for discovery and listening.
pub ports: Ports,
/// Networking protocols being run by the local node.
pub protocols: BTreeMap<String, ProtocolInfo>,
}
impl NodeInfo {
/// Creates a new instance of `NodeInfo`.
pub fn new(enr: NodeRecord) -> NodeInfo {
let protocol_info =
BTreeMap::from([("eth".into(), ProtocolInfo::Eth(EthProtocolInfo::default()))]);
NodeInfo {
enode: enr,
id: enr.id,
ip: enr.address,
listen_addr: enr.tcp_addr(),
name: "Reth".to_owned(),
ports: Ports { discovery: enr.udp_port, listener: enr.tcp_port },
protocols: protocol_info,
}
}
}
/// Ports exposed by the node for discovery and listening.
#[derive(Serialize, Deserialize, Debug)]
pub struct Ports {
/// Port exposed for node discovery.
pub discovery: u16,
/// Port exposed for listening.
pub listener: u16,
}
/// Information about the different protocols that can be run by the node (ETH, )
#[derive(Serialize, Deserialize, Debug)]
pub enum ProtocolInfo {
/// Information about the Ethereum Wire Protocol.
Eth(EthProtocolInfo),
}
/// Information about the Ethereum Wire Protocol (ETH)
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct EthProtocolInfo {
/// The current difficulty at the head of the chain.
pub difficulty: U256,
/// The block hash of the head of the chain.
pub head: H256,
/// Network ID in base 10.
pub network: u64,
/// Genesis block of the current chain.
pub genesis: H256,
}

View File

@ -76,7 +76,7 @@ pub struct PeerProtocolsInfo {
}
/// Peer Ethereum protocol information
#[derive(Debug, Clone, Default, Serialize)]
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct EthProtocolInfo {
/// Negotiated ethereum protocol version
pub version: u32,

View File

@ -9,6 +9,8 @@
//!
//! Provides all relevant types for the various RPC endpoints, grouped by namespace.
mod admin;
mod eth;
pub use admin::*;
pub use eth::*;

View File

@ -1,7 +1,9 @@
use jsonrpsee::core::RpcResult;
use reth_network::{peers::PeerKind, NetworkHandle};
use reth_network_api::PeersInfo;
use reth_primitives::NodeRecord;
use reth_rpc_api::AdminApiServer;
use reth_rpc_types::NodeInfo;
/// `admin` API implementation.
///
@ -11,6 +13,13 @@ pub struct AdminApi {
network: NetworkHandle,
}
impl AdminApi {
/// Creates a new instance of `AdminApi`.
pub fn new(network: NetworkHandle) -> AdminApi {
AdminApi { network }
}
}
impl AdminApiServer for AdminApi {
fn add_peer(&self, record: NodeRecord) -> RpcResult<bool> {
self.network.add_peer(record.id, record.tcp_addr());
@ -38,6 +47,12 @@ impl AdminApiServer for AdminApi {
) -> jsonrpsee::types::SubscriptionResult {
todo!()
}
fn node_info(&self) -> RpcResult<NodeInfo> {
let enr = self.network.local_node_record();
Ok(NodeInfo::new(enr))
}
}
impl std::fmt::Debug for AdminApi {