use std::time::Duration;
#[derive(Debug, Clone, Copy)]
pub struct TokenBucket {
pub capacity: u32,
pub refill_per_second: u32,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct IssuanceRateLimiter {
pub long_tail_did_class: TokenBucket,
pub service_class: TokenBucket,
pub anonymous_class: TokenBucket,
pub recently_active_did_lru_cap: usize,
}
impl Default for IssuanceRateLimiter {
fn default() -> Self {
IssuanceRateLimiter {
long_tail_did_class: TokenBucket {
capacity: 1000,
refill_per_second: 100,
},
service_class: TokenBucket {
capacity: 10_000,
refill_per_second: 1000,
},
anonymous_class: TokenBucket {
capacity: 1000,
refill_per_second: 100,
},
recently_active_did_lru_cap: 10_000,
}
}
}
impl IssuanceRateLimiter {
#[must_use]
pub fn worst_case_refill(&self, b: &TokenBucket) -> Duration {
if b.refill_per_second == 0 {
Duration::MAX
} else {
Duration::from_secs(u64::from(b.capacity) / u64::from(b.refill_per_second))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_token_buckets_within_sane_bounds() {
let r = IssuanceRateLimiter::default();
assert!(r.service_class.capacity > r.long_tail_did_class.capacity);
assert!(r.long_tail_did_class.capacity > 0);
assert!(r.anonymous_class.capacity > 0);
assert_eq!(r.recently_active_did_lru_cap, 10_000);
}
}