diff --git a/src/main.rs b/src/main.rs index dc2ab5a..9cafc2b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,17 +48,23 @@ fn main() { println!("Simulating Adversarial Server Processing Messages.."); server.test_messages(); - let round_statistics = server.statistics(); + let (round_stats, party_stats) = server.statistics(); + + let if_uniform = (round_stats.num_messages as f64) / (round_stats.num_registered_parties as f64); + println!( + "Round had {} messages, send to {} parties ({:.2} is uniform distribution)", + round_stats.num_messages, round_stats.num_registered_parties, if_uniform + ); let mut stdout = StandardStream::stdout(ColorChoice::Always); - for (party, stats) in round_statistics.iter() { - if stats.trivial_breaks > 0 || stats.observed_skew > 10.0 { + for (party, stats) in party_stats.iter() { + if stats.trivial_breaks > 0 || stats.observed_skew > (if_uniform * stats.ideal_rate) { stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red))).unwrap(); } else { stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green))).unwrap(); } writeln!( &mut stdout, - "Party {} | Ideal: {} | Observed: {} ({:.2}) | Skew: {} ({:.2}) | Trivial Attributions this Round: {}", + "Party {} | Ideal: {} | Observed: {} ({:.2}) | Skew: {} ({}) | Trivial Attributions this Round: {}", party, stats.ideal_rate, stats.observed_messages, diff --git a/src/parties.rs b/src/parties.rs index 38c065e..c1ec805 100644 --- a/src/parties.rs +++ b/src/parties.rs @@ -36,9 +36,10 @@ impl SimulatedParties { { let v = distribution.sample(rng).to_u16().unwrap(); let receiver = rng.gen_range(0..self.parties.len()); - println!("[Oracle] {} received {} messages", self.parties.get(receiver).unwrap().public_key().id(), v); + let receiver_public_key = self.parties.get(receiver).unwrap().public_key(); + println!("[Oracle] {} received {} messages", receiver_public_key.id(), v); for _i in 0..v { - let tag = self.parties.get(receiver).unwrap().public_key().generate_tag(); + let tag = receiver_public_key.generate_tag(); server.add_message(tag); //message_oracle.push(receiver); } diff --git a/src/server.rs b/src/server.rs index e830e11..b20968a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -4,10 +4,16 @@ use hashbrown::HashMap; pub struct SimulatedServer { keybase: Vec<(FuzzyDetectionKey, FuzzyPublicKey)>, messages: Vec, - tags_to_keys_cache: HashMap>, + tags_to_keys_cache: HashMap>, keys_to_tags_cache: HashMap>, } +pub struct RoundStatistics { + pub num_registered_parties: usize, + pub num_messages: usize, +} + +#[derive(Debug)] pub struct PartyStatistics { pub ideal_rate: f64, pub expected_messages: f64, @@ -30,7 +36,7 @@ impl SimulatedServer { 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![]); + self.keys_to_tags_cache.insert(public_key.id(), vec![]); } pub fn add_message(&mut self, tag: FuzzyTag) { @@ -40,24 +46,30 @@ impl SimulatedServer { pub fn test_messages(&mut self) { for message in self.messages.iter() { - for (detection_key, _) in self.keybase.iter() { + for (detection_key, public_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()); + self.tags_to_keys_cache.get_mut(message.to_string().as_str()).unwrap().push((*public_key).clone()); + + self.keys_to_tags_cache.get_mut(public_key.id().as_str()).unwrap().push((*message).clone()); } } } } - pub fn statistics(&self) -> HashMap { - let mut stats = HashMap::new(); + pub fn statistics(&self) -> (RoundStatistics, HashMap) { + let mut party_stats = HashMap::new(); + let round_stats = RoundStatistics { + num_messages: self.messages.len(), + num_registered_parties: self.keybase.len(), + }; for (party, pub_key) in self.keybase.iter() { - let matched = self.keys_to_tags_cache[party.id().as_str()].clone(); + let matched = self.keys_to_tags_cache[pub_key.id().as_str()].clone(); let observed_messages = matched.len(); let ideal_rate = party.false_positive_probability(); + let expected_messages = ideal_rate * (round_stats.num_messages as f64); + 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_messages = (observed_messages as f64) - expected_messages; let observed_skew = (observed_messages as f64) / expected_messages; let mut trivial_breaks = 0; @@ -67,19 +79,21 @@ impl SimulatedServer { } } - stats.insert( - pub_key.id(), - PartyStatistics { - ideal_rate, - expected_messages, - observed_messages, - observed_rate, - observed_skew_messages, - observed_skew, - trivial_breaks, - }, - ); + let p_stats = PartyStatistics { + ideal_rate, + expected_messages, + observed_messages, + observed_rate, + observed_skew_messages, + observed_skew, + trivial_breaks, + }; + + println!("{:?}", p_stats); + + party_stats.insert(pub_key.id(), p_stats); } - stats + + (round_stats, party_stats) } }