LES Peer Info (#4195)
* connected peers function for network service * get LES peer info in sync API * new peer info in RPC
This commit is contained in:
parent
35666f718b
commit
3ff9324ec0
@ -77,7 +77,7 @@ impl<'a> IoContext for NetworkContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Basic context for a the protocol.
|
/// Basic context for the protocol.
|
||||||
pub trait BasicContext {
|
pub trait BasicContext {
|
||||||
/// Returns the relevant's peer persistent Id (aka NodeId).
|
/// Returns the relevant's peer persistent Id (aka NodeId).
|
||||||
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
|
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
|
||||||
|
@ -316,6 +316,12 @@ impl LightProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to get peer status.
|
||||||
|
pub fn peer_status(&self, peer: &PeerId) -> Option<Status> {
|
||||||
|
self.peers.read().get(&peer)
|
||||||
|
.map(|peer| peer.lock().status.clone())
|
||||||
|
}
|
||||||
|
|
||||||
/// Check the maximum amount of requests of a specific type
|
/// Check the maximum amount of requests of a specific type
|
||||||
/// which a peer would be able to serve. Returns zero if the
|
/// which a peer would be able to serve. Returns zero if the
|
||||||
/// peer is unknown or has no buffer flow parameters.
|
/// peer is unknown or has no buffer flow parameters.
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use util::{H256, RwLock};
|
use util::{H256, RwLock};
|
||||||
use ethsync::{SyncProvider, SyncStatus, SyncState, PeerInfo, TransactionStats};
|
use ethsync::{SyncProvider, EthProtocolInfo, SyncStatus, SyncState, PeerInfo, TransactionStats};
|
||||||
|
|
||||||
/// TestSyncProvider config.
|
/// TestSyncProvider config.
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
@ -78,9 +78,12 @@ impl SyncProvider for TestSyncProvider {
|
|||||||
capabilities: vec!["eth/62".to_owned(), "eth/63".to_owned()],
|
capabilities: vec!["eth/62".to_owned(), "eth/63".to_owned()],
|
||||||
remote_address: "127.0.0.1:7777".to_owned(),
|
remote_address: "127.0.0.1:7777".to_owned(),
|
||||||
local_address: "127.0.0.1:8888".to_owned(),
|
local_address: "127.0.0.1:8888".to_owned(),
|
||||||
eth_version: 62,
|
eth_info: Some(EthProtocolInfo {
|
||||||
eth_difficulty: Some(40.into()),
|
version: 62,
|
||||||
eth_head: 50.into()
|
difficulty: Some(40.into()),
|
||||||
|
head: 50.into(),
|
||||||
|
}),
|
||||||
|
les_info: None,
|
||||||
},
|
},
|
||||||
PeerInfo {
|
PeerInfo {
|
||||||
id: None,
|
id: None,
|
||||||
@ -88,9 +91,12 @@ impl SyncProvider for TestSyncProvider {
|
|||||||
capabilities: vec!["eth/63".to_owned(), "eth/64".to_owned()],
|
capabilities: vec!["eth/63".to_owned(), "eth/64".to_owned()],
|
||||||
remote_address: "Handshake".to_owned(),
|
remote_address: "Handshake".to_owned(),
|
||||||
local_address: "127.0.0.1:3333".to_owned(),
|
local_address: "127.0.0.1:3333".to_owned(),
|
||||||
eth_version: 64,
|
eth_info: Some(EthProtocolInfo {
|
||||||
eth_difficulty: None,
|
version: 64,
|
||||||
eth_head: 60.into()
|
difficulty: None,
|
||||||
|
head: 60.into()
|
||||||
|
}),
|
||||||
|
les_info: None,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ fn rpc_parity_net_peers() {
|
|||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":{"active":0,"connected":120,"max":50,"peers":[{"caps":["eth/62","eth/63"],"id":"node1","name":"Parity/1","network":{"localAddress":"127.0.0.1:8888","remoteAddress":"127.0.0.1:7777"},"protocols":{"eth":{"difficulty":"0x28","head":"0000000000000000000000000000000000000000000000000000000000000032","version":62}}},{"caps":["eth/63","eth/64"],"id":null,"name":"Parity/2","network":{"localAddress":"127.0.0.1:3333","remoteAddress":"Handshake"},"protocols":{"eth":{"difficulty":null,"head":"000000000000000000000000000000000000000000000000000000000000003c","version":64}}}]},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":{"active":0,"connected":120,"max":50,"peers":[{"caps":["eth/62","eth/63"],"id":"node1","name":"Parity/1","network":{"localAddress":"127.0.0.1:8888","remoteAddress":"127.0.0.1:7777"},"protocols":{"eth":{"difficulty":"0x28","head":"0000000000000000000000000000000000000000000000000000000000000032","version":62},"les":null}},{"caps":["eth/63","eth/64"],"id":null,"name":"Parity/2","network":{"localAddress":"127.0.0.1:3333","remoteAddress":"Handshake"},"protocols":{"eth":{"difficulty":null,"head":"000000000000000000000000000000000000000000000000000000000000003c","version":64},"les":null}}]},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,8 @@ pub use self::hash::{H64, H160, H256, H512, H520, H2048};
|
|||||||
pub use self::index::Index;
|
pub use self::index::Index;
|
||||||
pub use self::log::Log;
|
pub use self::log::Log;
|
||||||
pub use self::sync::{
|
pub use self::sync::{
|
||||||
SyncStatus, SyncInfo, Peers, PeerInfo, PeerNetworkInfo, PeerProtocolsInfo, PeerEthereumProtocolInfo,
|
SyncStatus, SyncInfo, Peers, PeerInfo, PeerNetworkInfo, PeerProtocolsInfo,
|
||||||
TransactionStats, ChainStatus
|
TransactionStats, ChainStatus, EthProtocolInfo, LesProtocolInfo,
|
||||||
};
|
};
|
||||||
pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus};
|
pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus};
|
||||||
pub use self::transaction_request::TransactionRequest;
|
pub use self::transaction_request::TransactionRequest;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use ethsync::{PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats};
|
use ethsync::{self, PeerInfo as SyncPeerInfo, TransactionStats as SyncTransactionStats};
|
||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
use v1::types::{U256, H512};
|
use v1::types::{U256, H512};
|
||||||
|
|
||||||
@ -82,12 +82,14 @@ pub struct PeerNetworkInfo {
|
|||||||
#[derive(Default, Debug, Serialize)]
|
#[derive(Default, Debug, Serialize)]
|
||||||
pub struct PeerProtocolsInfo {
|
pub struct PeerProtocolsInfo {
|
||||||
/// Ethereum protocol information
|
/// Ethereum protocol information
|
||||||
pub eth: Option<PeerEthereumProtocolInfo>,
|
pub eth: Option<EthProtocolInfo>,
|
||||||
|
/// LES protocol information.
|
||||||
|
pub les: Option<LesProtocolInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peer Ethereum protocol information
|
/// Peer Ethereum protocol information
|
||||||
#[derive(Default, Debug, Serialize)]
|
#[derive(Default, Debug, Serialize)]
|
||||||
pub struct PeerEthereumProtocolInfo {
|
pub struct EthProtocolInfo {
|
||||||
/// Negotiated ethereum protocol version
|
/// Negotiated ethereum protocol version
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
/// Peer total difficulty if known
|
/// Peer total difficulty if known
|
||||||
@ -96,6 +98,37 @@ pub struct PeerEthereumProtocolInfo {
|
|||||||
pub head: String,
|
pub head: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ethsync::EthProtocolInfo> for EthProtocolInfo {
|
||||||
|
fn from(info: ethsync::EthProtocolInfo) -> Self {
|
||||||
|
EthProtocolInfo {
|
||||||
|
version: info.version,
|
||||||
|
difficulty: info.difficulty.map(Into::into),
|
||||||
|
head: info.head.hex(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Peer LES protocol information
|
||||||
|
#[derive(Default, Debug, Serialize)]
|
||||||
|
pub struct LesProtocolInfo {
|
||||||
|
/// Negotiated LES protocol version
|
||||||
|
pub version: u32,
|
||||||
|
/// Peer total difficulty
|
||||||
|
pub difficulty: U256,
|
||||||
|
/// SHA3 of peer best block hash
|
||||||
|
pub head: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ethsync::LesProtocolInfo> for LesProtocolInfo {
|
||||||
|
fn from(info: ethsync::LesProtocolInfo) -> Self {
|
||||||
|
LesProtocolInfo {
|
||||||
|
version: info.version,
|
||||||
|
difficulty: info.difficulty.into(),
|
||||||
|
head: info.head.hex(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Sync status
|
/// Sync status
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum SyncStatus {
|
pub enum SyncStatus {
|
||||||
@ -137,11 +170,8 @@ impl From<SyncPeerInfo> for PeerInfo {
|
|||||||
local_address: p.local_address,
|
local_address: p.local_address,
|
||||||
},
|
},
|
||||||
protocols: PeerProtocolsInfo {
|
protocols: PeerProtocolsInfo {
|
||||||
eth: Some(PeerEthereumProtocolInfo {
|
eth: p.eth_info.map(Into::into),
|
||||||
version: p.eth_version,
|
les: p.les_info.map(Into::into),
|
||||||
difficulty: p.eth_difficulty.map(|d| d.into()),
|
|
||||||
head: p.eth_head.hex(),
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ use parking_lot::RwLock;
|
|||||||
use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT};
|
use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT};
|
||||||
use light::client::LightChainClient;
|
use light::client::LightChainClient;
|
||||||
use light::Provider;
|
use light::Provider;
|
||||||
use light::net::{LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext};
|
use light::net::{self as light_net, LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext};
|
||||||
|
|
||||||
/// Parity sync protocol
|
/// Parity sync protocol
|
||||||
pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par";
|
pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par";
|
||||||
@ -123,12 +123,44 @@ pub struct PeerInfo {
|
|||||||
pub remote_address: String,
|
pub remote_address: String,
|
||||||
/// Local endpoint address
|
/// Local endpoint address
|
||||||
pub local_address: String,
|
pub local_address: String,
|
||||||
/// Ethereum protocol version
|
/// Eth protocol info.
|
||||||
pub eth_version: u32,
|
pub eth_info: Option<EthProtocolInfo>,
|
||||||
|
/// Light protocol info.
|
||||||
|
pub les_info: Option<LesProtocolInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ethereum protocol info.
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
|
pub struct EthProtocolInfo {
|
||||||
|
/// Protocol version
|
||||||
|
pub version: u32,
|
||||||
/// SHA3 of peer best block hash
|
/// SHA3 of peer best block hash
|
||||||
pub eth_head: H256,
|
pub head: H256,
|
||||||
/// Peer total difficulty if known
|
/// Peer total difficulty if known
|
||||||
pub eth_difficulty: Option<U256>,
|
pub difficulty: Option<U256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// LES protocol info.
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
|
pub struct LesProtocolInfo {
|
||||||
|
/// Protocol version
|
||||||
|
pub version: u32,
|
||||||
|
/// SHA3 of peer best block hash
|
||||||
|
pub head: H256,
|
||||||
|
/// Peer total difficulty if known
|
||||||
|
pub difficulty: U256,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<light_net::Status> for LesProtocolInfo {
|
||||||
|
fn from(status: light_net::Status) -> Self {
|
||||||
|
LesProtocolInfo {
|
||||||
|
version: status.protocol_version,
|
||||||
|
head: status.head_hash,
|
||||||
|
difficulty: status.head_td,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EthSync initialization parameters.
|
/// EthSync initialization parameters.
|
||||||
@ -214,11 +246,28 @@ impl SyncProvider for EthSync {
|
|||||||
|
|
||||||
/// Get sync peers
|
/// Get sync peers
|
||||||
fn peers(&self) -> Vec<PeerInfo> {
|
fn peers(&self) -> Vec<PeerInfo> {
|
||||||
// TODO: [rob] LES peers/peer info
|
self.network.with_context_eval(self.subprotocol_name, |ctx| {
|
||||||
self.network.with_context_eval(self.subprotocol_name, |context| {
|
let peer_ids = self.network.connected_peers();
|
||||||
let sync_io = NetSyncIo::new(context, &*self.eth_handler.chain, &*self.eth_handler.snapshot_service, &self.eth_handler.overlay);
|
let eth_sync = self.eth_handler.sync.read();
|
||||||
self.eth_handler.sync.write().peers(&sync_io)
|
let light_proto = self.light_proto.as_ref();
|
||||||
}).unwrap_or(Vec::new())
|
|
||||||
|
peer_ids.into_iter().filter_map(|peer_id| {
|
||||||
|
let session_info = match ctx.session_info(peer_id) {
|
||||||
|
None => return None,
|
||||||
|
Some(info) => info,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(PeerInfo {
|
||||||
|
id: session_info.id.map(|id| id.hex()),
|
||||||
|
client_version: session_info.client_version,
|
||||||
|
capabilities: session_info.peer_capabilities.into_iter().map(|c| c.to_string()).collect(),
|
||||||
|
remote_address: session_info.remote_address,
|
||||||
|
local_address: session_info.local_address,
|
||||||
|
eth_info: eth_sync.peer_info(&peer_id),
|
||||||
|
les_info: light_proto.as_ref().and_then(|lp| lp.peer_status(&peer_id)).map(Into::into),
|
||||||
|
})
|
||||||
|
}).collect()
|
||||||
|
}).unwrap_or_else(Vec::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enode(&self) -> Option<String> {
|
fn enode(&self) -> Option<String> {
|
||||||
|
@ -102,7 +102,7 @@ use super::SyncConfig;
|
|||||||
use block_sync::{BlockDownloader, BlockRequest, BlockDownloaderImportError as DownloaderImportError, DownloadAction};
|
use block_sync::{BlockDownloader, BlockRequest, BlockDownloaderImportError as DownloaderImportError, DownloadAction};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use snapshot::{Snapshot, ChunkType};
|
use snapshot::{Snapshot, ChunkType};
|
||||||
use api::{PeerInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID};
|
use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID};
|
||||||
use transactions_stats::{TransactionsStats, Stats as TransactionStats};
|
use transactions_stats::{TransactionsStats, Stats as TransactionStats};
|
||||||
|
|
||||||
known_heap_size!(0, PeerInfo);
|
known_heap_size!(0, PeerInfo);
|
||||||
@ -431,22 +431,14 @@ impl ChainSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns information on peers connections
|
/// Returns information on peers connections
|
||||||
pub fn peers(&self, io: &SyncIo) -> Vec<PeerInfoDigest> {
|
pub fn peer_info(&self, peer_id: &PeerId) -> Option<PeerInfoDigest> {
|
||||||
self.peers.iter()
|
self.peers.get(peer_id).map(|peer_data| {
|
||||||
.filter_map(|(&peer_id, peer_data)|
|
PeerInfoDigest {
|
||||||
io.peer_session_info(peer_id).map(|session_info|
|
version: peer_data.protocol_version as u32,
|
||||||
PeerInfoDigest {
|
difficulty: peer_data.difficulty,
|
||||||
id: session_info.id.map(|id| id.hex()),
|
head: peer_data.latest_hash,
|
||||||
client_version: session_info.client_version,
|
}
|
||||||
capabilities: session_info.peer_capabilities.into_iter().map(|c| c.to_string()).collect(),
|
})
|
||||||
remote_address: session_info.remote_address,
|
|
||||||
local_address: session_info.local_address,
|
|
||||||
eth_version: peer_data.protocol_version as u32,
|
|
||||||
eth_difficulty: peer_data.difficulty,
|
|
||||||
eth_head: peer_data.latest_hash,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns transactions propagation statistics
|
/// Returns transactions propagation statistics
|
||||||
|
@ -75,7 +75,7 @@ mod api;
|
|||||||
pub use api::{
|
pub use api::{
|
||||||
EthSync, Params, SyncProvider, ManageNetwork, SyncConfig,
|
EthSync, Params, SyncProvider, ManageNetwork, SyncConfig,
|
||||||
ServiceConfiguration, NetworkConfiguration, PeerInfo, AllowIP, TransactionStats,
|
ServiceConfiguration, NetworkConfiguration, PeerInfo, AllowIP, TransactionStats,
|
||||||
LightSync, LightSyncParams,
|
LightSync, LightSyncParams, LesProtocolInfo, EthProtocolInfo,
|
||||||
};
|
};
|
||||||
pub use chain::{SyncStatus, SyncState};
|
pub use chain::{SyncStatus, SyncState};
|
||||||
pub use network::{is_valid_node_url, NonReservedPeerMode, NetworkError};
|
pub use network::{is_valid_node_url, NonReservedPeerMode, NetworkError};
|
||||||
|
@ -542,6 +542,20 @@ impl Host {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get all connected peers.
|
||||||
|
pub fn connected_peers(&self) -> Vec<PeerId> {
|
||||||
|
let sessions = self.sessions.read();
|
||||||
|
let sessions = &*sessions;
|
||||||
|
|
||||||
|
let mut peers = Vec::with_capacity(sessions.count());
|
||||||
|
for i in (0..MAX_SESSIONS).map(|x| x + FIRST_SESSION) {
|
||||||
|
if sessions.get(i).is_some() {
|
||||||
|
peers.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
peers
|
||||||
|
}
|
||||||
|
|
||||||
fn init_public_interface(&self, io: &IoContext<NetworkIoMessage>) -> Result<(), NetworkError> {
|
fn init_public_interface(&self, io: &IoContext<NetworkIoMessage>) -> Result<(), NetworkError> {
|
||||||
if self.info.read().public_endpoint.is_some() {
|
if self.info.read().public_endpoint.is_some() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use {NetworkProtocolHandler, NetworkConfiguration, NonReservedPeerMode};
|
use {NetworkProtocolHandler, NetworkConfiguration, NonReservedPeerMode};
|
||||||
use error::NetworkError;
|
use error::NetworkError;
|
||||||
use host::{Host, NetworkContext, NetworkIoMessage, ProtocolId};
|
use host::{Host, NetworkContext, NetworkIoMessage, PeerId, ProtocolId};
|
||||||
use stats::NetworkStats;
|
use stats::NetworkStats;
|
||||||
use io::*;
|
use io::*;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
@ -142,6 +142,11 @@ impl NetworkService {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a list of all connected peers by id.
|
||||||
|
pub fn connected_peers(&self) -> Vec<PeerId> {
|
||||||
|
self.host.read().as_ref().map(|h| h.connected_peers()).unwrap_or_else(Vec::new)
|
||||||
|
}
|
||||||
|
|
||||||
/// Try to add a reserved peer.
|
/// Try to add a reserved peer.
|
||||||
pub fn add_reserved_peer(&self, peer: &str) -> Result<(), NetworkError> {
|
pub fn add_reserved_peer(&self, peer: &str) -> Result<(), NetworkError> {
|
||||||
let host = self.host.read();
|
let host = self.host.read();
|
||||||
|
Loading…
Reference in New Issue
Block a user