Skip to content

Commit a46b84c

Browse files
authored
Merge pull request #6065 from obycode/fix/mock-mining
fix: mock miner should continue mining throughout tenure
2 parents a1e0b25 + 864d098 commit a46b84c

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
1818
- Added index for `next_ready_nakamoto_block()` which improves block processing performance.
1919
- Added a new field, `parent_burn_block_hash`, to the payload that is included in the `/new_burn_block` event observer payload.
2020

21+
### Fixed
22+
23+
- Fix regression in mock-mining, allowing the mock miner to continue mining blocks throughout a tenure instead of failing after mining the tenure change block.
24+
2125
## [3.1.0.0.8]
2226

2327
### Added

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

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use stacks::net::api::poststackerdbchunk::StackerDBErrorCodes;
4545
use stacks::net::p2p::NetworkHandle;
4646
use stacks::net::stackerdb::StackerDBs;
4747
use stacks::net::{NakamotoBlocksData, StacksMessageType};
48+
use stacks::types::chainstate::BlockHeaderHash;
4849
use stacks::util::get_epoch_time_secs;
4950
use stacks::util::secp256k1::MessageSignature;
5051
#[cfg(test)]
@@ -187,8 +188,8 @@ pub struct BlockMinerThread {
187188
keychain: Keychain,
188189
/// burnchain configuration
189190
burnchain: Burnchain,
190-
/// Last block mined
191-
last_block_mined: Option<NakamotoBlock>,
191+
/// Consensus hash and header hash of the last block mined
192+
last_block_mined: Option<(ConsensusHash, BlockHeaderHash)>,
192193
/// Number of blocks mined since a tenure change/extend was attempted
193194
mined_blocks: u64,
194195
/// Cost consumed by the current tenure
@@ -742,7 +743,10 @@ impl BlockMinerThread {
742743
Self::fault_injection_block_announce_stall(&new_block);
743744
self.globals.coord().announce_new_stacks_block();
744745

745-
self.last_block_mined = Some(new_block);
746+
self.last_block_mined = Some((
747+
new_block.header.consensus_hash,
748+
new_block.header.block_hash(),
749+
));
746750
self.mined_blocks += 1;
747751
Ok(true)
748752
}
@@ -756,16 +760,24 @@ impl BlockMinerThread {
756760
&mut self,
757761
chain_state: &mut StacksChainState,
758762
) -> Result<(), NakamotoNodeError> {
759-
let Some(last_block_mined) = &self.last_block_mined else {
763+
let Some((last_consensus_hash, last_bhh)) = &self.last_block_mined else {
760764
return Ok(());
761765
};
766+
767+
// If mock-mining, we don't need to wait for the last block to be
768+
// processed (because it will never be). Instead just wait
769+
// `min_time_between_blocks_ms`, then resume mining.
770+
if self.config.node.mock_mining {
771+
thread::sleep(Duration::from_millis(
772+
self.config.miner.min_time_between_blocks_ms,
773+
));
774+
return Ok(());
775+
}
776+
762777
loop {
763778
let (_, processed, _, _) = chain_state
764779
.nakamoto_blocks_db()
765-
.get_block_processed_and_signed_weight(
766-
&last_block_mined.header.consensus_hash,
767-
&last_block_mined.header.block_hash(),
768-
)?
780+
.get_block_processed_and_signed_weight(last_consensus_hash, &last_bhh)?
769781
.ok_or_else(|| NakamotoNodeError::UnexpectedChainState)?;
770782

771783
// Once the block has been processed and the miner is no longer
@@ -1380,6 +1392,30 @@ impl BlockMinerThread {
13801392
return Err(NakamotoNodeError::ParentNotFound);
13811393
};
13821394

1395+
// If we're mock mining, we need to manipulate the `last_block_mined`
1396+
// to match what it should be based on the actual chainstate.
1397+
if self.config.node.mock_mining {
1398+
if let Some((last_block_consensus_hash, _)) = &self.last_block_mined {
1399+
// If the parent block is in the same tenure, then we should
1400+
// pretend that we mined it.
1401+
if last_block_consensus_hash
1402+
== &parent_block_info.stacks_parent_header.consensus_hash
1403+
{
1404+
self.last_block_mined = Some((
1405+
parent_block_info.stacks_parent_header.consensus_hash,
1406+
parent_block_info
1407+
.stacks_parent_header
1408+
.anchored_header
1409+
.block_hash(),
1410+
));
1411+
} else {
1412+
// If the parent block is not in the same tenure, then we
1413+
// should act as though we haven't mined anything yet.
1414+
self.last_block_mined = None;
1415+
}
1416+
}
1417+
}
1418+
13831419
// create our coinbase if this is the first block we've mined this tenure
13841420
let tenure_start_info = self.make_tenure_start_info(
13851421
&chain_state,

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9040,14 +9040,17 @@ fn mock_mining() {
90409040
let follower_node_info = get_chain_info(&follower_conf);
90419041
info!("Node heights"; "miner" => miner_node_info.stacks_tip_height, "follower" => follower_node_info.stacks_tip_height);
90429042

9043+
// Wait for at least 2 blocks to be mined by the mock-miner
9044+
// This is to ensure that the mock miner has mined the tenure change
9045+
// block and at least one interim block.
90439046
wait_for(60, || {
90449047
Ok(follower_naka_mined_blocks.load(Ordering::SeqCst)
9045-
> follower_naka_mined_blocks_before)
9048+
> follower_naka_mined_blocks_before + 1)
90469049
})
90479050
.unwrap_or_else(|_| {
90489051
panic!(
90499052
"Timed out waiting for mock miner block {}",
9050-
follower_naka_mined_blocks_before + 1
9053+
follower_naka_mined_blocks_before + 2
90519054
)
90529055
});
90539056

0 commit comments

Comments
 (0)