Skip to content

Commit

Permalink
Merge pull request #5034 from stacks-network/test/miner-forking-signers
Browse files Browse the repository at this point in the history
Test: 2 miners with one attempting forks
  • Loading branch information
kantai committed Aug 1, 2024
2 parents 6b05a3f + 13e73fb commit a331129
Show file tree
Hide file tree
Showing 6 changed files with 477 additions and 37 deletions.
1 change: 1 addition & 0 deletions .github/workflows/bitcoin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ jobs:
- tests::signer::v0::bitcoind_forking_test
- tests::signer::v0::multiple_miners
- tests::signer::v0::mock_sign_epoch_25
- tests::signer::v0::miner_forking
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
- tests::nakamoto_integrations::check_block_heights
- tests::nakamoto_integrations::clarity_burn_state
Expand Down
15 changes: 9 additions & 6 deletions testnet/stacks-node/src/nakamoto_node/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,6 @@ use crate::run_loop::nakamoto::{Globals, RunLoop};
use crate::run_loop::RegisteredKey;
use crate::BitcoinRegtestController;

#[cfg(test)]
lazy_static::lazy_static! {
pub static ref TEST_SKIP_COMMIT_OP: std::sync::Mutex<Option<bool>> = std::sync::Mutex::new(None);
}

/// Command types for the Nakamoto relayer thread, issued to it by other threads
pub enum RelayerDirective {
/// Handle some new data that arrived on the network (such as blocks, transactions, and
Expand Down Expand Up @@ -937,7 +932,15 @@ impl RelayerThread {
let mut last_committed = self.make_block_commit(&tip_block_ch, &tip_block_bh)?;
#[cfg(test)]
{
if TEST_SKIP_COMMIT_OP.lock().unwrap().unwrap_or(false) {
if self
.globals
.counters
.naka_skip_commit_op
.0
.lock()
.unwrap()
.unwrap_or(false)
{
warn!("Relayer: not submitting block-commit to bitcoin network due to test directive.");
return Ok(());
}
Expand Down
14 changes: 14 additions & 0 deletions testnet/stacks-node/src/run_loop/neon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ impl std::ops::Deref for RunLoopCounter {
}
}

#[cfg(test)]
#[derive(Clone)]
pub struct TestFlag(pub Arc<std::sync::Mutex<Option<bool>>>);

#[cfg(test)]
impl Default for TestFlag {
fn default() -> Self {
Self(Arc::new(std::sync::Mutex::new(None)))
}
}

#[derive(Clone, Default)]
pub struct Counters {
pub blocks_processed: RunLoopCounter,
Expand All @@ -95,6 +106,9 @@ pub struct Counters {
pub naka_mined_blocks: RunLoopCounter,
pub naka_proposed_blocks: RunLoopCounter,
pub naka_mined_tenures: RunLoopCounter,

#[cfg(test)]
pub naka_skip_commit_op: TestFlag,
}

impl Counters {
Expand Down
59 changes: 40 additions & 19 deletions testnet/stacks-node/src/tests/nakamoto_integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ use wsts::net::Message;
use super::bitcoin_regtest::BitcoinCoreController;
use crate::config::{EventKeyType, EventObserverConfig, InitialBalance};
use crate::nakamoto_node::miner::TEST_BROADCAST_STALL;
use crate::nakamoto_node::relayer::TEST_SKIP_COMMIT_OP;
use crate::neon::{Counters, RunLoopCounter};
use crate::operations::BurnchainOpSigner;
use crate::run_loop::boot_nakamoto;
Expand Down Expand Up @@ -626,6 +625,21 @@ where
Ok(())
}

pub fn wait_for<F>(timeout_secs: u64, mut check: F) -> Result<(), String>
where
F: FnMut() -> Result<bool, String>,
{
let start = Instant::now();
while !check()? {
if start.elapsed() > Duration::from_secs(timeout_secs) {
error!("Timed out waiting for check to process");
return Err("Timed out".into());
}
thread::sleep(Duration::from_millis(100));
}
Ok(())
}

/// Mine a bitcoin block, and wait until:
/// (1) a new block has been processed by the coordinator
pub fn next_block_and_process_new_stacks_block(
Expand Down Expand Up @@ -1627,6 +1641,10 @@ fn multiple_miners() {

let (mut naka_conf, _miner_account) = naka_neon_integration_conf(None);
naka_conf.node.local_peer_seed = vec![1, 1, 1, 1];
naka_conf.miner.mining_key = Some(Secp256k1PrivateKey::from_seed(&[1]));

let node_2_rpc = 51026;
let node_2_p2p = 51025;
let http_origin = format!("http://{}", &naka_conf.node.rpc_bind);
naka_conf.miner.wait_on_interim_blocks = Duration::from_secs(1);
let sender_sk = Secp256k1PrivateKey::new();
Expand All @@ -1651,7 +1669,11 @@ fn multiple_miners() {
let stacker_sk = setup_stacker(&mut naka_conf);

let mut conf_node_2 = naka_conf.clone();
set_random_binds(&mut conf_node_2);
let localhost = "127.0.0.1";
conf_node_2.node.rpc_bind = format!("{}:{}", localhost, node_2_rpc);
conf_node_2.node.p2p_bind = format!("{}:{}", localhost, node_2_p2p);
conf_node_2.node.data_url = format!("http://{}:{}", localhost, node_2_rpc);
conf_node_2.node.p2p_address = format!("{}:{}", localhost, node_2_p2p);
conf_node_2.node.seed = vec![2, 2, 2, 2];
conf_node_2.burnchain.local_mining_public_key = Some(
Keychain::default(conf_node_2.node.seed.clone())
Expand All @@ -1660,6 +1682,8 @@ fn multiple_miners() {
);
conf_node_2.node.local_peer_seed = vec![2, 2, 2, 2];
conf_node_2.node.miner = true;
conf_node_2.miner.mining_key = Some(Secp256k1PrivateKey::from_seed(&[2]));
conf_node_2.events_observers.clear();

let node_1_sk = Secp256k1PrivateKey::from_seed(&naka_conf.node.local_peer_seed);
let node_1_pk = StacksPublicKey::from_private(&node_1_sk);
Expand Down Expand Up @@ -1799,16 +1823,14 @@ fn multiple_miners() {
make_stacks_transfer(&sender_sk, sender_nonce, send_fee, &recipient, send_amt);
submit_tx(&http_origin, &transfer_tx);

loop {
wait_for(20, || {
let blocks_processed = coord_channel
.lock()
.expect("Mutex poisoned")
.get_stacks_blocks_processed();
if blocks_processed > blocks_processed_before {
break;
}
thread::sleep(Duration::from_millis(100));
}
Ok(blocks_processed > blocks_processed_before)
})
.unwrap();

let info = get_chain_info_result(&naka_conf).unwrap();
assert_ne!(info.stacks_tip, last_tip);
Expand All @@ -1818,13 +1840,10 @@ fn multiple_miners() {
last_tip_height = info.stacks_tip_height;
}

let start_time = Instant::now();
while commits_submitted.load(Ordering::SeqCst) <= commits_before {
if start_time.elapsed() >= Duration::from_secs(20) {
panic!("Timed out waiting for block-commit");
}
thread::sleep(Duration::from_millis(100));
}
wait_for(20, || {
Ok(commits_submitted.load(Ordering::SeqCst) > commits_before)
})
.unwrap();
}

// load the chain tip, and assert that it is a nakamoto block and at least 30 blocks have advanced in epoch 3
Expand Down Expand Up @@ -3723,6 +3742,7 @@ fn forked_tenure_is_ignored() {
naka_submitted_commits: commits_submitted,
naka_proposed_blocks: proposals_submitted,
naka_mined_blocks: mined_blocks,
naka_skip_commit_op: test_skip_commit_op,
..
} = run_loop.counters();

Expand Down Expand Up @@ -3791,7 +3811,7 @@ fn forked_tenure_is_ignored() {
info!("Commit op is submitted; unpause tenure B's block");

// Unpause the broadcast of Tenure B's block, do not submit commits.
TEST_SKIP_COMMIT_OP.lock().unwrap().replace(true);
test_skip_commit_op.0.lock().unwrap().replace(true);
TEST_BROADCAST_STALL.lock().unwrap().replace(false);

// Wait for a stacks block to be broadcasted
Expand All @@ -3816,7 +3836,7 @@ fn forked_tenure_is_ignored() {
let commits_before = commits_submitted.load(Ordering::SeqCst);
let blocks_before = mined_blocks.load(Ordering::SeqCst);
next_block_and(&mut btc_regtest_controller, 60, || {
TEST_SKIP_COMMIT_OP.lock().unwrap().replace(false);
test_skip_commit_op.0.lock().unwrap().replace(false);
let commits_count = commits_submitted.load(Ordering::SeqCst);
let blocks_count = mined_blocks.load(Ordering::SeqCst);
Ok(commits_count > commits_before && blocks_count > blocks_before)
Expand Down Expand Up @@ -5478,6 +5498,7 @@ fn continue_tenure_extend() {
blocks_processed,
naka_submitted_commits: commits_submitted,
naka_proposed_blocks: proposals_submitted,
naka_skip_commit_op: test_skip_commit_op,
..
} = run_loop.counters();

Expand Down Expand Up @@ -5549,7 +5570,7 @@ fn continue_tenure_extend() {
);

info!("Pausing commit ops to trigger a tenure extend.");
TEST_SKIP_COMMIT_OP.lock().unwrap().replace(true);
test_skip_commit_op.0.lock().unwrap().replace(true);

next_block_and(&mut btc_regtest_controller, 60, || Ok(true)).unwrap();

Expand Down Expand Up @@ -5604,7 +5625,7 @@ fn continue_tenure_extend() {
);

info!("Resuming commit ops to mine regular tenures.");
TEST_SKIP_COMMIT_OP.lock().unwrap().replace(false);
test_skip_commit_op.0.lock().unwrap().replace(false);

// Mine 15 more regular nakamoto tenures
for _i in 0..15 {
Expand Down
8 changes: 7 additions & 1 deletion testnet/stacks-node/src/tests/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use wsts::state_machine::PublicKeys;

use crate::config::{Config as NeonConfig, EventKeyType, EventObserverConfig, InitialBalance};
use crate::event_dispatcher::MinedNakamotoBlockEvent;
use crate::neon::Counters;
use crate::neon::{Counters, TestFlag};
use crate::run_loop::boot_nakamoto;
use crate::tests::bitcoin_regtest::BitcoinCoreController;
use crate::tests::nakamoto_integrations::{
Expand All @@ -81,6 +81,7 @@ pub struct RunningNodes {
pub blocks_processed: Arc<AtomicU64>,
pub nakamoto_blocks_proposed: Arc<AtomicU64>,
pub nakamoto_blocks_mined: Arc<AtomicU64>,
pub nakamoto_test_skip_commit_op: TestFlag,
pub coord_channel: Arc<Mutex<CoordinatorChannels>>,
pub conf: NeonConfig,
}
Expand All @@ -91,6 +92,8 @@ pub struct SignerTest<S> {
pub running_nodes: RunningNodes,
// The spawned signers and their threads
pub spawned_signers: Vec<S>,
// The spawned signers and their threads
pub signer_configs: Vec<SignerConfig>,
// the private keys of the signers
pub signer_stacks_private_keys: Vec<StacksPrivateKey>,
// link to the stacks node
Expand Down Expand Up @@ -208,6 +211,7 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
signer_stacks_private_keys,
stacks_client,
run_stamp,
signer_configs,
}
}

Expand Down Expand Up @@ -679,6 +683,7 @@ fn setup_stx_btc_node<G: FnMut(&mut NeonConfig) -> ()>(
naka_submitted_commits: commits_submitted,
naka_proposed_blocks: naka_blocks_proposed,
naka_mined_blocks: naka_blocks_mined,
naka_skip_commit_op: nakamoto_test_skip_commit_op,
..
} = run_loop.counters();

Expand Down Expand Up @@ -711,6 +716,7 @@ fn setup_stx_btc_node<G: FnMut(&mut NeonConfig) -> ()>(
blocks_processed: blocks_processed.0,
nakamoto_blocks_proposed: naka_blocks_proposed.0,
nakamoto_blocks_mined: naka_blocks_mined.0,
nakamoto_test_skip_commit_op,
coord_channel,
conf: naka_conf,
}
Expand Down
Loading

0 comments on commit a331129

Please sign in to comment.