Optimize stakes cache and rewards at epoch boundaries (#20432)

* Optimize stakes cache and rewards at epoch boundaries

* Fetch from accounts db

* Add cli flag for disabling epoch boundary optimization
This commit is contained in:
Justin Starry
2021-10-06 00:53:26 -04:00
committed by GitHub
parent 48d3627c8b
commit 129716f3f0
10 changed files with 731 additions and 41 deletions

View File

@ -1098,7 +1098,9 @@ fn stake_weighted_credits_observed(
// utility function, used by runtime
// returns a tuple of (stakers_reward,voters_reward)
pub fn redeem_rewards(
#[doc(hidden)]
#[deprecated(note = "remove after optimize_epoch_boundary_updates feature is active")]
pub fn redeem_rewards_slow(
rewarded_epoch: Epoch,
stake_account: &mut AccountSharedData,
vote_account: &mut AccountSharedData,
@ -1147,7 +1149,9 @@ pub fn redeem_rewards(
}
// utility function, used by runtime
pub fn calculate_points(
#[doc(hidden)]
#[deprecated(note = "remove after optimize_epoch_boundary_updates feature is active")]
pub fn calculate_points_slow(
stake_account: &AccountSharedData,
vote_account: &AccountSharedData,
stake_history: Option<&StakeHistory>,
@ -1167,6 +1171,74 @@ pub fn calculate_points(
}
}
// utility function, used by runtime
// returns a tuple of (stakers_reward,voters_reward)
#[doc(hidden)]
pub fn redeem_rewards(
rewarded_epoch: Epoch,
stake_state: StakeState,
stake_account: &mut AccountSharedData,
vote_state: &VoteState,
point_value: &PointValue,
stake_history: Option<&StakeHistory>,
inflation_point_calc_tracer: Option<impl Fn(&InflationPointCalculationEvent)>,
fix_activating_credits_observed: bool,
) -> Result<(u64, u64), InstructionError> {
if let StakeState::Stake(meta, mut stake) = stake_state {
if let Some(inflation_point_calc_tracer) = inflation_point_calc_tracer.as_ref() {
inflation_point_calc_tracer(
&InflationPointCalculationEvent::EffectiveStakeAtRewardedEpoch(
stake.stake(rewarded_epoch, stake_history),
),
);
inflation_point_calc_tracer(&InflationPointCalculationEvent::RentExemptReserve(
meta.rent_exempt_reserve,
));
inflation_point_calc_tracer(&InflationPointCalculationEvent::Commission(
vote_state.commission,
));
}
if let Some((stakers_reward, voters_reward)) = redeem_stake_rewards(
rewarded_epoch,
&mut stake,
point_value,
vote_state,
stake_history,
inflation_point_calc_tracer,
fix_activating_credits_observed,
) {
stake_account.checked_add_lamports(stakers_reward)?;
stake_account.set_state(&StakeState::Stake(meta, stake))?;
Ok((stakers_reward, voters_reward))
} else {
Err(StakeError::NoCreditsToRedeem.into())
}
} else {
Err(InstructionError::InvalidAccountData)
}
}
// utility function, used by runtime
#[doc(hidden)]
pub fn calculate_points(
stake_state: &StakeState,
vote_state: &VoteState,
stake_history: Option<&StakeHistory>,
) -> Result<u128, InstructionError> {
if let StakeState::Stake(_meta, stake) = stake_state {
Ok(calculate_stake_points(
stake,
vote_state,
stake_history,
null_tracer(),
))
} else {
Err(InstructionError::InvalidAccountData)
}
}
// utility function, used by Split
//This emulates current Rent math in order to preserve backward compatibility. In the future, and
//to support variable rent, the Split instruction should pass in the Rent sysvar instead.