Rework create validator stake account (#1539)
This commit is contained in:
parent
f2de73da8e
commit
9f38a6f4b2
|
@ -277,13 +277,10 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) ->
|
||||||
create_validator_stake_account(
|
create_validator_stake_account(
|
||||||
&spl_stake_pool::id(),
|
&spl_stake_pool::id(),
|
||||||
&pool,
|
&pool,
|
||||||
|
&config.owner.pubkey(),
|
||||||
&config.fee_payer.pubkey(),
|
&config.fee_payer.pubkey(),
|
||||||
&stake_account,
|
&stake_account,
|
||||||
&vote_account,
|
&vote_account,
|
||||||
&config.owner.pubkey(),
|
|
||||||
&config.owner.pubkey(),
|
|
||||||
&solana_program::system_program::id(),
|
|
||||||
&stake_program_id(),
|
|
||||||
)?,
|
)?,
|
||||||
],
|
],
|
||||||
Some(&config.fee_payer.pubkey()),
|
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()?;
|
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
|
||||||
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
|
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)?;
|
send_transaction(&config, transaction)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,6 @@ fn command_vsa_add(
|
||||||
&token_receiver,
|
&token_receiver,
|
||||||
&pool_data.pool_mint,
|
&pool_data.pool_mint,
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake_program_id(),
|
|
||||||
)?,
|
)?,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -468,7 +467,6 @@ fn command_vsa_remove(
|
||||||
&withdraw_from,
|
&withdraw_from,
|
||||||
&pool_data.pool_mint,
|
&pool_data.pool_mint,
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake_program_id(),
|
|
||||||
)?,
|
)?,
|
||||||
],
|
],
|
||||||
Some(&config.fee_payer.pubkey()),
|
Some(&config.fee_payer.pubkey()),
|
||||||
|
@ -645,7 +643,6 @@ fn command_deposit(
|
||||||
&pool_data.owner_fee_account,
|
&pool_data.owner_fee_account,
|
||||||
&pool_data.pool_mint,
|
&pool_data.pool_mint,
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake_program_id(),
|
|
||||||
)?,
|
)?,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -984,7 +981,6 @@ fn command_withdraw(
|
||||||
&withdraw_from,
|
&withdraw_from,
|
||||||
&pool_data.pool_mint,
|
&pool_data.pool_mint,
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake_program_id(),
|
|
||||||
withdraw_stake.pool_amount,
|
withdraw_stake.pool_amount,
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
|
@ -1163,7 +1159,7 @@ fn main() {
|
||||||
.help("Max number of validators included in the stake pool"),
|
.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(
|
||||||
Arg::with_name("pool")
|
Arg::with_name("pool")
|
||||||
.index(1)
|
.index(1)
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
crate::stake,
|
||||||
borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
|
borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
|
||||||
solana_program::{
|
solana_program::{
|
||||||
instruction::{AccountMeta, Instruction},
|
instruction::{AccountMeta, Instruction},
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
sysvar,
|
system_program, sysvar,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,17 +49,17 @@ pub enum StakePoolInstruction {
|
||||||
/// Creates new program account for accumulating stakes for a particular validator
|
/// Creates new program account for accumulating stakes for a particular validator
|
||||||
///
|
///
|
||||||
/// 0. `[]` Stake pool account this stake will belong to
|
/// 0. `[]` Stake pool account this stake will belong to
|
||||||
/// 1. `[ws]` Funding account (must be a system account)
|
/// 1. `[s]` Owner
|
||||||
/// 2. `[w]` Stake account to be created
|
/// 2. `[ws]` Funding account (must be a system account)
|
||||||
/// 3. `[]` Validator this stake account will vote for
|
/// 3. `[w]` Stake account to be created
|
||||||
/// 4. `[]` Stake authority for the new stake account
|
/// 4. `[]` Validator this stake account will vote for
|
||||||
/// 5. `[]` Withdraw authority for the new stake account
|
/// 5. `[]` Rent sysvar
|
||||||
/// 6. `[]` Rent sysvar
|
/// 6. `[]` System program
|
||||||
/// 7. `[]` System program
|
/// 7. `[]` Stake program
|
||||||
/// 8. `[]` Stake program
|
|
||||||
CreateValidatorStakeAccount,
|
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
|
/// 0. `[w]` Stake pool
|
||||||
/// 1. `[s]` Owner
|
/// 1. `[s]` Owner
|
||||||
|
@ -185,24 +186,23 @@ pub fn initialize(
|
||||||
pub fn create_validator_stake_account(
|
pub fn create_validator_stake_account(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
stake_pool: &Pubkey,
|
stake_pool: &Pubkey,
|
||||||
|
owner: &Pubkey,
|
||||||
funder: &Pubkey,
|
funder: &Pubkey,
|
||||||
stake_account: &Pubkey,
|
stake_account: &Pubkey,
|
||||||
validator: &Pubkey,
|
validator: &Pubkey,
|
||||||
stake_authority: &Pubkey,
|
|
||||||
withdraw_authority: &Pubkey,
|
|
||||||
system_program_id: &Pubkey,
|
|
||||||
stake_program_id: &Pubkey,
|
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> Result<Instruction, ProgramError> {
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
AccountMeta::new_readonly(*stake_pool, false),
|
AccountMeta::new_readonly(*stake_pool, false),
|
||||||
|
AccountMeta::new_readonly(*owner, true),
|
||||||
AccountMeta::new(*funder, true),
|
AccountMeta::new(*funder, true),
|
||||||
AccountMeta::new(*stake_account, false),
|
AccountMeta::new(*stake_account, false),
|
||||||
AccountMeta::new_readonly(*validator, 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(sysvar::rent::id(), false),
|
||||||
AccountMeta::new_readonly(*system_program_id, false),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
AccountMeta::new_readonly(*stake_program_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 {
|
Ok(Instruction {
|
||||||
program_id: *program_id,
|
program_id: *program_id,
|
||||||
|
@ -220,10 +220,9 @@ pub fn add_validator_to_pool(
|
||||||
stake_pool_withdraw: &Pubkey,
|
stake_pool_withdraw: &Pubkey,
|
||||||
validator_list: &Pubkey,
|
validator_list: &Pubkey,
|
||||||
stake_account: &Pubkey,
|
stake_account: &Pubkey,
|
||||||
pool_tokens_to: &Pubkey,
|
pool_token_receiver: &Pubkey,
|
||||||
pool_mint: &Pubkey,
|
pool_mint: &Pubkey,
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
stake_program_id: &Pubkey,
|
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> Result<Instruction, ProgramError> {
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
AccountMeta::new(*stake_pool, false),
|
AccountMeta::new(*stake_pool, false),
|
||||||
|
@ -232,12 +231,12 @@ pub fn add_validator_to_pool(
|
||||||
AccountMeta::new_readonly(*stake_pool_withdraw, false),
|
AccountMeta::new_readonly(*stake_pool_withdraw, false),
|
||||||
AccountMeta::new(*validator_list, false),
|
AccountMeta::new(*validator_list, false),
|
||||||
AccountMeta::new(*stake_account, 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(*pool_mint, false),
|
||||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
|
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
|
||||||
AccountMeta::new_readonly(*token_program_id, false),
|
AccountMeta::new_readonly(*token_program_id, false),
|
||||||
AccountMeta::new_readonly(*stake_program_id, false),
|
AccountMeta::new_readonly(stake::id(), false),
|
||||||
];
|
];
|
||||||
Ok(Instruction {
|
Ok(Instruction {
|
||||||
program_id: *program_id,
|
program_id: *program_id,
|
||||||
|
@ -258,7 +257,6 @@ pub fn remove_validator_from_pool(
|
||||||
burn_from: &Pubkey,
|
burn_from: &Pubkey,
|
||||||
pool_mint: &Pubkey,
|
pool_mint: &Pubkey,
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
stake_program_id: &Pubkey,
|
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> Result<Instruction, ProgramError> {
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
AccountMeta::new(*stake_pool, false),
|
AccountMeta::new(*stake_pool, false),
|
||||||
|
@ -271,7 +269,7 @@ pub fn remove_validator_from_pool(
|
||||||
AccountMeta::new(*pool_mint, false),
|
AccountMeta::new(*pool_mint, false),
|
||||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
AccountMeta::new_readonly(*token_program_id, false),
|
AccountMeta::new_readonly(*token_program_id, false),
|
||||||
AccountMeta::new_readonly(*stake_program_id, false),
|
AccountMeta::new_readonly(stake::id(), false),
|
||||||
];
|
];
|
||||||
Ok(Instruction {
|
Ok(Instruction {
|
||||||
program_id: *program_id,
|
program_id: *program_id,
|
||||||
|
@ -330,7 +328,6 @@ pub fn deposit(
|
||||||
pool_fee_to: &Pubkey,
|
pool_fee_to: &Pubkey,
|
||||||
pool_mint: &Pubkey,
|
pool_mint: &Pubkey,
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
stake_program_id: &Pubkey,
|
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> Result<Instruction, ProgramError> {
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
AccountMeta::new(*stake_pool, false),
|
AccountMeta::new(*stake_pool, false),
|
||||||
|
@ -345,7 +342,7 @@ pub fn deposit(
|
||||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
|
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
|
||||||
AccountMeta::new_readonly(*token_program_id, false),
|
AccountMeta::new_readonly(*token_program_id, false),
|
||||||
AccountMeta::new_readonly(*stake_program_id, false),
|
AccountMeta::new_readonly(stake::id(), false),
|
||||||
];
|
];
|
||||||
Ok(Instruction {
|
Ok(Instruction {
|
||||||
program_id: *program_id,
|
program_id: *program_id,
|
||||||
|
@ -366,7 +363,6 @@ pub fn withdraw(
|
||||||
burn_from: &Pubkey,
|
burn_from: &Pubkey,
|
||||||
pool_mint: &Pubkey,
|
pool_mint: &Pubkey,
|
||||||
token_program_id: &Pubkey,
|
token_program_id: &Pubkey,
|
||||||
stake_program_id: &Pubkey,
|
|
||||||
amount: u64,
|
amount: u64,
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> Result<Instruction, ProgramError> {
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
|
@ -380,7 +376,7 @@ pub fn withdraw(
|
||||||
AccountMeta::new(*pool_mint, false),
|
AccountMeta::new(*pool_mint, false),
|
||||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
AccountMeta::new_readonly(*token_program_id, false),
|
AccountMeta::new_readonly(*token_program_id, false),
|
||||||
AccountMeta::new_readonly(*stake_program_id, false),
|
AccountMeta::new_readonly(stake::id(), false),
|
||||||
];
|
];
|
||||||
Ok(Instruction {
|
Ok(Instruction {
|
||||||
program_id: *program_id,
|
program_id: *program_id,
|
||||||
|
|
|
@ -403,24 +403,38 @@ impl Processor {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// Stake pool account
|
// Stake pool account
|
||||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
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
|
// Account creation funder account
|
||||||
let funder_info = next_account_info(account_info_iter)?;
|
let funder_info = next_account_info(account_info_iter)?;
|
||||||
// Stake account to be created
|
// Stake account to be created
|
||||||
let stake_account_info = next_account_info(account_info_iter)?;
|
let stake_account_info = next_account_info(account_info_iter)?;
|
||||||
// Validator this stake account will vote for
|
// Validator this stake account will vote for
|
||||||
let validator_info = next_account_info(account_info_iter)?;
|
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
|
// Rent sysvar account
|
||||||
let rent_info = next_account_info(account_info_iter)?;
|
let rent_info = next_account_info(account_info_iter)?;
|
||||||
let rent = &Rent::from_account_info(rent_info)?;
|
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
|
// System program id
|
||||||
let system_program_info = next_account_info(account_info_iter)?;
|
let system_program_info = next_account_info(account_info_iter)?;
|
||||||
// Staking program id
|
// Staking program id
|
||||||
let stake_program_info = next_account_info(account_info_iter)?;
|
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
|
// Check program ids
|
||||||
if *system_program_info.key != solana_program::system_program::id() {
|
if *system_program_info.key != solana_program::system_program::id() {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
|
@ -466,8 +480,8 @@ impl Processor {
|
||||||
&stake::initialize(
|
&stake::initialize(
|
||||||
&stake_account_info.key,
|
&stake_account_info.key,
|
||||||
&stake::Authorized {
|
&stake::Authorized {
|
||||||
staker: *stake_authority_info.key,
|
staker: *owner_info.key,
|
||||||
withdrawer: *withdraw_authority_info.key,
|
withdrawer: *owner_info.key,
|
||||||
},
|
},
|
||||||
&stake::Lockup::default(),
|
&stake::Lockup::default(),
|
||||||
),
|
),
|
||||||
|
@ -476,6 +490,22 @@ impl Processor {
|
||||||
rent_info.clone(),
|
rent_info.clone(),
|
||||||
stake_program_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(),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,10 @@ use std::str::FromStr;
|
||||||
solana_program::declare_id!("Stake11111111111111111111111111111111111111");
|
solana_program::declare_id!("Stake11111111111111111111111111111111111111");
|
||||||
|
|
||||||
const STAKE_CONFIG: &str = "StakeConfig11111111111111111111111111111111";
|
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
|
/// FIXME copied from solana stake program
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||||
|
@ -489,8 +493,18 @@ pub fn delegate_stake(
|
||||||
AccountMeta::new_readonly(*vote_pubkey, false),
|
AccountMeta::new_readonly(*vote_pubkey, false),
|
||||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
AccountMeta::new_readonly(sysvar::stake_history::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),
|
AccountMeta::new_readonly(*authorized_pubkey, true),
|
||||||
];
|
];
|
||||||
Instruction::new_with_bincode(id(), &StakeInstruction::DelegateStake, account_metas)
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -3,12 +3,16 @@
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
borsh::BorshDeserialize,
|
borsh::{BorshDeserialize, BorshSerialize},
|
||||||
helpers::*,
|
helpers::*,
|
||||||
solana_program::hash::Hash,
|
solana_program::{
|
||||||
|
hash::Hash,
|
||||||
|
instruction::{AccountMeta, Instruction, InstructionError},
|
||||||
|
pubkey::Pubkey,
|
||||||
|
sysvar,
|
||||||
|
},
|
||||||
solana_program_test::*,
|
solana_program_test::*,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
instruction::InstructionError,
|
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
transaction::TransactionError,
|
transaction::TransactionError,
|
||||||
|
@ -237,26 +241,32 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let wrong_stake_program = Keypair::new();
|
let wrong_stake_program = Pubkey::new_unique();
|
||||||
|
|
||||||
let mut transaction = Transaction::new_with_payer(
|
let accounts = vec![
|
||||||
&[instruction::deposit(
|
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
|
||||||
&id(),
|
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false),
|
||||||
&stake_pool_accounts.validator_list.pubkey(),
|
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
|
||||||
&stake_pool_accounts.deposit_authority,
|
AccountMeta::new(user_stake.pubkey(), false),
|
||||||
&stake_pool_accounts.withdraw_authority,
|
AccountMeta::new(validator_stake_account.stake_account, false),
|
||||||
&user_stake.pubkey(),
|
AccountMeta::new(user_pool_account.pubkey(), false),
|
||||||
&validator_stake_account.stake_account,
|
AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false),
|
||||||
&user_pool_account.pubkey(),
|
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
|
||||||
&stake_pool_accounts.pool_fee_account.pubkey(),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
|
||||||
&spl_token::id(),
|
AccountMeta::new_readonly(spl_token::id(), false),
|
||||||
&wrong_stake_program.pubkey(),
|
AccountMeta::new_readonly(wrong_stake_program, false),
|
||||||
)
|
];
|
||||||
.unwrap()],
|
let instruction = Instruction {
|
||||||
Some(&payer.pubkey()),
|
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);
|
transaction.sign(&[&payer], recent_blockhash);
|
||||||
let transaction_error = banks_client
|
let transaction_error = banks_client
|
||||||
.process_transaction(transaction)
|
.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_fee_account.pubkey(),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&wrong_token_program.pubkey(),
|
&wrong_token_program.pubkey(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
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]
|
#[tokio::test]
|
||||||
async fn test_stake_pool_deposit_to_unknown_validator() {
|
async fn test_stake_pool_deposit_to_unknown_validator() {
|
||||||
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
|
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(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
validator_stake_account
|
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;
|
.await;
|
||||||
|
|
||||||
let user_pool_account = Keypair::new();
|
let user_pool_account = Keypair::new();
|
||||||
|
|
|
@ -300,30 +300,26 @@ pub async fn create_validator_stake_account(
|
||||||
payer: &Keypair,
|
payer: &Keypair,
|
||||||
recent_blockhash: &Hash,
|
recent_blockhash: &Hash,
|
||||||
stake_pool: &Pubkey,
|
stake_pool: &Pubkey,
|
||||||
|
owner: &Keypair,
|
||||||
stake_account: &Pubkey,
|
stake_account: &Pubkey,
|
||||||
validator: &Pubkey,
|
validator: &Pubkey,
|
||||||
stake_authority: &Pubkey,
|
|
||||||
withdraw_authority: &Pubkey,
|
|
||||||
) {
|
) {
|
||||||
let mut transaction = Transaction::new_with_payer(
|
let mut transaction = Transaction::new_with_payer(
|
||||||
&[
|
&[
|
||||||
instruction::create_validator_stake_account(
|
instruction::create_validator_stake_account(
|
||||||
&id(),
|
&id(),
|
||||||
&stake_pool,
|
&stake_pool,
|
||||||
|
&owner.pubkey(),
|
||||||
&payer.pubkey(),
|
&payer.pubkey(),
|
||||||
&stake_account,
|
&stake_account,
|
||||||
&validator,
|
&validator,
|
||||||
&stake_authority,
|
|
||||||
&withdraw_authority,
|
|
||||||
&solana_program::system_program::id(),
|
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
system_instruction::transfer(&payer.pubkey(), &stake_account, TEST_STAKE_AMOUNT),
|
system_instruction::transfer(&payer.pubkey(), &stake_account, TEST_STAKE_AMOUNT),
|
||||||
],
|
],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
);
|
);
|
||||||
transaction.sign(&[payer], *recent_blockhash);
|
transaction.sign(&[payer, owner], *recent_blockhash);
|
||||||
banks_client.process_transaction(transaction).await.unwrap();
|
banks_client.process_transaction(transaction).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,29 +389,18 @@ impl ValidatorStakeAccount {
|
||||||
mut banks_client: &mut BanksClient,
|
mut banks_client: &mut BanksClient,
|
||||||
payer: &Keypair,
|
payer: &Keypair,
|
||||||
recent_blockhash: &Hash,
|
recent_blockhash: &Hash,
|
||||||
|
owner: &Keypair,
|
||||||
) {
|
) {
|
||||||
// make stake account
|
create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await;
|
||||||
let user_stake_authority = Keypair::new();
|
|
||||||
create_validator_stake_account(
|
create_validator_stake_account(
|
||||||
&mut banks_client,
|
&mut banks_client,
|
||||||
&payer,
|
&payer,
|
||||||
&recent_blockhash,
|
&recent_blockhash,
|
||||||
&self.stake_pool,
|
&self.stake_pool,
|
||||||
|
owner,
|
||||||
&self.stake_account,
|
&self.stake_account,
|
||||||
&self.vote.pubkey(),
|
&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;
|
.await;
|
||||||
|
|
||||||
|
@ -424,11 +409,22 @@ impl ValidatorStakeAccount {
|
||||||
&payer,
|
&payer,
|
||||||
&recent_blockhash,
|
&recent_blockhash,
|
||||||
&self.stake_account,
|
&self.stake_account,
|
||||||
&user_stake_authority,
|
&owner,
|
||||||
&self.target_authority,
|
&self.target_authority,
|
||||||
stake::StakeAuthorize::Staker,
|
stake::StakeAuthorize::Staker,
|
||||||
)
|
)
|
||||||
.await;
|
.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_fee_account.pubkey(),
|
||||||
&self.pool_mint.pubkey(),
|
&self.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -575,7 +570,6 @@ impl StakePoolAccounts {
|
||||||
pool_account,
|
pool_account,
|
||||||
&self.pool_mint.pubkey(),
|
&self.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
amount,
|
amount,
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
|
@ -606,7 +600,6 @@ impl StakePoolAccounts {
|
||||||
pool_account,
|
pool_account,
|
||||||
&self.pool_mint.pubkey(),
|
&self.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -636,7 +629,6 @@ impl StakePoolAccounts {
|
||||||
pool_account,
|
pool_account,
|
||||||
&self.pool_mint.pubkey(),
|
&self.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -657,7 +649,12 @@ pub async fn simple_add_validator_to_pool(
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
user_stake
|
user_stake
|
||||||
.create_and_delegate(banks_client, &payer, &recent_blockhash)
|
.create_and_delegate(
|
||||||
|
banks_client,
|
||||||
|
&payer,
|
||||||
|
&recent_blockhash,
|
||||||
|
&stake_pool_accounts.owner,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let user_pool_account = Keypair::new();
|
let user_pool_account = Keypair::new();
|
||||||
|
|
|
@ -8,12 +8,12 @@ use {
|
||||||
helpers::*,
|
helpers::*,
|
||||||
solana_program::{
|
solana_program::{
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
instruction::{AccountMeta, Instruction},
|
instruction::{AccountMeta, Instruction, InstructionError},
|
||||||
|
pubkey::Pubkey,
|
||||||
sysvar,
|
sysvar,
|
||||||
},
|
},
|
||||||
solana_program_test::*,
|
solana_program_test::*,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
instruction::InstructionError,
|
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
transaction::{Transaction, TransactionError},
|
transaction::{Transaction, TransactionError},
|
||||||
transport::TransportError,
|
transport::TransportError,
|
||||||
|
@ -43,7 +43,12 @@ async fn setup() -> (
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
user_stake
|
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;
|
.await;
|
||||||
|
|
||||||
// make pool token account
|
// make pool token account
|
||||||
|
@ -170,7 +175,6 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&stake::id(),
|
&stake::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -215,7 +219,6 @@ async fn test_add_validator_to_pool_with_wrong_pool_mint_account() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&wrong_pool_mint.pubkey(),
|
&wrong_pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -264,7 +267,6 @@ async fn test_add_validator_to_pool_with_wrong_validator_list_account() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -359,7 +361,6 @@ async fn test_not_owner_try_to_add_validator_to_pool() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
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]
|
#[tokio::test]
|
||||||
async fn test_add_validator_to_pool_with_wrong_stake_program_id() {
|
async fn test_add_validator_to_pool_with_wrong_stake_program_id() {
|
||||||
let (
|
let (
|
||||||
|
@ -510,25 +448,30 @@ async fn test_add_validator_to_pool_with_wrong_stake_program_id() {
|
||||||
user_pool_account,
|
user_pool_account,
|
||||||
) = setup().await;
|
) = setup().await;
|
||||||
|
|
||||||
let wrong_stake_program = Keypair::new();
|
let wrong_stake_program = Pubkey::new_unique();
|
||||||
|
|
||||||
let mut transaction = Transaction::new_with_payer(
|
let accounts = vec![
|
||||||
&[instruction::add_validator_to_pool(
|
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
|
||||||
&id(),
|
AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true),
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false),
|
||||||
&stake_pool_accounts.owner.pubkey(),
|
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
|
||||||
&stake_pool_accounts.deposit_authority,
|
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
|
||||||
&stake_pool_accounts.withdraw_authority,
|
AccountMeta::new(user_stake.stake_account, false),
|
||||||
&stake_pool_accounts.validator_list.pubkey(),
|
AccountMeta::new(user_pool_account.pubkey(), false),
|
||||||
&user_stake.stake_account,
|
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
|
||||||
&user_pool_account.pubkey(),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
|
||||||
&spl_token::id(),
|
AccountMeta::new_readonly(spl_token::id(), false),
|
||||||
&wrong_stake_program.pubkey(),
|
AccountMeta::new_readonly(wrong_stake_program, false),
|
||||||
)
|
];
|
||||||
.unwrap()],
|
let instruction = Instruction {
|
||||||
Some(&payer.pubkey()),
|
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);
|
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
|
||||||
let transaction_error = banks_client
|
let transaction_error = banks_client
|
||||||
.process_transaction(transaction)
|
.process_transaction(transaction)
|
||||||
|
@ -563,7 +506,12 @@ async fn test_add_too_many_validator_stake_accounts() {
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
user_stake
|
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;
|
.await;
|
||||||
|
|
||||||
// make pool token account
|
// make pool token account
|
||||||
|
@ -595,7 +543,12 @@ async fn test_add_too_many_validator_stake_accounts() {
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
user_stake
|
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;
|
.await;
|
||||||
let error = stake_pool_accounts
|
let error = stake_pool_accounts
|
||||||
.add_validator_to_pool(
|
.add_validator_to_pool(
|
||||||
|
|
|
@ -2,22 +2,76 @@
|
||||||
|
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
|
||||||
use crate::solana_program::pubkey::Pubkey;
|
use {
|
||||||
use helpers::*;
|
bincode::deserialize,
|
||||||
|
borsh::BorshSerialize,
|
||||||
use bincode::deserialize;
|
helpers::*,
|
||||||
use solana_program_test::*;
|
solana_program::{
|
||||||
use solana_sdk::{
|
instruction::{AccountMeta, Instruction, InstructionError},
|
||||||
instruction::InstructionError,
|
pubkey::Pubkey,
|
||||||
|
system_program, sysvar,
|
||||||
|
},
|
||||||
|
solana_program_test::*,
|
||||||
|
solana_sdk::{
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
transaction::TransactionError,
|
transaction::TransactionError,
|
||||||
transport::TransportError,
|
transport::TransportError,
|
||||||
|
},
|
||||||
|
spl_stake_pool::{error, id, instruction, processor, stake},
|
||||||
};
|
};
|
||||||
use spl_stake_pool::*;
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[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 (mut banks_client, payer, recent_blockhash) = program_test().start().await;
|
||||||
let stake_pool_accounts = StakePoolAccounts::new();
|
let stake_pool_accounts = StakePoolAccounts::new();
|
||||||
stake_pool_accounts
|
stake_pool_accounts
|
||||||
|
@ -26,8 +80,6 @@ async fn test_create_validator_stake_account() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let validator = Pubkey::new_unique();
|
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(
|
let (stake_account, _) = processor::Processor::find_stake_address_for_validator(
|
||||||
&id(),
|
&id(),
|
||||||
|
@ -39,37 +91,136 @@ async fn test_create_validator_stake_account() {
|
||||||
&[instruction::create_validator_stake_account(
|
&[instruction::create_validator_stake_account(
|
||||||
&id(),
|
&id(),
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
|
&stake_pool_accounts.owner.pubkey(),
|
||||||
&payer.pubkey(),
|
&payer.pubkey(),
|
||||||
&stake_account,
|
&stake_account,
|
||||||
&validator,
|
&validator,
|
||||||
&user_stake_authority.pubkey(),
|
|
||||||
&user_withdraw_authority.pubkey(),
|
|
||||||
&solana_program::system_program::id(),
|
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
);
|
);
|
||||||
transaction.sign(&[&payer], recent_blockhash);
|
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
|
||||||
banks_client.process_transaction(transaction).await.unwrap();
|
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!(
|
assert_eq!(
|
||||||
&meta.authorized.withdrawer,
|
transaction_error,
|
||||||
&user_withdraw_authority.pubkey()
|
TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[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 (mut banks_client, payer, recent_blockhash) = program_test().start().await;
|
||||||
let stake_pool_accounts = StakePoolAccounts::new();
|
let stake_pool_accounts = StakePoolAccounts::new();
|
||||||
stake_pool_accounts
|
stake_pool_accounts
|
||||||
|
@ -78,26 +229,21 @@ async fn test_create_validator_stake_account_with_incorrect_address() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let validator = Pubkey::new_unique();
|
let validator = Pubkey::new_unique();
|
||||||
let user_stake_authority = Keypair::new();
|
|
||||||
let user_withdraw_authority = Keypair::new();
|
|
||||||
let stake_account = Keypair::new();
|
let stake_account = Keypair::new();
|
||||||
|
|
||||||
let mut transaction = Transaction::new_with_payer(
|
let mut transaction = Transaction::new_with_payer(
|
||||||
&[instruction::create_validator_stake_account(
|
&[instruction::create_validator_stake_account(
|
||||||
&id(),
|
&id(),
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
|
&stake_pool_accounts.owner.pubkey(),
|
||||||
&payer.pubkey(),
|
&payer.pubkey(),
|
||||||
&stake_account.pubkey(),
|
&stake_account.pubkey(),
|
||||||
&validator,
|
&validator,
|
||||||
&user_stake_authority.pubkey(),
|
|
||||||
&user_withdraw_authority.pubkey(),
|
|
||||||
&solana_program::system_program::id(),
|
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
);
|
);
|
||||||
transaction.sign(&[&payer], recent_blockhash);
|
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
|
||||||
let transaction_error = banks_client
|
let transaction_error = banks_client
|
||||||
.process_transaction(transaction)
|
.process_transaction(transaction)
|
||||||
.await
|
.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"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,13 +8,12 @@ use {
|
||||||
helpers::*,
|
helpers::*,
|
||||||
solana_program::{
|
solana_program::{
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
instruction::{AccountMeta, Instruction},
|
instruction::{AccountMeta, Instruction, InstructionError},
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
sysvar,
|
sysvar,
|
||||||
},
|
},
|
||||||
solana_program_test::*,
|
solana_program_test::*,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
instruction::InstructionError,
|
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
transaction::{Transaction, TransactionError},
|
transaction::{Transaction, TransactionError},
|
||||||
transport::TransportError,
|
transport::TransportError,
|
||||||
|
@ -45,7 +44,12 @@ async fn setup() -> (
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
user_stake
|
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;
|
.await;
|
||||||
|
|
||||||
// make pool token account
|
// make pool token account
|
||||||
|
@ -165,26 +169,31 @@ async fn test_remove_validator_from_pool_with_wrong_stake_program_id() {
|
||||||
_,
|
_,
|
||||||
) = setup().await;
|
) = setup().await;
|
||||||
|
|
||||||
let wrong_stake_program = Keypair::new();
|
let wrong_stake_program = Pubkey::new_unique();
|
||||||
|
|
||||||
let new_authority = Pubkey::new_unique();
|
let new_authority = Pubkey::new_unique();
|
||||||
let mut transaction = Transaction::new_with_payer(
|
let accounts = vec![
|
||||||
&[instruction::remove_validator_from_pool(
|
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
|
||||||
&id(),
|
AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true),
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
|
||||||
&stake_pool_accounts.owner.pubkey(),
|
AccountMeta::new_readonly(new_authority, false),
|
||||||
&stake_pool_accounts.withdraw_authority,
|
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
|
||||||
&new_authority,
|
AccountMeta::new(user_stake.stake_account, false),
|
||||||
&stake_pool_accounts.validator_list.pubkey(),
|
AccountMeta::new(user_pool_account.pubkey(), false),
|
||||||
&user_stake.stake_account,
|
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
|
||||||
&user_pool_account.pubkey(),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
AccountMeta::new_readonly(spl_token::id(), false),
|
||||||
&spl_token::id(),
|
AccountMeta::new_readonly(wrong_stake_program, false),
|
||||||
&wrong_stake_program.pubkey(),
|
];
|
||||||
)
|
let instruction = Instruction {
|
||||||
.unwrap()],
|
program_id: id(),
|
||||||
Some(&payer.pubkey()),
|
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);
|
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
|
||||||
let transaction_error = banks_client
|
let transaction_error = banks_client
|
||||||
.process_transaction(transaction)
|
.process_transaction(transaction)
|
||||||
|
@ -230,7 +239,6 @@ async fn test_remove_validator_from_pool_with_wrong_token_program_id() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&wrong_token_program.pubkey(),
|
&wrong_token_program.pubkey(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -277,7 +285,6 @@ async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&wrong_pool_mint.pubkey(),
|
&wrong_pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -328,7 +335,6 @@ async fn test_remove_validator_from_pool_with_wrong_validator_list_account() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
|
@ -444,7 +450,6 @@ async fn test_not_owner_try_to_remove_validator_from_pool() {
|
||||||
&user_pool_account.pubkey(),
|
&user_pool_account.pubkey(),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
&stake::id(),
|
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.unwrap()],
|
||||||
Some(&payer.pubkey()),
|
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]
|
#[tokio::test]
|
||||||
async fn test_remove_validator_from_pool_from_unupdated_stake_pool() {} // TODO
|
async fn test_remove_validator_from_pool_from_unupdated_stake_pool() {} // TODO
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,16 @@
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
borsh::BorshDeserialize,
|
borsh::{BorshDeserialize, BorshSerialize},
|
||||||
helpers::*,
|
helpers::*,
|
||||||
solana_program::hash::Hash,
|
solana_program::{
|
||||||
solana_program::pubkey::Pubkey,
|
hash::Hash,
|
||||||
|
instruction::{AccountMeta, Instruction, InstructionError},
|
||||||
|
pubkey::Pubkey,
|
||||||
|
sysvar,
|
||||||
|
},
|
||||||
solana_program_test::*,
|
solana_program_test::*,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
instruction::InstructionError,
|
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
transaction::{Transaction, TransactionError},
|
transaction::{Transaction, TransactionError},
|
||||||
transport::TransportError,
|
transport::TransportError,
|
||||||
|
@ -204,26 +207,30 @@ async fn test_stake_pool_withdraw_with_wrong_stake_program() {
|
||||||
let user_stake_recipient = Keypair::new();
|
let user_stake_recipient = Keypair::new();
|
||||||
|
|
||||||
let new_authority = Pubkey::new_unique();
|
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(
|
let accounts = vec![
|
||||||
&[instruction::withdraw(
|
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
|
||||||
&id(),
|
AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false),
|
||||||
&stake_pool_accounts.stake_pool.pubkey(),
|
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
|
||||||
&stake_pool_accounts.validator_list.pubkey(),
|
AccountMeta::new(validator_stake_account.stake_account, false),
|
||||||
&stake_pool_accounts.withdraw_authority,
|
AccountMeta::new(user_stake_recipient.pubkey(), false),
|
||||||
&validator_stake_account.stake_account,
|
AccountMeta::new_readonly(new_authority, false),
|
||||||
&user_stake_recipient.pubkey(),
|
AccountMeta::new(deposit_info.user_pool_account, false),
|
||||||
&new_authority,
|
AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false),
|
||||||
&deposit_info.user_pool_account,
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
AccountMeta::new_readonly(spl_token::id(), false),
|
||||||
&spl_token::id(),
|
AccountMeta::new_readonly(wrong_stake_program, false),
|
||||||
&wrong_stake_program.pubkey(),
|
];
|
||||||
tokens_to_burn,
|
let instruction = Instruction {
|
||||||
)
|
program_id: id(),
|
||||||
.unwrap()],
|
accounts,
|
||||||
Some(&payer.pubkey()),
|
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);
|
transaction.sign(&[&payer], recent_blockhash);
|
||||||
let transaction_error = banks_client
|
let transaction_error = banks_client
|
||||||
.process_transaction(transaction)
|
.process_transaction(transaction)
|
||||||
|
@ -314,7 +321,6 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() {
|
||||||
&deposit_info.user_pool_account,
|
&deposit_info.user_pool_account,
|
||||||
&stake_pool_accounts.pool_mint.pubkey(),
|
&stake_pool_accounts.pool_mint.pubkey(),
|
||||||
&wrong_token_program.pubkey(),
|
&wrong_token_program.pubkey(),
|
||||||
&stake::id(),
|
|
||||||
tokens_to_burn,
|
tokens_to_burn,
|
||||||
)
|
)
|
||||||
.unwrap()],
|
.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]
|
#[tokio::test]
|
||||||
async fn test_stake_pool_withdraw_from_unknown_validator() {
|
async fn test_stake_pool_withdraw_from_unknown_validator() {
|
||||||
let (mut banks_client, payer, recent_blockhash) = program_test().start().await;
|
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(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
validator_stake_account
|
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;
|
.await;
|
||||||
|
|
||||||
let user_stake = ValidatorStakeAccount::new_with_target_authority(
|
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(),
|
&stake_pool_accounts.stake_pool.pubkey(),
|
||||||
);
|
);
|
||||||
user_stake
|
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;
|
.await;
|
||||||
|
|
||||||
let user_pool_account = Keypair::new();
|
let user_pool_account = Keypair::new();
|
||||||
|
|
Loading…
Reference in New Issue