Skip to content

Commit

Permalink
Merge pull request #5054 from stacks-network/ci/fix-signers-tests
Browse files Browse the repository at this point in the history
Fix: Signers CI tests and refresh signer config behaviors
  • Loading branch information
kantai authored Aug 9, 2024
2 parents a4d3ff9 + 9f4b56e commit 5aa1ed5
Show file tree
Hide file tree
Showing 13 changed files with 648 additions and 287 deletions.
1 change: 1 addition & 0 deletions .github/workflows/bitcoin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ jobs:
- tests::signer::v0::mock_sign_epoch_25
- tests::signer::v0::signer_set_rollover
- tests::signer::v0::miner_forking
- tests::signer::v0::reloads_signer_set_in
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
- tests::nakamoto_integrations::check_block_heights
- tests::nakamoto_integrations::clarity_burn_state
Expand Down
5 changes: 3 additions & 2 deletions libsigner/src/runloop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,14 @@ impl<
let (event_send, event_recv) = channel();
event_receiver.add_consumer(event_send);

let bind_port = bind_addr.port();
event_receiver.bind(bind_addr)?;
let stop_signaler = event_receiver.get_stop_signaler()?;
let mut ret_stop_signaler = event_receiver.get_stop_signaler()?;

// start a thread for the event receiver
let event_thread = thread::Builder::new()
.name("event_receiver".to_string())
.name(format!("event_receiver:{bind_port}"))
.stack_size(THREAD_STACK_SIZE)
.spawn(move || event_receiver.main_loop())
.map_err(|e| {
Expand All @@ -262,7 +263,7 @@ impl<

// start receiving events and doing stuff with them
let runloop_thread = thread::Builder::new()
.name(format!("signer_runloop:{}", bind_addr.port()))
.name(format!("signer_runloop:{bind_port}"))
.stack_size(THREAD_STACK_SIZE)
.spawn(move || {
signer_loop.main_loop(event_recv, command_receiver, result_sender, stop_signaler)
Expand Down
3 changes: 3 additions & 0 deletions stacks-signer/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ use stacks_common::debug;
const BACKOFF_INITIAL_INTERVAL: u64 = 128;
/// Backoff timer max interval in milliseconds
const BACKOFF_MAX_INTERVAL: u64 = 16384;
/// Backoff timer max elapsed seconds
const BACKOFF_MAX_ELAPSED: u64 = 5;

#[derive(thiserror::Error, Debug)]
/// Client error type
Expand Down Expand Up @@ -109,6 +111,7 @@ where
let backoff_timer = backoff::ExponentialBackoffBuilder::new()
.with_initial_interval(Duration::from_millis(BACKOFF_INITIAL_INTERVAL))
.with_max_interval(Duration::from_millis(BACKOFF_MAX_INTERVAL))
.with_max_elapsed_time(Some(Duration::from_secs(BACKOFF_MAX_ELAPSED)))
.build();

backoff::retry_notify(backoff_timer, request_fn, notify).map_err(|_| ClientError::RetryTimeout)
Expand Down
40 changes: 31 additions & 9 deletions stacks-signer/src/client/stacks_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use blockstack_lib::net::api::get_tenures_fork_info::{
use blockstack_lib::net::api::getaccount::AccountEntryResponse;
use blockstack_lib::net::api::getpoxinfo::RPCPoxInfoData;
use blockstack_lib::net::api::getsortition::{SortitionInfo, RPC_SORTITION_INFO_PATH};
use blockstack_lib::net::api::getstackers::GetStackersResponse;
use blockstack_lib::net::api::getstackers::{GetStackersErrors, GetStackersResponse};
use blockstack_lib::net::api::postblock::StacksBlockAcceptedData;
use blockstack_lib::net::api::postblock_proposal::NakamotoBlockProposal;
use blockstack_lib::net::api::postblock_v3;
Expand All @@ -44,6 +44,7 @@ use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier};
use clarity::vm::{ClarityName, ContractName, Value as ClarityValue};
use libsigner::v0::messages::PeerInfo;
use reqwest::header::AUTHORIZATION;
use serde::Deserialize;
use serde_json::json;
use slog::{slog_debug, slog_warn};
use stacks_common::codec::StacksMessageCodec;
Expand Down Expand Up @@ -80,6 +81,12 @@ pub struct StacksClient {
auth_password: String,
}

#[derive(Deserialize)]
struct GetStackersErrorResp {
err_type: String,
err_msg: String,
}

impl From<&GlobalConfig> for StacksClient {
fn from(config: &GlobalConfig) -> Self {
Self {
Expand Down Expand Up @@ -514,23 +521,38 @@ impl StacksClient {
&self,
reward_cycle: u64,
) -> Result<Option<Vec<NakamotoSignerEntry>>, ClientError> {
debug!("Getting reward set for reward cycle {reward_cycle}...");
let timer = crate::monitoring::new_rpc_call_timer(
&self.reward_set_path(reward_cycle),
&self.http_origin,
);
let send_request = || {
self.stacks_node_client
let response = self
.stacks_node_client
.get(self.reward_set_path(reward_cycle))
.send()
.map_err(backoff::Error::transient)
.map_err(|e| backoff::Error::transient(e.into()))?;
let status = response.status();
if status.is_success() {
return response
.json()
.map_err(|e| backoff::Error::permanent(e.into()));
}
let error_data = response.json::<GetStackersErrorResp>().map_err(|e| {
warn!("Failed to parse the GetStackers error response: {e}");
backoff::Error::permanent(e.into())
})?;
if &error_data.err_type == GetStackersErrors::NOT_AVAILABLE_ERR_TYPE {
return Err(backoff::Error::transient(ClientError::NoSortitionOnChain));
} else {
warn!("Got error response ({status}): {}", error_data.err_msg);
return Err(backoff::Error::permanent(ClientError::RequestFailure(
status,
)));
}
};
let response = retry_with_exponential_backoff(send_request)?;
let stackers_response =
retry_with_exponential_backoff::<_, ClientError, GetStackersResponse>(send_request)?;
timer.stop_and_record();
if !response.status().is_success() {
return Err(ClientError::RequestFailure(response.status()));
}
let stackers_response = response.json::<GetStackersResponse>()?;
Ok(stackers_response.stacker_set.signers)
}

Expand Down
2 changes: 0 additions & 2 deletions stacks-signer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ use crate::runloop::{RunLoop, RunLoopCommand};
pub trait Signer<T: SignerEventTrait>: Debug + Display {
/// Create a new `Signer` instance
fn new(config: SignerConfig) -> Self;
/// Update the `Signer` instance's with the next reward cycle data `SignerConfig`
fn update_signer(&mut self, next_signer_config: &SignerConfig);
/// Get the reward cycle of the signer
fn reward_cycle(&self) -> u64;
/// Process an event
Expand Down
Loading

0 comments on commit 5aa1ed5

Please sign in to comment.