Contractless/src/orphans/checkup_state.rs

52 lines
1.6 KiB
Rust
Raw Normal View History

use crate::{AtomicBool, AtomicOrdering};
use std::sync::atomic::AtomicU32;
static ORPHAN_CHECK_RUNNING: AtomicBool = AtomicBool::new(false);
static ORPHAN_RECHECK_REQUESTED: AtomicBool = AtomicBool::new(false);
static ORPHAN_RECHECK_FROM_HEIGHT: AtomicU32 = AtomicU32::new(0);
fn store_earliest_recheck_height(incoming_height: u32) {
let mut current = ORPHAN_RECHECK_FROM_HEIGHT.load(AtomicOrdering::SeqCst);
while current == 0 || incoming_height < current {
match ORPHAN_RECHECK_FROM_HEIGHT.compare_exchange(
current,
incoming_height,
AtomicOrdering::SeqCst,
AtomicOrdering::SeqCst,
) {
Ok(_) => return,
Err(next_current) => current = next_current,
}
}
}
pub fn try_begin_orphan_check() -> bool {
if ORPHAN_CHECK_RUNNING
.compare_exchange(false, true, AtomicOrdering::SeqCst, AtomicOrdering::SeqCst)
.is_err()
{
return false;
}
ORPHAN_RECHECK_REQUESTED.store(false, AtomicOrdering::SeqCst);
ORPHAN_RECHECK_FROM_HEIGHT.store(0, AtomicOrdering::SeqCst);
true
}
pub fn request_orphan_recheck(incoming_height: u32) {
store_earliest_recheck_height(incoming_height);
ORPHAN_RECHECK_REQUESTED.store(true, AtomicOrdering::SeqCst);
}
pub fn take_orphan_recheck_height() -> Option<u32> {
if !ORPHAN_RECHECK_REQUESTED.swap(false, AtomicOrdering::SeqCst) {
return None;
}
Some(ORPHAN_RECHECK_FROM_HEIGHT.swap(0, AtomicOrdering::SeqCst))
}
pub fn finish_orphan_check() {
ORPHAN_CHECK_RUNNING.store(false, AtomicOrdering::SeqCst);
}