diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs index 44664ac99..778f8319a 100644 --- a/gossip/src/cluster_info.rs +++ b/gossip/src/cluster_info.rs @@ -254,7 +254,7 @@ pub fn make_accounts_hashes_message( pub(crate) type Ping = ping_pong::Ping<[u8; GOSSIP_PING_TOKEN_SIZE]>; // TODO These messages should go through the gpu pipeline for spam filtering -#[frozen_abi(digest = "F2XvJ1e5qdQdtUcRhMNYAJFbMBJyFi3NRbfdfghzBajW")] +#[frozen_abi(digest = "skH6cJ1MHfUyJKVaTfRRDV9y29HjuRpfReFpxXMWNky")] #[derive(Serialize, Deserialize, Debug, AbiEnumVisitor, AbiExample)] #[allow(clippy::large_enum_variant)] pub(crate) enum Protocol { @@ -371,7 +371,7 @@ fn retain_staked(values: &mut Vec, stakes: &HashMap) { // Unstaked nodes can still help repair. CrdsData::EpochSlots(_, _) => true, // Unstaked nodes can still serve snapshots. - CrdsData::SnapshotHashes(_) => true, + CrdsData::SnapshotHashes(_) | CrdsData::IncrementalSnapshotHashes(_) => true, // Otherwise unstaked voting nodes will show up with no version in // the various dashboards. CrdsData::Version(_) => true, diff --git a/gossip/src/crds_value.rs b/gossip/src/crds_value.rs index b2ab4f9f6..d862572bc 100644 --- a/gossip/src/crds_value.rs +++ b/gossip/src/crds_value.rs @@ -91,6 +91,7 @@ pub enum CrdsData { Version(Version), NodeInstance(NodeInstance), DuplicateShred(DuplicateShredIndex, DuplicateShred), + IncrementalSnapshotHashes(IncrementalSnapshotHashes), } impl Sanitize for CrdsData { @@ -127,6 +128,7 @@ impl Sanitize for CrdsData { shred.sanitize() } } + CrdsData::IncrementalSnapshotHashes(val) => val.sanitize(), } } } @@ -204,6 +206,33 @@ impl SnapshotHashes { } } } + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, AbiExample)] +pub struct IncrementalSnapshotHashes { + from: Pubkey, + base: (Slot, Hash), + hashes: Vec<(Slot, Hash)>, + wallclock: u64, +} + +impl Sanitize for IncrementalSnapshotHashes { + fn sanitize(&self) -> Result<(), SanitizeError> { + sanitize_wallclock(self.wallclock)?; + if self.base.0 >= MAX_SLOT { + return Err(SanitizeError::ValueOutOfBounds); + } + for (slot, _) in &self.hashes { + if *slot >= MAX_SLOT { + return Err(SanitizeError::ValueOutOfBounds); + } + if self.base.0 >= *slot { + return Err(SanitizeError::InvalidValue); + } + } + self.from.sanitize() + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, AbiExample)] pub struct LowestSlot { pub from: Pubkey, @@ -467,6 +496,7 @@ pub enum CrdsValueLabel { Version(Pubkey), NodeInstance(Pubkey), DuplicateShred(DuplicateShredIndex, Pubkey), + IncrementalSnapshotHashes(Pubkey), } impl fmt::Display for CrdsValueLabel { @@ -482,6 +512,9 @@ impl fmt::Display for CrdsValueLabel { CrdsValueLabel::Version(_) => write!(f, "Version({})", self.pubkey()), CrdsValueLabel::NodeInstance(pk) => write!(f, "NodeInstance({})", pk), CrdsValueLabel::DuplicateShred(ix, pk) => write!(f, "DuplicateShred({}, {})", ix, pk), + CrdsValueLabel::IncrementalSnapshotHashes(_) => { + write!(f, "IncrementalSnapshotHashes({})", self.pubkey()) + } } } } @@ -499,6 +532,7 @@ impl CrdsValueLabel { CrdsValueLabel::Version(p) => *p, CrdsValueLabel::NodeInstance(p) => *p, CrdsValueLabel::DuplicateShred(_, p) => *p, + CrdsValueLabel::IncrementalSnapshotHashes(p) => *p, } } } @@ -547,6 +581,7 @@ impl CrdsValue { CrdsData::Version(version) => version.wallclock, CrdsData::NodeInstance(node) => node.wallclock, CrdsData::DuplicateShred(_, shred) => shred.wallclock, + CrdsData::IncrementalSnapshotHashes(hash) => hash.wallclock, } } pub fn pubkey(&self) -> Pubkey { @@ -561,6 +596,7 @@ impl CrdsValue { CrdsData::Version(version) => version.from, CrdsData::NodeInstance(node) => node.from, CrdsData::DuplicateShred(_, shred) => shred.from, + CrdsData::IncrementalSnapshotHashes(hash) => hash.from, } } pub fn label(&self) -> CrdsValueLabel { @@ -575,6 +611,9 @@ impl CrdsValue { CrdsData::Version(_) => CrdsValueLabel::Version(self.pubkey()), CrdsData::NodeInstance(node) => CrdsValueLabel::NodeInstance(node.from), CrdsData::DuplicateShred(ix, shred) => CrdsValueLabel::DuplicateShred(*ix, shred.from), + CrdsData::IncrementalSnapshotHashes(_) => { + CrdsValueLabel::IncrementalSnapshotHashes(self.pubkey()) + } } } pub fn contact_info(&self) -> Option<&ContactInfo> {