Refactor: process_instruction() (#20448)

* Adds first_instruction_account parameter to process_instruction().

* Removes InvokeContext::remove_first_keyed_account() from all BPF loaders.

* Removes InvokeContext::remove_first_keyed_account() from all builtin programs.

* Removes InvokeContext::remove_first_keyed_account() from all mock ups.

* Deprecates InvokeContext::remove_first_keyed_account().

* Documents index base of keyed_account_at_index().

* Adds dynamic offset to call sites of "keyed_account_at_index()".
This commit is contained in:
Alexander Meißner
2021-10-08 11:41:07 +02:00
committed by GitHub
parent a6a4cfda89
commit 4e65487d2f
17 changed files with 1364 additions and 1366 deletions

View File

@ -80,6 +80,7 @@ macro_rules! declare_builtin_name {
///
/// fn my_process_instruction(
/// program_id: &Pubkey,
/// first_instruction_account: usize,
/// keyed_accounts: &[KeyedAccount],
/// instruction_data: &[u8],
/// ) -> Result<(), InstructionError> {
@ -111,6 +112,7 @@ macro_rules! declare_builtin_name {
///
/// fn my_process_instruction(
/// program_id: &Pubkey,
/// first_instruction_account: usize,
/// keyed_accounts: &[KeyedAccount],
/// instruction_data: &[u8],
/// ) -> Result<(), InstructionError> {

View File

@ -95,6 +95,7 @@ macro_rules! declare_name {
///
/// fn my_process_instruction(
/// program_id: &Pubkey,
/// first_instruction_account: usize,
/// instruction_data: &[u8],
/// invoke_context: &mut dyn InvokeContext,
/// ) -> Result<(), InstructionError> {
@ -128,6 +129,7 @@ macro_rules! declare_name {
///
/// fn my_process_instruction(
/// program_id: &Pubkey,
/// first_instruction_account: usize,
/// instruction_data: &[u8],
/// invoke_context: &mut dyn InvokeContext,
/// ) -> Result<(), InstructionError> {
@ -154,10 +156,11 @@ macro_rules! declare_program(
#[no_mangle]
pub extern "C" fn $name(
program_id: &$crate::pubkey::Pubkey,
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn $crate::process_instruction::InvokeContext,
) -> Result<(), $crate::instruction::InstructionError> {
$entrypoint(program_id, instruction_data, invoke_context)
$entrypoint(program_id, first_instruction_account, instruction_data, invoke_context)
}
)
);

View File

@ -217,6 +217,8 @@ pub fn next_keyed_account<'a, 'b, I: Iterator<Item = &'a KeyedAccount<'b>>>(
}
/// Return the KeyedAccount at the specified index or a NotEnoughAccountKeys error
///
/// Index zero starts at the chain of program accounts, followed by the instruction accounts.
pub fn keyed_account_at_index<'a>(
keyed_accounts: &'a [KeyedAccount],
index: usize,

View File

@ -4,6 +4,7 @@ use itertools::Itertools;
use solana_sdk::{
account::AccountSharedData,
compute_budget::ComputeBudget,
feature_set::remove_native_loader,
fee_calculator::FeeCalculator,
hash::Hash,
instruction::{CompiledInstruction, Instruction, InstructionError},
@ -27,7 +28,7 @@ pub type LoaderEntrypoint = unsafe extern "C" fn(
) -> Result<(), InstructionError>;
pub type ProcessInstructionWithContext =
fn(&Pubkey, &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
fn(&Pubkey, usize, &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
pub struct InvokeContextStackFrame<'a> {
pub key: Pubkey,
@ -81,6 +82,10 @@ pub trait InvokeContext {
/// Get the program ID of the currently executing program
fn get_caller(&self) -> Result<&Pubkey, InstructionError>;
/// Removes the first keyed account
#[deprecated(
since = "1.9.0",
note = "To be removed together with remove_native_loader"
)]
fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError>;
/// Get the list of keyed accounts
fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError>;
@ -395,8 +400,8 @@ pub trait Executor: Debug + Send + Sync {
/// Execute the program
fn execute(
&self,
loader_id: &Pubkey,
program_id: &Pubkey,
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
use_jit: bool,
@ -538,12 +543,14 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
.ok_or(InstructionError::CallDepth)
}
fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> {
let stack_frame = &mut self
.invoke_stack
.last_mut()
.ok_or(InstructionError::CallDepth)?;
stack_frame.keyed_accounts_range.start =
stack_frame.keyed_accounts_range.start.saturating_add(1);
if !self.is_feature_active(&remove_native_loader::id()) {
let stack_frame = &mut self
.invoke_stack
.last_mut()
.ok_or(InstructionError::CallDepth)?;
stack_frame.keyed_accounts_range.start =
stack_frame.keyed_accounts_range.start.saturating_add(1);
}
Ok(())
}
fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> {