pub mod sim; mod stats; mod types; use std::{env, process}; use crate::types::{Quorum, Region}; use crate::stats::{CurrentStats, CumulativeStats}; use crate::sim::Simulation; use rand_pcg::Pcg64; use rand::SeedableRng; fn usage(cmd: &String) { eprintln!("Usage: {} h m r k g iters seed", cmd); eprintln!("h: number of honest nodes"); eprintln!("m: number of malicious nodes"); eprintln!("lg_r: log_2 of the number of regions"); eprintln!("lg_c: log_2 of the number of regions per quorum"); eprintln!("k: k - 1 no. of secondary joins in CCR before new primary joins are accepted"); eprintln!("g: desired number of nodes in a *region*"); eprintln!("T: number of iterations after initialization"); eprintln!("seed: random seed"); } fn main() { let args: Vec = env::args().collect(); if args.len() != 9 { usage(&args[0]); process::exit(1); } let valid_args: Vec = args.iter().enumerate() .filter(|(i, _)| *i != 0) .map(|(_, v)| v.parse::()) .filter(|x| x.is_ok()) .map(|x| x.unwrap()) .collect(); if valid_args.len() != 8 { usage(&args[0]); process::exit(1); } let h = valid_args[0]; let m = valid_args[1]; let lg_r = valid_args[2]; let lg_c = valid_args[3]; let k = valid_args[4]; let g = valid_args[5]; let iters = valid_args[6]; let seed = valid_args[7]; if (lg_c > lg_r) | (k > g) { usage(&args[0]); process::exit(1); } let blankregion = Region { num_honest: 0, num_malicious: 0, last_join: 0 }; let blankquorum = Quorum { tot_honest: 0, tot_malicious: 0, tot_last_join: 0, num_nodes_since_last_primary_join: 0, }; let mut sim = Simulation { done_init: false, now: 0, rand: Pcg64::seed_from_u64(seed as u64), quorums: Vec::new(), regions: Vec::new(), lg_regions_per_quorum: lg_c, num_region_mask: (1<