use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Duration;
#[derive(Debug, Default)]
pub struct Bip353Metrics {
resolutions_total: AtomicU64,
resolutions_success: AtomicU64,
resolutions_failed: AtomicU64,
cache_hits: AtomicU64,
cache_misses: AtomicU64,
address_reuse_detected: AtomicU64,
}
#[derive(Debug, Clone)]
pub struct ResolutionStats {
pub total: u64,
pub success: u64,
pub failed: u64,
pub success_rate: f64,
}
#[derive(Debug, Clone)]
pub struct CacheStats {
pub hits: u64,
pub misses: u64,
pub total: u64,
pub hit_rate: f64,
}
impl Bip353Metrics {
pub fn new() -> Self {
Self::default()
}
pub async fn record_resolution_success(&self, _domain: &str, _duration: Duration) {
self.resolutions_total.fetch_add(1, Ordering::Relaxed);
self.resolutions_success.fetch_add(1, Ordering::Relaxed);
}
pub async fn record_resolution_failure(&self, _domain: &str, _error_type: &str) {
self.resolutions_total.fetch_add(1, Ordering::Relaxed);
self.resolutions_failed.fetch_add(1, Ordering::Relaxed);
}
pub fn record_cache_hit(&self) {
self.cache_hits.fetch_add(1, Ordering::Relaxed);
}
pub fn record_cache_miss(&self) {
self.cache_misses.fetch_add(1, Ordering::Relaxed);
}
pub fn record_address_reuse(&self) {
self.address_reuse_detected.fetch_add(1, Ordering::Relaxed);
}
pub fn get_resolution_stats(&self) -> ResolutionStats {
let total = self.resolutions_total.load(Ordering::Relaxed);
let success = self.resolutions_success.load(Ordering::Relaxed);
let failed = self.resolutions_failed.load(Ordering::Relaxed);
ResolutionStats {
total,
success,
failed,
success_rate: if total > 0 { (success as f64) / (total as f64) } else { 0.0 },
}
}
pub fn get_cache_stats(&self) -> CacheStats {
let hits = self.cache_hits.load(Ordering::Relaxed);
let misses = self.cache_misses.load(Ordering::Relaxed);
let total = hits + misses;
CacheStats {
hits,
misses,
total,
hit_rate: if total > 0 { (hits as f64) / (total as f64) } else { 0.0 },
}
}
}