Skip to content

Commit

Permalink
uses immutable HashMap for vote_accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
behzadnouri committed Mar 16, 2022
1 parent 18bddbc commit b66527d
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 66 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dashmap = { version = "4.0.2", features = ["rayon", "raw-api"] }
etcd-client = { version = "0.8.4", features = ["tls"] }
fs_extra = "1.2.0"
histogram = "0.6.9"
im = { version = "15.0.0", features = ["rayon", "serde"] }
itertools = "0.10.3"
log = "0.4.14"
lru = "0.7.3"
Expand Down
9 changes: 5 additions & 4 deletions core/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use {
tower_storage::{SavedTower, SavedTowerVersions, TowerStorage},
},
chrono::prelude::*,
im::HashMap as ImHashMap,
solana_ledger::{ancestor_iterator::AncestorIterator, blockstore::Blockstore, blockstore_db},
solana_runtime::{
bank::Bank, bank_forks::BankForks, commitment::VOTE_THRESHOLD_SIZE,
Expand Down Expand Up @@ -253,7 +254,7 @@ impl Tower {
pub(crate) fn collect_vote_lockouts(
vote_account_pubkey: &Pubkey,
bank_slot: Slot,
vote_accounts: &HashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>,
vote_accounts: &ImHashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>,
ancestors: &HashMap<Slot, HashSet<Slot>>,
get_frozen_hash: impl Fn(Slot) -> Option<Hash>,
latest_validator_votes_for_frozen_banks: &mut LatestValidatorVotesForFrozenBanks,
Expand Down Expand Up @@ -636,7 +637,7 @@ impl Tower {
descendants: &HashMap<Slot, HashSet<u64>>,
progress: &ProgressMap,
total_stake: u64,
epoch_vote_accounts: &HashMap<Pubkey, (u64, VoteAccount)>,
epoch_vote_accounts: &ImHashMap<Pubkey, (u64, VoteAccount)>,
latest_validator_votes_for_frozen_banks: &LatestValidatorVotesForFrozenBanks,
heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice,
) -> SwitchForkDecision {
Expand Down Expand Up @@ -929,7 +930,7 @@ impl Tower {
descendants: &HashMap<Slot, HashSet<u64>>,
progress: &ProgressMap,
total_stake: u64,
epoch_vote_accounts: &HashMap<Pubkey, (u64, VoteAccount)>,
epoch_vote_accounts: &ImHashMap<Pubkey, (u64, VoteAccount)>,
latest_validator_votes_for_frozen_banks: &LatestValidatorVotesForFrozenBanks,
heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice,
) -> SwitchForkDecision {
Expand Down Expand Up @@ -1398,7 +1399,7 @@ pub mod test {
trees::tr,
};

fn gen_stakes(stake_votes: &[(u64, &[u64])]) -> HashMap<Pubkey, (u64, VoteAccount)> {
fn gen_stakes(stake_votes: &[(u64, &[u64])]) -> ImHashMap<Pubkey, (u64, VoteAccount)> {
stake_votes
.iter()
.map(|(lamports, votes)| {
Expand Down
7 changes: 4 additions & 3 deletions core/src/progress_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use {
consensus::{Stake, VotedStakes},
replay_stage::SUPERMINORITY_THRESHOLD,
},
im::HashMap as ImHashMap,
solana_ledger::blockstore_processor::{ConfirmationProgress, ConfirmationTiming},
solana_program_runtime::timings::ExecuteTimingType,
solana_runtime::{bank::Bank, bank_forks::BankForks, vote_account::VoteAccount},
Expand Down Expand Up @@ -516,7 +517,7 @@ impl PropagatedStats {
&mut self,
node_pubkey: &Pubkey,
vote_account_pubkeys: &[Pubkey],
epoch_vote_accounts: &HashMap<Pubkey, (u64, VoteAccount)>,
epoch_vote_accounts: &ImHashMap<Pubkey, (u64, VoteAccount)>,
) {
self.propagated_node_ids.insert(*node_pubkey);
for vote_account_pubkey in vote_account_pubkeys.iter() {
Expand Down Expand Up @@ -727,7 +728,7 @@ mod test {
let vote_account_pubkeys: Vec<_> = std::iter::repeat_with(solana_sdk::pubkey::new_rand)
.take(num_vote_accounts)
.collect();
let epoch_vote_accounts: HashMap<_, _> = vote_account_pubkeys
let epoch_vote_accounts: ImHashMap<_, _> = vote_account_pubkeys
.iter()
.skip(num_vote_accounts - staked_vote_accounts)
.map(|pubkey| (*pubkey, (1, VoteAccount::default())))
Expand Down Expand Up @@ -769,7 +770,7 @@ mod test {
let vote_account_pubkeys: Vec<_> = std::iter::repeat_with(solana_sdk::pubkey::new_rand)
.take(num_vote_accounts)
.collect();
let epoch_vote_accounts: HashMap<_, _> = vote_account_pubkeys
let epoch_vote_accounts: ImHashMap<_, _> = vote_account_pubkeys
.iter()
.skip(num_vote_accounts - staked_vote_accounts)
.map(|pubkey| (*pubkey, (1, VoteAccount::default())))
Expand Down
1 change: 1 addition & 0 deletions ledger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ chrono-humanize = "0.2.1"
crossbeam-channel = "0.5"
fs_extra = "1.2.0"
futures = "0.3.21"
im = { version = "15.0.0", features = ["rayon", "serde"] }
itertools = "0.10.3"
lazy_static = "1.4.0"
libc = "0.2.120"
Expand Down
8 changes: 5 additions & 3 deletions ledger/src/blockstore_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use {
},
chrono_humanize::{Accuracy, HumanTime, Tense},
crossbeam_channel::{unbounded, Sender},
im::HashMap as ImHashMap,
itertools::Itertools,
log::*,
rand::{seq::SliceRandom, thread_rng},
Expand Down Expand Up @@ -1348,7 +1349,7 @@ fn supermajority_root(roots: &[(Slot, u64)], total_epoch_stake: u64) -> Option<S
fn supermajority_root_from_vote_accounts(
bank_slot: Slot,
total_epoch_stake: u64,
vote_accounts: &HashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>,
vote_accounts: &ImHashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>,
) -> Option<Slot> {
let mut roots_stakes: Vec<(Slot, u64)> = vote_accounts
.iter()
Expand Down Expand Up @@ -3798,7 +3799,7 @@ pub mod tests {
#[allow(clippy::field_reassign_with_default)]
fn test_supermajority_root_from_vote_accounts() {
let convert_to_vote_accounts =
|roots_stakes: Vec<(Slot, u64)>| -> HashMap<Pubkey, (u64, VoteAccount)> {
|roots_stakes: Vec<(Slot, u64)>| -> ImHashMap<Pubkey, (u64, VoteAccount)> {
roots_stakes
.into_iter()
.map(|(root, stake)| {
Expand All @@ -3824,7 +3825,8 @@ pub mod tests {

// Supermajority root should be None
assert!(
supermajority_root_from_vote_accounts(slot, total_stake, &HashMap::default()).is_none()
supermajority_root_from_vote_accounts(slot, total_stake, &ImHashMap::default())
.is_none()
);

// Supermajority root should be None
Expand Down
9 changes: 5 additions & 4 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ use {
},
byteorder::{ByteOrder, LittleEndian},
dashmap::DashMap,
im::HashMap as ImHashMap,
itertools::Itertools,
log::*,
rand::Rng,
Expand Down Expand Up @@ -4470,7 +4471,7 @@ impl Bank {
#[allow(clippy::needless_collect)]
fn distribute_rent_to_validators(
&self,
vote_accounts: &HashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>,
vote_accounts: &ImHashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>,
rent_to_be_distributed: u64,
) {
let mut total_staked = 0;
Expand Down Expand Up @@ -6101,9 +6102,9 @@ impl Bank {

/// current vote accounts for this bank along with the stake
/// attributed to each account
pub fn vote_accounts(&self) -> Arc<HashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>> {
pub fn vote_accounts(&self) -> ImHashMap<Pubkey, (/*stake:*/ u64, VoteAccount)> {
let stakes = self.stakes_cache.stakes();
Arc::from(stakes.vote_accounts())
ImHashMap::from(stakes.vote_accounts())
}

/// Vote account for the given vote account pubkey along with the stake.
Expand All @@ -6130,7 +6131,7 @@ impl Bank {
pub fn epoch_vote_accounts(
&self,
epoch: Epoch,
) -> Option<&HashMap<Pubkey, (u64, VoteAccount)>> {
) -> Option<&ImHashMap<Pubkey, (u64, VoteAccount)>> {
let epoch_stakes = self.epoch_stakes.get(&epoch)?.stakes();
Some(epoch_stakes.vote_accounts().as_ref())
}
Expand Down
5 changes: 3 additions & 2 deletions runtime/src/epoch_stakes.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use {
crate::{stakes::Stakes, vote_account::VoteAccount},
im::HashMap as ImHashMap,
serde::{Deserialize, Serialize},
solana_sdk::{clock::Epoch, pubkey::Pubkey},
std::{collections::HashMap, sync::Arc},
Expand Down Expand Up @@ -60,7 +61,7 @@ impl EpochStakes {
}

fn parse_epoch_vote_accounts(
epoch_vote_accounts: &HashMap<Pubkey, (u64, VoteAccount)>,
epoch_vote_accounts: &ImHashMap<Pubkey, (u64, VoteAccount)>,
leader_schedule_epoch: Epoch,
) -> (u64, NodeIdToVoteAccounts, EpochAuthorizedVoters) {
let mut node_id_to_vote_accounts: NodeIdToVoteAccounts = HashMap::new();
Expand Down Expand Up @@ -185,7 +186,7 @@ pub(crate) mod tests {
.collect();

// Create and process the vote accounts
let epoch_vote_accounts: HashMap<_, _> = vote_accounts_map
let epoch_vote_accounts: ImHashMap<_, _> = vote_accounts_map
.iter()
.flat_map(|(_, vote_accounts)| {
vote_accounts.iter().map(|v| {
Expand Down
15 changes: 7 additions & 8 deletions runtime/src/stake_weighted_timestamp.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/// A helper for calculating a stake-weighted timestamp estimate from a set of timestamps and epoch
/// stake.
use solana_sdk::{
clock::{Slot, UnixTimestamp},
pubkey::Pubkey,
};
use std::{
borrow::Borrow,
collections::{BTreeMap, HashMap},
time::Duration,
use {
im::HashMap,
solana_sdk::{
clock::{Slot, UnixTimestamp},
pubkey::Pubkey,
},
std::{borrow::Borrow, collections::BTreeMap, time::Duration},
};

pub(crate) const MAX_ALLOWABLE_DRIFT_PERCENTAGE: u32 = 50;
Expand Down
15 changes: 6 additions & 9 deletions runtime/src/stakes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
use {
crate::{
stake_history::StakeHistory,
vote_account::{VoteAccount, VoteAccounts, VoteAccountsHashMap},
vote_account::{VoteAccount, VoteAccounts},
},
dashmap::DashMap,
im::HashMap as ImHashMap,
num_derive::ToPrimitive,
num_traits::ToPrimitive,
rayon::{
iter::{IntoParallelRefIterator, ParallelIterator},
ThreadPool,
},
rayon::{prelude::*, ThreadPool},
solana_sdk::{
account::{AccountSharedData, ReadableAccount},
clock::{Epoch, Slot},
Expand Down Expand Up @@ -175,7 +172,7 @@ impl Stakes {
thread_pool.install(|| {
let stake_delegations = &self.stake_delegations;
let stake_history = &mut self.stake_history;
let vote_accounts: &VoteAccountsHashMap = self.vote_accounts.as_ref();
let vote_accounts: Vec<_> = self.vote_accounts.iter().collect();

// construct map of vote pubkey -> list of stake delegations
let vote_delegations: HashMap<Pubkey, Vec<&Delegation>> = {
Expand Down Expand Up @@ -213,8 +210,8 @@ impl Stakes {
}

// refresh the stake distribution of vote accounts for the next epoch, using new stake history
let vote_accounts_for_next_epoch: VoteAccountsHashMap = vote_accounts
.par_iter()
let vote_accounts_for_next_epoch: HashMap<_, _> = vote_accounts
.into_par_iter()
.map(|(vote_pubkey, (_stake, vote_account))| {
let delegated_stake = vote_delegations
.get(vote_pubkey)
Expand All @@ -231,7 +228,7 @@ impl Stakes {
.collect();

// overwrite vote accounts so that staked nodes singleton is reset
self.vote_accounts = VoteAccounts::from(Arc::new(vote_accounts_for_next_epoch));
self.vote_accounts = VoteAccounts::from(ImHashMap::from(vote_accounts_for_next_epoch));
});
}

Expand Down
Loading

0 comments on commit b66527d

Please sign in to comment.