@@ -44,6 +44,7 @@ use crate::chainstate::nakamoto::coordinator::load_nakamoto_reward_set;
44
44
use crate :: chainstate:: nakamoto:: miner:: NakamotoBlockBuilder ;
45
45
use crate :: chainstate:: nakamoto:: signer_set:: NakamotoSigners ;
46
46
use crate :: chainstate:: nakamoto:: test_signers:: TestSigners ;
47
+ use crate :: chainstate:: nakamoto:: test_stall:: * ;
47
48
use crate :: chainstate:: nakamoto:: tests:: get_account;
48
49
use crate :: chainstate:: nakamoto:: tests:: node:: TestStacker ;
49
50
use crate :: chainstate:: nakamoto:: {
@@ -2453,3 +2454,89 @@ pub fn simple_nakamoto_coordinator_10_extended_tenures_10_sortitions() -> TestPe
2453
2454
fn test_nakamoto_coordinator_10_tenures_and_extensions_10_blocks ( ) {
2454
2455
simple_nakamoto_coordinator_10_extended_tenures_10_sortitions ( ) ;
2455
2456
}
2457
+
2458
+ #[ test]
2459
+ fn process_next_nakamoto_block_deadlock ( ) {
2460
+ let private_key = StacksPrivateKey :: from_seed ( & [ 2 ] ) ;
2461
+ let addr = StacksAddress :: p2pkh ( false , & StacksPublicKey :: from_private ( & private_key) ) ;
2462
+
2463
+ let num_stackers: u32 = 4 ;
2464
+ let mut signing_key_seed = num_stackers. to_be_bytes ( ) . to_vec ( ) ;
2465
+ signing_key_seed. extend_from_slice ( & [ 1 , 1 , 1 , 1 ] ) ;
2466
+ let signing_key = StacksPrivateKey :: from_seed ( signing_key_seed. as_slice ( ) ) ;
2467
+ let test_stackers = ( 0 ..num_stackers)
2468
+ . map ( |index| TestStacker {
2469
+ signer_private_key : signing_key. clone ( ) ,
2470
+ stacker_private_key : StacksPrivateKey :: from_seed ( & index. to_be_bytes ( ) ) ,
2471
+ amount : u64:: MAX as u128 - 10000 ,
2472
+ pox_addr : Some ( PoxAddress :: Standard (
2473
+ StacksAddress :: new (
2474
+ C32_ADDRESS_VERSION_TESTNET_SINGLESIG ,
2475
+ Hash160 :: from_data ( & index. to_be_bytes ( ) ) ,
2476
+ ) ,
2477
+ Some ( AddressHashMode :: SerializeP2PKH ) ,
2478
+ ) ) ,
2479
+ max_amount : None ,
2480
+ } )
2481
+ . collect :: < Vec < _ > > ( ) ;
2482
+ let test_signers = TestSigners :: new ( vec ! [ signing_key] ) ;
2483
+ let mut pox_constants = TestPeerConfig :: default ( ) . burnchain . pox_constants ;
2484
+ pox_constants. reward_cycle_length = 10 ;
2485
+ pox_constants. v2_unlock_height = 21 ;
2486
+ pox_constants. pox_3_activation_height = 26 ;
2487
+ pox_constants. v3_unlock_height = 27 ;
2488
+ pox_constants. pox_4_activation_height = 28 ;
2489
+
2490
+ let mut boot_plan = NakamotoBootPlan :: new ( function_name ! ( ) )
2491
+ . with_test_stackers ( test_stackers. clone ( ) )
2492
+ . with_test_signers ( test_signers. clone ( ) )
2493
+ . with_private_key ( private_key) ;
2494
+ boot_plan. pox_constants = pox_constants;
2495
+
2496
+ info ! ( "Creating peer" ) ;
2497
+
2498
+ let mut peer = boot_plan. boot_into_nakamoto_peer ( vec ! [ ] , None ) ;
2499
+ let mut sortition_db = peer. sortdb ( ) . reopen ( ) . unwrap ( ) ;
2500
+ let ( chainstate, _) = & mut peer
2501
+ . stacks_node
2502
+ . as_mut ( )
2503
+ . unwrap ( )
2504
+ . chainstate
2505
+ . reopen ( )
2506
+ . unwrap ( ) ;
2507
+
2508
+ enable_process_block_stall ( ) ;
2509
+
2510
+ let miner_thread = std:: thread:: spawn ( move || {
2511
+ info ! ( " ------------------------------- MINING TENURE" ) ;
2512
+ let ( block, burn_height, ..) =
2513
+ peer. single_block_tenure ( & private_key, |_| { } , |_| { } , |_| true ) ;
2514
+ info ! ( " ------------------------------- TENURE MINED" ) ;
2515
+ } ) ;
2516
+
2517
+ // Wait a bit, to ensure the miner has reached the stall
2518
+ std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 10 ) ) ;
2519
+
2520
+ // Lock the sortdb
2521
+ info ! ( " ------------------------------- TRYING TO LOCK THE SORTDB" ) ;
2522
+ let sort_tx = sortition_db. tx_begin ( ) . unwrap ( ) ;
2523
+ info ! ( " ------------------------------- SORTDB LOCKED" ) ;
2524
+
2525
+ // Un-stall the block processing
2526
+ disable_process_block_stall ( ) ;
2527
+
2528
+ // Wait a bit, to ensure the tenure will have grabbed any locks it needs
2529
+ std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 10 ) ) ;
2530
+
2531
+ // Lock the chainstate db
2532
+ info ! ( " ------------------------------- TRYING TO LOCK THE CHAINSTATE" ) ;
2533
+ let chainstate_tx = chainstate. chainstate_tx_begin ( ) . unwrap ( ) ;
2534
+
2535
+ info ! ( " ------------------------------- SORTDB AND CHAINSTATE LOCKED" ) ;
2536
+ drop ( chainstate_tx) ;
2537
+ drop ( sort_tx) ;
2538
+ info ! ( " ------------------------------- MAIN THREAD FINISHED" ) ;
2539
+
2540
+ // Wait for the blocker and miner threads to finish
2541
+ miner_thread. join ( ) . unwrap ( ) ;
2542
+ }
0 commit comments