Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ use {
native_loader,
pubkey::Pubkey,
rent::Rent,
<<<<<<< HEAD
sysvar::Sysvar,
=======
saturating_add_assign,
>>>>>>> 2370e6143 (Perf: Store deserialized sysvars in the sysvars cache (#22455))
transaction_context::{InstructionAccount, TransactionAccount, TransactionContext},
},
std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc, sync::Arc},
Expand Down Expand Up @@ -946,6 +950,7 @@ impl<'a> InvokeContext<'a> {
&self.current_compute_budget
}

<<<<<<< HEAD
/// Get the value of a sysvar by its id
pub fn get_sysvar<T: Sysvar>(&self, id: &Pubkey) -> Result<T, InstructionError> {
self.sysvars
Expand All @@ -961,6 +966,11 @@ impl<'a> InvokeContext<'a> {
ic_msg!(self, "Unable to get sysvar {}", id);
InstructionError::UnsupportedSysvar
})
=======
/// Get cached sysvars
pub fn get_sysvar_cache(&self) -> &SysvarCache {
&self.sysvar_cache
>>>>>>> 2370e6143 (Perf: Store deserialized sysvars in the sysvars cache (#22455))
}
}

Expand Down
81 changes: 81 additions & 0 deletions program-runtime/src/sysvar_cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#[allow(deprecated)]
use solana_sdk::sysvar::fees::Fees;
use {
solana_sdk::{
instruction::InstructionError,
sysvar::{
clock::Clock, epoch_schedule::EpochSchedule, rent::Rent, slot_hashes::SlotHashes,
},
},
std::sync::Arc,
};

#[cfg(RUSTC_WITH_SPECIALIZATION)]
impl ::solana_frozen_abi::abi_example::AbiExample for SysvarCache {
fn example() -> Self {
// SysvarCache is not Serialize so just rely on Default.
SysvarCache::default()
}
}

#[derive(Default, Clone, Debug)]
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 get_clock(&self) -> Result<Arc<Clock>, InstructionError> {
self.clock
.clone()
.ok_or(InstructionError::UnsupportedSysvar)
}

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));
}
}
41 changes: 35 additions & 6 deletions program-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
//! The solana-program-test provides a BanksClient-based test framework BPF programs
#![allow(clippy::integer_arithmetic)]

<<<<<<< HEAD
// Export types so test clients can limit their solana crate dependencies
pub use solana_banks_client::BanksClient;
=======
>>>>>>> 2370e6143 (Perf: Store deserialized sysvars in the sysvars cache (#22455))
// Export tokio for test clients
pub use tokio;
use {
Expand All @@ -20,10 +23,16 @@ use {
solana_sdk::{
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
account_info::AccountInfo,
<<<<<<< HEAD
clock::{Clock, Slot},
entrypoint::{ProgramResult, SUCCESS},
epoch_schedule::EpochSchedule,
feature_set::demote_program_write_locks,
=======
clock::Slot,
compute_budget::ComputeBudget,
entrypoint::{ProgramResult, SUCCESS},
>>>>>>> 2370e6143 (Perf: Store deserialized sysvars in the sysvars cache (#22455))
fee_calculator::{FeeCalculator, FeeRateGovernor},
genesis_config::{ClusterType, GenesisConfig},
hash::Hash,
Expand All @@ -38,11 +47,15 @@ use {
pubkey::Pubkey,
rent::Rent,
signature::{Keypair, Signer},
<<<<<<< HEAD
sysvar::{
clock, epoch_schedule,
fees::{self, Fees},
rent, Sysvar,
},
=======
sysvar::{Sysvar, SysvarId},
>>>>>>> 2370e6143 (Perf: Store deserialized sysvars in the sysvars cache (#22455))
},
solana_vote_program::vote_state::{VoteState, VoteStateVersions},
std::{
Expand Down Expand Up @@ -191,8 +204,8 @@ macro_rules! processor {
};
}

fn get_sysvar<T: Default + Sysvar + Sized + serde::de::DeserializeOwned>(
id: &Pubkey,
fn get_sysvar<T: Default + Sysvar + Sized + serde::de::DeserializeOwned + Clone>(
sysvar: Result<Arc<T>, InstructionError>,
var_addr: *mut u8,
) -> u64 {
let invoke_context = get_invoke_context();
Expand Down Expand Up @@ -225,7 +238,17 @@ fn get_sysvar<T: Default + Sysvar + Sized + serde::de::DeserializeOwned>(
panic!("Exceeded compute budget");
}

<<<<<<< HEAD
SUCCESS
=======
match sysvar {
Ok(sysvar_data) => unsafe {
*(var_addr as *mut _ as *mut T) = T::clone(&sysvar_data);
SUCCESS
},
Err(_) => UNSUPPORTED_SYSVAR,
}
>>>>>>> 2370e6143 (Perf: Store deserialized sysvars in the sysvars cache (#22455))
}

struct SyscallStubs {}
Expand Down Expand Up @@ -380,19 +403,25 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
}

fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 {
get_sysvar::<Clock>(&clock::id(), var_addr)
get_sysvar(
get_invoke_context().get_sysvar_cache().get_clock(),
var_addr,
)
}

fn sol_get_epoch_schedule_sysvar(&self, var_addr: *mut u8) -> u64 {
get_sysvar::<EpochSchedule>(&epoch_schedule::id(), var_addr)
get_sysvar(
get_invoke_context().get_sysvar_cache().get_epoch_schedule(),
var_addr,
)
}

fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 {
get_sysvar::<Fees>(&fees::id(), var_addr)
get_sysvar(get_invoke_context().get_sysvar_cache().get_fees(), var_addr)
}

fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 {
get_sysvar::<Rent>(&rent::id(), var_addr)
get_sysvar(get_invoke_context().get_sysvar_cache().get_rent(), var_addr)
}
}

Expand Down
Loading