Skip to content

Commit e085939

Browse files
committed
test fixes, some cleanup
1 parent 5002ef6 commit e085939

File tree

5 files changed

+84
-48
lines changed

5 files changed

+84
-48
lines changed

stacks-signer/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub trait Signer<T: SignerEventTrait>: Debug + Display {
7272
stacks_client: &StacksClient,
7373
sortition_state: &mut Option<SortitionsView>,
7474
event: Option<&SignerEvent<T>>,
75-
res: &Sender<Vec<SignerResult>>,
75+
res: &Sender<SignerResult>,
7676
current_reward_cycle: u64,
7777
);
7878
/// Check if the signer is in the middle of processing blocks
@@ -82,18 +82,18 @@ pub trait Signer<T: SignerEventTrait>: Debug + Display {
8282
}
8383

8484
/// A wrapper around the running signer type for the signer
85-
pub type RunningSigner<T> = libsigner::RunningSigner<SignerEventReceiver<T>, Vec<SignerResult>, T>;
85+
pub type RunningSigner<T> = libsigner::RunningSigner<SignerEventReceiver<T>, SignerResult, T>;
8686

8787
/// The wrapper for the runloop signer type
8888
type RunLoopSigner<S, T> =
89-
libsigner::Signer<Vec<SignerResult>, RunLoop<S, T>, SignerEventReceiver<T>, T>;
89+
libsigner::Signer<SignerResult, RunLoop<S, T>, SignerEventReceiver<T>, T>;
9090

9191
/// The spawned signer
9292
pub struct SpawnedSigner<S: Signer<T> + Send, T: SignerEventTrait> {
9393
/// The underlying running signer thread handle
9494
running_signer: RunningSigner<T>,
9595
/// The result receiver for interacting with the running signer
96-
pub res_recv: Receiver<Vec<SignerResult>>,
96+
pub res_recv: Receiver<SignerResult>,
9797
/// The spawned signer's config
9898
pub config: GlobalConfig,
9999
/// Phantom data for the signer type
@@ -102,12 +102,12 @@ pub struct SpawnedSigner<S: Signer<T> + Send, T: SignerEventTrait> {
102102

103103
impl<S: Signer<T> + Send, T: SignerEventTrait> SpawnedSigner<S, T> {
104104
/// Stop the signer thread and return the final state
105-
pub fn stop(self) -> Option<Vec<SignerResult>> {
105+
pub fn stop(self) -> Option<SignerResult> {
106106
self.running_signer.stop()
107107
}
108108

109109
/// Wait for the signer to terminate, and get the final state. WARNING: This will hang forever if the event receiver stop signal was never sent/no error occurred.
110-
pub fn join(self) -> Option<Vec<SignerResult>> {
110+
pub fn join(self) -> Option<SignerResult> {
111111
self.running_signer.join()
112112
}
113113
}

stacks-signer/src/runloop.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug> RunLo
481481
}
482482

483483
impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug>
484-
SignerRunLoop<Vec<SignerResult>, T> for RunLoop<Signer, T>
484+
SignerRunLoop<SignerResult, T> for RunLoop<Signer, T>
485485
{
486486
fn set_event_timeout(&mut self, timeout: Duration) {
487487
self.config.event_timeout = timeout;
@@ -494,8 +494,8 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug>
494494
fn run_one_pass(
495495
&mut self,
496496
event: Option<SignerEvent<T>>,
497-
res: &Sender<Vec<SignerResult>>,
498-
) -> Option<Vec<SignerResult>> {
497+
res: &Sender<SignerResult>,
498+
) -> Option<SignerResult> {
499499
debug!(
500500
"Running one pass for the signer. state={:?}, event={event:?}",
501501
self.state
@@ -536,8 +536,7 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug>
536536

537537
// This is the only event that we respond to from the outer signer runloop
538538
if let Some(SignerEvent::StatusCheck) = event {
539-
info!("Signer status check requested: {:?}.", self.state);
540-
if let Err(e) = res.send(vec![StateInfo {
539+
let state_info = StateInfo {
541540
runloop_state: self.state,
542541
reward_cycle_info: self.current_reward_cycle_info,
543542
running_signers: self
@@ -558,9 +557,10 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug>
558557
)
559558
})
560559
.collect(),
561-
}
562-
.into()])
563-
{
560+
};
561+
info!("Signer status check requested: {state_info:?}");
562+
563+
if let Err(e) = res.send(state_info.into()) {
564564
error!("Failed to send status check result: {e}.");
565565
}
566566
}

stacks-signer/src/v0/signer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl SignerTrait<SignerMessage> for Signer {
176176
stacks_client: &StacksClient,
177177
sortition_state: &mut Option<SortitionsView>,
178178
event: Option<&SignerEvent<SignerMessage>>,
179-
_res: &Sender<Vec<SignerResult>>,
179+
_res: &Sender<SignerResult>,
180180
current_reward_cycle: u64,
181181
) {
182182
let event_parity = match event {

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

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,11 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
214214

215215
/// Send a status request to each spawned signer
216216
pub fn send_status_request(&self, exclude: &HashSet<usize>) {
217-
for signer_ix in 0..self.spawned_signers.len() {
217+
for (signer_ix, signer_config) in self.signer_configs.iter().enumerate() {
218218
if exclude.contains(&signer_ix) {
219219
continue;
220220
}
221-
let port = 3000 + signer_ix;
222-
let endpoint = format!("http://localhost:{port}");
223-
let path = format!("{endpoint}/status");
221+
let path = format!("http://{}/status", signer_config.endpoint);
224222

225223
debug!("Issue status request to {path}");
226224
let client = reqwest::blocking::Client::new();
@@ -471,7 +469,14 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
471469
}
472470
})
473471
else {
474-
warn!("Local state machine for signer #{ix} not set for reward cycle ${current_rc} yet");
472+
let rcs_set: Vec<_> = signer_state.signer_state_machines.iter().map(|(rc, state)| {
473+
(rc, state.is_some())
474+
}).collect();
475+
warn!(
476+
"Local state machine for signer #{ix} not set for reward cycle #{current_rc} yet";
477+
"burn_block_height" => info_cur.burn_block_height,
478+
"rcs_set" => ?rcs_set
479+
);
475480
return false;
476481
};
477482

@@ -702,6 +707,24 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
702707
.collect()
703708
}
704709

710+
/// Replace the test's configured signer st
711+
pub fn replace_signers(
712+
&mut self,
713+
new_signers: Vec<SpawnedSigner<S, T>>,
714+
new_signers_sks: Vec<StacksPrivateKey>,
715+
new_signer_configs: Vec<SignerConfig>,
716+
) -> (
717+
Vec<SpawnedSigner<S, T>>,
718+
Vec<StacksPrivateKey>,
719+
Vec<SignerConfig>,
720+
) {
721+
let old_signers = std::mem::replace(&mut self.spawned_signers, new_signers);
722+
let old_signers_sks =
723+
std::mem::replace(&mut self.signer_stacks_private_keys, new_signers_sks);
724+
let old_signers_confs = std::mem::replace(&mut self.signer_configs, new_signer_configs);
725+
(old_signers, old_signers_sks, old_signers_confs)
726+
}
727+
705728
/// Get status check results (if returned) from each signer without blocking
706729
/// Returns Some() or None() for each signer, in order of `self.spawned_signers`
707730
pub fn get_states(&mut self, exclude: &HashSet<usize>) -> Vec<Option<StateInfo>> {
@@ -711,17 +734,14 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
711734
output.push(None);
712735
continue;
713736
}
714-
let Ok(mut results) = signer.res_recv.try_recv() else {
715-
debug!("Could not receive latest state from signer #{ix}");
716-
output.push(None);
717-
continue;
718-
};
719-
assert!(results.len() <= 1, "Received multiple states from the signer receiver: this test function assumes it should only ever receive 1");
720-
let Some(SignerResult::StatusCheck(state_info)) = results.pop() else {
721-
debug!("Could not receive latest state from signer #{ix}");
737+
let Ok(results) = signer.res_recv.try_recv() else {
738+
info!("Could not receive latest state from signer #{ix}");
722739
output.push(None);
723740
continue;
724741
};
742+
// Note: if we ever add more signer result enum variants, this function
743+
// should push None and continue for non-StatusCheck variants
744+
let SignerResult::StatusCheck(state_info) = results;
725745
output.push(Some(state_info));
726746
}
727747
output

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

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4648,12 +4648,16 @@ fn signer_set_rollover() {
46484648
None,
46494649
);
46504650

4651+
let new_signer_configs: Vec<_> = new_signer_configs
4652+
.iter()
4653+
.map(|conf_str| SignerConfig::load_from_str(conf_str).unwrap())
4654+
.collect();
4655+
46514656
let new_spawned_signers: Vec<_> = new_signer_configs
46524657
.iter()
4653-
.map(|conf| {
4658+
.map(|signer_config| {
46544659
info!("spawning signer");
4655-
let signer_config = SignerConfig::load_from_str(conf).unwrap();
4656-
SpawnedSigner::new(signer_config)
4660+
SpawnedSigner::new(signer_config.clone())
46574661
})
46584662
.collect();
46594663

@@ -4663,8 +4667,7 @@ fn signer_set_rollover() {
46634667
initial_balances,
46644668
|_| {},
46654669
|naka_conf| {
4666-
for toml in new_signer_configs.clone() {
4667-
let signer_config = SignerConfig::load_from_str(&toml).unwrap();
4670+
for signer_config in new_signer_configs.clone() {
46684671
info!(
46694672
"---- Adding signer endpoint to naka conf ({}) ----",
46704673
signer_config.endpoint
@@ -4697,9 +4700,8 @@ fn signer_set_rollover() {
46974700
let short_timeout = Duration::from_secs(20);
46984701

46994702
// Verify that naka_conf has our new signer's event observers
4700-
for toml in &new_signer_configs {
4701-
let signer_config = SignerConfig::load_from_str(toml).unwrap();
4702-
let endpoint = format!("{}", signer_config.endpoint);
4703+
for signer_config in &new_signer_configs {
4704+
let endpoint = signer_config.endpoint.to_string();
47034705
assert!(signer_test
47044706
.running_nodes
47054707
.conf
@@ -4843,7 +4845,20 @@ fn signer_set_rollover() {
48434845
assert!(new_signer_public_keys.contains(&signer.signing_key.to_vec()));
48444846
}
48454847

4846-
info!("---- Mining to the next reward cycle (block {next_cycle_height}) -----",);
4848+
info!("---- Mining to just before the next reward cycle (block {next_cycle_height}) -----",);
4849+
signer_test.run_until_burnchain_height_nakamoto(
4850+
Duration::from_secs(60),
4851+
next_cycle_height.saturating_sub(1),
4852+
new_num_signers,
4853+
);
4854+
4855+
let (old_spawned_signers, _, _) = signer_test.replace_signers(
4856+
new_spawned_signers,
4857+
new_signer_private_keys,
4858+
new_signer_configs,
4859+
);
4860+
4861+
info!("---- Mining into the next reward cycle (block {next_cycle_height}) -----",);
48474862
signer_test.run_until_burnchain_height_nakamoto(
48484863
Duration::from_secs(60),
48494864
next_cycle_height,
@@ -4887,7 +4902,7 @@ fn signer_set_rollover() {
48874902
}
48884903

48894904
signer_test.shutdown();
4890-
for signer in new_spawned_signers {
4905+
for signer in old_spawned_signers {
48914906
assert!(signer.stop().is_none());
48924907
}
48934908
}
@@ -12308,6 +12323,7 @@ fn signer_can_accept_rejected_block() {
1230812323
info!("Submitted transfer tx and waiting for block proposal");
1230912324
let block = wait_for_block_proposal(30, block_height_before + 1, &miner_pk)
1231012325
.expect("Timed out waiting for block proposal");
12326+
let expected_block_height = block.header.chain_length;
1231112327

1231212328
// Wait for signer[0] to reject the block
1231312329
wait_for_block_rejections(30, block.header.signer_signature_hash(), 1)
@@ -12337,18 +12353,18 @@ fn signer_can_accept_rejected_block() {
1233712353
wait_for(60, || {
1233812354
let blocks = test_observer::get_blocks();
1233912355

12340-
// Look for a block with height `block_height_before + 1`
12341-
if let Some(block) = blocks
12356+
// Look for a block with expected height
12357+
let Some(block) = blocks
1234212358
.iter()
12343-
.find(|block| block["block_height"].as_u64() == Some(block_height_before + 1))
12344-
{
12345-
if transfers_in_block(block) == 1 {
12346-
Ok(true) // Success: found the block with exactly 1 transfer
12347-
} else {
12348-
Err("Transfer included in block".into()) // Found the block, but it has the wrong number of transfers
12349-
}
12359+
.find(|block| block["block_height"].as_u64() == Some(expected_block_height)) else {
12360+
return Ok(false) // Keep waiting if the block hasn't appeared yet
12361+
};
12362+
12363+
let transfers_included_in_block = transfers_in_block(block);
12364+
if transfers_included_in_block == 1 {
12365+
Ok(true) // Success: found the block with exactly 1 transfer
1235012366
} else {
12351-
Ok(false) // Keep waiting if the block hasn't appeared yet
12367+
Err(format!("Unexpected amount of transfers included in block. Found: {transfers_included_in_block}"))
1235212368
}
1235312369
})
1235412370
.expect("Timed out waiting for block");

0 commit comments

Comments
 (0)