pub mod sim; mod stats; mod types; use std::{env, process}; use crate::types::{Quorum, Region, NodeCount}; use crate::stats::{CurrentStats, CumulativeStats}; use crate::sim::Simulation; use rand_pcg::Pcg64; use rand::SeedableRng; // use log::{info, error, set_logger}; // use simplelog::*; // use std::fs::File; fn usage(cmd: &String) { eprintln!("Usage: {} h m lg_r k g lg_c T S", cmd); eprintln!("h: number of honest nodes"); eprintln!("m: number of malicious nodes"); eprintln!("lg_r: log_2 of the number of regions"); eprintln!("k: k - 1 no. of secondary joins in CCR before new primary joins are accepted, k*g/g' nodes cuckoo-ed out with each primary join"); eprintln!("g: desired number of nodes in a *region*"); eprintln!("lg_c: log_2 of the number of regions per quorum"); eprintln!("T: number of iterations after initialization"); eprintln!("S: number of seeds"); } fn run_print_errors(sim: &mut Simulation, is_init: bool, h: usize, m: usize, ctr: usize, max: usize) -> bool { let (prefix, iter, iters, inserted, inserted_below_bmax, rejoined_below_bmax, number_rejoined) = if is_init { let (init_iter, a, b, c, d) = sim.init(h, m); ("FAILED INIT ".to_string(), init_iter, m, a, b, c, d) } else { let (a, b, c, d) = sim.move_malicious(); ("FAILED MOVE MALICIOUS ".to_string(), ctr, max, a, b, c, d) }; if !inserted { let reason = "due to failed malicious node cuckoo insert"; println!("{} iteration {} / {} {}", prefix, iter, iters, reason); } if !inserted_below_bmax { let reason = "as b_max was broken by moving malicious node"; println!("{} iteration {} / {} {}", prefix, iter, iters, reason); } if !rejoined_below_bmax { let reason = "as b_max was broken by re-joining node".to_string(); println!("{} iteration {} / {} {} {}", prefix, iter, iters, reason, number_rejoined + 1); } inserted && inserted_below_bmax && rejoined_below_bmax } fn run_sim_for_seed(h: NodeCount, m: NodeCount, lg_r: NodeCount, lg_c: NodeCount, k: NodeCount, g: NodeCount, iters: usize, seed: usize) -> (f64, NodeCount, NodeCount) { let blankregion = Region { num_honest: 0, num_malicious: 0, last_join: 0, num_nodes_since_last_primary_join: 0, }; let blankquorum = Quorum { tot_honest: 0, tot_malicious: 0, tot_last_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< = 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 k = valid_args[3]; let g = valid_args[4]; let lg_c = valid_args[5]; let iters = valid_args[6]; let no_of_seeds = valid_args[7]; if (lg_c > lg_r) | (k > g) { usage(&args[0]); process::exit(1); } let mut b_0_array : Vec = vec![999.0; no_of_seeds]; let mut mins_array : Vec = vec![1000; no_of_seeds]; let mut maxs_array : Vec = vec![0; no_of_seeds]; for seed_ctr in 1..no_of_seeds + 1 { let (b0, mins, maxs) = run_sim_for_seed(h, m, lg_r, lg_c, k, g, iters, seed_ctr); b_0_array[seed_ctr - 1] = b0; mins_array[seed_ctr - 1] = mins; maxs_array[seed_ctr - 1] = maxs; } let max_b_0 = b_0_array.iter().cloned().fold(-1./0. /* -inf */, f64::max); let min_mins = mins_array.iter().cloned().fold(1000, NodeCount::min); let max_maxs = maxs_array.iter().cloned().fold(0, NodeCount::max); println!("FINAL Max_b_0={} min_s={} max_s={}", max_b_0, min_mins, max_maxs); }