From 8188c1dd5934e45a7be410d2087087b6282008d9 Mon Sep 17 00:00:00 2001 From: Jack May Date: Wed, 29 Sep 2021 19:50:38 -0700 Subject: [PATCH] add unchecked invokes (#20313) --- sdk/program/src/program.rs | 45 +++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/sdk/program/src/program.rs b/sdk/program/src/program.rs index bf3bd1654..45873e2d6 100644 --- a/sdk/program/src/program.rs +++ b/sdk/program/src/program.rs @@ -2,18 +2,36 @@ use crate::{ account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, pubkey::Pubkey, }; -/// Invoke a cross-program instruction +/// Invoke a cross-program instruction. /// -/// Note that the program id of the instruction being issued must also be included in -/// `account_infos`. +/// 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, &[]) } +/// Invoke a cross-program instruction but don't enforce RefCell handling. +/// +/// Notes: +/// - 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, &[]) +} + /// Invoke a cross-program instruction with program signatures /// -/// Note that the program id of the instruction being issued must also be included in -/// `account_infos`. +/// 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], @@ -35,6 +53,23 @@ pub fn invoke_signed( } } + invoke_signed_unchecked(instruction, account_infos, signers_seeds) +} + +/// Invoke a cross-program instruction with program signatures but don't check +/// RefCell handling. +/// +/// Note: +/// - 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], + signers_seeds: &[&[&[u8]]], +) -> ProgramResult { #[cfg(target_arch = "bpf")] { extern "C" {