Adds peers and connected_peers to lighthouse http API (#1030)
This commit is contained in:
parent
fa7147f7c5
commit
9e42a851e4
@ -3,9 +3,10 @@
|
||||
//! Currently using identify to fingerprint.
|
||||
|
||||
use libp2p::identify::IdentifyInfo;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Various client and protocol information related to a node.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct Client {
|
||||
/// The client's name (Ex: lighthouse, prism, nimbus, etc)
|
||||
pub kind: ClientKind,
|
||||
@ -19,7 +20,7 @@ pub struct Client {
|
||||
pub agent_string: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub enum ClientKind {
|
||||
/// A lighthouse node (the best kind).
|
||||
Lighthouse,
|
||||
@ -125,6 +126,11 @@ fn client_from_agent_version(agent_version: &str) -> (ClientKind, String, String
|
||||
}
|
||||
(kind, version, os_version)
|
||||
}
|
||||
Some("github.com") => {
|
||||
let kind = ClientKind::Prysm;
|
||||
let unknown = String::from("unknown");
|
||||
(kind, unknown.clone(), unknown)
|
||||
}
|
||||
_ => {
|
||||
let unknown = String::from("unknown");
|
||||
(ClientKind::Unknown, unknown.clone(), unknown)
|
||||
|
@ -2,12 +2,17 @@ use super::client::Client;
|
||||
use super::peerdb::{Rep, DEFAULT_REPUTATION};
|
||||
use crate::rpc::MetaData;
|
||||
use crate::Multiaddr;
|
||||
use serde::{
|
||||
ser::{SerializeStructVariant, Serializer},
|
||||
Serialize,
|
||||
};
|
||||
use std::time::Instant;
|
||||
use types::{EthSpec, Slot, SubnetId};
|
||||
use PeerConnectionStatus::*;
|
||||
|
||||
/// Information about a given connected peer.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct PeerInfo<T: EthSpec> {
|
||||
/// The connection status of the peer
|
||||
_status: PeerStatus,
|
||||
@ -54,7 +59,7 @@ impl<T: EthSpec> PeerInfo<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub enum PeerStatus {
|
||||
/// The peer is healthy
|
||||
Healthy,
|
||||
@ -69,7 +74,7 @@ impl Default for PeerStatus {
|
||||
}
|
||||
|
||||
/// Connection Status of the peer
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PeerConnectionStatus {
|
||||
Connected {
|
||||
/// number of ingoing connections
|
||||
@ -86,12 +91,41 @@ pub enum PeerConnectionStatus {
|
||||
since: Instant,
|
||||
},
|
||||
Unknown {
|
||||
/// time since we know of this peer
|
||||
/// time since we last saw this peer
|
||||
since: Instant,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
/// Serialization for http requests.
|
||||
impl Serialize for PeerConnectionStatus {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
match self {
|
||||
Connected { n_in, n_out } => {
|
||||
let mut s = serializer.serialize_struct_variant("", 0, "Connected", 2)?;
|
||||
s.serialize_field("in", n_in)?;
|
||||
s.serialize_field("out", n_out)?;
|
||||
s.end()
|
||||
}
|
||||
Disconnected { since } => {
|
||||
let mut s = serializer.serialize_struct_variant("", 1, "Disconnected", 1)?;
|
||||
s.serialize_field("since", &since.elapsed().as_secs())?;
|
||||
s.end()
|
||||
}
|
||||
Banned { since } => {
|
||||
let mut s = serializer.serialize_struct_variant("", 2, "Banned", 1)?;
|
||||
s.serialize_field("since", &since.elapsed().as_secs())?;
|
||||
s.end()
|
||||
}
|
||||
Unknown { since } => {
|
||||
let mut s = serializer.serialize_struct_variant("", 3, "Unknown", 1)?;
|
||||
s.serialize_field("since", &since.elapsed().as_secs())?;
|
||||
s.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub enum PeerSyncStatus {
|
||||
/// At the current state as our node or ahead of us.
|
||||
Synced {
|
||||
|
@ -41,8 +41,13 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
.map_or(DEFAULT_REPUTATION, |info| info.reputation)
|
||||
}
|
||||
|
||||
/// Returns an iterator over all peers in the db.
|
||||
pub fn peers(&self) -> impl Iterator<Item = (&PeerId, &PeerInfo<TSpec>)> {
|
||||
self.peers.iter()
|
||||
}
|
||||
|
||||
/// Gives the ids of all known peers.
|
||||
pub fn peers(&self) -> impl Iterator<Item = &PeerId> {
|
||||
pub fn peer_ids(&self) -> impl Iterator<Item = &PeerId> {
|
||||
self.peers.keys()
|
||||
}
|
||||
|
||||
@ -66,7 +71,14 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
}
|
||||
|
||||
/// Gives the ids of all known connected peers.
|
||||
pub fn connected_peers(&self) -> impl Iterator<Item = &PeerId> {
|
||||
pub fn connected_peers(&self) -> impl Iterator<Item = (&PeerId, &PeerInfo<TSpec>)> {
|
||||
self.peers
|
||||
.iter()
|
||||
.filter(|(_, info)| info.connection_status.is_connected())
|
||||
}
|
||||
|
||||
/// Gives the ids of all known connected peers.
|
||||
pub fn connected_peer_ids(&self) -> impl Iterator<Item = &PeerId> {
|
||||
self.peers
|
||||
.iter()
|
||||
.filter(|(_, info)| info.connection_status.is_connected())
|
||||
@ -373,7 +385,7 @@ mod tests {
|
||||
}
|
||||
assert_eq!(pdb.n_dc, 0);
|
||||
|
||||
for p in pdb.connected_peers().cloned().collect::<Vec<_>>() {
|
||||
for p in pdb.connected_peer_ids().cloned().collect::<Vec<_>>() {
|
||||
pdb.disconnect(&p);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Available RPC methods types and ids.
|
||||
|
||||
use crate::types::EnrBitfield;
|
||||
use serde::Serialize;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use types::{Epoch, EthSpec, Hash256, SignedBeaconBlock, Slot};
|
||||
|
||||
@ -37,7 +38,8 @@ pub struct Ping {
|
||||
}
|
||||
|
||||
/// The METADATA response structure.
|
||||
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
|
||||
#[derive(Encode, Decode, Clone, Debug, PartialEq, Serialize)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct MetaData<T: EthSpec> {
|
||||
/// A sequential counter indicating when data gets modified.
|
||||
pub seq_number: u64,
|
||||
|
@ -80,7 +80,7 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||
|
||||
/// Returns the number of libp2p connected peers.
|
||||
pub fn connected_peers(&self) -> usize {
|
||||
self.peers.read().connected_peers().count()
|
||||
self.peers.read().connected_peer_ids().count()
|
||||
}
|
||||
|
||||
/// Returns in the node is syncing.
|
||||
|
@ -2,12 +2,57 @@
|
||||
|
||||
use crate::response_builder::ResponseBuilder;
|
||||
use crate::ApiResult;
|
||||
use eth2_libp2p::NetworkGlobals;
|
||||
use eth2_libp2p::{NetworkGlobals, PeerInfo};
|
||||
use hyper::{Body, Request};
|
||||
use serde::Serialize;
|
||||
use std::sync::Arc;
|
||||
use types::EthSpec;
|
||||
|
||||
/// The syncing state of the beacon node.
|
||||
pub fn syncing<T: EthSpec>(req: Request<Body>, network: Arc<NetworkGlobals<T>>) -> ApiResult {
|
||||
ResponseBuilder::new(&req)?.body_no_ssz(&network.sync_state())
|
||||
pub fn syncing<T: EthSpec>(
|
||||
req: Request<Body>,
|
||||
network_globals: Arc<NetworkGlobals<T>>,
|
||||
) -> ApiResult {
|
||||
ResponseBuilder::new(&req)?.body_no_ssz(&network_globals.sync_state())
|
||||
}
|
||||
|
||||
/// Returns all known peers and corresponding information
|
||||
pub fn peers<T: EthSpec>(req: Request<Body>, network_globals: Arc<NetworkGlobals<T>>) -> ApiResult {
|
||||
let peers: Vec<Peer<T>> = network_globals
|
||||
.peers
|
||||
.read()
|
||||
.peers()
|
||||
.map(|(peer_id, peer_info)| Peer {
|
||||
peer_id: peer_id.to_string(),
|
||||
peer_info: peer_info.clone(),
|
||||
})
|
||||
.collect();
|
||||
ResponseBuilder::new(&req)?.body_no_ssz(&peers)
|
||||
}
|
||||
|
||||
/// Returns all known connected peers and their corresponding information
|
||||
pub fn connected_peers<T: EthSpec>(
|
||||
req: Request<Body>,
|
||||
network_globals: Arc<NetworkGlobals<T>>,
|
||||
) -> ApiResult {
|
||||
let peers: Vec<Peer<T>> = network_globals
|
||||
.peers
|
||||
.read()
|
||||
.connected_peers()
|
||||
.map(|(peer_id, peer_info)| Peer {
|
||||
peer_id: peer_id.to_string(),
|
||||
peer_info: peer_info.clone(),
|
||||
})
|
||||
.collect();
|
||||
ResponseBuilder::new(&req)?.body_no_ssz(&peers)
|
||||
}
|
||||
|
||||
/// Information returned by `peers` and `connected_peers`.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
struct Peer<T: EthSpec> {
|
||||
/// The Peer's ID
|
||||
peer_id: String,
|
||||
/// The PeerInfo associated with the peer.
|
||||
peer_info: PeerInfo<T>,
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ pub fn get_peer_list<T: BeaconChainTypes>(
|
||||
let connected_peers: Vec<String> = network
|
||||
.peers
|
||||
.read()
|
||||
.connected_peers()
|
||||
.connected_peer_ids()
|
||||
.map(PeerId::to_string)
|
||||
.collect();
|
||||
ResponseBuilder::new(&req)?.body_no_ssz(&connected_peers)
|
||||
|
@ -203,7 +203,6 @@ pub fn route<T: BeaconChainTypes>(
|
||||
(&Method::GET, "/advanced/operation_pool") => {
|
||||
into_boxfut(advanced::get_operation_pool::<T>(req, beacon_chain))
|
||||
}
|
||||
|
||||
(&Method::GET, "/metrics") => into_boxfut(metrics::get_prometheus::<T>(
|
||||
req,
|
||||
beacon_chain,
|
||||
@ -215,7 +214,12 @@ pub fn route<T: BeaconChainTypes>(
|
||||
(&Method::GET, "/lighthouse/syncing") => {
|
||||
into_boxfut(lighthouse::syncing::<T::EthSpec>(req, network_globals))
|
||||
}
|
||||
|
||||
(&Method::GET, "/lighthouse/peers") => {
|
||||
into_boxfut(lighthouse::peers::<T::EthSpec>(req, network_globals))
|
||||
}
|
||||
(&Method::GET, "/lighthouse/connected_peers") => into_boxfut(
|
||||
lighthouse::connected_peers::<T::EthSpec>(req, network_globals),
|
||||
),
|
||||
_ => Box::new(futures::future::err(ApiError::NotFound(
|
||||
"Request path and/or method not found.".to_owned(),
|
||||
))),
|
||||
|
@ -7,6 +7,8 @@ The `/lighthouse` endpoints provide lighthouse-specific information about the be
|
||||
HTTP Path | Description |
|
||||
| --- | -- |
|
||||
[`/lighthouse/syncing`](#lighthousesyncing) | Get the node's syncing status
|
||||
[`/lighthouse/peers`](#lighthousepeers) | Get the peers info known by the beacon node
|
||||
[`/lighthouse/connected_peers`](#lighthousepeers) | Get the connected_peers known by the beacon node
|
||||
|
||||
## `/lighthouse/syncing`
|
||||
|
||||
@ -52,3 +54,129 @@ If the node is synced
|
||||
"Synced"
|
||||
}
|
||||
```
|
||||
|
||||
## `/lighthouse/peers`
|
||||
|
||||
Get all known peers info from the beacon node.
|
||||
|
||||
### HTTP Specification
|
||||
|
||||
| Property | Specification |
|
||||
| --- |--- |
|
||||
Path | `/lighthouse/peers`
|
||||
Method | GET
|
||||
JSON Encoding | Object
|
||||
Query Parameters | None
|
||||
Typical Responses | 200
|
||||
|
||||
### Example Response
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"peer_id" : "16Uiu2HAmTEinipUS3haxqucrn7d7SmCKx5XzAVbAZCiNW54ncynG",
|
||||
"peer_info" : {
|
||||
"_status" : "Healthy",
|
||||
"client" : {
|
||||
"agent_string" : "github.com/libp2p/go-libp2p",
|
||||
"kind" : "Prysm",
|
||||
"os_version" : "unknown",
|
||||
"protocol_version" : "ipfs/0.1.0",
|
||||
"version" : "unknown"
|
||||
},
|
||||
"connection_status" : {
|
||||
"Disconnected" : {
|
||||
"since" : 3
|
||||
}
|
||||
},
|
||||
"listening_addresses" : [
|
||||
"/ip4/10.3.58.241/tcp/9001",
|
||||
"/ip4/35.172.14.146/tcp/9001",
|
||||
"/ip4/35.172.14.146/tcp/9001"
|
||||
],
|
||||
"meta_data" : {
|
||||
"attnets" : "0x0000000000000000",
|
||||
"seq_number" : 0
|
||||
},
|
||||
"reputation" : 20,
|
||||
"sync_status" : {
|
||||
"Synced" : {
|
||||
"status_head_slot" : 18146
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"peer_id" : "16Uiu2HAm8XZfPv3YjktCjitSRtfS7UfHfEvpiUyHrdiX6uAD55xZ",
|
||||
"peer_info" : {
|
||||
"_status" : "Healthy",
|
||||
"client" : {
|
||||
"agent_string" : null,
|
||||
"kind" : "Unknown",
|
||||
"os_version" : "unknown",
|
||||
"protocol_version" : "unknown",
|
||||
"version" : "unknown"
|
||||
},
|
||||
"connection_status" : {
|
||||
"Disconnected" : {
|
||||
"since" : 5
|
||||
}
|
||||
},
|
||||
"listening_addresses" : [],
|
||||
"meta_data" : {
|
||||
"attnets" : "0x0900000000000000",
|
||||
"seq_number" : 0
|
||||
},
|
||||
"reputation" : 20,
|
||||
"sync_status" : "Unknown"
|
||||
}
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## `/lighthouse/connected_peers`
|
||||
|
||||
Get all known peers info from the beacon node.
|
||||
|
||||
### HTTP Specification
|
||||
|
||||
| Property | Specification |
|
||||
| --- |--- |
|
||||
Path | `/lighthouse/connected_peers`
|
||||
Method | GET
|
||||
JSON Encoding | Object
|
||||
Query Parameters | None
|
||||
Typical Responses | 200
|
||||
|
||||
### Example Response
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"peer_id" : "16Uiu2HAm8XZfPv3YjktCjitSRtfS7UfHfEvpiUyHrdiX6uAD55xZ",
|
||||
"peer_info" : {
|
||||
"_status" : "Healthy",
|
||||
"client" : {
|
||||
"agent_string" : null,
|
||||
"kind" : "Unknown",
|
||||
"os_version" : "unknown",
|
||||
"protocol_version" : "unknown",
|
||||
"version" : "unknown"
|
||||
},
|
||||
"connection_status" : {
|
||||
"Connected" : {
|
||||
"in" : 5,
|
||||
"out" : 2
|
||||
}
|
||||
},
|
||||
"listening_addresses" : [],
|
||||
"meta_data" : {
|
||||
"attnets" : "0x0900000000000000",
|
||||
"seq_number" : 0
|
||||
},
|
||||
"reputation" : 20,
|
||||
"sync_status" : "Unknown"
|
||||
}
|
||||
},
|
||||
]
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user