use {
crate::banking_stage::LikeClusterInfo,
itertools::Itertools,
solana_clock::{FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, NUM_CONSECUTIVE_LEADER_SLOTS},
solana_gossip::{
cluster_info::ClusterInfo,
contact_info::{ContactInfoQuery, Protocol},
},
solana_poh::poh_recorder::PohRecorder,
std::{net::SocketAddr, sync::RwLock},
};
pub(crate) fn upcoming_leader_tpu_vote_sockets(
cluster_info: &ClusterInfo,
poh_recorder: &RwLock<PohRecorder>,
fanout_slots: u64,
protocol: Protocol,
) -> Vec<SocketAddr> {
let upcoming_leaders = {
let poh_recorder = poh_recorder.read().unwrap();
(0..fanout_slots)
.filter_map(|n_slots| poh_recorder.leader_after_n_slots(n_slots))
.collect_vec()
};
upcoming_leaders
.into_iter()
.dedup()
.filter_map(|leader_pubkey| {
cluster_info.lookup_contact_info(&leader_pubkey, |node| node.tpu_vote(protocol))?
})
.dedup()
.collect()
}
pub(crate) fn next_leaders(
cluster_info: &impl LikeClusterInfo,
poh_recorder: &RwLock<PohRecorder>,
max_count: u64,
port_selector: impl ContactInfoQuery<Option<SocketAddr>>,
) -> Vec<SocketAddr> {
let recorder = poh_recorder.read().unwrap();
let leader_pubkeys: Vec<_> = (0..max_count)
.filter_map(|i| {
recorder.leader_after_n_slots(
FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET + i * NUM_CONSECUTIVE_LEADER_SLOTS,
)
})
.collect();
drop(recorder);
leader_pubkeys
.iter()
.filter_map(|leader_pubkey| {
cluster_info.lookup_contact_info(leader_pubkey, &port_selector)?
})
.collect()
}