Set staking authority instruction removed (#1469)
* Set staking authority instruction removed * Fixed fmt errors
This commit is contained in:
parent
662f38f939
commit
d0bf7157cf
|
@ -30,7 +30,7 @@ use spl_stake_pool::{
|
|||
instruction::{
|
||||
add_validator_stake_account, create_validator_stake_account, deposit,
|
||||
initialize as initialize_pool, remove_validator_stake_account, set_owner,
|
||||
set_staking_authority, update_list_balance, update_pool_balance, withdraw, Fee as PoolFee,
|
||||
update_list_balance, update_pool_balance, withdraw, Fee as PoolFee,
|
||||
InitArgs as PoolInitArgs,
|
||||
},
|
||||
processor::Processor as PoolProcessor,
|
||||
|
@ -947,44 +947,6 @@ fn command_withdraw(
|
|||
Ok(Some(transaction))
|
||||
}
|
||||
|
||||
fn command_set_staking_auth(
|
||||
config: &Config,
|
||||
pool: &Pubkey,
|
||||
stake_account: &Pubkey,
|
||||
new_staker: &Pubkey,
|
||||
) -> CommandResult {
|
||||
let pool_data = config.rpc_client.get_account_data(&pool)?;
|
||||
let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap();
|
||||
|
||||
let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id(
|
||||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
PoolProcessor::AUTHORITY_WITHDRAW,
|
||||
pool_data.withdraw_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[set_staking_authority(
|
||||
&spl_stake_pool::id(),
|
||||
&pool,
|
||||
&config.owner.pubkey(),
|
||||
&pool_withdraw_authority,
|
||||
&stake_account,
|
||||
&new_staker,
|
||||
&stake_program_id(),
|
||||
)?],
|
||||
Some(&config.fee_payer.pubkey()),
|
||||
);
|
||||
|
||||
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
|
||||
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
|
||||
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
|
||||
unique_signers!(signers);
|
||||
transaction.sign(&signers, recent_blockhash);
|
||||
Ok(Some(transaction))
|
||||
}
|
||||
|
||||
fn command_set_owner(
|
||||
config: &Config,
|
||||
pool: &Pubkey,
|
||||
|
@ -1299,35 +1261,6 @@ fn main() {
|
|||
.help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."),
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("set-staking-auth").about("Changes staking authority of one of the accounts from the stake pool.")
|
||||
.arg(
|
||||
Arg::with_name("pool")
|
||||
.long("pool")
|
||||
.validator(is_pubkey)
|
||||
.value_name("ADDRESS")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.help("Stake pool address."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("stake_account")
|
||||
.long("stake-account")
|
||||
.validator(is_pubkey)
|
||||
.value_name("ADDRESS")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.help("Stake account address to change staking authority."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("new_staker")
|
||||
.long("new-staker")
|
||||
.validator(is_pubkey)
|
||||
.value_name("ADDRESS")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.help("Public key of the new staker account."),
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("set-owner").about("Changes owner or fee receiver account for the stake pool.")
|
||||
.arg(
|
||||
Arg::with_name("pool")
|
||||
|
@ -1470,12 +1403,6 @@ fn main() {
|
|||
&stake_receiver,
|
||||
)
|
||||
}
|
||||
("set-staking-auth", Some(arg_matches)) => {
|
||||
let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap();
|
||||
let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap();
|
||||
let new_staker: Pubkey = pubkey_of(arg_matches, "new_staker").unwrap();
|
||||
command_set_staking_auth(&config, &pool_account, &stake_account, &new_staker)
|
||||
}
|
||||
("set-owner", Some(arg_matches)) => {
|
||||
let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap();
|
||||
let new_owner: Option<Pubkey> = pubkey_of(arg_matches, "new_owner");
|
||||
|
|
|
@ -140,17 +140,6 @@ pub enum StakePoolInstruction {
|
|||
/// userdata: amount to withdraw
|
||||
Withdraw(u64),
|
||||
|
||||
/// Update the staking pubkey for a stake
|
||||
///
|
||||
/// 0. `[w]` StakePool
|
||||
/// 1. `[s]` Owner
|
||||
/// 2. `[]` withdraw authority
|
||||
/// 3. `[w]` Stake to update the staking pubkey
|
||||
/// 4. '[]` Staking pubkey.
|
||||
/// 5. '[]' Sysvar clock account (reserved for future use)
|
||||
/// 6. `[]` Stake program id,
|
||||
SetStakingAuthority,
|
||||
|
||||
/// Update owner
|
||||
///
|
||||
/// 0. `[w]` StakePool
|
||||
|
@ -182,8 +171,7 @@ impl StakePoolInstruction {
|
|||
let val: &u64 = unpack(input)?;
|
||||
Self::Withdraw(*val)
|
||||
}
|
||||
8 => Self::SetStakingAuthority,
|
||||
9 => Self::SetOwner,
|
||||
8 => Self::SetOwner,
|
||||
_ => return Err(ProgramError::InvalidAccountData),
|
||||
})
|
||||
}
|
||||
|
@ -223,11 +211,8 @@ impl StakePoolInstruction {
|
|||
let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut u64) };
|
||||
*value = *val;
|
||||
}
|
||||
Self::SetStakingAuthority => {
|
||||
output[0] = 8;
|
||||
}
|
||||
Self::SetOwner => {
|
||||
output[0] = 9;
|
||||
output[0] = 8;
|
||||
}
|
||||
}
|
||||
Ok(output)
|
||||
|
@ -486,34 +471,6 @@ pub fn withdraw(
|
|||
})
|
||||
}
|
||||
|
||||
/// Creates a 'set staking authority' instruction.
|
||||
pub fn set_staking_authority(
|
||||
program_id: &Pubkey,
|
||||
stake_pool: &Pubkey,
|
||||
stake_pool_owner: &Pubkey,
|
||||
stake_pool_withdraw: &Pubkey,
|
||||
stake_account_to_update: &Pubkey,
|
||||
stake_account_new_authority: &Pubkey,
|
||||
stake_program_id: &Pubkey,
|
||||
) -> Result<Instruction, ProgramError> {
|
||||
let args = StakePoolInstruction::SetStakingAuthority;
|
||||
let data = args.serialize()?;
|
||||
let accounts = vec![
|
||||
AccountMeta::new(*stake_pool, false),
|
||||
AccountMeta::new_readonly(*stake_pool_owner, true),
|
||||
AccountMeta::new_readonly(*stake_pool_withdraw, false),
|
||||
AccountMeta::new(*stake_account_to_update, false),
|
||||
AccountMeta::new_readonly(*stake_account_new_authority, false),
|
||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||
AccountMeta::new_readonly(*stake_program_id, false),
|
||||
];
|
||||
Ok(Instruction {
|
||||
program_id: *program_id,
|
||||
accounts,
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a 'set owner' instruction.
|
||||
pub fn set_owner(
|
||||
program_id: &Pubkey,
|
||||
|
|
|
@ -1147,51 +1147,6 @@ impl Processor {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
/// Processes [SetStakeAuthority](enum.Instruction.html).
|
||||
pub fn process_set_staking_auth(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||
let owner_info = next_account_info(account_info_iter)?;
|
||||
let withdraw_info = next_account_info(account_info_iter)?;
|
||||
let stake_info = next_account_info(account_info_iter)?;
|
||||
let staker_info = next_account_info(account_info_iter)?;
|
||||
// (Reserved)
|
||||
let reserved = next_account_info(account_info_iter)?;
|
||||
// Stake program id
|
||||
let stake_program_info = next_account_info(account_info_iter)?;
|
||||
|
||||
// Check program ids
|
||||
if *stake_program_info.key != stake::id() {
|
||||
return Err(ProgramError::IncorrectProgramId);
|
||||
}
|
||||
|
||||
let stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?;
|
||||
if !stake_pool.is_initialized() {
|
||||
return Err(StakePoolError::InvalidState.into());
|
||||
}
|
||||
|
||||
// Check authority account
|
||||
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
||||
|
||||
// Check owner validity and signature
|
||||
stake_pool.check_owner(owner_info)?;
|
||||
|
||||
Self::stake_authorize(
|
||||
stake_pool_info.key,
|
||||
stake_info.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
staker_info.key,
|
||||
stake::StakeAuthorize::Staker,
|
||||
reserved.clone(),
|
||||
stake_program_info.clone(),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Processes [SetOwner](enum.Instruction.html).
|
||||
pub fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||
|
@ -1257,10 +1212,6 @@ impl Processor {
|
|||
msg!("Instruction: Withdraw");
|
||||
Self::process_withdraw(program_id, amount, accounts)
|
||||
}
|
||||
StakePoolInstruction::SetStakingAuthority => {
|
||||
msg!("Instruction: SetStakingAuthority");
|
||||
Self::process_set_staking_auth(program_id, accounts)
|
||||
}
|
||||
StakePoolInstruction::SetOwner => {
|
||||
msg!("Instruction: SetOwner");
|
||||
Self::process_set_owner(program_id, accounts)
|
||||
|
|
|
@ -1,273 +0,0 @@
|
|||
#![cfg(feature = "test-bpf")]
|
||||
|
||||
mod helpers;
|
||||
|
||||
use bincode::deserialize;
|
||||
use helpers::*;
|
||||
use solana_program::hash::Hash;
|
||||
use solana_program::instruction::AccountMeta;
|
||||
use solana_program::instruction::Instruction;
|
||||
use solana_program::sysvar;
|
||||
use solana_program_test::*;
|
||||
use solana_sdk::{
|
||||
instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction,
|
||||
transaction::TransactionError, transport::TransportError,
|
||||
};
|
||||
use spl_stake_pool::*;
|
||||
|
||||
async fn setup() -> (
|
||||
BanksClient,
|
||||
Keypair,
|
||||
Hash,
|
||||
StakePoolAccounts,
|
||||
ValidatorStakeAccount,
|
||||
) {
|
||||
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(),
|
||||
);
|
||||
user_stake
|
||||
.create_and_delegate(&mut banks_client, &payer, &recent_blockhash)
|
||||
.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 error = stake_pool_accounts
|
||||
.add_validator_stake_account(
|
||||
&mut banks_client,
|
||||
&payer,
|
||||
&recent_blockhash,
|
||||
&user_stake.stake_account,
|
||||
&user_pool_account.pubkey(),
|
||||
)
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
(
|
||||
banks_client,
|
||||
payer,
|
||||
recent_blockhash,
|
||||
stake_pool_accounts,
|
||||
user_stake,
|
||||
)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_set_staking_authority() {
|
||||
let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) =
|
||||
setup().await;
|
||||
|
||||
let new_staking_pubkey = Keypair::new().pubkey();
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[instruction::set_staking_authority(
|
||||
&id(),
|
||||
&stake_pool_accounts.stake_pool.pubkey(),
|
||||
&stake_pool_accounts.owner.pubkey(),
|
||||
&stake_pool_accounts.withdraw_authority,
|
||||
&user_stake.stake_account,
|
||||
&new_staking_pubkey,
|
||||
&stake::id(),
|
||||
)
|
||||
.unwrap()],
|
||||
Some(&payer.pubkey()),
|
||||
);
|
||||
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
|
||||
banks_client.process_transaction(transaction).await.unwrap();
|
||||
|
||||
// Check of stake account authority has changed
|
||||
let stake = get_account(&mut banks_client, &user_stake.stake_account).await;
|
||||
let stake_state = deserialize::<stake::StakeState>(&stake.data).unwrap();
|
||||
match stake_state {
|
||||
stake::StakeState::Stake(meta, _) => {
|
||||
assert_eq!(&meta.authorized.staker, &new_staking_pubkey);
|
||||
assert_eq!(
|
||||
&meta.authorized.withdrawer,
|
||||
&stake_pool_accounts.withdraw_authority
|
||||
);
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_set_staking_authority_with_wrong_stake_program_id() {
|
||||
let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) =
|
||||
setup().await;
|
||||
|
||||
let new_staking_pubkey = Keypair::new().pubkey();
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[instruction::set_staking_authority(
|
||||
&id(),
|
||||
&stake_pool_accounts.stake_pool.pubkey(),
|
||||
&stake_pool_accounts.owner.pubkey(),
|
||||
&stake_pool_accounts.withdraw_authority,
|
||||
&user_stake.stake_account,
|
||||
&new_staking_pubkey,
|
||||
&Keypair::new().pubkey(),
|
||||
)
|
||||
.unwrap()],
|
||||
Some(&payer.pubkey()),
|
||||
);
|
||||
transaction.sign(&[&payer, &stake_pool_accounts.owner], 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 set staking authority with wrong stake program ID"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_set_staking_authority_with_wrong_withdraw_authority() {
|
||||
let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) =
|
||||
setup().await;
|
||||
|
||||
let new_staking_pubkey = Keypair::new().pubkey();
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[instruction::set_staking_authority(
|
||||
&id(),
|
||||
&stake_pool_accounts.stake_pool.pubkey(),
|
||||
&stake_pool_accounts.owner.pubkey(),
|
||||
&Keypair::new().pubkey(),
|
||||
&user_stake.stake_account,
|
||||
&new_staking_pubkey,
|
||||
&stake::id(),
|
||||
)
|
||||
.unwrap()],
|
||||
Some(&payer.pubkey()),
|
||||
);
|
||||
transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash);
|
||||
let transaction_error = banks_client
|
||||
.process_transaction(transaction)
|
||||
.await
|
||||
.err()
|
||||
.unwrap();
|
||||
|
||||
match transaction_error {
|
||||
TransportError::TransactionError(TransactionError::InstructionError(
|
||||
_,
|
||||
InstructionError::Custom(error_index),
|
||||
)) => {
|
||||
let program_error = error::StakePoolError::InvalidProgramAddress as u32;
|
||||
assert_eq!(error_index, program_error);
|
||||
}
|
||||
_ => panic!(
|
||||
"Wrong error occurs while try to set staking authority with wrong withdraw authority"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_set_staking_authority_with_wrong_owner() {
|
||||
let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) =
|
||||
setup().await;
|
||||
|
||||
let new_staking_pubkey = Keypair::new().pubkey();
|
||||
let wrong_owner = Keypair::new();
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[instruction::set_staking_authority(
|
||||
&id(),
|
||||
&stake_pool_accounts.stake_pool.pubkey(),
|
||||
&wrong_owner.pubkey(),
|
||||
&stake_pool_accounts.withdraw_authority,
|
||||
&user_stake.stake_account,
|
||||
&new_staking_pubkey,
|
||||
&stake::id(),
|
||||
)
|
||||
.unwrap()],
|
||||
Some(&payer.pubkey()),
|
||||
);
|
||||
transaction.sign(&[&payer, &wrong_owner], recent_blockhash);
|
||||
let transaction_error = banks_client
|
||||
.process_transaction(transaction)
|
||||
.await
|
||||
.err()
|
||||
.unwrap();
|
||||
|
||||
match transaction_error {
|
||||
TransportError::TransactionError(TransactionError::InstructionError(
|
||||
_,
|
||||
InstructionError::Custom(error_index),
|
||||
)) => {
|
||||
let program_error = error::StakePoolError::WrongOwner as u32;
|
||||
assert_eq!(error_index, program_error);
|
||||
}
|
||||
_ => panic!("Wrong error occurs while try to set staking authority with wrong owner"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_set_staking_authority_without_signature() {
|
||||
let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) =
|
||||
setup().await;
|
||||
|
||||
let new_staking_pubkey = Keypair::new().pubkey();
|
||||
|
||||
let args = instruction::StakePoolInstruction::SetStakingAuthority;
|
||||
let data = args.serialize().unwrap();
|
||||
let accounts = vec![
|
||||
AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false),
|
||||
AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false),
|
||||
AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false),
|
||||
AccountMeta::new(user_stake.stake_account, false),
|
||||
AccountMeta::new_readonly(new_staking_pubkey, false),
|
||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||
AccountMeta::new_readonly(stake::id(), false),
|
||||
];
|
||||
let instruction = Instruction {
|
||||
program_id: id(),
|
||||
accounts,
|
||||
data,
|
||||
};
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(&[instruction], 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(
|
||||
_,
|
||||
InstructionError::Custom(error_index),
|
||||
)) => {
|
||||
let program_error = error::StakePoolError::SignatureMissing as u32;
|
||||
assert_eq!(error_index, program_error);
|
||||
}
|
||||
_ => panic!("Wrong error occurs while try to set staking authority without signature"),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue