use moka::sync::Cache;
#[derive(Debug, thiserror::Error)]
pub enum ReplayCacheError {
#[error("replay cache operation failed: {0}")]
Other(String),
}
pub trait ReplayCache: Send + Sync {
fn insert_if_absent(
&self,
client_nonce: [u8; 32],
expires_at: u64,
now: u64,
) -> Result<bool, ReplayCacheError>;
}
#[derive(Debug, Clone)]
pub struct MokaReplayCache {
inner: Cache<[u8; 32], u64>,
}
impl MokaReplayCache {
pub fn new(max_capacity: u64) -> Self {
Self {
inner: Cache::builder().max_capacity(max_capacity).build(),
}
}
}
impl ReplayCache for MokaReplayCache {
fn insert_if_absent(
&self,
client_nonce: [u8; 32],
expires_at: u64,
now: u64,
) -> Result<bool, ReplayCacheError> {
if let Some(exp) = self.inner.get(&client_nonce) {
if exp > now {
return Ok(false);
}
self.inner.invalidate(&client_nonce);
}
self.inner.insert(client_nonce, expires_at);
Ok(true)
}
}