@@ -4130,31 +4130,34 @@ fn locally_rejected_blocks_overriden_by_global_acceptance() {
4130
4130
vec ! [ ( sender_addr. clone( ) , ( send_amt + send_fee) * nmb_txs) ] ,
4131
4131
) ;
4132
4132
let http_origin = format ! ( "http://{}" , & signer_test. running_nodes. conf. node. rpc_bind) ;
4133
- let long_timeout = Duration :: from_secs ( 200 ) ;
4134
- let short_timeout = Duration :: from_secs ( 30 ) ;
4133
+ let long_timeout = 60 ;
4134
+ let short_timeout = 30 ;
4135
4135
signer_test. boot_to_epoch_3 ( ) ;
4136
+
4136
4137
info ! ( "------------------------- Test Mine Nakamoto Block N -------------------------" ) ;
4137
4138
let mined_blocks = signer_test. running_nodes . nakamoto_blocks_mined . clone ( ) ;
4138
4139
let info_before = signer_test
4139
4140
. stacks_client
4140
4141
. get_peer_info ( )
4141
4142
. expect ( "Failed to get peer info" ) ;
4142
- // submit a tx so that the miner will mine a stacks block
4143
+
4144
+ // submit a tx so that the miner will mine a stacks block N
4143
4145
let mut sender_nonce = 0 ;
4144
4146
let transfer_tx =
4145
4147
make_stacks_transfer ( & sender_sk, sender_nonce, send_fee, & recipient, send_amt) ;
4146
4148
let tx = submit_tx ( & http_origin, & transfer_tx) ;
4149
+ sender_nonce += 1 ;
4147
4150
info ! ( "Submitted tx {tx} in to mine block N" ) ;
4148
- wait_for ( short_timeout. as_secs ( ) , || {
4151
+
4152
+ wait_for ( short_timeout, || {
4149
4153
let info_after = signer_test
4150
4154
. stacks_client
4151
4155
. get_peer_info ( )
4152
4156
. expect ( "Failed to get peer info" ) ;
4153
4157
Ok ( info_after. stacks_tip_height > info_before. stacks_tip_height )
4154
4158
} )
4155
- . expect ( "Timed out waiting for block to be mined and processed" ) ;
4159
+ . expect ( "Timed out waiting for N to be mined and processed" ) ;
4156
4160
4157
- sender_nonce += 1 ;
4158
4161
let info_after = signer_test
4159
4162
. stacks_client
4160
4163
. get_peer_info ( )
@@ -4173,13 +4176,13 @@ fn locally_rejected_blocks_overriden_by_global_acceptance() {
4173
4176
. len ( ) ;
4174
4177
assert_eq ! ( nmb_signatures, num_signers) ;
4175
4178
4176
- // Ensure that the block was accepted globally so the stacks tip has not advanced to N
4179
+ // Ensure that the block was accepted globally so the stacks tip has advanced to N
4177
4180
let nakamoto_blocks = test_observer:: get_mined_nakamoto_blocks ( ) ;
4178
4181
let block_n = nakamoto_blocks. last ( ) . unwrap ( ) ;
4179
4182
assert_eq ! ( info_after. stacks_tip. to_string( ) , block_n. block_hash) ;
4180
4183
4181
4184
info ! ( "------------------------- Mine Nakamoto Block N+1 -------------------------" ) ;
4182
- // Make less than 30% of the signers reject the block to ensure it is marked globally accepted
4185
+ // Make less than 30% of the signers reject the block and ensure it is STILL marked globally accepted
4183
4186
let rejecting_signers: Vec < _ > = signer_test
4184
4187
. signer_stacks_private_keys
4185
4188
. iter ( )
@@ -4191,26 +4194,28 @@ fn locally_rejected_blocks_overriden_by_global_acceptance() {
4191
4194
. unwrap ( )
4192
4195
. replace ( rejecting_signers. clone ( ) ) ;
4193
4196
test_observer:: clear ( ) ;
4194
- let transfer_tx =
4195
- make_stacks_transfer ( & sender_sk, sender_nonce, send_fee, & recipient, send_amt) ;
4196
- let tx = submit_tx ( & http_origin, & transfer_tx) ;
4197
- sender_nonce += 1 ;
4198
- info ! ( "Submitted tx {tx} in to mine block N+1" ) ;
4199
- let start_time = Instant :: now ( ) ;
4197
+
4198
+ // submit a tx so that the miner will mine a stacks block N+1
4200
4199
let blocks_before = mined_blocks. load ( Ordering :: SeqCst ) ;
4201
4200
let info_before = signer_test
4202
4201
. stacks_client
4203
4202
. get_peer_info ( )
4204
4203
. expect ( "Failed to get peer info" ) ;
4205
- wait_for ( short_timeout. as_secs ( ) , || {
4204
+ let transfer_tx =
4205
+ make_stacks_transfer ( & sender_sk, sender_nonce, send_fee, & recipient, send_amt) ;
4206
+ let tx = submit_tx ( & http_origin, & transfer_tx) ;
4207
+ sender_nonce += 1 ;
4208
+ info ! ( "Submitted tx {tx} in to mine block N+1" ) ;
4209
+
4210
+ wait_for ( short_timeout, || {
4206
4211
let info_after = signer_test
4207
4212
. stacks_client
4208
4213
. get_peer_info ( )
4209
4214
. expect ( "Failed to get peer info" ) ;
4210
4215
Ok ( info_after. stacks_tip_height > info_before. stacks_tip_height )
4211
4216
} )
4212
4217
. expect ( "Timed out waiting for block to be mined and processed" ) ;
4213
- loop {
4218
+ wait_for ( long_timeout , || {
4214
4219
let stackerdb_events = test_observer:: get_stackerdb_chunks ( ) ;
4215
4220
let block_rejections = stackerdb_events
4216
4221
. into_iter ( )
@@ -4235,14 +4240,10 @@ fn locally_rejected_blocks_overriden_by_global_acceptance() {
4235
4240
}
4236
4241
} )
4237
4242
. collect :: < Vec < _ > > ( ) ;
4238
- if block_rejections. len ( ) == rejecting_signers. len ( ) {
4239
- break ;
4240
- }
4241
- assert ! (
4242
- start_time. elapsed( ) < long_timeout,
4243
- "FAIL: Test timed out while waiting for block proposal rejections" ,
4244
- ) ;
4245
- }
4243
+ Ok ( block_rejections. len ( ) == rejecting_signers. len ( ) )
4244
+ } )
4245
+ . expect ( "Timed out waiting for block proposal rejections" ) ;
4246
+
4246
4247
// Assert the block was mined
4247
4248
let info_after = signer_test
4248
4249
. stacks_client
@@ -4263,25 +4264,27 @@ fn locally_rejected_blocks_overriden_by_global_acceptance() {
4263
4264
. len ( ) ;
4264
4265
assert_eq ! ( nmb_signatures, num_signers - rejecting_signers. len( ) ) ;
4265
4266
4266
- // Ensure that the block was accepted globally so the stacks tip has advanced to N+1
4267
+ // Ensure that the block was still accepted globally so the stacks tip has advanced to N+1
4267
4268
let nakamoto_blocks = test_observer:: get_mined_nakamoto_blocks ( ) ;
4268
4269
let block_n_1 = nakamoto_blocks. last ( ) . unwrap ( ) ;
4269
4270
assert_eq ! ( info_after. stacks_tip. to_string( ) , block_n_1. block_hash) ;
4270
4271
assert_ne ! ( block_n_1, block_n) ;
4271
4272
4272
4273
info ! ( "------------------------- Test Mine Nakamoto Block N+2 -------------------------" ) ;
4274
+ // Ensure that all signers accept the block proposal N+2
4273
4275
let info_before = signer_test. stacks_client . get_peer_info ( ) . unwrap ( ) ;
4274
4276
let blocks_before = mined_blocks. load ( Ordering :: SeqCst ) ;
4275
4277
TEST_REJECT_ALL_BLOCK_PROPOSAL
4276
4278
. lock ( )
4277
4279
. unwrap ( )
4278
4280
. replace ( Vec :: new ( ) ) ;
4279
4281
4282
+ // submit a tx so that the miner will mine a stacks block N+2 and ensure ALL signers accept it
4280
4283
let transfer_tx =
4281
4284
make_stacks_transfer ( & sender_sk, sender_nonce, send_fee, & recipient, send_amt) ;
4282
4285
let tx = submit_tx ( & http_origin, & transfer_tx) ;
4283
4286
info ! ( "Submitted tx {tx} in to mine block N+2" ) ;
4284
- wait_for ( short_timeout. as_secs ( ) , || {
4287
+ wait_for ( short_timeout, || {
4285
4288
let info_after = signer_test
4286
4289
. stacks_client
4287
4290
. get_peer_info ( )
@@ -4297,20 +4300,35 @@ fn locally_rejected_blocks_overriden_by_global_acceptance() {
4297
4300
info_before. stacks_tip_height + 1 ,
4298
4301
info_after. stacks_tip_height,
4299
4302
) ;
4300
- let nmb_signatures = signer_test
4301
- . stacks_client
4302
- . get_tenure_tip ( & info_after. stacks_tip_consensus_hash )
4303
- . expect ( "Failed to get tip" )
4304
- . as_stacks_nakamoto ( )
4305
- . expect ( "Not a Nakamoto block" )
4306
- . signer_signature
4307
- . len ( ) ;
4308
- assert_eq ! ( nmb_signatures, num_signers) ;
4309
4303
// Ensure that the block was accepted globally so the stacks tip has advanced to N+2
4310
4304
let nakamoto_blocks = test_observer:: get_mined_nakamoto_blocks ( ) ;
4311
4305
let block_n_2 = nakamoto_blocks. last ( ) . unwrap ( ) ;
4312
4306
assert_eq ! ( info_after. stacks_tip. to_string( ) , block_n_2. block_hash) ;
4313
4307
assert_ne ! ( block_n_2, block_n_1) ;
4308
+
4309
+ // Make sure that ALL signers accepted the block proposal
4310
+ wait_for ( short_timeout, || {
4311
+ let signatures = test_observer:: get_stackerdb_chunks ( )
4312
+ . into_iter ( )
4313
+ . flat_map ( |chunk| chunk. modified_slots )
4314
+ . filter_map ( |chunk| {
4315
+ let message = SignerMessage :: consensus_deserialize ( & mut chunk. data . as_slice ( ) )
4316
+ . expect ( "Failed to deserialize SignerMessage" ) ;
4317
+ match message {
4318
+ SignerMessage :: BlockResponse ( BlockResponse :: Accepted ( ( hash, signature) ) ) => {
4319
+ if hash == block_n_2. signer_signature_hash {
4320
+ Some ( signature)
4321
+ } else {
4322
+ None
4323
+ }
4324
+ }
4325
+ _ => None ,
4326
+ }
4327
+ } )
4328
+ . collect :: < Vec < _ > > ( ) ;
4329
+ Ok ( signatures. len ( ) == num_signers)
4330
+ } )
4331
+ . expect ( "FAIL: Timed out waiting for block proposal acceptance by ALL signers" ) ;
4314
4332
}
4315
4333
4316
4334
#[ test]
@@ -4351,7 +4369,7 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4351
4369
vec ! [ ( sender_addr. clone( ) , ( send_amt + send_fee) * nmb_txs) ] ,
4352
4370
) ;
4353
4371
let http_origin = format ! ( "http://{}" , & signer_test. running_nodes. conf. node. rpc_bind) ;
4354
- let short_timeout = Duration :: from_secs ( 30 ) ;
4372
+ let short_timeout = 30 ;
4355
4373
signer_test. boot_to_epoch_3 ( ) ;
4356
4374
info ! ( "------------------------- Starting Tenure A -------------------------" ) ;
4357
4375
info ! ( "------------------------- Test Mine Nakamoto Block N -------------------------" ) ;
@@ -4360,13 +4378,15 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4360
4378
. stacks_client
4361
4379
. get_peer_info ( )
4362
4380
. expect ( "Failed to get peer info" ) ;
4381
+
4363
4382
// submit a tx so that the miner will mine a stacks block
4364
4383
let mut sender_nonce = 0 ;
4365
4384
let transfer_tx =
4366
4385
make_stacks_transfer ( & sender_sk, sender_nonce, send_fee, & recipient, send_amt) ;
4367
4386
let tx = submit_tx ( & http_origin, & transfer_tx) ;
4387
+ sender_nonce += 1 ;
4368
4388
info ! ( "Submitted tx {tx} in to mine block N" ) ;
4369
- wait_for ( short_timeout. as_secs ( ) , || {
4389
+ wait_for ( short_timeout, || {
4370
4390
let info_after = signer_test
4371
4391
. stacks_client
4372
4392
. get_peer_info ( )
@@ -4375,17 +4395,15 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4375
4395
} )
4376
4396
. expect ( "Timed out waiting for block to be mined and processed" ) ;
4377
4397
4378
- sender_nonce += 1 ;
4398
+ // Ensure that the block was accepted globally so the stacks tip has advanced to N
4379
4399
let info_after = signer_test
4380
4400
. stacks_client
4381
4401
. get_peer_info ( )
4382
4402
. expect ( "Failed to get peer info" ) ;
4383
-
4384
4403
assert_eq ! (
4385
4404
info_before. stacks_tip_height + 1 ,
4386
4405
info_after. stacks_tip_height
4387
4406
) ;
4388
-
4389
4407
let nakamoto_blocks = test_observer:: get_mined_nakamoto_blocks ( ) ;
4390
4408
let block_n = nakamoto_blocks. last ( ) . unwrap ( ) ;
4391
4409
assert_eq ! ( info_after. stacks_tip. to_string( ) , block_n. block_hash) ;
@@ -4404,16 +4422,19 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4404
4422
. replace ( ignoring_signers. clone ( ) ) ;
4405
4423
// Clear the stackerdb chunks
4406
4424
test_observer:: clear ( ) ;
4425
+
4426
+ // submit a tx so that the miner will ATTEMPT to mine a stacks block N+1
4407
4427
let transfer_tx =
4408
4428
make_stacks_transfer ( & sender_sk, sender_nonce, send_fee, & recipient, send_amt) ;
4409
4429
let tx = submit_tx ( & http_origin, & transfer_tx) ;
4430
+
4410
4431
info ! ( "Submitted tx {tx} in to attempt to mine block N+1" ) ;
4411
4432
let blocks_before = mined_blocks. load ( Ordering :: SeqCst ) ;
4412
4433
let info_before = signer_test
4413
4434
. stacks_client
4414
4435
. get_peer_info ( )
4415
4436
. expect ( "Failed to get peer info" ) ;
4416
- wait_for ( short_timeout. as_secs ( ) , || {
4437
+ wait_for ( short_timeout, || {
4417
4438
let ignored_signers = test_observer:: get_stackerdb_chunks ( )
4418
4439
. into_iter ( )
4419
4440
. flat_map ( |chunk| chunk. modified_slots )
@@ -4433,20 +4454,22 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4433
4454
Ok ( ignored_signers. len ( ) + ignoring_signers. len ( ) == num_signers)
4434
4455
} )
4435
4456
. expect ( "FAIL: Timed out waiting for block proposal acceptance" ) ;
4457
+
4436
4458
let blocks_after = mined_blocks. load ( Ordering :: SeqCst ) ;
4437
4459
let info_after = signer_test
4438
4460
. stacks_client
4439
4461
. get_peer_info ( )
4440
4462
. expect ( "Failed to get peer info" ) ;
4441
4463
assert_eq ! ( blocks_after, blocks_before) ;
4442
4464
assert_eq ! ( info_after, info_before) ;
4443
- // Ensure that the block was not accepted globally so the stacks tip has not advanced to N+1
4465
+ // Ensure that the block was NOT accepted globally so the stacks tip has NOT advanced to N+1
4444
4466
let nakamoto_blocks = test_observer:: get_mined_nakamoto_blocks ( ) ;
4445
4467
let block_n_1 = nakamoto_blocks. last ( ) . unwrap ( ) ;
4446
4468
assert_ne ! ( block_n_1, block_n) ;
4447
4469
assert_ne ! ( info_after. stacks_tip. to_string( ) , block_n_1. block_hash) ;
4448
4470
4449
4471
info ! ( "------------------------- Starting Tenure B -------------------------" ) ;
4472
+ // Start a new tenure and ensure the miner can propose a new block N+1' that is accepted by all signers
4450
4473
let commits_submitted = signer_test. running_nodes . commits_submitted . clone ( ) ;
4451
4474
let commits_before = commits_submitted. load ( Ordering :: SeqCst ) ;
4452
4475
next_block_and (
@@ -4458,23 +4481,19 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4458
4481
} ,
4459
4482
)
4460
4483
. unwrap ( ) ;
4484
+
4461
4485
info ! (
4462
4486
"------------------------- Mine Nakamoto Block N+1' in Tenure B -------------------------"
4463
4487
) ;
4464
- TEST_IGNORE_ALL_BLOCK_PROPOSALS
4465
- . lock ( )
4466
- . unwrap ( )
4467
- . replace ( Vec :: new ( ) ) ;
4468
4488
let info_before = signer_test
4469
4489
. stacks_client
4470
4490
. get_peer_info ( )
4471
4491
. expect ( "Failed to get peer info" ) ;
4472
- // submit a tx so that the miner will mine a stacks block
4473
- let transfer_tx =
4474
- make_stacks_transfer ( & sender_sk, sender_nonce, send_fee, & recipient, send_amt) ;
4475
- let tx = submit_tx ( & http_origin, & transfer_tx) ;
4476
- info ! ( "Submitted tx {tx} in to mine block N" ) ;
4477
- wait_for ( short_timeout. as_secs ( ) , || {
4492
+ TEST_IGNORE_ALL_BLOCK_PROPOSALS
4493
+ . lock ( )
4494
+ . unwrap ( )
4495
+ . replace ( Vec :: new ( ) ) ;
4496
+ wait_for ( short_timeout, || {
4478
4497
let info_after = signer_test
4479
4498
. stacks_client
4480
4499
. get_peer_info ( )
@@ -4491,15 +4510,6 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4491
4510
info_before. stacks_tip_height + 1 ,
4492
4511
info_after. stacks_tip_height
4493
4512
) ;
4494
- let nmb_signatures = signer_test
4495
- . stacks_client
4496
- . get_tenure_tip ( & info_after. stacks_tip_consensus_hash )
4497
- . expect ( "Failed to get tip" )
4498
- . as_stacks_nakamoto ( )
4499
- . expect ( "Not a Nakamoto block" )
4500
- . signer_signature
4501
- . len ( ) ;
4502
- assert_eq ! ( nmb_signatures, num_signers) ;
4503
4513
4504
4514
// Ensure that the block was accepted globally so the stacks tip has advanced to N+1'
4505
4515
let nakamoto_blocks = test_observer:: get_mined_nakamoto_blocks ( ) ;
@@ -4509,6 +4519,30 @@ fn reorg_locally_accepted_blocks_across_tenures_succeeds() {
4509
4519
block_n_1_prime. block_hash
4510
4520
) ;
4511
4521
assert_ne ! ( block_n_1_prime, block_n) ;
4522
+
4523
+ // Make sure that ALL signers accepted the block proposal even though they signed a conflicting one in prior tenure
4524
+ wait_for ( short_timeout, || {
4525
+ let signatures = test_observer:: get_stackerdb_chunks ( )
4526
+ . into_iter ( )
4527
+ . flat_map ( |chunk| chunk. modified_slots )
4528
+ . filter_map ( |chunk| {
4529
+ let message = SignerMessage :: consensus_deserialize ( & mut chunk. data . as_slice ( ) )
4530
+ . expect ( "Failed to deserialize SignerMessage" ) ;
4531
+ match message {
4532
+ SignerMessage :: BlockResponse ( BlockResponse :: Accepted ( ( hash, signature) ) ) => {
4533
+ if hash == block_n_1_prime. signer_signature_hash {
4534
+ Some ( signature)
4535
+ } else {
4536
+ None
4537
+ }
4538
+ }
4539
+ _ => None ,
4540
+ }
4541
+ } )
4542
+ . collect :: < Vec < _ > > ( ) ;
4543
+ Ok ( signatures. len ( ) == num_signers)
4544
+ } )
4545
+ . expect ( "FAIL: Timed out waiting for block proposal acceptance by ALL signers" ) ;
4512
4546
}
4513
4547
4514
4548
#[ test]
0 commit comments