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:
parent
bcd43d7a79
commit
0cd57addcf
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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| {},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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| {},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -655,6 +655,7 @@ mod tests {
|
|||
expected_result,
|
||||
super::process_instruction,
|
||||
|_invoke_context| {},
|
||||
|_invoke_context| {},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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| {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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| {},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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!(
|
||||
|
|
Loading…
Reference in New Issue