diff --git a/harness/src/fuzz/firedancer.rs b/harness/src/fuzz/firedancer.rs index bdf77f05..dee98721 100644 --- a/harness/src/fuzz/firedancer.rs +++ b/harness/src/fuzz/firedancer.rs @@ -8,7 +8,6 @@ use { crate::{ accounts::{compile_accounts, CompiledAccounts}, result::{Check, InstructionResult}, - sysvar::Sysvars, Mollusk, DEFAULT_LOADER_KEY, }, mollusk_svm_fuzz_fixture_firedancer::{ @@ -136,7 +135,6 @@ fn parse_fixture_context( let mollusk = Mollusk { compute_budget, feature_set: epoch_context.feature_set.clone(), - sysvars: Sysvars::fill_from_accounts(&accounts), ..Default::default() }; diff --git a/harness/src/lib.rs b/harness/src/lib.rs index 5fa5102d..ab808f89 100644 --- a/harness/src/lib.rs +++ b/harness/src/lib.rs @@ -44,10 +44,7 @@ use { accounts::CompiledAccounts, mollusk_svm_error::error::{MolluskError, MolluskPanic}, solana_compute_budget::compute_budget::ComputeBudget, - solana_program_runtime::{ - invoke_context::{EnvironmentConfig, InvokeContext}, - sysvar_cache::SysvarCache, - }, + solana_program_runtime::invoke_context::{EnvironmentConfig, InvokeContext}, solana_sdk::{ account::AccountSharedData, bpf_loader_upgradeable, feature_set::FeatureSet, fee::FeeStructure, hash::Hash, instruction::Instruction, pubkey::Pubkey, @@ -175,17 +172,18 @@ impl Mollusk { ); let invoke_result = { - let mut cache = self.program_cache.cache().write().unwrap(); + let mut program_cache = self.program_cache.cache().write().unwrap(); + let sysvar_cache = self.sysvars.setup_sysvar_cache(accounts); InvokeContext::new( &mut transaction_context, - &mut cache, + &mut program_cache, EnvironmentConfig::new( Hash::default(), None, None, Arc::new(self.feature_set.clone()), self.fee_structure.lamports_per_signature, - &SysvarCache::from(&self.sysvars), + &sysvar_cache, ), None, self.compute_budget, diff --git a/harness/src/sysvar.rs b/harness/src/sysvar.rs index 4fd6a544..9972a2b2 100644 --- a/harness/src/sysvar.rs +++ b/harness/src/sysvar.rs @@ -59,36 +59,6 @@ impl Default for Sysvars { } impl Sysvars { - /// Create a `Sysvars` instance from a list of accounts. Any missing - /// sysvars will be filled with default values. - pub fn fill_from_accounts(accounts: &[(Pubkey, AccountSharedData)]) -> Self { - let mut me = Self::default(); - for (key, account) in accounts { - if key == &Clock::id() { - me.clock = bincode::deserialize(account.data()).unwrap(); - } - if key == &EpochRewards::id() { - me.epoch_rewards = bincode::deserialize(account.data()).unwrap(); - } - if key == &EpochSchedule::id() { - me.epoch_schedule = bincode::deserialize(account.data()).unwrap(); - } - if key == &LastRestartSlot::id() { - me.last_restart_slot = bincode::deserialize(account.data()).unwrap(); - } - if key == &Rent::id() { - me.rent = bincode::deserialize(account.data()).unwrap(); - } - if key == &SlotHashes::id() { - me.slot_hashes = bincode::deserialize(account.data()).unwrap(); - } - if key == &StakeHistory::id() { - me.stake_history = bincode::deserialize(account.data()).unwrap(); - } - } - me - } - fn sysvar_account(&self, sysvar: &T) -> (Pubkey, AccountSharedData) { let data = bincode::serialize::(sysvar).unwrap(); let space = data.len(); @@ -172,6 +142,47 @@ impl Sysvars { } } } + + pub(crate) fn setup_sysvar_cache( + &self, + accounts: &[(Pubkey, AccountSharedData)], + ) -> SysvarCache { + let mut sysvar_cache = SysvarCache::default(); + + // First fill any sysvar cache entries from the provided accounts. + sysvar_cache.fill_missing_entries(|pubkey, set_sysvar| { + if let Some((_, account)) = accounts.iter().find(|(key, _)| key == pubkey) { + set_sysvar(account.data()) + } + }); + + // Then fill the rest with the entries from `self`. + sysvar_cache.fill_missing_entries(|pubkey, set_sysvar| { + if pubkey.eq(&Clock::id()) { + set_sysvar(&bincode::serialize(&self.clock).unwrap()); + } + if pubkey.eq(&EpochRewards::id()) { + set_sysvar(&bincode::serialize(&self.epoch_rewards).unwrap()); + } + if pubkey.eq(&EpochSchedule::id()) { + set_sysvar(&bincode::serialize(&self.epoch_schedule).unwrap()); + } + if pubkey.eq(&LastRestartSlot::id()) { + set_sysvar(&bincode::serialize(&self.last_restart_slot).unwrap()); + } + if pubkey.eq(&Rent::id()) { + set_sysvar(&bincode::serialize(&self.rent).unwrap()); + } + if pubkey.eq(&SlotHashes::id()) { + set_sysvar(&bincode::serialize(&self.slot_hashes).unwrap()); + } + if pubkey.eq(&StakeHistory::id()) { + set_sysvar(&bincode::serialize(&self.stake_history).unwrap()); + } + }); + + sysvar_cache + } } impl From<&Sysvars> for SysvarCache {