Native/builtin programs now receive an InvokeContext

This commit is contained in:
Michael Vines
2020-10-28 20:21:50 -07:00
parent ca00197009
commit df8dab9d2b
36 changed files with 402 additions and 251 deletions

View File

@ -2211,6 +2211,7 @@ dependencies = [
"hex",
"hmac",
"itertools",
"lazy_static",
"libsecp256k1",
"log",
"memmap",

View File

@ -12,10 +12,8 @@ use solana_rbpf::vm::{Executable, InstructionMeter};
use solana_runtime::{
bank::Bank,
bank_client::BankClient,
bpf_test_utils::MockInvokeContext,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
loader_utils::load_program,
process_instruction::InvokeContext,
};
use solana_sdk::{
account::Account,
@ -24,6 +22,7 @@ use solana_sdk::{
entrypoint::SUCCESS,
instruction::{AccountMeta, Instruction},
message::Message,
process_instruction::{InvokeContext, MockInvokeContext},
pubkey::Pubkey,
signature::{Keypair, Signer},
};

View File

@ -12,10 +12,8 @@ use solana_rbpf::vm::Executable;
use solana_runtime::{
bank::Bank,
bank_client::BankClient,
bpf_test_utils::MockInvokeContext,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
loader_utils::load_program,
process_instruction::{ComputeBudget, InvokeContext},
};
use solana_sdk::{
account::Account,
@ -26,6 +24,7 @@ use solana_sdk::{
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
keyed_account::KeyedAccount,
message::Message,
process_instruction::{ComputeBudget, InvokeContext, MockInvokeContext},
pubkey::Pubkey,
signature::{Keypair, Signer},
sysvar::{clock, fees, rent, slot_hashes, stake_history},

View File

@ -17,17 +17,16 @@ use solana_rbpf::{
memory_region::MemoryRegion,
vm::{Config, EbpfVm, Executable, InstructionMeter},
};
use solana_runtime::{
feature_set::{bpf_just_in_time_compilation, compute_budget_balancing},
process_instruction::{ComputeMeter, Executor, InvokeContext},
};
use solana_sdk::{
bpf_loader, bpf_loader_deprecated,
decode_error::DecodeError,
entrypoint::SUCCESS,
feature_set::compute_budget_balancing,
feature_set::{bpf_just_in_time_compilation, compute_budget_balancing},
instruction::InstructionError,
keyed_account::{is_executable, next_keyed_account, KeyedAccount},
loader_instruction::LoaderInstruction,
process_instruction::{ComputeMeter, Executor, InvokeContext},
program_utils::limited_deserialize,
pubkey::Pubkey,
};
@ -326,14 +325,15 @@ impl Executor for BPFExecutor {
mod tests {
use super::*;
use rand::Rng;
use solana_runtime::{
bpf_test_utils::MockInvokeContext,
use solana_runtime::message_processor::{Executors, ThisInvokeContext};
use solana_sdk::{
account::Account,
feature_set::FeatureSet,
message_processor::{Executors, ThisInvokeContext},
process_instruction::ComputeBudget,
instruction::InstructionError,
process_instruction::{ComputeBudget, MockInvokeContext},
rent::Rent,
};
use solana_sdk::{account::Account, instruction::InstructionError, pubkey::Pubkey, rent::Rent};
use std::{fs::File, io::Read, ops::Range};
use std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc};
struct TestInstructionMeter {
remaining: u64,

View File

@ -7,22 +7,20 @@ use solana_rbpf::{
memory_region::{AccessType, MemoryMapping},
vm::{EbpfVm, Syscall, SyscallObject},
};
use solana_runtime::{
feature_set::{
pubkey_log_syscall_enabled, ristretto_mul_syscall_enabled, sha256_syscall_enabled,
},
message_processor::MessageProcessor,
process_instruction::{ComputeMeter, InvokeContext, Logger},
};
use solana_runtime::message_processor::MessageProcessor;
use solana_sdk::{
account::Account,
account_info::AccountInfo,
bpf_loader, bpf_loader_deprecated,
bpf_loader_deprecated,
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
feature_set::{
pubkey_log_syscall_enabled, ristretto_mul_syscall_enabled, sha256_syscall_enabled,
},
hash::{Hasher, HASH_BYTES},
instruction::{AccountMeta, Instruction, InstructionError},
keyed_account::KeyedAccount,
message::Message,
process_instruction::{ComputeMeter, InvokeContext, Logger},
program_error::ProgramError,
pubkey::{Pubkey, PubkeyError},
};
@ -1351,8 +1349,11 @@ fn call<'a>(
mod tests {
use super::*;
use solana_rbpf::memory_region::MemoryRegion;
use solana_runtime::bpf_test_utils::{MockComputeMeter, MockLogger};
use solana_sdk::hash::hashv;
use solana_sdk::{
bpf_loader,
hash::hashv,
process_instruction::{MockComputeMeter, MockLogger},
};
use std::str::FromStr;
macro_rules! assert_access_violation {

View File

@ -10,6 +10,7 @@ use solana_sdk::{
hash::hash,
instruction::InstructionError,
keyed_account::{next_keyed_account, KeyedAccount},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
};
@ -116,6 +117,7 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts_iter = &mut keyed_accounts.iter();
let instruction = limited_deserialize(data)?;

View File

@ -3,15 +3,19 @@
use crate::ConfigKeys;
use bincode::deserialize;
use log::*;
use solana_sdk::instruction::InstructionError;
use solana_sdk::keyed_account::{next_keyed_account, KeyedAccount};
use solana_sdk::program_utils::limited_deserialize;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::{
instruction::InstructionError,
keyed_account::{next_keyed_account, KeyedAccount},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
};
pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
let key_list: ConfigKeys = limited_deserialize(data)?;
let keyed_accounts_iter = &mut keyed_accounts.iter();
@ -109,6 +113,7 @@ mod tests {
use solana_sdk::{
account::Account,
keyed_account::create_keyed_is_signer_accounts,
process_instruction::MockInvokeContext,
signature::{Keypair, Signer},
system_instruction::SystemInstruction,
};
@ -162,7 +167,12 @@ mod tests {
let accounts = vec![(&config_pubkey, true, &config_account)];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instructions[1].data),
process_instruction(
&id(),
&keyed_accounts,
&instructions[1].data,
&mut MockInvokeContext::default()
),
Ok(())
);
@ -192,7 +202,12 @@ mod tests {
let accounts = vec![(&config_pubkey, true, &config_account)];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Ok(())
);
assert_eq!(
@ -214,7 +229,12 @@ mod tests {
let accounts = vec![(&config_pubkey, true, &config_account)];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::InvalidInstructionData)
);
}
@ -232,7 +252,12 @@ mod tests {
let accounts = vec![(&config_pubkey, false, &config_account)];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::MissingRequiredSignature)
);
}
@ -262,7 +287,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Ok(())
);
let meta_data: ConfigKeys = deserialize(&config_account.borrow().data).unwrap();
@ -288,7 +318,12 @@ mod tests {
let accounts = vec![(&signer0_pubkey, true, &signer0_account)];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::InvalidAccountData)
);
}
@ -314,7 +349,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::MissingRequiredSignature)
);
@ -325,7 +365,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::MissingRequiredSignature)
);
}
@ -357,7 +402,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Ok(())
);
@ -372,7 +422,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Ok(())
);
let meta_data: ConfigKeys = deserialize(&config_account.borrow().data).unwrap();
@ -392,7 +447,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::MissingRequiredSignature)
);
@ -410,7 +470,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::MissingRequiredSignature)
);
}
@ -443,7 +508,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Ok(())
);
@ -457,7 +527,12 @@ mod tests {
];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Ok(())
);
let meta_data: ConfigKeys = deserialize(&config_account.borrow().data).unwrap();
@ -473,7 +548,12 @@ mod tests {
let accounts = vec![(&config_pubkey, true, &config_account)];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instruction.data),
process_instruction(
&id(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default()
),
Err(InstructionError::MissingRequiredSignature)
);
}
@ -487,7 +567,12 @@ mod tests {
let accounts = vec![];
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
assert_eq!(
process_instruction(&id(), &keyed_accounts, &instructions[1].data),
process_instruction(
&id(),
&keyed_accounts,
&instructions[1].data,
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys)
);
}

View File

@ -9,7 +9,7 @@ use serde_derive::Serialize;
use solana_metrics::inc_new_counter_info;
use solana_sdk::{
decode_error::DecodeError, instruction::InstructionError, keyed_account::KeyedAccount,
program_utils::limited_deserialize, pubkey::Pubkey,
process_instruction::InvokeContext, program_utils::limited_deserialize, pubkey::Pubkey,
};
use std::cmp;
use thiserror::Error;
@ -464,6 +464,7 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
solana_logger::setup();

View File

@ -1,6 +1,7 @@
use solana_sdk::instruction::InstructionError;
use solana_sdk::keyed_account::KeyedAccount;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::{
instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext,
pubkey::Pubkey,
};
solana_sdk::declare_program!(
"FaiLure111111111111111111111111111111111111",
@ -12,6 +13,7 @@ fn process_instruction(
_program_id: &Pubkey,
_keyed_accounts: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
Err(InstructionError::Custom(0))
}

View File

@ -1,7 +1,8 @@
use log::*;
use solana_sdk::instruction::InstructionError;
use solana_sdk::keyed_account::KeyedAccount;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::{
instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext,
pubkey::Pubkey,
};
solana_sdk::declare_program!(
"Noop111111111111111111111111111111111111111",
@ -13,6 +14,7 @@ fn process_instruction(
program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
solana_logger::setup();
trace!("noop: program_id: {:?}", program_id);

View File

@ -5,6 +5,7 @@ use bincode::serialize_into;
use solana_sdk::{
instruction::InstructionError,
keyed_account::{next_keyed_account, KeyedAccount},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
};
@ -30,6 +31,7 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
let new_owner_pubkey: Pubkey = limited_deserialize(data)?;
let keyed_accounts_iter = &mut keyed_accounts.iter();

View File

@ -1,24 +1,20 @@
use solana_sdk::pubkey::Pubkey;
use solana_sdk::{
instruction::{Instruction, InstructionError},
keyed_account::KeyedAccount,
process_instruction::InvokeContext,
pubkey::Pubkey,
};
pub fn process_instruction(
_program_id: &Pubkey,
_keyed_accounts: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
// Should be already checked by now.
Ok(())
}
solana_sdk::declare_program!(
solana_sdk::secp256k1_program::ID,
solana_keccak_secp256k1_program,
process_instruction
);
pub fn new_secp256k1_instruction(
priv_key: &secp256k1::SecretKey,
message_arr: &[u8],

View File

@ -10,6 +10,7 @@ use solana_sdk::{
decode_error::DecodeError,
instruction::{AccountMeta, Instruction, InstructionError},
keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
system_instruction,
@ -446,6 +447,7 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
trace!("process_instruction: {:?}", data);
trace!("keyed_accounts: {:?}", keyed_accounts);
@ -525,6 +527,7 @@ mod tests {
use bincode::serialize;
use solana_sdk::{
account::{self, Account},
process_instruction::MockInvokeContext,
rent::Rent,
sysvar::stake_history::StakeHistory,
};
@ -562,7 +565,12 @@ mod tests {
.zip(accounts.iter())
.map(|(meta, account)| KeyedAccount::new(&meta.pubkey, meta.is_signer, account))
.collect();
super::process_instruction(&Pubkey::default(), &keyed_accounts, &instruction.data)
super::process_instruction(
&Pubkey::default(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default(),
)
}
}
@ -661,6 +669,7 @@ mod tests {
Lockup::default()
))
.unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys),
);
@ -679,6 +688,7 @@ mod tests {
Lockup::default()
))
.unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys),
);
@ -696,6 +706,7 @@ mod tests {
Lockup::default()
))
.unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::InvalidArgument),
);
@ -717,6 +728,7 @@ mod tests {
Lockup::default()
))
.unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::InvalidAccountData),
);
@ -731,6 +743,7 @@ mod tests {
&create_default_account()
),],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys),
);
@ -745,6 +758,7 @@ mod tests {
&create_default_account()
)],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys),
);
@ -776,6 +790,7 @@ mod tests {
),
],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::InvalidAccountData),
);
@ -802,6 +817,7 @@ mod tests {
),
],
&serialize(&StakeInstruction::Withdraw(42)).unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::InvalidArgument),
);
@ -816,6 +832,7 @@ mod tests {
&create_default_account()
)],
&serialize(&StakeInstruction::Withdraw(42)).unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys),
);
@ -836,6 +853,7 @@ mod tests {
),
],
&serialize(&StakeInstruction::Deactivate).unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::InvalidArgument),
);
@ -846,6 +864,7 @@ mod tests {
&Pubkey::default(),
&[],
&serialize(&StakeInstruction::Deactivate).unwrap(),
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys),
);

View File

@ -10,6 +10,7 @@ use solana_sdk::{
account::Account,
instruction::InstructionError,
keyed_account::{next_keyed_account, KeyedAccount},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
};
@ -59,6 +60,7 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts_iter = &mut keyed_accounts.iter();
let contract_account = &mut next_keyed_account(keyed_accounts_iter)?.try_account_ref_mut()?;

View File

@ -14,6 +14,7 @@ use solana_sdk::{
hash::Hash,
instruction::{AccountMeta, Instruction, InstructionError},
keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
system_instruction,
@ -277,6 +278,7 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
trace!("process_instruction: {:?}", data);
trace!("keyed_accounts: {:?}", keyed_accounts);
@ -333,6 +335,7 @@ mod tests {
use super::*;
use solana_sdk::{
account::{self, Account},
process_instruction::MockInvokeContext,
rent::Rent,
};
use std::cell::RefCell;
@ -341,7 +344,12 @@ mod tests {
#[test]
fn test_vote_process_instruction_decode_bail() {
assert_eq!(
super::process_instruction(&Pubkey::default(), &[], &[],),
super::process_instruction(
&Pubkey::default(),
&[],
&[],
&mut MockInvokeContext::default()
),
Err(InstructionError::NotEnoughAccountKeys),
);
}
@ -374,7 +382,12 @@ mod tests {
.zip(accounts.iter())
.map(|(meta, account)| KeyedAccount::new(&meta.pubkey, meta.is_signer, account))
.collect();
super::process_instruction(&Pubkey::default(), &keyed_accounts, &instruction.data)
super::process_instruction(
&Pubkey::default(),
&keyed_accounts,
&instruction.data,
&mut MockInvokeContext::default(),
)
}
}