Skip to content

Commit

Permalink
Merge pull request #5023 from stacks-network/test/multi-miner-signers
Browse files Browse the repository at this point in the history
Test: multi-miner & multi-signer scenario
  • Loading branch information
kantai authored Aug 1, 2024
2 parents 5a3825d + c50dff8 commit e3b8e29
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 33 deletions.
1 change: 1 addition & 0 deletions .github/workflows/bitcoin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ jobs:
- tests::signer::v0::forked_tenure_invalid
- tests::signer::v0::empty_sortition
- tests::signer::v0::bitcoind_forking_test
- tests::signer::v0::multiple_miners
- tests::signer::v0::mock_sign_epoch_25
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
- tests::nakamoto_integrations::check_block_heights
Expand Down
4 changes: 2 additions & 2 deletions testnet/stacks-node/src/tests/nakamoto_integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ lazy_static! {
StacksEpoch {
epoch_id: StacksEpochId::Epoch25,
start_height: 201,
end_height: 251,
end_height: 231,
block_limit: HELIUM_BLOCK_LIMIT_20.clone(),
network_epoch: PEER_VERSION_EPOCH_2_5
},
StacksEpoch {
epoch_id: StacksEpochId::Epoch30,
start_height: 251,
start_height: 231,
end_height: STACKS_EPOCH_MAX,
block_limit: HELIUM_BLOCK_LIMIT_20.clone(),
network_epoch: PEER_VERSION_EPOCH_3_0
Expand Down
118 changes: 90 additions & 28 deletions testnet/stacks-node/src/tests/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use stacks::chainstate::stacks::{StacksPrivateKey, ThresholdSignature};
use stacks::core::StacksEpoch;
use stacks::net::api::postblock_proposal::BlockValidateResponse;
use stacks::types::chainstate::StacksAddress;
use stacks::util::secp256k1::MessageSignature;
use stacks::util::secp256k1::{MessageSignature, Secp256k1PublicKey};
use stacks_common::codec::StacksMessageCodec;
use stacks_common::consts::SIGNER_SLOTS_PER_USER;
use stacks_common::types::StacksEpochId;
Expand Down Expand Up @@ -105,14 +105,26 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
initial_balances: Vec<(StacksAddress, u64)>,
wait_on_signers: Option<Duration>,
) -> Self {
Self::new_with_config_modifications(num_signers, initial_balances, wait_on_signers, |_| {})
Self::new_with_config_modifications(
num_signers,
initial_balances,
wait_on_signers,
|_| {},
|_| {},
&[],
)
}

fn new_with_config_modifications<F: Fn(&mut SignerConfig) -> ()>(
fn new_with_config_modifications<
F: FnMut(&mut SignerConfig) -> (),
G: FnMut(&mut NeonConfig) -> (),
>(
num_signers: usize,
initial_balances: Vec<(StacksAddress, u64)>,
wait_on_signers: Option<Duration>,
modifier: F,
mut signer_config_modifier: F,
node_config_modifier: G,
btc_miner_pubkeys: &[Secp256k1PublicKey],
) -> Self {
// Generate Signer Data
let signer_stacks_private_keys = (0..num_signers)
Expand All @@ -136,11 +148,10 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
} else {
naka_conf.miner.wait_on_signers = Duration::from_secs(10);
}

let run_stamp = rand::random();

// Setup the signer and coordinator configurations
let signer_configs = build_signer_config_tomls(
let signer_configs: Vec<_> = build_signer_config_tomls(
&signer_stacks_private_keys,
&naka_conf.node.rpc_bind,
Some(Duration::from_millis(128)), // Timeout defaults to 5 seconds. Let's override it to 128 milliseconds.
Expand All @@ -151,23 +162,45 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
Some(100_000),
None,
Some(9000),
);

let spawned_signers: Vec<_> = (0..num_signers)
.into_iter()
.map(|i| {
info!("spawning signer");
let mut signer_config =
SignerConfig::load_from_str(&signer_configs[i as usize]).unwrap();
modifier(&mut signer_config);
SpawnedSigner::new(signer_config)
})
)
.into_iter()
.map(|toml| {
let mut signer_config = SignerConfig::load_from_str(&toml).unwrap();
signer_config_modifier(&mut signer_config);
signer_config
})
.collect();
assert_eq!(signer_configs.len(), num_signers);

let spawned_signers = signer_configs
.iter()
.cloned()
.map(SpawnedSigner::new)
.collect();

// Setup the nodes and deploy the contract to it
let node = setup_stx_btc_node(naka_conf, &signer_stacks_private_keys, &signer_configs);
let config = SignerConfig::load_from_str(&signer_configs[0]).unwrap();
let stacks_client = StacksClient::from(&config);
let btc_miner_pubkeys = if btc_miner_pubkeys.is_empty() {
let pk = Secp256k1PublicKey::from_hex(
naka_conf
.burnchain
.local_mining_public_key
.as_ref()
.unwrap(),
)
.unwrap();
&[pk]
} else {
btc_miner_pubkeys
};
let node = setup_stx_btc_node(
naka_conf,
&signer_stacks_private_keys,
&signer_configs,
btc_miner_pubkeys,
node_config_modifier,
);
let config = signer_configs.first().unwrap();
let stacks_client = StacksClient::from(config);

Self {
running_nodes: node,
Expand Down Expand Up @@ -294,6 +327,33 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
test_observer::get_mined_nakamoto_blocks().pop().unwrap()
}

fn mine_block_wait_on_processing(&mut self, timeout: Duration) {
let commits_submitted = self.running_nodes.commits_submitted.clone();
let blocks_len = test_observer::get_blocks().len();
let mined_block_time = Instant::now();
next_block_and_mine_commit(
&mut self.running_nodes.btc_regtest_controller,
timeout.as_secs(),
&self.running_nodes.coord_channel,
&commits_submitted,
)
.unwrap();

let t_start = Instant::now();
while test_observer::get_blocks().len() <= blocks_len {
assert!(
t_start.elapsed() < timeout,
"Timed out while waiting for nakamoto block to be processed"
);
thread::sleep(Duration::from_secs(1));
}
let mined_block_elapsed_time = mined_block_time.elapsed();
info!(
"Nakamoto block mine time elapsed: {:?}",
mined_block_elapsed_time
);
}

fn wait_for_confirmed_block_v1(
&mut self,
block_signer_sighash: &Sha512Trunc256Sum,
Expand Down Expand Up @@ -537,17 +597,17 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
}
}

fn setup_stx_btc_node(
fn setup_stx_btc_node<G: FnMut(&mut NeonConfig) -> ()>(
mut naka_conf: NeonConfig,
signer_stacks_private_keys: &[StacksPrivateKey],
signer_config_tomls: &[String],
signer_configs: &[SignerConfig],
btc_miner_pubkeys: &[Secp256k1PublicKey],
mut node_config_modifier: G,
) -> RunningNodes {
// Spawn the endpoints for observing signers
for toml in signer_config_tomls {
let signer_config = SignerConfig::load_from_str(toml).unwrap();

for signer_config in signer_configs {
naka_conf.events_observers.insert(EventObserverConfig {
endpoint: format!("{}", signer_config.endpoint),
endpoint: signer_config.endpoint.to_string(),
events_keys: vec![
EventKeyType::StackerDBChunks,
EventKeyType::BlockProposal,
Expand Down Expand Up @@ -593,6 +653,8 @@ fn setup_stx_btc_node(
}
}
}
node_config_modifier(&mut naka_conf);

info!("Make new BitcoinCoreController");
let mut btcd_controller = BitcoinCoreController::new(naka_conf.clone());
btcd_controller
Expand All @@ -604,8 +666,8 @@ fn setup_stx_btc_node(
let mut btc_regtest_controller = BitcoinRegtestController::new(naka_conf.clone(), None);

info!("Bootstraping...");
// Bootstrap the chain to BEFORE epoch 2.5 to enable mock mining of blocks in Epoch 2.5 tests
btc_regtest_controller.bootstrap_chain(195);
// Should be 201 for other tests?
btc_regtest_controller.bootstrap_chain_to_pks(195, btc_miner_pubkeys);

info!("Chain bootstrapped...");

Expand Down
Loading

0 comments on commit e3b8e29

Please sign in to comment.