Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test: multi-miner & multi-signer scenario #5023

Merged
merged 3 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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