Files
lighthouse/beacon_node/network/src/sync/peer_sync_info.rs
Age Manning 1fe0ac72be Underflow and Typo (#6885)
I was looking at sync and noticed a potential underflow and a typo, so just fixed those whilst I was in there.
2025-01-30 06:22:59 +00:00

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
}
}
}
}