use {
crate::{crds_data::CrdsData, crds_value::CrdsValue},
solana_pubkey::Pubkey,
std::collections::HashMap,
};
pub(crate) enum GossipFilterDirection {
Ingress,
EgressPush,
EgressPullResponse,
}
const MIN_NUM_STAKED_NODES: usize = 500;
pub(crate) const MIN_STAKE_FOR_GOSSIP: u64 = solana_native_token::LAMPORTS_PER_SOL;
#[inline]
#[must_use]
pub(crate) fn should_retain_crds_value(
value: &CrdsValue,
stakes: &HashMap<Pubkey, u64>,
direction: GossipFilterDirection,
) -> bool {
let retain_if_staked = || {
stakes.len() < MIN_NUM_STAKED_NODES || {
let stake = stakes.get(&value.pubkey()).copied();
stake.unwrap_or_default() >= MIN_STAKE_FOR_GOSSIP
}
};
use GossipFilterDirection::*;
match value.data() {
CrdsData::ContactInfo(_) => true,
CrdsData::SnapshotHashes(_) => true,
CrdsData::DuplicateShred(_, _) => retain_if_staked(),
CrdsData::LowestSlot(0, _)
| CrdsData::RestartHeaviestFork(_)
| CrdsData::RestartLastVotedForkSlots(_) => retain_if_staked(),
CrdsData::EpochSlots(_, _) => match direction {
Ingress => true,
EgressPush | EgressPullResponse => retain_if_staked(),
},
CrdsData::Vote(_, _) => match direction {
Ingress | EgressPush => true,
EgressPullResponse => retain_if_staked(),
},
CrdsData::AccountsHashes(_) => false,
CrdsData::LegacyContactInfo(_) => false,
CrdsData::LegacySnapshotHashes(_) => false,
CrdsData::LegacyVersion(_) => false,
CrdsData::LowestSlot(1.., _) => false,
CrdsData::NodeInstance(_) => false,
CrdsData::Version(_) => false,
}
}