diff --git a/stackslib/src/net/mod.rs b/stackslib/src/net/mod.rs index 695574769c..18451cd7c4 100644 --- a/stackslib/src/net/mod.rs +++ b/stackslib/src/net/mod.rs @@ -3384,6 +3384,10 @@ pub mod test { let old_tip = self.network.stacks_tip.clone(); + // make sure the right state machines run + let epoch2_passes = self.network.epoch2_state_machine_passes; + let nakamoto_passes = self.network.nakamoto_state_machine_passes; + let ret = self.network.run( &indexer, &sortdb, @@ -3396,6 +3400,30 @@ pub mod test { &rpc_handler_args, ); + if self.network.get_current_epoch().epoch_id >= StacksEpochId::Epoch30 { + assert_eq!( + self.network.nakamoto_state_machine_passes, + nakamoto_passes + 1 + ); + let epoch2_expected_passes = if self.network.stacks_tip.is_nakamoto + && !self.network.connection_opts.force_nakamoto_epoch_transition + { + epoch2_passes + } else { + epoch2_passes + 1 + }; + assert_eq!( + self.network.epoch2_state_machine_passes, + epoch2_expected_passes + ); + } + if self + .network + .need_epoch2_state_machines(self.network.get_current_epoch().epoch_id) + { + assert_eq!(self.network.epoch2_state_machine_passes, epoch2_passes + 1); + } + self.sortdb = Some(sortdb); self.stacks_node = Some(stacks_node); self.mempool = Some(mempool); @@ -3467,6 +3495,10 @@ pub mod test { .unwrap_or(RPCHandlerArgsType::make_default()); let old_tip = self.network.stacks_tip.clone(); + // make sure the right state machines run + let epoch2_passes = self.network.epoch2_state_machine_passes; + let nakamoto_passes = self.network.nakamoto_state_machine_passes; + let ret = self.network.run( &indexer, &sortdb, @@ -3479,6 +3511,30 @@ pub mod test { &rpc_handler_args, ); + if self.network.get_current_epoch().epoch_id >= StacksEpochId::Epoch30 { + assert_eq!( + self.network.nakamoto_state_machine_passes, + nakamoto_passes + 1 + ); + let epoch2_expected_passes = if self.network.stacks_tip.is_nakamoto + && !self.network.connection_opts.force_nakamoto_epoch_transition + { + epoch2_passes + } else { + epoch2_passes + 1 + }; + assert_eq!( + self.network.epoch2_state_machine_passes, + epoch2_expected_passes + ); + } + if self + .network + .need_epoch2_state_machines(self.network.get_current_epoch().epoch_id) + { + assert_eq!(self.network.epoch2_state_machine_passes, epoch2_passes + 1); + } + self.sortdb = Some(sortdb); self.stacks_node = Some(stacks_node); self.mempool = Some(mempool); diff --git a/stackslib/src/net/p2p.rs b/stackslib/src/net/p2p.rs index fd8561326a..6e2e8ce461 100644 --- a/stackslib/src/net/p2p.rs +++ b/stackslib/src/net/p2p.rs @@ -423,6 +423,12 @@ pub struct PeerNetwork { // how many downloader passes have we done? pub num_downloader_passes: u64, + // number of epoch2 state machine passes + pub(crate) epoch2_state_machine_passes: u128, + + // number of nakamoto state machine passes + pub(crate) nakamoto_state_machine_passes: u128, + // to whom did we send a block or microblock stream as part of our anti-entropy protocol, and // when did we send it? antientropy_blocks: HashMap>, @@ -593,6 +599,8 @@ impl PeerNetwork { num_state_machine_passes: 0, num_inv_sync_passes: 0, num_downloader_passes: 0, + epoch2_state_machine_passes: 0, + nakamoto_state_machine_passes: 0, antientropy_blocks: HashMap::new(), antientropy_microblocks: HashMap::new(), @@ -3554,6 +3562,15 @@ impl PeerNetwork { } } + /// Check to see if we need to run the epoch 2.x state machines. + /// This will be true if we're either in epoch 2.5 or lower, OR, if we're in epoch 3.0 or + /// higher AND the Stacks tip is not yet a Nakamoto block. This latter condition indicates + /// that the epoch 2.x state machines are still needed to download the final epoch 2.x blocks. + pub(crate) fn need_epoch2_state_machines(&self, epoch_id: StacksEpochId) -> bool { + epoch_id < StacksEpochId::Epoch30 + || (epoch_id >= StacksEpochId::Epoch30 && !self.stacks_tip.is_nakamoto) + } + /// Do the actual work in the state machine. /// Return true if we need to prune connections. /// This will call the epoch-appropriate network worker @@ -3582,11 +3599,8 @@ impl PeerNetwork { // in Nakamoto epoch, but we might still be doing epoch 2.x things since Nakamoto does // not begin on a reward cycle boundary. - if cur_epoch.epoch_id == StacksEpochId::Epoch30 - && (self.burnchain_tip.block_height - <= cur_epoch.start_height - + u64::from(self.burnchain.pox_constants.reward_cycle_length) - || self.connection_opts.force_nakamoto_epoch_transition) + if self.need_epoch2_state_machines(cur_epoch.epoch_id) + || self.connection_opts.force_nakamoto_epoch_transition { debug!( "{:?}: run Epoch 2.x work loop in Nakamoto epoch", @@ -3636,6 +3650,8 @@ impl PeerNetwork { ibd: bool, network_result: &mut NetworkResult, ) { + self.nakamoto_state_machine_passes += 1; + // always do an inv sync let learned = self.do_network_inv_sync_nakamoto(sortdb, ibd); debug!( @@ -3683,6 +3699,8 @@ impl PeerNetwork { ibd: bool, network_result: &mut NetworkResult, ) -> bool { + self.epoch2_state_machine_passes += 1; + // do some Actual Work(tm) let mut do_prune = false; let mut did_cycle = false;