pub struct NonceBook { /* private fields */ }Expand description
Capacity-bounded LRU+TTL store of
NonceObservations.
The store reuses the same
LruTtlStore primitive the
ChallengeMemory
uses (T83). That keeps eviction + expiry semantics
consistent across both short-horizon stores and satisfies
the “no new cache store” requirement.
§Example
use stygian_charon::token_lifecycle::{ChallengeClass, NonceBook};
use stygian_charon::vendor_classifier::VendorId;
use std::num::NonZeroUsize;
use std::time::Duration;
let book = NonceBook::with_defaults();
book.record(VendorId::Cloudflare, ChallengeClass::Interstitial, "nonce-1");
assert_eq!(book.observation_count(VendorId::Cloudflare, "nonce-1"), Some(1));Implementations§
Source§impl NonceBook
impl NonceBook
Sourcepub fn new(capacity: NonZeroUsize, ttl: Duration) -> Self
pub fn new(capacity: NonZeroUsize, ttl: Duration) -> Self
Create a new nonce book with explicit capacity and TTL.
§Example
use stygian_charon::token_lifecycle::NonceBook;
use std::num::NonZeroUsize;
use std::time::Duration;
let book = NonceBook::new(NonZeroUsize::new(8).expect("non-zero"), Duration::from_mins(1));
assert!(book.is_empty());Sourcepub fn with_default_ttl(capacity: NonZeroUsize) -> Self
pub fn with_default_ttl(capacity: NonZeroUsize) -> Self
Capacity-bounded NonceBook with DEFAULT_NONCE_TTL.
Sourcepub fn with_defaults() -> Self
pub fn with_defaults() -> Self
Capacity-bounded NonceBook with DEFAULT_NONCE_BOOK_CAPACITY
and DEFAULT_NONCE_TTL.
§Example
use stygian_charon::token_lifecycle::NonceBook;
let book = NonceBook::with_defaults();
assert_eq!(book.ttl(), stygian_charon::token_lifecycle::DEFAULT_NONCE_TTL);Sourcepub fn record(
&self,
vendor: VendorId,
challenge_class: ChallengeClass,
nonce: &str,
)
pub fn record( &self, vendor: VendorId, challenge_class: ChallengeClass, nonce: &str, )
Record an observation for a (vendor, nonce) tuple. The
observation count is incremented atomically with the
read-modify-write sequence; the LRU recency is not
bumped on the read so a high-volume key does not crowd
out less common keys.
§Example
use stygian_charon::token_lifecycle::{ChallengeClass, NonceBook};
use stygian_charon::vendor_classifier::VendorId;
let book = NonceBook::with_defaults();
book.record(VendorId::PerimeterX, ChallengeClass::IntegrityCheck, "n");
book.record(VendorId::PerimeterX, ChallengeClass::IntegrityCheck, "n");
assert_eq!(book.observation_count(VendorId::PerimeterX, "n"), Some(2));Sourcepub fn observation_count(&self, vendor: VendorId, nonce: &str) -> Option<u32>
pub fn observation_count(&self, vendor: VendorId, nonce: &str) -> Option<u32>
Look up the current observation count for a (vendor, nonce) tuple. Returns None when the key is absent or
has expired.
§Example
use stygian_charon::token_lifecycle::NonceBook;
use stygian_charon::vendor_classifier::VendorId;
let book = NonceBook::with_defaults();
assert!(book.observation_count(VendorId::Unknown, "nope").is_none());Sourcepub fn lookup(&self, vendor: VendorId, nonce: &str) -> Option<NonceObservation>
pub fn lookup(&self, vendor: VendorId, nonce: &str) -> Option<NonceObservation>
Look up the full NonceObservation for a (vendor, nonce) tuple.
Sourcepub fn invalidate(&self, vendor: VendorId, nonce: &str)
pub fn invalidate(&self, vendor: VendorId, nonce: &str)
Invalidate a single (vendor, nonce) key.