use std::collections::HashSet;
use std::sync::Mutex;
use super::error::SealedTransferError;
pub trait NonceStore: Send + Sync {
fn check_and_record<'a>(
&'a self,
bundle_id: &'a [u8; 16],
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = Result<(), SealedTransferError>> + Send + 'a>,
>;
}
#[derive(Default)]
pub struct InMemoryNonceStore {
seen: Mutex<HashSet<[u8; 16]>>,
}
impl InMemoryNonceStore {
pub fn new() -> Self {
Self::default()
}
}
impl NonceStore for InMemoryNonceStore {
fn check_and_record<'a>(
&'a self,
bundle_id: &'a [u8; 16],
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = Result<(), SealedTransferError>> + Send + 'a>,
> {
let id = *bundle_id;
Box::pin(async move {
let mut set = self
.seen
.lock()
.map_err(|e| SealedTransferError::NonceStore(format!("poisoned mutex: {e}")))?;
if !set.insert(id) {
return Err(SealedTransferError::NonceReplay);
}
Ok(())
})
}
}