mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-11 04:31:51 +00:00
I was looking at sync and noticed a potential underflow and a typo, so just fixed those whilst I was in there.
88 lines
3.7 KiB
Rust
88 lines
3.7 KiB
Rust
use super::manager::SLOT_IMPORT_TOLERANCE;
|
|
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
|
use lighthouse_network::{SyncInfo, SyncStatus as PeerSyncStatus};
|
|
use std::cmp::Ordering;
|
|
|
|
/// The type of peer relative to our current state.
|
|
pub enum PeerSyncType {
|
|
/// The peer is on our chain and is fully synced with respect to our chain.
|
|
FullySynced,
|
|
/// The peer has a greater knowledge of the chain than us that warrants a full sync.
|
|
Advanced,
|
|
/// A peer is behind in the sync and not useful to us for downloading blocks.
|
|
Behind,
|
|
}
|
|
|
|
impl PeerSyncType {
|
|
pub fn as_sync_status(&self, info: &SyncInfo) -> PeerSyncStatus {
|
|
match self {
|
|
PeerSyncType::FullySynced => PeerSyncStatus::Synced { info: info.clone() },
|
|
PeerSyncType::Behind => PeerSyncStatus::Behind { info: info.clone() },
|
|
PeerSyncType::Advanced => PeerSyncStatus::Advanced { info: info.clone() },
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn remote_sync_type<T: BeaconChainTypes>(
|
|
local: &SyncInfo,
|
|
remote: &SyncInfo,
|
|
chain: &BeaconChain<T>,
|
|
) -> PeerSyncType {
|
|
// auxiliary variables for clarity: Inclusive boundaries of the range in which we consider a peer's
|
|
// head "near" ours.
|
|
let near_range_start = local.head_slot.saturating_sub(SLOT_IMPORT_TOLERANCE);
|
|
let near_range_end = local.head_slot.saturating_add(SLOT_IMPORT_TOLERANCE);
|
|
|
|
match remote.finalized_epoch.cmp(&local.finalized_epoch) {
|
|
Ordering::Less => {
|
|
// The node has a lower finalized epoch, their chain is not useful to us. There are two
|
|
// cases where a node can have a lower finalized epoch:
|
|
//
|
|
// ## The node is on the same chain
|
|
//
|
|
// If a node is on the same chain but has a lower finalized epoch, their head must be
|
|
// lower than ours. Therefore, we have nothing to request from them.
|
|
//
|
|
// ## The node is on a fork
|
|
//
|
|
// If a node is on a fork that has a lower finalized epoch, switching to that fork would
|
|
// cause us to revert a finalized block. This is not permitted, therefore we have no
|
|
// interest in their blocks.
|
|
//
|
|
// We keep these peers to allow them to sync from us.
|
|
PeerSyncType::Behind
|
|
}
|
|
Ordering::Equal => {
|
|
// NOTE: if a peer has our same `finalized_epoch` with a different `finalized_root`
|
|
// they are not considered relevant and won't be propagated to sync.
|
|
// Check if the peer is the peer is inside the tolerance range to be considered synced.
|
|
if remote.head_slot < near_range_start {
|
|
PeerSyncType::Behind
|
|
} else if remote.head_slot > near_range_end
|
|
&& !chain.block_is_known_to_fork_choice(&remote.head_root)
|
|
{
|
|
// This peer has a head ahead enough of ours and we have no knowledge of their best
|
|
// block.
|
|
PeerSyncType::Advanced
|
|
} else {
|
|
// This peer is either in the tolerance range, or ahead us with an already rejected
|
|
// block.
|
|
PeerSyncType::FullySynced
|
|
}
|
|
}
|
|
Ordering::Greater => {
|
|
if (local.finalized_epoch + 1 == remote.finalized_epoch
|
|
&& near_range_start <= remote.head_slot
|
|
&& remote.head_slot <= near_range_end)
|
|
|| chain.block_is_known_to_fork_choice(&remote.head_root)
|
|
{
|
|
// This peer is near enough to us to be considered synced, or
|
|
// we have already synced up to this peer's head
|
|
PeerSyncType::FullySynced
|
|
} else {
|
|
PeerSyncType::Advanced
|
|
}
|
|
}
|
|
}
|
|
}
|