Replaces MockInvokeContext by ThisInvokeContext in tests (#20881)

* Replaces MockInvokeContext by ThisInvokeContext in BpfLoader, SystemInstructionProcessor, CLIs, ConfigProcessor, StakeProcessor and VoteProcessor.

* Finally, removes MockInvokeContext, MockComputeMeter and MockLogger.

* Adjusts assert_instruction_count test.

* Moves ThisInvokeContext to the program-runtime crate.
This commit is contained in:
Alexander Meißner
2021-11-04 21:47:32 +01:00
committed by GitHub
parent 0597594943
commit 7200c5106e
33 changed files with 2640 additions and 2783 deletions

View File

@@ -2566,6 +2566,7 @@ dependencies = [
"solana-cli-output",
"solana-logger 1.9.0",
"solana-measure",
"solana-program-runtime",
"solana-runtime",
"solana-sdk",
"solana-transaction-status",
@@ -3230,6 +3231,7 @@ dependencies = [
name = "solana-program-runtime"
version = "1.9.0"
dependencies = [
"bincode",
"libc",
"libloading",
"log",
@@ -3438,6 +3440,7 @@ dependencies = [
"solana-frozen-abi 1.9.0",
"solana-frozen-abi-macro 1.9.0",
"solana-metrics",
"solana-program-runtime",
"solana-sdk",
"solana-vote-program",
"thiserror",

View File

@@ -35,6 +35,7 @@ solana-logger = { path = "../../logger", version = "=1.9.0" }
solana-measure = { path = "../../measure", version = "=1.9.0" }
solana_rbpf = "=0.2.14"
solana-runtime = { path = "../../runtime", version = "=1.9.0" }
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.0" }
solana-sdk = { path = "../../sdk", version = "=1.9.0" }
solana-transaction-status = { path = "../../transaction-status", version = "=1.9.0" }
solana-account-decoder = { path = "../../account-decoder", version = "=1.9.0" }

View File

@@ -18,18 +18,18 @@ use solana_runtime::{
genesis_utils::{create_genesis_config, GenesisConfigInfo},
loader_utils::load_program,
};
use solana_program_runtime::invoke_context::with_mock_invoke_context;
use solana_sdk::{
account::AccountSharedData,
bpf_loader,
client::SyncClient,
entrypoint::SUCCESS,
instruction::{AccountMeta, Instruction},
message::Message,
process_instruction::{InvokeContext, MockComputeMeter, MockInvokeContext},
process_instruction::InvokeContext,
pubkey::Pubkey,
signature::{Keypair, Signer},
};
use std::{cell::RefCell, env, fs::File, io::Read, mem, path::PathBuf, rc::Rc, sync::Arc};
use std::{env, fs::File, io::Read, mem, path::PathBuf, sync::Arc};
use test::Bencher;
/// BPF program file extension
@@ -94,93 +94,73 @@ fn bench_program_alu(bencher: &mut Bencher) {
.write_u64::<LittleEndian>(ARMSTRONG_LIMIT)
.unwrap();
inner_iter.write_u64::<LittleEndian>(0).unwrap();
let loader_id = bpf_loader::id();
let program_id = solana_sdk::pubkey::new_rand();
let accounts = [
(
program_id,
RefCell::new(AccountSharedData::new(0, 0, &loader_id)),
),
(
solana_sdk::pubkey::new_rand(),
RefCell::new(AccountSharedData::new(
1,
10000001,
&solana_sdk::pubkey::new_rand(),
)),
),
];
let keyed_accounts: Vec<_> = accounts
.iter()
.map(|(key, account)| solana_sdk::keyed_account::KeyedAccount::new(&key, false, &account))
.collect();
let mut invoke_context = MockInvokeContext::new(&program_id, keyed_accounts);
let elf = load_elf("bench_alu").unwrap();
let mut executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&elf,
None,
Config::default(),
register_syscalls(&mut invoke_context).unwrap(),
)
.unwrap();
executable.jit_compile().unwrap();
let compute_meter = invoke_context.get_compute_meter();
let mut instruction_meter = ThisInstructionMeter { compute_meter };
let mut vm = create_vm(
&loader_id,
executable.as_ref(),
&mut inner_iter,
&mut invoke_context,
&[],
)
.unwrap();
let loader_id = bpf_loader::id();
with_mock_invoke_context(loader_id, 10000001, |invoke_context| {
let mut executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&elf,
None,
Config::default(),
register_syscalls(invoke_context).unwrap(),
)
.unwrap();
executable.jit_compile().unwrap();
let compute_meter = invoke_context.get_compute_meter();
let mut instruction_meter = ThisInstructionMeter { compute_meter };
let mut vm = create_vm(
&loader_id,
executable.as_ref(),
&mut inner_iter,
invoke_context,
&[],
)
.unwrap();
println!("Interpreted:");
assert_eq!(
SUCCESS,
vm.execute_program_interpreted(&mut instruction_meter)
.unwrap()
);
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
assert_eq!(
ARMSTRONG_EXPECTED,
LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
);
println!("Interpreted:");
assert_eq!(
SUCCESS,
vm.execute_program_interpreted(&mut instruction_meter)
.unwrap()
);
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
assert_eq!(
ARMSTRONG_EXPECTED,
LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
);
bencher.iter(|| {
vm.execute_program_interpreted(&mut instruction_meter)
.unwrap();
bencher.iter(|| {
vm.execute_program_interpreted(&mut instruction_meter)
.unwrap();
});
let instructions = vm.get_total_instruction_count();
let summary = bencher.bench(|_bencher| {}).unwrap();
println!(" {:?} instructions", instructions);
println!(" {:?} ns/iter median", summary.median as u64);
assert!(0f64 != summary.median);
let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
println!(" {:?} MIPS", mips);
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
println!("JIT to native:");
assert_eq!(
SUCCESS,
vm.execute_program_jit(&mut instruction_meter).unwrap()
);
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
assert_eq!(
ARMSTRONG_EXPECTED,
LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
);
bencher.iter(|| vm.execute_program_jit(&mut instruction_meter).unwrap());
let summary = bencher.bench(|_bencher| {}).unwrap();
println!(" {:?} instructions", instructions);
println!(" {:?} ns/iter median", summary.median as u64);
assert!(0f64 != summary.median);
let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
println!(" {:?} MIPS", mips);
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
});
let instructions = vm.get_total_instruction_count();
let summary = bencher.bench(|_bencher| {}).unwrap();
println!(" {:?} instructions", instructions);
println!(" {:?} ns/iter median", summary.median as u64);
assert!(0f64 != summary.median);
let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
println!(" {:?} MIPS", mips);
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
println!("JIT to native:");
assert_eq!(
SUCCESS,
vm.execute_program_jit(&mut instruction_meter).unwrap()
);
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
assert_eq!(
ARMSTRONG_EXPECTED,
LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
);
bencher.iter(|| vm.execute_program_jit(&mut instruction_meter).unwrap());
let summary = bencher.bench(|_bencher| {}).unwrap();
println!(" {:?} instructions", instructions);
println!(" {:?} ns/iter median", summary.median as u64);
assert!(0f64 != summary.median);
let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
println!(" {:?} MIPS", mips);
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
}
#[bench]
@@ -220,125 +200,102 @@ fn bench_program_execute_noop(bencher: &mut Bencher) {
#[bench]
fn bench_create_vm(bencher: &mut Bencher) {
const BUDGET: u64 = 200_000;
let loader_id = bpf_loader::id();
let accounts = [RefCell::new(AccountSharedData::new(
1,
10000001,
&solana_sdk::pubkey::new_rand(),
))];
let keys = [solana_sdk::pubkey::new_rand()];
let keyed_accounts: Vec<_> = keys
.iter()
.zip(&accounts)
.map(|(key, account)| solana_sdk::keyed_account::KeyedAccount::new(&key, false, &account))
.collect();
let instruction_data = vec![0u8];
let mut invoke_context = MockInvokeContext::new(&loader_id, keyed_accounts);
invoke_context.compute_meter = Rc::new(RefCell::new(MockComputeMeter { remaining: BUDGET }));
// Serialize account data
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
let (mut serialized, account_lengths) = serialize_parameters(
&loader_id,
&solana_sdk::pubkey::new_rand(),
keyed_accounts,
&instruction_data,
)
.unwrap();
let elf = load_elf("noop").unwrap();
let executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&elf,
None,
Config::default(),
register_syscalls(&mut invoke_context).unwrap(),
)
.unwrap();
let loader_id = bpf_loader::id();
with_mock_invoke_context(loader_id, 10000001, |invoke_context| {
const BUDGET: u64 = 200_000;
let compute_meter = invoke_context.get_compute_meter();
{
let mut compute_meter = compute_meter.borrow_mut();
let to_consume = compute_meter.get_remaining() - BUDGET;
compute_meter.consume(to_consume).unwrap();
}
bencher.iter(|| {
let _ = create_vm(
&loader_id,
executable.as_ref(),
serialized.as_slice_mut(),
&mut invoke_context,
&account_lengths,
// Serialize account data
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
let (mut serialized, account_lengths) = serialize_parameters(
&keyed_accounts[0].unsigned_key(),
&keyed_accounts[1].unsigned_key(),
&keyed_accounts[2..],
&[],
)
.unwrap();
let executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&elf,
None,
Config::default(),
register_syscalls(invoke_context).unwrap(),
)
.unwrap();
bencher.iter(|| {
let _ = create_vm(
&loader_id,
executable.as_ref(),
serialized.as_slice_mut(),
invoke_context,
&account_lengths,
)
.unwrap();
});
});
}
#[bench]
fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
const BUDGET: u64 = 200_000;
let loader_id = bpf_loader::id();
let program_id = solana_sdk::pubkey::new_rand();
let accounts = [
(
program_id,
RefCell::new(AccountSharedData::new(0, 0, &loader_id)),
),
(
solana_sdk::pubkey::new_rand(),
RefCell::new(AccountSharedData::new(
1,
10000001,
&solana_sdk::pubkey::new_rand(),
)),
),
];
let keyed_accounts: Vec<_> = accounts
.iter()
.map(|(key, account)| solana_sdk::keyed_account::KeyedAccount::new(&key, false, &account))
.collect();
let instruction_data = vec![0u8];
let mut invoke_context = MockInvokeContext::new(&program_id, keyed_accounts);
invoke_context.compute_meter = Rc::new(RefCell::new(MockComputeMeter { remaining: BUDGET }));
// Serialize account data
let (mut serialized, account_lengths) = serialize_parameters(
&loader_id,
&program_id,
&invoke_context.get_keyed_accounts().unwrap()[1..],
&instruction_data,
)
.unwrap();
let elf = load_elf("tuner").unwrap();
let executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&elf,
None,
Config::default(),
register_syscalls(&mut invoke_context).unwrap(),
)
.unwrap();
let compute_meter = invoke_context.get_compute_meter();
let mut instruction_meter = ThisInstructionMeter { compute_meter };
let mut vm = create_vm(
&loader_id,
executable.as_ref(),
serialized.as_slice_mut(),
&mut invoke_context,
&account_lengths,
)
.unwrap();
let loader_id = bpf_loader::id();
with_mock_invoke_context(loader_id, 10000001, |invoke_context| {
const BUDGET: u64 = 200_000;
let compute_meter = invoke_context.get_compute_meter();
{
let mut compute_meter = compute_meter.borrow_mut();
let to_consume = compute_meter.get_remaining() - BUDGET;
compute_meter.consume(to_consume).unwrap();
}
let mut measure = Measure::start("tune");
let _ = vm.execute_program_interpreted(&mut instruction_meter);
measure.stop();
// Serialize account data
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
let (mut serialized, account_lengths) = serialize_parameters(
&keyed_accounts[0].unsigned_key(),
&keyed_accounts[1].unsigned_key(),
&keyed_accounts[2..],
&[],
)
.unwrap();
assert_eq!(
0,
instruction_meter.get_remaining(),
"Tuner must consume the whole budget"
);
println!(
"{:?} compute units took {:?} us ({:?} instructions)",
BUDGET - instruction_meter.get_remaining(),
measure.as_us(),
vm.get_total_instruction_count(),
);
let executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&elf,
None,
Config::default(),
register_syscalls(invoke_context).unwrap(),
)
.unwrap();
let mut instruction_meter = ThisInstructionMeter { compute_meter };
let mut vm = create_vm(
&loader_id,
executable.as_ref(),
serialized.as_slice_mut(),
invoke_context,
&account_lengths,
)
.unwrap();
let mut measure = Measure::start("tune");
let _ = vm.execute_program_interpreted(&mut instruction_meter);
measure.stop();
assert_eq!(
0,
instruction_meter.get_remaining(),
"Tuner must consume the whole budget"
);
println!(
"{:?} compute units took {:?} us ({:?} instructions)",
BUDGET - instruction_meter.get_remaining(),
measure.as_us(),
vm.get_total_instruction_count(),
);
});
}

View File

@@ -31,6 +31,7 @@ use solana_runtime::{
upgrade_program,
},
};
use solana_program_runtime::invoke_context::with_mock_invoke_context;
use solana_sdk::{
account::{AccountSharedData, ReadableAccount},
account_utils::StateMut,
@@ -40,10 +41,9 @@ use solana_sdk::{
compute_budget::{ComputeBudget, ComputeBudgetInstruction},
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
keyed_account::KeyedAccount,
loader_instruction,
message::{Message, SanitizedMessage},
process_instruction::{InvokeContext, MockInvokeContext},
process_instruction::InvokeContext,
pubkey::Pubkey,
signature::{keypair_from_seed, Keypair, Signer},
system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
@@ -56,8 +56,8 @@ use solana_transaction_status::{
TransactionStatusMeta, TransactionWithStatusMeta, UiTransactionEncoding,
};
use std::{
cell::RefCell, collections::HashMap, convert::TryFrom, env, fs::File, io::Read, path::PathBuf,
str::FromStr, sync::Arc,
collections::HashMap, convert::TryFrom, env, fs::File, io::Read, path::PathBuf, str::FromStr,
sync::Arc,
};
/// BPF program file extension
@@ -190,109 +190,103 @@ fn upgrade_bpf_program(
);
}
fn run_program(
name: &str,
loader_id: &Pubkey,
program_id: &Pubkey,
parameter_accounts: Vec<KeyedAccount>,
instruction_data: &[u8],
) -> Result<u64, InstructionError> {
fn run_program(name: &str) -> u64 {
let mut file = File::open(create_bpf_path(name)).unwrap();
let mut data = vec![];
file.read_to_end(&mut data).unwrap();
let mut invoke_context = MockInvokeContext::new(&program_id, parameter_accounts);
let (parameter_bytes, account_lengths) = serialize_parameters(
&loader_id,
program_id,
&invoke_context.get_keyed_accounts().unwrap()[1..],
&instruction_data,
)
.unwrap();
let compute_meter = invoke_context.get_compute_meter();
let mut instruction_meter = ThisInstructionMeter { compute_meter };
let config = Config {
enable_instruction_tracing: true,
..Config::default()
};
let mut executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&data,
None,
config,
register_syscalls(&mut invoke_context).unwrap(),
)
.unwrap();
executable.jit_compile().unwrap();
let mut instruction_count = 0;
let mut tracer = None;
for i in 0..2 {
let mut parameter_bytes = parameter_bytes.clone();
{
invoke_context.set_return_data(Vec::new()).unwrap();
let mut vm = create_vm(
&loader_id,
executable.as_ref(),
parameter_bytes.as_slice_mut(),
&mut invoke_context,
&account_lengths,
)
.unwrap();
let result = if i == 0 {
vm.execute_program_interpreted(&mut instruction_meter)
} else {
vm.execute_program_jit(&mut instruction_meter)
};
assert_eq!(SUCCESS, result.unwrap());
if i == 1 {
assert_eq!(instruction_count, vm.get_total_instruction_count());
}
instruction_count = vm.get_total_instruction_count();
if config.enable_instruction_tracing {
if i == 1 {
if !Tracer::compare(tracer.as_ref().unwrap(), vm.get_tracer()) {
let analysis = Analysis::from_executable(executable.as_ref());
let stdout = std::io::stdout();
println!("TRACE (interpreted):");
tracer
.as_ref()
.unwrap()
.write(&mut stdout.lock(), &analysis)
.unwrap();
println!("TRACE (jit):");
vm.get_tracer()
.write(&mut stdout.lock(), &analysis)
.unwrap();
assert!(false);
} else if log_enabled!(Trace) {
let analysis = Analysis::from_executable(executable.as_ref());
let mut trace_buffer = Vec::<u8>::new();
tracer
.as_ref()
.unwrap()
.write(&mut trace_buffer, &analysis)
.unwrap();
let trace_string = String::from_utf8(trace_buffer).unwrap();
trace!("BPF Program Instruction Trace:\n{}", trace_string);
}
}
tracer = Some(vm.get_tracer().clone());
}
}
let parameter_accounts = invoke_context.get_keyed_accounts().unwrap();
deserialize_parameters(
&loader_id,
parameter_accounts,
parameter_bytes.as_slice(),
&account_lengths,
true,
let loader_id = bpf_loader::id();
with_mock_invoke_context(loader_id, 0, |invoke_context| {
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
let (parameter_bytes, account_lengths) = serialize_parameters(
&keyed_accounts[0].unsigned_key(),
&keyed_accounts[1].unsigned_key(),
&keyed_accounts[2..],
&[],
)
.unwrap();
}
Ok(instruction_count)
let compute_meter = invoke_context.get_compute_meter();
let mut instruction_meter = ThisInstructionMeter { compute_meter };
let config = Config {
enable_instruction_tracing: true,
..Config::default()
};
let mut executable = <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&data,
None,
config,
register_syscalls(invoke_context).unwrap(),
)
.unwrap();
executable.jit_compile().unwrap();
let mut instruction_count = 0;
let mut tracer = None;
for i in 0..2 {
invoke_context.set_return_data(Vec::new()).unwrap();
let mut parameter_bytes = parameter_bytes.clone();
{
let mut vm = create_vm(
&loader_id,
executable.as_ref(),
parameter_bytes.as_slice_mut(),
invoke_context,
&account_lengths,
)
.unwrap();
let result = if i == 0 {
vm.execute_program_interpreted(&mut instruction_meter)
} else {
vm.execute_program_jit(&mut instruction_meter)
};
assert_eq!(SUCCESS, result.unwrap());
if i == 1 {
assert_eq!(instruction_count, vm.get_total_instruction_count());
}
instruction_count = vm.get_total_instruction_count();
if config.enable_instruction_tracing {
if i == 1 {
if !Tracer::compare(tracer.as_ref().unwrap(), vm.get_tracer()) {
let analysis = Analysis::from_executable(executable.as_ref());
let stdout = std::io::stdout();
println!("TRACE (interpreted):");
tracer
.as_ref()
.unwrap()
.write(&mut stdout.lock(), &analysis)
.unwrap();
println!("TRACE (jit):");
vm.get_tracer()
.write(&mut stdout.lock(), &analysis)
.unwrap();
assert!(false);
} else if log_enabled!(Trace) {
let analysis = Analysis::from_executable(executable.as_ref());
let mut trace_buffer = Vec::<u8>::new();
tracer
.as_ref()
.unwrap()
.write(&mut trace_buffer, &analysis)
.unwrap();
let trace_string = String::from_utf8(trace_buffer).unwrap();
trace!("BPF Program Instruction Trace:\n{}", trace_string);
}
}
tracer = Some(vm.get_tracer().clone());
}
}
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
deserialize_parameters(
&loader_id,
&keyed_accounts[2..],
parameter_bytes.as_slice(),
&account_lengths,
true,
)
.unwrap();
}
instruction_count
})
}
fn process_transaction_and_record_inner(
@@ -1377,8 +1371,8 @@ fn assert_instruction_count() {
("noop++", 5),
("relative_call", 26),
("return_data", 980),
("sanity", 1246),
("sanity++", 1250),
("sanity", 1248),
("sanity++", 1252),
("secp256k1_recover", 25383),
("sha", 1328),
("struct_pass", 108),
@@ -1390,17 +1384,17 @@ fn assert_instruction_count() {
programs.extend_from_slice(&[
("solana_bpf_rust_128bit", 584),
("solana_bpf_rust_alloc", 7388),
("solana_bpf_rust_custom_heap", 535),
("solana_bpf_rust_custom_heap", 536),
("solana_bpf_rust_dep_crate", 47),
("solana_bpf_rust_external_spend", 506),
("solana_bpf_rust_external_spend", 507),
("solana_bpf_rust_iter", 824),
("solana_bpf_rust_many_args", 941),
("solana_bpf_rust_mem", 3085),
("solana_bpf_rust_mem", 3086),
("solana_bpf_rust_membuiltins", 3976),
("solana_bpf_rust_noop", 480),
("solana_bpf_rust_noop", 481),
("solana_bpf_rust_param_passing", 146),
("solana_bpf_rust_rand", 487),
("solana_bpf_rust_sanity", 8454),
("solana_bpf_rust_rand", 488),
("solana_bpf_rust_sanity", 8455),
("solana_bpf_rust_secp256k1_recover", 25216),
("solana_bpf_rust_sha", 30692),
]);
@@ -1409,17 +1403,7 @@ fn assert_instruction_count() {
let mut passed = true;
println!("\n {:36} expected actual diff", "BPF program");
for program in programs.iter() {
let loader_id = bpf_loader::id();
let program_id = Pubkey::new_unique();
let key = Pubkey::new_unique();
let mut program_account = RefCell::new(AccountSharedData::new(0, 0, &loader_id));
let mut account = RefCell::new(AccountSharedData::default());
let parameter_accounts = vec![
KeyedAccount::new(&program_id, false, &mut program_account),
KeyedAccount::new(&key, false, &mut account),
];
let count =
run_program(program.0, &loader_id, &program_id, parameter_accounts, &[]).unwrap();
let count = run_program(program.0);
let diff: i64 = count as i64 - program.1 as i64;
println!(
" {:36} {:8} {:6} {:+5} ({:+3.0}%)",

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
use crate::{alloc, BpfError};
use alloc::Alloc;
use solana_program_runtime::InstructionProcessor;
use solana_program_runtime::instruction_processor::InstructionProcessor;
use solana_rbpf::{
aligned_memory::AlignedMemory,
ebpf,
@@ -31,7 +31,7 @@ use solana_sdk::{
message::Message,
native_loader,
precompiles::is_precompile,
process_instruction::{self, stable_log, ComputeMeter, InvokeContext, Logger},
process_instruction::{stable_log, ComputeMeter, InvokeContext, Logger},
program::MAX_RETURN_DATA,
pubkey::{Pubkey, PubkeyError, MAX_SEEDS, MAX_SEED_LEN},
rent::Rent,
@@ -982,7 +982,7 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
.consume(invoke_context.get_compute_budget().sysvar_base_cost + size_of::<T>() as u64)?;
let var = translate_type_mut::<T>(memory_mapping, var_addr, loader_id)?;
*var = process_instruction::get_sysvar::<T>(*invoke_context, id)
*var = solana_program_runtime::invoke_context::get_sysvar::<T>(*invoke_context, id)
.map_err(SyscallError::InstructionError)?;
Ok(SUCCESS)
@@ -2427,16 +2427,17 @@ impl<'a> SyscallObject<BpfError> for SyscallLogData<'a> {
#[cfg(test)]
mod tests {
use super::*;
use solana_program_runtime::{
invoke_context::{ThisComputeMeter, ThisInvokeContext, ThisLogger},
log_collector::LogCollector,
};
use solana_rbpf::{
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
};
use solana_sdk::{
bpf_loader,
fee_calculator::FeeCalculator,
hash::hashv,
process_instruction::{MockComputeMeter, MockInvokeContext, MockLogger},
bpf_loader, feature_set::FeatureSet, fee_calculator::FeeCalculator, hash::hashv,
};
use std::str::FromStr;
use std::{str::FromStr, sync::Arc};
macro_rules! assert_access_violation {
($result:expr, $va:expr, $len:expr) => {
@@ -2762,10 +2763,7 @@ mod tests {
)
.unwrap();
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter {
remaining: string.len() as u64 - 1,
}));
let compute_meter = ThisComputeMeter::new_ref(string.len() as u64 - 1);
let mut syscall_panic = SyscallPanic {
compute_meter,
loader_id: &bpf_loader::id(),
@@ -2787,10 +2785,7 @@ mod tests {
result
);
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter {
remaining: string.len() as u64,
}));
let compute_meter = ThisComputeMeter::new_ref(string.len() as u64);
let mut syscall_panic = SyscallPanic {
compute_meter,
loader_id: &bpf_loader::id(),
@@ -2812,17 +2807,6 @@ mod tests {
fn test_syscall_sol_log() {
let string = "Gaggablaghblagh!";
let addr = string.as_ptr() as *const _ as u64;
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter { remaining: 1000000 }));
let log = Rc::new(RefCell::new(vec![]));
let logger: Rc<RefCell<dyn Logger>> =
Rc::new(RefCell::new(MockLogger { log: log.clone() }));
let mut syscall_sol_log = SyscallLog {
compute_meter,
logger,
loader_id: &bpf_loader::id(),
};
let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>(
vec![
@@ -2838,21 +2822,39 @@ mod tests {
&config,
)
.unwrap();
let log = Rc::new(LogCollector::default());
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call(
0x100000000,
string.len() as u64,
0,
0,
0,
&memory_mapping,
&mut result,
);
result.unwrap();
assert_eq!(log.borrow().len(), 1);
assert_eq!(log.borrow()[0], "Program log: Gaggablaghblagh!");
{
let mut syscall_sol_log = SyscallLog {
compute_meter: ThisComputeMeter::new_ref(string.len() as u64),
logger: ThisLogger::new_ref(Some(log.clone())),
loader_id: &bpf_loader::id(),
};
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call(
0x100000000,
string.len() as u64,
0,
0,
0,
&memory_mapping,
&mut result,
);
result.unwrap();
}
let log: Vec<String> = match Rc::try_unwrap(log) {
Ok(log) => log.into(),
Err(_) => panic!("Unwrap failed"),
};
assert_eq!(log.len(), 1);
assert_eq!(log[0], "Program log: Gaggablaghblagh!");
let mut syscall_sol_log = SyscallLog {
compute_meter: ThisComputeMeter::new_ref(string.len() as u64 * 3),
logger: ThisLogger::new_ref(None),
loader_id: &bpf_loader::id(),
};
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call(
0x100000001, // AccessViolation
@@ -2886,14 +2888,9 @@ mod tests {
&mut result,
);
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter {
remaining: (string.len() as u64 * 2) - 1,
}));
let logger: Rc<RefCell<dyn Logger>> = Rc::new(RefCell::new(MockLogger { log }));
let mut syscall_sol_log = SyscallLog {
compute_meter,
logger,
compute_meter: ThisComputeMeter::new_ref((string.len() as u64 * 2) - 1),
logger: ThisLogger::new_ref(None),
loader_id: &bpf_loader::id(),
};
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
@@ -2927,45 +2924,33 @@ mod tests {
#[test]
fn test_syscall_sol_log_u64() {
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter {
remaining: std::u64::MAX,
}));
let log = Rc::new(RefCell::new(vec![]));
let logger: Rc<RefCell<dyn Logger>> =
Rc::new(RefCell::new(MockLogger { log: log.clone() }));
let mut syscall_sol_log_u64 = SyscallLogU64 {
cost: 0,
compute_meter,
logger,
let log = Rc::new(LogCollector::default());
{
let mut syscall_sol_log_u64 = SyscallLogU64 {
cost: 0,
compute_meter: ThisComputeMeter::new_ref(std::u64::MAX),
logger: ThisLogger::new_ref(Some(log.clone())),
};
let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>(vec![], &config).unwrap();
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log_u64.call(1, 2, 3, 4, 5, &memory_mapping, &mut result);
result.unwrap();
}
let log: Vec<String> = match Rc::try_unwrap(log) {
Ok(log) => log.into(),
Err(_) => panic!("Unwrap failed"),
};
let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>(vec![], &config).unwrap();
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log_u64.call(1, 2, 3, 4, 5, &memory_mapping, &mut result);
result.unwrap();
assert_eq!(log.borrow().len(), 1);
assert_eq!(log.borrow()[0], "Program log: 0x1, 0x2, 0x3, 0x4, 0x5");
assert_eq!(log.len(), 1);
assert_eq!(log[0], "Program log: 0x1, 0x2, 0x3, 0x4, 0x5");
}
#[test]
fn test_syscall_sol_pubkey() {
let pubkey = Pubkey::from_str("MoqiU1vryuCGQSxFKA1SZ316JdLEFFhoAu6cKUNk7dN").unwrap();
let addr = &pubkey.as_ref()[0] as *const _ as u64;
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter { remaining: 2 }));
let log = Rc::new(RefCell::new(vec![]));
let logger: Rc<RefCell<dyn Logger>> =
Rc::new(RefCell::new(MockLogger { log: log.clone() }));
let mut syscall_sol_pubkey = SyscallLogPubkey {
cost: 1,
compute_meter,
logger,
loader_id: &bpf_loader::id(),
};
let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>(
vec![
@@ -2981,15 +2966,36 @@ mod tests {
&config,
)
.unwrap();
let log = Rc::new(LogCollector::default());
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_pubkey.call(0x100000000, 0, 0, 0, 0, &memory_mapping, &mut result);
result.unwrap();
assert_eq!(log.borrow().len(), 1);
{
let mut syscall_sol_pubkey = SyscallLogPubkey {
cost: 1,
compute_meter: ThisComputeMeter::new_ref(1),
logger: ThisLogger::new_ref(Some(log.clone())),
loader_id: &bpf_loader::id(),
};
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_pubkey.call(0x100000000, 0, 0, 0, 0, &memory_mapping, &mut result);
result.unwrap();
}
let log: Vec<String> = match Rc::try_unwrap(log) {
Ok(log) => log.into(),
Err(_) => panic!("Unwrap failed"),
};
assert_eq!(log.len(), 1);
assert_eq!(
log.borrow()[0],
log[0],
"Program log: MoqiU1vryuCGQSxFKA1SZ316JdLEFFhoAu6cKUNk7dN"
);
let mut syscall_sol_pubkey = SyscallLogPubkey {
cost: 1,
compute_meter: ThisComputeMeter::new_ref(1),
logger: ThisLogger::new_ref(None),
loader_id: &bpf_loader::id(),
};
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_pubkey.call(
0x100000001, // AccessViolation
@@ -3191,10 +3197,7 @@ mod tests {
&config,
)
.unwrap();
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter {
remaining: (bytes1.len() + bytes2.len()) as u64,
}));
let compute_meter = ThisComputeMeter::new_ref((bytes1.len() + bytes2.len()) as u64);
let mut syscall = SyscallSha256 {
sha256_base_cost: 0,
sha256_byte_cost: 2,
@@ -3281,11 +3284,15 @@ mod tests {
leader_schedule_epoch: 4,
unix_timestamp: 5,
};
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_clock).unwrap();
let sysvars = &[(sysvar::clock::id(), data)];
invoke_context.sysvars = sysvars;
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&[],
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
let mut syscall = SyscallGetClockSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
@@ -3325,11 +3332,15 @@ mod tests {
first_normal_epoch: 3,
first_normal_slot: 4,
};
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
let sysvars = &[(sysvar::epoch_schedule::id(), data)];
invoke_context.sysvars = sysvars;
let sysvars = [(sysvar::epoch_schedule::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&[],
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
let mut syscall = SyscallGetEpochScheduleSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
@@ -3376,11 +3387,15 @@ mod tests {
lamports_per_signature: 1,
},
};
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_fees).unwrap();
let sysvars = &[(sysvar::fees::id(), data)];
invoke_context.sysvars = sysvars;
let sysvars = [(sysvar::fees::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&[],
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
let mut syscall = SyscallGetFeesSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
@@ -3418,11 +3433,15 @@ mod tests {
exemption_threshold: 2.0,
burn_percent: 3,
};
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_rent).unwrap();
let sysvars = &[(sysvar::rent::id(), data)];
invoke_context.sysvars = sysvars;
let sysvars = [(sysvar::rent::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&[],
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
let mut syscall = SyscallGetRentSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
@@ -3530,11 +3549,9 @@ mod tests {
program_id: &Pubkey,
remaining: u64,
) -> Result<Pubkey, EbpfError<BpfError>> {
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter { remaining }));
let mut syscall = SyscallCreateProgramAddress {
cost: 1,
compute_meter: compute_meter.clone(),
compute_meter: ThisComputeMeter::new_ref(remaining),
loader_id: &bpf_loader::id(),
};
let (address, _) = call_program_address_common(seeds, program_id, &mut syscall)?;
@@ -3546,11 +3563,9 @@ mod tests {
program_id: &Pubkey,
remaining: u64,
) -> Result<(Pubkey, u8), EbpfError<BpfError>> {
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
Rc::new(RefCell::new(MockComputeMeter { remaining }));
let mut syscall = SyscallTryFindProgramAddress {
cost: 1,
compute_meter: compute_meter.clone(),
compute_meter: ThisComputeMeter::new_ref(remaining),
loader_id: &bpf_loader::id(),
};
call_program_address_common(seeds, program_id, &mut syscall)

View File

@@ -18,6 +18,7 @@ solana-sdk = { path = "../../sdk", version = "=1.9.0" }
[dev-dependencies]
solana-logger = { path = "../../logger", version = "=1.9.0" }
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.0" }
[lib]
crate-type = ["lib"]

View File

@@ -138,28 +138,25 @@ mod tests {
use crate::{config_instruction, get_config_data, id, ConfigKeys, ConfigState};
use bincode::serialized_size;
use serde_derive::{Deserialize, Serialize};
use solana_program_runtime::invoke_context::mock_process_instruction;
use solana_sdk::{
account::{Account, AccountSharedData},
keyed_account::create_keyed_accounts_unified,
process_instruction::MockInvokeContext,
account::AccountSharedData,
pubkey::Pubkey,
signature::{Keypair, Signer},
system_instruction::SystemInstruction,
};
use std::cell::RefCell;
use std::{cell::RefCell, rc::Rc};
fn process_instruction(
owner: &Pubkey,
instruction_data: &[u8],
keyed_accounts: &[(bool, bool, &Pubkey, &RefCell<AccountSharedData>)],
keyed_accounts: &[(bool, bool, Pubkey, Rc<RefCell<AccountSharedData>>)],
) -> Result<(), InstructionError> {
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
let mut keyed_accounts = keyed_accounts.to_vec();
keyed_accounts.insert(0, (false, false, owner, &processor_account));
super::process_instruction(
1,
mock_process_instruction(
&id(),
Vec::new(),
instruction_data,
&mut MockInvokeContext::new(owner, create_keyed_accounts_unified(&keyed_accounts)),
keyed_accounts,
super::process_instruction,
)
}
@@ -187,8 +184,10 @@ mod tests {
}
}
fn create_config_account(keys: Vec<(Pubkey, bool)>) -> (Keypair, RefCell<AccountSharedData>) {
let from_pubkey = solana_sdk::pubkey::new_rand();
fn create_config_account(
keys: Vec<(Pubkey, bool)>,
) -> (Keypair, Rc<RefCell<AccountSharedData>>) {
let from_pubkey = Pubkey::new_unique();
let config_keypair = Keypair::new();
let config_pubkey = config_keypair.pubkey();
@@ -204,14 +203,10 @@ mod tests {
} => space,
_ => panic!("Not a CreateAccount system instruction"),
};
let config_account = RefCell::new(AccountSharedData::from(Account {
data: vec![0; space as usize],
owner: id(),
..Account::default()
}));
let keyed_accounts = [(true, false, &config_pubkey, &config_account)];
let config_account = AccountSharedData::new_ref(0, space as usize, &id());
let keyed_accounts = [(true, false, config_pubkey, config_account.clone())];
assert_eq!(
process_instruction(&id(), &instructions[1].data, &keyed_accounts),
process_instruction(&instructions[1].data, &keyed_accounts),
Ok(())
);
@@ -237,9 +232,9 @@ mod tests {
let my_config = MyConfig::new(42);
let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config);
let keyed_accounts = [(true, false, &config_pubkey, &config_account)];
let keyed_accounts = [(true, false, config_pubkey, config_account.clone())];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Ok(())
);
assert_eq!(
@@ -258,9 +253,9 @@ mod tests {
let mut instruction = config_instruction::store(&config_pubkey, true, keys, &my_config);
instruction.data = vec![0; 123]; // <-- Replace data with a vector that's too large
let keyed_accounts = [(true, false, &config_pubkey, &config_account)];
let keyed_accounts = [(true, false, config_pubkey, config_account)];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::InvalidInstructionData)
);
}
@@ -275,9 +270,9 @@ mod tests {
let mut instruction = config_instruction::store(&config_pubkey, true, vec![], &my_config);
instruction.accounts[0].is_signer = false; // <----- not a signer
let keyed_accounts = [(false, false, &config_pubkey, &config_account)];
let keyed_accounts = [(false, false, config_pubkey, config_account)];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::MissingRequiredSignature)
);
}
@@ -285,9 +280,9 @@ mod tests {
#[test]
fn test_process_store_with_additional_signers() {
solana_logger::setup();
let pubkey = solana_sdk::pubkey::new_rand();
let signer0_pubkey = solana_sdk::pubkey::new_rand();
let signer1_pubkey = solana_sdk::pubkey::new_rand();
let pubkey = Pubkey::new_unique();
let signer0_pubkey = Pubkey::new_unique();
let signer1_pubkey = Pubkey::new_unique();
let keys = vec![
(pubkey, false),
(signer0_pubkey, true),
@@ -298,15 +293,15 @@ mod tests {
let my_config = MyConfig::new(42);
let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config);
let signer0_account = RefCell::new(AccountSharedData::default());
let signer1_account = RefCell::new(AccountSharedData::default());
let signer0_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let signer1_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let keyed_accounts = [
(true, false, &config_pubkey, &config_account),
(true, false, &signer0_pubkey, &signer0_account),
(true, false, &signer1_pubkey, &signer1_account),
(true, false, config_pubkey, config_account.clone()),
(true, false, signer0_pubkey, signer0_account),
(true, false, signer1_pubkey, signer1_account),
];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Ok(())
);
let meta_data: ConfigKeys = deserialize(config_account.borrow().data()).unwrap();
@@ -320,21 +315,18 @@ mod tests {
#[test]
fn test_process_store_without_config_signer() {
solana_logger::setup();
let pubkey = solana_sdk::pubkey::new_rand();
let signer0_pubkey = solana_sdk::pubkey::new_rand();
let pubkey = Pubkey::new_unique();
let signer0_pubkey = Pubkey::new_unique();
let keys = vec![(pubkey, false), (signer0_pubkey, true)];
let (config_keypair, _) = create_config_account(keys.clone());
let config_pubkey = config_keypair.pubkey();
let my_config = MyConfig::new(42);
let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config);
let signer0_account = RefCell::new(AccountSharedData::from(Account {
owner: id(),
..Account::default()
}));
let keyed_accounts = [(true, false, &signer0_pubkey, &signer0_account)];
let signer0_account = AccountSharedData::new_ref(0, 0, &id());
let keyed_accounts = [(true, false, signer0_pubkey, signer0_account)];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::InvalidAccountData)
);
}
@@ -342,10 +334,10 @@ mod tests {
#[test]
fn test_process_store_with_bad_additional_signer() {
solana_logger::setup();
let signer0_pubkey = solana_sdk::pubkey::new_rand();
let signer1_pubkey = solana_sdk::pubkey::new_rand();
let signer0_account = RefCell::new(AccountSharedData::default());
let signer1_account = RefCell::new(AccountSharedData::default());
let signer0_pubkey = Pubkey::new_unique();
let signer1_pubkey = Pubkey::new_unique();
let signer0_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let signer1_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let keys = vec![(signer0_pubkey, true)];
let (config_keypair, config_account) = create_config_account(keys.clone());
let config_pubkey = config_keypair.pubkey();
@@ -355,18 +347,18 @@ mod tests {
// Config-data pubkey doesn't match signer
let mut keyed_accounts = [
(true, false, &config_pubkey, &config_account),
(true, false, &signer1_pubkey, &signer1_account),
(true, false, config_pubkey, config_account),
(true, false, signer1_pubkey, signer1_account),
];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::MissingRequiredSignature)
);
// Config-data pubkey not a signer
keyed_accounts[1] = (false, false, &signer0_pubkey, &signer0_account);
keyed_accounts[1] = (false, false, signer0_pubkey, signer0_account);
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::MissingRequiredSignature)
);
}
@@ -374,13 +366,13 @@ mod tests {
#[test]
fn test_config_updates() {
solana_logger::setup();
let pubkey = solana_sdk::pubkey::new_rand();
let signer0_pubkey = solana_sdk::pubkey::new_rand();
let signer1_pubkey = solana_sdk::pubkey::new_rand();
let signer2_pubkey = solana_sdk::pubkey::new_rand();
let signer0_account = RefCell::new(AccountSharedData::default());
let signer1_account = RefCell::new(AccountSharedData::default());
let signer2_account = RefCell::new(AccountSharedData::default());
let pubkey = Pubkey::new_unique();
let signer0_pubkey = Pubkey::new_unique();
let signer1_pubkey = Pubkey::new_unique();
let signer2_pubkey = Pubkey::new_unique();
let signer0_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let signer1_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let signer2_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let keys = vec![
(pubkey, false),
(signer0_pubkey, true),
@@ -392,12 +384,12 @@ mod tests {
let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config);
let mut keyed_accounts = [
(true, false, &config_pubkey, &config_account),
(true, false, &signer0_pubkey, &signer0_account),
(true, false, &signer1_pubkey, &signer1_account),
(true, false, config_pubkey, config_account.clone()),
(true, false, signer0_pubkey, signer0_account),
(true, false, signer1_pubkey, signer1_account),
];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Ok(())
);
@@ -407,7 +399,7 @@ mod tests {
config_instruction::store(&config_pubkey, false, keys.clone(), &new_config);
keyed_accounts[0].0 = false;
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Ok(())
);
let meta_data: ConfigKeys = deserialize(config_account.borrow().data()).unwrap();
@@ -423,7 +415,7 @@ mod tests {
let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config);
keyed_accounts[2].0 = false;
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::MissingRequiredSignature)
);
@@ -434,9 +426,9 @@ mod tests {
(signer2_pubkey, true),
];
let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config);
keyed_accounts[2] = (true, false, &signer2_pubkey, &signer2_account);
keyed_accounts[2] = (true, false, signer2_pubkey, signer2_account);
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::MissingRequiredSignature)
);
}
@@ -446,7 +438,7 @@ mod tests {
solana_logger::setup();
let config_address = Pubkey::new_unique();
let signer0_pubkey = Pubkey::new_unique();
let signer0_account = RefCell::new(AccountSharedData::default());
let signer0_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let keys = vec![
(config_address, false),
(signer0_pubkey, true),
@@ -459,12 +451,12 @@ mod tests {
// Attempt initialization with duplicate signer inputs
let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config);
let keyed_accounts = [
(true, false, &config_pubkey, &config_account),
(true, false, &signer0_pubkey, &signer0_account),
(true, false, &signer0_pubkey, &signer0_account),
(true, false, config_pubkey, config_account),
(true, false, signer0_pubkey, signer0_account.clone()),
(true, false, signer0_pubkey, signer0_account),
];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::InvalidArgument),
);
}
@@ -475,8 +467,8 @@ mod tests {
let config_address = Pubkey::new_unique();
let signer0_pubkey = Pubkey::new_unique();
let signer1_pubkey = Pubkey::new_unique();
let signer0_account = RefCell::new(AccountSharedData::default());
let signer1_account = RefCell::new(AccountSharedData::default());
let signer0_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let signer1_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let keys = vec![
(config_address, false),
(signer0_pubkey, true),
@@ -488,12 +480,12 @@ mod tests {
let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config);
let mut keyed_accounts = [
(true, false, &config_pubkey, &config_account),
(true, false, &signer0_pubkey, &signer0_account),
(true, false, &signer1_pubkey, &signer1_account),
(true, false, config_pubkey, config_account),
(true, false, signer0_pubkey, signer0_account),
(true, false, signer1_pubkey, signer1_account),
];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Ok(()),
);
@@ -505,9 +497,9 @@ mod tests {
(signer0_pubkey, true),
];
let instruction = config_instruction::store(&config_pubkey, false, dupe_keys, &new_config);
keyed_accounts[2] = keyed_accounts[1];
keyed_accounts[2] = keyed_accounts[1].clone();
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::InvalidArgument),
);
}
@@ -515,9 +507,9 @@ mod tests {
#[test]
fn test_config_updates_requiring_config() {
solana_logger::setup();
let pubkey = solana_sdk::pubkey::new_rand();
let signer0_pubkey = solana_sdk::pubkey::new_rand();
let signer0_account = RefCell::new(AccountSharedData::default());
let pubkey = Pubkey::new_unique();
let signer0_pubkey = Pubkey::new_unique();
let signer0_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let keys = vec![
(pubkey, false),
(signer0_pubkey, true),
@@ -535,11 +527,11 @@ mod tests {
let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config);
let keyed_accounts = [
(true, false, &config_pubkey, &config_account),
(true, false, &signer0_pubkey, &signer0_account),
(true, false, config_pubkey, config_account.clone()),
(true, false, signer0_pubkey, signer0_account),
];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Ok(())
);
@@ -548,7 +540,7 @@ mod tests {
let instruction =
config_instruction::store(&config_pubkey, true, keys.clone(), &new_config);
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Ok(())
);
let meta_data: ConfigKeys = deserialize(config_account.borrow().data()).unwrap();
@@ -563,32 +555,32 @@ mod tests {
let keys = vec![(pubkey, false), (config_keypair.pubkey(), true)];
let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config);
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts[0..1]),
process_instruction(&instruction.data, &keyed_accounts[0..1]),
Err(InstructionError::MissingRequiredSignature)
);
}
#[test]
fn test_config_initialize_no_panic() {
let from_pubkey = solana_sdk::pubkey::new_rand();
let config_pubkey = solana_sdk::pubkey::new_rand();
let from_pubkey = Pubkey::new_unique();
let config_pubkey = Pubkey::new_unique();
let (_, _config_account) = create_config_account(vec![]);
let instructions =
config_instruction::create_account::<MyConfig>(&from_pubkey, &config_pubkey, 1, vec![]);
assert_eq!(
process_instruction(&id(), &instructions[1].data, &[]),
process_instruction(&instructions[1].data, &[]),
Err(InstructionError::NotEnoughAccountKeys)
);
}
#[test]
fn test_config_bad_owner() {
let from_pubkey = solana_sdk::pubkey::new_rand();
let config_pubkey = solana_sdk::pubkey::new_rand();
let from_pubkey = Pubkey::new_unique();
let config_pubkey = Pubkey::new_unique();
let new_config = MyConfig::new(84);
let signer0_pubkey = solana_sdk::pubkey::new_rand();
let signer0_account = RefCell::new(AccountSharedData::default());
let config_account = RefCell::new(AccountSharedData::default());
let signer0_pubkey = Pubkey::new_unique();
let signer0_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let config_account = AccountSharedData::new_ref(0, 0, &Pubkey::new_unique());
let (_, _config_account) = create_config_account(vec![]);
let keys = vec![
(from_pubkey, false),
@@ -598,11 +590,11 @@ mod tests {
let instruction = config_instruction::store(&config_pubkey, true, keys, &new_config);
let keyed_accounts = [
(true, false, &config_pubkey, &config_account),
(true, false, &signer0_pubkey, &signer0_account),
(true, false, config_pubkey, config_account),
(true, false, signer0_pubkey, signer0_account),
];
assert_eq!(
process_instruction(&id(), &instruction.data, &keyed_accounts),
process_instruction(&instruction.data, &keyed_accounts),
Err(InstructionError::InvalidAccountOwner)
);
}

View File

@@ -20,6 +20,7 @@ solana-frozen-abi = { path = "../../frozen-abi", version = "=1.9.0" }
solana-frozen-abi-macro = { path = "../../frozen-abi/macro", version = "=1.9.0" }
solana-metrics = { path = "../../metrics", version = "=1.9.0" }
solana-sdk = { path = "../../sdk", version = "=1.9.0" }
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.0" }
solana-vote-program = { path = "../vote", version = "=1.9.0" }
solana-config-program = { path = "../config", version = "=1.9.0" }
thiserror = "1.0"

View File

@@ -1,11 +1,12 @@
use {
crate::{config, stake_state::StakeAccount},
log::*,
solana_program_runtime::invoke_context::get_sysvar,
solana_sdk::{
feature_set,
instruction::InstructionError,
keyed_account::{from_keyed_account, get_signers, keyed_account_at_index},
process_instruction::{get_sysvar, InvokeContext},
process_instruction::InvokeContext,
program_utils::limited_deserialize,
stake::{
instruction::StakeInstruction,
@@ -326,11 +327,13 @@ mod tests {
use super::*;
use crate::stake_state::{Meta, StakeState};
use bincode::serialize;
use solana_program_runtime::invoke_context::{
mock_process_instruction, prepare_mock_invoke_context, ThisInvokeContext,
};
use solana_sdk::{
account::{self, Account, AccountSharedData, WritableAccount},
account::{self, AccountSharedData},
feature_set::FeatureSet,
instruction::{AccountMeta, Instruction},
keyed_account::create_keyed_accounts_unified,
process_instruction::MockInvokeContext,
pubkey::Pubkey,
rent::Rent,
stake::{
@@ -340,17 +343,14 @@ mod tests {
},
sysvar::{stake_history::StakeHistory, Sysvar},
};
use std::{cell::RefCell, str::FromStr};
use std::{cell::RefCell, rc::Rc, str::FromStr, sync::Arc};
fn create_default_account() -> RefCell<AccountSharedData> {
RefCell::new(AccountSharedData::default())
fn create_default_account() -> Rc<RefCell<AccountSharedData>> {
AccountSharedData::new_ref(0, 0, &Pubkey::new_unique())
}
fn create_default_stake_account() -> RefCell<AccountSharedData> {
RefCell::new(AccountSharedData::from(Account {
owner: id(),
..Account::default()
}))
fn create_default_stake_account() -> Rc<RefCell<AccountSharedData>> {
AccountSharedData::new_ref(0, 0, &id())
}
fn invalid_stake_state_pubkey() -> Pubkey {
@@ -370,91 +370,73 @@ mod tests {
}
fn process_instruction(
owner: &Pubkey,
instruction_data: &[u8],
keyed_accounts: &[(bool, bool, &Pubkey, &RefCell<AccountSharedData>)],
keyed_accounts: &[(bool, bool, Pubkey, Rc<RefCell<AccountSharedData>>)],
) -> Result<(), InstructionError> {
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
let mut keyed_accounts = keyed_accounts.to_vec();
keyed_accounts.insert(0, (false, false, owner, &processor_account));
super::process_instruction(
1,
mock_process_instruction(
&id(),
Vec::new(),
instruction_data,
&mut MockInvokeContext::new(owner, create_keyed_accounts_unified(&keyed_accounts)),
keyed_accounts,
super::process_instruction,
)
}
fn process_instruction_as_one_arg(instruction: &Instruction) -> Result<(), InstructionError> {
let processor_account = RefCell::new(AccountSharedData::from(Account {
owner: solana_sdk::native_loader::id(),
..Account::default()
}));
let accounts: Vec<_> = instruction
let accounts = instruction.accounts.iter().map(|meta| {
Rc::new(RefCell::new(if sysvar::clock::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&sysvar::clock::Clock::default())
} else if sysvar::rewards::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&sysvar::rewards::Rewards::new(0.0))
} else if sysvar::stake_history::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&StakeHistory::default())
} else if stake_config::check_id(&meta.pubkey) {
config::create_account(0, &stake_config::Config::default())
} else if sysvar::rent::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&Rent::default())
} else if meta.pubkey == invalid_stake_state_pubkey() {
AccountSharedData::new(0, 0, &id())
} else if meta.pubkey == invalid_vote_state_pubkey() {
AccountSharedData::new(0, 0, &solana_vote_program::id())
} else if meta.pubkey == spoofed_stake_state_pubkey() {
AccountSharedData::new(0, 0, &spoofed_stake_program_id())
} else {
AccountSharedData::new(0, 0, &id())
}))
});
let keyed_accounts: Vec<_> = instruction
.accounts
.iter()
.map(|meta| {
RefCell::new(if sysvar::clock::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&sysvar::clock::Clock::default())
} else if sysvar::rewards::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&sysvar::rewards::Rewards::new(
0.0,
))
} else if sysvar::stake_history::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&StakeHistory::default())
} else if stake_config::check_id(&meta.pubkey) {
config::create_account(0, &stake_config::Config::default())
} else if sysvar::rent::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&Rent::default())
} else if meta.pubkey == invalid_stake_state_pubkey() {
AccountSharedData::from(Account {
owner: id(),
..Account::default()
})
} else if meta.pubkey == invalid_vote_state_pubkey() {
AccountSharedData::from(Account {
owner: solana_vote_program::id(),
..Account::default()
})
} else if meta.pubkey == spoofed_stake_state_pubkey() {
AccountSharedData::from(Account {
owner: spoofed_stake_program_id(),
..Account::default()
})
} else {
AccountSharedData::from(Account {
owner: id(),
..Account::default()
})
})
})
.zip(accounts)
.map(|(meta, account)| (meta.is_signer, meta.is_writable, meta.pubkey, account))
.collect();
{
let mut keyed_accounts: Vec<_> = instruction
.accounts
.iter()
.zip(accounts.iter())
.map(|(meta, account)| (meta.is_signer, false, &meta.pubkey, account))
.collect();
let processor_id = id();
keyed_accounts.insert(0, (false, false, &processor_id, &processor_account));
let mut invoke_context = MockInvokeContext::new(
&processor_id,
create_keyed_accounts_unified(&keyed_accounts),
);
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
let sysvars = &[(sysvar::clock::id(), data)];
invoke_context.sysvars = sysvars;
super::process_instruction(1, &instruction.data, &mut invoke_context)
}
let mut preparation = prepare_mock_invoke_context(&[], &instruction.data, &keyed_accounts);
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
let program_indices = vec![preparation.accounts.len()];
preparation.accounts.push((id(), processor_account));
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&preparation.accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context.push(
&preparation.message,
&preparation.message.instructions[0],
&program_indices,
Some(&preparation.account_indices),
)?;
super::process_instruction(1, &instruction.data, &mut invoke_context)
}
#[test]
fn test_stake_process_instruction() {
assert_eq!(
process_instruction_as_one_arg(&instruction::initialize(
&Pubkey::default(),
&Pubkey::new_unique(),
&Authorized::default(),
&Lockup::default()
)),
@@ -462,9 +444,9 @@ mod tests {
);
assert_eq!(
process_instruction_as_one_arg(&instruction::authorize(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
StakeAuthorize::Staker,
None,
)),
@@ -473,8 +455,8 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(
&instruction::split(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
100,
&invalid_stake_state_pubkey(),
)[2]
@@ -484,9 +466,9 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(
&instruction::merge(
&Pubkey::default(),
&Pubkey::new_unique(),
&invalid_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::new_unique(),
)[0]
),
Err(InstructionError::InvalidAccountData),
@@ -494,11 +476,11 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(
&instruction::split_with_seed(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
100,
&invalid_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::new_unique(),
"seed"
)[1]
),
@@ -506,17 +488,17 @@ mod tests {
);
assert_eq!(
process_instruction_as_one_arg(&instruction::delegate_stake(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
&invalid_vote_state_pubkey(),
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction_as_one_arg(&instruction::withdraw(
&Pubkey::default(),
&Pubkey::default(),
&solana_sdk::pubkey::new_rand(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
100,
None,
)),
@@ -524,16 +506,16 @@ mod tests {
);
assert_eq!(
process_instruction_as_one_arg(&instruction::deactivate_stake(
&Pubkey::default(),
&Pubkey::default()
&Pubkey::new_unique(),
&Pubkey::new_unique()
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction_as_one_arg(&instruction::set_lockup(
&Pubkey::default(),
&Pubkey::new_unique(),
&LockupArgs::default(),
&Pubkey::default()
&Pubkey::new_unique()
)),
Err(InstructionError::InvalidAccountData),
);
@@ -552,8 +534,8 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(&instruction::authorize(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
StakeAuthorize::Staker,
None,
)),
@@ -563,9 +545,9 @@ mod tests {
process_instruction_as_one_arg(
&instruction::split(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::new_unique(),
100,
&Pubkey::default(),
&Pubkey::new_unique(),
)[2]
),
Err(InstructionError::InvalidAccountOwner),
@@ -573,8 +555,8 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(
&instruction::split(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
100,
&spoofed_stake_state_pubkey(),
)[2]
@@ -585,8 +567,8 @@ mod tests {
process_instruction_as_one_arg(
&instruction::merge(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
)[0]
),
Err(InstructionError::InvalidAccountOwner),
@@ -594,9 +576,9 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(
&instruction::merge(
&Pubkey::default(),
&Pubkey::new_unique(),
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::new_unique(),
)[0]
),
Err(InstructionError::IncorrectProgramId),
@@ -605,10 +587,10 @@ mod tests {
process_instruction_as_one_arg(
&instruction::split_with_seed(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::new_unique(),
100,
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
"seed"
)[1]
),
@@ -617,16 +599,16 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(&instruction::delegate_stake(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
)),
Err(InstructionError::InvalidAccountOwner),
);
assert_eq!(
process_instruction_as_one_arg(&instruction::withdraw(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&solana_sdk::pubkey::new_rand(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
100,
None,
)),
@@ -635,7 +617,7 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(&instruction::deactivate_stake(
&spoofed_stake_state_pubkey(),
&Pubkey::default()
&Pubkey::new_unique()
)),
Err(InstructionError::InvalidAccountOwner),
);
@@ -643,7 +625,7 @@ mod tests {
process_instruction_as_one_arg(&instruction::set_lockup(
&spoofed_stake_state_pubkey(),
&LockupArgs::default(),
&Pubkey::default()
&Pubkey::new_unique()
)),
Err(InstructionError::InvalidAccountOwner),
);
@@ -656,7 +638,6 @@ mod tests {
// gets the "is_empty()" check
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Initialize(
Authorized::default(),
Lockup::default()
@@ -668,12 +649,11 @@ mod tests {
);
// no account for rent
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let keyed_accounts = [(false, false, &stake_address, &stake_account)];
let keyed_accounts = [(false, false, stake_address, stake_account)];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Initialize(
Authorized::default(),
Lockup::default()
@@ -685,17 +665,16 @@ mod tests {
);
// rent fails to deserialize
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let rent_address = sysvar::rent::id();
let rent_account = create_default_account();
let keyed_accounts = [
(false, false, &stake_address, &stake_account),
(false, false, &rent_address, &rent_account),
(false, false, stake_address, stake_account),
(false, false, rent_address, rent_account),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Initialize(
Authorized::default(),
Lockup::default()
@@ -707,19 +686,18 @@ mod tests {
);
// fails to deserialize stake state
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let rent_address = sysvar::rent::id();
let rent_account = RefCell::new(account::create_account_shared_data_for_test(
let rent_account = Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&Rent::default(),
));
)));
let keyed_accounts = [
(false, false, &stake_address, &stake_account),
(false, false, &rent_address, &rent_account),
(false, false, stake_address, stake_account),
(false, false, rent_address, rent_account),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Initialize(
Authorized::default(),
Lockup::default()
@@ -731,12 +709,11 @@ mod tests {
);
// gets the first check in delegate, wrong number of accounts
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let keyed_accounts = [(false, false, &stake_address, &stake_account)];
let keyed_accounts = [(false, false, stake_address, stake_account)];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::DelegateStake).unwrap(),
&keyed_accounts,
),
@@ -744,12 +721,11 @@ mod tests {
);
// gets the sub-check for number of args
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let keyed_accounts = [(false, false, &stake_address, &stake_account)];
let keyed_accounts = [(false, false, stake_address, stake_account)];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::DelegateStake).unwrap(),
&keyed_accounts,
),
@@ -757,34 +733,33 @@ mod tests {
);
// gets the check non-deserialize-able account in delegate_stake
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let vote_address = Pubkey::default();
let mut bad_vote_account = create_default_account();
bad_vote_account
.get_mut()
.set_owner(solana_vote_program::id());
let vote_address = Pubkey::new_unique();
let vote_account = AccountSharedData::new_ref(0, 0, &solana_vote_program::id());
let clock_address = sysvar::clock::id();
let clock_account = RefCell::new(account::create_account_shared_data_for_test(
let clock_account = Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&sysvar::clock::Clock::default(),
));
)));
let stake_history_address = sysvar::stake_history::id();
let stake_history_account = RefCell::new(account::create_account_shared_data_for_test(
&sysvar::stake_history::StakeHistory::default(),
));
let stake_history_account =
Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&sysvar::stake_history::StakeHistory::default(),
)));
let config_address = stake_config::id();
let config_account =
RefCell::new(config::create_account(0, &stake_config::Config::default()));
let config_account = Rc::new(RefCell::new(config::create_account(
0,
&stake_config::Config::default(),
)));
let keyed_accounts = [
(true, false, &stake_address, &stake_account),
(false, false, &vote_address, &bad_vote_account),
(false, false, &clock_address, &clock_account),
(false, false, &stake_history_address, &stake_history_account),
(false, false, &config_address, &config_account),
(true, false, stake_address, stake_account),
(false, false, vote_address, vote_account),
(false, false, clock_address, clock_account),
(false, false, stake_history_address, stake_history_account),
(false, false, config_address, config_account),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::DelegateStake).unwrap(),
&keyed_accounts,
),
@@ -792,27 +767,26 @@ mod tests {
);
// Tests 3rd keyed account is of correct type (Clock instead of rewards) in withdraw
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let vote_address = Pubkey::default();
let vote_address = Pubkey::new_unique();
let vote_account = create_default_account();
let rewards_address = sysvar::rewards::id();
let rewards_account = RefCell::new(account::create_account_shared_data_for_test(
let rewards_account = Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&sysvar::rewards::Rewards::new(0.0),
));
)));
let stake_history_address = sysvar::stake_history::id();
let stake_history_account = RefCell::new(account::create_account_shared_data_for_test(
&StakeHistory::default(),
let stake_history_account = Rc::new(RefCell::new(
account::create_account_shared_data_for_test(&StakeHistory::default()),
));
let keyed_accounts = [
(false, false, &stake_address, &stake_account),
(false, false, &vote_address, &vote_account),
(false, false, &rewards_address, &rewards_account),
(false, false, &stake_history_address, &stake_history_account),
(false, false, stake_address, stake_account),
(false, false, vote_address, vote_account),
(false, false, rewards_address, rewards_account),
(false, false, stake_history_address, stake_history_account),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Withdraw(42)).unwrap(),
&keyed_accounts,
),
@@ -820,12 +794,11 @@ mod tests {
);
// Tests correct number of accounts are provided in withdraw
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let keyed_accounts = [(false, false, &stake_address, &stake_account)];
let keyed_accounts = [(false, false, stake_address, stake_account)];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Withdraw(42)).unwrap(),
&keyed_accounts,
),
@@ -833,19 +806,18 @@ mod tests {
);
// Tests 2nd keyed account is of correct type (Clock instead of rewards) in deactivate
let stake_address = Pubkey::default();
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let rewards_address = sysvar::rewards::id();
let rewards_account = RefCell::new(account::create_account_shared_data_for_test(
let rewards_account = Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&sysvar::rewards::Rewards::new(0.0),
));
)));
let keyed_accounts = [
(false, false, &stake_address, &stake_account),
(false, false, &rewards_address, &rewards_account),
(false, false, stake_address, stake_account),
(false, false, rewards_address, rewards_account),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Deactivate).unwrap(),
&keyed_accounts,
),
@@ -854,11 +826,7 @@ mod tests {
// Tests correct number of accounts are provided in deactivate
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::Deactivate).unwrap(),
&[],
),
process_instruction(&serialize(&StakeInstruction::Deactivate).unwrap(), &[]),
Err(InstructionError::NotEnoughAccountKeys),
);
}
@@ -885,21 +853,20 @@ mod tests {
&id(),
);
let rent_address = sysvar::rent::id();
let rent_account = RefCell::new(account::create_account_shared_data_for_test(
let rent_account = Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&Rent::default(),
));
)));
let staker_account = create_default_account();
let withdrawer_account = create_default_account();
let keyed_accounts: [(bool, bool, &Pubkey, &RefCell<AccountSharedData>); 4] = [
(false, false, &stake_address, &stake_account),
(false, false, &rent_address, &rent_account),
(false, false, &staker, &staker_account),
(true, false, &withdrawer, &withdrawer_account),
let keyed_accounts = [
(false, false, stake_address, stake_account),
(false, false, rent_address, rent_account),
(false, false, staker, staker_account),
(true, false, withdrawer, withdrawer_account.clone()),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::InitializeChecked).unwrap(),
&keyed_accounts,
),
@@ -935,39 +902,39 @@ mod tests {
);
// Test AuthorizeChecked with authority signer
let stake_account = AccountSharedData::new_ref_data_with_space(
42,
&StakeState::Initialized(Meta::auto(&authorized_address)),
std::mem::size_of::<StakeState>(),
&id(),
)
.unwrap();
let stake_account = Rc::new(
AccountSharedData::new_ref_data_with_space(
42,
&StakeState::Initialized(Meta::auto(&authorized_address)),
std::mem::size_of::<StakeState>(),
&id(),
)
.unwrap(),
);
let clock_address = sysvar::clock::id();
let clock_account = RefCell::new(account::create_account_shared_data_for_test(
let clock_account = Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&Clock::default(),
));
)));
let authorized_account = create_default_account();
let new_authorized_account = create_default_account();
let mut keyed_accounts = [
(false, false, &stake_address, &stake_account),
(false, false, &clock_address, &clock_account),
(true, false, &authorized_address, &authorized_account),
(true, false, &staker, &new_authorized_account),
(false, false, stake_address, stake_account),
(false, false, clock_address, clock_account.clone()),
(true, false, authorized_address, authorized_account.clone()),
(true, false, staker, new_authorized_account.clone()),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::AuthorizeChecked(StakeAuthorize::Staker)).unwrap(),
&keyed_accounts,
),
Ok(()),
);
keyed_accounts[3] = (true, false, &withdrawer, &new_authorized_account);
keyed_accounts[3] = (true, false, withdrawer, new_authorized_account.clone());
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::AuthorizeChecked(
StakeAuthorize::Withdrawer
))
@@ -1013,22 +980,23 @@ mod tests {
);
// Test AuthorizeCheckedWithSeed with authority signer
let stake_account = AccountSharedData::new_ref_data_with_space(
42,
&StakeState::Initialized(Meta::auto(&address_with_seed)),
std::mem::size_of::<StakeState>(),
&id(),
)
.unwrap();
let stake_account = Rc::new(
AccountSharedData::new_ref_data_with_space(
42,
&StakeState::Initialized(Meta::auto(&address_with_seed)),
std::mem::size_of::<StakeState>(),
&id(),
)
.unwrap(),
);
let mut keyed_accounts = [
(false, false, &address_with_seed, &stake_account),
(true, false, &authorized_owner, &authorized_account),
(false, false, &clock_address, &clock_account),
(true, false, &staker, &new_authorized_account),
(false, false, address_with_seed, stake_account),
(true, false, authorized_owner, authorized_account),
(false, false, clock_address, clock_account),
(true, false, staker, new_authorized_account.clone()),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::AuthorizeCheckedWithSeed(
AuthorizeCheckedWithSeedArgs {
stake_authorize: StakeAuthorize::Staker,
@@ -1042,10 +1010,9 @@ mod tests {
Ok(()),
);
keyed_accounts[3] = (true, false, &withdrawer, &new_authorized_account);
keyed_accounts[3] = (true, false, withdrawer, new_authorized_account);
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&StakeInstruction::AuthorizeCheckedWithSeed(
AuthorizeCheckedWithSeedArgs {
stake_authorize: StakeAuthorize::Withdrawer,
@@ -1077,42 +1044,45 @@ mod tests {
);
// Test SetLockupChecked with lockup custodian signer
let stake_account = AccountSharedData::new_ref_data_with_space(
42,
&StakeState::Initialized(Meta::auto(&withdrawer)),
std::mem::size_of::<StakeState>(),
&id(),
)
.unwrap();
let stake_account = Rc::new(
AccountSharedData::new_ref_data_with_space(
42,
&StakeState::Initialized(Meta::auto(&withdrawer)),
std::mem::size_of::<StakeState>(),
&id(),
)
.unwrap(),
);
let custodian_account = create_default_account();
let processor_account = RefCell::new(AccountSharedData::from(Account {
owner: solana_sdk::native_loader::id(),
..Account::default()
}));
let keyed_accounts = [
(false, false, &id(), &processor_account),
(false, false, &stake_address, &stake_account),
(true, false, &withdrawer, &withdrawer_account),
(true, false, &custodian, &custodian_account),
(false, false, stake_address, stake_account),
(true, false, withdrawer, withdrawer_account),
(true, false, custodian, custodian_account),
];
let mut invoke_context =
MockInvokeContext::new(&id(), create_keyed_accounts_unified(&keyed_accounts));
let mut preparation = prepare_mock_invoke_context(&[], &instruction.data, &keyed_accounts);
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
let program_indices = vec![preparation.accounts.len()];
preparation.accounts.push((id(), processor_account));
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
let sysvars = &[(sysvar::clock::id(), data)];
invoke_context.sysvars = sysvars;
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = ThisInvokeContext::new_mock_with_sysvars_and_features(
&preparation.accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context
.push(
&preparation.message,
&preparation.message.instructions[0],
&program_indices,
Some(&preparation.account_indices),
)
.unwrap();
assert_eq!(
super::process_instruction(
1,
&serialize(&StakeInstruction::SetLockupChecked(LockupCheckedArgs {
unix_timestamp: None,
epoch: Some(1),
}))
.unwrap(),
&mut invoke_context,
),
super::process_instruction(1, &instruction.data, &mut invoke_context),
Ok(()),
);
}

View File

@@ -1373,11 +1373,11 @@ fn do_create_account(
mod tests {
use super::*;
use proptest::prelude::*;
use solana_program_runtime::invoke_context::ThisInvokeContext;
use solana_sdk::{
account::{AccountSharedData, WritableAccount},
clock::UnixTimestamp,
native_token,
process_instruction::MockInvokeContext,
pubkey::Pubkey,
system_program,
};
@@ -5069,13 +5069,13 @@ mod tests {
#[test]
fn test_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
let stake_lamports = 42;
let signers = vec![authorized_pubkey].into_iter().collect();
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
for state in &[
StakeState::Initialized(Meta::auto(&authorized_pubkey)),
@@ -5179,7 +5179,7 @@ mod tests {
#[test]
fn test_merge_self_fails() {
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let stake_address = Pubkey::new_unique();
let authority_pubkey = Pubkey::new_unique();
let signers = HashSet::from_iter(vec![authority_pubkey]);
@@ -5224,6 +5224,7 @@ mod tests {
#[test]
fn test_merge_incorrect_authorized_staker() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
@@ -5232,7 +5233,6 @@ mod tests {
let signers = vec![authorized_pubkey].into_iter().collect();
let wrong_signers = vec![wrong_authorized_pubkey].into_iter().collect();
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
for state in &[
StakeState::Initialized(Meta::auto(&authorized_pubkey)),
@@ -5293,12 +5293,12 @@ mod tests {
#[test]
fn test_merge_invalid_account_data() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
let stake_lamports = 42;
let signers = vec![authorized_pubkey].into_iter().collect();
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
for state in &[
StakeState::Uninitialized,
@@ -5343,6 +5343,7 @@ mod tests {
#[test]
fn test_merge_fake_stake_source() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let stake_pubkey = solana_sdk::pubkey::new_rand();
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
let authorized_pubkey = solana_sdk::pubkey::new_rand();
@@ -5368,7 +5369,6 @@ mod tests {
.expect("source_stake_account");
let source_stake_keyed_account =
KeyedAccount::new(&source_stake_pubkey, true, &source_stake_account);
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
assert_eq!(
stake_keyed_account.merge(
@@ -5385,6 +5385,7 @@ mod tests {
#[test]
fn test_merge_active_stake() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let base_lamports = 4242424242;
let stake_address = Pubkey::new_unique();
let source_address = Pubkey::new_unique();
@@ -5438,7 +5439,6 @@ mod tests {
let mut clock = Clock::default();
let mut stake_history = StakeHistory::default();
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
clock.epoch = 0;
let mut effective = base_lamports;
@@ -6007,6 +6007,7 @@ mod tests {
#[test]
fn test_things_can_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let good_stake = Stake {
credits_observed: 4242,
delegation: Delegation {
@@ -6016,7 +6017,6 @@ mod tests {
..Delegation::default()
},
};
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let identical = good_stake;
assert!(
@@ -6105,7 +6105,7 @@ mod tests {
#[test]
fn test_metas_can_merge_pre_v4() {
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
// Identical Metas can merge
assert!(MergeKind::metas_can_merge(
&invoke_context,
@@ -6191,7 +6191,7 @@ mod tests {
#[test]
fn test_metas_can_merge_v4() {
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
// Identical Metas can merge
assert!(MergeKind::metas_can_merge(
&invoke_context,
@@ -6337,6 +6337,7 @@ mod tests {
#[test]
fn test_merge_kind_get_if_mergeable() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let authority_pubkey = Pubkey::new_unique();
let initial_lamports = 4242424242;
let rent = Rent::default();
@@ -6357,7 +6358,6 @@ mod tests {
let stake_keyed_account = KeyedAccount::new(&authority_pubkey, true, &stake_account);
let mut clock = Clock::default();
let mut stake_history = StakeHistory::default();
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
// Uninitialized state fails
assert_eq!(
@@ -6569,6 +6569,7 @@ mod tests {
#[test]
fn test_merge_kind_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let lamports = 424242;
let meta = Meta {
rent_exempt_reserve: 42,
@@ -6584,7 +6585,6 @@ mod tests {
let inactive = MergeKind::Inactive(Meta::default(), lamports);
let activation_epoch = MergeKind::ActivationEpoch(meta, stake);
let fully_active = MergeKind::FullyActive(meta, stake);
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
assert_eq!(
inactive
@@ -6647,6 +6647,7 @@ mod tests {
#[test]
fn test_active_stake_merge() {
let invoke_context = ThisInvokeContext::new_mock(&[], &[]);
let delegation_a = 4_242_424_242u64;
let delegation_b = 6_200_000_000u64;
let credits_a = 124_521_000u64;
@@ -6670,8 +6671,6 @@ mod tests {
credits_observed: credits_a,
};
let invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
// activating stake merge, match credits observed
let activation_epoch_a = MergeKind::ActivationEpoch(meta, stake_a);
let activation_epoch_b = MergeKind::ActivationEpoch(meta, stake_b);

View File

@@ -23,6 +23,9 @@ solana-metrics = { path = "../../metrics", version = "=1.9.0" }
solana-sdk = { path = "../../sdk", version = "=1.9.0" }
thiserror = "1.0"
[dev-dependencies]
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.0" }
[build-dependencies]
rustc_version = "0.4"

View File

@@ -405,41 +405,37 @@ pub fn process_instruction(
mod tests {
use super::*;
use bincode::serialize;
use solana_program_runtime::invoke_context::mock_process_instruction;
use solana_sdk::{
account::{self, Account, AccountSharedData},
keyed_account::create_keyed_accounts_unified,
process_instruction::MockInvokeContext,
rent::Rent,
};
use std::cell::RefCell;
use std::str::FromStr;
use std::{cell::RefCell, rc::Rc};
fn create_default_account() -> RefCell<AccountSharedData> {
RefCell::new(AccountSharedData::default())
fn create_default_account() -> Rc<RefCell<AccountSharedData>> {
AccountSharedData::new_ref(0, 0, &Pubkey::new_unique())
}
fn process_instruction(
owner: &Pubkey,
instruction_data: &[u8],
keyed_accounts: &[(bool, bool, &Pubkey, &RefCell<AccountSharedData>)],
keyed_accounts: &[(bool, bool, Pubkey, Rc<RefCell<AccountSharedData>>)],
) -> Result<(), InstructionError> {
let processor_account = AccountSharedData::new_ref(0, 0, &solana_sdk::native_loader::id());
let mut keyed_accounts = keyed_accounts.to_vec();
keyed_accounts.insert(0, (false, false, owner, &processor_account));
super::process_instruction(
1,
mock_process_instruction(
&id(),
Vec::new(),
instruction_data,
&mut MockInvokeContext::new(owner, create_keyed_accounts_unified(&keyed_accounts)),
keyed_accounts,
super::process_instruction,
)
}
#[allow(clippy::same_item_push)]
fn process_instruction_as_one_arg(instruction: &Instruction) -> Result<(), InstructionError> {
let mut accounts: Vec<_> = instruction
.accounts
.iter()
.map(|meta| {
RefCell::new(if sysvar::clock::check_id(&meta.pubkey) {
Rc::new(RefCell::new(if sysvar::clock::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&Clock::default())
} else if sysvar::slot_hashes::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&SlotHashes::default())
@@ -455,22 +451,26 @@ mod tests {
owner: id(),
..Account::default()
})
})
}))
})
.collect();
#[allow(clippy::same_item_push)]
for _ in 0..instruction.accounts.len() {
accounts.push(RefCell::new(AccountSharedData::default()));
}
{
let keyed_accounts: Vec<_> = instruction
.accounts
.iter()
.zip(accounts.iter())
.map(|(meta, account)| (meta.is_signer, false, &meta.pubkey, account))
.collect();
process_instruction(&Pubkey::default(), &instruction.data, &keyed_accounts)
accounts.push(AccountSharedData::new_ref(0, 0, &Pubkey::new_unique()));
}
let keyed_accounts: Vec<_> = instruction
.accounts
.iter()
.zip(accounts.into_iter())
.map(|(meta, account)| (meta.is_signer, meta.is_writable, meta.pubkey, account))
.collect();
solana_program_runtime::invoke_context::mock_process_instruction(
&id(),
Vec::new(),
&instruction.data,
&keyed_accounts,
super::process_instruction,
)
}
fn invalid_vote_state_pubkey() -> Pubkey {
@@ -481,7 +481,7 @@ mod tests {
#[test]
fn test_vote_process_instruction_decode_bail() {
assert_eq!(
process_instruction(&Pubkey::default(), &[], &[]),
process_instruction(&[], &[]),
Err(InstructionError::NotEnoughAccountKeys),
);
}
@@ -491,7 +491,7 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(&vote(
&invalid_vote_state_pubkey(),
&Pubkey::default(),
&Pubkey::new_unique(),
Vote::default(),
)),
Err(InstructionError::InvalidAccountOwner),
@@ -502,8 +502,8 @@ mod tests {
fn test_vote_process_instruction() {
solana_logger::setup();
let instructions = create_account(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
&VoteInit::default(),
100,
);
@@ -513,16 +513,16 @@ mod tests {
);
assert_eq!(
process_instruction_as_one_arg(&vote(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
Vote::default(),
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction_as_one_arg(&vote_switch(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
Vote::default(),
Hash::default(),
)),
@@ -530,25 +530,25 @@ mod tests {
);
assert_eq!(
process_instruction_as_one_arg(&authorize(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
VoteAuthorize::Voter,
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction_as_one_arg(&update_validator_identity(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction_as_one_arg(&update_commission(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
0,
)),
Err(InstructionError::InvalidAccountData),
@@ -556,10 +556,10 @@ mod tests {
assert_eq!(
process_instruction_as_one_arg(&withdraw(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
0,
&Pubkey::default()
&Pubkey::new_unique()
)),
Err(InstructionError::InvalidAccountData),
);
@@ -624,21 +624,20 @@ mod tests {
// Test with new_authorized_pubkey signer
let vote_account = AccountSharedData::new_ref(100, VoteState::size_of(), &id());
let clock_address = sysvar::clock::id();
let clock_account = RefCell::new(account::create_account_shared_data_for_test(
let clock_account = Rc::new(RefCell::new(account::create_account_shared_data_for_test(
&Clock::default(),
));
)));
let default_authorized_pubkey = Pubkey::default();
let authorized_account = create_default_account();
let new_authorized_account = create_default_account();
let keyed_accounts: [(bool, bool, &Pubkey, &RefCell<AccountSharedData>); 4] = [
(false, false, &vote_pubkey, &vote_account),
(false, false, &clock_address, &clock_account),
(true, false, &default_authorized_pubkey, &authorized_account),
(true, false, &new_authorized_pubkey, &new_authorized_account),
let keyed_accounts = [
(false, false, vote_pubkey, vote_account),
(false, false, clock_address, clock_account),
(true, false, default_authorized_pubkey, authorized_account),
(true, false, new_authorized_pubkey, new_authorized_account),
];
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&VoteInstruction::AuthorizeChecked(VoteAuthorize::Voter)).unwrap(),
&keyed_accounts,
),
@@ -647,7 +646,6 @@ mod tests {
assert_eq!(
process_instruction(
&Pubkey::default(),
&serialize(&VoteInstruction::AuthorizeChecked(
VoteAuthorize::Withdrawer
))