Skip to content

Commit c37babd

Browse files
authored
Merge pull request #5163 from stacks-network/fix/mock-mine-if-sortition-winner
Check if we are the sortition winner before attempting to mock sign
2 parents 6ee1aa9 + b7e29b0 commit c37babd

File tree

4 files changed

+274
-68
lines changed

4 files changed

+274
-68
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ jobs:
9494
- tests::signer::v0::bitcoind_forking_test
9595
- tests::signer::v0::multiple_miners
9696
- tests::signer::v0::mock_sign_epoch_25
97+
- tests::signer::v0::multiple_miners_mock_sign_epoch_25
9798
- tests::signer::v0::signer_set_rollover
9899
- tests::signer::v0::miner_forking
99100
- tests::signer::v0::reloads_signer_set_in

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,14 @@ impl SignCoordinator {
406406

407407
match miners_session.put_chunk(&chunk) {
408408
Ok(ack) => {
409-
debug!("Wrote message to stackerdb: {ack:?}");
410-
Ok(())
411-
}
412-
Err(e) => {
413-
warn!("Failed to write message to stackerdb {e:?}");
414-
Err("Failed to write message to stackerdb".into())
409+
if ack.accepted {
410+
debug!("Wrote message to stackerdb: {ack:?}");
411+
Ok(())
412+
} else {
413+
Err(format!("{ack:?}"))
414+
}
415415
}
416+
Err(e) => Err(format!("{e:?}")),
416417
}
417418
}
418419

testnet/stacks-node/src/neon_node.rs

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,17 +2340,12 @@ impl BlockMinerThread {
23402340
}
23412341

23422342
/// Read any mock signatures from stackerdb and respond to them
2343-
pub fn send_mock_miner_messages(&mut self) -> Result<(), ChainstateError> {
2344-
let miner_config = self.config.get_miner_config();
2345-
if !miner_config.pre_nakamoto_mock_signing {
2346-
debug!("Pre-Nakamoto mock signing is disabled");
2347-
return Ok(());
2348-
}
2349-
2343+
pub fn send_mock_miner_messages(&mut self) -> Result<(), String> {
23502344
let burn_db_path = self.config.get_burn_db_file_path();
23512345
let burn_db = SortitionDB::open(&burn_db_path, false, self.burnchain.pox_constants.clone())
23522346
.expect("FATAL: could not open sortition DB");
2353-
let epoch_id = SortitionDB::get_stacks_epoch(burn_db.conn(), self.burn_block.block_height)?
2347+
let epoch_id = SortitionDB::get_stacks_epoch(burn_db.conn(), self.burn_block.block_height)
2348+
.map_err(|e| e.to_string())?
23542349
.expect("FATAL: no epoch defined")
23552350
.epoch_id;
23562351
if epoch_id != StacksEpochId::Epoch25 {
@@ -2360,6 +2355,12 @@ impl BlockMinerThread {
23602355
return Ok(());
23612356
}
23622357

2358+
let miner_config = self.config.get_miner_config();
2359+
if !miner_config.pre_nakamoto_mock_signing {
2360+
debug!("Pre-Nakamoto mock signing is disabled");
2361+
return Ok(());
2362+
}
2363+
23632364
let mining_key = miner_config
23642365
.mining_key
23652366
.expect("Cannot mock sign without mining key");
@@ -2374,25 +2375,31 @@ impl BlockMinerThread {
23742375
}
23752376

23762377
// find out which slot we're in. If we are not the latest sortition winner, we should not be sending anymore messages anyway
2377-
let stackerdbs = StackerDBs::connect(&self.config.get_stacker_db_file_path(), false)?;
2378-
let (_, miners_info) =
2379-
NakamotoChainState::make_miners_stackerdb_config(&burn_db, &self.burn_block)?;
2380-
let idx = miners_info.get_latest_winner_index();
2381-
let sortitions = miners_info.get_sortitions();
2382-
let election_sortition = *sortitions
2383-
.get(idx as usize)
2384-
.expect("FATAL: latest winner index out of bounds");
2385-
2386-
let miner_contract_id = boot_code_id(MINERS_NAME, self.config.is_mainnet());
2387-
let mut miners_stackerdb =
2388-
StackerDBSession::new(&self.config.node.rpc_bind, miner_contract_id);
2389-
2378+
let ih = burn_db.index_handle(&self.burn_block.sortition_id);
2379+
let last_winner_snapshot = ih
2380+
.get_last_snapshot_with_sortition(self.burn_block.block_height)
2381+
.map_err(|e| e.to_string())?;
2382+
2383+
if last_winner_snapshot.miner_pk_hash
2384+
!= Some(Hash160::from_node_public_key(
2385+
&StacksPublicKey::from_private(&mining_key),
2386+
))
2387+
{
2388+
return Ok(());
2389+
}
2390+
let election_sortition = last_winner_snapshot.consensus_hash;
23902391
let mock_proposal =
23912392
MockProposal::new(peer_info, self.config.burnchain.chain_id, &mining_key);
23922393

23932394
info!("Sending mock proposal to stackerdb: {mock_proposal:?}");
23942395

2395-
if let Err(e) = SignCoordinator::send_miners_message(
2396+
let stackerdbs = StackerDBs::connect(&self.config.get_stacker_db_file_path(), false)
2397+
.map_err(|e| e.to_string())?;
2398+
let miner_contract_id = boot_code_id(MINERS_NAME, self.config.is_mainnet());
2399+
let mut miners_stackerdb =
2400+
StackerDBSession::new(&self.config.node.rpc_bind, miner_contract_id);
2401+
2402+
SignCoordinator::send_miners_message(
23962403
&mining_key,
23972404
&burn_db,
23982405
&self.burn_block,
@@ -2402,24 +2409,26 @@ impl BlockMinerThread {
24022409
self.config.is_mainnet(),
24032410
&mut miners_stackerdb,
24042411
&election_sortition,
2405-
) {
2406-
warn!("Failed to send mock proposal to stackerdb: {:?}", &e);
2407-
return Ok(());
2408-
}
2412+
)
2413+
.map_err(|e| {
2414+
warn!("Failed to write mock proposal to stackerdb.");
2415+
e
2416+
})?;
24092417

24102418
// Retrieve any MockSignatures from stackerdb
24112419
info!("Waiting for mock signatures...");
2412-
let mock_signatures =
2413-
self.wait_for_mock_signatures(&mock_proposal, &stackerdbs, Duration::from_secs(10))?;
2420+
let mock_signatures = self
2421+
.wait_for_mock_signatures(&mock_proposal, &stackerdbs, Duration::from_secs(10))
2422+
.map_err(|e| e.to_string())?;
24142423

24152424
let mock_block = MockBlock {
24162425
mock_proposal,
24172426
mock_signatures,
24182427
};
24192428

24202429
info!("Sending mock block to stackerdb: {mock_block:?}");
2421-
if let Err(e) = SignCoordinator::send_miners_message(
2422-
&miner_config.mining_key.expect("BUG: no mining key"),
2430+
SignCoordinator::send_miners_message(
2431+
&mining_key,
24232432
&burn_db,
24242433
&self.burn_block,
24252434
&stackerdbs,
@@ -2428,9 +2437,11 @@ impl BlockMinerThread {
24282437
self.config.is_mainnet(),
24292438
&mut miners_stackerdb,
24302439
&election_sortition,
2431-
) {
2432-
warn!("Failed to send mock block to stackerdb: {:?}", &e);
2433-
}
2440+
)
2441+
.map_err(|e| {
2442+
warn!("Failed to write mock block to stackerdb.");
2443+
e
2444+
})?;
24342445
Ok(())
24352446
}
24362447

@@ -3795,7 +3806,7 @@ impl RelayerThread {
37953806
}
37963807

37973808
let Some(mut miner_thread_state) =
3798-
self.create_block_miner(registered_key, last_burn_block, issue_timestamp_ms)
3809+
self.create_block_miner(registered_key, last_burn_block.clone(), issue_timestamp_ms)
37993810
else {
38003811
return false;
38013812
};

0 commit comments

Comments
 (0)