Unifies ThisInvokeContext and dyn trait InvokeContext. (#21563)

This commit is contained in:
Alexander Meißner 2021-12-02 18:47:16 +01:00 committed by GitHub
parent 8dfa83c579
commit bfdb775ffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 366 additions and 431 deletions

View File

@ -24,7 +24,7 @@ use solana_client::{
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
tpu_client::{TpuClient, TpuClientConfig},
};
use solana_program_runtime::invoke_context::ThisInvokeContext;
use solana_program_runtime::invoke_context::InvokeContext;
use solana_rbpf::{elf::Executable, verifier, vm::Config};
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
use solana_sdk::{
@ -1991,7 +1991,7 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
let mut program_data = Vec::new();
file.read_to_end(&mut program_data)
.map_err(|err| format!("Unable to read program file: {}", err))?;
let mut invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let mut invoke_context = InvokeContext::new_mock(&[], &[]);
// Verify the program
Executable::<BpfError, ThisInstructionMeter>::from_elf(

View File

@ -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,
&[],
&[],

View File

@ -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()?;

View File

@ -84,26 +84,25 @@ pub enum ProgramTestError {
}
thread_local! {
static INVOKE_CONTEXT: RefCell<Option<(usize, usize)>> = RefCell::new(None);
static INVOKE_CONTEXT: RefCell<Option<usize>> = RefCell::new(None);
}
fn set_invoke_context(new: &mut dyn InvokeContext) {
INVOKE_CONTEXT.with(|invoke_context| unsafe {
invoke_context.replace(Some(transmute::<_, (usize, usize)>(new)))
});
fn set_invoke_context(new: &mut InvokeContext) {
INVOKE_CONTEXT
.with(|invoke_context| unsafe { invoke_context.replace(Some(transmute::<_, usize>(new))) });
}
fn get_invoke_context<'a>() -> &'a mut dyn InvokeContext {
let fat = INVOKE_CONTEXT.with(|invoke_context| match *invoke_context.borrow() {
fn get_invoke_context<'a, 'b>() -> &'a mut InvokeContext<'b> {
let ptr = INVOKE_CONTEXT.with(|invoke_context| match *invoke_context.borrow() {
Some(val) => val,
None => panic!("Invoke context not set!"),
});
unsafe { transmute::<(usize, usize), &mut dyn InvokeContext>(fat) }
unsafe { transmute::<usize, &mut InvokeContext>(ptr) }
}
pub fn builtin_process_instruction(
process_instruction: solana_sdk::entrypoint::ProcessInstruction,
_first_instruction_account: usize,
input: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
set_invoke_context(invoke_context);
@ -187,7 +186,7 @@ macro_rules! processor {
Some(
|first_instruction_account: usize,
input: &[u8],
invoke_context: &mut dyn solana_program_test::InvokeContext| {
invoke_context: &mut solana_program_test::InvokeContext| {
$crate::builtin_process_instruction(
$process_instruction,
first_instruction_account,

View File

@ -11,7 +11,7 @@ use solana_bpf_loader_program::{
ThisInstructionMeter,
};
use solana_measure::measure::Measure;
use solana_program_runtime::invoke_context::{with_mock_invoke_context, InvokeContext};
use solana_program_runtime::invoke_context::with_mock_invoke_context;
use solana_rbpf::{
elf::Executable,
vm::{Config, InstructionMeter, SyscallRegistry},

View File

@ -18,7 +18,7 @@ use solana_bpf_rust_invoke::instructions::*;
use solana_bpf_rust_realloc::instructions::*;
use solana_bpf_rust_realloc_invoke::instructions::*;
use solana_cli_output::display::println_transaction;
use solana_program_runtime::invoke_context::{with_mock_invoke_context, InvokeContext};
use solana_program_runtime::invoke_context::with_mock_invoke_context;
use solana_rbpf::{
elf::Executable,
static_analysis::Analysis,

View File

@ -69,7 +69,7 @@ pub enum BpfError {
}
impl UserDefinedError for BpfError {}
fn map_ebpf_error(invoke_context: &dyn InvokeContext, e: EbpfError<BpfError>) -> InstructionError {
fn map_ebpf_error(invoke_context: &InvokeContext, e: EbpfError<BpfError>) -> InstructionError {
ic_msg!(invoke_context, "{}", e);
InstructionError::InvalidAccountData
}
@ -77,7 +77,7 @@ fn map_ebpf_error(invoke_context: &dyn InvokeContext, e: EbpfError<BpfError>) ->
pub fn create_executor(
programdata_account_index: usize,
programdata_offset: usize,
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
use_jit: bool,
reject_unresolved_syscalls: bool,
) -> Result<Arc<BpfExecutor>, InstructionError> {
@ -123,7 +123,7 @@ fn write_program_data(
program_account_index: usize,
program_data_offset: usize,
bytes: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
let program = keyed_account_at_index(keyed_accounts, program_account_index)?;
@ -150,10 +150,10 @@ fn check_loader_id(id: &Pubkey) -> bool {
}
/// Create the BPF virtual machine
pub fn create_vm<'a>(
pub fn create_vm<'a, 'b>(
program: &'a Executable<BpfError, ThisInstructionMeter>,
parameter_bytes: &mut [u8],
invoke_context: &'a mut dyn InvokeContext,
invoke_context: &'a mut InvokeContext<'b>,
orig_data_lens: &'a [usize],
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
let compute_budget = invoke_context.get_compute_budget();
@ -174,7 +174,7 @@ pub fn create_vm<'a>(
pub fn process_instruction(
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
process_instruction_common(
first_instruction_account,
@ -187,7 +187,7 @@ pub fn process_instruction(
pub fn process_instruction_jit(
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
process_instruction_common(
first_instruction_account,
@ -200,7 +200,7 @@ pub fn process_instruction_jit(
fn process_instruction_common(
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
use_jit: bool,
) -> Result<(), InstructionError> {
let log_collector = invoke_context.get_log_collector();
@ -317,7 +317,7 @@ fn process_instruction_common(
fn process_loader_upgradeable_instruction(
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
use_jit: bool,
) -> Result<(), InstructionError> {
let log_collector = invoke_context.get_log_collector();
@ -867,7 +867,7 @@ fn common_close_account(
fn process_loader_instruction(
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
use_jit: bool,
) -> Result<(), InstructionError> {
let program_id = invoke_context.get_caller()?;
@ -949,11 +949,11 @@ impl Debug for BpfExecutor {
}
impl Executor for BpfExecutor {
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> {
let log_collector = invoke_context.get_log_collector();
@ -1309,7 +1309,7 @@ mod tests {
&keyed_accounts,
|first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext| {
invoke_context: &mut InvokeContext| {
let compute_meter = invoke_context.get_compute_meter();
let remaining = compute_meter.borrow_mut().get_remaining();
compute_meter.borrow_mut().consume(remaining).unwrap();

View File

@ -313,9 +313,7 @@ pub fn deserialize_parameters_aligned(
#[cfg(test)]
mod tests {
use super::*;
use solana_program_runtime::invoke_context::{
prepare_mock_invoke_context, InvokeContext, ThisInvokeContext,
};
use solana_program_runtime::invoke_context::{prepare_mock_invoke_context, InvokeContext};
use solana_sdk::{
account::{Account, AccountSharedData},
account_info::AccountInfo,
@ -448,7 +446,7 @@ mod tests {
let program_indices = [0];
let preparation =
prepare_mock_invoke_context(&program_indices, &instruction_data, &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,

View File

@ -44,7 +44,7 @@ use solana_sdk::{
};
use std::{
alloc::Layout,
cell::{Ref, RefCell, RefMut},
cell::{RefCell, RefMut},
mem::{align_of, size_of},
rc::Rc,
slice::from_raw_parts_mut,
@ -115,7 +115,7 @@ impl SyscallConsume for Rc<RefCell<ComputeMeter>> {
use crate::allocator_bump::BpfAllocator;
pub fn register_syscalls(
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<SyscallRegistry, EbpfError<BpfError>> {
let mut syscall_registry = SyscallRegistry::default();
@ -206,9 +206,9 @@ macro_rules! bind_feature_gated_syscall_context_object {
};
}
pub fn bind_syscall_context_objects<'a>(
pub fn bind_syscall_context_objects<'a, 'b>(
vm: &mut EbpfVm<'a, BpfError, crate::ThisInstructionMeter>,
invoke_context: &'a mut dyn InvokeContext,
invoke_context: &'a mut InvokeContext<'b>,
heap: AlignedMemory,
orig_data_lens: &'a [usize],
) -> Result<(), EbpfError<BpfError>> {
@ -534,10 +534,10 @@ impl SyscallObject<BpfError> for SyscallAbort {
/// Panic syscall function, called when the BPF program calls 'sol_panic_()`
/// Causes the BPF program to be halted immediately
/// Log a user's info message
pub struct SyscallPanic<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallPanic<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallPanic<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallPanic<'a, 'b> {
fn call(
&mut self,
file: u64,
@ -573,10 +573,10 @@ impl<'a> SyscallObject<BpfError> for SyscallPanic<'a> {
}
/// Log a user's info message
pub struct SyscallLog<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallLog<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallLog<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallLog<'a, 'b> {
fn call(
&mut self,
addr: u64,
@ -619,10 +619,10 @@ impl<'a> SyscallObject<BpfError> for SyscallLog<'a> {
}
/// Log 5 64-bit values
pub struct SyscallLogU64<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallLogU64<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallLogU64<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallLogU64<'a, 'b> {
fn call(
&mut self,
arg1: u64,
@ -654,10 +654,10 @@ impl<'a> SyscallObject<BpfError> for SyscallLogU64<'a> {
}
/// Log current compute consumption
pub struct SyscallLogBpfComputeUnits<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallLogBpfComputeUnits<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallLogBpfComputeUnits<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallLogBpfComputeUnits<'a, 'b> {
fn call(
&mut self,
_arg1: u64,
@ -686,10 +686,10 @@ impl<'a> SyscallObject<BpfError> for SyscallLogBpfComputeUnits<'a> {
}
/// Log 5 64-bit values
pub struct SyscallLogPubkey<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallLogPubkey<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallLogPubkey<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallLogPubkey<'a, 'b> {
fn call(
&mut self,
pubkey_addr: u64,
@ -800,10 +800,10 @@ fn translate_and_check_program_address_inputs<'a>(
}
/// Create a program address
struct SyscallCreateProgramAddress<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
struct SyscallCreateProgramAddress<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a, 'b> {
fn call(
&mut self,
seeds_addr: u64,
@ -859,10 +859,10 @@ impl<'a> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a> {
}
/// Create a program address
struct SyscallTryFindProgramAddress<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
struct SyscallTryFindProgramAddress<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a, 'b> {
fn call(
&mut self,
seeds_addr: u64,
@ -932,10 +932,10 @@ impl<'a> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a> {
}
/// SHA256
pub struct SyscallSha256<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallSha256<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallSha256<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
fn call(
&mut self,
vals_addr: u64,
@ -1004,7 +1004,7 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
var_addr: u64,
loader_id: &Pubkey,
memory_mapping: &MemoryMapping,
invoke_context: Rc<RefCell<&mut dyn InvokeContext>>,
invoke_context: Rc<RefCell<&mut InvokeContext>>,
) -> Result<u64, EbpfError<BpfError>> {
let invoke_context = invoke_context
.try_borrow()
@ -1022,10 +1022,10 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
}
/// Get a Clock sysvar
struct SyscallGetClockSysvar<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
struct SyscallGetClockSysvar<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallGetClockSysvar<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallGetClockSysvar<'a, 'b> {
fn call(
&mut self,
var_addr: u64,
@ -1058,10 +1058,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetClockSysvar<'a> {
}
}
/// Get a EpochSchedule sysvar
struct SyscallGetEpochScheduleSysvar<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
struct SyscallGetEpochScheduleSysvar<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a, 'b> {
fn call(
&mut self,
var_addr: u64,
@ -1094,11 +1094,11 @@ impl<'a> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a> {
}
}
/// Get a Fees sysvar
struct SyscallGetFeesSysvar<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
struct SyscallGetFeesSysvar<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
#[allow(deprecated)]
impl<'a> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a, 'b> {
fn call(
&mut self,
var_addr: u64,
@ -1131,10 +1131,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a> {
}
}
/// Get a Rent sysvar
struct SyscallGetRentSysvar<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
struct SyscallGetRentSysvar<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallGetRentSysvar<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallGetRentSysvar<'a, 'b> {
fn call(
&mut self,
var_addr: u64,
@ -1168,10 +1168,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetRentSysvar<'a> {
}
// Keccak256
pub struct SyscallKeccak256<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallKeccak256<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallKeccak256<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
fn call(
&mut self,
vals_addr: u64,
@ -1246,10 +1246,10 @@ fn check_overlapping(src_addr: u64, dst_addr: u64, n: u64) -> bool {
}
/// memcpy
pub struct SyscallMemcpy<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallMemcpy<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallMemcpy<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcpy<'a, 'b> {
fn call(
&mut self,
dst_addr: u64,
@ -1295,10 +1295,10 @@ impl<'a> SyscallObject<BpfError> for SyscallMemcpy<'a> {
}
}
/// memmove
pub struct SyscallMemmove<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallMemmove<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallMemmove<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallMemmove<'a, 'b> {
fn call(
&mut self,
dst_addr: u64,
@ -1339,10 +1339,10 @@ impl<'a> SyscallObject<BpfError> for SyscallMemmove<'a> {
}
}
/// memcmp
pub struct SyscallMemcmp<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallMemcmp<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallMemcmp<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcmp<'a, 'b> {
fn call(
&mut self,
s1_addr: u64,
@ -1396,10 +1396,10 @@ impl<'a> SyscallObject<BpfError> for SyscallMemcmp<'a> {
}
}
/// memset
pub struct SyscallMemset<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallMemset<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallMemset<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallMemset<'a, 'b> {
fn call(
&mut self,
s_addr: u64,
@ -1437,11 +1437,11 @@ impl<'a> SyscallObject<BpfError> for SyscallMemset<'a> {
}
/// secp256k1_recover
pub struct SyscallSecp256k1Recover<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallSecp256k1Recover<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a, 'b> {
fn call(
&mut self,
hash_addr: u64,
@ -1538,10 +1538,10 @@ impl<'a> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a> {
}
// Blake3
pub struct SyscallBlake3<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallBlake3<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallBlake3<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
fn call(
&mut self,
vals_addr: u64,
@ -1629,25 +1629,24 @@ type TranslatedAccounts<'a> = (
);
/// Implemented by language specific data structure translators
trait SyscallInvokeSigned<'a> {
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
trait SyscallInvokeSigned<'a, 'b> {
fn get_context_mut(&self) -> Result<RefMut<&'a mut InvokeContext<'b>>, EbpfError<BpfError>>;
fn translate_instruction(
&self,
loader_id: &Pubkey,
addr: u64,
memory_mapping: &MemoryMapping,
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<Instruction, EbpfError<BpfError>>;
fn translate_accounts(
&self,
fn translate_accounts<'c>(
&'c self,
loader_id: &Pubkey,
message: &Message,
account_infos_addr: u64,
account_infos_len: u64,
memory_mapping: &MemoryMapping,
invoke_context: &mut dyn InvokeContext,
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>;
invoke_context: &mut InvokeContext,
) -> Result<TranslatedAccounts<'c>, EbpfError<BpfError>>;
fn translate_signers(
&self,
loader_id: &Pubkey,
@ -1659,27 +1658,23 @@ trait SyscallInvokeSigned<'a> {
}
/// Cross-program invocation called from Rust
pub struct SyscallInvokeSignedRust<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallInvokeSignedRust<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
orig_data_lens: &'a [usize],
}
impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedRust<'a, 'b> {
fn get_context_mut(&self) -> Result<RefMut<&'a mut InvokeContext<'b>>, EbpfError<BpfError>> {
self.invoke_context
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
}
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
}
fn translate_instruction(
&self,
loader_id: &Pubkey,
addr: u64,
memory_mapping: &MemoryMapping,
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<Instruction, EbpfError<BpfError>> {
let ix = translate_type::<Instruction>(memory_mapping, addr, loader_id)?;
@ -1706,15 +1701,15 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
})
}
fn translate_accounts(
&self,
fn translate_accounts<'c>(
&'c self,
loader_id: &Pubkey,
message: &Message,
account_infos_addr: u64,
account_infos_len: u64,
memory_mapping: &MemoryMapping,
invoke_context: &mut dyn InvokeContext,
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>> {
invoke_context: &mut InvokeContext,
) -> Result<TranslatedAccounts<'c>, EbpfError<BpfError>> {
let account_infos = translate_slice::<AccountInfo>(
memory_mapping,
account_infos_addr,
@ -1733,7 +1728,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
})
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
let translate = |account_info: &AccountInfo, invoke_context: &dyn InvokeContext| {
let translate = |account_info: &AccountInfo, invoke_context: &InvokeContext| {
// Translate the account from user space
let lamports = {
@ -1866,7 +1861,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
}
}
}
impl<'a> SyscallObject<BpfError> for SyscallInvokeSignedRust<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallInvokeSignedRust<'a, 'b> {
fn call(
&mut self,
instruction_addr: u64,
@ -1940,28 +1935,23 @@ struct SolSignerSeedsC {
}
/// Cross-program invocation called from C
pub struct SyscallInvokeSignedC<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallInvokeSignedC<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
orig_data_lens: &'a [usize],
}
impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedC<'a, 'b> {
fn get_context_mut(&self) -> Result<RefMut<&'a mut InvokeContext<'b>>, EbpfError<BpfError>> {
self.invoke_context
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
}
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
}
fn translate_instruction(
&self,
loader_id: &Pubkey,
addr: u64,
memory_mapping: &MemoryMapping,
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<Instruction, EbpfError<BpfError>> {
let ix_c = translate_type::<SolInstruction>(memory_mapping, addr, loader_id)?;
@ -2000,15 +1990,15 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
})
}
fn translate_accounts(
&self,
fn translate_accounts<'c>(
&'c self,
loader_id: &Pubkey,
message: &Message,
account_infos_addr: u64,
account_infos_len: u64,
memory_mapping: &MemoryMapping,
invoke_context: &mut dyn InvokeContext,
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>> {
invoke_context: &mut InvokeContext,
) -> Result<TranslatedAccounts<'c>, EbpfError<BpfError>> {
let account_infos = translate_slice::<SolAccountInfo>(
memory_mapping,
account_infos_addr,
@ -2023,7 +2013,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
})
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
let translate = |account_info: &SolAccountInfo, invoke_context: &dyn InvokeContext| {
let translate = |account_info: &SolAccountInfo, invoke_context: &InvokeContext| {
// Translate the account from user space
let lamports =
@ -2133,7 +2123,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
}
}
}
impl<'a> SyscallObject<BpfError> for SyscallInvokeSignedC<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallInvokeSignedC<'a, 'b> {
fn call(
&mut self,
instruction_addr: u64,
@ -2160,12 +2150,12 @@ fn get_translated_accounts<'a, T, F>(
message: &Message,
account_info_keys: &[&Pubkey],
account_infos: &[T],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
orig_data_lens: &[usize],
do_translate: F,
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>
where
F: Fn(&T, &dyn InvokeContext) -> Result<CallerAccount<'a>, EbpfError<BpfError>>,
F: Fn(&T, &InvokeContext) -> Result<CallerAccount<'a>, EbpfError<BpfError>>,
{
let demote_program_write_locks =
invoke_context.is_feature_active(&demote_program_write_locks::id());
@ -2248,7 +2238,7 @@ where
fn check_instruction_size(
num_accounts: usize,
data_len: usize,
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), EbpfError<BpfError>> {
let size = num_accounts
.saturating_mul(size_of::<AccountMeta>())
@ -2262,7 +2252,7 @@ fn check_instruction_size(
fn check_account_infos(
len: usize,
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), EbpfError<BpfError>> {
if len * size_of::<Pubkey>() > invoke_context.get_compute_budget().max_cpi_instruction_size {
// Cap the number of account_infos a caller can pass to approximate
@ -2275,7 +2265,7 @@ fn check_account_infos(
fn check_authorized_program(
program_id: &Pubkey,
instruction_data: &[u8],
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), EbpfError<BpfError>> {
#[allow(clippy::blocks_in_if_conditions)]
if native_loader::check_id(program_id)
@ -2296,8 +2286,8 @@ fn check_authorized_program(
}
/// Call process instruction, common to both Rust and C
fn call<'a>(
syscall: &mut dyn SyscallInvokeSigned<'a>,
fn call<'a, 'b: 'a>(
syscall: &mut dyn SyscallInvokeSigned<'a, 'b>,
instruction_addr: u64,
account_infos_addr: u64,
account_infos_len: u64,
@ -2413,10 +2403,10 @@ fn call<'a>(
}
// Return data handling
pub struct SyscallSetReturnData<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallSetReturnData<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallSetReturnData<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
fn call(
&mut self,
addr: u64,
@ -2474,10 +2464,10 @@ impl<'a> SyscallObject<BpfError> for SyscallSetReturnData<'a> {
}
}
pub struct SyscallGetReturnData<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallGetReturnData<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallGetReturnData<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
fn call(
&mut self,
return_data_addr: u64,
@ -2541,10 +2531,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetReturnData<'a> {
}
// Log data handling
pub struct SyscallLogData<'a> {
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
pub struct SyscallLogData<'a, 'b> {
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
}
impl<'a> SyscallObject<BpfError> for SyscallLogData<'a> {
impl<'a, 'b> SyscallObject<BpfError> for SyscallLogData<'a, 'b> {
fn call(
&mut self,
addr: u64,
@ -2624,7 +2614,7 @@ impl<'a> SyscallObject<BpfError> for SyscallLogData<'a> {
#[cfg(test)]
mod tests {
use super::*;
use solana_program_runtime::invoke_context::ThisInvokeContext;
use solana_program_runtime::invoke_context::InvokeContext;
use solana_rbpf::{
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
};
@ -2945,7 +2935,7 @@ mod tests {
&[Instruction::new_with_bytes(program_id, &[], vec![])],
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();
@ -3022,7 +3012,7 @@ mod tests {
&[Instruction::new_with_bytes(program_id, &[], vec![])],
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();
@ -3126,7 +3116,7 @@ mod tests {
&[Instruction::new_with_bytes(program_id, &[], vec![])],
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();
@ -3168,7 +3158,7 @@ mod tests {
&[Instruction::new_with_bytes(program_id, &[], vec![])],
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();
@ -3433,7 +3423,7 @@ mod tests {
)
.unwrap();
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
invoke_context
.get_compute_meter()
.borrow_mut()
@ -3540,7 +3530,7 @@ mod tests {
let mut data = vec![];
bincode::serialize_into(&mut data, &src_clock).unwrap();
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
@ -3589,7 +3579,7 @@ mod tests {
let mut data = vec![];
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
let sysvars = [(sysvar::epoch_schedule::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
@ -3645,7 +3635,7 @@ mod tests {
let mut data = vec![];
bincode::serialize_into(&mut data, &src_fees).unwrap();
let sysvars = [(sysvar::fees::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
@ -3692,7 +3682,7 @@ mod tests {
let mut data = vec![];
bincode::serialize_into(&mut data, &src_rent).unwrap();
let sysvars = [(sysvar::rent::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
@ -3802,7 +3792,7 @@ mod tests {
}
fn create_program_address(
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
seeds: &[&[u8]],
address: &Pubkey,
) -> Result<Pubkey, EbpfError<BpfError>> {
@ -3814,7 +3804,7 @@ mod tests {
}
fn try_find_program_address(
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
seeds: &[&[u8]],
address: &Pubkey,
) -> Result<(Pubkey, u8), EbpfError<BpfError>> {
@ -3835,7 +3825,7 @@ mod tests {
&[Instruction::new_with_bytes(program_id, &[], vec![])],
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();
@ -3951,7 +3941,7 @@ mod tests {
&[Instruction::new_with_bytes(program_id, &[], vec![])],
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();

View File

@ -4,7 +4,7 @@ use solana_sdk::instruction::InstructionError;
pub fn process_instruction(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
// Do nothing, compute budget instructions handled by the runtime
Ok(())

View File

@ -16,7 +16,7 @@ use std::collections::BTreeSet;
pub fn process_instruction(
first_instruction_account: usize,
data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;

View File

@ -25,7 +25,7 @@ pub use solana_sdk::stake::instruction::*;
pub fn process_instruction(
first_instruction_account: usize,
data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
@ -327,7 +327,7 @@ mod tests {
use crate::stake_state::{Meta, StakeState};
use bincode::serialize;
use solana_program_runtime::invoke_context::{
mock_process_instruction, prepare_mock_invoke_context, ThisInvokeContext,
mock_process_instruction, prepare_mock_invoke_context, InvokeContext,
};
use solana_sdk::{
account::{self, AccountSharedData},
@ -416,7 +416,7 @@ mod tests {
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&preparation.accounts,
&[],
&sysvars,
@ -1066,7 +1066,7 @@ mod tests {
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&preparation.accounts,
&[],
&sysvars,

View File

@ -395,7 +395,7 @@ pub trait StakeAccount {
) -> Result<(), InstructionError>;
fn merge(
&self,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
source_stake: &KeyedAccount,
clock: &Clock,
stake_history: &StakeHistory,
@ -701,7 +701,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
fn merge(
&self,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
source_account: &KeyedAccount,
clock: &Clock,
stake_history: &StakeHistory,
@ -865,7 +865,7 @@ impl MergeKind {
}
fn get_if_mergeable(
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
stake_keyed_account: &KeyedAccount,
clock: &Clock,
stake_history: &StakeHistory,
@ -897,7 +897,7 @@ impl MergeKind {
}
fn metas_can_merge(
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
stake: &Meta,
source: &Meta,
clock: Option<&Clock>,
@ -926,7 +926,7 @@ impl MergeKind {
}
fn active_delegations_can_merge(
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
stake: &Delegation,
source: &Delegation,
) -> Result<(), InstructionError> {
@ -946,7 +946,7 @@ impl MergeKind {
// Remove this when the `stake_merge_with_unmatched_credits_observed` feature is removed
fn active_stakes_can_merge(
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
stake: &Stake,
source: &Stake,
) -> Result<(), InstructionError> {
@ -969,7 +969,7 @@ impl MergeKind {
fn merge(
self,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
source: Self,
clock: Option<&Clock>,
) -> Result<Option<StakeState>, InstructionError> {
@ -1033,7 +1033,7 @@ impl MergeKind {
}
fn merge_delegation_stake_and_credits_observed(
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
stake: &mut Stake,
absorbed_lamports: u64,
absorbed_credits_observed: u64,
@ -1372,7 +1372,7 @@ fn do_create_account(
mod tests {
use super::*;
use proptest::prelude::*;
use solana_program_runtime::invoke_context::ThisInvokeContext;
use solana_program_runtime::invoke_context::InvokeContext;
use solana_sdk::{
account::{AccountSharedData, WritableAccount},
clock::UnixTimestamp,
@ -5068,7 +5068,7 @@ mod tests {
#[test]
fn test_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
@ -5178,7 +5178,7 @@ mod tests {
#[test]
fn test_merge_self_fails() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let stake_address = Pubkey::new_unique();
let authority_pubkey = Pubkey::new_unique();
let signers = HashSet::from_iter(vec![authority_pubkey]);
@ -5223,7 +5223,7 @@ mod tests {
#[test]
fn test_merge_incorrect_authorized_staker() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
@ -5292,7 +5292,7 @@ mod tests {
#[test]
fn test_merge_invalid_account_data() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
@ -5342,7 +5342,7 @@ mod tests {
#[test]
fn test_merge_fake_stake_source() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
@ -5384,7 +5384,7 @@ mod tests {
#[test]
fn test_merge_active_stake() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let base_lamports = 4242424242;
let stake_address = Pubkey::new_unique();
let source_address = Pubkey::new_unique();
@ -5453,7 +5453,7 @@ mod tests {
);
fn try_merge(
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
stake_account: &KeyedAccount,
source_account: &KeyedAccount,
clock: &Clock,
@ -6006,7 +6006,7 @@ mod tests {
#[test]
fn test_things_can_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let good_stake = Stake {
credits_observed: 4242,
delegation: Delegation {
@ -6104,7 +6104,7 @@ mod tests {
#[test]
fn test_metas_can_merge_pre_v4() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// Identical Metas can merge
assert!(MergeKind::metas_can_merge(
&invoke_context,
@ -6190,7 +6190,7 @@ mod tests {
#[test]
fn test_metas_can_merge_v4() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// Identical Metas can merge
assert!(MergeKind::metas_can_merge(
&invoke_context,
@ -6336,7 +6336,7 @@ mod tests {
#[test]
fn test_merge_kind_get_if_mergeable() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let authority_pubkey = Pubkey::new_unique();
let initial_lamports = 4242424242;
let rent = Rent::default();
@ -6568,7 +6568,7 @@ mod tests {
#[test]
fn test_merge_kind_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let lamports = 424242;
let meta = Meta {
rent_exempt_reserve: 42,
@ -6646,7 +6646,7 @@ mod tests {
#[test]
fn test_active_stake_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let delegation_a = 4_242_424_242u64;
let delegation_b = 6_200_000_000u64;
let credits_a = 124_521_000u64;

View File

@ -310,7 +310,7 @@ fn verify_rent_exemption(
pub fn process_instruction(
first_instruction_account: usize,
data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;

View File

@ -5,9 +5,7 @@ use solana_bpf_loader_program::{
create_vm, serialization::serialize_parameters, syscalls::register_syscalls, BpfError,
ThisInstructionMeter,
};
use solana_program_runtime::invoke_context::{
prepare_mock_invoke_context, InvokeContext, ThisInvokeContext,
};
use solana_program_runtime::invoke_context::{prepare_mock_invoke_context, InvokeContext};
use solana_rbpf::{
assembler::assemble,
elf::Executable,
@ -202,7 +200,7 @@ native machine code before execting it in the virtual machine.",
};
let program_indices = [0, 1];
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,

View File

@ -34,7 +34,7 @@ const NOOP_PROGRAM_ID: [u8; 32] = [
fn process_instruction(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
Ok(())
}

View File

@ -6958,7 +6958,7 @@ pub(crate) mod tests {
fn mock_process_instruction(
first_instruction_account: usize,
data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> result::Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
if let Ok(instruction) = bincode::deserialize(data) {
@ -10709,7 +10709,7 @@ pub(crate) mod tests {
fn mock_vote_processor(
_first_instruction_account: usize,
_instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
let program_id = invoke_context.get_caller()?;
if mock_vote_program_id() != *program_id {
@ -10767,7 +10767,7 @@ pub(crate) mod tests {
fn mock_vote_processor(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
Err(InstructionError::Custom(42))
}
@ -10817,7 +10817,7 @@ pub(crate) mod tests {
fn mock_ix_processor(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
Err(InstructionError::Custom(42))
}
@ -11705,7 +11705,7 @@ pub(crate) mod tests {
fn mock_process_instruction(
first_instruction_account: usize,
data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> result::Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
let lamports = data[0] as u64;
@ -11763,7 +11763,7 @@ pub(crate) mod tests {
fn mock_process_instruction(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> result::Result<(), InstructionError> {
Ok(())
}
@ -11949,7 +11949,7 @@ pub(crate) mod tests {
fn mock_ok_vote_processor(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
Ok(())
}
@ -12199,7 +12199,7 @@ pub(crate) mod tests {
fn nested_processor(
first_instruction_account: usize,
_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> result::Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
let account = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
@ -12473,7 +12473,7 @@ pub(crate) mod tests {
fn mock_ix_processor(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
Ok(())
}
@ -12522,7 +12522,7 @@ pub(crate) mod tests {
fn mock_ix_processor(
_first_instruction_account: usize,
_data: &[u8],
_context: &mut dyn InvokeContext,
_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
Ok(())
}
@ -12899,11 +12899,11 @@ pub(crate) mod tests {
#[derive(Debug)]
struct TestExecutor {}
impl Executor for TestExecutor {
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,
) -> std::result::Result<(), InstructionError> {
Ok(())
@ -13422,7 +13422,7 @@ pub(crate) mod tests {
fn mock_process_instruction(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
Ok(())
}
@ -14923,7 +14923,7 @@ pub(crate) mod tests {
fn mock_ix_processor(
first_instruction_account: usize,
_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
use solana_sdk::account::WritableAccount;
let keyed_accounts = invoke_context.get_keyed_accounts()?;
@ -15135,7 +15135,7 @@ pub(crate) mod tests {
fn mock_ix_processor(
_first_instruction_account: usize,
_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
let compute_budget = invoke_context.get_compute_budget();
assert_eq!(
@ -15180,7 +15180,7 @@ pub(crate) mod tests {
fn mock_ix_processor(
_first_instruction_account: usize,
_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), InstructionError> {
let compute_budget = invoke_context.get_compute_budget();
assert_eq!(

View File

@ -15,7 +15,7 @@ fn process_instruction_with_program_logging(
process_instruction: ProcessInstructionWithContext,
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let logger = invoke_context.get_log_collector();
let program_id = invoke_context.get_caller()?;
@ -35,7 +35,7 @@ macro_rules! with_program_logging {
($process_instruction:expr) => {
|first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext| {
invoke_context: &mut InvokeContext| {
process_instruction_with_program_logging(
$process_instruction,
first_instruction_account,
@ -135,7 +135,7 @@ fn genesis_builtins() -> Vec<Builtin> {
fn dummy_process_instruction(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
Ok(())
}

View File

@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
use solana_measure::measure::Measure;
use solana_program_runtime::{
instruction_recorder::InstructionRecorder,
invoke_context::{BuiltinProgram, ComputeMeter, Executors, InvokeContext, ThisInvokeContext},
invoke_context::{BuiltinProgram, ComputeMeter, Executors, InvokeContext},
log_collector::LogCollector,
timings::ExecuteDetailsTimings,
};
@ -56,7 +56,7 @@ impl MessageProcessor {
blockhash: Hash,
lamports_per_signature: u64,
) -> Result<(), TransactionError> {
let mut invoke_context = ThisInvokeContext::new(
let mut invoke_context = InvokeContext::new(
rent,
accounts,
builtin_programs,
@ -165,7 +165,7 @@ mod tests {
fn mock_system_process_instruction(
first_instruction_account: usize,
data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
if let Ok(instruction) = bincode::deserialize(data) {
@ -336,7 +336,7 @@ mod tests {
fn mock_system_process_instruction(
first_instruction_account: usize,
data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
if let Ok(instruction) = bincode::deserialize(data) {
@ -537,7 +537,7 @@ mod tests {
fn mock_process_instruction(
_first_instruction_account: usize,
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
_invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
Err(InstructionError::Custom(0xbabb1e))
}

View File

@ -16,7 +16,7 @@ pub trait NonceKeyedAccount {
fn advance_nonce_account(
&self,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
fn withdraw_nonce_account(
&self,
@ -24,19 +24,19 @@ pub trait NonceKeyedAccount {
to: &KeyedAccount,
rent: &Rent,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
fn initialize_nonce_account(
&self,
nonce_authority: &Pubkey,
rent: &Rent,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
fn authorize_nonce_account(
&self,
nonce_authority: &Pubkey,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
}
@ -44,7 +44,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
fn advance_nonce_account(
&self,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
let merge_nonce_error_into_system_error = invoke_context
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
@ -108,7 +108,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
to: &KeyedAccount,
rent: &Rent,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
let merge_nonce_error_into_system_error = invoke_context
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
@ -194,7 +194,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
&self,
nonce_authority: &Pubkey,
rent: &Rent,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
let merge_nonce_error_into_system_error = invoke_context
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
@ -245,7 +245,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
&self,
nonce_authority: &Pubkey,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
let merge_nonce_error_into_system_error = invoke_context
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
@ -294,7 +294,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
#[cfg(test)]
mod test {
use super::*;
use solana_program_runtime::invoke_context::ThisInvokeContext;
use solana_program_runtime::invoke_context::InvokeContext;
use solana_sdk::{
account::ReadableAccount,
account_utils::State as AccountUtilsState,
@ -322,8 +322,8 @@ mod test {
)
}
fn create_invoke_context_with_blockhash<'a>(seed: usize) -> ThisInvokeContext<'a> {
let mut invoke_context = ThisInvokeContext::new_mock(&[], &[]);
fn create_invoke_context_with_blockhash<'a>(seed: usize) -> InvokeContext<'a> {
let mut invoke_context = InvokeContext::new_mock(&[], &[]);
let (blockhash, lamports_per_signature) = create_test_blockhash(seed);
invoke_context.set_blockhash(blockhash);
invoke_context.set_lamports_per_signature(lamports_per_signature);
@ -1017,7 +1017,7 @@ mod test {
let result = nonce_account.authorize_nonce_account(
&Pubkey::default(),
&signers,
&ThisInvokeContext::new_mock(&[], &[]),
&InvokeContext::new_mock(&[], &[]),
);
assert_eq!(result, Err(InstructionError::InvalidAccountData));
})

View File

@ -35,7 +35,7 @@ impl Address {
fn create(
address: &Pubkey,
with_seed: Option<(&Pubkey, &str, &Pubkey)>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<Self, InstructionError> {
let base = if let Some((base, seed, owner)) = with_seed {
let address_with_seed = Pubkey::create_with_seed(base, seed, owner)?;
@ -66,7 +66,7 @@ fn allocate(
address: &Address,
space: u64,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
if !address.is_signer(signers) {
ic_msg!(
@ -108,7 +108,7 @@ fn assign(
address: &Address,
owner: &Pubkey,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
// no work to do, just return
if account.owner() == owner {
@ -141,7 +141,7 @@ fn allocate_and_assign(
space: u64,
owner: &Pubkey,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
allocate(to, to_address, space, signers, invoke_context)?;
assign(to, to_address, owner, signers, invoke_context)
@ -155,7 +155,7 @@ fn create_account(
space: u64,
owner: &Pubkey,
signers: &HashSet<Pubkey>,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
// if it looks like the `to` account is already in use, bail
{
@ -178,7 +178,7 @@ fn transfer_verified(
from: &KeyedAccount,
to: &KeyedAccount,
lamports: u64,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
if !from.data_is_empty()? {
ic_msg!(invoke_context, "Transfer: `from` must not carry data");
@ -203,7 +203,7 @@ fn transfer(
from: &KeyedAccount,
to: &KeyedAccount,
lamports: u64,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
if !invoke_context.is_feature_active(&feature_set::system_transfer_zero_check::id())
&& lamports == 0
@ -230,7 +230,7 @@ fn transfer_with_seed(
from_owner: &Pubkey,
to: &KeyedAccount,
lamports: u64,
invoke_context: &dyn InvokeContext,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError> {
if !invoke_context.is_feature_active(&feature_set::system_transfer_zero_check::id())
&& lamports == 0
@ -265,7 +265,7 @@ fn transfer_with_seed(
pub fn process_instruction(
first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
let instruction = limited_deserialize(instruction_data)?;
@ -481,7 +481,7 @@ mod tests {
use super::*;
use crate::{bank::Bank, bank_client::BankClient};
use bincode::serialize;
use solana_program_runtime::invoke_context::{mock_process_instruction, ThisInvokeContext};
use solana_program_runtime::invoke_context::{mock_process_instruction, InvokeContext};
#[allow(deprecated)]
use solana_sdk::{
account::{self, Account, AccountSharedData},
@ -638,7 +638,7 @@ mod tests {
#[test]
fn test_address_create_with_seed_mismatch() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let from = Pubkey::new_unique();
let seed = "dull boy";
let to = Pubkey::new_unique();
@ -652,7 +652,7 @@ mod tests {
#[test]
fn test_create_account_with_seed_missing_sig() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let new_owner = Pubkey::new(&[9; 32]);
let from = Pubkey::new_unique();
let seed = "dull boy";
@ -682,7 +682,7 @@ mod tests {
#[test]
fn test_create_with_zero_lamports() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// create account with zero lamports transferred
let new_owner = Pubkey::new(&[9; 32]);
let from = Pubkey::new_unique();
@ -716,7 +716,7 @@ mod tests {
#[test]
fn test_create_negative_lamports() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// Attempt to create account with more lamports than remaining in from_account
let new_owner = Pubkey::new(&[9; 32]);
let from = Pubkey::new_unique();
@ -740,7 +740,7 @@ mod tests {
#[test]
fn test_request_more_than_allowed_data_length() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let from_account = AccountSharedData::new_ref(100, 0, &system_program::id());
let from = Pubkey::new_unique();
let to_account = AccountSharedData::new_ref(0, 0, &system_program::id());
@ -787,7 +787,7 @@ mod tests {
#[test]
fn test_create_already_in_use() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// Attempt to create system account in account already owned by another program
let new_owner = Pubkey::new(&[9; 32]);
let from = Pubkey::new_unique();
@ -855,7 +855,7 @@ mod tests {
#[test]
fn test_create_unsigned() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// Attempt to create an account without signing the transfer
let new_owner = Pubkey::new(&[9; 32]);
let from = Pubkey::new_unique();
@ -910,7 +910,7 @@ mod tests {
#[test]
fn test_create_sysvar_invalid_id_with_feature() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// Attempt to create system account in account already owned by another program
let from = Pubkey::new_unique();
let from_account = AccountSharedData::new_ref(100, 0, &system_program::id());
@ -944,12 +944,8 @@ mod tests {
feature_set
.inactive
.insert(feature_set::rent_for_sysvars::id());
let invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&[],
&[],
&[],
Arc::new(feature_set),
);
let invoke_context =
InvokeContext::new_mock_with_sysvars_and_features(&[], &[], &[], Arc::new(feature_set));
// Attempt to create system account in account already owned by another program
let from = Pubkey::new_unique();
let from_account = AccountSharedData::new_ref(100, 0, &system_program::id());
@ -975,7 +971,7 @@ mod tests {
#[test]
fn test_create_data_populated() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
// Attempt to create system account in account with populated data
let new_owner = Pubkey::new(&[9; 32]);
let from = Pubkey::new_unique();
@ -1009,7 +1005,7 @@ mod tests {
#[test]
fn test_create_from_account_is_nonce_fail() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let nonce = Pubkey::new_unique();
let nonce_account = AccountSharedData::new_ref_data(
42,
@ -1045,7 +1041,7 @@ mod tests {
#[test]
fn test_assign() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let new_owner = Pubkey::new(&[9; 32]);
let pubkey = Pubkey::new_unique();
let mut account = AccountSharedData::new(100, 0, &system_program::id());
@ -1085,7 +1081,7 @@ mod tests {
#[test]
fn test_assign_to_sysvar_with_feature() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let new_owner = sysvar::id();
let from = Pubkey::new_unique();
let mut from_account = AccountSharedData::new(100, 0, &system_program::id());
@ -1111,12 +1107,8 @@ mod tests {
feature_set
.inactive
.insert(feature_set::rent_for_sysvars::id());
let invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&[],
&[],
&[],
Arc::new(feature_set),
);
let invoke_context =
InvokeContext::new_mock_with_sysvars_and_features(&[], &[], &[], Arc::new(feature_set));
let new_owner = sysvar::id();
let from = Pubkey::new_unique();
let mut from_account = AccountSharedData::new(100, 0, &system_program::id());
@ -1154,7 +1146,7 @@ mod tests {
#[test]
fn test_transfer_lamports() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let from = Pubkey::new_unique();
let from_account = AccountSharedData::new_ref(100, 0, &Pubkey::new(&[2; 32])); // account owner should not matter
let to = Pubkey::new(&[3; 32]);
@ -1192,7 +1184,7 @@ mod tests {
#[test]
fn test_transfer_with_seed() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let base = Pubkey::new_unique();
let base_account = AccountSharedData::new_ref(100, 0, &Pubkey::new(&[2; 32])); // account owner should not matter
let from_base_keyed_account = KeyedAccount::new(&base, true, &base_account);
@ -1252,7 +1244,7 @@ mod tests {
#[test]
fn test_transfer_lamports_from_nonce_account_fail() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let invoke_context = InvokeContext::new_mock(&[], &[]);
let from = Pubkey::new_unique();
let from_account = AccountSharedData::new_ref_data(
100,
@ -1582,7 +1574,7 @@ mod tests {
&keyed_accounts,
|first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext| {
invoke_context: &mut InvokeContext| {
invoke_context.set_blockhash(hash(&serialize(&0).unwrap()));
super::process_instruction(
first_instruction_account,
@ -1998,7 +1990,7 @@ mod tests {
&keyed_accounts,
|first_instruction_account: usize,
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext| {
invoke_context: &mut InvokeContext| {
invoke_context.set_blockhash(hash(&serialize(&0).unwrap()));
super::process_instruction(
first_instruction_account,