Unifies ThisInvokeContext and dyn trait InvokeContext. (#21563)
This commit is contained in:
committed by
GitHub
parent
8dfa83c579
commit
bfdb775ffc
@ -24,7 +24,7 @@ use solana_client::{
|
|||||||
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
|
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
|
||||||
tpu_client::{TpuClient, TpuClientConfig},
|
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_rbpf::{elf::Executable, verifier, vm::Config};
|
||||||
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
||||||
use solana_sdk::{
|
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();
|
let mut program_data = Vec::new();
|
||||||
file.read_to_end(&mut program_data)
|
file.read_to_end(&mut program_data)
|
||||||
.map_err(|err| format!("Unable to read program file: {}", err))?;
|
.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
|
// Verify the program
|
||||||
Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||||
|
@ -22,7 +22,7 @@ use solana_sdk::{
|
|||||||
use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
pub type ProcessInstructionWithContext =
|
pub type ProcessInstructionWithContext =
|
||||||
fn(usize, &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
|
fn(usize, &[u8], &mut InvokeContext) -> Result<(), InstructionError>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BuiltinProgram {
|
pub struct BuiltinProgram {
|
||||||
@ -36,7 +36,7 @@ impl std::fmt::Debug for BuiltinProgram {
|
|||||||
type ErasedProcessInstructionWithContext = fn(
|
type ErasedProcessInstructionWithContext = fn(
|
||||||
usize,
|
usize,
|
||||||
&'static [u8],
|
&'static [u8],
|
||||||
&'static mut dyn InvokeContext,
|
&'static mut InvokeContext<'static>,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
|
|
||||||
// rustc doesn't compile due to bug without this work around
|
// rustc doesn't compile due to bug without this work around
|
||||||
@ -50,11 +50,11 @@ impl std::fmt::Debug for BuiltinProgram {
|
|||||||
/// Program executor
|
/// Program executor
|
||||||
pub trait Executor: Debug + Send + Sync {
|
pub trait Executor: Debug + Send + Sync {
|
||||||
/// Execute the program
|
/// Execute the program
|
||||||
fn execute(
|
fn execute<'a, 'b>(
|
||||||
&self,
|
&self,
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &'a mut InvokeContext<'b>,
|
||||||
use_jit: bool,
|
use_jit: bool,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ impl<'a> StackFrame<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ThisInvokeContext<'a> {
|
pub struct InvokeContext<'a> {
|
||||||
instruction_index: usize,
|
instruction_index: usize,
|
||||||
invoke_stack: Vec<StackFrame<'a>>,
|
invoke_stack: Vec<StackFrame<'a>>,
|
||||||
rent: Rent,
|
rent: Rent,
|
||||||
@ -150,7 +150,8 @@ pub struct ThisInvokeContext<'a> {
|
|||||||
lamports_per_signature: u64,
|
lamports_per_signature: u64,
|
||||||
return_data: (Pubkey, Vec<u8>),
|
return_data: (Pubkey, Vec<u8>),
|
||||||
}
|
}
|
||||||
impl<'a> ThisInvokeContext<'a> {
|
|
||||||
|
impl<'a> InvokeContext<'a> {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
rent: Rent,
|
rent: Rent,
|
||||||
@ -221,117 +222,9 @@ impl<'a> ThisInvokeContext<'a> {
|
|||||||
Arc::new(FeatureSet::all_enabled()),
|
Arc::new(FeatureSet::all_enabled()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Invocation context passed to loaders
|
|
||||||
pub trait InvokeContext {
|
|
||||||
/// Push a stack frame onto the invocation stack
|
/// Push a stack frame onto the invocation stack
|
||||||
fn push(
|
pub 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(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
@ -430,13 +323,19 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
));
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn pop(&mut self) {
|
|
||||||
|
/// Pop a stack frame from the invocation stack
|
||||||
|
pub fn pop(&mut self) {
|
||||||
self.invoke_stack.pop();
|
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()
|
self.invoke_stack.len()
|
||||||
}
|
}
|
||||||
fn verify(
|
|
||||||
|
/// Verify the results of an instruction
|
||||||
|
pub fn verify(
|
||||||
&mut self,
|
&mut self,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
@ -501,7 +400,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn verify_and_update(
|
|
||||||
|
/// Verify and update PreAccount state based on program execution
|
||||||
|
pub fn verify_and_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
account_indices: &[usize],
|
account_indices: &[usize],
|
||||||
@ -580,7 +481,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn native_invoke(
|
|
||||||
|
/// Entrypoint for a cross-program invocation from a builtin program
|
||||||
|
pub fn native_invoke(
|
||||||
&mut self,
|
&mut self,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
signers: &[Pubkey],
|
signers: &[Pubkey],
|
||||||
@ -623,7 +526,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn create_message(
|
|
||||||
|
/// Helper to prepare for process_cross_program_instruction()
|
||||||
|
pub fn create_message(
|
||||||
&mut self,
|
&mut self,
|
||||||
instruction: &Instruction,
|
instruction: &Instruction,
|
||||||
signers: &[Pubkey],
|
signers: &[Pubkey],
|
||||||
@ -734,7 +639,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
|
|
||||||
Ok((message, caller_write_privileges, program_indices))
|
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,
|
&mut self,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
program_indices: &[usize],
|
program_indices: &[usize],
|
||||||
@ -766,7 +673,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
self.pop();
|
self.pop();
|
||||||
result
|
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 keyed_accounts = self.get_keyed_accounts()?;
|
||||||
let root_account = keyed_account_at_index(keyed_accounts, 0)
|
let root_account = keyed_account_at_index(keyed_accounts, 0)
|
||||||
.map_err(|_| InstructionError::UnsupportedProgramId)?;
|
.map_err(|_| InstructionError::UnsupportedProgramId)?;
|
||||||
@ -802,18 +711,28 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
}
|
}
|
||||||
Err(InstructionError::UnsupportedProgramId)
|
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
|
self.invoke_stack
|
||||||
.last()
|
.last()
|
||||||
.and_then(|frame| frame.program_id())
|
.and_then(|frame| frame.program_id())
|
||||||
.ok_or(InstructionError::CallDepth)
|
.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()
|
self.get_instruction_keyed_accounts()
|
||||||
.and_then(|keyed_accounts| keyed_accounts.first().ok_or(InstructionError::CallDepth))
|
.and_then(|keyed_accounts| keyed_accounts.first().ok_or(InstructionError::CallDepth))
|
||||||
.and_then(|keyed_account| keyed_account.owner())
|
.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()) {
|
if !self.is_feature_active(&remove_native_loader::id()) {
|
||||||
let stack_frame = &mut self
|
let stack_frame = &mut self
|
||||||
.invoke_stack
|
.invoke_stack
|
||||||
@ -824,13 +743,17 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
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
|
self.invoke_stack
|
||||||
.last()
|
.last()
|
||||||
.map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()])
|
.map(|frame| &frame.keyed_accounts[frame.keyed_accounts_range.clone()])
|
||||||
.ok_or(InstructionError::CallDepth)
|
.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
|
let frame = self
|
||||||
.invoke_stack
|
.invoke_stack
|
||||||
.last()
|
.last()
|
||||||
@ -841,30 +764,47 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
.ok_or(InstructionError::CallDepth)?;
|
.ok_or(InstructionError::CallDepth)?;
|
||||||
Ok(&frame.keyed_accounts[first_instruction_account..])
|
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()
|
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()
|
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);
|
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)
|
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;
|
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 {
|
if let Some(instruction_recorders) = &self.instruction_recorders {
|
||||||
instruction_recorders[self.instruction_index].record_instruction(instruction.clone());
|
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)
|
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() {
|
for (index, (key, account)) in self.accounts.iter().enumerate().rev() {
|
||||||
if key == pubkey {
|
if key == pubkey {
|
||||||
return Some((index, account.clone()));
|
return Some((index, account.clone()));
|
||||||
@ -872,7 +812,9 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn update_timing(
|
|
||||||
|
/// Update timing
|
||||||
|
pub fn update_timing(
|
||||||
&mut self,
|
&mut self,
|
||||||
serialize_us: u64,
|
serialize_us: u64,
|
||||||
create_vm_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.execute_us = self.timings.execute_us.saturating_add(execute_us);
|
||||||
self.timings.deserialize_us = self.timings.deserialize_us.saturating_add(deserialize_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
|
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
|
&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;
|
self.blockhash = hash;
|
||||||
}
|
}
|
||||||
fn get_blockhash(&self) -> &Hash {
|
|
||||||
|
/// Get this invocation's blockhash
|
||||||
|
pub fn get_blockhash(&self) -> &Hash {
|
||||||
&self.blockhash
|
&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;
|
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
|
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);
|
self.return_data = (*self.get_caller()?, data);
|
||||||
Ok(())
|
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)
|
(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,
|
// This method which has a generic parameter is outside of the InvokeContext,
|
||||||
// because the InvokeContext is a dyn Trait.
|
// because the InvokeContext is a dyn Trait.
|
||||||
pub fn get_sysvar<T: Sysvar>(
|
pub fn get_sysvar<T: Sysvar>(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
id: &Pubkey,
|
id: &Pubkey,
|
||||||
) -> Result<T, InstructionError> {
|
) -> Result<T, InstructionError> {
|
||||||
invoke_context
|
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,
|
loader_id: Pubkey,
|
||||||
account_size: usize,
|
account_size: usize,
|
||||||
mut callback: F,
|
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 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
|
invoke_context
|
||||||
.push(
|
.push(
|
||||||
&preparation.message,
|
&preparation.message,
|
||||||
@ -1045,7 +1003,7 @@ pub fn mock_process_instruction(
|
|||||||
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
|
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
|
||||||
program_indices.insert(0, preparation.accounts.len());
|
program_indices.insert(0, preparation.accounts.len());
|
||||||
preparation.accounts.push((*loader_id, processor_account));
|
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(
|
invoke_context.push(
|
||||||
&preparation.message,
|
&preparation.message,
|
||||||
&preparation.message.instructions[0],
|
&preparation.message.instructions[0],
|
||||||
@ -1081,7 +1039,7 @@ mod tests {
|
|||||||
fn mock_process_instruction(
|
fn mock_process_instruction(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1089,7 +1047,7 @@ mod tests {
|
|||||||
fn mock_ix_processor(
|
fn mock_ix_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_context: &mut dyn InvokeContext,
|
_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1110,7 +1068,7 @@ mod tests {
|
|||||||
fn mock_process_instruction(
|
fn mock_process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let program_id = invoke_context.get_caller()?;
|
let program_id = invoke_context.get_caller()?;
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
@ -1184,7 +1142,7 @@ mod tests {
|
|||||||
&[Instruction::new_with_bytes(invoke_stack[0], &[0], metas)],
|
&[Instruction::new_with_bytes(invoke_stack[0], &[0], metas)],
|
||||||
None,
|
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
|
// Check call depth increases and has a limit
|
||||||
let mut depth_reached = 0;
|
let mut depth_reached = 0;
|
||||||
@ -1271,7 +1229,7 @@ mod tests {
|
|||||||
)],
|
)],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.push(&message, &message.instructions[0], &[0], None)
|
.push(&message, &message.instructions[0], &[0], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1336,7 +1294,7 @@ mod tests {
|
|||||||
program_id: callee_program_id,
|
program_id: callee_program_id,
|
||||||
process_instruction: mock_process_instruction,
|
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
|
invoke_context
|
||||||
.push(&message, &caller_instruction, &program_indices[..1], None)
|
.push(&message, &caller_instruction, &program_indices[..1], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1463,7 +1421,7 @@ mod tests {
|
|||||||
program_id: callee_program_id,
|
program_id: callee_program_id,
|
||||||
process_instruction: mock_process_instruction,
|
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
|
invoke_context
|
||||||
.push(&message, &caller_instruction, &program_indices, None)
|
.push(&message, &caller_instruction, &program_indices, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1551,7 +1509,7 @@ mod tests {
|
|||||||
let mut feature_set = FeatureSet::all_enabled();
|
let mut feature_set = FeatureSet::all_enabled();
|
||||||
feature_set.deactivate(&tx_wide_compute_cap::id());
|
feature_set.deactivate(&tx_wide_compute_cap::id());
|
||||||
feature_set.deactivate(&requestable_heap_size::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,
|
&accounts,
|
||||||
&[],
|
&[],
|
||||||
&[],
|
&[],
|
||||||
|
@ -33,7 +33,7 @@ use thiserror::Error;
|
|||||||
pub type LoaderEntrypoint = unsafe extern "C" fn(
|
pub type LoaderEntrypoint = unsafe extern "C" fn(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
|
|
||||||
// Prototype of a native program entry point
|
// Prototype of a native program entry point
|
||||||
@ -165,7 +165,7 @@ impl NativeLoader {
|
|||||||
&self,
|
&self,
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let (program_id, name_vec) = {
|
let (program_id, name_vec) = {
|
||||||
let program_id = invoke_context.get_caller()?;
|
let program_id = invoke_context.get_caller()?;
|
||||||
|
@ -84,26 +84,25 @@ pub enum ProgramTestError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
thread_local! {
|
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) {
|
fn set_invoke_context(new: &mut InvokeContext) {
|
||||||
INVOKE_CONTEXT.with(|invoke_context| unsafe {
|
INVOKE_CONTEXT
|
||||||
invoke_context.replace(Some(transmute::<_, (usize, usize)>(new)))
|
.with(|invoke_context| unsafe { invoke_context.replace(Some(transmute::<_, usize>(new))) });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
fn get_invoke_context<'a>() -> &'a mut dyn InvokeContext {
|
fn get_invoke_context<'a, 'b>() -> &'a mut InvokeContext<'b> {
|
||||||
let fat = INVOKE_CONTEXT.with(|invoke_context| match *invoke_context.borrow() {
|
let ptr = INVOKE_CONTEXT.with(|invoke_context| match *invoke_context.borrow() {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => panic!("Invoke context not set!"),
|
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(
|
pub fn builtin_process_instruction(
|
||||||
process_instruction: solana_sdk::entrypoint::ProcessInstruction,
|
process_instruction: solana_sdk::entrypoint::ProcessInstruction,
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
input: &[u8],
|
input: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
set_invoke_context(invoke_context);
|
set_invoke_context(invoke_context);
|
||||||
|
|
||||||
@ -187,7 +186,7 @@ macro_rules! processor {
|
|||||||
Some(
|
Some(
|
||||||
|first_instruction_account: usize,
|
|first_instruction_account: usize,
|
||||||
input: &[u8],
|
input: &[u8],
|
||||||
invoke_context: &mut dyn solana_program_test::InvokeContext| {
|
invoke_context: &mut solana_program_test::InvokeContext| {
|
||||||
$crate::builtin_process_instruction(
|
$crate::builtin_process_instruction(
|
||||||
$process_instruction,
|
$process_instruction,
|
||||||
first_instruction_account,
|
first_instruction_account,
|
||||||
|
@ -11,7 +11,7 @@ use solana_bpf_loader_program::{
|
|||||||
ThisInstructionMeter,
|
ThisInstructionMeter,
|
||||||
};
|
};
|
||||||
use solana_measure::measure::Measure;
|
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::{
|
use solana_rbpf::{
|
||||||
elf::Executable,
|
elf::Executable,
|
||||||
vm::{Config, InstructionMeter, SyscallRegistry},
|
vm::{Config, InstructionMeter, SyscallRegistry},
|
||||||
|
@ -18,7 +18,7 @@ use solana_bpf_rust_invoke::instructions::*;
|
|||||||
use solana_bpf_rust_realloc::instructions::*;
|
use solana_bpf_rust_realloc::instructions::*;
|
||||||
use solana_bpf_rust_realloc_invoke::instructions::*;
|
use solana_bpf_rust_realloc_invoke::instructions::*;
|
||||||
use solana_cli_output::display::println_transaction;
|
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::{
|
use solana_rbpf::{
|
||||||
elf::Executable,
|
elf::Executable,
|
||||||
static_analysis::Analysis,
|
static_analysis::Analysis,
|
||||||
|
@ -69,7 +69,7 @@ pub enum BpfError {
|
|||||||
}
|
}
|
||||||
impl UserDefinedError for 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);
|
ic_msg!(invoke_context, "{}", e);
|
||||||
InstructionError::InvalidAccountData
|
InstructionError::InvalidAccountData
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ fn map_ebpf_error(invoke_context: &dyn InvokeContext, e: EbpfError<BpfError>) ->
|
|||||||
pub fn create_executor(
|
pub fn create_executor(
|
||||||
programdata_account_index: usize,
|
programdata_account_index: usize,
|
||||||
programdata_offset: usize,
|
programdata_offset: usize,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
use_jit: bool,
|
use_jit: bool,
|
||||||
reject_unresolved_syscalls: bool,
|
reject_unresolved_syscalls: bool,
|
||||||
) -> Result<Arc<BpfExecutor>, InstructionError> {
|
) -> Result<Arc<BpfExecutor>, InstructionError> {
|
||||||
@ -123,7 +123,7 @@ fn write_program_data(
|
|||||||
program_account_index: usize,
|
program_account_index: usize,
|
||||||
program_data_offset: usize,
|
program_data_offset: usize,
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
let program = keyed_account_at_index(keyed_accounts, program_account_index)?;
|
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
|
/// Create the BPF virtual machine
|
||||||
pub fn create_vm<'a>(
|
pub fn create_vm<'a, 'b>(
|
||||||
program: &'a Executable<BpfError, ThisInstructionMeter>,
|
program: &'a Executable<BpfError, ThisInstructionMeter>,
|
||||||
parameter_bytes: &mut [u8],
|
parameter_bytes: &mut [u8],
|
||||||
invoke_context: &'a mut dyn InvokeContext,
|
invoke_context: &'a mut InvokeContext<'b>,
|
||||||
orig_data_lens: &'a [usize],
|
orig_data_lens: &'a [usize],
|
||||||
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
|
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
|
||||||
let compute_budget = invoke_context.get_compute_budget();
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
@ -174,7 +174,7 @@ pub fn create_vm<'a>(
|
|||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
process_instruction_common(
|
process_instruction_common(
|
||||||
first_instruction_account,
|
first_instruction_account,
|
||||||
@ -187,7 +187,7 @@ pub fn process_instruction(
|
|||||||
pub fn process_instruction_jit(
|
pub fn process_instruction_jit(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
process_instruction_common(
|
process_instruction_common(
|
||||||
first_instruction_account,
|
first_instruction_account,
|
||||||
@ -200,7 +200,7 @@ pub fn process_instruction_jit(
|
|||||||
fn process_instruction_common(
|
fn process_instruction_common(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
use_jit: bool,
|
use_jit: bool,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let log_collector = invoke_context.get_log_collector();
|
let log_collector = invoke_context.get_log_collector();
|
||||||
@ -317,7 +317,7 @@ fn process_instruction_common(
|
|||||||
fn process_loader_upgradeable_instruction(
|
fn process_loader_upgradeable_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
use_jit: bool,
|
use_jit: bool,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let log_collector = invoke_context.get_log_collector();
|
let log_collector = invoke_context.get_log_collector();
|
||||||
@ -867,7 +867,7 @@ fn common_close_account(
|
|||||||
fn process_loader_instruction(
|
fn process_loader_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
use_jit: bool,
|
use_jit: bool,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let program_id = invoke_context.get_caller()?;
|
let program_id = invoke_context.get_caller()?;
|
||||||
@ -949,11 +949,11 @@ impl Debug for BpfExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Executor for BpfExecutor {
|
impl Executor for BpfExecutor {
|
||||||
fn execute(
|
fn execute<'a, 'b>(
|
||||||
&self,
|
&self,
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &'a mut InvokeContext<'b>,
|
||||||
use_jit: bool,
|
use_jit: bool,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let log_collector = invoke_context.get_log_collector();
|
let log_collector = invoke_context.get_log_collector();
|
||||||
@ -1309,7 +1309,7 @@ mod tests {
|
|||||||
&keyed_accounts,
|
&keyed_accounts,
|
||||||
|first_instruction_account: usize,
|
|first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext| {
|
invoke_context: &mut InvokeContext| {
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
let compute_meter = invoke_context.get_compute_meter();
|
||||||
let remaining = compute_meter.borrow_mut().get_remaining();
|
let remaining = compute_meter.borrow_mut().get_remaining();
|
||||||
compute_meter.borrow_mut().consume(remaining).unwrap();
|
compute_meter.borrow_mut().consume(remaining).unwrap();
|
||||||
|
@ -313,9 +313,7 @@ pub fn deserialize_parameters_aligned(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use solana_program_runtime::invoke_context::{
|
use solana_program_runtime::invoke_context::{prepare_mock_invoke_context, InvokeContext};
|
||||||
prepare_mock_invoke_context, InvokeContext, ThisInvokeContext,
|
|
||||||
};
|
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::{Account, AccountSharedData},
|
account::{Account, AccountSharedData},
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
@ -448,7 +446,7 @@ mod tests {
|
|||||||
let program_indices = [0];
|
let program_indices = [0];
|
||||||
let preparation =
|
let preparation =
|
||||||
prepare_mock_invoke_context(&program_indices, &instruction_data, &keyed_accounts);
|
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
|
invoke_context
|
||||||
.push(
|
.push(
|
||||||
&preparation.message,
|
&preparation.message,
|
||||||
|
@ -44,7 +44,7 @@ use solana_sdk::{
|
|||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
cell::{Ref, RefCell, RefMut},
|
cell::{RefCell, RefMut},
|
||||||
mem::{align_of, size_of},
|
mem::{align_of, size_of},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
slice::from_raw_parts_mut,
|
slice::from_raw_parts_mut,
|
||||||
@ -115,7 +115,7 @@ impl SyscallConsume for Rc<RefCell<ComputeMeter>> {
|
|||||||
use crate::allocator_bump::BpfAllocator;
|
use crate::allocator_bump::BpfAllocator;
|
||||||
|
|
||||||
pub fn register_syscalls(
|
pub fn register_syscalls(
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<SyscallRegistry, EbpfError<BpfError>> {
|
) -> Result<SyscallRegistry, EbpfError<BpfError>> {
|
||||||
let mut syscall_registry = SyscallRegistry::default();
|
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>,
|
vm: &mut EbpfVm<'a, BpfError, crate::ThisInstructionMeter>,
|
||||||
invoke_context: &'a mut dyn InvokeContext,
|
invoke_context: &'a mut InvokeContext<'b>,
|
||||||
heap: AlignedMemory,
|
heap: AlignedMemory,
|
||||||
orig_data_lens: &'a [usize],
|
orig_data_lens: &'a [usize],
|
||||||
) -> Result<(), EbpfError<BpfError>> {
|
) -> Result<(), EbpfError<BpfError>> {
|
||||||
@ -534,10 +534,10 @@ impl SyscallObject<BpfError> for SyscallAbort {
|
|||||||
/// Panic syscall function, called when the BPF program calls 'sol_panic_()`
|
/// Panic syscall function, called when the BPF program calls 'sol_panic_()`
|
||||||
/// Causes the BPF program to be halted immediately
|
/// Causes the BPF program to be halted immediately
|
||||||
/// Log a user's info message
|
/// Log a user's info message
|
||||||
pub struct SyscallPanic<'a> {
|
pub struct SyscallPanic<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
file: u64,
|
file: u64,
|
||||||
@ -573,10 +573,10 @@ impl<'a> SyscallObject<BpfError> for SyscallPanic<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Log a user's info message
|
/// Log a user's info message
|
||||||
pub struct SyscallLog<'a> {
|
pub struct SyscallLog<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
addr: u64,
|
addr: u64,
|
||||||
@ -619,10 +619,10 @@ impl<'a> SyscallObject<BpfError> for SyscallLog<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Log 5 64-bit values
|
/// Log 5 64-bit values
|
||||||
pub struct SyscallLogU64<'a> {
|
pub struct SyscallLogU64<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
arg1: u64,
|
arg1: u64,
|
||||||
@ -654,10 +654,10 @@ impl<'a> SyscallObject<BpfError> for SyscallLogU64<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Log current compute consumption
|
/// Log current compute consumption
|
||||||
pub struct SyscallLogBpfComputeUnits<'a> {
|
pub struct SyscallLogBpfComputeUnits<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
_arg1: u64,
|
_arg1: u64,
|
||||||
@ -686,10 +686,10 @@ impl<'a> SyscallObject<BpfError> for SyscallLogBpfComputeUnits<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Log 5 64-bit values
|
/// Log 5 64-bit values
|
||||||
pub struct SyscallLogPubkey<'a> {
|
pub struct SyscallLogPubkey<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
pubkey_addr: u64,
|
pubkey_addr: u64,
|
||||||
@ -800,10 +800,10 @@ fn translate_and_check_program_address_inputs<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a program address
|
/// Create a program address
|
||||||
struct SyscallCreateProgramAddress<'a> {
|
struct SyscallCreateProgramAddress<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
seeds_addr: u64,
|
seeds_addr: u64,
|
||||||
@ -859,10 +859,10 @@ impl<'a> SyscallObject<BpfError> for SyscallCreateProgramAddress<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a program address
|
/// Create a program address
|
||||||
struct SyscallTryFindProgramAddress<'a> {
|
struct SyscallTryFindProgramAddress<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
seeds_addr: u64,
|
seeds_addr: u64,
|
||||||
@ -932,10 +932,10 @@ impl<'a> SyscallObject<BpfError> for SyscallTryFindProgramAddress<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// SHA256
|
/// SHA256
|
||||||
pub struct SyscallSha256<'a> {
|
pub struct SyscallSha256<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
vals_addr: u64,
|
vals_addr: u64,
|
||||||
@ -1004,7 +1004,7 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
|
|||||||
var_addr: u64,
|
var_addr: u64,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
invoke_context: Rc<RefCell<&mut dyn InvokeContext>>,
|
invoke_context: Rc<RefCell<&mut InvokeContext>>,
|
||||||
) -> Result<u64, EbpfError<BpfError>> {
|
) -> Result<u64, EbpfError<BpfError>> {
|
||||||
let invoke_context = invoke_context
|
let invoke_context = invoke_context
|
||||||
.try_borrow()
|
.try_borrow()
|
||||||
@ -1022,10 +1022,10 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a Clock sysvar
|
/// Get a Clock sysvar
|
||||||
struct SyscallGetClockSysvar<'a> {
|
struct SyscallGetClockSysvar<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
var_addr: u64,
|
var_addr: u64,
|
||||||
@ -1058,10 +1058,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetClockSysvar<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get a EpochSchedule sysvar
|
/// Get a EpochSchedule sysvar
|
||||||
struct SyscallGetEpochScheduleSysvar<'a> {
|
struct SyscallGetEpochScheduleSysvar<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
var_addr: u64,
|
var_addr: u64,
|
||||||
@ -1094,11 +1094,11 @@ impl<'a> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get a Fees sysvar
|
/// Get a Fees sysvar
|
||||||
struct SyscallGetFeesSysvar<'a> {
|
struct SyscallGetFeesSysvar<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
|
||||||
}
|
}
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<'a> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a> {
|
impl<'a, 'b> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a, 'b> {
|
||||||
fn call(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
var_addr: u64,
|
var_addr: u64,
|
||||||
@ -1131,10 +1131,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get a Rent sysvar
|
/// Get a Rent sysvar
|
||||||
struct SyscallGetRentSysvar<'a> {
|
struct SyscallGetRentSysvar<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
var_addr: u64,
|
var_addr: u64,
|
||||||
@ -1168,10 +1168,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetRentSysvar<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Keccak256
|
// Keccak256
|
||||||
pub struct SyscallKeccak256<'a> {
|
pub struct SyscallKeccak256<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
vals_addr: u64,
|
vals_addr: u64,
|
||||||
@ -1246,10 +1246,10 @@ fn check_overlapping(src_addr: u64, dst_addr: u64, n: u64) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// memcpy
|
/// memcpy
|
||||||
pub struct SyscallMemcpy<'a> {
|
pub struct SyscallMemcpy<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
dst_addr: u64,
|
dst_addr: u64,
|
||||||
@ -1295,10 +1295,10 @@ impl<'a> SyscallObject<BpfError> for SyscallMemcpy<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// memmove
|
/// memmove
|
||||||
pub struct SyscallMemmove<'a> {
|
pub struct SyscallMemmove<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
dst_addr: u64,
|
dst_addr: u64,
|
||||||
@ -1339,10 +1339,10 @@ impl<'a> SyscallObject<BpfError> for SyscallMemmove<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// memcmp
|
/// memcmp
|
||||||
pub struct SyscallMemcmp<'a> {
|
pub struct SyscallMemcmp<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
s1_addr: u64,
|
s1_addr: u64,
|
||||||
@ -1396,10 +1396,10 @@ impl<'a> SyscallObject<BpfError> for SyscallMemcmp<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// memset
|
/// memset
|
||||||
pub struct SyscallMemset<'a> {
|
pub struct SyscallMemset<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
s_addr: u64,
|
s_addr: u64,
|
||||||
@ -1437,11 +1437,11 @@ impl<'a> SyscallObject<BpfError> for SyscallMemset<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// secp256k1_recover
|
/// secp256k1_recover
|
||||||
pub struct SyscallSecp256k1Recover<'a> {
|
pub struct SyscallSecp256k1Recover<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
hash_addr: u64,
|
hash_addr: u64,
|
||||||
@ -1538,10 +1538,10 @@ impl<'a> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Blake3
|
// Blake3
|
||||||
pub struct SyscallBlake3<'a> {
|
pub struct SyscallBlake3<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
vals_addr: u64,
|
vals_addr: u64,
|
||||||
@ -1629,25 +1629,24 @@ type TranslatedAccounts<'a> = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// Implemented by language specific data structure translators
|
/// Implemented by language specific data structure translators
|
||||||
trait SyscallInvokeSigned<'a> {
|
trait SyscallInvokeSigned<'a, 'b> {
|
||||||
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut InvokeContext<'b>>, EbpfError<BpfError>>;
|
||||||
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
|
|
||||||
fn translate_instruction(
|
fn translate_instruction(
|
||||||
&self,
|
&self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
addr: u64,
|
addr: u64,
|
||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<Instruction, EbpfError<BpfError>>;
|
) -> Result<Instruction, EbpfError<BpfError>>;
|
||||||
fn translate_accounts(
|
fn translate_accounts<'c>(
|
||||||
&self,
|
&'c self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
account_infos_addr: u64,
|
account_infos_addr: u64,
|
||||||
account_infos_len: u64,
|
account_infos_len: u64,
|
||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>;
|
) -> Result<TranslatedAccounts<'c>, EbpfError<BpfError>>;
|
||||||
fn translate_signers(
|
fn translate_signers(
|
||||||
&self,
|
&self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
@ -1659,27 +1658,23 @@ trait SyscallInvokeSigned<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Cross-program invocation called from Rust
|
/// Cross-program invocation called from Rust
|
||||||
pub struct SyscallInvokeSignedRust<'a> {
|
pub struct SyscallInvokeSignedRust<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
|
||||||
orig_data_lens: &'a [usize],
|
orig_data_lens: &'a [usize],
|
||||||
}
|
}
|
||||||
impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedRust<'a, 'b> {
|
||||||
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut InvokeContext<'b>>, EbpfError<BpfError>> {
|
||||||
self.invoke_context
|
self.invoke_context
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
.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(
|
fn translate_instruction(
|
||||||
&self,
|
&self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
addr: u64,
|
addr: u64,
|
||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<Instruction, EbpfError<BpfError>> {
|
) -> Result<Instruction, EbpfError<BpfError>> {
|
||||||
let ix = translate_type::<Instruction>(memory_mapping, addr, loader_id)?;
|
let ix = translate_type::<Instruction>(memory_mapping, addr, loader_id)?;
|
||||||
|
|
||||||
@ -1706,15 +1701,15 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_accounts(
|
fn translate_accounts<'c>(
|
||||||
&self,
|
&'c self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
account_infos_addr: u64,
|
account_infos_addr: u64,
|
||||||
account_infos_len: u64,
|
account_infos_len: u64,
|
||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>> {
|
) -> Result<TranslatedAccounts<'c>, EbpfError<BpfError>> {
|
||||||
let account_infos = translate_slice::<AccountInfo>(
|
let account_infos = translate_slice::<AccountInfo>(
|
||||||
memory_mapping,
|
memory_mapping,
|
||||||
account_infos_addr,
|
account_infos_addr,
|
||||||
@ -1733,7 +1728,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
.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
|
// Translate the account from user space
|
||||||
|
|
||||||
let lamports = {
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
instruction_addr: u64,
|
instruction_addr: u64,
|
||||||
@ -1940,28 +1935,23 @@ struct SolSignerSeedsC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Cross-program invocation called from C
|
/// Cross-program invocation called from C
|
||||||
pub struct SyscallInvokeSignedC<'a> {
|
pub struct SyscallInvokeSignedC<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
|
||||||
orig_data_lens: &'a [usize],
|
orig_data_lens: &'a [usize],
|
||||||
}
|
}
|
||||||
impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedC<'a, 'b> {
|
||||||
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>> {
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut InvokeContext<'b>>, EbpfError<BpfError>> {
|
||||||
self.invoke_context
|
self.invoke_context
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
.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(
|
fn translate_instruction(
|
||||||
&self,
|
&self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
addr: u64,
|
addr: u64,
|
||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<Instruction, EbpfError<BpfError>> {
|
) -> Result<Instruction, EbpfError<BpfError>> {
|
||||||
let ix_c = translate_type::<SolInstruction>(memory_mapping, addr, loader_id)?;
|
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(
|
fn translate_accounts<'c>(
|
||||||
&self,
|
&'c self,
|
||||||
loader_id: &Pubkey,
|
loader_id: &Pubkey,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
account_infos_addr: u64,
|
account_infos_addr: u64,
|
||||||
account_infos_len: u64,
|
account_infos_len: u64,
|
||||||
memory_mapping: &MemoryMapping,
|
memory_mapping: &MemoryMapping,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>> {
|
) -> Result<TranslatedAccounts<'c>, EbpfError<BpfError>> {
|
||||||
let account_infos = translate_slice::<SolAccountInfo>(
|
let account_infos = translate_slice::<SolAccountInfo>(
|
||||||
memory_mapping,
|
memory_mapping,
|
||||||
account_infos_addr,
|
account_infos_addr,
|
||||||
@ -2023,7 +2013,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, EbpfError<BpfError>>>()?;
|
.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
|
// Translate the account from user space
|
||||||
|
|
||||||
let lamports =
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
instruction_addr: u64,
|
instruction_addr: u64,
|
||||||
@ -2160,12 +2150,12 @@ fn get_translated_accounts<'a, T, F>(
|
|||||||
message: &Message,
|
message: &Message,
|
||||||
account_info_keys: &[&Pubkey],
|
account_info_keys: &[&Pubkey],
|
||||||
account_infos: &[T],
|
account_infos: &[T],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
orig_data_lens: &[usize],
|
orig_data_lens: &[usize],
|
||||||
do_translate: F,
|
do_translate: F,
|
||||||
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>
|
) -> Result<TranslatedAccounts<'a>, EbpfError<BpfError>>
|
||||||
where
|
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 =
|
let demote_program_write_locks =
|
||||||
invoke_context.is_feature_active(&demote_program_write_locks::id());
|
invoke_context.is_feature_active(&demote_program_write_locks::id());
|
||||||
@ -2248,7 +2238,7 @@ where
|
|||||||
fn check_instruction_size(
|
fn check_instruction_size(
|
||||||
num_accounts: usize,
|
num_accounts: usize,
|
||||||
data_len: usize,
|
data_len: usize,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), EbpfError<BpfError>> {
|
) -> Result<(), EbpfError<BpfError>> {
|
||||||
let size = num_accounts
|
let size = num_accounts
|
||||||
.saturating_mul(size_of::<AccountMeta>())
|
.saturating_mul(size_of::<AccountMeta>())
|
||||||
@ -2262,7 +2252,7 @@ fn check_instruction_size(
|
|||||||
|
|
||||||
fn check_account_infos(
|
fn check_account_infos(
|
||||||
len: usize,
|
len: usize,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), EbpfError<BpfError>> {
|
) -> Result<(), EbpfError<BpfError>> {
|
||||||
if len * size_of::<Pubkey>() > invoke_context.get_compute_budget().max_cpi_instruction_size {
|
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
|
// Cap the number of account_infos a caller can pass to approximate
|
||||||
@ -2275,7 +2265,7 @@ fn check_account_infos(
|
|||||||
fn check_authorized_program(
|
fn check_authorized_program(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), EbpfError<BpfError>> {
|
) -> Result<(), EbpfError<BpfError>> {
|
||||||
#[allow(clippy::blocks_in_if_conditions)]
|
#[allow(clippy::blocks_in_if_conditions)]
|
||||||
if native_loader::check_id(program_id)
|
if native_loader::check_id(program_id)
|
||||||
@ -2296,8 +2286,8 @@ fn check_authorized_program(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Call process instruction, common to both Rust and C
|
/// Call process instruction, common to both Rust and C
|
||||||
fn call<'a>(
|
fn call<'a, 'b: 'a>(
|
||||||
syscall: &mut dyn SyscallInvokeSigned<'a>,
|
syscall: &mut dyn SyscallInvokeSigned<'a, 'b>,
|
||||||
instruction_addr: u64,
|
instruction_addr: u64,
|
||||||
account_infos_addr: u64,
|
account_infos_addr: u64,
|
||||||
account_infos_len: u64,
|
account_infos_len: u64,
|
||||||
@ -2413,10 +2403,10 @@ fn call<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return data handling
|
// Return data handling
|
||||||
pub struct SyscallSetReturnData<'a> {
|
pub struct SyscallSetReturnData<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
addr: u64,
|
addr: u64,
|
||||||
@ -2474,10 +2464,10 @@ impl<'a> SyscallObject<BpfError> for SyscallSetReturnData<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SyscallGetReturnData<'a> {
|
pub struct SyscallGetReturnData<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
return_data_addr: u64,
|
return_data_addr: u64,
|
||||||
@ -2541,10 +2531,10 @@ impl<'a> SyscallObject<BpfError> for SyscallGetReturnData<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log data handling
|
// Log data handling
|
||||||
pub struct SyscallLogData<'a> {
|
pub struct SyscallLogData<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
addr: u64,
|
addr: u64,
|
||||||
@ -2624,7 +2614,7 @@ impl<'a> SyscallObject<BpfError> for SyscallLogData<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use solana_program_runtime::invoke_context::ThisInvokeContext;
|
use solana_program_runtime::invoke_context::InvokeContext;
|
||||||
use solana_rbpf::{
|
use solana_rbpf::{
|
||||||
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
|
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
|
||||||
};
|
};
|
||||||
@ -2945,7 +2935,7 @@ mod tests {
|
|||||||
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.push(&message, &message.instructions[0], &[0], None)
|
.push(&message, &message.instructions[0], &[0], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -3022,7 +3012,7 @@ mod tests {
|
|||||||
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.push(&message, &message.instructions[0], &[0], None)
|
.push(&message, &message.instructions[0], &[0], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -3126,7 +3116,7 @@ mod tests {
|
|||||||
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.push(&message, &message.instructions[0], &[0], None)
|
.push(&message, &message.instructions[0], &[0], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -3168,7 +3158,7 @@ mod tests {
|
|||||||
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.push(&message, &message.instructions[0], &[0], None)
|
.push(&message, &message.instructions[0], &[0], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -3433,7 +3423,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.get_compute_meter()
|
.get_compute_meter()
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
@ -3540,7 +3530,7 @@ mod tests {
|
|||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_clock).unwrap();
|
bincode::serialize_into(&mut data, &src_clock).unwrap();
|
||||||
let sysvars = [(sysvar::clock::id(), data)];
|
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,
|
&accounts,
|
||||||
&[],
|
&[],
|
||||||
&sysvars,
|
&sysvars,
|
||||||
@ -3589,7 +3579,7 @@ mod tests {
|
|||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
|
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
|
||||||
let sysvars = [(sysvar::epoch_schedule::id(), data)];
|
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,
|
&accounts,
|
||||||
&[],
|
&[],
|
||||||
&sysvars,
|
&sysvars,
|
||||||
@ -3645,7 +3635,7 @@ mod tests {
|
|||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_fees).unwrap();
|
bincode::serialize_into(&mut data, &src_fees).unwrap();
|
||||||
let sysvars = [(sysvar::fees::id(), data)];
|
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,
|
&accounts,
|
||||||
&[],
|
&[],
|
||||||
&sysvars,
|
&sysvars,
|
||||||
@ -3692,7 +3682,7 @@ mod tests {
|
|||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_rent).unwrap();
|
bincode::serialize_into(&mut data, &src_rent).unwrap();
|
||||||
let sysvars = [(sysvar::rent::id(), data)];
|
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,
|
&accounts,
|
||||||
&[],
|
&[],
|
||||||
&sysvars,
|
&sysvars,
|
||||||
@ -3802,7 +3792,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_program_address(
|
fn create_program_address(
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
seeds: &[&[u8]],
|
seeds: &[&[u8]],
|
||||||
address: &Pubkey,
|
address: &Pubkey,
|
||||||
) -> Result<Pubkey, EbpfError<BpfError>> {
|
) -> Result<Pubkey, EbpfError<BpfError>> {
|
||||||
@ -3814,7 +3804,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_find_program_address(
|
fn try_find_program_address(
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
seeds: &[&[u8]],
|
seeds: &[&[u8]],
|
||||||
address: &Pubkey,
|
address: &Pubkey,
|
||||||
) -> Result<(Pubkey, u8), EbpfError<BpfError>> {
|
) -> Result<(Pubkey, u8), EbpfError<BpfError>> {
|
||||||
@ -3835,7 +3825,7 @@ mod tests {
|
|||||||
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.push(&message, &message.instructions[0], &[0], None)
|
.push(&message, &message.instructions[0], &[0], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -3951,7 +3941,7 @@ mod tests {
|
|||||||
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
&[Instruction::new_with_bytes(program_id, &[], vec![])],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&accounts, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||||
invoke_context
|
invoke_context
|
||||||
.push(&message, &message.instructions[0], &[0], None)
|
.push(&message, &message.instructions[0], &[0], None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -4,7 +4,7 @@ use solana_sdk::instruction::InstructionError;
|
|||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
// Do nothing, compute budget instructions handled by the runtime
|
// Do nothing, compute budget instructions handled by the runtime
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -16,7 +16,7 @@ use std::collections::BTreeSet;
|
|||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ pub use solana_sdk::stake::instruction::*;
|
|||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ mod tests {
|
|||||||
use crate::stake_state::{Meta, StakeState};
|
use crate::stake_state::{Meta, StakeState};
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use solana_program_runtime::invoke_context::{
|
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::{
|
use solana_sdk::{
|
||||||
account::{self, AccountSharedData},
|
account::{self, AccountSharedData},
|
||||||
@ -416,7 +416,7 @@ mod tests {
|
|||||||
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
||||||
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
||||||
let sysvars = [(sysvar::clock::id(), data)];
|
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,
|
&preparation.accounts,
|
||||||
&[],
|
&[],
|
||||||
&sysvars,
|
&sysvars,
|
||||||
@ -1066,7 +1066,7 @@ mod tests {
|
|||||||
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
||||||
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
||||||
let sysvars = [(sysvar::clock::id(), data)];
|
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,
|
&preparation.accounts,
|
||||||
&[],
|
&[],
|
||||||
&sysvars,
|
&sysvars,
|
||||||
|
@ -395,7 +395,7 @@ pub trait StakeAccount {
|
|||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
fn merge(
|
fn merge(
|
||||||
&self,
|
&self,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
source_stake: &KeyedAccount,
|
source_stake: &KeyedAccount,
|
||||||
clock: &Clock,
|
clock: &Clock,
|
||||||
stake_history: &StakeHistory,
|
stake_history: &StakeHistory,
|
||||||
@ -701,7 +701,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
|||||||
|
|
||||||
fn merge(
|
fn merge(
|
||||||
&self,
|
&self,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
source_account: &KeyedAccount,
|
source_account: &KeyedAccount,
|
||||||
clock: &Clock,
|
clock: &Clock,
|
||||||
stake_history: &StakeHistory,
|
stake_history: &StakeHistory,
|
||||||
@ -865,7 +865,7 @@ impl MergeKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_if_mergeable(
|
fn get_if_mergeable(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
stake_keyed_account: &KeyedAccount,
|
stake_keyed_account: &KeyedAccount,
|
||||||
clock: &Clock,
|
clock: &Clock,
|
||||||
stake_history: &StakeHistory,
|
stake_history: &StakeHistory,
|
||||||
@ -897,7 +897,7 @@ impl MergeKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn metas_can_merge(
|
fn metas_can_merge(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
stake: &Meta,
|
stake: &Meta,
|
||||||
source: &Meta,
|
source: &Meta,
|
||||||
clock: Option<&Clock>,
|
clock: Option<&Clock>,
|
||||||
@ -926,7 +926,7 @@ impl MergeKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn active_delegations_can_merge(
|
fn active_delegations_can_merge(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
stake: &Delegation,
|
stake: &Delegation,
|
||||||
source: &Delegation,
|
source: &Delegation,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
@ -946,7 +946,7 @@ impl MergeKind {
|
|||||||
|
|
||||||
// Remove this when the `stake_merge_with_unmatched_credits_observed` feature is removed
|
// Remove this when the `stake_merge_with_unmatched_credits_observed` feature is removed
|
||||||
fn active_stakes_can_merge(
|
fn active_stakes_can_merge(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
stake: &Stake,
|
stake: &Stake,
|
||||||
source: &Stake,
|
source: &Stake,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
@ -969,7 +969,7 @@ impl MergeKind {
|
|||||||
|
|
||||||
fn merge(
|
fn merge(
|
||||||
self,
|
self,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
source: Self,
|
source: Self,
|
||||||
clock: Option<&Clock>,
|
clock: Option<&Clock>,
|
||||||
) -> Result<Option<StakeState>, InstructionError> {
|
) -> Result<Option<StakeState>, InstructionError> {
|
||||||
@ -1033,7 +1033,7 @@ impl MergeKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn merge_delegation_stake_and_credits_observed(
|
fn merge_delegation_stake_and_credits_observed(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
stake: &mut Stake,
|
stake: &mut Stake,
|
||||||
absorbed_lamports: u64,
|
absorbed_lamports: u64,
|
||||||
absorbed_credits_observed: u64,
|
absorbed_credits_observed: u64,
|
||||||
@ -1372,7 +1372,7 @@ fn do_create_account(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
use solana_program_runtime::invoke_context::ThisInvokeContext;
|
use solana_program_runtime::invoke_context::InvokeContext;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::{AccountSharedData, WritableAccount},
|
account::{AccountSharedData, WritableAccount},
|
||||||
clock::UnixTimestamp,
|
clock::UnixTimestamp,
|
||||||
@ -5068,7 +5068,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge() {
|
fn test_merge() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let stake_pubkey = solana_sdk::pubkey::new_rand();
|
let stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
@ -5178,7 +5178,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_self_fails() {
|
fn test_merge_self_fails() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let stake_address = Pubkey::new_unique();
|
let stake_address = Pubkey::new_unique();
|
||||||
let authority_pubkey = Pubkey::new_unique();
|
let authority_pubkey = Pubkey::new_unique();
|
||||||
let signers = HashSet::from_iter(vec![authority_pubkey]);
|
let signers = HashSet::from_iter(vec![authority_pubkey]);
|
||||||
@ -5223,7 +5223,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_incorrect_authorized_staker() {
|
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 stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
@ -5292,7 +5292,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_invalid_account_data() {
|
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 stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
@ -5342,7 +5342,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_fake_stake_source() {
|
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 stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
@ -5384,7 +5384,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_active_stake() {
|
fn test_merge_active_stake() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let base_lamports = 4242424242;
|
let base_lamports = 4242424242;
|
||||||
let stake_address = Pubkey::new_unique();
|
let stake_address = Pubkey::new_unique();
|
||||||
let source_address = Pubkey::new_unique();
|
let source_address = Pubkey::new_unique();
|
||||||
@ -5453,7 +5453,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
fn try_merge(
|
fn try_merge(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
stake_account: &KeyedAccount,
|
stake_account: &KeyedAccount,
|
||||||
source_account: &KeyedAccount,
|
source_account: &KeyedAccount,
|
||||||
clock: &Clock,
|
clock: &Clock,
|
||||||
@ -6006,7 +6006,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_things_can_merge() {
|
fn test_things_can_merge() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let good_stake = Stake {
|
let good_stake = Stake {
|
||||||
credits_observed: 4242,
|
credits_observed: 4242,
|
||||||
delegation: Delegation {
|
delegation: Delegation {
|
||||||
@ -6104,7 +6104,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_metas_can_merge_pre_v4() {
|
fn test_metas_can_merge_pre_v4() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
// Identical Metas can merge
|
// Identical Metas can merge
|
||||||
assert!(MergeKind::metas_can_merge(
|
assert!(MergeKind::metas_can_merge(
|
||||||
&invoke_context,
|
&invoke_context,
|
||||||
@ -6190,7 +6190,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_metas_can_merge_v4() {
|
fn test_metas_can_merge_v4() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
// Identical Metas can merge
|
// Identical Metas can merge
|
||||||
assert!(MergeKind::metas_can_merge(
|
assert!(MergeKind::metas_can_merge(
|
||||||
&invoke_context,
|
&invoke_context,
|
||||||
@ -6336,7 +6336,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_kind_get_if_mergeable() {
|
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 authority_pubkey = Pubkey::new_unique();
|
||||||
let initial_lamports = 4242424242;
|
let initial_lamports = 4242424242;
|
||||||
let rent = Rent::default();
|
let rent = Rent::default();
|
||||||
@ -6568,7 +6568,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_kind_merge() {
|
fn test_merge_kind_merge() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let lamports = 424242;
|
let lamports = 424242;
|
||||||
let meta = Meta {
|
let meta = Meta {
|
||||||
rent_exempt_reserve: 42,
|
rent_exempt_reserve: 42,
|
||||||
@ -6646,7 +6646,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_active_stake_merge() {
|
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_a = 4_242_424_242u64;
|
||||||
let delegation_b = 6_200_000_000u64;
|
let delegation_b = 6_200_000_000u64;
|
||||||
let credits_a = 124_521_000u64;
|
let credits_a = 124_521_000u64;
|
||||||
|
@ -310,7 +310,7 @@ fn verify_rent_exemption(
|
|||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
|
|
||||||
|
@ -5,9 +5,7 @@ use solana_bpf_loader_program::{
|
|||||||
create_vm, serialization::serialize_parameters, syscalls::register_syscalls, BpfError,
|
create_vm, serialization::serialize_parameters, syscalls::register_syscalls, BpfError,
|
||||||
ThisInstructionMeter,
|
ThisInstructionMeter,
|
||||||
};
|
};
|
||||||
use solana_program_runtime::invoke_context::{
|
use solana_program_runtime::invoke_context::{prepare_mock_invoke_context, InvokeContext};
|
||||||
prepare_mock_invoke_context, InvokeContext, ThisInvokeContext,
|
|
||||||
};
|
|
||||||
use solana_rbpf::{
|
use solana_rbpf::{
|
||||||
assembler::assemble,
|
assembler::assemble,
|
||||||
elf::Executable,
|
elf::Executable,
|
||||||
@ -202,7 +200,7 @@ native machine code before execting it in the virtual machine.",
|
|||||||
};
|
};
|
||||||
let program_indices = [0, 1];
|
let program_indices = [0, 1];
|
||||||
let preparation = prepare_mock_invoke_context(&program_indices, &[], &keyed_accounts);
|
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
|
invoke_context
|
||||||
.push(
|
.push(
|
||||||
&preparation.message,
|
&preparation.message,
|
||||||
|
@ -34,7 +34,7 @@ const NOOP_PROGRAM_ID: [u8; 32] = [
|
|||||||
fn process_instruction(
|
fn process_instruction(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -6958,7 +6958,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_process_instruction(
|
fn mock_process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> result::Result<(), InstructionError> {
|
) -> result::Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
if let Ok(instruction) = bincode::deserialize(data) {
|
if let Ok(instruction) = bincode::deserialize(data) {
|
||||||
@ -10709,7 +10709,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_vote_processor(
|
fn mock_vote_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
let program_id = invoke_context.get_caller()?;
|
let program_id = invoke_context.get_caller()?;
|
||||||
if mock_vote_program_id() != *program_id {
|
if mock_vote_program_id() != *program_id {
|
||||||
@ -10767,7 +10767,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_vote_processor(
|
fn mock_vote_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
Err(InstructionError::Custom(42))
|
Err(InstructionError::Custom(42))
|
||||||
}
|
}
|
||||||
@ -10817,7 +10817,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_ix_processor(
|
fn mock_ix_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
Err(InstructionError::Custom(42))
|
Err(InstructionError::Custom(42))
|
||||||
}
|
}
|
||||||
@ -11705,7 +11705,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_process_instruction(
|
fn mock_process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> result::Result<(), InstructionError> {
|
) -> result::Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
let lamports = data[0] as u64;
|
let lamports = data[0] as u64;
|
||||||
@ -11763,7 +11763,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_process_instruction(
|
fn mock_process_instruction(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> result::Result<(), InstructionError> {
|
) -> result::Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -11949,7 +11949,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_ok_vote_processor(
|
fn mock_ok_vote_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -12199,7 +12199,7 @@ pub(crate) mod tests {
|
|||||||
fn nested_processor(
|
fn nested_processor(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> result::Result<(), InstructionError> {
|
) -> result::Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
let account = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
let account = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||||
@ -12473,7 +12473,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_ix_processor(
|
fn mock_ix_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -12522,7 +12522,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_ix_processor(
|
fn mock_ix_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_context: &mut dyn InvokeContext,
|
_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -12899,11 +12899,11 @@ pub(crate) mod tests {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestExecutor {}
|
struct TestExecutor {}
|
||||||
impl Executor for TestExecutor {
|
impl Executor for TestExecutor {
|
||||||
fn execute(
|
fn execute<'a, 'b>(
|
||||||
&self,
|
&self,
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &'a mut InvokeContext<'b>,
|
||||||
_use_jit: bool,
|
_use_jit: bool,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -13422,7 +13422,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_process_instruction(
|
fn mock_process_instruction(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
|
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -14923,7 +14923,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_ix_processor(
|
fn mock_ix_processor(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
use solana_sdk::account::WritableAccount;
|
use solana_sdk::account::WritableAccount;
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
@ -15135,7 +15135,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_ix_processor(
|
fn mock_ix_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
let compute_budget = invoke_context.get_compute_budget();
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -15180,7 +15180,7 @@ pub(crate) mod tests {
|
|||||||
fn mock_ix_processor(
|
fn mock_ix_processor(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> std::result::Result<(), InstructionError> {
|
||||||
let compute_budget = invoke_context.get_compute_budget();
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -15,7 +15,7 @@ fn process_instruction_with_program_logging(
|
|||||||
process_instruction: ProcessInstructionWithContext,
|
process_instruction: ProcessInstructionWithContext,
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let logger = invoke_context.get_log_collector();
|
let logger = invoke_context.get_log_collector();
|
||||||
let program_id = invoke_context.get_caller()?;
|
let program_id = invoke_context.get_caller()?;
|
||||||
@ -35,7 +35,7 @@ macro_rules! with_program_logging {
|
|||||||
($process_instruction:expr) => {
|
($process_instruction:expr) => {
|
||||||
|first_instruction_account: usize,
|
|first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext| {
|
invoke_context: &mut InvokeContext| {
|
||||||
process_instruction_with_program_logging(
|
process_instruction_with_program_logging(
|
||||||
$process_instruction,
|
$process_instruction,
|
||||||
first_instruction_account,
|
first_instruction_account,
|
||||||
@ -135,7 +135,7 @@ fn genesis_builtins() -> Vec<Builtin> {
|
|||||||
fn dummy_process_instruction(
|
fn dummy_process_instruction(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_program_runtime::{
|
use solana_program_runtime::{
|
||||||
instruction_recorder::InstructionRecorder,
|
instruction_recorder::InstructionRecorder,
|
||||||
invoke_context::{BuiltinProgram, ComputeMeter, Executors, InvokeContext, ThisInvokeContext},
|
invoke_context::{BuiltinProgram, ComputeMeter, Executors, InvokeContext},
|
||||||
log_collector::LogCollector,
|
log_collector::LogCollector,
|
||||||
timings::ExecuteDetailsTimings,
|
timings::ExecuteDetailsTimings,
|
||||||
};
|
};
|
||||||
@ -56,7 +56,7 @@ impl MessageProcessor {
|
|||||||
blockhash: Hash,
|
blockhash: Hash,
|
||||||
lamports_per_signature: u64,
|
lamports_per_signature: u64,
|
||||||
) -> Result<(), TransactionError> {
|
) -> Result<(), TransactionError> {
|
||||||
let mut invoke_context = ThisInvokeContext::new(
|
let mut invoke_context = InvokeContext::new(
|
||||||
rent,
|
rent,
|
||||||
accounts,
|
accounts,
|
||||||
builtin_programs,
|
builtin_programs,
|
||||||
@ -165,7 +165,7 @@ mod tests {
|
|||||||
fn mock_system_process_instruction(
|
fn mock_system_process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
if let Ok(instruction) = bincode::deserialize(data) {
|
if let Ok(instruction) = bincode::deserialize(data) {
|
||||||
@ -336,7 +336,7 @@ mod tests {
|
|||||||
fn mock_system_process_instruction(
|
fn mock_system_process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
if let Ok(instruction) = bincode::deserialize(data) {
|
if let Ok(instruction) = bincode::deserialize(data) {
|
||||||
@ -537,7 +537,7 @@ mod tests {
|
|||||||
fn mock_process_instruction(
|
fn mock_process_instruction(
|
||||||
_first_instruction_account: usize,
|
_first_instruction_account: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_invoke_context: &mut dyn InvokeContext,
|
_invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
Err(InstructionError::Custom(0xbabb1e))
|
Err(InstructionError::Custom(0xbabb1e))
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ pub trait NonceKeyedAccount {
|
|||||||
fn advance_nonce_account(
|
fn advance_nonce_account(
|
||||||
&self,
|
&self,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
fn withdraw_nonce_account(
|
fn withdraw_nonce_account(
|
||||||
&self,
|
&self,
|
||||||
@ -24,19 +24,19 @@ pub trait NonceKeyedAccount {
|
|||||||
to: &KeyedAccount,
|
to: &KeyedAccount,
|
||||||
rent: &Rent,
|
rent: &Rent,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
fn initialize_nonce_account(
|
fn initialize_nonce_account(
|
||||||
&self,
|
&self,
|
||||||
nonce_authority: &Pubkey,
|
nonce_authority: &Pubkey,
|
||||||
rent: &Rent,
|
rent: &Rent,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
fn authorize_nonce_account(
|
fn authorize_nonce_account(
|
||||||
&self,
|
&self,
|
||||||
nonce_authority: &Pubkey,
|
nonce_authority: &Pubkey,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
|||||||
fn advance_nonce_account(
|
fn advance_nonce_account(
|
||||||
&self,
|
&self,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let merge_nonce_error_into_system_error = invoke_context
|
let merge_nonce_error_into_system_error = invoke_context
|
||||||
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
||||||
@ -108,7 +108,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
|||||||
to: &KeyedAccount,
|
to: &KeyedAccount,
|
||||||
rent: &Rent,
|
rent: &Rent,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let merge_nonce_error_into_system_error = invoke_context
|
let merge_nonce_error_into_system_error = invoke_context
|
||||||
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
||||||
@ -194,7 +194,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
|||||||
&self,
|
&self,
|
||||||
nonce_authority: &Pubkey,
|
nonce_authority: &Pubkey,
|
||||||
rent: &Rent,
|
rent: &Rent,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let merge_nonce_error_into_system_error = invoke_context
|
let merge_nonce_error_into_system_error = invoke_context
|
||||||
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
||||||
@ -245,7 +245,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
|||||||
&self,
|
&self,
|
||||||
nonce_authority: &Pubkey,
|
nonce_authority: &Pubkey,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let merge_nonce_error_into_system_error = invoke_context
|
let merge_nonce_error_into_system_error = invoke_context
|
||||||
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
.is_feature_active(&feature_set::merge_nonce_error_into_system_error::id());
|
||||||
@ -294,7 +294,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use solana_program_runtime::invoke_context::ThisInvokeContext;
|
use solana_program_runtime::invoke_context::InvokeContext;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::ReadableAccount,
|
account::ReadableAccount,
|
||||||
account_utils::State as AccountUtilsState,
|
account_utils::State as AccountUtilsState,
|
||||||
@ -322,8 +322,8 @@ mod test {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_invoke_context_with_blockhash<'a>(seed: usize) -> ThisInvokeContext<'a> {
|
fn create_invoke_context_with_blockhash<'a>(seed: usize) -> InvokeContext<'a> {
|
||||||
let mut invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let mut invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let (blockhash, lamports_per_signature) = create_test_blockhash(seed);
|
let (blockhash, lamports_per_signature) = create_test_blockhash(seed);
|
||||||
invoke_context.set_blockhash(blockhash);
|
invoke_context.set_blockhash(blockhash);
|
||||||
invoke_context.set_lamports_per_signature(lamports_per_signature);
|
invoke_context.set_lamports_per_signature(lamports_per_signature);
|
||||||
@ -1017,7 +1017,7 @@ mod test {
|
|||||||
let result = nonce_account.authorize_nonce_account(
|
let result = nonce_account.authorize_nonce_account(
|
||||||
&Pubkey::default(),
|
&Pubkey::default(),
|
||||||
&signers,
|
&signers,
|
||||||
&ThisInvokeContext::new_mock(&[], &[]),
|
&InvokeContext::new_mock(&[], &[]),
|
||||||
);
|
);
|
||||||
assert_eq!(result, Err(InstructionError::InvalidAccountData));
|
assert_eq!(result, Err(InstructionError::InvalidAccountData));
|
||||||
})
|
})
|
||||||
|
@ -35,7 +35,7 @@ impl Address {
|
|||||||
fn create(
|
fn create(
|
||||||
address: &Pubkey,
|
address: &Pubkey,
|
||||||
with_seed: Option<(&Pubkey, &str, &Pubkey)>,
|
with_seed: Option<(&Pubkey, &str, &Pubkey)>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<Self, InstructionError> {
|
) -> Result<Self, InstructionError> {
|
||||||
let base = if let Some((base, seed, owner)) = with_seed {
|
let base = if let Some((base, seed, owner)) = with_seed {
|
||||||
let address_with_seed = Pubkey::create_with_seed(base, seed, owner)?;
|
let address_with_seed = Pubkey::create_with_seed(base, seed, owner)?;
|
||||||
@ -66,7 +66,7 @@ fn allocate(
|
|||||||
address: &Address,
|
address: &Address,
|
||||||
space: u64,
|
space: u64,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
if !address.is_signer(signers) {
|
if !address.is_signer(signers) {
|
||||||
ic_msg!(
|
ic_msg!(
|
||||||
@ -108,7 +108,7 @@ fn assign(
|
|||||||
address: &Address,
|
address: &Address,
|
||||||
owner: &Pubkey,
|
owner: &Pubkey,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
// no work to do, just return
|
// no work to do, just return
|
||||||
if account.owner() == owner {
|
if account.owner() == owner {
|
||||||
@ -141,7 +141,7 @@ fn allocate_and_assign(
|
|||||||
space: u64,
|
space: u64,
|
||||||
owner: &Pubkey,
|
owner: &Pubkey,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
allocate(to, to_address, space, signers, invoke_context)?;
|
allocate(to, to_address, space, signers, invoke_context)?;
|
||||||
assign(to, to_address, owner, signers, invoke_context)
|
assign(to, to_address, owner, signers, invoke_context)
|
||||||
@ -155,7 +155,7 @@ fn create_account(
|
|||||||
space: u64,
|
space: u64,
|
||||||
owner: &Pubkey,
|
owner: &Pubkey,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
// if it looks like the `to` account is already in use, bail
|
// if it looks like the `to` account is already in use, bail
|
||||||
{
|
{
|
||||||
@ -178,7 +178,7 @@ fn transfer_verified(
|
|||||||
from: &KeyedAccount,
|
from: &KeyedAccount,
|
||||||
to: &KeyedAccount,
|
to: &KeyedAccount,
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
if !from.data_is_empty()? {
|
if !from.data_is_empty()? {
|
||||||
ic_msg!(invoke_context, "Transfer: `from` must not carry data");
|
ic_msg!(invoke_context, "Transfer: `from` must not carry data");
|
||||||
@ -203,7 +203,7 @@ fn transfer(
|
|||||||
from: &KeyedAccount,
|
from: &KeyedAccount,
|
||||||
to: &KeyedAccount,
|
to: &KeyedAccount,
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
if !invoke_context.is_feature_active(&feature_set::system_transfer_zero_check::id())
|
if !invoke_context.is_feature_active(&feature_set::system_transfer_zero_check::id())
|
||||||
&& lamports == 0
|
&& lamports == 0
|
||||||
@ -230,7 +230,7 @@ fn transfer_with_seed(
|
|||||||
from_owner: &Pubkey,
|
from_owner: &Pubkey,
|
||||||
to: &KeyedAccount,
|
to: &KeyedAccount,
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
if !invoke_context.is_feature_active(&feature_set::system_transfer_zero_check::id())
|
if !invoke_context.is_feature_active(&feature_set::system_transfer_zero_check::id())
|
||||||
&& lamports == 0
|
&& lamports == 0
|
||||||
@ -265,7 +265,7 @@ fn transfer_with_seed(
|
|||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
first_instruction_account: usize,
|
first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
let instruction = limited_deserialize(instruction_data)?;
|
let instruction = limited_deserialize(instruction_data)?;
|
||||||
@ -481,7 +481,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::{bank::Bank, bank_client::BankClient};
|
use crate::{bank::Bank, bank_client::BankClient};
|
||||||
use bincode::serialize;
|
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)]
|
#[allow(deprecated)]
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::{self, Account, AccountSharedData},
|
account::{self, Account, AccountSharedData},
|
||||||
@ -638,7 +638,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_address_create_with_seed_mismatch() {
|
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 from = Pubkey::new_unique();
|
||||||
let seed = "dull boy";
|
let seed = "dull boy";
|
||||||
let to = Pubkey::new_unique();
|
let to = Pubkey::new_unique();
|
||||||
@ -652,7 +652,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_account_with_seed_missing_sig() {
|
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 new_owner = Pubkey::new(&[9; 32]);
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
let seed = "dull boy";
|
let seed = "dull boy";
|
||||||
@ -682,7 +682,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_with_zero_lamports() {
|
fn test_create_with_zero_lamports() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
// create account with zero lamports transferred
|
// create account with zero lamports transferred
|
||||||
let new_owner = Pubkey::new(&[9; 32]);
|
let new_owner = Pubkey::new(&[9; 32]);
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
@ -716,7 +716,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_negative_lamports() {
|
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
|
// Attempt to create account with more lamports than remaining in from_account
|
||||||
let new_owner = Pubkey::new(&[9; 32]);
|
let new_owner = Pubkey::new(&[9; 32]);
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
@ -740,7 +740,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_request_more_than_allowed_data_length() {
|
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_account = AccountSharedData::new_ref(100, 0, &system_program::id());
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
let to_account = AccountSharedData::new_ref(0, 0, &system_program::id());
|
let to_account = AccountSharedData::new_ref(0, 0, &system_program::id());
|
||||||
@ -787,7 +787,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_already_in_use() {
|
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
|
// Attempt to create system account in account already owned by another program
|
||||||
let new_owner = Pubkey::new(&[9; 32]);
|
let new_owner = Pubkey::new(&[9; 32]);
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
@ -855,7 +855,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_unsigned() {
|
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
|
// Attempt to create an account without signing the transfer
|
||||||
let new_owner = Pubkey::new(&[9; 32]);
|
let new_owner = Pubkey::new(&[9; 32]);
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
@ -910,7 +910,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_sysvar_invalid_id_with_feature() {
|
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
|
// Attempt to create system account in account already owned by another program
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
let from_account = AccountSharedData::new_ref(100, 0, &system_program::id());
|
let from_account = AccountSharedData::new_ref(100, 0, &system_program::id());
|
||||||
@ -944,12 +944,8 @@ mod tests {
|
|||||||
feature_set
|
feature_set
|
||||||
.inactive
|
.inactive
|
||||||
.insert(feature_set::rent_for_sysvars::id());
|
.insert(feature_set::rent_for_sysvars::id());
|
||||||
let invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
|
let invoke_context =
|
||||||
&[],
|
InvokeContext::new_mock_with_sysvars_and_features(&[], &[], &[], Arc::new(feature_set));
|
||||||
&[],
|
|
||||||
&[],
|
|
||||||
Arc::new(feature_set),
|
|
||||||
);
|
|
||||||
// Attempt to create system account in account already owned by another program
|
// Attempt to create system account in account already owned by another program
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
let from_account = AccountSharedData::new_ref(100, 0, &system_program::id());
|
let from_account = AccountSharedData::new_ref(100, 0, &system_program::id());
|
||||||
@ -975,7 +971,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_data_populated() {
|
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
|
// Attempt to create system account in account with populated data
|
||||||
let new_owner = Pubkey::new(&[9; 32]);
|
let new_owner = Pubkey::new(&[9; 32]);
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
@ -1009,7 +1005,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_from_account_is_nonce_fail() {
|
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 = Pubkey::new_unique();
|
||||||
let nonce_account = AccountSharedData::new_ref_data(
|
let nonce_account = AccountSharedData::new_ref_data(
|
||||||
42,
|
42,
|
||||||
@ -1045,7 +1041,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_assign() {
|
fn test_assign() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let new_owner = Pubkey::new(&[9; 32]);
|
let new_owner = Pubkey::new(&[9; 32]);
|
||||||
let pubkey = Pubkey::new_unique();
|
let pubkey = Pubkey::new_unique();
|
||||||
let mut account = AccountSharedData::new(100, 0, &system_program::id());
|
let mut account = AccountSharedData::new(100, 0, &system_program::id());
|
||||||
@ -1085,7 +1081,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_assign_to_sysvar_with_feature() {
|
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 new_owner = sysvar::id();
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
let mut from_account = AccountSharedData::new(100, 0, &system_program::id());
|
let mut from_account = AccountSharedData::new(100, 0, &system_program::id());
|
||||||
@ -1111,12 +1107,8 @@ mod tests {
|
|||||||
feature_set
|
feature_set
|
||||||
.inactive
|
.inactive
|
||||||
.insert(feature_set::rent_for_sysvars::id());
|
.insert(feature_set::rent_for_sysvars::id());
|
||||||
let invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
|
let invoke_context =
|
||||||
&[],
|
InvokeContext::new_mock_with_sysvars_and_features(&[], &[], &[], Arc::new(feature_set));
|
||||||
&[],
|
|
||||||
&[],
|
|
||||||
Arc::new(feature_set),
|
|
||||||
);
|
|
||||||
let new_owner = sysvar::id();
|
let new_owner = sysvar::id();
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
let mut from_account = AccountSharedData::new(100, 0, &system_program::id());
|
let mut from_account = AccountSharedData::new(100, 0, &system_program::id());
|
||||||
@ -1154,7 +1146,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transfer_lamports() {
|
fn test_transfer_lamports() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let from = Pubkey::new_unique();
|
let from = Pubkey::new_unique();
|
||||||
let from_account = AccountSharedData::new_ref(100, 0, &Pubkey::new(&[2; 32])); // account owner should not matter
|
let from_account = AccountSharedData::new_ref(100, 0, &Pubkey::new(&[2; 32])); // account owner should not matter
|
||||||
let to = Pubkey::new(&[3; 32]);
|
let to = Pubkey::new(&[3; 32]);
|
||||||
@ -1192,7 +1184,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transfer_with_seed() {
|
fn test_transfer_with_seed() {
|
||||||
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
|
let invoke_context = InvokeContext::new_mock(&[], &[]);
|
||||||
let base = Pubkey::new_unique();
|
let base = Pubkey::new_unique();
|
||||||
let base_account = AccountSharedData::new_ref(100, 0, &Pubkey::new(&[2; 32])); // account owner should not matter
|
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);
|
let from_base_keyed_account = KeyedAccount::new(&base, true, &base_account);
|
||||||
@ -1252,7 +1244,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transfer_lamports_from_nonce_account_fail() {
|
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 = Pubkey::new_unique();
|
||||||
let from_account = AccountSharedData::new_ref_data(
|
let from_account = AccountSharedData::new_ref_data(
|
||||||
100,
|
100,
|
||||||
@ -1582,7 +1574,7 @@ mod tests {
|
|||||||
&keyed_accounts,
|
&keyed_accounts,
|
||||||
|first_instruction_account: usize,
|
|first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext| {
|
invoke_context: &mut InvokeContext| {
|
||||||
invoke_context.set_blockhash(hash(&serialize(&0).unwrap()));
|
invoke_context.set_blockhash(hash(&serialize(&0).unwrap()));
|
||||||
super::process_instruction(
|
super::process_instruction(
|
||||||
first_instruction_account,
|
first_instruction_account,
|
||||||
@ -1998,7 +1990,7 @@ mod tests {
|
|||||||
&keyed_accounts,
|
&keyed_accounts,
|
||||||
|first_instruction_account: usize,
|
|first_instruction_account: usize,
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
invoke_context: &mut dyn InvokeContext| {
|
invoke_context: &mut InvokeContext| {
|
||||||
invoke_context.set_blockhash(hash(&serialize(&0).unwrap()));
|
invoke_context.set_blockhash(hash(&serialize(&0).unwrap()));
|
||||||
super::process_instruction(
|
super::process_instruction(
|
||||||
first_instruction_account,
|
first_instruction_account,
|
||||||
|
Reference in New Issue
Block a user