2021-02-01 07:50:59 +00:00
|
|
|
use crate::parties::SimulatedParties;
|
|
|
|
use crate::server::SimulatedServer;
|
|
|
|
use rand_distr::Pareto;
|
|
|
|
use std::io::Write;
|
|
|
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
2021-02-14 04:43:54 +00:00
|
|
|
mod datasets;
|
2021-02-03 13:05:59 +00:00
|
|
|
mod oracle;
|
2021-02-01 07:50:59 +00:00
|
|
|
mod parties;
|
2021-02-13 07:36:04 +00:00
|
|
|
mod probability;
|
2021-02-14 04:43:54 +00:00
|
|
|
mod server;
|
2021-02-01 07:50:59 +00:00
|
|
|
use clap::Clap;
|
2021-02-02 02:33:43 +00:00
|
|
|
use tracing::event;
|
|
|
|
|
2021-02-14 04:43:54 +00:00
|
|
|
use crate::datasets::{CsvDataset, TemporalDataset};
|
2021-02-03 13:05:59 +00:00
|
|
|
use crate::oracle::Oracle;
|
2021-02-02 02:33:43 +00:00
|
|
|
use tracing::Level;
|
|
|
|
use tracing_subscriber;
|
|
|
|
use tracing_subscriber::FmtSubscriber;
|
2021-02-01 07:50:59 +00:00
|
|
|
|
|
|
|
#[derive(Clap)]
|
2021-02-01 20:20:30 +00:00
|
|
|
#[clap(version = "1.0", author = "Sarah Jamie Lewis <sarah@openprivacy.ca>")]
|
2021-02-01 07:50:59 +00:00
|
|
|
struct Opts {
|
|
|
|
/// the number of parties to simulate
|
|
|
|
#[clap(short, long, default_value = "10")]
|
|
|
|
num_parties: usize,
|
|
|
|
|
2021-02-13 07:36:04 +00:00
|
|
|
/// dataset
|
|
|
|
#[clap(short, long, default_value = "")]
|
|
|
|
dataset: String,
|
|
|
|
|
2021-02-01 07:50:59 +00:00
|
|
|
/// samples per round
|
|
|
|
#[clap(short, long, default_value = "10")]
|
|
|
|
samples_per_round: usize,
|
|
|
|
|
|
|
|
/// minimum false positive rate
|
2021-02-14 04:43:54 +00:00
|
|
|
#[clap(long, default_value = "1")]
|
2021-02-01 07:50:59 +00:00
|
|
|
min_p: usize,
|
|
|
|
|
|
|
|
/// maximum false positive rate
|
2021-02-14 04:43:54 +00:00
|
|
|
#[clap(long, default_value = "8")]
|
2021-02-01 07:50:59 +00:00
|
|
|
max_p: usize,
|
2021-02-02 02:33:43 +00:00
|
|
|
|
|
|
|
#[clap(short, long)]
|
|
|
|
trace: bool,
|
2021-02-03 00:38:45 +00:00
|
|
|
|
|
|
|
#[clap(short, long, default_value = "0")]
|
|
|
|
prob_entangled: f64,
|
2021-02-14 04:43:54 +00:00
|
|
|
|
|
|
|
#[clap(long, default_value = "0")]
|
|
|
|
sample: usize,
|
|
|
|
|
|
|
|
#[clap(long, default_value = "0")]
|
|
|
|
skip: usize,
|
2021-02-01 07:50:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let opts: Opts = Opts::parse();
|
2021-02-02 02:33:43 +00:00
|
|
|
let level = match opts.trace {
|
|
|
|
true => Level::TRACE,
|
|
|
|
_ => Level::INFO,
|
|
|
|
};
|
2021-02-03 13:05:59 +00:00
|
|
|
|
|
|
|
let mut oracle = Oracle::new();
|
2021-02-10 07:23:50 +00:00
|
|
|
let mut max = 0;
|
2021-02-03 13:05:59 +00:00
|
|
|
let subscriber = FmtSubscriber::default();
|
2021-02-02 02:33:43 +00:00
|
|
|
tracing::subscriber::with_default(subscriber, || {
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
let mut server = SimulatedServer::new();
|
2021-02-01 07:50:59 +00:00
|
|
|
|
2021-02-14 04:43:54 +00:00
|
|
|
if opts.dataset == "none" {
|
2021-02-13 07:36:04 +00:00
|
|
|
let simulated_parties = SimulatedParties::new_simulation(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, &mut oracle);
|
2021-02-14 04:43:54 +00:00
|
|
|
server.finalize();
|
2021-02-13 07:36:04 +00:00
|
|
|
}
|
2021-02-01 07:50:59 +00:00
|
|
|
|
2021-02-13 07:36:04 +00:00
|
|
|
let pareto = Pareto::new(1.0, 1.0).unwrap();
|
2021-02-01 07:50:59 +00:00
|
|
|
|
2021-02-13 07:36:04 +00:00
|
|
|
{
|
|
|
|
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, &mut oracle));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let dataset = CsvDataset::load_dataset(opts.dataset.as_str());
|
|
|
|
event!(Level::INFO, "Registering parties from {} which containts {}", opts.dataset, dataset.num_parties());
|
2021-02-14 04:43:54 +00:00
|
|
|
dataset.register_with_server(&mut server, &mut rng, opts.min_p, opts.max_p, &mut oracle);
|
|
|
|
server.finalize();
|
|
|
|
event!(Level::INFO, "Playing back {} events from {}", dataset.num_records(), opts.dataset);
|
|
|
|
let mut sample = dataset.num_records();
|
|
|
|
if opts.sample != 0 {
|
|
|
|
sample = opts.sample;
|
|
|
|
}
|
|
|
|
dataset.playthough_traffic(&mut server, &mut oracle, opts.sample, opts.skip, opts.prob_entangled, &mut rng);
|
2021-02-02 02:33:43 +00:00
|
|
|
}
|
2021-02-01 23:23:01 +00:00
|
|
|
|
2021-02-02 02:33:43 +00:00
|
|
|
{
|
2021-02-03 13:05:59 +00:00
|
|
|
let (server_oracle, round_stats, party_stats) = server.statistics();
|
2021-02-02 02:33:43 +00:00
|
|
|
let if_uniform = (round_stats.num_messages as f64) / (round_stats.num_registered_parties as f64);
|
|
|
|
event!(
|
|
|
|
Level::INFO,
|
|
|
|
"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);
|
2021-02-13 07:36:04 +00:00
|
|
|
for (index, (party, stats)) in party_stats.iter().enumerate() {
|
|
|
|
if stats.trivial_breaks > 0 || (stats.observed_messages > 2 && stats.observed_skew > 2.0) {
|
2021-02-02 02:33:43 +00:00
|
|
|
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,
|
2021-02-13 07:36:04 +00:00
|
|
|
"({}) Party {} | Ideal: {:>8.2} {:>8.2} | Observed: {:>8.2} ({:>6.2}) | Skew: {:>8.2} ({:>6.2}) | Trivial Attributions this Round: {}",
|
|
|
|
index,
|
2021-02-02 02:33:43 +00:00
|
|
|
party,
|
|
|
|
stats.ideal_rate,
|
|
|
|
stats.ideal_rate * (round_stats.num_messages as f64),
|
|
|
|
stats.observed_messages,
|
|
|
|
100.0 * stats.observed_rate,
|
|
|
|
stats.observed_skew_messages,
|
|
|
|
stats.observed_skew,
|
|
|
|
stats.trivial_breaks
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
}
|
2021-02-13 07:36:04 +00:00
|
|
|
let max = server_oracle.compile_to_dot("server_event.dot", true, false, 1.0);
|
2021-02-10 07:23:50 +00:00
|
|
|
println!("Max from server: {}", max);
|
2021-02-13 07:36:04 +00:00
|
|
|
oracle.compile_to_dot("actual_events.dot", false, false, 1.0);
|
2021-02-10 07:23:50 +00:00
|
|
|
|
2021-02-13 07:36:04 +00:00
|
|
|
//server_oracle.compile_to_dot("server_event_inverse.dot", true, true,max);
|
2021-02-01 07:50:59 +00:00
|
|
|
}
|
2021-02-02 02:33:43 +00:00
|
|
|
});
|
2021-02-01 07:50:59 +00:00
|
|
|
}
|