fuzzytags-sim/src/main.rs

104 lines
3.8 KiB
Rust
Raw Normal View History

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};
mod parties;
mod server;
use clap::Clap;
use tracing::event;
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 {
/// Sets a custom config file. Could have been an Option<T> with no default too
#[clap(short, long, default_value = "24")]
gamma: usize,
/// the number of parties to simulate
#[clap(short, long, default_value = "10")]
num_parties: usize,
/// samples per round
#[clap(short, long, default_value = "10")]
samples_per_round: usize,
/// minimum false positive rate
#[clap(short, long, default_value = "1")]
min_p: usize,
/// maximum false positive rate
#[clap(short, long, default_value = "8")]
max_p: usize,
#[clap(short, long)]
trace: bool,
2021-02-01 07:50:59 +00:00
}
fn main() {
let opts: Opts = Opts::parse();
let level = match opts.trace {
true => Level::TRACE,
_ => Level::INFO,
};
let subscriber = FmtSubscriber::builder().with_max_level(level).finish();
tracing::subscriber::with_default(subscriber, || {
let mut rng = rand::thread_rng();
let mut server = SimulatedServer::new();
2021-02-01 07:50:59 +00:00
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);
simulated_parties.register_with_server(&mut server, &mut rng, opts.min_p, opts.max_p);
}
2021-02-01 07:50:59 +00:00
let pareto = Pareto::new(1.0, 1.0).unwrap();
2021-02-01 07:50:59 +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));
}
2021-02-01 07:50:59 +00:00
{
event!(Level::INFO, "Simulating Adversarial Server Processing Messages..");
server.test_messages();
}
{
let (round_stats, party_stats) = server.statistics();
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);
for (party, stats) in party_stats.iter() {
if stats.trivial_breaks > 0 || (stats.observed_messages > 2 && 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: {:>8.2} {:>8.2} | Observed: {:>8.2} ({:>6.2}) | Skew: {:>8.2} ({:>6.2}) | Trivial Attributions this Round: {}",
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-01 07:50:59 +00:00
}
});
2021-02-01 07:50:59 +00:00
}