From 235c0034182bc0520661e10fc9bcd5d96f8a0f42 Mon Sep 17 00:00:00 2001 From: Evan Batsell Date: Mon, 24 Jun 2024 11:36:19 -0400 Subject: [PATCH] Fixes after rebase --- programs/steward/idl/steward.json | 187 +++++++++++++++++- .../steward/src/instructions/compute_score.rs | 2 +- .../src/instructions/epoch_maintenance.rs | 16 +- .../src/instructions/reset_steward_state.rs | 12 +- .../src/instructions/spl_passthrough.rs | 6 +- programs/steward/src/lib.rs | 4 +- programs/steward/src/state/steward_state.rs | 26 ++- .../auto_remove_validator_from_pool.rs | 2 +- .../commands/actions/remove_bad_validators.rs | 2 +- .../steward-cli/src/commands/command_args.rs | 4 +- .../cranks/compute_instant_unstake.rs | 4 +- .../src/commands/cranks/compute_score.rs | 4 +- .../src/commands/cranks/rebalance.rs | 4 +- .../info/view_next_index_to_remove.rs | 2 +- .../src/commands/info/view_state.rs | 4 +- 15 files changed, 230 insertions(+), 49 deletions(-) diff --git a/programs/steward/idl/steward.json b/programs/steward/idl/steward.json index 9ea51b4a..37285e0e 100644 --- a/programs/steward/idl/steward.json +++ b/programs/steward/idl/steward.json @@ -1,5 +1,5 @@ { - "address": "Stewardf95sJbmtcZsyagb2dg4Mo8eVQho8gpECvLx8", + "address": "sssh4zkKhX8jXTNQz1xDHyGpygzgu2UhcRcUvZihBjP", "metadata": { "name": "steward", "version": "0.1.0", @@ -56,6 +56,10 @@ { "name": "config" }, + { + "name": "steward_state", + "writable": true + }, { "name": "stake_pool_program" }, @@ -134,10 +138,14 @@ ], "accounts": [ { - "name": "validator_history_account" + "name": "config" }, { - "name": "config" + "name": "steward_state", + "writable": true + }, + { + "name": "validator_history_account" }, { "name": "stake_pool_program" @@ -285,6 +293,43 @@ } ] }, + { + "name": "close_steward_accounts", + "docs": [ + "Closes Steward PDA accounts associated with a given Config (StewardStateAccount, and Staker).", + "Config is not closed as it is a Keypair, so lamports can simply be withdrawn.", + "Reclaims lamports to authority" + ], + "discriminator": [ + 172, + 171, + 212, + 186, + 90, + 10, + 181, + 24 + ], + "accounts": [ + { + "name": "config" + }, + { + "name": "staker", + "writable": true + }, + { + "name": "state_account", + "writable": true + }, + { + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [] + }, { "name": "compute_delegations", "docs": [ @@ -587,6 +632,45 @@ } ] }, + { + "name": "epoch_maintenance", + "docs": [ + "Housekeeping, run at the start of any new epoch before any other instructions" + ], + "discriminator": [ + 208, + 225, + 211, + 82, + 219, + 242, + 58, + 200 + ], + "accounts": [ + { + "name": "config" + }, + { + "name": "state_account", + "writable": true + }, + { + "name": "validator_list" + }, + { + "name": "stake_pool" + } + ], + "args": [ + { + "name": "validator_index_to_remove", + "type": { + "option": "u64" + } + } + ] + }, { "name": "idle", "docs": [ @@ -1145,6 +1229,43 @@ } ] }, + { + "name": "reset_steward_state", + "docs": [ + "Resets steward state account to its initial state." + ], + "discriminator": [ + 84, + 248, + 158, + 46, + 200, + 205, + 234, + 86 + ], + "accounts": [ + { + "name": "state_account", + "writable": true + }, + { + "name": "config" + }, + { + "name": "stake_pool" + }, + { + "name": "validator_list" + }, + { + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [] + }, { "name": "resume_steward", "discriminator": [ @@ -1560,6 +1681,31 @@ "code": 6022, "name": "ValidatorHistoryMismatch", "msg": "Validator history account does not match vote account" + }, + { + "code": 6023, + "name": "EpochMaintenanceNotComplete", + "msg": "Epoch Maintenance must be called before continuing" + }, + { + "code": 6024, + "name": "StakePoolNotUpdated", + "msg": "The stake pool must be updated before continuing" + }, + { + "code": 6025, + "name": "ValidatorNotMarkedForRemoval", + "msg": "Validator not marked for removal" + }, + { + "code": 6026, + "name": "ValidatorsHaveNotBeenRemoved", + "msg": "Validators have not been removed" + }, + { + "code": 6027, + "name": "ListStateMismatch", + "msg": "Validator List count does not match state machine" } ], "types": [ @@ -2250,7 +2396,8 @@ "name": "StewardState", "docs": [ "Tracks state of the stake pool.", - "Follow state transitions here: [TODO add link to github diagram]" + "Follow state transitions here:", + "https://github.com/jito-foundation/stakenet/blob/master/programs/steward/state-machine-diagram.png" ], "serialization": "bytemuck", "repr": { @@ -2369,6 +2516,18 @@ } } }, + { + "name": "validators_to_remove", + "docs": [ + "Marks a validator for removal after `remove_validator_from_pool` has been called on the stake pool", + "This is cleaned up in the next epoch" + ], + "type": { + "defined": { + "name": "BitMask" + } + } + }, { "name": "start_computing_scores_slot", "docs": [ @@ -2419,6 +2578,13 @@ ], "type": "u64" }, + { + "name": "validators_added", + "docs": [ + "Number of validators added to the pool in the current cycle" + ], + "type": "u16" + }, { "name": "compute_delegations_completed", "docs": [ @@ -2441,6 +2607,17 @@ } } }, + { + "name": "checked_validators_removed_from_list", + "docs": [ + "So we only have to check the validator list once for `ReadyToRemove`" + ], + "type": { + "defined": { + "name": "U8Bool" + } + } + }, { "name": "_padding0", "docs": [ @@ -2449,7 +2626,7 @@ "type": { "array": [ "u8", - 40006 + 40003 ] } } diff --git a/programs/steward/src/instructions/compute_score.rs b/programs/steward/src/instructions/compute_score.rs index c93f618a..53d32d51 100644 --- a/programs/steward/src/instructions/compute_score.rs +++ b/programs/steward/src/instructions/compute_score.rs @@ -91,7 +91,7 @@ pub fn handler(ctx: Context, validator_list_index: usize) -> Resul validator_list_index, &cluster_history, &config, - num_pool_validators, + num_pool_validators as u64, )?; maybe_transition_and_emit( diff --git a/programs/steward/src/instructions/epoch_maintenance.rs b/programs/steward/src/instructions/epoch_maintenance.rs index 4cf1bd30..037ec2d7 100644 --- a/programs/steward/src/instructions/epoch_maintenance.rs +++ b/programs/steward/src/instructions/epoch_maintenance.rs @@ -1,7 +1,8 @@ use crate::{ errors::StewardError, utils::{ - check_validator_list_has_stake_status, get_stake_pool, get_validator_list_length, StakePool, + check_validator_list_has_stake_status, deserialize_stake_pool, get_stake_pool_address, + get_validator_list_length, }, Config, StewardStateAccount, }; @@ -19,13 +20,15 @@ pub struct EpochMaintenance<'info> { )] pub state_account: AccountLoader<'info, StewardStateAccount>, - #[account(mut, address = stake_pool.validator_list)] + /// CHECK: Correct account guaranteed if address is correct + #[account(address = deserialize_stake_pool(&stake_pool)?.validator_list)] pub validator_list: AccountInfo<'info>, + /// CHECK: Correct account guaranteed if address is correct #[account( - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, } /// Runs maintenance tasks at the start of each epoch, needs to be run multiple times @@ -35,7 +38,7 @@ pub fn handler( ctx: Context, validator_index_to_remove: Option, ) -> Result<()> { - let stake_pool = &ctx.accounts.stake_pool; + let stake_pool = deserialize_stake_pool(&ctx.accounts.stake_pool)?; let mut state_account = ctx.accounts.state_account.load_mut()?; let clock = Clock::get()?; @@ -65,7 +68,8 @@ pub fn handler( // Ensure we have a 1-1 mapping between the number of validators in the list and the number of validators in the state require!( - state_account.state.num_pool_validators + state_account.state.validators_added as usize + state_account.state.num_pool_validators as usize + + state_account.state.validators_added as usize - validators_to_remove == validators_in_list, StewardError::ListStateMismatch diff --git a/programs/steward/src/instructions/reset_steward_state.rs b/programs/steward/src/instructions/reset_steward_state.rs index 0140f7d6..9ec002ac 100644 --- a/programs/steward/src/instructions/reset_steward_state.rs +++ b/programs/steward/src/instructions/reset_steward_state.rs @@ -2,7 +2,7 @@ use crate::{ constants::{MAX_VALIDATORS, SORTED_INDEX_DEFAULT}, errors::StewardError, state::{Config, StewardStateAccount}, - utils::{get_config_authority, get_stake_pool, StakePool}, + utils::{deserialize_stake_pool, get_config_authority, get_stake_pool_address}, BitMask, Delegation, StewardStateEnum, STATE_PADDING_0_SIZE, }; use anchor_lang::prelude::*; @@ -19,10 +19,12 @@ pub struct ResetStewardState<'info> { pub config: AccountLoader<'info, Config>, - #[account(address = get_stake_pool(&config)?)] - pub stake_pool: Account<'info, StakePool>, + /// CHECK: Correct account guaranteed if address is correct + #[account(address = get_stake_pool_address(&config)?)] + pub stake_pool: AccountInfo<'info>, - #[account(address = stake_pool.validator_list)] + /// CHECK: Correct account guaranteed if address is correct + #[account(address = deserialize_stake_pool(&stake_pool)?.validator_list)] pub validator_list: AccountInfo<'info>, #[account(mut, address = get_config_authority(&config)?)] @@ -44,7 +46,7 @@ pub fn handler(ctx: Context) -> Result<()> { let (_, validator_list) = ValidatorListHeader::deserialize_vec(validator_list_data)?; state_account.state.state_tag = StewardStateEnum::ComputeScores; - state_account.state.num_pool_validators = validator_list.len() as usize; + state_account.state.num_pool_validators = validator_list.len() as u64; state_account.state.scores = [0; MAX_VALIDATORS]; state_account.state.sorted_score_indices = [SORTED_INDEX_DEFAULT; MAX_VALIDATORS]; state_account.state.yield_scores = [0; MAX_VALIDATORS]; diff --git a/programs/steward/src/instructions/spl_passthrough.rs b/programs/steward/src/instructions/spl_passthrough.rs index fb6771d0..901d6b0b 100644 --- a/programs/steward/src/instructions/spl_passthrough.rs +++ b/programs/steward/src/instructions/spl_passthrough.rs @@ -165,7 +165,7 @@ pub struct RemoveValidatorFromPool<'info> { /// CHECK: passing through, checks are done by spl-stake-pool pub withdraw_authority: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool - #[account(mut)] + #[account(mut, address = deserialize_stake_pool(&stake_pool)?.validator_list)] pub validator_list: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool #[account(mut)] @@ -335,7 +335,7 @@ pub struct IncreaseValidatorStake<'info> { /// CHECK: passing through, checks are done by spl-stake-pool pub withdraw_authority: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool - #[account(mut, address = stake_pool.validator_list)] + #[account(mut, address = deserialize_stake_pool(&stake_pool)?.validator_list)] pub validator_list: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool #[account( @@ -464,7 +464,7 @@ pub struct DecreaseValidatorStake<'info> { /// CHECK: passing through, checks are done by spl-stake-pool pub withdraw_authority: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool - #[account(mut, address = stake_pool.validator_list)] + #[account(mut, address = deserialize_stake_pool(&stake_pool)?.validator_list)] pub validator_list: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool #[account( diff --git a/programs/steward/src/lib.rs b/programs/steward/src/lib.rs index 4f9578b7..0e280f7b 100644 --- a/programs/steward/src/lib.rs +++ b/programs/steward/src/lib.rs @@ -94,9 +94,9 @@ pub mod steward { /// Housekeeping, run at the start of any new epoch before any other instructions pub fn epoch_maintenance( ctx: Context, - validator_index_to_remove: Option, + validator_index_to_remove: Option, ) -> Result<()> { - instructions::epoch_maintenance::handler(ctx, validator_index_to_remove) + instructions::epoch_maintenance::handler(ctx, validator_index_to_remove.map(|x| x as usize)) } /// Computes score for a the validator at `validator_list_index` for the current cycle. diff --git a/programs/steward/src/state/steward_state.rs b/programs/steward/src/state/steward_state.rs index 6ad1c68d..3cf17131 100644 --- a/programs/steward/src/state/steward_state.rs +++ b/programs/steward/src/state/steward_state.rs @@ -469,14 +469,14 @@ impl StewardState { .position(|&i| i == index as u16); if let Some(yield_score_index) = yield_score_index { - for i in yield_score_index..self.num_pool_validators { + for i in yield_score_index..num_pool_validators { let next_i = i.checked_add(1).ok_or(StewardError::ArithmeticError)?; self.sorted_yield_score_indices[i] = self.sorted_yield_score_indices[next_i]; } } if let Some(score_index) = score_index { - for i in score_index..self.num_pool_validators { + for i in score_index..num_pool_validators { let next_i = i.checked_add(1).ok_or(StewardError::ArithmeticError)?; self.sorted_score_indices[i] = self.sorted_score_indices[next_i]; } @@ -496,16 +496,15 @@ impl StewardState { } // Clear values on empty last index - self.validator_lamport_balances[self.num_pool_validators] = 0; - self.scores[self.num_pool_validators] = 0; - self.yield_scores[self.num_pool_validators] = 0; - self.sorted_score_indices[self.num_pool_validators] = SORTED_INDEX_DEFAULT; - self.sorted_yield_score_indices[self.num_pool_validators] = SORTED_INDEX_DEFAULT; - self.delegations[self.num_pool_validators] = Delegation::default(); - self.instant_unstake.set(self.num_pool_validators, false)?; - self.validators_to_remove - .set(self.num_pool_validators, false)?; - self.progress.set(self.num_pool_validators, false)?; + self.validator_lamport_balances[num_pool_validators] = 0; + self.scores[num_pool_validators] = 0; + self.yield_scores[num_pool_validators] = 0; + self.sorted_score_indices[num_pool_validators] = SORTED_INDEX_DEFAULT; + self.sorted_yield_score_indices[num_pool_validators] = SORTED_INDEX_DEFAULT; + self.delegations[num_pool_validators] = Delegation::default(); + self.instant_unstake.set(num_pool_validators, false)?; + self.validators_to_remove.set(num_pool_validators, false)?; + self.progress.set(num_pool_validators, false)?; Ok(()) } @@ -568,8 +567,7 @@ impl StewardState { // Updates num_pool_validators at the start of the cycle so validator additions later won't be considered require!( - num_pool_validators - == self.num_pool_validators + self.validators_added as usize, + num_pool_validators == self.num_pool_validators + self.validators_added as u64, StewardError::ListStateMismatch ); self.num_pool_validators = num_pool_validators; diff --git a/utils/steward-cli/src/commands/actions/auto_remove_validator_from_pool.rs b/utils/steward-cli/src/commands/actions/auto_remove_validator_from_pool.rs index 6b80c248..9fa2f442 100644 --- a/utils/steward-cli/src/commands/actions/auto_remove_validator_from_pool.rs +++ b/utils/steward-cli/src/commands/actions/auto_remove_validator_from_pool.rs @@ -85,7 +85,7 @@ pub async fn command_auto_remove_validator_from_pool( } .to_account_metas(None), data: jito_steward::instruction::AutoRemoveValidatorFromPool { - validator_list_index: validator_index, + validator_list_index: validator_index as u64, } .data(), }; diff --git a/utils/steward-cli/src/commands/actions/remove_bad_validators.rs b/utils/steward-cli/src/commands/actions/remove_bad_validators.rs index 40a6bb07..a444ec42 100644 --- a/utils/steward-cli/src/commands/actions/remove_bad_validators.rs +++ b/utils/steward-cli/src/commands/actions/remove_bad_validators.rs @@ -122,7 +122,7 @@ pub async fn command_remove_bad_validators( } .to_account_metas(None), data: jito_steward::instruction::RemoveValidatorFromPool { - validator_list_index: *validator_index, + validator_list_index: *validator_index as u64, } .data(), } diff --git a/utils/steward-cli/src/commands/command_args.rs b/utils/steward-cli/src/commands/command_args.rs index 7a3e6aea..35786910 100644 --- a/utils/steward-cli/src/commands/command_args.rs +++ b/utils/steward-cli/src/commands/command_args.rs @@ -80,7 +80,7 @@ pub struct ConfigParameters { /// Scoring window such that the validators are all scored within a similar timeframe (in slots) #[arg(long, env)] - pub compute_score_slot_range: Option, + pub compute_score_slot_range: Option, /// Point in epoch progress before instant unstake can be computed #[arg(long, env)] @@ -328,7 +328,7 @@ pub struct CrankEpochMaintenance { /// Validator index to remove, gotten from `validators_to_remove` Bitmask #[arg(long, env)] - pub validator_index_to_remove: Option, + pub validator_index_to_remove: Option, } #[derive(Parser)] diff --git a/utils/steward-cli/src/commands/cranks/compute_instant_unstake.rs b/utils/steward-cli/src/commands/cranks/compute_instant_unstake.rs index b9aad99b..c4f5f7eb 100644 --- a/utils/steward-cli/src/commands/cranks/compute_instant_unstake.rs +++ b/utils/steward-cli/src/commands/cranks/compute_instant_unstake.rs @@ -46,7 +46,7 @@ pub async fn command_crank_compute_instant_unstake( } } - let validators_to_run = (0..steward_accounts.state_account.state.num_pool_validators) + let validators_to_run = (0..steward_accounts.state_account.state.num_pool_validators as usize) .filter_map(|validator_index| { let has_been_scored = steward_accounts .state_account @@ -84,7 +84,7 @@ pub async fn command_crank_compute_instant_unstake( } .to_account_metas(None), data: jito_steward::instruction::ComputeInstantUnstake { - validator_list_index: *validator_index, + validator_list_index: *validator_index as u64, } .data(), }) diff --git a/utils/steward-cli/src/commands/cranks/compute_score.rs b/utils/steward-cli/src/commands/cranks/compute_score.rs index f8ce4dcb..92d888a8 100644 --- a/utils/steward-cli/src/commands/cranks/compute_score.rs +++ b/utils/steward-cli/src/commands/cranks/compute_score.rs @@ -46,7 +46,7 @@ pub async fn command_crank_compute_score( } } - let validators_to_run = (0..steward_accounts.state_account.state.num_pool_validators) + let validators_to_run = (0..steward_accounts.state_account.state.num_pool_validators as usize) .filter_map(|validator_index| { let has_been_scored = steward_accounts .state_account @@ -90,7 +90,7 @@ pub async fn command_crank_compute_score( } .to_account_metas(None), data: jito_steward::instruction::ComputeScore { - validator_list_index: *validator_index, + validator_list_index: *validator_index as u64, } .data(), } diff --git a/utils/steward-cli/src/commands/cranks/rebalance.rs b/utils/steward-cli/src/commands/cranks/rebalance.rs index e3e86481..62b94f4b 100644 --- a/utils/steward-cli/src/commands/cranks/rebalance.rs +++ b/utils/steward-cli/src/commands/cranks/rebalance.rs @@ -47,7 +47,7 @@ pub async fn command_crank_rebalance( } } - let validators_to_run = (0..steward_accounts.state_account.state.num_pool_validators) + let validators_to_run = (0..steward_accounts.state_account.state.num_pool_validators as usize) .filter_map(|validator_index| { let has_been_rebalanced = steward_accounts .state_account @@ -114,7 +114,7 @@ pub async fn command_crank_rebalance( } .to_account_metas(None), data: jito_steward::instruction::Rebalance { - validator_list_index: *validator_index, + validator_list_index: *validator_index as u64, } .data(), } diff --git a/utils/steward-cli/src/commands/info/view_next_index_to_remove.rs b/utils/steward-cli/src/commands/info/view_next_index_to_remove.rs index 511b78c8..97bbc383 100644 --- a/utils/steward-cli/src/commands/info/view_next_index_to_remove.rs +++ b/utils/steward-cli/src/commands/info/view_next_index_to_remove.rs @@ -27,7 +27,7 @@ fn _print_next_index_to_remove(steward_state_accounts: &UsefulStewardAccounts) { for i in 0..steward_state_accounts .state_account .state - .num_pool_validators + .num_pool_validators as usize { let value = steward_state_accounts .state_account diff --git a/utils/steward-cli/src/commands/info/view_state.rs b/utils/steward-cli/src/commands/info/view_state.rs index 1703de4f..a96d8073 100644 --- a/utils/steward-cli/src/commands/info/view_state.rs +++ b/utils/steward-cli/src/commands/info/view_state.rs @@ -132,7 +132,7 @@ fn _print_default_state( "Progress: {:?} / {} ({} remaining)\n", state.progress.count(), state.num_pool_validators, - state.num_pool_validators - state.progress.count() + state.num_pool_validators - state.progress.count() as u64 ); formatted_string += &format!( "Validator Lamport Balances Count: {}\n", @@ -154,7 +154,7 @@ fn _print_default_state( "Progress: {:?} / {} ( {} left )\n", state.progress.count(), state.num_pool_validators, - state.num_pool_validators - state.progress.count() + state.num_pool_validators - state.progress.count() as u64 ); formatted_string += &format!( "Start Computing Scores Slot: {}\n",