Skip to content

Commit

Permalink
Stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
ebatsell committed Nov 5, 2024
1 parent ef3d216 commit 3bdc75a
Show file tree
Hide file tree
Showing 18 changed files with 745 additions and 15 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions clients/js/jito_tip_router/errors/jitoTipRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ export const JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN = 0x2200; // 87
export const JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES = 0x2201; // 8705
/** FeeCapExceeded: Fee cap exceeded */
export const JITO_TIP_ROUTER_ERROR__FEE_CAP_EXCEEDED = 0x2300; // 8960
/** IncorrectNcnAdmin: Incorrect NCN Admin */
export const JITO_TIP_ROUTER_ERROR__INCORRECT_NCN_ADMIN = 0x2400; // 9216
/** IncorrectNcn: Incorrect NCN */
export const JITO_TIP_ROUTER_ERROR__INCORRECT_NCN = 0x2401; // 9217

export type JitoTipRouterError =
| typeof JITO_TIP_ROUTER_ERROR__ARITHMETIC_OVERFLOW
| typeof JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES
| typeof JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO
| typeof JITO_TIP_ROUTER_ERROR__FEE_CAP_EXCEEDED
| typeof JITO_TIP_ROUTER_ERROR__INCORRECT_NCN
| typeof JITO_TIP_ROUTER_ERROR__INCORRECT_NCN_ADMIN
| typeof JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN
| typeof JITO_TIP_ROUTER_ERROR__MODULO_OVERFLOW
| typeof JITO_TIP_ROUTER_ERROR__NO_MORE_TABLE_SLOTS;
Expand All @@ -45,6 +51,8 @@ if (process.env.NODE_ENV !== 'production') {
[JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES]: `Cannnot create future weight tables`,
[JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO]: `Zero in the denominator`,
[JITO_TIP_ROUTER_ERROR__FEE_CAP_EXCEEDED]: `Fee cap exceeded`,
[JITO_TIP_ROUTER_ERROR__INCORRECT_NCN]: `Incorrect NCN`,
[JITO_TIP_ROUTER_ERROR__INCORRECT_NCN_ADMIN]: `Incorrect NCN Admin`,
[JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN]: `Incorrect weight table admin`,
[JITO_TIP_ROUTER_ERROR__MODULO_OVERFLOW]: `Modulo Overflow`,
[JITO_TIP_ROUTER_ERROR__NO_MORE_TABLE_SLOTS]: `No more table slots available`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ pub enum JitoTipRouterError {
/// 8960 - Fee cap exceeded
#[error("Fee cap exceeded")]
FeeCapExceeded = 0x2300,
/// 9216 - Incorrect NCN Admin
#[error("Incorrect NCN Admin")]
IncorrectNcnAdmin = 0x2400,
/// 9217 - Incorrect NCN
#[error("Incorrect NCN")]
IncorrectNcn = 0x2401,
}

impl solana_program::program_error::PrintProgramError for JitoTipRouterError {
Expand Down
4 changes: 4 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ pub enum TipRouterError {
CannotCreateFutureWeightTables = 0x2201,
#[error("Fee cap exceeded")]
FeeCapExceeded = 0x2300,
#[error("Incorrect NCN Admin")]
IncorrectNcnAdmin = 0x2400,
#[error("Incorrect NCN")]
IncorrectNcn = 0x2401,
}

impl<T> DecodeError<T> for TipRouterError {
Expand Down
36 changes: 27 additions & 9 deletions core/src/ncn_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ pub struct Fees {
}

impl Fees {
pub fn new(
pub const fn new(
wallet: Pubkey,
dao_fee_share_bps: u64,
ncn_fee_share_bps: u64,
Expand Down Expand Up @@ -160,21 +160,39 @@ impl Fees {
}
}

pub fn block_engine_fee(&self, current_epoch: u64) -> u64 {
pub const fn block_engine_fee(&self, current_epoch: u64) -> u64 {
self.current_fee(current_epoch).block_engine_fee_bps
}

pub fn dao_fee(&self, current_epoch: u64) -> u64 {
// TODO adjust based on block engine fee
self.current_fee(current_epoch).dao_share_bps
/// Calculate fee as a portion of remaining BPS after block engine fee
/// new_fee = dao_fee_bps / ((10000 - block_engine_fee_bps) / 10000)
/// = dao_fee_bps * 10000 / (10000 - block_engine_fee_bps)
pub fn dao_fee(&self, current_epoch: u64) -> Result<u64, TipRouterError> {
let fee = self.current_fee(current_epoch);
let remaining_bps = MAX_FEE_BPS
.checked_sub(fee.block_engine_fee_bps)
.ok_or(TipRouterError::ArithmeticOverflow)?;
fee.dao_share_bps
.checked_mul(MAX_FEE_BPS)
.and_then(|x| x.checked_div(remaining_bps))
.ok_or(TipRouterError::ArithmeticOverflow)
}

pub fn ncn_fee(&self, current_epoch: u64) -> u64 {
// TODO adjust based on block engine fee
self.current_fee(current_epoch).ncn_share_bps
/// Calculate fee as a portion of remaining BPS after block engine fee
/// new_fee = ncn_fee_bps / ((10000 - block_engine_fee_bps) / 10000)
/// = ncn_fee_bps * 10000 / (10000 - block_engine_fee_bps)
pub fn ncn_fee(&self, current_epoch: u64) -> Result<u64, TipRouterError> {
let fee = self.current_fee(current_epoch);
let remaining_bps = MAX_FEE_BPS
.checked_sub(fee.block_engine_fee_bps)
.ok_or(TipRouterError::ArithmeticOverflow)?;
fee.ncn_share_bps
.checked_mul(MAX_FEE_BPS)
.and_then(|x| x.checked_div(remaining_bps))
.ok_or(TipRouterError::ArithmeticOverflow)
}

pub fn fee_wallet(&self, current_epoch: u64) -> Pubkey {
pub const fn fee_wallet(&self, current_epoch: u64) -> Pubkey {
self.current_fee(current_epoch).wallet
}

Expand Down
10 changes: 10 additions & 0 deletions idl/jito_tip_router.json
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,16 @@
"code": 8960,
"name": "FeeCapExceeded",
"msg": "Fee cap exceeded"
},
{
"code": 9216,
"name": "IncorrectNcnAdmin",
"msg": "Incorrect NCN Admin"
},
{
"code": 9217,
"name": "IncorrectNcn",
"msg": "Incorrect NCN"
}
],
"metadata": {
Expand Down
2 changes: 2 additions & 0 deletions integration_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jito-jsm-core = { workspace = true }
jito-restaking-core = { workspace = true }
jito-restaking-program = { workspace = true }
jito-restaking-sdk = { workspace = true }
jito-tip-router-core = { workspace = true }
jito-tip-router-program = { workspace = true }
jito-vault-core = { workspace = true }
jito-vault-program = { workspace = true }
jito-vault-sdk = { workspace = true }
Expand Down
42 changes: 42 additions & 0 deletions integration_tests/tests/fixtures/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use solana_program::{instruction::InstructionError, program_error::ProgramError};
use solana_program_test::BanksClientError;
use solana_sdk::transaction::TransactionError;
use thiserror::Error;

pub mod restaking_client;
pub mod test_builder;
pub mod tip_router_client;
pub mod vault_client;

pub type TestResult<T> = Result<T, TestError>;

#[derive(Error, Debug)]
pub enum TestError {
#[error(transparent)]
BanksClientError(#[from] BanksClientError),
#[error(transparent)]
ProgramError(#[from] ProgramError),
}

impl TestError {
pub fn to_transaction_error(&self) -> Option<TransactionError> {
match self {
TestError::BanksClientError(e) => match e {
BanksClientError::TransactionError(e) => Some(e.clone()),
BanksClientError::SimulationError { err, .. } => Some(err.clone()),
_ => None,
},
TestError::ProgramError(_) => None,
}
}
}

#[inline(always)]
#[track_caller]
pub fn assert_ix_error<T>(test_error: Result<T, TestError>, ix_error: InstructionError) {
assert!(test_error.is_err());
assert_eq!(
test_error.err().unwrap().to_transaction_error().unwrap(),
TransactionError::InstructionError(0, ix_error)
);
}
132 changes: 132 additions & 0 deletions integration_tests/tests/fixtures/restaking_client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use jito_restaking_core::{config::Config, ncn::Ncn};
use jito_restaking_sdk::sdk::{initialize_config, initialize_ncn};
use solana_program_test::BanksClient;
use solana_sdk::{
commitment_config::CommitmentLevel, native_token::sol_to_lamports, pubkey::Pubkey,
signature::Keypair, signer::Signer, system_instruction::transfer, transaction::Transaction,
};

use super::TestResult;

#[derive(Debug)]
pub struct NcnRoot {
pub ncn_pubkey: Pubkey,
pub ncn_admin: Keypair,
}

pub struct RestakingProgramClient {
banks_client: BanksClient,
payer: Keypair,
}

impl RestakingProgramClient {
pub const fn new(banks_client: BanksClient, payer: Keypair) -> Self {
Self {
banks_client,
payer,
}
}

pub async fn process_transaction(&mut self, tx: &Transaction) -> TestResult<()> {
self.banks_client
.process_transaction_with_preflight_and_commitment(
tx.clone(),
CommitmentLevel::Processed,
)
.await?;
Ok(())
}

pub async fn _airdrop(&mut self, to: &Pubkey, sol: f64) -> TestResult<()> {
let blockhash = self.banks_client.get_latest_blockhash().await?;
self.banks_client
.process_transaction_with_preflight_and_commitment(
Transaction::new_signed_with_payer(
&[transfer(&self.payer.pubkey(), to, sol_to_lamports(sol))],
Some(&self.payer.pubkey()),
&[&self.payer],
blockhash,
),
CommitmentLevel::Processed,
)
.await?;
Ok(())
}

pub async fn do_initialize_config(&mut self) -> TestResult<Keypair> {
let restaking_config_pubkey = Config::find_program_address(&jito_restaking_program::id()).0;
let restaking_config_admin = Keypair::new();

self._airdrop(&restaking_config_admin.pubkey(), 1.0).await?;
self.initialize_config(&restaking_config_pubkey, &restaking_config_admin)
.await?;

Ok(restaking_config_admin)
}

pub async fn initialize_config(
&mut self,
config: &Pubkey,
config_admin: &Keypair,
) -> TestResult<()> {
let blockhash = self.banks_client.get_latest_blockhash().await?;
self.process_transaction(&Transaction::new_signed_with_payer(
&[initialize_config(
&jito_restaking_program::id(),
config,
&config_admin.pubkey(),
&jito_vault_program::id(),
)],
Some(&config_admin.pubkey()),
&[config_admin],
blockhash,
))
.await
}

pub async fn do_initialize_ncn(&mut self) -> TestResult<NcnRoot> {
let ncn_admin = Keypair::new();
let ncn_base = Keypair::new();

self._airdrop(&ncn_admin.pubkey(), 1.0).await?;

let ncn_pubkey =
Ncn::find_program_address(&jito_restaking_program::id(), &ncn_base.pubkey()).0;
self.initialize_ncn(
&Config::find_program_address(&jito_restaking_program::id()).0,
&ncn_pubkey,
&ncn_admin,
&ncn_base,
)
.await?;

Ok(NcnRoot {
ncn_pubkey,
ncn_admin,
})
}

pub async fn initialize_ncn(
&mut self,
config: &Pubkey,
ncn: &Pubkey,
ncn_admin: &Keypair,
ncn_base: &Keypair,
) -> TestResult<()> {
let blockhash = self.banks_client.get_latest_blockhash().await?;

self.process_transaction(&Transaction::new_signed_with_payer(
&[initialize_ncn(
&jito_restaking_program::id(),
config,
ncn,
&ncn_admin.pubkey(),
&ncn_base.pubkey(),
)],
Some(&ncn_admin.pubkey()),
&[&ncn_admin, &ncn_base],
blockhash,
))
.await
}
}
Loading

0 comments on commit 3bdc75a

Please sign in to comment.