add store_vote_accounts_partitioned (#32061)
* add store_vote_accounts_partitioned * pr feedback
This commit is contained in:
parent
9b2c9b8f5a
commit
b89ce94d33
|
@ -1105,7 +1105,7 @@ struct VoteReward {
|
||||||
|
|
||||||
type VoteRewards = DashMap<Pubkey, VoteReward>;
|
type VoteRewards = DashMap<Pubkey, VoteReward>;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
struct VoteRewardsAccounts {
|
struct VoteRewardsAccounts {
|
||||||
/// reward info for each vote account pubkey.
|
/// reward info for each vote account pubkey.
|
||||||
/// This type is used by `update_reward_history()`
|
/// This type is used by `update_reward_history()`
|
||||||
|
@ -3164,6 +3164,33 @@ impl Bank {
|
||||||
.sum::<i64>() as u64
|
.sum::<i64>() as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn store_vote_accounts_partitioned(
|
||||||
|
&self,
|
||||||
|
vote_account_rewards: VoteRewardsAccounts,
|
||||||
|
metrics: &mut RewardsMetrics,
|
||||||
|
) -> Vec<(Pubkey, RewardInfo)> {
|
||||||
|
let (_, measure_us) = measure_us!({
|
||||||
|
// reformat data to make it not sparse.
|
||||||
|
// `StorableAccounts` does not efficiently handle sparse data.
|
||||||
|
// Not all entries in `vote_account_rewards.accounts_to_store` have a Some(account) to store.
|
||||||
|
let to_store = vote_account_rewards
|
||||||
|
.accounts_to_store
|
||||||
|
.iter()
|
||||||
|
.filter_map(|account| account.as_ref())
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, account)| (&vote_account_rewards.rewards[i].0, account))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
self.store_accounts((self.slot(), &to_store[..], self.include_slot_in_hash()));
|
||||||
|
});
|
||||||
|
|
||||||
|
metrics
|
||||||
|
.store_vote_accounts_us
|
||||||
|
.fetch_add(measure_us, Relaxed);
|
||||||
|
|
||||||
|
vote_account_rewards.rewards
|
||||||
|
}
|
||||||
|
|
||||||
fn store_vote_accounts(
|
fn store_vote_accounts(
|
||||||
&self,
|
&self,
|
||||||
vote_account_rewards: VoteRewards,
|
vote_account_rewards: VoteRewards,
|
||||||
|
|
|
@ -159,6 +159,30 @@ impl StakeReward {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl VoteReward {
|
||||||
|
pub fn new_random() -> Self {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let validator_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
let validator_stake_lamports = rng.gen_range(1, 200);
|
||||||
|
let validator_voting_keypair = Keypair::new();
|
||||||
|
|
||||||
|
let validator_vote_account = vote_state::create_account(
|
||||||
|
&validator_voting_keypair.pubkey(),
|
||||||
|
&validator_pubkey,
|
||||||
|
rng.gen_range(1, 20),
|
||||||
|
validator_stake_lamports,
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
vote_account: validator_vote_account,
|
||||||
|
commission: rng.gen_range(1, 20),
|
||||||
|
vote_rewards: rng.gen_range(1, 200),
|
||||||
|
vote_needs_store: rng.gen_range(1, 20) > 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_race_register_tick_freeze() {
|
fn test_race_register_tick_freeze() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
@ -12661,6 +12685,62 @@ fn test_update_reward_history_in_partition_empty() {
|
||||||
assert_eq!(num_in_history, 0);
|
assert_eq!(num_in_history, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_store_vote_accounts_partitioned() {
|
||||||
|
let (genesis_config, _mint_keypair) = create_genesis_config(1_000_000 * LAMPORTS_PER_SOL);
|
||||||
|
let bank = Bank::new_for_tests(&genesis_config);
|
||||||
|
|
||||||
|
let expected_vote_rewards_num = 100;
|
||||||
|
|
||||||
|
let vote_rewards = (0..expected_vote_rewards_num)
|
||||||
|
.map(|_| Some((Pubkey::new_unique(), VoteReward::new_random())))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut vote_rewards_account = VoteRewardsAccounts::default();
|
||||||
|
vote_rewards.iter().for_each(|e| {
|
||||||
|
if let Some(p) = &e {
|
||||||
|
let info = RewardInfo {
|
||||||
|
reward_type: RewardType::Voting,
|
||||||
|
lamports: p.1.vote_rewards as i64,
|
||||||
|
post_balance: p.1.vote_rewards,
|
||||||
|
commission: Some(p.1.commission),
|
||||||
|
};
|
||||||
|
vote_rewards_account.rewards.push((p.0, info));
|
||||||
|
vote_rewards_account
|
||||||
|
.accounts_to_store
|
||||||
|
.push(e.as_ref().map(|p| p.1.vote_account.clone()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut metrics = RewardsMetrics::default();
|
||||||
|
|
||||||
|
let stored_vote_accounts =
|
||||||
|
bank.store_vote_accounts_partitioned(vote_rewards_account, &mut metrics);
|
||||||
|
assert_eq!(expected_vote_rewards_num, stored_vote_accounts.len());
|
||||||
|
|
||||||
|
// load accounts to make sure they were stored correctly
|
||||||
|
vote_rewards.iter().for_each(|e| {
|
||||||
|
if let Some(p) = &e {
|
||||||
|
let (k, account) = (p.0, p.1.vote_account.clone());
|
||||||
|
let loaded_account = bank.load_slow_with_fixed_root(&bank.ancestors, &k).unwrap();
|
||||||
|
assert!(accounts_equal(&loaded_account.0, &account));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_store_vote_accounts_partitioned_empty() {
|
||||||
|
let (genesis_config, _mint_keypair) = create_genesis_config(1_000_000 * LAMPORTS_PER_SOL);
|
||||||
|
let bank = Bank::new_for_tests(&genesis_config);
|
||||||
|
|
||||||
|
let expected = 0;
|
||||||
|
let vote_rewards = VoteRewardsAccounts::default();
|
||||||
|
let mut metrics = RewardsMetrics::default();
|
||||||
|
|
||||||
|
let stored_vote_accounts = bank.store_vote_accounts_partitioned(vote_rewards, &mut metrics);
|
||||||
|
assert_eq!(expected, stored_vote_accounts.len());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_system_instruction_allocate() {
|
fn test_system_instruction_allocate() {
|
||||||
let (genesis_config, mint_keypair) = create_genesis_config(sol_to_lamports(1.0));
|
let (genesis_config, mint_keypair) = create_genesis_config(sol_to_lamports(1.0));
|
||||||
|
|
Loading…
Reference in New Issue