From 0527b296516adebee40e80c5bd1df465dc809392 Mon Sep 17 00:00:00 2001 From: Evan B Date: Wed, 19 Jun 2024 19:25:55 -0400 Subject: [PATCH] Build IDL Anchor 0.30 (#48) Fixes to build IDL for new Anchor 0.30 spec. New IDL spec breaking changes: * `usize` not supported in instructions or accounts * Need to implement IdlBuild for types that are non-native * Added manual deserialization functions for stake pool and validator list so we don't need to define them * New features needed in build files --------- Co-authored-by: Coach Chuck <169060940+coachchucksol@users.noreply.github.com> Co-authored-by: Christian --- .github/workflows/build.yaml | 23 +- Cargo.lock | 70 +- programs/steward/Cargo.toml | 4 +- programs/steward/idl/steward.json | 3263 +++++++++++------ programs/steward/src/constants.rs | 6 +- programs/steward/src/delegation.rs | 8 +- .../auto_add_validator_to_pool.rs | 13 +- .../auto_remove_validator_from_pool.rs | 21 +- .../instructions/compute_instant_unstake.rs | 1 + .../steward/src/instructions/compute_score.rs | 3 +- .../src/instructions/initialize_config.rs | 9 +- .../steward/src/instructions/realloc_state.rs | 3 +- .../steward/src/instructions/rebalance.rs | 22 +- .../src/instructions/spl_passthrough.rs | 74 +- programs/steward/src/lib.rs | 28 +- programs/steward/src/score.rs | 3 +- programs/steward/src/state/bitmask.rs | 3 +- programs/steward/src/state/parameters.rs | 121 +- programs/steward/src/state/steward_state.rs | 81 +- programs/steward/src/utils.rs | 67 +- programs/validator-history/Cargo.toml | 4 +- .../idl/validator_history.json | 1154 +++--- tests/src/spl_stake_pool_cli.rs | 2 + tests/tests/steward/test_algorithms.rs | 2 +- tests/tests/steward/test_integration.rs | 25 +- tests/tests/steward/test_parameters.rs | 2 +- tests/tests/steward/test_spl_passthrough.rs | 6 +- tests/tests/steward/test_state_transitions.rs | 2 +- 28 files changed, 3160 insertions(+), 1860 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6dc936b8..0cf0cc76 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -21,7 +21,7 @@ jobs: uses: baptiste0928/cargo-install@v3 with: crate: cargo-audit - - run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2023-0065 --ignore RUSTSEC-2024-0336 + - run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2023-0065 --ignore RUSTSEC-2024-0336 --ignore RUSTSEC-2024-0344 lint: name: lint @@ -81,9 +81,9 @@ jobs: run: echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH # build the program and IDL; exit if error - - run: anchor build --no-idl - # - name: Check for diff on IDL - # run: git diff --exit-code + - run: anchor build --idl idl + - name: Check for diff on IDL + run: git diff --exit-code # run verified build - run: solana-verify build --library-name validator_history @@ -100,11 +100,16 @@ jobs: with: name: jito_steward.so path: target/deploy/jito_steward.so - # - name: Upload IDL - # uses: actions/upload-artifact@v4 - # with: - # name: validator_history.json - # path: programs/validator-history/idl/validator_history.json + - name: Upload Validator History IDL + uses: actions/upload-artifact@v4 + with: + name: validator_history.json + path: programs/validator-history/idl/validator_history.json + - name: Upload Jito Steward IDL + uses: actions/upload-artifact@v4 + with: + name: jito_steward.json + path: programs/steward/idl/jito_steward.json # tests run on verified build test: diff --git a/Cargo.lock b/Cargo.lock index 41bb3bf2..13282434 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,6 +243,7 @@ dependencies = [ "anchor-derive-accounts", "anchor-derive-serde", "anchor-derive-space", + "anchor-lang-idl", "arrayref", "base64 0.21.7", "bincode", @@ -259,7 +260,9 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b29da81eae478b1bb846749b06b8a2cb9c6f9ed26ca793b0c916793fdf36adab" dependencies = [ + "anchor-syn", "anyhow", + "regex", "serde", "serde_json", ] @@ -272,6 +275,7 @@ checksum = "ac53f2378bc08e89e20c2b893c01986ffd34cfbc69a17e35bd6f754753e9fdad" dependencies = [ "anyhow", "bs58 0.5.0", + "cargo_toml", "heck 0.3.3", "proc-macro2", "quote", @@ -1012,9 +1016,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.14.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea31d69bda4949c1c1562c1e6f042a1caefac98cdc8a298260a2ff41c1e2d42b" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" dependencies = [ "bytemuck_derive", ] @@ -1073,6 +1077,16 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cargo_toml" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" +dependencies = [ + "serde", + "toml 0.8.12", +] + [[package]] name = "cc" version = "1.0.83" @@ -3514,7 +3528,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -4219,6 +4233,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -6594,11 +6617,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.12", +] + [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -6608,7 +6646,7 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.2.2", "toml_datetime", - "winnow", + "winnow 0.5.39", ] [[package]] @@ -6619,7 +6657,20 @@ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.2", "toml_datetime", - "winnow", + "winnow 0.5.39", +] + +[[package]] +name = "toml_edit" +version = "0.22.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" +dependencies = [ + "indexmap 2.2.2", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.12", ] [[package]] @@ -7351,6 +7402,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ff33f391015ecab21cd092389215eb265ef9496a9a07b6bee7d3529831deda" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/programs/steward/Cargo.toml b/programs/steward/Cargo.toml index 5560b02f..874bfcfe 100644 --- a/programs/steward/Cargo.toml +++ b/programs/steward/Cargo.toml @@ -17,10 +17,10 @@ no-log-ix-name = [] cpi = ["no-entrypoint"] default = ["custom-heap"] custom-heap = [] -# idl-build = ["anchor-lang/idl-build"] +idl-build = ["anchor-lang/idl-build", "no-entrypoint"] [dependencies] -anchor-lang = "0.30.0" +anchor-lang = { features = ["idl-build"], version = "0.30.0" } bincode = "1.3.3" blake3 = "1.3.1" borsh = "0.10.0" diff --git a/programs/steward/idl/steward.json b/programs/steward/idl/steward.json index 642b84c2..9ea51b4a 100644 --- a/programs/steward/idl/steward.json +++ b/programs/steward/idl/steward.json @@ -1,1504 +1,2455 @@ { - "version": "0.1.0", - "name": "steward", + "address": "Stewardf95sJbmtcZsyagb2dg4Mo8eVQho8gpECvLx8", + "metadata": { + "name": "steward", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Program for permissionlessly managing an SPL Stake Pool" + }, "instructions": [ { - "name": "initializeConfig", + "name": "add_validator_to_blacklist", + "docs": [ + "Adds the validator at `index` to the blacklist. It will be instant unstaked and never receive delegations" + ], + "discriminator": [ + 18, + 30, + 248, + 201, + 28, + 196, + 137, + 118 + ], "accounts": [ { "name": "config", - "isMut": true, - "isSigner": true + "writable": true }, { - "name": "staker", - "isMut": true, - "isSigner": false + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [ + { + "name": "index", + "type": "u32" + } + ] + }, + { + "name": "add_validator_to_pool", + "discriminator": [ + 181, + 6, + 29, + 25, + 192, + 211, + 190, + 187 + ], + "accounts": [ + { + "name": "config" }, { - "name": "stakePool", - "isMut": true, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "validatorHistoryConfig", - "isMut": false, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "staker" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "reserve_stake", + "writable": true }, { - "name": "signer", - "isMut": true, - "isSigner": true - } - ], - "args": [ + "name": "withdraw_authority" + }, { - "name": "authority", - "type": "publicKey" - } - ] - }, - { - "name": "initializeState", - "accounts": [ + "name": "validator_list", + "writable": true + }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "stake_account", + "writable": true }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "rent" }, { - "name": "signer", - "isMut": true, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "reallocState", - "accounts": [ + "name": "clock" + }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "stake_history" }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "stake_config" }, { - "name": "validatorHistoryConfig", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [] + "args": [ + { + "name": "validator_seed", + "type": { + "option": "u32" + } + } + ] }, { - "name": "autoAddValidatorToPool", + "name": "auto_add_validator_to_pool", + "docs": [ + "Adds a validator to the pool if it has a validator history account, matches stake_minimum, and is not yet in the pool" + ], + "discriminator": [ + 166, + 226, + 7, + 8, + 169, + 239, + 220, + 69 + ], "accounts": [ { - "name": "validatorHistoryAccount", - "isMut": false, - "isSigner": false + "name": "validator_history_account" }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "stakePool", - "isMut": true, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "staker", - "isMut": false, - "isSigner": false + "name": "staker" }, { - "name": "reserveStake", - "isMut": true, - "isSigner": false + "name": "reserve_stake", + "writable": true }, { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false + "name": "withdraw_authority" }, { - "name": "validatorList", - "isMut": true, - "isSigner": false + "name": "validator_list", + "writable": true }, { - "name": "stakeAccount", - "isMut": true, - "isSigner": false + "name": "stake_account", + "writable": true }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "rent", - "isMut": false, - "isSigner": false + "name": "rent" }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "clock" }, { - "name": "stakeHistory", - "isMut": false, - "isSigner": false + "name": "stake_history" }, { - "name": "stakeConfig", - "isMut": false, - "isSigner": false + "name": "stake_config" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [] }, { - "name": "computeScore", + "name": "auto_remove_validator_from_pool", + "docs": [ + "Removes a validator from the pool if its stake account is inactive or the vote account has closed" + ], + "discriminator": [ + 65, + 39, + 73, + 213, + 52, + 34, + 181, + 94 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false + "name": "validator_history_account" }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "config" }, { - "name": "validatorHistory", - "isMut": false, - "isSigner": false + "name": "state_account", + "writable": true }, { - "name": "validatorHistoryConfig", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "clusterHistory", - "isMut": false, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "signer", - "isMut": true, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "computeDelegations", - "accounts": [ + "name": "staker" + }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "reserve_stake", + "writable": true + }, + { + "name": "withdraw_authority" + }, + { + "name": "validator_list", + "writable": true + }, + { + "name": "stake_account", + "writable": true + }, + { + "name": "transient_stake_account", + "docs": [ + "Account may not exist yet so no owner check done" + ], + "writable": true + }, + { + "name": "vote_account" + }, + { + "name": "rent" + }, + { + "name": "clock" + }, + { + "name": "stake_history" + }, + { + "name": "stake_config" }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "system_program" }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [] + "args": [ + { + "name": "validator_list_index", + "type": "u64" + } + ] }, { - "name": "idle", + "name": "compute_delegations", + "docs": [ + "Computes delegation for a validator for the current cycle.", + "All validators must have delegations computed before stake can be delegated" + ], + "discriminator": [ + 249, + 138, + 49, + 247, + 69, + 32, + 11, + 175 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "state_account", + "writable": true }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [] }, { - "name": "computeInstantUnstake", + "name": "compute_instant_unstake", + "docs": [ + "Checks if a validator at `validator_list_index` should be instant unstaked, and marks it if so" + ], + "discriminator": [ + 172, + 220, + 51, + 183, + 2, + 94, + 253, + 251 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false + "name": "config" + }, + { + "name": "state_account", + "writable": true }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "validator_history" }, { - "name": "validatorHistory", - "isMut": false, - "isSigner": false + "name": "validator_list" }, { - "name": "clusterHistory", - "isMut": false, - "isSigner": false + "name": "cluster_history" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [] + "args": [ + { + "name": "validator_list_index", + "type": "u64" + } + ] }, { - "name": "recomputeDelegations", + "name": "compute_score", + "docs": [ + "Computes score for a the validator at `validator_list_index` for the current cycle." + ], + "discriminator": [ + 161, + 101, + 4, + 93, + 120, + 62, + 41, + 20 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false + "name": "config" + }, + { + "name": "state_account", + "writable": true }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "validator_history" }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "validator_list" }, { - "name": "validatorList", - "isMut": false, - "isSigner": false + "name": "cluster_history" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [] + "args": [ + { + "name": "validator_list_index", + "type": "u64" + } + ] }, { - "name": "unstake", + "name": "decrease_additional_validator_stake", + "discriminator": [ + 90, + 22, + 113, + 73, + 21, + 229, + 33, + 83 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "steward_state", + "writable": true }, { - "name": "validatorHistory", - "isMut": false, - "isSigner": false + "name": "validator_history", + "writable": true }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "staker", - "isMut": false, - "isSigner": false + "name": "stake_pool" }, { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false + "name": "staker" }, { - "name": "validatorList", - "isMut": false, - "isSigner": false + "name": "withdraw_authority" }, { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "name": "validator_list", + "writable": true }, { - "name": "transientStakeAccount", - "isMut": false, - "isSigner": false + "name": "reserve_stake", + "writable": true }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "stake_account", + "writable": true }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "ephemeral_stake_account", + "writable": true }, { - "name": "rent", - "isMut": false, - "isSigner": false + "name": "transient_stake_account", + "writable": true }, { - "name": "stakeHistory", - "isMut": false, - "isSigner": false + "name": "clock" }, { - "name": "stakeConfig", - "isMut": false, - "isSigner": false + "name": "stake_history" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [ { - "name": "validatorListIndex", - "type": { - "defined": "usize" - } + "name": "lamports", + "type": "u64" + }, + { + "name": "transient_seed", + "type": "u64" + }, + { + "name": "ephemeral_seed", + "type": "u64" } ] }, { - "name": "delegate", + "name": "decrease_validator_stake", + "discriminator": [ + 145, + 203, + 107, + 123, + 71, + 63, + 35, + 225 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false - }, - { - "name": "stateAccount", - "isMut": true, - "isSigner": false + "name": "config" }, { - "name": "validatorHistory", - "isMut": false, - "isSigner": false + "name": "steward_state", + "writable": true }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "validator_history", + "writable": true }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "staker", - "isMut": false, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false + "name": "staker" }, { - "name": "validatorList", - "isMut": false, - "isSigner": false + "name": "withdraw_authority" }, { - "name": "reserveStake", - "isMut": false, - "isSigner": false + "name": "validator_list", + "writable": true }, { - "name": "transientStakeAccount", - "isMut": false, - "isSigner": false + "name": "reserve_stake", + "writable": true }, { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "name": "stake_account", + "writable": true }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "transient_stake_account", + "writable": true }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "rent", - "isMut": false, - "isSigner": false + "name": "clock" }, { - "name": "stakeHistory", - "isMut": false, - "isSigner": false + "name": "rent" }, { - "name": "stakeConfig", - "isMut": false, - "isSigner": false + "name": "stake_history" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [ { - "name": "validatorListIndex", - "type": { - "defined": "usize" - } + "name": "lamports", + "type": "u64" + }, + { + "name": "transient_seed", + "type": "u64" } ] }, { - "name": "setNewAuthority", + "name": "idle", + "docs": [ + "Idle state, waiting for epoch progress before transitioning to next state" + ], + "discriminator": [ + 200, + 79, + 16, + 41, + 251, + 91, + 239, + 83 + ], "accounts": [ { - "name": "config", - "isMut": true, - "isSigner": false + "name": "config" }, { - "name": "newAuthority", - "isMut": false, - "isSigner": false + "name": "state_account", + "writable": true }, { - "name": "authority", - "isMut": true, - "isSigner": true + "name": "signer", + "writable": true, + "signer": true } ], "args": [] }, { - "name": "pauseSteward", + "name": "increase_additional_validator_stake", + "discriminator": [ + 93, + 136, + 94, + 230, + 32, + 54, + 167, + 242 + ], "accounts": [ { - "name": "config", - "isMut": true, - "isSigner": false + "name": "config" }, { - "name": "authority", - "isMut": true, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "resumeSteward", - "accounts": [ + "name": "steward_state", + "writable": true + }, { - "name": "config", - "isMut": true, - "isSigner": false + "name": "validator_history", + "writable": true }, { - "name": "authority", - "isMut": true, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "addValidatorToBlacklist", - "accounts": [ + "name": "stake_pool_program" + }, { - "name": "config", - "isMut": true, - "isSigner": false + "name": "stake_pool" }, { - "name": "authority", - "isMut": true, - "isSigner": true - } - ], - "args": [ + "name": "staker" + }, { - "name": "index", - "type": "u32" - } - ] - }, - { - "name": "removeValidatorFromBlacklist", - "accounts": [ + "name": "withdraw_authority" + }, { - "name": "config", - "isMut": true, - "isSigner": false + "name": "validator_list", + "writable": true }, { - "name": "authority", - "isMut": true, - "isSigner": true - } - ], - "args": [ + "name": "reserve_stake", + "writable": true + }, { - "name": "index", - "type": "u32" - } - ] - }, - { - "name": "updateParameters", - "accounts": [ + "name": "ephemeral_stake_account", + "writable": true + }, { - "name": "config", - "isMut": true, - "isSigner": false + "name": "transient_stake_account", + "writable": true }, { - "name": "authority", - "isMut": true, - "isSigner": true - } - ], - "args": [ + "name": "stake_account" + }, { - "name": "updateParametersArgs", - "type": { - "defined": "UpdateParametersArgs" - } - } - ] - }, - { - "name": "setStaker", - "accounts": [ + "name": "vote_account" + }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "clock" }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "stake_history" }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "stake_config" }, { - "name": "staker", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "newStaker", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [] + "args": [ + { + "name": "lamports", + "type": "u64" + }, + { + "name": "transient_seed", + "type": "u64" + }, + { + "name": "ephemeral_seed", + "type": "u64" + } + ] }, { - "name": "addValidatorToPool", + "name": "increase_validator_stake", + "discriminator": [ + 5, + 121, + 50, + 243, + 14, + 159, + 97, + 6 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "steward_state", + "writable": true }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "validator_history", + "writable": true }, { - "name": "staker", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" + }, + { + "name": "stake_pool", + "writable": true + }, + { + "name": "staker" + }, + { + "name": "withdraw_authority" }, { - "name": "reserveStake", - "isMut": false, - "isSigner": false + "name": "validator_list", + "writable": true }, { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false + "name": "reserve_stake", + "writable": true }, { - "name": "validatorList", - "isMut": false, - "isSigner": false + "name": "transient_stake_account", + "writable": true }, { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "name": "stake_account", + "writable": true }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "rent", - "isMut": false, - "isSigner": false + "name": "clock" }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "rent" }, { - "name": "stakeHistory", - "isMut": false, - "isSigner": false + "name": "stake_history" }, { - "name": "stakeConfig", - "isMut": false, - "isSigner": false + "name": "stake_config" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [ { - "name": "validatorSeed", - "type": { - "option": "u32" - } + "name": "lamports", + "type": "u64" + }, + { + "name": "transient_seed", + "type": "u64" } ] }, { - "name": "removeValidatorFromPool", + "name": "initialize_config", + "discriminator": [ + 208, + 127, + 21, + 1, + 194, + 190, + 196, + 70 + ], "accounts": [ { "name": "config", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePool", - "isMut": false, - "isSigner": false + "writable": true, + "signer": true }, { "name": "staker", - "isMut": false, - "isSigner": false - }, - { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "validatorList", - "isMut": false, - "isSigner": false - }, - { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "writable": true }, { - "name": "transientStakeAccount", - "isMut": false, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [] - }, - { - "name": "setPreferredValidator", - "accounts": [ + "args": [ { - "name": "config", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePool", - "isMut": false, - "isSigner": false - }, - { - "name": "staker", - "isMut": false, - "isSigner": false - }, - { - "name": "validatorList", - "isMut": false, - "isSigner": false - }, - { - "name": "signer", - "isMut": true, - "isSigner": true - } - ], - "args": [ - { - "name": "validatorType", - "type": { - "defined": "PreferredValidatorType" - } + "name": "authority", + "type": "pubkey" }, { - "name": "validator", + "name": "update_parameters_args", "type": { - "option": "publicKey" + "defined": { + "name": "UpdateParametersArgs" + } } } ] }, { - "name": "increaseValidatorStake", + "name": "initialize_state", + "docs": [ + "Creates state account" + ], + "discriminator": [ + 190, + 171, + 224, + 219, + 217, + 72, + 199, + 176 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false + "name": "state_account", + "writable": true }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "staker", - "isMut": false, - "isSigner": false - }, + "name": "signer", + "writable": true, + "signer": true + } + ], + "args": [] + }, + { + "name": "pause_steward", + "discriminator": [ + 214, + 85, + 52, + 67, + 192, + 238, + 178, + 102 + ], + "accounts": [ { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false + "name": "config", + "writable": true }, { - "name": "validatorList", - "isMut": false, - "isSigner": false - }, + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [] + }, + { + "name": "realloc_state", + "docs": [ + "Increases state account by 10KiB each ix until it reaches StewardStateAccount::SIZE" + ], + "discriminator": [ + 67, + 181, + 233, + 214, + 215, + 148, + 245, + 126 + ], + "accounts": [ { - "name": "reserveStake", - "isMut": false, - "isSigner": false + "name": "state_account", + "writable": true }, { - "name": "transientStakeAccount", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "name": "validator_list" }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "clock", - "isMut": false, - "isSigner": false - }, + "name": "signer", + "writable": true, + "signer": true + } + ], + "args": [] + }, + { + "name": "rebalance", + "docs": [ + "Increases or decreases stake for a validator at `validator_list_index` to match the target stake,", + "given constraints on increase/decrease priority, reserve balance, and unstaking caps" + ], + "discriminator": [ + 108, + 158, + 77, + 9, + 210, + 52, + 88, + 62 + ], + "accounts": [ { - "name": "rent", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "stakeHistory", - "isMut": false, - "isSigner": false + "name": "state_account", + "writable": true }, { - "name": "stakeConfig", - "isMut": false, - "isSigner": false + "name": "validator_history" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "stake_pool" }, { - "name": "signer", - "isMut": true, - "isSigner": true - } - ], - "args": [ - { - "name": "lamports", - "type": "u64" + "name": "staker", + "writable": true }, { - "name": "transientSeed", - "type": "u64" - } - ] - }, - { - "name": "decreaseValidatorStake", - "accounts": [ - { - "name": "config", - "isMut": false, - "isSigner": false + "name": "withdraw_authority" }, { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "name": "validator_list", + "writable": true }, { - "name": "stakePool", - "isMut": false, - "isSigner": false + "name": "reserve_stake", + "writable": true }, { - "name": "staker", - "isMut": false, - "isSigner": false + "name": "stake_account", + "writable": true }, { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false + "name": "transient_stake_account", + "docs": [ + "Account may not exist yet so no owner check done" + ], + "writable": true }, { - "name": "validatorList", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "name": "clock" }, { - "name": "transientStakeAccount", - "isMut": false, - "isSigner": false + "name": "rent" }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "stake_history" }, { - "name": "rent", - "isMut": false, - "isSigner": false + "name": "stake_config" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [ { - "name": "lamports", - "type": "u64" - }, - { - "name": "transientSeed", + "name": "validator_list_index", "type": "u64" } ] }, { - "name": "increaseAdditionalValidatorStake", + "name": "remove_validator_from_blacklist", + "docs": [ + "Removes the validator at `index` from the blacklist" + ], + "discriminator": [ + 253, + 48, + 101, + 237, + 109, + 14, + 153, + 208 + ], "accounts": [ { "name": "config", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false + "writable": true }, { - "name": "stakePool", - "isMut": false, - "isSigner": false - }, + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [ { - "name": "staker", - "isMut": false, - "isSigner": false - }, + "name": "index", + "type": "u32" + } + ] + }, + { + "name": "remove_validator_from_pool", + "discriminator": [ + 161, + 32, + 213, + 239, + 221, + 15, + 181, + 114 + ], + "accounts": [ { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "validatorList", - "isMut": false, - "isSigner": false + "name": "steward_state", + "writable": true }, { - "name": "reserveStake", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "ephemeralStakeAccount", - "isMut": false, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "transientStakeAccount", - "isMut": false, - "isSigner": false + "name": "staker" }, { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "name": "withdraw_authority" }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "validator_list", + "writable": true }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "stake_account", + "writable": true }, { - "name": "stakeHistory", - "isMut": false, - "isSigner": false + "name": "transient_stake_account", + "writable": true }, { - "name": "stakeConfig", - "isMut": false, - "isSigner": false + "name": "clock" }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "stake_program" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [ { - "name": "lamports", - "type": "u64" - }, - { - "name": "transientSeed", - "type": "u64" - }, - { - "name": "ephemeralSeed", + "name": "validator_list_index", "type": "u64" } ] }, { - "name": "decreaseAdditionalValidatorStake", + "name": "resume_steward", + "discriminator": [ + 25, + 71, + 153, + 183, + 197, + 197, + 187, + 3 + ], "accounts": [ { "name": "config", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePool", - "isMut": false, - "isSigner": false - }, - { - "name": "staker", - "isMut": false, - "isSigner": false + "writable": true }, { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false - }, + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [] + }, + { + "name": "set_new_authority", + "discriminator": [ + 94, + 40, + 220, + 124, + 122, + 142, + 142, + 98 + ], + "accounts": [ { - "name": "validatorList", - "isMut": false, - "isSigner": false + "name": "config", + "writable": true }, { - "name": "stakeAccount", - "isMut": false, - "isSigner": false + "name": "new_authority" }, { - "name": "ephemeralStakeAccount", - "isMut": false, - "isSigner": false - }, + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [] + }, + { + "name": "set_preferred_validator", + "discriminator": [ + 114, + 42, + 19, + 98, + 212, + 97, + 109, + 13 + ], + "accounts": [ { - "name": "transientStakeAccount", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "clock", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "stakeHistory", - "isMut": false, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "staker" }, { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "validator_list" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [ { - "name": "lamports", - "type": "u64" - }, - { - "name": "transientSeed", - "type": "u64" + "name": "validator_type", + "type": { + "defined": { + "name": "PreferredValidatorType" + } + } }, { - "name": "ephemeralSeed", - "type": "u64" + "name": "validator", + "type": { + "option": "pubkey" + } } ] }, { - "name": "redelegate", + "name": "set_staker", + "discriminator": [ + 149, + 203, + 114, + 28, + 80, + 138, + 17, + 131 + ], "accounts": [ { - "name": "config", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePoolProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "stakePool", - "isMut": false, - "isSigner": false - }, - { - "name": "staker", - "isMut": false, - "isSigner": false - }, - { - "name": "withdrawAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "validatorList", - "isMut": false, - "isSigner": false - }, - { - "name": "sourceStakeAccount", - "isMut": false, - "isSigner": false - }, - { - "name": "sourceEphemeralStakeAccount", - "isMut": false, - "isSigner": false - }, - { - "name": "sourceTransientStakeAccount", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "destinationTransientStakeAccount", - "isMut": false, - "isSigner": false + "name": "stake_pool_program" }, { - "name": "destinationStakeAccount", - "isMut": false, - "isSigner": false + "name": "stake_pool", + "writable": true }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "staker" }, { - "name": "clock", - "isMut": false, - "isSigner": false - }, - { - "name": "stakeHistory", - "isMut": false, - "isSigner": false - }, - { - "name": "stakeConfig", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "stakeProgram", - "isMut": false, - "isSigner": false + "name": "new_staker" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [ - { - "name": "lamports", - "type": "u64" - }, + "args": [] + }, + { + "name": "update_parameters", + "docs": [ + "For parameters that are present in args, the instruction checks that they are within sensible bounds and saves them to config struct" + ], + "discriminator": [ + 116, + 107, + 24, + 207, + 101, + 49, + 213, + 77 + ], + "accounts": [ { - "name": "sourceTransientStakeSeed", - "type": "u64" + "name": "config", + "writable": true }, { - "name": "ephemeralStakeSeed", - "type": "u64" - }, + "name": "authority", + "writable": true, + "signer": true + } + ], + "args": [ { - "name": "destinationTransientSeed", - "type": "u64" + "name": "update_parameters_args", + "type": { + "defined": { + "name": "UpdateParametersArgs" + } + } } ] } ], "accounts": [ + { + "name": "ClusterHistory", + "discriminator": [ + 41, + 154, + 241, + 80, + 135, + 88, + 85, + 252 + ] + }, { "name": "Config", - "type": { - "kind": "struct", - "fields": [ - { - "name": "stakePool", - "type": "publicKey" - }, - { - "name": "authority", - "type": "publicKey" - }, - { - "name": "minimumStakeLamports", - "type": "u64" - }, - { - "name": "blacklist", - "type": { - "defined": "BitMask" - } - }, - { - "name": "parameters", - "type": { - "defined": "Parameters" - } - }, - { - "name": "paused", - "type": "u8" - }, - { - "name": "padding1", - "type": { - "array": [ - "u8", - 1023 - ] - } - } - ] - } + "discriminator": [ + 155, + 12, + 170, + 224, + 30, + 250, + 204, + 130 + ] }, { "name": "Staker", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - } - ] - } + "discriminator": [ + 171, + 229, + 193, + 85, + 67, + 177, + 151, + 4 + ] }, { "name": "StewardStateAccount", - "type": { - "kind": "struct", - "fields": [ - { - "name": "state", - "type": { - "defined": "StewardState" - } - }, - { - "name": "bump", - "type": "u8" - }, - { - "name": "padding", - "type": { + "discriminator": [ + 55, + 216, + 46, + 49, + 148, + 67, + 228, + 29 + ] + }, + { + "name": "ValidatorHistory", + "discriminator": [ + 205, + 25, + 8, + 221, + 253, + 131, + 2, + 146 + ] + } + ], + "events": [ + { + "name": "DecreaseComponents", + "discriminator": [ + 129, + 8, + 124, + 12, + 11, + 140, + 0, + 8 + ] + }, + { + "name": "InstantUnstakeComponents", + "discriminator": [ + 217, + 80, + 196, + 114, + 226, + 11, + 127, + 77 + ] + }, + { + "name": "ScoreComponents", + "discriminator": [ + 218, + 204, + 53, + 7, + 22, + 2, + 217, + 251 + ] + }, + { + "name": "StateTransition", + "discriminator": [ + 106, + 9, + 120, + 247, + 169, + 106, + 206, + 233 + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "ScoringNotComplete", + "msg": "Scoring must be completed before any other steps can be taken" + }, + { + "code": 6001, + "name": "ValidatorNotInList", + "msg": "Validator does not exist at the ValidatorList index provided" + }, + { + "code": 6002, + "name": "AddValidatorsNotComplete", + "msg": "Add validators step must be completed before any other steps can be taken" + }, + { + "code": 6003, + "name": "EpochNotOver", + "msg": "Cannot reset state before epoch is over" + }, + { + "code": 6004, + "name": "Unauthorized", + "msg": "Unauthorized to perform this action" + }, + { + "code": 6005, + "name": "BitmaskOutOfBounds", + "msg": "Bitmask index out of bounds" + }, + { + "code": 6006, + "name": "StateNotReset", + "msg": "Epoch state not reset" + }, + { + "code": 6007, + "name": "ValidatorOutOfRange", + "msg": "Validator History created after epoch start, out of range" + }, + { + "code": 6008, + "name": "InvalidState" + }, + { + "code": 6009, + "name": "ValidatorBelowStakeMinimum", + "msg": "Validator not eligible to be added to the pool. Must meet stake minimum" + }, + { + "code": 6010, + "name": "ValidatorBelowLivenessMinimum", + "msg": "Validator not eligible to be added to the pool. Must meet recent voting minimum" + }, + { + "code": 6011, + "name": "VoteHistoryNotRecentEnough", + "msg": "Validator History vote data not recent enough to be used for scoring. Must be updated this epoch" + }, + { + "code": 6012, + "name": "StakeHistoryNotRecentEnough", + "msg": "Validator History stake data not recent enough to be used for scoring. Must be updated this epoch" + }, + { + "code": 6013, + "name": "ClusterHistoryNotRecentEnough", + "msg": "Cluster History data not recent enough to be used for scoring. Must be updated this epoch" + }, + { + "code": 6014, + "name": "StateMachinePaused", + "msg": "Steward State Machine is paused. No state machine actions can be taken" + }, + { + "code": 6015, + "name": "InvalidParameterValue", + "msg": "Config parameter is out of range or otherwise invalid" + }, + { + "code": 6016, + "name": "InstantUnstakeNotReady", + "msg": "Instant unstake cannot be performed yet." + }, + { + "code": 6017, + "name": "ValidatorIndexOutOfBounds", + "msg": "Validator index out of bounds of state machine" + }, + { + "code": 6018, + "name": "ValidatorListTypeMismatch", + "msg": "ValidatorList account type mismatch" + }, + { + "code": 6019, + "name": "ArithmeticError", + "msg": "An operation caused an overflow/underflow" + }, + { + "code": 6020, + "name": "ValidatorNotRemovable", + "msg": "Validator not eligible for removal. Must be delinquent or have closed vote account" + }, + { + "code": 6021, + "name": "MaxValidatorsReached", + "msg": "Max validators reached" + }, + { + "code": 6022, + "name": "ValidatorHistoryMismatch", + "msg": "Validator history account does not match vote account" + } + ], + "types": [ + { + "name": "BitMask", + "docs": [ + "Data structure used to efficiently pack a binary array, primarily used to store all validators.", + "Each validator has an index (its index in the spl_stake_pool::ValidatorList), corresponding to a bit in the bitmask.", + "When an operation is executed on a validator, the bit corresponding to that validator's index is set to 1.", + "When all bits are 1, the operation is complete." + ], + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "values", + "type": { + "array": [ + "u64", + 79 + ] + } + } + ] + } + }, + { + "name": "CircBuf", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "idx", + "type": "u64" + }, + { + "name": "is_empty", + "type": "u8" + }, + { + "name": "padding", + "type": { "array": [ "u8", 7 ] } + }, + { + "name": "arr", + "type": { + "array": [ + { + "defined": { + "name": "ValidatorHistoryEntry" + } + }, + 512 + ] + } } ] } - } - ], - "types": [ + }, { - "name": "BitMask", + "name": "CircBufCluster", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { "kind": "struct", "fields": [ { - "name": "values", + "name": "idx", + "type": "u64" + }, + { + "name": "is_empty", + "type": "u8" + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "arr", + "type": { + "array": [ + { + "defined": { + "name": "ClusterHistoryEntry" + } + }, + 512 + ] + } + } + ] + } + }, + { + "name": "ClientVersion", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "major", + "type": "u8" + }, + { + "name": "minor", + "type": "u8" + }, + { + "name": "patch", + "type": "u16" + } + ] + } + }, + { + "name": "ClusterHistory", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "struct_version", + "type": "u64" + }, + { + "name": "bump", + "type": "u8" + }, + { + "name": "_padding0", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "cluster_history_last_update_slot", + "type": "u64" + }, + { + "name": "_padding1", + "type": { + "array": [ + "u8", + 232 + ] + } + }, + { + "name": "history", + "type": { + "defined": { + "name": "CircBufCluster" + } + } + } + ] + } + }, + { + "name": "ClusterHistoryEntry", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "total_blocks", + "type": "u32" + }, + { + "name": "epoch", + "type": "u16" + }, + { + "name": "padding0", + "type": { + "array": [ + "u8", + 2 + ] + } + }, + { + "name": "epoch_start_timestamp", + "type": "u64" + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 240 + ] + } + } + ] + } + }, + { + "name": "Config", + "docs": [ + "Config is a user-provided keypair.", + "This is so there can be multiple configs per stake pool, and one party can't", + "squat a config address for another party's stake pool." + ], + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "stake_pool", + "docs": [ + "SPL Stake Pool address that this program is managing" + ], + "type": "pubkey" + }, + { + "name": "authority", + "docs": [ + "Authority for pool stewardship, can execute SPL Staker commands and adjust Delegation parameters" + ], + "type": "pubkey" + }, + { + "name": "blacklist", + "docs": [ + "Bitmask representing index of validators that are not allowed delegation" + ], + "type": { + "defined": { + "name": "BitMask" + } + } + }, + { + "name": "parameters", + "docs": [ + "Parameters for scoring, delegation, and state machine" + ], + "type": { + "defined": { + "name": "Parameters" + } + } + }, + { + "name": "_padding", + "docs": [ + "Padding for future governance parameters" + ], + "type": { + "array": [ + "u8", + 1023 + ] + } + }, + { + "name": "paused", + "docs": [ + "Halts any state machine progress" + ], + "type": { + "defined": { + "name": "U8Bool" + } + } + } + ] + } + }, + { + "name": "DecreaseComponents", + "type": { + "kind": "struct", + "fields": [ + { + "name": "scoring_unstake_lamports", + "type": "u64" + }, + { + "name": "instant_unstake_lamports", + "type": "u64" + }, + { + "name": "stake_deposit_unstake_lamports", + "type": "u64" + }, + { + "name": "total_unstake_lamports", + "type": "u64" + } + ] + } + }, + { + "name": "Delegation", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "numerator", + "type": "u32" + }, + { + "name": "denominator", + "type": "u32" + } + ] + } + }, + { + "name": "InstantUnstakeComponents", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instant_unstake", + "docs": [ + "Aggregate of all checks" + ], + "type": "bool" + }, + { + "name": "delinquency_check", + "docs": [ + "Checks if validator has missed > instant_unstake_delinquency_threshold_ratio of votes this epoch" + ], + "type": "bool" + }, + { + "name": "commission_check", + "docs": [ + "Checks if validator has increased commission > commission_threshold" + ], + "type": "bool" + }, + { + "name": "mev_commission_check", + "docs": [ + "Checks if validator has increased MEV commission > mev_commission_bps_threshold" + ], + "type": "bool" + }, + { + "name": "is_blacklisted", + "docs": [ + "Checks if validator was added to blacklist blacklisted" + ], + "type": "bool" + }, + { + "name": "vote_account", + "type": "pubkey" + }, + { + "name": "epoch", + "type": "u16" + } + ] + } + }, + { + "name": "Parameters", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "mev_commission_range", + "docs": [ + "Number of epochs to consider for MEV commission" + ], + "type": "u16" + }, + { + "name": "epoch_credits_range", + "docs": [ + "Number of epochs to consider for epoch credits" + ], + "type": "u16" + }, + { + "name": "commission_range", + "docs": [ + "Number of epochs to consider for commission" + ], + "type": "u16" + }, + { + "name": "mev_commission_bps_threshold", + "docs": [ + "Highest MEV commission rate allowed in bps" + ], + "type": "u16" + }, + { + "name": "scoring_delinquency_threshold_ratio", + "docs": [ + "Proportion of delinquent slots to total slots to trigger delinquency measurement in scoring" + ], + "type": "f64" + }, + { + "name": "instant_unstake_delinquency_threshold_ratio", + "docs": [ + "Proportion of delinquent slots to total slots to trigger instant unstake" + ], + "type": "f64" + }, + { + "name": "commission_threshold", + "docs": [ + "Highest commission rate allowed in commission_range epochs, in percent" + ], + "type": "u8" + }, + { + "name": "historical_commission_threshold", + "docs": [ + "Highest commission rate allowed in tracked history" + ], + "type": "u8" + }, + { + "name": "padding0", + "docs": [ + "Required so that the struct is 8-byte aligned", + "https://doc.rust-lang.org/reference/type-layout.html#reprc-structs" + ], + "type": { + "array": [ + "u8", + 6 + ] + } + }, + { + "name": "num_delegation_validators", + "docs": [ + "Number of validators to delegate to" + ], + "type": "u32" + }, + { + "name": "scoring_unstake_cap_bps", + "docs": [ + "Maximum amount of the pool to be unstaked in a cycle for scoring (in basis points)" + ], + "type": "u32" + }, + { + "name": "instant_unstake_cap_bps", + "type": "u32" + }, + { + "name": "stake_deposit_unstake_cap_bps", + "docs": [ + "Maximum amount of the pool to be unstaked in a cycle from stake deposits (in basis points)" + ], + "type": "u32" + }, + { + "name": "compute_score_slot_range", + "docs": [ + "Number of slots that scoring must be completed in" + ], + "type": "u64" + }, + { + "name": "instant_unstake_epoch_progress", + "docs": [ + "Progress in epoch before instant unstake is allowed" + ], + "type": "f64" + }, + { + "name": "instant_unstake_inputs_epoch_progress", + "docs": [ + "Validator history copy_vote_account and Cluster History must be updated past this epoch progress before calculating instant unstake" + ], + "type": "f64" + }, + { + "name": "num_epochs_between_scoring", + "docs": [ + "Number of epochs a given validator set will be delegated to before recomputing scores" + ], + "type": "u64" + }, + { + "name": "minimum_stake_lamports", + "docs": [ + "Minimum stake required to be added to pool ValidatorList and eligible for delegation" + ], + "type": "u64" + }, + { + "name": "minimum_voting_epochs", + "docs": [ + "Minimum epochs voting required to be in the pool ValidatorList and eligible for delegation" + ], + "type": "u64" + } + ] + } + }, + { + "name": "PreferredValidatorType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Deposit" + }, + { + "name": "Withdraw" + } + ] + } + }, + { + "name": "ScoreComponents", + "type": { + "kind": "struct", + "fields": [ + { + "name": "score", + "docs": [ + "Product of all scoring components" + ], + "type": "f64" + }, + { + "name": "yield_score", + "docs": [ + "vote_credits_ratio * (1 - commission)" + ], + "type": "f64" + }, + { + "name": "mev_commission_score", + "docs": [ + "If max mev commission in mev_commission_range epochs is less than threshold, score is 1.0, else 0" + ], + "type": "f64" + }, + { + "name": "blacklisted_score", + "docs": [ + "If validator is blacklisted, score is 0.0, else 1.0" + ], + "type": "f64" + }, + { + "name": "superminority_score", + "docs": [ + "If validator is not in the superminority, score is 1.0, else 0.0" + ], + "type": "f64" + }, + { + "name": "delinquency_score", + "docs": [ + "If delinquency is not > threshold in any epoch, score is 1.0, else 0.0" + ], + "type": "f64" + }, + { + "name": "running_jito_score", + "docs": [ + "If validator has a mev commission in the last 10 epochs, score is 1.0, else 0.0" + ], + "type": "f64" + }, + { + "name": "commission_score", + "docs": [ + "If max commission in commission_range epochs is less than commission_threshold, score is 1.0, else 0.0" + ], + "type": "f64" + }, + { + "name": "historical_commission_score", + "docs": [ + "If max commission in all validator history epochs is less than historical_commission_threshold, score is 1.0, else 0.0" + ], + "type": "f64" + }, + { + "name": "vote_credits_ratio", + "docs": [ + "Average vote credits in last epoch_credits_range epochs / average blocks in last epoch_credits_range epochs", + "Excluding current epoch" + ], + "type": "f64" + }, + { + "name": "vote_account", + "type": "pubkey" + }, + { + "name": "epoch", + "type": "u16" + } + ] + } + }, + { + "name": "Staker", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" + } + ] + } + }, + { + "name": "StateTransition", + "type": { + "kind": "struct", + "fields": [ + { + "name": "epoch", + "type": "u64" + }, + { + "name": "slot", + "type": "u64" + }, + { + "name": "previous_state", + "type": "string" + }, + { + "name": "new_state", + "type": "string" + } + ] + } + }, + { + "name": "StewardState", + "docs": [ + "Tracks state of the stake pool.", + "Follow state transitions here: [TODO add link to github diagram]" + ], + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "state_tag", + "docs": [ + "Current state of the Steward" + ], + "type": { + "defined": { + "name": "StewardStateEnum" + } + } + }, + { + "name": "validator_lamport_balances", + "docs": [ + "Internal lamport balance of each validator, used to track stake deposits that need to be unstaked,", + "so not always equal to the stake account balance." + ], + "type": { + "array": [ + "u64", + 5000 + ] + } + }, + { + "name": "scores", + "docs": [ + "Overall score of validator, used to determine delegates and order for delegation." + ], + "type": { + "array": [ + "u32", + 5000 + ] + } + }, + { + "name": "sorted_score_indices", + "docs": [ + "Indices of validators, sorted by score descending" + ], + "type": { + "array": [ + "u16", + 5000 + ] + } + }, + { + "name": "yield_scores", + "docs": [ + "Yield component of the score. Used as secondary priority, to determine order for unstaking." + ], + "type": { + "array": [ + "u32", + 5000 + ] + } + }, + { + "name": "sorted_yield_score_indices", + "docs": [ + "Indices of validators, sorted by yield score descending" + ], + "type": { + "array": [ + "u16", + 5000 + ] + } + }, + { + "name": "delegations", + "docs": [ + "Target share of pool represented as a proportion, indexed by spl_stake_pool::ValidatorList index" + ], + "type": { + "array": [ + { + "defined": { + "name": "Delegation" + } + }, + 5000 + ] + } + }, + { + "name": "instant_unstake", + "docs": [ + "Each bit represents a validator, true if validator should be unstaked" + ], + "type": { + "defined": { + "name": "BitMask" + } + } + }, + { + "name": "progress", + "docs": [ + "Tracks progress of states that require one instruction per validator" + ], + "type": { + "defined": { + "name": "BitMask" + } + } + }, + { + "name": "start_computing_scores_slot", + "docs": [ + "Slot of the first ComputeScores instruction in the current cycle" + ], + "type": "u64" + }, + { + "name": "current_epoch", + "docs": [ + "Internal current epoch, for tracking when epoch has changed" + ], + "type": "u64" + }, + { + "name": "next_cycle_epoch", + "docs": [ + "Next cycle start" + ], + "type": "u64" + }, + { + "name": "num_pool_validators", + "docs": [ + "Number of validators in the stake pool, used to determine the number of validators to be scored.", + "Updated at the start of each cycle and when validators are removed." + ], + "type": "u64" + }, + { + "name": "scoring_unstake_total", + "docs": [ + "Total lamports that have been due to scoring this cycle" + ], + "type": "u64" + }, + { + "name": "instant_unstake_total", + "docs": [ + "Total lamports that have been due to instant unstaking this cycle" + ], + "type": "u64" + }, + { + "name": "stake_deposit_unstake_total", + "docs": [ + "Total lamports that have been due to stake deposits this cycle" + ], + "type": "u64" + }, + { + "name": "compute_delegations_completed", + "docs": [ + "Tracks whether delegation computation has been completed" + ], + "type": { + "defined": { + "name": "U8Bool" + } + } + }, + { + "name": "rebalance_completed", + "docs": [ + "Tracks whether unstake and delegate steps have completed" + ], + "type": { + "defined": { + "name": "U8Bool" + } + } + }, + { + "name": "_padding0", + "docs": [ + "Future state and #[repr(C)] alignment" + ], "type": { "array": [ - "u64", - 157 + "u8", + 40006 ] } } @@ -1506,76 +2457,84 @@ } }, { - "name": "Parameters", + "name": "StewardStateAccount", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { "kind": "struct", "fields": [ { - "name": "mevCommissionRange", - "type": "u16" - }, - { - "name": "epochCreditsRange", - "type": "u16" - }, - { - "name": "commissionRange", - "type": "u16" - }, - { - "name": "mevCommissionBpsThreshold", - "type": "u16" - }, - { - "name": "scoringDelinquencyThresholdRatio", - "type": "f64" + "name": "state", + "type": { + "defined": { + "name": "StewardState" + } + } }, { - "name": "instantUnstakeDelinquencyThresholdRatio", - "type": "f64" + "name": "is_initialized", + "type": { + "defined": { + "name": "U8Bool" + } + } }, { - "name": "commissionThreshold", + "name": "bump", "type": "u8" }, { - "name": "padding0", + "name": "_padding", "type": { "array": [ "u8", - 7 + 6 ] } - }, - { - "name": "minPerfScore", - "type": "f64" - }, + } + ] + } + }, + { + "name": "StewardStateEnum", + "type": { + "kind": "enum", + "variants": [ { - "name": "minStakeAmount", - "type": "f64" + "name": "ComputeScores" }, { - "name": "computeScoreSlotRange", - "type": { - "defined": "usize" - } + "name": "ComputeDelegations" }, { - "name": "instantUnstakeEpochProgress", - "type": "f64" + "name": "Idle" }, { - "name": "clusterHistoryUpdateEpochProgress", - "type": "f64" + "name": "ComputeInstantUnstake" }, { - "name": "voteAccountUpdateEpochProgress", - "type": "f64" - }, + "name": "Rebalance" + } + ] + } + }, + { + "name": "U8Bool", + "docs": [ + "A boolean type stored as a u8." + ], + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ { - "name": "numEpochsBetweenScoring", - "type": "u64" + "name": "value", + "type": "u8" } ] } @@ -1586,87 +2545,109 @@ "kind": "struct", "fields": [ { - "name": "mevCommissionRange", + "name": "mev_commission_range", "type": { "option": "u16" } }, { - "name": "epochCreditsRange", + "name": "epoch_credits_range", "type": { "option": "u16" } }, { - "name": "commissionRange", + "name": "commission_range", "type": { "option": "u16" } }, { - "name": "scoringDelinquencyThresholdRatio", + "name": "scoring_delinquency_threshold_ratio", "type": { "option": "f64" } }, { - "name": "instantUnstakeDelinquencyThresholdRatio", + "name": "instant_unstake_delinquency_threshold_ratio", "type": { "option": "f64" } }, { - "name": "mevCommissionBpsThreshold", + "name": "mev_commission_bps_threshold", "type": { "option": "u16" } }, { - "name": "commissionThreshold", + "name": "commission_threshold", "type": { "option": "u8" } }, { - "name": "minPerfScore", + "name": "historical_commission_threshold", "type": { - "option": "f64" + "option": "u8" } }, { - "name": "minStakeAmount", + "name": "num_delegation_validators", "type": { - "option": "f64" + "option": "u32" } }, { - "name": "instantUnstakeEpochProgress", + "name": "scoring_unstake_cap_bps", "type": { - "option": "f64" + "option": "u32" } }, { - "name": "computeScoreSlotRange", + "name": "instant_unstake_cap_bps", "type": { - "option": { - "defined": "usize" - } + "option": "u32" + } + }, + { + "name": "stake_deposit_unstake_cap_bps", + "type": { + "option": "u32" } }, { - "name": "clusterHistoryUpdateEpochProgress", + "name": "instant_unstake_epoch_progress", "type": { "option": "f64" } }, { - "name": "voteAccountUpdateEpochProgress", + "name": "compute_score_slot_range", + "type": { + "option": "u64" + } + }, + { + "name": "instant_unstake_inputs_epoch_progress", "type": { "option": "f64" } }, { - "name": "numEpochsBetweenScoring", + "name": "num_epochs_between_scoring", + "type": { + "option": "u64" + } + }, + { + "name": "minimum_stake_lamports", + "type": { + "option": "u64" + } + }, + { + "name": "minimum_voting_epochs", "type": { "option": "u64" } @@ -1675,126 +2656,148 @@ } }, { - "name": "StewardStateEnum", + "name": "ValidatorHistory", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { - "kind": "enum", - "variants": [ + "kind": "struct", + "fields": [ { - "name": "ComputeScores" + "name": "struct_version", + "type": "u32" }, { - "name": "ComputeDelegations" + "name": "vote_account", + "type": "pubkey" }, { - "name": "Idle" + "name": "index", + "type": "u32" }, { - "name": "ComputeInstantUnstake" + "name": "bump", + "type": "u8" + }, + { + "name": "_padding0", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "last_ip_timestamp", + "type": "u64" }, { - "name": "RecomputeDelegations" + "name": "last_version_timestamp", + "type": "u64" }, { - "name": "Unstake" + "name": "_padding1", + "type": { + "array": [ + "u8", + 232 + ] + } }, { - "name": "Delegate" + "name": "history", + "type": { + "defined": { + "name": "CircBuf" + } + } } ] } - } - ], - "events": [ - { - "name": "StateTransition", - "fields": [ - { - "name": "previousState", - "type": "string", - "index": false - }, - { - "name": "newState", - "type": "string", - "index": false - } - ] - } - ], - "errors": [ - { - "code": 6000, - "name": "ScoringNotComplete", - "msg": "Scoring must be completed before any other steps can be taken" - }, - { - "code": 6001, - "name": "ValidatorNotInList", - "msg": "Validator does not exist at the ValidatorList index provided" - }, - { - "code": 6002, - "name": "AddValidatorsNotComplete", - "msg": "Add validators step must be completed before any other steps can be taken" - }, - { - "code": 6003, - "name": "EpochNotOver", - "msg": "Cannot reset state before epoch is over" - }, - { - "code": 6004, - "name": "Unauthorized", - "msg": "Unauthorized to perform this action" - }, - { - "code": 6005, - "name": "BitmaskOutOfBounds", - "msg": "Bitmask index out of bounds" - }, - { - "code": 6006, - "name": "StateNotReset", - "msg": "Epoch state not reset" - }, - { - "code": 6007, - "name": "ValidatorOutOfRange", - "msg": "Validator History created after epoch start, out of range" - }, - { - "code": 6008, - "name": "InvalidState" - }, - { - "code": 6009, - "name": "ValidatorBelowStakeMinimum", - "msg": "Validator not eligible to be added to the pool. Must meet stake minimum" - }, - { - "code": 6010, - "name": "ValidatorBelowLivenessMinimum", - "msg": "Validator not eligible to be added to the pool. Must meet recent voting minimum" - }, - { - "code": 6011, - "name": "ValidatorHistoryNotRecentEnough", - "msg": "Validator History data not recent enough to be used for scoring. Must be updated this epoch" - }, - { - "code": 6012, - "name": "ClusterHistoryNotRecentEnough", - "msg": "Cluster History data not recent enough to be used for scoring. Must be updated this epoch" }, { - "code": 6013, - "name": "StateMachinePaused", - "msg": "Steward State Machine is paused. No state machine actions can be taken" - }, - { - "code": 6014, - "name": "InvalidParameterValue", - "msg": "Config parameter is out of range or otherwise invalid" + "name": "ValidatorHistoryEntry", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "activated_stake_lamports", + "type": "u64" + }, + { + "name": "epoch", + "type": "u16" + }, + { + "name": "mev_commission", + "type": "u16" + }, + { + "name": "epoch_credits", + "type": "u32" + }, + { + "name": "commission", + "type": "u8" + }, + { + "name": "client_type", + "type": "u8" + }, + { + "name": "version", + "type": { + "defined": { + "name": "ClientVersion" + } + } + }, + { + "name": "ip", + "type": { + "array": [ + "u8", + 4 + ] + } + }, + { + "name": "padding0", + "type": "u8" + }, + { + "name": "is_superminority", + "type": "u8" + }, + { + "name": "rank", + "type": "u32" + }, + { + "name": "vote_account_last_update_slot", + "type": "u64" + }, + { + "name": "mev_earned", + "type": "u32" + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 84 + ] + } + } + ] + } } ] } \ No newline at end of file diff --git a/programs/steward/src/constants.rs b/programs/steward/src/constants.rs index 8957cf82..1bacb9c5 100644 --- a/programs/steward/src/constants.rs +++ b/programs/steward/src/constants.rs @@ -10,8 +10,8 @@ pub const EPOCH_PROGRESS_MAX: f64 = 0.99; // Cannot go more than 100 epochs without scoring pub const NUM_EPOCHS_BETWEEN_SCORING_MAX: u64 = 100; // Cannot score validators in under 100 slots, to submit 1 instruction per validator -pub const COMPUTE_SCORE_SLOT_RANGE_MIN: usize = 100; +pub const COMPUTE_SCORE_SLOT_RANGE_MIN: u64 = 100; #[cfg(feature = "mainnet-beta")] -pub const VALIDATOR_HISTORY_FIRST_RELIABLE_EPOCH: usize = 520; +pub const VALIDATOR_HISTORY_FIRST_RELIABLE_EPOCH: u64 = 520; #[cfg(not(feature = "mainnet-beta"))] -pub const VALIDATOR_HISTORY_FIRST_RELIABLE_EPOCH: usize = 0; +pub const VALIDATOR_HISTORY_FIRST_RELIABLE_EPOCH: u64 = 0; diff --git a/programs/steward/src/delegation.rs b/programs/steward/src/delegation.rs index fc333a76..2ea078ae 100644 --- a/programs/steward/src/delegation.rs +++ b/programs/steward/src/delegation.rs @@ -39,7 +39,7 @@ pub fn decrease_stake_calculation( minimum_delegation: u64, stake_rent: u64, ) -> Result { - if target_index >= state.num_pool_validators { + if target_index >= state.num_pool_validators as usize { return Err(StewardError::ValidatorIndexOutOfBounds.into()); } @@ -47,7 +47,7 @@ pub fn decrease_stake_calculation( .checked_add(stake_rent) .ok_or(StewardError::ArithmeticError)?; - for idx in state.sorted_yield_score_indices[..state.num_pool_validators] + for idx in state.sorted_yield_score_indices[..state.num_pool_validators as usize] .iter() .rev() { @@ -115,7 +115,7 @@ pub fn increase_stake_calculation( minimum_delegation: u64, stake_rent: u64, ) -> Result { - if target_index >= state.num_pool_validators { + if target_index >= state.num_pool_validators as usize { return Err(StewardError::ValidatorIndexOutOfBounds.into()); } let target_lamports: u64 = @@ -126,7 +126,7 @@ pub fn increase_stake_calculation( .ok_or(StewardError::ArithmeticError)?; if current_lamports < target_lamports { - for idx in state.sorted_score_indices[..state.num_pool_validators].iter() { + for idx in state.sorted_score_indices[..state.num_pool_validators as usize].iter() { let temp_index = *idx as usize; let lamports = if state.delegations[temp_index].numerator > 0 && !state.instant_unstake.get(temp_index)? 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 99b405c1..8ecb5b47 100644 --- a/programs/steward/src/instructions/auto_add_validator_to_pool.rs +++ b/programs/steward/src/instructions/auto_add_validator_to_pool.rs @@ -1,7 +1,7 @@ use crate::constants::{MAX_VALIDATORS, STAKE_POOL_WITHDRAW_SEED}; use crate::errors::StewardError; use crate::state::{Config, Staker}; -use crate::utils::{get_stake_pool, StakePool}; +use crate::utils::{deserialize_stake_pool, get_stake_pool_address}; use anchor_lang::prelude::*; use anchor_lang::solana_program::{program::invoke_signed, stake, sysvar, vote}; use spl_stake_pool::find_stake_program_address; @@ -26,11 +26,12 @@ pub struct AutoAddValidator<'info> { )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], @@ -39,7 +40,7 @@ pub struct AutoAddValidator<'info> { pub staker: Account<'info, Staker>, /// CHECK: passing through, checks are done by spl-stake-pool - #[account(mut, address = stake_pool.reserve_stake)] + #[account(mut, address = deserialize_stake_pool(&stake_pool)?.reserve_stake)] pub reserve_stake: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool @@ -49,12 +50,12 @@ pub struct AutoAddValidator<'info> { STAKE_POOL_WITHDRAW_SEED ], seeds::program = spl_stake_pool::ID, - bump = stake_pool.stake_withdraw_bump_seed + bump = deserialize_stake_pool(&stake_pool)?.stake_withdraw_bump_seed )] 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 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 27c1cb09..15b8b67d 100644 --- a/programs/steward/src/instructions/auto_remove_validator_from_pool.rs +++ b/programs/steward/src/instructions/auto_remove_validator_from_pool.rs @@ -3,7 +3,9 @@ use std::num::NonZeroU32; use crate::constants::STAKE_POOL_WITHDRAW_SEED; use crate::errors::StewardError; use crate::state::{Config, Staker}; -use crate::utils::{get_stake_pool, get_validator_stake_info_at_index, StakePool}; +use crate::utils::{ + deserialize_stake_pool, get_stake_pool_address, get_validator_stake_info_at_index, +}; use crate::StewardStateAccount; use anchor_lang::solana_program::{program::invoke_signed, stake, sysvar, vote}; use anchor_lang::{prelude::*, system_program}; @@ -13,7 +15,7 @@ use spl_stake_pool::{find_stake_program_address, find_transient_stake_program_ad use validator_history::state::ValidatorHistory; #[derive(Accounts)] -#[instruction(validator_list_index: usize)] +#[instruction(validator_list_index: u64)] pub struct AutoRemoveValidator<'info> { #[account( seeds = [ValidatorHistory::SEED, vote_account.key().as_ref()], @@ -37,11 +39,12 @@ pub struct AutoRemoveValidator<'info> { )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], @@ -50,7 +53,7 @@ pub struct AutoRemoveValidator<'info> { pub staker: Account<'info, Staker>, /// CHECK: passing through, checks are done by spl-stake-pool - #[account(mut, address = stake_pool.reserve_stake)] + #[account(mut, address = deserialize_stake_pool(&stake_pool)?.reserve_stake)] pub reserve_stake: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool @@ -60,12 +63,12 @@ pub struct AutoRemoveValidator<'info> { STAKE_POOL_WITHDRAW_SEED ], seeds::program = spl_stake_pool::ID, - bump = stake_pool.stake_withdraw_bump_seed + bump = deserialize_stake_pool(&stake_pool)?.stake_withdraw_bump_seed )] 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 @@ -77,7 +80,7 @@ pub struct AutoRemoveValidator<'info> { &stake_pool.key(), NonZeroU32::new( u32::from( - get_validator_stake_info_at_index(&validator_list, validator_list_index)? + get_validator_stake_info_at_index(&validator_list, validator_list_index as usize)? .validator_seed_suffix ) ) @@ -94,7 +97,7 @@ pub struct AutoRemoveValidator<'info> { &spl_stake_pool::id(), &vote_account.key(), &stake_pool.key(), - get_validator_stake_info_at_index(&validator_list, validator_list_index)?.transient_seed_suffix.into() + get_validator_stake_info_at_index(&validator_list, validator_list_index as usize)?.transient_seed_suffix.into() ).0 )] pub transient_stake_account: AccountInfo<'info>, diff --git a/programs/steward/src/instructions/compute_instant_unstake.rs b/programs/steward/src/instructions/compute_instant_unstake.rs index a87b7fcb..9bcd64f4 100644 --- a/programs/steward/src/instructions/compute_instant_unstake.rs +++ b/programs/steward/src/instructions/compute_instant_unstake.rs @@ -18,6 +18,7 @@ pub struct ComputeInstantUnstake<'info> { pub validator_history: AccountLoader<'info, ValidatorHistory>, + /// CHECK: TODO add validator list to config #[account(owner = spl_stake_pool::id())] pub validator_list: AccountInfo<'info>, diff --git a/programs/steward/src/instructions/compute_score.rs b/programs/steward/src/instructions/compute_score.rs index a9a32e9d..81125003 100644 --- a/programs/steward/src/instructions/compute_score.rs +++ b/programs/steward/src/instructions/compute_score.rs @@ -20,6 +20,7 @@ pub struct ComputeScore<'info> { pub validator_history: AccountLoader<'info, ValidatorHistory>, + /// CHECK: Account owner checked, account type checked in get_validator_stake_info_at_index #[account(owner = spl_stake_pool::id())] pub validator_list: AccountInfo<'info>, @@ -53,7 +54,7 @@ pub fn handler(ctx: Context, validator_list_index: usize) -> Resul let num_pool_validators = { let mut validator_list_data = validator_list.try_borrow_mut_data()?; let (_, validator_list) = ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; - validator_list.len() as usize + validator_list.len() as u64 }; if config.is_paused() { diff --git a/programs/steward/src/instructions/initialize_config.rs b/programs/steward/src/instructions/initialize_config.rs index 7b22765c..12a5ccaa 100644 --- a/programs/steward/src/instructions/initialize_config.rs +++ b/programs/steward/src/instructions/initialize_config.rs @@ -1,6 +1,6 @@ use anchor_lang::{prelude::*, solana_program::program::invoke}; -use crate::{utils::StakePool, Config, Staker, UpdateParametersArgs}; +use crate::{utils::deserialize_stake_pool, Config, Staker, UpdateParametersArgs}; #[derive(Accounts)] pub struct InitializeConfig<'info> { @@ -23,8 +23,9 @@ pub struct InitializeConfig<'info> { )] pub staker: Account<'info, Staker>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account(mut)] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, /// CHECK: CPI program #[account(address = spl_stake_pool::ID)] @@ -34,7 +35,7 @@ pub struct InitializeConfig<'info> { #[account( mut, - address = stake_pool.staker + address = deserialize_stake_pool(&stake_pool)?.staker )] pub signer: Signer<'info>, } @@ -44,6 +45,8 @@ pub fn handler( authority: Pubkey, update_parameters_args: &UpdateParametersArgs, ) -> Result<()> { + // Confirm that the stake pool is valid + let _ = deserialize_stake_pool(&ctx.accounts.stake_pool)?; let mut config = ctx.accounts.config.load_init()?; config.stake_pool = ctx.accounts.stake_pool.key(); config.authority = authority; diff --git a/programs/steward/src/instructions/realloc_state.rs b/programs/steward/src/instructions/realloc_state.rs index e7b94a62..fadaf40c 100644 --- a/programs/steward/src/instructions/realloc_state.rs +++ b/programs/steward/src/instructions/realloc_state.rs @@ -43,6 +43,7 @@ pub struct ReallocState<'info> { pub config: AccountLoader<'info, Config>, + /// CHECK: TODO add validator_list address to config #[account( owner = spl_stake_pool::ID, )] @@ -73,7 +74,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/rebalance.rs b/programs/steward/src/instructions/rebalance.rs index 9befdd26..92ef5a46 100644 --- a/programs/steward/src/instructions/rebalance.rs +++ b/programs/steward/src/instructions/rebalance.rs @@ -20,12 +20,12 @@ use crate::{ delegation::RebalanceType, errors::StewardError, maybe_transition_and_emit, - utils::{get_stake_pool, get_validator_stake_info_at_index, StakePool}, + utils::{deserialize_stake_pool, get_stake_pool_address, get_validator_stake_info_at_index}, Config, Staker, StewardStateAccount, }; #[derive(Accounts)] -#[instruction(validator_list_index: usize)] +#[instruction(validator_list_index: u64)] pub struct Rebalance<'info> { pub config: AccountLoader<'info, Config>, @@ -47,8 +47,9 @@ pub struct Rebalance<'info> { #[account(address = spl_stake_pool::ID)] pub stake_pool_program: AccountInfo<'info>, - #[account(address = get_stake_pool(&config)?)] - pub stake_pool: Account<'info, StakePool>, + /// CHECK: passing through, checks are done by spl-stake-pool + #[account(address = get_stake_pool_address(&config)?)] + pub stake_pool: AccountInfo<'info>, #[account( mut, @@ -64,21 +65,21 @@ pub struct Rebalance<'info> { STAKE_POOL_WITHDRAW_SEED ], seeds::program = spl_stake_pool::ID, - bump = stake_pool.stake_withdraw_bump_seed + bump = deserialize_stake_pool(&stake_pool)?.stake_withdraw_bump_seed )] pub withdraw_authority: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = stake_pool.validator_list + 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, - address = stake_pool.reserve_stake + address = deserialize_stake_pool(&stake_pool)?.reserve_stake )] pub reserve_stake: AccountInfo<'info>, @@ -91,7 +92,7 @@ pub struct Rebalance<'info> { &stake_pool.key(), NonZeroU32::new( u32::from( - get_validator_stake_info_at_index(&validator_list, validator_list_index)? + get_validator_stake_info_at_index(&validator_list, validator_list_index as usize)? .validator_seed_suffix ) ) @@ -108,7 +109,7 @@ pub struct Rebalance<'info> { &spl_stake_pool::id(), &vote_account.key(), &stake_pool.key(), - get_validator_stake_info_at_index(&validator_list, validator_list_index)?.transient_seed_suffix.into() + get_validator_stake_info_at_index(&validator_list, validator_list_index as usize)?.transient_seed_suffix.into() ).0 )] pub transient_stake_account: AccountInfo<'info>, @@ -171,7 +172,8 @@ pub fn handler(ctx: Context, validator_list_index: usize) -> Result<( let validator_list_data = &mut ctx.accounts.validator_list.try_borrow_mut_data()?; let (_, validator_list) = ValidatorListHeader::deserialize_vec(validator_list_data)?; - let stake_pool_lamports_with_fixed_cost = ctx.accounts.stake_pool.total_lamports; + let stake_pool_lamports_with_fixed_cost = + deserialize_stake_pool(&ctx.accounts.stake_pool)?.total_lamports; let reserve_lamports_with_rent = ctx.accounts.reserve_stake.lamports(); state_account.state.rebalance( diff --git a/programs/steward/src/instructions/spl_passthrough.rs b/programs/steward/src/instructions/spl_passthrough.rs index 741a63c6..ed4224a8 100644 --- a/programs/steward/src/instructions/spl_passthrough.rs +++ b/programs/steward/src/instructions/spl_passthrough.rs @@ -8,8 +8,8 @@ use crate::constants::MAX_VALIDATORS; use crate::errors::StewardError; use crate::state::{Config, Staker}; use crate::utils::{ - get_config_authority, get_stake_pool, get_validator_stake_info_at_index, StakePool, - ValidatorList, + deserialize_stake_pool, get_config_authority, get_stake_pool_address, + get_validator_stake_info_at_index, }; use crate::StewardStateAccount; use anchor_lang::prelude::*; @@ -30,9 +30,10 @@ pub struct AddValidatorToPool<'info> { pub stake_pool_program: AccountInfo<'info>, #[account( mut, - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + /// CHECK: passing through, checks are done by spl-stake-pool + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump @@ -44,7 +45,7 @@ pub struct AddValidatorToPool<'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(mut)] @@ -131,11 +132,12 @@ pub struct RemoveValidatorFromPool<'info> { address = spl_stake_pool::ID )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump @@ -143,8 +145,9 @@ pub struct RemoveValidatorFromPool<'info> { pub staker: Account<'info, Staker>, /// 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)] - pub validator_list: Account<'info, ValidatorList>, + pub validator_list: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool #[account(mut)] pub stake_account: AccountInfo<'info>, @@ -166,7 +169,7 @@ pub fn remove_validator_from_pool_handler( ) -> Result<()> { let mut state_account = ctx.accounts.steward_state.load_mut()?; - if validator_list_index < state_account.state.num_pool_validators { + if validator_list_index < state_account.state.num_pool_validators as usize { let validator_list_stake_info = get_validator_stake_info_at_index( &ctx.accounts.validator_list.to_account_info(), validator_list_index, @@ -223,25 +226,27 @@ pub struct SetPreferredValidator<'info> { address = spl_stake_pool::ID )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump )] pub staker: Account<'info, Staker>, - #[account(address = stake_pool.validator_list)] - pub validator_list: Account<'info, ValidatorList>, + /// CHECK: passing through, checks are done by spl-stake-pool + #[account(address = deserialize_stake_pool(&stake_pool)?.validator_list)] + pub validator_list: AccountInfo<'info>, #[account(mut, address = get_config_authority(&config)?)] pub signer: Signer<'info>, } pub fn set_preferred_validator_handler( ctx: Context, - validator_type: PreferredValidatorType, + validator_type: &PreferredValidatorType, validator: Option, ) -> Result<()> { invoke_signed( @@ -250,7 +255,7 @@ pub fn set_preferred_validator_handler( &ctx.accounts.stake_pool.key(), &ctx.accounts.staker.key(), &ctx.accounts.validator_list.key(), - validator_type, + validator_type.clone(), validator, ), &[ @@ -288,11 +293,12 @@ pub struct IncreaseValidatorStake<'info> { address = spl_stake_pool::ID )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump @@ -306,7 +312,7 @@ pub struct IncreaseValidatorStake<'info> { /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = stake_pool.reserve_stake + address = deserialize_stake_pool(&stake_pool)?.reserve_stake )] pub reserve_stake: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool @@ -416,11 +422,12 @@ pub struct DecreaseValidatorStake<'info> { address = spl_stake_pool::ID )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump @@ -434,7 +441,7 @@ pub struct DecreaseValidatorStake<'info> { /// CHECK: passing through, checks are done by spl-stake-pool #[account( mut, - address = stake_pool.reserve_stake + address = deserialize_stake_pool(&stake_pool)?.reserve_stake )] pub reserve_stake: AccountInfo<'info>, /// CHECK: passing through, checks are done by spl-stake-pool @@ -538,10 +545,11 @@ pub struct IncreaseAdditionalValidatorStake<'info> { address = spl_stake_pool::ID )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump @@ -549,8 +557,9 @@ pub struct IncreaseAdditionalValidatorStake<'info> { pub staker: Account<'info, Staker>, /// CHECK: passing through, checks are done by spl-stake-pool pub withdraw_authority: AccountInfo<'info>, - #[account(mut, address = stake_pool.validator_list)] - pub validator_list: Account<'info, ValidatorList>, + /// CHECK: passing through, checks are done by spl-stake-pool + #[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)] pub reserve_stake: AccountInfo<'info>, @@ -671,10 +680,11 @@ pub struct DecreaseAdditionalValidatorStake<'info> { )] /// CHECK: CPI program pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( - address = get_stake_pool(&config)? + address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump @@ -682,8 +692,9 @@ pub struct DecreaseAdditionalValidatorStake<'info> { pub staker: Account<'info, Staker>, /// CHECK: passing through, checks are done by spl-stake-pool pub withdraw_authority: AccountInfo<'info>, - #[account(mut, address = stake_pool.validator_list)] - pub validator_list: Account<'info, ValidatorList>, + /// CHECK: passing through, checks are done by spl-stake-pool + #[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)] pub reserve_stake: AccountInfo<'info>, @@ -777,10 +788,11 @@ pub struct SetStaker<'info> { address = spl_stake_pool::ID )] pub stake_pool_program: AccountInfo<'info>, + /// CHECK: passing through, checks are done by spl-stake-pool #[account( - mut, address = get_stake_pool(&config)? + mut, address = get_stake_pool_address(&config)? )] - pub stake_pool: Account<'info, StakePool>, + pub stake_pool: AccountInfo<'info>, #[account( seeds = [Staker::SEED, config.key().as_ref()], bump = staker.bump diff --git a/programs/steward/src/lib.rs b/programs/steward/src/lib.rs index c668bc0b..493e622e 100644 --- a/programs/steward/src/lib.rs +++ b/programs/steward/src/lib.rs @@ -1,8 +1,9 @@ #![allow(clippy::redundant_pub_crate)] use anchor_lang::prelude::*; +use anchor_lang::IdlBuild; use instructions::*; -use spl_stake_pool::instruction::PreferredValidatorType; +use crate::utils::PreferredValidatorType; mod allocator; pub mod constants; @@ -85,14 +86,14 @@ pub mod steward { /// Removes a validator from the pool if its stake account is inactive or the vote account has closed pub fn auto_remove_validator_from_pool( ctx: Context, - validator_list_index: usize, + validator_list_index: u64, ) -> Result<()> { - instructions::auto_remove_validator_from_pool::handler(ctx, validator_list_index) + instructions::auto_remove_validator_from_pool::handler(ctx, validator_list_index as usize) } /// Computes score for a the validator at `validator_list_index` for the current cycle. - pub fn compute_score(ctx: Context, validator_list_index: usize) -> Result<()> { - instructions::compute_score::handler(ctx, validator_list_index) + pub fn compute_score(ctx: Context, validator_list_index: u64) -> Result<()> { + instructions::compute_score::handler(ctx, validator_list_index as usize) } /// Computes delegation for a validator for the current cycle. @@ -109,15 +110,15 @@ pub mod steward { /// Checks if a validator at `validator_list_index` should be instant unstaked, and marks it if so pub fn compute_instant_unstake( ctx: Context, - validator_list_index: usize, + validator_list_index: u64, ) -> Result<()> { - instructions::compute_instant_unstake::handler(ctx, validator_list_index) + instructions::compute_instant_unstake::handler(ctx, validator_list_index as usize) } /// Increases or decreases stake for a validator at `validator_list_index` to match the target stake, /// given constraints on increase/decrease priority, reserve balance, and unstaking caps - pub fn rebalance(ctx: Context, validator_list_index: usize) -> Result<()> { - instructions::rebalance::handler(ctx, validator_list_index) + pub fn rebalance(ctx: Context, validator_list_index: u64) -> Result<()> { + instructions::rebalance::handler(ctx, validator_list_index as usize) } /* Admin instructions */ @@ -175,9 +176,12 @@ pub mod steward { pub fn remove_validator_from_pool( ctx: Context, - validator_list_index: usize, + validator_list_index: u64, ) -> Result<()> { - instructions::spl_passthrough::remove_validator_from_pool_handler(ctx, validator_list_index) + instructions::spl_passthrough::remove_validator_from_pool_handler( + ctx, + validator_list_index as usize, + ) } pub fn set_preferred_validator( @@ -187,7 +191,7 @@ pub mod steward { ) -> Result<()> { instructions::spl_passthrough::set_preferred_validator_handler( ctx, - validator_type, + validator_type.as_ref(), validator, ) } diff --git a/programs/steward/src/score.rs b/programs/steward/src/score.rs index 762344aa..d0e04e2c 100644 --- a/programs/steward/src/score.rs +++ b/programs/steward/src/score.rs @@ -1,5 +1,6 @@ use anchor_lang::{ - prelude::event, solana_program::pubkey::Pubkey, AnchorDeserialize, AnchorSerialize, Result, + prelude::event, solana_program::pubkey::Pubkey, AnchorDeserialize, AnchorSerialize, IdlBuild, + Result, }; use validator_history::{ClusterHistory, ValidatorHistory}; diff --git a/programs/steward/src/state/bitmask.rs b/programs/steward/src/state/bitmask.rs index 9d82f2d9..529cfe64 100644 --- a/programs/steward/src/state/bitmask.rs +++ b/programs/steward/src/state/bitmask.rs @@ -72,7 +72,8 @@ impl BitMask { } #[allow(clippy::integer_division)] - pub fn is_complete(&self, num_validators: usize) -> Result { + pub fn is_complete(&self, num_validators: u64) -> Result { + let num_validators = num_validators as usize; if num_validators > MAX_VALIDATORS { return Err(StewardError::BitmaskOutOfBounds.into()); } diff --git a/programs/steward/src/state/parameters.rs b/programs/steward/src/state/parameters.rs index 0bfaa01f..1f287358 100644 --- a/programs/steward/src/state/parameters.rs +++ b/programs/steward/src/state/parameters.rs @@ -1,3 +1,5 @@ +use anchor_lang::idl::types::*; +use anchor_lang::idl::*; use anchor_lang::{prelude::Result, zero_copy}; use borsh::{BorshDeserialize, BorshSerialize}; use validator_history::utils::cast_epoch; @@ -28,13 +30,120 @@ pub struct UpdateParametersArgs { pub stake_deposit_unstake_cap_bps: Option, // State machine parameters pub instant_unstake_epoch_progress: Option, - pub compute_score_slot_range: Option, + pub compute_score_slot_range: Option, pub instant_unstake_inputs_epoch_progress: Option, pub num_epochs_between_scoring: Option, pub minimum_stake_lamports: Option, pub minimum_voting_epochs: Option, } +// #[cfg(feature = "idl-build")] +impl IdlBuild for UpdateParametersArgs { + fn create_type() -> Option { + Some(IdlTypeDef { + name: "UpdateParametersArgs".to_string(), + ty: IdlTypeDefTy::Struct { + fields: Some(IdlDefinedFields::Named(vec![ + IdlField { + name: "mev_commission_range".to_string(), + ty: IdlType::Option(Box::new(IdlType::U16)), + docs: Default::default(), + }, + IdlField { + name: "epoch_credits_range".to_string(), + ty: IdlType::Option(Box::new(IdlType::U16)), + docs: Default::default(), + }, + IdlField { + name: "commission_range".to_string(), + ty: IdlType::Option(Box::new(IdlType::U16)), + docs: Default::default(), + }, + IdlField { + name: "scoring_delinquency_threshold_ratio".to_string(), + ty: IdlType::Option(Box::new(IdlType::F64)), + docs: Default::default(), + }, + IdlField { + name: "instant_unstake_delinquency_threshold_ratio".to_string(), + ty: IdlType::Option(Box::new(IdlType::F64)), + docs: Default::default(), + }, + IdlField { + name: "mev_commission_bps_threshold".to_string(), + ty: IdlType::Option(Box::new(IdlType::U16)), + docs: Default::default(), + }, + IdlField { + name: "commission_threshold".to_string(), + ty: IdlType::Option(Box::new(IdlType::U8)), + docs: Default::default(), + }, + IdlField { + name: "historical_commission_threshold".to_string(), + ty: IdlType::Option(Box::new(IdlType::U8)), + docs: Default::default(), + }, + IdlField { + name: "num_delegation_validators".to_string(), + ty: IdlType::Option(Box::new(IdlType::U32)), + docs: Default::default(), + }, + IdlField { + name: "scoring_unstake_cap_bps".to_string(), + ty: IdlType::Option(Box::new(IdlType::U32)), + docs: Default::default(), + }, + IdlField { + name: "instant_unstake_cap_bps".to_string(), + ty: IdlType::Option(Box::new(IdlType::U32)), + docs: Default::default(), + }, + IdlField { + name: "stake_deposit_unstake_cap_bps".to_string(), + ty: IdlType::Option(Box::new(IdlType::U32)), + docs: Default::default(), + }, + IdlField { + name: "instant_unstake_epoch_progress".to_string(), + ty: IdlType::Option(Box::new(IdlType::F64)), + docs: Default::default(), + }, + IdlField { + name: "compute_score_slot_range".to_string(), + ty: IdlType::Option(Box::new(IdlType::U64)), + docs: Default::default(), + }, + IdlField { + name: "instant_unstake_inputs_epoch_progress".to_string(), + ty: IdlType::Option(Box::new(IdlType::F64)), + docs: Default::default(), + }, + IdlField { + name: "num_epochs_between_scoring".to_string(), + ty: IdlType::Option(Box::new(IdlType::U64)), + docs: Default::default(), + }, + IdlField { + name: "minimum_stake_lamports".to_string(), + ty: IdlType::Option(Box::new(IdlType::U64)), + docs: Default::default(), + }, + IdlField { + name: "minimum_voting_epochs".to_string(), + ty: IdlType::Option(Box::new(IdlType::U64)), + docs: Default::default(), + }, + ])), + }, + docs: Default::default(), + generics: Default::default(), + serialization: Default::default(), + repr: Default::default(), + }) + } +} + #[derive(BorshSerialize, Default)] #[zero_copy] pub struct Parameters { @@ -82,7 +191,7 @@ pub struct Parameters { /////// State machine operation parameters /////// /// Number of slots that scoring must be completed in - pub compute_score_slot_range: usize, + pub compute_score_slot_range: u64, /// Progress in epoch before instant unstake is allowed pub instant_unstake_epoch_progress: f64, @@ -218,11 +327,11 @@ impl Parameters { /// Validate reasonable bounds on parameters pub fn validate(&self, current_epoch: u64, slots_per_epoch: u64) -> Result<()> { // Cannot evaluate epochs before VALIDATOR_HISTORY_FIRST_RELIABLE_EPOCH or beyond the CircBuf length - let window_max = (current_epoch as usize) + let window_max = current_epoch .checked_sub(VALIDATOR_HISTORY_FIRST_RELIABLE_EPOCH) .ok_or(StewardError::ArithmeticError)? - .min(validator_history::ValidatorHistory::MAX_ITEMS - 1); - let window_max = cast_epoch(window_max as u64)?; + .min(validator_history::ValidatorHistory::MAX_ITEMS as u64 - 1); + let window_max = cast_epoch(window_max)?; if self.mev_commission_range > window_max { return Err(StewardError::InvalidParameterValue.into()); @@ -288,7 +397,7 @@ impl Parameters { return Err(StewardError::InvalidParameterValue.into()); } - if !(COMPUTE_SCORE_SLOT_RANGE_MIN..=slots_per_epoch as usize) + if !(COMPUTE_SCORE_SLOT_RANGE_MIN..=slots_per_epoch) .contains(&self.compute_score_slot_range) { return Err(StewardError::InvalidParameterValue.into()); diff --git a/programs/steward/src/state/steward_state.rs b/programs/steward/src/state/steward_state.rs index 60c975d0..e141a9ed 100644 --- a/programs/steward/src/state/steward_state.rs +++ b/programs/steward/src/state/steward_state.rs @@ -13,15 +13,16 @@ use crate::{ utils::{epoch_progress, get_target_lamports, stake_lamports_at_validator_list_index, U8Bool}, Config, Parameters, }; -use anchor_lang::prelude::*; +use anchor_lang::idl::types::*; +use anchor_lang::{prelude::*, IdlBuild}; use bytemuck::{Pod, Zeroable}; use spl_stake_pool::big_vec::BigVec; use validator_history::{ClusterHistory, ValidatorHistory}; // Tests will fail here - comment out msg! to pass -fn invalid_state_error(expected: String, actual: String) -> Error { - msg!("Invalid state. Expected {}, Actual {}", expected, actual); +fn invalid_state_error(_expected: String, _actual: String) -> Error { + // msg!("Invalid state. Expected {}, Actual {}", expected, actual); StewardError::InvalidState.into() } @@ -98,7 +99,7 @@ pub struct StewardState { /// Number of validators in the stake pool, used to determine the number of validators to be scored. /// Updated at the start of each cycle and when validators are removed. - pub num_pool_validators: usize, + pub num_pool_validators: u64, /// Total lamports that have been due to scoring this cycle pub scoring_unstake_total: u64, @@ -191,6 +192,42 @@ impl Display for StewardStateEnum { } } +impl IdlBuild for StewardStateEnum { + fn create_type() -> Option { + Some(IdlTypeDef { + name: "StewardStateEnum".to_string(), + ty: IdlTypeDefTy::Enum { + variants: vec![ + IdlEnumVariant { + name: "ComputeScores".to_string(), + fields: None, + }, + IdlEnumVariant { + name: "ComputeDelegations".to_string(), + fields: None, + }, + IdlEnumVariant { + name: "Idle".to_string(), + fields: None, + }, + IdlEnumVariant { + name: "ComputeInstantUnstake".to_string(), + fields: None, + }, + IdlEnumVariant { + name: "Rebalance".to_string(), + fields: None, + }, + ], + }, + docs: Default::default(), + generics: Default::default(), + serialization: Default::default(), + repr: Default::default(), + }) + } +} + impl StewardState { /// Top level transition method. Tries to transition to a new state based on current state and epoch conditions pub fn transition( @@ -388,9 +425,10 @@ impl StewardState { .num_pool_validators .checked_sub(1) .ok_or(StewardError::ArithmeticError)?; + let num_pool_validators = self.num_pool_validators as usize; // Shift all validator state to the left - for i in index..self.num_pool_validators { + for i in index..num_pool_validators { let next_i = i.checked_add(1).ok_or(StewardError::ArithmeticError)?; self.validator_lamport_balances[i] = self.validator_lamport_balances[next_i]; self.scores[i] = self.scores[next_i]; @@ -400,6 +438,7 @@ impl StewardState { .set(i, self.instant_unstake.get(next_i)?)?; self.progress.set(i, self.progress.get(next_i)?)?; } + // Update score indices let yield_score_index = self .sorted_yield_score_indices @@ -412,17 +451,17 @@ impl StewardState { .position(|&i| i == index as u16) .ok_or(StewardError::ValidatorIndexOutOfBounds)?; - 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]; } - 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]; } - for i in 0..self.num_pool_validators { + for i in 0..num_pool_validators { if self.sorted_yield_score_indices[i] as usize > index { self.sorted_yield_score_indices[i] = self.sorted_yield_score_indices[i] .checked_sub(1) @@ -436,14 +475,14 @@ 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.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.progress.set(num_pool_validators, false)?; Ok(()) } @@ -463,7 +502,7 @@ impl StewardState { index: usize, cluster: &ClusterHistory, config: &Config, - num_pool_validators: usize, + num_pool_validators: u64, ) -> Result<()> { if matches!(self.state_tag, StewardStateEnum::ComputeScores) { let current_epoch = clock.epoch; @@ -495,7 +534,7 @@ impl StewardState { .ok_or(StewardError::ArithmeticError)?; if self.progress.is_empty() || current_epoch > self.current_epoch - || slots_since_scoring_started > config.parameters.compute_score_slot_range as u64 + || slots_since_scoring_started > config.parameters.compute_score_slot_range { self.reset_state_for_new_cycle( clock.epoch, @@ -552,8 +591,8 @@ impl StewardState { } let validators_to_delegate = select_validators_to_delegate( - &self.scores[..self.num_pool_validators], - &self.sorted_score_indices[..self.num_pool_validators], + &self.scores[..self.num_pool_validators as usize], + &self.sorted_score_indices[..self.num_pool_validators as usize], config.parameters.num_delegation_validators as usize, ); @@ -815,7 +854,7 @@ impl StewardState { } let next_i = index.checked_add(1).ok_or(StewardError::ArithmeticError)?; - for i in next_i..self.num_pool_validators { + for i in next_i..self.num_pool_validators as usize { if self.delegations[i].numerator > 0 { self.delegations[i].denominator = self.delegations[i].denominator.saturating_sub(1).max(1); diff --git a/programs/steward/src/utils.rs b/programs/steward/src/utils.rs index 6d6436de..96f281fd 100644 --- a/programs/steward/src/utils.rs +++ b/programs/steward/src/utils.rs @@ -1,6 +1,6 @@ use std::ops::{Deref, Not}; -use anchor_lang::prelude::*; +use anchor_lang::{idl::types::*, prelude::*}; use borsh::{BorshDeserialize, BorshSerialize}; use spl_pod::{bytemuck::pod_from_bytes, primitives::PodU64, solana_program::program_pack::Pack}; use spl_stake_pool::{ @@ -10,7 +10,7 @@ use spl_stake_pool::{ use crate::{errors::StewardError, Config, Delegation}; -pub fn get_stake_pool(account: &AccountLoader) -> Result { +pub fn get_stake_pool_address(account: &AccountLoader) -> Result { let config = account.load()?; Ok(config.stake_pool) } @@ -121,6 +121,69 @@ impl From for bool { } } +pub fn deserialize_stake_pool( + account_info: &AccountInfo, +) -> Result { + if account_info.owner != &spl_stake_pool::ID { + return Err(ProgramError::InvalidAccountOwner.into()); + } + let data = account_info.try_borrow_data()?; + Ok(spl_stake_pool::state::StakePool::deserialize( + &mut data.as_ref(), + )?) +} + +pub fn deserialize_validator_list( + account_info: &AccountInfo, +) -> Result { + if account_info.owner != &spl_stake_pool::ID { + return Err(ProgramError::InvalidAccountOwner.into()); + } + let data = account_info.try_borrow_data()?; + Ok(spl_stake_pool::state::ValidatorList::deserialize( + &mut data.as_ref(), + )?) +} + +#[derive(BorshDeserialize, BorshSerialize)] +pub struct PreferredValidatorType(spl_stake_pool::instruction::PreferredValidatorType); + +impl AsRef for PreferredValidatorType { + fn as_ref(&self) -> &spl_stake_pool::instruction::PreferredValidatorType { + &self.0 + } +} + +impl From for PreferredValidatorType { + fn from(val: spl_stake_pool::instruction::PreferredValidatorType) -> Self { + Self(val) + } +} + +impl IdlBuild for PreferredValidatorType { + fn create_type() -> Option { + Some(IdlTypeDef { + name: "PreferredValidatorType".to_string(), + ty: IdlTypeDefTy::Enum { + variants: vec![ + IdlEnumVariant { + name: "Deposit".to_string(), + fields: None, + }, + IdlEnumVariant { + name: "Withdraw".to_string(), + fields: None, + }, + ], + }, + docs: Default::default(), + generics: Default::default(), + serialization: Default::default(), + repr: Default::default(), + }) + } +} + #[derive(Clone)] pub struct StakePool(spl_stake_pool::state::StakePool); diff --git a/programs/validator-history/Cargo.toml b/programs/validator-history/Cargo.toml index c252075f..6ed95c8c 100644 --- a/programs/validator-history/Cargo.toml +++ b/programs/validator-history/Cargo.toml @@ -20,10 +20,10 @@ no-log-ix-name = [] cpi = ["no-entrypoint"] default = ["custom-heap"] custom-heap = [] -# idl-build = ["anchor-lang/idl-build"] +idl-build = ["anchor-lang/idl-build", "no-entrypoint"] [dependencies] -anchor-lang = "0.30.0" +anchor-lang = { features = ["idl-build"], version = "0.30.0" } bincode = "1.3.3" bytemuck = { version = "1.13.1", features = ["derive", "min_const_generics"] } cfg-if = "1.0.0" diff --git a/programs/validator-history/idl/validator_history.json b/programs/validator-history/idl/validator_history.json index 0b8bf879..0de57d0a 100644 --- a/programs/validator-history/idl/validator_history.json +++ b/programs/validator-history/idl/validator_history.json @@ -1,163 +1,147 @@ { - "version": "0.1.0", - "name": "validator_history", + "address": "HistoryJTGbKQD2mRgLZ3XhqHnN811Qpez8X9kCcGHoa", + "metadata": { + "name": "validator_history", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Program for tracking validator metrics on chain" + }, "instructions": [ { - "name": "initializeValidatorHistoryAccount", + "name": "backfill_total_blocks", + "discriminator": [ + 223, + 59, + 120, + 117, + 34, + 248, + 117, + 220 + ], "accounts": [ { - "name": "validatorHistoryAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "cluster_history_account", + "writable": true }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "signer", - "isMut": true, - "isSigner": true + "name": "oracle_authority", + "writable": true, + "signer": true } ], - "args": [] - }, - { - "name": "reallocValidatorHistoryAccount", - "accounts": [ - { - "name": "validatorHistoryAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "config", - "isMut": true, - "isSigner": false - }, - { - "name": "voteAccount", - "isMut": false, - "isSigner": false, - "docs": [ - "Used to read validator commission." - ] - }, + "args": [ { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "epoch", + "type": "u64" }, { - "name": "signer", - "isMut": true, - "isSigner": true + "name": "blocks_in_epoch", + "type": "u32" } - ], - "args": [] + ] }, { - "name": "initializeClusterHistoryAccount", + "name": "copy_cluster_info", + "discriminator": [ + 124, + 126, + 139, + 134, + 126, + 230, + 100, + 37 + ], "accounts": [ { - "name": "clusterHistoryAccount", - "isMut": true, - "isSigner": false + "name": "cluster_history_account", + "writable": true }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "slot_history" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [] }, { - "name": "reallocClusterHistoryAccount", + "name": "copy_gossip_contact_info", + "discriminator": [ + 246, + 174, + 228, + 249, + 28, + 209, + 69, + 85 + ], "accounts": [ { - "name": "clusterHistoryAccount", - "isMut": true, - "isSigner": false + "name": "validator_history_account", + "writable": true }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "signer", - "isMut": true, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "copyVoteAccount", - "accounts": [ - { - "name": "validatorHistoryAccount", - "isMut": true, - "isSigner": false + "name": "instructions" }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "signer", - "isMut": true, - "isSigner": true + "name": "oracle_authority", + "writable": true, + "signer": true } ], "args": [] }, { - "name": "copyTipDistributionAccount", + "name": "copy_tip_distribution_account", + "discriminator": [ + 208, + 213, + 185, + 210, + 103, + 124, + 128, + 173 + ], "accounts": [ { - "name": "validatorHistoryAccount", - "isMut": true, - "isSigner": false + "name": "validator_history_account", + "writable": true }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false, + "name": "vote_account", "docs": [ "Used to read validator commission." ] }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "config" }, { - "name": "tipDistributionAccount", - "isMut": false, - "isSigner": false, + "name": "tip_distribution_account", "docs": [ "`owner = config.tip_distribution_program.key()` here is sufficient." ] }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], "args": [ @@ -168,206 +152,299 @@ ] }, { - "name": "initializeConfig", + "name": "copy_vote_account", + "discriminator": [ + 171, + 204, + 73, + 59, + 129, + 63, + 134, + 61 + ], "accounts": [ { - "name": "config", - "isMut": true, - "isSigner": false + "name": "validator_history_account", + "writable": true }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { "name": "signer", - "isMut": true, - "isSigner": true + "writable": true, + "signer": true } ], - "args": [ - { - "name": "authority", - "type": "publicKey" - } - ] + "args": [] }, { - "name": "setNewTipDistributionProgram", + "name": "initialize_cluster_history_account", + "discriminator": [ + 8, + 204, + 21, + 27, + 253, + 9, + 10, + 78 + ], "accounts": [ { - "name": "config", - "isMut": true, - "isSigner": false + "name": "cluster_history_account", + "writable": true }, { - "name": "newTipDistributionProgram", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "admin", - "isMut": false, - "isSigner": true + "name": "signer", + "writable": true, + "signer": true } ], "args": [] }, { - "name": "setNewAdmin", + "name": "initialize_config", + "discriminator": [ + 208, + 127, + 21, + 1, + 194, + 190, + 196, + 70 + ], "accounts": [ { "name": "config", - "isMut": true, - "isSigner": false + "writable": true }, { - "name": "newAdmin", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "admin", - "isMut": false, - "isSigner": true + "name": "signer", + "writable": true, + "signer": true } ], - "args": [] + "args": [ + { + "name": "authority", + "type": "pubkey" + } + ] }, { - "name": "setNewOracleAuthority", + "name": "initialize_validator_history_account", + "discriminator": [ + 61, + 152, + 10, + 77, + 196, + 242, + 89, + 36 + ], "accounts": [ { - "name": "config", - "isMut": true, - "isSigner": false + "name": "validator_history_account", + "writable": true }, { - "name": "newOracleAuthority", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "admin", - "isMut": false, - "isSigner": true + "name": "system_program" + }, + { + "name": "signer", + "writable": true, + "signer": true } ], "args": [] }, { - "name": "updateStakeHistory", + "name": "realloc_cluster_history_account", + "discriminator": [ + 249, + 51, + 161, + 22, + 107, + 40, + 129, + 104 + ], "accounts": [ { - "name": "validatorHistoryAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "cluster_history_account", + "writable": true }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "system_program" }, { - "name": "oracleAuthority", - "isMut": true, - "isSigner": true + "name": "signer", + "writable": true, + "signer": true } ], - "args": [ + "args": [] + }, + { + "name": "realloc_validator_history_account", + "discriminator": [ + 196, + 17, + 33, + 140, + 174, + 130, + 33, + 12 + ], + "accounts": [ { - "name": "epoch", - "type": "u64" + "name": "validator_history_account", + "writable": true }, { - "name": "lamports", - "type": "u64" + "name": "config", + "writable": true }, { - "name": "rank", - "type": "u32" + "name": "vote_account", + "docs": [ + "Used to read validator commission." + ] }, { - "name": "isSuperminority", - "type": "bool" + "name": "system_program" + }, + { + "name": "signer", + "writable": true, + "signer": true } - ] + ], + "args": [] }, { - "name": "copyGossipContactInfo", + "name": "set_new_admin", + "discriminator": [ + 62, + 156, + 4, + 148, + 79, + 162, + 148, + 252 + ], "accounts": [ { - "name": "validatorHistoryAccount", - "isMut": true, - "isSigner": false + "name": "config", + "writable": true }, { - "name": "voteAccount", - "isMut": false, - "isSigner": false + "name": "new_admin" }, { - "name": "instructions", - "isMut": false, - "isSigner": false - }, + "name": "admin", + "signer": true + } + ], + "args": [] + }, + { + "name": "set_new_oracle_authority", + "discriminator": [ + 70, + 73, + 21, + 170, + 82, + 128, + 144, + 56 + ], + "accounts": [ { "name": "config", - "isMut": false, - "isSigner": false + "writable": true + }, + { + "name": "new_oracle_authority" }, { - "name": "oracleAuthority", - "isMut": true, - "isSigner": true + "name": "admin", + "signer": true } ], "args": [] }, { - "name": "copyClusterInfo", + "name": "set_new_tip_distribution_program", + "discriminator": [ + 200, + 69, + 235, + 182, + 178, + 62, + 130, + 217 + ], "accounts": [ { - "name": "clusterHistoryAccount", - "isMut": true, - "isSigner": false + "name": "config", + "writable": true }, { - "name": "slotHistory", - "isMut": false, - "isSigner": false + "name": "new_tip_distribution_program" }, { - "name": "signer", - "isMut": true, - "isSigner": true + "name": "admin", + "signer": true } ], "args": [] }, { - "name": "backfillTotalBlocks", + "name": "update_stake_history", + "discriminator": [ + 213, + 212, + 103, + 144, + 8, + 212, + 173, + 232 + ], "accounts": [ { - "name": "clusterHistoryAccount", - "isMut": true, - "isSigner": false + "name": "validator_history_account", + "writable": true }, { - "name": "config", - "isMut": false, - "isSigner": false + "name": "vote_account" }, { - "name": "signer", - "isMut": true, - "isSigner": true + "name": "config" + }, + { + "name": "oracle_authority", + "writable": true, + "signer": true } ], "args": [ @@ -376,64 +453,148 @@ "type": "u64" }, { - "name": "blocksInEpoch", + "name": "lamports", + "type": "u64" + }, + { + "name": "rank", "type": "u32" + }, + { + "name": "is_superminority", + "type": "bool" } ] } ], "accounts": [ + { + "name": "ClusterHistory", + "discriminator": [ + 41, + 154, + 241, + 80, + 135, + 88, + 85, + 252 + ] + }, { "name": "Config", - "type": { - "kind": "struct", - "fields": [ - { - "name": "tipDistributionProgram", - "type": "publicKey" - }, - { - "name": "admin", - "type": "publicKey" - }, - { - "name": "oracleAuthority", - "type": "publicKey" - }, - { - "name": "counter", - "type": "u32" - }, - { - "name": "bump", - "type": "u8" - } - ] - } + "discriminator": [ + 155, + 12, + 170, + 224, + 30, + 250, + 204, + 130 + ] }, { "name": "ValidatorHistory", + "discriminator": [ + 205, + 25, + 8, + 221, + 253, + 131, + 2, + 146 + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "AccountFullySized", + "msg": "Account already reached proper size, no more allocations allowed" + }, + { + "code": 6001, + "name": "InvalidEpochCredits", + "msg": "Invalid epoch credits, credits must exist and each value must be greater than previous credits" + }, + { + "code": 6002, + "name": "EpochOutOfRange", + "msg": "Epoch is out of range of history" + }, + { + "code": 6003, + "name": "NotSigVerified", + "msg": "Gossip Signature Verification not performed" + }, + { + "code": 6004, + "name": "GossipDataInvalid", + "msg": "Gossip Data Invalid" + }, + { + "code": 6005, + "name": "UnsupportedIpFormat", + "msg": "Unsupported IP Format, only IpAddr::V4 is supported" + }, + { + "code": 6006, + "name": "NotEnoughVotingHistory", + "msg": "Not enough voting history to create account. Minimum 5 epochs required" + }, + { + "code": 6007, + "name": "GossipDataTooOld", + "msg": "Gossip data too old. Data cannot be older than the last recorded timestamp for a field" + }, + { + "code": 6008, + "name": "GossipDataInFuture", + "msg": "Gossip timestamp too far in the future" + }, + { + "code": 6009, + "name": "ArithmeticError", + "msg": "Arithmetic Error (overflow/underflow)" + }, + { + "code": 6010, + "name": "SlotHistoryOutOfDate", + "msg": "Slot history sysvar is not containing expected slots" + }, + { + "code": 6011, + "name": "EpochTooLarge", + "msg": "Epoch larger than 65535, cannot be stored" + }, + { + "code": 6012, + "name": "DuplicateEpoch", + "msg": "Inserting duplicate epoch" + } + ], + "types": [ + { + "name": "CircBuf", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { "kind": "struct", "fields": [ { - "name": "structVersion", - "type": "u32" - }, - { - "name": "voteAccount", - "type": "publicKey" - }, - { - "name": "index", - "type": "u32" + "name": "idx", + "type": "u64" }, { - "name": "bump", + "name": "is_empty", "type": "u8" }, { - "name": "padding0", + "name": "padding", "type": { "array": [ "u8", @@ -442,46 +603,40 @@ } }, { - "name": "lastIpTimestamp", - "type": "u64" - }, - { - "name": "lastVersionTimestamp", - "type": "u64" - }, - { - "name": "padding1", + "name": "arr", "type": { "array": [ - "u8", - 232 + { + "defined": { + "name": "ValidatorHistoryEntry" + } + }, + 512 ] } - }, - { - "name": "history", - "type": { - "defined": "CircBuf" - } } ] } }, { - "name": "ClusterHistory", + "name": "CircBufCluster", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { "kind": "struct", "fields": [ { - "name": "structVersion", + "name": "idx", "type": "u64" }, { - "name": "bump", + "name": "is_empty", "type": "u8" }, { - "name": "padding0", + "name": "padding", "type": { "array": [ "u8", @@ -490,99 +645,15 @@ } }, { - "name": "clusterHistoryLastUpdateSlot", - "type": "u64" - }, - { - "name": "padding1", - "type": { - "array": [ - "u8", - 232 - ] - } - }, - { - "name": "history", - "type": { - "defined": "CircBufCluster" - } - } - ] - } - } - ], - "types": [ - { - "name": "ValidatorHistoryEntry", - "type": { - "kind": "struct", - "fields": [ - { - "name": "activatedStakeLamports", - "type": "u64" - }, - { - "name": "epoch", - "type": "u16" - }, - { - "name": "mevCommission", - "type": "u16" - }, - { - "name": "epochCredits", - "type": "u32" - }, - { - "name": "commission", - "type": "u8" - }, - { - "name": "clientType", - "type": "u8" - }, - { - "name": "version", - "type": { - "defined": "ClientVersion" - } - }, - { - "name": "ip", - "type": { - "array": [ - "u8", - 4 - ] - } - }, - { - "name": "padding0", - "type": "u8" - }, - { - "name": "isSuperminority", - "type": "u8" - }, - { - "name": "rank", - "type": "u32" - }, - { - "name": "voteAccountLastUpdateSlot", - "type": "u64" - }, - { - "name": "mevEarned", - "type": "u32" - }, - { - "name": "padding1", + "name": "arr", "type": { "array": [ - "u8", - 84 + { + "defined": { + "name": "ClusterHistoryEntry" + } + }, + 512 ] } } @@ -591,6 +662,10 @@ }, { "name": "ClientVersion", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { "kind": "struct", "fields": [ @@ -610,20 +685,24 @@ } }, { - "name": "CircBuf", + "name": "ClusterHistory", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { "kind": "struct", "fields": [ { - "name": "idx", + "name": "struct_version", "type": "u64" }, { - "name": "isEmpty", + "name": "bump", "type": "u8" }, { - "name": "padding", + "name": "_padding0", "type": { "array": [ "u8", @@ -632,26 +711,40 @@ } }, { - "name": "arr", + "name": "cluster_history_last_update_slot", + "type": "u64" + }, + { + "name": "_padding1", "type": { "array": [ - { - "defined": "ValidatorHistoryEntry" - }, - 512 + "u8", + 232 ] } + }, + { + "name": "history", + "type": { + "defined": { + "name": "CircBufCluster" + } + } } ] } }, { "name": "ClusterHistoryEntry", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { "kind": "struct", "fields": [ { - "name": "totalBlocks", + "name": "total_blocks", "type": "u32" }, { @@ -668,7 +761,7 @@ } }, { - "name": "epochStartTimestamp", + "name": "epoch_start_timestamp", "type": "u64" }, { @@ -684,281 +777,176 @@ } }, { - "name": "CircBufCluster", + "name": "Config", "type": { "kind": "struct", "fields": [ { - "name": "idx", - "type": "u64" + "name": "tip_distribution_program", + "type": "pubkey" }, { - "name": "isEmpty", - "type": "u8" + "name": "admin", + "type": "pubkey" }, { - "name": "padding", - "type": { - "array": [ - "u8", - 7 - ] - } + "name": "oracle_authority", + "type": "pubkey" }, { - "name": "arr", - "type": { - "array": [ - { - "defined": "ClusterHistoryEntry" - }, - 512 - ] - } + "name": "counter", + "type": "u32" + }, + { + "name": "bump", + "type": "u8" } ] } }, { - "name": "CrdsData", - "docs": [ - "CrdsData that defines the different types of items CrdsValues can hold", - "* Merge Strategy - Latest wallclock is picked", - "* LowestSlot index is deprecated" - ], + "name": "ValidatorHistory", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { - "kind": "enum", - "variants": [ - { - "name": "LegacyContactInfo", - "fields": [ - { - "defined": "LegacyContactInfo" - } - ] - }, - { - "name": "Vote" - }, - { - "name": "LowestSlot" - }, + "kind": "struct", + "fields": [ { - "name": "LegacySnapshotHashes" + "name": "struct_version", + "type": "u32" }, { - "name": "AccountsHashes" + "name": "vote_account", + "type": "pubkey" }, { - "name": "EpochSlots" + "name": "index", + "type": "u32" }, { - "name": "LegacyVersion", - "fields": [ - { - "defined": "LegacyVersion" - } - ] + "name": "bump", + "type": "u8" }, { - "name": "Version", - "fields": [ - { - "defined": "Version2" - } - ] + "name": "_padding0", + "type": { + "array": [ + "u8", + 7 + ] + } }, { - "name": "NodeInstance" + "name": "last_ip_timestamp", + "type": "u64" }, { - "name": "DuplicateShred" + "name": "last_version_timestamp", + "type": "u64" }, { - "name": "SnapshotHashes" + "name": "_padding1", + "type": { + "array": [ + "u8", + 232 + ] + } }, { - "name": "ContactInfo", - "fields": [ - { - "defined": "ContactInfo" + "name": "history", + "type": { + "defined": { + "name": "CircBuf" } - ] + } } ] } }, { - "name": "Error", + "name": "ValidatorHistoryEntry", + "serialization": "bytemuck", + "repr": { + "kind": "c" + }, "type": { - "kind": "enum", - "variants": [ + "kind": "struct", + "fields": [ { - "name": "DuplicateIpAddr", - "fields": [ - { - "defined": "IpAddr" - } - ] - }, - { - "name": "DuplicateSocket", - "fields": [ - "u8" - ] - }, - { - "name": "InvalidIpAddrIndex", - "fields": [ - { - "name": "index", - "type": "u8" - }, - { - "name": "numAddrs", - "type": { - "defined": "usize" - } - } - ] - }, - { - "name": "InvalidPort", - "fields": [ - "u16" - ] - }, - { - "name": "InvalidQuicSocket", - "fields": [ - { - "option": { - "defined": "SocketAddr" - } - }, - { - "option": { - "defined": "SocketAddr" - } - } - ] + "name": "activated_stake_lamports", + "type": "u64" }, { - "name": "IpAddrsSaturated" + "name": "epoch", + "type": "u16" }, { - "name": "MulticastIpAddr", - "fields": [ - { - "defined": "IpAddr" - } - ] + "name": "mev_commission", + "type": "u16" }, { - "name": "PortOffsetsOverflow" + "name": "epoch_credits", + "type": "u32" }, { - "name": "SocketNotFound", - "fields": [ - "u8" - ] + "name": "commission", + "type": "u8" }, { - "name": "UnspecifiedIpAddr", - "fields": [ - { - "defined": "IpAddr" - } - ] + "name": "client_type", + "type": "u8" }, { - "name": "UnusedIpAddr", - "fields": [ - { - "defined": "IpAddr" + "name": "version", + "type": { + "defined": { + "name": "ClientVersion" } - ] - } - ] - } - }, - { - "name": "ValidatorHistoryVersion", - "type": { - "kind": "enum", - "variants": [ + } + }, + { + "name": "ip", + "type": { + "array": [ + "u8", + 4 + ] + } + }, + { + "name": "padding0", + "type": "u8" + }, + { + "name": "is_superminority", + "type": "u8" + }, + { + "name": "rank", + "type": "u32" + }, + { + "name": "vote_account_last_update_slot", + "type": "u64" + }, + { + "name": "mev_earned", + "type": "u32" + }, { - "name": "V0" + "name": "padding1", + "type": { + "array": [ + "u8", + 84 + ] + } } ] } } - ], - "errors": [ - { - "code": 6000, - "name": "AccountFullySized", - "msg": "Account already reached proper size, no more allocations allowed" - }, - { - "code": 6001, - "name": "InvalidEpochCredits", - "msg": "Invalid epoch credits, credits must exist and each value must be greater than previous credits" - }, - { - "code": 6002, - "name": "EpochOutOfRange", - "msg": "Epoch is out of range of history" - }, - { - "code": 6003, - "name": "NotSigVerified", - "msg": "Gossip Signature Verification not performed" - }, - { - "code": 6004, - "name": "GossipDataInvalid", - "msg": "Gossip Data Invalid" - }, - { - "code": 6005, - "name": "UnsupportedIpFormat", - "msg": "Unsupported IP Format, only IpAddr::V4 is supported" - }, - { - "code": 6006, - "name": "NotEnoughVotingHistory", - "msg": "Not enough voting history to create account. Minimum 5 epochs required" - }, - { - "code": 6007, - "name": "GossipDataTooOld", - "msg": "Gossip data too old. Data cannot be older than the last recorded timestamp for a field" - }, - { - "code": 6008, - "name": "GossipDataInFuture", - "msg": "Gossip timestamp too far in the future" - }, - { - "code": 6009, - "name": "ArithmeticError", - "msg": "Arithmetic Error (overflow/underflow)" - }, - { - "code": 6010, - "name": "SlotHistoryOutOfDate", - "msg": "Slot history sysvar is not containing expected slots" - }, - { - "code": 6011, - "name": "EpochTooLarge", - "msg": "Epoch larger than 65535, cannot be stored" - }, - { - "code": 6012, - "name": "DuplicateEpoch", - "msg": "Inserting duplicate epoch" - } ] } \ No newline at end of file diff --git a/tests/src/spl_stake_pool_cli.rs b/tests/src/spl_stake_pool_cli.rs index 930989b8..c9643c5a 100644 --- a/tests/src/spl_stake_pool_cli.rs +++ b/tests/src/spl_stake_pool_cli.rs @@ -30,6 +30,8 @@ macro_rules! unique_signers { } type Error = Box; + +#[allow(dead_code)] pub struct CliConfig { pub manager: Keypair, pub staker: Keypair, diff --git a/tests/tests/steward/test_algorithms.rs b/tests/tests/steward/test_algorithms.rs index c5c5ba6e..83e0b464 100644 --- a/tests/tests/steward/test_algorithms.rs +++ b/tests/tests/steward/test_algorithms.rs @@ -1028,7 +1028,7 @@ fn test_increase_stake_calculation() { &state, 0, u64::from(validator_list[0].active_stake_lamports) - minimum_delegation, - 2000 * LAMPORTS_PER_SOL - (state.num_pool_validators as u64 * minimum_delegation), + 2000 * LAMPORTS_PER_SOL - (state.num_pool_validators * minimum_delegation), &validator_list_bigvec, 1002 * LAMPORTS_PER_SOL, minimum_delegation, diff --git a/tests/tests/steward/test_integration.rs b/tests/tests/steward/test_integration.rs index b1a231ad..8e158ef6 100644 --- a/tests/tests/steward/test_integration.rs +++ b/tests/tests/steward/test_integration.rs @@ -80,7 +80,7 @@ async fn test_compute_delegations() { steward_state_account.state.sorted_yield_score_indices[i] = yield_score_vec[i].0 as u16; } - steward_state_account.state.num_pool_validators = MAX_VALIDATORS; + steward_state_account.state.num_pool_validators = MAX_VALIDATORS as u64; steward_state_account.state.state_tag = jito_steward::state::StewardStateEnum::ComputeDelegations; steward_state_account.state.current_epoch = clock.epoch; @@ -176,7 +176,8 @@ async fn test_compute_scores() { fixture.initialize_config(None).await; fixture.initialize_steward_state().await; - let epoch_credits = vec![(0, 1, 0), (1, 2, 1), (2, 3, 2), (3, 4, 3), (4, 5, 4)]; + let epoch_credits: Vec<(u64, u64, u64)> = + vec![(0, 1, 0), (1, 2, 1), (2, 3, 2), (3, 4, 3), (4, 5, 4)]; let vote_account = Pubkey::new_unique(); let validator_history_account = Pubkey::find_program_address( &[ValidatorHistory::SEED, vote_account.as_ref()], @@ -239,7 +240,7 @@ async fn test_compute_scores() { fixture.load_and_deserialize(&fixture.steward_state).await; // Basic state setup - steward_state_account.state.num_pool_validators = MAX_VALIDATORS; + steward_state_account.state.num_pool_validators = MAX_VALIDATORS as u64; steward_state_account.state.state_tag = jito_steward::state::StewardStateEnum::ComputeScores; steward_state_account.state.current_epoch = clock.epoch; steward_state_account.state.next_cycle_epoch = @@ -296,7 +297,7 @@ async fn test_compute_scores() { } .to_account_metas(None), data: jito_steward::instruction::ComputeScore { - validator_list_index: validator_history.index as usize, + validator_list_index: validator_history.index as u64, } .data(), }; @@ -578,7 +579,7 @@ async fn test_compute_instant_unstake() { } .to_account_metas(None), data: jito_steward::instruction::ComputeInstantUnstake { - validator_list_index: validator_history.index as usize, + validator_list_index: validator_history.index as u64, } .data(), }; @@ -676,7 +677,7 @@ async fn test_idle() { steward_state_account.state.state_tag = StewardStateEnum::Idle; steward_state_account.state.next_cycle_epoch = epoch_schedule.first_normal_epoch + 10; steward_state_account.state.current_epoch = epoch_schedule.first_normal_epoch; - steward_state_account.state.num_pool_validators = MAX_VALIDATORS; + steward_state_account.state.num_pool_validators = MAX_VALIDATORS as u64; ctx.borrow_mut().set_account( &fixture.steward_state, @@ -806,7 +807,7 @@ async fn test_rebalance_increase() { steward_config.parameters.stake_deposit_unstake_cap_bps = 0; steward_config.parameters.minimum_voting_epochs = 1; steward_state_account.state.state_tag = StewardStateEnum::Rebalance; - steward_state_account.state.num_pool_validators = MAX_VALIDATORS - 1; + steward_state_account.state.num_pool_validators = MAX_VALIDATORS as u64 - 1; steward_state_account.state.next_cycle_epoch = epoch_schedule.first_normal_epoch + 10; steward_state_account.state.current_epoch = epoch_schedule.first_normal_epoch; @@ -964,7 +965,7 @@ async fn test_rebalance_increase() { } .to_account_metas(None), data: jito_steward::instruction::Rebalance { - validator_list_index: MAX_VALIDATORS - 1, + validator_list_index: MAX_VALIDATORS as u64 - 1, } .data(), }; @@ -1047,7 +1048,7 @@ async fn test_rebalance_decrease() { steward_config.parameters.minimum_voting_epochs = 1; steward_state_account.state.state_tag = StewardStateEnum::Rebalance; - steward_state_account.state.num_pool_validators = MAX_VALIDATORS - 1; + steward_state_account.state.num_pool_validators = MAX_VALIDATORS as u64 - 1; steward_state_account.state.next_cycle_epoch = epoch_schedule.first_normal_epoch + 10; steward_state_account.state.current_epoch = epoch_schedule.first_normal_epoch; @@ -1273,7 +1274,7 @@ async fn test_rebalance_decrease() { } .to_account_metas(None), data: jito_steward::instruction::Rebalance { - validator_list_index: MAX_VALIDATORS - 1, + validator_list_index: MAX_VALIDATORS as u64 - 1, } .data(), }; @@ -1450,7 +1451,7 @@ async fn test_rebalance_other_cases() { } .to_account_metas(None), data: jito_steward::instruction::Rebalance { - validator_list_index: MAX_VALIDATORS - 1, + validator_list_index: MAX_VALIDATORS as u64 - 1, } .data(), }; @@ -1469,7 +1470,7 @@ async fn test_rebalance_other_cases() { fixture.load_and_deserialize(&fixture.steward_state).await; steward_state_account.state.state_tag = StewardStateEnum::Idle; - steward_state_account.state.num_pool_validators = MAX_VALIDATORS; + steward_state_account.state.num_pool_validators = MAX_VALIDATORS as u64; steward_state_account.state.next_cycle_epoch = epoch_schedule.first_normal_epoch + 10; steward_state_account.state.current_epoch = epoch_schedule.first_normal_epoch; steward_config.set_paused(false); diff --git a/tests/tests/steward/test_parameters.rs b/tests/tests/steward/test_parameters.rs index b9861af9..591dce04 100644 --- a/tests/tests/steward/test_parameters.rs +++ b/tests/tests/steward/test_parameters.rs @@ -836,7 +836,7 @@ fn test_compute_score_slot_range() { // Cannot be above slots_per_epoch let new_value = slots_per_epoch + 1; let update_parameters = UpdateParametersArgs { - compute_score_slot_range: Some(new_value as usize), + compute_score_slot_range: Some(new_value), ..UpdateParametersArgs::default() }; let result = _test_parameter(&update_parameters, None, Some(slots_per_epoch), None); diff --git a/tests/tests/steward/test_spl_passthrough.rs b/tests/tests/steward/test_spl_passthrough.rs index 8347119b..a3448572 100644 --- a/tests/tests/steward/test_spl_passthrough.rs +++ b/tests/tests/steward/test_spl_passthrough.rs @@ -98,7 +98,7 @@ async fn _setup_test_steward_state( steward_config.parameters.instant_unstake_cap_bps = 0; steward_config.parameters.stake_deposit_unstake_cap_bps = 0; steward_state_account.state.state_tag = StewardStateEnum::Idle; - steward_state_account.state.num_pool_validators = validators_to_add - 1; + steward_state_account.state.num_pool_validators = validators_to_add as u64 - 1; steward_state_account.state.next_cycle_epoch = epoch_schedule.first_normal_epoch + 10; steward_state_account.state.current_epoch = epoch_schedule.first_normal_epoch; @@ -232,7 +232,7 @@ async fn _set_and_check_preferred_validator( } .to_account_metas(None), data: jito_steward::instruction::SetPreferredValidator { - validator_type: preferred_validator_type.clone(), + validator_type: preferred_validator_type.clone().into(), validator, } .data(), @@ -559,7 +559,7 @@ async fn test_remove_validator_from_pool() { } .to_account_metas(None), data: jito_steward::instruction::RemoveValidatorFromPool { - validator_list_index, + validator_list_index: validator_list_index as u64, } .data(), }; diff --git a/tests/tests/steward/test_state_transitions.rs b/tests/tests/steward/test_state_transitions.rs index c05bc3a9..75e3eea8 100644 --- a/tests/tests/steward/test_state_transitions.rs +++ b/tests/tests/steward/test_state_transitions.rs @@ -338,7 +338,7 @@ pub fn test_rebalance_to_idle() { state.state_tag = StewardStateEnum::Rebalance; - for i in 0..state.num_pool_validators { + for i in 0..state.num_pool_validators as usize { let _ = state.progress.set(i, true); assert!(matches!(state.state_tag, StewardStateEnum::Rebalance)); }