2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use rayon::iter::ParallelIterator;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use rayon::prelude::*;
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-02 17:35:03 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use serial_test_derive::serial;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-21 10:23:33 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use solana_core::cluster_info::{compute_retransmit_peers, ClusterInfo};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use solana_core::contact_info::ContactInfo;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use solana_sdk::pubkey::Pubkey;
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-30 21:31:35 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use std::collections::{HashMap, HashSet};
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use std::sync::mpsc::channel;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use std::sync::mpsc::TryRecvError;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use std::sync::mpsc::{Receiver, Sender};
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use std::sync::Arc;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use std::sync::Mutex;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use std::time::Instant;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								type Nodes = HashMap<Pubkey, (bool, HashSet<i32>, Receiver<(i32, bool)>)>;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn num_threads() -> usize {
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-16 12:53:13 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    num_cpus::get()
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/// Search for the a node with the given balance
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								fn find_insert_shred(id: &Pubkey, shred: i32, batches: &mut [Nodes]) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    batches.par_iter_mut().for_each(|batch| {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if batch.contains_key(id) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            let _ = batch.get_mut(id).unwrap().1.insert(shred);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								fn retransmit(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    mut shuffled_nodes: Vec<ContactInfo>,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    senders: &HashMap<Pubkey, Sender<(i32, bool)>>,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    cluster: &ClusterInfo,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    fanout: usize,
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    shred: i32,
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    retransmit: bool,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								) -> i32 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut seed = [0; 32];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut my_index = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut index = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    shuffled_nodes.retain(|c| {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if c.id == cluster.id() {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            my_index = index;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            false
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            index += 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            true
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    seed[0..4].copy_from_slice(&shred.to_le_bytes());
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-04 11:52:02 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let shuffled_indices = (0..shuffled_nodes.len()).collect();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let (neighbors, children) = compute_retransmit_peers(fanout, my_index, shuffled_indices);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    children.into_iter().for_each(|i| {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        let s = senders.get(&shuffled_nodes[i].id).unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        let _ = s.send((shred, retransmit));
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if retransmit {
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-04 11:52:02 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        neighbors.into_iter().for_each(|i| {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            let s = senders.get(&shuffled_nodes[i].id).unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            let _ = s.send((shred, false));
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    shred
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#[allow(clippy::type_complexity)]
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								fn run_simulation(stakes: &[u64], fanout: usize) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let num_threads = num_threads();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // set timeout to 5 minutes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let timeout = 60 * 5;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // describe the leader
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-30 21:37:33 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let leader_info = ContactInfo::new_localhost(&Pubkey::new_rand(), 0);
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-21 12:54:45 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let cluster_info = ClusterInfo::new_with_invalid_keypair(leader_info.clone());
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    // setup staked nodes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut staked_nodes = HashMap::new();
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // setup accounts for all nodes (leader has 0 bal)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let (s, r) = channel();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let senders: Arc<Mutex<HashMap<Pubkey, Sender<(i32, bool)>>>> =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Arc::new(Mutex::new(HashMap::new()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    senders.lock().unwrap().insert(leader_info.id, s);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut batches: Vec<Nodes> = Vec::with_capacity(num_threads);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    (0..num_threads).for_each(|_| batches.push(HashMap::new()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    batches
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        .get_mut(0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        .unwrap()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        .insert(leader_info.id, (false, HashSet::new(), r));
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let range: Vec<_> = (1..=stakes.len()).collect();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let chunk_size = (stakes.len() + num_threads - 1) / num_threads;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    range.chunks(chunk_size).for_each(|chunk| {
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        chunk.iter().for_each(|i| {
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            //distribute neighbors across threads to maximize parallel compute
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            let batch_ix = *i as usize % batches.len();
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-30 21:37:33 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            let node = ContactInfo::new_localhost(&Pubkey::new_rand(), 0);
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            staked_nodes.insert(node.id, stakes[*i - 1]);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            cluster_info.insert_info(node.clone());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            let (s, r) = channel();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            batches
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                .get_mut(batch_ix)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                .unwrap()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                .insert(node.id, (false, HashSet::new(), r));
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            senders.lock().unwrap().insert(node.id, s);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        })
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-21 12:54:45 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let c_info = cluster_info.clone_with_id(&cluster_info.id());
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-16 17:11:18 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let staked_nodes = Arc::new(staked_nodes);
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let shreds_len = 100;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let shuffled_peers: Vec<Vec<ContactInfo>> = (0..shreds_len as i32)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        .map(|i| {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            let mut seed = [0; 32];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            seed[0..4].copy_from_slice(&i.to_le_bytes());
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-04 11:52:02 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            let (peers, stakes_and_index) =
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-16 17:11:18 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                cluster_info.sorted_retransmit_peers_and_stakes(Some(staked_nodes.clone()));
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-08 14:41:16 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            let (_, shuffled_stakes_and_indexes) = ClusterInfo::shuffle_peers_and_index(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                &cluster_info.id(),
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-04 11:52:02 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                &peers,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                &stakes_and_index,
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-30 13:41:11 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                seed,
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-04 11:52:02 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            );
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            shuffled_stakes_and_indexes
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-04 11:52:02 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                .into_iter()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                .map(|(_, i)| peers[i].clone())
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                .collect()
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        })
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        .collect();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    // create some "shreds".
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-15 17:35:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    (0..shreds_len).for_each(|i| {
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        let broadcast_table = &shuffled_peers[i];
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        find_insert_shred(&broadcast_table[0].id, i as i32, &mut batches);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    assert!(!batches.is_empty());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-06 12:48:40 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    // start turbine simulation
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let now = Instant::now();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    batches.par_iter_mut().for_each(|batch| {
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        let mut remaining = batch.len();
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        let senders: HashMap<_, _> = senders.lock().unwrap().clone();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        while remaining > 0 {
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            for (id, (layer1_done, recv, r)) in batch.iter_mut() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                assert!(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    now.elapsed().as_secs() < timeout,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    "Timed out with {:?} remaining nodes",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    remaining
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                );
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-21 12:54:45 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                let cluster = c_info.clone_with_id(id);
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if !*layer1_done {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    recv.iter().for_each(|i| {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        retransmit(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            shuffled_peers[*i as usize].clone(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            &senders,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            &cluster,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            fanout,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            *i,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            true,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    *layer1_done = true;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                //send and recv
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if recv.len() < shreds_len {
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    loop {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        match r.try_recv() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            Ok((data, retx)) => {
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                if recv.insert(data) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                    let _ = retransmit(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                        shuffled_peers[data as usize].clone(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                        &senders,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                        &cluster,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                        fanout,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                        data,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                        retx,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                }
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 11:49:31 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                if recv.len() == shreds_len {
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 20:38:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                    remaining -= 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    break;
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            Err(TryRecvError::Disconnected) => break,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            Err(TryRecvError::Empty) => break,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Recommended to not run these tests in parallel (they are resource heavy and want all the compute)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//todo add tests with network failures
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Run with a single layer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[test]
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-02 17:35:03 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#[serial]
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn test_retransmit_small() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let stakes: Vec<_> = (0..200).map(|i| i).collect();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    run_simulation(&stakes, 200);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Make sure at least 2 layers are used
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[test]
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-02 17:35:03 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#[serial]
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn test_retransmit_medium() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let num_nodes = 2000;
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let stakes: Vec<_> = (0..num_nodes).map(|i| i).collect();
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    run_simulation(&stakes, 200);
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Make sure at least 2 layers are used but with equal stakes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[test]
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-02 17:35:03 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#[serial]
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								fn test_retransmit_medium_equal_stakes() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let num_nodes = 2000;
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let stakes: Vec<_> = (0..num_nodes).map(|_| 10).collect();
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    run_simulation(&stakes, 200);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Scale down the network and make sure many layers are used
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[test]
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-02 17:35:03 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#[serial]
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn test_retransmit_large() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let num_nodes = 4000;
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-19 21:07:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let stakes: Vec<_> = (0..num_nodes).map(|i| i).collect();
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-07 13:24:58 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    run_simulation(&stakes, 2);
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 09:46:30 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |