Ver Fonte

Refactor - Split `InstructionContext` (#7574)

* Splits owned fields of InstructionContext into its own structure and adds a backref for the TransactionContext.

* Uses get_key_of_instruction_account() where possible.

* Cleans up unused parameters.

* Renames get_instruction_context_stack_height() => get_instruction_stack_height().

* Renames Instruction => InstructionFrame.
Alexander Meißner há 3 meses atrás
pai
commit
2e45d33cf2

+ 1 - 2
ledger-tool/src/program.rs

@@ -528,8 +528,7 @@ pub fn program(ledger_path: &Path, matches: &ArgMatches<'_>) {
         .unwrap();
     invoke_context.push().unwrap();
     let (_parameter_bytes, regions, account_lengths) = serialize_parameters(
-        invoke_context.transaction_context,
-        invoke_context
+        &invoke_context
             .transaction_context
             .get_current_instruction_context()
             .unwrap(),

+ 3 - 2
ledger/src/blockstore_processor.rs

@@ -3567,10 +3567,11 @@ pub mod tests {
         declare_process_instruction!(MockBuiltinErr, 1, |invoke_context| {
             let instruction_errors = get_instruction_errors();
 
-            let err = invoke_context
+            let instruction_context = invoke_context
                 .transaction_context
                 .get_current_instruction_context()
-                .expect("Failed to get instruction context")
+                .expect("Failed to get instruction context");
+            let err = instruction_context
                 .get_instruction_data()
                 .first()
                 .expect("Failed to get instruction data");

+ 21 - 32
program-runtime/src/invoke_context.rs

@@ -252,31 +252,21 @@ impl<'a> InvokeContext<'a> {
                 self.transaction_context.get_instruction_trace_length(),
             )?;
         let program_id = instruction_context
-            .get_program_key(self.transaction_context)
+            .get_program_key()
             .map_err(|_| InstructionError::UnsupportedProgramId)?;
-        if self
-            .transaction_context
-            .get_instruction_context_stack_height()
-            != 0
-        {
-            let contains = (0..self
-                .transaction_context
-                .get_instruction_context_stack_height())
-                .any(|level| {
+        if self.transaction_context.get_instruction_stack_height() != 0 {
+            let contains =
+                (0..self.transaction_context.get_instruction_stack_height()).any(|level| {
                     self.transaction_context
                         .get_instruction_context_at_nesting_level(level)
-                        .and_then(|instruction_context| {
-                            instruction_context.get_program_key(self.transaction_context)
-                        })
+                        .and_then(|instruction_context| instruction_context.get_program_key())
                         .map(|program_key| program_key == program_id)
                         .unwrap_or(false)
                 });
             let is_last = self
                 .transaction_context
                 .get_current_instruction_context()
-                .and_then(|instruction_context| {
-                    instruction_context.get_program_key(self.transaction_context)
-                })
+                .and_then(|instruction_context| instruction_context.get_program_key())
                 .map(|program_key| program_key == program_id)
                 .unwrap_or(false);
             if contains && !is_last {
@@ -300,8 +290,7 @@ impl<'a> InvokeContext<'a> {
     /// Current height of the invocation stack, top level instructions are height
     /// `solana_instruction::TRANSACTION_LEVEL_STACK_HEIGHT`
     pub fn get_stack_height(&self) -> usize {
-        self.transaction_context
-            .get_instruction_context_stack_height()
+        self.transaction_context.get_instruction_stack_height()
     }
 
     /// Entrypoint for a cross-program invocation from a builtin program
@@ -538,9 +527,9 @@ impl<'a> InvokeContext<'a> {
         let process_executable_chain_time = Measure::start("process_executable_chain_time");
 
         let builtin_id = {
-            let owner_id = instruction_context.get_program_owner(self.transaction_context)?;
+            let owner_id = instruction_context.get_program_owner()?;
             if native_loader::check_id(&owner_id) {
-                *instruction_context.get_program_key(self.transaction_context)?
+                *instruction_context.get_program_key()?
             } else if bpf_loader_deprecated::check_id(&owner_id)
                 || bpf_loader::check_id(&owner_id)
                 || bpf_loader_upgradeable::check_id(&owner_id)
@@ -567,7 +556,7 @@ impl<'a> InvokeContext<'a> {
         }
         .ok_or(InstructionError::UnsupportedProgramId)?;
 
-        let program_id = *instruction_context.get_program_key(self.transaction_context)?;
+        let program_id = *instruction_context.get_program_key()?;
         self.transaction_context
             .set_return_data(program_id, Vec::new())?;
         let logger = self.get_log_collector();
@@ -706,7 +695,7 @@ impl<'a> InvokeContext<'a> {
         self.transaction_context
             .get_current_instruction_context()
             .and_then(|instruction_context| {
-                let owner_id = instruction_context.get_program_owner(self.transaction_context);
+                let owner_id = instruction_context.get_program_owner();
                 debug_assert!(owner_id.is_ok());
                 owner_id
             })
@@ -982,7 +971,7 @@ mod tests {
             let transaction_context = &invoke_context.transaction_context;
             let instruction_context = transaction_context.get_current_instruction_context()?;
             let instruction_data = instruction_context.get_instruction_data();
-            let program_id = instruction_context.get_program_key(transaction_context)?;
+            let program_id = instruction_context.get_program_key()?;
             let instruction_accounts = (0..4)
                 .map(|instruction_account_index| {
                     InstructionAccount::new(instruction_account_index, false, false)
@@ -991,14 +980,14 @@ mod tests {
             assert_eq!(
                 program_id,
                 instruction_context
-                    .try_borrow_instruction_account(transaction_context, 0)?
+                    .try_borrow_instruction_account(0)?
                     .get_owner()
             );
             assert_ne!(
                 instruction_context
-                    .try_borrow_instruction_account(transaction_context, 1)?
+                    .try_borrow_instruction_account(1)?
                     .get_owner(),
-                instruction_context.get_key_of_instruction_account(0, transaction_context)?
+                instruction_context.get_key_of_instruction_account(0)?
             );
 
             if let Ok(instruction) = bincode::deserialize(instruction_data) {
@@ -1006,17 +995,17 @@ mod tests {
                     MockInstruction::NoopSuccess => (),
                     MockInstruction::NoopFail => return Err(InstructionError::GenericError),
                     MockInstruction::ModifyOwned => instruction_context
-                        .try_borrow_instruction_account(transaction_context, 0)?
+                        .try_borrow_instruction_account(0)?
                         .set_data_from_slice(&[1])?,
                     MockInstruction::ModifyNotOwned => instruction_context
-                        .try_borrow_instruction_account(transaction_context, 1)?
+                        .try_borrow_instruction_account(1)?
                         .set_data_from_slice(&[1])?,
                     MockInstruction::ModifyReadonly => instruction_context
-                        .try_borrow_instruction_account(transaction_context, 2)?
+                        .try_borrow_instruction_account(2)?
                         .set_data_from_slice(&[1])?,
                     MockInstruction::UnbalancedPush => {
                         instruction_context
-                            .try_borrow_instruction_account(transaction_context, 0)?
+                            .try_borrow_instruction_account(0)?
                             .checked_add_lamports(1)?;
                         let program_id = *transaction_context.get_key_of_account_at_index(3)?;
                         let metas = vec![
@@ -1046,7 +1035,7 @@ mod tests {
                             .and(invoke_context.pop())?;
                     }
                     MockInstruction::UnbalancedPop => instruction_context
-                        .try_borrow_instruction_account(transaction_context, 0)?
+                        .try_borrow_instruction_account(0)?
                         .checked_add_lamports(1)?,
                     MockInstruction::ConsumeComputeUnits {
                         compute_units_to_consume,
@@ -1058,7 +1047,7 @@ mod tests {
                         return desired_result;
                     }
                     MockInstruction::Resize { new_len } => instruction_context
-                        .try_borrow_instruction_account(transaction_context, 0)?
+                        .try_borrow_instruction_account(0)?
                         .set_data_from_slice(&vec![0; new_len as usize])?,
                 }
             } else {

+ 19 - 36
program-runtime/src/serialization.rs

@@ -13,8 +13,7 @@ use {
     solana_sdk_ids::bpf_loader_deprecated,
     solana_system_interface::MAX_PERMITTED_DATA_LENGTH,
     solana_transaction_context::{
-        BorrowedAccount, IndexOfAccount, InstructionContext, TransactionContext,
-        MAX_ACCOUNTS_PER_INSTRUCTION,
+        BorrowedAccount, IndexOfAccount, InstructionContext, MAX_ACCOUNTS_PER_INSTRUCTION,
     },
     std::mem::{self, size_of},
 };
@@ -220,7 +219,6 @@ impl Serializer {
 }
 
 pub fn serialize_parameters(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stricter_abi_and_runtime_constraints: bool,
     account_data_direct_mapping: bool,
@@ -238,9 +236,9 @@ pub fn serialize_parameters(
         return Err(InstructionError::MaxAccountsExceeded);
     }
 
-    let program_id = *instruction_context.get_program_key(transaction_context)?;
+    let program_id = *instruction_context.get_program_key()?;
     let is_loader_deprecated =
-        instruction_context.get_program_owner(transaction_context)? == bpf_loader_deprecated::id();
+        instruction_context.get_program_owner()? == bpf_loader_deprecated::id();
 
     let accounts = (0..instruction_context.get_number_of_instruction_accounts())
         .map(|instruction_account_index| {
@@ -251,7 +249,7 @@ pub fn serialize_parameters(
                 SerializeAccount::Duplicate(index)
             } else {
                 let account = instruction_context
-                    .try_borrow_instruction_account(transaction_context, instruction_account_index)
+                    .try_borrow_instruction_account(instruction_account_index)
                     .unwrap();
                 SerializeAccount::Account(instruction_account_index, account)
             }
@@ -284,7 +282,6 @@ pub fn serialize_parameters(
 }
 
 pub fn deserialize_parameters(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stricter_abi_and_runtime_constraints: bool,
     account_data_direct_mapping: bool,
@@ -292,11 +289,10 @@ pub fn deserialize_parameters(
     accounts_metadata: &[SerializedAccountMetadata],
 ) -> Result<(), InstructionError> {
     let is_loader_deprecated =
-        instruction_context.get_program_owner(transaction_context)? == bpf_loader_deprecated::id();
+        instruction_context.get_program_owner()? == bpf_loader_deprecated::id();
     let account_lengths = accounts_metadata.iter().map(|a| a.original_data_len);
     if is_loader_deprecated {
         deserialize_parameters_unaligned(
-            transaction_context,
             instruction_context,
             stricter_abi_and_runtime_constraints,
             account_data_direct_mapping,
@@ -305,7 +301,6 @@ pub fn deserialize_parameters(
         )
     } else {
         deserialize_parameters_aligned(
-            transaction_context,
             instruction_context,
             stricter_abi_and_runtime_constraints,
             account_data_direct_mapping,
@@ -407,7 +402,6 @@ fn serialize_parameters_unaligned(
 }
 
 fn deserialize_parameters_unaligned<I: IntoIterator<Item = usize>>(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stricter_abi_and_runtime_constraints: bool,
     account_data_direct_mapping: bool,
@@ -423,8 +417,8 @@ fn deserialize_parameters_unaligned<I: IntoIterator<Item = usize>>(
             instruction_context.is_instruction_account_duplicate(instruction_account_index)?;
         start += 1; // is_dup
         if duplicate.is_none() {
-            let mut borrowed_account = instruction_context
-                .try_borrow_instruction_account(transaction_context, instruction_account_index)?;
+            let mut borrowed_account =
+                instruction_context.try_borrow_instruction_account(instruction_account_index)?;
             start += size_of::<u8>(); // is_signer
             start += size_of::<u8>(); // is_writable
             start += size_of::<Pubkey>(); // key
@@ -570,7 +564,6 @@ fn serialize_parameters_aligned(
 }
 
 fn deserialize_parameters_aligned<I: IntoIterator<Item = usize>>(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stricter_abi_and_runtime_constraints: bool,
     account_data_direct_mapping: bool,
@@ -588,8 +581,8 @@ fn deserialize_parameters_aligned<I: IntoIterator<Item = usize>>(
         if duplicate.is_some() {
             start += 7; // padding to 64-bit aligned
         } else {
-            let mut borrowed_account = instruction_context
-                .try_borrow_instruction_account(transaction_context, instruction_account_index)?;
+            let mut borrowed_account =
+                instruction_context.try_borrow_instruction_account(instruction_account_index)?;
             start += size_of::<u8>() // is_signer
                 + size_of::<u8>() // is_writable
                 + size_of::<u8>() // executable
@@ -672,7 +665,7 @@ mod tests {
         solana_sbpf::{memory_region::MemoryMapping, program::SBPFVersion, vm::Config},
         solana_sdk_ids::bpf_loader,
         solana_system_interface::MAX_PERMITTED_ACCOUNTS_DATA_ALLOCATIONS_PER_TRANSACTION,
-        solana_transaction_context::InstructionAccount,
+        solana_transaction_context::{InstructionAccount, TransactionContext},
         std::{
             cell::RefCell,
             mem::transmute,
@@ -786,8 +779,7 @@ mod tests {
                     .unwrap();
 
                 let serialization_result = serialize_parameters(
-                    invoke_context.transaction_context,
-                    instruction_context,
+                    &instruction_context,
                     stricter_abi_and_runtime_constraints,
                     false, // account_data_direct_mapping
                     true,  // mask_out_rent_epoch_in_vm_serialization
@@ -943,8 +935,7 @@ mod tests {
 
             // check serialize_parameters_aligned
             let (mut serialized, regions, accounts_metadata) = serialize_parameters(
-                invoke_context.transaction_context,
-                instruction_context,
+                &instruction_context,
                 stricter_abi_and_runtime_constraints,
                 false, // account_data_direct_mapping
                 true,  // mask_out_rent_epoch_in_vm_serialization
@@ -1004,8 +995,7 @@ mod tests {
             }
 
             deserialize_parameters(
-                invoke_context.transaction_context,
-                instruction_context,
+                &instruction_context,
                 stricter_abi_and_runtime_constraints,
                 false, // account_data_direct_mapping
                 serialized.as_slice(),
@@ -1035,8 +1025,7 @@ mod tests {
                 .unwrap();
 
             let (mut serialized, regions, account_lengths) = serialize_parameters(
-                invoke_context.transaction_context,
-                instruction_context,
+                &instruction_context,
                 stricter_abi_and_runtime_constraints,
                 false, // account_data_direct_mapping
                 true,  // mask_out_rent_epoch_in_vm_serialization
@@ -1075,8 +1064,7 @@ mod tests {
             }
 
             deserialize_parameters(
-                invoke_context.transaction_context,
-                instruction_context,
+                &instruction_context,
                 stricter_abi_and_runtime_constraints,
                 false, // account_data_direct_mapping
                 serialized.as_slice(),
@@ -1201,8 +1189,7 @@ mod tests {
 
             // check serialize_parameters_aligned
             let (_serialized, regions, _accounts_metadata) = serialize_parameters(
-                invoke_context.transaction_context,
-                instruction_context,
+                &instruction_context,
                 true,
                 false, // account_data_direct_mapping
                 mask_out_rent_epoch_in_vm_serialization,
@@ -1244,8 +1231,7 @@ mod tests {
                 .unwrap();
 
             let (_serialized, regions, _account_lengths) = serialize_parameters(
-                invoke_context.transaction_context,
-                instruction_context,
+                &instruction_context,
                 true,
                 false, // account_data_direct_mapping
                 mask_out_rent_epoch_in_vm_serialization,
@@ -1475,10 +1461,7 @@ mod tests {
             .map(|(index_in_instruction, account_start_offset)| {
                 create_memory_region_of_account(
                     &mut instruction_context
-                        .try_borrow_instruction_account(
-                            &transaction_context,
-                            index_in_instruction as IndexOfAccount,
-                        )
+                        .try_borrow_instruction_account(index_in_instruction as IndexOfAccount)
                         .unwrap(),
                     *account_start_offset,
                 )
@@ -1598,7 +1581,7 @@ mod tests {
         let remaining_allowed_growth: usize = 0x700;
         for index_in_instruction in 4..6 {
             let mut borrowed_account = instruction_context
-                .try_borrow_instruction_account(&transaction_context, index_in_instruction)
+                .try_borrow_instruction_account(index_in_instruction)
                 .unwrap();
             borrowed_account
                 .set_data_from_slice(&vec![0u8; MAX_PERMITTED_DATA_LENGTH as usize])

+ 10 - 35
program-runtime/src/sysvar_cache.rs

@@ -15,7 +15,7 @@ use {
     solana_svm_type_overrides::sync::Arc,
     solana_sysvar::{stake_history::StakeHistory, Sysvar},
     solana_sysvar_id::SysvarId,
-    solana_transaction_context::{IndexOfAccount, InstructionContext, TransactionContext},
+    solana_transaction_context::{IndexOfAccount, InstructionContext},
 };
 
 #[cfg(feature = "frozen-abi")]
@@ -284,13 +284,12 @@ pub mod get_sysvar_with_account_check {
     use super::*;
 
     fn check_sysvar_account<S: Sysvar>(
-        transaction_context: &TransactionContext,
         instruction_context: &InstructionContext,
         instruction_account_index: IndexOfAccount,
     ) -> Result<(), InstructionError> {
-        let index_in_transaction = instruction_context
-            .get_index_of_instruction_account_in_transaction(instruction_account_index)?;
-        if !S::check_id(transaction_context.get_key_of_account_at_index(index_in_transaction)?) {
+        if !S::check_id(
+            instruction_context.get_key_of_instruction_account(instruction_account_index)?,
+        ) {
             return Err(InstructionError::InvalidArgument);
         }
         Ok(())
@@ -301,11 +300,7 @@ pub mod get_sysvar_with_account_check {
         instruction_context: &InstructionContext,
         instruction_account_index: IndexOfAccount,
     ) -> Result<Arc<Clock>, InstructionError> {
-        check_sysvar_account::<Clock>(
-            invoke_context.transaction_context,
-            instruction_context,
-            instruction_account_index,
-        )?;
+        check_sysvar_account::<Clock>(instruction_context, instruction_account_index)?;
         invoke_context.get_sysvar_cache().get_clock()
     }
 
@@ -314,11 +309,7 @@ pub mod get_sysvar_with_account_check {
         instruction_context: &InstructionContext,
         instruction_account_index: IndexOfAccount,
     ) -> Result<Arc<Rent>, InstructionError> {
-        check_sysvar_account::<Rent>(
-            invoke_context.transaction_context,
-            instruction_context,
-            instruction_account_index,
-        )?;
+        check_sysvar_account::<Rent>(instruction_context, instruction_account_index)?;
         invoke_context.get_sysvar_cache().get_rent()
     }
 
@@ -327,11 +318,7 @@ pub mod get_sysvar_with_account_check {
         instruction_context: &InstructionContext,
         instruction_account_index: IndexOfAccount,
     ) -> Result<Arc<SlotHashes>, InstructionError> {
-        check_sysvar_account::<SlotHashes>(
-            invoke_context.transaction_context,
-            instruction_context,
-            instruction_account_index,
-        )?;
+        check_sysvar_account::<SlotHashes>(instruction_context, instruction_account_index)?;
         invoke_context.get_sysvar_cache().get_slot_hashes()
     }
 
@@ -341,11 +328,7 @@ pub mod get_sysvar_with_account_check {
         instruction_context: &InstructionContext,
         instruction_account_index: IndexOfAccount,
     ) -> Result<Arc<RecentBlockhashes>, InstructionError> {
-        check_sysvar_account::<RecentBlockhashes>(
-            invoke_context.transaction_context,
-            instruction_context,
-            instruction_account_index,
-        )?;
+        check_sysvar_account::<RecentBlockhashes>(instruction_context, instruction_account_index)?;
         invoke_context.get_sysvar_cache().get_recent_blockhashes()
     }
 
@@ -354,11 +337,7 @@ pub mod get_sysvar_with_account_check {
         instruction_context: &InstructionContext,
         instruction_account_index: IndexOfAccount,
     ) -> Result<Arc<StakeHistory>, InstructionError> {
-        check_sysvar_account::<StakeHistory>(
-            invoke_context.transaction_context,
-            instruction_context,
-            instruction_account_index,
-        )?;
+        check_sysvar_account::<StakeHistory>(instruction_context, instruction_account_index)?;
         invoke_context.get_sysvar_cache().get_stake_history()
     }
 
@@ -367,11 +346,7 @@ pub mod get_sysvar_with_account_check {
         instruction_context: &InstructionContext,
         instruction_account_index: IndexOfAccount,
     ) -> Result<Arc<LastRestartSlot>, InstructionError> {
-        check_sysvar_account::<LastRestartSlot>(
-            invoke_context.transaction_context,
-            instruction_context,
-            instruction_account_index,
-        )?;
+        check_sysvar_account::<LastRestartSlot>(instruction_context, instruction_account_index)?;
         invoke_context.get_sysvar_cache().get_last_restart_slot()
     }
 }

+ 9 - 18
program-test/src/lib.rs

@@ -116,7 +116,7 @@ pub fn invoke_builtin_function(
     invoke_context.consume_checked(1)?;
 
     let log_collector = invoke_context.get_log_collector();
-    let program_id = instruction_context.get_program_key(transaction_context)?;
+    let program_id = instruction_context.get_program_key()?;
     stable_log::program_invoke(
         &log_collector,
         program_id,
@@ -131,8 +131,7 @@ pub fn invoke_builtin_function(
         .get_feature_set()
         .mask_out_rent_epoch_in_vm_serialization;
     let (mut parameter_bytes, _regions, _account_lengths) = serialize_parameters(
-        transaction_context,
-        instruction_context,
+        &instruction_context,
         false, // There is no VM so stricter_abi_and_runtime_constraints can not be implemented here
         false, // There is no VM so account_data_direct_mapping can not be implemented here
         mask_out_rent_epoch_in_vm_serialization,
@@ -174,8 +173,7 @@ pub fn invoke_builtin_function(
 
     // Commit AccountInfo changes back into KeyedAccounts
     for i in deduplicated_indices.into_iter() {
-        let mut borrowed_account =
-            instruction_context.try_borrow_instruction_account(transaction_context, i)?;
+        let mut borrowed_account = instruction_context.try_borrow_instruction_account(i)?;
         if borrowed_account.is_writable() {
             if let Some(account_info) = account_info_map.get(borrowed_account.get_key()) {
                 if borrowed_account.get_lamports() != account_info.lamports() {
@@ -256,9 +254,7 @@ impl solana_sysvar::program_stubs::SyscallStubs for SyscallStubs {
         let instruction_context = transaction_context
             .get_current_instruction_context()
             .unwrap();
-        let caller = instruction_context
-            .get_program_key(transaction_context)
-            .unwrap();
+        let caller = instruction_context.get_program_key().unwrap();
 
         stable_log::program_invoke(
             &log_collector,
@@ -280,11 +276,8 @@ impl solana_sysvar::program_stubs::SyscallStubs for SyscallStubs {
         let instruction_context = transaction_context
             .get_current_instruction_context()
             .unwrap();
-
-        let next_instruction_accounts = transaction_context
-            .get_next_instruction_context()
-            .unwrap()
-            .instruction_accounts();
+        let next_instruction_context = transaction_context.get_next_instruction_context().unwrap();
+        let next_instruction_accounts = next_instruction_context.instruction_accounts();
         let mut account_indices = Vec::with_capacity(next_instruction_accounts.len());
         for instruction_account in next_instruction_accounts.iter() {
             let account_key = transaction_context
@@ -300,7 +293,7 @@ impl solana_sysvar::program_stubs::SyscallStubs for SyscallStubs {
                 .get_index_of_account_in_instruction(instruction_account.index_in_transaction)
                 .unwrap();
             let mut borrowed_account = instruction_context
-                .try_borrow_instruction_account(transaction_context, index_in_caller)
+                .try_borrow_instruction_account(index_in_caller)
                 .unwrap();
             if borrowed_account.get_lamports() != account_info.lamports() {
                 borrowed_account
@@ -345,7 +338,7 @@ impl solana_sysvar::program_stubs::SyscallStubs for SyscallStubs {
                 .get_index_of_account_in_instruction(index_in_transaction)
                 .unwrap();
             let borrowed_account = instruction_context
-                .try_borrow_instruction_account(transaction_context, index_in_caller)
+                .try_borrow_instruction_account(index_in_caller)
                 .unwrap();
             let account_info = &account_infos[account_info_index];
             **account_info.try_borrow_mut_lamports().unwrap() = borrowed_account.get_lamports();
@@ -425,9 +418,7 @@ impl solana_sysvar::program_stubs::SyscallStubs for SyscallStubs {
         let instruction_context = transaction_context
             .get_current_instruction_context()
             .unwrap();
-        let caller = *instruction_context
-            .get_program_key(transaction_context)
-            .unwrap();
+        let caller = *instruction_context.get_program_key().unwrap();
         transaction_context
             .set_return_data(caller, data.to_vec())
             .unwrap();

+ 6 - 12
programs/bpf_loader/benches/serialization.rs

@@ -115,8 +115,7 @@ fn bench_serialize_unaligned(c: &mut Criterion) {
     c.bench_function("serialize_unaligned", |b| {
         b.iter(|| {
             let _ = serialize_parameters(
-                &transaction_context,
-                instruction_context,
+                &instruction_context,
                 true, // stricter_abi_and_runtime_constraints
                 true, // account_data_direct_mapping
                 true, // mask_out_rent_epoch_in_vm_serialization
@@ -134,8 +133,7 @@ fn bench_serialize_unaligned_copy_account_data(c: &mut Criterion) {
     c.bench_function("serialize_unaligned_copy_account_data", |b| {
         b.iter(|| {
             let _ = serialize_parameters(
-                &transaction_context,
-                instruction_context,
+                &instruction_context,
                 false, // stricter_abi_and_runtime_constraints
                 false, // account_data_direct_mapping
                 true,  // mask_out_rent_epoch_in_vm_serialization
@@ -154,8 +152,7 @@ fn bench_serialize_aligned(c: &mut Criterion) {
     c.bench_function("serialize_aligned", |b| {
         b.iter(|| {
             let _ = serialize_parameters(
-                &transaction_context,
-                instruction_context,
+                &instruction_context,
                 true, // stricter_abi_and_runtime_constraints
                 true, // account_data_direct_mapping
                 true, // mask_out_rent_epoch_in_vm_serialization
@@ -174,8 +171,7 @@ fn bench_serialize_aligned_copy_account_data(c: &mut Criterion) {
     c.bench_function("serialize_aligned_copy_account_data", |b| {
         b.iter(|| {
             let _ = serialize_parameters(
-                &transaction_context,
-                instruction_context,
+                &instruction_context,
                 false, // stricter_abi_and_runtime_constraints
                 false, // account_data_direct_mapping
                 true,  // mask_out_rent_epoch_in_vm_serialization
@@ -194,8 +190,7 @@ fn bench_serialize_unaligned_max_accounts(c: &mut Criterion) {
     c.bench_function("serialize_unaligned_max_accounts", |b| {
         b.iter(|| {
             let _ = serialize_parameters(
-                &transaction_context,
-                instruction_context,
+                &instruction_context,
                 true, // stricter_abi_and_runtime_constraints
                 true, // account_data_direct_mapping
                 true, // mask_out_rent_epoch_in_vm_serialization
@@ -214,8 +209,7 @@ fn bench_serialize_aligned_max_accounts(c: &mut Criterion) {
     c.bench_function("serialize_aligned_max_accounts", |b| {
         b.iter(|| {
             let _ = serialize_parameters(
-                &transaction_context,
-                instruction_context,
+                &instruction_context,
                 true, // stricter_abi_and_runtime_constraints
                 true, // account_data_direct_mapping
                 true, // mask_out_rent_epoch_in_vm_serialization

+ 77 - 153
programs/bpf_loader/src/lib.rs

@@ -215,7 +215,7 @@ fn write_program_data(
 ) -> Result<(), InstructionError> {
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
     let data = program.get_data_mut()?;
     let write_offset = program_data_offset.saturating_add(bytes.len());
     if data.len() < write_offset {
@@ -381,12 +381,12 @@ pub(crate) fn process_instruction_inner(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let program_id = instruction_context.get_program_key(transaction_context)?;
-    let owner_id = instruction_context.get_program_owner(transaction_context)?;
+    let program_id = instruction_context.get_program_key()?;
+    let owner_id = instruction_context.get_program_owner()?;
 
     // Program Management Instruction
     if native_loader::check_id(&owner_id) {
-        let program_id = instruction_context.get_program_key(transaction_context)?;
+        let program_id = instruction_context.get_program_key()?;
         return if bpf_loader_upgradeable::check_id(program_id) {
             invoke_context.consume_checked(UPGRADEABLE_LOADER_COMPUTE_UNITS)?;
             process_loader_upgradeable_instruction(invoke_context)
@@ -441,22 +441,19 @@ fn process_loader_upgradeable_instruction(
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
     let instruction_data = instruction_context.get_instruction_data();
-    let program_id = instruction_context.get_program_key(transaction_context)?;
+    let program_id = instruction_context.get_program_key()?;
 
     match limited_deserialize(instruction_data, solana_packet::PACKET_DATA_SIZE as u64)? {
         UpgradeableLoaderInstruction::InitializeBuffer => {
             instruction_context.check_number_of_instruction_accounts(2)?;
-            let mut buffer =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut buffer = instruction_context.try_borrow_instruction_account(0)?;
 
             if UpgradeableLoaderState::Uninitialized != buffer.get_state()? {
                 ic_logger_msg!(log_collector, "Buffer account already initialized");
                 return Err(InstructionError::AccountAlreadyInitialized);
             }
 
-            let authority_key = Some(*transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-            )?);
+            let authority_key = Some(*instruction_context.get_key_of_instruction_account(1)?);
 
             buffer.set_state(&UpgradeableLoaderState::Buffer {
                 authority_address: authority_key,
@@ -464,17 +461,14 @@ fn process_loader_upgradeable_instruction(
         }
         UpgradeableLoaderInstruction::Write { offset, bytes } => {
             instruction_context.check_number_of_instruction_accounts(2)?;
-            let buffer =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let buffer = instruction_context.try_borrow_instruction_account(0)?;
 
             if let UpgradeableLoaderState::Buffer { authority_address } = buffer.get_state()? {
                 if authority_address.is_none() {
                     ic_logger_msg!(log_collector, "Buffer is immutable");
                     return Err(InstructionError::Immutable); // TODO better error code
                 }
-                let authority_key = Some(*transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-                )?);
+                let authority_key = Some(*instruction_context.get_key_of_instruction_account(1)?);
                 if authority_address != authority_key {
                     ic_logger_msg!(log_collector, "Incorrect buffer authority provided");
                     return Err(InstructionError::IncorrectAuthority);
@@ -496,24 +490,18 @@ fn process_loader_upgradeable_instruction(
         }
         UpgradeableLoaderInstruction::DeployWithMaxDataLen { max_data_len } => {
             instruction_context.check_number_of_instruction_accounts(4)?;
-            let payer_key = *transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-            )?;
-            let programdata_key = *transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-            )?;
-            let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 4)?;
+            let payer_key = *instruction_context.get_key_of_instruction_account(0)?;
+            let programdata_key = *instruction_context.get_key_of_instruction_account(1)?;
+            let rent =
+                get_sysvar_with_account_check::rent(invoke_context, &instruction_context, 4)?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 5)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 5)?;
             instruction_context.check_number_of_instruction_accounts(8)?;
-            let authority_key = Some(*transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(7)?,
-            )?);
+            let authority_key = Some(*instruction_context.get_key_of_instruction_account(7)?);
 
             // Verify Program account
 
-            let program =
-                instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
+            let program = instruction_context.try_borrow_instruction_account(2)?;
             if UpgradeableLoaderState::Uninitialized != program.get_state()? {
                 ic_logger_msg!(log_collector, "Program account already initialized");
                 return Err(InstructionError::AccountAlreadyInitialized);
@@ -531,8 +519,7 @@ fn process_loader_upgradeable_instruction(
 
             // Verify Buffer account
 
-            let buffer =
-                instruction_context.try_borrow_instruction_account(transaction_context, 3)?;
+            let buffer = instruction_context.try_borrow_instruction_account(3)?;
             if let UpgradeableLoaderState::Buffer { authority_address } = buffer.get_state()? {
                 if authority_address != authority_key {
                     ic_logger_msg!(log_collector, "Buffer and upgrade authority don't match");
@@ -580,10 +567,8 @@ fn process_loader_upgradeable_instruction(
 
             // Drain the Buffer account to payer before paying for programdata account
             {
-                let mut buffer =
-                    instruction_context.try_borrow_instruction_account(transaction_context, 3)?;
-                let mut payer =
-                    instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+                let mut buffer = instruction_context.try_borrow_instruction_account(3)?;
+                let mut payer = instruction_context.try_borrow_instruction_account(0)?;
                 payer.checked_add_lamports(buffer.get_lamports())?;
                 buffer.set_lamports(0)?;
             }
@@ -604,7 +589,7 @@ fn process_loader_upgradeable_instruction(
 
             let transaction_context = &invoke_context.transaction_context;
             let instruction_context = transaction_context.get_current_instruction_context()?;
-            let caller_program_id = instruction_context.get_program_key(transaction_context)?;
+            let caller_program_id = instruction_context.get_program_key()?;
             let signers = [[new_program_id.as_ref(), &[bump_seed]]]
                 .iter()
                 .map(|seeds| Pubkey::create_program_address(seeds, caller_program_id))
@@ -614,8 +599,7 @@ fn process_loader_upgradeable_instruction(
             // Load and verify the program bits
             let transaction_context = &invoke_context.transaction_context;
             let instruction_context = transaction_context.get_current_instruction_context()?;
-            let buffer =
-                instruction_context.try_borrow_instruction_account(transaction_context, 3)?;
+            let buffer = instruction_context.try_borrow_instruction_account(3)?;
             deploy_program!(
                 invoke_context,
                 &new_program_id,
@@ -634,8 +618,7 @@ fn process_loader_upgradeable_instruction(
 
             // Update the ProgramData account and record the program bits
             {
-                let mut programdata =
-                    instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
+                let mut programdata = instruction_context.try_borrow_instruction_account(1)?;
                 programdata.set_state(&UpgradeableLoaderState::ProgramData {
                     slot: clock.slot,
                     upgrade_authority_address: authority_key,
@@ -647,8 +630,7 @@ fn process_loader_upgradeable_instruction(
                             ..programdata_data_offset.saturating_add(buffer_data_len),
                     )
                     .ok_or(InstructionError::AccountDataTooSmall)?;
-                let mut buffer =
-                    instruction_context.try_borrow_instruction_account(transaction_context, 3)?;
+                let mut buffer = instruction_context.try_borrow_instruction_account(3)?;
                 let src_slice = buffer
                     .get_data()
                     .get(buffer_data_offset..)
@@ -658,8 +640,7 @@ fn process_loader_upgradeable_instruction(
             }
 
             // Update the Program account
-            let mut program =
-                instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
+            let mut program = instruction_context.try_borrow_instruction_account(2)?;
             program.set_state(&UpgradeableLoaderState::Program {
                 programdata_address: programdata_key,
             })?;
@@ -670,21 +651,17 @@ fn process_loader_upgradeable_instruction(
         }
         UpgradeableLoaderInstruction::Upgrade => {
             instruction_context.check_number_of_instruction_accounts(3)?;
-            let programdata_key = *transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-            )?;
-            let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 4)?;
+            let programdata_key = *instruction_context.get_key_of_instruction_account(0)?;
+            let rent =
+                get_sysvar_with_account_check::rent(invoke_context, &instruction_context, 4)?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 5)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 5)?;
             instruction_context.check_number_of_instruction_accounts(7)?;
-            let authority_key = Some(*transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(6)?,
-            )?);
+            let authority_key = Some(*instruction_context.get_key_of_instruction_account(6)?);
 
             // Verify Program account
 
-            let program =
-                instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
+            let program = instruction_context.try_borrow_instruction_account(1)?;
             if !program.is_writable() {
                 ic_logger_msg!(log_collector, "Program account not writeable");
                 return Err(InstructionError::InvalidArgument);
@@ -710,8 +687,7 @@ fn process_loader_upgradeable_instruction(
 
             // Verify Buffer account
 
-            let buffer =
-                instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
+            let buffer = instruction_context.try_borrow_instruction_account(2)?;
             if let UpgradeableLoaderState::Buffer { authority_address } = buffer.get_state()? {
                 if authority_address != authority_key {
                     ic_logger_msg!(log_collector, "Buffer and upgrade authority don't match");
@@ -738,8 +714,7 @@ fn process_loader_upgradeable_instruction(
 
             // Verify ProgramData account
 
-            let programdata =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let programdata = instruction_context.try_borrow_instruction_account(0)?;
             let programdata_data_offset = UpgradeableLoaderState::size_of_programdata_metadata();
             let programdata_balance_required =
                 1.max(rent.minimum_balance(programdata.get_data().len()));
@@ -787,8 +762,7 @@ fn process_loader_upgradeable_instruction(
             drop(programdata);
 
             // Load and verify the program bits
-            let buffer =
-                instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
+            let buffer = instruction_context.try_borrow_instruction_account(2)?;
             deploy_program!(
                 invoke_context,
                 &new_program_id,
@@ -807,8 +781,7 @@ fn process_loader_upgradeable_instruction(
 
             // Update the ProgramData account, record the upgraded data, and zero
             // the rest
-            let mut programdata =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut programdata = instruction_context.try_borrow_instruction_account(0)?;
             {
                 programdata.set_state(&UpgradeableLoaderState::ProgramData {
                     slot: clock.slot,
@@ -821,8 +794,7 @@ fn process_loader_upgradeable_instruction(
                             ..programdata_data_offset.saturating_add(buffer_data_len),
                     )
                     .ok_or(InstructionError::AccountDataTooSmall)?;
-                let buffer =
-                    instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
+                let buffer = instruction_context.try_borrow_instruction_account(2)?;
                 let src_slice = buffer
                     .get_data()
                     .get(buffer_data_offset..)
@@ -836,10 +808,8 @@ fn process_loader_upgradeable_instruction(
                 .fill(0);
 
             // Fund ProgramData to rent-exemption, spill the rest
-            let mut buffer =
-                instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
-            let mut spill =
-                instruction_context.try_borrow_instruction_account(transaction_context, 3)?;
+            let mut buffer = instruction_context.try_borrow_instruction_account(2)?;
+            let mut spill = instruction_context.try_borrow_instruction_account(3)?;
             spill.checked_add_lamports(
                 programdata
                     .get_lamports()
@@ -854,17 +824,9 @@ fn process_loader_upgradeable_instruction(
         }
         UpgradeableLoaderInstruction::SetAuthority => {
             instruction_context.check_number_of_instruction_accounts(2)?;
-            let mut account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-            let present_authority_key = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-            )?;
-            let new_authority = instruction_context
-                .get_index_of_instruction_account_in_transaction(2)
-                .and_then(|index_in_transaction| {
-                    transaction_context.get_key_of_account_at_index(index_in_transaction)
-                })
-                .ok();
+            let mut account = instruction_context.try_borrow_instruction_account(0)?;
+            let present_authority_key = instruction_context.get_key_of_instruction_account(1)?;
+            let new_authority = instruction_context.get_key_of_instruction_account(2).ok();
 
             match account.get_state()? {
                 UpgradeableLoaderState::Buffer { authority_address } => {
@@ -926,14 +888,9 @@ fn process_loader_upgradeable_instruction(
             }
 
             instruction_context.check_number_of_instruction_accounts(3)?;
-            let mut account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-            let present_authority_key = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-            )?;
-            let new_authority_key = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(2)?,
-            )?;
+            let mut account = instruction_context.try_borrow_instruction_account(0)?;
+            let present_authority_key = instruction_context.get_key_of_instruction_account(1)?;
+            let new_authority_key = instruction_context.get_key_of_instruction_account(2)?;
 
             match account.get_state()? {
                 UpgradeableLoaderState::Buffer { authority_address } => {
@@ -1001,15 +958,14 @@ fn process_loader_upgradeable_instruction(
                 );
                 return Err(InstructionError::InvalidArgument);
             }
-            let mut close_account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut close_account = instruction_context.try_borrow_instruction_account(0)?;
             let close_key = *close_account.get_key();
             let close_account_state = close_account.get_state()?;
             close_account.set_data_length(UpgradeableLoaderState::size_of_uninitialized())?;
             match close_account_state {
                 UpgradeableLoaderState::Uninitialized => {
-                    let mut recipient_account = instruction_context
-                        .try_borrow_instruction_account(transaction_context, 1)?;
+                    let mut recipient_account =
+                        instruction_context.try_borrow_instruction_account(1)?;
                     recipient_account.checked_add_lamports(close_account.get_lamports())?;
                     close_account.set_lamports(0)?;
 
@@ -1018,12 +974,7 @@ fn process_loader_upgradeable_instruction(
                 UpgradeableLoaderState::Buffer { authority_address } => {
                     instruction_context.check_number_of_instruction_accounts(3)?;
                     drop(close_account);
-                    common_close_account(
-                        &authority_address,
-                        transaction_context,
-                        instruction_context,
-                        &log_collector,
-                    )?;
+                    common_close_account(&authority_address, &instruction_context, &log_collector)?;
 
                     ic_logger_msg!(log_collector, "Closed Buffer {}", close_key);
                 }
@@ -1033,8 +984,7 @@ fn process_loader_upgradeable_instruction(
                 } => {
                     instruction_context.check_number_of_instruction_accounts(4)?;
                     drop(close_account);
-                    let program_account = instruction_context
-                        .try_borrow_instruction_account(transaction_context, 3)?;
+                    let program_account = instruction_context.try_borrow_instruction_account(3)?;
                     let program_key = *program_account.get_key();
 
                     if !program_account.is_writable() {
@@ -1066,8 +1016,7 @@ fn process_loader_upgradeable_instruction(
                             drop(program_account);
                             common_close_account(
                                 &authority_address,
-                                transaction_context,
-                                instruction_context,
+                                &instruction_context,
                                 &log_collector,
                             )?;
                             let clock = invoke_context.get_sysvar_cache().get_clock()?;
@@ -1124,23 +1073,17 @@ fn process_loader_upgradeable_instruction(
             }
 
             instruction_context.check_number_of_instruction_accounts(3)?;
-            let programdata_address = *transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-            )?;
-            let program_address = *transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-            )?;
-            let provided_authority_address = *transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(2)?,
-            )?;
+            let programdata_address = *instruction_context.get_key_of_instruction_account(0)?;
+            let program_address = *instruction_context.get_key_of_instruction_account(1)?;
+            let provided_authority_address =
+                *instruction_context.get_key_of_instruction_account(2)?;
             let clock_slot = invoke_context
                 .get_sysvar_cache()
                 .get_clock()
                 .map(|clock| clock.slot)?;
 
             // Verify ProgramData account
-            let programdata =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let programdata = instruction_context.try_borrow_instruction_account(0)?;
             if !programdata.is_writable() {
                 ic_logger_msg!(log_collector, "ProgramData account not writeable");
                 return Err(InstructionError::InvalidArgument);
@@ -1182,8 +1125,7 @@ fn process_loader_upgradeable_instruction(
             }
 
             // Verify Program account
-            let mut program =
-                instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
+            let mut program = instruction_context.try_borrow_instruction_account(1)?;
             if !program.is_writable() {
                 ic_logger_msg!(log_collector, "Program account not writeable");
                 return Err(InstructionError::InvalidArgument);
@@ -1209,8 +1151,7 @@ fn process_loader_upgradeable_instruction(
             program.set_owner(&loader_v4::id().to_bytes())?;
             drop(program);
 
-            let mut programdata =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut programdata = instruction_context.try_borrow_instruction_account(0)?;
             programdata.set_lamports(0)?;
             drop(programdata);
 
@@ -1279,8 +1220,7 @@ fn process_loader_upgradeable_instruction(
 
             let transaction_context = &invoke_context.transaction_context;
             let instruction_context = transaction_context.get_current_instruction_context()?;
-            let mut programdata =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut programdata = instruction_context.try_borrow_instruction_account(0)?;
             programdata.set_data_from_slice(&[])?;
             drop(programdata);
 
@@ -1299,7 +1239,7 @@ fn common_extend_program(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let program_id = instruction_context.get_program_key(transaction_context)?;
+    let program_id = instruction_context.get_program_key()?;
 
     const PROGRAM_DATA_ACCOUNT_INDEX: IndexOfAccount = 0;
     const PROGRAM_ACCOUNT_INDEX: IndexOfAccount = 1;
@@ -1312,8 +1252,8 @@ fn common_extend_program(
         return Err(InstructionError::InvalidInstructionData);
     }
 
-    let programdata_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, PROGRAM_DATA_ACCOUNT_INDEX)?;
+    let programdata_account =
+        instruction_context.try_borrow_instruction_account(PROGRAM_DATA_ACCOUNT_INDEX)?;
     let programdata_key = *programdata_account.get_key();
 
     if program_id != programdata_account.get_owner() {
@@ -1325,8 +1265,8 @@ fn common_extend_program(
         return Err(InstructionError::InvalidArgument);
     }
 
-    let program_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, PROGRAM_ACCOUNT_INDEX)?;
+    let program_account =
+        instruction_context.try_borrow_instruction_account(PROGRAM_ACCOUNT_INDEX)?;
     if !program_account.is_writable() {
         ic_logger_msg!(log_collector, "Program account is not writable");
         return Err(InstructionError::InvalidArgument);
@@ -1391,12 +1331,8 @@ fn common_extend_program(
         }
 
         if check_authority {
-            let authority_key = Some(
-                *transaction_context.get_key_of_account_at_index(
-                    instruction_context
-                        .get_index_of_instruction_account_in_transaction(AUTHORITY_ACCOUNT_INDEX)?,
-                )?,
-            );
+            let authority_key =
+                Some(*instruction_context.get_key_of_instruction_account(AUTHORITY_ACCOUNT_INDEX)?);
             if upgrade_authority_address != authority_key {
                 ic_logger_msg!(log_collector, "Incorrect upgrade authority provided");
                 return Err(InstructionError::IncorrectAuthority);
@@ -1426,10 +1362,8 @@ fn common_extend_program(
     // Dereference the program ID to prevent overlapping mutable/immutable borrow of invoke context
     let program_id = *program_id;
     if required_payment > 0 {
-        let payer_key = *transaction_context.get_key_of_account_at_index(
-            instruction_context
-                .get_index_of_instruction_account_in_transaction(optional_payer_account_index)?,
-        )?;
+        let payer_key =
+            *instruction_context.get_key_of_instruction_account(optional_payer_account_index)?;
 
         invoke_context.native_invoke(
             system_instruction::transfer(&payer_key, &programdata_key, required_payment),
@@ -1439,8 +1373,8 @@ fn common_extend_program(
 
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut programdata_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, PROGRAM_DATA_ACCOUNT_INDEX)?;
+    let mut programdata_account =
+        instruction_context.try_borrow_instruction_account(PROGRAM_DATA_ACCOUNT_INDEX)?;
     programdata_account.set_data_length(new_len)?;
 
     let programdata_data_offset = UpgradeableLoaderState::size_of_programdata_metadata();
@@ -1458,8 +1392,8 @@ fn common_extend_program(
     );
     drop(programdata_account);
 
-    let mut programdata_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, PROGRAM_DATA_ACCOUNT_INDEX)?;
+    let mut programdata_account =
+        instruction_context.try_borrow_instruction_account(PROGRAM_DATA_ACCOUNT_INDEX)?;
     programdata_account.set_state(&UpgradeableLoaderState::ProgramData {
         slot: clock_slot,
         upgrade_authority_address,
@@ -1476,7 +1410,6 @@ fn common_extend_program(
 
 fn common_close_account(
     authority_address: &Option<Pubkey>,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     log_collector: &Option<Rc<RefCell<LogCollector>>>,
 ) -> Result<(), InstructionError> {
@@ -1484,11 +1417,7 @@ fn common_close_account(
         ic_logger_msg!(log_collector, "Account is immutable");
         return Err(InstructionError::Immutable);
     }
-    if *authority_address
-        != Some(*transaction_context.get_key_of_account_at_index(
-            instruction_context.get_index_of_instruction_account_in_transaction(2)?,
-        )?)
-    {
+    if *authority_address != Some(*instruction_context.get_key_of_instruction_account(2)?) {
         ic_logger_msg!(log_collector, "Incorrect authority provided");
         return Err(InstructionError::IncorrectAuthority);
     }
@@ -1497,10 +1426,8 @@ fn common_close_account(
         return Err(InstructionError::MissingRequiredSignature);
     }
 
-    let mut close_account =
-        instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-    let mut recipient_account =
-        instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
+    let mut close_account = instruction_context.try_borrow_instruction_account(0)?;
+    let mut recipient_account = instruction_context.try_borrow_instruction_account(1)?;
 
     recipient_account.checked_add_lamports(close_account.get_lamports())?;
     close_account.set_lamports(0)?;
@@ -1523,9 +1450,9 @@ fn execute<'a, 'b: 'a>(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let program_id = *instruction_context.get_program_key(transaction_context)?;
+    let program_id = *instruction_context.get_program_key()?;
     let is_loader_deprecated =
-        instruction_context.get_program_owner(transaction_context)? == bpf_loader_deprecated::id();
+        instruction_context.get_program_owner()? == bpf_loader_deprecated::id();
     #[cfg(any(target_os = "windows", not(target_arch = "x86_64")))]
     let use_jit = false;
     #[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
@@ -1539,8 +1466,7 @@ fn execute<'a, 'b: 'a>(
 
     let mut serialize_time = Measure::start("serialize");
     let (parameter_bytes, regions, accounts_metadata) = serialization::serialize_parameters(
-        invoke_context.transaction_context,
-        instruction_context,
+        &instruction_context,
         stricter_abi_and_runtime_constraints,
         invoke_context.account_data_direct_mapping,
         mask_out_rent_epoch_in_vm_serialization,
@@ -1647,7 +1573,6 @@ fn execute<'a, 'b: 'a>(
                             let instruction_context =
                                 transaction_context.get_current_instruction_context()?;
                             let account = instruction_context.try_borrow_instruction_account(
-                                transaction_context,
                                 instruction_account_index as IndexOfAccount,
                             )?;
                             if vm_addr.saturating_add(len) <= vm_addr_range.end {
@@ -1705,8 +1630,7 @@ fn execute<'a, 'b: 'a>(
         stricter_abi_and_runtime_constraints: bool,
     ) -> Result<(), InstructionError> {
         serialization::deserialize_parameters(
-            invoke_context.transaction_context,
-            invoke_context
+            &invoke_context
                 .transaction_context
                 .get_current_instruction_context()?,
             stricter_abi_and_runtime_constraints,

+ 27 - 47
programs/loader-v4/src/lib.rs

@@ -93,13 +93,11 @@ fn process_instruction_write(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-    let authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(1)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
+    let authority_address = instruction_context.get_key_of_instruction_account(1)?;
     let state = check_program_account(
         &log_collector,
-        instruction_context,
+        &instruction_context,
         &program,
         authority_address,
     )?;
@@ -128,15 +126,12 @@ fn process_instruction_copy(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-    let authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(1)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
-    let source_program =
-        instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
+    let authority_address = instruction_context.get_key_of_instruction_account(1)?;
+    let source_program = instruction_context.try_borrow_instruction_account(2)?;
     let state = check_program_account(
         &log_collector,
-        instruction_context,
+        &instruction_context,
         &program,
         authority_address,
     )?;
@@ -185,10 +180,8 @@ fn process_instruction_set_program_length(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-    let authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(1)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
+    let authority_address = instruction_context.get_key_of_instruction_account(1)?;
     let is_initialization = program.get_data().len() < LoaderV4State::program_data_offset();
     if is_initialization {
         if !loader_v4::check_id(program.get_owner()) {
@@ -206,7 +199,7 @@ fn process_instruction_set_program_length(
     } else {
         let state = check_program_account(
             &log_collector,
-            instruction_context,
+            &instruction_context,
             &program,
             authority_address,
         )?;
@@ -232,9 +225,7 @@ fn process_instruction_set_program_length(
             return Err(InstructionError::InsufficientFunds);
         }
         std::cmp::Ordering::Greater => {
-            let recipient = instruction_context
-                .try_borrow_instruction_account(transaction_context, 2)
-                .ok();
+            let recipient = instruction_context.try_borrow_instruction_account(2).ok();
             if let Some(mut recipient) = recipient {
                 if !instruction_context.is_instruction_account_writable(2)? {
                     ic_logger_msg!(log_collector, "Recipient is not writeable");
@@ -274,13 +265,11 @@ fn process_instruction_deploy(invoke_context: &mut InvokeContext) -> Result<(),
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-    let authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(1)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
+    let authority_address = instruction_context.get_key_of_instruction_account(1)?;
     let state = check_program_account(
         &log_collector,
-        instruction_context,
+        &instruction_context,
         &program,
         authority_address,
     )?;
@@ -324,14 +313,12 @@ fn process_instruction_retract(invoke_context: &mut InvokeContext) -> Result<(),
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
 
-    let authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(1)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
+    let authority_address = instruction_context.get_key_of_instruction_account(1)?;
     let state = check_program_account(
         &log_collector,
-        instruction_context,
+        &instruction_context,
         &program,
         authority_address,
     )?;
@@ -368,16 +355,12 @@ fn process_instruction_transfer_authority(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-    let authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(1)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
-    let new_authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(2)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
+    let authority_address = instruction_context.get_key_of_instruction_account(1)?;
+    let new_authority_address = instruction_context.get_key_of_instruction_account(2)?;
     let state = check_program_account(
         &log_collector,
-        instruction_context,
+        &instruction_context,
         &program,
         authority_address,
     )?;
@@ -400,13 +383,11 @@ fn process_instruction_finalize(
     let log_collector = invoke_context.get_log_collector();
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
-    let authority_address = instruction_context
-        .get_index_of_instruction_account_in_transaction(1)
-        .and_then(|index| transaction_context.get_key_of_account_at_index(index))?;
+    let program = instruction_context.try_borrow_instruction_account(0)?;
+    let authority_address = instruction_context.get_key_of_instruction_account(1)?;
     let state = check_program_account(
         &log_collector,
-        instruction_context,
+        &instruction_context,
         &program,
         authority_address,
     )?;
@@ -415,8 +396,7 @@ fn process_instruction_finalize(
         return Err(InstructionError::InvalidArgument);
     }
     drop(program);
-    let next_version =
-        instruction_context.try_borrow_instruction_account(transaction_context, 2)?;
+    let next_version = instruction_context.try_borrow_instruction_account(2)?;
     if !loader_v4::check_id(next_version.get_owner()) {
         ic_logger_msg!(log_collector, "Next version is not owned by loader");
         return Err(InstructionError::InvalidAccountOwner);
@@ -432,7 +412,7 @@ fn process_instruction_finalize(
     }
     let address_of_next_version = *next_version.get_key();
     drop(next_version);
-    let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+    let mut program = instruction_context.try_borrow_instruction_account(0)?;
     let state = get_state_mut(program.get_data_mut()?)?;
     state.authority_address_or_next_version = address_of_next_version;
     state.status = LoaderV4Status::Finalized;
@@ -461,7 +441,7 @@ fn process_instruction_inner(
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
     let instruction_data = instruction_context.get_instruction_data();
-    let program_id = instruction_context.get_program_key(transaction_context)?;
+    let program_id = instruction_context.get_program_key()?;
     if loader_v4::check_id(program_id) {
         invoke_context.consume_checked(DEFAULT_COMPUTE_UNITS)?;
         match limited_deserialize(instruction_data, solana_packet::PACKET_DATA_SIZE as u64)? {

+ 2 - 4
programs/sbf/benches/bpf_loader.rs

@@ -243,8 +243,7 @@ fn bench_create_vm(bencher: &mut Bencher) {
 
     // Serialize account data
     let (_serialized, regions, account_lengths) = serialize_parameters(
-        invoke_context.transaction_context,
-        invoke_context
+        &invoke_context
             .transaction_context
             .get_current_instruction_context()
             .unwrap(),
@@ -279,8 +278,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
 
     // Serialize account data
     let (_serialized, regions, account_lengths) = serialize_parameters(
-        invoke_context.transaction_context,
-        invoke_context
+        &invoke_context
             .transaction_context
             .get_current_instruction_context()
             .unwrap(),

+ 37 - 84
programs/stake/src/stake_instruction.rs

@@ -17,11 +17,10 @@ use {
         program::id,
         state::{Authorized, Lockup},
     },
-    solana_transaction_context::{IndexOfAccount, InstructionContext, TransactionContext},
+    solana_transaction_context::{IndexOfAccount, InstructionContext},
 };
 
 fn get_optional_pubkey<'a>(
-    transaction_context: &'a TransactionContext,
     instruction_context: &'a InstructionContext,
     instruction_account_index: IndexOfAccount,
     should_be_signer: bool,
@@ -33,13 +32,7 @@ fn get_optional_pubkey<'a>(
             {
                 return Err(InstructionError::MissingRequiredSignature);
             }
-            Some(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(
-                        instruction_account_index,
-                    )?,
-                )?,
-            )
+            Some(instruction_context.get_key_of_instruction_account(instruction_account_index)?)
         } else {
             None
         },
@@ -56,7 +49,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
     trace!("process_instruction: {data:?}");
 
     let get_stake_account = || {
-        let me = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+        let me = instruction_context.try_borrow_instruction_account(0)?;
         if *me.get_owner() != id() {
             return Err(InstructionError::InvalidAccountOwner);
         }
@@ -72,7 +65,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         .map(|epoch_rewards| epoch_rewards.active)
         .unwrap_or(false);
 
-    let signers = instruction_context.get_signers(transaction_context)?;
+    let signers = instruction_context.get_signers()?;
 
     let stake_instruction: StakeInstruction =
         limited_deserialize(data, solana_packet::PACKET_DATA_SIZE as u64)?;
@@ -83,16 +76,16 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
     match stake_instruction {
         StakeInstruction::Initialize(authorized, lockup) => {
             let mut me = get_stake_account()?;
-            let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
+            let rent =
+                get_sysvar_with_account_check::rent(invoke_context, &instruction_context, 1)?;
             initialize(&mut me, &authorized, &lockup, &rent)
         }
         StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => {
             let mut me = get_stake_account()?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 1)?;
             instruction_context.check_number_of_instruction_accounts(3)?;
-            let custodian_pubkey =
-                get_optional_pubkey(transaction_context, instruction_context, 3, false)?;
+            let custodian_pubkey = get_optional_pubkey(&instruction_context, 3, false)?;
 
             authorize(
                 &mut me,
@@ -107,13 +100,11 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             let mut me = get_stake_account()?;
             instruction_context.check_number_of_instruction_accounts(2)?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
-            let custodian_pubkey =
-                get_optional_pubkey(transaction_context, instruction_context, 3, false)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 2)?;
+            let custodian_pubkey = get_optional_pubkey(&instruction_context, 3, false)?;
 
             authorize_with_seed(
-                transaction_context,
-                instruction_context,
+                &instruction_context,
                 &mut me,
                 1,
                 &args.authority_seed,
@@ -128,17 +119,16 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             let me = get_stake_account()?;
             instruction_context.check_number_of_instruction_accounts(2)?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 2)?;
             let stake_history = get_sysvar_with_account_check::stake_history(
                 invoke_context,
-                instruction_context,
+                &instruction_context,
                 3,
             )?;
             instruction_context.check_number_of_instruction_accounts(5)?;
             drop(me);
             delegate(
-                transaction_context,
-                instruction_context,
+                &instruction_context,
                 0,
                 1,
                 &clock,
@@ -153,8 +143,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             drop(me);
             split(
                 invoke_context,
-                transaction_context,
-                instruction_context,
+                &instruction_context,
                 0,
                 lamports,
                 1,
@@ -165,17 +154,16 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             let me = get_stake_account()?;
             instruction_context.check_number_of_instruction_accounts(2)?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 2)?;
             let stake_history = get_sysvar_with_account_check::stake_history(
                 invoke_context,
-                instruction_context,
+                &instruction_context,
                 3,
             )?;
             drop(me);
             merge(
                 invoke_context,
-                transaction_context,
-                instruction_context,
+                &instruction_context,
                 0,
                 1,
                 &clock,
@@ -187,17 +175,16 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             let me = get_stake_account()?;
             instruction_context.check_number_of_instruction_accounts(2)?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 2)?;
             let stake_history = get_sysvar_with_account_check::stake_history(
                 invoke_context,
-                instruction_context,
+                &instruction_context,
                 3,
             )?;
             instruction_context.check_number_of_instruction_accounts(5)?;
             drop(me);
             withdraw(
-                transaction_context,
-                instruction_context,
+                &instruction_context,
                 0,
                 lamports,
                 1,
@@ -215,7 +202,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         StakeInstruction::Deactivate => {
             let mut me = get_stake_account()?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 1)?;
             deactivate(&mut me, &clock, &signers)
         }
         StakeInstruction::SetLockup(lockup) => {
@@ -226,12 +213,8 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         StakeInstruction::InitializeChecked => {
             let mut me = get_stake_account()?;
             instruction_context.check_number_of_instruction_accounts(4)?;
-            let staker_pubkey = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(2)?,
-            )?;
-            let withdrawer_pubkey = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(3)?,
-            )?;
+            let staker_pubkey = instruction_context.get_key_of_instruction_account(2)?;
+            let withdrawer_pubkey = instruction_context.get_key_of_instruction_account(3)?;
             if !instruction_context.is_instruction_account_signer(3)? {
                 return Err(InstructionError::MissingRequiredSignature);
             }
@@ -241,22 +224,20 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
                 withdrawer: *withdrawer_pubkey,
             };
 
-            let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
+            let rent =
+                get_sysvar_with_account_check::rent(invoke_context, &instruction_context, 1)?;
             initialize(&mut me, &authorized, &Lockup::default(), &rent)
         }
         StakeInstruction::AuthorizeChecked(stake_authorize) => {
             let mut me = get_stake_account()?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 1)?;
             instruction_context.check_number_of_instruction_accounts(4)?;
-            let authorized_pubkey = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(3)?,
-            )?;
+            let authorized_pubkey = instruction_context.get_key_of_instruction_account(3)?;
             if !instruction_context.is_instruction_account_signer(3)? {
                 return Err(InstructionError::MissingRequiredSignature);
             }
-            let custodian_pubkey =
-                get_optional_pubkey(transaction_context, instruction_context, 4, false)?;
+            let custodian_pubkey = get_optional_pubkey(&instruction_context, 4, false)?;
 
             authorize(
                 &mut me,
@@ -271,20 +252,16 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             let mut me = get_stake_account()?;
             instruction_context.check_number_of_instruction_accounts(2)?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 2)?;
             instruction_context.check_number_of_instruction_accounts(4)?;
-            let authorized_pubkey = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(3)?,
-            )?;
+            let authorized_pubkey = instruction_context.get_key_of_instruction_account(3)?;
             if !instruction_context.is_instruction_account_signer(3)? {
                 return Err(InstructionError::MissingRequiredSignature);
             }
-            let custodian_pubkey =
-                get_optional_pubkey(transaction_context, instruction_context, 4, false)?;
+            let custodian_pubkey = get_optional_pubkey(&instruction_context, 4, false)?;
 
             authorize_with_seed(
-                transaction_context,
-                instruction_context,
+                &instruction_context,
                 &mut me,
                 1,
                 &args.authority_seed,
@@ -297,8 +274,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         StakeInstruction::SetLockupChecked(lockup_checked) => {
             let mut me = get_stake_account()?;
-            let custodian_pubkey =
-                get_optional_pubkey(transaction_context, instruction_context, 2, true)?;
+            let custodian_pubkey = get_optional_pubkey(&instruction_context, 2, true)?;
 
             let lockup = LockupArgs {
                 unix_timestamp: lockup_checked.unix_timestamp,
@@ -322,14 +298,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             instruction_context.check_number_of_instruction_accounts(3)?;
 
             let clock = invoke_context.get_sysvar_cache().get_clock()?;
-            deactivate_delinquent(
-                transaction_context,
-                instruction_context,
-                &mut me,
-                1,
-                2,
-                clock.epoch,
-            )
+            deactivate_delinquent(&instruction_context, &mut me, 1, 2, clock.epoch)
         }
         #[allow(deprecated)]
         StakeInstruction::Redelegate => {
@@ -338,27 +307,11 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         StakeInstruction::MoveStake(lamports) => {
             instruction_context.check_number_of_instruction_accounts(3)?;
-            move_stake(
-                invoke_context,
-                transaction_context,
-                instruction_context,
-                0,
-                lamports,
-                1,
-                2,
-            )
+            move_stake(invoke_context, &instruction_context, 0, lamports, 1, 2)
         }
         StakeInstruction::MoveLamports(lamports) => {
             instruction_context.check_number_of_instruction_accounts(3)?;
-            move_lamports(
-                invoke_context,
-                transaction_context,
-                instruction_context,
-                0,
-                lamports,
-                1,
-                2,
-            )
+            move_lamports(invoke_context, &instruction_context, 0, lamports, 1, 2)
         }
     }
 });

+ 49 - 87
programs/stake/src/stake_state.rs

@@ -24,9 +24,7 @@ use {
     },
     solana_svm_log_collector::ic_msg,
     solana_sysvar::stake_history::{StakeHistory, StakeHistoryEntry},
-    solana_transaction_context::{
-        BorrowedAccount, IndexOfAccount, InstructionContext, TransactionContext,
-    },
+    solana_transaction_context::{BorrowedAccount, IndexOfAccount, InstructionContext},
     solana_vote_interface::state::{VoteState, VoteStateVersions},
     std::{collections::HashSet, convert::TryFrom},
 };
@@ -123,7 +121,6 @@ fn redelegate_stake(
 
 fn move_stake_or_lamports_shared_checks(
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     source_account: &BorrowedAccount,
     lamports: u64,
@@ -131,10 +128,8 @@ fn move_stake_or_lamports_shared_checks(
     stake_authority_index: IndexOfAccount,
 ) -> Result<(MergeKind, MergeKind), InstructionError> {
     // authority must sign
-    let stake_authority_pubkey = transaction_context.get_key_of_account_at_index(
-        instruction_context
-            .get_index_of_instruction_account_in_transaction(stake_authority_index)?,
-    )?;
+    let stake_authority_pubkey =
+        instruction_context.get_key_of_instruction_account(stake_authority_index)?;
     if !instruction_context.is_instruction_account_signer(stake_authority_index)? {
         return Err(InstructionError::MissingRequiredSignature);
     }
@@ -275,7 +270,6 @@ pub fn authorize(
 
 #[allow(clippy::too_many_arguments)]
 pub fn authorize_with_seed(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stake_account: &mut BorrowedAccount,
     authority_base_index: IndexOfAccount,
@@ -288,10 +282,8 @@ pub fn authorize_with_seed(
 ) -> Result<(), InstructionError> {
     let mut signers = HashSet::default();
     if instruction_context.is_instruction_account_signer(authority_base_index)? {
-        let base_pubkey = transaction_context.get_key_of_account_at_index(
-            instruction_context
-                .get_index_of_instruction_account_in_transaction(authority_base_index)?,
-        )?;
+        let base_pubkey =
+            instruction_context.get_key_of_instruction_account(authority_base_index)?;
         signers.insert(Pubkey::create_with_seed(
             base_pubkey,
             authority_seed,
@@ -310,7 +302,6 @@ pub fn authorize_with_seed(
 
 #[allow(clippy::too_many_arguments)]
 pub fn delegate(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stake_account_index: IndexOfAccount,
     vote_account_index: IndexOfAccount,
@@ -319,8 +310,7 @@ pub fn delegate(
     signers: &HashSet<Pubkey>,
     invoke_context: &InvokeContext,
 ) -> Result<(), InstructionError> {
-    let vote_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, vote_account_index)?;
+    let vote_account = instruction_context.try_borrow_instruction_account(vote_account_index)?;
     if *vote_account.get_owner() != solana_sdk_ids::vote::id() {
         return Err(InstructionError::IncorrectProgramId);
     }
@@ -328,8 +318,8 @@ pub fn delegate(
     let vote_state = vote_account.get_state::<VoteStateVersions>();
     drop(vote_account);
 
-    let mut stake_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, stake_account_index)?;
+    let mut stake_account =
+        instruction_context.try_borrow_instruction_account(stake_account_index)?;
     match stake_account.get_state()? {
         StakeStateV2::Initialized(meta) => {
             meta.authorized.check(signers, StakeAuthorize::Staker)?;
@@ -396,15 +386,13 @@ pub fn set_lockup(
 
 pub fn split(
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stake_account_index: IndexOfAccount,
     lamports: u64,
     split_index: IndexOfAccount,
     signers: &HashSet<Pubkey>,
 ) -> Result<(), InstructionError> {
-    let split =
-        instruction_context.try_borrow_instruction_account(transaction_context, split_index)?;
+    let split = instruction_context.try_borrow_instruction_account(split_index)?;
     if *split.get_owner() != id() {
         return Err(InstructionError::IncorrectProgramId);
     }
@@ -416,8 +404,7 @@ pub fn split(
     }
     let split_lamport_balance = split.get_lamports();
     drop(split);
-    let stake_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, stake_account_index)?;
+    let stake_account = instruction_context.try_borrow_instruction_account(stake_account_index)?;
     if lamports > stake_account.get_lamports() {
         return Err(InstructionError::InsufficientFunds);
     }
@@ -437,7 +424,6 @@ pub fn split(
             };
             let validated_split_info = validate_split_amount(
                 invoke_context,
-                transaction_context,
                 instruction_context,
                 stake_account_index,
                 split_index,
@@ -492,19 +478,17 @@ pub fn split(
             let mut split_meta = meta;
             split_meta.rent_exempt_reserve = validated_split_info.destination_rent_exempt_reserve;
 
-            let mut stake_account = instruction_context
-                .try_borrow_instruction_account(transaction_context, stake_account_index)?;
+            let mut stake_account =
+                instruction_context.try_borrow_instruction_account(stake_account_index)?;
             stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags))?;
             drop(stake_account);
-            let mut split = instruction_context
-                .try_borrow_instruction_account(transaction_context, split_index)?;
+            let mut split = instruction_context.try_borrow_instruction_account(split_index)?;
             split.set_state(&StakeStateV2::Stake(split_meta, split_stake, stake_flags))?;
         }
         StakeStateV2::Initialized(meta) => {
             meta.authorized.check(signers, StakeAuthorize::Staker)?;
             let validated_split_info = validate_split_amount(
                 invoke_context,
-                transaction_context,
                 instruction_context,
                 stake_account_index,
                 split_index,
@@ -515,15 +499,12 @@ pub fn split(
             )?;
             let mut split_meta = meta;
             split_meta.rent_exempt_reserve = validated_split_info.destination_rent_exempt_reserve;
-            let mut split = instruction_context
-                .try_borrow_instruction_account(transaction_context, split_index)?;
+            let mut split = instruction_context.try_borrow_instruction_account(split_index)?;
             split.set_state(&StakeStateV2::Initialized(split_meta))?;
         }
         StakeStateV2::Uninitialized => {
-            let stake_pubkey = transaction_context.get_key_of_account_at_index(
-                instruction_context
-                    .get_index_of_instruction_account_in_transaction(stake_account_index)?,
-            )?;
+            let stake_pubkey =
+                instruction_context.get_key_of_instruction_account(stake_account_index)?;
             if !signers.contains(stake_pubkey) {
                 return Err(InstructionError::MissingRequiredSignature);
             }
@@ -532,26 +513,24 @@ pub fn split(
     }
 
     // Deinitialize state upon zero balance
-    let mut stake_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, stake_account_index)?;
+    let mut stake_account =
+        instruction_context.try_borrow_instruction_account(stake_account_index)?;
     if lamports == stake_account.get_lamports() {
         stake_account.set_state(&StakeStateV2::Uninitialized)?;
     }
     drop(stake_account);
 
-    let mut split =
-        instruction_context.try_borrow_instruction_account(transaction_context, split_index)?;
+    let mut split = instruction_context.try_borrow_instruction_account(split_index)?;
     split.checked_add_lamports(lamports)?;
     drop(split);
-    let mut stake_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, stake_account_index)?;
+    let mut stake_account =
+        instruction_context.try_borrow_instruction_account(stake_account_index)?;
     stake_account.checked_sub_lamports(lamports)?;
     Ok(())
 }
 
 pub fn merge(
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stake_account_index: IndexOfAccount,
     source_account_index: IndexOfAccount,
@@ -559,8 +538,8 @@ pub fn merge(
     stake_history: &StakeHistory,
     signers: &HashSet<Pubkey>,
 ) -> Result<(), InstructionError> {
-    let mut source_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, source_account_index)?;
+    let mut source_account =
+        instruction_context.try_borrow_instruction_account(source_account_index)?;
     // Ensure source isn't spoofed
     if *source_account.get_owner() != id() {
         return Err(InstructionError::IncorrectProgramId);
@@ -572,8 +551,8 @@ pub fn merge(
     {
         return Err(InstructionError::InvalidArgument);
     }
-    let mut stake_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, stake_account_index)?;
+    let mut stake_account =
+        instruction_context.try_borrow_instruction_account(stake_account_index)?;
 
     ic_msg!(invoke_context, "Checking if destination stake is mergeable");
     let stake_merge_kind = MergeKind::get_if_mergeable(
@@ -616,22 +595,20 @@ pub fn merge(
 
 pub fn move_stake(
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     source_account_index: IndexOfAccount,
     lamports: u64,
     destination_account_index: IndexOfAccount,
     stake_authority_index: IndexOfAccount,
 ) -> Result<(), InstructionError> {
-    let mut source_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, source_account_index)?;
+    let mut source_account =
+        instruction_context.try_borrow_instruction_account(source_account_index)?;
 
-    let mut destination_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, destination_account_index)?;
+    let mut destination_account =
+        instruction_context.try_borrow_instruction_account(destination_account_index)?;
 
     let (source_merge_kind, destination_merge_kind) = move_stake_or_lamports_shared_checks(
         invoke_context,
-        transaction_context,
         instruction_context,
         &source_account,
         lamports,
@@ -751,22 +728,20 @@ pub fn move_stake(
 
 pub fn move_lamports(
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     source_account_index: IndexOfAccount,
     lamports: u64,
     destination_account_index: IndexOfAccount,
     stake_authority_index: IndexOfAccount,
 ) -> Result<(), InstructionError> {
-    let mut source_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, source_account_index)?;
+    let mut source_account =
+        instruction_context.try_borrow_instruction_account(source_account_index)?;
 
-    let mut destination_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, destination_account_index)?;
+    let mut destination_account =
+        instruction_context.try_borrow_instruction_account(destination_account_index)?;
 
     let (source_merge_kind, _) = move_stake_or_lamports_shared_checks(
         invoke_context,
-        transaction_context,
         instruction_context,
         &source_account,
         lamports,
@@ -797,7 +772,6 @@ pub fn move_lamports(
 
 #[allow(clippy::too_many_arguments)]
 pub fn withdraw(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stake_account_index: IndexOfAccount,
     lamports: u64,
@@ -808,18 +782,16 @@ pub fn withdraw(
     custodian_index: Option<IndexOfAccount>,
     new_rate_activation_epoch: Option<Epoch>,
 ) -> Result<(), InstructionError> {
-    let withdraw_authority_pubkey = transaction_context.get_key_of_account_at_index(
-        instruction_context
-            .get_index_of_instruction_account_in_transaction(withdraw_authority_index)?,
-    )?;
+    let withdraw_authority_pubkey =
+        instruction_context.get_key_of_instruction_account(withdraw_authority_index)?;
     if !instruction_context.is_instruction_account_signer(withdraw_authority_index)? {
         return Err(InstructionError::MissingRequiredSignature);
     }
     let mut signers = HashSet::new();
     signers.insert(*withdraw_authority_pubkey);
 
-    let mut stake_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, stake_account_index)?;
+    let mut stake_account =
+        instruction_context.try_borrow_instruction_account(stake_account_index)?;
     let (lockup, reserve, is_staked) = match stake_account.get_state()? {
         StakeStateV2::Stake(meta, stake, _stake_flag) => {
             meta.authorized
@@ -858,12 +830,7 @@ pub fn withdraw(
     //   the custodian, both epoch and unix_timestamp must have passed
     let custodian_pubkey = if let Some(custodian_index) = custodian_index {
         if instruction_context.is_instruction_account_signer(custodian_index)? {
-            Some(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context
-                        .get_index_of_instruction_account_in_transaction(custodian_index)?,
-                )?,
-            )
+            Some(instruction_context.get_key_of_instruction_account(custodian_index)?)
         } else {
             None
         }
@@ -892,26 +859,22 @@ pub fn withdraw(
 
     stake_account.checked_sub_lamports(lamports)?;
     drop(stake_account);
-    let mut to =
-        instruction_context.try_borrow_instruction_account(transaction_context, to_index)?;
+    let mut to = instruction_context.try_borrow_instruction_account(to_index)?;
     to.checked_add_lamports(lamports)?;
     Ok(())
 }
 
 pub(crate) fn deactivate_delinquent(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     stake_account: &mut BorrowedAccount,
     delinquent_vote_account_index: IndexOfAccount,
     reference_vote_account_index: IndexOfAccount,
     current_epoch: Epoch,
 ) -> Result<(), InstructionError> {
-    let delinquent_vote_account_pubkey = transaction_context.get_key_of_account_at_index(
-        instruction_context
-            .get_index_of_instruction_account_in_transaction(delinquent_vote_account_index)?,
-    )?;
-    let delinquent_vote_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, delinquent_vote_account_index)?;
+    let delinquent_vote_account_pubkey =
+        instruction_context.get_key_of_instruction_account(delinquent_vote_account_index)?;
+    let delinquent_vote_account =
+        instruction_context.try_borrow_instruction_account(delinquent_vote_account_index)?;
     if *delinquent_vote_account.get_owner() != solana_sdk_ids::vote::id() {
         return Err(InstructionError::IncorrectProgramId);
     }
@@ -919,8 +882,8 @@ pub(crate) fn deactivate_delinquent(
         .get_state::<VoteStateVersions>()?
         .convert_to_current();
 
-    let reference_vote_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, reference_vote_account_index)?;
+    let reference_vote_account =
+        instruction_context.try_borrow_instruction_account(reference_vote_account_index)?;
     if *reference_vote_account.get_owner() != solana_sdk_ids::vote::id() {
         return Err(InstructionError::IncorrectProgramId);
     }
@@ -993,7 +956,6 @@ struct ValidatedSplitInfo {
 /// not, return an error.
 fn validate_split_amount(
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     source_account_index: IndexOfAccount,
     destination_account_index: IndexOfAccount,
@@ -1002,12 +964,12 @@ fn validate_split_amount(
     additional_required_lamports: u64,
     source_is_active: bool,
 ) -> Result<ValidatedSplitInfo, InstructionError> {
-    let source_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, source_account_index)?;
+    let source_account =
+        instruction_context.try_borrow_instruction_account(source_account_index)?;
     let source_lamports = source_account.get_lamports();
     drop(source_account);
-    let destination_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, destination_account_index)?;
+    let destination_account =
+        instruction_context.try_borrow_instruction_account(destination_account_index)?;
     let destination_lamports = destination_account.get_lamports();
     let destination_data_len = destination_account.get_data().len();
     drop(destination_account);

+ 58 - 75
programs/system/src/system_instruction.rs

@@ -10,9 +10,7 @@ use {
     solana_svm_log_collector::ic_msg,
     solana_system_interface::error::SystemError,
     solana_sysvar::rent::Rent,
-    solana_transaction_context::{
-        BorrowedAccount, IndexOfAccount, InstructionContext, TransactionContext,
-    },
+    solana_transaction_context::{BorrowedAccount, IndexOfAccount, InstructionContext},
     std::collections::HashSet,
 };
 
@@ -83,11 +81,9 @@ pub(crate) fn withdraw_nonce_account(
     rent: &Rent,
     signers: &HashSet<Pubkey>,
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
 ) -> Result<(), InstructionError> {
-    let mut from = instruction_context
-        .try_borrow_instruction_account(transaction_context, from_account_index)?;
+    let mut from = instruction_context.try_borrow_instruction_account(from_account_index)?;
     if !from.is_writable() {
         ic_msg!(
             invoke_context,
@@ -151,8 +147,7 @@ pub(crate) fn withdraw_nonce_account(
 
     from.checked_sub_lamports(lamports)?;
     drop(from);
-    let mut to = instruction_context
-        .try_borrow_instruction_account(transaction_context, to_account_index)?;
+    let mut to = instruction_context.try_borrow_instruction_account(to_account_index)?;
     to.checked_add_lamports(lamports)?;
 
     Ok(())
@@ -325,7 +320,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let data = nonce::state::Data {
             authority: *nonce_account.get_key(),
@@ -376,7 +371,7 @@ mod test {
 
         set_invoke_context_blockhash!(invoke_context, 0);
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let withdraw_lamports = nonce_account.get_lamports();
         let expect_nonce_lamports = nonce_account.get_lamports() - withdraw_lamports;
@@ -390,15 +385,14 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         )
         .unwrap();
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         // Empties Account balance
         assert_eq!(nonce_account.get_lamports(), expect_nonce_lamports);
@@ -419,7 +413,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         set_invoke_context_blockhash!(invoke_context, 31);
         let authority = *nonce_account.get_key();
@@ -450,7 +444,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -471,7 +465,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -490,10 +484,10 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let nonce_authority = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX + 1)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX + 1)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -517,10 +511,10 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let nonce_authority = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX + 1)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX + 1)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -541,10 +535,10 @@ mod test {
             instruction_accounts
         );
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -563,15 +557,14 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         )
         .unwrap();
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -589,10 +582,10 @@ mod test {
             instruction_accounts
         );
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -608,8 +601,7 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         );
         assert_eq!(result, Err(InstructionError::MissingRequiredSignature));
     }
@@ -624,7 +616,7 @@ mod test {
             instruction_accounts
         );
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -640,8 +632,7 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         );
         assert_eq!(result, Err(InstructionError::InsufficientFunds));
     }
@@ -656,10 +647,10 @@ mod test {
             instruction_accounts
         );
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -676,15 +667,14 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         )
         .unwrap();
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -702,15 +692,14 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         )
         .unwrap();
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -728,10 +717,10 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -759,15 +748,14 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         )
         .unwrap();
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         let data = nonce::state::Data::new(
@@ -793,15 +781,14 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         )
         .unwrap();
         let nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -819,10 +806,10 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let to_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(WITHDRAW_TO_ACCOUNT_INDEX)
             .unwrap();
         set_invoke_context_blockhash!(invoke_context, 0);
         let authorized = *nonce_account.get_key();
@@ -839,8 +826,7 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         );
         assert_eq!(result, Err(SystemError::NonceBlockhashNotExpired.into()));
     }
@@ -855,7 +841,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         set_invoke_context_blockhash!(invoke_context, 95);
         let authorized = *nonce_account.get_key();
@@ -872,8 +858,7 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         );
         assert_eq!(result, Err(InstructionError::InsufficientFunds));
     }
@@ -888,7 +873,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         set_invoke_context_blockhash!(invoke_context, 95);
         let authorized = *nonce_account.get_key();
@@ -905,8 +890,7 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         );
         assert_eq!(result, Err(InstructionError::InsufficientFunds));
     }
@@ -921,7 +905,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         set_invoke_context_blockhash!(invoke_context, 95);
         let authorized = *nonce_account.get_key();
@@ -938,8 +922,7 @@ mod test {
             &rent,
             &signers,
             &invoke_context,
-            transaction_context,
-            instruction_context,
+            &instruction_context,
         );
         assert_eq!(result, Err(InstructionError::InsufficientFunds));
     }
@@ -954,7 +937,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let versions = nonce_account.get_state::<Versions>().unwrap();
         assert_eq!(versions.state(), &State::Uninitialized);
@@ -986,7 +969,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         set_invoke_context_blockhash!(invoke_context, 31);
         let authorized = *nonce_account.get_key();
@@ -1007,7 +990,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         nonce_account.checked_sub_lamports(42 * 2).unwrap();
         set_invoke_context_blockhash!(invoke_context, 63);
@@ -1027,7 +1010,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -1057,7 +1040,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -1080,7 +1063,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(*nonce_account.get_key());
@@ -1102,7 +1085,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(nonce_account.get_key());
@@ -1157,7 +1140,7 @@ mod test {
             instruction_accounts
         );
         let mut nonce_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
+            .try_borrow_instruction_account(NONCE_ACCOUNT_INDEX)
             .unwrap();
         let mut signers = HashSet::new();
         signers.insert(nonce_account.get_key());

+ 35 - 87
programs/system/src/system_processor.rs

@@ -17,9 +17,7 @@ use {
     solana_system_interface::{
         error::SystemError, instruction::SystemInstruction, MAX_PERMITTED_DATA_LENGTH,
     },
-    solana_transaction_context::{
-        BorrowedAccount, IndexOfAccount, InstructionContext, TransactionContext,
-    },
+    solana_transaction_context::{BorrowedAccount, IndexOfAccount, InstructionContext},
     std::collections::HashSet,
 };
 
@@ -152,13 +150,11 @@ fn create_account(
     owner: &Pubkey,
     signers: &HashSet<Pubkey>,
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
 ) -> Result<(), InstructionError> {
     // if it looks like the `to` account is already in use, bail
     {
-        let mut to = instruction_context
-            .try_borrow_instruction_account(transaction_context, to_account_index)?;
+        let mut to = instruction_context.try_borrow_instruction_account(to_account_index)?;
         if to.get_lamports() > 0 {
             ic_msg!(
                 invoke_context,
@@ -175,7 +171,6 @@ fn create_account(
         to_account_index,
         lamports,
         invoke_context,
-        transaction_context,
         instruction_context,
     )
 }
@@ -185,11 +180,9 @@ fn transfer_verified(
     to_account_index: IndexOfAccount,
     lamports: u64,
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
 ) -> Result<(), InstructionError> {
-    let mut from = instruction_context
-        .try_borrow_instruction_account(transaction_context, from_account_index)?;
+    let mut from = instruction_context.try_borrow_instruction_account(from_account_index)?;
     if !from.get_data().is_empty() {
         ic_msg!(invoke_context, "Transfer: `from` must not carry data");
         return Err(InstructionError::InvalidArgument);
@@ -206,8 +199,7 @@ fn transfer_verified(
 
     from.checked_sub_lamports(lamports)?;
     drop(from);
-    let mut to = instruction_context
-        .try_borrow_instruction_account(transaction_context, to_account_index)?;
+    let mut to = instruction_context.try_borrow_instruction_account(to_account_index)?;
     to.checked_add_lamports(lamports)?;
     Ok(())
 }
@@ -217,17 +209,13 @@ fn transfer(
     to_account_index: IndexOfAccount,
     lamports: u64,
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
 ) -> Result<(), InstructionError> {
     if !instruction_context.is_instruction_account_signer(from_account_index)? {
         ic_msg!(
             invoke_context,
             "Transfer: `from` account {} must sign",
-            transaction_context.get_key_of_account_at_index(
-                instruction_context
-                    .get_index_of_instruction_account_in_transaction(from_account_index)?,
-            )?,
+            instruction_context.get_key_of_instruction_account(from_account_index)?,
         );
         return Err(InstructionError::MissingRequiredSignature);
     }
@@ -237,7 +225,6 @@ fn transfer(
         to_account_index,
         lamports,
         invoke_context,
-        transaction_context,
         instruction_context,
     )
 }
@@ -250,32 +237,23 @@ fn transfer_with_seed(
     to_account_index: IndexOfAccount,
     lamports: u64,
     invoke_context: &InvokeContext,
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
 ) -> Result<(), InstructionError> {
     if !instruction_context.is_instruction_account_signer(from_base_account_index)? {
         ic_msg!(
             invoke_context,
             "Transfer: 'from' account {:?} must sign",
-            transaction_context.get_key_of_account_at_index(
-                instruction_context
-                    .get_index_of_instruction_account_in_transaction(from_base_account_index)?,
-            )?,
+            instruction_context.get_key_of_instruction_account(from_base_account_index,)?,
         );
         return Err(InstructionError::MissingRequiredSignature);
     }
     let address_from_seed = Pubkey::create_with_seed(
-        transaction_context.get_key_of_account_at_index(
-            instruction_context
-                .get_index_of_instruction_account_in_transaction(from_base_account_index)?,
-        )?,
+        instruction_context.get_key_of_instruction_account(from_base_account_index)?,
         from_seed,
         from_owner,
     )?;
 
-    let from_key = transaction_context.get_key_of_account_at_index(
-        instruction_context.get_index_of_instruction_account_in_transaction(from_account_index)?,
-    )?;
+    let from_key = instruction_context.get_key_of_instruction_account(from_account_index)?;
     if *from_key != address_from_seed {
         ic_msg!(
             invoke_context,
@@ -291,7 +269,6 @@ fn transfer_with_seed(
         to_account_index,
         lamports,
         invoke_context,
-        transaction_context,
         instruction_context,
     )
 }
@@ -307,7 +284,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
 
     trace!("process_instruction: {instruction:?}");
 
-    let signers = instruction_context.get_signers(transaction_context)?;
+    let signers = instruction_context.get_signers()?;
     match instruction {
         SystemInstruction::CreateAccount {
             lamports,
@@ -316,9 +293,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         } => {
             instruction_context.check_number_of_instruction_accounts(2)?;
             let to_address = Address::create(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-                )?,
+                instruction_context.get_key_of_instruction_account(1)?,
                 None,
                 invoke_context,
             )?;
@@ -331,8 +306,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
                 &owner,
                 &signers,
                 invoke_context,
-                transaction_context,
-                instruction_context,
+                &instruction_context,
             )
         }
         SystemInstruction::CreateAccountWithSeed {
@@ -344,9 +318,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         } => {
             instruction_context.check_number_of_instruction_accounts(2)?;
             let to_address = Address::create(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-                )?,
+                instruction_context.get_key_of_instruction_account(1)?,
                 Some((&base, &seed, &owner)),
                 invoke_context,
             )?;
@@ -359,18 +331,14 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
                 &owner,
                 &signers,
                 invoke_context,
-                transaction_context,
-                instruction_context,
+                &instruction_context,
             )
         }
         SystemInstruction::Assign { owner } => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut account = instruction_context.try_borrow_instruction_account(0)?;
             let address = Address::create(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-                )?,
+                instruction_context.get_key_of_instruction_account(0)?,
                 None,
                 invoke_context,
             )?;
@@ -378,14 +346,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         SystemInstruction::Transfer { lamports } => {
             instruction_context.check_number_of_instruction_accounts(2)?;
-            transfer(
-                0,
-                1,
-                lamports,
-                invoke_context,
-                transaction_context,
-                instruction_context,
-            )
+            transfer(0, 1, lamports, invoke_context, &instruction_context)
         }
         SystemInstruction::TransferWithSeed {
             lamports,
@@ -401,18 +362,16 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
                 2,
                 lamports,
                 invoke_context,
-                transaction_context,
-                instruction_context,
+                &instruction_context,
             )
         }
         SystemInstruction::AdvanceNonceAccount => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut me =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut me = instruction_context.try_borrow_instruction_account(0)?;
             #[allow(deprecated)]
             let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
                 invoke_context,
-                instruction_context,
+                &instruction_context,
                 1,
             )?;
             if recent_blockhashes.is_empty() {
@@ -429,10 +388,11 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             #[allow(deprecated)]
             let _recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
                 invoke_context,
-                instruction_context,
+                &instruction_context,
                 2,
             )?;
-            let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 3)?;
+            let rent =
+                get_sysvar_with_account_check::rent(invoke_context, &instruction_context, 3)?;
             withdraw_nonce_account(
                 0,
                 lamports,
@@ -440,18 +400,16 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
                 &rent,
                 &signers,
                 invoke_context,
-                transaction_context,
-                instruction_context,
+                &instruction_context,
             )
         }
         SystemInstruction::InitializeNonceAccount(authorized) => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut me =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut me = instruction_context.try_borrow_instruction_account(0)?;
             #[allow(deprecated)]
             let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
                 invoke_context,
-                instruction_context,
+                &instruction_context,
                 1,
             )?;
             if recent_blockhashes.is_empty() {
@@ -461,19 +419,18 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
                 );
                 return Err(SystemError::NonceNoRecentBlockhashes.into());
             }
-            let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 2)?;
+            let rent =
+                get_sysvar_with_account_check::rent(invoke_context, &instruction_context, 2)?;
             initialize_nonce_account(&mut me, &authorized, &rent, invoke_context)
         }
         SystemInstruction::AuthorizeNonceAccount(nonce_authority) => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut me =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut me = instruction_context.try_borrow_instruction_account(0)?;
             authorize_nonce_account(&mut me, &nonce_authority, &signers, invoke_context)
         }
         SystemInstruction::UpgradeNonceAccount => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut nonce_account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut nonce_account = instruction_context.try_borrow_instruction_account(0)?;
             if !system_program::check_id(nonce_account.get_owner()) {
                 return Err(InstructionError::InvalidAccountOwner);
             }
@@ -488,12 +445,9 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         SystemInstruction::Allocate { space } => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut account = instruction_context.try_borrow_instruction_account(0)?;
             let address = Address::create(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-                )?,
+                instruction_context.get_key_of_instruction_account(0)?,
                 None,
                 invoke_context,
             )?;
@@ -506,12 +460,9 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             owner,
         } => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut account = instruction_context.try_borrow_instruction_account(0)?;
             let address = Address::create(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-                )?,
+                instruction_context.get_key_of_instruction_account(0)?,
                 Some((&base, &seed, &owner)),
                 invoke_context,
             )?;
@@ -526,12 +477,9 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         SystemInstruction::AssignWithSeed { base, seed, owner } => {
             instruction_context.check_number_of_instruction_accounts(1)?;
-            let mut account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+            let mut account = instruction_context.try_borrow_instruction_account(0)?;
             let address = Address::create(
-                transaction_context.get_key_of_account_at_index(
-                    instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-                )?,
+                instruction_context.get_key_of_instruction_account(0)?,
                 Some((&base, &seed, &owner)),
                 invoke_context,
             )?;

+ 21 - 29
programs/vote/src/vote_processor.rs

@@ -10,7 +10,7 @@ use {
         sysvar_cache::get_sysvar_with_account_check,
     },
     solana_pubkey::Pubkey,
-    solana_transaction_context::{BorrowedAccount, InstructionContext, TransactionContext},
+    solana_transaction_context::{BorrowedAccount, InstructionContext},
     solana_vote_interface::{instruction::VoteInstruction, program::id, state::VoteAuthorize},
     std::collections::HashSet,
 };
@@ -18,7 +18,6 @@ use {
 fn process_authorize_with_seed_instruction(
     invoke_context: &InvokeContext,
     instruction_context: &InstructionContext,
-    transaction_context: &TransactionContext,
     vote_account: &mut BorrowedAccount,
     new_authority: &Pubkey,
     authorization_type: VoteAuthorize,
@@ -28,9 +27,7 @@ fn process_authorize_with_seed_instruction(
     let clock = get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
     let mut expected_authority_keys: HashSet<Pubkey> = HashSet::default();
     if instruction_context.is_instruction_account_signer(2)? {
-        let base_pubkey = transaction_context.get_key_of_account_at_index(
-            instruction_context.get_index_of_instruction_account_in_transaction(2)?,
-        )?;
+        let base_pubkey = instruction_context.get_key_of_instruction_account(2)?;
         expected_authority_keys.insert(Pubkey::create_with_seed(
             base_pubkey,
             current_authority_derived_key_seed,
@@ -57,33 +54,33 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
 
     trace!("process_instruction: {data:?}");
 
-    let mut me = instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+    let mut me = instruction_context.try_borrow_instruction_account(0)?;
     if *me.get_owner() != id() {
         return Err(InstructionError::InvalidAccountOwner);
     }
 
-    let signers = instruction_context.get_signers(transaction_context)?;
+    let signers = instruction_context.get_signers()?;
     match limited_deserialize(data, solana_packet::PACKET_DATA_SIZE as u64)? {
         VoteInstruction::InitializeAccount(vote_init) => {
-            let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
+            let rent =
+                get_sysvar_with_account_check::rent(invoke_context, &instruction_context, 1)?;
             if !rent.is_exempt(me.get_lamports(), me.get_data().len()) {
                 return Err(InstructionError::InsufficientFunds);
             }
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 2)?;
             vote_state::initialize_account(&mut me, &vote_init, &signers, &clock)
         }
         VoteInstruction::Authorize(voter_pubkey, vote_authorize) => {
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 1)?;
             vote_state::authorize(&mut me, &voter_pubkey, vote_authorize, &signers, &clock)
         }
         VoteInstruction::AuthorizeWithSeed(args) => {
             instruction_context.check_number_of_instruction_accounts(3)?;
             process_authorize_with_seed_instruction(
                 invoke_context,
-                instruction_context,
-                transaction_context,
+                &instruction_context,
                 &mut me,
                 &args.new_authority,
                 args.authorization_type,
@@ -93,16 +90,13 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         VoteInstruction::AuthorizeCheckedWithSeed(args) => {
             instruction_context.check_number_of_instruction_accounts(4)?;
-            let new_authority = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(3)?,
-            )?;
+            let new_authority = instruction_context.get_key_of_instruction_account(3)?;
             if !instruction_context.is_instruction_account_signer(3)? {
                 return Err(InstructionError::MissingRequiredSignature);
             }
             process_authorize_with_seed_instruction(
                 invoke_context,
-                instruction_context,
-                transaction_context,
+                &instruction_context,
                 &mut me,
                 new_authority,
                 args.authorization_type,
@@ -112,9 +106,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         VoteInstruction::UpdateValidatorIdentity => {
             instruction_context.check_number_of_instruction_accounts(2)?;
-            let node_pubkey = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-            )?;
+            let node_pubkey = instruction_context.get_key_of_instruction_account(1)?;
             vote_state::update_validator_identity(&mut me, node_pubkey, &signers)
         }
         VoteInstruction::UpdateCommission(commission) => {
@@ -132,10 +124,13 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
             if invoke_context.is_deprecate_legacy_vote_ixs_active() {
                 return Err(InstructionError::InvalidInstructionData);
             }
-            let slot_hashes =
-                get_sysvar_with_account_check::slot_hashes(invoke_context, instruction_context, 1)?;
+            let slot_hashes = get_sysvar_with_account_check::slot_hashes(
+                invoke_context,
+                &instruction_context,
+                1,
+            )?;
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 2)?;
             vote_state::process_vote_with_account(&mut me, &slot_hashes, &clock, &vote, &signers)
         }
         VoteInstruction::UpdateVoteState(vote_state_update)
@@ -190,8 +185,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
 
             drop(me);
             vote_state::withdraw(
-                transaction_context,
-                instruction_context,
+                &instruction_context,
                 0,
                 lamports,
                 1,
@@ -202,14 +196,12 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context|
         }
         VoteInstruction::AuthorizeChecked(vote_authorize) => {
             instruction_context.check_number_of_instruction_accounts(4)?;
-            let voter_pubkey = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(3)?,
-            )?;
+            let voter_pubkey = instruction_context.get_key_of_instruction_account(3)?;
             if !instruction_context.is_instruction_account_signer(3)? {
                 return Err(InstructionError::MissingRequiredSignature);
             }
             let clock =
-                get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
+                get_sysvar_with_account_check::clock(invoke_context, &instruction_context, 1)?;
             vote_state::authorize(&mut me, voter_pubkey, vote_authorize, &signers, &clock)
         }
     }

+ 8 - 12
programs/vote/src/vote_state/mod.rs

@@ -11,9 +11,7 @@ use {
     solana_pubkey::Pubkey,
     solana_rent::Rent,
     solana_slot_hashes::SlotHash,
-    solana_transaction_context::{
-        BorrowedAccount, IndexOfAccount, InstructionContext, TransactionContext,
-    },
+    solana_transaction_context::{BorrowedAccount, IndexOfAccount, InstructionContext},
     solana_vote_interface::{error::VoteError, program::id},
     std::{
         cmp::Ordering,
@@ -811,7 +809,6 @@ fn verify_authorized_signer<S: std::hash::BuildHasher>(
 
 /// Withdraw funds from the vote account
 pub fn withdraw<S: std::hash::BuildHasher>(
-    transaction_context: &TransactionContext,
     instruction_context: &InstructionContext,
     vote_account_index: IndexOfAccount,
     lamports: u64,
@@ -820,8 +817,8 @@ pub fn withdraw<S: std::hash::BuildHasher>(
     rent_sysvar: &Rent,
     clock: &Clock,
 ) -> Result<(), InstructionError> {
-    let mut vote_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, vote_account_index)?;
+    let mut vote_account =
+        instruction_context.try_borrow_instruction_account(vote_account_index)?;
     let vote_state: VoteState = vote_account
         .get_state::<VoteStateVersions>()?
         .convert_to_current();
@@ -861,8 +858,7 @@ pub fn withdraw<S: std::hash::BuildHasher>(
 
     vote_account.checked_sub_lamports(lamports)?;
     drop(vote_account);
-    let mut to_account = instruction_context
-        .try_borrow_instruction_account(transaction_context, to_account_index)?;
+    let mut to_account = instruction_context.try_borrow_instruction_account(to_account_index)?;
     to_account.checked_add_lamports(lamports)?;
     Ok(())
 }
@@ -1072,7 +1068,7 @@ mod tests {
         solana_account::{state_traits::StateMut, AccountSharedData},
         solana_clock::DEFAULT_SLOTS_PER_EPOCH,
         solana_sha256_hasher::hash,
-        solana_transaction_context::InstructionAccount,
+        solana_transaction_context::{InstructionAccount, TransactionContext},
         std::cell::RefCell,
         test_case::test_case,
     };
@@ -1178,7 +1174,7 @@ mod tests {
         // Get the BorrowedAccount from the InstructionContext which is what is used to manipulate and inspect account
         // state
         let mut borrowed_account = instruction_context
-            .try_borrow_instruction_account(&transaction_context, 0)
+            .try_borrow_instruction_account(0)
             .unwrap();
 
         // Ensure that the vote state started out at 1_14_11
@@ -1230,7 +1226,7 @@ mod tests {
         // Test that when the feature is enabled, if the vote account does have sufficient lamports, the
         // new vote state is written out
         assert_eq!(
-            borrowed_account.set_lamports(rent.minimum_balance(VoteState::size_of()),),
+            borrowed_account.set_lamports(rent.minimum_balance(VoteState::size_of())),
             Ok(())
         );
         assert_eq!(
@@ -1329,7 +1325,7 @@ mod tests {
         // Get the BorrowedAccount from the InstructionContext which is what is used to manipulate and inspect account
         // state
         let mut borrowed_account = instruction_context
-            .try_borrow_instruction_account(&transaction_context, 0)
+            .try_borrow_instruction_account(0)
             .unwrap();
 
         let epoch_schedule = std::sync::Arc::new(EpochSchedule::without_warmup());

+ 10 - 17
programs/zk-elgamal-proof/src/lib.rs

@@ -45,8 +45,8 @@ where
 
     // if instruction data is exactly 5 bytes, then read proof from an account
     let context_data = if instruction_data.len() == INSTRUCTION_DATA_LENGTH_WITH_PROOF_ACCOUNT {
-        let proof_data_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, accessed_accounts)?;
+        let proof_data_account =
+            instruction_context.try_borrow_instruction_account(accessed_accounts)?;
         accessed_accounts = accessed_accounts.checked_add(1).unwrap();
 
         let proof_data_offset = u32::from_le_bytes(
@@ -93,14 +93,11 @@ where
     // create context state if additional accounts are provided with the instruction
     if instruction_context.get_number_of_instruction_accounts() > accessed_accounts {
         let context_state_authority = *instruction_context
-            .try_borrow_instruction_account(
-                transaction_context,
-                accessed_accounts.checked_add(1).unwrap(),
-            )?
+            .try_borrow_instruction_account(accessed_accounts.checked_add(1).unwrap())?
             .get_key();
 
-        let mut proof_context_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, accessed_accounts)?;
+        let mut proof_context_account =
+            instruction_context.try_borrow_instruction_account(accessed_accounts)?;
 
         if *proof_context_account.get_owner() != id() {
             return Err(InstructionError::InvalidAccountOwner);
@@ -135,19 +132,16 @@ fn process_close_proof_context(invoke_context: &mut InvokeContext) -> Result<(),
             return Err(InstructionError::MissingRequiredSignature);
         }
 
-        *instruction_context.get_key_of_instruction_account(2, transaction_context)?
+        *instruction_context.get_key_of_instruction_account(2)?
     };
 
-    let proof_context_account_pubkey =
-        *instruction_context.get_key_of_instruction_account(0, transaction_context)?;
-    let destination_account_pubkey =
-        *instruction_context.get_key_of_instruction_account(1, transaction_context)?;
+    let proof_context_account_pubkey = *instruction_context.get_key_of_instruction_account(0)?;
+    let destination_account_pubkey = *instruction_context.get_key_of_instruction_account(1)?;
     if proof_context_account_pubkey == destination_account_pubkey {
         return Err(InstructionError::InvalidInstructionData);
     }
 
-    let mut proof_context_account =
-        instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+    let mut proof_context_account = instruction_context.try_borrow_instruction_account(0)?;
     let proof_context_state_meta =
         ProofContextStateMeta::try_from_bytes(proof_context_account.get_data())?;
     let expected_owner_pubkey = proof_context_state_meta.context_state_authority;
@@ -156,8 +150,7 @@ fn process_close_proof_context(invoke_context: &mut InvokeContext) -> Result<(),
         return Err(InstructionError::InvalidAccountOwner);
     }
 
-    let mut destination_account =
-        instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
+    let mut destination_account = instruction_context.try_borrow_instruction_account(1)?;
     destination_account.checked_add_lamports(proof_context_account.get_lamports())?;
     proof_context_account.set_lamports(0)?;
     proof_context_account.set_data_length(0)?;

+ 11 - 17
programs/zk-token-proof/src/lib.rs

@@ -55,8 +55,8 @@ where
             return Err(InstructionError::InvalidInstructionData);
         }
 
-        let proof_data_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, accessed_accounts)?;
+        let proof_data_account =
+            instruction_context.try_borrow_instruction_account(accessed_accounts)?;
         accessed_accounts = accessed_accounts.checked_add(1).unwrap();
 
         let proof_data_offset = u32::from_le_bytes(
@@ -102,12 +102,10 @@ where
 
     // create context state if additional accounts are provided with the instruction
     if instruction_context.get_number_of_instruction_accounts() > accessed_accounts {
-        let context_state_authority = *instruction_context.get_key_of_instruction_account(
-            accessed_accounts.checked_add(1).unwrap(),
-            transaction_context,
-        )?;
-        let mut proof_context_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, accessed_accounts)?;
+        let context_state_authority = *instruction_context
+            .get_key_of_instruction_account(accessed_accounts.checked_add(1).unwrap())?;
+        let mut proof_context_account =
+            instruction_context.try_borrow_instruction_account(accessed_accounts)?;
 
         if *proof_context_account.get_owner() != id() {
             return Err(InstructionError::InvalidAccountOwner);
@@ -142,19 +140,16 @@ fn process_close_proof_context(invoke_context: &mut InvokeContext) -> Result<(),
             return Err(InstructionError::MissingRequiredSignature);
         }
 
-        *instruction_context.get_program_key(transaction_context)?
+        *instruction_context.get_program_key()?
     };
 
-    let proof_context_account_pubkey =
-        *instruction_context.get_key_of_instruction_account(0, transaction_context)?;
-    let destination_account_pubkey =
-        *instruction_context.get_key_of_instruction_account(1, transaction_context)?;
+    let proof_context_account_pubkey = *instruction_context.get_key_of_instruction_account(0)?;
+    let destination_account_pubkey = *instruction_context.get_key_of_instruction_account(1)?;
     if proof_context_account_pubkey == destination_account_pubkey {
         return Err(InstructionError::InvalidInstructionData);
     }
 
-    let mut proof_context_account =
-        instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
+    let mut proof_context_account = instruction_context.try_borrow_instruction_account(0)?;
     let proof_context_state_meta =
         ProofContextStateMeta::try_from_bytes(proof_context_account.get_data())?;
     let expected_owner_pubkey = proof_context_state_meta.context_state_authority;
@@ -163,8 +158,7 @@ fn process_close_proof_context(invoke_context: &mut InvokeContext) -> Result<(),
         return Err(InstructionError::InvalidAccountOwner);
     }
 
-    let mut destination_account =
-        instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
+    let mut destination_account = instruction_context.try_borrow_instruction_account(1)?;
     destination_account.checked_add_lamports(proof_context_account.get_lamports())?;
     proof_context_account.set_lamports(0)?;
     proof_context_account.set_data_length(0)?;

+ 3 - 9
rpc/src/rpc.rs

@@ -4649,15 +4649,9 @@ pub mod tests {
         ic_logger_msg!(log_collector, "I am logging from a builtin program!");
         ic_logger_msg!(log_collector, "I am about to CPI to System!");
 
-        let from_pubkey = *transaction_context.get_key_of_account_at_index(
-            instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-        )?;
-        let to_pubkey = *transaction_context.get_key_of_account_at_index(
-            instruction_context.get_index_of_instruction_account_in_transaction(1)?,
-        )?;
-        let owner_pubkey = *transaction_context.get_key_of_account_at_index(
-            instruction_context.get_index_of_instruction_account_in_transaction(2)?,
-        )?;
+        let from_pubkey = *instruction_context.get_key_of_instruction_account(0)?;
+        let to_pubkey = *instruction_context.get_key_of_instruction_account(1)?;
+        let owner_pubkey = *instruction_context.get_key_of_instruction_account(2)?;
 
         invoke_context.native_invoke(
             system_instruction::create_account(

+ 1 - 3
runtime/src/bank/builtin_programs.rs

@@ -102,9 +102,7 @@ mod tests_core_bpf_migration {
             let transaction_context = &invoke_context.transaction_context;
             let instruction_context = transaction_context.get_current_instruction_context()?;
 
-            let target_program_id = transaction_context.get_key_of_account_at_index(
-                instruction_context.get_index_of_instruction_account_in_transaction(0)?,
-            )?;
+            let target_program_id = instruction_context.get_key_of_instruction_account(0)?;
 
             let instruction = Instruction::new_with_bytes(*target_program_id, &[], Vec::new());
 

+ 14 - 14
runtime/src/bank/tests.rs

@@ -3409,7 +3409,7 @@ fn test_add_builtin() {
     declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
         let transaction_context = &invoke_context.transaction_context;
         let instruction_context = transaction_context.get_current_instruction_context()?;
-        let program_id = instruction_context.get_program_key(transaction_context)?;
+        let program_id = instruction_context.get_program_key()?;
         if mock_vote_program_id() != *program_id {
             return Err(InstructionError::IncorrectProgramId);
         }
@@ -4683,16 +4683,16 @@ fn test_transaction_with_duplicate_accounts_in_instruction() {
         let instruction_data = instruction_context.get_instruction_data();
         let lamports = u64::from_le_bytes(instruction_data.try_into().unwrap());
         instruction_context
-            .try_borrow_instruction_account(transaction_context, 2)?
+            .try_borrow_instruction_account(2)?
             .checked_sub_lamports(lamports)?;
         instruction_context
-            .try_borrow_instruction_account(transaction_context, 1)?
+            .try_borrow_instruction_account(1)?
             .checked_add_lamports(lamports)?;
         instruction_context
-            .try_borrow_instruction_account(transaction_context, 0)?
+            .try_borrow_instruction_account(0)?
             .checked_sub_lamports(lamports)?;
         instruction_context
-            .try_borrow_instruction_account(transaction_context, 1)?
+            .try_borrow_instruction_account(1)?
             .checked_add_lamports(lamports)?;
         Ok(())
     });
@@ -8548,7 +8548,7 @@ fn test_transfer_sysvar() {
         let transaction_context = &invoke_context.transaction_context;
         let instruction_context = transaction_context.get_current_instruction_context()?;
         instruction_context
-            .try_borrow_instruction_account(transaction_context, 1)?
+            .try_borrow_instruction_account(1)?
             .set_data_from_slice(&[0; 40])?;
         Ok(())
     });
@@ -9462,10 +9462,10 @@ declare_process_instruction!(MockTransferBuiltin, 1, |invoke_context| {
         match instruction {
             MockTransferInstruction::Transfer(amount) => {
                 instruction_context
-                    .try_borrow_instruction_account(transaction_context, 1)?
+                    .try_borrow_instruction_account(1)?
                     .checked_sub_lamports(amount)?;
                 instruction_context
-                    .try_borrow_instruction_account(transaction_context, 2)?
+                    .try_borrow_instruction_account(2)?
                     .checked_add_lamports(amount)?;
                 Ok(())
             }
@@ -10139,28 +10139,28 @@ declare_process_instruction!(MockReallocBuiltin, 1, |invoke_context| {
             MockReallocInstruction::Realloc(new_size, new_balance, _) => {
                 // Set data length
                 instruction_context
-                    .try_borrow_instruction_account(transaction_context, 1)?
+                    .try_borrow_instruction_account(1)?
                     .set_data_length(new_size)?;
 
                 // set balance
                 let current_balance = instruction_context
-                    .try_borrow_instruction_account(transaction_context, 1)?
+                    .try_borrow_instruction_account(1)?
                     .get_lamports();
                 let diff_balance = (new_balance as i64).saturating_sub(current_balance as i64);
                 let amount = diff_balance.unsigned_abs();
                 if diff_balance.is_positive() {
                     instruction_context
-                        .try_borrow_instruction_account(transaction_context, 0)?
+                        .try_borrow_instruction_account(0)?
                         .checked_sub_lamports(amount)?;
                     instruction_context
-                        .try_borrow_instruction_account(transaction_context, 1)?
+                        .try_borrow_instruction_account(1)?
                         .set_lamports(new_balance)?;
                 } else {
                     instruction_context
-                        .try_borrow_instruction_account(transaction_context, 0)?
+                        .try_borrow_instruction_account(0)?
                         .checked_add_lamports(amount)?;
                     instruction_context
-                        .try_borrow_instruction_account(transaction_context, 1)?
+                        .try_borrow_instruction_account(1)?
                         .set_lamports(new_balance)?;
                 }
                 Ok(())

+ 12 - 15
svm/src/message_processor.rs

@@ -147,16 +147,16 @@ mod tests {
                     MockSystemInstruction::Correct => Ok(()),
                     MockSystemInstruction::TransferLamports { lamports } => {
                         instruction_context
-                            .try_borrow_instruction_account(transaction_context, 0)?
+                            .try_borrow_instruction_account(0)?
                             .checked_sub_lamports(lamports)?;
                         instruction_context
-                            .try_borrow_instruction_account(transaction_context, 1)?
+                            .try_borrow_instruction_account(1)?
                             .checked_add_lamports(lamports)?;
                         Ok(())
                     }
                     MockSystemInstruction::ChangeData { data } => {
                         instruction_context
-                            .try_borrow_instruction_account(transaction_context, 1)?
+                            .try_borrow_instruction_account(1)?
                             .set_data_from_slice(&[data])?;
                         Ok(())
                     }
@@ -361,15 +361,12 @@ mod tests {
             let transaction_context = &invoke_context.transaction_context;
             let instruction_context = transaction_context.get_current_instruction_context()?;
             let instruction_data = instruction_context.get_instruction_data();
-            let mut to_account =
-                instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
+            let mut to_account = instruction_context.try_borrow_instruction_account(1)?;
             if let Ok(instruction) = bincode::deserialize(instruction_data) {
                 match instruction {
                     MockSystemInstruction::BorrowFail => {
-                        let from_account = instruction_context
-                            .try_borrow_instruction_account(transaction_context, 0)?;
-                        let dup_account = instruction_context
-                            .try_borrow_instruction_account(transaction_context, 2)?;
+                        let from_account = instruction_context.try_borrow_instruction_account(0)?;
+                        let dup_account = instruction_context.try_borrow_instruction_account(2)?;
                         if from_account.get_lamports() != dup_account.get_lamports() {
                             return Err(InstructionError::InvalidArgument);
                         }
@@ -377,10 +374,10 @@ mod tests {
                     }
                     MockSystemInstruction::MultiBorrowMut => {
                         let lamports_a = instruction_context
-                            .try_borrow_instruction_account(transaction_context, 0)?
+                            .try_borrow_instruction_account(0)?
                             .get_lamports();
                         let lamports_b = instruction_context
-                            .try_borrow_instruction_account(transaction_context, 2)?
+                            .try_borrow_instruction_account(2)?
                             .get_lamports();
                         if lamports_a != lamports_b {
                             return Err(InstructionError::InvalidArgument);
@@ -388,14 +385,14 @@ mod tests {
                         Ok(())
                     }
                     MockSystemInstruction::DoWork { lamports, data } => {
-                        let mut dup_account = instruction_context
-                            .try_borrow_instruction_account(transaction_context, 2)?;
+                        let mut dup_account =
+                            instruction_context.try_borrow_instruction_account(2)?;
                         dup_account.checked_sub_lamports(lamports)?;
                         to_account.checked_add_lamports(lamports)?;
                         dup_account.set_data_from_slice(&[data])?;
                         drop(dup_account);
-                        let mut from_account = instruction_context
-                            .try_borrow_instruction_account(transaction_context, 0)?;
+                        let mut from_account =
+                            instruction_context.try_borrow_instruction_account(0)?;
                         from_account.checked_sub_lamports(lamports)?;
                         to_account.checked_add_lamports(lamports)?;
                         Ok(())

+ 2 - 2
svm/src/transaction_processor.rs

@@ -1276,10 +1276,10 @@ mod tests {
             instruction_trace.len(),
         );
         for (index_in_trace, stack_height) in instruction_trace.into_iter().enumerate() {
-            while stack_height <= transaction_context.get_instruction_context_stack_height() {
+            while stack_height <= transaction_context.get_instruction_stack_height() {
                 transaction_context.pop().unwrap();
             }
-            if stack_height > transaction_context.get_instruction_context_stack_height() {
+            if stack_height > transaction_context.get_instruction_stack_height() {
                 transaction_context
                     .configure_next_instruction_for_tests(0, vec![], &[index_in_trace as u8])
                     .unwrap();

+ 35 - 31
syscalls/src/cpi.rs

@@ -814,8 +814,7 @@ where
 
         let index_in_caller = instruction_context
             .get_index_of_account_in_instruction(instruction_account.index_in_transaction)?;
-        let callee_account = instruction_context
-            .try_borrow_instruction_account(transaction_context, index_in_caller)?;
+        let callee_account = instruction_context.try_borrow_instruction_account(index_in_caller)?;
         let account_key = invoke_context
             .transaction_context
             .get_key_of_account_at_index(instruction_account.index_in_transaction)?;
@@ -995,7 +994,7 @@ fn cpi_common<S: SyscallInvokeSigned>(
     )?;
     let transaction_context = &invoke_context.transaction_context;
     let instruction_context = transaction_context.get_current_instruction_context()?;
-    let caller_program_id = instruction_context.get_program_key(transaction_context)?;
+    let caller_program_id = instruction_context.get_program_key()?;
     let signers = S::translate_signers(
         caller_program_id,
         signers_seeds_addr,
@@ -1031,10 +1030,8 @@ fn cpi_common<S: SyscallInvokeSigned>(
         .stricter_abi_and_runtime_constraints;
 
     for translate_account in accounts.iter_mut() {
-        let mut callee_account = instruction_context.try_borrow_instruction_account(
-            transaction_context,
-            translate_account.index_in_caller,
-        )?;
+        let mut callee_account = instruction_context
+            .try_borrow_instruction_account(translate_account.index_in_caller)?;
         if translate_account.update_caller_account_info {
             update_caller_account(
                 invoke_context,
@@ -1049,10 +1046,8 @@ fn cpi_common<S: SyscallInvokeSigned>(
 
     if stricter_abi_and_runtime_constraints {
         for translate_account in accounts.iter() {
-            let mut callee_account = instruction_context.try_borrow_instruction_account(
-                transaction_context,
-                translate_account.index_in_caller,
-            )?;
+            let mut callee_account = instruction_context
+                .try_borrow_instruction_account(translate_account.index_in_caller)?;
             if translate_account.update_caller_account_region {
                 update_caller_account_region(
                     memory_mapping,
@@ -1344,15 +1339,15 @@ mod tests {
     }
 
     macro_rules! borrow_instruction_account {
-        ($invoke_context:expr, $index:expr) => {{
+        ($borrowed_account:ident, $invoke_context:expr, $index:expr) => {
             let instruction_context = $invoke_context
                 .transaction_context
                 .get_current_instruction_context()
                 .unwrap();
-            instruction_context
-                .try_borrow_instruction_account($invoke_context.transaction_context, $index)
-                .unwrap()
-        }};
+            let $borrowed_account = instruction_context
+                .try_borrow_instruction_account($index)
+                .unwrap();
+        };
     }
 
     #[test]
@@ -1511,9 +1506,13 @@ mod tests {
         .unwrap();
 
         let mut caller_account = mock_caller_account.caller_account();
-
-        let mut callee_account = borrow_instruction_account!(invoke_context, 0);
-
+        let instruction_context = invoke_context
+            .transaction_context
+            .get_current_instruction_context()
+            .unwrap();
+        let mut callee_account = instruction_context
+            .try_borrow_instruction_account(0)
+            .unwrap();
         callee_account.set_lamports(42).unwrap();
         callee_account
             .set_owner(Pubkey::new_unique().as_ref())
@@ -1571,8 +1570,13 @@ mod tests {
         };
         let serialized_len = || unsafe { *len_ptr.cast::<u64>() as usize };
         let mut caller_account = mock_caller_account.caller_account();
-
-        let mut callee_account = borrow_instruction_account!(invoke_context, 0);
+        let instruction_context = invoke_context
+            .transaction_context
+            .get_current_instruction_context()
+            .unwrap();
+        let mut callee_account = instruction_context
+            .try_borrow_instruction_account(0)
+            .unwrap();
 
         for (new_value, expected_realloc_size) in [
             (b"foo".to_vec(), MAX_PERMITTED_DATA_INCREASE + 3),
@@ -1672,7 +1676,7 @@ mod tests {
 
         let caller_account = mock_caller_account.caller_account();
 
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
 
         *caller_account.lamports = 42;
         *caller_account.owner = Pubkey::new_unique();
@@ -1686,7 +1690,7 @@ mod tests {
         )
         .unwrap();
 
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
         assert_eq!(callee_account.get_lamports(), 42);
         assert_eq!(caller_account.owner, callee_account.get_owner());
     }
@@ -1710,7 +1714,7 @@ mod tests {
             MockCallerAccount::new(1234, *account.owner(), account.data(), false);
 
         let mut caller_account = mock_caller_account.caller_account();
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
 
         // stricter_abi_and_runtime_constraints does not copy data in update_callee_account()
         caller_account.serialized_data[0] = b'b';
@@ -1722,7 +1726,7 @@ mod tests {
             false, // account_data_direct_mapping
         )
         .unwrap();
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
         assert_eq!(callee_account.get_data(), b"boobar");
 
         // growing resize
@@ -1745,7 +1749,7 @@ mod tests {
         let mut data = b"baz".to_vec();
         *caller_account.ref_to_len_in_vm = data.len() as u64;
         caller_account.serialized_data = &mut data;
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
         assert_eq!(
             update_callee_account(
                 true, // check_aligned
@@ -1764,7 +1768,7 @@ mod tests {
         *caller_account.ref_to_len_in_vm = 0;
         let mut owner = system_program::id();
         caller_account.owner = &mut owner;
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
         update_callee_account(
             true, // check_aligned
             &caller_account,
@@ -1773,7 +1777,7 @@ mod tests {
             true, // account_data_direct_mapping
         )
         .unwrap();
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
         assert_eq!(callee_account.get_data(), b"");
 
         // growing beyond address_space_reserved_for_account
@@ -1813,7 +1817,7 @@ mod tests {
         let mut mock_caller_account =
             MockCallerAccount::new(1234, *account.owner(), account.data(), false);
         let mut caller_account = mock_caller_account.caller_account();
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
 
         // stricter_abi_and_runtime_constraints does not copy data in update_callee_account()
         caller_account.serialized_data[0] = b'b';
@@ -1832,7 +1836,7 @@ mod tests {
         let mut data = b"foobarbaz".to_vec();
         *caller_account.ref_to_len_in_vm = data.len() as u64;
         caller_account.serialized_data = &mut data;
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
         assert_matches!(
             update_callee_account(
                 true, // check_aligned
@@ -1848,7 +1852,7 @@ mod tests {
         let mut data = b"baz".to_vec();
         *caller_account.ref_to_len_in_vm = data.len() as u64;
         caller_account.serialized_data = &mut data;
-        let callee_account = borrow_instruction_account!(invoke_context, 0);
+        borrow_instruction_account!(callee_account, invoke_context, 0);
         assert_matches!(
             update_callee_account(
                 true, // check_aligned

+ 5 - 12
syscalls/src/lib.rs

@@ -1461,7 +1461,7 @@ declare_builtin_function!(
         let program_id = *transaction_context
             .get_current_instruction_context()
             .and_then(|instruction_context| {
-                instruction_context.get_program_key(transaction_context)
+                instruction_context.get_program_key()
             })?;
 
         transaction_context.set_return_data(program_id, return_data)?;
@@ -1581,19 +1581,12 @@ declare_builtin_function!(
                 let _ = result_header;
 
                 *program_id = *instruction_context
-                    .get_program_key(invoke_context.transaction_context)?;
+                    .get_program_key()?;
                 data.clone_from_slice(instruction_context.get_instruction_data());
                 let account_metas = (0..instruction_context.get_number_of_instruction_accounts())
                     .map(|instruction_account_index| {
                         Ok(AccountMeta {
-                            pubkey: *invoke_context
-                                .transaction_context
-                                .get_key_of_account_at_index(
-                                    instruction_context
-                                        .get_index_of_instruction_account_in_transaction(
-                                            instruction_account_index,
-                                        )?,
-                                )?,
+                            pubkey: *instruction_context.get_key_of_instruction_account(instruction_account_index)?,
                             is_signer: instruction_context
                                 .is_instruction_account_signer(instruction_account_index)?,
                             is_writable: instruction_context
@@ -4435,14 +4428,14 @@ mod tests {
             while stack_height
                 <= invoke_context
                     .transaction_context
-                    .get_instruction_context_stack_height()
+                    .get_instruction_stack_height()
             {
                 invoke_context.transaction_context.pop().unwrap();
             }
             if stack_height
                 > invoke_context
                     .transaction_context
-                    .get_instruction_context_stack_height()
+                    .get_instruction_stack_height()
             {
                 let instruction_accounts = vec![InstructionAccount::new(
                     index_in_trace.saturating_add(1) as IndexOfAccount,

+ 85 - 71
transaction-context/src/lib.rs

@@ -53,7 +53,7 @@ static_assertions::const_assert_eq!(
     solana_account_info::MAX_PERMITTED_DATA_INCREASE,
 );
 
-/// Index of an account inside of the TransactionContext or an InstructionContext.
+/// Index of an account inside of the transaction or an instruction.
 pub type IndexOfAccount = u16;
 
 /// Contains account meta data which varies between instruction.
@@ -215,7 +215,7 @@ pub struct TransactionContext {
     instruction_stack_capacity: usize,
     instruction_trace_capacity: usize,
     instruction_stack: Vec<usize>,
-    instruction_trace: Vec<InstructionContext>,
+    instruction_trace: Vec<InstructionFrame>,
     top_level_instruction_index: usize,
     return_data: TransactionReturnData,
     #[cfg(not(target_os = "solana"))]
@@ -241,7 +241,7 @@ impl TransactionContext {
             instruction_stack_capacity,
             instruction_trace_capacity,
             instruction_stack: Vec::with_capacity(instruction_stack_capacity),
-            instruction_trace: vec![InstructionContext::default()],
+            instruction_trace: vec![InstructionFrame::default()],
             top_level_instruction_index: 0,
             return_data: TransactionReturnData::default(),
             rent,
@@ -291,34 +291,43 @@ impl TransactionContext {
             .map(|index| index as IndexOfAccount)
     }
 
-    /// Gets the max length of the InstructionContext trace
+    /// Gets the max length of the instruction trace
     pub fn get_instruction_trace_capacity(&self) -> usize {
         self.instruction_trace_capacity
     }
 
     /// Returns the instruction trace length.
     ///
-    /// Not counting the last empty InstructionContext which is always pre-reserved for the next instruction.
+    /// Not counting the last empty instruction which is always pre-reserved for the next instruction.
     /// See also `get_next_instruction_context()`.
     pub fn get_instruction_trace_length(&self) -> usize {
         self.instruction_trace.len().saturating_sub(1)
     }
 
-    /// Gets an InstructionContext by its index in the trace
+    /// Gets a view on an instruction by its index in the trace
     pub fn get_instruction_context_at_index_in_trace(
         &self,
         index_in_trace: usize,
-    ) -> Result<&InstructionContext, InstructionError> {
-        self.instruction_trace
+    ) -> Result<InstructionContext, InstructionError> {
+        let instruction = self
+            .instruction_trace
             .get(index_in_trace)
-            .ok_or(InstructionError::CallDepth)
+            .ok_or(InstructionError::CallDepth)?;
+        Ok(InstructionContext {
+            transaction_context: self,
+            nesting_level: instruction.nesting_level,
+            program_account_index_in_tx: instruction.program_account_index_in_tx,
+            instruction_accounts: &instruction.instruction_accounts,
+            dedup_map: &instruction.dedup_map,
+            instruction_data: &instruction.instruction_data,
+        })
     }
 
-    /// Gets an InstructionContext by its nesting level in the stack
+    /// Gets a view on the instruction by its nesting level in the stack
     pub fn get_instruction_context_at_nesting_level(
         &self,
         nesting_level: usize,
-    ) -> Result<&InstructionContext, InstructionError> {
+    ) -> Result<InstructionContext, InstructionError> {
         let index_in_trace = *self
             .instruction_stack
             .get(nesting_level)
@@ -328,26 +337,38 @@ impl TransactionContext {
         Ok(instruction_context)
     }
 
-    /// Gets the max height of the InstructionContext stack
+    /// Gets the max height of the instruction stack
     pub fn get_instruction_stack_capacity(&self) -> usize {
         self.instruction_stack_capacity
     }
 
     /// Gets instruction stack height, top-level instructions are height
     /// `solana_instruction::TRANSACTION_LEVEL_STACK_HEIGHT`
-    pub fn get_instruction_context_stack_height(&self) -> usize {
+    pub fn get_instruction_stack_height(&self) -> usize {
         self.instruction_stack.len()
     }
 
-    /// Returns the current InstructionContext
-    pub fn get_current_instruction_context(&self) -> Result<&InstructionContext, InstructionError> {
+    /// Returns a view on the current instruction
+    pub fn get_current_instruction_context(&self) -> Result<InstructionContext, InstructionError> {
         let level = self
-            .get_instruction_context_stack_height()
+            .get_instruction_stack_height()
             .checked_sub(1)
             .ok_or(InstructionError::CallDepth)?;
         self.get_instruction_context_at_nesting_level(level)
     }
 
+    /// Returns a view on the next instruction. This function assumes it has already been
+    /// configured with the correct values in `prepare_next_instruction` or
+    /// `prepare_next_top_level_instruction`
+    pub fn get_next_instruction_context(&self) -> Result<InstructionContext, InstructionError> {
+        let index_in_trace = self
+            .instruction_trace
+            .len()
+            .checked_sub(1)
+            .ok_or(InstructionError::CallDepth)?;
+        self.get_instruction_context_at_index_in_trace(index_in_trace)
+    }
+
     /// Configures the next instruction.
     ///
     /// The last InstructionContext is always empty and pre-reserved for the next instruction.
@@ -359,14 +380,14 @@ impl TransactionContext {
         instruction_data: &[u8],
     ) -> Result<(), InstructionError> {
         debug_assert_eq!(deduplication_map.len(), MAX_ACCOUNTS_PER_TRANSACTION);
-        let instruction_context = self
+        let instruction = self
             .instruction_trace
             .last_mut()
             .ok_or(InstructionError::CallDepth)?;
-        instruction_context.program_account_index_in_tx = program_index;
-        instruction_context.instruction_accounts = instruction_accounts;
-        instruction_context.instruction_data = instruction_data.to_vec();
-        instruction_context.dedup_map = deduplication_map;
+        instruction.program_account_index_in_tx = program_index;
+        instruction.instruction_accounts = instruction_accounts;
+        instruction.instruction_data = instruction_data.to_vec();
+        instruction.dedup_map = deduplication_map;
         Ok(())
     }
 
@@ -394,34 +415,25 @@ impl TransactionContext {
         )
     }
 
-    /// Returns the immutable InstructionContext. This function assumes it has already been
-    /// configured with the correct values in `prepare_next_instruction` or
-    /// `prepare_next_top_level_instruction`
-    pub fn get_next_instruction_context(&self) -> Result<&InstructionContext, InstructionError> {
-        self.instruction_trace
-            .last()
-            .ok_or(InstructionError::CallDepth)
-    }
-
-    /// Pushes the next InstructionContext
+    /// Pushes the next instruction
     #[cfg(not(target_os = "solana"))]
     pub fn push(&mut self) -> Result<(), InstructionError> {
-        let nesting_level = self.get_instruction_context_stack_height();
+        let nesting_level = self.get_instruction_stack_height();
         if !self.instruction_stack.is_empty() && self.accounts.get_lamports_delta() != 0 {
             return Err(InstructionError::UnbalancedInstruction);
         }
         {
-            let instruction_context = self
+            let instruction = self
                 .instruction_trace
                 .last_mut()
                 .ok_or(InstructionError::CallDepth)?;
-            instruction_context.nesting_level = nesting_level;
+            instruction.nesting_level = nesting_level;
         }
         let index_in_trace = self.get_instruction_trace_length();
         if index_in_trace >= self.instruction_trace_capacity {
             return Err(InstructionError::MaxInstructionTraceLengthExceeded);
         }
-        self.instruction_trace.push(InstructionContext::default());
+        self.instruction_trace.push(InstructionFrame::default());
         if nesting_level >= self.instruction_stack_capacity {
             return Err(InstructionError::CallDepth);
         }
@@ -439,7 +451,7 @@ impl TransactionContext {
         Ok(())
     }
 
-    /// Pops the current InstructionContext
+    /// Pops the current instruction
     #[cfg(not(target_os = "solana"))]
     pub fn pop(&mut self) -> Result<(), InstructionError> {
         if self.instruction_stack.is_empty() {
@@ -475,12 +487,12 @@ impl TransactionContext {
         }
     }
 
-    /// Gets the return data of the current InstructionContext or any above
+    /// Gets the return data of the current instruction or any above
     pub fn get_return_data(&self) -> (&Pubkey, &[u8]) {
         (&self.return_data.program_id, &self.return_data.data)
     }
 
-    /// Set the return data of the current InstructionContext
+    /// Set the return data of the current instruction
     pub fn set_return_data(
         &mut self,
         program_id: Pubkey,
@@ -579,11 +591,9 @@ pub struct TransactionReturnData {
     pub data: Vec<u8>,
 }
 
-/// Loaded instruction shared between runtime and programs.
-///
-/// This context is valid for the entire duration of a (possibly cross program) instruction being processed.
+/// Instruction shared between runtime and programs.
 #[derive(Debug, Clone, Default)]
-pub struct InstructionContext {
+pub struct InstructionFrame {
     nesting_level: usize,
     program_account_index_in_tx: IndexOfAccount,
     instruction_accounts: Vec<InstructionAccount>,
@@ -594,7 +604,19 @@ pub struct InstructionContext {
     instruction_data: Vec<u8>,
 }
 
-impl InstructionContext {
+/// View interface to read instructions.
+#[derive(Debug, Clone)]
+pub struct InstructionContext<'a> {
+    transaction_context: &'a TransactionContext,
+    // The rest of the fields are redundant shortcuts
+    nesting_level: usize,
+    program_account_index_in_tx: IndexOfAccount,
+    instruction_accounts: &'a [InstructionAccount],
+    dedup_map: &'a [u8],
+    instruction_data: &'a [u8],
+}
+
+impl<'a> InstructionContext<'a> {
     /// How many Instructions were on the stack after this one was pushed
     ///
     /// That is the number of nested parent Instructions plus one (itself).
@@ -621,7 +643,7 @@ impl InstructionContext {
 
     /// Data parameter for the programs `process_instruction` handler
     pub fn get_instruction_data(&self) -> &[u8] {
-        &self.instruction_data
+        self.instruction_data
     }
 
     /// Searches for an instruction account by its key
@@ -702,24 +724,19 @@ impl InstructionContext {
     }
 
     /// Gets the key of the last program account of this Instruction
-    pub fn get_program_key<'a, 'b: 'a>(
-        &'a self,
-        transaction_context: &'b TransactionContext,
-    ) -> Result<&'b Pubkey, InstructionError> {
+    pub fn get_program_key(&self) -> Result<&'a Pubkey, InstructionError> {
         self.get_index_of_program_account_in_transaction()
             .and_then(|index_in_transaction| {
-                transaction_context.get_key_of_account_at_index(index_in_transaction)
+                self.transaction_context
+                    .get_key_of_account_at_index(index_in_transaction)
             })
     }
 
     /// Get the owner of the program account of this instruction
-    pub fn get_program_owner(
-        &self,
-        transaction_context: &TransactionContext,
-    ) -> Result<Pubkey, InstructionError> {
+    pub fn get_program_owner(&self) -> Result<Pubkey, InstructionError> {
         self.get_index_of_program_account_in_transaction()
             .and_then(|index_in_transaction| {
-                transaction_context
+                self.transaction_context
                     .accounts
                     .try_borrow(index_in_transaction)
             })
@@ -727,22 +744,22 @@ impl InstructionContext {
     }
 
     /// Gets an instruction account of this Instruction
-    pub fn try_borrow_instruction_account<'a, 'b: 'a>(
-        &'a self,
-        transaction_context: &'b TransactionContext,
+    pub fn try_borrow_instruction_account(
+        &self,
         index_in_instruction: IndexOfAccount,
-    ) -> Result<BorrowedAccount<'a>, InstructionError> {
+    ) -> Result<BorrowedAccount, InstructionError> {
         let instruction_account = *self
             .instruction_accounts
             .get(index_in_instruction as usize)
             .ok_or(InstructionError::NotEnoughAccountKeys)?;
 
-        let account = transaction_context
+        let account = self
+            .transaction_context
             .accounts
             .try_borrow_mut(instruction_account.index_in_transaction)?;
 
         Ok(BorrowedAccount {
-            transaction_context,
+            transaction_context: self.transaction_context,
             instruction_account,
             account,
             index_in_transaction_of_instruction_program: self.program_account_index_in_tx,
@@ -774,15 +791,13 @@ impl InstructionContext {
     }
 
     /// Calculates the set of all keys of signer instruction accounts in this Instruction
-    pub fn get_signers(
-        &self,
-        transaction_context: &TransactionContext,
-    ) -> Result<HashSet<Pubkey>, InstructionError> {
+    pub fn get_signers(&self) -> Result<HashSet<Pubkey>, InstructionError> {
         let mut result = HashSet::new();
         for instruction_account in self.instruction_accounts.iter() {
             if instruction_account.is_signer() {
                 result.insert(
-                    *transaction_context
+                    *self
+                        .transaction_context
                         .get_key_of_account_at_index(instruction_account.index_in_transaction)?,
                 );
             }
@@ -791,16 +806,15 @@ impl InstructionContext {
     }
 
     pub fn instruction_accounts(&self) -> &[InstructionAccount] {
-        &self.instruction_accounts
+        self.instruction_accounts
     }
 
-    pub fn get_key_of_instruction_account<'a>(
+    pub fn get_key_of_instruction_account(
         &self,
         index_in_instruction: IndexOfAccount,
-        transaction_context: &'a TransactionContext,
     ) -> Result<&'a Pubkey, InstructionError> {
         self.get_index_of_instruction_account_in_transaction(index_in_instruction)
-            .and_then(|idx| transaction_context.get_key_of_account_at_index(idx))
+            .and_then(|idx| self.transaction_context.get_key_of_account_at_index(idx))
     }
 }
 
@@ -1261,10 +1275,10 @@ mod tests {
         let result = instruction_context.get_index_of_program_account_in_transaction();
         assert_eq!(result, Err(InstructionError::NotEnoughAccountKeys));
 
-        let result = instruction_context.get_program_key(&transaction_context);
+        let result = instruction_context.get_program_key();
         assert_eq!(result, Err(InstructionError::NotEnoughAccountKeys));
 
-        let result = instruction_context.get_program_owner(&transaction_context);
+        let result = instruction_context.get_program_owner();
         assert_eq!(result.err(), Some(InstructionError::NotEnoughAccountKeys));
     }
 }