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:
committed by
GitHub
parent
0597594943
commit
7200c5106e
@ -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(()),
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user