Perf: Store deserialized sysvars in the sysvars cache (#22455)

* Perf: Store deserialized sysvars in sysvars cache

* add bench
This commit is contained in:
Justin Starry
2022-01-13 13:36:21 +08:00
committed by GitHub
parent f2908ed475
commit 2370e61431
11 changed files with 382 additions and 165 deletions

View File

@ -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(