diff --git a/core/src/cluster_slots_service.rs b/core/src/cluster_slots_service.rs index 71405db18..8b7cde3de 100644 --- a/core/src/cluster_slots_service.rs +++ b/core/src/cluster_slots_service.rs @@ -179,7 +179,7 @@ impl ClusterSlotsService { mod test { use { super::*, - solana_gossip::{cluster_info::Node, crds_value::CrdsValueLabel}, + solana_gossip::{cluster_info::Node, crds_value::LowestSlot}, solana_sdk::pubkey::Pubkey, }; @@ -191,10 +191,8 @@ mod test { ClusterSlotsService::update_lowest_slot(5, &cluster_info); cluster_info.flush_push_queue(); let lowest = { - let label = CrdsValueLabel::LowestSlot(pubkey); let gossip_crds = cluster_info.gossip.crds.read().unwrap(); - let entry = gossip_crds.get(&label).unwrap(); - entry.value.lowest_slot().unwrap().clone() + gossip_crds.get::<&LowestSlot>(pubkey).unwrap().clone() }; assert_eq!(lowest.lowest, 5); } diff --git a/gossip/benches/crds_shards.rs b/gossip/benches/crds_shards.rs index 04493322b..494a9f394 100644 --- a/gossip/benches/crds_shards.rs +++ b/gossip/benches/crds_shards.rs @@ -21,7 +21,7 @@ fn new_test_crds_value(rng: &mut R) -> VersionedCrdsValue { let label = value.label(); let mut crds = Crds::default(); crds.insert(value, timestamp()).unwrap(); - crds.get(&label).cloned().unwrap() + crds.get::<&VersionedCrdsValue>(&label).cloned().unwrap() } fn bench_crds_shards_find(bencher: &mut Bencher, num_values: usize, mask_bits: u32) { diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs index e73b56073..beb44c9f2 100644 --- a/gossip/src/cluster_info.rs +++ b/gossip/src/cluster_info.rs @@ -628,7 +628,7 @@ impl ClusterInfo { F: FnOnce(&ContactInfo) -> Y, { let gossip_crds = self.gossip.crds.read().unwrap(); - gossip_crds.get_contact_info(*id).map(map) + gossip_crds.get(*id).map(map) } pub fn lookup_contact_info_by_gossip_addr( @@ -653,8 +653,8 @@ impl ClusterInfo { let label = CrdsValueLabel::EpochSlots(ix, self_pubkey); let gossip_crds = self.gossip.crds.read().unwrap(); gossip_crds - .get(&label) - .and_then(|v| v.value.epoch_slots()) + .get::<&CrdsValue>(&label) + .and_then(|v| v.epoch_slots()) .cloned() .unwrap_or_else(|| EpochSlots::new(self_pubkey, timestamp())) } @@ -816,7 +816,7 @@ impl ClusterInfo { let last = { let gossip_crds = self.gossip.crds.read().unwrap(); gossip_crds - .get_lowest_slot(self_pubkey) + .get::<&LowestSlot>(self_pubkey) .map(|x| x.lowest) .unwrap_or_default() }; @@ -843,7 +843,7 @@ impl ClusterInfo { (0..crds_value::MAX_EPOCH_SLOTS) .filter_map(|ix| { let label = CrdsValueLabel::EpochSlots(ix, self_pubkey); - let epoch_slots = gossip_crds.get(&label)?.value.epoch_slots()?; + let epoch_slots = gossip_crds.get::<&CrdsValue>(&label)?.epoch_slots()?; let first_slot = epoch_slots.first_slot()?; Some((epoch_slots.wallclock, first_slot, ix)) }) @@ -985,9 +985,9 @@ impl ClusterInfo { (0..MAX_LOCKOUT_HISTORY as u8) .filter_map(|ix| { let vote = CrdsValueLabel::Vote(ix, self_pubkey); - let vote = gossip_crds.get(&vote)?; + let vote: &CrdsData = gossip_crds.get(&vote)?; num_crds_votes += 1; - match &vote.value.data { + match &vote { CrdsData::Vote(_, vote) if should_evict_vote(vote) => { Some((vote.wallclock, ix)) } @@ -1009,8 +1009,8 @@ impl ClusterInfo { self.time_gossip_read_lock("gossip_read_push_vote", &self.stats.push_vote_read); (0..MAX_LOCKOUT_HISTORY as u8).find(|ix| { let vote = CrdsValueLabel::Vote(*ix, self_pubkey); - if let Some(vote) = gossip_crds.get(&vote) { - match &vote.value.data { + if let Some(vote) = gossip_crds.get::<&CrdsData>(&vote) { + match &vote { CrdsData::Vote(_, prev_vote) => match prev_vote.slot() { Some(prev_vote_slot) => prev_vote_slot == vote_slot, None => { @@ -1084,8 +1084,8 @@ impl ClusterInfo { F: FnOnce(&Vec<(Slot, Hash)>) -> Y, { self.time_gossip_read_lock("get_accounts_hash", &self.stats.get_accounts_hash) - .get(&CrdsValueLabel::AccountsHashes(*pubkey)) - .map(|x| &x.value.accounts_hash().unwrap().hashes) + .get::<&CrdsValue>(&CrdsValueLabel::AccountsHashes(*pubkey)) + .map(|x| &x.accounts_hash().unwrap().hashes) .map(map) } @@ -1094,10 +1094,8 @@ impl ClusterInfo { F: FnOnce(&Vec<(Slot, Hash)>) -> Y, { let gossip_crds = self.gossip.crds.read().unwrap(); - gossip_crds - .get(&CrdsValueLabel::SnapshotHashes(*pubkey)) - .map(|x| &x.value.snapshot_hash().unwrap().hashes) - .map(map) + let hashes = &gossip_crds.get::<&SnapshotHash>(*pubkey)?.hashes; + Some(map(hashes)) } /// Returns epoch-slots inserted since the given cursor. @@ -1120,12 +1118,10 @@ impl ClusterInfo { pub fn get_node_version(&self, pubkey: &Pubkey) -> Option { let gossip_crds = self.gossip.crds.read().unwrap(); - let version = gossip_crds.get(&CrdsValueLabel::Version(*pubkey)); - if let Some(version) = version.and_then(|v| v.value.version()) { + if let Some(version) = gossip_crds.get::<&Version>(*pubkey) { return Some(version.version.clone()); } - let version = gossip_crds.get(&CrdsValueLabel::LegacyVersion(*pubkey))?; - let version = version.value.legacy_version()?; + let version: &crds_value::LegacyVersion = gossip_crds.get(*pubkey)?; Some(version.version.clone().into()) } @@ -1198,7 +1194,7 @@ impl ClusterInfo { && node.shred_version == self_shred_version && ContactInfo::is_valid_tvu_address(&node.tvu) && ContactInfo::is_valid_address(&node.serve_repair) - && match gossip_crds.get_lowest_slot(node.id) { + && match gossip_crds.get::<&LowestSlot>(node.id) { None => true, // fallback to legacy behavior Some(lowest_slot) => lowest_slot.lowest <= slot, } @@ -1446,7 +1442,7 @@ impl ClusterInfo { push_messages .into_iter() .filter_map(|(pubkey, messages)| { - let peer = gossip_crds.get_contact_info(pubkey)?; + let peer: &ContactInfo = gossip_crds.get(pubkey)?; Some((peer.gossip, messages)) }) .collect() @@ -2197,7 +2193,7 @@ impl ClusterInfo { .into_par_iter() .with_min_len(256) .filter_map(|(from, prunes)| { - let peer = gossip_crds.get_contact_info(from)?; + let peer: &ContactInfo = gossip_crds.get(from)?; let mut prune_data = PruneData { pubkey: self_pubkey, prunes, @@ -3294,7 +3290,7 @@ mod tests { let label = CrdsValueLabel::ContactInfo(d.id); cluster_info.insert_info(d); let gossip_crds = cluster_info.gossip.crds.read().unwrap(); - assert!(gossip_crds.get(&label).is_some()); + assert!(gossip_crds.get::<&CrdsValue>(&label).is_some()); } fn assert_in_range(x: u16, range: (u16, u16)) { @@ -3559,7 +3555,7 @@ mod tests { let gossip_crds = cluster_info.gossip.crds.read().unwrap(); let mut vote_slots = HashSet::new(); for label in labels { - match &gossip_crds.get(&label).unwrap().value.data { + match &gossip_crds.get::<&CrdsData>(&label).unwrap() { CrdsData::Vote(_, vote) => { assert!(vote_slots.insert(vote.slot().unwrap())); } diff --git a/gossip/src/crds.rs b/gossip/src/crds.rs index fcba2230c..71ae737ad 100644 --- a/gossip/src/crds.rs +++ b/gossip/src/crds.rs @@ -27,8 +27,9 @@ use { crate::{ contact_info::ContactInfo, + crds_entry::CrdsEntry, crds_shards::CrdsShards, - crds_value::{CrdsData, CrdsValue, CrdsValueLabel, LowestSlot}, + crds_value::{CrdsData, CrdsValue, CrdsValueLabel}, }, bincode::serialize, indexmap::{ @@ -241,31 +242,24 @@ impl Crds { } } - pub fn get(&self, label: &CrdsValueLabel) -> Option<&VersionedCrdsValue> { - self.table.get(label) - } - - pub fn get_contact_info(&self, pubkey: Pubkey) -> Option<&ContactInfo> { - let label = CrdsValueLabel::ContactInfo(pubkey); - self.table.get(&label)?.value.contact_info() + pub fn get<'a, 'b, V>(&'a self, key: V::Key) -> Option + where + V: CrdsEntry<'a, 'b>, + { + V::get_entry(&self.table, key) } pub(crate) fn get_shred_version(&self, pubkey: &Pubkey) -> Option { self.shred_versions.get(pubkey).copied() } - pub fn get_lowest_slot(&self, pubkey: Pubkey) -> Option<&LowestSlot> { - let lable = CrdsValueLabel::LowestSlot(pubkey); - self.table.get(&lable)?.value.lowest_slot() - } - /// Returns all entries which are ContactInfo. - pub fn get_nodes(&self) -> impl Iterator { + pub(crate) fn get_nodes(&self) -> impl Iterator { self.nodes.iter().map(move |i| self.table.index(*i)) } /// Returns ContactInfo of all known nodes. - pub fn get_nodes_contact_info(&self) -> impl Iterator { + pub(crate) fn get_nodes_contact_info(&self) -> impl Iterator { self.get_nodes().map(|v| match &v.value.data { CrdsData::ContactInfo(info) => info, _ => panic!("this should not happen!"), @@ -337,7 +331,7 @@ impl Crds { self.table.values() } - pub fn par_values(&self) -> ParValues<'_, CrdsValueLabel, VersionedCrdsValue> { + pub(crate) fn par_values(&self) -> ParValues<'_, CrdsValueLabel, VersionedCrdsValue> { self.table.par_values() } @@ -361,7 +355,7 @@ impl Crds { /// Returns all crds values which the first 'mask_bits' /// of their hash value is equal to 'mask'. - pub fn filter_bitmask( + pub(crate) fn filter_bitmask( &self, mask: u64, mask_bits: u32, @@ -372,7 +366,7 @@ impl Crds { } /// Update the timestamp's of all the labels that are associated with Pubkey - pub fn update_record_timestamp(&mut self, pubkey: &Pubkey, now: u64) { + pub(crate) fn update_record_timestamp(&mut self, pubkey: &Pubkey, now: u64) { // It suffices to only overwrite the origin's timestamp since that is // used when purging old values. If the origin does not exist in the // table, fallback to exhaustive update on all associated records. @@ -1075,7 +1069,7 @@ mod tests { // Remove contact-info. Shred version should stay there since there // are still values associated with the pubkey. crds.remove(&CrdsValueLabel::ContactInfo(pubkey), timestamp()); - assert_eq!(crds.get_contact_info(pubkey), None); + assert_eq!(crds.get::<&ContactInfo>(pubkey), None); assert_eq!(crds.get_shred_version(&pubkey), Some(8)); // Remove the remaining entry with the same pubkey. crds.remove(&CrdsValueLabel::SnapshotHashes(pubkey), timestamp()); diff --git a/gossip/src/crds_entry.rs b/gossip/src/crds_entry.rs new file mode 100644 index 000000000..3492af296 --- /dev/null +++ b/gossip/src/crds_entry.rs @@ -0,0 +1,121 @@ +use { + crate::{ + contact_info::ContactInfo, + crds::VersionedCrdsValue, + crds_value::{ + CrdsData, CrdsValue, CrdsValueLabel, LegacyVersion, LowestSlot, SnapshotHash, Version, + }, + }, + indexmap::IndexMap, + solana_sdk::pubkey::Pubkey, +}; + +type CrdsTable = IndexMap; + +/// Represents types which can be looked up from crds table given a key. e.g. +/// CrdsValueLabel -> VersionedCrdsValue, CrdsValue, CrdsData +/// Pubkey -> ContactInfo, LowestSlot, SnapshotHash, ... +pub trait CrdsEntry<'a, 'b>: Sized { + type Key; // Lookup key. + fn get_entry(table: &'a CrdsTable, key: Self::Key) -> Option; +} + +macro_rules! impl_crds_entry ( + // Lookup by CrdsValueLabel. + ($name:ident, |$entry:ident| $body:expr) => ( + impl<'a, 'b> CrdsEntry<'a, 'b> for &'a $name { + type Key = &'b CrdsValueLabel; + fn get_entry(table:&'a CrdsTable, key: Self::Key) -> Option { + let $entry = table.get(key); + $body + } + } + ); + // Lookup by Pubkey. + ($name:ident, $pat:pat, $expr:expr) => ( + impl<'a, 'b> CrdsEntry<'a, 'b> for &'a $name { + type Key = Pubkey; + fn get_entry(table:&'a CrdsTable, key: Self::Key) -> Option { + let key = CrdsValueLabel::$name(key); + match &table.get(&key)?.value.data { + $pat => Some($expr), + _ => None, + } + } + } + ); +); + +// Lookup by CrdsValueLabel. +impl_crds_entry!(CrdsData, |entry| Some(&entry?.value.data)); +impl_crds_entry!(CrdsValue, |entry| Some(&entry?.value)); +impl_crds_entry!(VersionedCrdsValue, |entry| entry); + +// Lookup by Pubkey. +impl_crds_entry!(ContactInfo, CrdsData::ContactInfo(node), node); +impl_crds_entry!(LegacyVersion, CrdsData::LegacyVersion(version), version); +impl_crds_entry!(LowestSlot, CrdsData::LowestSlot(_, slot), slot); +impl_crds_entry!(Version, CrdsData::Version(version), version); + +impl<'a, 'b> CrdsEntry<'a, 'b> for &'a SnapshotHash { + type Key = Pubkey; + fn get_entry(table: &'a CrdsTable, key: Self::Key) -> Option { + let key = CrdsValueLabel::SnapshotHashes(key); + match &table.get(&key)?.value.data { + CrdsData::SnapshotHashes(snapshot_hash) => Some(snapshot_hash), + _ => None, + } + } +} + +#[cfg(test)] +mod tests { + use { + super::*, + crate::{crds::Crds, crds_value::new_rand_timestamp}, + rand::seq::SliceRandom, + solana_sdk::signature::Keypair, + std::collections::HashMap, + }; + + #[test] + fn test_get_crds_entry() { + let mut rng = rand::thread_rng(); + let mut crds = Crds::default(); + let keypairs: Vec<_> = std::iter::repeat_with(Keypair::new).take(32).collect(); + let mut entries = HashMap::new(); + for _ in 0..256 { + let keypair = keypairs.choose(&mut rng).unwrap(); + let value = CrdsValue::new_rand(&mut rng, Some(keypair)); + let key = value.label(); + if let Ok(()) = crds.insert(value.clone(), new_rand_timestamp(&mut rng)) { + entries.insert(key, value); + } + } + assert!(crds.len() > 64); + assert_eq!(crds.len(), entries.len()); + for entry in entries.values() { + let key = entry.label(); + assert_eq!(crds.get::<&CrdsValue>(&key), Some(entry)); + assert_eq!(crds.get::<&CrdsData>(&key), Some(&entry.data)); + assert_eq!(crds.get::<&VersionedCrdsValue>(&key).unwrap().value, *entry); + let key = entry.pubkey(); + match &entry.data { + CrdsData::ContactInfo(node) => { + assert_eq!(crds.get::<&ContactInfo>(key), Some(node)) + } + CrdsData::LowestSlot(_, slot) => { + assert_eq!(crds.get::<&LowestSlot>(key), Some(slot)) + } + CrdsData::Version(version) => assert_eq!(crds.get::<&Version>(key), Some(version)), + CrdsData::LegacyVersion(version) => { + assert_eq!(crds.get::<&LegacyVersion>(key), Some(version)) + } + CrdsData::SnapshotHashes(hash) => { + assert_eq!(crds.get::<&SnapshotHash>(key), Some(hash)) + } + _ => (), + } + } + } +} diff --git a/gossip/src/crds_gossip_pull.rs b/gossip/src/crds_gossip_pull.rs index fd24694f6..453d478e3 100644 --- a/gossip/src/crds_gossip_pull.rs +++ b/gossip/src/crds_gossip_pull.rs @@ -266,7 +266,7 @@ impl CrdsGossipPull { Some((node, _gossip_addr)) => node, }; let filters = self.build_crds_filters(thread_pool, crds, bloom_size); - let peer = match crds.read().unwrap().get_contact_info(peer) { + let peer = match crds.read().unwrap().get::<&ContactInfo>(peer) { None => return Err(CrdsGossipError::NoPeers), Some(node) => node.clone(), }; @@ -393,7 +393,7 @@ impl CrdsGossipPull { } else if now <= response.wallclock().saturating_add(timeout) { active_values.push(response); None - } else if crds.get_contact_info(owner).is_some() { + } else if crds.get::<&ContactInfo>(owner).is_some() { // Silently insert this old value without bumping record // timestamps expired_values.push(response); @@ -1275,8 +1275,11 @@ pub(crate) mod tests { CrdsGossipPull::process_pull_requests(&dest_crds, callers, 1); let dest_crds = dest_crds.read().unwrap(); assert!(rsp.iter().all(|rsp| rsp.is_empty())); - assert!(dest_crds.get(&caller.label()).is_some()); - assert_eq!(dest_crds.get(&caller.label()).unwrap().local_timestamp, 1); + assert!(dest_crds.get::<&CrdsValue>(&caller.label()).is_some()); + assert_eq!(1, { + let entry: &VersionedCrdsValue = dest_crds.get(&caller.label()).unwrap(); + entry.local_timestamp + }); } #[test] fn test_process_pull_request_response() { @@ -1315,7 +1318,10 @@ pub(crate) mod tests { assert_eq!(same_key.label(), new.label()); assert!(same_key.wallclock() < new.wallclock()); node_crds.insert(same_key.clone(), 0).unwrap(); - assert_eq!(node_crds.get(&same_key.label()).unwrap().local_timestamp, 0); + assert_eq!(0, { + let entry: &VersionedCrdsValue = node_crds.get(&same_key.label()).unwrap(); + entry.local_timestamp + }); let node_crds = RwLock::new(node_crds); let mut done = false; let mut pings = Vec::new(); @@ -1369,12 +1375,14 @@ pub(crate) mod tests { assert_eq!(failed, 0); assert_eq!(1, { let node_crds = node_crds.read().unwrap(); - node_crds.get(&new.label()).unwrap().local_timestamp + let entry: &VersionedCrdsValue = node_crds.get(&new.label()).unwrap(); + entry.local_timestamp }); // verify that the whole record was updated for dest since this is a response from dest assert_eq!(1, { let node_crds = node_crds.read().unwrap(); - node_crds.get(&same_key.label()).unwrap().local_timestamp + let entry: &VersionedCrdsValue = node_crds.get(&same_key.label()).unwrap(); + entry.local_timestamp }); done = true; break; @@ -1398,11 +1406,13 @@ pub(crate) mod tests { 0, ))); node_crds.insert(old.clone(), 0).unwrap(); - let value_hash = node_crds.get(&old.label()).unwrap().value_hash; - + let value_hash = { + let entry: &VersionedCrdsValue = node_crds.get(&old.label()).unwrap(); + entry.value_hash + }; //verify self is valid assert_eq!( - node_crds.get(&node_label).unwrap().value.label(), + node_crds.get::<&CrdsValue>(&node_label).unwrap().label(), node_label ); // purge @@ -1413,9 +1423,12 @@ pub(crate) mod tests { //verify self is still valid after purge assert_eq!(node_label, { let node_crds = node_crds.read().unwrap(); - node_crds.get(&node_label).unwrap().value.label() + node_crds.get::<&CrdsValue>(&node_label).unwrap().label() }); - assert_eq!(node_crds.read().unwrap().get(&old.label()), None); + assert_eq!( + node_crds.read().unwrap().get::<&CrdsValue>(&old.label()), + None + ); assert_eq!(node_crds.read().unwrap().num_purged(), 1); for _ in 0..30 { // there is a chance of a false positive with bloom filters diff --git a/gossip/src/crds_gossip_push.rs b/gossip/src/crds_gossip_push.rs index e1d502d5b..bf73b7d4b 100644 --- a/gossip/src/crds_gossip_push.rs +++ b/gossip/src/crds_gossip_push.rs @@ -561,7 +561,7 @@ mod test { push.process_push_message(&crds, &Pubkey::default(), vec![value.clone()], 0), [Ok(label.pubkey())], ); - assert_eq!(crds.read().unwrap().get(&label).unwrap().value, value); + assert_eq!(crds.read().unwrap().get::<&CrdsValue>(&label), Some(&value)); // push it again assert_eq!( @@ -956,7 +956,10 @@ mod test { push.process_push_message(&crds, &Pubkey::default(), vec![value.clone()], 0), [Ok(label.pubkey())] ); - assert_eq!(crds.write().unwrap().get(&label).unwrap().value, value); + assert_eq!( + crds.write().unwrap().get::<&CrdsValue>(&label), + Some(&value) + ); // push it again assert_eq!( diff --git a/gossip/src/crds_shards.rs b/gossip/src/crds_shards.rs index 9412ac0a0..f410ac5cd 100644 --- a/gossip/src/crds_shards.rs +++ b/gossip/src/crds_shards.rs @@ -145,7 +145,7 @@ mod test { let label = value.label(); let mut crds = Crds::default(); crds.insert(value, timestamp()).unwrap(); - crds.get(&label).cloned().unwrap() + crds.get::<&VersionedCrdsValue>(&label).cloned().unwrap() } // Returns true if the first mask_bits most significant bits of hash is the diff --git a/gossip/src/crds_value.rs b/gossip/src/crds_value.rs index 1976d2781..daf653c8a 100644 --- a/gossip/src/crds_value.rs +++ b/gossip/src/crds_value.rs @@ -584,56 +584,20 @@ impl CrdsValue { } } - #[cfg(test)] - fn vote(&self) -> Option<&Vote> { - match &self.data { - CrdsData::Vote(_, vote) => Some(vote), - _ => None, - } - } - - pub fn lowest_slot(&self) -> Option<&LowestSlot> { - match &self.data { - CrdsData::LowestSlot(_, slots) => Some(slots), - _ => None, - } - } - - pub fn snapshot_hash(&self) -> Option<&SnapshotHash> { - match &self.data { - CrdsData::SnapshotHashes(slots) => Some(slots), - _ => None, - } - } - - pub fn accounts_hash(&self) -> Option<&SnapshotHash> { + pub(crate) fn accounts_hash(&self) -> Option<&SnapshotHash> { match &self.data { CrdsData::AccountsHashes(slots) => Some(slots), _ => None, } } - pub fn epoch_slots(&self) -> Option<&EpochSlots> { + pub(crate) fn epoch_slots(&self) -> Option<&EpochSlots> { match &self.data { CrdsData::EpochSlots(_, slots) => Some(slots), _ => None, } } - pub fn legacy_version(&self) -> Option<&LegacyVersion> { - match &self.data { - CrdsData::LegacyVersion(legacy_version) => Some(legacy_version), - _ => None, - } - } - - pub fn version(&self) -> Option<&Version> { - match &self.data { - CrdsData::Version(version) => Some(version), - _ => None, - } - } - /// Returns the size (in bytes) of a CrdsValue pub fn size(&self) -> u64 { serialized_size(&self).expect("unable to serialize contact info") @@ -641,7 +605,7 @@ impl CrdsValue { /// Returns true if, regardless of prunes, this crds-value /// should be pushed to the receiving node. - pub fn should_force_push(&self, peer: &Pubkey) -> bool { + pub(crate) fn should_force_push(&self, peer: &Pubkey) -> bool { match &self.data { CrdsData::NodeInstance(node) => node.from == *peer, _ => false, @@ -710,7 +674,10 @@ mod test { Vote::new(Pubkey::default(), test_tx(), 0), )); assert_eq!(v.wallclock(), 0); - let key = v.vote().unwrap().from; + let key = match &v.data { + CrdsData::Vote(_, vote) => vote.from, + _ => panic!(), + }; assert_eq!(v.label(), CrdsValueLabel::Vote(0, key)); let v = CrdsValue::new_unsigned(CrdsData::LowestSlot( @@ -718,7 +685,10 @@ mod test { LowestSlot::new(Pubkey::default(), 0, 0), )); assert_eq!(v.wallclock(), 0); - let key = v.lowest_slot().unwrap().from; + let key = match &v.data { + CrdsData::LowestSlot(_, data) => data.from, + _ => panic!(), + }; assert_eq!(v.label(), CrdsValueLabel::LowestSlot(key)); } diff --git a/gossip/src/lib.rs b/gossip/src/lib.rs index e5b2d7ccc..1c5f7ccec 100644 --- a/gossip/src/lib.rs +++ b/gossip/src/lib.rs @@ -6,6 +6,7 @@ mod cluster_info_metrics; #[macro_use] pub mod contact_info; pub mod crds; +pub mod crds_entry; pub mod crds_gossip; pub mod crds_gossip_error; pub mod crds_gossip_pull; diff --git a/gossip/tests/crds_gossip.rs b/gossip/tests/crds_gossip.rs index c4de78a38..07d2635aa 100644 --- a/gossip/tests/crds_gossip.rs +++ b/gossip/tests/crds_gossip.rs @@ -187,7 +187,7 @@ fn ring_network_create(num: usize) -> Network { let start_id = keys[k]; let label = CrdsValueLabel::ContactInfo(start_id); let gossip_crds = start.gossip.crds.read().unwrap(); - gossip_crds.get(&label).unwrap().value.clone() + gossip_crds.get::<&CrdsValue>(&label).unwrap().clone() }; let end = network.get_mut(&keys[(k + 1) % keys.len()]).unwrap(); let mut end_crds = end.gossip.crds.write().unwrap(); @@ -221,7 +221,7 @@ fn connected_staked_network_create(stakes: &[u64]) -> Network { let start = &network[k]; let start_label = CrdsValueLabel::ContactInfo(*k); let gossip_crds = start.gossip.crds.read().unwrap(); - gossip_crds.get(&start_label).unwrap().value.clone() + gossip_crds.get::<&CrdsValue>(&start_label).unwrap().clone() }) .collect(); for (end_pubkey, end) in network.iter_mut() { @@ -276,7 +276,7 @@ fn network_simulator(thread_pool: &ThreadPool, network: &mut Network, max_conver let node_pubkey = node.keypair.pubkey(); let mut m = { let node_crds = node.gossip.crds.read().unwrap(); - node_crds.get_contact_info(node_pubkey).cloned().unwrap() + node_crds.get::<&ContactInfo>(node_pubkey).cloned().unwrap() }; m.wallclock = now; node.gossip.process_push_message( @@ -495,7 +495,7 @@ fn network_run_pull( let from_pubkey = from.keypair.pubkey(); let label = CrdsValueLabel::ContactInfo(from_pubkey); let gossip_crds = from.gossip.crds.read().unwrap(); - let self_info = gossip_crds.get(&label).unwrap().value.clone(); + let self_info = gossip_crds.get::<&CrdsValue>(&label).unwrap().clone(); Some((peer.id, filters, self_info)) }) .collect()