diff --git a/core/benches/cluster_nodes.rs b/core/benches/cluster_nodes.rs index 662902d2b..f22da675e 100644 --- a/core/benches/cluster_nodes.rs +++ b/core/benches/cluster_nodes.rs @@ -50,7 +50,7 @@ fn get_retransmit_peers_deterministic( 0, ); let (_root_distance, _neighbors, _children) = cluster_nodes.get_retransmit_peers( - *slot_leader, + slot_leader, &shred, root_bank, solana_gossip::cluster_info::DATA_PLANE_FANOUT, diff --git a/core/src/cluster_nodes.rs b/core/src/cluster_nodes.rs index 21038a065..795f7897a 100644 --- a/core/src/cluster_nodes.rs +++ b/core/src/cluster_nodes.rs @@ -122,7 +122,7 @@ impl ClusterNodes { socket_addr_space: &SocketAddrSpace, ) -> Vec { const MAX_CONTACT_INFO_AGE: Duration = Duration::from_secs(2 * 60); - let shred_seed = shred.seed(self.pubkey); + let shred_seed = shred.id().seed(&self.pubkey); let mut rng = ChaChaRng::from_seed(shred_seed); let index = match self.weighted_shuffle.first(&mut rng) { None => return Vec::default(), @@ -176,7 +176,7 @@ impl ClusterNodes { impl ClusterNodes { pub(crate) fn get_retransmit_addrs( &self, - slot_leader: Pubkey, + slot_leader: &Pubkey, shred: &Shred, root_bank: &Bank, fanout: usize, @@ -212,7 +212,7 @@ impl ClusterNodes { pub fn get_retransmit_peers( &self, - slot_leader: Pubkey, + slot_leader: &Pubkey, shred: &Shred, root_bank: &Bank, fanout: usize, @@ -221,12 +221,12 @@ impl ClusterNodes { Vec<&Node>, // neighbors Vec<&Node>, // children ) { - let shred_seed = shred.seed(slot_leader); + let shred_seed = shred.id().seed(slot_leader); let mut weighted_shuffle = self.weighted_shuffle.clone(); // Exclude slot leader from list of nodes. - if slot_leader == self.pubkey { + if slot_leader == &self.pubkey { error!("retransmit from slot leader: {}", slot_leader); - } else if let Some(index) = self.index.get(&slot_leader) { + } else if let Some(index) = self.index.get(slot_leader) { weighted_shuffle.remove_index(*index); }; let mut rng = ChaChaRng::from_seed(shred_seed); diff --git a/core/src/retransmit_stage.rs b/core/src/retransmit_stage.rs index ecc631da6..2385d7b46 100644 --- a/core/src/retransmit_stage.rs +++ b/core/src/retransmit_stage.rs @@ -255,7 +255,7 @@ fn retransmit( .map(|(index, (shred, slot_leader, cluster_nodes))| { let (root_distance, num_nodes) = retransmit_shred( &shred, - slot_leader, + &slot_leader, &root_bank, &cluster_nodes, socket_addr_space, @@ -274,7 +274,7 @@ fn retransmit( let index = thread_pool.current_thread_index().unwrap(); let (root_distance, num_nodes) = retransmit_shred( &shred, - slot_leader, + &slot_leader, &root_bank, &cluster_nodes, socket_addr_space, @@ -296,7 +296,7 @@ fn retransmit( fn retransmit_shred( shred: &Shred, - slot_leader: Pubkey, + slot_leader: &Pubkey, root_bank: &Bank, cluster_nodes: &ClusterNodes, socket_addr_space: &SocketAddrSpace, diff --git a/ledger/src/shred.rs b/ledger/src/shred.rs index 048dde7d5..22177c350 100644 --- a/ledger/src/shred.rs +++ b/ledger/src/shred.rs @@ -226,6 +226,17 @@ impl ShredId { pub(crate) fn unwrap(&self) -> (Slot, /*shred index:*/ u32, ShredType) { (self.0, self.1, self.2) } + + pub fn seed(&self, leader: &Pubkey) -> [u8; 32] { + let ShredId(slot, index, shred_type) = self; + hashv(&[ + &slot.to_le_bytes(), + &u8::from(*shred_type).to_le_bytes(), + &index.to_le_bytes(), + AsRef::<[u8]>::as_ref(leader), + ]) + .to_bytes() + } } /// Tuple which identifies erasure coding set that the shred belongs to. @@ -431,16 +442,6 @@ impl Shred { self.set_signature(signature); } - pub fn seed(&self, leader_pubkey: Pubkey) -> [u8; 32] { - hashv(&[ - &self.slot().to_le_bytes(), - &u8::from(self.shred_type()).to_le_bytes(), - &self.index().to_le_bytes(), - &leader_pubkey.to_bytes(), - ]) - .to_bytes() - } - #[inline] pub fn shred_type(&self) -> ShredType { ShredType::from(self.common_header().shred_variant) @@ -1076,6 +1077,31 @@ mod tests { } } + #[test] + fn test_shred_seed() { + let mut rng = ChaChaRng::from_seed([147u8; 32]); + let leader = Pubkey::new_from_array(rng.gen()); + let key = ShredId( + 141939602, // slot + 28685, // index + ShredType::Data, + ); + assert_eq!( + bs58::encode(key.seed(&leader)).into_string(), + "Gp4kUM4ZpWGQN5XSCyM9YHYWEBCAZLa94ZQuSgDE4r56" + ); + let leader = Pubkey::new_from_array(rng.gen()); + let key = ShredId( + 141945197, // slot + 23418, // index + ShredType::Code, + ); + assert_eq!( + bs58::encode(key.seed(&leader)).into_string(), + "G1gmFe1QUM8nhDApk6BqvPgw3TQV2Qc5bpKppa96qbVb" + ); + } + fn verify_shred_layout(shred: &Shred, packet: &Packet) { let data = layout::get_shred(packet).unwrap(); assert_eq!(layout::get_slot(data), Some(shred.slot()));