@ -6,7 +6,7 @@ use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
|||||||
use solana_rbpf::EbpfVm;
|
use solana_rbpf::EbpfVm;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
entrypoint_native::InvokeContext,
|
entrypoint_native::{InvokeContext, ProcessInstruction},
|
||||||
instruction::{CompiledInstruction, InstructionError},
|
instruction::{CompiledInstruction, InstructionError},
|
||||||
message::Message,
|
message::Message,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
@ -152,4 +152,7 @@ impl InvokeContext for MockInvokeContext {
|
|||||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
||||||
Ok(&self.key)
|
Ok(&self.key)
|
||||||
}
|
}
|
||||||
|
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,7 +259,8 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account, instruction::CompiledInstruction, message::Message, rent::Rent,
|
account::Account, entrypoint_native::ProcessInstruction, instruction::CompiledInstruction,
|
||||||
|
message::Message, rent::Rent,
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc};
|
use std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc};
|
||||||
|
|
||||||
@ -283,6 +284,9 @@ mod tests {
|
|||||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
||||||
Ok(&self.key)
|
Ok(&self.key)
|
||||||
}
|
}
|
||||||
|
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -6,7 +6,7 @@ use solana_rbpf::{
|
|||||||
memory_region::{translate_addr, MemoryRegion},
|
memory_region::{translate_addr, MemoryRegion},
|
||||||
EbpfVm,
|
EbpfVm,
|
||||||
};
|
};
|
||||||
use solana_runtime::{builtin_programs::get_builtin_programs, message_processor::MessageProcessor};
|
use solana_runtime::message_processor::MessageProcessor;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
account::KeyedAccount,
|
account::KeyedAccount,
|
||||||
@ -767,9 +767,8 @@ fn call<'a>(
|
|||||||
let program_account = (*accounts[callee_program_id_index]).clone();
|
let program_account = (*accounts[callee_program_id_index]).clone();
|
||||||
let executable_accounts = vec![(callee_program_id, program_account)];
|
let executable_accounts = vec![(callee_program_id, program_account)];
|
||||||
let mut message_processor = MessageProcessor::default();
|
let mut message_processor = MessageProcessor::default();
|
||||||
let builtin_programs = get_builtin_programs();
|
for (program_id, process_instruction) in invoke_context.get_programs().iter() {
|
||||||
for program in builtin_programs.iter() {
|
message_processor.add_program(*program_id, *process_instruction);
|
||||||
message_processor.add_program(program.id, program.process_instruction);
|
|
||||||
}
|
}
|
||||||
message_processor.add_loader(bpf_loader::id(), crate::process_instruction);
|
message_processor.add_loader(bpf_loader::id(), crate::process_instruction);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
blockhash_queue::BlockhashQueue,
|
blockhash_queue::BlockhashQueue,
|
||||||
builtin_programs::get_builtin_programs,
|
builtin_programs::get_builtin_programs,
|
||||||
epoch_stakes::{EpochStakes, NodeVoteAccounts},
|
epoch_stakes::{EpochStakes, NodeVoteAccounts},
|
||||||
message_processor::{MessageProcessor, ProcessInstruction},
|
message_processor::MessageProcessor,
|
||||||
nonce_utils,
|
nonce_utils,
|
||||||
rent_collector::RentCollector,
|
rent_collector::RentCollector,
|
||||||
stakes::Stakes,
|
stakes::Stakes,
|
||||||
@ -35,6 +35,7 @@ use solana_sdk::{
|
|||||||
Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_TICKS_PER_SECOND,
|
Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_TICKS_PER_SECOND,
|
||||||
MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES, SECONDS_PER_DAY,
|
MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES, SECONDS_PER_DAY,
|
||||||
},
|
},
|
||||||
|
entrypoint_native::ProcessInstruction,
|
||||||
epoch_info::EpochInfo,
|
epoch_info::EpochInfo,
|
||||||
epoch_schedule::EpochSchedule,
|
epoch_schedule::EpochSchedule,
|
||||||
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{message_processor::ProcessInstruction, system_instruction_processor};
|
use crate::system_instruction_processor;
|
||||||
use solana_sdk::{pubkey::Pubkey, system_program};
|
use solana_sdk::{entrypoint_native::ProcessInstruction, pubkey::Pubkey, system_program};
|
||||||
|
|
||||||
pub struct BuiltinProgram {
|
pub struct BuiltinProgram {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::{create_keyed_readonly_accounts, Account, KeyedAccount},
|
account::{create_keyed_readonly_accounts, Account, KeyedAccount},
|
||||||
clock::Epoch,
|
clock::Epoch,
|
||||||
entrypoint_native::InvokeContext,
|
entrypoint_native::{InvokeContext, ProcessInstruction},
|
||||||
instruction::{CompiledInstruction, InstructionError},
|
instruction::{CompiledInstruction, InstructionError},
|
||||||
message::Message,
|
message::Message,
|
||||||
native_loader,
|
native_loader,
|
||||||
@ -151,21 +151,28 @@ impl PreAccount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Default)]
|
||||||
pub struct ThisInvokeContext {
|
pub struct ThisInvokeContext {
|
||||||
pub program_ids: Vec<Pubkey>,
|
pub program_ids: Vec<Pubkey>,
|
||||||
pub rent: Rent,
|
pub rent: Rent,
|
||||||
pub pre_accounts: Vec<PreAccount>,
|
pub pre_accounts: Vec<PreAccount>,
|
||||||
|
pub programs: Vec<(Pubkey, ProcessInstruction)>,
|
||||||
}
|
}
|
||||||
impl ThisInvokeContext {
|
impl ThisInvokeContext {
|
||||||
const MAX_INVOCATION_DEPTH: usize = 5;
|
const MAX_INVOCATION_DEPTH: usize = 5;
|
||||||
pub fn new(program_id: &Pubkey, rent: Rent, pre_accounts: Vec<PreAccount>) -> Self {
|
pub fn new(
|
||||||
|
program_id: &Pubkey,
|
||||||
|
rent: Rent,
|
||||||
|
pre_accounts: Vec<PreAccount>,
|
||||||
|
programs: Vec<(Pubkey, ProcessInstruction)>,
|
||||||
|
) -> Self {
|
||||||
let mut program_ids = Vec::with_capacity(Self::MAX_INVOCATION_DEPTH);
|
let mut program_ids = Vec::with_capacity(Self::MAX_INVOCATION_DEPTH);
|
||||||
program_ids.push(*program_id);
|
program_ids.push(*program_id);
|
||||||
Self {
|
Self {
|
||||||
program_ids,
|
program_ids,
|
||||||
rent,
|
rent,
|
||||||
pre_accounts,
|
pre_accounts,
|
||||||
|
programs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,9 +214,12 @@ impl InvokeContext for ThisInvokeContext {
|
|||||||
.last()
|
.last()
|
||||||
.ok_or(InstructionError::GenericError)
|
.ok_or(InstructionError::GenericError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
|
||||||
|
&self.programs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ProcessInstruction = fn(&Pubkey, &[KeyedAccount], &[u8]) -> Result<(), InstructionError>;
|
|
||||||
pub type ProcessInstructionWithContext =
|
pub type ProcessInstructionWithContext =
|
||||||
fn(&Pubkey, &[KeyedAccount], &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
|
fn(&Pubkey, &[KeyedAccount], &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
|
||||||
|
|
||||||
@ -479,6 +489,7 @@ impl MessageProcessor {
|
|||||||
instruction.program_id(&message.account_keys),
|
instruction.program_id(&message.account_keys),
|
||||||
rent_collector.rent,
|
rent_collector.rent,
|
||||||
pre_accounts,
|
pre_accounts,
|
||||||
|
self.programs.clone(),
|
||||||
);
|
);
|
||||||
let keyed_accounts =
|
let keyed_accounts =
|
||||||
Self::create_keyed_accounts(message, instruction, executable_accounts, accounts)?;
|
Self::create_keyed_accounts(message, instruction, executable_accounts, accounts)?;
|
||||||
@ -555,7 +566,7 @@ mod tests {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
let mut invoke_context =
|
let mut invoke_context =
|
||||||
ThisInvokeContext::new(&program_ids[0], Rent::default(), pre_accounts);
|
ThisInvokeContext::new(&program_ids[0], Rent::default(), pre_accounts, vec![]);
|
||||||
|
|
||||||
// Check call depth increases and has a limit
|
// Check call depth increases and has a limit
|
||||||
let mut depth_reached = 1;
|
let mut depth_reached = 1;
|
||||||
@ -1303,6 +1314,7 @@ mod tests {
|
|||||||
&caller_program_id,
|
&caller_program_id,
|
||||||
Rent::default(),
|
Rent::default(),
|
||||||
vec![owned_preaccount, not_owned_preaccount],
|
vec![owned_preaccount, not_owned_preaccount],
|
||||||
|
vec![],
|
||||||
);
|
);
|
||||||
let metas = vec![
|
let metas = vec![
|
||||||
AccountMeta::new(owned_key, false),
|
AccountMeta::new(owned_key, false),
|
||||||
|
@ -146,6 +146,8 @@ macro_rules! declare_loader(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pub type ProcessInstruction = fn(&Pubkey, &[KeyedAccount], &[u8]) -> Result<(), InstructionError>;
|
||||||
|
|
||||||
/// Cross-program invocation context passed to loaders
|
/// Cross-program invocation context passed to loaders
|
||||||
pub trait InvokeContext {
|
pub trait InvokeContext {
|
||||||
fn push(&mut self, key: &Pubkey) -> Result<(), InstructionError>;
|
fn push(&mut self, key: &Pubkey) -> Result<(), InstructionError>;
|
||||||
@ -157,4 +159,5 @@ pub trait InvokeContext {
|
|||||||
accounts: &[Rc<RefCell<Account>>],
|
accounts: &[Rc<RefCell<Account>>],
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError>;
|
fn get_caller(&self) -> Result<&Pubkey, InstructionError>;
|
||||||
|
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user