Add native loader entry points (#9486)

This commit is contained in:
Jack May
2020-04-15 09:41:29 -07:00
committed by GitHub
parent 40737e9efa
commit 241a05fc52
17 changed files with 273 additions and 471 deletions

View File

@ -1,22 +1,18 @@
use crate::{native_loader, rent_collector::RentCollector, system_instruction_processor};
use crate::{
native_loader::NativeLoader, rent_collector::RentCollector, system_instruction_processor,
};
use serde::{Deserialize, Serialize};
use solana_sdk::{
account::{create_keyed_readonly_accounts, Account, KeyedAccount},
clock::Epoch,
entrypoint_native,
instruction::{CompiledInstruction, InstructionError},
message::Message,
native_loader::id as native_loader_id,
native_loader,
pubkey::Pubkey,
system_program,
transaction::TransactionError,
};
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::RwLock};
#[cfg(unix)]
use libloading::os::unix::*;
#[cfg(windows)]
use libloading::os::windows::*;
use std::{cell::RefCell, rc::Rc};
// The relevant state of an account before an Instruction executes, used
// to verify account integrity after the Instruction completes
@ -159,14 +155,13 @@ impl PreAccount {
}
pub type ProcessInstruction = fn(&Pubkey, &[KeyedAccount], &[u8]) -> Result<(), InstructionError>;
pub type SymbolCache = RwLock<HashMap<Vec<u8>, Symbol<entrypoint_native::Entrypoint>>>;
#[derive(Serialize, Deserialize)]
pub struct MessageProcessor {
#[serde(skip)]
instruction_processors: Vec<(Pubkey, ProcessInstruction)>,
#[serde(skip)]
symbol_cache: SymbolCache,
native_loader: NativeLoader,
}
impl Default for MessageProcessor {
fn default() -> Self {
@ -177,7 +172,7 @@ impl Default for MessageProcessor {
Self {
instruction_processors,
symbol_cache: RwLock::new(HashMap::new()),
native_loader: NativeLoader::default(),
}
}
}
@ -218,10 +213,10 @@ impl MessageProcessor {
})
.collect();
keyed_accounts.append(&mut keyed_accounts2);
assert!(keyed_accounts[0].executable()?, "account not executable");
let root_program_id = keyed_accounts[0].unsigned_key();
for (id, process_instruction) in &self.instruction_processors {
let root_program_id = keyed_accounts[0].unsigned_key();
if id == root_program_id {
return process_instruction(
&root_program_id,
@ -231,12 +226,15 @@ impl MessageProcessor {
}
}
native_loader::invoke_entrypoint(
&native_loader_id(),
&keyed_accounts,
&instruction.data,
&self.symbol_cache,
)
if native_loader::check_id(&keyed_accounts[0].owner()?) {
self.native_loader.process_instruction(
&native_loader::id(),
&keyed_accounts,
&instruction.data,
)
} else {
Err(InstructionError::UnsupportedProgramId)
}
}
/// Record the initial state of the accounts so that they can be compared