1use std::sync::atomic::{AtomicU64, Ordering};
4use std::time::Duration;
5
6#[derive(Debug, Default)]
7pub struct Bip353Metrics {
8 resolutions_total: AtomicU64,
10 resolutions_success: AtomicU64,
11 resolutions_failed: AtomicU64,
12 cache_hits: AtomicU64,
13 cache_misses: AtomicU64,
14 address_reuse_detected: AtomicU64,
15}
16
17#[derive(Debug, Clone)]
18pub struct ResolutionStats {
19 pub total: u64,
20 pub success: u64,
21 pub failed: u64,
22 pub success_rate: f64,
23}
24
25#[derive(Debug, Clone)]
26pub struct CacheStats {
27 pub hits: u64,
28 pub misses: u64,
29 pub total: u64,
30 pub hit_rate: f64,
31}
32
33impl Bip353Metrics {
34 pub fn new() -> Self {
35 Self::default()
36 }
37
38 pub async fn record_resolution_success(&self, _domain: &str, _duration: Duration) {
40 self.resolutions_total.fetch_add(1, Ordering::Relaxed);
41 self.resolutions_success.fetch_add(1, Ordering::Relaxed);
42 }
43
44 pub async fn record_resolution_failure(&self, _domain: &str, _error_type: &str) {
46 self.resolutions_total.fetch_add(1, Ordering::Relaxed);
47 self.resolutions_failed.fetch_add(1, Ordering::Relaxed);
48 }
49
50 pub fn record_cache_hit(&self) {
52 self.cache_hits.fetch_add(1, Ordering::Relaxed);
53 }
54
55 pub fn record_cache_miss(&self) {
57 self.cache_misses.fetch_add(1, Ordering::Relaxed);
58 }
59
60 pub fn record_address_reuse(&self) {
62 self.address_reuse_detected.fetch_add(1, Ordering::Relaxed);
63 }
64
65 pub fn get_resolution_stats(&self) -> ResolutionStats {
67 let total = self.resolutions_total.load(Ordering::Relaxed);
68 let success = self.resolutions_success.load(Ordering::Relaxed);
69 let failed = self.resolutions_failed.load(Ordering::Relaxed);
70
71 ResolutionStats {
72 total,
73 success,
74 failed,
75 success_rate: if total > 0 { (success as f64) / (total as f64) } else { 0.0 },
76 }
77 }
78
79 pub fn get_cache_stats(&self) -> CacheStats {
81 let hits = self.cache_hits.load(Ordering::Relaxed);
82 let misses = self.cache_misses.load(Ordering::Relaxed);
83 let total = hits + misses;
84
85 CacheStats {
86 hits,
87 misses,
88 total,
89 hit_rate: if total > 0 { (hits as f64) / (total as f64) } else { 0.0 },
90 }
91 }
92}