Rework create validator stake account (#1539)

This commit is contained in:
Jon Cinque 2021-03-31 00:54:15 +02:00 committed by GitHub
parent f2de73da8e
commit 9f38a6f4b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 447 additions and 640 deletions

View File

@ -277,13 +277,10 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) ->
create_validator_stake_account(
&spl_stake_pool::id(),
&pool,
&config.owner.pubkey(),
&config.fee_payer.pubkey(),
&stake_account,
&vote_account,
&config.owner.pubkey(),
&config.owner.pubkey(),
&solana_program::system_program::id(),
&stake_program_id(),
)?,
],
Some(&config.fee_payer.pubkey()),
@ -291,7 +288,10 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) ->
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash);
transaction.sign(
&[config.fee_payer.as_ref(), config.owner.as_ref()],
recent_blockhash,
);
send_transaction(&config, transaction)?;
Ok(())
}
@ -377,7 +377,6 @@ fn command_vsa_add(
&token_receiver,
&pool_data.pool_mint,
&spl_token::id(),
&stake_program_id(),
)?,
]);
@ -468,7 +467,6 @@ fn command_vsa_remove(
&withdraw_from,
&pool_data.pool_mint,
&spl_token::id(),
&stake_program_id(),
)?,
],
Some(&config.fee_payer.pubkey()),
@ -645,7 +643,6 @@ fn command_deposit(
&pool_data.owner_fee_account,
&pool_data.pool_mint,
&spl_token::id(),
&stake_program_id(),
)?,
]);
@ -984,7 +981,6 @@ fn command_withdraw(
&withdraw_from,
&pool_data.pool_mint,
&spl_token::id(),
&stake_program_id(),
withdraw_stake.pool_amount,
)?);
}
@ -1163,7 +1159,7 @@ fn main() {
.help("Max number of validators included in the stake pool"),
)
)
.subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool")
.subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool. Must be signed by the pool owner.")
.arg(
Arg::with_name("pool")
.index(1)

View File

@ -3,12 +3,13 @@
#![allow(clippy::too_many_arguments)]
use {
crate::stake,
borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
solana_program::{
instruction::{AccountMeta, Instruction},
program_error::ProgramError,
pubkey::Pubkey,
sysvar,
system_program, sysvar,
},
};
@ -48,17 +49,17 @@ pub enum StakePoolInstruction {
/// Creates new program account for accumulating stakes for a particular validator
///
/// 0. `[]` Stake pool account this stake will belong to
/// 1. `[ws]` Funding account (must be a system account)
/// 2. `[w]` Stake account to be created
/// 3. `[]` Validator this stake account will vote for
/// 4. `[]` Stake authority for the new stake account
/// 5. `[]` Withdraw authority for the new stake account
/// 6. `[]` Rent sysvar
/// 7. `[]` System program
/// 8. `[]` Stake program
/// 1. `[s]` Owner
/// 2. `[ws]` Funding account (must be a system account)
/// 3. `[w]` Stake account to be created
/// 4. `[]` Validator this stake account will vote for
/// 5. `[]` Rent sysvar
/// 6. `[]` System program
/// 7. `[]` Stake program
CreateValidatorStakeAccount,
/// Adds validator stake account to the pool
/// Adds stake account delegated to validator to the pool's list of
/// managed validators
///
/// 0. `[w]` Stake pool
/// 1. `[s]` Owner
@ -185,24 +186,23 @@ pub fn initialize(
pub fn create_validator_stake_account(
program_id: &Pubkey,
stake_pool: &Pubkey,
owner: &Pubkey,
funder: &Pubkey,
stake_account: &Pubkey,
validator: &Pubkey,
stake_authority: &Pubkey,
withdraw_authority: &Pubkey,
system_program_id: &Pubkey,
stake_program_id: &Pubkey,
) -> Result<Instruction, ProgramError> {
let accounts = vec![
AccountMeta::new_readonly(*stake_pool, false),
AccountMeta::new_readonly(*owner, true),
AccountMeta::new(*funder, true),
AccountMeta::new(*stake_account, false),
AccountMeta::new_readonly(*validator, false),
AccountMeta::new_readonly(*stake_authority, false),
AccountMeta::new_readonly(*withdraw_authority, false),
AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(*system_program_id, false),
AccountMeta::new_readonly(*stake_program_id, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(stake::config_id(), false),
AccountMeta::new_readonly(system_program::id(), false),
AccountMeta::new_readonly(stake::id(), false),
];
Ok(Instruction {
program_id: *program_id,
@ -220,10 +220,9 @@ pub fn add_validator_to_pool(
stake_pool_withdraw: &Pubkey,
validator_list: &Pubkey,
stake_account: &Pubkey,
pool_tokens_to: &Pubkey,
pool_token_receiver: &Pubkey,
pool_mint: &Pubkey,
token_program_id: &Pubkey,
stake_program_id: &Pubkey,
) -> Result<Instruction, ProgramError> {
let accounts = vec![
AccountMeta::new(*stake_pool, false),
@ -232,12 +231,12 @@ pub fn add_validator_to_pool(
AccountMeta::new_readonly(*stake_pool_withdraw, false),
AccountMeta::new(*validator_list, false),
AccountMeta::new(*stake_account, false),
AccountMeta::new(*pool_tokens_to, false),
AccountMeta::new(*pool_token_receiver, false),
AccountMeta::new(*pool_mint, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(*token_program_id, false),
AccountMeta::new_readonly(*stake_program_id, false),
AccountMeta::new_readonly(stake::id(), false),
];
Ok(Instruction {
program_id: *program_id,
@ -258,7 +257,6 @@ pub fn remove_validator_from_pool(
burn_from: &Pubkey,
pool_mint: &Pubkey,
token_program_id: &Pubkey,
stake_program_id: &Pubkey,
) -> Result<Instruction, ProgramError> {
let accounts = vec![
AccountMeta::new(*stake_pool, false),
@ -271,7 +269,7 @@ pub fn remove_validator_from_pool(
AccountMeta::new(*pool_mint, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(*token_program_id, false),
AccountMeta::new_readonly(*stake_program_id, false),
AccountMeta::new_readonly(stake::id(), false),
];
Ok(Instruction {
program_id: *program_id,
@ -330,7 +328,6 @@ pub fn deposit(
pool_fee_to: &Pubkey,
pool_mint: &Pubkey,
token_program_id: &Pubkey,
stake_program_id: &Pubkey,
) -> Result<Instruction, ProgramError> {
let accounts = vec![
AccountMeta::new(*stake_pool, false),
@ -345,7 +342,7 @@ pub fn deposit(
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(*token_program_id, false),
AccountMeta::new_readonly(*stake_program_id, false),
AccountMeta::new_readonly(stake::id(), false),
];
Ok(Instruction {
program_id: *program_id,
@ -366,7 +363,6 @@ pub fn withdraw(
burn_from: &Pubkey,
pool_mint: &Pubkey,
token_program_id: &Pubkey,
stake_program_id: &Pubkey,
amount: u64,
) -> Result<Instruction, ProgramError> {
let accounts = vec![
@ -380,7 +376,7 @@ pub fn withdraw(
AccountMeta::new(*pool_mint, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(*token_program_id, false),
AccountMeta::new_readonly(*stake_program_id, false),
AccountMeta::new_readonly(stake::id(), false),
];
Ok(Instruction {
program_id: *program_id,

View File

@ -403,24 +403,38 @@ impl Processor {
let account_info_iter = &mut accounts.iter();
// Stake pool account
let stake_pool_info = next_account_info(account_info_iter)?;
// Owner account
let owner_info = next_account_info(account_info_iter)?;
// Account creation funder account
let funder_info = next_account_info(account_info_iter)?;
// Stake account to be created
let stake_account_info = next_account_info(account_info_iter)?;
// Validator this stake account will vote for
let validator_info = next_account_info(account_info_iter)?;
// Stake authority for the new stake account
let stake_authority_info = next_account_info(account_info_iter)?;
// Withdraw authority for the new stake account
let withdraw_authority_info = next_account_info(account_info_iter)?;
// Rent sysvar account
let rent_info = next_account_info(account_info_iter)?;
let rent = &Rent::from_account_info(rent_info)?;
// Clock sysvar account
let clock_info = next_account_info(account_info_iter)?;
// Stake history sysvar account
let stake_history_info = next_account_info(account_info_iter)?;
// Stake config sysvar account
let stake_config_info = next_account_info(account_info_iter)?;
// System program id
let system_program_info = next_account_info(account_info_iter)?;
// Staking program id
let stake_program_info = next_account_info(account_info_iter)?;
// Get stake pool stake (and check if it is initialized)
if stake_pool_info.owner != program_id {
return Err(ProgramError::IncorrectProgramId);
}
let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
if !stake_pool.is_valid() {
return Err(StakePoolError::InvalidState.into());
}
stake_pool.check_owner(owner_info)?;
// Check program ids
if *system_program_info.key != solana_program::system_program::id() {
return Err(ProgramError::IncorrectProgramId);
@ -466,8 +480,8 @@ impl Processor {
&stake::initialize(
&stake_account_info.key,
&stake::Authorized {
staker: *stake_authority_info.key,
withdrawer: *withdraw_authority_info.key,
staker: *owner_info.key,
withdrawer: *owner_info.key,
},
&stake::Lockup::default(),
),
@ -476,6 +490,22 @@ impl Processor {
rent_info.clone(),
stake_program_info.clone(),
],
)?;
invoke(
&stake::delegate_stake(
&stake_account_info.key,
&owner_info.key,
&validator_info.key,
),
&[
stake_account_info.clone(),
validator_info.clone(),
clock_info.clone(),
stake_history_info.clone(),
stake_config_info.clone(),
owner_info.clone(),
],
)
}

View File

@ -13,6 +13,10 @@ use std::str::FromStr;
solana_program::declare_id!("Stake11111111111111111111111111111111111111");
const STAKE_CONFIG: &str = "StakeConfig11111111111111111111111111111111";
/// Id for stake config account
pub fn config_id() -> Pubkey {
Pubkey::from_str(STAKE_CONFIG).unwrap()
}
/// FIXME copied from solana stake program
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
@ -489,8 +493,18 @@ pub fn delegate_stake(
AccountMeta::new_readonly(*vote_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(Pubkey::from_str(STAKE_CONFIG).unwrap(), false),
AccountMeta::new_readonly(config_id(), false),
AccountMeta::new_readonly(*authorized_pubkey, true),
];
Instruction::new_with_bincode(id(), &StakeInstruction::DelegateStake, account_metas)
}
/// FIXME copied from stake program
pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction {
let account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(*authorized_pubkey, true),
];
Instruction::new_with_bincode(id(), &StakeInstruction::Deactivate, account_metas)
}

View File

@ -3,12 +3,16 @@
mod helpers;
use {
borsh::BorshDeserialize,
borsh::{BorshDeserialize, BorshSerialize},
helpers::*,
solana_program::hash::Hash,
solana_program::{
hash::Hash,
instruction::{AccountMeta, Instruction, InstructionError},
pubkey::Pubkey,
sysvar,
},
solana_program_test::*,
solana_sdk::{
instruction::InstructionError,
signature::{Keypair, Signer},
transaction::Transaction,
transaction::TransactionError,
@ -237,26 +241,32 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() {
.await
.unwrap();
let wrong_stake_program = Keypair::new();
let wrong_stake_program = Pubkey::new_unique();
let mut transaction = Transaction::new_with_payer(
&[instruction::deposit(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&stake_pool_accounts.validator_list.pubkey(),
&stake_pool_accounts.deposit_authority,
&stake_pool_accounts.withdraw_authority,
&user_stake.pubkey(),
&validator_stake_account.stake_account,
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_fee_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&wrong_stake_program.pubkey(),
)
.unwrap()],
Some(&payer.pubkey()),
);
let accounts = vec![
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false),
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
AccountMeta::new(user_stake.pubkey(), false),
AccountMeta::new(validator_stake_account.stake_account, false),
AccountMeta::new(user_pool_account.pubkey(), false),
AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false),
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
AccountMeta::new_readonly(wrong_stake_program, false),
];
let instruction = Instruction {
program_id: id(),
accounts,
data: instruction::StakePoolInstruction::Deposit
.try_to_vec()
.unwrap(),
};
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
transaction.sign(&[&payer], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
@ -392,7 +402,6 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() {
&stake_pool_accounts.pool_fee_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&wrong_token_program.pubkey(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -481,88 +490,6 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() {
}
}
#[tokio::test]
async fn test_stake_pool_deposit_where_stake_acc_not_in_stake_state() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let validator_stake_account = ValidatorStakeAccount::new_with_target_authority(
&stake_pool_accounts.deposit_authority,
&stake_pool_accounts.stake_pool.pubkey(),
);
let user_stake_authority = Keypair::new();
create_validator_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&validator_stake_account.stake_pool,
&validator_stake_account.stake_account,
&validator_stake_account.vote.pubkey(),
&user_stake_authority.pubkey(),
&validator_stake_account.target_authority,
)
.await;
let user_pool_account = Keypair::new();
let user = Keypair::new();
create_token_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_pool_account,
&stake_pool_accounts.pool_mint.pubkey(),
&user.pubkey(),
)
.await
.unwrap();
let user_stake_acc = Keypair::new();
let lockup = stake::Lockup::default();
let authorized = stake::Authorized {
staker: stake_pool_accounts.deposit_authority,
withdrawer: stake_pool_accounts.deposit_authority,
};
create_independent_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake_acc,
&authorized,
&lockup,
)
.await;
let transaction_error = stake_pool_accounts
.deposit_stake(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake_acc.pubkey(),
&user_pool_account.pubkey(),
&validator_stake_account.stake_account,
)
.await
.err()
.unwrap();
match transaction_error {
TransportError::TransactionError(TransactionError::InstructionError(
_,
InstructionError::Custom(error_index),
)) => {
let program_error = error::StakePoolError::WrongStakeState as u32;
assert_eq!(error_index, program_error);
}
_ => panic!(
"Wrong error occurs while try to make a deposit when stake acc not in stake state"
),
}
}
#[tokio::test]
async fn test_stake_pool_deposit_to_unknown_validator() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
@ -577,7 +504,12 @@ async fn test_stake_pool_deposit_to_unknown_validator() {
&stake_pool_accounts.stake_pool.pubkey(),
);
validator_stake_account
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
.create_and_delegate(
&mut banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
let user_pool_account = Keypair::new();

View File

@ -300,30 +300,26 @@ pub async fn create_validator_stake_account(
payer: &Keypair,
recent_blockhash: &Hash,
stake_pool: &Pubkey,
owner: &Keypair,
stake_account: &Pubkey,
validator: &Pubkey,
stake_authority: &Pubkey,
withdraw_authority: &Pubkey,
) {
let mut transaction = Transaction::new_with_payer(
&[
instruction::create_validator_stake_account(
&id(),
&stake_pool,
&owner.pubkey(),
&payer.pubkey(),
&stake_account,
&validator,
&stake_authority,
&withdraw_authority,
&solana_program::system_program::id(),
&stake::id(),
)
.unwrap(),
system_instruction::transfer(&payer.pubkey(), &stake_account, TEST_STAKE_AMOUNT),
],
Some(&payer.pubkey()),
);
transaction.sign(&[payer], *recent_blockhash);
transaction.sign(&[payer, owner], *recent_blockhash);
banks_client.process_transaction(transaction).await.unwrap();
}
@ -393,29 +389,18 @@ impl ValidatorStakeAccount {
mut banks_client: &mut BanksClient,
payer: &Keypair,
recent_blockhash: &Hash,
owner: &Keypair,
) {
// make stake account
let user_stake_authority = Keypair::new();
create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await;
create_validator_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&self.stake_pool,
owner,
&self.stake_account,
&self.vote.pubkey(),
&user_stake_authority.pubkey(),
&self.target_authority,
)
.await;
create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await;
delegate_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&self.stake_account,
&user_stake_authority,
&self.vote.pubkey(),
)
.await;
@ -424,11 +409,22 @@ impl ValidatorStakeAccount {
&payer,
&recent_blockhash,
&self.stake_account,
&user_stake_authority,
&owner,
&self.target_authority,
stake::StakeAuthorize::Staker,
)
.await;
authorize_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&self.stake_account,
&owner,
&self.target_authority,
stake::StakeAuthorize::Withdrawer,
)
.await;
}
}
@ -542,7 +538,6 @@ impl StakePoolAccounts {
&self.pool_fee_account.pubkey(),
&self.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -575,7 +570,6 @@ impl StakePoolAccounts {
pool_account,
&self.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
amount,
)
.unwrap()],
@ -606,7 +600,6 @@ impl StakePoolAccounts {
pool_account,
&self.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -636,7 +629,6 @@ impl StakePoolAccounts {
pool_account,
&self.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -657,7 +649,12 @@ pub async fn simple_add_validator_to_pool(
&stake_pool_accounts.stake_pool.pubkey(),
);
user_stake
.create_and_delegate(banks_client, &payer, &recent_blockhash)
.create_and_delegate(
banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
let user_pool_account = Keypair::new();

View File

@ -8,12 +8,12 @@ use {
helpers::*,
solana_program::{
hash::Hash,
instruction::{AccountMeta, Instruction},
instruction::{AccountMeta, Instruction, InstructionError},
pubkey::Pubkey,
sysvar,
},
solana_program_test::*,
solana_sdk::{
instruction::InstructionError,
signature::{Keypair, Signer},
transaction::{Transaction, TransactionError},
transport::TransportError,
@ -43,7 +43,12 @@ async fn setup() -> (
&stake_pool_accounts.stake_pool.pubkey(),
);
user_stake
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
.create_and_delegate(
&mut banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
// make pool token account
@ -170,7 +175,6 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() {
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&stake::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -215,7 +219,6 @@ async fn test_add_validator_to_pool_with_wrong_pool_mint_account() {
&user_pool_account.pubkey(),
&wrong_pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -264,7 +267,6 @@ async fn test_add_validator_to_pool_with_wrong_validator_list_account() {
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -359,7 +361,6 @@ async fn test_not_owner_try_to_add_validator_to_pool() {
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -436,69 +437,6 @@ async fn test_not_owner_try_to_add_validator_to_pool_without_signature() {
}
}
#[tokio::test]
async fn test_add_validator_to_pool_when_stake_acc_not_in_stake_state() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let user = Keypair::new();
let user_stake = ValidatorStakeAccount::new_with_target_authority(
&stake_pool_accounts.deposit_authority,
&stake_pool_accounts.stake_pool.pubkey(),
);
let user_stake_authority = Keypair::new();
create_validator_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake.stake_pool,
&user_stake.stake_account,
&user_stake.vote.pubkey(),
&user_stake_authority.pubkey(),
&user_stake.target_authority,
)
.await;
let user_pool_account = Keypair::new();
create_token_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_pool_account,
&stake_pool_accounts.pool_mint.pubkey(),
&user.pubkey(),
)
.await
.unwrap();
let transaction_error = stake_pool_accounts
.add_validator_to_pool(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake.stake_account,
&user_pool_account.pubkey(),
)
.await
.unwrap();
match transaction_error {
TransportError::TransactionError(TransactionError::InstructionError(
_,
InstructionError::Custom(error_index),
)) => {
let program_error = error::StakePoolError::WrongStakeState as u32;
assert_eq!(error_index, program_error);
}
_ => panic!("Wrong error occurs while try to add validator stake account when it isn't in stake state"),
}
}
#[tokio::test]
async fn test_add_validator_to_pool_with_wrong_stake_program_id() {
let (
@ -510,25 +448,30 @@ async fn test_add_validator_to_pool_with_wrong_stake_program_id() {
user_pool_account,
) = setup().await;
let wrong_stake_program = Keypair::new();
let wrong_stake_program = Pubkey::new_unique();
let mut transaction = Transaction::new_with_payer(
&[instruction::add_validator_to_pool(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&stake_pool_accounts.owner.pubkey(),
&stake_pool_accounts.deposit_authority,
&stake_pool_accounts.withdraw_authority,
&stake_pool_accounts.validator_list.pubkey(),
&user_stake.stake_account,
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&wrong_stake_program.pubkey(),
)
.unwrap()],
Some(&payer.pubkey()),
);
let accounts = vec![
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true),
AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false),
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
AccountMeta::new(user_stake.stake_account, false),
AccountMeta::new(user_pool_account.pubkey(), false),
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
AccountMeta::new_readonly(wrong_stake_program, false),
];
let instruction = Instruction {
program_id: id(),
accounts,
data: instruction::StakePoolInstruction::AddValidatorToPool
.try_to_vec()
.unwrap(),
};
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
@ -563,7 +506,12 @@ async fn test_add_too_many_validator_stake_accounts() {
&stake_pool_accounts.stake_pool.pubkey(),
);
user_stake
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
.create_and_delegate(
&mut banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
// make pool token account
@ -595,7 +543,12 @@ async fn test_add_too_many_validator_stake_accounts() {
&stake_pool_accounts.stake_pool.pubkey(),
);
user_stake
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
.create_and_delegate(
&mut banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
let error = stake_pool_accounts
.add_validator_to_pool(

View File

@ -2,22 +2,76 @@
mod helpers;
use crate::solana_program::pubkey::Pubkey;
use helpers::*;
use bincode::deserialize;
use solana_program_test::*;
use solana_sdk::{
instruction::InstructionError,
signature::{Keypair, Signer},
transaction::Transaction,
transaction::TransactionError,
transport::TransportError,
use {
bincode::deserialize,
borsh::BorshSerialize,
helpers::*,
solana_program::{
instruction::{AccountMeta, Instruction, InstructionError},
pubkey::Pubkey,
system_program, sysvar,
},
solana_program_test::*,
solana_sdk::{
signature::{Keypair, Signer},
transaction::Transaction,
transaction::TransactionError,
transport::TransportError,
},
spl_stake_pool::{error, id, instruction, processor, stake},
};
use spl_stake_pool::*;
#[tokio::test]
async fn test_create_validator_stake_account() {
async fn success_create_validator_stake_account() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let validator = Keypair::new();
create_vote(&mut banks_client, &payer, &recent_blockhash, &validator).await;
let (stake_account, _) = processor::Processor::find_stake_address_for_validator(
&id(),
&validator.pubkey(),
&stake_pool_accounts.stake_pool.pubkey(),
);
let mut transaction = Transaction::new_with_payer(
&[instruction::create_validator_stake_account(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&stake_pool_accounts.owner.pubkey(),
&payer.pubkey(),
&stake_account,
&validator.pubkey(),
)
.unwrap()],
Some(&payer.pubkey()),
);
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
banks_client.process_transaction(transaction).await.unwrap();
// Check authorities
let stake = get_account(&mut banks_client, &stake_account).await;
let stake_state = deserialize::<stake::StakeState>(&stake.data).unwrap();
match stake_state {
stake::StakeState::Stake(meta, stake) => {
assert_eq!(&meta.authorized.staker, &stake_pool_accounts.owner.pubkey());
assert_eq!(
&meta.authorized.withdrawer,
&stake_pool_accounts.owner.pubkey()
);
assert_eq!(stake.delegation.voter_pubkey, validator.pubkey());
}
_ => panic!(),
}
}
#[tokio::test]
async fn fail_create_validator_stake_account_on_non_vote_account() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
@ -26,8 +80,6 @@ async fn test_create_validator_stake_account() {
.unwrap();
let validator = Pubkey::new_unique();
let user_stake_authority = Keypair::new();
let user_withdraw_authority = Keypair::new();
let (stake_account, _) = processor::Processor::find_stake_address_for_validator(
&id(),
@ -39,37 +91,136 @@ async fn test_create_validator_stake_account() {
&[instruction::create_validator_stake_account(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&stake_pool_accounts.owner.pubkey(),
&payer.pubkey(),
&stake_account,
&validator,
&user_stake_authority.pubkey(),
&user_withdraw_authority.pubkey(),
&solana_program::system_program::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
);
transaction.sign(&[&payer], recent_blockhash);
banks_client.process_transaction(transaction).await.unwrap();
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
.await
.err()
.unwrap()
.unwrap();
// Check authorities
let stake = get_account(&mut banks_client, &stake_account).await;
let stake_state = deserialize::<stake::StakeState>(&stake.data).unwrap();
match stake_state {
stake::StakeState::Initialized(meta) => {
assert_eq!(&meta.authorized.staker, &user_stake_authority.pubkey());
assert_eq!(
&meta.authorized.withdrawer,
&user_withdraw_authority.pubkey()
);
}
_ => panic!(),
}
assert_eq!(
transaction_error,
TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,)
);
}
#[tokio::test]
async fn test_create_validator_stake_account_with_incorrect_address() {
async fn fail_create_validator_stake_account_with_wrong_system_program() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let validator = Pubkey::new_unique();
let (stake_account, _) = processor::Processor::find_stake_address_for_validator(
&id(),
&validator,
&stake_pool_accounts.stake_pool.pubkey(),
);
let wrong_system_program = Pubkey::new_unique();
let accounts = vec![
AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false),
AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true),
AccountMeta::new(payer.pubkey(), true),
AccountMeta::new(stake_account, false),
AccountMeta::new_readonly(validator, false),
AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(stake::config_id(), false),
AccountMeta::new_readonly(wrong_system_program, false),
AccountMeta::new_readonly(stake::id(), false),
];
let instruction = Instruction {
program_id: id(),
accounts,
data: instruction::StakePoolInstruction::CreateValidatorStakeAccount
.try_to_vec()
.unwrap(),
};
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
.await
.err()
.unwrap()
.unwrap();
assert_eq!(
transaction_error,
TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,)
);
}
#[tokio::test]
async fn fail_create_validator_stake_account_with_wrong_stake_program() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let validator = Pubkey::new_unique();
let (stake_account, _) = processor::Processor::find_stake_address_for_validator(
&id(),
&validator,
&stake_pool_accounts.stake_pool.pubkey(),
);
let wrong_stake_program = Pubkey::new_unique();
let accounts = vec![
AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false),
AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true),
AccountMeta::new(payer.pubkey(), true),
AccountMeta::new(stake_account, false),
AccountMeta::new_readonly(validator, false),
AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(stake::config_id(), false),
AccountMeta::new_readonly(system_program::id(), false),
AccountMeta::new_readonly(wrong_stake_program, false),
];
let instruction = Instruction {
program_id: id(),
accounts,
data: instruction::StakePoolInstruction::CreateValidatorStakeAccount
.try_to_vec()
.unwrap(),
};
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
.await
.err()
.unwrap()
.unwrap();
assert_eq!(
transaction_error,
TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,)
);
}
#[tokio::test]
async fn fail_create_validator_stake_account_with_incorrect_address() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
@ -78,26 +229,21 @@ async fn test_create_validator_stake_account_with_incorrect_address() {
.unwrap();
let validator = Pubkey::new_unique();
let user_stake_authority = Keypair::new();
let user_withdraw_authority = Keypair::new();
let stake_account = Keypair::new();
let mut transaction = Transaction::new_with_payer(
&[instruction::create_validator_stake_account(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&stake_pool_accounts.owner.pubkey(),
&payer.pubkey(),
&stake_account.pubkey(),
&validator,
&user_stake_authority.pubkey(),
&user_withdraw_authority.pubkey(),
&solana_program::system_program::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
);
transaction.sign(&[&payer], recent_blockhash);
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
.await
@ -117,109 +263,3 @@ async fn test_create_validator_stake_account_with_incorrect_address() {
),
}
}
#[tokio::test]
async fn test_create_validator_stake_account_with_wrong_system_program() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let validator = Pubkey::new_unique();
let user_stake_authority = Keypair::new();
let user_withdraw_authority = Keypair::new();
let (stake_account, _) = processor::Processor::find_stake_address_for_validator(
&id(),
&validator,
&stake_pool_accounts.stake_pool.pubkey(),
);
let wrong_system_program = Keypair::new();
let mut transaction = Transaction::new_with_payer(
&[instruction::create_validator_stake_account(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&payer.pubkey(),
&stake_account,
&validator,
&user_stake_authority.pubkey(),
&user_withdraw_authority.pubkey(),
&wrong_system_program.pubkey(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
);
transaction.sign(&[&payer], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
.await
.err()
.unwrap();
match transaction_error {
TransportError::TransactionError(TransactionError::InstructionError(_, error)) => {
assert_eq!(error, InstructionError::IncorrectProgramId);
}
_ => panic!(
"Wrong error occurs while try to create validator stake account with wrong token program ID"
),
}
}
#[tokio::test]
async fn test_create_validator_stake_account_with_wrong_stake_program() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let validator = Pubkey::new_unique();
let user_stake_authority = Keypair::new();
let user_withdraw_authority = Keypair::new();
let (stake_account, _) = processor::Processor::find_stake_address_for_validator(
&id(),
&validator,
&stake_pool_accounts.stake_pool.pubkey(),
);
let wrong_stake_program = Keypair::new();
let mut transaction = Transaction::new_with_payer(
&[instruction::create_validator_stake_account(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&payer.pubkey(),
&stake_account,
&validator,
&user_stake_authority.pubkey(),
&user_withdraw_authority.pubkey(),
&solana_program::system_program::id(),
&wrong_stake_program.pubkey(),
)
.unwrap()],
Some(&payer.pubkey()),
);
transaction.sign(&[&payer], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
.await
.err()
.unwrap();
match transaction_error {
TransportError::TransactionError(TransactionError::InstructionError(_, error)) => {
assert_eq!(error, InstructionError::IncorrectProgramId);
}
_ => panic!(
"Wrong error occurs while try to create validator stake account with wrong stake program ID"
),
}
}

View File

@ -8,13 +8,12 @@ use {
helpers::*,
solana_program::{
hash::Hash,
instruction::{AccountMeta, Instruction},
instruction::{AccountMeta, Instruction, InstructionError},
pubkey::Pubkey,
sysvar,
},
solana_program_test::*,
solana_sdk::{
instruction::InstructionError,
signature::{Keypair, Signer},
transaction::{Transaction, TransactionError},
transport::TransportError,
@ -45,7 +44,12 @@ async fn setup() -> (
&stake_pool_accounts.stake_pool.pubkey(),
);
user_stake
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
.create_and_delegate(
&mut banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
// make pool token account
@ -165,26 +169,31 @@ async fn test_remove_validator_from_pool_with_wrong_stake_program_id() {
_,
) = setup().await;
let wrong_stake_program = Keypair::new();
let wrong_stake_program = Pubkey::new_unique();
let new_authority = Pubkey::new_unique();
let mut transaction = Transaction::new_with_payer(
&[instruction::remove_validator_from_pool(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&stake_pool_accounts.owner.pubkey(),
&stake_pool_accounts.withdraw_authority,
&new_authority,
&stake_pool_accounts.validator_list.pubkey(),
&user_stake.stake_account,
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&wrong_stake_program.pubkey(),
)
.unwrap()],
Some(&payer.pubkey()),
);
let accounts = vec![
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true),
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
AccountMeta::new_readonly(new_authority, false),
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
AccountMeta::new(user_stake.stake_account, false),
AccountMeta::new(user_pool_account.pubkey(), false),
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
AccountMeta::new_readonly(wrong_stake_program, false),
];
let instruction = Instruction {
program_id: id(),
accounts,
data: instruction::StakePoolInstruction::RemoveValidatorFromPool
.try_to_vec()
.unwrap(),
};
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
@ -230,7 +239,6 @@ async fn test_remove_validator_from_pool_with_wrong_token_program_id() {
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&wrong_token_program.pubkey(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -277,7 +285,6 @@ async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() {
&user_pool_account.pubkey(),
&wrong_pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -328,7 +335,6 @@ async fn test_remove_validator_from_pool_with_wrong_validator_list_account() {
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -444,7 +450,6 @@ async fn test_not_owner_try_to_remove_validator_from_pool() {
&user_pool_account.pubkey(),
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&stake::id(),
)
.unwrap()],
Some(&payer.pubkey()),
@ -523,72 +528,6 @@ async fn test_not_owner_try_to_remove_validator_from_pool_without_signature() {
}
}
#[tokio::test]
async fn test_remove_validator_from_pool_when_stake_acc_not_in_stake_state() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let user = Keypair::new();
let user_stake = ValidatorStakeAccount::new_with_target_authority(
&stake_pool_accounts.deposit_authority,
&stake_pool_accounts.stake_pool.pubkey(),
);
let user_stake_authority = Keypair::new();
create_validator_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake.stake_pool,
&user_stake.stake_account,
&user_stake.vote.pubkey(),
&user_stake_authority.pubkey(),
&user_stake.target_authority,
)
.await;
let user_pool_account = Keypair::new();
create_token_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_pool_account,
&stake_pool_accounts.pool_mint.pubkey(),
&user.pubkey(),
)
.await
.unwrap();
let new_authority = Pubkey::new_unique();
let transaction_error = stake_pool_accounts
.remove_validator_from_pool(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake.stake_account,
&user_pool_account.pubkey(),
&new_authority,
)
.await
.unwrap();
match transaction_error {
TransportError::TransactionError(TransactionError::InstructionError(
_,
InstructionError::Custom(error_index),
)) => {
let program_error = error::StakePoolError::WrongStakeState as u32;
assert_eq!(error_index, program_error);
}
_ => panic!("Wrong error occurs while try to add validator stake account when it isn't in stake state"),
}
}
#[tokio::test]
async fn test_remove_validator_from_pool_from_unupdated_stake_pool() {} // TODO

View File

@ -3,13 +3,16 @@
mod helpers;
use {
borsh::BorshDeserialize,
borsh::{BorshDeserialize, BorshSerialize},
helpers::*,
solana_program::hash::Hash,
solana_program::pubkey::Pubkey,
solana_program::{
hash::Hash,
instruction::{AccountMeta, Instruction, InstructionError},
pubkey::Pubkey,
sysvar,
},
solana_program_test::*,
solana_sdk::{
instruction::InstructionError,
signature::{Keypair, Signer},
transaction::{Transaction, TransactionError},
transport::TransportError,
@ -204,26 +207,30 @@ async fn test_stake_pool_withdraw_with_wrong_stake_program() {
let user_stake_recipient = Keypair::new();
let new_authority = Pubkey::new_unique();
let wrong_stake_program = Keypair::new();
let wrong_stake_program = Pubkey::new_unique();
let mut transaction = Transaction::new_with_payer(
&[instruction::withdraw(
&id(),
&stake_pool_accounts.stake_pool.pubkey(),
&stake_pool_accounts.validator_list.pubkey(),
&stake_pool_accounts.withdraw_authority,
&validator_stake_account.stake_account,
&user_stake_recipient.pubkey(),
&new_authority,
&deposit_info.user_pool_account,
&stake_pool_accounts.pool_mint.pubkey(),
&spl_token::id(),
&wrong_stake_program.pubkey(),
tokens_to_burn,
)
.unwrap()],
Some(&payer.pubkey()),
);
let accounts = vec![
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
AccountMeta::new(validator_stake_account.stake_account, false),
AccountMeta::new(user_stake_recipient.pubkey(), false),
AccountMeta::new_readonly(new_authority, false),
AccountMeta::new(deposit_info.user_pool_account, false),
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
AccountMeta::new_readonly(wrong_stake_program, false),
];
let instruction = Instruction {
program_id: id(),
accounts,
data: instruction::StakePoolInstruction::Withdraw(tokens_to_burn)
.try_to_vec()
.unwrap(),
};
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
transaction.sign(&[&payer], recent_blockhash);
let transaction_error = banks_client
.process_transaction(transaction)
@ -314,7 +321,6 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() {
&deposit_info.user_pool_account,
&stake_pool_accounts.pool_mint.pubkey(),
&wrong_token_program.pubkey(),
&stake::id(),
tokens_to_burn,
)
.unwrap()],
@ -382,112 +388,6 @@ async fn test_stake_pool_withdraw_with_wrong_validator_list() {
}
}
#[tokio::test]
async fn test_stake_pool_withdraw_when_stake_acc_not_in_stake_state() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
let stake_pool_accounts = StakePoolAccounts::new();
stake_pool_accounts
.initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash)
.await
.unwrap();
let validator_stake_account = ValidatorStakeAccount::new_with_target_authority(
&stake_pool_accounts.deposit_authority,
&stake_pool_accounts.stake_pool.pubkey(),
);
let user_stake_authority = Keypair::new();
create_validator_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&validator_stake_account.stake_pool,
&validator_stake_account.stake_account,
&validator_stake_account.vote.pubkey(),
&user_stake_authority.pubkey(),
&validator_stake_account.target_authority,
)
.await;
let user = Keypair::new();
// make stake account
let user_stake = Keypair::new();
let lockup = stake::Lockup::default();
let authorized = stake::Authorized {
staker: stake_pool_accounts.deposit_authority,
withdrawer: stake_pool_accounts.deposit_authority,
};
create_independent_stake_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake,
&authorized,
&lockup,
)
.await;
// make pool token account
let user_pool_account = Keypair::new();
create_token_account(
&mut banks_client,
&payer,
&recent_blockhash,
&user_pool_account,
&stake_pool_accounts.pool_mint.pubkey(),
&user.pubkey(),
)
.await
.unwrap();
let user_pool_account = user_pool_account.pubkey();
let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await;
let tokens_to_burn = pool_tokens / 4;
// Delegate tokens for burning
delegate_tokens(
&mut banks_client,
&payer,
&recent_blockhash,
&user_pool_account,
&user,
&stake_pool_accounts.withdraw_authority,
tokens_to_burn,
)
.await;
// Create stake account to withdraw to
let user_stake_recipient = Keypair::new();
let new_authority = Pubkey::new_unique();
let transaction_error = stake_pool_accounts
.withdraw_stake(
&mut banks_client,
&payer,
&recent_blockhash,
&user_stake_recipient.pubkey(),
&user_pool_account,
&validator_stake_account.stake_account,
&new_authority,
tokens_to_burn,
)
.await
.err()
.unwrap();
match transaction_error {
TransportError::TransactionError(TransactionError::InstructionError(
_,
InstructionError::Custom(error_index),
)) => {
let program_error = error::StakePoolError::WrongStakeState as u32;
assert_eq!(error_index, program_error);
}
_ => panic!("Wrong error occurs while try to withdraw when stake acc not in stake state"),
}
}
#[tokio::test]
async fn test_stake_pool_withdraw_from_unknown_validator() {
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
@ -502,7 +402,12 @@ async fn test_stake_pool_withdraw_from_unknown_validator() {
&stake_pool_accounts.stake_pool.pubkey(),
);
validator_stake_account
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
.create_and_delegate(
&mut banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
let user_stake = ValidatorStakeAccount::new_with_target_authority(
@ -510,7 +415,12 @@ async fn test_stake_pool_withdraw_from_unknown_validator() {
&stake_pool_accounts.stake_pool.pubkey(),
);
user_stake
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
.create_and_delegate(
&mut banks_client,
&payer,
&recent_blockhash,
&stake_pool_accounts.owner,
)
.await;
let user_pool_account = Keypair::new();