Add built-in programs to InvokeContext (#10383)

automerge
This commit is contained in:
Michael Vines 2020-06-03 12:48:19 -07:00 committed by GitHub
parent ea9b958dff
commit a4cd96609c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 14 deletions

View File

@ -6,7 +6,7 @@ use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
use solana_rbpf::EbpfVm;
use solana_sdk::{
account::Account,
entrypoint_native::InvokeContext,
entrypoint_native::{InvokeContext, ProcessInstruction},
instruction::{CompiledInstruction, InstructionError},
message::Message,
pubkey::Pubkey,
@ -152,4 +152,7 @@ impl InvokeContext for MockInvokeContext {
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
Ok(&self.key)
}
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
&[]
}
}

View File

@ -259,7 +259,8 @@ mod tests {
use super::*;
use rand::Rng;
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};
@ -283,6 +284,9 @@ mod tests {
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
Ok(&self.key)
}
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
&[]
}
}
#[test]

View File

@ -6,7 +6,7 @@ use solana_rbpf::{
memory_region::{translate_addr, MemoryRegion},
EbpfVm,
};
use solana_runtime::{builtin_programs::get_builtin_programs, message_processor::MessageProcessor};
use solana_runtime::message_processor::MessageProcessor;
use solana_sdk::{
account::Account,
account::KeyedAccount,
@ -767,9 +767,8 @@ fn call<'a>(
let program_account = (*accounts[callee_program_id_index]).clone();
let executable_accounts = vec![(callee_program_id, program_account)];
let mut message_processor = MessageProcessor::default();
let builtin_programs = get_builtin_programs();
for program in builtin_programs.iter() {
message_processor.add_program(program.id, program.process_instruction);
for (program_id, process_instruction) in invoke_context.get_programs().iter() {
message_processor.add_program(*program_id, *process_instruction);
}
message_processor.add_loader(bpf_loader::id(), crate::process_instruction);

View File

@ -12,7 +12,7 @@ use crate::{
blockhash_queue::BlockhashQueue,
builtin_programs::get_builtin_programs,
epoch_stakes::{EpochStakes, NodeVoteAccounts},
message_processor::{MessageProcessor, ProcessInstruction},
message_processor::MessageProcessor,
nonce_utils,
rent_collector::RentCollector,
stakes::Stakes,
@ -35,6 +35,7 @@ use solana_sdk::{
Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_TICKS_PER_SECOND,
MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES, SECONDS_PER_DAY,
},
entrypoint_native::ProcessInstruction,
epoch_info::EpochInfo,
epoch_schedule::EpochSchedule,
fee_calculator::{FeeCalculator, FeeRateGovernor},

View File

@ -1,5 +1,5 @@
use crate::{message_processor::ProcessInstruction, system_instruction_processor};
use solana_sdk::{pubkey::Pubkey, system_program};
use crate::system_instruction_processor;
use solana_sdk::{entrypoint_native::ProcessInstruction, pubkey::Pubkey, system_program};
pub struct BuiltinProgram {
pub name: String,

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use solana_sdk::{
account::{create_keyed_readonly_accounts, Account, KeyedAccount},
clock::Epoch,
entrypoint_native::InvokeContext,
entrypoint_native::{InvokeContext, ProcessInstruction},
instruction::{CompiledInstruction, InstructionError},
message::Message,
native_loader,
@ -151,21 +151,28 @@ impl PreAccount {
}
}
#[derive(Debug, Default)]
#[derive(Default)]
pub struct ThisInvokeContext {
pub program_ids: Vec<Pubkey>,
pub rent: Rent,
pub pre_accounts: Vec<PreAccount>,
pub programs: Vec<(Pubkey, ProcessInstruction)>,
}
impl ThisInvokeContext {
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);
program_ids.push(*program_id);
Self {
program_ids,
rent,
pre_accounts,
programs,
}
}
}
@ -207,9 +214,12 @@ impl InvokeContext for ThisInvokeContext {
.last()
.ok_or(InstructionError::GenericError)
}
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
&self.programs
}
}
pub type ProcessInstruction = fn(&Pubkey, &[KeyedAccount], &[u8]) -> Result<(), InstructionError>;
pub type ProcessInstructionWithContext =
fn(&Pubkey, &[KeyedAccount], &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
@ -479,6 +489,7 @@ impl MessageProcessor {
instruction.program_id(&message.account_keys),
rent_collector.rent,
pre_accounts,
self.programs.clone(),
);
let keyed_accounts =
Self::create_keyed_accounts(message, instruction, executable_accounts, accounts)?;
@ -555,7 +566,7 @@ mod tests {
))
}
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
let mut depth_reached = 1;
@ -1303,6 +1314,7 @@ mod tests {
&caller_program_id,
Rent::default(),
vec![owned_preaccount, not_owned_preaccount],
vec![],
);
let metas = vec![
AccountMeta::new(owned_key, false),

View File

@ -146,6 +146,8 @@ macro_rules! declare_loader(
)
);
pub type ProcessInstruction = fn(&Pubkey, &[KeyedAccount], &[u8]) -> Result<(), InstructionError>;
/// Cross-program invocation context passed to loaders
pub trait InvokeContext {
fn push(&mut self, key: &Pubkey) -> Result<(), InstructionError>;
@ -157,4 +159,5 @@ pub trait InvokeContext {
accounts: &[Rc<RefCell<Account>>],
) -> Result<(), InstructionError>;
fn get_caller(&self) -> Result<&Pubkey, InstructionError>;
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)];
}