Unifies ThisInvokeContext and dyn trait InvokeContext. (#21563)
This commit is contained in:
committed by
GitHub
parent
8dfa83c579
commit
bfdb775ffc
@ -22,7 +22,7 @@ use solana_sdk::{
|
||||
use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc, sync::Arc};
|
||||
|
||||
pub type ProcessInstructionWithContext =
|
||||
fn(usize, &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
|
||||
fn(usize, &[u8], &mut InvokeContext) -> Result<(), InstructionError>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BuiltinProgram {
|
||||
@ -36,7 +36,7 @@ impl std::fmt::Debug for BuiltinProgram {
|
||||
type ErasedProcessInstructionWithContext = fn(
|
||||
usize,
|
||||
&'static [u8],
|
||||
&'static mut dyn InvokeContext,
|
||||
&'static mut InvokeContext<'static>,
|
||||
) -> Result<(), InstructionError>;
|
||||
|
||||
// rustc doesn't compile due to bug without this work around
|
||||
@ -50,11 +50,11 @@ impl std::fmt::Debug for BuiltinProgram {
|
||||
/// Program executor
|
||||
pub trait Executor: Debug + Send + Sync {
|
||||
/// Execute the program
|
||||
fn execute(
|
||||
fn execute<'a, 'b>(
|
||||
&self,
|
||||
first_instruction_account: usize,
|
||||
instruction_data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
invoke_context: &'a mut InvokeContext<'b>,
|
||||
use_jit: bool,
|
||||
) -> Result<(), InstructionError>;
|
||||
}
|
||||
@ -130,7 +130,7 @@ impl<'a> StackFrame<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ThisInvokeContext<'a> {
|
||||
pub struct InvokeContext<'a> {
|
||||
instruction_index: usize,
|
||||
invoke_stack: Vec<StackFrame<'a>>,
|
||||
rent: Rent,
|
||||
@ -150,7 +150,8 @@ pub struct ThisInvokeContext<'a> {
|
||||
lamports_per_signature: u64,
|
||||
return_data: (Pubkey, Vec<u8>),
|
||||
}
|
||||
impl<'a> ThisInvokeContext<'a> {
|
||||
|
||||
impl<'a> InvokeContext<'a> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
rent: Rent,
|
||||
@ -221,117 +222,9 @@ impl<'a> ThisInvokeContext<'a> {
|
||||
Arc::new(FeatureSet::all_enabled()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Invocation context passed to loaders
|
||||
pub trait InvokeContext {
|
||||
/// Push a stack frame onto the invocation stack
|
||||
fn push(
|
||||
&mut self,
|
||||
message: &Message,
|
||||
instruction: &CompiledInstruction,
|
||||
program_indices: &[usize],
|
||||
account_indices: Option<&[usize]>,
|
||||
) -> Result<(), InstructionError>;
|
||||
/// Pop a stack frame from the invocation stack
|
||||
fn pop(&mut self);
|
||||
/// Current depth of the invocation stake
|
||||
fn invoke_depth(&self) -> usize;
|
||||
/// Verify the results of an instruction
|
||||
fn verify(
|
||||
&mut self,
|
||||
message: &Message,
|
||||
instruction: &CompiledInstruction,
|
||||
program_indices: &[usize],
|
||||
) -> Result<(), InstructionError>;
|
||||
/// Verify and update PreAccount state based on program execution
|
||||
fn verify_and_update(
|
||||
&mut self,
|
||||
instruction: &CompiledInstruction,
|
||||
account_indices: &[usize],
|
||||
write_privileges: &[bool],
|
||||
) -> Result<(), InstructionError>;
|
||||
/// Entrypoint for a cross-program invocation from a native program
|
||||
fn native_invoke(
|
||||
&mut self,
|
||||
instruction: Instruction,
|
||||
signers: &[Pubkey],
|
||||
) -> Result<(), InstructionError>;
|
||||
/// Helper to prepare for process_cross_program_instruction()
|
||||
fn create_message(
|
||||
&mut self,
|
||||
instruction: &Instruction,
|
||||
signers: &[Pubkey],
|
||||
) -> Result<(Message, Vec<bool>, Vec<usize>), InstructionError>;
|
||||
/// Process a cross-program instruction
|
||||
fn process_cross_program_instruction(
|
||||
&mut self,
|
||||
message: &Message,
|
||||
program_indices: &[usize],
|
||||
account_indices: &[usize],
|
||||
caller_write_privileges: &[bool],
|
||||
) -> Result<(), InstructionError>;
|
||||
/// Calls the instruction's program entrypoint method
|
||||
fn process_instruction(&mut self, instruction_data: &[u8]) -> Result<(), InstructionError>;
|
||||
/// Get the program ID of the currently executing program
|
||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError>;
|
||||
/// Get the owner of the currently executing program
|
||||
fn get_loader(&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>;
|
||||
/// 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<Rc<RefCell<LogCollector>>>;
|
||||
/// Get this invocation's ComputeMeter
|
||||
fn get_compute_meter(&self) -> Rc<RefCell<ComputeMeter>>;
|
||||
/// Loaders may need to do work in order to execute a program. Cache
|
||||
/// the work that can be re-used across executions
|
||||
fn add_executor(&self, pubkey: &Pubkey, executor: Arc<dyn Executor>);
|
||||
/// Get the completed loader work that can be re-used across executions
|
||||
fn get_executor(&self, pubkey: &Pubkey) -> Option<Arc<dyn Executor>>;
|
||||
/// Set which instruction in the message is currently being recorded
|
||||
fn set_instruction_index(&mut self, instruction_index: usize);
|
||||
/// Record invoked instruction
|
||||
fn record_instruction(&self, instruction: &Instruction);
|
||||
/// Get the bank's active feature set
|
||||
fn is_feature_active(&self, feature_id: &Pubkey) -> bool;
|
||||
/// Find an account_index and account by its key
|
||||
fn get_account(&self, pubkey: &Pubkey) -> Option<(usize, Rc<RefCell<AccountSharedData>>)>;
|
||||
/// Update timing
|
||||
fn update_timing(
|
||||
&mut self,
|
||||
serialize_us: u64,
|
||||
create_vm_us: u64,
|
||||
execute_us: u64,
|
||||
deserialize_us: u64,
|
||||
);
|
||||
/// Get sysvars
|
||||
fn get_sysvars(&self) -> &[(Pubkey, Vec<u8>)];
|
||||
/// Get this invocation's compute budget
|
||||
fn get_compute_budget(&self) -> &ComputeBudget;
|
||||
/// Set this invocation's blockhash
|
||||
fn set_blockhash(&mut self, hash: Hash);
|
||||
/// Get this invocation's blockhash
|
||||
fn get_blockhash(&self) -> &Hash;
|
||||
/// Set this invocation's lamports_per_signature value
|
||||
fn set_lamports_per_signature(&mut self, lamports_per_signature: u64);
|
||||
/// Get this invocation's lamports_per_signature value
|
||||
fn get_lamports_per_signature(&self) -> u64;
|
||||
/// Set the return data
|
||||
fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError>;
|
||||
/// Get the return data
|
||||
fn get_return_data(&self) -> (Pubkey, &[u8]);
|
||||
}
|
||||
|
||||
impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
fn push(
|
||||
pub fn push(
|
||||
&mut self,
|
||||
message: &Message,
|
||||
instruction: &CompiledInstruction,
|
||||
@ -430,13 +323,19 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
fn pop(&mut self) {
|
||||
|
||||
/// Pop a stack frame from the invocation stack
|
||||
pub fn pop(&mut self) {
|
||||
self.invoke_stack.pop();
|
||||
}
|
||||
fn invoke_depth(&self) -> usize {
|
||||
|
||||
/// Current depth of the invocation stack
|
||||
pub fn invoke_depth(&self) -> usize {
|
||||
self.invoke_stack.len()
|
||||
}
|
||||
fn verify(
|
||||
|
||||
/// Verify the results of an instruction
|
||||
pub fn verify(
|
||||
&mut self,
|
||||
message: &Message,
|
||||
instruction: &CompiledInstruction,
|
||||
@ -501,7 +400,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn verify_and_update(
|
||||
|
||||
/// Verify and update PreAccount state based on program execution
|
||||
pub fn verify_and_update(
|
||||
&mut self,
|
||||
instruction: &CompiledInstruction,
|
||||
account_indices: &[usize],
|
||||
@ -580,7 +481,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn native_invoke(
|
||||
|
||||
/// Entrypoint for a cross-program invocation from a builtin program
|
||||
pub fn native_invoke(
|
||||
&mut self,
|
||||
instruction: Instruction,
|
||||
signers: &[Pubkey],
|
||||
@ -623,7 +526,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn create_message(
|
||||
|
||||
/// Helper to prepare for process_cross_program_instruction()
|
||||
pub fn create_message(
|
||||
&mut self,
|
||||
instruction: &Instruction,
|
||||
signers: &[Pubkey],
|
||||
@ -734,7 +639,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
|
||||
Ok((message, caller_write_privileges, program_indices))
|
||||
}
|
||||
fn process_cross_program_instruction(
|
||||
|
||||
/// Process a cross-program instruction
|
||||
pub fn process_cross_program_instruction(
|
||||
&mut self,
|
||||
message: &Message,
|
||||
program_indices: &[usize],
|
||||
@ -766,7 +673,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
self.pop();
|
||||
result
|
||||
}
|
||||
fn process_instruction(&mut self, instruction_data: &[u8]) -> Result<(), InstructionError> {
|
||||
|
||||
/// Calls the instruction's program entrypoint method
|
||||
pub fn process_instruction(&mut self, instruction_data: &[u8]) -> Result<(), InstructionError> {
|
||||
let keyed_accounts = self.get_keyed_accounts()?;
|
||||
let root_account = keyed_account_at_index(keyed_accounts, 0)
|
||||
.map_err(|_| InstructionError::UnsupportedProgramId)?;
|
||||
@ -802,18 +711,28 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
}
|
||||
Err(InstructionError::UnsupportedProgramId)
|
||||
}
|
||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
||||
|
||||
/// Get the program ID of the currently executing program
|
||||
pub fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
||||
self.invoke_stack
|
||||
.last()
|
||||
.and_then(|frame| frame.program_id())
|
||||
.ok_or(InstructionError::CallDepth)
|
||||
}
|
||||
fn get_loader(&self) -> Result<Pubkey, InstructionError> {
|
||||
|
||||
/// Get the owner of the currently executing program
|
||||
pub fn get_loader(&self) -> Result<Pubkey, InstructionError> {
|
||||
self.get_instruction_keyed_accounts()
|
||||
.and_then(|keyed_accounts| keyed_accounts.first().ok_or(InstructionError::CallDepth))
|
||||
.and_then(|keyed_account| keyed_account.owner())
|
||||
}
|
||||
fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> {
|
||||
|
||||
/// Removes the first keyed account
|
||||
#[deprecated(
|
||||
since = "1.9.0",
|
||||
note = "To be removed together with remove_native_loader"
|
||||
)]
|
||||
pub fn remove_first_keyed_account(&mut self) -> Result<(), InstructionError> {
|
||||
if !self.is_feature_active(&remove_native_loader::id()) {
|
||||
let stack_frame = &mut self
|
||||
.invoke_stack
|
||||
@ -824,13 +743,17 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> {
|
||||
|
||||
/// Get the list of keyed accounts
|
||||
pub fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> {
|
||||
self.invoke_stack
|
||||
.last()
|
||||
.map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()])
|
||||
.ok_or(InstructionError::CallDepth)
|
||||
}
|
||||
fn get_instruction_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> {
|
||||
|
||||
/// Get the list of keyed accounts skipping `first_instruction_account` many entries
|
||||
pub fn get_instruction_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> {
|
||||
let frame = self
|
||||
.invoke_stack
|
||||
.last()
|
||||
@ -841,30 +764,47 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
.ok_or(InstructionError::CallDepth)?;
|
||||
Ok(&frame.keyed_accounts[first_instruction_account..])
|
||||
}
|
||||
fn get_log_collector(&self) -> Option<Rc<RefCell<LogCollector>>> {
|
||||
|
||||
/// Get this invocation's LogCollector
|
||||
pub fn get_log_collector(&self) -> Option<Rc<RefCell<LogCollector>>> {
|
||||
self.log_collector.clone()
|
||||
}
|
||||
fn get_compute_meter(&self) -> Rc<RefCell<ComputeMeter>> {
|
||||
|
||||
/// Get this invocation's ComputeMeter
|
||||
pub fn get_compute_meter(&self) -> Rc<RefCell<ComputeMeter>> {
|
||||
self.compute_meter.clone()
|
||||
}
|
||||
fn add_executor(&self, pubkey: &Pubkey, executor: Arc<dyn Executor>) {
|
||||
|
||||
/// Loaders may need to do work in order to execute a program. Cache
|
||||
/// the work that can be re-used across executions
|
||||
pub fn add_executor(&self, pubkey: &Pubkey, executor: Arc<dyn Executor>) {
|
||||
self.executors.borrow_mut().insert(*pubkey, executor);
|
||||
}
|
||||
fn get_executor(&self, pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
|
||||
|
||||
/// Get the completed loader work that can be re-used across execution
|
||||
pub fn get_executor(&self, pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
|
||||
self.executors.borrow().get(pubkey)
|
||||
}
|
||||
fn set_instruction_index(&mut self, instruction_index: usize) {
|
||||
|
||||
/// Set which instruction in the message is currently being recorded
|
||||
pub fn set_instruction_index(&mut self, instruction_index: usize) {
|
||||
self.instruction_index = instruction_index;
|
||||
}
|
||||
fn record_instruction(&self, instruction: &Instruction) {
|
||||
|
||||
/// Record invoked instruction
|
||||
pub fn record_instruction(&self, instruction: &Instruction) {
|
||||
if let Some(instruction_recorders) = &self.instruction_recorders {
|
||||
instruction_recorders[self.instruction_index].record_instruction(instruction.clone());
|
||||
}
|
||||
}
|
||||
fn is_feature_active(&self, feature_id: &Pubkey) -> bool {
|
||||
|
||||
/// Get the bank's active feature set
|
||||
pub fn is_feature_active(&self, feature_id: &Pubkey) -> bool {
|
||||
self.feature_set.is_active(feature_id)
|
||||
}
|
||||
fn get_account(&self, pubkey: &Pubkey) -> Option<(usize, Rc<RefCell<AccountSharedData>>)> {
|
||||
|
||||
/// Find an account_index and account by its key
|
||||
pub fn get_account(&self, pubkey: &Pubkey) -> Option<(usize, Rc<RefCell<AccountSharedData>>)> {
|
||||
for (index, (key, account)) in self.accounts.iter().enumerate().rev() {
|
||||
if key == pubkey {
|
||||
return Some((index, account.clone()));
|
||||
@ -872,7 +812,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
}
|
||||
None
|
||||
}
|
||||
fn update_timing(
|
||||
|
||||
/// Update timing
|
||||
pub fn update_timing(
|
||||
&mut self,
|
||||
serialize_us: u64,
|
||||
create_vm_us: u64,
|
||||
@ -884,29 +826,45 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
self.timings.execute_us = self.timings.execute_us.saturating_add(execute_us);
|
||||
self.timings.deserialize_us = self.timings.deserialize_us.saturating_add(deserialize_us);
|
||||
}
|
||||
fn get_sysvars(&self) -> &[(Pubkey, Vec<u8>)] {
|
||||
|
||||
/// Get cached sysvars
|
||||
pub fn get_sysvars(&self) -> &[(Pubkey, Vec<u8>)] {
|
||||
self.sysvars
|
||||
}
|
||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
||||
|
||||
/// Get this invocation's compute budget
|
||||
pub fn get_compute_budget(&self) -> &ComputeBudget {
|
||||
&self.current_compute_budget
|
||||
}
|
||||
fn set_blockhash(&mut self, hash: Hash) {
|
||||
|
||||
/// Set this invocation's blockhash
|
||||
pub fn set_blockhash(&mut self, hash: Hash) {
|
||||
self.blockhash = hash;
|
||||
}
|
||||
fn get_blockhash(&self) -> &Hash {
|
||||
|
||||
/// Get this invocation's blockhash
|
||||
pub fn get_blockhash(&self) -> &Hash {
|
||||
&self.blockhash
|
||||
}
|
||||
fn set_lamports_per_signature(&mut self, lamports_per_signature: u64) {
|
||||
|
||||
/// Set this invocation's lamports_per_signature value
|
||||
pub fn set_lamports_per_signature(&mut self, lamports_per_signature: u64) {
|
||||
self.lamports_per_signature = lamports_per_signature;
|
||||
}
|
||||
fn get_lamports_per_signature(&self) -> u64 {
|
||||
|
||||
/// Get this invocation's lamports_per_signature value
|
||||
pub fn get_lamports_per_signature(&self) -> u64 {
|
||||
self.lamports_per_signature
|
||||
}
|
||||
fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError> {
|
||||
|
||||
/// Set the return data
|
||||
pub fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError> {
|
||||
self.return_data = (*self.get_caller()?, data);
|
||||
Ok(())
|
||||
}
|
||||
fn get_return_data(&self) -> (Pubkey, &[u8]) {
|
||||
|
||||
/// Get the return data
|
||||
pub fn get_return_data(&self) -> (Pubkey, &[u8]) {
|
||||
(self.return_data.0, &self.return_data.1)
|
||||
}
|
||||
}
|
||||
@ -914,7 +872,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||
// This method which has a generic parameter is outside of the InvokeContext,
|
||||
// because the InvokeContext is a dyn Trait.
|
||||
pub fn get_sysvar<T: Sysvar>(
|
||||
invoke_context: &dyn InvokeContext,
|
||||
invoke_context: &InvokeContext,
|
||||
id: &Pubkey,
|
||||
) -> Result<T, InstructionError> {
|
||||
invoke_context
|
||||
@ -994,7 +952,7 @@ pub fn prepare_mock_invoke_context(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_mock_invoke_context<R, F: FnMut(&mut ThisInvokeContext) -> R>(
|
||||
pub fn with_mock_invoke_context<R, F: FnMut(&mut InvokeContext) -> R>(
|
||||
loader_id: Pubkey,
|
||||
account_size: usize,
|
||||
mut callback: F,
|
||||
@ -1021,7 +979,7 @@ pub fn with_mock_invoke_context<R, F: FnMut(&mut ThisInvokeContext) -> R>(
|
||||
),
|
||||
];
|
||||
let preparation = prepare_mock_invoke_context(&program_indices, &[], &keyed_accounts);
|
||||
let mut invoke_context = ThisInvokeContext::new_mock(&preparation.accounts, &[]);
|
||||
let mut invoke_context = InvokeContext::new_mock(&preparation.accounts, &[]);
|
||||
invoke_context
|
||||
.push(
|
||||
&preparation.message,
|
||||
@ -1045,7 +1003,7 @@ pub fn mock_process_instruction(
|
||||
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
|
||||
program_indices.insert(0, preparation.accounts.len());
|
||||
preparation.accounts.push((*loader_id, processor_account));
|
||||
let mut invoke_context = ThisInvokeContext::new_mock(&preparation.accounts, &[]);
|
||||
let mut invoke_context = InvokeContext::new_mock(&preparation.accounts, &[]);
|
||||
invoke_context.push(
|
||||
&preparation.message,
|
||||
&preparation.message.instructions[0],
|
||||
@ -1081,7 +1039,7 @@ mod tests {
|
||||
fn mock_process_instruction(
|
||||
_first_instruction_account: usize,
|
||||
_data: &[u8],
|
||||
_invoke_context: &mut dyn InvokeContext,
|
||||
_invoke_context: &mut InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -1089,7 +1047,7 @@ mod tests {
|
||||
fn mock_ix_processor(
|
||||
_first_instruction_account: usize,
|
||||
_data: &[u8],
|
||||
_context: &mut dyn InvokeContext,
|
||||
_context: &mut InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -1110,7 +1068,7 @@ mod tests {
|
||||
fn mock_process_instruction(
|
||||
first_instruction_account: usize,
|
||||
data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let program_id = invoke_context.get_caller()?;
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
@ -1184,7 +1142,7 @@ mod tests {
|
||||
&[Instruction::new_with_bytes(invoke_stack[0], &[0], metas)],
|
||||
None,
|
||||
);
|
||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
|
||||
// Check call depth increases and has a limit
|
||||
let mut depth_reached = 0;
|
||||
@ -1271,7 +1229,7 @@ mod tests {
|
||||
)],
|
||||
None,
|
||||
);
|
||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
invoke_context
|
||||
.push(&message, &message.instructions[0], &[0], None)
|
||||
.unwrap();
|
||||
@ -1336,7 +1294,7 @@ mod tests {
|
||||
program_id: callee_program_id,
|
||||
process_instruction: mock_process_instruction,
|
||||
}];
|
||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, builtin_programs);
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, builtin_programs);
|
||||
invoke_context
|
||||
.push(&message, &caller_instruction, &program_indices[..1], None)
|
||||
.unwrap();
|
||||
@ -1463,7 +1421,7 @@ mod tests {
|
||||
program_id: callee_program_id,
|
||||
process_instruction: mock_process_instruction,
|
||||
}];
|
||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, builtin_programs);
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, builtin_programs);
|
||||
invoke_context
|
||||
.push(&message, &caller_instruction, &program_indices, None)
|
||||
.unwrap();
|
||||
@ -1551,7 +1509,7 @@ mod tests {
|
||||
let mut feature_set = FeatureSet::all_enabled();
|
||||
feature_set.deactivate(&tx_wide_compute_cap::id());
|
||||
feature_set.deactivate(&requestable_heap_size::id());
|
||||
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
|
||||
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
|
||||
&accounts,
|
||||
&[],
|
||||
&[],
|
||||
|
@ -33,7 +33,7 @@ use thiserror::Error;
|
||||
pub type LoaderEntrypoint = unsafe extern "C" fn(
|
||||
program_id: &Pubkey,
|
||||
instruction_data: &[u8],
|
||||
invoke_context: &dyn InvokeContext,
|
||||
invoke_context: &InvokeContext,
|
||||
) -> Result<(), InstructionError>;
|
||||
|
||||
// Prototype of a native program entry point
|
||||
@ -165,7 +165,7 @@ impl NativeLoader {
|
||||
&self,
|
||||
first_instruction_account: usize,
|
||||
instruction_data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let (program_id, name_vec) = {
|
||||
let program_id = invoke_context.get_caller()?;
|
||||
|
Reference in New Issue
Block a user