diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 3edb9f02ab..7ee931b138 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -277,6 +277,8 @@ pub trait InvokeContext { fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError>; /// Get the list of keyed accounts fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError>; + /// Get the list of keyed accounts skipping `first_instruction_account` many entries + fn get_instruction_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError>; /// Get this invocation's LogCollector fn get_log_collector(&self) -> Option>>; /// Get this invocation's ComputeMeter @@ -621,7 +623,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { let message = Message::new(&[instruction.clone()], None); // Gather keyed_accounts in the order of message.account_keys - let caller_keyed_accounts = self.get_keyed_accounts()?; + let caller_keyed_accounts = self.get_instruction_keyed_accounts()?; let callee_keyed_accounts = message .account_keys .iter() @@ -815,6 +817,17 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { .map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()]) .ok_or(InstructionError::CallDepth) } + 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..]) + } fn get_log_collector(&self) -> Option>> { self.log_collector.clone() } diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 81c6b7d4c6..3aa5c6326b 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -2003,7 +2003,7 @@ where let demote_program_write_locks = invoke_context.is_feature_active(&demote_program_write_locks::id()); let keyed_accounts = invoke_context - .get_keyed_accounts() + .get_instruction_keyed_accounts() .map_err(SyscallError::InstructionError)?; let mut account_indices = Vec::with_capacity(message.account_keys.len()); let mut accounts = Vec::with_capacity(message.account_keys.len());