Update Syncing logic (#1042)

* Prevent duplicate parent block lookups

* Updates logic for handling re-status'd peers

* Allow block lookup if the block is close to head

* Correct ordering of sync logs

* Remove comments in block processer, clean up sim
This commit is contained in:
Age Manning
2020-04-22 23:58:10 +10:00
committed by GitHub
parent aacec7a4a7
commit 0b82e9f8a9
14 changed files with 386 additions and 201 deletions

View File

@@ -20,6 +20,6 @@ pub use config::Config as NetworkConfig;
pub use libp2p::gossipsub::{MessageId, Topic, TopicHash};
pub use libp2p::{multiaddr, Multiaddr};
pub use libp2p::{PeerId, Swarm};
pub use peer_manager::{PeerDB, PeerInfo, PeerSyncStatus};
pub use peer_manager::{PeerDB, PeerInfo, PeerSyncStatus, SyncInfo};
pub use rpc::RPCEvent;
pub use service::{Service, NETWORK_KEY_FILENAME};

View File

@@ -16,9 +16,11 @@ use types::EthSpec;
mod client;
mod peer_info;
mod peer_sync_status;
mod peerdb;
pub use peer_info::{PeerInfo, PeerSyncStatus};
pub use peer_info::PeerInfo;
pub use peer_sync_status::{PeerSyncStatus, SyncInfo};
/// The minimum reputation before a peer is disconnected.
// Most likely this needs tweaking
const _MINIMUM_REPUTATION_BEFORE_BAN: Rep = 20;

View File

@@ -1,5 +1,6 @@
use super::client::Client;
use super::peerdb::{Rep, DEFAULT_REPUTATION};
use super::PeerSyncStatus;
use crate::rpc::MetaData;
use crate::Multiaddr;
use serde::{
@@ -7,7 +8,7 @@ use serde::{
Serialize,
};
use std::time::Instant;
use types::{EthSpec, Slot, SubnetId};
use types::{EthSpec, SubnetId};
use PeerConnectionStatus::*;
/// Information about a given connected peer.
@@ -130,23 +131,6 @@ impl Serialize for PeerConnectionStatus {
}
}
#[derive(Clone, Debug, Serialize)]
/// The current sync status of the peer.
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 {
/// 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,
}
impl Default for PeerConnectionStatus {
fn default() -> Self {
PeerConnectionStatus::Dialing {

View File

@@ -0,0 +1,104 @@
//! Handles individual sync status for peers.
use serde::Serialize;
use types::{Epoch, Hash256, Slot};
#[derive(Clone, Debug, Serialize)]
/// The current sync status of the peer.
pub enum PeerSyncStatus {
/// At the current state as our node or ahead of us.
Synced { info: SyncInfo },
/// The peer has greater knowledge about the canonical chain than we do.
Advanced { info: SyncInfo },
/// Is behind our current head and not useful for block downloads.
Behind { info: SyncInfo },
/// Not currently known as a STATUS handshake has not occurred.
Unknown,
}
/// This is stored inside the PeerSyncStatus and is very similar to `PeerSyncInfo` in the
/// `Network` crate.
#[derive(Clone, Debug, Serialize)]
pub struct SyncInfo {
pub status_head_slot: Slot,
pub status_head_root: Hash256,
pub status_finalized_epoch: Epoch,
pub status_finalized_root: Hash256,
}
impl PeerSyncStatus {
/// Returns true if the peer has advanced knowledge of the chain.
pub fn is_advanced(&self) -> bool {
match self {
PeerSyncStatus::Advanced { .. } => true,
_ => false,
}
}
/// Returns true if the peer is up to date with the current chain.
pub fn is_synced(&self) -> bool {
match self {
PeerSyncStatus::Synced { .. } => true,
_ => false,
}
}
/// Returns true if the peer is behind the current chain.
pub fn is_behind(&self) -> bool {
match self {
PeerSyncStatus::Behind { .. } => true,
_ => false,
}
}
/// Updates the sync state given a fully synced peer.
/// Returns true if the state has changed.
pub fn update_synced(&mut self, info: SyncInfo) -> bool {
let new_state = PeerSyncStatus::Synced { info };
match self {
PeerSyncStatus::Synced { .. } => {
*self = new_state;
false // state was not updated
}
_ => {
*self = new_state;
true
}
}
}
/// Updates the sync state given a peer that is further ahead in the chain than us.
/// Returns true if the state has changed.
pub fn update_ahead(&mut self, info: SyncInfo) -> bool {
let new_state = PeerSyncStatus::Advanced { info };
match self {
PeerSyncStatus::Advanced { .. } => {
*self = new_state;
false // state was not updated
}
_ => {
*self = new_state;
true
}
}
}
/// Updates the sync state given a peer that is behind us in the chain.
/// Returns true if the state has changed.
pub fn update_behind(&mut self, info: SyncInfo) -> bool {
let new_state = PeerSyncStatus::Behind { info };
match self {
PeerSyncStatus::Behind { .. } => {
*self = new_state;
false // state was not updated
}
_ => {
*self = new_state;
true
}
}
}
}

View File

@@ -1,4 +1,5 @@
use super::peer_info::{PeerConnectionStatus, PeerInfo, PeerSyncStatus};
use super::peer_info::{PeerConnectionStatus, PeerInfo};
use super::peer_sync_status::PeerSyncStatus;
use crate::rpc::methods::MetaData;
use crate::PeerId;
use slog::{crit, warn};
@@ -101,7 +102,7 @@ impl<TSpec: EthSpec> PeerDB<TSpec> {
self.peers
.iter()
.filter(|(_, info)| {
if let PeerSyncStatus::Synced { .. } = info.sync_status {
if info.sync_status.is_synced() || info.sync_status.is_advanced() {
return info.connection_status.is_connected();
}
false