Cleanup - mock_process_instruction() (#31088)

* Uses declare_process_instruction!() in all tests.

* Adds post_adjustments to mock_process_instruction().
Removes "solana_sbf_rust_external_spend" from assert_instruction_count() as it panics.
This commit is contained in:
Alexander Meißner 2023-04-07 12:53:19 +02:00 committed by GitHub
parent bcd43d7a79
commit 0cd57addcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 252 additions and 423 deletions

View File

@ -41,13 +41,18 @@ use {
/// Adapter so we can unify the interfaces of built-in programs and syscalls
#[macro_export]
macro_rules! declare_process_instruction {
($cu_to_consume:expr) => {
pub fn process_instruction(
invoke_context: &mut InvokeContext,
) -> Result<(), Box<dyn std::error::Error>> {
($process_instruction:ident, $cu_to_consume:expr, |$invoke_context:ident| $inner:tt) => {
pub fn $process_instruction(
invoke_context: &mut $crate::invoke_context::InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
fn process_instruction_inner(
$invoke_context: &mut $crate::invoke_context::InvokeContext,
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
$inner
}
if invoke_context
.feature_set
.is_active(&feature_set::native_programs_consume_cu::id())
.is_active(&solana_sdk::feature_set::native_programs_consume_cu::id())
{
invoke_context.consume_checked($cu_to_consume)?;
}
@ -919,7 +924,7 @@ macro_rules! with_mock_invoke_context {
};
}
pub fn mock_process_instruction<F: FnMut(&mut InvokeContext)>(
pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut InvokeContext)>(
loader_id: &Pubkey,
mut program_indices: Vec<IndexOfAccount>,
instruction_data: &[u8],
@ -928,6 +933,7 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext)>(
expected_result: Result<(), InstructionError>,
process_instruction: ProcessInstructionWithContext,
mut pre_adjustments: F,
mut post_adjustments: G,
) -> Vec<AccountSharedData> {
let mut instruction_accounts: Vec<InstructionAccount> =
Vec::with_capacity(instruction_account_metas.len());
@ -971,6 +977,7 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext)>(
&mut ExecuteTimings::default(),
);
assert_eq!(result, expected_result);
post_adjustments(&mut invoke_context);
let mut transaction_accounts = transaction_context.deconstruct_without_keys().unwrap();
transaction_accounts.pop();
transaction_accounts
@ -1030,105 +1037,105 @@ mod tests {
const MOCK_BUILTIN_COMPUTE_UNIT_COST: u64 = 1;
#[allow(clippy::integer_arithmetic)]
fn mock_process_instruction(
invoke_context: &mut InvokeContext,
) -> Result<(), Box<dyn std::error::Error>> {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
let program_id = instruction_context.get_last_program_key(transaction_context)?;
// mock builtin must consume units
invoke_context.consume_checked(MOCK_BUILTIN_COMPUTE_UNIT_COST)?;
let instruction_accounts = (0..4)
.map(|instruction_account_index| InstructionAccount {
index_in_transaction: instruction_account_index,
index_in_caller: instruction_account_index,
index_in_callee: instruction_account_index,
is_signer: false,
is_writable: false,
})
.collect::<Vec<_>>();
assert_eq!(
program_id,
instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.get_owner()
);
assert_ne!(
instruction_context
.try_borrow_instruction_account(transaction_context, 1)?
.get_owner(),
instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.get_key()
);
if let Ok(instruction) = bincode::deserialize(instruction_data) {
match instruction {
MockInstruction::NoopSuccess => (),
MockInstruction::NoopFail => return Err(Box::new(InstructionError::GenericError)),
MockInstruction::ModifyOwned => instruction_context
declare_process_instruction!(
process_instruction,
MOCK_BUILTIN_COMPUTE_UNIT_COST,
|invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
let program_id = instruction_context.get_last_program_key(transaction_context)?;
let instruction_accounts = (0..4)
.map(|instruction_account_index| InstructionAccount {
index_in_transaction: instruction_account_index,
index_in_caller: instruction_account_index,
index_in_callee: instruction_account_index,
is_signer: false,
is_writable: false,
})
.collect::<Vec<_>>();
assert_eq!(
program_id,
instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.set_data_from_slice(&[1])?,
MockInstruction::ModifyNotOwned => instruction_context
.get_owner()
);
assert_ne!(
instruction_context
.try_borrow_instruction_account(transaction_context, 1)?
.set_data_from_slice(&[1])?,
MockInstruction::ModifyReadonly => instruction_context
.try_borrow_instruction_account(transaction_context, 2)?
.set_data_from_slice(&[1])?,
MockInstruction::UnbalancedPush => {
instruction_context
.get_owner(),
instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.get_key()
);
if let Ok(instruction) = bincode::deserialize(instruction_data) {
match instruction {
MockInstruction::NoopSuccess => (),
MockInstruction::NoopFail => return Err(InstructionError::GenericError),
MockInstruction::ModifyOwned => instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.checked_add_lamports(1)?;
let program_id = *transaction_context.get_key_of_account_at_index(3)?;
let metas = vec![
AccountMeta::new_readonly(
*transaction_context.get_key_of_account_at_index(0)?,
false,
),
AccountMeta::new_readonly(
*transaction_context.get_key_of_account_at_index(1)?,
false,
),
];
let inner_instruction = Instruction::new_with_bincode(
program_id,
&MockInstruction::NoopSuccess,
metas,
);
invoke_context
.transaction_context
.get_next_instruction_context()
.unwrap()
.configure(&[3], &instruction_accounts, &[]);
let result = invoke_context.push();
assert_eq!(result, Err(InstructionError::UnbalancedInstruction));
result?;
invoke_context
.native_invoke(inner_instruction.into(), &[])
.and(invoke_context.pop())?;
.set_data_from_slice(&[1])?,
MockInstruction::ModifyNotOwned => instruction_context
.try_borrow_instruction_account(transaction_context, 1)?
.set_data_from_slice(&[1])?,
MockInstruction::ModifyReadonly => instruction_context
.try_borrow_instruction_account(transaction_context, 2)?
.set_data_from_slice(&[1])?,
MockInstruction::UnbalancedPush => {
instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.checked_add_lamports(1)?;
let program_id = *transaction_context.get_key_of_account_at_index(3)?;
let metas = vec![
AccountMeta::new_readonly(
*transaction_context.get_key_of_account_at_index(0)?,
false,
),
AccountMeta::new_readonly(
*transaction_context.get_key_of_account_at_index(1)?,
false,
),
];
let inner_instruction = Instruction::new_with_bincode(
program_id,
&MockInstruction::NoopSuccess,
metas,
);
invoke_context
.transaction_context
.get_next_instruction_context()
.unwrap()
.configure(&[3], &instruction_accounts, &[]);
let result = invoke_context.push();
assert_eq!(result, Err(InstructionError::UnbalancedInstruction));
result?;
invoke_context
.native_invoke(inner_instruction.into(), &[])
.and(invoke_context.pop())?;
}
MockInstruction::UnbalancedPop => instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.checked_add_lamports(1)?,
MockInstruction::ConsumeComputeUnits {
compute_units_to_consume,
desired_result,
} => {
invoke_context
.consume_checked(compute_units_to_consume)
.map_err(|_| InstructionError::ComputationalBudgetExceeded)?;
return desired_result;
}
MockInstruction::Resize { new_len } => instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.set_data(vec![0; new_len as usize])?,
}
MockInstruction::UnbalancedPop => instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.checked_add_lamports(1)?,
MockInstruction::ConsumeComputeUnits {
compute_units_to_consume,
desired_result,
} => {
invoke_context.consume_checked(compute_units_to_consume)?;
return desired_result
.map_err(|err| Box::new(err) as Box<dyn std::error::Error>);
}
MockInstruction::Resize { new_len } => instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.set_data(vec![0; new_len as usize])?,
} else {
return Err(InstructionError::InvalidInstructionData);
}
} else {
return Err(Box::new(InstructionError::InvalidInstructionData));
Ok(())
}
Ok(())
}
);
#[test]
fn test_instruction_stack_height() {
@ -1236,7 +1243,7 @@ mod tests {
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
let builtin_programs = &[BuiltinProgram {
program_id: callee_program_id,
process_instruction: mock_process_instruction,
process_instruction,
}];
invoke_context.builtin_programs = builtin_programs;
@ -1381,7 +1388,7 @@ mod tests {
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
let builtin_programs = &[BuiltinProgram {
program_id: program_key,
process_instruction: mock_process_instruction,
process_instruction,
}];
invoke_context.builtin_programs = builtin_programs;

View File

@ -18,10 +18,7 @@ use {
std::convert::TryFrom,
};
declare_process_instruction!(750);
pub fn process_instruction_inner(
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
declare_process_instruction!(process_instruction, 750, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
@ -39,7 +36,7 @@ pub fn process_instruction_inner(
}
ProgramInstruction::CloseLookupTable => Processor::close_lookup_table(invoke_context),
}
}
});
fn checked_add(a: usize, b: usize) -> Result<usize, InstructionError> {
a.checked_add(b).ok_or(InstructionError::ArithmeticOverflow)

View File

@ -1696,6 +1696,7 @@ mod tests {
expected_result,
super::process_instruction,
|_invoke_context| {},
|_invoke_context| {},
)
}
@ -1982,6 +1983,7 @@ mod tests {
|invoke_context| {
invoke_context.mock_set_remaining(0);
},
|_invoke_context| {},
);
// Case: Account not a program
@ -2524,6 +2526,7 @@ mod tests {
expected_result,
super::process_instruction,
|_invoke_context| {},
|_invoke_context| {},
)
}

View File

@ -1,16 +1,6 @@
use {solana_program_runtime::invoke_context::InvokeContext, solana_sdk::feature_set};
pub fn process_instruction(
invoke_context: &mut InvokeContext,
) -> Result<(), Box<dyn std::error::Error>> {
// Consume compute units if feature `native_programs_consume_cu` is activated,
if invoke_context
.feature_set
.is_active(&feature_set::native_programs_consume_cu::id())
{
invoke_context.consume_checked(150)?;
}
use solana_program_runtime::declare_process_instruction;
declare_process_instruction!(process_instruction, 150, |_invoke_context| {
// Do nothing, compute budget instructions handled by the runtime
Ok(())
}
});

View File

@ -3,7 +3,7 @@
use {
crate::ConfigKeys,
bincode::deserialize,
solana_program_runtime::{declare_process_instruction, ic_msg, invoke_context::InvokeContext},
solana_program_runtime::{declare_process_instruction, ic_msg},
solana_sdk::{
feature_set, instruction::InstructionError, program_utils::limited_deserialize,
pubkey::Pubkey, transaction_context::IndexOfAccount,
@ -11,10 +11,7 @@ use {
std::collections::BTreeSet,
};
declare_process_instruction!(450);
pub fn process_instruction_inner(
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
declare_process_instruction!(process_instruction, 450, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let data = instruction_context.get_instruction_data();
@ -134,7 +131,7 @@ pub fn process_instruction_inner(
}
config_account.get_data_mut()?[..data.len()].copy_from_slice(data);
Ok(())
}
});
#[cfg(test)]
mod tests {
@ -168,6 +165,7 @@ mod tests {
expected_result,
super::process_instruction,
|_invoke_context| {},
|_invoke_context| {},
)
}

View File

@ -655,6 +655,7 @@ mod tests {
expected_result,
super::process_instruction,
|_invoke_context| {},
|_invoke_context| {},
)
}

View File

@ -19,9 +19,7 @@ use {
parse_bpf_upgradeable_loader, BpfUpgradeableLoaderAccountType,
},
solana_ledger::token_balances::collect_token_balances,
solana_program_runtime::{
compute_budget::ComputeBudget, invoke_context::InvokeContext, timings::ExecuteTimings,
},
solana_program_runtime::{compute_budget::ComputeBudget, timings::ExecuteTimings},
solana_rbpf::vm::ContextObject,
solana_runtime::{
bank::{
@ -86,7 +84,7 @@ use {
system_program,
transaction::{SanitizedTransaction, Transaction, TransactionError},
},
std::{str::FromStr, sync::Arc, time::Duration},
std::{cell::RefCell, str::FromStr, sync::Arc, time::Duration},
};
#[cfg(feature = "sbf_rust")]
@ -1370,8 +1368,8 @@ fn assert_instruction_count() {
("noop++", 5),
("relative_call", 210),
("return_data", 980),
("sanity", 3259),
("sanity++", 3159),
("sanity", 2377),
("sanity++", 2277),
("secp256k1_recover", 25383),
("sha", 1355),
("struct_pass", 108),
@ -1385,7 +1383,6 @@ fn assert_instruction_count() {
("solana_sbf_rust_alloc", 5067),
("solana_sbf_rust_custom_heap", 398),
("solana_sbf_rust_dep_crate", 2),
("solana_sbf_rust_external_spend", 288),
("solana_sbf_rust_iter", 1013),
("solana_sbf_rust_many_args", 1289),
("solana_sbf_rust_mem", 2067),
@ -1393,7 +1390,7 @@ fn assert_instruction_count() {
("solana_sbf_rust_noop", 275),
("solana_sbf_rust_param_passing", 146),
("solana_sbf_rust_rand", 378),
("solana_sbf_rust_sanity", 10759),
("solana_sbf_rust_sanity", 51931),
("solana_sbf_rust_secp256k1_recover", 91185),
("solana_sbf_rust_sha", 24059),
]);
@ -1407,7 +1404,7 @@ fn assert_instruction_count() {
(program_key, AccountSharedData::new(0, 0, &loader_id)),
(
Pubkey::new_unique(),
AccountSharedData::new(0, 8, &program_key),
AccountSharedData::new(0, 0, &program_key),
),
];
let instruction_accounts = vec![AccountMeta {
@ -1419,11 +1416,8 @@ fn assert_instruction_count() {
.1
.set_data_from_slice(&load_program_from_file(program_name));
transaction_accounts[0].1.set_executable(true);
transaction_accounts[1]
.1
.set_state(expected_consumption)
.unwrap();
let prev_compute_meter = RefCell::new(0);
print!(" {:36} {:8}", program_name, *expected_consumption);
mock_process_instruction(
&loader_id,
@ -1432,29 +1426,23 @@ fn assert_instruction_count() {
transaction_accounts,
instruction_accounts,
Ok(()),
|invoke_context: &mut InvokeContext| {
let expected_consumption: u64 = invoke_context
.transaction_context
.get_current_instruction_context()
.unwrap()
.try_borrow_instruction_account(&invoke_context.transaction_context, 0)
.unwrap()
.get_state()
.unwrap();
let prev_compute_meter = invoke_context.get_remaining();
let _result = solana_bpf_loader_program::process_instruction(invoke_context);
let consumption = prev_compute_meter.saturating_sub(invoke_context.get_remaining());
let diff: i64 = consumption as i64 - expected_consumption as i64;
solana_bpf_loader_program::process_instruction,
|invoke_context| {
*prev_compute_meter.borrow_mut() = invoke_context.get_remaining();
},
|invoke_context| {
let consumption = prev_compute_meter
.borrow()
.saturating_sub(invoke_context.get_remaining());
let diff: i64 = consumption as i64 - *expected_consumption as i64;
println!(
"{:6} {:+5} ({:+3.0}%)",
consumption,
diff,
100.0_f64 * consumption as f64 / expected_consumption as f64 - 100.0_f64,
100.0_f64 * consumption as f64 / *expected_consumption as f64 - 100.0_f64,
);
assert_eq!(consumption, expected_consumption);
Ok(())
assert_eq!(consumption, *expected_consumption);
},
|_invoke_context| {},
);
}
}

View File

@ -8,8 +8,7 @@ use {
},
log::*,
solana_program_runtime::{
declare_process_instruction, invoke_context::InvokeContext,
sysvar_cache::get_sysvar_with_account_check,
declare_process_instruction, sysvar_cache::get_sysvar_with_account_check,
},
solana_sdk::{
clock::Clock,
@ -52,10 +51,7 @@ fn get_optional_pubkey<'a>(
)
}
declare_process_instruction!(750);
pub fn process_instruction_inner(
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
declare_process_instruction!(process_instruction, 750, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let data = instruction_context.get_instruction_data();
@ -479,7 +475,7 @@ pub fn process_instruction_inner(
Err(err)
}
}
}
});
#[cfg(test)]
mod tests {
@ -595,6 +591,7 @@ mod tests {
|invoke_context| {
invoke_context.feature_set = Arc::clone(&feature_set);
},
|_invoke_context| {},
)
}
@ -6344,17 +6341,16 @@ mod tests {
transaction_accounts,
instruction_accounts,
Ok(()),
super::process_instruction,
|invoke_context| {
invoke_context.feature_set = Arc::clone(&feature_set);
},
|invoke_context| {
super::process_instruction(invoke_context)?;
let expected_minimum_delegation =
crate::get_minimum_delegation(&invoke_context.feature_set).to_le_bytes();
let actual_minimum_delegation =
invoke_context.transaction_context.get_return_data().1;
assert_eq!(expected_minimum_delegation, actual_minimum_delegation);
Ok(())
},
|invoke_context| {
invoke_context.feature_set = Arc::clone(&feature_set);
},
);
}

View File

@ -56,12 +56,9 @@ fn process_authorize_with_seed_instruction(
)
}
// Citing `runtime/src/block_cost_limit.rs`, vote has statically defined 2_100
// Citing `runtime/src/block_cost_limit.rs`, vote has statically defined 2100
// units; can consume based on instructions in the future like `bpf_loader` does.
declare_process_instruction!(2_100);
pub fn process_instruction_inner(
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
declare_process_instruction!(process_instruction, 2100, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let data = instruction_context.get_instruction_data();
@ -260,7 +257,7 @@ pub fn process_instruction_inner(
}
}
}
}
});
#[cfg(test)]
mod tests {
@ -325,6 +322,7 @@ mod tests {
expected_result,
super::process_instruction,
|_invoke_context| {},
|_invoke_context| {},
)
}
@ -345,6 +343,7 @@ mod tests {
|invoke_context| {
invoke_context.feature_set = std::sync::Arc::new(FeatureSet::default());
},
|_invoke_context| {},
)
}

View File

@ -114,10 +114,7 @@ fn process_close_proof_context(invoke_context: &mut InvokeContext) -> Result<(),
Ok(())
}
declare_process_instruction!(0);
pub fn process_instruction_inner(
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
declare_process_instruction!(process_instruction, 0, |invoke_context| {
if invoke_context.get_stack_height() != TRANSACTION_LEVEL_STACK_HEIGHT {
// Not supported as an inner instruction
return Err(InstructionError::UnsupportedProgramId);
@ -195,4 +192,4 @@ pub fn process_instruction_inner(
process_verify_proof::<PubkeyValidityData, PubkeyValidityProofContext>(invoke_context)
}
}
}
});

View File

@ -34,8 +34,9 @@ use {
solana_logger,
solana_program_runtime::{
compute_budget::{self, ComputeBudget, MAX_COMPUTE_UNIT_LIMIT},
declare_process_instruction,
executor_cache::TransactionExecutorCache,
invoke_context::{mock_process_instruction, InvokeContext},
invoke_context::mock_process_instruction,
loaded_programs::{LoadedProgram, LoadedProgramType},
prioritization_fee::{PrioritizationFeeDetails, PrioritizationFeeType},
timings::ExecuteTimings,
@ -107,7 +108,6 @@ use {
fs::File,
io::Read,
rc::Rc,
result,
str::FromStr,
sync::{
atomic::{
@ -752,6 +752,11 @@ fn assert_capitalization_diff(
}
}
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
// Default for all tests which don't bring their own processor
Ok(())
});
#[test]
fn test_store_account_and_update_capitalization_missing() {
let bank = create_simple_test_bank(0);
@ -1340,9 +1345,7 @@ fn test_rent_complex() {
Deduction,
}
fn mock_process_instruction(
invoke_context: &mut InvokeContext,
) -> result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
@ -1359,9 +1362,9 @@ fn test_rent_complex() {
}
}
} else {
Err(Box::new(InstructionError::InvalidInstructionData))
Err(InstructionError::InvalidInstructionData)
}
}
});
let (mut genesis_config, _mint_keypair) = create_genesis_config(10);
let mut keypairs: Vec<Keypair> = Vec::with_capacity(14);
@ -1377,7 +1380,7 @@ fn test_rent_complex() {
root_bank.restore_old_behavior_for_fragile_tests();
let root_bank = Arc::new(root_bank);
let mut bank = create_child_bank_for_rent_test(&root_bank, &genesis_config);
bank.add_builtin("mock_program", &mock_program_id, mock_process_instruction);
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
assert_eq!(bank.last_blockhash(), genesis_config.hash());
@ -5070,23 +5073,21 @@ fn test_add_builtin() {
fn mock_vote_program_id() -> Pubkey {
Pubkey::from([42u8; 32])
}
fn mock_vote_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let program_id = instruction_context.get_last_program_key(transaction_context)?;
if mock_vote_program_id() != *program_id {
return Err(Box::new(InstructionError::IncorrectProgramId));
return Err(InstructionError::IncorrectProgramId);
}
Err(Box::new(InstructionError::Custom(42)))
}
Err(InstructionError::Custom(42))
});
assert!(bank.get_account(&mock_vote_program_id()).is_none());
bank.add_builtin(
"mock_vote_program",
&mock_vote_program_id(),
mock_vote_processor,
process_instruction,
);
assert!(bank.get_account(&mock_vote_program_id()).is_some());
@ -5128,13 +5129,9 @@ fn test_add_duplicate_static_program() {
} = create_genesis_config_with_leader(500, &solana_sdk::pubkey::new_rand(), 0);
let mut bank = Bank::new_for_tests(&genesis_config);
fn mock_vote_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
// mock builtin must consume units
invoke_context.consume_checked(1)?;
Err(Box::new(InstructionError::Custom(42)))
}
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
Err(InstructionError::Custom(42))
});
let mock_account = Keypair::new();
let mock_validator_identity = Keypair::new();
@ -5159,7 +5156,7 @@ fn test_add_duplicate_static_program() {
bank.add_builtin(
"solana_vote_program",
&solana_vote_program::id(),
mock_vote_processor,
process_instruction,
);
let new_vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap();
// Vote loader account should not be updated since it was included in the genesis config.
@ -5178,13 +5175,9 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
for pass in 0..5 {
let mut bank = create_simple_test_bank(500);
fn mock_ix_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
// mock builtin must consume units
invoke_context.consume_checked(1)?;
Err(Box::new(InstructionError::Custom(42)))
}
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
Err(InstructionError::Custom(42))
});
// Non-builtin loader accounts can not be used for instruction processing
{
@ -5215,8 +5208,8 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
continue;
}
bank.add_builtin("mock_program1", &vote_id, mock_ix_processor);
bank.add_builtin("mock_program2", &stake_id, mock_ix_processor);
bank.add_builtin("mock_program1", &vote_id, process_instruction);
bank.add_builtin("mock_program2", &stake_id, process_instruction);
{
let stakes = bank.stakes_cache.stakes();
assert!(stakes.vote_accounts().as_ref().is_empty());
@ -5239,8 +5232,8 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
// Re-adding builtin programs should be no-op
bank.update_accounts_hash_for_tests();
let old_hash = bank.get_accounts_hash().unwrap();
bank.add_builtin("mock_program1", &vote_id, mock_ix_processor);
bank.add_builtin("mock_program2", &stake_id, mock_ix_processor);
bank.add_builtin("mock_program1", &vote_id, process_instruction);
bank.add_builtin("mock_program2", &stake_id, process_instruction);
add_root_and_flush_write_cache(&bank);
bank.update_accounts_hash_for_tests();
let new_hash = bank.get_accounts_hash().unwrap();
@ -6470,15 +6463,11 @@ fn test_transaction_with_duplicate_accounts_in_instruction() {
let (genesis_config, mint_keypair) = create_genesis_config(500);
let mut bank = Bank::new_for_tests(&genesis_config);
fn mock_process_instruction(
invoke_context: &mut InvokeContext,
) -> result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
let lamports = u64::from_le_bytes(instruction_data.try_into().unwrap());
// mock builtin must consume units
invoke_context.consume_checked(1)?;
instruction_context
.try_borrow_instruction_account(transaction_context, 2)?
.checked_sub_lamports(lamports)?;
@ -6492,10 +6481,10 @@ fn test_transaction_with_duplicate_accounts_in_instruction() {
.try_borrow_instruction_account(transaction_context, 1)?
.checked_add_lamports(lamports)?;
Ok(())
}
});
let mock_program_id = Pubkey::from([2u8; 32]);
bank.add_builtin("mock_program", &mock_program_id, mock_process_instruction);
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
let from_pubkey = solana_sdk::pubkey::new_rand();
let to_pubkey = solana_sdk::pubkey::new_rand();
@ -6530,17 +6519,8 @@ fn test_transaction_with_program_ids_passed_to_programs() {
let (genesis_config, mint_keypair) = create_genesis_config(500);
let mut bank = Bank::new_for_tests(&genesis_config);
#[allow(clippy::unnecessary_wraps)]
fn mock_process_instruction(
invoke_context: &mut InvokeContext,
) -> result::Result<(), Box<dyn std::error::Error>> {
// mock builtin must consume units
invoke_context.consume_checked(1)?;
Ok(())
}
let mock_program_id = Pubkey::from([2u8; 32]);
bank.add_builtin("mock_program", &mock_program_id, mock_process_instruction);
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
let from_pubkey = solana_sdk::pubkey::new_rand();
let to_pubkey = solana_sdk::pubkey::new_rand();
@ -6592,11 +6572,7 @@ fn test_account_ids_after_program_ids() {
tx.message.account_keys.push(solana_sdk::pubkey::new_rand());
bank.add_builtin(
"mock_vote",
&solana_vote_program::id(),
mock_ok_vote_processor,
);
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
let result = bank.process_transaction(&tx);
assert_eq!(result, Ok(()));
let account = bank.get_account(&solana_vote_program::id()).unwrap();
@ -6646,11 +6622,7 @@ fn test_duplicate_account_key() {
AccountMeta::new(to_pubkey, false),
];
bank.add_builtin(
"mock_vote",
&solana_vote_program::id(),
mock_ok_vote_processor,
);
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
let mut tx = Transaction::new_signed_with_payer(
@ -6679,11 +6651,7 @@ fn test_process_transaction_with_too_many_account_locks() {
AccountMeta::new(to_pubkey, false),
];
bank.add_builtin(
"mock_vote",
&solana_vote_program::id(),
mock_ok_vote_processor,
);
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
let mut tx = Transaction::new_signed_with_payer(
@ -6716,11 +6684,7 @@ fn test_program_id_as_payer() {
AccountMeta::new(to_pubkey, false),
];
bank.add_builtin(
"mock_vote",
&solana_vote_program::id(),
mock_ok_vote_processor,
);
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
let mut tx = Transaction::new_signed_with_payer(
@ -6750,15 +6714,6 @@ fn test_program_id_as_payer() {
assert_eq!(result, Err(TransactionError::SanitizeFailure));
}
#[allow(clippy::unnecessary_wraps)]
fn mock_ok_vote_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
// mock builtin must consume units
invoke_context.consume_checked(1)?;
Ok(())
}
#[test]
fn test_ref_account_key_after_program_id() {
let (genesis_config, mint_keypair) = create_genesis_config(500);
@ -6772,11 +6727,7 @@ fn test_ref_account_key_after_program_id() {
AccountMeta::new(to_pubkey, false),
];
bank.add_builtin(
"mock_vote",
&solana_vote_program::id(),
mock_ok_vote_processor,
);
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
let mut tx = Transaction::new_signed_with_payer(
@ -6807,7 +6758,7 @@ fn test_fuzz_instructions() {
.map(|i| {
let key = solana_sdk::pubkey::new_rand();
let name = format!("program{i:?}");
bank.add_builtin(&name, &key, mock_ok_vote_processor);
bank.add_builtin(&name, &key, process_instruction);
(key, name.as_bytes().to_vec())
})
.collect();
@ -6999,23 +6950,21 @@ fn test_bank_hash_consistency() {
#[test]
fn test_same_program_id_uses_unqiue_executable_accounts() {
fn nested_processor(
invoke_context: &mut InvokeContext,
) -> result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let _ = instruction_context
.try_borrow_program_account(transaction_context, 1)?
.checked_add_lamports(1);
Ok(())
}
});
let (genesis_config, mint_keypair) = create_genesis_config(50000);
let mut bank = Bank::new_for_tests(&genesis_config);
// Add a new program
let program1_pubkey = solana_sdk::pubkey::new_rand();
bank.add_builtin("program", &program1_pubkey, nested_processor);
bank.add_builtin("program", &program1_pubkey, process_instruction);
// Add a new program owned by the first
let program2_pubkey = solana_sdk::pubkey::new_rand();
@ -7220,13 +7169,6 @@ fn test_shrink_candidate_slots_cached() {
#[test]
fn test_add_builtin_no_overwrite() {
#[allow(clippy::unnecessary_wraps)]
fn mock_ix_processor(
_invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
Ok(())
}
let slot = 123;
let program_id = solana_sdk::pubkey::new_rand();
@ -7239,25 +7181,18 @@ fn test_add_builtin_no_overwrite() {
Arc::get_mut(&mut bank)
.unwrap()
.add_builtin("mock_program", &program_id, mock_ix_processor);
.add_builtin("mock_program", &program_id, process_instruction);
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
let mut bank = Arc::new(new_from_parent(&bank));
Arc::get_mut(&mut bank)
.unwrap()
.add_builtin("mock_program", &program_id, mock_ix_processor);
.add_builtin("mock_program", &program_id, process_instruction);
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
}
#[test]
fn test_add_builtin_loader_no_overwrite() {
#[allow(clippy::unnecessary_wraps)]
fn mock_ix_processor(
_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
Ok(())
}
let slot = 123;
let loader_id = solana_sdk::pubkey::new_rand();
@ -7270,13 +7205,13 @@ fn test_add_builtin_loader_no_overwrite() {
Arc::get_mut(&mut bank)
.unwrap()
.add_builtin("mock_program", &loader_id, mock_ix_processor);
.add_builtin("mock_program", &loader_id, process_instruction);
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
let mut bank = Arc::new(new_from_parent(&bank));
Arc::get_mut(&mut bank)
.unwrap()
.add_builtin("mock_program", &loader_id, mock_ix_processor);
.add_builtin("mock_program", &loader_id, process_instruction);
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
}
@ -8053,6 +7988,7 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() {
Ok(()),
solana_bpf_loader_program::process_instruction,
|_invoke_context| {},
|_invoke_context| {},
);
// Test initialized program account
@ -9999,10 +9935,7 @@ fn test_tx_return_data() {
);
let mut bank = Bank::new_for_tests(&genesis_config);
let mock_program_id = Pubkey::from([2u8; 32]);
fn mock_process_instruction(
invoke_context: &mut InvokeContext,
) -> result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let mock_program_id = Pubkey::from([2u8; 32]);
let transaction_context = &mut invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
@ -10016,9 +9949,11 @@ fn test_tx_return_data() {
.unwrap();
}
Ok(())
}
});
let mock_program_id = Pubkey::from([2u8; 32]);
let blockhash = bank.last_blockhash();
bank.add_builtin("mock_program", &mock_program_id, mock_process_instruction);
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
for index in [
None,
@ -10197,21 +10132,17 @@ fn test_transfer_sysvar() {
);
let mut bank = Bank::new_for_tests(&genesis_config);
fn mock_ix_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
// mock builtin should consume units
let _ = invoke_context.consume_checked(1);
instruction_context
.try_borrow_instruction_account(transaction_context, 1)?
.set_data(vec![0; 40])?;
Ok(())
}
});
let program_id = solana_sdk::pubkey::new_rand();
bank.add_builtin("mock_program1", &program_id, mock_ix_processor);
bank.add_builtin("mock_program1", &program_id, process_instruction);
let blockhash = bank.last_blockhash();
#[allow(deprecated)]
@ -10410,9 +10341,7 @@ fn test_compute_budget_program_noop() {
);
let mut bank = Bank::new_for_tests(&genesis_config);
fn mock_ix_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let compute_budget = invoke_context.get_compute_budget();
assert_eq!(
*compute_budget,
@ -10422,12 +10351,10 @@ fn test_compute_budget_program_noop() {
..ComputeBudget::default()
}
);
// mock builtin should consume units
let _ = invoke_context.consume_checked(1);
Ok(())
}
});
let program_id = solana_sdk::pubkey::new_rand();
bank.add_builtin("mock_program", &program_id, mock_ix_processor);
bank.add_builtin("mock_program", &program_id, process_instruction);
let message = Message::new(
&[
@ -10457,9 +10384,7 @@ fn test_compute_request_instruction() {
);
let mut bank = Bank::new_for_tests(&genesis_config);
fn mock_ix_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let compute_budget = invoke_context.get_compute_budget();
assert_eq!(
*compute_budget,
@ -10469,12 +10394,10 @@ fn test_compute_request_instruction() {
..ComputeBudget::default()
}
);
// mock builtin should consume units
let _ = invoke_context.consume_checked(1);
Ok(())
}
});
let program_id = solana_sdk::pubkey::new_rand();
bank.add_builtin("mock_program", &program_id, mock_ix_processor);
bank.add_builtin("mock_program", &program_id, process_instruction);
let message = Message::new(
&[
@ -10511,9 +10434,7 @@ fn test_failed_compute_request_instruction() {
bank.transfer(10, &mint_keypair, &payer1_keypair.pubkey())
.unwrap();
fn mock_ix_processor(
invoke_context: &mut InvokeContext,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let compute_budget = invoke_context.get_compute_budget();
assert_eq!(
*compute_budget,
@ -10524,9 +10445,9 @@ fn test_failed_compute_request_instruction() {
}
);
Ok(())
}
});
let program_id = solana_sdk::pubkey::new_rand();
bank.add_builtin("mock_program", &program_id, mock_ix_processor);
bank.add_builtin("mock_program", &program_id, process_instruction);
// This message will not be executed because the compute budget request is invalid
let message0 = Message::new(
@ -11076,14 +10997,10 @@ enum MockTransferInstruction {
Transfer(u64),
}
fn mock_transfer_process_instruction(
invoke_context: &mut InvokeContext,
) -> result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(mock_transfer_process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
// mock builtin must consume units
invoke_context.consume_checked(1)?;
if let Ok(instruction) = bincode::deserialize(instruction_data) {
match instruction {
MockTransferInstruction::Transfer(amount) => {
@ -11097,9 +11014,9 @@ fn mock_transfer_process_instruction(
}
}
} else {
Err(Box::new(InstructionError::InvalidInstructionData))
Err(InstructionError::InvalidInstructionData)
}
}
});
fn create_mock_transfer(
payer: &Keypair,
@ -11888,14 +11805,10 @@ enum MockReallocInstruction {
Realloc(usize, u64, Pubkey),
}
fn mock_realloc_process_instruction(
invoke_context: &mut InvokeContext,
) -> result::Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(mock_realloc_process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
// mock builtin must consume units
invoke_context.consume_checked(1)?;
if let Ok(instruction) = bincode::deserialize(instruction_data) {
match instruction {
MockReallocInstruction::Realloc(new_size, new_balance, _) => {
@ -11929,9 +11842,9 @@ fn mock_realloc_process_instruction(
}
}
} else {
Err(Box::new(InstructionError::InvalidInstructionData))
Err(InstructionError::InvalidInstructionData)
}
}
});
fn create_mock_realloc_tx(
payer: &Keypair,

View File

@ -188,6 +188,7 @@ mod tests {
use {
super::*,
crate::rent_collector::RentCollector,
solana_program_runtime::declare_process_instruction,
solana_sdk::{
account::{AccountSharedData, ReadableAccount},
instruction::{AccountMeta, Instruction, InstructionError},
@ -217,14 +218,10 @@ mod tests {
ChangeData { data: u8 },
}
fn mock_system_process_instruction(
invoke_context: &mut InvokeContext,
) -> Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
// mock builtin should consume units
let _ = invoke_context.consume_checked(1);
if let Ok(instruction) = bincode::deserialize(instruction_data) {
match instruction {
MockSystemInstruction::Correct => Ok(()),
@ -245,9 +242,9 @@ mod tests {
}
}
} else {
Err(Box::new(InstructionError::InvalidInstructionData))
Err(InstructionError::InvalidInstructionData)
}
}
});
let writable_pubkey = Pubkey::new_unique();
let readonly_pubkey = Pubkey::new_unique();
@ -256,7 +253,7 @@ mod tests {
let rent_collector = RentCollector::default();
let builtin_programs = &[BuiltinProgram {
program_id: mock_system_program_id,
process_instruction: mock_system_process_instruction,
process_instruction,
}];
let accounts = vec![
@ -430,16 +427,12 @@ mod tests {
DoWork { lamports: u64, data: u8 },
}
fn mock_system_process_instruction(
invoke_context: &mut InvokeContext,
) -> Result<(), Box<dyn std::error::Error>> {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
let mut to_account =
instruction_context.try_borrow_instruction_account(transaction_context, 1)?;
// mock builtin should consume units
let _ = invoke_context.consume_checked(1);
if let Ok(instruction) = bincode::deserialize(instruction_data) {
match instruction {
MockSystemInstruction::BorrowFail => {
@ -448,7 +441,7 @@ mod tests {
let dup_account = instruction_context
.try_borrow_instruction_account(transaction_context, 2)?;
if from_account.get_lamports() != dup_account.get_lamports() {
return Err(Box::new(InstructionError::InvalidArgument));
return Err(InstructionError::InvalidArgument);
}
Ok(())
}
@ -460,7 +453,7 @@ mod tests {
.try_borrow_instruction_account(transaction_context, 2)?
.get_lamports();
if lamports_a != lamports_b {
return Err(Box::new(InstructionError::InvalidArgument));
return Err(InstructionError::InvalidArgument);
}
Ok(())
}
@ -479,15 +472,15 @@ mod tests {
}
}
} else {
Err(Box::new(InstructionError::InvalidInstructionData))
Err(InstructionError::InvalidInstructionData)
}
}
});
let mock_program_id = Pubkey::from([2u8; 32]);
let rent_collector = RentCollector::default();
let builtin_programs = &[BuiltinProgram {
program_id: mock_program_id,
process_instruction: mock_system_process_instruction,
process_instruction,
}];
let accounts = vec![
@ -645,16 +638,12 @@ mod tests {
#[test]
fn test_precompile() {
let mock_program_id = Pubkey::new_unique();
fn mock_process_instruction(
invoke_context: &mut InvokeContext,
) -> Result<(), Box<dyn std::error::Error>> {
// mock builtin should consume units
let _ = invoke_context.consume_checked(1);
Err(Box::new(InstructionError::Custom(0xbabb1e)))
}
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
Err(InstructionError::Custom(0xbabb1e))
});
let builtin_programs = &[BuiltinProgram {
program_id: mock_program_id,
process_instruction: mock_process_instruction,
process_instruction,
}];
let mut secp256k1_account = AccountSharedData::new(1, 0, &native_loader::id());

View File

@ -316,10 +316,7 @@ fn transfer_with_seed(
)
}
declare_process_instruction!(150);
pub fn process_instruction_inner(
invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> {
declare_process_instruction!(process_instruction, 150, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let instruction_data = instruction_context.get_instruction_data();
@ -558,7 +555,7 @@ pub fn process_instruction_inner(
assign(&mut account, &address, &owner, &signers, invoke_context)
}
}
}
});
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum SystemAccountKind {
@ -614,8 +611,7 @@ mod tests {
crate::{bank::Bank, bank_client::BankClient},
bincode::serialize,
solana_program_runtime::{
invoke_context::{mock_process_instruction, ProcessInstructionWithContext},
with_mock_invoke_context,
invoke_context::mock_process_instruction, with_mock_invoke_context,
},
std::sync::Arc,
};
@ -634,7 +630,6 @@ mod tests {
transaction_accounts: Vec<(Pubkey, AccountSharedData)>,
instruction_accounts: Vec<AccountMeta>,
expected_result: Result<(), InstructionError>,
process_instruction: ProcessInstructionWithContext,
) -> Vec<AccountSharedData> {
mock_process_instruction(
&system_program::id(),
@ -643,7 +638,8 @@ mod tests {
transaction_accounts,
instruction_accounts,
expected_result,
process_instruction,
super::process_instruction,
|_invoke_context| {},
|_invoke_context| {},
)
}
@ -691,7 +687,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 50);
assert_eq!(accounts[1].lamports(), 50);
@ -731,7 +726,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 50);
assert_eq!(accounts[1].lamports(), 50);
@ -778,7 +772,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 50);
assert_eq!(accounts[1].lamports(), 50);
@ -830,7 +823,6 @@ mod tests {
},
],
Err(InstructionError::MissingRequiredSignature),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1], AccountSharedData::default());
@ -866,7 +858,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1].lamports(), 0);
@ -904,7 +895,6 @@ mod tests {
},
],
Err(SystemError::ResultWithNegativeLamports.into()),
super::process_instruction,
);
}
@ -938,7 +928,6 @@ mod tests {
vec![(from, from_account.clone()), (to, to_account.clone())],
instruction_accounts.clone(),
Err(SystemError::InvalidAccountDataLength.into()),
super::process_instruction,
);
// Trying to request equal or less data length than permitted will be successful
@ -952,7 +941,6 @@ mod tests {
vec![(from, from_account), (to, to_account)],
instruction_accounts,
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[1].lamports(), 50);
assert_eq!(accounts[1].data().len() as u64, MAX_PERMITTED_DATA_LENGTH);
@ -990,7 +978,6 @@ mod tests {
},
],
Err(SystemError::AccountAlreadyInUse.into()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1], unchanged_account);
@ -1019,7 +1006,6 @@ mod tests {
},
],
Err(SystemError::AccountAlreadyInUse.into()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1], unchanged_account);
@ -1048,7 +1034,6 @@ mod tests {
},
],
Err(SystemError::AccountAlreadyInUse.into()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1], unchanged_account);
@ -1088,7 +1073,6 @@ mod tests {
},
],
Err(InstructionError::MissingRequiredSignature),
super::process_instruction,
);
// Haven't signed to account
@ -1113,7 +1097,6 @@ mod tests {
},
],
Err(InstructionError::MissingRequiredSignature),
super::process_instruction,
);
// Don't support unsigned creation with zero lamports (ephemeral account)
@ -1139,7 +1122,6 @@ mod tests {
},
],
Err(InstructionError::MissingRequiredSignature),
super::process_instruction,
);
}
@ -1173,7 +1155,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
}
@ -1210,7 +1191,6 @@ mod tests {
},
],
Err(SystemError::AccountAlreadyInUse.into()),
super::process_instruction,
);
}
@ -1247,7 +1227,6 @@ mod tests {
},
],
Err(InstructionError::InvalidArgument),
super::process_instruction,
);
}
@ -1270,7 +1249,6 @@ mod tests {
is_writable: true,
}],
Ok(()),
super::process_instruction,
);
// owner does change, signature needed
@ -1283,7 +1261,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::MissingRequiredSignature),
super::process_instruction,
);
process_instruction(
@ -1295,7 +1272,6 @@ mod tests {
is_writable: true,
}],
Ok(()),
super::process_instruction,
);
// assign to sysvar instead of system_program
@ -1311,7 +1287,6 @@ mod tests {
is_writable: true,
}],
Ok(()),
super::process_instruction,
);
}
@ -1327,7 +1302,6 @@ mod tests {
Vec::new(),
Vec::new(),
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
// Attempt to transfer with no destination
@ -1344,7 +1318,6 @@ mod tests {
is_writable: false,
}],
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
}
@ -1374,7 +1347,6 @@ mod tests {
transaction_accounts.clone(),
instruction_accounts.clone(),
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 50);
assert_eq!(accounts[1].lamports(), 51);
@ -1385,7 +1357,6 @@ mod tests {
transaction_accounts.clone(),
instruction_accounts.clone(),
Err(SystemError::ResultWithNegativeLamports.into()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1].lamports(), 1);
@ -1396,7 +1367,6 @@ mod tests {
transaction_accounts.clone(),
instruction_accounts,
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1].lamports(), 1);
@ -1418,7 +1388,6 @@ mod tests {
},
],
Err(InstructionError::MissingRequiredSignature),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[1].lamports(), 1);
@ -1465,7 +1434,6 @@ mod tests {
transaction_accounts.clone(),
instruction_accounts.clone(),
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 50);
assert_eq!(accounts[2].lamports(), 51);
@ -1481,7 +1449,6 @@ mod tests {
transaction_accounts.clone(),
instruction_accounts.clone(),
Err(SystemError::ResultWithNegativeLamports.into()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[2].lamports(), 1);
@ -1497,7 +1464,6 @@ mod tests {
transaction_accounts,
instruction_accounts,
Ok(()),
super::process_instruction,
);
assert_eq!(accounts[0].lamports(), 100);
assert_eq!(accounts[2].lamports(), 1);
@ -1538,7 +1504,6 @@ mod tests {
},
],
Err(InstructionError::InvalidArgument),
super::process_instruction,
);
}
@ -1766,7 +1731,6 @@ mod tests {
transaction_accounts,
instruction.accounts,
expected_result,
super::process_instruction,
)
}
@ -1786,7 +1750,6 @@ mod tests {
Vec::new(),
Vec::new(),
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
}
@ -1802,7 +1765,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
}
@ -1837,7 +1799,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
let blockhash = hash(&serialize(&0).unwrap());
#[allow(deprecated)]
@ -1846,7 +1807,9 @@ mod tests {
vec![IterItem(0u64, &blockhash, 0); sysvar::recent_blockhashes::MAX_ENTRIES]
.into_iter(),
);
process_instruction(
mock_process_instruction(
&system_program::id(),
Vec::new(),
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(),
vec![
(nonce_address, accounts[0].clone()),
@ -1865,10 +1828,11 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
|invoke_context: &mut InvokeContext| {
invoke_context.blockhash = hash(&serialize(&0).unwrap());
super::process_instruction(invoke_context)
},
|_invoke_context| {},
);
}
@ -1893,7 +1857,6 @@ mod tests {
Vec::new(),
Vec::new(),
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
}
@ -1909,7 +1872,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
}
@ -1951,7 +1913,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
}
@ -1962,7 +1923,6 @@ mod tests {
Vec::new(),
Vec::new(),
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
}
@ -1979,7 +1939,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::NotEnoughAccountKeys),
super::process_instruction,
);
}
@ -2014,7 +1973,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
}
@ -2049,7 +2007,6 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
process_instruction(
&serialize(&SystemInstruction::AuthorizeNonceAccount(nonce_address)).unwrap(),
@ -2060,7 +2017,6 @@ mod tests {
is_writable: true,
}],
Ok(()),
super::process_instruction,
);
}
@ -2162,7 +2118,6 @@ mod tests {
},
],
Err(NonceError::NoRecentBlockhashes.into()),
super::process_instruction,
);
}
@ -2197,14 +2152,15 @@ mod tests {
},
],
Ok(()),
super::process_instruction,
);
#[allow(deprecated)]
let new_recent_blockhashes_account =
solana_sdk::recent_blockhashes_account::create_account_with_data_for_test(
vec![].into_iter(),
);
process_instruction(
mock_process_instruction(
&system_program::id(),
Vec::new(),
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(),
vec![
(nonce_address, accounts[0].clone()),
@ -2223,10 +2179,11 @@ mod tests {
},
],
Err(NonceError::NoRecentBlockhashes.into()),
super::process_instruction,
|invoke_context: &mut InvokeContext| {
invoke_context.blockhash = hash(&serialize(&0).unwrap());
super::process_instruction(invoke_context)
},
|_invoke_context| {},
);
}
@ -2249,7 +2206,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::InvalidAccountOwner),
super::process_instruction,
);
assert_eq!(accounts.len(), 1);
assert_eq!(accounts[0], nonce_account);
@ -2283,7 +2239,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::InvalidArgument),
super::process_instruction,
);
assert_eq!(accounts.len(), 1);
assert_eq!(accounts[0], nonce_account);
@ -2298,7 +2253,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::InvalidArgument),
super::process_instruction,
);
assert_eq!(accounts.len(), 1);
assert_eq!(accounts[0], nonce_account);
@ -2322,7 +2276,6 @@ mod tests {
is_writable: false, // Should fail!
}],
Err(InstructionError::InvalidArgument),
super::process_instruction,
);
assert_eq!(accounts.len(), 1);
assert_eq!(accounts[0], nonce_account);
@ -2335,7 +2288,6 @@ mod tests {
is_writable: true,
}],
Ok(()),
super::process_instruction,
);
assert_eq!(accounts.len(), 1);
let nonce_account = accounts.remove(0);
@ -2360,7 +2312,6 @@ mod tests {
is_writable: true,
}],
Err(InstructionError::InvalidArgument),
super::process_instruction,
);
assert_eq!(accounts.len(), 1);
assert_eq!(