* Perf: Store deserialized sysvars in the sysvars cache (#22455) * Perf: Store deserialized sysvars in sysvars cache * add bench * resolve conflicts Co-authored-by: Justin Starry <justin@solana.com>
This commit is contained in:
@ -27,7 +27,6 @@ use {
|
||||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
saturating_add_assign,
|
||||
sysvar::Sysvar,
|
||||
},
|
||||
std::{borrow::Cow, cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc, sync::Arc},
|
||||
};
|
||||
@ -951,21 +950,9 @@ impl<'a> InvokeContext<'a> {
|
||||
&self.current_compute_budget
|
||||
}
|
||||
|
||||
/// Get the value of a sysvar by its id
|
||||
pub fn get_sysvar<T: Sysvar>(&self, id: &Pubkey) -> Result<T, InstructionError> {
|
||||
self.sysvar_cache
|
||||
.iter()
|
||||
.find_map(|(key, data)| {
|
||||
if id == key {
|
||||
bincode::deserialize(data).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
ic_msg!(self, "Unable to get sysvar {}", id);
|
||||
InstructionError::UnsupportedSysvar
|
||||
})
|
||||
/// Get cached sysvars
|
||||
pub fn get_sysvar_cache(&self) -> &SysvarCache {
|
||||
&self.sysvar_cache
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,13 @@
|
||||
#[allow(deprecated)]
|
||||
use solana_sdk::sysvar::fees::Fees;
|
||||
use {
|
||||
solana_sdk::{
|
||||
account::{AccountSharedData, ReadableAccount},
|
||||
pubkey::Pubkey,
|
||||
instruction::InstructionError,
|
||||
sysvar::{
|
||||
clock::Clock, epoch_schedule::EpochSchedule, rent::Rent, slot_hashes::SlotHashes,
|
||||
},
|
||||
},
|
||||
std::ops::Deref,
|
||||
std::sync::Arc,
|
||||
};
|
||||
|
||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||
@ -15,25 +19,63 @@ impl ::solana_frozen_abi::abi_example::AbiExample for SysvarCache {
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct SysvarCache(Vec<(Pubkey, Vec<u8>)>);
|
||||
|
||||
impl Deref for SysvarCache {
|
||||
type Target = Vec<(Pubkey, Vec<u8>)>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
pub struct SysvarCache {
|
||||
clock: Option<Arc<Clock>>,
|
||||
epoch_schedule: Option<Arc<EpochSchedule>>,
|
||||
#[allow(deprecated)]
|
||||
fees: Option<Arc<Fees>>,
|
||||
rent: Option<Arc<Rent>>,
|
||||
slot_hashes: Option<Arc<SlotHashes>>,
|
||||
}
|
||||
|
||||
impl SysvarCache {
|
||||
pub fn push_entry(&mut self, pubkey: Pubkey, data: Vec<u8>) {
|
||||
self.0.push((pubkey, data));
|
||||
pub fn get_clock(&self) -> Result<Arc<Clock>, InstructionError> {
|
||||
self.clock
|
||||
.clone()
|
||||
.ok_or(InstructionError::UnsupportedSysvar)
|
||||
}
|
||||
|
||||
pub fn update_entry(&mut self, pubkey: &Pubkey, new_account: &AccountSharedData) {
|
||||
if let Some(position) = self.iter().position(|(id, _data)| id == pubkey) {
|
||||
self.0[position].1 = new_account.data().to_vec();
|
||||
} else {
|
||||
self.0.push((*pubkey, new_account.data().to_vec()));
|
||||
}
|
||||
pub fn set_clock(&mut self, clock: Clock) {
|
||||
self.clock = Some(Arc::new(clock));
|
||||
}
|
||||
|
||||
pub fn get_epoch_schedule(&self) -> Result<Arc<EpochSchedule>, InstructionError> {
|
||||
self.epoch_schedule
|
||||
.clone()
|
||||
.ok_or(InstructionError::UnsupportedSysvar)
|
||||
}
|
||||
|
||||
pub fn set_epoch_schedule(&mut self, epoch_schedule: EpochSchedule) {
|
||||
self.epoch_schedule = Some(Arc::new(epoch_schedule));
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[allow(deprecated)]
|
||||
pub fn get_fees(&self) -> Result<Arc<Fees>, InstructionError> {
|
||||
self.fees.clone().ok_or(InstructionError::UnsupportedSysvar)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[allow(deprecated)]
|
||||
pub fn set_fees(&mut self, fees: Fees) {
|
||||
self.fees = Some(Arc::new(fees));
|
||||
}
|
||||
|
||||
pub fn get_rent(&self) -> Result<Arc<Rent>, InstructionError> {
|
||||
self.rent.clone().ok_or(InstructionError::UnsupportedSysvar)
|
||||
}
|
||||
|
||||
pub fn set_rent(&mut self, rent: Rent) {
|
||||
self.rent = Some(Arc::new(rent));
|
||||
}
|
||||
|
||||
pub fn get_slot_hashes(&self) -> Result<Arc<SlotHashes>, InstructionError> {
|
||||
self.slot_hashes
|
||||
.clone()
|
||||
.ok_or(InstructionError::UnsupportedSysvar)
|
||||
}
|
||||
|
||||
pub fn set_slot_hashes(&mut self, slot_hashes: SlotHashes) {
|
||||
self.slot_hashes = Some(Arc::new(slot_hashes));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user