main.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. pub mod sim;
  2. mod stats;
  3. mod types;
  4. use std::{env, process};
  5. use crate::types::{Quorum, Region, NodeCount};
  6. use crate::stats::{CurrentStats, CumulativeStats};
  7. use crate::sim::Simulation;
  8. use rand_pcg::Pcg64;
  9. use rand::SeedableRng;
  10. // use log::{info, error, set_logger};
  11. // use simplelog::*;
  12. // use std::fs::File;
  13. fn usage(cmd: &String) {
  14. eprintln!("Usage: {} h m lg_r k g lg_c T S", cmd);
  15. eprintln!("h: number of honest nodes");
  16. eprintln!("m: number of malicious nodes");
  17. eprintln!("lg_r: log_2 of the number of regions");
  18. 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");
  19. eprintln!("g: desired number of nodes in a *region*");
  20. eprintln!("lg_c: log_2 of the number of regions per quorum");
  21. eprintln!("T: number of iterations after initialization");
  22. eprintln!("S: number of seeds");
  23. }
  24. fn run_print_errors(sim: &mut Simulation, is_init: bool, h: usize, m: usize, ctr: usize, max: usize) -> bool
  25. {
  26. let (prefix, iter, iters, inserted, inserted_below_bmax, rejoined_below_bmax, number_rejoined) = if is_init
  27. {
  28. let (init_iter, a, b, c, d) = sim.init(h, m);
  29. ("FAILED INIT ".to_string(), init_iter, m, a, b, c, d)
  30. }
  31. else
  32. {
  33. let (a, b, c, d) = sim.move_malicious();
  34. ("FAILED MOVE MALICIOUS ".to_string(), ctr, max, a, b, c, d)
  35. };
  36. if !inserted {
  37. let reason = "due to failed malicious node cuckoo insert";
  38. println!("{} iteration {} / {} {}", prefix, iter, iters, reason);
  39. }
  40. if !inserted_below_bmax {
  41. let reason = "as b_max was broken by moving malicious node";
  42. println!("{} iteration {} / {} {}", prefix, iter, iters, reason);
  43. }
  44. if !rejoined_below_bmax {
  45. let reason = "as b_max was broken by re-joining node".to_string();
  46. println!("{} iteration {} / {} {} {}", prefix, iter, iters, reason, number_rejoined + 1);
  47. }
  48. inserted && inserted_below_bmax && rejoined_below_bmax
  49. }
  50. fn run_sim_for_seed(h: NodeCount, m: NodeCount, lg_r: NodeCount, lg_c: NodeCount,
  51. k: NodeCount, g: NodeCount, iters: usize, seed: usize) ->
  52. (f64, NodeCount, NodeCount)
  53. {
  54. let blankregion = Region {
  55. num_honest: 0,
  56. num_malicious: 0,
  57. last_join: 0,
  58. num_nodes_since_last_primary_join: 0,
  59. };
  60. let blankquorum = Quorum {
  61. tot_honest: 0,
  62. tot_malicious: 0,
  63. tot_last_join: 0,
  64. };
  65. let mut sim = Simulation {
  66. done_init: false,
  67. now: 0,
  68. rand: Pcg64::seed_from_u64(seed as u64),
  69. quorums: Vec::new(),
  70. regions: Vec::new(),
  71. lg_regions_per_quorum: lg_c,
  72. num_region_mask: (1<<lg_r)-1,
  73. cur_stats: CurrentStats::default(),
  74. cum_stats: CumulativeStats::default(),
  75. k,
  76. g,
  77. };
  78. sim.regions.resize(1<<lg_r, blankregion);
  79. sim.quorums.resize(1<<(lg_r-lg_c), blankquorum);
  80. eprintln!("Starting simulation n={}, h={}, m={}, 2^r={} regions, CCR: k={}, desired quorum size: g={}, regions/quorum: 2^c={}, T={}, seed={}",
  81. h+m, h, m, 1 << lg_r, k, g, 1 << lg_c, iters, seed);
  82. let successful_init = run_print_errors(&mut sim, true, h, m, 0, 0);
  83. let mut successful_move_malicious = false;
  84. if successful_init {
  85. for iter in 0..iters {
  86. successful_move_malicious = run_print_errors(&mut sim, false, 0, 0, iter, iters);
  87. if !successful_move_malicious
  88. {break;}
  89. }
  90. }
  91. println!("Results for seed={} h={} m={} 2^r={} k={} g={} 2^c={} T={}:",
  92. seed, h, m, 1 << lg_r, k, g, 1<< lg_c, iters);
  93. sim.cum_stats.print();
  94. if successful_init && successful_move_malicious
  95. {
  96. (sim.cum_stats.max_b_0, sim.cum_stats.min_tot_nodes, sim.cum_stats.max_tot_nodes)
  97. } else {
  98. (999.0, 1000000, 0)
  99. }
  100. }
  101. fn main() {
  102. let args: Vec<String> = env::args().collect();
  103. if args.len() != 9 {
  104. usage(&args[0]);
  105. process::exit(1);
  106. }
  107. let valid_args: Vec<usize> = args.iter().enumerate()
  108. .filter(|(i, _)| *i != 0)
  109. .map(|(_, v)| v.parse::<usize>())
  110. .filter(|x| x.is_ok())
  111. .map(|x| x.unwrap())
  112. .collect();
  113. if valid_args.len() != 8 {
  114. usage(&args[0]);
  115. process::exit(1);
  116. }
  117. let h = valid_args[0];
  118. let m = valid_args[1];
  119. let lg_r = valid_args[2];
  120. let k = valid_args[3];
  121. let g = valid_args[4];
  122. let lg_c = valid_args[5];
  123. let iters = valid_args[6];
  124. let no_of_seeds = valid_args[7];
  125. if (lg_c > lg_r) | (k > g) {
  126. usage(&args[0]);
  127. process::exit(1);
  128. }
  129. let mut b_0_array : Vec<f64> = vec![999.0; no_of_seeds];
  130. let mut mins_array : Vec<NodeCount> = vec![1000; no_of_seeds];
  131. let mut maxs_array : Vec<NodeCount> = vec![0; no_of_seeds];
  132. for seed_ctr in 1..no_of_seeds + 1 {
  133. let (b0, mins, maxs) = run_sim_for_seed(h, m, lg_r, lg_c, k, g, iters, seed_ctr);
  134. b_0_array[seed_ctr - 1] = b0;
  135. mins_array[seed_ctr - 1] = mins;
  136. maxs_array[seed_ctr - 1] = maxs;
  137. }
  138. let max_b_0 = b_0_array.iter().cloned().fold(-1./0. /* -inf */, f64::max);
  139. let min_mins = mins_array.iter().cloned().fold(1000, NodeCount::min);
  140. let max_maxs = maxs_array.iter().cloned().fold(0, NodeCount::max);
  141. println!("FINAL Max_b_0={} min_s={} max_s={}", max_b_0, min_mins, max_maxs);
  142. }