Skip to content

Commit

Permalink
revises turbine peers shuffling order
Browse files Browse the repository at this point in the history
Turbine randomly shuffles cluster nodes on a broadcast tree for each
shred. This requires knowing the stakes and nodes' contact-infos (from
gossip).

However gossip is subject to partitioning and propogation delays.
Additionally unstaked nodes may join and leave the cluster at any
moment, changing the cluster view from one node to another.

This commit:
* Always arranges the unstaked nodes at the bottom of turbine broadcast
  tree.
* Staked nodes are always included regardless of if their contact-info
  is available in gossip or not.
* Uses the unbiased WeightedShuffle construct for shuffling nodes.
  • Loading branch information
behzadnouri committed Oct 7, 2021
1 parent 5e431fb commit f9f816b
Show file tree
Hide file tree
Showing 7 changed files with 355 additions and 64 deletions.
18 changes: 9 additions & 9 deletions core/src/broadcast_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use {
Sender as CrossbeamSender,
},
itertools::Itertools,
solana_gossip::cluster_info::{ClusterInfo, ClusterInfoError},
solana_gossip::cluster_info::{ClusterInfo, ClusterInfoError, DATA_PLANE_FANOUT},
solana_ledger::{blockstore::Blockstore, shred::Shred},
solana_measure::measure::Measure,
solana_metrics::{inc_new_counter_error, inc_new_counter_info},
Expand All @@ -33,6 +33,7 @@ use {
},
std::{
collections::HashMap,
iter::repeat,
net::UdpSocket,
sync::{
atomic::{AtomicBool, Ordering},
Expand Down Expand Up @@ -412,8 +413,6 @@ pub fn broadcast_shreds(
) -> Result<()> {
let mut result = Ok(());
let mut shred_select = Measure::start("shred_select");
// Only the leader broadcasts shreds.
let leader = cluster_info.id();
let (root_bank, working_bank) = {
let bank_forks = bank_forks.read().unwrap();
(bank_forks.root_bank(), bank_forks.working_bank())
Expand All @@ -427,12 +426,13 @@ pub fn broadcast_shreds(
cluster_nodes_cache.get(slot, &root_bank, &working_bank, cluster_info);
update_peer_stats(&cluster_nodes, last_datapoint_submit);
let root_bank = root_bank.clone();
shreds.filter_map(move |shred| {
let seed = shred.seed(leader, &root_bank);
let node = cluster_nodes.get_broadcast_peer(seed)?;
socket_addr_space
.check(&node.tvu)
.then(|| (&shred.payload, node.tvu))
shreds.flat_map(move |shred| {
repeat(&shred.payload).zip(cluster_nodes.get_broadcast_addrs(
shred,
&root_bank,
DATA_PLANE_FANOUT,
socket_addr_space,
))
})
})
.collect();
Expand Down
13 changes: 11 additions & 2 deletions core/src/broadcast_stage/broadcast_duplicates_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use {
crate::cluster_nodes::ClusterNodesCache,
itertools::Itertools,
solana_entry::entry::Entry,
solana_gossip::cluster_info::DATA_PLANE_FANOUT,
solana_ledger::shred::Shredder,
solana_sdk::{
hash::Hash,
Expand Down Expand Up @@ -246,6 +247,11 @@ impl BroadcastRun for BroadcastDuplicatesRun {
(bank_forks.root_bank(), bank_forks.working_bank())
};
let self_pubkey = cluster_info.id();
let nodes: Vec<_> = cluster_info
.all_peers()
.into_iter()
.map(|(node, _)| node)
.collect();

// Creat cluster partition.
let cluster_partition: HashSet<Pubkey> = {
Expand Down Expand Up @@ -273,8 +279,11 @@ impl BroadcastRun for BroadcastDuplicatesRun {
let packets: Vec<_> = shreds
.iter()
.filter_map(|shred| {
let seed = shred.seed(self_pubkey, &root_bank);
let node = cluster_nodes.get_broadcast_peer(seed)?;
let addr = cluster_nodes
.get_broadcast_addrs(shred, &root_bank, DATA_PLANE_FANOUT, socket_addr_space)
.first()
.copied()?;
let node = nodes.iter().find(|node| node.tvu == addr)?;
if !socket_addr_space.check(&node.tvu) {
return None;
}
Expand Down
Loading

0 comments on commit f9f816b

Please sign in to comment.