Code cleanup v2
This commit is contained in:
parent
2cd7adbf87
commit
b97849d206
|
@ -607,7 +607,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult {
|
||||||
for validator in validator_list.validators {
|
for validator in validator_list.validators {
|
||||||
println!(
|
println!(
|
||||||
"Vote Account: {}\tBalance: {}\tEpoch: {}",
|
"Vote Account: {}\tBalance: {}\tEpoch: {}",
|
||||||
validator.validator_account, validator.balance, validator.last_update_epoch
|
validator.vote_account, validator.balance, validator.last_update_epoch
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -654,7 +654,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult {
|
||||||
} else {
|
} else {
|
||||||
let (stake_account, _) = find_stake_address_for_validator(
|
let (stake_account, _) = find_stake_address_for_validator(
|
||||||
&spl_stake_pool::id(),
|
&spl_stake_pool::id(),
|
||||||
&item.validator_account,
|
&item.vote_account,
|
||||||
&pool,
|
&pool,
|
||||||
);
|
);
|
||||||
Some(stake_account)
|
Some(stake_account)
|
||||||
|
|
|
@ -66,14 +66,14 @@ impl Processor {
|
||||||
|
|
||||||
/// Checks if validator stake account is a proper program address
|
/// Checks if validator stake account is a proper program address
|
||||||
pub fn is_validator_stake_address(
|
pub fn is_validator_stake_address(
|
||||||
validator_account: &Pubkey,
|
vote_account: &Pubkey,
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
stake_pool_info: &AccountInfo,
|
stake_pool_info: &AccountInfo,
|
||||||
stake_account_info: &AccountInfo,
|
stake_account_info: &AccountInfo,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Check stake account address validity
|
// Check stake account address validity
|
||||||
let (stake_address, _) =
|
let (stake_address, _) =
|
||||||
find_stake_address_for_validator(&program_id, &validator_account, &stake_pool_info.key);
|
find_stake_address_for_validator(&program_id, &vote_account, &stake_pool_info.key);
|
||||||
stake_address == *stake_account_info.key
|
stake_address == *stake_account_info.key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,17 +83,17 @@ impl Processor {
|
||||||
stake_pool_info: &AccountInfo,
|
stake_pool_info: &AccountInfo,
|
||||||
stake_account_info: &AccountInfo,
|
stake_account_info: &AccountInfo,
|
||||||
) -> Result<Pubkey, ProgramError> {
|
) -> Result<Pubkey, ProgramError> {
|
||||||
let validator_account = Self::get_validator(stake_account_info)?;
|
let vote_account = Self::get_validator(stake_account_info)?;
|
||||||
|
|
||||||
if !Self::is_validator_stake_address(
|
if !Self::is_validator_stake_address(
|
||||||
&validator_account,
|
&vote_account,
|
||||||
program_id,
|
program_id,
|
||||||
stake_pool_info,
|
stake_pool_info,
|
||||||
stake_account_info,
|
stake_account_info,
|
||||||
) {
|
) {
|
||||||
return Err(StakePoolError::InvalidStakeAccountAddress.into());
|
return Err(StakePoolError::InvalidStakeAccountAddress.into());
|
||||||
}
|
}
|
||||||
Ok(validator_account)
|
Ok(vote_account)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Issue a stake_split instruction.
|
/// Issue a stake_split instruction.
|
||||||
|
@ -249,33 +249,27 @@ impl Processor {
|
||||||
let validator_list_info = next_account_info(account_info_iter)?;
|
let validator_list_info = next_account_info(account_info_iter)?;
|
||||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||||
let owner_fee_info = next_account_info(account_info_iter)?;
|
let owner_fee_info = next_account_info(account_info_iter)?;
|
||||||
// Clock sysvar account
|
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let clock = &Clock::from_account_info(clock_info)?;
|
let clock = &Clock::from_account_info(clock_info)?;
|
||||||
// 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)?;
|
||||||
// Token program ID
|
|
||||||
let token_program_info = next_account_info(account_info_iter)?;
|
let token_program_info = next_account_info(account_info_iter)?;
|
||||||
|
|
||||||
// Check if transaction was signed by owner
|
|
||||||
if !owner_info.is_signer {
|
if !owner_info.is_signer {
|
||||||
return Err(StakePoolError::SignatureMissing.into());
|
return Err(StakePoolError::SignatureMissing.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
||||||
// Stake pool account should not be already initialized
|
|
||||||
if !stake_pool.is_uninitialized() {
|
if !stake_pool.is_uninitialized() {
|
||||||
return Err(StakePoolError::AlreadyInUse.into());
|
return Err(StakePoolError::AlreadyInUse.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if validator stake list storage is unitialized
|
|
||||||
let mut validator_list =
|
let mut validator_list =
|
||||||
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
||||||
if !validator_list.is_uninitialized() {
|
if !validator_list.is_uninitialized() {
|
||||||
return Err(StakePoolError::AlreadyInUse.into());
|
return Err(StakePoolError::AlreadyInUse.into());
|
||||||
}
|
}
|
||||||
// Check validator list size
|
|
||||||
let data_length = validator_list_info.data_len();
|
let data_length = validator_list_info.data_len();
|
||||||
let expected_max_validators = ValidatorList::calculate_max_validators(data_length);
|
let expected_max_validators = ValidatorList::calculate_max_validators(data_length);
|
||||||
if expected_max_validators != max_validators as usize || max_validators == 0 {
|
if expected_max_validators != max_validators as usize || max_validators == 0 {
|
||||||
|
@ -285,13 +279,11 @@ impl Processor {
|
||||||
validator_list.validators.clear();
|
validator_list.validators.clear();
|
||||||
validator_list.max_validators = max_validators;
|
validator_list.max_validators = max_validators;
|
||||||
|
|
||||||
// Check if stake pool account is rent-exempt
|
|
||||||
if !rent.is_exempt(stake_pool_info.lamports(), stake_pool_info.data_len()) {
|
if !rent.is_exempt(stake_pool_info.lamports(), stake_pool_info.data_len()) {
|
||||||
msg!("Stake pool not rent-exempt");
|
msg!("Stake pool not rent-exempt");
|
||||||
return Err(ProgramError::AccountNotRentExempt);
|
return Err(ProgramError::AccountNotRentExempt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if validator stake list account is rent-exempt
|
|
||||||
if !rent.is_exempt(
|
if !rent.is_exempt(
|
||||||
validator_list_info.lamports(),
|
validator_list_info.lamports(),
|
||||||
validator_list_info.data_len(),
|
validator_list_info.data_len(),
|
||||||
|
@ -305,17 +297,14 @@ impl Processor {
|
||||||
return Err(StakePoolError::FeeTooHigh.into());
|
return Err(StakePoolError::FeeTooHigh.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if fee account's owner the same as token program id
|
|
||||||
if owner_fee_info.owner != token_program_info.key {
|
if owner_fee_info.owner != token_program_info.key {
|
||||||
return Err(StakePoolError::InvalidFeeAccount.into());
|
return Err(StakePoolError::InvalidFeeAccount.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check pool mint program ID
|
|
||||||
if pool_mint_info.owner != token_program_info.key {
|
if pool_mint_info.owner != token_program_info.key {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for owner fee account to have proper mint assigned
|
|
||||||
if *pool_mint_info.key
|
if *pool_mint_info.key
|
||||||
!= spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint
|
!= spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint
|
||||||
{
|
{
|
||||||
|
@ -360,31 +349,19 @@ impl Processor {
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// 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)?;
|
let owner_info = next_account_info(account_info_iter)?;
|
||||||
// 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
|
|
||||||
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
|
|
||||||
let validator_info = next_account_info(account_info_iter)?;
|
let validator_info = next_account_info(account_info_iter)?;
|
||||||
// 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)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
// Stake history sysvar account
|
|
||||||
let stake_history_info = next_account_info(account_info_iter)?;
|
let stake_history_info = next_account_info(account_info_iter)?;
|
||||||
// Stake config sysvar account
|
|
||||||
let stake_config_info = next_account_info(account_info_iter)?;
|
let stake_config_info = next_account_info(account_info_iter)?;
|
||||||
// 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
|
|
||||||
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 {
|
if stake_pool_info.owner != program_id {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
@ -394,7 +371,6 @@ impl Processor {
|
||||||
}
|
}
|
||||||
stake_pool.check_owner(owner_info)?;
|
stake_pool.check_owner(owner_info)?;
|
||||||
|
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
@ -402,7 +378,6 @@ impl Processor {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check stake account address validity
|
|
||||||
let (stake_address, bump_seed) = find_stake_address_for_validator(
|
let (stake_address, bump_seed) = find_stake_address_for_validator(
|
||||||
&program_id,
|
&program_id,
|
||||||
&validator_info.key,
|
&validator_info.key,
|
||||||
|
@ -474,52 +449,35 @@ impl Processor {
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// Stake pool account
|
|
||||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||||
// Pool owner account
|
|
||||||
let owner_info = next_account_info(account_info_iter)?;
|
let owner_info = next_account_info(account_info_iter)?;
|
||||||
// Stake pool deposit authority
|
|
||||||
let deposit_info = next_account_info(account_info_iter)?;
|
let deposit_info = next_account_info(account_info_iter)?;
|
||||||
// Stake pool withdraw authority
|
|
||||||
let withdraw_info = next_account_info(account_info_iter)?;
|
let withdraw_info = next_account_info(account_info_iter)?;
|
||||||
// Account storing validator stake list
|
|
||||||
let validator_list_info = next_account_info(account_info_iter)?;
|
let validator_list_info = next_account_info(account_info_iter)?;
|
||||||
// Stake account to add to the pool
|
|
||||||
let stake_account_info = next_account_info(account_info_iter)?;
|
let stake_account_info = next_account_info(account_info_iter)?;
|
||||||
// User account to receive pool tokens
|
|
||||||
let dest_user_info = next_account_info(account_info_iter)?;
|
let dest_user_info = next_account_info(account_info_iter)?;
|
||||||
// Pool token mint account
|
|
||||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||||
// Clock sysvar account
|
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let clock = &Clock::from_account_info(clock_info)?;
|
let clock = &Clock::from_account_info(clock_info)?;
|
||||||
// Stake history sysvar account
|
|
||||||
let stake_history_info = next_account_info(account_info_iter)?;
|
let stake_history_info = next_account_info(account_info_iter)?;
|
||||||
let stake_history = &StakeHistory::from_account_info(stake_history_info)?;
|
let stake_history = &StakeHistory::from_account_info(stake_history_info)?;
|
||||||
// Pool token program id
|
|
||||||
let token_program_info = next_account_info(account_info_iter)?;
|
let token_program_info = next_account_info(account_info_iter)?;
|
||||||
// Staking program id
|
|
||||||
let stake_program_info = next_account_info(account_info_iter)?;
|
let stake_program_info = next_account_info(account_info_iter)?;
|
||||||
|
|
||||||
// Check program ids
|
|
||||||
if *stake_program_info.key != stake_program::id() {
|
if *stake_program_info.key != stake_program::id() {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get stake pool stake (and check if it is initialized)
|
|
||||||
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
||||||
if !stake_pool.is_valid() {
|
if !stake_pool.is_valid() {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check authority accounts
|
|
||||||
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
||||||
stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?;
|
stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?;
|
||||||
|
|
||||||
// Check owner validity and signature
|
|
||||||
stake_pool.check_owner(owner_info)?;
|
stake_pool.check_owner(owner_info)?;
|
||||||
|
|
||||||
// Check stake pool last update epoch
|
|
||||||
if stake_pool.last_update_epoch < clock.epoch {
|
if stake_pool.last_update_epoch < clock.epoch {
|
||||||
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
||||||
}
|
}
|
||||||
|
@ -531,12 +489,10 @@ impl Processor {
|
||||||
return Err(StakePoolError::WrongPoolMint.into());
|
return Err(StakePoolError::WrongPoolMint.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validator stake account list storage
|
|
||||||
if *validator_list_info.key != stake_pool.validator_list {
|
if *validator_list_info.key != stake_pool.validator_list {
|
||||||
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read validator stake list account and check if it is valid
|
|
||||||
let mut validator_list =
|
let mut validator_list =
|
||||||
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
||||||
if !validator_list.is_valid() {
|
if !validator_list.is_valid() {
|
||||||
|
@ -546,10 +502,10 @@ impl Processor {
|
||||||
return Err(ProgramError::AccountDataTooSmall);
|
return Err(ProgramError::AccountDataTooSmall);
|
||||||
}
|
}
|
||||||
|
|
||||||
let validator_account =
|
let vote_account =
|
||||||
Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?;
|
Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?;
|
||||||
|
|
||||||
if validator_list.contains(&validator_account) {
|
if validator_list.contains(&vote_account) {
|
||||||
return Err(StakePoolError::ValidatorAlreadyAdded.into());
|
return Err(StakePoolError::ValidatorAlreadyAdded.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,7 +548,7 @@ impl Processor {
|
||||||
|
|
||||||
// Add validator to the list and save
|
// Add validator to the list and save
|
||||||
validator_list.validators.push(ValidatorStakeInfo {
|
validator_list.validators.push(ValidatorStakeInfo {
|
||||||
validator_account,
|
vote_account,
|
||||||
balance: stake_lamports,
|
balance: stake_lamports,
|
||||||
last_update_epoch: clock.epoch,
|
last_update_epoch: clock.epoch,
|
||||||
});
|
});
|
||||||
|
@ -613,48 +569,31 @@ impl Processor {
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// Stake pool account
|
|
||||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||||
// Pool owner account
|
|
||||||
let owner_info = next_account_info(account_info_iter)?;
|
let owner_info = next_account_info(account_info_iter)?;
|
||||||
// Stake pool withdraw authority
|
|
||||||
let withdraw_info = next_account_info(account_info_iter)?;
|
let withdraw_info = next_account_info(account_info_iter)?;
|
||||||
// New stake authority
|
|
||||||
let new_stake_authority_info = next_account_info(account_info_iter)?;
|
let new_stake_authority_info = next_account_info(account_info_iter)?;
|
||||||
// Account storing validator stake list
|
|
||||||
let validator_list_info = next_account_info(account_info_iter)?;
|
let validator_list_info = next_account_info(account_info_iter)?;
|
||||||
// Stake account to remove from the pool
|
|
||||||
let stake_account_info = next_account_info(account_info_iter)?;
|
let stake_account_info = next_account_info(account_info_iter)?;
|
||||||
// User account with pool tokens to burn from
|
|
||||||
let burn_from_info = next_account_info(account_info_iter)?;
|
let burn_from_info = next_account_info(account_info_iter)?;
|
||||||
// Pool token mint account
|
|
||||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||||
// Clock sysvar account
|
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let clock = &Clock::from_account_info(clock_info)?;
|
let clock = &Clock::from_account_info(clock_info)?;
|
||||||
// Pool token program id
|
|
||||||
let token_program_info = next_account_info(account_info_iter)?;
|
let token_program_info = next_account_info(account_info_iter)?;
|
||||||
// Staking program id
|
|
||||||
let stake_program_info = next_account_info(account_info_iter)?;
|
let stake_program_info = next_account_info(account_info_iter)?;
|
||||||
|
|
||||||
// Check program ids
|
|
||||||
if *stake_program_info.key != stake_program::id() {
|
if *stake_program_info.key != stake_program::id() {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get stake pool stake (and check if it is initialized)
|
|
||||||
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
||||||
if !stake_pool.is_valid() {
|
if !stake_pool.is_valid() {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check authority account
|
|
||||||
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
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)?;
|
stake_pool.check_owner(owner_info)?;
|
||||||
|
|
||||||
// Check stake pool last update epoch
|
|
||||||
if stake_pool.last_update_epoch < clock.epoch {
|
if stake_pool.last_update_epoch < clock.epoch {
|
||||||
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
||||||
}
|
}
|
||||||
|
@ -666,26 +605,23 @@ impl Processor {
|
||||||
return Err(StakePoolError::WrongPoolMint.into());
|
return Err(StakePoolError::WrongPoolMint.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validator stake account list storage
|
|
||||||
if *validator_list_info.key != stake_pool.validator_list {
|
if *validator_list_info.key != stake_pool.validator_list {
|
||||||
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read validator stake list account and check if it is valid
|
|
||||||
let mut validator_list =
|
let mut validator_list =
|
||||||
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
||||||
if !validator_list.is_valid() {
|
if !validator_list.is_valid() {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let validator_account =
|
let vote_account =
|
||||||
Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?;
|
Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?;
|
||||||
|
|
||||||
if !validator_list.contains(&validator_account) {
|
if !validator_list.contains(&vote_account) {
|
||||||
return Err(StakePoolError::ValidatorNotFound.into());
|
return Err(StakePoolError::ValidatorNotFound.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Withdrawer and Staker authority to the provided authority
|
|
||||||
for authority in &[
|
for authority in &[
|
||||||
stake_program::StakeAuthorize::Withdrawer,
|
stake_program::StakeAuthorize::Withdrawer,
|
||||||
stake_program::StakeAuthorize::Staker,
|
stake_program::StakeAuthorize::Staker,
|
||||||
|
@ -722,7 +658,7 @@ impl Processor {
|
||||||
// Remove validator from the list and save
|
// Remove validator from the list and save
|
||||||
validator_list
|
validator_list
|
||||||
.validators
|
.validators
|
||||||
.retain(|item| item.validator_account != validator_account);
|
.retain(|item| item.vote_account != vote_account);
|
||||||
validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?;
|
validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?;
|
||||||
|
|
||||||
// Save amounts to the stake pool state
|
// Save amounts to the stake pool state
|
||||||
|
@ -740,22 +676,18 @@ impl Processor {
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// Account storing validator stake list
|
|
||||||
let validator_list_info = next_account_info(account_info_iter)?;
|
let validator_list_info = next_account_info(account_info_iter)?;
|
||||||
// Clock sysvar account
|
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let clock = &Clock::from_account_info(clock_info)?;
|
let clock = &Clock::from_account_info(clock_info)?;
|
||||||
// Validator stake accounts
|
|
||||||
let validator_stake_accounts = account_info_iter.as_slice();
|
let validator_stake_accounts = account_info_iter.as_slice();
|
||||||
|
|
||||||
// Read validator stake list account and check if it is valid
|
|
||||||
let mut validator_list =
|
let mut validator_list =
|
||||||
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
||||||
if !validator_list.is_valid() {
|
if !validator_list.is_valid() {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let validator_accounts: Vec<Option<Pubkey>> = validator_stake_accounts
|
let vote_accounts: Vec<Option<Pubkey>> = validator_stake_accounts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|stake| Self::get_validator(stake).ok())
|
.map(|stake| Self::get_validator(stake).ok())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -766,12 +698,11 @@ impl Processor {
|
||||||
if validator_stake_record.last_update_epoch >= clock.epoch {
|
if validator_stake_record.last_update_epoch >= clock.epoch {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (validator_stake_account, validator_account) in validator_stake_accounts
|
for (validator_stake_account, vote_account) in
|
||||||
.iter()
|
validator_stake_accounts.iter().zip(vote_accounts.iter())
|
||||||
.zip(validator_accounts.iter())
|
|
||||||
{
|
{
|
||||||
if validator_stake_record.validator_account
|
if validator_stake_record.vote_account
|
||||||
!= validator_account.ok_or(StakePoolError::WrongStakeState)?
|
!= vote_account.ok_or(StakePoolError::WrongStakeState)?
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -794,26 +725,20 @@ impl Processor {
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// Stake pool account
|
|
||||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||||
// Account storing validator stake list
|
|
||||||
let validator_list_info = next_account_info(account_info_iter)?;
|
let validator_list_info = next_account_info(account_info_iter)?;
|
||||||
// Clock sysvar account
|
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let clock = &Clock::from_account_info(clock_info)?;
|
let clock = &Clock::from_account_info(clock_info)?;
|
||||||
|
|
||||||
// Get stake pool stake (and check if it is initialized)
|
|
||||||
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
|
||||||
if !stake_pool.is_valid() {
|
if !stake_pool.is_valid() {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validator stake account list storage
|
|
||||||
if *validator_list_info.key != stake_pool.validator_list {
|
if *validator_list_info.key != stake_pool.validator_list {
|
||||||
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read validator stake list account and check if it is valid
|
|
||||||
let validator_list =
|
let validator_list =
|
||||||
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
||||||
if !validator_list.is_valid() {
|
if !validator_list.is_valid() {
|
||||||
|
@ -867,36 +792,22 @@ impl Processor {
|
||||||
/// Processes [Deposit](enum.Instruction.html).
|
/// Processes [Deposit](enum.Instruction.html).
|
||||||
pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// Stake pool
|
|
||||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||||
// Account storing validator stake list
|
|
||||||
let validator_list_info = next_account_info(account_info_iter)?;
|
let validator_list_info = next_account_info(account_info_iter)?;
|
||||||
// Stake pool deposit authority
|
|
||||||
let deposit_info = next_account_info(account_info_iter)?;
|
let deposit_info = next_account_info(account_info_iter)?;
|
||||||
// Stake pool withdraw authority
|
|
||||||
let withdraw_info = next_account_info(account_info_iter)?;
|
let withdraw_info = next_account_info(account_info_iter)?;
|
||||||
// Stake account to join the pool (withdraw should be set to stake pool deposit)
|
|
||||||
let stake_info = next_account_info(account_info_iter)?;
|
let stake_info = next_account_info(account_info_iter)?;
|
||||||
// Validator stake account to merge with
|
|
||||||
let validator_stake_account_info = next_account_info(account_info_iter)?;
|
let validator_stake_account_info = next_account_info(account_info_iter)?;
|
||||||
// User account to receive pool tokens
|
|
||||||
let dest_user_info = next_account_info(account_info_iter)?;
|
let dest_user_info = next_account_info(account_info_iter)?;
|
||||||
// Account to receive pool fee tokens
|
|
||||||
let owner_fee_info = next_account_info(account_info_iter)?;
|
let owner_fee_info = next_account_info(account_info_iter)?;
|
||||||
// Pool token mint account
|
|
||||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||||
// Clock sysvar account
|
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let clock = &Clock::from_account_info(clock_info)?;
|
let clock = &Clock::from_account_info(clock_info)?;
|
||||||
// Stake history sysvar account
|
|
||||||
let stake_history_info = next_account_info(account_info_iter)?;
|
let stake_history_info = next_account_info(account_info_iter)?;
|
||||||
let stake_history = &StakeHistory::from_account_info(stake_history_info)?;
|
let stake_history = &StakeHistory::from_account_info(stake_history_info)?;
|
||||||
// Pool token program id
|
|
||||||
let token_program_info = next_account_info(account_info_iter)?;
|
let token_program_info = next_account_info(account_info_iter)?;
|
||||||
// Stake program id
|
|
||||||
let stake_program_info = next_account_info(account_info_iter)?;
|
let stake_program_info = next_account_info(account_info_iter)?;
|
||||||
|
|
||||||
// Check program ids
|
|
||||||
if *stake_program_info.key != stake_program::id() {
|
if *stake_program_info.key != stake_program::id() {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
@ -906,10 +817,8 @@ impl Processor {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if stake is active
|
|
||||||
Self::check_stake_activation(stake_info, clock, stake_history)?;
|
Self::check_stake_activation(stake_info, clock, stake_history)?;
|
||||||
|
|
||||||
// Check authority accounts
|
|
||||||
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
||||||
stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?;
|
stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?;
|
||||||
|
|
||||||
|
@ -920,28 +829,25 @@ impl Processor {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validator stake account list storage
|
|
||||||
if *validator_list_info.key != stake_pool.validator_list {
|
if *validator_list_info.key != stake_pool.validator_list {
|
||||||
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check stake pool last update epoch
|
|
||||||
if stake_pool.last_update_epoch < clock.epoch {
|
if stake_pool.last_update_epoch < clock.epoch {
|
||||||
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read validator stake list account and check if it is valid
|
|
||||||
let mut validator_list =
|
let mut validator_list =
|
||||||
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
||||||
if !validator_list.is_valid() {
|
if !validator_list.is_valid() {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let validator_account =
|
let vote_account =
|
||||||
Self::get_validator_checked(program_id, stake_pool_info, validator_stake_account_info)?;
|
Self::get_validator_checked(program_id, stake_pool_info, validator_stake_account_info)?;
|
||||||
|
|
||||||
let validator_list_item = validator_list
|
let validator_list_item = validator_list
|
||||||
.find_mut(&validator_account)
|
.find_mut(&vote_account)
|
||||||
.ok_or(StakePoolError::ValidatorNotFound)?;
|
.ok_or(StakePoolError::ValidatorNotFound)?;
|
||||||
|
|
||||||
let stake_lamports = **stake_info.lamports.borrow();
|
let stake_lamports = **stake_info.lamports.borrow();
|
||||||
|
@ -1031,31 +937,19 @@ impl Processor {
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
// Stake pool
|
|
||||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||||
// Account storing validator stake list
|
|
||||||
let validator_list_info = next_account_info(account_info_iter)?;
|
let validator_list_info = next_account_info(account_info_iter)?;
|
||||||
// Stake pool withdraw authority
|
|
||||||
let withdraw_info = next_account_info(account_info_iter)?;
|
let withdraw_info = next_account_info(account_info_iter)?;
|
||||||
// Stake account to split
|
|
||||||
let stake_split_from = next_account_info(account_info_iter)?;
|
let stake_split_from = next_account_info(account_info_iter)?;
|
||||||
// Unitialized stake account to receive withdrawal
|
|
||||||
let stake_split_to = next_account_info(account_info_iter)?;
|
let stake_split_to = next_account_info(account_info_iter)?;
|
||||||
// User account to set as a new withdraw authority
|
|
||||||
let user_stake_authority = next_account_info(account_info_iter)?;
|
let user_stake_authority = next_account_info(account_info_iter)?;
|
||||||
// User account with pool tokens to burn from
|
|
||||||
let burn_from_info = next_account_info(account_info_iter)?;
|
let burn_from_info = next_account_info(account_info_iter)?;
|
||||||
// Pool token mint account
|
|
||||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||||
// Clock sysvar account
|
|
||||||
let clock_info = next_account_info(account_info_iter)?;
|
let clock_info = next_account_info(account_info_iter)?;
|
||||||
let clock = &Clock::from_account_info(clock_info)?;
|
let clock = &Clock::from_account_info(clock_info)?;
|
||||||
// Pool token program id
|
|
||||||
let token_program_info = next_account_info(account_info_iter)?;
|
let token_program_info = next_account_info(account_info_iter)?;
|
||||||
// Stake program id
|
|
||||||
let stake_program_info = next_account_info(account_info_iter)?;
|
let stake_program_info = next_account_info(account_info_iter)?;
|
||||||
|
|
||||||
// Check program ids
|
|
||||||
if *stake_program_info.key != stake_program::id() {
|
if *stake_program_info.key != stake_program::id() {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
@ -1065,35 +959,31 @@ impl Processor {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check authority account
|
|
||||||
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?;
|
||||||
|
|
||||||
if stake_pool.token_program_id != *token_program_info.key {
|
if stake_pool.token_program_id != *token_program_info.key {
|
||||||
return Err(ProgramError::IncorrectProgramId);
|
return Err(ProgramError::IncorrectProgramId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validator stake account list storage
|
|
||||||
if *validator_list_info.key != stake_pool.validator_list {
|
if *validator_list_info.key != stake_pool.validator_list {
|
||||||
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
return Err(StakePoolError::InvalidValidatorStakeList.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check stake pool last update epoch
|
|
||||||
if stake_pool.last_update_epoch < clock.epoch {
|
if stake_pool.last_update_epoch < clock.epoch {
|
||||||
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read validator stake list account and check if it is valid
|
|
||||||
let mut validator_list =
|
let mut validator_list =
|
||||||
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
try_from_slice_unchecked::<ValidatorList>(&validator_list_info.data.borrow())?;
|
||||||
if !validator_list.is_valid() {
|
if !validator_list.is_valid() {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let validator_account =
|
let vote_account =
|
||||||
Self::get_validator_checked(program_id, stake_pool_info, stake_split_from)?;
|
Self::get_validator_checked(program_id, stake_pool_info, stake_split_from)?;
|
||||||
|
|
||||||
let validator_list_item = validator_list
|
let validator_list_item = validator_list
|
||||||
.find_mut(&validator_account)
|
.find_mut(&vote_account)
|
||||||
.ok_or(StakePoolError::ValidatorNotFound)?;
|
.ok_or(StakePoolError::ValidatorNotFound)?;
|
||||||
|
|
||||||
let stake_amount = stake_pool
|
let stake_amount = stake_pool
|
||||||
|
@ -1168,10 +1058,8 @@ impl Processor {
|
||||||
return Err(StakePoolError::InvalidState.into());
|
return Err(StakePoolError::InvalidState.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check owner validity and signature
|
|
||||||
stake_pool.check_owner(owner_info)?;
|
stake_pool.check_owner(owner_info)?;
|
||||||
|
|
||||||
// Check for owner fee account to have proper mint assigned
|
|
||||||
if stake_pool.pool_mint
|
if stake_pool.pool_mint
|
||||||
!= spl_token::state::Account::unpack_from_slice(&new_owner_fee_info.data.borrow())?.mint
|
!= spl_token::state::Account::unpack_from_slice(&new_owner_fee_info.data.borrow())?.mint
|
||||||
{
|
{
|
||||||
|
@ -1183,6 +1071,7 @@ impl Processor {
|
||||||
stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?;
|
stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes [Instruction](enum.Instruction.html).
|
/// Processes [Instruction](enum.Instruction.html).
|
||||||
pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {
|
pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {
|
||||||
let instruction = StakePoolInstruction::try_from_slice(input)?;
|
let instruction = StakePoolInstruction::try_from_slice(input)?;
|
||||||
|
|
|
@ -170,10 +170,10 @@ pub struct ValidatorList {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
||||||
pub struct ValidatorStakeInfo {
|
pub struct ValidatorStakeInfo {
|
||||||
/// Validator account pubkey
|
/// Validator vote account address
|
||||||
pub validator_account: Pubkey,
|
pub vote_account: Pubkey,
|
||||||
|
|
||||||
/// Account balance in lamports
|
/// Balance of the validator's stake account
|
||||||
pub balance: u64,
|
pub balance: u64,
|
||||||
|
|
||||||
/// Last epoch balance field was updated
|
/// Last epoch balance field was updated
|
||||||
|
@ -197,23 +197,23 @@ impl ValidatorList {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if contains validator with particular pubkey
|
/// Check if contains validator with particular pubkey
|
||||||
pub fn contains(&self, validator: &Pubkey) -> bool {
|
pub fn contains(&self, vote_account: &Pubkey) -> bool {
|
||||||
self.validators
|
self.validators
|
||||||
.iter()
|
.iter()
|
||||||
.any(|x| x.validator_account == *validator)
|
.any(|x| x.vote_account == *vote_account)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if contains validator with particular pubkey (mutable)
|
/// Check if contains validator with particular pubkey
|
||||||
pub fn find_mut(&mut self, validator: &Pubkey) -> Option<&mut ValidatorStakeInfo> {
|
pub fn find_mut(&mut self, vote_account: &Pubkey) -> Option<&mut ValidatorStakeInfo> {
|
||||||
self.validators
|
self.validators
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|x| x.validator_account == *validator)
|
.find(|x| x.vote_account == *vote_account)
|
||||||
}
|
}
|
||||||
/// Check if contains validator with particular pubkey (immutable)
|
/// Check if contains validator with particular pubkey
|
||||||
pub fn find(&self, validator: &Pubkey) -> Option<&ValidatorStakeInfo> {
|
pub fn find(&self, vote_account: &Pubkey) -> Option<&ValidatorStakeInfo> {
|
||||||
self.validators
|
self.validators
|
||||||
.iter()
|
.iter()
|
||||||
.find(|x| x.validator_account == *validator)
|
.find(|x| x.vote_account == *vote_account)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if validator stake list is actually initialized as a validator stake list
|
/// Check if validator stake list is actually initialized as a validator stake list
|
||||||
|
@ -271,17 +271,17 @@ mod test {
|
||||||
max_validators,
|
max_validators,
|
||||||
validators: vec![
|
validators: vec![
|
||||||
ValidatorStakeInfo {
|
ValidatorStakeInfo {
|
||||||
validator_account: Pubkey::new_from_array([1; 32]),
|
vote_account: Pubkey::new_from_array([1; 32]),
|
||||||
balance: 123456789,
|
balance: 123456789,
|
||||||
last_update_epoch: 987654321,
|
last_update_epoch: 987654321,
|
||||||
},
|
},
|
||||||
ValidatorStakeInfo {
|
ValidatorStakeInfo {
|
||||||
validator_account: Pubkey::new_from_array([2; 32]),
|
vote_account: Pubkey::new_from_array([2; 32]),
|
||||||
balance: 998877665544,
|
balance: 998877665544,
|
||||||
last_update_epoch: 11223445566,
|
last_update_epoch: 11223445566,
|
||||||
},
|
},
|
||||||
ValidatorStakeInfo {
|
ValidatorStakeInfo {
|
||||||
validator_account: Pubkey::new_from_array([3; 32]),
|
vote_account: Pubkey::new_from_array([3; 32]),
|
||||||
balance: 0,
|
balance: 0,
|
||||||
last_update_epoch: 999999999999999,
|
last_update_epoch: 999999999999999,
|
||||||
},
|
},
|
||||||
|
|
|
@ -129,7 +129,7 @@ async fn test_add_validator_to_pool() {
|
||||||
account_type: state::AccountType::ValidatorList,
|
account_type: state::AccountType::ValidatorList,
|
||||||
max_validators: stake_pool_accounts.max_validators,
|
max_validators: stake_pool_accounts.max_validators,
|
||||||
validators: vec![state::ValidatorStakeInfo {
|
validators: vec![state::ValidatorStakeInfo {
|
||||||
validator_account: user_stake.vote.pubkey(),
|
vote_account: user_stake.vote.pubkey(),
|
||||||
last_update_epoch: 0,
|
last_update_epoch: 0,
|
||||||
balance: stake_account_balance,
|
balance: stake_account_balance,
|
||||||
}]
|
}]
|
||||||
|
|
Loading…
Reference in New Issue