Skip to content

Commit

Permalink
FIX: Avoid MAX CU during route ixs (#32)
Browse files Browse the repository at this point in the history
+ route ix's now take `max_iterations` as a parameter to avoid max CU -
they will pick up where they left off
+ large test to test max values
  • Loading branch information
coachchucksol authored Dec 22, 2024
1 parent 59e600a commit fe47f04
Show file tree
Hide file tree
Showing 31 changed files with 810 additions and 139 deletions.
10 changes: 10 additions & 0 deletions clients/js/jito_tip_router/accounts/baseRewardRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
getArrayEncoder,
getStructDecoder,
getStructEncoder,
getU16Decoder,
getU16Encoder,
getU64Decoder,
getU64Encoder,
getU8Decoder,
Expand Down Expand Up @@ -55,6 +57,8 @@ export type BaseRewardRouter = {
rewardPool: bigint;
rewardsProcessed: bigint;
reserved: Array<number>;
lastNcnGroupIndex: number;
lastVoteIndex: number;
baseFeeGroupRewards: Array<BaseRewardRouterRewards>;
ncnFeeGroupRewards: Array<BaseRewardRouterRewards>;
ncnFeeGroupRewardRoutes: Array<NcnRewardRoute>;
Expand All @@ -70,6 +74,8 @@ export type BaseRewardRouterArgs = {
rewardPool: number | bigint;
rewardsProcessed: number | bigint;
reserved: Array<number>;
lastNcnGroupIndex: number;
lastVoteIndex: number;
baseFeeGroupRewards: Array<BaseRewardRouterRewardsArgs>;
ncnFeeGroupRewards: Array<BaseRewardRouterRewardsArgs>;
ncnFeeGroupRewardRoutes: Array<NcnRewardRouteArgs>;
Expand All @@ -86,6 +92,8 @@ export function getBaseRewardRouterEncoder(): Encoder<BaseRewardRouterArgs> {
['rewardPool', getU64Encoder()],
['rewardsProcessed', getU64Encoder()],
['reserved', getArrayEncoder(getU8Encoder(), { size: 128 })],
['lastNcnGroupIndex', getU8Encoder()],
['lastVoteIndex', getU16Encoder()],
[
'baseFeeGroupRewards',
getArrayEncoder(getBaseRewardRouterRewardsEncoder(), { size: 8 }),
Expand All @@ -112,6 +120,8 @@ export function getBaseRewardRouterDecoder(): Decoder<BaseRewardRouter> {
['rewardPool', getU64Decoder()],
['rewardsProcessed', getU64Decoder()],
['reserved', getArrayDecoder(getU8Decoder(), { size: 128 })],
['lastNcnGroupIndex', getU8Decoder()],
['lastVoteIndex', getU16Decoder()],
[
'baseFeeGroupRewards',
getArrayDecoder(getBaseRewardRouterRewardsDecoder(), { size: 8 }),
Expand Down
10 changes: 10 additions & 0 deletions clients/js/jito_tip_router/accounts/ncnRewardRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
getArrayEncoder,
getStructDecoder,
getStructEncoder,
getU16Decoder,
getU16Encoder,
getU64Decoder,
getU64Encoder,
getU8Decoder,
Expand Down Expand Up @@ -58,6 +60,8 @@ export type NcnRewardRouter = {
rewardsProcessed: bigint;
operatorRewards: bigint;
reserved: Array<number>;
lastRewardsToProcess: bigint;
lastVaultOperatorDelegationIndex: number;
vaultRewardRoutes: Array<VaultRewardRoute>;
};

Expand All @@ -74,6 +78,8 @@ export type NcnRewardRouterArgs = {
rewardsProcessed: number | bigint;
operatorRewards: number | bigint;
reserved: Array<number>;
lastRewardsToProcess: number | bigint;
lastVaultOperatorDelegationIndex: number;
vaultRewardRoutes: Array<VaultRewardRouteArgs>;
};

Expand All @@ -91,6 +97,8 @@ export function getNcnRewardRouterEncoder(): Encoder<NcnRewardRouterArgs> {
['rewardsProcessed', getU64Encoder()],
['operatorRewards', getU64Encoder()],
['reserved', getArrayEncoder(getU8Encoder(), { size: 128 })],
['lastRewardsToProcess', getU64Encoder()],
['lastVaultOperatorDelegationIndex', getU16Encoder()],
[
'vaultRewardRoutes',
getArrayEncoder(getVaultRewardRouteEncoder(), { size: 64 }),
Expand All @@ -112,6 +120,8 @@ export function getNcnRewardRouterDecoder(): Decoder<NcnRewardRouter> {
['rewardsProcessed', getU64Decoder()],
['operatorRewards', getU64Decoder()],
['reserved', getArrayDecoder(getU8Decoder(), { size: 128 })],
['lastRewardsToProcess', getU64Decoder()],
['lastVaultOperatorDelegationIndex', getU16Decoder()],
[
'vaultRewardRoutes',
getArrayDecoder(getVaultRewardRouteDecoder(), { size: 64 }),
Expand Down
8 changes: 6 additions & 2 deletions clients/js/jito_tip_router/errors/jitoTipRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,12 @@ export const JITO_TIP_ROUTER_ERROR__BAD_SWITCHBOARD_VALUE = 0x223a; // 8762
export const JITO_TIP_ROUTER_ERROR__STALE_SWITCHBOARD_FEED = 0x223b; // 8763
/** NoFeedWeightOrSwitchboardFeed: Weight entry needs either a feed or a no feed weight */
export const JITO_TIP_ROUTER_ERROR__NO_FEED_WEIGHT_OR_SWITCHBOARD_FEED = 0x223c; // 8764
/** RouterStillRouting: Router still routing */
export const JITO_TIP_ROUTER_ERROR__ROUTER_STILL_ROUTING = 0x223d; // 8765
/** InvalidEpochsBeforeStall: Invalid epochs before stall */
export const JITO_TIP_ROUTER_ERROR__INVALID_EPOCHS_BEFORE_STALL = 0x223d; // 8765
export const JITO_TIP_ROUTER_ERROR__INVALID_EPOCHS_BEFORE_STALL = 0x223e; // 8766
/** InvalidSlotsAfterConsensus: Invalid slots after consensus */
export const JITO_TIP_ROUTER_ERROR__INVALID_SLOTS_AFTER_CONSENSUS = 0x223e; // 8766
export const JITO_TIP_ROUTER_ERROR__INVALID_SLOTS_AFTER_CONSENSUS = 0x223f; // 8767

export type JitoTipRouterError =
| typeof JITO_TIP_ROUTER_ERROR__ARITHMETIC_FLOOR_ERROR
Expand Down Expand Up @@ -211,6 +213,7 @@ export type JitoTipRouterError =
| typeof JITO_TIP_ROUTER_ERROR__OPERATOR_REWARD_NOT_FOUND
| typeof JITO_TIP_ROUTER_ERROR__OPERATOR_VOTES_FULL
| typeof JITO_TIP_ROUTER_ERROR__REGISTRY_NOT_INITIALIZED
| typeof JITO_TIP_ROUTER_ERROR__ROUTER_STILL_ROUTING
| typeof JITO_TIP_ROUTER_ERROR__STALE_SWITCHBOARD_FEED
| typeof JITO_TIP_ROUTER_ERROR__SWITCHBOARD_NOT_REGISTERED
| typeof JITO_TIP_ROUTER_ERROR__TABLE_NOT_INITIALIZED
Expand Down Expand Up @@ -287,6 +290,7 @@ if (process.env.NODE_ENV !== 'production') {
[JITO_TIP_ROUTER_ERROR__OPERATOR_REWARD_NOT_FOUND]: `Operator Reward not found`,
[JITO_TIP_ROUTER_ERROR__OPERATOR_VOTES_FULL]: `Operator votes full`,
[JITO_TIP_ROUTER_ERROR__REGISTRY_NOT_INITIALIZED]: `Registry not initialized`,
[JITO_TIP_ROUTER_ERROR__ROUTER_STILL_ROUTING]: `Router still routing`,
[JITO_TIP_ROUTER_ERROR__STALE_SWITCHBOARD_FEED]: `Stale switchboard feed`,
[JITO_TIP_ROUTER_ERROR__SWITCHBOARD_NOT_REGISTERED]: `Switchboard not registered`,
[JITO_TIP_ROUTER_ERROR__TABLE_NOT_INITIALIZED]: `Table not initialized`,
Expand Down
11 changes: 10 additions & 1 deletion clients/js/jito_tip_router/instructions/routeBaseRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
combineCodec,
getStructDecoder,
getStructEncoder,
getU16Decoder,
getU16Encoder,
getU64Decoder,
getU64Encoder,
getU8Decoder,
Expand Down Expand Up @@ -74,15 +76,20 @@ export type RouteBaseRewardsInstruction<

export type RouteBaseRewardsInstructionData = {
discriminator: number;
maxIterations: number;
epoch: bigint;
};

export type RouteBaseRewardsInstructionDataArgs = { epoch: number | bigint };
export type RouteBaseRewardsInstructionDataArgs = {
maxIterations: number;
epoch: number | bigint;
};

export function getRouteBaseRewardsInstructionDataEncoder(): Encoder<RouteBaseRewardsInstructionDataArgs> {
return transformEncoder(
getStructEncoder([
['discriminator', getU8Encoder()],
['maxIterations', getU16Encoder()],
['epoch', getU64Encoder()],
]),
(value) => ({ ...value, discriminator: ROUTE_BASE_REWARDS_DISCRIMINATOR })
Expand All @@ -92,6 +99,7 @@ export function getRouteBaseRewardsInstructionDataEncoder(): Encoder<RouteBaseRe
export function getRouteBaseRewardsInstructionDataDecoder(): Decoder<RouteBaseRewardsInstructionData> {
return getStructDecoder([
['discriminator', getU8Decoder()],
['maxIterations', getU16Decoder()],
['epoch', getU64Decoder()],
]);
}
Expand Down Expand Up @@ -122,6 +130,7 @@ export type RouteBaseRewardsInput<
baseRewardRouter: Address<TAccountBaseRewardRouter>;
baseRewardReceiver: Address<TAccountBaseRewardReceiver>;
restakingProgram: Address<TAccountRestakingProgram>;
maxIterations: RouteBaseRewardsInstructionDataArgs['maxIterations'];
epoch: RouteBaseRewardsInstructionDataArgs['epoch'];
};

Expand Down
7 changes: 7 additions & 0 deletions clients/js/jito_tip_router/instructions/routeNcnRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
combineCodec,
getStructDecoder,
getStructEncoder,
getU16Decoder,
getU16Encoder,
getU64Decoder,
getU64Encoder,
getU8Decoder,
Expand Down Expand Up @@ -75,11 +77,13 @@ export type RouteNcnRewardsInstruction<
export type RouteNcnRewardsInstructionData = {
discriminator: number;
ncnFeeGroup: number;
maxIterations: number;
epoch: bigint;
};

export type RouteNcnRewardsInstructionDataArgs = {
ncnFeeGroup: number;
maxIterations: number;
epoch: number | bigint;
};

Expand All @@ -88,6 +92,7 @@ export function getRouteNcnRewardsInstructionDataEncoder(): Encoder<RouteNcnRewa
getStructEncoder([
['discriminator', getU8Encoder()],
['ncnFeeGroup', getU8Encoder()],
['maxIterations', getU16Encoder()],
['epoch', getU64Encoder()],
]),
(value) => ({ ...value, discriminator: ROUTE_NCN_REWARDS_DISCRIMINATOR })
Expand All @@ -98,6 +103,7 @@ export function getRouteNcnRewardsInstructionDataDecoder(): Decoder<RouteNcnRewa
return getStructDecoder([
['discriminator', getU8Decoder()],
['ncnFeeGroup', getU8Decoder()],
['maxIterations', getU16Decoder()],
['epoch', getU64Decoder()],
]);
}
Expand Down Expand Up @@ -129,6 +135,7 @@ export type RouteNcnRewardsInput<
ncnRewardReceiver: Address<TAccountNcnRewardReceiver>;
restakingProgram: Address<TAccountRestakingProgram>;
ncnFeeGroup: RouteNcnRewardsInstructionDataArgs['ncnFeeGroup'];
maxIterations: RouteNcnRewardsInstructionDataArgs['maxIterations'];
epoch: RouteNcnRewardsInstructionDataArgs['epoch'];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct BaseRewardRouter {
pub rewards_processed: u64,
#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]
pub reserved: [u8; 128],
pub last_ncn_group_index: u8,
pub last_vote_index: u16,
pub base_fee_group_rewards: [BaseRewardRouterRewards; 8],
pub ncn_fee_group_rewards: [BaseRewardRouterRewards; 8],
#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub struct NcnRewardRouter {
pub operator_rewards: u64,
#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]
pub reserved: [u8; 128],
pub last_rewards_to_process: u64,
pub last_vault_operator_delegation_index: u16,
#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]
pub vault_reward_routes: [VaultRewardRoute; 64],
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,15 @@ pub enum JitoTipRouterError {
/// 8764 - Weight entry needs either a feed or a no feed weight
#[error("Weight entry needs either a feed or a no feed weight")]
NoFeedWeightOrSwitchboardFeed = 0x223C,
/// 8765 - Invalid epochs before stall
/// 8765 - Router still routing
#[error("Router still routing")]
RouterStillRouting = 0x223D,
/// 8766 - Invalid epochs before stall
#[error("Invalid epochs before stall")]
InvalidEpochsBeforeStall = 0x223D,
/// 8766 - Invalid slots after consensus
InvalidEpochsBeforeStall = 0x223E,
/// 8767 - Invalid slots after consensus
#[error("Invalid slots after consensus")]
InvalidSlotsAfterConsensus = 0x223E,
InvalidSlotsAfterConsensus = 0x223F,
}

impl solana_program::program_error::PrintProgramError for JitoTipRouterError {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ impl Default for RouteBaseRewardsInstructionData {
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RouteBaseRewardsInstructionArgs {
pub max_iterations: u16,
pub epoch: u64,
}

Expand All @@ -120,6 +121,7 @@ pub struct RouteBaseRewardsBuilder {
base_reward_router: Option<solana_program::pubkey::Pubkey>,
base_reward_receiver: Option<solana_program::pubkey::Pubkey>,
restaking_program: Option<solana_program::pubkey::Pubkey>,
max_iterations: Option<u16>,
epoch: Option<u64>,
__remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
}
Expand Down Expand Up @@ -176,6 +178,11 @@ impl RouteBaseRewardsBuilder {
self
}
#[inline(always)]
pub fn max_iterations(&mut self, max_iterations: u16) -> &mut Self {
self.max_iterations = Some(max_iterations);
self
}
#[inline(always)]
pub fn epoch(&mut self, epoch: u64) -> &mut Self {
self.epoch = Some(epoch);
self
Expand Down Expand Up @@ -216,6 +223,10 @@ impl RouteBaseRewardsBuilder {
.expect("restaking_program is not set"),
};
let args = RouteBaseRewardsInstructionArgs {
max_iterations: self
.max_iterations
.clone()
.expect("max_iterations is not set"),
epoch: self.epoch.clone().expect("epoch is not set"),
};

Expand Down Expand Up @@ -406,6 +417,7 @@ impl<'a, 'b> RouteBaseRewardsCpiBuilder<'a, 'b> {
base_reward_router: None,
base_reward_receiver: None,
restaking_program: None,
max_iterations: None,
epoch: None,
__remaining_accounts: Vec::new(),
});
Expand Down Expand Up @@ -465,6 +477,11 @@ impl<'a, 'b> RouteBaseRewardsCpiBuilder<'a, 'b> {
self
}
#[inline(always)]
pub fn max_iterations(&mut self, max_iterations: u16) -> &mut Self {
self.instruction.max_iterations = Some(max_iterations);
self
}
#[inline(always)]
pub fn epoch(&mut self, epoch: u64) -> &mut Self {
self.instruction.epoch = Some(epoch);
self
Expand Down Expand Up @@ -511,6 +528,11 @@ impl<'a, 'b> RouteBaseRewardsCpiBuilder<'a, 'b> {
signers_seeds: &[&[&[u8]]],
) -> solana_program::entrypoint::ProgramResult {
let args = RouteBaseRewardsInstructionArgs {
max_iterations: self
.instruction
.max_iterations
.clone()
.expect("max_iterations is not set"),
epoch: self.instruction.epoch.clone().expect("epoch is not set"),
};
let instruction = RouteBaseRewardsCpi {
Expand Down Expand Up @@ -563,6 +585,7 @@ struct RouteBaseRewardsCpiBuilderInstruction<'a, 'b> {
base_reward_router: Option<&'b solana_program::account_info::AccountInfo<'a>>,
base_reward_receiver: Option<&'b solana_program::account_info::AccountInfo<'a>>,
restaking_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
max_iterations: Option<u16>,
epoch: Option<u64>,
/// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`.
__remaining_accounts: Vec<(
Expand Down
Loading

0 comments on commit fe47f04

Please sign in to comment.