Add epoch_rewards to sysvar cache (#32155)

add epoch_rewards to sysvar cache

Co-authored-by: HaoranYi <haoran.yi@solana.com>
This commit is contained in:
HaoranYi 2023-06-20 15:01:34 -05:00 committed by GitHub
parent bfaf073ecf
commit 203544293b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 4 deletions

View File

@ -8,8 +8,8 @@ use {
instruction::InstructionError,
pubkey::Pubkey,
sysvar::{
clock::Clock, epoch_schedule::EpochSchedule, rent::Rent, slot_hashes::SlotHashes,
stake_history::StakeHistory, Sysvar, SysvarId,
clock::Clock, epoch_rewards::EpochRewards, epoch_schedule::EpochSchedule, rent::Rent,
slot_hashes::SlotHashes, stake_history::StakeHistory, Sysvar, SysvarId,
},
transaction_context::{IndexOfAccount, InstructionContext, TransactionContext},
},
@ -28,6 +28,7 @@ impl ::solana_frozen_abi::abi_example::AbiExample for SysvarCache {
pub struct SysvarCache {
clock: Option<Arc<Clock>>,
epoch_schedule: Option<Arc<EpochSchedule>>,
epoch_rewards: Option<Arc<EpochRewards>>,
#[allow(deprecated)]
fees: Option<Arc<Fees>>,
rent: Option<Arc<Rent>>,
@ -59,6 +60,16 @@ impl SysvarCache {
self.epoch_schedule = Some(Arc::new(epoch_schedule));
}
pub fn get_epoch_rewards(&self) -> Result<Arc<EpochRewards>, InstructionError> {
self.epoch_rewards
.clone()
.ok_or(InstructionError::UnsupportedSysvar)
}
pub fn set_epoch_rewards(&mut self, epoch_rewards: EpochRewards) {
self.epoch_rewards = Some(Arc::new(epoch_rewards));
}
#[deprecated]
#[allow(deprecated)]
pub fn get_fees(&self) -> Result<Arc<Fees>, InstructionError> {
@ -141,6 +152,15 @@ impl SysvarCache {
}
});
}
if self.epoch_rewards.is_none() {
get_account_data(&EpochRewards::id(), &mut |data: &[u8]| {
if let Ok(epoch_rewards) = bincode::deserialize(data) {
self.set_epoch_rewards(epoch_rewards);
}
});
}
#[allow(deprecated)]
if self.fees.is_none() {
get_account_data(&Fees::id(), &mut |data: &[u8]| {

View File

@ -27,7 +27,10 @@ impl Bank {
mod tests {
use {
super::*,
solana_sdk::{genesis_config::create_genesis_config, pubkey::Pubkey},
solana_sdk::{
feature_set, genesis_config::create_genesis_config, pubkey::Pubkey,
sysvar::epoch_rewards::EpochRewards,
},
std::sync::Arc,
};
@ -48,6 +51,7 @@ mod tests {
assert!(bank0_cached_fees.is_ok());
assert!(bank0_cached_rent.is_ok());
assert!(bank0_sysvar_cache.get_slot_hashes().is_err());
assert!(bank0_sysvar_cache.get_epoch_rewards().is_err()); // partitioned epoch reward feature is not enabled
let bank1 = Arc::new(Bank::new_from_parent(
&bank0,
@ -66,6 +70,7 @@ mod tests {
assert!(bank1_cached_fees.is_ok());
assert!(bank1_cached_rent.is_ok());
assert!(bank1_sysvar_cache.get_slot_hashes().is_ok());
assert!(bank1_sysvar_cache.get_epoch_rewards().is_err());
assert_ne!(bank0_cached_clock, bank1_cached_clock);
assert_eq!(bank0_cached_epoch_schedule, bank1_cached_epoch_schedule);
@ -85,6 +90,7 @@ mod tests {
assert!(bank2_cached_fees.is_ok());
assert!(bank2_cached_rent.is_ok());
assert!(bank2_sysvar_cache.get_slot_hashes().is_ok());
assert!(bank2_sysvar_cache.get_epoch_rewards().is_err()); // partitioned epoch reward feature is not enabled
assert_ne!(bank1_cached_clock, bank2_cached_clock);
assert_eq!(bank1_cached_epoch_schedule, bank2_cached_epoch_schedule);
@ -101,7 +107,7 @@ mod tests {
fn test_reset_and_fill_sysvar_cache() {
let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), bank0.slot() + 1);
let mut bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), bank0.slot() + 1);
let bank1_sysvar_cache = bank1.sysvar_cache.read().unwrap();
let bank1_cached_clock = bank1_sysvar_cache.get_clock();
@ -109,12 +115,14 @@ mod tests {
let bank1_cached_fees = bank1_sysvar_cache.get_fees();
let bank1_cached_rent = bank1_sysvar_cache.get_rent();
let bank1_cached_slot_hashes = bank1_sysvar_cache.get_slot_hashes();
let bank1_cached_epoch_rewards = bank1_sysvar_cache.get_epoch_rewards();
assert!(bank1_cached_clock.is_ok());
assert!(bank1_cached_epoch_schedule.is_ok());
assert!(bank1_cached_fees.is_ok());
assert!(bank1_cached_rent.is_ok());
assert!(bank1_cached_slot_hashes.is_ok());
assert!(bank1_cached_epoch_rewards.is_err());
drop(bank1_sysvar_cache);
bank1.reset_sysvar_cache();
@ -125,8 +133,23 @@ mod tests {
assert!(bank1_sysvar_cache.get_fees().is_err());
assert!(bank1_sysvar_cache.get_rent().is_err());
assert!(bank1_sysvar_cache.get_slot_hashes().is_err());
assert!(bank1_sysvar_cache.get_epoch_rewards().is_err());
drop(bank1_sysvar_cache);
// inject a reward sysvar for test
bank1.activate_feature(&feature_set::enable_partitioned_epoch_reward::id());
let expected_epoch_rewards = EpochRewards {
total_rewards: 100,
distributed_rewards: 10,
distribution_complete_block_height: 42,
};
bank1.create_epoch_rewards_sysvar(
expected_epoch_rewards.total_rewards,
expected_epoch_rewards.distributed_rewards,
expected_epoch_rewards.distribution_complete_block_height,
);
bank1.fill_missing_sysvar_cache_entries();
let bank1_sysvar_cache = bank1.sysvar_cache.read().unwrap();
@ -141,5 +164,9 @@ mod tests {
bank1_sysvar_cache.get_slot_hashes(),
bank1_cached_slot_hashes
);
assert_eq!(
*bank1_sysvar_cache.get_epoch_rewards().unwrap(),
expected_epoch_rewards,
);
}
}