From e59ba78fc47da2ff3fff458bb85e4dcb65584e6a Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Wed, 31 Jul 2024 17:00:41 -0600 Subject: [PATCH 1/4] almost there --- utils/steward-cli/src/commands/actions/mod.rs | 1 + .../src/commands/actions/surgery.rs | 95 +++++++++++++++++++ .../steward-cli/src/commands/command_args.rs | 18 +++- utils/steward-cli/src/main.rs | 13 +-- 4 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 utils/steward-cli/src/commands/actions/surgery.rs diff --git a/utils/steward-cli/src/commands/actions/mod.rs b/utils/steward-cli/src/commands/actions/mod.rs index 26b60d27..c98c0656 100644 --- a/utils/steward-cli/src/commands/actions/mod.rs +++ b/utils/steward-cli/src/commands/actions/mod.rs @@ -2,4 +2,5 @@ pub mod auto_add_validator_from_pool; pub mod auto_remove_validator_from_pool; pub mod remove_bad_validators; pub mod reset_state; +pub mod surgery; pub mod update_config; diff --git a/utils/steward-cli/src/commands/actions/surgery.rs b/utils/steward-cli/src/commands/actions/surgery.rs new file mode 100644 index 00000000..e806027e --- /dev/null +++ b/utils/steward-cli/src/commands/actions/surgery.rs @@ -0,0 +1,95 @@ +use std::sync::Arc; + +use anchor_lang::{InstructionData, ToAccountMetas}; +use anyhow::Result; +use solana_client::nonblocking::rpc_client::RpcClient; +use solana_program::instruction::Instruction; + +use solana_sdk::{ + pubkey::Pubkey, signature::read_keypair_file, signer::Signer, transaction::Transaction, +}; + +use crate::{ + commands::command_args::Surgery, + utils::{ + accounts::{ + get_all_steward_accounts, get_steward_state_account, get_steward_state_address, + }, + transactions::configure_instruction, + }, +}; + +pub async fn command_surgery( + args: Surgery, + client: &Arc, + program_id: Pubkey, +) -> Result<()> { + let validator_list_index: u64 = 0; + let mark_for_removal: u8 = 0xFF; // TRUE + let immediate: u8 = 0x00; // FALSE + + let authority = read_keypair_file(args.permissioned_parameters.authority_keypair_path) + .expect("Failed reading keypair file ( Authority )"); + + let steward_config_address = args.permissioned_parameters.steward_config; + let steward_state_address = get_steward_state_address(&program_id, &steward_config_address); + + let steward_state_account = + get_steward_state_account(client, &program_id, &steward_config_address); + + { + // CHECK index + + println!("Validator list index: {}", validator_list_index); + println!("Mark for removal: {}", mark_for_removal); + println!("Immediate: {}", immediate); + } + + if args.submit_ix { + let ix = Instruction { + program_id, + accounts: jito_steward::accounts::AdminMarkForRemoval { + state_account: steward_state_address, + config: steward_config_address, + authority: authority.pubkey(), + } + .to_account_metas(None), + data: jito_steward::instruction::AdminMarkForRemoval { + validator_list_index, + mark_for_removal, + immediate, + } + .data(), + }; + + let blockhash = client.get_latest_blockhash().await?; + + let configured_ix = configure_instruction( + &[ix], + args.permissioned_parameters + .transaction_parameters + .priority_fee, + args.permissioned_parameters + .transaction_parameters + .compute_limit, + args.permissioned_parameters + .transaction_parameters + .heap_size, + ); + + let transaction = Transaction::new_signed_with_payer( + &configured_ix, + Some(&authority.pubkey()), + &[&authority], + blockhash, + ); + + let signature = client + .send_and_confirm_transaction_with_spinner(&transaction) + .await?; + + println!("Signature: {}", signature); + } + + Ok(()) +} diff --git a/utils/steward-cli/src/commands/command_args.rs b/utils/steward-cli/src/commands/command_args.rs index 35786910..2d2935b7 100644 --- a/utils/steward-cli/src/commands/command_args.rs +++ b/utils/steward-cli/src/commands/command_args.rs @@ -189,14 +189,15 @@ pub enum Commands { // Views ViewState(ViewState), ViewConfig(ViewConfig), - ViewNextIndexToRemove(ViewNextIndexToRemove), + // ViewNextIndexToRemove(ViewNextIndexToRemove), // Actions InitConfig(InitConfig), UpdateConfig(UpdateConfig), - InitState(InitState), - ResetState(ResetState), + // InitState(InitState), + // ResetState(ResetState), + Surgery(Surgery), RemoveBadValidators(RemoveBadValidators), AutoRemoveValidatorFromPool(AutoRemoveValidatorFromPool), @@ -289,6 +290,17 @@ pub struct ResetState { pub permissioned_parameters: PermissionedParameters, } +#[derive(Parser)] +#[command(about = "Mark the correct validator for removal")] +pub struct Surgery { + #[command(flatten)] + pub permissioned_parameters: PermissionedParameters, + + /// Validator index of validator list to remove + #[arg(long, default_value = "false")] + pub submit_ix: bool, +} + #[derive(Parser)] #[command(about = "Removes bad validators from the pool")] pub struct RemoveBadValidators { diff --git a/utils/steward-cli/src/main.rs b/utils/steward-cli/src/main.rs index 79e941a3..c207e69d 100644 --- a/utils/steward-cli/src/main.rs +++ b/utils/steward-cli/src/main.rs @@ -5,7 +5,7 @@ use commands::{ auto_add_validator_from_pool::command_auto_add_validator_from_pool, auto_remove_validator_from_pool::command_auto_remove_validator_from_pool, remove_bad_validators::command_remove_bad_validators, reset_state::command_reset_state, - update_config::command_update_config, + surgery::command_surgery, update_config::command_update_config, }, command_args::{Args, Commands}, cranks::{ @@ -42,15 +42,16 @@ async fn main() -> Result<()> { // ---- Views ---- Commands::ViewConfig(args) => command_view_config(args, &client, program_id).await, Commands::ViewState(args) => command_view_state(args, &client, program_id).await, - Commands::ViewNextIndexToRemove(args) => { - command_view_next_index_to_remove(args, &client, program_id).await - } + // Commands::ViewNextIndexToRemove(args) => { + // command_view_next_index_to_remove(args, &client, program_id).await + // } // --- Actions --- Commands::InitConfig(args) => command_init_config(args, &client, program_id).await, Commands::UpdateConfig(args) => command_update_config(args, &client, program_id).await, - Commands::InitState(args) => command_init_state(args, &client, program_id).await, - Commands::ResetState(args) => command_reset_state(args, &client, program_id).await, + // Commands::InitState(args) => command_init_state(args, &client, program_id).await, + // Commands::ResetState(args) => command_reset_state(args, &client, program_id).await, + Commands::Surgery(args) => command_surgery(args, &client, program_id).await, Commands::AutoRemoveValidatorFromPool(args) => { command_auto_remove_validator_from_pool(args, &client, program_id).await } From 1463d29d1242055f04596c03d2f854f8480e0196 Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Wed, 31 Jul 2024 17:06:05 -0600 Subject: [PATCH 2/4] added admin mark ix --- .../instructions/admin_mark_for_removal.rs | 45 +++++++++++++++++++ programs/steward/src/instructions/mod.rs | 2 + programs/steward/src/lib.rs | 16 +++++++ 3 files changed, 63 insertions(+) create mode 100644 programs/steward/src/instructions/admin_mark_for_removal.rs diff --git a/programs/steward/src/instructions/admin_mark_for_removal.rs b/programs/steward/src/instructions/admin_mark_for_removal.rs new file mode 100644 index 00000000..a15ddfd7 --- /dev/null +++ b/programs/steward/src/instructions/admin_mark_for_removal.rs @@ -0,0 +1,45 @@ +use anchor_lang::prelude::*; + +use crate::{utils::get_config_admin, Config, StewardStateAccount}; + +#[derive(Accounts)] +pub struct AdminMarkForRemoval<'info> { + #[account(mut)] + pub config: AccountLoader<'info, Config>, + + #[account( + mut, + seeds = [StewardStateAccount::SEED, config.key().as_ref()], + bump + )] + pub state_account: AccountLoader<'info, StewardStateAccount>, + + #[account(mut, address = get_config_admin(&config)?)] + pub authority: Signer<'info>, +} + +/* +Used by the admin to unstick the machine +*/ +pub fn handler( + ctx: Context, + validator_list_index: usize, + mark_for_removal: bool, + immediate: bool, +) -> Result<()> { + let mut state = ctx.accounts.state_account.load_mut()?; + + if immediate { + state + .state + .validators_for_immediate_removal + .set(validator_list_index, mark_for_removal)?; + } else { + state + .state + .validators_to_remove + .set(validator_list_index, mark_for_removal)?; + } + + Ok(()) +} diff --git a/programs/steward/src/instructions/mod.rs b/programs/steward/src/instructions/mod.rs index 27337283..bf719923 100644 --- a/programs/steward/src/instructions/mod.rs +++ b/programs/steward/src/instructions/mod.rs @@ -1,5 +1,6 @@ #![allow(ambiguous_glob_reexports)] pub mod add_validator_to_blacklist; +pub mod admin_mark_for_removal; pub mod auto_add_validator_to_pool; pub mod auto_remove_validator_from_pool; pub mod close_steward_accounts; @@ -21,6 +22,7 @@ pub mod spl_passthrough; pub mod update_parameters; pub use add_validator_to_blacklist::*; +pub use admin_mark_for_removal::*; pub use auto_add_validator_to_pool::*; pub use auto_remove_validator_from_pool::*; pub use close_steward_accounts::*; diff --git a/programs/steward/src/lib.rs b/programs/steward/src/lib.rs index 67b9ae69..9eda916a 100644 --- a/programs/steward/src/lib.rs +++ b/programs/steward/src/lib.rs @@ -62,6 +62,7 @@ If manual intervention is required, the following spl-stake-pool instructions ar */ #[program] pub mod steward { + use super::*; /* Initialization instructions */ @@ -191,6 +192,21 @@ pub mod steward { instructions::reset_steward_state::handler(ctx) } + /// Admin to mark or unmark validator for removal and unstuck the machine + pub fn admin_mark_for_removal( + ctx: Context, + validator_list_index: u64, + mark_for_removal: u8, + immediate: u8, + ) -> Result<()> { + instructions::admin_mark_for_removal::handler( + ctx, + validator_list_index as usize, + mark_for_removal != 0, + immediate != 0, + ) + } + /// 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 From f1eef4f3e5221c5008bd25113578b2068903cd3d Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Wed, 31 Jul 2024 17:29:20 -0600 Subject: [PATCH 3/4] fixed issues --- .../src/commands/actions/surgery.rs | 36 +++++++++++++++---- .../steward-cli/src/commands/command_args.rs | 16 ++++++--- utils/steward-cli/src/main.rs | 10 +++--- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/utils/steward-cli/src/commands/actions/surgery.rs b/utils/steward-cli/src/commands/actions/surgery.rs index e806027e..c9819069 100644 --- a/utils/steward-cli/src/commands/actions/surgery.rs +++ b/utils/steward-cli/src/commands/actions/surgery.rs @@ -13,7 +13,8 @@ use crate::{ commands::command_args::Surgery, utils::{ accounts::{ - get_all_steward_accounts, get_steward_state_account, get_steward_state_address, + get_steward_config_account, get_steward_state_account, get_steward_state_address, + get_validator_list_account, }, transactions::configure_instruction, }, @@ -24,9 +25,21 @@ pub async fn command_surgery( client: &Arc, program_id: Pubkey, ) -> Result<()> { - let validator_list_index: u64 = 0; - let mark_for_removal: u8 = 0xFF; // TRUE - let immediate: u8 = 0x00; // FALSE + let validator_list_index: u64 = args.validator_list_index as u64; + let mark_for_removal: u8 = { + if args.mark_for_removal { + 0xFF // TRUE + } else { + 0x00 // FALSE + } + }; + let immediate: u8 = { + if args.immediate { + 0xFF // TRUE + } else { + 0x00 // FALSE + } + }; let authority = read_keypair_file(args.permissioned_parameters.authority_keypair_path) .expect("Failed reading keypair file ( Authority )"); @@ -34,15 +47,24 @@ pub async fn command_surgery( let steward_config_address = args.permissioned_parameters.steward_config; let steward_state_address = get_steward_state_address(&program_id, &steward_config_address); - let steward_state_account = - get_steward_state_account(client, &program_id, &steward_config_address); + let steward_config_account = + get_steward_config_account(client, &steward_config_address).await?; + let validator_list_account = + get_validator_list_account(client, &steward_config_account.validator_list).await?; { - // CHECK index + println!("Submit: {}", args.submit_ix); println!("Validator list index: {}", validator_list_index); println!("Mark for removal: {}", mark_for_removal); println!("Immediate: {}", immediate); + + let validator_to_mark = validator_list_account + .validators + .get(validator_list_index as usize) + .unwrap(); + + println!("Validator to mark: {:?}", validator_to_mark); } if args.submit_ix { diff --git a/utils/steward-cli/src/commands/command_args.rs b/utils/steward-cli/src/commands/command_args.rs index 2d2935b7..14c16a46 100644 --- a/utils/steward-cli/src/commands/command_args.rs +++ b/utils/steward-cli/src/commands/command_args.rs @@ -189,14 +189,14 @@ pub enum Commands { // Views ViewState(ViewState), ViewConfig(ViewConfig), - // ViewNextIndexToRemove(ViewNextIndexToRemove), + ViewNextIndexToRemove(ViewNextIndexToRemove), // Actions InitConfig(InitConfig), UpdateConfig(UpdateConfig), - // InitState(InitState), - // ResetState(ResetState), + InitState(InitState), + ResetState(ResetState), Surgery(Surgery), RemoveBadValidators(RemoveBadValidators), @@ -296,7 +296,15 @@ pub struct Surgery { #[command(flatten)] pub permissioned_parameters: PermissionedParameters, - /// Validator index of validator list to remove + #[arg(long)] + pub mark_for_removal: bool, + + #[arg(long)] + pub immediate: bool, + + #[arg(long)] + pub validator_list_index: usize, + #[arg(long, default_value = "false")] pub submit_ix: bool, } diff --git a/utils/steward-cli/src/main.rs b/utils/steward-cli/src/main.rs index c207e69d..aa119b76 100644 --- a/utils/steward-cli/src/main.rs +++ b/utils/steward-cli/src/main.rs @@ -42,15 +42,15 @@ async fn main() -> Result<()> { // ---- Views ---- Commands::ViewConfig(args) => command_view_config(args, &client, program_id).await, Commands::ViewState(args) => command_view_state(args, &client, program_id).await, - // Commands::ViewNextIndexToRemove(args) => { - // command_view_next_index_to_remove(args, &client, program_id).await - // } + Commands::ViewNextIndexToRemove(args) => { + command_view_next_index_to_remove(args, &client, program_id).await + } // --- Actions --- Commands::InitConfig(args) => command_init_config(args, &client, program_id).await, Commands::UpdateConfig(args) => command_update_config(args, &client, program_id).await, - // Commands::InitState(args) => command_init_state(args, &client, program_id).await, - // Commands::ResetState(args) => command_reset_state(args, &client, program_id).await, + Commands::InitState(args) => command_init_state(args, &client, program_id).await, + Commands::ResetState(args) => command_reset_state(args, &client, program_id).await, Commands::Surgery(args) => command_surgery(args, &client, program_id).await, Commands::AutoRemoveValidatorFromPool(args) => { command_auto_remove_validator_from_pool(args, &client, program_id).await From 4cdb86bfdbd79ecb4e1a15a746b5725b93457bb3 Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Wed, 31 Jul 2024 17:35:12 -0600 Subject: [PATCH 4/4] can run surgery --- utils/steward-cli/initial_notes.md | 22 ++++++++++++++++--- .../src/commands/actions/surgery.rs | 3 +-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/utils/steward-cli/initial_notes.md b/utils/steward-cli/initial_notes.md index fe3ab76a..3c58d586 100644 --- a/utils/steward-cli/initial_notes.md +++ b/utils/steward-cli/initial_notes.md @@ -1,10 +1,10 @@ # Accounts -**Authority** +**Authority** `aaaDerwdMyzNkoX1aSoTi3UtFe2W45vh5wCgQNhsjF8` -**Steward Config** +**Steward Config** `6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5` **Stake Pool** @@ -19,6 +19,7 @@ # Initial Commands ## Create Config + ```bash cargo run init-config \ --authority-keypair-path ../../credentials/stakenet_test.json \ @@ -45,6 +46,7 @@ cargo run init-config \ ``` ## Update Config + ```bash cargo run update-config \ --authority-keypair-path ../../credentials/stakenet_test.json \ @@ -54,71 +56,85 @@ cargo run update-config \ ``` ## Create State + ```bash cargo run init-state --authority-keypair-path ../../credentials/stakenet_test.json --stake-pool 3DuPtyTAKrxKfHkSPZ5fqCayMcGru1BarAKKTfGDeo2j --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 ``` ## View Config + ```bash cargo run view-config --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 ``` ## View State + ```bash cargo run view-state --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 ``` ## View State Per Validator + ```bash cargo run view-state-per-validator --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 ``` ## View Next Index To Remove + ```bash cargo run view-next-index-to-remove --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 ``` ## Auto Remove Validator + ```bash cargo run auto-remove-validator-from-pool --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json --validator-index-to-remove 1397 ``` ## Auto Add Validator + ```bash cargo run auto-add-validator-from-pool --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json --vote-account 4m64H5TbwAGtZVnxaGAVoTSwjZGV8BCLKRPr8agKQv4Z ``` ## Remove Bad Validators + ```bash cargo run remove-bad-validators --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json ``` ## Crank Epoch Maintenance + ```bash cargo run crank-epoch-maintenance --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json ``` ## Crank Compute Score + ```bash cargo run crank-compute-score --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json ``` ## Crank Compute Delegations + ```bash cargo run crank-compute-delegations --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json ``` ## Crank Idle + ```bash cargo run crank-idle --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json ``` ## Crank Compute Instant Unstake + ```bash cargo run crank-compute-instant-unstake --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json ``` ## Crank Rebalance + ```bash cargo run crank-rebalance --steward-config 6auT7Q91SSgAoYLAnu449DK1MK9skDmtiLmtkCECP1b5 --payer-keypair-path ../../credentials/stakenet_test.json ``` @@ -157,4 +173,4 @@ INSTANT_UNSTAKE_INPUTS_EPOCH_PROGRESS=0.50 NUM_EPOCHS_BETWEEN_SCORING=3 MINIMUM_STAKE_LAMPORTS=100000000000 MINIMUM_VOTING_EPOCHS=5 -``` \ No newline at end of file +``` diff --git a/utils/steward-cli/src/commands/actions/surgery.rs b/utils/steward-cli/src/commands/actions/surgery.rs index c9819069..ea997f0f 100644 --- a/utils/steward-cli/src/commands/actions/surgery.rs +++ b/utils/steward-cli/src/commands/actions/surgery.rs @@ -13,8 +13,7 @@ use crate::{ commands::command_args::Surgery, utils::{ accounts::{ - get_steward_config_account, get_steward_state_account, get_steward_state_address, - get_validator_list_account, + get_steward_config_account, get_steward_state_address, get_validator_list_account, }, transactions::configure_instruction, },