Skip to content

Commit e3b8e29

Browse files
authored
Merge pull request #5023 from stacks-network/test/multi-miner-signers
Test: multi-miner & multi-signer scenario
2 parents 5a3825d + c50dff8 commit e3b8e29

File tree

4 files changed

+242
-33
lines changed

4 files changed

+242
-33
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ jobs:
9191
- tests::signer::v0::forked_tenure_invalid
9292
- tests::signer::v0::empty_sortition
9393
- tests::signer::v0::bitcoind_forking_test
94+
- tests::signer::v0::multiple_miners
9495
- tests::signer::v0::mock_sign_epoch_25
9596
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
9697
- tests::nakamoto_integrations::check_block_heights

testnet/stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,13 @@ lazy_static! {
167167
StacksEpoch {
168168
epoch_id: StacksEpochId::Epoch25,
169169
start_height: 201,
170-
end_height: 251,
170+
end_height: 231,
171171
block_limit: HELIUM_BLOCK_LIMIT_20.clone(),
172172
network_epoch: PEER_VERSION_EPOCH_2_5
173173
},
174174
StacksEpoch {
175175
epoch_id: StacksEpochId::Epoch30,
176-
start_height: 251,
176+
start_height: 231,
177177
end_height: STACKS_EPOCH_MAX,
178178
block_limit: HELIUM_BLOCK_LIMIT_20.clone(),
179179
network_epoch: PEER_VERSION_EPOCH_3_0

testnet/stacks-node/src/tests/signer/mod.rs

Lines changed: 90 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use stacks::chainstate::stacks::{StacksPrivateKey, ThresholdSignature};
4444
use stacks::core::StacksEpoch;
4545
use stacks::net::api::postblock_proposal::BlockValidateResponse;
4646
use stacks::types::chainstate::StacksAddress;
47-
use stacks::util::secp256k1::MessageSignature;
47+
use stacks::util::secp256k1::{MessageSignature, Secp256k1PublicKey};
4848
use stacks_common::codec::StacksMessageCodec;
4949
use stacks_common::consts::SIGNER_SLOTS_PER_USER;
5050
use stacks_common::types::StacksEpochId;
@@ -105,14 +105,26 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
105105
initial_balances: Vec<(StacksAddress, u64)>,
106106
wait_on_signers: Option<Duration>,
107107
) -> Self {
108-
Self::new_with_config_modifications(num_signers, initial_balances, wait_on_signers, |_| {})
108+
Self::new_with_config_modifications(
109+
num_signers,
110+
initial_balances,
111+
wait_on_signers,
112+
|_| {},
113+
|_| {},
114+
&[],
115+
)
109116
}
110117

111-
fn new_with_config_modifications<F: Fn(&mut SignerConfig) -> ()>(
118+
fn new_with_config_modifications<
119+
F: FnMut(&mut SignerConfig) -> (),
120+
G: FnMut(&mut NeonConfig) -> (),
121+
>(
112122
num_signers: usize,
113123
initial_balances: Vec<(StacksAddress, u64)>,
114124
wait_on_signers: Option<Duration>,
115-
modifier: F,
125+
mut signer_config_modifier: F,
126+
node_config_modifier: G,
127+
btc_miner_pubkeys: &[Secp256k1PublicKey],
116128
) -> Self {
117129
// Generate Signer Data
118130
let signer_stacks_private_keys = (0..num_signers)
@@ -136,11 +148,10 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
136148
} else {
137149
naka_conf.miner.wait_on_signers = Duration::from_secs(10);
138150
}
139-
140151
let run_stamp = rand::random();
141152

142153
// Setup the signer and coordinator configurations
143-
let signer_configs = build_signer_config_tomls(
154+
let signer_configs: Vec<_> = build_signer_config_tomls(
144155
&signer_stacks_private_keys,
145156
&naka_conf.node.rpc_bind,
146157
Some(Duration::from_millis(128)), // Timeout defaults to 5 seconds. Let's override it to 128 milliseconds.
@@ -151,23 +162,45 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
151162
Some(100_000),
152163
None,
153164
Some(9000),
154-
);
155-
156-
let spawned_signers: Vec<_> = (0..num_signers)
157-
.into_iter()
158-
.map(|i| {
159-
info!("spawning signer");
160-
let mut signer_config =
161-
SignerConfig::load_from_str(&signer_configs[i as usize]).unwrap();
162-
modifier(&mut signer_config);
163-
SpawnedSigner::new(signer_config)
164-
})
165+
)
166+
.into_iter()
167+
.map(|toml| {
168+
let mut signer_config = SignerConfig::load_from_str(&toml).unwrap();
169+
signer_config_modifier(&mut signer_config);
170+
signer_config
171+
})
172+
.collect();
173+
assert_eq!(signer_configs.len(), num_signers);
174+
175+
let spawned_signers = signer_configs
176+
.iter()
177+
.cloned()
178+
.map(SpawnedSigner::new)
165179
.collect();
166180

167181
// Setup the nodes and deploy the contract to it
168-
let node = setup_stx_btc_node(naka_conf, &signer_stacks_private_keys, &signer_configs);
169-
let config = SignerConfig::load_from_str(&signer_configs[0]).unwrap();
170-
let stacks_client = StacksClient::from(&config);
182+
let btc_miner_pubkeys = if btc_miner_pubkeys.is_empty() {
183+
let pk = Secp256k1PublicKey::from_hex(
184+
naka_conf
185+
.burnchain
186+
.local_mining_public_key
187+
.as_ref()
188+
.unwrap(),
189+
)
190+
.unwrap();
191+
&[pk]
192+
} else {
193+
btc_miner_pubkeys
194+
};
195+
let node = setup_stx_btc_node(
196+
naka_conf,
197+
&signer_stacks_private_keys,
198+
&signer_configs,
199+
btc_miner_pubkeys,
200+
node_config_modifier,
201+
);
202+
let config = signer_configs.first().unwrap();
203+
let stacks_client = StacksClient::from(config);
171204

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

330+
fn mine_block_wait_on_processing(&mut self, timeout: Duration) {
331+
let commits_submitted = self.running_nodes.commits_submitted.clone();
332+
let blocks_len = test_observer::get_blocks().len();
333+
let mined_block_time = Instant::now();
334+
next_block_and_mine_commit(
335+
&mut self.running_nodes.btc_regtest_controller,
336+
timeout.as_secs(),
337+
&self.running_nodes.coord_channel,
338+
&commits_submitted,
339+
)
340+
.unwrap();
341+
342+
let t_start = Instant::now();
343+
while test_observer::get_blocks().len() <= blocks_len {
344+
assert!(
345+
t_start.elapsed() < timeout,
346+
"Timed out while waiting for nakamoto block to be processed"
347+
);
348+
thread::sleep(Duration::from_secs(1));
349+
}
350+
let mined_block_elapsed_time = mined_block_time.elapsed();
351+
info!(
352+
"Nakamoto block mine time elapsed: {:?}",
353+
mined_block_elapsed_time
354+
);
355+
}
356+
297357
fn wait_for_confirmed_block_v1(
298358
&mut self,
299359
block_signer_sighash: &Sha512Trunc256Sum,
@@ -537,17 +597,17 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
537597
}
538598
}
539599

540-
fn setup_stx_btc_node(
600+
fn setup_stx_btc_node<G: FnMut(&mut NeonConfig) -> ()>(
541601
mut naka_conf: NeonConfig,
542602
signer_stacks_private_keys: &[StacksPrivateKey],
543-
signer_config_tomls: &[String],
603+
signer_configs: &[SignerConfig],
604+
btc_miner_pubkeys: &[Secp256k1PublicKey],
605+
mut node_config_modifier: G,
544606
) -> RunningNodes {
545607
// Spawn the endpoints for observing signers
546-
for toml in signer_config_tomls {
547-
let signer_config = SignerConfig::load_from_str(toml).unwrap();
548-
608+
for signer_config in signer_configs {
549609
naka_conf.events_observers.insert(EventObserverConfig {
550-
endpoint: format!("{}", signer_config.endpoint),
610+
endpoint: signer_config.endpoint.to_string(),
551611
events_keys: vec![
552612
EventKeyType::StackerDBChunks,
553613
EventKeyType::BlockProposal,
@@ -593,6 +653,8 @@ fn setup_stx_btc_node(
593653
}
594654
}
595655
}
656+
node_config_modifier(&mut naka_conf);
657+
596658
info!("Make new BitcoinCoreController");
597659
let mut btcd_controller = BitcoinCoreController::new(naka_conf.clone());
598660
btcd_controller
@@ -604,8 +666,8 @@ fn setup_stx_btc_node(
604666
let mut btc_regtest_controller = BitcoinRegtestController::new(naka_conf.clone(), None);
605667

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

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

0 commit comments

Comments
 (0)