Factor out LockedPubkeyReferences (#10198)

Co-authored-by: Carl <carl@solana.com>
This commit is contained in:
carllin
2020-05-22 23:23:17 -07:00
committed by GitHub
parent 36a36d1c83
commit 42aaacf520
3 changed files with 39 additions and 32 deletions

View File

@ -3,6 +3,7 @@ use crate::{
consensus::VOTE_THRESHOLD_SIZE, consensus::VOTE_THRESHOLD_SIZE,
crds_value::CrdsValueLabel, crds_value::CrdsValueLabel,
poh_recorder::PohRecorder, poh_recorder::PohRecorder,
pubkey_references::LockedPubkeyReferences,
result::{Error, Result}, result::{Error, Result},
rpc_subscriptions::RpcSubscriptions, rpc_subscriptions::RpcSubscriptions,
sigverify, sigverify,
@ -66,7 +67,7 @@ pub struct VoteTracker {
epoch_authorized_voters: RwLock<HashMap<Epoch, Arc<EpochAuthorizedVoters>>>, epoch_authorized_voters: RwLock<HashMap<Epoch, Arc<EpochAuthorizedVoters>>>,
leader_schedule_epoch: RwLock<Epoch>, leader_schedule_epoch: RwLock<Epoch>,
current_epoch: RwLock<Epoch>, current_epoch: RwLock<Epoch>,
keys: RwLock<HashSet<Arc<Pubkey>>>, keys: LockedPubkeyReferences,
epoch_schedule: EpochSchedule, epoch_schedule: EpochSchedule,
} }
@ -132,7 +133,7 @@ impl VoteTracker {
w_slot_vote_tracker.updates = Some(vec![pubkey.clone()]); w_slot_vote_tracker.updates = Some(vec![pubkey.clone()]);
} }
self.keys.write().unwrap().insert(pubkey); self.keys.get_or_insert(&pubkey);
} }
fn update_leader_schedule_epoch(&self, root_bank: &Bank) { fn update_leader_schedule_epoch(&self, root_bank: &Bank) {
@ -182,10 +183,7 @@ impl VoteTracker {
.write() .write()
.unwrap() .unwrap()
.retain(|epoch, _| epoch >= &root_epoch); .retain(|epoch, _| epoch >= &root_epoch);
self.keys self.keys.purge();
.write()
.unwrap()
.retain(|pubkey| Arc::strong_count(pubkey) > 1);
*self.current_epoch.write().unwrap() = root_epoch; *self.current_epoch.write().unwrap() = root_epoch;
} }
} }
@ -513,16 +511,8 @@ impl ClusterInfoVoteListener {
continue; continue;
} }
} }
let mut unduplicated_pubkey = let unduplicated_pubkey = vote_tracker.keys.get_or_insert(vote_pubkey);
vote_tracker.keys.read().unwrap().get(vote_pubkey).cloned(); diff.entry(slot).or_default().insert(unduplicated_pubkey);
if unduplicated_pubkey.is_none() {
let new_key = Arc::new(*vote_pubkey);
vote_tracker.keys.write().unwrap().insert(new_key.clone());
unduplicated_pubkey = Some(new_key);
}
diff.entry(slot)
.or_default()
.insert(unduplicated_pubkey.unwrap());
} }
subscriptions.notify_vote(&vote); subscriptions.notify_vote(&vote);
@ -731,7 +721,7 @@ mod tests {
// Check `keys` and `epoch_authorized_voters` are purged when new // Check `keys` and `epoch_authorized_voters` are purged when new
// root bank moves to the next epoch // root bank moves to the next epoch
assert!(vote_tracker.keys.read().unwrap().contains(&new_voter)); assert!(vote_tracker.keys.0.read().unwrap().contains(&new_voter));
let current_epoch = bank.epoch(); let current_epoch = bank.epoch();
let new_epoch_bank = Bank::new_from_parent( let new_epoch_bank = Bank::new_from_parent(
&bank, &bank,
@ -740,7 +730,7 @@ mod tests {
.get_first_slot_in_epoch(current_epoch + 1), .get_first_slot_in_epoch(current_epoch + 1),
); );
vote_tracker.process_new_root_bank(&new_epoch_bank); vote_tracker.process_new_root_bank(&new_epoch_bank);
assert!(!vote_tracker.keys.read().unwrap().contains(&new_voter)); assert!(!vote_tracker.keys.0.read().unwrap().contains(&new_voter));
assert_eq!( assert_eq!(
*vote_tracker.current_epoch.read().unwrap(), *vote_tracker.current_epoch.read().unwrap(),
current_epoch + 1 current_epoch + 1
@ -994,6 +984,7 @@ mod tests {
let ref_count = Arc::strong_count( let ref_count = Arc::strong_count(
&vote_tracker &vote_tracker
.keys .keys
.0
.read() .read()
.unwrap() .unwrap()
.get(&validator0_keypairs.vote_keypair.pubkey()) .get(&validator0_keypairs.vote_keypair.pubkey())
@ -1045,6 +1036,7 @@ mod tests {
let ref_count = Arc::strong_count( let ref_count = Arc::strong_count(
&vote_tracker &vote_tracker
.keys .keys
.0
.read() .read()
.unwrap() .unwrap()
.get(&validator0_keypairs.vote_keypair.pubkey()) .get(&validator0_keypairs.vote_keypair.pubkey())

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
cluster_info::ClusterInfo, contact_info::ContactInfo, epoch_slots::EpochSlots, cluster_info::ClusterInfo, contact_info::ContactInfo, epoch_slots::EpochSlots,
serve_repair::RepairType, pubkey_references::LockedPubkeyReferences, serve_repair::RepairType,
}; };
use solana_ledger::bank_forks::BankForks; use solana_ledger::bank_forks::BankForks;
use solana_runtime::epoch_stakes::NodeIdToVoteAccounts; use solana_runtime::epoch_stakes::NodeIdToVoteAccounts;
@ -16,7 +16,7 @@ pub type ClusterSlotsMap = RwLock<HashMap<Slot, Arc<RwLock<SlotPubkeys>>>>;
#[derive(Default)] #[derive(Default)]
pub struct ClusterSlots { pub struct ClusterSlots {
cluster_slots: ClusterSlotsMap, cluster_slots: ClusterSlotsMap,
keys: RwLock<HashSet<Arc<Pubkey>>>, keys: LockedPubkeyReferences,
since: RwLock<Option<u64>>, since: RwLock<Option<u64>>,
validator_stakes: RwLock<Arc<NodeIdToVoteAccounts>>, validator_stakes: RwLock<Arc<NodeIdToVoteAccounts>>,
epoch: RwLock<Option<u64>>, epoch: RwLock<Option<u64>>,
@ -41,20 +41,12 @@ impl ClusterSlots {
if *slot <= root { if *slot <= root {
continue; continue;
} }
let pubkey = Arc::new(epoch_slots.from); let unduplicated_pubkey = self.keys.get_or_insert(&epoch_slots.from);
let exists = self.keys.read().unwrap().get(&pubkey).is_some(); self.insert_node_id(*slot, unduplicated_pubkey);
if !exists {
self.keys.write().unwrap().insert(pubkey.clone());
}
let from = self.keys.read().unwrap().get(&pubkey).unwrap().clone();
self.insert_node_id(*slot, from);
} }
} }
self.cluster_slots.write().unwrap().retain(|x, _| *x > root); self.cluster_slots.write().unwrap().retain(|x, _| *x > root);
self.keys self.keys.purge();
.write()
.unwrap()
.retain(|x| Arc::strong_count(x) > 1);
*self.since.write().unwrap() = since; *self.since.write().unwrap() = since;
} }

View File

@ -1,5 +1,9 @@
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use std::{collections::HashSet, rc::Rc}; use std::{
collections::HashSet,
rc::Rc,
sync::{Arc, RwLock},
};
#[derive(Default)] #[derive(Default)]
pub struct PubkeyReferences(HashSet<Rc<Pubkey>>); pub struct PubkeyReferences(HashSet<Rc<Pubkey>>);
@ -19,3 +23,22 @@ impl PubkeyReferences {
self.0.retain(|x| Rc::strong_count(x) > 1); self.0.retain(|x| Rc::strong_count(x) > 1);
} }
} }
#[derive(Default)]
pub struct LockedPubkeyReferences(pub RwLock<HashSet<Arc<Pubkey>>>);
impl LockedPubkeyReferences {
pub fn get_or_insert(&self, pubkey: &Pubkey) -> Arc<Pubkey> {
let mut cached_pubkey = self.0.read().unwrap().get(pubkey).cloned();
if cached_pubkey.is_none() {
let new_pubkey = Arc::new(*pubkey);
self.0.write().unwrap().insert(new_pubkey.clone());
cached_pubkey = Some(new_pubkey);
}
cached_pubkey.unwrap()
}
pub fn purge(&self) {
self.0.write().unwrap().retain(|x| Arc::strong_count(x) > 1);
}
}