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.
|
/// 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 {
|
pub struct NetworkStatus {
|
||||||
/// The local node client version.
|
/// The local node client version.
|
||||||
pub client_version: String,
|
pub client_version: String,
|
||||||
@ -95,11 +95,11 @@ pub struct NetworkStatus {
|
|||||||
/// Information about the Ethereum Wire Protocol.
|
/// Information about the Ethereum Wire Protocol.
|
||||||
pub eth_protocol_info: EthProtocolInfo,
|
pub eth_protocol_info: EthProtocolInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about the Ethereum Wire Protocol (ETH)
|
/// Information about the Ethereum Wire Protocol (ETH)
|
||||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct EthProtocolInfo {
|
pub struct EthProtocolInfo {
|
||||||
/// The current difficulty at the head of the chain.
|
/// The current difficulty at the head of the chain.
|
||||||
|
#[serde(deserialize_with = "reth_primitives::serde_helper::deserialize_json_u256")]
|
||||||
pub difficulty: U256,
|
pub difficulty: U256,
|
||||||
/// The block hash of the head of the chain.
|
/// The block hash of the head of the chain.
|
||||||
pub head: H256,
|
pub head: H256,
|
||||||
|
|||||||
@ -9,6 +9,12 @@ use std::{fmt, str::FromStr};
|
|||||||
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||||
pub struct JsonU256(pub U256);
|
pub struct JsonU256(pub U256);
|
||||||
|
|
||||||
|
impl From<JsonU256> for U256 {
|
||||||
|
fn from(value: JsonU256) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Serialize for JsonU256 {
|
impl Serialize for JsonU256 {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::JsonU256;
|
use super::JsonU256;
|
||||||
|
|||||||
@ -96,13 +96,18 @@ mod __reexport {
|
|||||||
pub use tiny_keccak;
|
pub use tiny_keccak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Useful reexports
|
||||||
|
pub use __reexport::*;
|
||||||
|
|
||||||
/// Various utilities
|
/// Various utilities
|
||||||
pub mod utils {
|
pub mod utils {
|
||||||
pub use ethers_core::types::serde_helpers;
|
pub use ethers_core::types::serde_helpers;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Useful reexports
|
/// Helpers for working with serde
|
||||||
pub use __reexport::*;
|
pub mod serde_helper {
|
||||||
|
pub use crate::jsonu256::deserialize_json_u256;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the keccak256 hash for the given data.
|
/// Returns the keccak256 hash for the given data.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@ -93,7 +93,17 @@ impl fmt::Display for NodeRecord {
|
|||||||
f.write_str("enode://")?;
|
f.write_str("enode://")?;
|
||||||
hex::encode(self.id.as_bytes()).fmt(f)?;
|
hex::encode(self.id.as_bytes()).fmt(f)?;
|
||||||
f.write_char('@')?;
|
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(':')?;
|
f.write_char(':')?;
|
||||||
self.tcp_port.fmt(f)?;
|
self.tcp_port.fmt(f)?;
|
||||||
if self.tcp_port != self.udp_port {
|
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 reth_primitives::{NodeRecord, PeerId};
|
||||||
use serde::{Deserialize, Serialize};
|
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
|
/// Represents the `admin_nodeInfo` response, which can be queried for all the information
|
||||||
/// known about the running node at the networking granularity.
|
/// known about the running node at the networking granularity.
|
||||||
///
|
///
|
||||||
/// Note: this format is not standardized. Reth follows Geth's format,
|
/// Note: this format is not standardized. Reth follows Geth's format,
|
||||||
/// see: <https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-admin>
|
/// 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 {
|
pub struct NodeInfo {
|
||||||
/// Enode in URL format.
|
/// Enode of the node in URL format.
|
||||||
pub enode: NodeRecord,
|
pub enode: NodeRecord,
|
||||||
/// ID of the local node.
|
/// ID of the local node.
|
||||||
pub id: PeerId,
|
pub id: PeerId,
|
||||||
@ -21,9 +24,10 @@ pub struct NodeInfo {
|
|||||||
pub listen_addr: SocketAddr,
|
pub listen_addr: SocketAddr,
|
||||||
/// Ports exposed by the node for discovery and listening.
|
/// Ports exposed by the node for discovery and listening.
|
||||||
pub ports: Ports,
|
pub ports: Ports,
|
||||||
|
/// Name of the network
|
||||||
|
pub name: String,
|
||||||
/// Networking protocols being run by the local node.
|
/// Networking protocols being run by the local node.
|
||||||
#[serde(flatten)]
|
pub protocols: Protocols,
|
||||||
pub status: NetworkStatus,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeInfo {
|
impl NodeInfo {
|
||||||
@ -35,16 +39,42 @@ impl NodeInfo {
|
|||||||
ip: enr.address,
|
ip: enr.address,
|
||||||
listen_addr: enr.tcp_addr(),
|
listen_addr: enr.tcp_addr(),
|
||||||
ports: Ports { discovery: enr.udp_port, listener: enr.tcp_port },
|
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.
|
/// Ports exposed by the node for discovery and listening.
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct Ports {
|
pub struct Ports {
|
||||||
/// Port exposed for node discovery.
|
/// Port exposed for node discovery.
|
||||||
pub discovery: u16,
|
pub discovery: u16,
|
||||||
/// Port exposed for listening.
|
/// Port exposed for listening.
|
||||||
pub listener: u16,
|
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