mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-07-16 02:40:04 +00:00
65 lines
1.8 KiB
Rust
65 lines
1.8 KiB
Rust
//! Retry gate for possibly-transient block-apply failures.
|
|
|
|
/// Counts consecutive apply failures per block id so the ingest loop can
|
|
/// retry before parking.
|
|
///
|
|
/// A failure streak is keyed to one block id: a failure of a different block
|
|
/// starts a fresh streak. Reset only on a genuinely applied block — the
|
|
/// `AlreadyApplied` replay of the prefix after a retry cycle must not clear
|
|
/// the failing block's streak.
|
|
pub struct ApplyRetryGate {
|
|
failing: Option<(u64, u32)>,
|
|
}
|
|
|
|
impl ApplyRetryGate {
|
|
#[must_use]
|
|
pub const fn new() -> Self {
|
|
Self { failing: None }
|
|
}
|
|
|
|
/// Registers a failed apply of `block_id`; returns its consecutive
|
|
/// attempt count.
|
|
pub const fn register_failure(&mut self, block_id: u64) -> u32 {
|
|
let attempts = match self.failing {
|
|
Some((id, attempts)) if id == block_id => attempts.saturating_add(1),
|
|
_ => 1,
|
|
};
|
|
self.failing = Some((block_id, attempts));
|
|
attempts
|
|
}
|
|
|
|
/// Clears the streak; call when a block actually applies.
|
|
pub const fn reset(&mut self) {
|
|
self.failing = None;
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn counts_consecutive_failures_of_same_block() {
|
|
let mut gate = ApplyRetryGate::new();
|
|
assert_eq!(gate.register_failure(7), 1);
|
|
assert_eq!(gate.register_failure(7), 2);
|
|
assert_eq!(gate.register_failure(7), 3);
|
|
}
|
|
|
|
#[test]
|
|
fn different_block_starts_fresh_streak() {
|
|
let mut gate = ApplyRetryGate::new();
|
|
gate.register_failure(7);
|
|
gate.register_failure(7);
|
|
assert_eq!(gate.register_failure(8), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn reset_clears_streak() {
|
|
let mut gate = ApplyRetryGate::new();
|
|
gate.register_failure(7);
|
|
gate.reset();
|
|
assert_eq!(gate.register_failure(7), 1);
|
|
}
|
|
}
|