From 6f3f6eddb2de5ef3581264f8d6693361bdabd2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 6 Dec 2021 21:20:16 +0100 Subject: [PATCH] Updates documentation around what needs to be passed in CPI. (#21633) --- .../programming-model/calling-between-programs.md | 8 ++------ program-runtime/src/invoke_context.rs | 7 +++++-- sdk/program/src/program.rs | 8 -------- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/docs/src/developing/programming-model/calling-between-programs.md b/docs/src/developing/programming-model/calling-between-programs.md index 96a41764b48ae4..200377e27e3585 100644 --- a/docs/src/developing/programming-model/calling-between-programs.md +++ b/docs/src/developing/programming-model/calling-between-programs.md @@ -54,12 +54,8 @@ mod acme { `invoke()` is built into Solana's runtime and is responsible for routing the given instruction to the `token` program via the instruction's `program_id` -field. - -Note that `invoke` requires the caller to pass all the accounts required by the -instruction being invoked. This means that both the executable account (the -ones that matches the instruction's program id) and the accounts passed to the -instruction processor. +field. The caller has to pass all the accounts required by the instruction +being invoked, except for the executable account (with the key `program_id`). Before invoking `pay()`, the runtime must ensure that `acme` didn't modify any accounts owned by `token`. It does this by applying the runtime's policy to the diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 3d2ec0d5e936db..8447719b991bf4 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -740,7 +740,7 @@ impl<'a> InvokeContext<'a> { Ok(()) } - /// Get the list of keyed accounts + /// Get the list of keyed accounts including the chain of program accounts pub fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { self.invoke_stack .last() @@ -748,7 +748,10 @@ impl<'a> InvokeContext<'a> { .ok_or(InstructionError::CallDepth) } - /// 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: The `KeyedAccount` at index `0` has the key `program_id` and + /// is followed by the `KeyedAccount`s passed by the caller. pub fn get_instruction_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> { let frame = self .invoke_stack diff --git a/sdk/program/src/program.rs b/sdk/program/src/program.rs index 45873e2d64a748..f07099a0f5245b 100644 --- a/sdk/program/src/program.rs +++ b/sdk/program/src/program.rs @@ -7,8 +7,6 @@ use crate::{ /// Notes: /// - RefCell checking can be compute unit expensive, to avoid that expense use /// `invoke_unchecked` instead, but at your own risk. -/// - The program id of the instruction being issued must also be included in -/// `account_infos`. pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult { invoke_signed(instruction, account_infos, &[]) } @@ -19,8 +17,6 @@ pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo]) -> Progr /// - The missing checks ensured that the invocation doesn't violate the borrow /// rules of the `AccountInfo` fields that are wrapped in `RefCell`s. To /// include the checks call `invoke` instead. -/// - The program id of the instruction being issued must also be included in -/// `account_infos`. pub fn invoke_unchecked(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult { invoke_signed_unchecked(instruction, account_infos, &[]) } @@ -30,8 +26,6 @@ pub fn invoke_unchecked(instruction: &Instruction, account_infos: &[AccountInfo] /// Notes: /// - RefCell checking can be compute unit expensive, to avoid that expense use /// `invoke_signed_unchecked` instead, but at your own risk. -/// - The program id of the instruction being issued must also be included in -/// `account_infos`. pub fn invoke_signed( instruction: &Instruction, account_infos: &[AccountInfo], @@ -63,8 +57,6 @@ pub fn invoke_signed( /// - The missing checks ensured that the invocation doesn't violate the borrow /// rules of the `AccountInfo` fields that are wrapped in `RefCell`s. To /// include the checks call `invoke_signed` instead. -/// - The program id of the instruction being issued must also be included in -/// `account_infos`. pub fn invoke_signed_unchecked( instruction: &Instruction, account_infos: &[AccountInfo],