Skip to content

Commit a9cb93a

Browse files
authored
Merge pull request #5206 from stacks-network/fix/5205
Fix/5205
2 parents aa27bda + d9c002c commit a9cb93a

File tree

3 files changed

+68
-85
lines changed

3 files changed

+68
-85
lines changed

stackslib/src/net/p2p.rs

Lines changed: 35 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3560,8 +3560,8 @@ impl PeerNetwork {
35603560
let prune = if cur_epoch.epoch_id >= StacksEpochId::Epoch30 {
35613561
debug!("{:?}: run Nakamoto work loop", self.get_local_peer());
35623562

3563-
// in Nakamoto epoch, so do Nakamoto things
3564-
let prune = self.do_network_work_nakamoto(
3563+
// in Nakamoto epoch, so we can always prune
3564+
self.do_network_work_nakamoto(
35653565
burnchain_height,
35663566
sortdb,
35673567
chainstate,
@@ -3593,9 +3593,10 @@ impl PeerNetwork {
35933593
"{:?}: ran Epoch 2.x work loop in Nakamoto epoch",
35943594
self.get_local_peer()
35953595
);
3596-
prune || epoch2_prune
3596+
epoch2_prune
35973597
} else {
3598-
prune
3598+
// we can always prune in Nakamoto, since all state machines pin their connections
3599+
true
35993600
}
36003601
} else {
36013602
// in epoch 2.x, so do epoch 2.x things
@@ -3623,89 +3624,41 @@ impl PeerNetwork {
36233624
chainstate: &mut StacksChainState,
36243625
ibd: bool,
36253626
network_result: &mut NetworkResult,
3626-
) -> bool {
3627-
// do some Actual Work(tm)
3628-
let mut do_prune = false;
3629-
let mut did_cycle = false;
3630-
3631-
while !did_cycle {
3632-
// always do an inv sync
3633-
let learned = self.do_network_inv_sync_nakamoto(sortdb, ibd);
3634-
debug!(
3635-
"{:?}: network work state is {:?}",
3636-
self.get_local_peer(),
3637-
&self.nakamoto_work_state;
3638-
"learned_new_blocks?" => learned
3639-
);
3640-
3641-
// always do block download
3642-
let new_blocks = self
3643-
.do_network_block_sync_nakamoto(burnchain_height, sortdb, chainstate, ibd)
3644-
.map_err(|e| {
3645-
warn!(
3646-
"{:?}: Failed to perform Nakamoto block sync: {:?}",
3647-
&self.get_local_peer(),
3648-
&e
3649-
);
3650-
e
3651-
})
3652-
.unwrap_or(HashMap::new());
3653-
3654-
network_result.consume_nakamoto_blocks(new_blocks);
3655-
3656-
let cur_state = self.nakamoto_work_state;
3657-
match self.nakamoto_work_state {
3658-
PeerNetworkWorkState::GetPublicIP => {
3659-
if cfg!(test) && self.connection_opts.disable_natpunch {
3660-
self.nakamoto_work_state = PeerNetworkWorkState::BlockDownload;
3661-
} else {
3662-
// (re)determine our public IP address
3663-
let done = self.do_get_public_ip();
3664-
if done {
3665-
self.nakamoto_work_state = PeerNetworkWorkState::BlockDownload;
3666-
}
3667-
}
3668-
}
3669-
PeerNetworkWorkState::BlockInvSync => {
3670-
// this state is useless in Nakamoto since we're always doing inv-syncs
3671-
self.nakamoto_work_state = PeerNetworkWorkState::BlockDownload;
3672-
}
3673-
PeerNetworkWorkState::BlockDownload => {
3674-
// this state is useless in Nakamoto since we're always doing download-syncs
3675-
self.nakamoto_work_state = PeerNetworkWorkState::AntiEntropy;
3676-
}
3677-
PeerNetworkWorkState::AntiEntropy => {
3678-
debug!(
3679-
"{:?}: Block anti-entropy for Nakamoto is not yet implemented",
3680-
self.get_local_peer()
3681-
);
3682-
self.nakamoto_work_state = PeerNetworkWorkState::Prune;
3683-
}
3684-
PeerNetworkWorkState::Prune => {
3685-
// did one pass
3686-
did_cycle = true;
3687-
do_prune = true;
3627+
) {
3628+
// always do an inv sync
3629+
let learned = self.do_network_inv_sync_nakamoto(sortdb, ibd);
3630+
debug!(
3631+
"{:?}: network work state is {:?}",
3632+
self.get_local_peer(),
3633+
&self.nakamoto_work_state;
3634+
"learned_new_blocks?" => learned
3635+
);
36883636

3689-
// restart
3690-
self.nakamoto_work_state = PeerNetworkWorkState::GetPublicIP;
3691-
}
3692-
}
3637+
// always do block download
3638+
let new_blocks = self
3639+
.do_network_block_sync_nakamoto(burnchain_height, sortdb, chainstate, ibd)
3640+
.map_err(|e| {
3641+
warn!(
3642+
"{:?}: Failed to perform Nakamoto block sync: {:?}",
3643+
&self.get_local_peer(),
3644+
&e
3645+
);
3646+
e
3647+
})
3648+
.unwrap_or(HashMap::new());
36933649

3694-
if self.nakamoto_work_state == cur_state {
3695-
// only break early if we can't make progress
3696-
break;
3697-
}
3698-
}
3650+
network_result.consume_nakamoto_blocks(new_blocks);
36993651

3700-
if did_cycle {
3701-
self.num_state_machine_passes += 1;
3702-
debug!(
3703-
"{:?}: Finished full p2p state-machine pass for Nakamoto ({})",
3704-
&self.local_peer, self.num_state_machine_passes
3705-
);
3652+
// make sure our public IP is fresh (this self-throttles if we recently learned it).
3653+
if !self.connection_opts.disable_natpunch {
3654+
self.do_get_public_ip();
37063655
}
37073656

3708-
do_prune
3657+
self.num_state_machine_passes += 1;
3658+
debug!(
3659+
"{:?}: Finished full p2p state-machine pass for Nakamoto ({})",
3660+
&self.local_peer, self.num_state_machine_passes
3661+
);
37093662
}
37103663

37113664
/// Do the actual work in the state machine.

testnet/stacks-node/src/nakamoto_node/miner.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ use crate::neon_node;
6060
use crate::run_loop::nakamoto::Globals;
6161
use crate::run_loop::RegisteredKey;
6262

63+
#[cfg(test)]
64+
pub static TEST_MINE_STALL: std::sync::Mutex<Option<bool>> = std::sync::Mutex::new(None);
6365
#[cfg(test)]
6466
pub static TEST_BROADCAST_STALL: std::sync::Mutex<Option<bool>> = std::sync::Mutex::new(None);
6567
#[cfg(test)]
@@ -291,6 +293,15 @@ impl BlockMinerThread {
291293
let mut attempts = 0;
292294
// now, actually run this tenure
293295
loop {
296+
#[cfg(test)]
297+
if *TEST_MINE_STALL.lock().unwrap() == Some(true) {
298+
// Do an extra check just so we don't log EVERY time.
299+
warn!("Mining is stalled due to testing directive");
300+
while *TEST_MINE_STALL.lock().unwrap() == Some(true) {
301+
std::thread::sleep(std::time::Duration::from_millis(10));
302+
}
303+
warn!("Mining is no longer stalled due to testing directive. Continuing...");
304+
}
294305
let new_block = loop {
295306
// If we're mock mining, we may not have processed the block that the
296307
// actual tenure winner committed to yet. So, before attempting to

testnet/stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ use wsts::net::Message;
9494

9595
use super::bitcoin_regtest::BitcoinCoreController;
9696
use crate::config::{EventKeyType, EventObserverConfig, InitialBalance};
97-
use crate::nakamoto_node::miner::{TEST_BLOCK_ANNOUNCE_STALL, TEST_BROADCAST_STALL};
97+
use crate::nakamoto_node::miner::{
98+
TEST_BLOCK_ANNOUNCE_STALL, TEST_BROADCAST_STALL, TEST_MINE_STALL,
99+
};
98100
use crate::neon::{Counters, RunLoopCounter};
99101
use crate::operations::BurnchainOpSigner;
100102
use crate::run_loop::boot_nakamoto;
@@ -5186,6 +5188,8 @@ fn clarity_burn_state() {
51865188
);
51875189
result.expect_result_ok().expect("Read-only call failed");
51885190

5191+
// Pause mining to prevent the stacks block from being mined before the tenure change is processed
5192+
TEST_MINE_STALL.lock().unwrap().replace(true);
51895193
// Submit a tx for the next block (the next block will be a new tenure, so the burn block height will increment)
51905194
let call_tx = tests::make_contract_call(
51915195
&sender_sk,
@@ -5201,8 +5205,23 @@ fn clarity_burn_state() {
52015205
}
52025206

52035207
let commits_before = commits_submitted.load(Ordering::SeqCst);
5204-
next_block_and_process_new_stacks_block(&mut btc_regtest_controller, 60, &coord_channel)
5205-
.unwrap();
5208+
let blocks_processed_before = coord_channel
5209+
.lock()
5210+
.expect("Mutex poisoned")
5211+
.get_stacks_blocks_processed();
5212+
next_block_and(&mut btc_regtest_controller, 60, || {
5213+
Ok(commits_submitted.load(Ordering::SeqCst) > commits_before)
5214+
})
5215+
.unwrap();
5216+
TEST_MINE_STALL.lock().unwrap().replace(false);
5217+
wait_for(20, || {
5218+
Ok(coord_channel
5219+
.lock()
5220+
.expect("Mutex poisoned")
5221+
.get_stacks_blocks_processed()
5222+
> blocks_processed_before)
5223+
})
5224+
.unwrap();
52065225

52075226
let info = get_chain_info(&naka_conf);
52085227
burn_block_height = info.burn_block_height as u128;

0 commit comments

Comments
 (0)