use super::signature_cache::SignatureCacheEntry;
use crate::signature_verification::{
reproducible_rng::reproducible_rng,
signature_cache::{SignatureCache, SignatureCacheStatistics},
};
use rand::RngCore;
fn random_signature_cache_entry<R: RngCore>(rng: &mut R) -> SignatureCacheEntry {
let mut pk = [0u8; 96];
let mut sig = [0u8; 48];
let mut msg = [0u8; 32];
rng.fill_bytes(&mut pk);
rng.fill_bytes(&mut sig);
rng.fill_bytes(&mut msg);
SignatureCacheEntry::new(&pk, &sig, &msg)
}
#[test]
fn should_have_signature_cache_behave_like_a_lru_cache() {
let cache_size = 1000;
let cache = SignatureCache::new(cache_size);
let rng = &mut reproducible_rng();
let mut entries = Vec::with_capacity(cache_size);
for i in 0..cache_size {
let expected_stats = SignatureCacheStatistics::new(i, 2 * i as u64, i as u64);
assert_eq!(cache.cache_statistics(), expected_stats);
let entry = random_signature_cache_entry(rng);
assert!(!cache.contains(&entry));
cache.insert(&entry);
assert!(cache.contains(&entry));
assert!(cache.contains(&entry));
entries.push(entry);
}
let expected_stats =
SignatureCacheStatistics::new(cache_size, 2 * cache_size as u64, cache_size as u64);
assert_eq!(cache.cache_statistics(), expected_stats);
for entry in &entries {
assert!(cache.contains(entry));
}
let expected_stats =
SignatureCacheStatistics::new(cache_size, 3 * cache_size as u64, cache_size as u64);
assert_eq!(cache.cache_statistics(), expected_stats);
for i in 0..cache_size {
let entry = random_signature_cache_entry(rng);
assert_eq!(cache.cache_statistics().size, cache_size);
assert!(!cache.contains(&entry));
cache.insert(&entry);
assert!(cache.contains(&entry));
assert_eq!(cache.cache_statistics().size, cache_size);
for entry in entries.iter().take(i) {
assert!(!cache.contains(entry));
}
}
for entry in &entries {
assert!(!cache.contains(entry));
}
}
#[test]
fn should_have_signature_cache_update_lru_status_after_cache_hit() {
let cache_size = 3;
let cache = SignatureCache::new(cache_size);
let rng = &mut reproducible_rng();
let entry1 = random_signature_cache_entry(rng);
let entry2 = random_signature_cache_entry(rng);
let entry3 = random_signature_cache_entry(rng);
let entry4 = random_signature_cache_entry(rng);
cache.insert(&entry1);
cache.insert(&entry2);
cache.insert(&entry3);
assert!(cache.contains(&entry1));
assert!(cache.contains(&entry2));
assert!(cache.contains(&entry3));
assert!(!cache.contains(&entry4));
cache.insert(&entry4);
assert!(cache.contains(&entry4));
assert!(cache.contains(&entry3));
assert!(cache.contains(&entry2));
assert!(!cache.contains(&entry1));
cache.insert(&entry1);
assert!(cache.contains(&entry1));
assert!(cache.contains(&entry2));
assert!(cache.contains(&entry3));
assert!(!cache.contains(&entry4));
}