Add Oracle and graphviz output
This commit is contained in:
parent
7ac7eaa193
commit
e681e35054
|
@ -13,5 +13,6 @@ rand_distr = "0.4.0"
|
||||||
hashbrown = "0.9.1"
|
hashbrown = "0.9.1"
|
||||||
termcolor = "1.1.2"
|
termcolor = "1.1.2"
|
||||||
clap = "3.0.0-beta.2"
|
clap = "3.0.0-beta.2"
|
||||||
tracing = "0.1.0"
|
tracing = "0.1.22"
|
||||||
tracing-subscriber = "0.2"
|
tracing-subscriber = "0.2.15"
|
||||||
|
hex = "0.4.2"
|
17
src/main.rs
17
src/main.rs
|
@ -3,11 +3,14 @@ use crate::server::SimulatedServer;
|
||||||
use rand_distr::Pareto;
|
use rand_distr::Pareto;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||||
|
mod oracle;
|
||||||
mod parties;
|
mod parties;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
use clap::Clap;
|
use clap::Clap;
|
||||||
use tracing::event;
|
use tracing::event;
|
||||||
|
|
||||||
|
use crate::oracle::Oracle;
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
use tracing_subscriber;
|
use tracing_subscriber;
|
||||||
use tracing_subscriber::FmtSubscriber;
|
use tracing_subscriber::FmtSubscriber;
|
||||||
|
@ -47,7 +50,10 @@ fn main() {
|
||||||
true => Level::TRACE,
|
true => Level::TRACE,
|
||||||
_ => Level::INFO,
|
_ => Level::INFO,
|
||||||
};
|
};
|
||||||
let subscriber = FmtSubscriber::builder().with_max_level(level).finish();
|
|
||||||
|
let mut oracle = Oracle::new();
|
||||||
|
|
||||||
|
let subscriber = FmtSubscriber::default();
|
||||||
tracing::subscriber::with_default(subscriber, || {
|
tracing::subscriber::with_default(subscriber, || {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut server = SimulatedServer::new();
|
let mut server = SimulatedServer::new();
|
||||||
|
@ -55,14 +61,14 @@ fn main() {
|
||||||
let simulated_parties = SimulatedParties::new_simulation(opts.num_parties, opts.gamma);
|
let simulated_parties = SimulatedParties::new_simulation(opts.num_parties, opts.gamma);
|
||||||
{
|
{
|
||||||
event!(Level::INFO, "Generating {} Parties and registering them with the server", opts.num_parties);
|
event!(Level::INFO, "Generating {} Parties and registering them with the server", opts.num_parties);
|
||||||
simulated_parties.register_with_server(&mut server, &mut rng, opts.min_p, opts.max_p);
|
simulated_parties.register_with_server(&mut server, &mut rng, opts.min_p, opts.max_p, &mut oracle);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pareto = Pareto::new(1.0, 1.0).unwrap();
|
let pareto = Pareto::new(1.0, 1.0).unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
event!(Level::INFO, "Simulating message sends using {} samples from a pareto distribution...", opts.samples_per_round);
|
event!(Level::INFO, "Simulating message sends using {} samples from a pareto distribution...", opts.samples_per_round);
|
||||||
(0..opts.samples_per_round).for_each(|_i| simulated_parties.sample_traffic(&mut server, &mut rng, pareto, opts.prob_entangled));
|
(0..opts.samples_per_round).for_each(|_i| simulated_parties.sample_traffic(&mut server, &mut rng, pareto, opts.prob_entangled, &mut oracle));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -71,7 +77,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let (round_stats, party_stats) = server.statistics();
|
let (server_oracle, round_stats, party_stats) = server.statistics();
|
||||||
let if_uniform = (round_stats.num_messages as f64) / (round_stats.num_registered_parties as f64);
|
let if_uniform = (round_stats.num_messages as f64) / (round_stats.num_registered_parties as f64);
|
||||||
event!(
|
event!(
|
||||||
Level::INFO,
|
Level::INFO,
|
||||||
|
@ -101,6 +107,9 @@ fn main() {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
server_oracle.compile_to_dot("server_event.dot", true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
oracle.compile_to_dot("actual_events.dot", false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
// todo would be neat to just make this a subscriber of the tracing log, but there doesn't
|
||||||
|
// seem to be a nice way for that API to do what we want.. so until then...
|
||||||
|
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Event {
|
||||||
|
sender: String,
|
||||||
|
intended_receiver: String,
|
||||||
|
entangled_receiver: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Oracle {
|
||||||
|
parties: Vec<String>,
|
||||||
|
actual_events: Vec<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Oracle {
|
||||||
|
pub fn new() -> Oracle {
|
||||||
|
Oracle {
|
||||||
|
parties: vec![],
|
||||||
|
actual_events: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_party(&mut self, party: String) {
|
||||||
|
self.parties.push(party);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_event(&mut self, sender: String, intended_receiver: String, entangled_receiver: Option<String>) {
|
||||||
|
self.actual_events.push(Event {
|
||||||
|
sender,
|
||||||
|
intended_receiver,
|
||||||
|
entangled_receiver,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compile_to_dot(&self, filename: &str, strict: bool) {
|
||||||
|
let mut output = File::create(filename).unwrap();
|
||||||
|
if strict {
|
||||||
|
write!(output, "strict ");
|
||||||
|
}
|
||||||
|
write!(output, "digraph {{\n");
|
||||||
|
write!(
|
||||||
|
output,
|
||||||
|
r#"K=2.5;
|
||||||
|
repulsiveforce=0.1;
|
||||||
|
overlap=true;
|
||||||
|
splines = true;
|
||||||
|
dpi=400;
|
||||||
|
penwidth = 0.8;
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
|
||||||
|
for party in self.parties.iter() {
|
||||||
|
let r = hex::decode(party).unwrap()[0];
|
||||||
|
let g = hex::decode(party).unwrap()[1];
|
||||||
|
let b = hex::decode(party).unwrap()[2];
|
||||||
|
writeln!(output, "\"{}\" [shape=point, color=\"#{:x}{:x}{:x}\"]", party, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in self.actual_events.iter() {
|
||||||
|
writeln!(output, "\"{}\" -> \"{}\" [arrowhead=none]", event.sender, event.intended_receiver);
|
||||||
|
match &event.entangled_receiver {
|
||||||
|
Some(entangled_receiver) => {
|
||||||
|
writeln!(output, "\"{}\" -> \"{}\" [arrowhead=none,style=dashed]", event.sender, entangled_receiver);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
write!(output, "}}");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::oracle::Oracle;
|
||||||
use crate::server::SimulatedServer;
|
use crate::server::SimulatedServer;
|
||||||
use fuzzytags::{FuzzyPublicKey, FuzzySecretKey};
|
use fuzzytags::{FuzzyPublicKey, FuzzySecretKey};
|
||||||
use rand::distributions::Distribution;
|
use rand::distributions::Distribution;
|
||||||
|
@ -22,24 +23,23 @@ impl SimulatedParties {
|
||||||
SimulatedParties { gamma, parties }
|
SimulatedParties { gamma, parties }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_with_server<R>(&self, server: &mut SimulatedServer, rng: &mut R, min_p: usize, max_p: usize)
|
pub fn register_with_server<R>(&self, server: &mut SimulatedServer, rng: &mut R, min_p: usize, max_p: usize, oracle: &mut Oracle)
|
||||||
where
|
where
|
||||||
R: Rng,
|
R: Rng,
|
||||||
{
|
{
|
||||||
let span = span!(Level::TRACE, "register_with_server");
|
|
||||||
let _enter = span.enter();
|
|
||||||
for party in self.parties.iter() {
|
for party in self.parties.iter() {
|
||||||
let n = rng.gen_range(min_p..max_p);
|
let n = rng.gen_range(min_p..max_p);
|
||||||
let span = span!(Level::TRACE, "{register}", party = party.public_key().id().as_str());
|
let span = span!(Level::INFO, "register", party = party.public_key().id().as_str());
|
||||||
let _enter = span.enter();
|
let _enter = span.enter();
|
||||||
let detection_key = party.extract(n);
|
let detection_key = party.extract(n);
|
||||||
event!(Level::TRACE, "create detection key {detection_key}", detection_key = detection_key.id().as_str());
|
event!(Level::TRACE, "create detection key {detection_key}", detection_key = detection_key.id().as_str());
|
||||||
event!(Level::TRACE, "register with server");
|
event!(Level::TRACE, "register with server");
|
||||||
server.register_key(&detection_key, &party.public_key());
|
server.register_key(&detection_key, &party.public_key());
|
||||||
|
oracle.register_party(party.public_key().id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample_traffic<R, D>(&self, server: &mut SimulatedServer, rng: &mut R, distribution: D, probs_entangled: f64)
|
pub fn sample_traffic<R, D>(&self, server: &mut SimulatedServer, rng: &mut R, distribution: D, probs_entangled: f64, oracle: &mut Oracle)
|
||||||
where
|
where
|
||||||
D: Distribution<f64>,
|
D: Distribution<f64>,
|
||||||
R: Rng,
|
R: Rng,
|
||||||
|
@ -47,31 +47,40 @@ impl SimulatedParties {
|
||||||
let span = span!(Level::INFO, "sample_traffic");
|
let span = span!(Level::INFO, "sample_traffic");
|
||||||
let _enter = span.enter();
|
let _enter = span.enter();
|
||||||
let v = distribution.sample(rng).to_u16().unwrap();
|
let v = distribution.sample(rng).to_u16().unwrap();
|
||||||
|
|
||||||
|
let sender = rng.gen_range(0..self.parties.len());
|
||||||
|
let sender_public_key = self.parties.get(sender).unwrap().public_key();
|
||||||
|
|
||||||
let receiver = rng.gen_range(0..self.parties.len());
|
let receiver = rng.gen_range(0..self.parties.len());
|
||||||
let receiver_public_key = self.parties.get(receiver).unwrap().public_key();
|
let receiver_public_key = self.parties.get(receiver).unwrap().public_key();
|
||||||
|
|
||||||
let entangle = rng.gen_bool(probs_entangled);
|
if sender != receiver {
|
||||||
if entangle {
|
let entangle = rng.gen_bool(probs_entangled);
|
||||||
let receiver_2 = rng.gen_range(0..self.parties.len());
|
if entangle {
|
||||||
let receiver_public_key_2 = self.parties.get(receiver_2).unwrap().public_key();
|
let receiver_2 = rng.gen_range(0..self.parties.len());
|
||||||
event!(
|
let receiver_public_key_2 = self.parties.get(receiver_2).unwrap().public_key();
|
||||||
Level::INFO,
|
event!(
|
||||||
"entangled send {party_1} {party_2}",
|
Level::INFO,
|
||||||
party_1 = receiver_public_key.id().as_str(),
|
"entangled send {party_1} {party_2}",
|
||||||
party_2 = receiver_public_key_2.id().as_str()
|
party_1 = receiver_public_key.id().as_str(),
|
||||||
);
|
party_2 = receiver_public_key_2.id().as_str()
|
||||||
|
);
|
||||||
|
|
||||||
for _i in 0..v {
|
for _i in 0..v {
|
||||||
let tag = FuzzyPublicKey::generate_entangled_tag(vec![receiver_public_key.clone(), receiver_public_key_2.clone()], self.gamma);
|
let tag = FuzzyPublicKey::generate_entangled_tag(vec![receiver_public_key.clone(), receiver_public_key_2.clone()], self.gamma);
|
||||||
event!(Level::TRACE, "message sent to server {tag}", tag = tag.to_string());
|
event!(Level::TRACE, "message sent to server {tag}", tag = tag.to_string());
|
||||||
server.add_message(tag);
|
server.add_message(tag, &sender_public_key);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
event!(Level::INFO, "regular send {party}", party = receiver_public_key.id().as_str());
|
oracle.add_event(sender_public_key.id().clone(), receiver_public_key.id(), Some(receiver_public_key_2.id()));
|
||||||
for _i in 0..v {
|
} else {
|
||||||
let tag = receiver_public_key.generate_tag();
|
event!(Level::INFO, "regular send {party}", party = receiver_public_key.id().as_str());
|
||||||
event!(Level::INFO, "message sent server {tag}", tag = tag.to_string());
|
for _i in 0..v {
|
||||||
server.add_message(tag);
|
let tag = receiver_public_key.generate_tag();
|
||||||
|
event!(Level::INFO, "message sent server {tag}", tag = tag.to_string());
|
||||||
|
server.add_message(tag, &sender_public_key);
|
||||||
|
}
|
||||||
|
oracle.add_event(sender_public_key.id().clone(), receiver_public_key.id(), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::oracle::Oracle;
|
||||||
use fuzzytags::{FuzzyDetectionKey, FuzzyPublicKey, FuzzyTag};
|
use fuzzytags::{FuzzyDetectionKey, FuzzyPublicKey, FuzzyTag};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use tracing::event;
|
use tracing::event;
|
||||||
|
@ -6,9 +7,10 @@ use tracing::Level;
|
||||||
|
|
||||||
pub struct SimulatedServer {
|
pub struct SimulatedServer {
|
||||||
keybase: Vec<(FuzzyDetectionKey, FuzzyPublicKey)>,
|
keybase: Vec<(FuzzyDetectionKey, FuzzyPublicKey)>,
|
||||||
messages: Vec<FuzzyTag>,
|
messages: Vec<(FuzzyTag, FuzzyPublicKey)>,
|
||||||
tags_to_keys_cache: HashMap<String, Vec<FuzzyPublicKey>>,
|
tags_to_keys_cache: HashMap<String, Vec<FuzzyPublicKey>>,
|
||||||
keys_to_tags_cache: HashMap<String, Vec<FuzzyTag>>,
|
keys_to_tags_cache: HashMap<String, Vec<FuzzyTag>>,
|
||||||
|
oracle: Oracle,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RoundStatistics {
|
pub struct RoundStatistics {
|
||||||
|
@ -34,35 +36,37 @@ impl SimulatedServer {
|
||||||
messages: vec![],
|
messages: vec![],
|
||||||
tags_to_keys_cache: HashMap::new(),
|
tags_to_keys_cache: HashMap::new(),
|
||||||
keys_to_tags_cache: HashMap::new(),
|
keys_to_tags_cache: HashMap::new(),
|
||||||
|
oracle: Oracle::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_key(&mut self, detection_key: &FuzzyDetectionKey, public_key: &FuzzyPublicKey) {
|
pub fn register_key(&mut self, detection_key: &FuzzyDetectionKey, public_key: &FuzzyPublicKey) {
|
||||||
self.keybase.push((detection_key.clone(), public_key.clone()));
|
self.keybase.push((detection_key.clone(), public_key.clone()));
|
||||||
self.keys_to_tags_cache.insert(public_key.id(), vec![]);
|
self.keys_to_tags_cache.insert(public_key.id(), vec![]);
|
||||||
|
self.oracle.register_party(public_key.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_message(&mut self, tag: FuzzyTag) {
|
pub fn add_message(&mut self, tag: FuzzyTag, sender_public_key: &FuzzyPublicKey) {
|
||||||
self.messages.push(tag.clone());
|
self.messages.push((tag.clone(), sender_public_key.clone()));
|
||||||
self.tags_to_keys_cache.insert(tag.to_string(), vec![]);
|
self.tags_to_keys_cache.insert(tag.to_string(), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_messages(&mut self) {
|
pub fn test_messages(&mut self) {
|
||||||
for message in self.messages.iter() {
|
for (message, sender) in self.messages.iter() {
|
||||||
for (detection_key, public_key) in self.keybase.iter() {
|
for (detection_key, public_key) in self.keybase.iter() {
|
||||||
let span = span!(Level::TRACE, "{detection}", party = public_key.id().as_str());
|
let span = span!(Level::TRACE, "{detection}", party = public_key.id().as_str());
|
||||||
let _enter = span.enter();
|
let _enter = span.enter();
|
||||||
if detection_key.test_tag(message) {
|
if detection_key.test_tag(message) {
|
||||||
event!(Level::TRACE, "Matched detection key for {key} to tag {tag} ", key = public_key.id(), tag = message.to_string());
|
event!(Level::TRACE, "Matched detection key for {key} to tag {tag} ", key = public_key.id(), tag = message.to_string());
|
||||||
self.tags_to_keys_cache.get_mut(message.to_string().as_str()).unwrap().push((*public_key).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());
|
self.keys_to_tags_cache.get_mut(public_key.id().as_str()).unwrap().push((*message).clone());
|
||||||
|
self.oracle.add_event(sender.id(), public_key.id(), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn statistics(&self) -> (RoundStatistics, HashMap<String, PartyStatistics>) {
|
pub fn statistics(&self) -> (Oracle, RoundStatistics, HashMap<String, PartyStatistics>) {
|
||||||
let mut party_stats = HashMap::new();
|
let mut party_stats = HashMap::new();
|
||||||
let round_stats = RoundStatistics {
|
let round_stats = RoundStatistics {
|
||||||
num_messages: self.messages.len(),
|
num_messages: self.messages.len(),
|
||||||
|
@ -98,6 +102,6 @@ impl SimulatedServer {
|
||||||
party_stats.insert(pub_key.id(), p_stats);
|
party_stats.insert(pub_key.id(), p_stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
(round_stats, party_stats)
|
(self.oracle.clone(), round_stats, party_stats)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue