Perf: Store deserialized sysvars in the sysvars cache (#22455)
* Perf: Store deserialized sysvars in sysvars cache * add bench
This commit is contained in:
@ -20,9 +20,7 @@ use {
|
||||
account::{ReadableAccount, WritableAccount},
|
||||
account_info::AccountInfo,
|
||||
blake3, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
|
||||
clock::Clock,
|
||||
entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, SUCCESS},
|
||||
epoch_schedule::EpochSchedule,
|
||||
feature_set::{
|
||||
self, blake3_syscall_enabled, disable_fees_sysvar, do_support_realloc,
|
||||
fixed_memcpy_nonoverlapping_check, libsecp256k1_0_5_upgrade_enabled,
|
||||
@ -36,11 +34,10 @@ use {
|
||||
program::MAX_RETURN_DATA,
|
||||
program_stubs::is_nonoverlapping,
|
||||
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::{Sysvar, SysvarId},
|
||||
transaction_context::InstructionAccount,
|
||||
},
|
||||
std::{
|
||||
@ -50,6 +47,7 @@ use {
|
||||
rc::Rc,
|
||||
slice::from_raw_parts_mut,
|
||||
str::{from_utf8, Utf8Error},
|
||||
sync::Arc,
|
||||
},
|
||||
thiserror::Error as ThisError,
|
||||
};
|
||||
@ -1070,8 +1068,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@ -1082,9 +1080,8 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
|
||||
.consume(invoke_context.get_compute_budget().sysvar_base_cost + size_of::<T>() as u64)?;
|
||||
let var = translate_type_mut::<T>(memory_mapping, var_addr, loader_id)?;
|
||||
|
||||
*var = invoke_context
|
||||
.get_sysvar::<T>(id)
|
||||
.map_err(SyscallError::InstructionError)?;
|
||||
let sysvar: Arc<T> = sysvar.map_err(SyscallError::InstructionError)?;
|
||||
*var = T::clone(sysvar.as_ref());
|
||||
|
||||
Ok(SUCCESS)
|
||||
}
|
||||
@ -1117,8 +1114,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetClockSysvar<'a, 'b> {
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
*result = get_sysvar::<Clock>(
|
||||
&sysvar::clock::id(),
|
||||
*result = get_sysvar(
|
||||
invoke_context.get_sysvar_cache().get_clock(),
|
||||
var_addr,
|
||||
&loader_id,
|
||||
memory_mapping,
|
||||
@ -1154,8 +1151,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a, 'b> {
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
*result = get_sysvar::<EpochSchedule>(
|
||||
&sysvar::epoch_schedule::id(),
|
||||
*result = get_sysvar(
|
||||
invoke_context.get_sysvar_cache().get_epoch_schedule(),
|
||||
var_addr,
|
||||
&loader_id,
|
||||
memory_mapping,
|
||||
@ -1192,8 +1189,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a, 'b> {
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
*result = get_sysvar::<Fees>(
|
||||
&sysvar::fees::id(),
|
||||
*result = get_sysvar(
|
||||
invoke_context.get_sysvar_cache().get_fees(),
|
||||
var_addr,
|
||||
&loader_id,
|
||||
memory_mapping,
|
||||
@ -1229,8 +1226,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetRentSysvar<'a, 'b> {
|
||||
.map_err(SyscallError::InstructionError),
|
||||
result
|
||||
);
|
||||
*result = get_sysvar::<Rent>(
|
||||
&sysvar::rent::id(),
|
||||
*result = get_sysvar(
|
||||
invoke_context.get_sysvar_cache().get_rent(),
|
||||
var_addr,
|
||||
&loader_id,
|
||||
memory_mapping,
|
||||
@ -2919,6 +2916,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogData<'a, 'b> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[allow(deprecated)]
|
||||
use solana_sdk::sysvar::fees::Fees;
|
||||
use {
|
||||
super::*,
|
||||
solana_program_runtime::{invoke_context::InvokeContext, sysvar_cache::SysvarCache},
|
||||
@ -2926,7 +2925,11 @@ mod tests {
|
||||
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
|
||||
},
|
||||
solana_sdk::{
|
||||
account::AccountSharedData, bpf_loader, fee_calculator::FeeCalculator, hash::hashv,
|
||||
account::AccountSharedData,
|
||||
bpf_loader,
|
||||
fee_calculator::FeeCalculator,
|
||||
hash::hashv,
|
||||
sysvar::{clock::Clock, epoch_schedule::EpochSchedule, rent::Rent},
|
||||
transaction_context::TransactionContext,
|
||||
},
|
||||
std::{borrow::Cow, str::FromStr},
|
||||
@ -3811,13 +3814,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);
|
||||
|
||||
let program_id = Pubkey::new_unique();
|
||||
let mut transaction_context = TransactionContext::new(
|
||||
|
Reference in New Issue
Block a user