Skip to content

Commit

Permalink
Merge branch 'master' into christian/keeper-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
coachchucksol authored Jun 4, 2024
2 parents 8e16a7a + b853f42 commit 79a3e49
Show file tree
Hide file tree
Showing 11 changed files with 1,128 additions and 72 deletions.
2 changes: 1 addition & 1 deletion programs/steward/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ Administrators can:
| `instant_unstake_epoch_progress` | 0.90 | Point in epoch progress before instant unstake can be computed |
| `instant_unstake_inputs_epoch_progress` | 0.50 | Inputs to “Compute Instant Unstake” need to be updated past this point in epoch progress |
| `num_epochs_between_scoring` | 10 | Cycle length - Number of epochs to run the Monitor->Rebalance loop |
| `minimum_stake_lamports` | 5,000,000,000 | Minimum number of stake lamports for a validator to be considered for the pool |
| `minimum_stake_lamports` | 5,000,000,000,000 (5000 SOL) | Minimum number of stake lamports for a validator to be considered for the pool |
| `minimum_voting_epochs` | 5 | Minimum number of consecutive epochs a validator has to vote before it can be considered for the pool |

## Code and Tests
Expand Down
21 changes: 19 additions & 2 deletions programs/steward/src/instructions/initialize_config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anchor_lang::{prelude::*, solana_program::program::invoke};

use crate::{utils::StakePool, Config, Staker};
use crate::{utils::StakePool, Config, Staker, UpdateParametersArgs};

#[derive(Accounts)]
pub struct InitializeConfig<'info> {
Expand Down Expand Up @@ -39,11 +39,28 @@ pub struct InitializeConfig<'info> {
pub signer: Signer<'info>,
}

pub fn handler(ctx: Context<InitializeConfig>, authority: Pubkey) -> Result<()> {
pub fn handler(
ctx: Context<InitializeConfig>,
authority: Pubkey,
update_parameters_args: &UpdateParametersArgs,
) -> Result<()> {
let mut config = ctx.accounts.config.load_init()?;
config.stake_pool = ctx.accounts.stake_pool.key();
config.authority = authority;

// Set Initial Parameters
let max_slots_in_epoch = EpochSchedule::get()?.slots_per_epoch;
let current_epoch = Clock::get()?.epoch;

let initial_parameters = config.parameters.get_valid_updated_parameters(
update_parameters_args,
current_epoch,
max_slots_in_epoch,
)?;

config.parameters = initial_parameters;

// Set the staker account
ctx.accounts.staker.bump = ctx.bumps.staker;
invoke(
&spl_stake_pool::instruction::set_staker(
Expand Down
12 changes: 10 additions & 2 deletions programs/steward/src/instructions/update_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@ pub fn handler(
ctx: Context<UpdateParameters>,
update_parameters_args: &UpdateParametersArgs,
) -> Result<()> {
let mut parameters = ctx.accounts.config.load_mut()?.parameters;
let mut config = ctx.accounts.config.load_mut()?;
let max_slots_in_epoch = EpochSchedule::get()?.slots_per_epoch;
let current_epoch = Clock::get()?.epoch;
parameters.update(update_parameters_args, current_epoch, max_slots_in_epoch)?;

let new_parameters = config.parameters.get_valid_updated_parameters(
update_parameters_args,
current_epoch,
max_slots_in_epoch,
)?;

config.parameters = new_parameters;

Ok(())
}
8 changes: 6 additions & 2 deletions programs/steward/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ pub mod steward {

// Initializes Config and Staker accounts. Must be called before any other instruction
// Requires Pool to be initialized
pub fn initialize_config(ctx: Context<InitializeConfig>, authority: Pubkey) -> Result<()> {
instructions::initialize_config::handler(ctx, authority)
pub fn initialize_config(
ctx: Context<InitializeConfig>,
authority: Pubkey,
update_parameters_args: UpdateParametersArgs,
) -> Result<()> {
instructions::initialize_config::handler(ctx, authority, &update_parameters_args)
}

/// Creates state account
Expand Down
17 changes: 9 additions & 8 deletions programs/steward/src/state/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
errors::StewardError,
};

#[derive(BorshSerialize, BorshDeserialize, Debug, Default)]
#[derive(BorshSerialize, BorshDeserialize, Debug, Default, Clone)]
pub struct UpdateParametersArgs {
// Scoring parameters
pub mev_commission_range: Option<u16>,
Expand Down Expand Up @@ -101,13 +101,13 @@ pub struct Parameters {
}

impl Parameters {
/// Update parameters that are present in the args struct and validates them
pub fn update(
&mut self,
/// Merges the updated parameters with the current parameters and validates them
pub fn get_valid_updated_parameters(
self,
args: &UpdateParametersArgs,
current_epoch: u64,
slots_per_epoch: u64,
) -> Result<()> {
) -> Result<Parameters> {
// Updates parameters and validates them
let UpdateParametersArgs {
mev_commission_range,
Expand All @@ -130,7 +130,7 @@ impl Parameters {
minimum_voting_epochs,
} = *args;

let mut new_parameters = *self;
let mut new_parameters = self;

if let Some(mev_commission_range) = mev_commission_range {
new_parameters.mev_commission_range = mev_commission_range;
Expand Down Expand Up @@ -209,9 +209,10 @@ impl Parameters {
new_parameters.minimum_voting_epochs = minimum_voting_epochs;
}

// Validation will throw an error if any of the parameters are invalid
new_parameters.validate(current_epoch, slots_per_epoch)?;
*self = new_parameters;
Ok(())

Ok(new_parameters)
}

/// Validate reasonable bounds on parameters
Expand Down
35 changes: 34 additions & 1 deletion tests/src/steward_fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use jito_steward::{
constants::{MAX_VALIDATORS, SORTED_INDEX_DEFAULT, STAKE_POOL_WITHDRAW_SEED},
utils::StakePool,
Config, Delegation, Parameters, Staker, StewardState, StewardStateAccount, StewardStateEnum,
UpdateParametersArgs,
};
use solana_program_test::*;
use solana_sdk::{
Expand Down Expand Up @@ -231,7 +232,29 @@ impl TestFixture {
}
}

pub async fn initialize_config(&self) {
pub async fn initialize_config(&self, parameters: Option<UpdateParametersArgs>) {
// Default parameters from JIP
let update_parameters_args = parameters.unwrap_or(UpdateParametersArgs {
mev_commission_range: Some(0), // Set to pass validation, where epochs starts at 0
epoch_credits_range: Some(0), // Set to pass validation, where epochs starts at 0
commission_range: Some(0), // Set to pass validation, where epochs starts at 0
scoring_delinquency_threshold_ratio: Some(0.85),
instant_unstake_delinquency_threshold_ratio: Some(0.70),
mev_commission_bps_threshold: Some(1000),
commission_threshold: Some(5),
historical_commission_threshold: Some(50),
num_delegation_validators: Some(200),
scoring_unstake_cap_bps: Some(750),
instant_unstake_cap_bps: Some(10),
stake_deposit_unstake_cap_bps: Some(10),
instant_unstake_epoch_progress: Some(0.90),
compute_score_slot_range: Some(1000),
instant_unstake_inputs_epoch_progress: Some(0.50),
num_epochs_between_scoring: Some(10),
minimum_stake_lamports: Some(5_000_000_000),
minimum_voting_epochs: Some(0), // Set to pass validation, where epochs starts at 0
});

let instruction = Instruction {
program_id: jito_steward::id(),
accounts: jito_steward::accounts::InitializeConfig {
Expand All @@ -245,6 +268,7 @@ impl TestFixture {
.to_account_metas(None),
data: jito_steward::instruction::InitializeConfig {
authority: self.keypair.pubkey(),
update_parameters_args,
}
.data(),
};
Expand Down Expand Up @@ -579,6 +603,15 @@ pub fn new_vote_account(
}
}

pub fn closed_vote_account() -> Account {
Account {
lamports: 0,
data: vec![0; VoteState::size_of()],
owner: anchor_lang::system_program::ID, // Close the account
..Account::default()
}
}

// TODO write a function to serialize any account with T: AnchorSerialize
pub fn serialized_validator_list_account(
validator_list: ValidatorList,
Expand Down
1 change: 1 addition & 0 deletions tests/tests/steward/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod test_algorithms;
mod test_integration;
mod test_parameters;
mod test_spl_passthrough;
mod test_state_methods;
mod test_state_transitions;
Expand Down
38 changes: 30 additions & 8 deletions tests/tests/steward/test_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use anchor_lang::{
use jito_steward::{
constants::{MAX_VALIDATORS, SORTED_INDEX_DEFAULT},
utils::{StakePool, ValidatorList},
Config, Delegation, StewardStateAccount, StewardStateEnum,
Config, Delegation, StewardStateAccount, StewardStateEnum, UpdateParametersArgs,
};
use solana_program_test::*;
use solana_sdk::{
Expand Down Expand Up @@ -36,7 +36,7 @@ async fn test_compute_delegations() {
let fixture = TestFixture::new().await;
let ctx = &fixture.ctx;
fixture.initialize_stake_pool().await;
fixture.initialize_config().await;
fixture.initialize_config(None).await;
fixture.initialize_steward_state().await;

let clock: Clock = fixture.get_sysvar().await;
Expand Down Expand Up @@ -173,7 +173,7 @@ async fn test_compute_scores() {
let fixture = TestFixture::new().await;
let ctx = &fixture.ctx;
fixture.initialize_stake_pool().await;
fixture.initialize_config().await;
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)];
Expand Down Expand Up @@ -422,7 +422,28 @@ async fn test_compute_instant_unstake() {
let fixture = TestFixture::new().await;
let ctx = &fixture.ctx;
fixture.initialize_stake_pool().await;
fixture.initialize_config().await;
fixture
.initialize_config(Some(UpdateParametersArgs {
mev_commission_range: Some(0), // Set to pass validation, where epochs starts at 0
epoch_credits_range: Some(0), // Set to pass validation, where epochs starts at 0
commission_range: Some(0), // Set to pass validation, where epochs starts at 0
scoring_delinquency_threshold_ratio: Some(0.85),
instant_unstake_delinquency_threshold_ratio: Some(0.70),
mev_commission_bps_threshold: Some(1000),
commission_threshold: Some(5),
historical_commission_threshold: Some(50),
num_delegation_validators: Some(200),
scoring_unstake_cap_bps: Some(750),
instant_unstake_cap_bps: Some(10),
stake_deposit_unstake_cap_bps: Some(10),
instant_unstake_epoch_progress: Some(0.0), // So that we don't have to increase the slots
compute_score_slot_range: Some(1000),
instant_unstake_inputs_epoch_progress: Some(0.50),
num_epochs_between_scoring: Some(10),
minimum_stake_lamports: Some(5_000_000_000),
minimum_voting_epochs: Some(0), // Set to pass validation, where epochs starts at 0
}))
.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)];
Expand All @@ -435,6 +456,7 @@ async fn test_compute_instant_unstake() {

let clock: Clock = fixture.get_sysvar().await;
let epoch_schedule: EpochSchedule = fixture.get_sysvar().await;

fixture.ctx.borrow_mut().set_account(
&vote_account,
&new_vote_account(Pubkey::new_unique(), vote_account, 100, Some(epoch_credits)).into(),
Expand Down Expand Up @@ -635,7 +657,7 @@ async fn test_idle() {
let fixture = TestFixture::new().await;
let ctx = &fixture.ctx;
fixture.initialize_stake_pool().await;
fixture.initialize_config().await;
fixture.initialize_config(None).await;
fixture.initialize_steward_state().await;

let clock: Clock = fixture.get_sysvar().await;
Expand Down Expand Up @@ -771,7 +793,7 @@ async fn test_rebalance_increase() {
.advance_num_epochs(epoch_schedule.first_normal_epoch - clock.epoch, 10)
.await;
fixture.initialize_stake_pool().await;
fixture.initialize_config().await;
fixture.initialize_config(None).await;
fixture.initialize_steward_state().await;

let mut steward_config: Config = fixture
Expand Down Expand Up @@ -1009,7 +1031,7 @@ async fn test_rebalance_decrease() {
.advance_num_epochs(epoch_schedule.first_normal_epoch - clock.epoch, 10)
.await;
fixture.initialize_stake_pool().await;
fixture.initialize_config().await;
fixture.initialize_config(None).await;
fixture.initialize_steward_state().await;

let mut steward_config: Config = fixture
Expand Down Expand Up @@ -1311,7 +1333,7 @@ async fn test_rebalance_other_cases() {
.advance_num_epochs(epoch_schedule.first_normal_epoch - clock.epoch, 10)
.await;
fixture.initialize_stake_pool().await;
fixture.initialize_config().await;
fixture.initialize_config(None).await;
fixture.initialize_steward_state().await;

let mut steward_config: Config = fixture
Expand Down
Loading

0 comments on commit 79a3e49

Please sign in to comment.