diff --git a/crates/wzp-relay/src/audio_scorer.rs b/crates/wzp-relay/src/audio_scorer.rs index c7abb47..1b5f656 100644 --- a/crates/wzp-relay/src/audio_scorer.rs +++ b/crates/wzp-relay/src/audio_scorer.rs @@ -20,7 +20,7 @@ const SILENCE_SIZE_THRESHOLD: usize = 16; /// Observation window for bitrate tracking. const BITRATE_WINDOW_SECS: u64 = 30; -/// Number of payload-size histogram bins. +// Number of payload-size histogram bins. // (SIZE_BINS reserved for future histogram-based bimodality) /// Verdict produced by the scorer after sufficient observation. @@ -190,7 +190,7 @@ impl AudioScorer { } } - Some(score.max(0.0).min(1.0)) + Some(score.clamp(0.0, 1.0)) } /// Map legitimacy score to a [`Verdict`]. @@ -299,7 +299,7 @@ impl AudioScorer { let large = self.size_samples.len() - small; let total = self.size_samples.len() as f64; let p_small = small as f64 / total; - let p_large = large as f64 / total; + let _p_large = large as f64 / total; // Max bimodality when both bins are equally populated (~0.5 each) let bimodality = 1.0 - (p_small - 0.5).abs() * 2.0; Some(bimodality) diff --git a/crates/wzp-relay/src/conformance.rs b/crates/wzp-relay/src/conformance.rs index 5741486..04763b9 100644 --- a/crates/wzp-relay/src/conformance.rs +++ b/crates/wzp-relay/src/conformance.rs @@ -27,6 +27,10 @@ pub enum Violation { RateCapExceeded, } +/// Error type returned when a [`TokenBucket`] does not hold enough tokens. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct TokenExhausted; + /// Simple token bucket for per-session rate capping (Tier E). /// /// Tokens represent bytes. The bucket refills at `refill_per_sec` bytes per @@ -61,9 +65,9 @@ impl TokenBucket { /// Attempt to consume `bytes` from the bucket. /// /// Refills based on elapsed time since the last call, then deducts the - /// cost. Returns `Ok(())` if enough tokens were available, `Err(())` - /// otherwise. - pub fn try_consume(&mut self, bytes: u64, now: Instant) -> Result<(), ()> { + /// cost. Returns `Ok(())` if enough tokens were available, + /// `Err(TokenExhausted)` otherwise. + pub fn try_consume(&mut self, bytes: u64, now: Instant) -> Result<(), TokenExhausted> { let elapsed = now.duration_since(self.last_refill); self.last_refill = now; self.tokens += elapsed.as_secs_f64() * self.refill_per_sec as f64; @@ -74,7 +78,7 @@ impl TokenBucket { self.tokens -= bytes as f64; Ok(()) } else { - Err(()) + Err(TokenExhausted) } } } diff --git a/crates/wzp-relay/src/presence.rs b/crates/wzp-relay/src/presence.rs index 85827ac..e17b2ed 100644 --- a/crates/wzp-relay/src/presence.rs +++ b/crates/wzp-relay/src/presence.rs @@ -63,6 +63,12 @@ pub struct PresenceRegistry { peers: HashMap, } +impl Default for PresenceRegistry { + fn default() -> Self { + Self::new() + } +} + impl PresenceRegistry { /// Create an empty registry. pub fn new() -> Self { diff --git a/crates/wzp-relay/src/response_policy.rs b/crates/wzp-relay/src/response_policy.rs index e990d63..b7a3a34 100644 --- a/crates/wzp-relay/src/response_policy.rs +++ b/crates/wzp-relay/src/response_policy.rs @@ -41,8 +41,6 @@ pub enum Action { pub struct ResponsePolicy { /// `(fingerprint, violation_code)` → last abusive instant. cooldowns: HashMap<(String, ViolationCode), Instant>, - /// Cool-down duration for first-time abuse. - cooldown_duration: Duration, /// Block duration for repeat abuse. block_duration: Duration, } @@ -51,8 +49,7 @@ impl ResponsePolicy { pub fn new() -> Self { Self { cooldowns: HashMap::new(), - cooldown_duration: Duration::from_secs(3600), // 1 h - block_duration: Duration::from_secs(86400), // 24 h + block_duration: Duration::from_secs(86400), // 24 h } }