diff --git a/programs/steward/src/instructions/auto_add_validator_to_pool.rs b/programs/steward/src/instructions/auto_add_validator_to_pool.rs index c2e05cd9..614093f3 100644 --- a/programs/steward/src/instructions/auto_add_validator_to_pool.rs +++ b/programs/steward/src/instructions/auto_add_validator_to_pool.rs @@ -2,7 +2,7 @@ use crate::constants::{MAX_VALIDATORS, STAKE_POOL_WITHDRAW_SEED}; use crate::errors::StewardError; use crate::events::AutoAddValidatorEvent; use crate::state::{Config, StewardStateAccount}; -use crate::utils::{deserialize_stake_pool, get_stake_pool_address}; +use crate::utils::{deserialize_stake_pool, get_stake_pool_address, get_validator_list_length}; use anchor_lang::prelude::*; use anchor_lang::solana_program::{program::invoke_signed, stake, sysvar, vote}; use spl_stake_pool::find_stake_program_address; @@ -106,13 +106,21 @@ pub fn handler(ctx: Context) -> Result<()> { let validator_history = ctx.accounts.validator_history_account.load()?; let epoch = Clock::get()?.epoch; - //TODO Cannot add if validator mismatch - - // Should not be able to add a validator if update is not complete - require!( - epoch == state_account.state.current_epoch, - StewardError::EpochMaintenanceNotComplete - ); + { + // CHECKS + require!( + epoch == state_account.state.current_epoch, + StewardError::EpochMaintenanceNotComplete + ); + + let validators_in_list = get_validator_list_length(&ctx.accounts.validator_list)?; + require!( + state_account.state.num_pool_validators as usize + + state_account.state.validators_added as usize + == validators_in_list, + StewardError::ListStateMismatch + ); + } let validator_list_len = { let validator_list_data = &mut ctx.accounts.validator_list.try_borrow_mut_data()?; diff --git a/programs/steward/src/instructions/auto_remove_validator_from_pool.rs b/programs/steward/src/instructions/auto_remove_validator_from_pool.rs index babe8dcc..4d2d2dac 100644 --- a/programs/steward/src/instructions/auto_remove_validator_from_pool.rs +++ b/programs/steward/src/instructions/auto_remove_validator_from_pool.rs @@ -5,7 +5,8 @@ use crate::errors::StewardError; use crate::events::AutoRemoveValidatorEvent; use crate::state::Config; use crate::utils::{ - deserialize_stake_pool, get_stake_pool_address, get_validator_stake_info_at_index, + deserialize_stake_pool, get_stake_pool_address, get_validator_list_length, + get_validator_stake_info_at_index, }; use crate::StewardStateAccount; use anchor_lang::solana_program::{program::invoke_signed, stake, sysvar, vote}; @@ -124,13 +125,27 @@ pub struct AutoRemoveValidator<'info> { */ pub fn handler(ctx: Context, validator_list_index: usize) -> Result<()> { - //TODO Cannot remove if mismatch - { let mut state_account = ctx.accounts.state_account.load_mut()?; let validator_list = &ctx.accounts.validator_list; let epoch = Clock::get()?.epoch; + { + // CHECKS + require!( + epoch == state_account.state.current_epoch, + StewardError::EpochMaintenanceNotComplete + ); + + let validators_in_list = get_validator_list_length(&ctx.accounts.validator_list)?; + require!( + state_account.state.num_pool_validators as usize + + state_account.state.validators_added as usize + == validators_in_list, + StewardError::ListStateMismatch + ); + } + let validator_stake_info = get_validator_stake_info_at_index(validator_list, validator_list_index)?; require!( diff --git a/programs/steward/src/instructions/index_mismatch_interrupt.rs b/programs/steward/src/instructions/index_mismatch_interrupt.rs index ef84e159..18146c04 100644 --- a/programs/steward/src/instructions/index_mismatch_interrupt.rs +++ b/programs/steward/src/instructions/index_mismatch_interrupt.rs @@ -1,11 +1,14 @@ use crate::{ errors::StewardError, events::IndexMismatchInterruptEvent, - utils::{deserialize_stake_pool, get_stake_pool_address, get_validator_list_length}, + utils::{ + deserialize_stake_pool, deserialize_validator_list, get_stake_pool_address, + get_validator_list_length, + }, Config, StewardStateAccount, }; use anchor_lang::prelude::*; -use spl_stake_pool::state::ValidatorListHeader; +use spl_stake_pool::state::StakeStatus; #[derive(Accounts)] pub struct IndexMismatchInterrupt<'info> { @@ -34,6 +37,22 @@ pub struct IndexMismatchInterrupt<'info> { /// - Remove delinquent validators pub fn handler(ctx: Context) -> Result<()> { let mut state_account = ctx.accounts.state_account.load_mut()?; + let validator_list = deserialize_validator_list(&ctx.accounts.validator_list)?; + + // { + // // Need there to be a mismatch + // require!( + // state_account.state.num_pool_validators as usize + // + state_account.state.validators_added as usize + // != validator_list.validators.len(), + // StewardError::ListStateMismatch + // ); + + // require!( + // state_account.state.validators_to_remove.count() > 0, + // StewardError::NoValidatorsToRemove + // ) + // } // How do we know if a validator has been removed? @@ -42,15 +61,30 @@ pub fn handler(ctx: Context) -> Result<()> { // Use diff amount to find correct index to remove //TODO take out validator index to remove - we always remove the lowest index - { - require!( - state_account - .state - .validators_to_remove - .get(validator_index_to_remove)?, - StewardError::ValidatorNotMarkedForRemoval - ); - } + let mut validator_index_to_remove = validator_list.validators.len(); + + // for i in smallest_index..validator_list.validators.len() { + // let validator = &validator_list.validators[i]; + // let stake_status = StakeStatus::try_from(validator.status).unwrap(); + + // match stake_status { + // StakeStatus::Active => { + // // If what's coming up is active this means the validator has been removed and + // // shifted + // validator_index_to_remove = i; + // } + // StakeStatus::DeactivatingTransient + // | StakeStatus::ReadyForRemoval + // | StakeStatus::DeactivatingValidator + // | StakeStatus::DeactivatingAll => { + // // Index has not yet been removed + // } + // } + + // if validator_index_to_remove != validator_list.validators.len() { + // break; + // } + // } state_account .state