Skip to content

Commit b41846b

Browse files
committed
fix: restart inv sync if burnchain tip changes
1 parent cddf696 commit b41846b

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

stackslib/src/net/inv/nakamoto.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -397,13 +397,19 @@ impl NakamotoTenureInv {
397397
if self.start_sync_time + inv_sync_interval <= now
398398
&& (self.cur_reward_cycle >= cur_rc || !self.online)
399399
{
400-
debug!("Reset inv comms for {}", &self.neighbor_address);
401-
self.online = true;
402-
self.start_sync_time = now;
403-
self.cur_reward_cycle = start_rc;
400+
self.reset_comms(start_rc);
404401
}
405402
}
406403

404+
/// Reset synchronization state for this peer in the last reward cycle.
405+
/// Called as part of processing a new burnchain block
406+
pub fn reset_comms(&mut self, start_rc: u64) {
407+
debug!("Reset inv comms for {}", &self.neighbor_address);
408+
self.online = true;
409+
self.start_sync_time = get_epoch_time_secs();
410+
self.cur_reward_cycle = start_rc;
411+
}
412+
407413
/// Get the reward cycle we're sync'ing for
408414
pub fn reward_cycle(&self) -> u64 {
409415
self.cur_reward_cycle
@@ -506,6 +512,19 @@ impl NakamotoTenureInv {
506512
}
507513
}
508514
}
515+
516+
/// Get the burnchain tip reward cycle for purposes of inv sync
517+
fn get_current_reward_cycle(tip: &BlockSnapshot, sortdb: &SortitionDB) -> u64 {
518+
// NOTE: reward cycles start when (sortition_height % reward_cycle_len) == 1, not 0, but
519+
// .block_height_to_reward_cycle does not account for this.
520+
sortdb
521+
.pox_constants
522+
.block_height_to_reward_cycle(
523+
sortdb.first_block_height,
524+
tip.block_height.saturating_sub(1),
525+
)
526+
.expect("FATAL: snapshot occurred before system start")
527+
}
509528
}
510529

511530
/// Nakamoto inventory state machine
@@ -593,15 +612,7 @@ impl<NC: NeighborComms> NakamotoInvStateMachine<NC> {
593612
.map(|(highest_rc, _)| *highest_rc)
594613
.unwrap_or(0);
595614

596-
// NOTE: reward cycles start when (sortition_height % reward_cycle_len) == 1, not 0, but
597-
// .block_height_to_reward_cycle does not account for this.
598-
let tip_rc = sortdb
599-
.pox_constants
600-
.block_height_to_reward_cycle(
601-
sortdb.first_block_height,
602-
tip.block_height.saturating_sub(1),
603-
)
604-
.expect("FATAL: snapshot occurred before system start");
615+
let tip_rc = NakamotoTenureInv::get_current_reward_cycle(tip, sortdb);
605616

606617
debug!(
607618
"Load all reward cycle consensus hashes from {} to {}",
@@ -794,7 +805,20 @@ impl<NC: NeighborComms> NakamotoInvStateMachine<NC> {
794805
Ok((num_msgs, learned))
795806
}
796807

808+
/// Top-level state machine execution
797809
pub fn run(&mut self, network: &mut PeerNetwork, sortdb: &SortitionDB, ibd: bool) -> bool {
810+
// if the burnchain tip has changed, then force all communications to reset for the current
811+
// reward cycle in order to hasten block download
812+
if let Some(last_sort_tip) = self.last_sort_tip.as_ref() {
813+
if last_sort_tip.consensus_hash != network.burnchain_tip.consensus_hash {
814+
debug!("Forcibly restarting all Nakamoto inventory comms due to burnchain tip change ({} != {})", &last_sort_tip.consensus_hash, &network.burnchain_tip.consensus_hash);
815+
let tip_rc = NakamotoTenureInv::get_current_reward_cycle(&network.burnchain_tip, sortdb);
816+
for inv_state in self.inventories.values_mut() {
817+
inv_state.reset_comms(tip_rc.saturating_sub(1));
818+
}
819+
}
820+
}
821+
798822
if let Err(e) = self.process_getnakamotoinv_begins(network, sortdb, ibd) {
799823
warn!(
800824
"{:?}: Failed to begin Nakamoto tenure inventory sync: {:?}",

0 commit comments

Comments
 (0)