expose peer information via rpc (#1362)

* expose peer information via rpc

* fixes tests

* cleanup

Co-Authored-By: xlc <xlchen1291@gmail.com>

* Update docs

Co-Authored-By: xlc <xlchen1291@gmail.com>

* Add missing docs

* keep original type for PeerInfo best_hash/best_number

* cleanup

* Update mod.rs
This commit is contained in:
Xiliang Chen
2019-01-10 00:18:24 +13:00
committed by Gav Wood
parent 43269f0dbc
commit eb3503b0c7
8 changed files with 91 additions and 9 deletions
+17
View File
@@ -45,6 +45,23 @@ pub struct Health {
pub is_syncing: bool,
}
/// Network Peer information
#[derive(Debug, PartialEq, Serialize)]
pub struct PeerInfo<Hash, Number> {
/// Peer Node Index
pub index: usize,
/// Peer ID
pub peer_id: String,
/// Roles
pub roles: String,
/// Protocol version
pub protocol_version: u32,
/// Peer best block hash
pub best_hash: Hash,
/// Peer best block number
pub best_number: Number,
}
impl fmt::Display for Health {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{} peers ({})", self.peers, if self.is_syncing {
+19 -4
View File
@@ -24,14 +24,14 @@ mod tests;
use std::sync::Arc;
use network;
use runtime_primitives::traits;
use runtime_primitives::traits::{self, Header as HeaderT};
use self::error::Result;
pub use self::helpers::{Properties, SystemInfo, Health};
pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo};
build_rpc_trait! {
/// Substrate system RPC API
pub trait SystemApi {
pub trait SystemApi<Hash, Number> {
/// Get the node's implementation name. Plain old string.
#[rpc(name = "system_name")]
fn system_name(&self) -> Result<String>;
@@ -55,6 +55,10 @@ build_rpc_trait! {
/// - not performing a major sync
#[rpc(name = "system_health")]
fn system_health(&self) -> Result<Health>;
/// Returns currently connected peers
#[rpc(name = "system_peers")]
fn system_peers(&self) -> Result<Vec<PeerInfo<Hash, Number>>>;
}
}
@@ -80,7 +84,7 @@ impl<B: traits::Block> System<B> {
}
}
impl<B: traits::Block> SystemApi for System<B> {
impl<B: traits::Block> SystemApi<B::Hash, <B::Header as HeaderT>::Number> for System<B> {
fn system_name(&self) -> Result<String> {
Ok(self.info.impl_name.clone())
}
@@ -115,4 +119,15 @@ impl<B: traits::Block> SystemApi for System<B> {
Ok(health)
}
}
fn system_peers(&self) -> Result<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>> {
Ok(self.sync.peers().into_iter().map(|(idx, peer_id, p)| PeerInfo {
index: idx,
peer_id: peer_id.map_or_else(Default::default, |p| p.to_base58()),
roles: format!("{:?}", p.roles),
protocol_version: p.protocol_version,
best_hash: p.best_hash,
best_number: p.best_number,
}).collect())
}
}
+27 -1
View File
@@ -16,8 +16,10 @@
use super::*;
use network::{self, SyncState, SyncStatus, ProtocolStatus};
use network::{self, SyncState, SyncStatus, ProtocolStatus, NodeIndex, PeerId, PeerInfo as NetworkPeerInfo, PublicKey};
use network::config::Roles;
use test_client::runtime::Block;
use primitives::H256;
#[derive(Default)]
struct Status {
@@ -37,6 +39,15 @@ impl network::SyncProvider<Block> for Status {
num_active_peers: 0,
}
}
fn peers(&self) -> Vec<(NodeIndex, Option<PeerId>, NetworkPeerInfo<Block>)> {
vec![(1, Some(PublicKey::Ed25519((0 .. 32).collect::<Vec<u8>>()).into()), NetworkPeerInfo {
roles: Roles::FULL,
protocol_version: 1,
best_hash: Default::default(),
best_number: 1
})]
}
}
@@ -129,3 +140,18 @@ fn system_health() {
}
);
}
#[test]
fn system_peers() {
assert_eq!(
api(None).system_peers().unwrap(),
vec![PeerInfo {
index: 1,
peer_id: "QmS5oyTmdjwBowwAH1D9YQnoe2HyWpVemH8qHiU5RqWPh4".into(),
roles: "FULL".into(),
protocol_version: 1,
best_hash: Default::default(),
best_number: 1u64,
}]
);
}