diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 054e34b4a..52c860bb6 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -278,24 +278,22 @@ impl<'a> InvokeContext<'a> { builtin_programs: &'a [BuiltinProgram], ) -> Self { let mut sysvar_cache = SysvarCache::default(); - sysvar_cache.fill_missing_entries(|pubkey| { - (0..transaction_context.get_number_of_accounts()).find_map(|index| { + sysvar_cache.fill_missing_entries(|pubkey, callback| { + for index in 0..transaction_context.get_number_of_accounts() { if transaction_context .get_key_of_account_at_index(index) .unwrap() == pubkey { - Some( + callback( transaction_context .get_account_at_index(index) .unwrap() .borrow() - .clone(), - ) - } else { - None + .data(), + ); } - }) + } }); Self::new( transaction_context, diff --git a/program-runtime/src/sysvar_cache.rs b/program-runtime/src/sysvar_cache.rs index 79ea90dc7..8c142fee1 100644 --- a/program-runtime/src/sysvar_cache.rs +++ b/program-runtime/src/sysvar_cache.rs @@ -3,7 +3,6 @@ use solana_sdk::sysvar::{fees::Fees, recent_blockhashes::RecentBlockhashes}; use { crate::invoke_context::InvokeContext, solana_sdk::{ - account::{AccountSharedData, ReadableAccount}, instruction::InstructionError, pubkey::Pubkey, sysvar::{ @@ -111,60 +110,60 @@ impl SysvarCache { self.stake_history = Some(Arc::new(stake_history)); } - pub fn fill_missing_entries Option>( + pub fn fill_missing_entries( &mut self, - mut load_sysvar_account: F, + mut get_account_data: F, ) { - if self.get_clock().is_err() { - if let Some(clock) = load_sysvar_account(&Clock::id()) - .and_then(|account| bincode::deserialize(account.data()).ok()) - { - self.set_clock(clock); - } + if self.clock.is_none() { + get_account_data(&Clock::id(), &mut |data: &[u8]| { + if let Ok(clock) = bincode::deserialize(data) { + self.set_clock(clock); + } + }); } - if self.get_epoch_schedule().is_err() { - if let Some(epoch_schedule) = load_sysvar_account(&EpochSchedule::id()) - .and_then(|account| bincode::deserialize(account.data()).ok()) - { - self.set_epoch_schedule(epoch_schedule); - } + if self.epoch_schedule.is_none() { + get_account_data(&EpochSchedule::id(), &mut |data: &[u8]| { + if let Ok(epoch_schedule) = bincode::deserialize(data) { + self.set_epoch_schedule(epoch_schedule); + } + }); } #[allow(deprecated)] - if self.get_fees().is_err() { - if let Some(fees) = load_sysvar_account(&Fees::id()) - .and_then(|account| bincode::deserialize(account.data()).ok()) - { - self.set_fees(fees); - } + if self.fees.is_none() { + get_account_data(&Fees::id(), &mut |data: &[u8]| { + if let Ok(fees) = bincode::deserialize(data) { + self.set_fees(fees); + } + }); } - if self.get_rent().is_err() { - if let Some(rent) = load_sysvar_account(&Rent::id()) - .and_then(|account| bincode::deserialize(account.data()).ok()) - { - self.set_rent(rent); - } + if self.rent.is_none() { + get_account_data(&Rent::id(), &mut |data: &[u8]| { + if let Ok(rent) = bincode::deserialize(data) { + self.set_rent(rent); + } + }); } - if self.get_slot_hashes().is_err() { - if let Some(slot_hashes) = load_sysvar_account(&SlotHashes::id()) - .and_then(|account| bincode::deserialize(account.data()).ok()) - { - self.set_slot_hashes(slot_hashes); - } + if self.slot_hashes.is_none() { + get_account_data(&SlotHashes::id(), &mut |data: &[u8]| { + if let Ok(slot_hashes) = bincode::deserialize(data) { + self.set_slot_hashes(slot_hashes); + } + }); } #[allow(deprecated)] - if self.get_recent_blockhashes().is_err() { - if let Some(recent_blockhashes) = load_sysvar_account(&RecentBlockhashes::id()) - .and_then(|account| bincode::deserialize(account.data()).ok()) - { - self.set_recent_blockhashes(recent_blockhashes); - } + if self.recent_blockhashes.is_none() { + get_account_data(&RecentBlockhashes::id(), &mut |data: &[u8]| { + if let Ok(recent_blockhashes) = bincode::deserialize(data) { + self.set_recent_blockhashes(recent_blockhashes); + } + }); } - if self.get_stake_history().is_err() { - if let Some(stake_history) = load_sysvar_account(&StakeHistory::id()) - .and_then(|account| bincode::deserialize(account.data()).ok()) - { - self.set_stake_history(stake_history); - } + if self.stake_history.is_none() { + get_account_data(&StakeHistory::id(), &mut |data: &[u8]| { + if let Ok(stake_history) = bincode::deserialize(data) { + self.set_stake_history(stake_history); + } + }); } } diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 40a074607..3d1050621 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -3764,7 +3764,7 @@ mod tests { epoch: Epoch::MAX, ..Clock::default() }; - transaction_accounts[3] = ( + transaction_accounts[4] = ( sysvar::clock::id(), account::create_account_shared_data_for_test(&clock), ); diff --git a/runtime/src/bank/sysvar_cache.rs b/runtime/src/bank/sysvar_cache.rs index 34deed615..83aa78ff1 100644 --- a/runtime/src/bank/sysvar_cache.rs +++ b/runtime/src/bank/sysvar_cache.rs @@ -1,9 +1,16 @@ -use {super::Bank, solana_program_runtime::sysvar_cache::SysvarCache}; +use { + super::Bank, solana_program_runtime::sysvar_cache::SysvarCache, + solana_sdk::account::ReadableAccount, +}; impl Bank { pub(crate) fn fill_missing_sysvar_cache_entries(&self) { let mut sysvar_cache = self.sysvar_cache.write().unwrap(); - sysvar_cache.fill_missing_entries(|pubkey| self.get_account_with_fixed_root(pubkey)); + sysvar_cache.fill_missing_entries(|pubkey, callback| { + if let Some(account) = self.get_account_with_fixed_root(pubkey) { + callback(account.data()); + } + }); } pub(crate) fn reset_sysvar_cache(&self) {