### Update to the latest cuckoo simulation code

Ian Goldberg 2 years ago
parent
commit
64ebbe5d68

#### + 0 - 99 cuckoo_simulation/cuckoo_vars.py View File

 ``@@ -1,99 +0,0 @@`` ``-import math`` ``-`` ``-def get_b_0(k, epsilon, ell, u):`` ``- # plot([(1+(1+u)*epsilon*x)/((1-ell)*x+(1+u)*epsilon*x+1), 0.25], (x, 0, 1))`` ``- return ((1+(1+u)*epsilon*k)/((1-ell)*k+(1+u)*epsilon*k+1))`` ``-`` ``-def get_delta_e(phi_e, gamma, K, n, epsilon):`` ``- return math.sqrt(abs(math.log(phi_e)*32*epsilon/(gamma*K**2*math.log(n))))`` ``-`` ``-def get_phi_e(delta_e, gamma, K, n, epsilon):`` ``- return math.exp(-1*gamma*((delta_e*K)**2)*math.log(n)/(32*epsilon))`` ``-`` ``-def get_delta_age_ell(phi_age_ell, c, K, n):`` ``- C=c*math.log(n)`` ``- return math.sqrt((2*C*K/n) - (2*math.log(phi_age_ell)/C))`` ``-`` ``-def get_phi_age_ell(delta_age_ell, C, K, n):`` ``- return math.exp(((C**2)*K/n) - ((delta_age_ell**2)*C/2))`` ``-`` ``-def get_delta_age_u(u, c, K, n):`` ``- C=c*math.log(n)`` ``- #delta_age_u**2/(1+delta_age_u)=A`` ``- A = ((2*C*K/n) - (2*math.log(u)/C))`` ``- #quadratic of the form x^2 - A*x - A = 0`` ``- #only one positive root as A is always positive.`` ``- root = 0.5 * (A + math.sqrt(A**2+4*A))`` ``- return root`` ``-`` ``-def get_phi_age_u(delta_age_u, C, K, n):`` ``- return math.exp(((C**2)*K/n) - ((delta_age_u**2)*C/(2*(1+delta_age_u))))`` ``-`` ``-def get_delta_n(gamma, epsilon, K, n):`` ``- return gamma*K*(math.log(n))**3/(epsilon*n)`` ``-`` ``-def get_delta_ell(delta_e, delta_age_ell, delta_n):`` ``- return delta_e + delta_age_ell - (delta_e * delta_age_ell) - ((1 - delta_e) * delta_n)`` ``-`` ``-def get_delta_u(delta_e, delta_age_u, delta_n):`` ``- return delta_e + delta_age_u + delta_e * delta_age_u + ((1 + delta_e) * delta_n)`` ``-`` ``-def get_p_i(phi_e, epsilon, phi_age_ell, phi_age_u, C):`` ``- phi_e_honest = phi_e**C`` ``- print(phi_e_honest)`` ``- phi_e_byz = (phi_e**(epsilon**2))**C`` ``- print(phi_e_byz)`` ``- p1 = phi_e_honest + 2*phi_age_ell + phi_e_byz`` ``- p2 = phi_e_honest + 2*phi_age_u + phi_e_byz`` ``- p3 = phi_e_honest + phi_age_ell`` ``- p4 = phi_e_byz + phi_age_u`` ``- return [p1, p2, p3, p4]`` ``-`` ``-n=10**8`` ``-K=20`` ``-c=40`` ``-C=c*math.log(n)`` ``-gamma=1`` ``-epsilon=0.2`` ``-`` ``-delta_e = 0.1`` ``-delta_age_ell = 0.12`` ``-delta_age_u = 0.11`` ``-`` ``-#phi_age_ell_1=0.02`` ``-#phi_age_u_1=0.02`` ``-#phi_e=5*(10**-30)`` ``-`` ``-#delta_age_u_1 = get_delta_age_u(phi_age_u_1, c, K, n)`` ``-#print("delta_age_u is: ", delta_age_u_1)`` ``-`` ``-#delta_age_ell_1 = get_delta_age_ell(phi_age_ell_1, c, K, n)`` ``-#print("delta_age_l is: ", delta_age_ell_1)`` ``-`` ``-delta_e_2 = get_delta_e(5*(10**-30), gamma, K, n, epsilon)`` ``-print("delta_e_2 is: ", delta_e_2)`` ``-`` ``-delta_n = get_delta_n(gamma, epsilon, K, n)`` ``-print("delta_n is: ", delta_n)`` ``-`` ``-delta_ell = get_delta_ell(delta_e, delta_age_ell, delta_n)`` ``-print("delta_ell is: ", delta_ell)`` ``-`` ``-delta_u = get_delta_u(delta_e, delta_age_ell, delta_n)`` ``-print("delta_u is: ", delta_u)`` ``-`` ``-b_0 = get_b_0(K, epsilon, delta_ell, delta_u)`` ``-print("b_0 is: ", b_0)`` ``-`` ``-phi_age_ell = get_phi_age_ell(delta_age_ell, C, K, n)`` ``-print("phi_age_ell is: ", phi_age_ell)`` ``-`` ``-phi_age_u = get_phi_age_u(delta_age_u, C, K, n)`` ``-print("phi_age_u is: ", phi_age_u)`` ``-`` ``-phi_e = get_phi_e(delta_e, gamma, K, n, epsilon)`` ``-print("phi_e is: ", phi_e)`` ``-print("phi_e^(epsilon^2) is: ", phi_e**(epsilon**2))`` ``-`` ``-[p1, p2, p3, p4] = get_p_i(phi_e, epsilon, phi_age_ell, phi_age_u, C)`` ``-print(p1, p2, p3, p4)``

#### + 35 - 0 cuckoo_simulation/find_m View File

 ``@@ -0,0 +1,35 @@`` ``+#!/bin/bash`` ``+`` ``+if [ \$# != 3 ]; then`` ``+ echo "Usage: \$0 g lgr lgc" >&2`` ``+ exit 1`` ``+fi`` ``+`` ``+g=\$1`` ``+lgr=\$2`` ``+lgc=\$3`` ``+n=\$((g< \$((mlow+1)) && (mhigh-mlow)*100 > mhigh)) = 1 ]; do`` ``+ mmid=\$(((mhigh + mlow)/2))`` ``+ b0mid=\$(runm \$mmid)`` ``+ echo \$mmid \$b0mid`` ``+ if [ \$b0mid \< 0.25 ]; then`` ``+ mlow=\$mmid`` ``+ else`` ``+ mhigh=\$mmid`` ``+ fi`` ``+done`` ``+echo \$mlow > \${gdir}/m.out``

#### + 22 - 0 cuckoo_simulation/run_m View File

 ``@@ -0,0 +1,22 @@`` ``+#!/bin/bash`` ``+`` ``+if [ \$# != 4 ]; then`` ``+ echo "Usage: \$0 g lgr lgc m" >&2`` ``+ exit 1`` ``+fi`` ``+`` ``+g=\$1`` ``+lgr=\$2`` ``+lgc=\$3`` ``+m=\$4`` ``+n=\$((g<> run.log`` ``+ stdbuf -o 0 ./target/release/cuckoo_simulation \$h \$m \$lgr \$k \$g \$lgc 100000 10 > \${gdir}/\${mdir}/k\${k}.out 2>&1 &`` ``+done`` ``+wait``

#### + 104 - 47 cuckoo_simulation/src/main.rs View File

 ``@@ -3,69 +3,68 @@ mod stats;`` `` mod types;`` `` `` `` use std::{env, process};`` ``-use crate::types::{Quorum, Region};`` ``+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 r k g iters seed", cmd);`` ``+ 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!("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!("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!("seed: random seed");`` ``+ eprintln!("S: number of seeds");`` `` }`` ``-`` ``-fn main() {`` ``- let args: Vec = env::args().collect();`` ``-`` ``- if args.len() != 9 {`` ``- usage(&args[0]);`` ``- process::exit(1);`` ``+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)`` `` }`` ``-`` ``- 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);`` ``+ 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);`` `` }`` ``-`` ``- 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);`` ``+ 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`` ``+ last_join: 0,`` ``+ num_nodes_since_last_primary_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 {`` ``@@ -85,18 +84,76 @@ fn main() {`` `` sim.regions.resize(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);`` `` }``

#### + 129 - 59 cuckoo_simulation/src/sim.rs View File

 ``@@ -4,6 +4,7 @@ use crate::stats::{CumulativeStats, CurrentStats};`` `` use reservoir_sampling::unweighted::core::l;`` `` use rand_pcg::Pcg64;`` `` use rand::RngCore;`` ``+use rand::seq::SliceRandom;`` `` `` `` pub struct Simulation {`` `` pub done_init: bool,`` ``@@ -24,6 +25,12 @@ impl Simulation {`` `` (self.rand.next_u64() as RegionCount) & self.num_region_mask`` `` }`` `` `` ``+ pub fn random_shuffle_regions(&mut self, n:usize) -> Vec {`` ``+ let mut vec: Vec = (0..n as u32).collect();`` ``+ vec.shuffle(&mut self.rand);`` ``+ vec`` ``+ }`` ``+`` `` // Reservoir-sampling to pick which nodes to kick out for CCR`` `` fn pick_honest_malicious_nodes_to_kick_out(&mut self, m: NodeCount, n: NodeCount, n_bad: NodeCount) -> NodeCount {`` `` let mut selected_indices: Vec = vec![0usize; m as usize];`` ``@@ -35,32 +42,67 @@ impl Simulation {`` `` }`` `` `` `` // Kick-out nodes as per CCR.`` ``- fn kick_out_nodes(&mut self, region: RegionCount) {`` ``+ fn kick_out_nodes(&mut self, region: RegionCount) -> (bool, usize) {`` ``+ // This func will always be called after at least 1 malicious node is inserted into the quorum.`` ``+ // TODO Check: We only want to chuck out k*g'/g nodes out of the *existing* nodes in the quorum.`` ``+ // So effectively, the no. of malicious nodes is decremented by 1 here.`` ``+ let num_malicious = self.regions[region].num_malicious - 1;`` ``+ let current_region_size = num_malicious + self.regions[region].num_honest;`` ``+ let number_to_kick_out : usize = (self.k as f64 * current_region_size as f64/ self.g as f64).round() as usize;`` ``+ // println!(`` ``+ // "KICKING OUT: ***Region {}*** had {} honest {} malicious nodes = total of {} nodes.",`` ``+ // region,`` ``+ // self.regions[region].num_honest,`` ``+ // num_malicious,`` ``+ // current_region_size`` ``+ // );`` `` let quorum = region >> self.lg_regions_per_quorum;`` ``- let current_region_size = self.regions[region].num_malicious + self.regions[region].num_honest;`` ``- let number_to_kick_out : usize = ((self.k * current_region_size / self.g ) as f64).round() as usize;`` ``- let num_malicious_to_kick_out = self.pick_honest_malicious_nodes_to_kick_out(number_to_kick_out, current_region_size, self.regions[region].num_malicious);`` ``- let num_honest_to_kick_out = number_to_kick_out - num_malicious_to_kick_out;`` ``-`` ``- self.regions[region].num_malicious -= num_malicious_to_kick_out;`` ``- self.regions[region].num_honest -= num_honest_to_kick_out;`` ``- self.quorums[quorum].tot_malicious -= num_malicious_to_kick_out;`` ``- self.quorums[quorum].tot_honest -= num_honest_to_kick_out;`` ``-`` ``- // Re-insert each node that was kicked out earlier, into new quorums, while maintaining`` ``- // honest/malicious status.`` ``- for _ in 0..num_honest_to_kick_out {`` ``- let secondary_join_region = self.rand_region();`` ``- self.insert(false, secondary_join_region, false);`` ``- }`` ``- for _ in 0..num_malicious_to_kick_out {`` ``- let secondary_join_region = self.rand_region();`` ``- self.insert(true, secondary_join_region, false);`` ``+`` ``+ if number_to_kick_out > 0`` ``+ {`` ``+ let num_malicious_to_kick_out = self.pick_honest_malicious_nodes_to_kick_out(number_to_kick_out, current_region_size, num_malicious);`` ``+ let num_honest_to_kick_out = number_to_kick_out - num_malicious_to_kick_out;`` ``+ // println!("KICKING OUT: We choose to kick out {} honest {} malicious nodes = total of {} nodes.",`` ``+ // num_honest_to_kick_out,`` ``+ // num_malicious_to_kick_out,`` ``+ // number_to_kick_out`` ``+ // );`` ``+`` ``+ self.regions[region].num_malicious -= num_malicious_to_kick_out;`` ``+ self.regions[region].num_honest -= num_honest_to_kick_out;`` ``+ self.quorums[quorum].tot_malicious -= num_malicious_to_kick_out;`` ``+ self.quorums[quorum].tot_honest -= num_honest_to_kick_out;`` ``+`` ``+ // Re-insert each node that was kicked out earlier, into new quorums, while maintaining`` ``+ // honest/malicious status.`` ``+ for _ctr in 0..num_honest_to_kick_out {`` ``+ let secondary_join_region = self.rand_region();`` ``+ // Don't need to check the return value as it'll continue to be true (only honest nodes were inserted)`` ``+ self.insert(false, secondary_join_region, false);`` ``+ // println!(`` ``+ // "KICKING OUT: honest node {} to region {}",`` ``+ // ctr, secondary_join_region`` ``+ // );`` ``+ }`` ``+ for ctr in 0..num_malicious_to_kick_out {`` ``+ let secondary_join_region = self.rand_region();`` ``+ let below_bmax = self.insert(true, secondary_join_region, false);`` ``+ if !below_bmax`` ``+ {`` ``+ return (below_bmax, ctr + 1);`` ``+ }`` ``+ // println!(`` ``+ // "KICKING OUT: malicious node {} to region {}",`` ``+ // ctr, secondary_join_region`` ``+ // );`` ``+ }`` ``+ return (true, num_malicious_to_kick_out)`` `` }`` ``+ (true, 0)`` `` }`` `` `` `` // Insert a new node into a given region in the DHT.`` ``- fn insert(&mut self, is_malicious: bool, region: RegionCount, is_primary_join: bool) {`` ``+ fn insert(&mut self, is_malicious: bool, region: RegionCount, is_primary_join: bool) -> bool {`` `` let quorum = region >> self.lg_regions_per_quorum;`` `` `` `` // Insert the new node into that region.`` ``@@ -73,92 +115,120 @@ impl Simulation {`` `` self.quorums[quorum].tot_honest += 1;`` `` }`` `` if is_primary_join {`` ``- self.quorums[quorum].num_nodes_since_last_primary_join = 0`` ``+ self.regions[region].num_nodes_since_last_primary_join = 0`` `` } else {`` ``- self.quorums[quorum].num_nodes_since_last_primary_join += 1`` ``+ self.regions[region].num_nodes_since_last_primary_join += 1`` `` }`` `` if self.done_init {`` ``- self.cur_stats.update(quorum, &self.quorums[quorum], false);`` ``+ return self.cur_stats.update(quorum, &self.quorums[quorum], false);`` ``+ // if broke_b_max {`` ``+ // print!("FAILED INVARIANT b_0 < 1/3 while re-inserting cuckoo-ed out nodes");`` ``+ // }`` `` }`` ``+ true`` `` }`` `` `` ``- pub fn init(&mut self, num_honest: NodeCount, num_malicious: NodeCount) {`` ``+ pub fn init(&mut self, num_honest: NodeCount, num_malicious: NodeCount) -> (usize, bool, bool, bool, usize) {`` `` for _ in 0..num_honest {`` `` // The original honest nodes are simply "mapped" to random locations -`` `` let target_region = self.rand_region();`` ``+ // Don't need to check the return value as it'll always be true (b_0 max won't be broken as only honest nodes were inserted)`` `` self.insert(false, target_region, false);`` `` }`` ``- for _ in 0..num_malicious {`` ``- self.cuckoo_insert();`` ``+ for ctr in 0..num_malicious {`` ``+ let (inserted, inserted_below_bmax, rejoined_below_bmax, number_rejoined) = self.cuckoo_insert();`` ``+ if !inserted || !inserted_below_bmax || !rejoined_below_bmax {`` ``+ return (ctr, inserted, inserted_below_bmax, rejoined_below_bmax, number_rejoined );`` ``+ }`` `` }`` `` self.done_init = true;`` `` self.cur_stats.dirty = true;`` `` self.collect_stats();`` `` self.update_cumstats(true);`` ``+ (num_malicious, true, true, true, 0)`` `` }`` `` `` `` // Insert a new node into a random region in the DHT, then`` `` // evict a fraction of nodes in that region into random`` `` // regions in the DHT (but don't evict nodes from the regions`` `` // _those_ nodes land in).`` ``- pub fn cuckoo_insert(&mut self) {`` ``- loop {`` ``- // Pick a random region to put the new node into. Also get the quorum for that region.`` ``- let region = self.rand_region();`` ``- let quorum = region >> self.lg_regions_per_quorum;`` ``+ pub fn cuckoo_insert(&mut self) -> (bool, bool, bool, usize) {`` ``+ let regions_ordering = self.random_shuffle_regions(self.regions.len());`` ``+ // println!("Random permutation of target regions: {:?}", regions_ordering);`` `` `` ``- if self.quorums[quorum].num_nodes_since_last_primary_join >= self.k - 1 {`` ``- self.kick_out_nodes(region);`` ``- self.insert(true, region, true); // True for primary join`` ``+ for ctr in 0..regions_ordering.len() {`` ``+ // Pick a random region to put the new node into. Also get the quorum for that region.`` ``+ let region = regions_ordering[ctr] as usize;`` ``+ // println!(`` ``+ // "TRYING CUCKOO INSERT: target region {} quorum {} no. of nodes since last 1ary join {} k {}",`` ``+ // region, quorum, self.regions[region].num_nodes_since_last_primary_join, self.k`` ``+ // );`` ``+ if self.regions[region].num_nodes_since_last_primary_join >= self.k - 1 {`` ``+ // println!("------ SUCCESSFUL CUCKOO INSERT: target region {}", region);`` ``+ let below_bmax_insert_own = self.insert(true, region, true); // True for primary join`` ``+ let (below_bmax_insert_kicked_out, no_of_malicious_kicked_out) = self.kick_out_nodes(region);`` `` `` `` // Update the age of the region that was emptied out.`` `` // self.quorums[quorum].tot_last_join += self.now - last_join;`` `` self.now += 1;`` `` // Cuckoo-ing after initialization: update stats for the quorum with the cuckood-out region`` `` if self.done_init {`` ``- self.cur_stats.update(quorum, &self.quorums[quorum], false);`` ``+ // as it's being updated in the collect_stats call essentially.`` ``+ // self.cur_stats.update(quorum, &self.quorums[quorum], false);`` `` self.collect_stats();`` `` self.update_cumstats(false);`` `` }`` ``- break;`` ``+ return (true, below_bmax_insert_own, below_bmax_insert_kicked_out, no_of_malicious_kicked_out)`` `` }`` `` }`` ``+ (false, true, true, 0)`` `` }`` `` `` `` // Remove an existing malicious node from the quorum that has the lowest fraction of faulty nodes`` ``- pub fn move_malicious(&mut self) {`` ``- let find_min_b_0_quorum = || {`` ``- let compute_b_0 = |q: Quorum| {`` ``- let b_0: f64 = if q.tot_honest > 0 {`` ``- (q.tot_malicious as f64) /`` ``- (q.tot_honest as f64)`` ``- } else if q.tot_malicious > 0 {`` ``- 1000000.0`` ``- } else {`` ``- 0.0`` ``- };`` ``- b_0`` ``+ pub fn move_malicious(&mut self) -> (bool, bool, bool, usize) {`` ``+ let find_min_b_0_region = || {`` ``+ let compute_b_0 = |r: Region| {`` ``+ (r.num_malicious as f64) / (r.num_honest as f64 + r.num_malicious as f64)`` `` };`` `` `` ``- let b_0_array: Vec = self.quorums.iter().map(|&q| compute_b_0(q)).collect();`` ``- let (min_b_0_quorum, _) = b_0_array.iter().enumerate().fold((0, 0.0), |(min_index, min_val), (index, &val)| if val < min_val {`` ``+ let b_0_array: Vec = self.regions.iter().map(|&q| compute_b_0(q)).collect();`` ``+ // eprintln!("b_0 array for");`` ``+ // let mut ctr: i8 = 0;`` ``+ // for &b_0 in &b_0_array {`` ``+ // print!("{} {},", ctr, b_0);`` ``+ // ctr = ctr + 1;`` ``+ // }`` ``+ // println!("\n");`` ``+ let (min_b_0_region, _) = b_0_array.iter().enumerate().fold((0, 1.0), |(min_index, min_val), (index, &val)| if val < min_val && val > 0.0 {`` ``+ // eprintln!(`` ``+ // "Replacing {} index {} with current val {} index {}",`` ``+ // min_val, min_index, val, index`` ``+ // );`` `` (index, val)`` `` } else {`` `` (min_index, min_val)`` `` });`` `` `` ``- min_b_0_quorum`` ``+ min_b_0_region`` `` };`` `` `` `` // Pick quorum with least fraction of byz nodes`` ``- let min_b_0_quorum = find_min_b_0_quorum();`` ``- if self.quorums[min_b_0_quorum].tot_malicious > 0 {`` ``- self.quorums[min_b_0_quorum].tot_malicious -= 1;`` ``- self.cur_stats.update(min_b_0_quorum, &self.quorums[min_b_0_quorum], false);`` ``+ let min_b_0_region = find_min_b_0_region();`` ``+ let min_b_0_quorum = min_b_0_region >> self.lg_regions_per_quorum;`` ``+ // eprintln!(`` ``+ // "MOVE MALICIOUS out of region {} which has {} honest {} malicious nodes",`` ``+ // min_b_0_region,`` ``+ // self.regions[min_b_0_region].num_honest,`` ``+ // self.regions[min_b_0_region].num_malicious`` ``+ // );`` ``+ self.regions[min_b_0_region].num_malicious -= 1;`` ``+ self.quorums[min_b_0_quorum].tot_malicious -= 1;`` ``+ // Don't need to check return value as b_0 for min_b_0_quorum decreases.`` ``+ self.cur_stats`` ``+ .update(min_b_0_quorum, &self.quorums[min_b_0_quorum], false);`` `` `` ``- // Insert it back into the DHT`` ``- self.cuckoo_insert();`` ``- }`` ``+ // Insert it back into the DHT`` ``+ return self.cuckoo_insert();`` `` }`` `` `` `` pub fn collect_stats(&mut self) {``

#### + 17 - 19 cuckoo_simulation/src/stats.rs View File

 ``@@ -22,11 +22,12 @@ pub struct CurrentStats {`` `` pub min_b_0: f64,`` `` pub min_b_0_quorum: RegionCount,`` `` pub max_b_0: f64,`` ``- pub max_epsilon_quorum: RegionCount,`` ``+ pub max_b_0_quorum: RegionCount,`` `` }`` `` `` `` impl CurrentStats {`` ``- pub fn update(&mut self, i: RegionCount, q: &Quorum, force: bool) {`` ``+ pub fn update(&mut self, i: RegionCount, q: &Quorum, force: bool) -> bool {`` ``+ let mut below_bmax: bool = true;`` `` if self.dirty == false && (`` `` self.min_tot_nodes_quorum == i ||`` `` self.max_tot_nodes_quorum == i ||`` ``@@ -37,7 +38,7 @@ impl CurrentStats {`` `` self.min_tot_last_join_quorum == i ||`` `` self.max_tot_last_join_quorum == i ||`` `` self.min_b_0_quorum == i ||`` ``- self.max_epsilon_quorum == i) {`` ``+ self.max_b_0_quorum == i) {`` `` self.dirty = true;`` `` }`` `` let nodes = q.tot_honest + q.tot_malicious;`` ``@@ -73,22 +74,19 @@ impl CurrentStats {`` `` self.max_tot_last_join = q.tot_last_join;`` `` self.max_tot_last_join_quorum = i;`` `` }`` ``- let b_0: f64 = if q.tot_honest > 0 {`` ``- (q.tot_malicious as f64) /`` ``- (q.tot_honest as f64)`` ``- } else if q.tot_malicious > 0 {`` ``- 1000000.0`` ``- } else {`` ``- 0.0`` ``- };`` ``- if force || b_0 < self.min_b_0 {`` ``+ let b_0 : f64 = (q.tot_malicious as f64) / (q.tot_honest as f64 + q.tot_malicious as f64);`` ``+ if force || (b_0 < self.min_b_0 && q.tot_malicious != 0) {`` `` self.min_b_0 = b_0;`` `` self.min_b_0_quorum = i;`` `` }`` `` if force || b_0 > self.max_b_0 {`` `` self.max_b_0 = b_0;`` ``- self.max_epsilon_quorum = i;`` ``+ self.max_b_0_quorum = i;`` ``+ if b_0 > 0.25 {`` ``+ below_bmax = false;`` ``+ }`` `` }`` ``+ below_bmax`` `` }`` `` `` `` #[allow(dead_code)]`` ``@@ -97,7 +95,7 @@ impl CurrentStats {`` `` print!("honest {} ({}) {} ({}) ", self.min_tot_honest, self.min_tot_honest_quorum, self.max_tot_honest, self.max_tot_honest_quorum);`` `` print!("malicious {} ({}) {} ({}) ", self.min_tot_malicious, self.min_tot_malicious_quorum, self.max_tot_malicious, self.max_tot_malicious_quorum);`` `` print!("lastjoin {} ({}) {} ({}) ", self.min_tot_last_join, self.min_tot_last_join_quorum, self.max_tot_last_join, self.max_tot_last_join_quorum);`` ``- println!("b_0 {} ({}) {} ({})", self.min_b_0, self.min_b_0_quorum, self.max_b_0, self.max_epsilon_quorum);`` ``+ println!("b_0 {} ({}) {} ({})", self.min_b_0, self.min_b_0_quorum, self.max_b_0, self.max_b_0_quorum);`` `` }`` `` }`` `` `` ``@@ -118,10 +116,10 @@ pub struct CumulativeStats {`` `` impl CumulativeStats {`` `` #[allow(dead_code)]`` `` pub fn print(&self) {`` ``- print!("nodes {} {} ", self.min_tot_nodes, self.max_tot_nodes);`` ``- print!("honest {} {} ", self.min_tot_honest, self.max_tot_honest);`` ``- print!("malicious {} {} ", self.min_tot_malicious, self.max_tot_malicious);`` ``- print!("age {} {} ", self.min_age, self.max_age);`` ``- println!("b_0 {} {}", self.min_b_0, self.max_b_0);`` ``+ println!("Total nodes: min {} max {}, honest: min {} max {}, malicious: min {} max {}, b_0: min {} max {}",`` ``+ self.min_tot_nodes, self.max_tot_nodes,`` ``+ self.min_tot_honest, self.max_tot_honest,`` ``+ self.min_tot_malicious, self.max_tot_malicious,`` ``+ self.min_b_0, self.max_b_0);`` `` }`` `` }``

#### + 0 - 8 cuckoo_simulation/src/test.rs View File

 ``@@ -1,8 +0,0 @@`` ``-use reservoir_sampling::unweighted::l;`` ``-`` ``-pub(crate) fn hehehehe () {`` ``- let mut sampled_arr = vec![0usize; 10];`` ``- println!("Orig array: {:?}", sampled_arr);`` ``- l(0usize..100, sampled_arr.as_mut_slice());`` ``- println!("Sampled array: {:?}", sampled_arr);`` ``-}``

#### + 1 - 2 cuckoo_simulation/src/types.rs View File

 ``@@ -1,5 +1,4 @@`` `` pub type NodeCount = usize;`` ``-pub type QuorumCount = usize;`` `` pub type TimeCount = usize;`` `` pub type RegionCount = usize;`` `` `` ``@@ -8,7 +7,6 @@ pub struct Quorum {`` `` pub tot_honest: NodeCount,`` `` pub tot_malicious: NodeCount,`` `` pub tot_last_join: TimeCount,`` ``- pub num_nodes_since_last_primary_join: NodeCount,`` `` }`` `` `` `` #[derive(Debug, Clone, Copy)]`` ``@@ -16,4 +14,5 @@ pub struct Region {`` `` pub(crate) num_honest: NodeCount,`` `` pub(crate) num_malicious: NodeCount,`` `` pub(crate) last_join: TimeCount,`` ``+ pub num_nodes_since_last_primary_join: NodeCount,`` `` }``