Skip to content

Commit

Permalink
Merge pull request #4926 from stacks-network/feat/retry-on-timeout
Browse files Browse the repository at this point in the history
feat: make miner retry when signature collection times out
  • Loading branch information
obycode authored Jul 2, 2024
2 parents 8638abb + 33a5627 commit 9dd8c81
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 7 deletions.
8 changes: 2 additions & 6 deletions testnet/stacks-node/src/nakamoto_node/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,8 @@ impl BlockMinerThread {
) {
Ok(x) => x,
Err(e) => {
error!(
"Unrecoverable error while gathering signatures: {e:?}. Ending tenure."
);
return Err(NakamotoNodeError::MiningFailure(
ChainstateError::MinerAborted,
));
error!("Error while gathering signatures: {e:?}. Will try mining again.");
continue;
}
};

Expand Down
1 change: 1 addition & 0 deletions testnet/stacks-node/src/tests/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
// That's the kind of thing an idiot would have on his luggage!
let password = "12345";
naka_conf.connection_options.block_proposal_token = Some(password.to_string());
naka_conf.miner.wait_on_signers = Duration::from_secs(10);

let run_stamp = rand::random();

Expand Down
90 changes: 89 additions & 1 deletion testnet/stacks-node/src/tests/signer/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ fn end_of_tenure() {

signer_test.boot_to_epoch_3();

// signer_test.mine_and_verify_confirmed_naka_block(Duration::from_secs(30), num_signers);
signer_test.mine_nakamoto_block(Duration::from_secs(30));

TEST_VALIDATE_STALL.lock().unwrap().replace(true);
Expand Down Expand Up @@ -518,3 +517,92 @@ fn end_of_tenure() {

signer_test.shutdown();
}

#[test]
#[ignore]
/// This test checks that the miner will retry when signature collection times out.
fn retry_on_timeout() {
if env::var("BITCOIND_TEST") != Ok("1".into()) {
return;
}

tracing_subscriber::registry()
.with(fmt::layer())
.with(EnvFilter::from_default_env())
.init();

info!("------------------------- Test Setup -------------------------");
let num_signers = 5;
let sender_sk = Secp256k1PrivateKey::new();
let sender_addr = tests::to_addr(&sender_sk);
let send_amt = 100;
let send_fee = 180;
let recipient = PrincipalData::from(StacksAddress::burn_address(false));
let mut signer_test: SignerTest<SpawnedSigner> = SignerTest::new(
num_signers,
vec![(sender_addr.clone(), send_amt + send_fee)],
);
let http_origin = format!("http://{}", &signer_test.running_nodes.conf.node.rpc_bind);

signer_test.boot_to_epoch_3();

signer_test.mine_nakamoto_block(Duration::from_secs(30));

// Stall block validation so the signers will not be able to sign.
TEST_VALIDATE_STALL.lock().unwrap().replace(true);

let proposals_before = signer_test
.running_nodes
.nakamoto_blocks_proposed
.load(Ordering::SeqCst);
let blocks_before = signer_test
.running_nodes
.nakamoto_blocks_mined
.load(Ordering::SeqCst);

// submit a tx so that the miner will mine a block
let sender_nonce = 0;
let transfer_tx =
make_stacks_transfer(&sender_sk, sender_nonce, send_fee, &recipient, send_amt);
submit_tx(&http_origin, &transfer_tx);

info!("Submitted transfer tx and waiting for block proposal");
loop {
let blocks_proposed = signer_test
.running_nodes
.nakamoto_blocks_proposed
.load(Ordering::SeqCst);
if blocks_proposed > proposals_before {
break;
}
std::thread::sleep(Duration::from_millis(100));
}

info!("Block proposed, verifying that it is not processed");

// Wait 20 seconds to be sure that the timeout has occurred
std::thread::sleep(Duration::from_secs(20));
assert_eq!(
signer_test
.running_nodes
.nakamoto_blocks_mined
.load(Ordering::SeqCst),
blocks_before
);

// Disable the stall and wait for the block to be processed on retry
info!("Disable the stall and wait for the block to be processed");
TEST_VALIDATE_STALL.lock().unwrap().replace(false);
loop {
let blocks_mined = signer_test
.running_nodes
.nakamoto_blocks_mined
.load(Ordering::SeqCst);
if blocks_mined > blocks_before {
break;
}
std::thread::sleep(Duration::from_millis(100));
}

signer_test.shutdown();
}

0 comments on commit 9dd8c81

Please sign in to comment.