Don't overwrite accounts with stale copies
This commit is contained in:
@@ -935,11 +935,11 @@ impl Bank {
|
||||
.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
|
||||
/// ( (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
|
||||
.read()
|
||||
.unwrap()
|
||||
@@ -950,25 +950,35 @@ impl Bank {
|
||||
self.get_account(&stake_pubkey),
|
||||
self.get_account(&delegation.voter_pubkey),
|
||||
) {
|
||||
(Some(stake_account), Some(vote_account)) => Some((
|
||||
(*stake_pubkey, stake_account),
|
||||
(delegation.voter_pubkey, vote_account),
|
||||
)),
|
||||
(Some(_stake_account), Some(_vote_account)) => {
|
||||
Some((*stake_pubkey, delegation.voter_pubkey))
|
||||
}
|
||||
(_, _) => None,
|
||||
}
|
||||
})
|
||||
.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
|
||||
/// successfully load and parse, return total payout
|
||||
fn pay_validator_rewards(&mut self, rewards: u64) -> f64 {
|
||||
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()
|
||||
.map(|pubkeys| self.paired_accounts(*pubkeys))
|
||||
.map(
|
||||
|((_stake_pubkey, stake_account), (_vote_pubkey, vote_account))| {
|
||||
stake_state::calculate_points(
|
||||
@@ -990,33 +1000,36 @@ impl Bank {
|
||||
let mut rewards = HashMap::new();
|
||||
|
||||
// pay according to point value
|
||||
stake_delegation_accounts.iter_mut().for_each(
|
||||
|((stake_pubkey, stake_account), (vote_pubkey, vote_account))| {
|
||||
let redeemed = stake_state::redeem_rewards(
|
||||
stake_account,
|
||||
vote_account,
|
||||
&point_value,
|
||||
Some(&stake_history),
|
||||
);
|
||||
if let Ok((stakers_reward, voters_reward)) = redeemed {
|
||||
self.store_account(&stake_pubkey, &stake_account);
|
||||
self.store_account(&vote_pubkey, &vote_account);
|
||||
|
||||
if voters_reward > 0 {
|
||||
*rewards.entry(*vote_pubkey).or_insert(0i64) += voters_reward as i64;
|
||||
}
|
||||
|
||||
if stakers_reward > 0 {
|
||||
*rewards.entry(*stake_pubkey).or_insert(0i64) += stakers_reward as i64;
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
"stake_state::redeem_rewards() failed for {}: {:?}",
|
||||
stake_pubkey, redeemed
|
||||
stake_delegation_pubkeys
|
||||
.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(
|
||||
&mut stake_account,
|
||||
&mut vote_account,
|
||||
&point_value,
|
||||
Some(&stake_history),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
if let Ok((stakers_reward, voters_reward)) = redeemed {
|
||||
self.store_account(&stake_pubkey, &stake_account);
|
||||
self.store_account(&vote_pubkey, &vote_account);
|
||||
|
||||
if voters_reward > 0 {
|
||||
*rewards.entry(vote_pubkey).or_insert(0i64) += voters_reward as i64;
|
||||
}
|
||||
|
||||
if stakers_reward > 0 {
|
||||
*rewards.entry(stake_pubkey).or_insert(0i64) += stakers_reward as i64;
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
"stake_state::redeem_rewards() failed for {}: {:?}",
|
||||
stake_pubkey, redeemed
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
assert_eq!(self.rewards, None);
|
||||
self.rewards = Some(rewards.drain().collect());
|
||||
@@ -4768,8 +4781,9 @@ mod tests {
|
||||
bank.store_account(&vote_id, &vote_account);
|
||||
|
||||
let validator_points: u128 = bank
|
||||
.stake_delegation_accounts()
|
||||
.stake_delegation_pubkeys()
|
||||
.iter()
|
||||
.map(|pubkeys| bank.paired_accounts(*pubkeys))
|
||||
.map(
|
||||
|((_stake_pubkey, stake_account), (_vote_pubkey, vote_account))| {
|
||||
stake_state::calculate_points(&stake_account, &vote_account, None).unwrap_or(0)
|
||||
|
Reference in New Issue
Block a user