Add native loader entry points (#9275)

This commit is contained in:
Jack May
2020-04-03 17:40:59 -07:00
committed by GitHub
parent c1441a2a8f
commit ed86d8d1fc
24 changed files with 297 additions and 154 deletions

View File

@ -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())
};
}

View File

@ -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

View File

@ -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 {

View File

@ -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(),
)
}

View File

@ -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(),

View File

@ -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(),
)
}