De-tangle processor/state dependencies
This commit is contained in:
parent
b97849d206
commit
67cb90f39c
|
@ -120,7 +120,7 @@ fn command_create_pool(
|
|||
let pool_account_balance = config
|
||||
.rpc_client
|
||||
.get_minimum_balance_for_rent_exemption(get_packed_len::<StakePool>())?;
|
||||
let empty_validator_list = ValidatorList::new_with_max_validators(max_validators);
|
||||
let empty_validator_list = ValidatorList::new(max_validators);
|
||||
let validator_list_size = get_instance_packed_len(&empty_validator_list)?;
|
||||
let validator_list_balance = config
|
||||
.rpc_client
|
||||
|
@ -272,7 +272,7 @@ fn command_vsa_add(
|
|||
command_update(config, pool)?;
|
||||
}
|
||||
|
||||
let pool_data = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let stake_pool = get_stake_pool(&config.rpc_client, pool)?;
|
||||
|
||||
let mut total_rent_free_balances: u64 = 0;
|
||||
|
||||
|
@ -286,7 +286,7 @@ fn command_vsa_add(
|
|||
&config,
|
||||
&token_receiver,
|
||||
&token_receiver_account,
|
||||
&pool_data.pool_mint,
|
||||
&stake_pool.pool_mint,
|
||||
&mut instructions,
|
||||
|balance| {
|
||||
signers.push(&token_receiver_account);
|
||||
|
@ -299,14 +299,14 @@ fn command_vsa_add(
|
|||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
AUTHORITY_DEPOSIT,
|
||||
pool_data.deposit_bump_seed,
|
||||
stake_pool.deposit_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
let pool_withdraw_authority: Pubkey = create_pool_authority_address(
|
||||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
AUTHORITY_WITHDRAW,
|
||||
pool_data.withdraw_bump_seed,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -332,10 +332,10 @@ fn command_vsa_add(
|
|||
&config.owner.pubkey(),
|
||||
&pool_deposit_authority,
|
||||
&pool_withdraw_authority,
|
||||
&pool_data.validator_list,
|
||||
&stake_pool.validator_list,
|
||||
&stake,
|
||||
&token_receiver,
|
||||
&pool_data.pool_mint,
|
||||
&stake_pool.pool_mint,
|
||||
&spl_token::id(),
|
||||
)?,
|
||||
]);
|
||||
|
@ -365,12 +365,12 @@ fn command_vsa_remove(
|
|||
command_update(config, pool)?;
|
||||
}
|
||||
|
||||
let pool_data = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let stake_pool = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let pool_withdraw_authority: Pubkey = create_pool_authority_address(
|
||||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
AUTHORITY_WITHDRAW,
|
||||
pool_data.withdraw_bump_seed,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -379,16 +379,16 @@ fn command_vsa_remove(
|
|||
|
||||
// Calculate amount of tokens to withdraw
|
||||
let stake_account = config.rpc_client.get_account(&stake)?;
|
||||
let tokens_to_withdraw = pool_data
|
||||
let tokens_to_withdraw = stake_pool
|
||||
.calc_pool_withdraw_amount(stake_account.lamports)
|
||||
.unwrap();
|
||||
|
||||
// Check balance and mint
|
||||
let token_account =
|
||||
get_token_account(&config.rpc_client, &withdraw_from, &pool_data.pool_mint)?;
|
||||
get_token_account(&config.rpc_client, &withdraw_from, &stake_pool.pool_mint)?;
|
||||
|
||||
if token_account.amount < tokens_to_withdraw {
|
||||
let pool_mint = get_token_mint(&config.rpc_client, &pool_data.pool_mint)?;
|
||||
let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?;
|
||||
return Err(format!(
|
||||
"Not enough balance to burn to remove validator stake account from the pool. {} pool tokens needed.",
|
||||
spl_token::amount_to_ui_amount(tokens_to_withdraw, pool_mint.decimals)
|
||||
|
@ -413,10 +413,10 @@ fn command_vsa_remove(
|
|||
&config.owner.pubkey(),
|
||||
&pool_withdraw_authority,
|
||||
&new_authority,
|
||||
&pool_data.validator_list,
|
||||
&stake_pool.validator_list,
|
||||
&stake,
|
||||
&withdraw_from,
|
||||
&pool_data.pool_mint,
|
||||
&stake_pool.pool_mint,
|
||||
&spl_token::id(),
|
||||
)?,
|
||||
],
|
||||
|
@ -490,7 +490,7 @@ fn command_deposit(
|
|||
command_update(config, pool)?;
|
||||
}
|
||||
|
||||
let pool_data = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let stake_pool = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let stake_state = get_stake_state(&config.rpc_client, &stake)?;
|
||||
|
||||
if config.verbose {
|
||||
|
@ -502,7 +502,7 @@ fn command_deposit(
|
|||
}?;
|
||||
|
||||
// Check if this vote account has staking account in the pool
|
||||
let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?;
|
||||
let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?;
|
||||
if !validator_list.contains(&vote_account) {
|
||||
return Err("Stake account for this validator does not exist in the pool.".into());
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ fn command_deposit(
|
|||
&config,
|
||||
&token_receiver,
|
||||
&token_receiver_account,
|
||||
&pool_data.pool_mint,
|
||||
&stake_pool.pool_mint,
|
||||
&mut instructions,
|
||||
|balance| {
|
||||
signers.push(&token_receiver_account);
|
||||
|
@ -542,14 +542,14 @@ fn command_deposit(
|
|||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
AUTHORITY_DEPOSIT,
|
||||
pool_data.deposit_bump_seed,
|
||||
stake_pool.deposit_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
let pool_withdraw_authority: Pubkey = create_pool_authority_address(
|
||||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
AUTHORITY_WITHDRAW,
|
||||
pool_data.withdraw_bump_seed,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -572,14 +572,14 @@ fn command_deposit(
|
|||
spl_stake_pool::instruction::deposit(
|
||||
&spl_stake_pool::id(),
|
||||
&pool,
|
||||
&pool_data.validator_list,
|
||||
&stake_pool.validator_list,
|
||||
&pool_deposit_authority,
|
||||
&pool_withdraw_authority,
|
||||
&stake,
|
||||
&validator_stake_account,
|
||||
&token_receiver,
|
||||
&pool_data.owner_fee_account,
|
||||
&pool_data.pool_mint,
|
||||
&stake_pool.owner_fee_account,
|
||||
&stake_pool.pool_mint,
|
||||
&spl_token::id(),
|
||||
)?,
|
||||
]);
|
||||
|
@ -599,11 +599,11 @@ fn command_deposit(
|
|||
}
|
||||
|
||||
fn command_list(config: &Config, pool: &Pubkey) -> CommandResult {
|
||||
let pool_data = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let stake_pool = get_stake_pool(&config.rpc_client, pool)?;
|
||||
|
||||
if config.verbose {
|
||||
println!("Current validator list");
|
||||
let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?;
|
||||
let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?;
|
||||
for validator in validator_list.validators {
|
||||
println!(
|
||||
"Vote Account: {}\tBalance: {}\tEpoch: {}",
|
||||
|
@ -616,7 +616,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult {
|
|||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
AUTHORITY_WITHDRAW,
|
||||
pool_data.withdraw_bump_seed,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -641,8 +641,8 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult {
|
|||
}
|
||||
|
||||
fn command_update(config: &Config, pool: &Pubkey) -> CommandResult {
|
||||
let pool_data = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?;
|
||||
let stake_pool = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?;
|
||||
let epoch_info = config.rpc_client.get_epoch_info()?;
|
||||
|
||||
let accounts_to_update: Vec<Pubkey> = validator_list
|
||||
|
@ -667,12 +667,12 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult {
|
|||
for chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) {
|
||||
instructions.push(spl_stake_pool::instruction::update_validator_list_balance(
|
||||
&spl_stake_pool::id(),
|
||||
&pool_data.validator_list,
|
||||
&stake_pool.validator_list,
|
||||
&chunk,
|
||||
)?);
|
||||
}
|
||||
|
||||
if instructions.is_empty() && pool_data.last_update_epoch == epoch_info.epoch {
|
||||
if instructions.is_empty() && stake_pool.last_update_epoch == epoch_info.epoch {
|
||||
println!("Stake pool balances are up to date, no update required.");
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -680,7 +680,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult {
|
|||
instructions.push(spl_stake_pool::instruction::update_stake_pool_balance(
|
||||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
&pool_data.validator_list,
|
||||
&stake_pool.validator_list,
|
||||
)?);
|
||||
|
||||
let mut transaction =
|
||||
|
@ -765,21 +765,21 @@ fn command_withdraw(
|
|||
command_update(config, pool)?;
|
||||
}
|
||||
|
||||
let pool_data = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let pool_mint = get_token_mint(&config.rpc_client, &pool_data.pool_mint)?;
|
||||
let stake_pool = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?;
|
||||
let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals);
|
||||
|
||||
let pool_withdraw_authority: Pubkey = create_pool_authority_address(
|
||||
&spl_stake_pool::id(),
|
||||
pool,
|
||||
AUTHORITY_WITHDRAW,
|
||||
pool_data.withdraw_bump_seed,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Check withdraw_from account type
|
||||
let token_account =
|
||||
get_token_account(&config.rpc_client, &withdraw_from, &pool_data.pool_mint)?;
|
||||
get_token_account(&config.rpc_client, &withdraw_from, &stake_pool.pool_mint)?;
|
||||
|
||||
// Check withdraw_from balance
|
||||
if token_account.amount < pool_amount {
|
||||
|
@ -794,7 +794,7 @@ fn command_withdraw(
|
|||
// Get the list of accounts to withdraw from
|
||||
let withdraw_accounts = prepare_withdraw_accounts(
|
||||
&config.rpc_client,
|
||||
&pool_data,
|
||||
&stake_pool,
|
||||
&pool_withdraw_authority,
|
||||
pool_amount,
|
||||
)?;
|
||||
|
@ -824,7 +824,7 @@ fn command_withdraw(
|
|||
// Go through prepared accounts and withdraw/claim them
|
||||
for withdraw_account in withdraw_accounts {
|
||||
// Convert pool tokens amount to lamports
|
||||
let sol_withdraw_amount = pool_data
|
||||
let sol_withdraw_amount = stake_pool
|
||||
.calc_lamports_withdraw_amount(withdraw_account.pool_amount)
|
||||
.unwrap();
|
||||
|
||||
|
@ -867,13 +867,13 @@ fn command_withdraw(
|
|||
instructions.push(spl_stake_pool::instruction::withdraw(
|
||||
&spl_stake_pool::id(),
|
||||
&pool,
|
||||
&pool_data.validator_list,
|
||||
&stake_pool.validator_list,
|
||||
&pool_withdraw_authority,
|
||||
&withdraw_account.address,
|
||||
&stake_receiver.unwrap(), // Cannot be none at this point
|
||||
&config.owner.pubkey(),
|
||||
&withdraw_from,
|
||||
&pool_data.pool_mint,
|
||||
&stake_pool.pool_mint,
|
||||
&spl_token::id(),
|
||||
withdraw_account.pool_amount,
|
||||
)?);
|
||||
|
@ -899,19 +899,20 @@ fn command_set_owner(
|
|||
new_owner: &Option<Pubkey>,
|
||||
new_fee_receiver: &Option<Pubkey>,
|
||||
) -> CommandResult {
|
||||
let pool_data = get_stake_pool(&config.rpc_client, pool)?;
|
||||
let stake_pool = get_stake_pool(&config.rpc_client, pool)?;
|
||||
|
||||
// If new accounts are missing in the arguments use the old ones
|
||||
let new_owner = match new_owner {
|
||||
None => pool_data.owner,
|
||||
None => stake_pool.owner,
|
||||
Some(value) => *value,
|
||||
};
|
||||
let new_fee_receiver = match new_fee_receiver {
|
||||
None => pool_data.owner_fee_account,
|
||||
None => stake_pool.owner_fee_account,
|
||||
Some(value) => {
|
||||
// Check for fee receiver being a valid token account and have to same mint as the stake pool
|
||||
let token_account = get_token_account(&config.rpc_client, value, &pool_data.pool_mint)?;
|
||||
if token_account.mint != pool_data.pool_mint {
|
||||
let token_account =
|
||||
get_token_account(&config.rpc_client, value, &stake_pool.pool_mint)?;
|
||||
if token_account.mint != stake_pool.pool_mint {
|
||||
return Err("Fee receiver account belongs to a different mint"
|
||||
.to_string()
|
||||
.into());
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use {
|
||||
borsh::{maybestd::io::Error, BorshDeserialize, BorshSerialize},
|
||||
std::io::{Result as IoResult, Write},
|
||||
std::io::{self, Write},
|
||||
};
|
||||
|
||||
/// Deserializes something and allows for incomplete reading
|
||||
|
@ -20,13 +20,13 @@ struct WriteCounter {
|
|||
}
|
||||
|
||||
impl Write for WriteCounter {
|
||||
fn write(&mut self, data: &[u8]) -> IoResult<usize> {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
let amount = data.len();
|
||||
self.count += amount;
|
||||
Ok(amount)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ fn process_instruction(
|
|||
if let Err(error) = Processor::process(program_id, accounts, instruction_data) {
|
||||
// catch the error so we can print it
|
||||
error.print::<StakePoolError>();
|
||||
return Err(error);
|
||||
Err(error)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use {
|
||||
crate::{
|
||||
borsh::try_from_slice_unchecked,
|
||||
create_pool_authority_address,
|
||||
error::StakePoolError,
|
||||
find_authority_bump_seed, find_stake_address_for_validator,
|
||||
instruction::{Fee, StakePoolInstruction},
|
||||
|
@ -38,24 +37,8 @@ use {
|
|||
/// Program state handler.
|
||||
pub struct Processor {}
|
||||
impl Processor {
|
||||
/// Checks withdraw or deposit authority
|
||||
pub fn check_authority(
|
||||
authority_to_check: &Pubkey,
|
||||
program_id: &Pubkey,
|
||||
stake_pool_key: &Pubkey,
|
||||
authority: &[u8],
|
||||
bump_seed: u8,
|
||||
) -> Result<(), ProgramError> {
|
||||
if *authority_to_check
|
||||
!= create_pool_authority_address(program_id, stake_pool_key, authority, bump_seed)?
|
||||
{
|
||||
return Err(StakePoolError::InvalidProgramAddress.into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns validator address for a particular stake account
|
||||
pub fn get_validator(stake_account_info: &AccountInfo) -> Result<Pubkey, ProgramError> {
|
||||
fn get_validator(stake_account_info: &AccountInfo) -> Result<Pubkey, ProgramError> {
|
||||
let stake_state: stake_program::StakeState = deserialize(&stake_account_info.data.borrow())
|
||||
.or(Err(ProgramError::InvalidAccountData))?;
|
||||
match stake_state {
|
||||
|
@ -65,7 +48,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Checks if validator stake account is a proper program address
|
||||
pub fn is_validator_stake_address(
|
||||
fn is_validator_stake_address(
|
||||
vote_account: &Pubkey,
|
||||
program_id: &Pubkey,
|
||||
stake_pool_info: &AccountInfo,
|
||||
|
@ -78,7 +61,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Returns validator address for a particular stake account and checks its validity
|
||||
pub fn get_validator_checked(
|
||||
fn get_validator_checked(
|
||||
program_id: &Pubkey,
|
||||
stake_pool_info: &AccountInfo,
|
||||
stake_account_info: &AccountInfo,
|
||||
|
@ -97,7 +80,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Issue a stake_split instruction.
|
||||
pub fn stake_split<'a>(
|
||||
fn stake_split<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
stake_account: AccountInfo<'a>,
|
||||
authority: AccountInfo<'a>,
|
||||
|
@ -118,7 +101,7 @@ impl Processor {
|
|||
|
||||
/// Issue a stake_merge instruction.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn stake_merge<'a>(
|
||||
fn stake_merge<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
stake_account: AccountInfo<'a>,
|
||||
authority: AccountInfo<'a>,
|
||||
|
@ -151,7 +134,7 @@ impl Processor {
|
|||
|
||||
/// Issue a stake_set_owner instruction.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn stake_authorize<'a>(
|
||||
fn stake_authorize<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
stake_account: AccountInfo<'a>,
|
||||
authority: AccountInfo<'a>,
|
||||
|
@ -159,7 +142,7 @@ impl Processor {
|
|||
bump_seed: u8,
|
||||
new_staker: &Pubkey,
|
||||
staker_auth: stake_program::StakeAuthorize,
|
||||
reserved: AccountInfo<'a>,
|
||||
clock: AccountInfo<'a>,
|
||||
stake_program_info: AccountInfo<'a>,
|
||||
) -> Result<(), ProgramError> {
|
||||
let me_bytes = stake_pool.to_bytes();
|
||||
|
@ -171,14 +154,14 @@ impl Processor {
|
|||
|
||||
invoke_signed(
|
||||
&ix,
|
||||
&[stake_account, reserved, authority, stake_program_info],
|
||||
&[stake_account, clock, authority, stake_program_info],
|
||||
signers,
|
||||
)
|
||||
}
|
||||
|
||||
/// Issue a spl_token `Burn` instruction.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn token_burn<'a>(
|
||||
fn token_burn<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
token_program: AccountInfo<'a>,
|
||||
burn_account: AccountInfo<'a>,
|
||||
|
@ -210,7 +193,7 @@ impl Processor {
|
|||
|
||||
/// Issue a spl_token `MintTo` instruction.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn token_mint_to<'a>(
|
||||
fn token_mint_to<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
token_program: AccountInfo<'a>,
|
||||
mint: AccountInfo<'a>,
|
||||
|
@ -237,7 +220,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes `Initialize` instruction.
|
||||
pub fn process_initialize(
|
||||
fn process_initialize(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
fee: Fee,
|
||||
|
@ -344,7 +327,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes `CreateValidatorStakeAccount` instruction.
|
||||
pub fn process_create_validator_stake_account(
|
||||
fn process_create_validator_stake_account(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
|
@ -444,7 +427,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes `AddValidatorToPool` instruction.
|
||||
pub fn process_add_validator_to_pool(
|
||||
fn process_add_validator_to_pool(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
|
@ -546,7 +529,6 @@ impl Processor {
|
|||
// Check if stake is warmed up
|
||||
Self::check_stake_activation(stake_account_info, clock, stake_history)?;
|
||||
|
||||
// Add validator to the list and save
|
||||
validator_list.validators.push(ValidatorStakeInfo {
|
||||
vote_account,
|
||||
balance: stake_lamports,
|
||||
|
@ -554,9 +536,7 @@ impl Processor {
|
|||
});
|
||||
validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?;
|
||||
|
||||
// Save amounts to the stake pool state
|
||||
stake_pool.pool_total += token_amount;
|
||||
// Only update stake total if the last state update epoch is current
|
||||
stake_pool.stake_total += stake_lamports;
|
||||
stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?;
|
||||
|
||||
|
@ -564,7 +544,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes `RemoveValidatorFromPool` instruction.
|
||||
pub fn process_remove_validator_from_pool(
|
||||
fn process_remove_validator_from_pool(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
|
@ -655,15 +635,12 @@ impl Processor {
|
|||
token_amount,
|
||||
)?;
|
||||
|
||||
// Remove validator from the list and save
|
||||
validator_list
|
||||
.validators
|
||||
.retain(|item| item.vote_account != vote_account);
|
||||
validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?;
|
||||
|
||||
// Save amounts to the stake pool state
|
||||
stake_pool.pool_total -= token_amount;
|
||||
// Only update stake total if the last state update epoch is current
|
||||
stake_pool.stake_total -= stake_lamports;
|
||||
stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?;
|
||||
|
||||
|
@ -671,7 +648,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes `UpdateValidatorListBalance` instruction.
|
||||
pub fn process_update_validator_list_balance(
|
||||
fn process_update_validator_list_balance(
|
||||
_program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
|
@ -720,7 +697,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes `UpdateStakePoolBalance` instruction.
|
||||
pub fn process_update_stake_pool_balance(
|
||||
fn process_update_stake_pool_balance(
|
||||
_program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
|
@ -761,7 +738,8 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Check stake activation status
|
||||
pub fn check_stake_activation(
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn check_stake_activation(
|
||||
_stake_info: &AccountInfo,
|
||||
_clock: &Clock,
|
||||
_stake_history: &StakeHistory,
|
||||
|
@ -790,7 +768,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes [Deposit](enum.Instruction.html).
|
||||
pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||
fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||
let validator_list_info = next_account_info(account_info_iter)?;
|
||||
|
@ -931,7 +909,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes [Withdraw](enum.Instruction.html).
|
||||
pub fn process_withdraw(
|
||||
fn process_withdraw(
|
||||
program_id: &Pubkey,
|
||||
pool_amount: u64,
|
||||
accounts: &[AccountInfo],
|
||||
|
@ -1046,7 +1024,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Processes [SetOwner](enum.Instruction.html).
|
||||
pub fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||
fn process_set_owner(_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)?;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! State transition types
|
||||
|
||||
use {
|
||||
crate::{error::StakePoolError, instruction::Fee, processor::Processor},
|
||||
crate::{error::StakePoolError, instruction::Fee},
|
||||
borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
|
||||
solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey},
|
||||
spl_math::checked_ceil_div::CheckedCeilDiv,
|
||||
|
@ -99,17 +99,38 @@ impl StakePool {
|
|||
.ok()
|
||||
}
|
||||
|
||||
/// Checks withdraw or deposit authority
|
||||
fn check_authority(
|
||||
authority: &Pubkey,
|
||||
program_id: &Pubkey,
|
||||
stake_pool_address: &Pubkey,
|
||||
seed: &[u8],
|
||||
bump_seed: u8,
|
||||
) -> Result<(), ProgramError> {
|
||||
if *authority
|
||||
!= crate::create_pool_authority_address(
|
||||
program_id,
|
||||
stake_pool_address,
|
||||
seed,
|
||||
bump_seed,
|
||||
)?
|
||||
{
|
||||
return Err(StakePoolError::InvalidProgramAddress.into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Checks withdraw authority
|
||||
pub fn check_authority_withdraw(
|
||||
&self,
|
||||
authority_to_check: &Pubkey,
|
||||
withdraw_authority: &Pubkey,
|
||||
program_id: &Pubkey,
|
||||
stake_pool_key: &Pubkey,
|
||||
stake_pool_address: &Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
Processor::check_authority(
|
||||
authority_to_check,
|
||||
Self::check_authority(
|
||||
withdraw_authority,
|
||||
program_id,
|
||||
stake_pool_key,
|
||||
stake_pool_address,
|
||||
crate::AUTHORITY_WITHDRAW,
|
||||
self.withdraw_bump_seed,
|
||||
)
|
||||
|
@ -117,14 +138,14 @@ impl StakePool {
|
|||
/// Checks deposit authority
|
||||
pub fn check_authority_deposit(
|
||||
&self,
|
||||
authority_to_check: &Pubkey,
|
||||
deposit_authority: &Pubkey,
|
||||
program_id: &Pubkey,
|
||||
stake_pool_key: &Pubkey,
|
||||
stake_pool_address: &Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
Processor::check_authority(
|
||||
authority_to_check,
|
||||
Self::check_authority(
|
||||
deposit_authority,
|
||||
program_id,
|
||||
stake_pool_key,
|
||||
stake_pool_address,
|
||||
crate::AUTHORITY_DEPOSIT,
|
||||
self.deposit_bump_seed,
|
||||
)
|
||||
|
@ -182,7 +203,7 @@ pub struct ValidatorStakeInfo {
|
|||
|
||||
impl ValidatorList {
|
||||
/// Create an empty instance containing space for `max_validators`
|
||||
pub fn new_with_max_validators(max_validators: u32) -> Self {
|
||||
pub fn new(max_validators: u32) -> Self {
|
||||
Self {
|
||||
account_type: AccountType::ValidatorList,
|
||||
max_validators,
|
||||
|
@ -239,8 +260,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_state_packing() {
|
||||
let max_validators = 10_000;
|
||||
let size = get_instance_packed_len(&ValidatorList::new_with_max_validators(max_validators))
|
||||
.unwrap();
|
||||
let size = get_instance_packed_len(&ValidatorList::new(max_validators)).unwrap();
|
||||
// Not initialized
|
||||
let stake_list = ValidatorList {
|
||||
account_type: AccountType::Uninitialized,
|
||||
|
@ -297,7 +317,7 @@ mod test {
|
|||
proptest! {
|
||||
#[test]
|
||||
fn stake_list_size_calculation(test_amount in 0..=100_000_u32) {
|
||||
let validators = ValidatorList::new_with_max_validators(test_amount);
|
||||
let validators = ValidatorList::new(test_amount);
|
||||
let size = get_instance_packed_len(&validators).unwrap();
|
||||
assert_eq!(ValidatorList::calculate_max_validators(size), test_amount as usize);
|
||||
assert_eq!(ValidatorList::calculate_max_validators(size.saturating_add(1)), test_amount as usize);
|
||||
|
|
|
@ -177,10 +177,8 @@ pub async fn create_stake_pool(
|
|||
) -> Result<(), TransportError> {
|
||||
let rent = banks_client.get_rent().await.unwrap();
|
||||
let rent_stake_pool = rent.minimum_balance(get_packed_len::<state::StakePool>());
|
||||
let validator_list_size = get_instance_packed_len(
|
||||
&state::ValidatorList::new_with_max_validators(max_validators),
|
||||
)
|
||||
.unwrap();
|
||||
let validator_list_size =
|
||||
get_instance_packed_len(&state::ValidatorList::new(max_validators)).unwrap();
|
||||
let rent_validator_list = rent.minimum_balance(validator_list_size);
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
|
|
|
@ -179,9 +179,9 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() {
|
|||
|
||||
let rent = banks_client.get_rent().await.unwrap();
|
||||
let rent_stake_pool = rent.minimum_balance(get_packed_len::<state::StakePool>());
|
||||
let validator_list_size = get_instance_packed_len(
|
||||
&state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators - 1),
|
||||
)
|
||||
let validator_list_size = get_instance_packed_len(&state::ValidatorList::new(
|
||||
stake_pool_accounts.max_validators - 1,
|
||||
))
|
||||
.unwrap();
|
||||
let rent_validator_list = rent.minimum_balance(validator_list_size);
|
||||
|
||||
|
@ -333,9 +333,9 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() {
|
|||
banks_client.process_transaction(transaction).await.unwrap();
|
||||
|
||||
let rent_stake_pool = rent.minimum_balance(get_packed_len::<state::StakePool>());
|
||||
let validator_list_size = get_instance_packed_len(
|
||||
&state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators),
|
||||
)
|
||||
let validator_list_size = get_instance_packed_len(&state::ValidatorList::new(
|
||||
stake_pool_accounts.max_validators,
|
||||
))
|
||||
.unwrap();
|
||||
let rent_validator_list = rent.minimum_balance(validator_list_size);
|
||||
|
||||
|
@ -499,9 +499,9 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() {
|
|||
.await;
|
||||
|
||||
let rent = banks_client.get_rent().await.unwrap();
|
||||
let validator_list_size = get_instance_packed_len(
|
||||
&state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators),
|
||||
)
|
||||
let validator_list_size = get_instance_packed_len(&state::ValidatorList::new(
|
||||
stake_pool_accounts.max_validators,
|
||||
))
|
||||
.unwrap();
|
||||
let rent_validator_list = rent.minimum_balance(validator_list_size);
|
||||
|
||||
|
@ -572,9 +572,9 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() {
|
|||
|
||||
let rent = banks_client.get_rent().await.unwrap();
|
||||
let rent_stake_pool = rent.minimum_balance(get_packed_len::<state::StakePool>());
|
||||
let validator_list_size = get_instance_packed_len(
|
||||
&state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators),
|
||||
)
|
||||
let validator_list_size = get_instance_packed_len(&state::ValidatorList::new(
|
||||
stake_pool_accounts.max_validators,
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
|
@ -646,9 +646,9 @@ async fn test_initialize_stake_pool_without_owner_signature() {
|
|||
|
||||
let rent = banks_client.get_rent().await.unwrap();
|
||||
let rent_stake_pool = rent.minimum_balance(get_packed_len::<state::StakePool>());
|
||||
let validator_list_size = get_instance_packed_len(
|
||||
&state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators),
|
||||
)
|
||||
let validator_list_size = get_instance_packed_len(&state::ValidatorList::new(
|
||||
stake_pool_accounts.max_validators,
|
||||
))
|
||||
.unwrap();
|
||||
let rent_validator_list = rent.minimum_balance(validator_list_size);
|
||||
|
||||
|
|
Loading…
Reference in New Issue