From 8f1134366489055ac294a3d77b8eb84ff950c055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Tue, 21 Dec 2021 12:53:22 +0100 Subject: [PATCH] Fix #21986 (#22035) * Partial revert "Updates documentation around what needs to be passed in CPI. (#21633)" * Enforces the program_id being passed explicitly by removing it from get_instruction_keyed_accounts(). * instruction_accounts => instructions_account (cherry picked from commit ba8e15848e5b7d52cce133e541e92c5aec361a6a) # Conflicts: # program-runtime/src/invoke_context.rs --- program-runtime/src/invoke_context.rs | 24 ++++++++++++------- .../rust/instruction_introspection/src/lib.rs | 14 +++++------ programs/bpf/tests/programs.rs | 5 +++- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 1da706a70f0059..a8113d2e765c88 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -724,9 +724,15 @@ impl<'a> InvokeContext<'a> { /// Get the owner of the currently executing program pub fn get_loader(&self) -> Result { - self.get_instruction_keyed_accounts() - .and_then(|keyed_accounts| keyed_accounts.first().ok_or(InstructionError::CallDepth)) - .and_then(|keyed_account| keyed_account.owner()) + let frame = self + .invoke_stack + .last() + .ok_or(InstructionError::CallDepth)?; + let first_instruction_account = frame + .number_of_program_accounts + .checked_sub(1) + .ok_or(InstructionError::CallDepth)?; + frame.keyed_accounts[first_instruction_account].owner() } /// Removes the first keyed account @@ -754,17 +760,19 @@ impl<'a> InvokeContext<'a> { .ok_or(InstructionError::CallDepth) } +<<<<<<< HEAD /// Get the list of keyed accounts skipping `first_instruction_account` many entries +======= + /// Get the list of keyed accounts without the chain of program accounts + /// + /// Note: This only contains the `KeyedAccount`s passed by the caller. +>>>>>>> ba8e15848 (Fix #21986 (#22035)) pub fn get_instruction_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { let frame = self .invoke_stack .last() .ok_or(InstructionError::CallDepth)?; - let first_instruction_account = frame - .number_of_program_accounts - .checked_sub(1) - .ok_or(InstructionError::CallDepth)?; - Ok(&frame.keyed_accounts[first_instruction_account..]) + Ok(&frame.keyed_accounts[frame.number_of_program_accounts..]) } /// Get this invocation's LogCollector diff --git a/programs/bpf/rust/instruction_introspection/src/lib.rs b/programs/bpf/rust/instruction_introspection/src/lib.rs index f39c811f42057f..726ff265f872bb 100644 --- a/programs/bpf/rust/instruction_introspection/src/lib.rs +++ b/programs/bpf/rust/instruction_introspection/src/lib.rs @@ -2,7 +2,6 @@ extern crate solana_program; use solana_program::{ - account_info::next_account_info, account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, @@ -25,20 +24,19 @@ fn process_instruction( } let secp_instruction_index = instruction_data[0]; - let account_info_iter = &mut accounts.iter(); - let instruction_accounts = next_account_info(account_info_iter)?; - assert_eq!(*instruction_accounts.key, instructions::id()); - let data_len = instruction_accounts.try_borrow_data()?.len(); + let instructions_account = accounts.last().ok_or(ProgramError::NotEnoughAccountKeys)?; + assert_eq!(*instructions_account.key, instructions::id()); + let data_len = instructions_account.try_borrow_data()?.len(); if data_len < 2 { return Err(ProgramError::InvalidAccountData); } let instruction = instructions::load_instruction_at_checked( secp_instruction_index as usize, - instruction_accounts, + instructions_account, )?; - let current_instruction = instructions::load_current_index_checked(instruction_accounts)?; + let current_instruction = instructions::load_current_index_checked(instructions_account)?; let my_index = instruction_data[1] as u16; assert_eq!(current_instruction, my_index); @@ -56,7 +54,7 @@ fn process_instruction( &[instruction_data[0], instruction_data[1], 1], vec![AccountMeta::new_readonly(instructions::id(), false)], ), - &[instruction_accounts.clone()], + accounts, )?; } diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 0c0021bd051e03..7a41fec56cd976 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -1449,7 +1449,10 @@ fn test_program_bpf_instruction_introspection() { ); // Passing transaction - let account_metas = vec![AccountMeta::new_readonly(sysvar::instructions::id(), false)]; + let account_metas = vec![ + AccountMeta::new(program_id, false), + AccountMeta::new(sysvar::instructions::id(), false), + ]; let instruction0 = Instruction::new_with_bytes(program_id, &[0u8, 0u8], account_metas.clone()); let instruction1 = Instruction::new_with_bytes(program_id, &[0u8, 1u8], account_metas.clone()); let instruction2 = Instruction::new_with_bytes(program_id, &[0u8, 2u8], account_metas);