mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-20 05:14:35 +00:00
Global Sync access (#994)
* Connect sync logic to network globals * Add further sync info to sync status * Build new syncing HTTP API methods * Fix bug in updating sync state * Highest slot is current slot * Update book for syncing API
This commit is contained in:
@@ -15,7 +15,7 @@ use types::EthSpec;
|
||||
mod peer_info;
|
||||
mod peerdb;
|
||||
|
||||
pub use peer_info::PeerInfo;
|
||||
pub use peer_info::{PeerInfo, PeerSyncStatus};
|
||||
/// The minimum reputation before a peer is disconnected.
|
||||
// Most likely this needs tweaking
|
||||
const MINIMUM_REPUTATION_BEFORE_BAN: Rep = 20;
|
||||
@@ -196,14 +196,14 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
|
||||
pub fn connect_ingoing(&mut self, peer_id: &PeerId) -> bool {
|
||||
self.update_reputations();
|
||||
let mut peerdb = self.network_globals.peers.write();
|
||||
peerdb.new_peer(peer_id);
|
||||
if !peerdb.connection_status(peer_id).is_banned() {
|
||||
peerdb.connect_ingoing(peer_id);
|
||||
// start a ping and status timer for the peer
|
||||
self.ping_peers.insert(peer_id.clone());
|
||||
self.status_peers.insert(peer_id.clone());
|
||||
|
||||
return true;
|
||||
}
|
||||
// start a ping and status timer for the peer
|
||||
self.ping_peers.insert(peer_id.clone());
|
||||
self.status_peers.insert(peer_id.clone());
|
||||
|
||||
false
|
||||
}
|
||||
@@ -213,14 +213,14 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
|
||||
pub fn connect_outgoing(&mut self, peer_id: &PeerId) -> bool {
|
||||
self.update_reputations();
|
||||
let mut peerdb = self.network_globals.peers.write();
|
||||
peerdb.new_peer(peer_id);
|
||||
if !peerdb.connection_status(peer_id).is_banned() {
|
||||
peerdb.connect_outgoing(peer_id);
|
||||
// start a ping and status timer for the peer
|
||||
self.ping_peers.insert(peer_id.clone());
|
||||
self.status_peers.insert(peer_id.clone());
|
||||
|
||||
return true;
|
||||
}
|
||||
// start a ping and status timer for the peer
|
||||
self.ping_peers.insert(peer_id.clone());
|
||||
self.status_peers.insert(peer_id.clone());
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::peerdb::{Rep, DEFAULT_REPUTATION};
|
||||
use crate::rpc::MetaData;
|
||||
use std::time::Instant;
|
||||
use types::{EthSpec, SubnetId};
|
||||
use types::{EthSpec, Slot, SubnetId};
|
||||
use PeerConnectionStatus::*;
|
||||
|
||||
/// Information about a given connected peer.
|
||||
@@ -17,7 +17,7 @@ pub struct PeerInfo<T: EthSpec> {
|
||||
pub connection_status: PeerConnectionStatus,
|
||||
/// The current syncing state of the peer. The state may be determined after it's initial
|
||||
/// connection.
|
||||
pub syncing_status: PeerSyncingStatus,
|
||||
pub sync_status: PeerSyncStatus,
|
||||
/// The ENR subnet bitfield of the peer. This may be determined after it's initial
|
||||
/// connection.
|
||||
pub meta_data: Option<MetaData<T>>,
|
||||
@@ -33,7 +33,7 @@ impl<TSpec: EthSpec> Default for PeerInfo<TSpec> {
|
||||
_version: vec![0],
|
||||
},
|
||||
connection_status: Default::default(),
|
||||
syncing_status: PeerSyncingStatus::Unknown,
|
||||
sync_status: PeerSyncStatus::Unknown,
|
||||
meta_data: None,
|
||||
}
|
||||
}
|
||||
@@ -98,14 +98,18 @@ pub enum PeerConnectionStatus {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PeerSyncingStatus {
|
||||
/// At the current state as our node.
|
||||
Synced,
|
||||
/// The peer is further ahead than our node and useful for block downloads.
|
||||
Ahead,
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum PeerSyncStatus {
|
||||
/// At the current state as our node or ahead of us.
|
||||
Synced {
|
||||
/// The last known head slot from the peer's handshake.
|
||||
status_head_slot: Slot,
|
||||
},
|
||||
/// Is behind our current head and not useful for block downloads.
|
||||
Behind,
|
||||
Behind {
|
||||
/// The last known head slot from the peer's handshake.
|
||||
status_head_slot: Slot,
|
||||
},
|
||||
/// Not currently known as a STATUS handshake has not occurred.
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::peer_info::{PeerConnectionStatus, PeerInfo};
|
||||
use super::peer_info::{PeerConnectionStatus, PeerInfo, PeerSyncStatus};
|
||||
use crate::rpc::methods::MetaData;
|
||||
use crate::PeerId;
|
||||
use slog::warn;
|
||||
use slog::{crit, warn};
|
||||
use std::collections::HashMap;
|
||||
use types::{EthSpec, SubnetId};
|
||||
|
||||
@@ -31,6 +31,9 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
peers: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
/// Gives the reputation of a peer, or DEFAULT_REPUTATION if it is unknown.
|
||||
pub fn reputation(&self, peer_id: &PeerId) -> Rep {
|
||||
self.peers
|
||||
@@ -53,6 +56,15 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
self.peers.get_mut(peer_id)
|
||||
}
|
||||
|
||||
/// Returns true if the peer is synced at least to our current head.
|
||||
pub fn peer_synced(&self, peer_id: &PeerId) -> bool {
|
||||
match self.peers.get(peer_id).map(|info| &info.sync_status) {
|
||||
Some(PeerSyncStatus::Synced { .. }) => true,
|
||||
Some(_) => false,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gives the ids of all known connected peers.
|
||||
pub fn connected_peers(&self) -> impl Iterator<Item = &PeerId> {
|
||||
self.peers
|
||||
@@ -61,6 +73,19 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
.map(|(peer_id, _)| peer_id)
|
||||
}
|
||||
|
||||
/// Gives the `peer_id` of all known connected and synced peers.
|
||||
pub fn synced_peers(&self) -> impl Iterator<Item = &PeerId> {
|
||||
self.peers
|
||||
.iter()
|
||||
.filter(|(_, info)| {
|
||||
if let PeerSyncStatus::Synced { .. } = info.sync_status {
|
||||
return info.connection_status.is_connected();
|
||||
}
|
||||
false
|
||||
})
|
||||
.map(|(peer_id, _)| peer_id)
|
||||
}
|
||||
|
||||
/// Gives an iterator of all peers on a given subnet.
|
||||
pub fn peers_on_subnet(&self, subnet_id: &SubnetId) -> impl Iterator<Item = &PeerId> {
|
||||
let subnet_id_filter = subnet_id.clone();
|
||||
@@ -115,6 +140,16 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
.map(|(id, _)| id)
|
||||
}
|
||||
|
||||
/// Gets the connection status of the peer.
|
||||
pub fn connection_status(&self, peer_id: &PeerId) -> PeerConnectionStatus {
|
||||
self.peer_info(peer_id)
|
||||
.map_or(PeerConnectionStatus::default(), |info| {
|
||||
info.connection_status.clone()
|
||||
})
|
||||
}
|
||||
|
||||
/* Setters */
|
||||
|
||||
/// Sets a peer as connected with an ingoing connection
|
||||
pub fn connect_ingoing(&mut self, peer_id: &PeerId) {
|
||||
let info = self
|
||||
@@ -128,15 +163,6 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
info.connection_status.connect_ingoing();
|
||||
}
|
||||
|
||||
/// Add the meta data of a peer.
|
||||
pub fn add_metadata(&mut self, peer_id: &PeerId, meta_data: MetaData<TSpec>) {
|
||||
if let Some(peer_info) = self.peers.get_mut(peer_id) {
|
||||
peer_info.meta_data = Some(meta_data);
|
||||
} else {
|
||||
warn!(self.log, "Tried to add meta data for a non-existant peer"; "peer_id" => format!("{}", peer_id));
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets a peer as connected with an outgoing connection
|
||||
pub fn connect_outgoing(&mut self, peer_id: &PeerId) {
|
||||
let info = self
|
||||
@@ -197,31 +223,35 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
info.connection_status.ban();
|
||||
}
|
||||
|
||||
/// Inserts a new peer with the default PeerInfo if it is not already present
|
||||
/// Returns if the peer was new to the PeerDB
|
||||
pub fn new_peer(&mut self, peer_id: &PeerId) -> bool {
|
||||
if !self.peers.contains_key(peer_id) {
|
||||
self.peers.insert(peer_id.clone(), Default::default());
|
||||
return true;
|
||||
/// Add the meta data of a peer.
|
||||
pub fn add_metadata(&mut self, peer_id: &PeerId, meta_data: MetaData<TSpec>) {
|
||||
if let Some(peer_info) = self.peers.get_mut(peer_id) {
|
||||
peer_info.meta_data = Some(meta_data);
|
||||
} else {
|
||||
warn!(self.log, "Tried to add meta data for a non-existant peer"; "peer_id" => format!("{}", peer_id));
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Sets the reputation of peer
|
||||
/// Sets the reputation of peer.
|
||||
pub fn set_reputation(&mut self, peer_id: &PeerId, rep: Rep) {
|
||||
let log_ref = &self.log;
|
||||
self.peers
|
||||
.entry(peer_id.clone())
|
||||
.or_insert_with(|| {
|
||||
warn!(log_ref, "Setting the reputation of an unknown peer";
|
||||
"peer_id" => format!("{:?}",peer_id));
|
||||
PeerInfo::default()
|
||||
})
|
||||
.reputation = rep;
|
||||
if let Some(peer_info) = self.peers.get_mut(peer_id) {
|
||||
peer_info.reputation = rep;
|
||||
} else {
|
||||
crit!(self.log, "Tried to modify reputation for an unknown peer"; "peer_id" => format!("{}",peer_id));
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the syncing status of a peer.
|
||||
pub fn set_sync_status(&mut self, peer_id: &PeerId, sync_status: PeerSyncStatus) {
|
||||
if let Some(peer_info) = self.peers.get_mut(peer_id) {
|
||||
peer_info.sync_status = sync_status;
|
||||
} else {
|
||||
crit!(self.log, "Tried to the sync status for an unknown peer"; "peer_id" => format!("{}",peer_id));
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds to a peer's reputation by `change`. If the reputation exceeds Rep's
|
||||
/// upper (lower) bounds, it stays at the maximum (minimum) value
|
||||
/// upper (lower) bounds, it stays at the maximum (minimum) value.
|
||||
pub fn add_reputation(&mut self, peer_id: &PeerId, change: Rep) {
|
||||
let log_ref = &self.log;
|
||||
let info = self.peers.entry(peer_id.clone()).or_insert_with(|| {
|
||||
@@ -231,13 +261,6 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
|
||||
});
|
||||
info.reputation = info.reputation.saturating_add(change);
|
||||
}
|
||||
|
||||
pub fn connection_status(&self, peer_id: &PeerId) -> PeerConnectionStatus {
|
||||
self.peer_info(peer_id)
|
||||
.map_or(PeerConnectionStatus::default(), |info| {
|
||||
info.connection_status.clone()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -355,9 +378,6 @@ mod tests {
|
||||
let p0 = PeerId::random();
|
||||
let p1 = PeerId::random();
|
||||
let p2 = PeerId::random();
|
||||
pdb.new_peer(&p0);
|
||||
pdb.new_peer(&p1);
|
||||
pdb.new_peer(&p2);
|
||||
pdb.connect_ingoing(&p0);
|
||||
pdb.connect_ingoing(&p1);
|
||||
pdb.connect_ingoing(&p2);
|
||||
@@ -378,9 +398,6 @@ mod tests {
|
||||
let p0 = PeerId::random();
|
||||
let p1 = PeerId::random();
|
||||
let p2 = PeerId::random();
|
||||
pdb.new_peer(&p0);
|
||||
pdb.new_peer(&p1);
|
||||
pdb.new_peer(&p2);
|
||||
pdb.connect_ingoing(&p0);
|
||||
pdb.connect_ingoing(&p1);
|
||||
pdb.connect_ingoing(&p2);
|
||||
@@ -401,7 +418,7 @@ mod tests {
|
||||
|
||||
let random_peer = PeerId::random();
|
||||
|
||||
pdb.new_peer(&random_peer);
|
||||
pdb.connect_ingoing(&random_peer);
|
||||
assert_eq!(pdb.n_dc, pdb.disconnected_peers().count());
|
||||
|
||||
pdb.connect_ingoing(&random_peer);
|
||||
|
||||
Reference in New Issue
Block a user