mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix(rpc): make NodeInfo behave as geth nodeInfo (#1200)
This commit is contained in:
@ -86,7 +86,7 @@ pub enum PeerKind {
|
||||
}
|
||||
|
||||
/// The status of the network being ran by the local node.
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct NetworkStatus {
|
||||
/// The local node client version.
|
||||
pub client_version: String,
|
||||
@ -95,11 +95,11 @@ pub struct NetworkStatus {
|
||||
/// Information about the Ethereum Wire Protocol.
|
||||
pub eth_protocol_info: EthProtocolInfo,
|
||||
}
|
||||
|
||||
/// Information about the Ethereum Wire Protocol (ETH)
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct EthProtocolInfo {
|
||||
/// The current difficulty at the head of the chain.
|
||||
#[serde(deserialize_with = "reth_primitives::serde_helper::deserialize_json_u256")]
|
||||
pub difficulty: U256,
|
||||
/// The block hash of the head of the chain.
|
||||
pub head: H256,
|
||||
|
||||
@ -9,6 +9,12 @@ use std::{fmt, str::FromStr};
|
||||
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub struct JsonU256(pub U256);
|
||||
|
||||
impl From<JsonU256> for U256 {
|
||||
fn from(value: JsonU256) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for JsonU256 {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@ -69,6 +75,15 @@ impl<'a> Visitor<'a> for JsonU256Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
/// Supports parsing `U256` numbers as strings via [JsonU256]
|
||||
pub fn deserialize_json_u256<'de, D>(deserializer: D) -> Result<U256, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let num = JsonU256::deserialize(deserializer)?;
|
||||
Ok(num.into())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::JsonU256;
|
||||
|
||||
@ -96,13 +96,18 @@ mod __reexport {
|
||||
pub use tiny_keccak;
|
||||
}
|
||||
|
||||
// Useful reexports
|
||||
pub use __reexport::*;
|
||||
|
||||
/// Various utilities
|
||||
pub mod utils {
|
||||
pub use ethers_core::types::serde_helpers;
|
||||
}
|
||||
|
||||
// Useful reexports
|
||||
pub use __reexport::*;
|
||||
/// Helpers for working with serde
|
||||
pub mod serde_helper {
|
||||
pub use crate::jsonu256::deserialize_json_u256;
|
||||
}
|
||||
|
||||
/// Returns the keccak256 hash for the given data.
|
||||
#[inline]
|
||||
|
||||
@ -93,7 +93,17 @@ impl fmt::Display for NodeRecord {
|
||||
f.write_str("enode://")?;
|
||||
hex::encode(self.id.as_bytes()).fmt(f)?;
|
||||
f.write_char('@')?;
|
||||
self.address.fmt(f)?;
|
||||
match self.address {
|
||||
IpAddr::V4(ip) => {
|
||||
ip.fmt(f)?;
|
||||
}
|
||||
IpAddr::V6(ip) => {
|
||||
// encapsulate with brackets
|
||||
f.write_char('[')?;
|
||||
ip.fmt(f)?;
|
||||
f.write_char(']')?;
|
||||
}
|
||||
}
|
||||
f.write_char(':')?;
|
||||
self.tcp_port.fmt(f)?;
|
||||
if self.tcp_port != self.udp_port {
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
use reth_network_api::NetworkStatus;
|
||||
use reth_network_api::{EthProtocolInfo, NetworkStatus};
|
||||
use reth_primitives::{NodeRecord, PeerId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
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)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct NodeInfo {
|
||||
/// Enode in URL format.
|
||||
/// Enode of the node in URL format.
|
||||
pub enode: NodeRecord,
|
||||
/// ID of the local node.
|
||||
pub id: PeerId,
|
||||
@ -21,9 +24,10 @@ pub struct NodeInfo {
|
||||
pub listen_addr: SocketAddr,
|
||||
/// Ports exposed by the node for discovery and listening.
|
||||
pub ports: Ports,
|
||||
/// Name of the network
|
||||
pub name: String,
|
||||
/// Networking protocols being run by the local node.
|
||||
#[serde(flatten)]
|
||||
pub status: NetworkStatus,
|
||||
pub protocols: Protocols,
|
||||
}
|
||||
|
||||
impl NodeInfo {
|
||||
@ -35,16 +39,42 @@ impl NodeInfo {
|
||||
ip: enr.address,
|
||||
listen_addr: enr.tcp_addr(),
|
||||
ports: Ports { discovery: enr.udp_port, listener: enr.tcp_port },
|
||||
status,
|
||||
name: status.client_version,
|
||||
protocols: Protocols { eth: status.eth_protocol_info, other: Default::default() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// All supported protocols
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Protocols {
|
||||
/// Info about `eth` sub-protocol
|
||||
pub eth: EthProtocolInfo,
|
||||
/// Placeholder for any other protocols
|
||||
#[serde(flatten, default)]
|
||||
pub other: BTreeMap<String, serde_json::Value>,
|
||||
}
|
||||
|
||||
/// Ports exposed by the node for discovery and listening.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Ports {
|
||||
/// Port exposed for node discovery.
|
||||
pub discovery: u16,
|
||||
/// Port exposed for listening.
|
||||
pub listener: u16,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_node_info_roundtrip() {
|
||||
let sample = r#"{"enode":"enode://44826a5d6a55f88a18298bca4773fca5749cdc3a5c9f308aa7d810e9b31123f3e7c5fba0b1d70aac5308426f47df2a128a6747040a3815cc7dd7167d03be320d@[::]:30303","id":"44826a5d6a55f88a18298bca4773fca5749cdc3a5c9f308aa7d810e9b31123f3e7c5fba0b1d70aac5308426f47df2a128a6747040a3815cc7dd7167d03be320d","ip":"::","listenAddr":"[::]:30303","name":"reth","ports":{"discovery":30303,"listener":30303},"protocols":{"eth":{"difficulty":17334254859343145000,"genesis":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3","head":"0xb83f73fbe6220c111136aefd27b160bf4a34085c65ba89f24246b3162257c36a","network":1}}}"#;
|
||||
|
||||
let info: NodeInfo = serde_json::from_str(sample).unwrap();
|
||||
let serialized = serde_json::to_string_pretty(&info).unwrap();
|
||||
let de_serialized: NodeInfo = serde_json::from_str(&serialized).unwrap();
|
||||
assert_eq!(info, de_serialized)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user