use std::collections::HashMap;
use async_trait::async_trait;
use crate::crypto::primitives::{EncValue, Tag};
use crate::error::VaultError;
pub struct RawEdbEntry {
pub tag: Tag,
pub value: EncValue,
}
#[async_trait(?Send)] pub trait EncryptedStore {
async fn get(&self, tag: &Tag) -> Result<Option<EncValue>, VaultError>;
async fn put(&self, tag: Tag, value: EncValue) -> Result<(), VaultError>;
async fn delete(&self, tag: &Tag) -> Result<(), VaultError>;
async fn get_batch(&self, tags: &[Tag]) -> Result<Vec<Option<EncValue>>, VaultError> {
let mut out = Vec::with_capacity(tags.len());
for tag in tags {
out.push(self.get(tag).await?);
}
Ok(out)
}
async fn atomic_update(
&self,
puts: Vec<RawEdbEntry>,
removes: Vec<Tag>,
) -> Result<(), VaultError> {
for entry in puts {
self.put(entry.tag, entry.value).await?;
}
for tag in removes {
self.delete(&tag).await?;
}
Ok(())
}
async fn padded_put_batch(
&self,
real_entries: Vec<RawEdbEntry>,
target_count: usize,
) -> Result<(), VaultError> {
use rand::RngCore;
use crate::crypto::primitives::LAMBDA;
if real_entries.len() > target_count {
return Err(VaultError::VolumeLimitExceeded { max: target_count });
}
let pad_count = target_count - real_entries.len();
let mut rng = rand::thread_rng();
for entry in real_entries {
self.put(entry.tag, entry.value).await?;
}
for _ in 0..pad_count {
let mut dummy_tag = [0u8; LAMBDA];
let mut dummy_val = vec![0u8; 60]; rng.fill_bytes(&mut dummy_tag);
rng.fill_bytes(&mut dummy_val);
self.put(Tag(dummy_tag), EncValue(dummy_val)).await?;
}
Ok(())
}
}
pub struct MockStore {
inner: std::sync::Mutex<HashMap<[u8; 32], Vec<u8>>>,
}
impl MockStore {
pub fn new() -> Self {
Self { inner: std::sync::Mutex::new(HashMap::new()) }
}
pub fn len(&self) -> usize {
self.inner.lock().unwrap().len()
}
}
impl Default for MockStore {
fn default() -> Self { Self::new() }
}
#[async_trait(?Send)]
impl EncryptedStore for MockStore {
async fn get(&self, tag: &Tag) -> Result<Option<EncValue>, VaultError> {
let map = self.inner.lock().unwrap();
Ok(map.get(&tag.0).map(|v| EncValue(v.clone())))
}
async fn put(&self, tag: Tag, value: EncValue) -> Result<(), VaultError> {
let mut map = self.inner.lock().unwrap();
map.insert(tag.0, value.0);
Ok(())
}
async fn delete(&self, tag: &Tag) -> Result<(), VaultError> {
let mut map = self.inner.lock().unwrap();
map.remove(&tag.0);
Ok(())
}
}