diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 2cb045fe3..f767b66a8 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -3262,6 +3262,18 @@ impl Bank { compute_budget.max_units, ))); + let (blockhash, fee_calculator) = { + let blockhash_queue = self.blockhash_queue.read().unwrap(); + let blockhash = blockhash_queue.last_hash(); + ( + blockhash, + blockhash_queue + .get_fee_calculator(&blockhash) + .cloned() + .unwrap_or_else(|| self.fee_calculator.clone()), + ) + }; + process_result = self.message_processor.process_message( tx.message(), &loader_refcells, @@ -3276,6 +3288,8 @@ impl Bank { &mut timings.details, self.rc.accounts.clone(), &self.ancestors, + blockhash, + fee_calculator, ); transaction_log_messages.push(Self::collect_log_messages(log_collector)); diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index c3ee9034b..1c37bf47c 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -14,6 +14,8 @@ use solana_sdk::{ instructions_sysvar_enabled, neon_evm_compute_budget, tx_wide_compute_cap, updated_verify_policy, FeatureSet, }, + fee_calculator::FeeCalculator, + hash::Hash, ic_logger_msg, ic_msg, instruction::{CompiledInstruction, Instruction, InstructionError}, keyed_account::{create_keyed_accounts_unified, keyed_account_at_index, KeyedAccount}, @@ -303,6 +305,8 @@ pub struct ThisInvokeContext<'a> { ancestors: &'a Ancestors, #[allow(clippy::type_complexity)] sysvars: RefCell>>)>>, + blockhash: &'a Hash, + fee_calculator: &'a FeeCalculator, } impl<'a> ThisInvokeContext<'a> { #[allow(clippy::too_many_arguments)] @@ -322,6 +326,8 @@ impl<'a> ThisInvokeContext<'a> { feature_set: Arc, account_db: Arc, ancestors: &'a Ancestors, + blockhash: &'a Hash, + fee_calculator: &'a FeeCalculator, ) -> Self { let pre_accounts = MessageProcessor::create_pre_accounts(message, instruction, accounts); let keyed_accounts = MessageProcessor::create_keyed_accounts( @@ -354,6 +360,8 @@ impl<'a> ThisInvokeContext<'a> { account_db, ancestors, sysvars: RefCell::new(vec![]), + blockhash, + fee_calculator, }; invoke_context .invoke_stack @@ -539,6 +547,12 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { fn get_compute_budget(&self) -> &ComputeBudget { &self.compute_budget } + fn get_blockhash(&self) -> &Hash { + self.blockhash + } + fn get_fee_calculator(&self) -> &FeeCalculator { + self.fee_calculator + } } pub struct ThisLogger { log_collector: Option>, @@ -1168,6 +1182,8 @@ impl MessageProcessor { timings: &mut ExecuteDetailsTimings, account_db: Arc, ancestors: &Ancestors, + blockhash: &Hash, + fee_calculator: &FeeCalculator, ) -> Result<(), InstructionError> { // Fixup the special instructions key if present // before the account pre-values are taken care of @@ -1211,6 +1227,8 @@ impl MessageProcessor { feature_set, account_db, ancestors, + blockhash, + fee_calculator, ); self.process_instruction(program_id, &instruction.data, &mut invoke_context)?; Self::verify( @@ -1250,6 +1268,8 @@ impl MessageProcessor { timings: &mut ExecuteDetailsTimings, account_db: Arc, ancestors: &Ancestors, + blockhash: Hash, + fee_calculator: FeeCalculator, ) -> Result<(), TransactionError> { for (instruction_index, instruction) in message.instructions.iter().enumerate() { let mut time = Measure::start("execute_instruction"); @@ -1274,6 +1294,8 @@ impl MessageProcessor { timings, account_db.clone(), ancestors, + &blockhash, + &fee_calculator, ) .map_err(|err| TransactionError::InstructionError(instruction_index as u8, err)); time.stop(); @@ -1337,6 +1359,8 @@ mod tests { None, ); let ancestors = Ancestors::default(); + let blockhash = Hash::default(); + let fee_calculator = FeeCalculator::default(); let mut invoke_context = ThisInvokeContext::new( &invoke_stack[0], Rent::default(), @@ -1353,6 +1377,8 @@ mod tests { Arc::new(FeatureSet::all_enabled()), Arc::new(Accounts::default()), &ancestors, + &blockhash, + &fee_calculator, ); // Check call depth increases and has a limit @@ -1965,6 +1991,8 @@ mod tests { &mut ExecuteDetailsTimings::default(), Arc::new(Accounts::default()), &ancestors, + Hash::default(), + FeeCalculator::default(), ); assert_eq!(result, Ok(())); assert_eq!(accounts[0].1.borrow().lamports(), 100); @@ -1993,6 +2021,8 @@ mod tests { &mut ExecuteDetailsTimings::default(), Arc::new(Accounts::default()), &ancestors, + Hash::default(), + FeeCalculator::default(), ); assert_eq!( result, @@ -2025,6 +2055,8 @@ mod tests { &mut ExecuteDetailsTimings::default(), Arc::new(Accounts::default()), &ancestors, + Hash::default(), + FeeCalculator::default(), ); assert_eq!( result, @@ -2149,6 +2181,8 @@ mod tests { &mut ExecuteDetailsTimings::default(), Arc::new(Accounts::default()), &ancestors, + Hash::default(), + FeeCalculator::default(), ); assert_eq!( result, @@ -2181,6 +2215,8 @@ mod tests { &mut ExecuteDetailsTimings::default(), Arc::new(Accounts::default()), &ancestors, + Hash::default(), + FeeCalculator::default(), ); assert_eq!(result, Ok(())); @@ -2211,6 +2247,8 @@ mod tests { &mut ExecuteDetailsTimings::default(), Arc::new(Accounts::default()), &ancestors, + Hash::default(), + FeeCalculator::default(), ); assert_eq!(result, Ok(())); assert_eq!(accounts[0].1.borrow().lamports(), 80); @@ -2299,6 +2337,8 @@ mod tests { let message = Message::new(&[instruction], None); let ancestors = Ancestors::default(); + let blockhash = Hash::default(); + let fee_calculator = FeeCalculator::default(); let mut invoke_context = ThisInvokeContext::new( &caller_program_id, Rent::default(), @@ -2315,6 +2355,8 @@ mod tests { Arc::new(FeatureSet::all_enabled()), Arc::new(Accounts::default()), &ancestors, + &blockhash, + &fee_calculator, ); // not owned account modified by the caller (before the invoke) @@ -2356,6 +2398,8 @@ mod tests { let message = Message::new(&[instruction], None); let ancestors = Ancestors::default(); + let blockhash = Hash::default(); + let fee_calculator = FeeCalculator::default(); let mut invoke_context = ThisInvokeContext::new( &caller_program_id, Rent::default(), @@ -2372,6 +2416,8 @@ mod tests { Arc::new(FeatureSet::all_enabled()), Arc::new(Accounts::default()), &ancestors, + &blockhash, + &fee_calculator, ); let caller_write_privileges = message diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 15eadd73a..65e9b5a97 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -1,6 +1,4 @@ use log::*; -#[allow(deprecated)] -use solana_sdk::sysvar::recent_blockhashes::RecentBlockhashes; use solana_sdk::{ account::{AccountSharedData, ReadableAccount, WritableAccount}, account_utils::StateMut, @@ -12,7 +10,7 @@ use solana_sdk::{ process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey, - system_instruction::{SystemError, SystemInstruction, MAX_PERMITTED_DATA_LENGTH}, + system_instruction::{NonceError, SystemError, SystemInstruction, MAX_PERMITTED_DATA_LENGTH}, system_program, sysvar::{self, rent::Rent}, }; @@ -353,27 +351,30 @@ pub fn process_instruction( } SystemInstruction::AdvanceNonceAccount => { let me = &mut keyed_account_at_index(keyed_accounts, 0)?; - me.advance_nonce_account( - #[allow(deprecated)] - &from_keyed_account::(keyed_account_at_index( - keyed_accounts, - 1, - )?)?, - &signers, - invoke_context, - ) + #[allow(deprecated)] + if from_keyed_account::( + keyed_account_at_index(keyed_accounts, 1)?, + )? + .is_empty() + { + ic_msg!( + invoke_context, + "Advance nonce account: recent blockhash list is empty", + ); + return Err(NonceError::NoRecentBlockhashes.into()); + } + me.advance_nonce_account(&signers, invoke_context) } SystemInstruction::WithdrawNonceAccount(lamports) => { let me = &mut keyed_account_at_index(keyed_accounts, 0)?; let to = &mut keyed_account_at_index(keyed_accounts, 1)?; + #[allow(deprecated)] + let _ = from_keyed_account::( + keyed_account_at_index(keyed_accounts, 2)?, + )?; me.withdraw_nonce_account( lamports, to, - #[allow(deprecated)] - &from_keyed_account::(keyed_account_at_index( - keyed_accounts, - 2, - )?)?, &from_keyed_account::(keyed_account_at_index(keyed_accounts, 3)?)?, &signers, invoke_context, @@ -381,13 +382,20 @@ pub fn process_instruction( } SystemInstruction::InitializeNonceAccount(authorized) => { let me = &mut keyed_account_at_index(keyed_accounts, 0)?; + #[allow(deprecated)] + if from_keyed_account::( + keyed_account_at_index(keyed_accounts, 1)?, + )? + .is_empty() + { + ic_msg!( + invoke_context, + "Initialize nonce account: recent blockhash list is empty", + ); + return Err(NonceError::NoRecentBlockhashes.into()); + } me.initialize_nonce_account( &authorized, - #[allow(deprecated)] - &from_keyed_account::(keyed_account_at_index( - keyed_accounts, - 1, - )?)?, &from_keyed_account::(keyed_account_at_index(keyed_accounts, 2)?)?, invoke_context, ) @@ -1562,33 +1570,30 @@ mod tests { &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ) .unwrap(); + let blockhash = &hash(&serialize(&0).unwrap()); let new_recent_blockhashes_account = RefCell::new( #[allow(deprecated)] solana_sdk::recent_blockhashes_account::create_account_with_data_for_test( vec![ - IterItem( - 0u64, - &hash(&serialize(&0).unwrap()), - &FeeCalculator::default() - ); + IterItem(0u64, blockhash, &FeeCalculator::default()); sysvar::recent_blockhashes::MAX_ENTRIES ] .into_iter(), ), ); + let owner = Pubkey::default(); + #[allow(deprecated)] + let blockhash_id = sysvar::recent_blockhashes::id(); + let mut invoke_context = &mut MockInvokeContext::new(vec![ + KeyedAccount::new(&owner, true, &nonce_acc), + KeyedAccount::new(&blockhash_id, false, &new_recent_blockhashes_account), + ]); + invoke_context.blockhash = *blockhash; assert_eq!( - process_instruction( + super::process_instruction( &Pubkey::default(), - vec![ - KeyedAccount::new(&Pubkey::default(), true, &nonce_acc,), - #[allow(deprecated)] - KeyedAccount::new( - &sysvar::recent_blockhashes::id(), - false, - &new_recent_blockhashes_account, - ), - ], &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(), + invoke_context, ), Ok(()), ); @@ -1902,4 +1907,75 @@ mod tests { .unwrap(); assert_eq!(get_system_account_kind(&nonce_account), None); } + + #[test] + fn test_nonce_initialize_with_empty_recent_blockhashes_fail() { + let nonce_acc = nonce_account::create_account(1_000_000); + let new_recent_blockhashes_account = RefCell::new( + #[allow(deprecated)] + solana_sdk::recent_blockhashes_account::create_account_with_data_for_test( + vec![].into_iter(), + ), + ); + assert_eq!( + process_instruction( + &Pubkey::default(), + vec![ + KeyedAccount::new(&Pubkey::default(), true, &nonce_acc), + KeyedAccount::new( + #[allow(deprecated)] + &sysvar::recent_blockhashes::id(), + false, + &new_recent_blockhashes_account, + ), + KeyedAccount::new(&sysvar::rent::id(), false, &create_default_rent_account()), + ], + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), + ), + Err(NonceError::NoRecentBlockhashes.into()) + ); + } + + #[test] + fn test_nonce_advance_with_empty_recent_blockhashes_fail() { + let nonce_acc = nonce_account::create_account(1_000_000); + process_instruction( + &Pubkey::default(), + vec![ + KeyedAccount::new(&Pubkey::default(), true, &nonce_acc), + KeyedAccount::new( + #[allow(deprecated)] + &sysvar::recent_blockhashes::id(), + false, + &create_default_recent_blockhashes_account(), + ), + KeyedAccount::new(&sysvar::rent::id(), false, &create_default_rent_account()), + ], + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), + ) + .unwrap(); + let blockhash = &hash(&serialize(&0).unwrap()); + let new_recent_blockhashes_account = RefCell::new( + #[allow(deprecated)] + solana_sdk::recent_blockhashes_account::create_account_with_data_for_test( + vec![].into_iter(), + ), + ); + let owner = Pubkey::default(); + #[allow(deprecated)] + let blockhash_id = sysvar::recent_blockhashes::id(); + let mut invoke_context = &mut MockInvokeContext::new(vec![ + KeyedAccount::new(&owner, true, &nonce_acc), + KeyedAccount::new(&blockhash_id, false, &new_recent_blockhashes_account), + ]); + invoke_context.blockhash = *blockhash; + assert_eq!( + super::process_instruction( + &Pubkey::default(), + &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(), + invoke_context, + ), + Err(NonceError::NoRecentBlockhashes.into()), + ); + } } diff --git a/sdk/program/src/sysvar/recent_blockhashes.rs b/sdk/program/src/sysvar/recent_blockhashes.rs index 8f1ba7d83..d1b196807 100644 --- a/sdk/program/src/sysvar/recent_blockhashes.rs +++ b/sdk/program/src/sysvar/recent_blockhashes.rs @@ -14,10 +14,6 @@ use std::{cmp::Ordering, collections::BinaryHeap, iter::FromIterator, ops::Deref )] pub const MAX_ENTRIES: usize = 150; -#[deprecated( - since = "1.8.0", - note = "Please do not use, will no longer be available in the future" -)] declare_deprecated_sysvar_id!( "SysvarRecentB1ockHashes11111111111111111111", RecentBlockhashes diff --git a/sdk/src/nonce_keyed_account.rs b/sdk/src/nonce_keyed_account.rs index 37031b59f..f2ddc1d78 100644 --- a/sdk/src/nonce_keyed_account.rs +++ b/sdk/src/nonce_keyed_account.rs @@ -15,15 +15,11 @@ use solana_program::{ system_instruction::NonceError, sysvar::rent::Rent, }; -#[allow(deprecated)] -use solana_sdk::sysvar::recent_blockhashes::RecentBlockhashes; use std::collections::HashSet; -#[allow(deprecated)] pub trait NonceKeyedAccount { fn advance_nonce_account( &self, - recent_blockhashes: &RecentBlockhashes, signers: &HashSet, invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError>; @@ -31,7 +27,6 @@ pub trait NonceKeyedAccount { &self, lamports: u64, to: &KeyedAccount, - recent_blockhashes: &RecentBlockhashes, rent: &Rent, signers: &HashSet, invoke_context: &dyn InvokeContext, @@ -39,7 +34,6 @@ pub trait NonceKeyedAccount { fn initialize_nonce_account( &self, nonce_authority: &Pubkey, - recent_blockhashes: &RecentBlockhashes, rent: &Rent, invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError>; @@ -52,21 +46,11 @@ pub trait NonceKeyedAccount { } impl<'a> NonceKeyedAccount for KeyedAccount<'a> { - #[allow(deprecated)] fn advance_nonce_account( &self, - recent_blockhashes: &RecentBlockhashes, signers: &HashSet, invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { - if recent_blockhashes.is_empty() { - ic_msg!( - invoke_context, - "Advance nonce account: recent blockhash list is empty", - ); - return Err(NonceError::NoRecentBlockhashes.into()); - } - let state = AccountUtilsState::::state(self)?.convert_to_current(); match state { State::Initialized(data) => { @@ -78,7 +62,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { ); return Err(InstructionError::MissingRequiredSignature); } - let recent_blockhash = recent_blockhashes[0].blockhash; + let recent_blockhash = *invoke_context.get_blockhash(); if data.blockhash == recent_blockhash { ic_msg!( invoke_context, @@ -89,7 +73,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { let new_data = nonce::state::Data { blockhash: recent_blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + fee_calculator: invoke_context.get_fee_calculator().clone(), ..data }; self.set_state(&Versions::new_current(State::Initialized(new_data))) @@ -105,12 +89,10 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { } } - #[allow(deprecated)] fn withdraw_nonce_account( &self, lamports: u64, to: &KeyedAccount, - recent_blockhashes: &RecentBlockhashes, rent: &Rent, signers: &HashSet, invoke_context: &dyn InvokeContext, @@ -130,7 +112,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { } State::Initialized(ref data) => { if lamports == self.lamports()? { - if data.blockhash == recent_blockhashes[0].blockhash { + if data.blockhash == *invoke_context.get_blockhash() { ic_msg!( invoke_context, "Withdraw nonce account: nonce can only advance once per slot" @@ -180,22 +162,12 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { Ok(()) } - #[allow(deprecated)] fn initialize_nonce_account( &self, nonce_authority: &Pubkey, - recent_blockhashes: &RecentBlockhashes, rent: &Rent, invoke_context: &dyn InvokeContext, ) -> Result<(), InstructionError> { - if recent_blockhashes.is_empty() { - ic_msg!( - invoke_context, - "Initialize nonce account: recent blockhash list is empty", - ); - return Err(NonceError::NoRecentBlockhashes.into()); - } - match AccountUtilsState::::state(self)?.convert_to_current() { State::Uninitialized => { let min_balance = rent.minimum_balance(self.data_len()?); @@ -210,8 +182,8 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { } let data = nonce::state::Data { authority: *nonce_authority, - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), }; self.set_state(&Versions::new_current(State::Initialized(data))) } @@ -274,18 +246,32 @@ where #[cfg(test)] mod test { use super::*; - #[allow(deprecated)] - use crate::sysvar::recent_blockhashes::create_test_recent_blockhashes; use crate::{ account::ReadableAccount, account_utils::State as AccountUtilsState, + fee_calculator::FeeCalculator, keyed_account::KeyedAccount, nonce::{self, State}, nonce_account::verify_nonce_account, process_instruction::MockInvokeContext, system_instruction::NonceError, }; - use solana_program::hash::Hash; + use solana_program::hash::{hash, Hash}; + + fn create_test_blockhash(seed: usize) -> (Hash, FeeCalculator) { + ( + hash(&bincode::serialize(&seed).unwrap()), + FeeCalculator::new((seed as u64).saturating_mul(100)), + ) + } + + fn create_invoke_context_with_blockhash<'a>(seed: usize) -> MockInvokeContext<'a> { + let mut invoke_context = MockInvokeContext::new(vec![]); + let (blockhash, fee_calculator) = create_test_blockhash(seed); + invoke_context.blockhash = blockhash; + invoke_context.fee_calculator = fee_calculator; + invoke_context + } #[test] fn default_is_uninitialized() { @@ -311,71 +297,51 @@ mod test { .convert_to_current(); // New is in Uninitialzed state assert_eq!(state, State::Uninitialized); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(95); + let invoke_context = create_invoke_context_with_blockhash(95); let authorized = keyed_account.unsigned_key(); keyed_account - .initialize_nonce_account( - authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(authorized, &rent, &invoke_context) .unwrap(); let state = AccountUtilsState::::state(keyed_account) .unwrap() .convert_to_current(); - #[allow(deprecated)] let data = nonce::state::Data { - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), ..data }; // First nonce instruction drives state from Uninitialized to Initialized assert_eq!(state, State::Initialized(data.clone())); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); keyed_account - .advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ) + .advance_nonce_account(&signers, &invoke_context) .unwrap(); let state = AccountUtilsState::::state(keyed_account) .unwrap() .convert_to_current(); - #[allow(deprecated)] let data = nonce::state::Data { - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), ..data }; // Second nonce instruction consumes and replaces stored nonce assert_eq!(state, State::Initialized(data.clone())); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(31); + let invoke_context = create_invoke_context_with_blockhash(31); keyed_account - .advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ) + .advance_nonce_account(&signers, &invoke_context) .unwrap(); let state = AccountUtilsState::::state(keyed_account) .unwrap() .convert_to_current(); - #[allow(deprecated)] let data = nonce::state::Data { - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), ..data }; // Third nonce instruction for fun and profit assert_eq!(state, State::Initialized(data)); with_test_keyed_account(42, false, |to_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let withdraw_lamports = keyed_account.account.borrow().lamports(); let expect_nonce_lamports = keyed_account.account.borrow().lamports() - withdraw_lamports; @@ -384,10 +350,9 @@ mod test { .withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ) .unwrap(); // Empties Account balance @@ -414,69 +379,27 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(31); + let invoke_context = create_invoke_context_with_blockhash(31); let authority = *nonce_account.unsigned_key(); nonce_account - .initialize_nonce_account( - &authority, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authority, &rent, &invoke_context) .unwrap(); let pubkey = *nonce_account.account.borrow().owner(); let nonce_account = KeyedAccount::new(&pubkey, false, nonce_account.account); let state = AccountUtilsState::::state(&nonce_account) .unwrap() .convert_to_current(); - #[allow(deprecated)] let data = nonce::state::Data { authority, - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), }; assert_eq!(state, State::Initialized(data)); let signers = HashSet::new(); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); - let result = nonce_account.advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ); - assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); - }) - } + let invoke_context = create_invoke_context_with_blockhash(0); - #[test] - fn nonce_inx_with_empty_recent_blockhashes_fail() { - let rent = Rent { - lamports_per_byte_year: 42, - ..Rent::default() - }; - let min_lamports = rent.minimum_balance(State::size()); - with_test_keyed_account(min_lamports + 42, true, |keyed_account| { - let mut signers = HashSet::new(); - signers.insert(*keyed_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); - let authorized = *keyed_account.unsigned_key(); - keyed_account - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) - .unwrap(); - let recent_blockhashes = vec![].into_iter().collect(); - let result = keyed_account.advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ); - assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); + let result = nonce_account.advance_nonce_account(&signers, &invoke_context); + assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) } @@ -490,22 +413,12 @@ mod test { with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let mut signers = HashSet::new(); signers.insert(*keyed_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); let authorized = *keyed_account.unsigned_key(); keyed_account - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); - let result = keyed_account.advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ); + let result = keyed_account.advance_nonce_account(&signers, &invoke_context); assert_eq!(result, Err(NonceError::NotExpired.into())); }) } @@ -520,13 +433,8 @@ mod test { with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let mut signers = HashSet::new(); signers.insert(*keyed_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); - let result = keyed_account.advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ); + let invoke_context = create_invoke_context_with_blockhash(63); + let result = keyed_account.advance_nonce_account(&signers, &invoke_context); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) } @@ -542,26 +450,15 @@ mod test { with_test_keyed_account(42, true, |nonce_authority| { let mut signers = HashSet::new(); signers.insert(*nonce_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); let authorized = *nonce_authority.unsigned_key(); nonce_account - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); let mut signers = HashSet::new(); signers.insert(*nonce_authority.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(31); - let result = nonce_account.advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ); + let invoke_context = create_invoke_context_with_blockhash(31); + let result = nonce_account.advance_nonce_account(&signers, &invoke_context); assert_eq!(result, Ok(())); }); }); @@ -578,22 +475,12 @@ mod test { with_test_keyed_account(42, false, |nonce_authority| { let mut signers = HashSet::new(); signers.insert(*nonce_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); let authorized = *nonce_authority.unsigned_key(); nonce_account - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); - let result = nonce_account.advance_nonce_account( - &recent_blockhashes, - &signers, - &MockInvokeContext::new(vec![]), - ); + let result = nonce_account.advance_nonce_account(&signers, &invoke_context); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }); }); @@ -614,8 +501,7 @@ mod test { with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); signers.insert(*nonce_keyed.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let withdraw_lamports = nonce_keyed.account.borrow().lamports(); let expect_nonce_lamports = nonce_keyed.account.borrow().lamports() - withdraw_lamports; @@ -624,10 +510,9 @@ mod test { .withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -661,16 +546,14 @@ mod test { assert_eq!(state, State::Uninitialized); with_test_keyed_account(42, false, |to_keyed| { let signers = HashSet::new(); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let lamports = nonce_keyed.account.borrow().lamports(); let result = nonce_keyed.withdraw_nonce_account( lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) @@ -692,16 +575,14 @@ mod test { with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); signers.insert(*nonce_keyed.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let lamports = nonce_keyed.account.borrow().lamports() + 1; let result = nonce_keyed.withdraw_nonce_account( lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -719,8 +600,7 @@ mod test { with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); signers.insert(*nonce_keyed.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let withdraw_lamports = nonce_keyed.account.borrow().lamports() / 2; let nonce_expect_lamports = nonce_keyed.account.borrow().lamports() - withdraw_lamports; @@ -729,10 +609,9 @@ mod test { .withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -752,10 +631,9 @@ mod test { .withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -781,25 +659,18 @@ mod test { with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { let mut signers = HashSet::new(); signers.insert(*nonce_keyed.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(31); + let invoke_context = create_invoke_context_with_blockhash(31); let authority = *nonce_keyed.unsigned_key(); nonce_keyed - .initialize_nonce_account( - &authority, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authority, &rent, &invoke_context) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) .unwrap() .convert_to_current(); - #[allow(deprecated)] let data = nonce::state::Data { authority, - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), }; assert_eq!(state, State::Initialized(data.clone())); with_test_keyed_account(42, false, |to_keyed| { @@ -811,19 +682,17 @@ mod test { .withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) .unwrap() .convert_to_current(); - #[allow(deprecated)] let data = nonce::state::Data { - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), ..data.clone() }; assert_eq!(state, State::Initialized(data)); @@ -832,8 +701,7 @@ mod test { nonce_expect_lamports ); assert_eq!(to_keyed.account.borrow().lamports(), to_expect_lamports); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let withdraw_lamports = nonce_keyed.account.borrow().lamports(); let nonce_expect_lamports = nonce_keyed.account.borrow().lamports() - withdraw_lamports; @@ -842,10 +710,9 @@ mod test { .withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ) .unwrap(); let state = AccountUtilsState::::state(nonce_keyed) @@ -869,16 +736,10 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let authorized = *nonce_keyed.unsigned_key(); nonce_keyed - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); @@ -887,10 +748,9 @@ mod test { let result = nonce_keyed.withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(NonceError::NotExpired.into())); }) @@ -905,30 +765,22 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(95); + let invoke_context = create_invoke_context_with_blockhash(95); let authorized = *nonce_keyed.unsigned_key(); nonce_keyed - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); let mut signers = HashSet::new(); signers.insert(*nonce_keyed.signer_key().unwrap()); let withdraw_lamports = nonce_keyed.account.borrow().lamports() + 1; let result = nonce_keyed.withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -943,30 +795,22 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(95); + let invoke_context = create_invoke_context_with_blockhash(95); let authorized = *nonce_keyed.unsigned_key(); nonce_keyed - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); with_test_keyed_account(42, false, |to_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); let mut signers = HashSet::new(); signers.insert(*nonce_keyed.signer_key().unwrap()); let withdraw_lamports = nonce_keyed.account.borrow().lamports() - min_lamports + 1; let result = nonce_keyed.withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -981,30 +825,22 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(95); + let invoke_context = create_invoke_context_with_blockhash(95); let authorized = *nonce_keyed.unsigned_key(); nonce_keyed - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); with_test_keyed_account(55, false, |to_keyed| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); let mut signers = HashSet::new(); signers.insert(*nonce_keyed.signer_key().unwrap()); let withdraw_lamports = u64::MAX - 54; let result = nonce_keyed.withdraw_nonce_account( withdraw_lamports, to_keyed, - &recent_blockhashes, &rent, &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) @@ -1025,20 +861,13 @@ mod test { assert_eq!(state, State::Uninitialized); let mut signers = HashSet::new(); signers.insert(*keyed_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let authority = *keyed_account.unsigned_key(); - let result = keyed_account.initialize_nonce_account( - &authority, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ); - #[allow(deprecated)] + let result = keyed_account.initialize_nonce_account(&authority, &rent, &invoke_context); let data = nonce::state::Data { authority, - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), }; assert_eq!(result, Ok(())); let state = AccountUtilsState::::state(keyed_account) @@ -1048,28 +877,6 @@ mod test { }) } - #[test] - fn initialize_inx_empty_recent_blockhashes_fail() { - let rent = Rent { - lamports_per_byte_year: 42, - ..Rent::default() - }; - let min_lamports = rent.minimum_balance(State::size()); - with_test_keyed_account(min_lamports + 42, true, |keyed_account| { - let mut signers = HashSet::new(); - signers.insert(*keyed_account.signer_key().unwrap()); - let recent_blockhashes = vec![].into_iter().collect(); - let authorized = *keyed_account.unsigned_key(); - let result = keyed_account.initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ); - assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into())); - }) - } - #[test] fn initialize_inx_initialized_account_fail() { let rent = Rent { @@ -1078,25 +885,14 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(31); + let invoke_context = create_invoke_context_with_blockhash(31); let authorized = *keyed_account.unsigned_key(); keyed_account - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); - let result = keyed_account.initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ); + let invoke_context = create_invoke_context_with_blockhash(0); + let result = + keyed_account.initialize_nonce_account(&authorized, &rent, &invoke_context); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) } @@ -1109,15 +905,10 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports - 42, true, |keyed_account| { - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(63); + let invoke_context = create_invoke_context_with_blockhash(63); let authorized = *keyed_account.unsigned_key(); - let result = keyed_account.initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ); + let result = + keyed_account.initialize_nonce_account(&authorized, &rent, &invoke_context); assert_eq!(result, Err(InstructionError::InsufficientFunds)); }) } @@ -1132,28 +923,21 @@ mod test { with_test_keyed_account(min_lamports + 42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(*nonce_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(31); + let invoke_context = create_invoke_context_with_blockhash(31); let authorized = *nonce_account.unsigned_key(); nonce_account - .initialize_nonce_account( - &authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); let authority = Pubkey::default(); - #[allow(deprecated)] let data = nonce::state::Data { authority, - blockhash: recent_blockhashes[0].blockhash, - fee_calculator: recent_blockhashes[0].fee_calculator.clone(), + blockhash: *invoke_context.get_blockhash(), + fee_calculator: invoke_context.get_fee_calculator().clone(), }; let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Ok(())); let state = AccountUtilsState::::state(nonce_account) @@ -1172,11 +956,12 @@ mod test { let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { let mut signers = HashSet::new(); + let invoke_context = MockInvokeContext::new(vec![]); signers.insert(*nonce_account.signer_key().unwrap()); let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(NonceError::BadAccountState.into())); }) @@ -1192,21 +977,15 @@ mod test { with_test_keyed_account(min_lamports + 42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(*nonce_account.signer_key().unwrap()); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(31); + let invoke_context = create_invoke_context_with_blockhash(31); let authorized = &Pubkey::default().clone(); nonce_account - .initialize_nonce_account( - authorized, - &recent_blockhashes, - &rent, - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(authorized, &rent, &invoke_context) .unwrap(); let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, - &MockInvokeContext::new(vec![]), + &invoke_context, ); assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); }) @@ -1220,21 +999,14 @@ mod test { let state: State = nonce_account.state().unwrap(); // New is in Uninitialzed state assert_eq!(state, State::Uninitialized); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let authorized = nonce_account.unsigned_key(); nonce_account - .initialize_nonce_account( - authorized, - &recent_blockhashes, - &Rent::free(), - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(authorized, &Rent::free(), &invoke_context) .unwrap(); assert!(verify_nonce_account( &nonce_account.account.borrow(), - #[allow(deprecated)] - &recent_blockhashes[0].blockhash, + invoke_context.get_blockhash(), )); }); } @@ -1257,21 +1029,15 @@ mod test { let state: State = nonce_account.state().unwrap(); // New is in Uninitialzed state assert_eq!(state, State::Uninitialized); - #[allow(deprecated)] - let recent_blockhashes = create_test_recent_blockhashes(0); + let invoke_context = create_invoke_context_with_blockhash(0); let authorized = nonce_account.unsigned_key(); nonce_account - .initialize_nonce_account( - authorized, - &recent_blockhashes, - &Rent::free(), - &MockInvokeContext::new(vec![]), - ) + .initialize_nonce_account(authorized, &Rent::free(), &invoke_context) .unwrap(); + let invoke_context = create_invoke_context_with_blockhash(1); assert!(!verify_nonce_account( &nonce_account.account.borrow(), - #[allow(deprecated)] - &recent_blockhashes[1].blockhash, + invoke_context.get_blockhash(), )); }); } diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 99d67bb6c..ec9289287 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -3,6 +3,8 @@ use solana_sdk::{ account::AccountSharedData, compute_budget::ComputeBudget, + fee_calculator::FeeCalculator, + hash::Hash, instruction::{CompiledInstruction, Instruction, InstructionError}, keyed_account::{create_keyed_accounts_unified, KeyedAccount}, pubkey::Pubkey, @@ -107,6 +109,10 @@ pub trait InvokeContext { fn get_sysvar_data(&self, id: &Pubkey) -> Option>>; /// Get this invocation's compute budget fn get_compute_budget(&self) -> &ComputeBudget; + /// Get this invocation's blockhash + fn get_blockhash(&self) -> &Hash; + /// Get this invocation's `FeeCalculator` + fn get_fee_calculator(&self) -> &FeeCalculator; } /// Convenience macro to log a message with an `Rc>` @@ -379,13 +385,14 @@ pub struct MockInvokeContext<'a> { pub invoke_stack: Vec>, pub logger: MockLogger, pub compute_budget: ComputeBudget, - #[allow(deprecated)] pub bpf_compute_budget: BpfComputeBudget, pub compute_meter: MockComputeMeter, pub programs: Vec<(Pubkey, ProcessInstructionWithContext)>, pub accounts: Vec<(Pubkey, Rc>)>, pub sysvars: Vec<(Pubkey, Option>>)>, pub disabled_features: HashSet, + pub blockhash: Hash, + pub fee_calculator: FeeCalculator, } impl<'a> MockInvokeContext<'a> { pub fn new(keyed_accounts: Vec>) -> Self { @@ -394,7 +401,6 @@ impl<'a> MockInvokeContext<'a> { invoke_stack: Vec::with_capacity(compute_budget.max_invoke_depth), logger: MockLogger::default(), compute_budget, - #[allow(deprecated)] bpf_compute_budget: compute_budget.into(), compute_meter: MockComputeMeter { remaining: std::i64::MAX as u64, @@ -403,6 +409,8 @@ impl<'a> MockInvokeContext<'a> { accounts: vec![], sysvars: vec![], disabled_features: HashSet::default(), + blockhash: Hash::default(), + fee_calculator: FeeCalculator::default(), }; invoke_context .invoke_stack @@ -525,4 +533,10 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn get_compute_budget(&self) -> &ComputeBudget { &self.compute_budget } + fn get_blockhash(&self) -> &Hash { + &self.blockhash + } + fn get_fee_calculator(&self) -> &FeeCalculator { + &self.fee_calculator + } }