Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Merged
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
34 changes: 18 additions & 16 deletions program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ use {
solana_sdk::{
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
account_info::AccountInfo,
clock::{Clock, Slot},
clock::Slot,
entrypoint::{ProgramResult, SUCCESS},
epoch_schedule::EpochSchedule,
execute_timings::ExecuteTimings,
feature_set::demote_program_write_locks,
fee_calculator::{FeeCalculator, FeeRateGovernor},
Expand All @@ -33,17 +32,13 @@ use {
native_token::sol_to_lamports,
poh_config::PohConfig,
process_instruction::{
self, stable_log, BpfComputeBudget, InvokeContext, ProcessInstructionWithContext,
stable_log, BpfComputeBudget, InvokeContext, ProcessInstructionWithContext,
},
program_error::{ProgramError, ACCOUNT_BORROW_FAILED, UNSUPPORTED_SYSVAR},
pubkey::Pubkey,
rent::Rent,
signature::{Keypair, Signer},
sysvar::{
clock, epoch_schedule,
fees::{self, Fees},
rent, Sysvar,
},
sysvar::Sysvar,
},
solana_vote_program::vote_state::{VoteState, VoteStateVersions},
std::{
Expand Down Expand Up @@ -192,8 +187,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 All @@ -207,9 +202,10 @@ fn get_sysvar<T: Default + Sysvar + Sized + serde::de::DeserializeOwned>(
{
panic!("Exceeded compute budget");
}
match process_instruction::get_sysvar::<T>(invoke_context, id) {

match sysvar {
Ok(sysvar_data) => unsafe {
*(var_addr as *mut _ as *mut T) = sysvar_data;
*(var_addr as *mut _ as *mut T) = T::clone(&sysvar_data);
SUCCESS
},
Err(_) => UNSUPPORTED_SYSVAR,
Expand Down Expand Up @@ -368,19 +364,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
85 changes: 52 additions & 33 deletions programs/bpf_loader/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ use {
account_utils::StateMut,
bpf_loader, bpf_loader_deprecated,
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
clock::Clock,
entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, SUCCESS},
epoch_schedule::EpochSchedule,
feature_set::{
allow_native_ids, check_seed_length, close_upgradeable_program_accounts, cpi_data_cost,
demote_program_write_locks, enforce_aligned_host_addrs, keccak256_syscall_enabled,
Expand All @@ -33,14 +31,13 @@ use {
keccak,
keyed_account::KeyedAccount,
native_loader,
process_instruction::{self, stable_log, ComputeMeter, InvokeContext, Logger},
process_instruction::{stable_log, ComputeMeter, InvokeContext, Logger},
program::MAX_RETURN_DATA,
pubkey::{Pubkey, PubkeyError, MAX_SEEDS, MAX_SEED_LEN},
rent::Rent,
secp256k1_recover::{
Secp256k1RecoverError, SECP256K1_PUBLIC_KEY_LENGTH, SECP256K1_SIGNATURE_LENGTH,
},
sysvar::{self, fees::Fees, Sysvar, SysvarId},
sysvar::{self, Sysvar, SysvarId},
},
std::{
alloc::Layout,
Expand All @@ -50,6 +47,7 @@ use {
rc::Rc,
slice::from_raw_parts_mut,
str::{from_utf8, Utf8Error},
sync::Arc,
},
thiserror::Error as ThisError,
};
Expand Down Expand Up @@ -1142,17 +1140,13 @@ impl<'a> SyscallObject<BpfError> for SyscallSha256<'a> {
}
}

fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
id: &Pubkey,
fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId + Clone>(
sysvar: Result<Arc<T>, InstructionError>,
var_addr: u64,
loader_id: &Pubkey,
memory_mapping: &MemoryMapping,
invoke_context: Rc<RefCell<&mut dyn InvokeContext>>,
invoke_context: &dyn InvokeContext,
) -> Result<u64, EbpfError<BpfError>> {
let invoke_context = invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed)?;

invoke_context.get_compute_meter().consume(
invoke_context.get_bpf_compute_budget().sysvar_base_cost + size_of::<T>() as u64,
)?;
Expand All @@ -1163,8 +1157,8 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
invoke_context.is_feature_active(&enforce_aligned_host_addrs::id()),
)?;

*var = process_instruction::get_sysvar::<T>(*invoke_context, id)
.map_err(SyscallError::InstructionError)?;
let sysvar: Arc<T> = sysvar.map_err(SyscallError::InstructionError)?;
*var = T::clone(sysvar.as_ref());

Ok(SUCCESS)
}
Expand All @@ -1185,12 +1179,18 @@ impl<'a> SyscallObject<BpfError> for SyscallGetClockSysvar<'a> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
*result = get_sysvar::<Clock>(
&sysvar::clock::id(),
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_clock(),
var_addr,
self.loader_id,
memory_mapping,
self.invoke_context.clone(),
*invoke_context,
);
}
}
Expand All @@ -1210,12 +1210,18 @@ impl<'a> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
*result = get_sysvar::<EpochSchedule>(
&sysvar::epoch_schedule::id(),
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_epoch_schedule(),
var_addr,
self.loader_id,
memory_mapping,
self.invoke_context.clone(),
*invoke_context,
);
}
}
Expand All @@ -1235,12 +1241,18 @@ impl<'a> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
*result = get_sysvar::<Fees>(
&sysvar::fees::id(),
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_fees(),
var_addr,
self.loader_id,
memory_mapping,
self.invoke_context.clone(),
*invoke_context,
);
}
}
Expand All @@ -1260,12 +1272,18 @@ impl<'a> SyscallObject<BpfError> for SyscallGetRentSysvar<'a> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
*result = get_sysvar::<Rent>(
&sysvar::rent::id(),
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_rent(),
var_addr,
self.loader_id,
memory_mapping,
self.invoke_context.clone(),
*invoke_context,
);
}
}
Expand Down Expand Up @@ -2771,9 +2789,13 @@ mod tests {
},
solana_sdk::{
bpf_loader,
clock::Clock,
epoch_schedule::EpochSchedule,
fee_calculator::FeeCalculator,
hash::hashv,
process_instruction::{MockComputeMeter, MockInvokeContext, MockLogger},
rent::Rent,
sysvar::fees::Fees,
sysvar_cache::SysvarCache,
},
std::{borrow::Cow, str::FromStr},
Expand Down Expand Up @@ -3647,13 +3669,10 @@ mod tests {
};

let mut sysvar_cache = SysvarCache::default();
sysvar_cache.push_entry(sysvar::clock::id(), bincode::serialize(&src_clock).unwrap());
sysvar_cache.push_entry(
sysvar::epoch_schedule::id(),
bincode::serialize(&src_epochschedule).unwrap(),
);
sysvar_cache.push_entry(sysvar::fees::id(), bincode::serialize(&src_fees).unwrap());
sysvar_cache.push_entry(sysvar::rent::id(), bincode::serialize(&src_rent).unwrap());
sysvar_cache.set_clock(src_clock.clone());
sysvar_cache.set_epoch_schedule(src_epochschedule);
sysvar_cache.set_fees(src_fees.clone());
sysvar_cache.set_rent(src_rent);

// Test clock sysvar
{
Expand Down
24 changes: 9 additions & 15 deletions programs/stake/src/stake_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ use {
feature_set,
instruction::InstructionError,
keyed_account::{from_keyed_account, get_signers, keyed_account_at_index},
process_instruction::{get_sysvar, InvokeContext},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
stake::{
instruction::StakeInstruction,
program::id,
state::{Authorized, Lockup},
},
sysvar::{self, clock::Clock, rent::Rent, stake_history::StakeHistory},
sysvar::{clock::Clock, rent::Rent, stake_history::StakeHistory},
},
};

Expand Down Expand Up @@ -167,11 +167,11 @@ pub fn process_instruction(
),
StakeInstruction::SetLockup(lockup) => {
let clock = if invoke_context.is_feature_active(&feature_set::stake_program_v4::id()) {
Some(get_sysvar::<Clock>(invoke_context, &sysvar::clock::id())?)
Some(invoke_context.get_sysvar_cache().get_clock()?)
} else {
None
};
me.set_lockup(&lockup, &signers, clock.as_ref())
me.set_lockup(&lockup, &signers, clock.as_deref())
}
StakeInstruction::InitializeChecked => {
if invoke_context.is_feature_active(&feature_set::vote_stake_checked_instructions::id())
Expand Down Expand Up @@ -262,8 +262,8 @@ pub fn process_instruction(
epoch: lockup_checked.epoch,
custodian,
};
let clock = Some(get_sysvar::<Clock>(invoke_context, &sysvar::clock::id())?);
me.set_lockup(&lockup, &signers, clock.as_ref())
let clock = Some(invoke_context.get_sysvar_cache().get_clock()?);
me.set_lockup(&lockup, &signers, clock.as_deref())
} else {
Err(InstructionError::InvalidInstructionData)
}
Expand All @@ -288,7 +288,7 @@ mod tests {
instruction::{self, LockupArgs},
state::{Authorized, Lockup, StakeAuthorize},
},
sysvar::stake_history::StakeHistory,
sysvar::{self, stake_history::StakeHistory},
sysvar_cache::SysvarCache,
},
std::{borrow::Cow, cell::RefCell, str::FromStr},
Expand Down Expand Up @@ -372,10 +372,7 @@ mod tests {

let mut invoke_context = MockInvokeContext::new(keyed_accounts);
let mut sysvar_cache = SysvarCache::default();
sysvar_cache.push_entry(
sysvar::clock::id(),
bincode::serialize(&Clock::default()).unwrap(),
);
sysvar_cache.set_clock(Clock::default());
invoke_context.sysvar_cache = Cow::Owned(sysvar_cache);
super::process_instruction(&Pubkey::default(), &instruction.data, &mut invoke_context)
}
Expand Down Expand Up @@ -1040,10 +1037,7 @@ mod tests {

let mut invoke_context = MockInvokeContext::new(keyed_accounts);
let mut sysvar_cache = SysvarCache::default();
sysvar_cache.push_entry(
sysvar::clock::id(),
bincode::serialize(&Clock::default()).unwrap(),
);
sysvar_cache.set_clock(Clock::default());
invoke_context.sysvar_cache = Cow::Owned(sysvar_cache);

assert_eq!(
Expand Down
Loading