Don't overwrite accounts with stale copies

This commit is contained in:
Ryo Onodera
2020-07-18 00:32:25 +09:00
parent 0a72e3cfe0
commit 9886d085a6

View File

@@ -935,11 +935,11 @@ impl Bank {
.fetch_add(validator_rewards_paid, Ordering::Relaxed); .fetch_add(validator_rewards_paid, Ordering::Relaxed);
} }
/// map stake delegations into resolved (pubkey, account) pairs /// map stake delegations into resolved pubkeys
/// returns a vector (has to be copied) of loaded /// returns a vector (has to be copied) of loaded
/// ( (staker info) (voter info) ) /// ( staker pubkey voter pubkey )
/// ///
fn stake_delegation_accounts(&self) -> Vec<((Pubkey, Account), (Pubkey, Account))> { fn stake_delegation_pubkeys(&self) -> Vec<(Pubkey, Pubkey)> {
self.stakes self.stakes
.read() .read()
.unwrap() .unwrap()
@@ -950,25 +950,35 @@ impl Bank {
self.get_account(&stake_pubkey), self.get_account(&stake_pubkey),
self.get_account(&delegation.voter_pubkey), self.get_account(&delegation.voter_pubkey),
) { ) {
(Some(stake_account), Some(vote_account)) => Some(( (Some(_stake_account), Some(_vote_account)) => {
(*stake_pubkey, stake_account), Some((*stake_pubkey, delegation.voter_pubkey))
(delegation.voter_pubkey, vote_account), }
)),
(_, _) => None, (_, _) => None,
} }
}) })
.collect() .collect()
} }
fn paired_accounts(
&self,
(stake_pubkey, vote_pubkey): (Pubkey, Pubkey),
) -> ((Pubkey, Account), (Pubkey, Account)) {
(
(stake_pubkey, self.get_account(&stake_pubkey).unwrap()),
(vote_pubkey, self.get_account(&vote_pubkey).unwrap()),
)
}
/// iterate over all stakes, redeem vote credits for each stake we can /// iterate over all stakes, redeem vote credits for each stake we can
/// successfully load and parse, return total payout /// successfully load and parse, return total payout
fn pay_validator_rewards(&mut self, rewards: u64) -> f64 { fn pay_validator_rewards(&mut self, rewards: u64) -> f64 {
let stake_history = self.stakes.read().unwrap().history().clone(); let stake_history = self.stakes.read().unwrap().history().clone();
let mut stake_delegation_accounts = self.stake_delegation_accounts(); let stake_delegation_pubkeys = self.stake_delegation_pubkeys();
let points: u128 = stake_delegation_accounts let points: u128 = stake_delegation_pubkeys
.iter() .iter()
.map(|pubkeys| self.paired_accounts(*pubkeys))
.map( .map(
|((_stake_pubkey, stake_account), (_vote_pubkey, vote_account))| { |((_stake_pubkey, stake_account), (_vote_pubkey, vote_account))| {
stake_state::calculate_points( stake_state::calculate_points(
@@ -990,11 +1000,14 @@ impl Bank {
let mut rewards = HashMap::new(); let mut rewards = HashMap::new();
// pay according to point value // pay according to point value
stake_delegation_accounts.iter_mut().for_each( stake_delegation_pubkeys
|((stake_pubkey, stake_account), (vote_pubkey, vote_account))| { .into_iter()
.map(|pubkeys| self.paired_accounts(pubkeys))
.for_each(
|((stake_pubkey, mut stake_account), (vote_pubkey, mut vote_account))| {
let redeemed = stake_state::redeem_rewards( let redeemed = stake_state::redeem_rewards(
stake_account, &mut stake_account,
vote_account, &mut vote_account,
&point_value, &point_value,
Some(&stake_history), Some(&stake_history),
); );
@@ -1003,11 +1016,11 @@ impl Bank {
self.store_account(&vote_pubkey, &vote_account); self.store_account(&vote_pubkey, &vote_account);
if voters_reward > 0 { if voters_reward > 0 {
*rewards.entry(*vote_pubkey).or_insert(0i64) += voters_reward as i64; *rewards.entry(vote_pubkey).or_insert(0i64) += voters_reward as i64;
} }
if stakers_reward > 0 { if stakers_reward > 0 {
*rewards.entry(*stake_pubkey).or_insert(0i64) += stakers_reward as i64; *rewards.entry(stake_pubkey).or_insert(0i64) += stakers_reward as i64;
} }
} else { } else {
debug!( debug!(
@@ -4768,8 +4781,9 @@ mod tests {
bank.store_account(&vote_id, &vote_account); bank.store_account(&vote_id, &vote_account);
let validator_points: u128 = bank let validator_points: u128 = bank
.stake_delegation_accounts() .stake_delegation_pubkeys()
.iter() .iter()
.map(|pubkeys| bank.paired_accounts(*pubkeys))
.map( .map(
|((_stake_pubkey, stake_account), (_vote_pubkey, vote_account))| { |((_stake_pubkey, stake_account), (_vote_pubkey, vote_account))| {
stake_state::calculate_points(&stake_account, &vote_account, None).unwrap_or(0) stake_state::calculate_points(&stake_account, &vote_account, None).unwrap_or(0)