-
Notifications
You must be signed in to change notification settings - Fork 937
Consistent logic to select range sync start_slot #8416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,16 @@ | ||
| use super::manager::SLOT_IMPORT_TOLERANCE; | ||
| use crate::status::ToStatusMessage; | ||
| use beacon_chain::{BeaconChain, BeaconChainTypes}; | ||
| use lighthouse_network::{SyncInfo, SyncStatus as PeerSyncStatus}; | ||
| use std::cmp::Ordering; | ||
| use types::{Epoch, EthSpec, Hash256, Slot}; | ||
|
|
||
| /// 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, | ||
| Advanced(PeerSyncTypeAdvanced), | ||
| /// A peer is behind in the sync and not useful to us for downloading blocks. | ||
| Behind, | ||
| } | ||
|
|
@@ -18,13 +20,52 @@ impl PeerSyncType { | |
| match self { | ||
| PeerSyncType::FullySynced => PeerSyncStatus::Synced { info: info.clone() }, | ||
| PeerSyncType::Behind => PeerSyncStatus::Behind { info: info.clone() }, | ||
| PeerSyncType::Advanced => PeerSyncStatus::Advanced { info: info.clone() }, | ||
| PeerSyncType::Advanced(_) => PeerSyncStatus::Advanced { info: info.clone() }, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub enum PeerSyncTypeAdvanced { | ||
| Finalized { | ||
| target_slot: Slot, | ||
| target_root: Hash256, | ||
| start_epoch: Epoch, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be per-peer? |
||
| }, | ||
| Head { | ||
| target_slot: Slot, | ||
| target_root: Hash256, | ||
| start_epoch: Epoch, | ||
| }, | ||
| } | ||
|
|
||
| #[derive(Clone)] | ||
| pub(crate) struct LocalSyncInfo { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs a comment |
||
| pub head_slot: Slot, | ||
| pub finalized_epoch: Epoch, | ||
| pub local_irreversible_epoch: Epoch, | ||
| } | ||
|
|
||
| impl LocalSyncInfo { | ||
| pub fn new<T: BeaconChainTypes>(chain: &BeaconChain<T>) -> Self { | ||
| let status = chain.status_message(); | ||
| // Max with the store in case the node has triggered manual finalization | ||
| let local_irreversible_epoch = std::cmp::max( | ||
| chain.head().finalized_checkpoint().epoch, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May as well use |
||
| chain | ||
| .store | ||
| .get_split_slot() | ||
| .epoch(T::EthSpec::slots_per_epoch()), | ||
| ); | ||
| Self { | ||
| head_slot: *status.head_slot(), | ||
| finalized_epoch: *status.finalized_epoch(), | ||
| local_irreversible_epoch, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub fn remote_sync_type<T: BeaconChainTypes>( | ||
| local: &SyncInfo, | ||
| local: &LocalSyncInfo, | ||
| remote: &SyncInfo, | ||
| chain: &BeaconChain<T>, | ||
| ) -> PeerSyncType { | ||
|
|
@@ -33,6 +74,10 @@ pub fn remote_sync_type<T: BeaconChainTypes>( | |
| let near_range_start = local.head_slot.saturating_sub(SLOT_IMPORT_TOLERANCE); | ||
| let near_range_end = local.head_slot.saturating_add(SLOT_IMPORT_TOLERANCE); | ||
|
|
||
| // With the remote peer's status message let's figure out if there are enough blocks to discover | ||
| // that we trigger sync from them. We don't want to sync any blocks from epochs prior to the | ||
| // local irreversible epoch. Our finalized epoch may be less than the local irreversible epoch. | ||
|
|
||
| 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 | ||
|
|
@@ -63,24 +108,55 @@ pub fn remote_sync_type<T: BeaconChainTypes>( | |
| { | ||
| // This peer has a head ahead enough of ours and we have no knowledge of their best | ||
| // block. | ||
| PeerSyncType::Advanced | ||
| PeerSyncType::Advanced(PeerSyncTypeAdvanced::Head { | ||
| target_root: remote.head_root, | ||
| target_slot: remote.head_slot, | ||
| start_epoch: local.local_irreversible_epoch, | ||
| }) | ||
| } 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 | ||
| if chain.block_is_known_to_fork_choice(&remote.head_root) { | ||
| // We have already synced up to this peer's head | ||
| PeerSyncType::FullySynced | ||
| } else { | ||
| PeerSyncType::Advanced | ||
| let finality_advanced = remote.finalized_epoch > local.finalized_epoch + 1; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A comment or a const for this |
||
| let head_advanced = remote.head_slot > near_range_end; | ||
| let finality_ahead_local_irreversible = | ||
| remote.finalized_epoch > local.local_irreversible_epoch; | ||
|
|
||
| if finality_advanced { | ||
| if finality_ahead_local_irreversible { | ||
| PeerSyncType::Advanced(PeerSyncTypeAdvanced::Finalized { | ||
| target_root: remote.finalized_root, | ||
| target_slot: remote | ||
| .finalized_epoch | ||
| .start_slot(T::EthSpec::slots_per_epoch()), | ||
| start_epoch: local.local_irreversible_epoch, | ||
| }) | ||
| } else if head_advanced { | ||
| PeerSyncType::Advanced(PeerSyncTypeAdvanced::Head { | ||
| target_root: remote.head_root, | ||
| target_slot: remote.head_slot, | ||
| start_epoch: local.local_irreversible_epoch, | ||
| }) | ||
| } else { | ||
| PeerSyncType::FullySynced | ||
| } | ||
| } else if head_advanced { | ||
| PeerSyncType::Advanced(PeerSyncTypeAdvanced::Head { | ||
| target_root: remote.head_root, | ||
| target_slot: remote.head_slot, | ||
| start_epoch: local.local_irreversible_epoch, | ||
| }) | ||
| } else { | ||
| // This peer is near enough to us to be considered synced | ||
| PeerSyncType::FullySynced | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs comment