openzeppelin_relayer/utils/transaction.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
use crate::constants::DEFAULT_TRANSACTION_SPEED;
use crate::models::evm::Speed;
use crate::utils::time::minutes_ms;
/// Gets the resubmit timeout for a given speed
/// Returns the timeout in milliseconds based on the speed:
/// - SafeLow: 10 minutes
/// - Average: 5 minutes
/// - Fast: 3 minutes
/// - Fastest: 2 minutes
/// If no speed is provided, uses the default transaction speed
pub fn get_resubmit_timeout_for_speed(speed: &Option<Speed>) -> i64 {
let speed_value = speed.clone().unwrap_or(DEFAULT_TRANSACTION_SPEED);
match speed_value {
Speed::SafeLow => minutes_ms(10),
Speed::Average => minutes_ms(5),
Speed::Fast => minutes_ms(3),
Speed::Fastest => minutes_ms(2),
}
}
/// Calculates the resubmit age with exponential backoff
///
/// # Arguments
/// * `timeout` - The base timeout in milliseconds
/// * `attempts` - The number of attempts made so far
///
/// # Returns
/// The new timeout with exponential backoff applied: timeout * 2^(attempts-1)
pub fn get_resubmit_timeout_with_backoff(timeout: i64, attempts: usize) -> i64 {
if attempts <= 1 {
timeout
} else {
timeout * 2_i64.pow((attempts - 1) as u32)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_resubmit_timeout_for_speed() {
// Test with existing speeds
assert_eq!(
get_resubmit_timeout_for_speed(&Some(Speed::SafeLow)),
minutes_ms(10)
);
assert_eq!(
get_resubmit_timeout_for_speed(&Some(Speed::Average)),
minutes_ms(5)
);
assert_eq!(
get_resubmit_timeout_for_speed(&Some(Speed::Fast)),
minutes_ms(3)
);
assert_eq!(
get_resubmit_timeout_for_speed(&Some(Speed::Fastest)),
minutes_ms(2)
);
// Test with None speed (should return default)
assert_eq!(
get_resubmit_timeout_for_speed(&None),
minutes_ms(3) // DEFAULT_TRANSACTION_SPEED is Speed::Fast
);
}
#[test]
fn test_get_resubmit_timeout_with_backoff() {
let base_timeout = 300000; // 5 minutes in ms
// First attempt - no backoff
assert_eq!(get_resubmit_timeout_with_backoff(base_timeout, 1), 300000);
// Second attempt - 2x backoff
assert_eq!(get_resubmit_timeout_with_backoff(base_timeout, 2), 600000);
// Third attempt - 4x backoff
assert_eq!(get_resubmit_timeout_with_backoff(base_timeout, 3), 1200000);
// Fourth attempt - 8x backoff
assert_eq!(get_resubmit_timeout_with_backoff(base_timeout, 4), 2400000);
// Edge case - attempt 0 should be treated as attempt 1
assert_eq!(get_resubmit_timeout_with_backoff(base_timeout, 0), 300000);
}
}