Add native loader entry points (#9275)
This commit is contained in:
@ -7,7 +7,19 @@ use crate::{account::KeyedAccount, instruction::InstructionError, pubkey::Pubkey
|
||||
/// program_id: Program ID of the currently executing program
|
||||
/// keyed_accounts: Accounts passed as part of the instruction
|
||||
/// instruction_data: Instruction data
|
||||
pub type Entrypoint = unsafe extern "C" fn(
|
||||
pub type ProgramEntrypoint = unsafe extern "C" fn(
|
||||
program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
instruction_data: &[u8],
|
||||
) -> Result<(), InstructionError>;
|
||||
|
||||
// Prototype of a native loader entry point
|
||||
///
|
||||
/// program_id: Program ID of the currently executing program
|
||||
/// keyed_accounts: Accounts passed as part of the instruction
|
||||
/// instruction_data: Instruction data
|
||||
/// invoke_context: Invocation context
|
||||
pub type LoaderEntrypoint = unsafe extern "C" fn(
|
||||
program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
instruction_data: &[u8],
|
||||
@ -89,7 +101,32 @@ macro_rules! declare_program(
|
||||
#[macro_export]
|
||||
macro_rules! $name {
|
||||
() => {
|
||||
(stringify!($name).to_string(), $crate::id())
|
||||
(solana_sdk::native_program_info!(stringify!($name).to_string()), $crate::id())
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn $name(
|
||||
program_id: &$crate::pubkey::Pubkey,
|
||||
keyed_accounts: &[$crate::account::KeyedAccount],
|
||||
instruction_data: &[u8],
|
||||
) -> Result<(), $crate::instruction::InstructionError> {
|
||||
$entrypoint(program_id, keyed_accounts, instruction_data)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
/// Same as declare_program but for native loaders
|
||||
#[macro_export]
|
||||
macro_rules! declare_loader(
|
||||
($bs58_string:expr, $name:ident, $entrypoint:expr) => (
|
||||
$crate::declare_id!($bs58_string);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! $name {
|
||||
() => {
|
||||
(solana_sdk::native_loader_info!(stringify!($name).to_string()), $crate::id())
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ use crate::{
|
||||
fee_calculator::FeeRateGovernor,
|
||||
hash::{hash, Hash},
|
||||
inflation::Inflation,
|
||||
native_loader,
|
||||
native_token::lamports_to_sol,
|
||||
poh_config::PohConfig,
|
||||
pubkey::Pubkey,
|
||||
@ -41,7 +42,7 @@ pub struct GenesisConfig {
|
||||
/// initial accounts
|
||||
pub accounts: BTreeMap<Pubkey, Account>,
|
||||
/// built-in programs
|
||||
pub native_instruction_processors: Vec<(String, Pubkey)>,
|
||||
pub native_instruction_processors: Vec<(native_loader::Info, Pubkey)>,
|
||||
/// accounts for network rewards, these do not count towards capitalization
|
||||
pub rewards_pools: BTreeMap<Pubkey, Account>,
|
||||
pub ticks_per_slot: u64,
|
||||
@ -104,7 +105,7 @@ impl Default for GenesisConfig {
|
||||
impl GenesisConfig {
|
||||
pub fn new(
|
||||
accounts: &[(Pubkey, Account)],
|
||||
native_instruction_processors: &[(String, Pubkey)],
|
||||
native_instruction_processors: &[(native_loader::Info, Pubkey)],
|
||||
) -> Self {
|
||||
Self {
|
||||
accounts: accounts
|
||||
@ -172,8 +173,8 @@ impl GenesisConfig {
|
||||
self.accounts.insert(pubkey, account);
|
||||
}
|
||||
|
||||
pub fn add_native_instruction_processor(&mut self, name: String, program_id: Pubkey) {
|
||||
self.native_instruction_processors.push((name, program_id));
|
||||
pub fn add_native_instruction_processor(&mut self, processor: (native_loader::Info, Pubkey)) {
|
||||
self.native_instruction_processors.push(processor);
|
||||
}
|
||||
|
||||
pub fn add_rewards_pool(&mut self, pubkey: Pubkey, account: Account) {
|
||||
@ -230,6 +231,7 @@ impl fmt::Display for GenesisConfig {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::signature::{Keypair, Signer};
|
||||
use solana_sdk::native_program_info;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn make_tmp_path(name: &str) -> PathBuf {
|
||||
@ -261,7 +263,10 @@ mod tests {
|
||||
Account::new(10_000, 0, &Pubkey::default()),
|
||||
);
|
||||
config.add_account(Pubkey::new_rand(), Account::new(1, 0, &Pubkey::default()));
|
||||
config.add_native_instruction_processor("hi".to_string(), Pubkey::new_rand());
|
||||
config.add_native_instruction_processor((
|
||||
native_program_info!("hi".to_string()),
|
||||
Pubkey::new_rand(),
|
||||
));
|
||||
|
||||
assert_eq!(config.accounts.len(), 2);
|
||||
assert!(config
|
||||
|
@ -134,6 +134,10 @@ pub enum InstructionError {
|
||||
/// Executable accounts must be rent exempt
|
||||
#[error("executable accounts must be rent exempt")]
|
||||
ExecutableAccountNotRentExempt,
|
||||
|
||||
/// Unsupported program id
|
||||
#[error("Unsupported program id")]
|
||||
UnsupportedProgramId,
|
||||
}
|
||||
|
||||
impl InstructionError {
|
||||
|
@ -1,5 +1,10 @@
|
||||
use crate::{native_loader, native_program_info, pubkey::Pubkey};
|
||||
|
||||
crate::declare_id!("MoveLdr111111111111111111111111111111111111");
|
||||
|
||||
pub fn solana_move_loader_program() -> (String, crate::pubkey::Pubkey) {
|
||||
("solana_move_loader_program".to_string(), id())
|
||||
pub fn solana_move_loader_program() -> (native_loader::Info, Pubkey) {
|
||||
(
|
||||
native_program_info!("solana_move_loader_program".to_string()),
|
||||
id(),
|
||||
)
|
||||
}
|
||||
|
@ -1,13 +1,46 @@
|
||||
use crate::{account::Account, hash::Hash};
|
||||
use num_derive::FromPrimitive;
|
||||
|
||||
crate::declare_id!("NativeLoader1111111111111111111111111111111");
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub struct Info {
|
||||
pub kind: Kind,
|
||||
pub name: String,
|
||||
}
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Eq, FromPrimitive, Hash, PartialEq, Serialize)]
|
||||
pub enum Kind {
|
||||
Program = 1,
|
||||
Loader = 2,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! native_program_info(
|
||||
($name:expr) => (
|
||||
$crate::native_loader::Info {
|
||||
kind: $crate::native_loader::Kind::Program,
|
||||
name: $name.to_string(),
|
||||
}
|
||||
)
|
||||
);
|
||||
#[macro_export]
|
||||
macro_rules! native_loader_info(
|
||||
($name:expr) => (
|
||||
$crate::native_loader::Info {
|
||||
kind: $crate::native_loader::Kind::Loader,
|
||||
name: $name.to_string(),
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
/// Create an executable account with the given shared object name.
|
||||
pub fn create_loadable_account(name: &str) -> Account {
|
||||
pub fn create_loadable_account(info: &Info) -> Account {
|
||||
let mut data = vec![info.kind as u8];
|
||||
data.extend_from_slice(info.name.as_bytes());
|
||||
Account {
|
||||
lamports: 1,
|
||||
owner: id(),
|
||||
data: name.as_bytes().to_vec(),
|
||||
data,
|
||||
executable: true,
|
||||
rent_epoch: 0,
|
||||
hash: Hash::default(),
|
||||
|
@ -1,5 +1,10 @@
|
||||
use crate::{native_loader, native_program_info, pubkey::Pubkey};
|
||||
|
||||
crate::declare_id!("11111111111111111111111111111111");
|
||||
|
||||
pub fn solana_system_program() -> (String, crate::pubkey::Pubkey) {
|
||||
("solana_system_program".to_string(), id())
|
||||
pub fn solana_system_program() -> (native_loader::Info, Pubkey) {
|
||||
(
|
||||
native_program_info!("solana_system_program".to_string()),
|
||||
id(),
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user