Refactoring: Move KeyedAccounts to InvokeContext (#15410)
Collects all parametric occurrences and the construction of keyed_accounts and puts them into InvokeContext.
This commit is contained in:
committed by
GitHub
parent
015bc034a5
commit
9dfcb921cf
@ -76,7 +76,7 @@ fn bench_program_create_executable(bencher: &mut Bencher) {
|
||||
|
||||
bencher.iter(|| {
|
||||
let _ =
|
||||
Executable::<BpfError, ThisInstructionMeter>::from_elf(&elf, None, Config::default())
|
||||
<dyn Executable::<BpfError, ThisInstructionMeter>>::from_elf(&elf, None, Config::default())
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
@ -91,11 +91,11 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||
.unwrap();
|
||||
inner_iter.write_u64::<LittleEndian>(0).unwrap();
|
||||
let loader_id = bpf_loader::id();
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
let mut invoke_context = MockInvokeContext::new(vec![]);
|
||||
|
||||
let elf = load_elf("bench_alu").unwrap();
|
||||
let mut executable =
|
||||
Executable::<BpfError, ThisInstructionMeter>::from_elf(&elf, None, Config::default())
|
||||
<dyn Executable::<BpfError, ThisInstructionMeter>>::from_elf(&elf, None, Config::default())
|
||||
.unwrap();
|
||||
executable.set_syscall_registry(register_syscalls(&mut invoke_context).unwrap());
|
||||
executable.jit_compile().unwrap();
|
||||
@ -105,7 +105,6 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
&mut inner_iter,
|
||||
&[],
|
||||
&mut invoke_context,
|
||||
)
|
||||
.unwrap();
|
||||
@ -195,8 +194,6 @@ fn bench_program_execute_noop(bencher: &mut Bencher) {
|
||||
fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||
const BUDGET: u64 = 200_000;
|
||||
let loader_id = bpf_loader::id();
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
invoke_context.compute_meter.remaining = BUDGET;
|
||||
|
||||
let accounts = [RefCell::new(AccountSharedData::new(
|
||||
1,
|
||||
@ -211,18 +208,22 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||
.collect();
|
||||
let instruction_data = vec![0u8];
|
||||
|
||||
let mut invoke_context = MockInvokeContext::new(keyed_accounts);
|
||||
invoke_context.compute_meter.remaining = BUDGET;
|
||||
|
||||
// Serialize account data
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
|
||||
let mut serialized = serialize_parameters(
|
||||
&bpf_loader::id(),
|
||||
&solana_sdk::pubkey::new_rand(),
|
||||
&keyed_accounts,
|
||||
keyed_accounts,
|
||||
&instruction_data,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let elf = load_elf("tuner").unwrap();
|
||||
let mut executable =
|
||||
Executable::<BpfError, ThisInstructionMeter>::from_elf(&elf, None, Config::default())
|
||||
<dyn Executable::<BpfError, ThisInstructionMeter>>::from_elf(&elf, None, Config::default())
|
||||
.unwrap();
|
||||
executable.set_syscall_registry(register_syscalls(&mut invoke_context).unwrap());
|
||||
let compute_meter = invoke_context.get_compute_meter();
|
||||
@ -231,7 +232,6 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
&mut serialized,
|
||||
&[],
|
||||
&mut invoke_context,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -179,7 +179,7 @@ fn upgrade_bpf_program(
|
||||
fn run_program(
|
||||
name: &str,
|
||||
program_id: &Pubkey,
|
||||
parameter_accounts: &[KeyedAccount],
|
||||
parameter_accounts: Vec<KeyedAccount>,
|
||||
instruction_data: &[u8],
|
||||
) -> Result<u64, InstructionError> {
|
||||
let path = create_bpf_path(name);
|
||||
@ -188,14 +188,14 @@ fn run_program(
|
||||
let mut data = vec![];
|
||||
file.read_to_end(&mut data).unwrap();
|
||||
let loader_id = bpf_loader::id();
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
let parameter_bytes = serialize_parameters(
|
||||
&bpf_loader::id(),
|
||||
program_id,
|
||||
parameter_accounts,
|
||||
¶meter_accounts,
|
||||
&instruction_data,
|
||||
)
|
||||
.unwrap();
|
||||
let mut invoke_context = MockInvokeContext::new(parameter_accounts);
|
||||
let compute_meter = invoke_context.get_compute_meter();
|
||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
||||
|
||||
@ -213,20 +213,46 @@ fn run_program(
|
||||
let mut tracer = None;
|
||||
for i in 0..2 {
|
||||
let mut parameter_bytes = parameter_bytes.clone();
|
||||
let mut vm = create_vm(
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
&mut parameter_bytes,
|
||||
parameter_accounts,
|
||||
&mut invoke_context,
|
||||
)
|
||||
.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());
|
||||
{
|
||||
let mut vm = create_vm(
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
&mut parameter_bytes,
|
||||
&mut invoke_context,
|
||||
)
|
||||
.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 mut tracer_display = String::new();
|
||||
tracer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.write(&mut tracer_display, vm.get_program())
|
||||
.unwrap();
|
||||
println!("TRACE (interpreted): {}", tracer_display);
|
||||
let mut tracer_display = String::new();
|
||||
vm.get_tracer()
|
||||
.write(&mut tracer_display, vm.get_program())
|
||||
.unwrap();
|
||||
println!("TRACE (jit): {}", tracer_display);
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
tracer = Some(vm.get_tracer().clone());
|
||||
}
|
||||
}
|
||||
let parameter_accounts = invoke_context.get_keyed_accounts().unwrap();
|
||||
deserialize_parameters(
|
||||
&bpf_loader::id(),
|
||||
parameter_accounts,
|
||||
@ -234,30 +260,6 @@ fn run_program(
|
||||
true,
|
||||
)
|
||||
.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 mut tracer_display = String::new();
|
||||
tracer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.write(&mut tracer_display, vm.get_program())
|
||||
.unwrap();
|
||||
println!("TRACE (interpreted): {}", tracer_display);
|
||||
let mut tracer_display = String::new();
|
||||
vm.get_tracer()
|
||||
.write(&mut tracer_display, vm.get_program())
|
||||
.unwrap();
|
||||
println!("TRACE (jit): {}", tracer_display);
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
tracer = Some(vm.get_tracer().clone());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(instruction_count)
|
||||
@ -1263,7 +1265,7 @@ fn assert_instruction_count() {
|
||||
let key = solana_sdk::pubkey::new_rand();
|
||||
let mut account = RefCell::new(AccountSharedData::default());
|
||||
let parameter_accounts = vec![KeyedAccount::new(&key, false, &mut account)];
|
||||
let count = run_program(program.0, &program_id, ¶meter_accounts[..], &[]).unwrap();
|
||||
let count = run_program(program.0, &program_id, parameter_accounts, &[]).unwrap();
|
||||
let diff: i64 = count as i64 - program.1 as i64;
|
||||
println!(" {:30} {:8} {:6} {:+4}", program.0, program.1, count, diff);
|
||||
if count > program.1 {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -169,7 +169,6 @@ macro_rules! bind_feature_gated_syscall_context_object {
|
||||
pub fn bind_syscall_context_objects<'a>(
|
||||
loader_id: &'a Pubkey,
|
||||
vm: &mut EbpfVm<'a, BpfError, crate::ThisInstructionMeter>,
|
||||
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
||||
invoke_context: &'a mut dyn InvokeContext,
|
||||
heap: Vec<u8>,
|
||||
) -> Result<(), EbpfError<BpfError>> {
|
||||
@ -299,7 +298,6 @@ pub fn bind_syscall_context_objects<'a>(
|
||||
// Cross-program invocation syscalls
|
||||
vm.bind_syscall_context_object(
|
||||
Box::new(SyscallInvokeSignedC {
|
||||
callers_keyed_accounts,
|
||||
invoke_context: invoke_context.clone(),
|
||||
loader_id,
|
||||
}),
|
||||
@ -307,7 +305,6 @@ pub fn bind_syscall_context_objects<'a>(
|
||||
)?;
|
||||
vm.bind_syscall_context_object(
|
||||
Box::new(SyscallInvokeSignedRust {
|
||||
callers_keyed_accounts,
|
||||
invoke_context: invoke_context.clone(),
|
||||
loader_id,
|
||||
}),
|
||||
@ -1029,7 +1026,6 @@ type TranslatedAccounts<'a> = (
|
||||
trait SyscallInvokeSigned<'a> {
|
||||
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
|
||||
fn get_context(&self) -> Result<Ref<&'a mut dyn InvokeContext>, EbpfError<BpfError>>;
|
||||
fn get_callers_keyed_accounts(&self) -> &'a [KeyedAccount<'a>];
|
||||
fn translate_instruction(
|
||||
&self,
|
||||
addr: u64,
|
||||
@ -1055,7 +1051,6 @@ trait SyscallInvokeSigned<'a> {
|
||||
|
||||
/// Cross-program invocation called from Rust
|
||||
pub struct SyscallInvokeSignedRust<'a> {
|
||||
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
||||
loader_id: &'a Pubkey,
|
||||
}
|
||||
@ -1070,9 +1065,6 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
|
||||
.try_borrow()
|
||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
||||
}
|
||||
fn get_callers_keyed_accounts(&self) -> &'a [KeyedAccount<'a>] {
|
||||
self.callers_keyed_accounts
|
||||
}
|
||||
fn translate_instruction(
|
||||
&self,
|
||||
addr: u64,
|
||||
@ -1350,7 +1342,6 @@ struct SolSignerSeedsC {
|
||||
|
||||
/// Cross-program invocation called from C
|
||||
pub struct SyscallInvokeSignedC<'a> {
|
||||
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
||||
loader_id: &'a Pubkey,
|
||||
}
|
||||
@ -1366,10 +1357,6 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
|
||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed.into())
|
||||
}
|
||||
|
||||
fn get_callers_keyed_accounts(&self) -> &'a [KeyedAccount<'a>] {
|
||||
self.callers_keyed_accounts
|
||||
}
|
||||
|
||||
fn translate_instruction(
|
||||
&self,
|
||||
addr: u64,
|
||||
@ -1777,8 +1764,9 @@ fn call<'a>(
|
||||
signers_seeds_len,
|
||||
memory_mapping,
|
||||
)?;
|
||||
let keyed_account_refs = syscall
|
||||
.get_callers_keyed_accounts()
|
||||
let keyed_account_refs = invoke_context
|
||||
.get_keyed_accounts()
|
||||
.map_err(SyscallError::InstructionError)?
|
||||
.iter()
|
||||
.collect::<Vec<&KeyedAccount>>();
|
||||
let (message, callee_program_id, callee_program_id_index) =
|
||||
@ -2683,7 +2671,7 @@ mod tests {
|
||||
leader_schedule_epoch: 4,
|
||||
unix_timestamp: 5,
|
||||
};
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
let mut invoke_context = MockInvokeContext::new(vec![]);
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_clock).unwrap();
|
||||
invoke_context
|
||||
@ -2725,7 +2713,7 @@ mod tests {
|
||||
first_normal_epoch: 3,
|
||||
first_normal_slot: 4,
|
||||
};
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
let mut invoke_context = MockInvokeContext::new(vec![]);
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
|
||||
invoke_context
|
||||
@ -2773,7 +2761,7 @@ mod tests {
|
||||
lamports_per_signature: 1,
|
||||
},
|
||||
};
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
let mut invoke_context = MockInvokeContext::new(vec![]);
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_fees).unwrap();
|
||||
invoke_context
|
||||
@ -2813,7 +2801,7 @@ mod tests {
|
||||
exemption_threshold: 2.0,
|
||||
burn_percent: 3,
|
||||
};
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
let mut invoke_context = MockInvokeContext::new(vec![]);
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_rent).unwrap();
|
||||
invoke_context
|
||||
|
@ -10,7 +10,7 @@ use solana_sdk::{
|
||||
account::{ReadableAccount, WritableAccount},
|
||||
hash::hash,
|
||||
instruction::InstructionError,
|
||||
keyed_account::{next_keyed_account, KeyedAccount},
|
||||
keyed_account::{keyed_account_at_index, KeyedAccount},
|
||||
process_instruction::InvokeContext,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
@ -116,22 +116,22 @@ fn apply_account_data(
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
_invoke_context: &mut dyn InvokeContext,
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let keyed_accounts_iter = &mut keyed_accounts.iter();
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
|
||||
let instruction = limited_deserialize(data)?;
|
||||
|
||||
trace!("process_instruction: {:?}", instruction);
|
||||
|
||||
match instruction {
|
||||
BudgetInstruction::InitializeAccount(expr) => {
|
||||
let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let contract_keyed_account = keyed_account_at_index(keyed_accounts, 0)?;
|
||||
|
||||
if let Some(payment) = expr.final_payment() {
|
||||
let to_keyed_account = contract_keyed_account;
|
||||
let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?;
|
||||
contract_keyed_account.try_account_ref_mut()?.lamports = 0;
|
||||
to_keyed_account.try_account_ref_mut()?.lamports += payment.lamports;
|
||||
return Ok(());
|
||||
@ -154,8 +154,8 @@ pub fn process_instruction(
|
||||
)
|
||||
}
|
||||
BudgetInstruction::ApplyTimestamp(dt) => {
|
||||
let witness_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let witness_keyed_account = keyed_account_at_index(keyed_accounts, 0)?;
|
||||
let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?;
|
||||
let mut budget_state =
|
||||
BudgetState::deserialize(&contract_keyed_account.try_account_ref()?.data())?;
|
||||
if !budget_state.is_pending() {
|
||||
@ -173,7 +173,7 @@ pub fn process_instruction(
|
||||
&mut budget_state,
|
||||
witness_keyed_account,
|
||||
contract_keyed_account,
|
||||
next_keyed_account(keyed_accounts_iter),
|
||||
keyed_account_at_index(keyed_accounts, 2),
|
||||
dt,
|
||||
)?;
|
||||
trace!("apply timestamp committed");
|
||||
@ -184,8 +184,8 @@ pub fn process_instruction(
|
||||
)
|
||||
}
|
||||
BudgetInstruction::ApplySignature => {
|
||||
let witness_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let witness_keyed_account = keyed_account_at_index(keyed_accounts, 0)?;
|
||||
let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?;
|
||||
let mut budget_state =
|
||||
BudgetState::deserialize(&contract_keyed_account.try_account_ref()?.data())?;
|
||||
if !budget_state.is_pending() {
|
||||
@ -203,7 +203,7 @@ pub fn process_instruction(
|
||||
&mut budget_state,
|
||||
witness_keyed_account,
|
||||
contract_keyed_account,
|
||||
next_keyed_account(keyed_accounts_iter),
|
||||
keyed_account_at_index(keyed_accounts, 2),
|
||||
)?;
|
||||
trace!("apply signature committed");
|
||||
budget_state.serialize(
|
||||
@ -213,8 +213,8 @@ pub fn process_instruction(
|
||||
)
|
||||
}
|
||||
BudgetInstruction::ApplyAccountData => {
|
||||
let witness_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let contract_keyed_account = next_keyed_account(keyed_accounts_iter)?;
|
||||
let witness_keyed_account = keyed_account_at_index(keyed_accounts, 0)?;
|
||||
let contract_keyed_account = keyed_account_at_index(keyed_accounts, 1)?;
|
||||
let mut budget_state =
|
||||
BudgetState::deserialize(&contract_keyed_account.try_account_ref()?.data())?;
|
||||
if !budget_state.is_pending() {
|
||||
@ -228,7 +228,7 @@ pub fn process_instruction(
|
||||
&mut budget_state,
|
||||
witness_keyed_account,
|
||||
contract_keyed_account,
|
||||
next_keyed_account(keyed_accounts_iter),
|
||||
keyed_account_at_index(keyed_accounts, 2),
|
||||
)?;
|
||||
trace!("apply account data committed");
|
||||
budget_state.serialize(
|
||||
|
@ -6,7 +6,7 @@ use solana_sdk::{
|
||||
account::{ReadableAccount, WritableAccount},
|
||||
feature_set, ic_msg,
|
||||
instruction::InstructionError,
|
||||
keyed_account::{next_keyed_account, KeyedAccount},
|
||||
keyed_account::keyed_account_at_index,
|
||||
process_instruction::InvokeContext,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
@ -14,14 +14,13 @@ use solana_sdk::{
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let key_list: ConfigKeys = limited_deserialize(data)?;
|
||||
let keyed_accounts_iter = &mut keyed_accounts.iter();
|
||||
let config_keyed_account = &mut next_keyed_account(keyed_accounts_iter)?;
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
|
||||
let key_list: ConfigKeys = limited_deserialize(data)?;
|
||||
let config_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?;
|
||||
let current_data: ConfigKeys = {
|
||||
let config_account = config_keyed_account.try_account_ref_mut()?;
|
||||
if invoke_context.is_feature_active(&feature_set::check_program_owner::id())
|
||||
@ -55,6 +54,7 @@ pub fn process_instruction(
|
||||
}
|
||||
|
||||
let mut counter = 0;
|
||||
let mut keyed_accounts_iter = keyed_accounts.iter().skip(1);
|
||||
for (signer, _) in key_list.keys.iter().filter(|(_, is_signer)| *is_signer) {
|
||||
counter += 1;
|
||||
if signer != config_keyed_account.unsigned_key() {
|
||||
@ -132,7 +132,7 @@ mod tests {
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use solana_sdk::{
|
||||
account::{Account, AccountSharedData},
|
||||
keyed_account::create_keyed_is_signer_accounts,
|
||||
keyed_account::create_keyed_accounts_unified,
|
||||
process_instruction::MockInvokeContext,
|
||||
signature::{Keypair, Signer},
|
||||
system_instruction::SystemInstruction,
|
||||
@ -185,14 +185,13 @@ mod tests {
|
||||
owner: id(),
|
||||
..Account::default()
|
||||
}));
|
||||
let accounts = vec![(&config_pubkey, true, &config_account)];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let accounts = vec![(true, false, &config_pubkey, &config_account)];
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instructions[1].data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Ok(())
|
||||
);
|
||||
@ -220,14 +219,13 @@ mod tests {
|
||||
let my_config = MyConfig::new(42);
|
||||
|
||||
let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config);
|
||||
let accounts = vec![(&config_pubkey, true, &config_account)];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let accounts = vec![(true, false, &config_pubkey, &config_account)];
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Ok(())
|
||||
);
|
||||
@ -247,14 +245,13 @@ 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 accounts = vec![(&config_pubkey, true, &config_account)];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let accounts = vec![(true, false, &config_pubkey, &config_account)];
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::InvalidInstructionData)
|
||||
);
|
||||
@ -270,14 +267,13 @@ mod tests {
|
||||
|
||||
let mut instruction = config_instruction::store(&config_pubkey, true, vec![], &my_config);
|
||||
instruction.accounts[0].is_signer = false; // <----- not a signer
|
||||
let accounts = vec![(&config_pubkey, false, &config_account)];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let accounts = vec![(false, false, &config_pubkey, &config_account)];
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
@ -302,17 +298,16 @@ mod tests {
|
||||
let signer0_account = RefCell::new(AccountSharedData::default());
|
||||
let signer1_account = RefCell::new(AccountSharedData::default());
|
||||
let accounts = vec![
|
||||
(&config_pubkey, true, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(&signer1_pubkey, true, &signer1_account),
|
||||
(true, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
(true, false, &signer1_pubkey, &signer1_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Ok(())
|
||||
);
|
||||
@ -339,14 +334,13 @@ mod tests {
|
||||
owner: id(),
|
||||
..Account::default()
|
||||
}));
|
||||
let accounts = vec![(&signer0_pubkey, true, &signer0_account)];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let accounts = vec![(true, false, &signer0_pubkey, &signer0_account)];
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::InvalidAccountData)
|
||||
);
|
||||
@ -368,32 +362,30 @@ mod tests {
|
||||
|
||||
// Config-data pubkey doesn't match signer
|
||||
let accounts = vec![
|
||||
(&config_pubkey, true, &config_account),
|
||||
(&signer1_pubkey, true, &signer1_account),
|
||||
(true, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer1_pubkey, &signer1_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
|
||||
// Config-data pubkey not a signer
|
||||
let accounts = vec![
|
||||
(&config_pubkey, true, &config_account),
|
||||
(&signer0_pubkey, false, &signer0_account),
|
||||
(true, false, &config_pubkey, &config_account),
|
||||
(false, false, &signer0_pubkey, &signer0_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
@ -420,17 +412,16 @@ mod tests {
|
||||
|
||||
let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config);
|
||||
let accounts = vec![
|
||||
(&config_pubkey, true, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(&signer1_pubkey, true, &signer1_account),
|
||||
(true, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
(true, false, &signer1_pubkey, &signer1_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Ok(())
|
||||
);
|
||||
@ -440,17 +431,16 @@ mod tests {
|
||||
let instruction =
|
||||
config_instruction::store(&config_pubkey, false, keys.clone(), &new_config);
|
||||
let accounts = vec![
|
||||
(&config_pubkey, false, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(&signer1_pubkey, true, &signer1_account),
|
||||
(false, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
(true, false, &signer1_pubkey, &signer1_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Ok(())
|
||||
);
|
||||
@ -466,17 +456,16 @@ mod tests {
|
||||
let keys = vec![(pubkey, false), (signer0_pubkey, true)];
|
||||
let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config);
|
||||
let accounts = vec![
|
||||
(&config_pubkey, false, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(&signer1_pubkey, false, &signer1_account),
|
||||
(false, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
(false, false, &signer1_pubkey, &signer1_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
@ -489,17 +478,16 @@ mod tests {
|
||||
];
|
||||
let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config);
|
||||
let accounts = vec![
|
||||
(&config_pubkey, false, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(&signer2_pubkey, true, &signer2_account),
|
||||
(false, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
(true, false, &signer2_pubkey, &signer2_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
@ -528,16 +516,15 @@ mod tests {
|
||||
|
||||
let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config);
|
||||
let accounts = vec![
|
||||
(&config_pubkey, true, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(true, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Ok(())
|
||||
);
|
||||
@ -547,16 +534,15 @@ mod tests {
|
||||
let instruction =
|
||||
config_instruction::store(&config_pubkey, true, keys.clone(), &new_config);
|
||||
let accounts = vec![
|
||||
(&config_pubkey, true, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(true, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Ok(())
|
||||
);
|
||||
@ -571,14 +557,13 @@ mod tests {
|
||||
// Attempt update with incomplete signatures
|
||||
let keys = vec![(pubkey, false), (config_keypair.pubkey(), true)];
|
||||
let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config);
|
||||
let accounts = vec![(&config_pubkey, true, &config_account)];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let accounts = vec![(true, false, &config_pubkey, &config_account)];
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
@ -591,13 +576,12 @@ mod tests {
|
||||
let instructions =
|
||||
config_instruction::create_account::<MyConfig>(&from_pubkey, &config_pubkey, 1, vec![]);
|
||||
let accounts = vec![];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instructions[1].data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys)
|
||||
);
|
||||
@ -619,16 +603,15 @@ mod tests {
|
||||
|
||||
let instruction = config_instruction::store(&config_pubkey, true, keys, &new_config);
|
||||
let accounts = vec![
|
||||
(&config_pubkey, true, &config_account),
|
||||
(&signer0_pubkey, true, &signer0_account),
|
||||
(true, false, &config_pubkey, &config_account),
|
||||
(true, false, &signer0_pubkey, &signer0_account),
|
||||
];
|
||||
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
|
||||
let keyed_accounts = create_keyed_accounts_unified(&accounts);
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
&id(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts),
|
||||
),
|
||||
Err(InstructionError::InvalidAccountOwner)
|
||||
);
|
||||
|
@ -487,12 +487,12 @@ impl ExchangeProcessor {
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
_invoke_context: &mut dyn InvokeContext,
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
solana_logger::setup();
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
|
||||
solana_logger::setup();
|
||||
match limited_deserialize::<ExchangeInstruction>(data)? {
|
||||
ExchangeInstruction::AccountRequest => {
|
||||
ExchangeProcessor::do_account_request(keyed_accounts)
|
||||
|
@ -1,6 +1,5 @@
|
||||
use solana_sdk::{
|
||||
instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext,
|
||||
pubkey::Pubkey,
|
||||
instruction::InstructionError, process_instruction::InvokeContext, pubkey::Pubkey,
|
||||
};
|
||||
|
||||
solana_sdk::declare_program!(
|
||||
@ -11,7 +10,6 @@ solana_sdk::declare_program!(
|
||||
|
||||
fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
_keyed_accounts: &[KeyedAccount],
|
||||
_data: &[u8],
|
||||
_invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use log::*;
|
||||
use solana_sdk::{
|
||||
instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext,
|
||||
pubkey::Pubkey,
|
||||
instruction::InstructionError, process_instruction::InvokeContext, pubkey::Pubkey,
|
||||
};
|
||||
|
||||
solana_sdk::declare_program!(
|
||||
@ -12,13 +11,11 @@ solana_sdk::declare_program!(
|
||||
|
||||
pub fn process_instruction(
|
||||
program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
_invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
solana_logger::setup();
|
||||
trace!("noop: program_id: {:?}", program_id);
|
||||
trace!("noop: keyed_accounts: {:#?}", keyed_accounts);
|
||||
trace!("noop: data: {:?}", data);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use bincode::serialize_into;
|
||||
use solana_sdk::{
|
||||
account::{ReadableAccount, WritableAccount},
|
||||
instruction::InstructionError,
|
||||
keyed_account::{next_keyed_account, KeyedAccount},
|
||||
keyed_account::{keyed_account_at_index, KeyedAccount},
|
||||
process_instruction::InvokeContext,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
@ -30,20 +30,20 @@ fn set_owner(
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
_invoke_context: &mut dyn InvokeContext,
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
|
||||
let new_owner_pubkey: Pubkey = limited_deserialize(data)?;
|
||||
let keyed_accounts_iter = &mut keyed_accounts.iter();
|
||||
let account_keyed_account = &mut next_keyed_account(keyed_accounts_iter)?;
|
||||
let account_keyed_account = &mut keyed_account_at_index(keyed_accounts, 0)?;
|
||||
let mut account_owner_pubkey: Pubkey =
|
||||
limited_deserialize(&account_keyed_account.try_account_ref()?.data())?;
|
||||
|
||||
if account_owner_pubkey == Pubkey::default() {
|
||||
account_owner_pubkey = new_owner_pubkey;
|
||||
} else {
|
||||
let owner_keyed_account = &mut next_keyed_account(keyed_accounts_iter)?;
|
||||
let owner_keyed_account = &mut keyed_account_at_index(keyed_accounts, 1)?;
|
||||
set_owner(
|
||||
&mut account_owner_pubkey,
|
||||
new_owner_pubkey,
|
||||
|
@ -1,11 +1,9 @@
|
||||
use solana_sdk::{
|
||||
instruction::InstructionError, keyed_account::KeyedAccount, process_instruction::InvokeContext,
|
||||
pubkey::Pubkey,
|
||||
instruction::InstructionError, process_instruction::InvokeContext, pubkey::Pubkey,
|
||||
};
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
_keyed_accounts: &[KeyedAccount],
|
||||
_data: &[u8],
|
||||
_invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
|
@ -10,7 +10,7 @@ use solana_sdk::{
|
||||
decode_error::DecodeError,
|
||||
feature_set,
|
||||
instruction::{AccountMeta, Instruction, InstructionError},
|
||||
keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount},
|
||||
keyed_account::{from_keyed_account, get_signers, keyed_account_at_index},
|
||||
process_instruction::InvokeContext,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
@ -483,17 +483,17 @@ pub fn set_lockup(
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
|
||||
trace!("process_instruction: {:?}", data);
|
||||
trace!("keyed_accounts: {:?}", keyed_accounts);
|
||||
|
||||
let signers = get_signers(keyed_accounts);
|
||||
|
||||
let keyed_accounts = &mut keyed_accounts.iter();
|
||||
let me = &next_keyed_account(keyed_accounts)?;
|
||||
let me = &keyed_account_at_index(keyed_accounts, 0)?;
|
||||
|
||||
if me.owner()? != id() {
|
||||
if invoke_context.is_feature_active(&feature_set::check_program_owner::id()) {
|
||||
@ -507,7 +507,7 @@ pub fn process_instruction(
|
||||
StakeInstruction::Initialize(authorized, lockup) => me.initialize(
|
||||
&authorized,
|
||||
&lockup,
|
||||
&from_keyed_account::<Rent>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<Rent>(keyed_account_at_index(keyed_accounts, 1)?)?,
|
||||
),
|
||||
StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => {
|
||||
let require_custodian_for_locked_stake_authorize = invoke_context.is_feature_active(
|
||||
@ -515,9 +515,11 @@ pub fn process_instruction(
|
||||
);
|
||||
|
||||
if require_custodian_for_locked_stake_authorize {
|
||||
let clock = from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?;
|
||||
let _current_authority = next_keyed_account(keyed_accounts)?;
|
||||
let custodian = keyed_accounts.next().map(|ka| ka.unsigned_key());
|
||||
let clock =
|
||||
from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 1)?)?;
|
||||
let _current_authority = keyed_account_at_index(keyed_accounts, 2)?;
|
||||
let custodian =
|
||||
keyed_account_at_index(keyed_accounts, 3).map(|ka| ka.unsigned_key());
|
||||
|
||||
me.authorize(
|
||||
&signers,
|
||||
@ -525,7 +527,7 @@ pub fn process_instruction(
|
||||
stake_authorize,
|
||||
require_custodian_for_locked_stake_authorize,
|
||||
&clock,
|
||||
custodian,
|
||||
custodian.ok(),
|
||||
)
|
||||
} else {
|
||||
me.authorize(
|
||||
@ -539,14 +541,16 @@ pub fn process_instruction(
|
||||
}
|
||||
}
|
||||
StakeInstruction::AuthorizeWithSeed(args) => {
|
||||
let authority_base = next_keyed_account(keyed_accounts)?;
|
||||
let authority_base = keyed_account_at_index(keyed_accounts, 1)?;
|
||||
let require_custodian_for_locked_stake_authorize = invoke_context.is_feature_active(
|
||||
&feature_set::require_custodian_for_locked_stake_authorize::id(),
|
||||
);
|
||||
|
||||
if require_custodian_for_locked_stake_authorize {
|
||||
let clock = from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?;
|
||||
let custodian = keyed_accounts.next().map(|ka| ka.unsigned_key());
|
||||
let clock =
|
||||
from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 2)?)?;
|
||||
let custodian =
|
||||
keyed_account_at_index(keyed_accounts, 3).map(|ka| ka.unsigned_key());
|
||||
|
||||
me.authorize_with_seed(
|
||||
&authority_base,
|
||||
@ -556,7 +560,7 @@ pub fn process_instruction(
|
||||
args.stake_authorize,
|
||||
require_custodian_for_locked_stake_authorize,
|
||||
&clock,
|
||||
custodian,
|
||||
custodian.ok(),
|
||||
)
|
||||
} else {
|
||||
me.authorize_with_seed(
|
||||
@ -572,44 +576,44 @@ pub fn process_instruction(
|
||||
}
|
||||
}
|
||||
StakeInstruction::DelegateStake => {
|
||||
let vote = next_keyed_account(keyed_accounts)?;
|
||||
let vote = keyed_account_at_index(keyed_accounts, 1)?;
|
||||
|
||||
me.delegate(
|
||||
&vote,
|
||||
&from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<StakeHistory>(next_keyed_account(keyed_accounts)?)?,
|
||||
&config::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 2)?)?,
|
||||
&from_keyed_account::<StakeHistory>(keyed_account_at_index(keyed_accounts, 3)?)?,
|
||||
&config::from_keyed_account(keyed_account_at_index(keyed_accounts, 4)?)?,
|
||||
&signers,
|
||||
)
|
||||
}
|
||||
StakeInstruction::Split(lamports) => {
|
||||
let split_stake = &next_keyed_account(keyed_accounts)?;
|
||||
let split_stake = &keyed_account_at_index(keyed_accounts, 1)?;
|
||||
me.split(lamports, split_stake, &signers)
|
||||
}
|
||||
StakeInstruction::Merge => {
|
||||
let source_stake = &next_keyed_account(keyed_accounts)?;
|
||||
let source_stake = &keyed_account_at_index(keyed_accounts, 1)?;
|
||||
me.merge(
|
||||
invoke_context,
|
||||
source_stake,
|
||||
&from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<StakeHistory>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 2)?)?,
|
||||
&from_keyed_account::<StakeHistory>(keyed_account_at_index(keyed_accounts, 3)?)?,
|
||||
&signers,
|
||||
)
|
||||
}
|
||||
|
||||
StakeInstruction::Withdraw(lamports) => {
|
||||
let to = &next_keyed_account(keyed_accounts)?;
|
||||
let to = &keyed_account_at_index(keyed_accounts, 1)?;
|
||||
me.withdraw(
|
||||
lamports,
|
||||
to,
|
||||
&from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<StakeHistory>(next_keyed_account(keyed_accounts)?)?,
|
||||
next_keyed_account(keyed_accounts)?,
|
||||
keyed_accounts.next(),
|
||||
&from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 2)?)?,
|
||||
&from_keyed_account::<StakeHistory>(keyed_account_at_index(keyed_accounts, 3)?)?,
|
||||
keyed_account_at_index(keyed_accounts, 4)?,
|
||||
keyed_account_at_index(keyed_accounts, 5).ok(),
|
||||
)
|
||||
}
|
||||
StakeInstruction::Deactivate => me.deactivate(
|
||||
&from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 1)?)?,
|
||||
&signers,
|
||||
),
|
||||
|
||||
@ -623,6 +627,7 @@ mod tests {
|
||||
use bincode::serialize;
|
||||
use solana_sdk::{
|
||||
account::{self, Account, AccountSharedData},
|
||||
keyed_account::KeyedAccount,
|
||||
process_instruction::MockInvokeContext,
|
||||
rent::Rent,
|
||||
sysvar::stake_history::StakeHistory,
|
||||
@ -707,9 +712,8 @@ mod tests {
|
||||
.collect();
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default(),
|
||||
&mut MockInvokeContext::new(keyed_accounts),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -918,202 +922,194 @@ mod tests {
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[],
|
||||
&serialize(&StakeInstruction::Initialize(
|
||||
Authorized::default(),
|
||||
Lockup::default()
|
||||
))
|
||||
.unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(vec![])
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys),
|
||||
);
|
||||
|
||||
// no account for rent
|
||||
let stake_address = Pubkey::default();
|
||||
let stake_account = create_default_stake_account();
|
||||
let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[KeyedAccount::new(
|
||||
&Pubkey::default(),
|
||||
false,
|
||||
&create_default_stake_account(),
|
||||
)],
|
||||
&serialize(&StakeInstruction::Initialize(
|
||||
Authorized::default(),
|
||||
Lockup::default()
|
||||
))
|
||||
.unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys),
|
||||
);
|
||||
|
||||
// rent fails to deserialize
|
||||
let stake_address = Pubkey::default();
|
||||
let stake_account = create_default_stake_account();
|
||||
let rent_address = sysvar::rent::id();
|
||||
let rent_account = create_default_account();
|
||||
let keyed_accounts = vec![
|
||||
KeyedAccount::new(&stake_address, false, &stake_account),
|
||||
KeyedAccount::new(&rent_address, false, &rent_account),
|
||||
];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[
|
||||
KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()),
|
||||
KeyedAccount::new(&sysvar::rent::id(), false, &create_default_account())
|
||||
],
|
||||
&serialize(&StakeInstruction::Initialize(
|
||||
Authorized::default(),
|
||||
Lockup::default()
|
||||
))
|
||||
.unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::InvalidArgument),
|
||||
);
|
||||
|
||||
// fails to deserialize stake state
|
||||
let stake_address = Pubkey::default();
|
||||
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(
|
||||
&Rent::default(),
|
||||
));
|
||||
let keyed_accounts = vec![
|
||||
KeyedAccount::new(&stake_address, false, &stake_account),
|
||||
KeyedAccount::new(&rent_address, false, &rent_account),
|
||||
];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[
|
||||
KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()),
|
||||
KeyedAccount::new(
|
||||
&sysvar::rent::id(),
|
||||
false,
|
||||
&RefCell::new(account::create_account_shared_data_for_test(
|
||||
&Rent::default()
|
||||
))
|
||||
)
|
||||
],
|
||||
&serialize(&StakeInstruction::Initialize(
|
||||
Authorized::default(),
|
||||
Lockup::default()
|
||||
))
|
||||
.unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
|
||||
// gets the first check in delegate, wrong number of accounts
|
||||
let stake_address = Pubkey::default();
|
||||
let stake_account = create_default_stake_account();
|
||||
let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[KeyedAccount::new(
|
||||
&Pubkey::default(),
|
||||
false,
|
||||
&create_default_stake_account()
|
||||
),],
|
||||
&serialize(&StakeInstruction::DelegateStake).unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys),
|
||||
);
|
||||
|
||||
// gets the sub-check for number of args
|
||||
let stake_address = Pubkey::default();
|
||||
let stake_account = create_default_stake_account();
|
||||
let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[KeyedAccount::new(
|
||||
&Pubkey::default(),
|
||||
false,
|
||||
&create_default_stake_account()
|
||||
)],
|
||||
&serialize(&StakeInstruction::DelegateStake).unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys),
|
||||
);
|
||||
|
||||
// gets the check non-deserialize-able account in delegate_stake
|
||||
let stake_address = Pubkey::default();
|
||||
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().owner = solana_vote_program::id();
|
||||
let clock_address = sysvar::clock::id();
|
||||
let clock_account = 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 config_address = config::id();
|
||||
let config_account = RefCell::new(config::create_account(0, &config::Config::default()));
|
||||
let keyed_accounts = vec![
|
||||
KeyedAccount::new(&stake_address, true, &stake_account),
|
||||
KeyedAccount::new(&vote_address, false, &bad_vote_account),
|
||||
KeyedAccount::new(&clock_address, false, &clock_account),
|
||||
KeyedAccount::new(&stake_history_address, false, &stake_history_account),
|
||||
KeyedAccount::new(&config_address, false, &config_account),
|
||||
];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[
|
||||
KeyedAccount::new(&Pubkey::default(), true, &create_default_stake_account()),
|
||||
KeyedAccount::new(&Pubkey::default(), false, &bad_vote_account),
|
||||
KeyedAccount::new(
|
||||
&sysvar::clock::id(),
|
||||
false,
|
||||
&RefCell::new(account::create_account_shared_data_for_test(
|
||||
&sysvar::clock::Clock::default(),
|
||||
))
|
||||
),
|
||||
KeyedAccount::new(
|
||||
&sysvar::stake_history::id(),
|
||||
false,
|
||||
&RefCell::new(account::create_account_shared_data_for_test(
|
||||
&sysvar::stake_history::StakeHistory::default(),
|
||||
))
|
||||
),
|
||||
KeyedAccount::new(
|
||||
&config::id(),
|
||||
false,
|
||||
&RefCell::new(config::create_account(0, &config::Config::default()))
|
||||
),
|
||||
],
|
||||
&serialize(&StakeInstruction::DelegateStake).unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
|
||||
// Tests 3rd keyed account is of correct type (Clock instead of rewards) in withdraw
|
||||
let stake_address = Pubkey::default();
|
||||
let stake_account = create_default_stake_account();
|
||||
let vote_address = Pubkey::default();
|
||||
let vote_account = create_default_account();
|
||||
let rewards_address = sysvar::rewards::id();
|
||||
let rewards_account = 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 keyed_accounts = vec![
|
||||
KeyedAccount::new(&stake_address, false, &stake_account),
|
||||
KeyedAccount::new(&vote_address, false, &vote_account),
|
||||
KeyedAccount::new(&rewards_address, false, &rewards_account),
|
||||
KeyedAccount::new(&stake_history_address, false, &stake_history_account),
|
||||
];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[
|
||||
KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()),
|
||||
KeyedAccount::new(&Pubkey::default(), false, &create_default_account()),
|
||||
KeyedAccount::new(
|
||||
&sysvar::rewards::id(),
|
||||
false,
|
||||
&RefCell::new(account::create_account_shared_data_for_test(
|
||||
&sysvar::rewards::Rewards::new(0.0),
|
||||
))
|
||||
),
|
||||
KeyedAccount::new(
|
||||
&sysvar::stake_history::id(),
|
||||
false,
|
||||
&RefCell::new(account::create_account_shared_data_for_test(
|
||||
&StakeHistory::default(),
|
||||
))
|
||||
),
|
||||
],
|
||||
&serialize(&StakeInstruction::Withdraw(42)).unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::InvalidArgument),
|
||||
);
|
||||
|
||||
// Tests correct number of accounts are provided in withdraw
|
||||
let stake_address = Pubkey::default();
|
||||
let stake_account = create_default_stake_account();
|
||||
let keyed_accounts = vec![KeyedAccount::new(&stake_address, false, &stake_account)];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[KeyedAccount::new(
|
||||
&Pubkey::default(),
|
||||
false,
|
||||
&create_default_stake_account()
|
||||
)],
|
||||
&serialize(&StakeInstruction::Withdraw(42)).unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys),
|
||||
);
|
||||
|
||||
// Tests 2nd keyed account is of correct type (Clock instead of rewards) in deactivate
|
||||
let stake_address = Pubkey::default();
|
||||
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(
|
||||
&sysvar::rewards::Rewards::new(0.0),
|
||||
));
|
||||
let keyed_accounts = vec![
|
||||
KeyedAccount::new(&stake_address, false, &stake_account),
|
||||
KeyedAccount::new(&rewards_address, false, &rewards_account),
|
||||
];
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[
|
||||
KeyedAccount::new(&Pubkey::default(), false, &create_default_stake_account()),
|
||||
KeyedAccount::new(
|
||||
&sysvar::rewards::id(),
|
||||
false,
|
||||
&RefCell::new(account::create_account_shared_data_for_test(
|
||||
&sysvar::rewards::Rewards::new(0.0),
|
||||
))
|
||||
),
|
||||
],
|
||||
&serialize(&StakeInstruction::Deactivate).unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(keyed_accounts)
|
||||
),
|
||||
Err(InstructionError::InvalidArgument),
|
||||
);
|
||||
@ -1122,9 +1118,8 @@ mod tests {
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[],
|
||||
&serialize(&StakeInstruction::Deactivate).unwrap(),
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(vec![])
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys),
|
||||
);
|
||||
|
@ -5103,9 +5103,9 @@ mod tests {
|
||||
let source_stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||
let authorized_pubkey = solana_sdk::pubkey::new_rand();
|
||||
let stake_lamports = 42;
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
|
||||
let signers = vec![authorized_pubkey].into_iter().collect();
|
||||
let invoke_context = MockInvokeContext::new(vec![]);
|
||||
|
||||
for state in &[
|
||||
StakeState::Initialized(Meta::auto(&authorized_pubkey)),
|
||||
@ -5213,7 +5213,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_merge_self_fails() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
let invoke_context = MockInvokeContext::new(vec![]);
|
||||
let stake_address = Pubkey::new_unique();
|
||||
let authority_pubkey = Pubkey::new_unique();
|
||||
let signers = HashSet::from_iter(vec![authority_pubkey]);
|
||||
@ -5257,7 +5257,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_merge_incorrect_authorized_staker() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
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();
|
||||
@ -5266,6 +5265,7 @@ 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(vec![]);
|
||||
|
||||
for state in &[
|
||||
StakeState::Initialized(Meta::auto(&authorized_pubkey)),
|
||||
@ -5327,12 +5327,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_merge_invalid_account_data() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
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(vec![]);
|
||||
|
||||
for state in &[
|
||||
StakeState::Uninitialized,
|
||||
@ -5379,7 +5379,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_merge_fake_stake_source() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
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();
|
||||
@ -5411,6 +5410,7 @@ 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(vec![]);
|
||||
|
||||
assert_eq!(
|
||||
stake_keyed_account.merge(
|
||||
@ -5426,7 +5426,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_merge_active_stake() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
let base_lamports = 4242424242;
|
||||
let stake_address = Pubkey::new_unique();
|
||||
let source_address = Pubkey::new_unique();
|
||||
@ -5480,6 +5479,7 @@ mod tests {
|
||||
|
||||
let mut clock = Clock::default();
|
||||
let mut stake_history = StakeHistory::default();
|
||||
let invoke_context = MockInvokeContext::new(vec![]);
|
||||
|
||||
clock.epoch = 0;
|
||||
let mut effective = base_lamports;
|
||||
@ -6144,7 +6144,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_things_can_merge() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
let good_stake = Stake {
|
||||
credits_observed: 4242,
|
||||
delegation: Delegation {
|
||||
@ -6154,6 +6153,7 @@ mod tests {
|
||||
..Delegation::default()
|
||||
},
|
||||
};
|
||||
let invoke_context = MockInvokeContext::new(vec![]);
|
||||
|
||||
let identical = good_stake;
|
||||
assert!(
|
||||
@ -6314,7 +6314,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_merge_kind_get_if_mergeable() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
let authority_pubkey = Pubkey::new_unique();
|
||||
let initial_lamports = 4242424242;
|
||||
let rent = Rent::default();
|
||||
@ -6333,9 +6332,9 @@ mod tests {
|
||||
)
|
||||
.expect("stake_account");
|
||||
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(vec![]);
|
||||
|
||||
// Uninitialized state fails
|
||||
assert_eq!(
|
||||
@ -6547,7 +6546,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_merge_kind_merge() {
|
||||
let invoke_context = MockInvokeContext::default();
|
||||
let lamports = 424242;
|
||||
let meta = Meta {
|
||||
rent_exempt_reserve: 42,
|
||||
@ -6563,6 +6561,7 @@ 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(vec![]);
|
||||
|
||||
assert_eq!(
|
||||
inactive
|
||||
|
@ -10,7 +10,7 @@ use solana_sdk::{
|
||||
account::{AccountSharedData, ReadableAccount, WritableAccount},
|
||||
feature_set,
|
||||
instruction::InstructionError,
|
||||
keyed_account::{next_keyed_account, KeyedAccount},
|
||||
keyed_account::{keyed_account_at_index, KeyedAccount},
|
||||
process_instruction::InvokeContext,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
@ -59,12 +59,12 @@ fn verify_signed_account<'a>(
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let keyed_accounts_iter = &mut keyed_accounts.iter();
|
||||
let contract_account = &mut next_keyed_account(keyed_accounts_iter)?.try_account_ref_mut()?;
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
|
||||
let contract_account = &mut keyed_account_at_index(keyed_accounts, 0)?.try_account_ref_mut()?;
|
||||
if invoke_context.is_feature_active(&feature_set::check_program_owner::id())
|
||||
&& contract_account.owner != crate::id()
|
||||
{
|
||||
@ -97,25 +97,25 @@ pub fn process_instruction(
|
||||
VestInstruction::InitializeAccount { .. } => {}
|
||||
VestInstruction::SetTerminator(new_pubkey) => {
|
||||
verify_signed_account(
|
||||
next_keyed_account(keyed_accounts_iter)?,
|
||||
keyed_account_at_index(keyed_accounts, 1)?,
|
||||
&vest_state.terminator_pubkey,
|
||||
)?;
|
||||
vest_state.terminator_pubkey = new_pubkey;
|
||||
}
|
||||
VestInstruction::SetPayee(new_pubkey) => {
|
||||
verify_signed_account(
|
||||
next_keyed_account(keyed_accounts_iter)?,
|
||||
keyed_account_at_index(keyed_accounts, 1)?,
|
||||
&vest_state.payee_pubkey,
|
||||
)?;
|
||||
vest_state.payee_pubkey = new_pubkey;
|
||||
}
|
||||
VestInstruction::RedeemTokens => {
|
||||
let current_date = verify_date_account(
|
||||
next_keyed_account(keyed_accounts_iter)?,
|
||||
keyed_account_at_index(keyed_accounts, 1)?,
|
||||
&vest_state.date_pubkey,
|
||||
)?;
|
||||
let mut payee_account = verify_account(
|
||||
next_keyed_account(keyed_accounts_iter)?,
|
||||
keyed_account_at_index(keyed_accounts, 2)?,
|
||||
&vest_state.payee_pubkey,
|
||||
)?;
|
||||
vest_state.redeem_tokens(contract_account, current_date, &mut payee_account);
|
||||
@ -127,11 +127,11 @@ pub fn process_instruction(
|
||||
contract_account.lamports
|
||||
};
|
||||
let terminator_account = verify_signed_account(
|
||||
next_keyed_account(keyed_accounts_iter)?,
|
||||
keyed_account_at_index(keyed_accounts, 1)?,
|
||||
&vest_state.terminator_pubkey,
|
||||
)?;
|
||||
let payee_keyed_account = keyed_accounts_iter.next();
|
||||
let mut payee_account = if let Some(payee_keyed_account) = payee_keyed_account {
|
||||
let payee_keyed_account = keyed_account_at_index(keyed_accounts, 2);
|
||||
let mut payee_account = if let Ok(payee_keyed_account) = payee_keyed_account {
|
||||
payee_keyed_account.try_account_ref_mut()?
|
||||
} else {
|
||||
terminator_account
|
||||
@ -140,7 +140,7 @@ pub fn process_instruction(
|
||||
}
|
||||
VestInstruction::VestAll => {
|
||||
verify_signed_account(
|
||||
next_keyed_account(keyed_accounts_iter)?,
|
||||
keyed_account_at_index(keyed_accounts, 1)?,
|
||||
&vest_state.terminator_pubkey,
|
||||
)?;
|
||||
vest_state.vest_all();
|
||||
|
@ -14,7 +14,7 @@ use solana_sdk::{
|
||||
feature_set,
|
||||
hash::Hash,
|
||||
instruction::{AccountMeta, Instruction, InstructionError},
|
||||
keyed_account::{from_keyed_account, get_signers, next_keyed_account, KeyedAccount},
|
||||
keyed_account::{from_keyed_account, get_signers, keyed_account_at_index, KeyedAccount},
|
||||
process_instruction::InvokeContext,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
@ -277,17 +277,17 @@ fn verify_rent_exemption(
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
keyed_accounts: &[KeyedAccount],
|
||||
data: &[u8],
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
|
||||
trace!("process_instruction: {:?}", data);
|
||||
trace!("keyed_accounts: {:?}", keyed_accounts);
|
||||
|
||||
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
||||
|
||||
let keyed_accounts = &mut keyed_accounts.iter();
|
||||
let me = &mut next_keyed_account(keyed_accounts)?;
|
||||
let me = &mut keyed_account_at_index(keyed_accounts, 0)?;
|
||||
|
||||
if invoke_context.is_feature_active(&feature_set::check_program_owner::id())
|
||||
&& me.owner()? != id()
|
||||
@ -297,12 +297,12 @@ pub fn process_instruction(
|
||||
|
||||
match limited_deserialize(data)? {
|
||||
VoteInstruction::InitializeAccount(vote_init) => {
|
||||
verify_rent_exemption(me, next_keyed_account(keyed_accounts)?)?;
|
||||
verify_rent_exemption(me, keyed_account_at_index(keyed_accounts, 1)?)?;
|
||||
vote_state::initialize_account(
|
||||
me,
|
||||
&vote_init,
|
||||
&signers,
|
||||
&from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 2)?)?,
|
||||
invoke_context.is_feature_active(&feature_set::check_init_vote_data::id()),
|
||||
)
|
||||
}
|
||||
@ -311,11 +311,11 @@ pub fn process_instruction(
|
||||
&voter_pubkey,
|
||||
vote_authorize,
|
||||
&signers,
|
||||
&from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 1)?)?,
|
||||
),
|
||||
VoteInstruction::UpdateValidatorIdentity => vote_state::update_validator_identity(
|
||||
me,
|
||||
next_keyed_account(keyed_accounts)?.unsigned_key(),
|
||||
keyed_account_at_index(keyed_accounts, 1)?.unsigned_key(),
|
||||
&signers,
|
||||
),
|
||||
VoteInstruction::UpdateCommission(commission) => {
|
||||
@ -325,14 +325,14 @@ pub fn process_instruction(
|
||||
inc_new_counter_info!("vote-native", 1);
|
||||
vote_state::process_vote(
|
||||
me,
|
||||
&from_keyed_account::<SlotHashes>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<Clock>(next_keyed_account(keyed_accounts)?)?,
|
||||
&from_keyed_account::<SlotHashes>(keyed_account_at_index(keyed_accounts, 1)?)?,
|
||||
&from_keyed_account::<Clock>(keyed_account_at_index(keyed_accounts, 2)?)?,
|
||||
&vote,
|
||||
&signers,
|
||||
)
|
||||
}
|
||||
VoteInstruction::Withdraw(lamports) => {
|
||||
let to = next_keyed_account(keyed_accounts)?;
|
||||
let to = keyed_account_at_index(keyed_accounts, 1)?;
|
||||
vote_state::withdraw(me, lamports, to, &signers)
|
||||
}
|
||||
}
|
||||
@ -356,8 +356,7 @@ mod tests {
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&[],
|
||||
&[],
|
||||
&mut MockInvokeContext::default()
|
||||
&mut MockInvokeContext::new(vec![])
|
||||
),
|
||||
Err(InstructionError::NotEnoughAccountKeys),
|
||||
);
|
||||
@ -401,9 +400,8 @@ mod tests {
|
||||
.collect();
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&keyed_accounts,
|
||||
&instruction.data,
|
||||
&mut MockInvokeContext::default(),
|
||||
&mut MockInvokeContext::new(keyed_accounts),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -788,7 +788,7 @@ mod tests {
|
||||
account::AccountSharedData,
|
||||
account_utils::StateMut,
|
||||
hash::hash,
|
||||
keyed_account::{get_signers, next_keyed_account},
|
||||
keyed_account::{get_signers, keyed_account_at_index},
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
|
||||
@ -1715,9 +1715,8 @@ mod tests {
|
||||
KeyedAccount::new(&authorized_withdrawer_pubkey, true, &withdrawer_account),
|
||||
];
|
||||
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
||||
let keyed_accounts = &mut keyed_accounts.iter();
|
||||
let vote_keyed_account = next_keyed_account(keyed_accounts).unwrap();
|
||||
let withdrawer_keyed_account = next_keyed_account(keyed_accounts).unwrap();
|
||||
let vote_keyed_account = keyed_account_at_index(keyed_accounts, 0).unwrap();
|
||||
let withdrawer_keyed_account = keyed_account_at_index(keyed_accounts, 1).unwrap();
|
||||
let res = withdraw(
|
||||
vote_keyed_account,
|
||||
lamports,
|
||||
|
Reference in New Issue
Block a user