use std::{
collections::HashMap,
sync::Arc,
time::{Duration, Instant},
};
use log::debug;
use tari_node_components::blocks::Block;
use tokio::sync::RwLock;
const LOG_TARGET: &str = "minotari::base_node::xmrig_proxy::storage";
const MAX_TEMPLATE_AGE: Duration = Duration::from_secs(20 * 60);
struct TemplateEntry {
block: Block,
inserted_at: Instant,
}
#[derive(Clone)]
pub struct BlockTemplateStorage {
inner: Arc<RwLock<HashMap<[u8; 32], TemplateEntry>>>,
}
impl BlockTemplateStorage {
pub fn new() -> Self {
Self {
inner: Arc::new(RwLock::new(HashMap::new())),
}
}
pub async fn store(&self, key: [u8; 32], block: Block) {
let mut map = self.inner.write().await;
map.insert(key, TemplateEntry {
block,
inserted_at: Instant::now(),
});
debug!(target: LOG_TARGET, "Stored template, total templates={}", map.len());
}
pub async fn take(&self, key: &[u8; 32]) -> Option<Block> {
let mut map = self.inner.write().await;
map.remove(key).map(|e| e.block)
}
pub async fn remove_outdated(&self) {
let now = Instant::now();
let mut map = self.inner.write().await;
let before = map.len();
map.retain(|_, e| now.duration_since(e.inserted_at) < MAX_TEMPLATE_AGE);
let removed = before.saturating_sub(map.len());
if removed > 0 {
debug!(target: LOG_TARGET, "Removed {removed} outdated templates");
}
}
}
impl Default for BlockTemplateStorage {
fn default() -> Self {
Self::new()
}
}