@@ -2,10 +2,18 @@ use crate::native_loader;
 | 
			
		||||
use crate::system_instruction_processor;
 | 
			
		||||
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
 | 
			
		||||
use solana_sdk::instruction::{CompiledInstruction, InstructionError};
 | 
			
		||||
use solana_sdk::instruction_processor_utils;
 | 
			
		||||
use solana_sdk::message::Message;
 | 
			
		||||
use solana_sdk::pubkey::Pubkey;
 | 
			
		||||
use solana_sdk::system_program;
 | 
			
		||||
use solana_sdk::transaction::TransactionError;
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::sync::RwLock;
 | 
			
		||||
 | 
			
		||||
#[cfg(unix)]
 | 
			
		||||
use libloading::os::unix::*;
 | 
			
		||||
#[cfg(windows)]
 | 
			
		||||
use libloading::os::windows::*;
 | 
			
		||||
 | 
			
		||||
/// Return true if the slice has any duplicate elements
 | 
			
		||||
pub fn has_duplicates<T: PartialEq>(xs: &[T]) -> bool {
 | 
			
		||||
@@ -75,8 +83,11 @@ fn verify_instruction(
 | 
			
		||||
pub type ProcessInstruction =
 | 
			
		||||
    fn(&Pubkey, &mut [KeyedAccount], &[u8], u64) -> Result<(), InstructionError>;
 | 
			
		||||
 | 
			
		||||
pub type SymbolCache = RwLock<HashMap<Vec<u8>, Symbol<instruction_processor_utils::Entrypoint>>>;
 | 
			
		||||
 | 
			
		||||
pub struct MessageProcessor {
 | 
			
		||||
    instruction_processors: Vec<(Pubkey, ProcessInstruction)>,
 | 
			
		||||
    symbol_cache: SymbolCache,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for MessageProcessor {
 | 
			
		||||
@@ -88,6 +99,7 @@ impl Default for MessageProcessor {
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            instruction_processors,
 | 
			
		||||
            symbol_cache: RwLock::new(HashMap::new()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -145,6 +157,7 @@ impl MessageProcessor {
 | 
			
		||||
            &mut keyed_accounts,
 | 
			
		||||
            &instruction.data,
 | 
			
		||||
            tick_height,
 | 
			
		||||
            &self.symbol_cache,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
//! Native loader
 | 
			
		||||
use crate::message_processor::SymbolCache;
 | 
			
		||||
use bincode::deserialize;
 | 
			
		||||
#[cfg(unix)]
 | 
			
		||||
use libloading::os::unix::*;
 | 
			
		||||
@@ -52,12 +53,18 @@ pub fn entrypoint(
 | 
			
		||||
    keyed_accounts: &mut [KeyedAccount],
 | 
			
		||||
    ix_data: &[u8],
 | 
			
		||||
    tick_height: u64,
 | 
			
		||||
    symbol_cache: &SymbolCache,
 | 
			
		||||
) -> Result<(), InstructionError> {
 | 
			
		||||
    if keyed_accounts[0].account.executable {
 | 
			
		||||
        // dispatch it
 | 
			
		||||
        let (names, params) = keyed_accounts.split_at_mut(1);
 | 
			
		||||
        let name = &names[0].account.data;
 | 
			
		||||
        let name = match str::from_utf8(name) {
 | 
			
		||||
        let name_vec = &names[0].account.data;
 | 
			
		||||
        if let Some(entrypoint) = symbol_cache.read().unwrap().get(name_vec) {
 | 
			
		||||
            unsafe {
 | 
			
		||||
                return entrypoint(program_id, params, ix_data, tick_height);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        let name = match str::from_utf8(name_vec) {
 | 
			
		||||
            Ok(v) => v,
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                warn!("Invalid UTF-8 sequence: {}", e);
 | 
			
		||||
@@ -81,7 +88,12 @@ pub fn entrypoint(
 | 
			
		||||
                            return Err(InstructionError::GenericError);
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                return entrypoint(program_id, params, ix_data, tick_height);
 | 
			
		||||
                let ret = entrypoint(program_id, params, ix_data, tick_height);
 | 
			
		||||
                symbol_cache
 | 
			
		||||
                    .write()
 | 
			
		||||
                    .unwrap()
 | 
			
		||||
                    .insert(name_vec.to_vec(), entrypoint);
 | 
			
		||||
                return ret;
 | 
			
		||||
            },
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                warn!("Unable to load: {:?}", e);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user