Skip to content

Commit cb9b51f

Browse files
Don't cast usize to u8 but deal with the overflow properly
1 parent 2652016 commit cb9b51f

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

src/client.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use api::ElectrumApi;
1010
use batch::Batch;
1111
use config::Config;
1212
use raw_client::*;
13+
use std::convert::TryFrom;
1314
use types::*;
1415

1516
/// Generalized Electrum client that supports multiple backends. This wraps
@@ -52,9 +53,9 @@ macro_rules! impl_inner_call {
5253
return res;
5354
},
5455
Err(e) => {
55-
let failed_attempts = (errors.len() + 1) as u8;
56+
let failed_attempts = errors.len() + 1;
5657

57-
if failed_attempts > $self.config.retry() {
58+
if retries_exhausted(failed_attempts, $self.config.retry()) {
5859
warn!("call '{}' failed after {} attempts", stringify!($name), failed_attempts);
5960
return Err(Error::AllAttemptsErrored(errors));
6061
}
@@ -91,6 +92,13 @@ macro_rules! impl_inner_call {
9192
}
9293
}
9394

95+
fn retries_exhausted(failed_attempts: usize, configured_retries: u8) -> bool {
96+
match u8::try_from(failed_attempts) {
97+
Ok(failed_attempts) => failed_attempts > configured_retries,
98+
Err(_) => true, // if the usize doesn't fit into a u8, we definitely exhausted our retries
99+
}
100+
}
101+
94102
impl ClientType {
95103
/// Constructor that supports multiple backends and allows configuration through
96104
/// the [Config]
@@ -294,3 +302,38 @@ impl ElectrumApi for Client {
294302
impl_inner_call!(self, calls_made)
295303
}
296304
}
305+
306+
#[cfg(test)]
307+
mod tests {
308+
use super::*;
309+
310+
#[test]
311+
fn more_failed_attempts_than_retries_means_exhausted() {
312+
let exhausted = retries_exhausted(10, 5);
313+
314+
assert_eq!(exhausted, true)
315+
}
316+
317+
#[test]
318+
fn failed_attempts_bigger_than_u8_means_exhausted() {
319+
let failed_attempts = u8::MAX as usize + 1;
320+
321+
let exhausted = retries_exhausted(failed_attempts, u8::MAX);
322+
323+
assert_eq!(exhausted, true)
324+
}
325+
326+
#[test]
327+
fn less_failed_attempts_means_not_exhausted() {
328+
let exhausted = retries_exhausted(2, 5);
329+
330+
assert_eq!(exhausted, false)
331+
}
332+
333+
#[test]
334+
fn attempts_equals_retries_means_not_exhausted_yet() {
335+
let exhausted = retries_exhausted(2, 2);
336+
337+
assert_eq!(exhausted, false)
338+
}
339+
}

0 commit comments

Comments
 (0)