use std::fmt::Debug;
use crate::{
utils::std_ext,
verifier::types::{Height, LightBlock, Status},
};
pub mod memory;
#[cfg(feature = "lightstore-sled")]
#[cfg_attr(docsrs, doc(cfg(feature = "lightstore-sled")))]
pub mod sled;
pub trait LightStore: Debug + Send + Sync {
fn get(&self, height: Height, status: Status) -> Option<LightBlock>;
fn update(&mut self, light_block: &LightBlock, status: Status);
fn insert(&mut self, light_block: LightBlock, status: Status);
fn remove(&mut self, height: Height, status: Status);
fn highest(&self, status: Status) -> Option<LightBlock>;
fn highest_before(&self, height: Height, status: Status) -> Option<LightBlock>;
fn lowest(&self, status: Status) -> Option<LightBlock>;
fn all(&self, status: Status) -> Box<dyn Iterator<Item = LightBlock>>;
fn get_non_failed(&self, height: Height) -> Option<(LightBlock, Status)> {
None.or_else(|| {
self.get(height, Status::Trusted)
.map(|lb| (lb, Status::Trusted))
})
.or_else(|| {
self.get(height, Status::Verified)
.map(|lb| (lb, Status::Verified))
})
.or_else(|| {
self.get(height, Status::Unverified)
.map(|lb| (lb, Status::Unverified))
})
}
fn highest_trusted_or_verified(&self) -> Option<LightBlock> {
let latest_trusted = self.highest(Status::Trusted);
let latest_verified = self.highest(Status::Verified);
std_ext::option::select(latest_trusted, latest_verified, |t, v| {
std_ext::cmp::max_by_key(t, v, |lb| lb.height())
})
}
fn highest_trusted_or_verified_before(&self, height: Height) -> Option<LightBlock> {
let highest_trusted = self.highest_before(height, Status::Trusted);
let highest_verified = self.highest_before(height, Status::Verified);
std_ext::option::select(highest_trusted, highest_verified, |t, v| {
std_ext::cmp::max_by_key(t, v, |lb| lb.height())
})
}
fn lowest_trusted_or_verified(&self) -> Option<LightBlock> {
let lowest_trusted = self.lowest(Status::Trusted);
let lowest_verified = self.lowest(Status::Verified);
std_ext::option::select(lowest_trusted, lowest_verified, |t, v| {
std_ext::cmp::min_by_key(t, v, |lb| lb.height())
})
}
fn get_trusted_or_verified(&self, height: Height) -> Option<LightBlock> {
self.get(height, Status::Trusted)
.or_else(|| self.get(height, Status::Verified))
}
}