Skip to content

Commit c973bea

Browse files
committed
test(wip): add test to verify deadlock in process_next_nakamoto_block
1 parent e65ad15 commit c973bea

File tree

1 file changed

+72
-0
lines changed
  • stackslib/src/chainstate/nakamoto/coordinator

1 file changed

+72
-0
lines changed

stackslib/src/chainstate/nakamoto/coordinator/tests.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,3 +2453,75 @@ pub fn simple_nakamoto_coordinator_10_extended_tenures_10_sortitions() -> TestPe
24532453
fn test_nakamoto_coordinator_10_tenures_and_extensions_10_blocks() {
24542454
simple_nakamoto_coordinator_10_extended_tenures_10_sortitions();
24552455
}
2456+
2457+
#[test]
2458+
fn process_next_nakamoto_block_deadlock() {
2459+
let private_key = StacksPrivateKey::from_seed(&[2]);
2460+
let addr = StacksAddress::p2pkh(false, &StacksPublicKey::from_private(&private_key));
2461+
2462+
let num_stackers: u32 = 4;
2463+
let mut signing_key_seed = num_stackers.to_be_bytes().to_vec();
2464+
signing_key_seed.extend_from_slice(&[1, 1, 1, 1]);
2465+
let signing_key = StacksPrivateKey::from_seed(signing_key_seed.as_slice());
2466+
let test_stackers = (0..num_stackers)
2467+
.map(|index| TestStacker {
2468+
signer_private_key: signing_key.clone(),
2469+
stacker_private_key: StacksPrivateKey::from_seed(&index.to_be_bytes()),
2470+
amount: u64::MAX as u128 - 10000,
2471+
pox_addr: Some(PoxAddress::Standard(
2472+
StacksAddress::new(
2473+
C32_ADDRESS_VERSION_TESTNET_SINGLESIG,
2474+
Hash160::from_data(&index.to_be_bytes()),
2475+
),
2476+
Some(AddressHashMode::SerializeP2PKH),
2477+
)),
2478+
max_amount: None,
2479+
})
2480+
.collect::<Vec<_>>();
2481+
let test_signers = TestSigners::new(vec![signing_key]);
2482+
let mut pox_constants = TestPeerConfig::default().burnchain.pox_constants;
2483+
pox_constants.reward_cycle_length = 10;
2484+
pox_constants.v2_unlock_height = 21;
2485+
pox_constants.pox_3_activation_height = 26;
2486+
pox_constants.v3_unlock_height = 27;
2487+
pox_constants.pox_4_activation_height = 28;
2488+
2489+
let mut boot_plan = NakamotoBootPlan::new(function_name!())
2490+
.with_test_stackers(test_stackers.clone())
2491+
.with_test_signers(test_signers.clone())
2492+
.with_private_key(private_key);
2493+
boot_plan.pox_constants = pox_constants;
2494+
2495+
info!("Creating peer");
2496+
2497+
let mut peer = boot_plan.boot_into_nakamoto_peer(vec![], None);
2498+
2499+
// Lock the sortdb
2500+
info!(" ------------------------------- TRYING TO LOCK THE SORTDB");
2501+
let mut sortition_db = peer.sortdb().reopen().unwrap();
2502+
let sort_tx = sortition_db.tx_begin().unwrap();
2503+
2504+
// Start another thread that opens the sortdb, waits 10s, then tries to
2505+
// lock the chainstate db. This should cause a deadlock if the block
2506+
// processing is not acquiring the locks in the correct order.
2507+
info!(" ------------------------------- SPAWNING BLOCKER THREAD");
2508+
let blocker_thread = std::thread::spawn(move || {
2509+
// Wait a bit, to ensure the tenure will have grabbed any locks it needs
2510+
std::thread::sleep(std::time::Duration::from_secs(10));
2511+
2512+
// Lock the chainstate db
2513+
info!(" ------------------------------- TRYING TO LOCK THE CHAINSTATE");
2514+
let chainstate = &mut peer.stacks_node.as_mut().unwrap().chainstate;
2515+
let (chainstate_tx, _) = chainstate.chainstate_tx_begin().unwrap();
2516+
2517+
info!(" ------------------------------- SORTDB AND CHAINSTATE LOCKED");
2518+
info!(" ------------------------------- BLOCKER THREAD FINISHED");
2519+
});
2520+
2521+
info!(" ------------------------------- MINING TENURE");
2522+
let (block, burn_height, ..) = peer.single_block_tenure(&private_key, |_| {}, |_| {}, |_| true);
2523+
info!(" ------------------------------- TENURE MINED");
2524+
2525+
// Wait for the blocker thread to finish
2526+
blocker_thread.join().unwrap();
2527+
}

0 commit comments

Comments
 (0)