@@ -27,7 +27,9 @@ use libsigner::v0::messages::{
27
27
} ;
28
28
use libsigner:: { BlockProposal , SignerSession , StackerDBSession } ;
29
29
use stacks:: address:: AddressHashMode ;
30
+ use stacks:: burnchains:: Txid ;
30
31
use stacks:: chainstate:: burn:: db:: sortdb:: SortitionDB ;
32
+ use stacks:: chainstate:: burn:: operations:: LeaderBlockCommitOp ;
31
33
use stacks:: chainstate:: nakamoto:: { NakamotoBlock , NakamotoBlockHeader , NakamotoChainState } ;
32
34
use stacks:: chainstate:: stacks:: address:: PoxAddress ;
33
35
use stacks:: chainstate:: stacks:: boot:: MINERS_NAME ;
@@ -68,15 +70,16 @@ use crate::nakamoto_node::sign_coordinator::TEST_IGNORE_SIGNERS;
68
70
use crate :: neon:: Counters ;
69
71
use crate :: run_loop:: boot_nakamoto;
70
72
use crate :: tests:: nakamoto_integrations:: {
71
- boot_to_epoch_25, boot_to_epoch_3_reward_set, next_block_and, setup_epoch_3_reward_set,
72
- wait_for, POX_4_DEFAULT_STACKER_BALANCE , POX_4_DEFAULT_STACKER_STX_AMT ,
73
+ boot_to_epoch_25, boot_to_epoch_3_reward_set, next_block_and, next_block_and_controller,
74
+ setup_epoch_3_reward_set, wait_for, POX_4_DEFAULT_STACKER_BALANCE ,
75
+ POX_4_DEFAULT_STACKER_STX_AMT ,
73
76
} ;
74
77
use crate :: tests:: neon_integrations:: {
75
78
get_account, get_chain_info, get_chain_info_opt, next_block_and_wait,
76
79
run_until_burnchain_height, submit_tx, submit_tx_fallible, test_observer,
77
80
} ;
78
81
use crate :: tests:: { self , make_stacks_transfer} ;
79
- use crate :: { nakamoto_node, BurnchainController , Config , Keychain } ;
82
+ use crate :: { nakamoto_node, BitcoinRegtestController , BurnchainController , Config , Keychain } ;
80
83
81
84
impl SignerTest < SpawnedSigner > {
82
85
/// Run the test until the first epoch 2.5 reward cycle.
@@ -1221,6 +1224,33 @@ fn bitcoind_forking_test() {
1221
1224
let miner_address = Keychain :: default ( conf. node . seed . clone ( ) )
1222
1225
. origin_address ( conf. is_mainnet ( ) )
1223
1226
. unwrap ( ) ;
1227
+ let miner_pk = signer_test
1228
+ . running_nodes
1229
+ . btc_regtest_controller
1230
+ . get_mining_pubkey ( )
1231
+ . as_deref ( )
1232
+ . map ( Secp256k1PublicKey :: from_hex)
1233
+ . unwrap ( )
1234
+ . unwrap ( ) ;
1235
+
1236
+ let get_unconfirmed_commit_data = |btc_controller : & mut BitcoinRegtestController | {
1237
+ let unconfirmed_utxo = btc_controller
1238
+ . get_all_utxos ( & miner_pk)
1239
+ . into_iter ( )
1240
+ . find ( |utxo| utxo. confirmations == 0 ) ?;
1241
+ let unconfirmed_txid = Txid :: from_bitcoin_tx_hash ( & unconfirmed_utxo. txid ) ;
1242
+ let unconfirmed_tx = btc_controller. get_raw_transaction ( & unconfirmed_txid) ;
1243
+ let unconfirmed_tx_opreturn_bytes = unconfirmed_tx. output [ 0 ] . script_pubkey . as_bytes ( ) ;
1244
+ info ! (
1245
+ "Unconfirmed tx bytes: {}" ,
1246
+ stacks:: util:: hash:: to_hex( unconfirmed_tx_opreturn_bytes)
1247
+ ) ;
1248
+ let data = LeaderBlockCommitOp :: parse_data (
1249
+ & unconfirmed_tx_opreturn_bytes[ unconfirmed_tx_opreturn_bytes. len ( ) - 77 ..] ,
1250
+ )
1251
+ . unwrap ( ) ;
1252
+ Some ( data)
1253
+ } ;
1224
1254
1225
1255
signer_test. boot_to_epoch_3 ( ) ;
1226
1256
info ! ( "------------------------- Reached Epoch 3.0 -------------------------" ) ;
@@ -1252,23 +1282,43 @@ fn bitcoind_forking_test() {
1252
1282
. build_next_block ( 1 ) ;
1253
1283
1254
1284
info ! ( "Wait for block off of shallow fork" ) ;
1255
- thread:: sleep ( Duration :: from_secs ( 15 ) ) ;
1256
1285
1257
1286
// we need to mine some blocks to get back to being considered a frequent miner
1258
- for _i in 0 ..3 {
1287
+ for i in 0 ..3 {
1288
+ let current_burn_height = get_chain_info ( & signer_test. running_nodes . conf ) . burn_block_height ;
1289
+ info ! (
1290
+ "Mining block #{i} to be considered a frequent miner" ;
1291
+ "current_burn_height" => current_burn_height,
1292
+ ) ;
1259
1293
let commits_count = signer_test
1260
1294
. running_nodes
1261
1295
. commits_submitted
1262
1296
. load ( Ordering :: SeqCst ) ;
1263
- next_block_and (
1297
+ next_block_and_controller (
1264
1298
& mut signer_test. running_nodes . btc_regtest_controller ,
1265
1299
60 ,
1266
- || {
1267
- Ok ( signer_test
1300
+ |btc_controller | {
1301
+ let commits_submitted = signer_test
1268
1302
. running_nodes
1269
1303
. commits_submitted
1270
- . load ( Ordering :: SeqCst )
1271
- > commits_count)
1304
+ . load ( Ordering :: SeqCst ) ;
1305
+ if commits_submitted <= commits_count {
1306
+ // wait until a commit was submitted
1307
+ return Ok ( false )
1308
+ }
1309
+ let Some ( payload) = get_unconfirmed_commit_data ( btc_controller) else {
1310
+ warn ! ( "Commit submitted, but bitcoin doesn't see it in the unconfirmed UTXO set, will try to wait." ) ;
1311
+ return Ok ( false )
1312
+ } ;
1313
+ let burn_parent_modulus = payload. burn_parent_modulus ;
1314
+ let current_modulus = u8:: try_from ( ( current_burn_height + 1 ) % 5 ) . unwrap ( ) ;
1315
+ info ! (
1316
+ "Ongoing Commit Operation check" ;
1317
+ "burn_parent_modulus" => burn_parent_modulus,
1318
+ "current_modulus" => current_modulus,
1319
+ "payload" => ?payload,
1320
+ ) ;
1321
+ Ok ( burn_parent_modulus == current_modulus)
1272
1322
} ,
1273
1323
)
1274
1324
. unwrap ( ) ;
@@ -1306,24 +1356,44 @@ fn bitcoind_forking_test() {
1306
1356
. btc_regtest_controller
1307
1357
. build_next_block ( 4 ) ;
1308
1358
1309
- info ! ( "Wait for block off of shallow fork" ) ;
1310
- thread:: sleep ( Duration :: from_secs ( 15 ) ) ;
1359
+ info ! ( "Wait for block off of deep fork" ) ;
1311
1360
1312
1361
// we need to mine some blocks to get back to being considered a frequent miner
1313
- for _i in 0 ..3 {
1362
+ for i in 0 ..3 {
1363
+ let current_burn_height = get_chain_info ( & signer_test. running_nodes . conf ) . burn_block_height ;
1364
+ info ! (
1365
+ "Mining block #{i} to be considered a frequent miner" ;
1366
+ "current_burn_height" => current_burn_height,
1367
+ ) ;
1314
1368
let commits_count = signer_test
1315
1369
. running_nodes
1316
1370
. commits_submitted
1317
1371
. load ( Ordering :: SeqCst ) ;
1318
- next_block_and (
1372
+ next_block_and_controller (
1319
1373
& mut signer_test. running_nodes . btc_regtest_controller ,
1320
1374
60 ,
1321
- || {
1322
- Ok ( signer_test
1375
+ |btc_controller | {
1376
+ let commits_submitted = signer_test
1323
1377
. running_nodes
1324
1378
. commits_submitted
1325
- . load ( Ordering :: SeqCst )
1326
- > commits_count)
1379
+ . load ( Ordering :: SeqCst ) ;
1380
+ if commits_submitted <= commits_count {
1381
+ // wait until a commit was submitted
1382
+ return Ok ( false )
1383
+ }
1384
+ let Some ( payload) = get_unconfirmed_commit_data ( btc_controller) else {
1385
+ warn ! ( "Commit submitted, but bitcoin doesn't see it in the unconfirmed UTXO set, will try to wait." ) ;
1386
+ return Ok ( false )
1387
+ } ;
1388
+ let burn_parent_modulus = payload. burn_parent_modulus ;
1389
+ let current_modulus = u8:: try_from ( ( current_burn_height + 1 ) % 5 ) . unwrap ( ) ;
1390
+ info ! (
1391
+ "Ongoing Commit Operation check" ;
1392
+ "burn_parent_modulus" => burn_parent_modulus,
1393
+ "current_modulus" => current_modulus,
1394
+ "payload" => ?payload,
1395
+ ) ;
1396
+ Ok ( burn_parent_modulus == current_modulus)
1327
1397
} ,
1328
1398
)
1329
1399
. unwrap ( ) ;
@@ -1333,7 +1403,8 @@ fn bitcoind_forking_test() {
1333
1403
1334
1404
assert_eq ! ( post_fork_2_nonce, pre_fork_2_nonce - 4 * 2 ) ;
1335
1405
1336
- for _i in 0 ..5 {
1406
+ for i in 0 ..5 {
1407
+ info ! ( "Mining post-fork tenure {} of 5" , i + 1 ) ;
1337
1408
signer_test. mine_nakamoto_block ( Duration :: from_secs ( 30 ) ) ;
1338
1409
}
1339
1410
0 commit comments