Skip to content

Commit 8b2d41c

Browse files
committed
CRC: retry post block up to limit if response status is not a success
Signed-off-by: Jacinta Ferrant <[email protected]>
1 parent c109144 commit 8b2d41c

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

stacks-signer/src/client/mod.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use libstackerdb::Error as StackerDBError;
2828
pub use stackerdb::*;
2929
pub use stacks_client::*;
3030
use stacks_common::codec::Error as CodecError;
31-
use stacks_common::debug;
31+
use stacks_common::{debug, warn};
3232

3333
/// Backoff timer initial interval in milliseconds
3434
const BACKOFF_INITIAL_INTERVAL: u64 = 128;
@@ -103,7 +103,7 @@ pub enum ClientError {
103103
pub fn retry_with_exponential_backoff<F, E, T>(request_fn: F) -> Result<T, ClientError>
104104
where
105105
F: FnMut() -> Result<T, backoff::Error<E>>,
106-
E: std::fmt::Debug,
106+
E: std::fmt::Debug + Into<ClientError>,
107107
{
108108
let notify = |err, dur| {
109109
debug!(
@@ -117,7 +117,16 @@ where
117117
.with_max_elapsed_time(Some(Duration::from_secs(BACKOFF_MAX_ELAPSED)))
118118
.build();
119119

120-
backoff::retry_notify(backoff_timer, request_fn, notify).map_err(|_| ClientError::RetryTimeout)
120+
backoff::retry_notify(backoff_timer, request_fn, notify).map_err(|e| match e {
121+
backoff::Error::Permanent(err) => {
122+
warn!("Non-retry error during request: {err:?}");
123+
err.into()
124+
}
125+
backoff::Error::Transient { err, .. } => {
126+
warn!("Exceeded max retries during request: {err:?}");
127+
err.into()
128+
}
129+
})
121130
}
122131

123132
#[cfg(test)]

stacks-signer/src/client/stacks_client.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -612,22 +612,30 @@ impl StacksClient {
612612
let path = format!("{}{}?broadcast=1", self.http_origin, postblock_v3::PATH);
613613
let timer = crate::monitoring::actions::new_rpc_call_timer(&path, &self.http_origin);
614614
let send_request = || {
615-
self.stacks_node_client
615+
let response = self
616+
.stacks_node_client
616617
.post(&path)
617618
.header("Content-Type", "application/octet-stream")
618619
.header(AUTHORIZATION, self.auth_password.clone())
619620
.body(block.serialize_to_vec())
620621
.send()
621622
.map_err(|e| {
622623
debug!("Failed to submit block to the Stacks node: {e:?}");
623-
backoff::Error::transient(e)
624-
})
624+
backoff::Error::transient(ClientError::from(e))
625+
})?;
626+
if !response.status().is_success() {
627+
warn!(
628+
"Failed to post block to stacks-node, will retry until limit reached";
629+
"http_status" => %response.status(),
630+
);
631+
return Err(backoff::Error::transient(ClientError::RequestFailure(
632+
response.status(),
633+
)));
634+
}
635+
Ok(response)
625636
};
626637
let response = retry_with_exponential_backoff(send_request)?;
627638
timer.stop_and_record();
628-
if !response.status().is_success() {
629-
return Err(ClientError::RequestFailure(response.status()));
630-
}
631639
let post_block_resp = response.json::<StacksBlockAcceptedData>()?;
632640
Ok(post_block_resp.accepted)
633641
}

0 commit comments

Comments
 (0)