Skip to content

Commit 6149710

Browse files
Fix: rename and cleanup submit_commit to ensure_commit and fix ordering issue in signers_Send_state_message_update
Signed-off-by: Jacinta Ferrant <236437600+jacinta-stacks@users.noreply.github.com>
1 parent dae48cf commit 6149710

File tree

7 files changed

+278
-338
lines changed

7 files changed

+278
-338
lines changed

stacks-node/src/tests/signer/commands/block_commit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ impl Command<SignerTestState, SignerTestContext> for MinerSubmitNakaBlockCommit
4949
.miners
5050
.lock()
5151
.unwrap()
52-
.submit_commit_miner_1(&sortdb),
52+
.ensure_commit_miner_1(&sortdb),
5353
2 => self
5454
.ctx
5555
.miners
5656
.lock()
5757
.unwrap()
58-
.submit_commit_miner_2(&sortdb),
58+
.ensure_commit_miner_2(&sortdb),
5959
_ => panic!(
6060
"Invalid miner index: {}. Expected 1 or 2.",
6161
self.miner_index

stacks-node/src/tests/signer/v0/mod.rs

Lines changed: 111 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,45 +1035,56 @@ impl MultipleMinerTest {
10351035
}
10361036

10371037
/// Ensures that miner 2 submits a commit pointing to the current view reported by the stacks node as expected
1038-
pub fn submit_commit_miner_2(&mut self, sortdb: &SortitionDB) {
1039-
if !self.rl2_counters.skip_commit_op.get() {
1040-
warn!("Miner 2's commit ops were not paused. This may result in no commit being submitted.");
1041-
}
1038+
/// Ensures that miner 2 has submitted a commit pointing to the current
1039+
/// view reported by the stacks node. Temporarily unpauses commits if
1040+
/// needed, waits until the commit counters reflect the current burn
1041+
/// height and stacks tip, then restores the previous pause state.
1042+
pub fn ensure_commit_miner_2(&mut self, sortdb: &SortitionDB) {
10421043
let burn_height = SortitionDB::get_canonical_burn_chain_tip(sortdb.conn())
10431044
.unwrap()
10441045
.block_height;
1045-
10461046
let stacks_height_before = self.get_peer_stacks_tip_height();
1047-
let rl2_commits_before = self
1048-
.rl2_counters
1049-
.naka_submitted_commits
1050-
.load(Ordering::SeqCst);
1051-
1052-
info!("Unpausing commits from RL2");
1053-
self.rl2_counters.skip_commit_op.set(false);
1047+
let was_paused = self.rl2_counters.skip_commit_op.get();
1048+
let commits_before = if was_paused {
1049+
info!("Unpausing commits from RL2");
1050+
Some(
1051+
self.rl2_counters
1052+
.naka_submitted_commits
1053+
.load(Ordering::SeqCst),
1054+
)
1055+
} else {
1056+
None
1057+
};
1058+
self.unpause_commits_miner_2();
10541059

1055-
info!("Waiting for commits from RL2");
1060+
info!("Waiting for RL2 commit at burn_height={burn_height}, stacks_height={stacks_height_before}");
10561061
wait_for(30, || {
1057-
Ok(self
1062+
let height_ok = self
10581063
.rl2_counters
1059-
.naka_submitted_commits
1064+
.naka_submitted_commit_last_burn_height
10601065
.load(Ordering::SeqCst)
1061-
> rl2_commits_before
1062-
&& self
1063-
.rl2_counters
1064-
.naka_submitted_commit_last_burn_height
1065-
.load(Ordering::SeqCst)
1066-
>= burn_height
1066+
>= burn_height
10671067
&& self
10681068
.rl2_counters
10691069
.naka_submitted_commit_last_stacks_tip
10701070
.load(Ordering::SeqCst)
1071-
>= stacks_height_before)
1071+
>= stacks_height_before;
1072+
let commit_incremented = commits_before
1073+
.map(|before| {
1074+
self.rl2_counters
1075+
.naka_submitted_commits
1076+
.load(Ordering::SeqCst)
1077+
> before
1078+
})
1079+
.unwrap_or(true);
1080+
Ok(height_ok && commit_incremented)
10721081
})
10731082
.expect("Timed out waiting for miner 2 to submit a commit op");
10741083

1075-
info!("Pausing commits from RL2");
1076-
self.rl2_counters.skip_commit_op.set(true);
1084+
if was_paused {
1085+
info!("Restoring paused state for RL2");
1086+
self.pause_commits_miner_2();
1087+
}
10771088
}
10781089

10791090
/// Pause miner 1's commits
@@ -1085,66 +1096,83 @@ impl MultipleMinerTest {
10851096
.set(true);
10861097
}
10871098

1099+
/// Unpause miner 1's commits
1100+
pub fn unpause_commits_miner_1(&mut self) {
1101+
self.signer_test
1102+
.running_nodes
1103+
.counters
1104+
.skip_commit_op
1105+
.set(false);
1106+
}
1107+
10881108
/// Pause miner 2's commits
10891109
pub fn pause_commits_miner_2(&mut self) {
10901110
self.rl2_counters.skip_commit_op.set(true);
10911111
}
10921112

1093-
/// Ensures that miner 1 submits a commit pointing to the current view reported by the stacks node as expected
1094-
pub fn submit_commit_miner_1(&mut self, sortdb: &SortitionDB) {
1095-
if !self.signer_test.running_nodes.counters.skip_commit_op.get() {
1096-
warn!("Miner 1's commit ops were not paused. This may result in no commit being submitted.");
1097-
}
1113+
/// Unpause miner 2's commits
1114+
pub fn unpause_commits_miner_2(&mut self) {
1115+
self.rl2_counters.skip_commit_op.set(false);
1116+
}
1117+
1118+
/// Ensures that miner 1 has submitted a commit pointing to the current
1119+
/// view reported by the stacks node. Temporarily unpauses commits if
1120+
/// needed, waits until the commit counters reflect the current burn
1121+
/// height and stacks tip, then restores the previous pause state.
1122+
pub fn ensure_commit_miner_1(&mut self, sortdb: &SortitionDB) {
10981123
let burn_height = SortitionDB::get_canonical_burn_chain_tip(sortdb.conn())
10991124
.unwrap()
11001125
.block_height;
11011126
let stacks_height_before = self.get_peer_stacks_tip_height();
1102-
let rl1_commits_before = self
1103-
.signer_test
1104-
.running_nodes
1105-
.counters
1106-
.naka_submitted_commits
1107-
.load(Ordering::SeqCst);
1108-
1109-
info!("Unpausing commits from RL1");
1110-
self.signer_test
1111-
.running_nodes
1112-
.counters
1113-
.skip_commit_op
1114-
.set(false);
1127+
let was_paused = self.signer_test.running_nodes.counters.skip_commit_op.get();
1128+
let commits_before = if was_paused {
1129+
info!("Unpausing commits from RL1");
1130+
Some(
1131+
self.signer_test
1132+
.running_nodes
1133+
.counters
1134+
.naka_submitted_commits
1135+
.load(Ordering::SeqCst),
1136+
)
1137+
} else {
1138+
None
1139+
};
1140+
self.unpause_commits_miner_1();
11151141

1116-
info!("Waiting for commits from RL1");
1142+
info!("Waiting for RL1 commit at burn_height={burn_height}, stacks_height={stacks_height_before}");
11171143
wait_for(30, || {
1118-
Ok(self
1144+
let height_ok = self
11191145
.signer_test
11201146
.running_nodes
11211147
.counters
1122-
.naka_submitted_commits
1148+
.naka_submitted_commit_last_burn_height
11231149
.load(Ordering::SeqCst)
1124-
> rl1_commits_before
1125-
&& self
1126-
.signer_test
1127-
.running_nodes
1128-
.counters
1129-
.naka_submitted_commit_last_burn_height
1130-
.load(Ordering::SeqCst)
1131-
>= burn_height
1150+
>= burn_height
11321151
&& self
11331152
.signer_test
11341153
.running_nodes
11351154
.counters
11361155
.naka_submitted_commit_last_stacks_tip
11371156
.load(Ordering::SeqCst)
1138-
>= stacks_height_before)
1157+
>= stacks_height_before;
1158+
let commit_incremented = commits_before
1159+
.map(|before| {
1160+
self.signer_test
1161+
.running_nodes
1162+
.counters
1163+
.naka_submitted_commits
1164+
.load(Ordering::SeqCst)
1165+
> before
1166+
})
1167+
.unwrap_or(true);
1168+
Ok(height_ok && commit_incremented)
11391169
})
11401170
.expect("Timed out waiting for miner 1 to submit a commit op");
11411171

1142-
info!("Pausing commits from RL1");
1143-
self.signer_test
1144-
.running_nodes
1145-
.counters
1146-
.skip_commit_op
1147-
.set(true);
1172+
if was_paused {
1173+
info!("Restoring paused state for RL1");
1174+
self.pause_commits_miner_1();
1175+
}
11481176
}
11491177

11501178
/// Shutdown the test harness
@@ -1257,12 +1285,14 @@ pub fn wait_for_block_proposal_block(
12571285

12581286
/// Returns all successfully deserialized (StackerDBChunkData, SignerMessage) pairs
12591287
/// from the test_observer stackerdb chunks, filtered to only include chunks from
1260-
/// signer contract IDs.
1288+
/// signer and miner contract IDs.
12611289
pub fn get_stackerdb_signer_messages() -> Vec<(StackerDBChunkData, SignerMessage)> {
12621290
test_observer::get_stackerdb_chunks()
12631291
.into_iter()
12641292
.filter(|event| {
1265-
event.contract_id.is_boot() && event.contract_id.name.starts_with(SIGNERS_NAME)
1293+
event.contract_id.is_boot()
1294+
&& (event.contract_id.name.starts_with(SIGNERS_NAME)
1295+
|| event.contract_id.name.starts_with(MINERS_NAME))
12661296
})
12671297
.flat_map(|chunk| chunk.modified_slots)
12681298
.filter_map(|chunk| {
@@ -6915,22 +6945,14 @@ fn signers_send_state_message_updates() {
69156945
},
69166946
);
69176947

6918-
let rl1_skip_commit_op = miners
6919-
.signer_test
6920-
.running_nodes
6921-
.counters
6922-
.skip_commit_op
6923-
.clone();
6924-
let rl2_skip_commit_op = miners.rl2_counters.skip_commit_op.clone();
6925-
69266948
let (conf_1, _) = miners.get_node_configs();
69276949
let (miner_pkh_1, miner_pkh_2) = miners.get_miner_public_key_hashes();
69286950
let (miner_pk_1, miner_pk_2) = miners.get_miner_public_keys();
69296951

69306952
info!("------------------------- Pause Miner 2's Block Commits -------------------------");
69316953

69326954
// Make sure Miner 2 cannot win a sortition at first.
6933-
rl2_skip_commit_op.set(true);
6955+
miners.pause_commits_miner_2();
69346956

69356957
miners.boot_to_epoch_3();
69366958

@@ -6950,11 +6972,10 @@ fn signers_send_state_message_updates() {
69506972
let starting_peer_height = get_chain_info(&conf_1).stacks_tip_height;
69516973
let starting_burn_height = get_burn_height();
69526974
let mut btc_blocks_mined = 0;
6953-
69546975
info!("------------------------- Pause Miner 1's Block Commit -------------------------");
69556976
// Make sure miner 1 doesn't submit any further block commits for the next tenure BEFORE mining the bitcoin block
6956-
rl1_skip_commit_op.set(true);
6957-
6977+
miners.ensure_commit_miner_1(&sortdb);
6978+
miners.pause_commits_miner_1();
69586979
info!("------------------------- Miner 1 Tenure Starts and Mines Block N-------------------------");
69596980
miners
69606981
.mine_bitcoin_block_and_tenure_change_tx(&sortdb, TenureChangeCause::BlockFound, 60)
@@ -6977,7 +6998,7 @@ fn signers_send_state_message_updates() {
69776998

69786999
info!("------------------------- Submit Miner 2 Block Commit -------------------------");
69797000
test_observer::clear();
6980-
miners.submit_commit_miner_2(&sortdb);
7001+
miners.ensure_commit_miner_2(&sortdb);
69817002

69827003
// Pause the block proposal broadcast so that miner 2 will be unable to broadcast its
69837004
// tenure change proposal BEFORE the block_proposal_timeout and will be marked invalid.
@@ -7010,9 +7031,6 @@ fn signers_send_state_message_updates() {
70107031
);
70117032
// Make sure that miner 2 gets marked invalid by not proposing a block BEFORE block_proposal_timeout
70127033
std::thread::sleep(block_proposal_timeout.add(Duration::from_secs(1)));
7013-
// Allow miner 2 to propose its late block and see the signer get marked malicious
7014-
TEST_BROADCAST_PROPOSAL_STALL.set(vec![miner_pk_1]);
7015-
70167034
info!("------------------------- Confirm Miner 1 is the Active Miner Again -------------------------");
70177035
wait_for_state_machine_update(
70187036
60,
@@ -7023,6 +7041,9 @@ fn signers_send_state_message_updates() {
70237041
)
70247042
.expect("Timed out waiting for signers to send their state update");
70257043

7044+
// Allow miner 2 to propose its late block and see the signer get marked malicious
7045+
TEST_BROADCAST_PROPOSAL_STALL.set(vec![miner_pk_1]);
7046+
70267047
info!(
70277048
"------------------------- Confirm Burn and Stacks Block Heights -------------------------"
70287049
);
@@ -7478,8 +7499,9 @@ fn miner_stackerdb_version_rollover() {
74787499
let sortdb = burnchain.open_sortition_db(true).unwrap();
74797500

74807501
info!("------------------------- Pause Miner 1's Block Commit -------------------------");
7481-
7482-
// Make sure miner 1 doesn't submit any further block commits for the next tenure BEFORE mining the bitcoin block
7502+
// Make sure the miner has submitted a commit for the latest burn block and also make sure it pauses
7503+
// before mining the bitcoin block so that the miner won't accidentally extend its tenure before we pause it.
7504+
miners.ensure_commit_miner_1(&sortdb);
74837505
miners.pause_commits_miner_1();
74847506

74857507
info!("------------------------- Miner 1 Wins Normal Tenure A -------------------------");
@@ -7519,31 +7541,31 @@ fn miner_stackerdb_version_rollover() {
75197541
let max_chunk = max_chunk.expect("Should have found a miner stackerdb message from Miner 1");
75207542

75217543
info!("------------------------- Miner 2 Wins Tenure B -------------------------");
7522-
miners.submit_commit_miner_2(&sortdb);
7544+
miners.ensure_commit_miner_2(&sortdb);
75237545

75247546
miners
75257547
.mine_bitcoin_block_and_tenure_change_tx(&sortdb, TenureChangeCause::BlockFound, 30)
75267548
.expect("Failed to mine BTC block");
75277549
verify_sortition_winner(&sortdb, &miner_pkh_2);
75287550

75297551
info!("------------------------- Miner 2 Wins Tenure C -------------------------");
7530-
miners.submit_commit_miner_2(&sortdb);
7552+
miners.ensure_commit_miner_2(&sortdb);
75317553

75327554
miners
75337555
.mine_bitcoin_block_and_tenure_change_tx(&sortdb, TenureChangeCause::BlockFound, 30)
75347556
.expect("Failed to mine BTC block");
75357557
verify_sortition_winner(&sortdb, &miner_pkh_2);
75367558

75377559
info!("------------------------- Miner 2 Wins Tenure D -------------------------");
7538-
miners.submit_commit_miner_2(&sortdb);
7560+
miners.ensure_commit_miner_2(&sortdb);
75397561

75407562
miners
75417563
.mine_bitcoin_block_and_tenure_change_tx(&sortdb, TenureChangeCause::BlockFound, 30)
75427564
.expect("Failed to mine BTC block");
75437565
verify_sortition_winner(&sortdb, &miner_pkh_2);
75447566

75457567
info!("----------------- Miner 1 Submits Block Commit ------------------");
7546-
miners.submit_commit_miner_1(&sortdb);
7568+
miners.ensure_commit_miner_1(&sortdb);
75477569

75487570
info!("------------------------- Miner 1 Wins Tenure E -------------------------");
75497571
miners
@@ -7865,7 +7887,7 @@ fn signer_loads_stackerdb_updates_on_startup() {
78657887
.expect("Not all signers accepted the block");
78667888

78677889
info!("------------------------- Miner B Wins Tenure B -------------------------");
7868-
miners.submit_commit_miner_2(&sortdb);
7890+
miners.ensure_commit_miner_2(&sortdb);
78697891
// Let's not mine anything until we see consensus on new tenure start.
78707892
TEST_MINE_SKIP.set(true);
78717893
miners.signer_test.mine_bitcoin_block();
@@ -8208,6 +8230,10 @@ fn burn_block_payload_includes_pox_transactions() {
82088230

82098231
info!("---- Starting test -----");
82108232

8233+
// Ensure both miners have submitted commits before mining the next BTC block
8234+
miners.ensure_commit_miner_1(&sortdb);
8235+
miners.ensure_commit_miner_2(&sortdb);
8236+
82118237
miners
82128238
.mine_bitcoin_blocks_and_confirm(&sortdb, 1, 30)
82138239
.expect("Failed to mine BTC block.");

0 commit comments

Comments
 (0)