fuzzytags-sim/src/server.rs

86 lines
3.0 KiB
Rust
Raw Normal View History

2021-02-01 07:50:59 +00:00
use fuzzytags::{FuzzyDetectionKey, FuzzyPublicKey, FuzzyTag};
use hashbrown::HashMap;
pub struct SimulatedServer {
keybase: Vec<(FuzzyDetectionKey, FuzzyPublicKey)>,
messages: Vec<FuzzyTag>,
tags_to_keys_cache: HashMap<String, Vec<FuzzyDetectionKey>>,
keys_to_tags_cache: HashMap<String, Vec<FuzzyTag>>,
}
pub struct PartyStatistics {
pub ideal_rate: f64,
pub expected_messages: f64,
pub observed_messages: usize,
pub observed_rate: f64,
pub observed_skew_messages: f64,
pub observed_skew: f64,
pub trivial_breaks: usize,
}
impl SimulatedServer {
pub fn new() -> SimulatedServer {
SimulatedServer {
keybase: vec![],
messages: vec![],
tags_to_keys_cache: HashMap::new(),
keys_to_tags_cache: HashMap::new(),
}
}
pub fn register_key(&mut self, detection_key: &FuzzyDetectionKey, public_key: &FuzzyPublicKey) {
self.keybase.push((detection_key.clone(), public_key.clone()));
self.keys_to_tags_cache.insert(detection_key.id(), vec![]);
}
pub fn add_message(&mut self, tag: FuzzyTag) {
self.messages.push(tag.clone());
self.tags_to_keys_cache.insert(tag.to_string(), vec![]);
}
pub fn test_messages(&mut self) {
for message in self.messages.iter() {
for (detection_key, _) in self.keybase.iter() {
if detection_key.test_tag(message) {
self.tags_to_keys_cache.get_mut(message.to_string().as_str()).unwrap().push((*detection_key).clone());
self.keys_to_tags_cache.get_mut(detection_key.id().as_str()).unwrap().push((*message).clone());
}
}
}
}
pub fn statistics(&self) -> HashMap<String, PartyStatistics> {
let mut stats = HashMap::new();
for (party, pub_key) in self.keybase.iter() {
let matched = self.keys_to_tags_cache[party.id().as_str()].clone();
let observed_messages = matched.len();
let ideal_rate = party.false_positive_probability();
let observed_rate = (observed_messages as f64) / (self.messages.len() as f64);
let expected_messages = ideal_rate * (self.messages.len() as f64);
let observed_skew_messages = expected_messages - (observed_messages as f64);
let observed_skew = observed_rate / ideal_rate;
let mut trivial_breaks = 0;
for tag in matched.iter() {
if self.tags_to_keys_cache[tag.to_string().as_str()].len() == 1 {
trivial_breaks += 1;
}
}
stats.insert(
pub_key.id(),
PartyStatistics {
ideal_rate,
expected_messages,
observed_messages,
observed_rate,
observed_skew_messages,
observed_skew,
trivial_breaks,
},
);
}
stats
}
}