@@ -49,6 +49,7 @@ use tracing_subscriber::prelude::*;
49
49
use tracing_subscriber:: { fmt, EnvFilter } ;
50
50
use wsts:: curve:: point:: Point ;
51
51
use wsts:: curve:: scalar:: Scalar ;
52
+ use wsts:: net:: Message ;
52
53
use wsts:: state_machine:: { OperationResult , PublicKeys } ;
53
54
54
55
use crate :: config:: { Config as NeonConfig , EventKeyType , EventObserverConfig , InitialBalance } ;
@@ -59,7 +60,7 @@ use crate::tests::bitcoin_regtest::BitcoinCoreController;
59
60
use crate :: tests:: nakamoto_integrations:: {
60
61
boot_to_epoch_3_reward_set, boot_to_epoch_3_reward_set_calculation_boundary,
61
62
naka_neon_integration_conf, next_block_and, next_block_and_mine_commit,
62
- next_block_and_process_new_stacks_block , POX_4_DEFAULT_STACKER_BALANCE ,
63
+ POX_4_DEFAULT_STACKER_BALANCE ,
63
64
} ;
64
65
use crate :: tests:: neon_integrations:: {
65
66
next_block_and_wait, run_until_burnchain_height, test_observer, wait_for_runloop,
@@ -1136,7 +1137,8 @@ fn stackerdb_delayed_dkg() {
1136
1137
1137
1138
info ! ( "------------------------- Test Setup -------------------------" ) ;
1138
1139
let timeout = Duration :: from_secs ( 200 ) ;
1139
- let mut signer_test = SignerTest :: new ( 3 ) ;
1140
+ let num_signers = 3 ;
1141
+ let mut signer_test = SignerTest :: new ( num_signers) ;
1140
1142
boot_to_epoch_3_reward_set_calculation_boundary (
1141
1143
& signer_test. running_nodes . conf ,
1142
1144
& signer_test. running_nodes . blocks_processed ,
@@ -1150,7 +1152,22 @@ fn stackerdb_delayed_dkg() {
1150
1152
let ( _, coordinator_public_key) = coordinator_selector. get_coordinator ( ) ;
1151
1153
let coordinator_public_key =
1152
1154
StacksPublicKey :: from_slice ( coordinator_public_key. to_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
1153
-
1155
+ let signer_slot_ids: Vec < _ > = ( 0 ..num_signers)
1156
+ . into_iter ( )
1157
+ . map ( |i| SignerSlotID ( i as u32 ) )
1158
+ . collect ( ) ;
1159
+ let mut stackerdbs: Vec < _ > = signer_slot_ids
1160
+ . iter ( )
1161
+ . map ( |i| {
1162
+ StackerDB :: new (
1163
+ & signer_test. running_nodes . conf . node . rpc_bind ,
1164
+ StacksPrivateKey :: new ( ) , // Doesn't matter what key we use. We are just reading, not writing
1165
+ false ,
1166
+ reward_cycle,
1167
+ * i,
1168
+ )
1169
+ } )
1170
+ . collect ( ) ;
1154
1171
info ! ( "------------------------- Stop Signers -------------------------" ) ;
1155
1172
let mut to_stop = None ;
1156
1173
for ( idx, key) in signer_test. signer_stacks_private_keys . iter ( ) . enumerate ( ) {
@@ -1170,7 +1187,6 @@ fn stackerdb_delayed_dkg() {
1170
1187
signer_key,
1171
1188
signer_key. to_hex( )
1172
1189
) ;
1173
-
1174
1190
info ! ( "------------------------- Start DKG -------------------------" ) ;
1175
1191
info ! ( "Waiting for DKG to start..." ) ;
1176
1192
// Advance one more to trigger DKG
@@ -1180,26 +1196,81 @@ fn stackerdb_delayed_dkg() {
1180
1196
|| Ok ( true ) ,
1181
1197
)
1182
1198
. expect ( "Failed to mine bitcoin block" ) ;
1183
- // Wait a bit so DKG is actually triggered and signers are not available to respond
1184
- std:: thread:: sleep ( Duration :: from_secs ( 5 ) ) ;
1199
+ // Do not proceed until we guarantee that DKG was triggered
1200
+ let start_time = Instant :: now ( ) ;
1201
+ loop {
1202
+ let stackerdb = stackerdbs. first_mut ( ) . unwrap ( ) ;
1203
+ let dkg_packets: Vec < _ > = stackerdb
1204
+ . get_dkg_packets ( & signer_slot_ids)
1205
+ . expect ( "Failed to get dkg packets" ) ;
1206
+ let begin_packets: Vec < _ > = dkg_packets
1207
+ . iter ( )
1208
+ . filter_map ( |packet| {
1209
+ if matches ! ( packet. msg, Message :: DkgBegin ( _) ) {
1210
+ Some ( packet)
1211
+ } else {
1212
+ None
1213
+ }
1214
+ } )
1215
+ . collect ( ) ;
1216
+ if !begin_packets. is_empty ( ) {
1217
+ break ;
1218
+ }
1219
+ assert ! (
1220
+ start_time. elapsed( ) < Duration :: from_secs( 30 ) ,
1221
+ "Timed out waiting for DKG to be triggered"
1222
+ ) ;
1223
+ }
1185
1224
1186
1225
info ! ( "------------------------- Restart Stopped Signer -------------------------" ) ;
1187
1226
1188
1227
signer_test. restart_signer ( signer_idx, signer_key) ;
1189
1228
1190
1229
info ! ( "------------------------- Wait for DKG -------------------------" ) ;
1191
1230
let key = signer_test. wait_for_dkg ( timeout) ;
1192
- // Sleep a bit to make sure the transactions are broadcast.
1193
- std:: thread:: sleep ( Duration :: from_secs ( 10 ) ) ;
1194
- // Mine a block and make sure the votes were mined
1195
- next_block_and_process_new_stacks_block (
1196
- & mut signer_test. running_nodes . btc_regtest_controller ,
1197
- timeout. as_secs ( ) ,
1198
- & signer_test. running_nodes . coord_channel ,
1199
- )
1200
- . unwrap ( ) ;
1201
- // Sleep a bit to make sure the contract gets updated
1202
- std:: thread:: sleep ( Duration :: from_secs ( 5 ) ) ;
1231
+ let mut transactions = HashSet :: with_capacity ( num_signers) ;
1232
+ let start_time = Instant :: now ( ) ;
1233
+ while transactions. len ( ) < num_signers {
1234
+ for stackerdb in stackerdbs. iter_mut ( ) {
1235
+ let current_transactions = stackerdb
1236
+ . get_current_transactions ( )
1237
+ . expect ( "Failed getting current transactions for signer slot id" ) ;
1238
+ for tx in current_transactions {
1239
+ transactions. insert ( tx. txid ( ) ) ;
1240
+ }
1241
+ }
1242
+ assert ! (
1243
+ start_time. elapsed( ) < Duration :: from_secs( 30 ) ,
1244
+ "Failed to retrieve pending vote transactions within timeout"
1245
+ ) ;
1246
+ }
1247
+
1248
+ // Make sure transactions get mined
1249
+ let start_time = Instant :: now ( ) ;
1250
+ while !transactions. is_empty ( ) {
1251
+ assert ! (
1252
+ start_time. elapsed( ) < Duration :: from_secs( 30 ) ,
1253
+ "Failed to mine transactions within timeout"
1254
+ ) ;
1255
+ next_block_and_wait (
1256
+ & mut signer_test. running_nodes . btc_regtest_controller ,
1257
+ & signer_test. running_nodes . blocks_processed ,
1258
+ ) ;
1259
+ let blocks = test_observer:: get_blocks ( ) ;
1260
+ for block in blocks. iter ( ) {
1261
+ let txs = block. get ( "transactions" ) . unwrap ( ) . as_array ( ) . unwrap ( ) ;
1262
+ for tx in txs. iter ( ) {
1263
+ let raw_tx = tx. get ( "raw_tx" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ;
1264
+ if raw_tx == "0x00" {
1265
+ continue ;
1266
+ }
1267
+ let tx_bytes = hex_bytes ( & raw_tx[ 2 ..] ) . unwrap ( ) ;
1268
+ let parsed = StacksTransaction :: consensus_deserialize ( & mut & tx_bytes[ ..] ) . unwrap ( ) ;
1269
+ transactions. remove ( & parsed. txid ( ) ) ;
1270
+ }
1271
+ }
1272
+ }
1273
+
1203
1274
// Make sure DKG did get set
1204
1275
assert_eq ! (
1205
1276
key,
0 commit comments