diff --git a/consensus/src/sync/light/sync_requests.rs b/consensus/src/sync/light/sync_requests.rs index bf90bd2cc1..7d7d9733f4 100644 --- a/consensus/src/sync/light/sync_requests.rs +++ b/consensus/src/sync/light/sync_requests.rs @@ -24,7 +24,7 @@ use crate::{ sync::{EpochIds, PeerMacroRequests}, LightMacroSync, }, - syncer::MacroSync, + syncer::{MacroSync, MacroSyncReturn}, }, }; @@ -180,7 +180,7 @@ impl LightMacroSync { pub(crate) fn request_macro_headers( &mut self, mut epoch_ids: EpochIds, - ) -> Option { + ) -> Option> { // Read our current blockchain state. let (our_epoch_id, our_epoch_number, our_block_number) = { let blockchain = self.blockchain.read(); @@ -204,7 +204,7 @@ impl LightMacroSync { peer = %epoch_ids.sender, "Peer is behind" ); - return Some(epoch_ids.sender); + return Some(MacroSyncReturn::Outdated(epoch_ids.sender)); } else { // Check that the epoch_id sent by the peer at our current epoch number corresponds to // our accepted state. If it doesn't, the peer is on a "permanent" fork, so we ban it. @@ -219,7 +219,7 @@ impl LightMacroSync { peer = %epoch_ids.sender, "Peer is on a different chain" ); - return Some(epoch_ids.sender); + return Some(MacroSyncReturn::Outdated(epoch_ids.sender)); } epoch_ids.ids = epoch_ids @@ -236,6 +236,13 @@ impl LightMacroSync { } } + // After discarding all epoch_ids & checkpoint prior to our current state + // It could happen that we don't have anything new to learn from this peer + if epoch_ids.ids.is_empty() && epoch_ids.checkpoint.is_none() { + log::debug!("Nothing new to learn from this peer, emit it as good"); + return Some(MacroSyncReturn::Good(epoch_ids.sender)); + } + let mut peer_requests = PeerMacroRequests::new(); log::trace!(%epoch_ids.sender, diff --git a/consensus/src/sync/light/sync_stream.rs b/consensus/src/sync/light/sync_stream.rs index 3d1b5fab44..94c522b54a 100644 --- a/consensus/src/sync/light/sync_stream.rs +++ b/consensus/src/sync/light/sync_stream.rs @@ -261,9 +261,26 @@ impl LightMacroSync { } } - // If the macro header process deems a peer useless, it is returned here and we emit it. - if let Some(agent) = self.request_macro_headers(epoch_ids) { - return Poll::Ready(Some(MacroSyncReturn::Outdated(agent))); + // Request the macro headers from the peer or emit it accordingly + if let Some(macro_sync_return) = self.request_macro_headers(epoch_ids) { + match macro_sync_return { + MacroSyncReturn::Good(peer_id) => { + // We are synced with this peer. + debug!(?peer_id, "Finished macro syncing with peer"); + + if self.blockchain.read().can_enforce_validity_window() { + // We can enforce the validity window, so we are done. + return Poll::Ready(Some(MacroSyncReturn::Good(peer_id))); + } else { + #[cfg(feature = "full")] + self.start_validity_synchronization(peer_id); + } + } + _ => { + // Propagate any other sync result (outdated is the only one that can be emitted by the macro headers process) + return Poll::Ready(Some(macro_sync_return)); + } + } } }