Add native loader entry points (#9275)
This commit is contained in:
@ -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
|
||||
@ -372,6 +370,7 @@ mod tests {
|
||||
instruction::{AccountMeta, Instruction, InstructionError},
|
||||
message::Message,
|
||||
native_loader::create_loadable_account,
|
||||
native_program_info,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -917,7 +916,9 @@ mod tests {
|
||||
accounts.push(account);
|
||||
|
||||
let mut loaders: Vec<Vec<(Pubkey, RefCell<Account>)>> = Vec::new();
|
||||
let account = RefCell::new(create_loadable_account("mock_system_program"));
|
||||
let account = RefCell::new(create_loadable_account(&native_program_info!(
|
||||
"mock_system_program"
|
||||
)));
|
||||
loaders.push(vec![(mock_system_program_id, account)]);
|
||||
|
||||
let from_pubkey = Pubkey::new_rand();
|
||||
@ -1040,7 +1041,9 @@ mod tests {
|
||||
accounts.push(account);
|
||||
|
||||
let mut loaders: Vec<Vec<(Pubkey, RefCell<Account>)>> = Vec::new();
|
||||
let account = RefCell::new(create_loadable_account("mock_system_program"));
|
||||
let account = RefCell::new(create_loadable_account(&native_program_info!(
|
||||
"mock_system_program"
|
||||
)));
|
||||
loaders.push(vec![(mock_program_id, account)]);
|
||||
|
||||
let from_pubkey = Pubkey::new_rand();
|
||||
|
Reference in New Issue
Block a user