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

3
Cargo.lock generated
View File

@ -3791,7 +3791,6 @@ dependencies = [
"solana-logger 1.5.0",
"solana-net-utils",
"solana-remote-wallet",
"solana-runtime",
"solana-sdk 1.5.0",
"solana-stake-program",
"solana-transaction-status",
@ -4638,6 +4637,7 @@ dependencies = [
"hex",
"hmac",
"itertools 0.9.0",
"lazy_static",
"libsecp256k1",
"log 0.4.8",
"memmap",
@ -5001,7 +5001,6 @@ dependencies = [
"solana-frozen-abi",
"solana-frozen-abi-macro",
"solana-logger 1.5.0",
"solana-runtime",
"solana-sdk 1.5.0",
]

View File

@ -39,7 +39,6 @@ solana-logger = { path = "../logger", version = "1.5.0" }
solana-net-utils = { path = "../net-utils", version = "1.5.0" }
solana_rbpf = "=0.2.0"
solana-remote-wallet = { path = "../remote-wallet", version = "1.5.0" }
solana-runtime = { path = "../runtime", version = "1.5.0" }
solana-sdk = { path = "../sdk", version = "1.5.0" }
solana-stake-program = { path = "../programs/stake", version = "1.5.0" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.0" }

View File

@ -9,12 +9,14 @@ use solana_clap_utils::{input_parsers::*, input_validators::*, keypair::*};
use solana_cli_output::{QuietDisplay, VerboseDisplay};
use solana_client::{client_error::ClientError, rpc_client::RpcClient};
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
use solana_runtime::{
use solana_sdk::{
clock::Slot,
feature::{self, Feature},
feature_set::FEATURE_NAMES,
};
use solana_sdk::{
clock::Slot, message::Message, pubkey::Pubkey, system_instruction, transaction::Transaction,
message::Message,
pubkey::Pubkey,
system_instruction,
transaction::Transaction,
};
use std::{collections::HashMap, fmt, sync::Arc};

View File

@ -1,8 +1,8 @@
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
use solana_ledger::blockstore::Blockstore;
use solana_measure::measure::Measure;
use solana_runtime::{bank::Bank, feature_set};
use solana_sdk::timing::slot_duration_from_slots_per_year;
use solana_runtime::bank::Bank;
use solana_sdk::{feature_set, timing::slot_duration_from_slots_per_year};
use std::{
collections::HashMap,
sync::{

View File

@ -52,10 +52,10 @@ use solana_perf::packet::{
};
use solana_rayon_threadlimit::get_thread_count;
use solana_runtime::bank_forks::BankForks;
use solana_runtime::feature_set::{self, FeatureSet};
use solana_sdk::hash::Hash;
use solana_sdk::{
clock::{Slot, DEFAULT_MS_PER_SLOT, DEFAULT_SLOTS_PER_EPOCH},
feature_set::{self, FeatureSet},
hash::Hash,
pubkey::Pubkey,
signature::{Keypair, Signable, Signature, Signer},
timing::timestamp,

View File

@ -1,8 +1,5 @@
use solana_runtime::{
bank::{Builtin, Builtins, Entrypoint},
feature_set,
};
use solana_sdk::{genesis_config::ClusterType, pubkey::Pubkey};
use solana_runtime::bank::{Builtin, Builtins, Entrypoint};
use solana_sdk::{feature_set, genesis_config::ClusterType, pubkey::Pubkey};
/// Builtin programs that are always available
fn genesis_builtins(cluster_type: ClusterType) -> Vec<Builtin> {

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

View File

@ -12,6 +12,7 @@ use solana_sdk::{
instruction::InstructionError,
keyed_account::KeyedAccount,
message::Message,
process_instruction::InvokeContext,
pubkey::Pubkey,
signature::{Keypair, Signer},
transaction::Transaction,
@ -33,6 +34,7 @@ fn process_instruction(
_program_id: &Pubkey,
_keyed_accounts: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
Ok(())
}

View File

@ -17,10 +17,6 @@ use crate::{
instruction_recorder::InstructionRecorder,
log_collector::LogCollector,
message_processor::{Executors, MessageProcessor},
process_instruction::{
ErasedProcessInstruction, ErasedProcessInstructionWithContext, Executor,
ProcessInstruction, ProcessInstructionWithContext,
},
rent_collector::RentCollector,
stakes::Stakes,
status_cache::{SlotDelta, StatusCache},
@ -55,6 +51,9 @@ use solana_sdk::{
native_loader,
native_token::sol_to_lamports,
nonce, nonce_account,
process_instruction::{
ErasedProcessInstructionWithContext, Executor, ProcessInstructionWithContext,
},
program_utils::limited_deserialize,
pubkey::Pubkey,
recent_blockhashes_account,
@ -140,7 +139,7 @@ type EpochCount = u64;
#[derive(Copy, Clone)]
pub enum Entrypoint {
Program(ProcessInstruction),
Program(ProcessInstructionWithContext),
Loader(ProcessInstructionWithContext),
}
@ -157,7 +156,7 @@ impl fmt::Debug for Entrypoint {
let entrypoint = match self {
Entrypoint::Program(instruction) => EntrypointForDebug::Program(format!(
"{:p}",
*instruction as ErasedProcessInstruction
*instruction as ErasedProcessInstructionWithContext
)),
Entrypoint::Loader(instruction) => EntrypointForDebug::Loader(format!(
"{:p}",
@ -224,7 +223,7 @@ impl AbiExample for Builtin {
Self {
name: String::default(),
id: Pubkey::default(),
entrypoint: Entrypoint::Program(|_, _, _| Ok(())),
entrypoint: Entrypoint::Program(|_, _, _, _| Ok(())),
}
}
}
@ -3827,9 +3826,13 @@ impl Bank {
&mut self,
name: &str,
program_id: Pubkey,
process_instruction: ProcessInstruction,
process_instruction_with_context: ProcessInstructionWithContext,
) {
self.add_builtin(name, program_id, Entrypoint::Program(process_instruction));
self.add_builtin(
name,
program_id,
Entrypoint::Program(process_instruction_with_context),
);
}
pub fn add_builtin_loader(
@ -4125,7 +4128,6 @@ mod tests {
BOOTSTRAP_VALIDATOR_LAMPORTS,
},
native_loader::NativeLoaderError,
process_instruction::InvokeContext,
status_cache::MAX_CACHE_ENTRIES,
};
use solana_sdk::{
@ -4138,6 +4140,7 @@ mod tests {
message::{Message, MessageHeader},
nonce,
poh_config::PohConfig,
process_instruction::InvokeContext,
rent::Rent,
signature::{Keypair, Signer},
system_instruction::{self, SystemError},
@ -4428,6 +4431,7 @@ mod tests {
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> result::Result<(), InstructionError> {
if let Ok(instruction) = bincode::deserialize(data) {
match instruction {
@ -7724,6 +7728,7 @@ mod tests {
program_id: &Pubkey,
_keyed_accounts: &[KeyedAccount],
_instruction_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> std::result::Result<(), InstructionError> {
if mock_vote_program_id() != *program_id {
return Err(InstructionError::IncorrectProgramId);
@ -7781,6 +7786,7 @@ mod tests {
_pubkey: &Pubkey,
_ka: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> std::result::Result<(), InstructionError> {
Err(InstructionError::Custom(42))
}
@ -7831,6 +7837,7 @@ mod tests {
_pubkey: &Pubkey,
_ka: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> std::result::Result<(), InstructionError> {
Err(InstructionError::Custom(42))
}
@ -8499,6 +8506,7 @@ mod tests {
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> result::Result<(), InstructionError> {
let lamports = data[0] as u64;
{
@ -8551,6 +8559,7 @@ mod tests {
_program_id: &Pubkey,
_keyed_accounts: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> result::Result<(), InstructionError> {
Ok(())
}
@ -8733,6 +8742,7 @@ mod tests {
_pubkey: &Pubkey,
_ka: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> std::result::Result<(), InstructionError> {
Ok(())
}
@ -8982,6 +8992,7 @@ mod tests {
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> result::Result<(), InstructionError> {
assert_eq!(42, keyed_accounts[0].lamports().unwrap());
let mut account = keyed_accounts[0].try_account_ref_mut()?;
@ -9163,6 +9174,7 @@ mod tests {
_pubkey: &Pubkey,
_ka: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> std::result::Result<(), InstructionError> {
Ok(())
}
@ -10065,22 +10077,15 @@ mod tests {
#[test]
fn test_debug_entrypoint() {
fn mock_process_instruction(
_program_id: &Pubkey,
_keyed_accounts: &[KeyedAccount],
_data: &[u8],
) -> std::result::Result<(), InstructionError> {
Ok(())
}
fn mock_ix_processor(
fn mock_processor(
_pubkey: &Pubkey,
_ka: &[KeyedAccount],
_data: &[u8],
_context: &mut dyn InvokeContext,
_invoke_context: &mut dyn InvokeContext,
) -> std::result::Result<(), InstructionError> {
Ok(())
}
assert!(!format!("{:?}", Entrypoint::Program(mock_process_instruction)).is_empty());
assert!(!format!("{:?}", Entrypoint::Loader(mock_ix_processor)).is_empty());
assert!(!format!("{:?}", Entrypoint::Program(mock_processor)).is_empty());
assert!(!format!("{:?}", Entrypoint::Loader(mock_processor)).is_empty());
}
}

View File

@ -1,96 +0,0 @@
use crate::process_instruction::{
ComputeBudget, ComputeMeter, Executor, InvokeContext, Logger, ProcessInstruction,
};
use solana_sdk::{
account::Account, instruction::CompiledInstruction, instruction::Instruction,
instruction::InstructionError, message::Message, pubkey::Pubkey,
};
use std::{cell::RefCell, rc::Rc, sync::Arc};
#[derive(Debug, Default, Clone)]
pub struct MockComputeMeter {
pub remaining: u64,
}
impl ComputeMeter for MockComputeMeter {
fn consume(&mut self, amount: u64) -> Result<(), InstructionError> {
let exceeded = self.remaining < amount;
self.remaining = self.remaining.saturating_sub(amount);
if exceeded {
return Err(InstructionError::ComputationalBudgetExceeded);
}
Ok(())
}
fn get_remaining(&self) -> u64 {
self.remaining
}
}
#[derive(Debug, Default, Clone)]
pub struct MockLogger {
pub log: Rc<RefCell<Vec<String>>>,
}
impl Logger for MockLogger {
fn log_enabled(&self) -> bool {
true
}
fn log(&mut self, message: &str) {
self.log.borrow_mut().push(message.to_string());
}
}
#[derive(Debug)]
pub struct MockInvokeContext {
pub key: Pubkey,
pub logger: MockLogger,
pub compute_budget: ComputeBudget,
pub compute_meter: MockComputeMeter,
}
impl Default for MockInvokeContext {
fn default() -> Self {
MockInvokeContext {
key: Pubkey::default(),
logger: MockLogger::default(),
compute_budget: ComputeBudget::default(),
compute_meter: MockComputeMeter {
remaining: std::i64::MAX as u64,
},
}
}
}
impl InvokeContext for MockInvokeContext {
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
Ok(())
}
fn pop(&mut self) {}
fn verify_and_update(
&mut self,
_message: &Message,
_instruction: &CompiledInstruction,
_accounts: &[Rc<RefCell<Account>>],
) -> Result<(), InstructionError> {
Ok(())
}
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
Ok(&self.key)
}
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
&[]
}
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
Rc::new(RefCell::new(self.logger.clone()))
}
fn get_compute_budget(&self) -> &ComputeBudget {
&self.compute_budget
}
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
Rc::new(RefCell::new(self.compute_meter.clone()))
}
fn add_executor(&mut self, _pubkey: &Pubkey, _executor: Arc<dyn Executor>) {}
fn get_executor(&mut self, _pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
None
}
fn record_instruction(&self, _instruction: &Instruction) {}
fn is_feature_active(&self, _feature_id: &Pubkey) -> bool {
true
}
}

View File

@ -10,12 +10,9 @@ pub mod bank_forks;
pub mod bank_utils;
mod blockhash_queue;
pub mod bloom;
pub mod bpf_test_utils;
pub mod builtins;
pub mod commitment;
pub mod epoch_stakes;
pub mod feature;
pub mod feature_set;
pub mod genesis_utils;
pub mod hardened_unpack;
pub mod instruction_recorder;
@ -23,7 +20,6 @@ pub mod loader_utils;
pub mod log_collector;
pub mod message_processor;
mod native_loader;
pub mod process_instruction;
pub mod rent_collector;
pub mod serde_snapshot;
pub mod snapshot_package;
@ -35,6 +31,10 @@ pub mod transaction_batch;
pub mod transaction_utils;
pub mod vote_sender_types;
// TODO: Refactor all feature users to reference the solana_sdk definitions directly and remove the
// next line
use solana_sdk::{feature, feature_set};
extern crate solana_config_program;
extern crate solana_stake_program;
extern crate solana_vote_program;

View File

@ -3,10 +3,6 @@ use crate::{
instruction_recorder::InstructionRecorder,
log_collector::LogCollector,
native_loader::NativeLoader,
process_instruction::{
ComputeBudget, ComputeMeter, ErasedProcessInstruction, ErasedProcessInstructionWithContext,
Executor, InvokeContext, Logger, ProcessInstruction, ProcessInstructionWithContext,
},
rent_collector::RentCollector,
};
use log::*;
@ -18,6 +14,10 @@ use solana_sdk::{
keyed_account::{create_keyed_readonly_accounts, KeyedAccount},
message::Message,
native_loader,
process_instruction::{
ComputeBudget, ComputeMeter, ErasedProcessInstructionWithContext, Executor, InvokeContext,
Logger, ProcessInstructionWithContext,
},
pubkey::Pubkey,
rent::Rent,
system_program,
@ -205,7 +205,7 @@ pub struct ThisInvokeContext {
program_ids: Vec<Pubkey>,
rent: Rent,
pre_accounts: Vec<PreAccount>,
programs: Vec<(Pubkey, ProcessInstruction)>,
programs: Vec<(Pubkey, ProcessInstructionWithContext)>,
logger: Rc<RefCell<dyn Logger>>,
compute_budget: ComputeBudget,
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
@ -218,7 +218,7 @@ impl ThisInvokeContext {
program_id: &Pubkey,
rent: Rent,
pre_accounts: Vec<PreAccount>,
programs: Vec<(Pubkey, ProcessInstruction)>,
programs: Vec<(Pubkey, ProcessInstructionWithContext)>,
log_collector: Option<Rc<LogCollector>>,
compute_budget: ComputeBudget,
executors: Rc<RefCell<Executors>>,
@ -281,7 +281,7 @@ impl InvokeContext for ThisInvokeContext {
.last()
.ok_or(InstructionError::GenericError)
}
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] {
&self.programs
}
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
@ -326,7 +326,7 @@ impl Logger for ThisLogger {
#[derive(Deserialize, Serialize)]
pub struct MessageProcessor {
#[serde(skip)]
programs: Vec<(Pubkey, ProcessInstruction)>,
programs: Vec<(Pubkey, ProcessInstructionWithContext)>,
#[serde(skip)]
loaders: Vec<(Pubkey, ProcessInstructionWithContext)>,
#[serde(skip)]
@ -349,7 +349,7 @@ impl std::fmt::Debug for MessageProcessor {
.programs
.iter()
.map(|(pubkey, instruction)| {
let erased_instruction: ErasedProcessInstruction = *instruction;
let erased_instruction: ErasedProcessInstructionWithContext = *instruction;
format!("{}: {:p}", pubkey, erased_instruction)
})
.collect::<Vec<_>>(),
@ -398,7 +398,11 @@ impl ::solana_frozen_abi::abi_example::AbiExample for MessageProcessor {
impl MessageProcessor {
/// Add a static entrypoint to intercept instructions before the dynamic loader.
pub fn add_program(&mut self, program_id: Pubkey, process_instruction: ProcessInstruction) {
pub fn add_program(
&mut self,
program_id: Pubkey,
process_instruction: ProcessInstructionWithContext,
) {
match self.programs.iter_mut().find(|(key, _)| program_id == *key) {
Some((_, processor)) => *processor = process_instruction,
None => self.programs.push((program_id, process_instruction)),
@ -476,6 +480,7 @@ impl MessageProcessor {
&root_id,
&keyed_accounts[1..],
instruction_data,
invoke_context,
);
}
}
@ -1266,6 +1271,7 @@ mod tests {
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
if let Ok(instruction) = bincode::deserialize(data) {
match instruction {
@ -1400,6 +1406,7 @@ mod tests {
_program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
if let Ok(instruction) = bincode::deserialize(data) {
match instruction {
@ -1559,6 +1566,7 @@ mod tests {
program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
assert_eq!(*program_id, keyed_accounts[0].owner()?);
assert_ne!(
@ -1675,6 +1683,7 @@ mod tests {
_program_id: &Pubkey,
_keyed_accounts: &[KeyedAccount],
_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
Ok(())
}

View File

@ -1,5 +1,4 @@
//! Native loader
use crate::process_instruction::{InvokeContext, LoaderEntrypoint};
#[cfg(unix)]
use libloading::os::unix::*;
#[cfg(windows)]
@ -11,6 +10,7 @@ use solana_sdk::{
entrypoint_native::ProgramEntrypoint,
instruction::InstructionError,
keyed_account::{next_keyed_account, KeyedAccount},
process_instruction::{InvokeContext, LoaderEntrypoint},
pubkey::Pubkey,
};
use std::{collections::HashMap, env, path::PathBuf, str, sync::RwLock};

View File

@ -6,6 +6,7 @@ use solana_sdk::{
keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount},
nonce,
nonce_keyed_account::NonceKeyedAccount,
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
system_instruction::{SystemError, SystemInstruction, MAX_PERMITTED_DATA_LENGTH},
@ -213,6 +214,7 @@ pub fn process_instruction(
_owner: &Pubkey,
keyed_accounts: &[KeyedAccount],
instruction_data: &[u8],
_invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
let instruction = limited_deserialize(instruction_data)?;
@ -363,7 +365,9 @@ mod tests {
hash::{hash, Hash},
instruction::{AccountMeta, Instruction, InstructionError},
message::Message,
nonce, nonce_account, recent_blockhashes_account,
nonce, nonce_account,
process_instruction::MockInvokeContext,
recent_blockhashes_account,
signature::{Keypair, Signer},
system_instruction, system_program, sysvar,
sysvar::recent_blockhashes::IterItem,
@ -381,6 +385,19 @@ mod tests {
}
}
fn process_instruction(
owner: &Pubkey,
keyed_accounts: &[KeyedAccount],
instruction_data: &[u8],
) -> Result<(), InstructionError> {
super::process_instruction(
owner,
keyed_accounts,
instruction_data,
&mut MockInvokeContext::default(),
)
}
fn create_default_account() -> RefCell<Account> {
RefCell::new(Account::default())
}
@ -1194,7 +1211,7 @@ 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)
process_instruction(&Pubkey::default(), &keyed_accounts, &instruction.data)
}
}
@ -1212,7 +1229,7 @@ mod tests {
#[test]
fn test_process_nonce_ix_no_keyed_accs_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[],
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap()
@ -1224,7 +1241,7 @@ mod tests {
#[test]
fn test_process_nonce_ix_only_nonce_acc_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[KeyedAccount::new(
&Pubkey::default(),
@ -1240,7 +1257,7 @@ mod tests {
#[test]
fn test_process_nonce_ix_bad_recent_blockhash_state_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(&Pubkey::default(), true, &create_default_account()),
@ -1259,7 +1276,7 @@ mod tests {
#[test]
fn test_process_nonce_ix_ok() {
let nonce_acc = nonce_account::create_account(1_000_000);
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(&Pubkey::default(), true, &nonce_acc),
@ -1288,7 +1305,7 @@ mod tests {
),
);
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(&Pubkey::default(), true, &nonce_acc,),
@ -1320,7 +1337,7 @@ mod tests {
#[test]
fn test_process_withdraw_ix_no_keyed_accs_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[],
&serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(),
@ -1332,7 +1349,7 @@ mod tests {
#[test]
fn test_process_withdraw_ix_only_nonce_acc_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[KeyedAccount::new(
&Pubkey::default(),
@ -1348,7 +1365,7 @@ mod tests {
#[test]
fn test_process_withdraw_ix_bad_recent_blockhash_state_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(&Pubkey::default(), true, &create_default_account()),
@ -1368,7 +1385,7 @@ mod tests {
#[test]
fn test_process_withdraw_ix_bad_rent_state_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(
@ -1393,7 +1410,7 @@ mod tests {
#[test]
fn test_process_withdraw_ix_ok() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(
@ -1418,7 +1435,7 @@ mod tests {
#[test]
fn test_process_initialize_ix_no_keyed_accs_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[],
&serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(),
@ -1430,7 +1447,7 @@ mod tests {
#[test]
fn test_process_initialize_ix_only_nonce_acc_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[KeyedAccount::new(
&Pubkey::default(),
@ -1446,7 +1463,7 @@ mod tests {
#[test]
fn test_process_initialize_bad_recent_blockhash_state_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(
@ -1469,7 +1486,7 @@ mod tests {
#[test]
fn test_process_initialize_ix_bad_rent_state_fail() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(
@ -1493,7 +1510,7 @@ mod tests {
#[test]
fn test_process_initialize_ix_ok() {
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(
@ -1517,7 +1534,7 @@ mod tests {
#[test]
fn test_process_authorize_ix_ok() {
let nonce_acc = nonce_account::create_account(1_000_000);
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(&Pubkey::default(), true, &nonce_acc),
@ -1532,7 +1549,7 @@ mod tests {
)
.unwrap();
assert_eq!(
super::process_instruction(
process_instruction(
&Pubkey::default(),
&[KeyedAccount::new(&Pubkey::default(), true, &nonce_acc,),],
&serialize(&SystemInstruction::AuthorizeNonceAccount(Pubkey::default(),)).unwrap(),

View File

@ -46,6 +46,7 @@ generic-array = { version = "0.14.3", default-features = false, features = ["ser
hex = "0.4.2"
hmac = "0.7.0"
itertools = "0.9.0"
lazy_static = "1.4.0"
log = "0.4.8"
memmap = { version = "0.7.0", optional = true }
num-derive = "0.3"

View File

@ -86,15 +86,19 @@ macro_rules! declare_name {
/// # // wrapper is used so that the macro invocation occurs in the item position
/// # // rather than in the statement position which isn't allowed.
/// # mod item_wrapper {
/// use solana_sdk::keyed_account::KeyedAccount;
/// use solana_sdk::instruction::InstructionError;
/// use solana_sdk::pubkey::Pubkey;
/// use solana_sdk::declare_program;
/// use solana_sdk::{
/// declare_program,
/// instruction::InstructionError,
/// keyed_account::KeyedAccount,
/// process_instruction::InvokeContext,
/// pubkey::Pubkey,
/// };
///
/// fn my_process_instruction(
/// program_id: &Pubkey,
/// keyed_accounts: &[KeyedAccount],
/// instruction_data: &[u8],
/// invoke_context: &mut dyn InvokeContext,
/// ) -> Result<(), InstructionError> {
/// // Process an instruction
/// Ok(())
@ -117,15 +121,19 @@ macro_rules! declare_name {
/// # // wrapper is used so that the macro invocation occurs in the item position
/// # // rather than in the statement position which isn't allowed.
/// # mod item_wrapper {
/// use solana_sdk::keyed_account::KeyedAccount;
/// use solana_sdk::instruction::InstructionError;
/// use solana_sdk::pubkey::Pubkey;
/// use solana_sdk::declare_program;
/// use solana_sdk::{
/// declare_program,
/// instruction::InstructionError,
/// keyed_account::KeyedAccount,
/// process_instruction::InvokeContext,
/// pubkey::Pubkey,
/// };
///
/// fn my_process_instruction(
/// program_id: &Pubkey,
/// keyed_accounts: &[KeyedAccount],
/// instruction_data: &[u8],
/// invoke_context: &mut dyn InvokeContext,
/// ) -> Result<(), InstructionError> {
/// // Process an instruction
/// Ok(())
@ -152,8 +160,9 @@ macro_rules! declare_program(
program_id: &$crate::pubkey::Pubkey,
keyed_accounts: &[$crate::keyed_account::KeyedAccount],
instruction_data: &[u8],
invoke_context: &mut dyn $crate::process_instruction::InvokeContext,
) -> Result<(), $crate::instruction::InstructionError> {
$entrypoint(program_id, keyed_accounts, instruction_data)
$entrypoint(program_id, keyed_accounts, instruction_data, invoke_context)
}
)
);

View File

@ -16,6 +16,8 @@ pub mod entrypoint;
pub mod entrypoint_deprecated;
pub mod entrypoint_native;
pub mod epoch_info;
pub mod feature;
pub mod feature_set;
pub mod genesis_config;
pub mod hard_forks;
pub mod hash;
@ -27,6 +29,7 @@ pub mod nonce_account;
pub mod nonce_keyed_account;
pub mod packet;
pub mod poh_config;
pub mod process_instruction;
pub mod program_utils;
pub mod pubkey;
pub mod recent_blockhashes_account;

View File

@ -1,9 +1,9 @@
use crate::feature_set::{
compute_budget_balancing, max_invoke_depth_4, max_program_call_depth_64,
pubkey_log_syscall_enabled, FeatureSet,
};
use solana_sdk::{
account::Account,
feature_set::{
compute_budget_balancing, max_invoke_depth_4, max_program_call_depth_64,
pubkey_log_syscall_enabled, FeatureSet,
},
instruction::{CompiledInstruction, Instruction, InstructionError},
keyed_account::KeyedAccount,
message::Message,
@ -24,7 +24,6 @@ pub type LoaderEntrypoint = unsafe extern "C" fn(
invoke_context: &dyn InvokeContext,
) -> Result<(), InstructionError>;
pub type ProcessInstruction = fn(&Pubkey, &[KeyedAccount], &[u8]) -> Result<(), InstructionError>;
pub type ProcessInstructionWithContext =
fn(&Pubkey, &[KeyedAccount], &[u8], &mut dyn InvokeContext) -> Result<(), InstructionError>;
@ -36,12 +35,6 @@ pub type ErasedProcessInstructionWithContext = fn(
&'static mut dyn InvokeContext,
) -> Result<(), InstructionError>;
pub type ErasedProcessInstruction = fn(
&'static Pubkey,
&'static [KeyedAccount<'static>],
&'static [u8],
) -> Result<(), InstructionError>;
/// Invocation context passed to loaders
pub trait InvokeContext {
/// Push a program ID on to the invocation stack
@ -58,7 +51,7 @@ pub trait InvokeContext {
/// Get the program ID of the currently executing program
fn get_caller(&self) -> Result<&Pubkey, InstructionError>;
/// Get a list of built-in programs
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)];
fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)];
/// Get this invocation's logger
fn get_logger(&self) -> Rc<RefCell<dyn Logger>>;
/// Get this invocation's compute budget
@ -185,3 +178,91 @@ pub trait Executor: Debug + Send + Sync {
invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError>;
}
#[derive(Debug, Default, Clone)]
pub struct MockComputeMeter {
pub remaining: u64,
}
impl ComputeMeter for MockComputeMeter {
fn consume(&mut self, amount: u64) -> Result<(), InstructionError> {
let exceeded = self.remaining < amount;
self.remaining = self.remaining.saturating_sub(amount);
if exceeded {
return Err(InstructionError::ComputationalBudgetExceeded);
}
Ok(())
}
fn get_remaining(&self) -> u64 {
self.remaining
}
}
#[derive(Debug, Default, Clone)]
pub struct MockLogger {
pub log: Rc<RefCell<Vec<String>>>,
}
impl Logger for MockLogger {
fn log_enabled(&self) -> bool {
true
}
fn log(&mut self, message: &str) {
self.log.borrow_mut().push(message.to_string());
}
}
#[derive(Debug)]
pub struct MockInvokeContext {
pub key: Pubkey,
pub logger: MockLogger,
pub compute_budget: ComputeBudget,
pub compute_meter: MockComputeMeter,
}
impl Default for MockInvokeContext {
fn default() -> Self {
MockInvokeContext {
key: Pubkey::default(),
logger: MockLogger::default(),
compute_budget: ComputeBudget::default(),
compute_meter: MockComputeMeter {
remaining: std::i64::MAX as u64,
},
}
}
}
impl InvokeContext for MockInvokeContext {
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
Ok(())
}
fn pop(&mut self) {}
fn verify_and_update(
&mut self,
_message: &Message,
_instruction: &CompiledInstruction,
_accounts: &[Rc<RefCell<Account>>],
) -> Result<(), InstructionError> {
Ok(())
}
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
Ok(&self.key)
}
fn get_programs(&self) -> &[(Pubkey, ProcessInstructionWithContext)] {
&[]
}
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
Rc::new(RefCell::new(self.logger.clone()))
}
fn get_compute_budget(&self) -> &ComputeBudget {
&self.compute_budget
}
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
Rc::new(RefCell::new(self.compute_meter.clone()))
}
fn add_executor(&mut self, _pubkey: &Pubkey, _executor: Arc<dyn Executor>) {}
fn get_executor(&mut self, _pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
None
}
fn record_instruction(&self, _instruction: &Instruction) {}
fn is_feature_active(&self, _feature_id: &Pubkey) -> bool {
true
}
}

View File

@ -16,7 +16,6 @@ solana-frozen-abi = { path = "../frozen-abi", version = "1.5.0" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "1.5.0" }
solana-logger = { path = "../logger", version = "1.5.0" }
solana-sdk = { path = "../sdk", version = "1.5.0" }
solana-runtime = { path = "../runtime", version = "1.5.0" }
[lib]
name = "solana_version"

View File

@ -51,7 +51,7 @@ fn compute_commit(sha1: Option<&'static str>) -> Option<u32> {
impl Default for Version {
fn default() -> Self {
let feature_set = u32::from_le_bytes(
solana_runtime::feature_set::ID.as_ref()[..4]
solana_sdk::feature_set::ID.as_ref()[..4]
.try_into()
.unwrap(),
);