From 3a7f258111dd050577648352eb92f89abb2f0563 Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Tue, 5 Nov 2024 14:41:55 -0700 Subject: [PATCH 1/5] almost ready for PR --- Cargo.lock | 176 +++++-- Cargo.toml | 1 + .../jito_tip_router/errors/jitoTipRouter.ts | 18 +- .../instructions/finalizeWeightTable.ts | 10 + .../instructions/updateWeightTable.ts | 17 +- clients/js/jito_tip_router/types/index.ts | 1 + .../js/jito_tip_router/types/jitoNumber.ts | 40 ++ .../js/jito_tip_router/types/weightEntry.ts | 16 +- .../src/generated/errors/jito_tip_router.rs | 12 + .../instructions/finalize_weight_table.rs | 40 ++ .../instructions/update_weight_table.rs | 50 +- .../src/generated/types/jito_number.rs | 13 + .../src/generated/types/mod.rs | 3 +- .../src/generated/types/weight_entry.rs | 4 +- core/Cargo.toml | 1 + core/src/depreciated_weight.rs | 474 ------------------ core/src/error.rs | 8 + core/src/instruction.rs | 5 +- core/src/jito_number.rs | 86 ++++ core/src/lib.rs | 1 + core/src/weight_table.rs | 96 +++- idl/jito_tip_router.json | 55 +- program/src/finalize_weight_table.rs | 7 +- program/src/lib.rs | 22 +- program/src/update_weight_table.rs | 18 +- 25 files changed, 532 insertions(+), 642 deletions(-) create mode 100644 clients/js/jito_tip_router/types/jitoNumber.ts create mode 100644 clients/rust/jito_tip_router/src/generated/types/jito_number.rs delete mode 100644 core/src/depreciated_weight.rs create mode 100644 core/src/jito_number.rs diff --git a/Cargo.lock b/Cargo.lock index b1ddcd1..cf2f54e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,7 +250,7 @@ dependencies = [ "borsh 0.10.4", "bytemuck", "getrandom 0.2.15", - "solana-program", + "solana-program 1.18.26", "thiserror", ] @@ -1208,7 +1208,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279a4314e755fb311d9e2dd6503fdc023f9c833ddceb158565b95b9323f5fd10" dependencies = [ - "solana-program", + "solana-program 1.18.26", ] [[package]] @@ -2357,7 +2357,7 @@ dependencies = [ "borsh 0.10.4", "bytemuck", "jito-account-traits-derive", - "solana-program", + "solana-program 1.18.26", ] [[package]] @@ -2369,7 +2369,7 @@ dependencies = [ "bytemuck", "jito-bytemuck", "shank", - "solana-program", + "solana-program 1.18.26", "spl-associated-token-account", "spl-token", "spl-token-2022 3.0.4", @@ -2388,7 +2388,7 @@ dependencies = [ "num-traits", "serde", "serde_with 3.11.0", - "solana-program", + "solana-program 1.18.26", "solana-sdk", "thiserror", ] @@ -2404,7 +2404,7 @@ dependencies = [ "jito-jsm-core", "jito-restaking-sdk", "shank", - "solana-program", + "solana-program 1.18.26", "spl-associated-token-account", "spl-token", "thiserror", @@ -2424,7 +2424,7 @@ dependencies = [ "jito-restaking-sdk", "jito-vault-core", "shank", - "solana-program", + "solana-program 1.18.26", "solana-security-txt", "spl-associated-token-account", "spl-token", @@ -2439,7 +2439,7 @@ source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176 dependencies = [ "borsh 0.10.4", "shank", - "solana-program", + "solana-program 1.18.26", "thiserror", ] @@ -2462,7 +2462,7 @@ dependencies = [ "log", "solana-account-decoder", "solana-cli-config", - "solana-program", + "solana-program 1.18.26", "solana-rpc-client", "solana-rpc-client-api", "solana-sdk", @@ -2483,7 +2483,7 @@ dependencies = [ "num-traits", "serde", "serde_with 3.11.0", - "solana-program", + "solana-program 1.18.26", "solana-sdk", "thiserror", ] @@ -2502,8 +2502,9 @@ dependencies = [ "jito-vault-core", "jito-vault-sdk", "shank", - "solana-program", + "solana-program 1.18.26", "spl-associated-token-account", + "spl-math", "spl-token", "thiserror", ] @@ -2524,7 +2525,7 @@ dependencies = [ "jito-vault-sdk", "log", "shank", - "solana-program", + "solana-program 1.18.26", "solana-program-test", "solana-sdk", "solana-security-txt", @@ -2552,7 +2553,7 @@ dependencies = [ "jito-vault-core", "jito-vault-sdk", "shank", - "solana-program", + "solana-program 1.18.26", "solana-security-txt", "spl-associated-token-account", "spl-token", @@ -2584,7 +2585,7 @@ dependencies = [ "num-traits", "serde", "serde_with 3.11.0", - "solana-program", + "solana-program 1.18.26", "solana-sdk", "thiserror", ] @@ -2600,7 +2601,7 @@ dependencies = [ "jito-jsm-core", "jito-vault-sdk", "shank", - "solana-program", + "solana-program 1.18.26", "spl-associated-token-account", "spl-token", "spl-token-2022 3.0.4", @@ -2621,7 +2622,7 @@ dependencies = [ "jito-vault-core", "jito-vault-sdk", "shank", - "solana-program", + "solana-program 1.18.26", "solana-security-txt", "spl-associated-token-account", "spl-token", @@ -2636,7 +2637,7 @@ source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176 dependencies = [ "borsh 0.10.4", "shank", - "solana-program", + "solana-program 1.18.26", "spl-token", "thiserror", ] @@ -4440,7 +4441,7 @@ dependencies = [ "serde", "solana-frozen-abi", "solana-frozen-abi-macro", - "solana-program", + "solana-program 1.18.26", "solana-program-runtime", "solana-sdk", "thiserror", @@ -4455,7 +4456,7 @@ dependencies = [ "borsh 1.5.1", "futures", "solana-banks-interface", - "solana-program", + "solana-program 1.18.26", "solana-sdk", "tarpc", "thiserror", @@ -4858,13 +4859,59 @@ dependencies = [ "sha3 0.10.8", "solana-frozen-abi", "solana-frozen-abi-macro", - "solana-sdk-macro", + "solana-sdk-macro 1.18.26", "thiserror", "tiny-bip39", "wasm-bindgen", "zeroize", ] +[[package]] +name = "solana-program" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2625a23c3813b620141ee447819b08d1b9a5f1c69a309754834e3f35798a21fb" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.22.1", + "bincode", + "bitflags 2.6.0", + "blake3", + "borsh 0.10.4", + "borsh 1.5.1", + "bs58 0.5.1", + "bv", + "bytemuck", + "bytemuck_derive", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.15", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memoffset 0.9.1", + "num-bigint 0.4.6", + "num-derive 0.4.2", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "sha3 0.10.8", + "solana-sdk-macro 2.0.14", + "thiserror", + "wasm-bindgen", +] + [[package]] name = "solana-program-runtime" version = "1.18.26" @@ -5190,8 +5237,8 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-logger", - "solana-program", - "solana-sdk-macro", + "solana-program 1.18.26", + "solana-sdk-macro 1.18.26", "thiserror", "uriparse", "wasm-bindgen", @@ -5210,6 +5257,19 @@ dependencies = [ "syn 2.0.85", ] +[[package]] +name = "solana-sdk-macro" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a5a1eabc890415d326707afe62cd7a2009236e8d899c1519566fc8f7e3977b" +dependencies = [ + "bs58 0.5.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.85", +] + [[package]] name = "solana-security-txt" version = "1.1.1" @@ -5424,7 +5484,7 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-metrics", - "solana-program", + "solana-program 1.18.26", "solana-program-runtime", "solana-sdk", "thiserror", @@ -5466,7 +5526,7 @@ dependencies = [ "serde", "serde_json", "sha3 0.9.1", - "solana-program", + "solana-program 1.18.26", "solana-sdk", "subtle", "thiserror", @@ -5524,7 +5584,7 @@ dependencies = [ "borsh 0.10.4", "num-derive 0.4.2", "num-traits", - "solana-program", + "solana-program 1.18.26", "spl-token", "spl-token-2022 1.0.0", "thiserror", @@ -5537,7 +5597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator-derive 0.1.2", ] @@ -5548,7 +5608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "210101376962bb22bb13be6daea34656ea1cbc248fce2164b146e39203b55e03" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator-derive 0.2.0", ] @@ -5600,13 +5660,27 @@ dependencies = [ "thiserror", ] +[[package]] +name = "spl-math" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc5a6cc7a4f0cf7813ce44153bba73280909f697d7f6baf7b9f223a255e7887" +dependencies = [ + "borsh 1.5.1", + "num-derive 0.4.2", + "num-traits", + "solana-program 2.0.14", + "thiserror", + "uint", +] + [[package]] name = "spl-memo" version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" dependencies = [ - "solana-program", + "solana-program 1.18.26", ] [[package]] @@ -5617,7 +5691,7 @@ checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" dependencies = [ "borsh 0.10.4", "bytemuck", - "solana-program", + "solana-program 1.18.26", "solana-zk-token-sdk", "spl-program-error 0.3.0", ] @@ -5630,7 +5704,7 @@ checksum = "c52d84c55efeef8edcc226743dc089d7e3888b8e3474569aa3eff152b37b9996" dependencies = [ "borsh 1.5.1", "bytemuck", - "solana-program", + "solana-program 1.18.26", "solana-zk-token-sdk", "spl-program-error 0.4.4", ] @@ -5643,7 +5717,7 @@ checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" dependencies = [ "num-derive 0.4.2", "num-traits", - "solana-program", + "solana-program 1.18.26", "spl-program-error-derive 0.3.2", "thiserror", ] @@ -5656,7 +5730,7 @@ checksum = "e45a49acb925db68aa501b926096b2164adbdcade7a0c24152af9f0742d0a602" dependencies = [ "num-derive 0.4.2", "num-traits", - "solana-program", + "solana-program 1.18.26", "spl-program-error-derive 0.4.1", "thiserror", ] @@ -5692,7 +5766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "615d381f48ddd2bb3c57c7f7fb207591a2a05054639b18a62e785117dd7a8683" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.1.0", "spl-pod 0.1.0", "spl-program-error 0.3.0", @@ -5706,7 +5780,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fab8edfd37be5fa17c9e42c1bff86abbbaf0494b031b37957f2728ad2ff842ba" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.2.5", "spl-pod 0.2.5", "spl-program-error 0.4.4", @@ -5724,7 +5798,7 @@ dependencies = [ "num-derive 0.3.3", "num-traits", "num_enum 0.6.1", - "solana-program", + "solana-program 1.18.26", "thiserror", ] @@ -5739,7 +5813,7 @@ dependencies = [ "num-derive 0.4.2", "num-traits", "num_enum 0.7.3", - "solana-program", + "solana-program 1.18.26", "solana-security-txt", "solana-zk-token-sdk", "spl-memo", @@ -5763,7 +5837,7 @@ dependencies = [ "num-derive 0.4.2", "num-traits", "num_enum 0.7.3", - "solana-program", + "solana-program 1.18.26", "solana-security-txt", "solana-zk-token-sdk", "spl-memo", @@ -5783,7 +5857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.1.0", "spl-pod 0.1.0", "spl-program-error 0.3.0", @@ -5796,7 +5870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "014817d6324b1e20c4bbc883e8ee30a5faa13e59d91d1b2b95df98b920150c17" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.2.5", "spl-pod 0.2.5", "spl-program-error 0.4.4", @@ -5809,7 +5883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" dependencies = [ "borsh 0.10.4", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.1.0", "spl-pod 0.1.0", "spl-program-error 0.3.0", @@ -5823,7 +5897,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3da00495b602ebcf5d8ba8b3ecff1ee454ce4c125c9077747be49c2d62335ba" dependencies = [ "borsh 1.5.1", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.2.5", "spl-pod 0.2.5", "spl-program-error 0.4.4", @@ -5838,7 +5912,7 @@ checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" dependencies = [ "arrayref", "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.1.0", "spl-pod 0.1.0", "spl-program-error 0.3.0", @@ -5854,7 +5928,7 @@ checksum = "a9b5c08a89838e5a2931f79b17f611857f281a14a2100968a3ccef352cb7414b" dependencies = [ "arrayref", "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.2.5", "spl-pod 0.2.5", "spl-program-error 0.4.4", @@ -5869,7 +5943,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.1.0", "spl-pod 0.1.0", "spl-program-error 0.3.0", @@ -5882,7 +5956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c872f93d0600e743116501eba2d53460e73a12c9a496875a42a7d70e034fe06d" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.26", "spl-discriminator 0.2.5", "spl-pod 0.2.5", "spl-program-error 0.4.4", @@ -6495,6 +6569,18 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "uint" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unicode-bidi" version = "0.3.17" diff --git a/Cargo.toml b/Cargo.toml index 3fa60d6..6d71fef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ serde = { version = "^1.0", features = ["derive"] } serde_with = "3.9.0" shank = "0.4.2" shank_idl = "0.4.2" +spl-math = { version = "0.3.0", features = ["no-entrypoint"] } solana-account-decoder = "~1.18" solana-cli-config = "~1.18" solana-program = "~1.18" diff --git a/clients/js/jito_tip_router/errors/jitoTipRouter.ts b/clients/js/jito_tip_router/errors/jitoTipRouter.ts index 9fe38be..6184f66 100644 --- a/clients/js/jito_tip_router/errors/jitoTipRouter.ts +++ b/clients/js/jito_tip_router/errors/jitoTipRouter.ts @@ -22,28 +22,44 @@ export const JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO = 0x2100; // 8448 export const JITO_TIP_ROUTER_ERROR__ARITHMETIC_OVERFLOW = 0x2101; // 8449 /** ModuloOverflow: Modulo Overflow */ export const JITO_TIP_ROUTER_ERROR__MODULO_OVERFLOW = 0x2102; // 8450 +/** NewPreciseNumberError: New precise number error */ +export const JITO_TIP_ROUTER_ERROR__NEW_PRECISE_NUMBER_ERROR = 0x2103; // 8451 +/** CastToImpreciseNumberError: Cast to imprecise number error */ +export const JITO_TIP_ROUTER_ERROR__CAST_TO_IMPRECISE_NUMBER_ERROR = 0x2104; // 8452 /** IncorrectWeightTableAdmin: Incorrect weight table admin */ export const JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN = 0x2200; // 8704 /** CannotCreateFutureWeightTables: Cannnot create future weight tables */ export const JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES = 0x2201; // 8705 +/** WeightMintsDoNotMatchLength: Weight mints do not match - length */ +export const JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_LENGTH = 0x2202; // 8706 +/** WeightMintsDoNotMatchMintHash: Weight mints do not match - mint hash */ +export const JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH = 0x2203; // 8707 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__CAST_TO_IMPRECISE_NUMBER_ERROR | typeof JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO | 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; + | typeof JITO_TIP_ROUTER_ERROR__NEW_PRECISE_NUMBER_ERROR + | typeof JITO_TIP_ROUTER_ERROR__NO_MORE_TABLE_SLOTS + | typeof JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_LENGTH + | typeof JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH; let jitoTipRouterErrorMessages: Record | undefined; if (process.env.NODE_ENV !== 'production') { jitoTipRouterErrorMessages = { [JITO_TIP_ROUTER_ERROR__ARITHMETIC_OVERFLOW]: `Overflow`, [JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES]: `Cannnot create future weight tables`, + [JITO_TIP_ROUTER_ERROR__CAST_TO_IMPRECISE_NUMBER_ERROR]: `Cast to imprecise number error`, [JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO]: `Zero in the denominator`, [JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN]: `Incorrect weight table admin`, [JITO_TIP_ROUTER_ERROR__MODULO_OVERFLOW]: `Modulo Overflow`, + [JITO_TIP_ROUTER_ERROR__NEW_PRECISE_NUMBER_ERROR]: `New precise number error`, [JITO_TIP_ROUTER_ERROR__NO_MORE_TABLE_SLOTS]: `No more table slots available`, + [JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_LENGTH]: `Weight mints do not match - length`, + [JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH]: `Weight mints do not match - mint hash`, }; } diff --git a/clients/js/jito_tip_router/instructions/finalizeWeightTable.ts b/clients/js/jito_tip_router/instructions/finalizeWeightTable.ts index f492b8a..ff56556 100644 --- a/clients/js/jito_tip_router/instructions/finalizeWeightTable.ts +++ b/clients/js/jito_tip_router/instructions/finalizeWeightTable.ts @@ -67,10 +67,14 @@ export type FinalizeWeightTableInstruction< export type FinalizeWeightTableInstructionData = { discriminator: number; ncnEpoch: bigint; + mintHash: bigint; + mintCount: number; }; export type FinalizeWeightTableInstructionDataArgs = { ncnEpoch: number | bigint; + mintHash: number | bigint; + mintCount: number; }; export function getFinalizeWeightTableInstructionDataEncoder(): Encoder { @@ -78,6 +82,8 @@ export function getFinalizeWeightTableInstructionDataEncoder(): Encoder ({ ...value, @@ -90,6 +96,8 @@ export function getFinalizeWeightTableInstructionDataDecoder(): Decoder; restakingProgramId: Address; ncnEpoch: FinalizeWeightTableInstructionDataArgs['ncnEpoch']; + mintHash: FinalizeWeightTableInstructionDataArgs['mintHash']; + mintCount: FinalizeWeightTableInstructionDataArgs['mintCount']; }; export function getFinalizeWeightTableInstruction< diff --git a/clients/js/jito_tip_router/instructions/updateWeightTable.ts b/clients/js/jito_tip_router/instructions/updateWeightTable.ts index 9157708..0fd6673 100644 --- a/clients/js/jito_tip_router/instructions/updateWeightTable.ts +++ b/clients/js/jito_tip_router/instructions/updateWeightTable.ts @@ -10,6 +10,8 @@ import { combineCodec, getStructDecoder, getStructEncoder, + getU128Decoder, + getU128Encoder, getU64Decoder, getU64Encoder, getU8Decoder, @@ -67,14 +69,12 @@ export type UpdateWeightTableInstruction< export type UpdateWeightTableInstructionData = { discriminator: number; ncnEpoch: bigint; - weightNumerator: bigint; - weightDenominator: bigint; + weight: bigint; }; export type UpdateWeightTableInstructionDataArgs = { ncnEpoch: number | bigint; - weightNumerator: number | bigint; - weightDenominator: number | bigint; + weight: number | bigint; }; export function getUpdateWeightTableInstructionDataEncoder(): Encoder { @@ -82,8 +82,7 @@ export function getUpdateWeightTableInstructionDataEncoder(): Encoder ({ ...value, discriminator: UPDATE_WEIGHT_TABLE_DISCRIMINATOR }) ); @@ -93,8 +92,7 @@ export function getUpdateWeightTableInstructionDataDecoder(): Decoder; restakingProgramId: Address; ncnEpoch: UpdateWeightTableInstructionDataArgs['ncnEpoch']; - weightNumerator: UpdateWeightTableInstructionDataArgs['weightNumerator']; - weightDenominator: UpdateWeightTableInstructionDataArgs['weightDenominator']; + weight: UpdateWeightTableInstructionDataArgs['weight']; }; export function getUpdateWeightTableInstruction< diff --git a/clients/js/jito_tip_router/types/index.ts b/clients/js/jito_tip_router/types/index.ts index 5597466..0c7494d 100644 --- a/clients/js/jito_tip_router/types/index.ts +++ b/clients/js/jito_tip_router/types/index.ts @@ -6,4 +6,5 @@ * @see https://github.com/kinobi-so/kinobi */ +export * from './jitoNumber'; export * from './weightEntry'; diff --git a/clients/js/jito_tip_router/types/jitoNumber.ts b/clients/js/jito_tip_router/types/jitoNumber.ts new file mode 100644 index 0000000..5347032 --- /dev/null +++ b/clients/js/jito_tip_router/types/jitoNumber.ts @@ -0,0 +1,40 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/kinobi-so/kinobi + */ + +import { + combineCodec, + getArrayDecoder, + getArrayEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + type Codec, + type Decoder, + type Encoder, +} from '@solana/web3.js'; + +export type JitoNumber = { value: Array }; + +export type JitoNumberArgs = JitoNumber; + +export function getJitoNumberEncoder(): Encoder { + return getStructEncoder([ + ['value', getArrayEncoder(getU8Encoder(), { size: 16 })], + ]); +} + +export function getJitoNumberDecoder(): Decoder { + return getStructDecoder([ + ['value', getArrayDecoder(getU8Decoder(), { size: 16 })], + ]); +} + +export function getJitoNumberCodec(): Codec { + return combineCodec(getJitoNumberEncoder(), getJitoNumberDecoder()); +} diff --git a/clients/js/jito_tip_router/types/weightEntry.ts b/clients/js/jito_tip_router/types/weightEntry.ts index 745e000..bf66fd3 100644 --- a/clients/js/jito_tip_router/types/weightEntry.ts +++ b/clients/js/jito_tip_router/types/weightEntry.ts @@ -12,29 +12,33 @@ import { getAddressEncoder, getStructDecoder, getStructEncoder, - getU64Decoder, - getU64Encoder, type Address, type Codec, type Decoder, type Encoder, } from '@solana/web3.js'; +import { + getJitoNumberDecoder, + getJitoNumberEncoder, + type JitoNumber, + type JitoNumberArgs, +} from '.'; -export type WeightEntry = { mint: Address; weight: bigint }; +export type WeightEntry = { mint: Address; weight: JitoNumber }; -export type WeightEntryArgs = { mint: Address; weight: number | bigint }; +export type WeightEntryArgs = { mint: Address; weight: JitoNumberArgs }; export function getWeightEntryEncoder(): Encoder { return getStructEncoder([ ['mint', getAddressEncoder()], - ['weight', getU64Encoder()], + ['weight', getJitoNumberEncoder()], ]); } export function getWeightEntryDecoder(): Decoder { return getStructDecoder([ ['mint', getAddressDecoder()], - ['weight', getU64Decoder()], + ['weight', getJitoNumberDecoder()], ]); } diff --git a/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs b/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs index 99bb832..9191ec4 100644 --- a/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs +++ b/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs @@ -21,12 +21,24 @@ pub enum JitoTipRouterError { /// 8450 - Modulo Overflow #[error("Modulo Overflow")] ModuloOverflow = 0x2102, + /// 8451 - New precise number error + #[error("New precise number error")] + NewPreciseNumberError = 0x2103, + /// 8452 - Cast to imprecise number error + #[error("Cast to imprecise number error")] + CastToImpreciseNumberError = 0x2104, /// 8704 - Incorrect weight table admin #[error("Incorrect weight table admin")] IncorrectWeightTableAdmin = 0x2200, /// 8705 - Cannnot create future weight tables #[error("Cannnot create future weight tables")] CannotCreateFutureWeightTables = 0x2201, + /// 8706 - Weight mints do not match - length + #[error("Weight mints do not match - length")] + WeightMintsDoNotMatchLength = 0x2202, + /// 8707 - Weight mints do not match - mint hash + #[error("Weight mints do not match - mint hash")] + WeightMintsDoNotMatchMintHash = 0x2203, } impl solana_program::program_error::PrintProgramError for JitoTipRouterError { diff --git a/clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs b/clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs index ab49228..f811789 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs @@ -82,6 +82,8 @@ impl Default for FinalizeWeightTableInstructionData { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FinalizeWeightTableInstructionArgs { pub ncn_epoch: u64, + pub mint_hash: u64, + pub mint_count: u8, } /// Instruction builder for `FinalizeWeightTable`. @@ -99,6 +101,8 @@ pub struct FinalizeWeightTableBuilder { weight_table_admin: Option, restaking_program_id: Option, ncn_epoch: Option, + mint_hash: Option, + mint_count: Option, __remaining_accounts: Vec, } @@ -137,6 +141,16 @@ impl FinalizeWeightTableBuilder { self.ncn_epoch = Some(ncn_epoch); self } + #[inline(always)] + pub fn mint_hash(&mut self, mint_hash: u64) -> &mut Self { + self.mint_hash = Some(mint_hash); + self + } + #[inline(always)] + pub fn mint_count(&mut self, mint_count: u8) -> &mut Self { + self.mint_count = Some(mint_count); + self + } /// Add an additional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -169,6 +183,8 @@ impl FinalizeWeightTableBuilder { }; let args = FinalizeWeightTableInstructionArgs { ncn_epoch: self.ncn_epoch.clone().expect("ncn_epoch is not set"), + mint_hash: self.mint_hash.clone().expect("mint_hash is not set"), + mint_count: self.mint_count.clone().expect("mint_count is not set"), }; accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) @@ -325,6 +341,8 @@ impl<'a, 'b> FinalizeWeightTableCpiBuilder<'a, 'b> { weight_table_admin: None, restaking_program_id: None, ncn_epoch: None, + mint_hash: None, + mint_count: None, __remaining_accounts: Vec::new(), }); Self { instruction } @@ -363,6 +381,16 @@ impl<'a, 'b> FinalizeWeightTableCpiBuilder<'a, 'b> { self.instruction.ncn_epoch = Some(ncn_epoch); self } + #[inline(always)] + pub fn mint_hash(&mut self, mint_hash: u64) -> &mut Self { + self.instruction.mint_hash = Some(mint_hash); + self + } + #[inline(always)] + pub fn mint_count(&mut self, mint_count: u8) -> &mut Self { + self.instruction.mint_count = Some(mint_count); + self + } /// Add an additional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -410,6 +438,16 @@ impl<'a, 'b> FinalizeWeightTableCpiBuilder<'a, 'b> { .ncn_epoch .clone() .expect("ncn_epoch is not set"), + mint_hash: self + .instruction + .mint_hash + .clone() + .expect("mint_hash is not set"), + mint_count: self + .instruction + .mint_count + .clone() + .expect("mint_count is not set"), }; let instruction = FinalizeWeightTableCpi { __program: self.instruction.__program, @@ -447,6 +485,8 @@ struct FinalizeWeightTableCpiBuilderInstruction<'a, 'b> { weight_table_admin: Option<&'b solana_program::account_info::AccountInfo<'a>>, restaking_program_id: Option<&'b solana_program::account_info::AccountInfo<'a>>, ncn_epoch: Option, + mint_hash: Option, + mint_count: Option, /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. __remaining_accounts: Vec<( &'b solana_program::account_info::AccountInfo<'a>, diff --git a/clients/rust/jito_tip_router/src/generated/instructions/update_weight_table.rs b/clients/rust/jito_tip_router/src/generated/instructions/update_weight_table.rs index 224b8ae..d2aa817 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/update_weight_table.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/update_weight_table.rs @@ -82,8 +82,7 @@ impl Default for UpdateWeightTableInstructionData { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct UpdateWeightTableInstructionArgs { pub ncn_epoch: u64, - pub weight_numerator: u64, - pub weight_denominator: u64, + pub weight: u128, } /// Instruction builder for `UpdateWeightTable`. @@ -101,8 +100,7 @@ pub struct UpdateWeightTableBuilder { weight_table_admin: Option, restaking_program_id: Option, ncn_epoch: Option, - weight_numerator: Option, - weight_denominator: Option, + weight: Option, __remaining_accounts: Vec, } @@ -142,13 +140,8 @@ impl UpdateWeightTableBuilder { self } #[inline(always)] - pub fn weight_numerator(&mut self, weight_numerator: u64) -> &mut Self { - self.weight_numerator = Some(weight_numerator); - self - } - #[inline(always)] - pub fn weight_denominator(&mut self, weight_denominator: u64) -> &mut Self { - self.weight_denominator = Some(weight_denominator); + pub fn weight(&mut self, weight: u128) -> &mut Self { + self.weight = Some(weight); self } /// Add an additional account to the instruction. @@ -183,14 +176,7 @@ impl UpdateWeightTableBuilder { }; let args = UpdateWeightTableInstructionArgs { ncn_epoch: self.ncn_epoch.clone().expect("ncn_epoch is not set"), - weight_numerator: self - .weight_numerator - .clone() - .expect("weight_numerator is not set"), - weight_denominator: self - .weight_denominator - .clone() - .expect("weight_denominator is not set"), + weight: self.weight.clone().expect("weight is not set"), }; accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) @@ -347,8 +333,7 @@ impl<'a, 'b> UpdateWeightTableCpiBuilder<'a, 'b> { weight_table_admin: None, restaking_program_id: None, ncn_epoch: None, - weight_numerator: None, - weight_denominator: None, + weight: None, __remaining_accounts: Vec::new(), }); Self { instruction } @@ -388,13 +373,8 @@ impl<'a, 'b> UpdateWeightTableCpiBuilder<'a, 'b> { self } #[inline(always)] - pub fn weight_numerator(&mut self, weight_numerator: u64) -> &mut Self { - self.instruction.weight_numerator = Some(weight_numerator); - self - } - #[inline(always)] - pub fn weight_denominator(&mut self, weight_denominator: u64) -> &mut Self { - self.instruction.weight_denominator = Some(weight_denominator); + pub fn weight(&mut self, weight: u128) -> &mut Self { + self.instruction.weight = Some(weight); self } /// Add an additional account to the instruction. @@ -444,16 +424,7 @@ impl<'a, 'b> UpdateWeightTableCpiBuilder<'a, 'b> { .ncn_epoch .clone() .expect("ncn_epoch is not set"), - weight_numerator: self - .instruction - .weight_numerator - .clone() - .expect("weight_numerator is not set"), - weight_denominator: self - .instruction - .weight_denominator - .clone() - .expect("weight_denominator is not set"), + weight: self.instruction.weight.clone().expect("weight is not set"), }; let instruction = UpdateWeightTableCpi { __program: self.instruction.__program, @@ -491,8 +462,7 @@ struct UpdateWeightTableCpiBuilderInstruction<'a, 'b> { weight_table_admin: Option<&'b solana_program::account_info::AccountInfo<'a>>, restaking_program_id: Option<&'b solana_program::account_info::AccountInfo<'a>>, ncn_epoch: Option, - weight_numerator: Option, - weight_denominator: Option, + weight: Option, /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. __remaining_accounts: Vec<( &'b solana_program::account_info::AccountInfo<'a>, diff --git a/clients/rust/jito_tip_router/src/generated/types/jito_number.rs b/clients/rust/jito_tip_router/src/generated/types/jito_number.rs new file mode 100644 index 0000000..76e377d --- /dev/null +++ b/clients/rust/jito_tip_router/src/generated/types/jito_number.rs @@ -0,0 +1,13 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! + +use borsh::{BorshDeserialize, BorshSerialize}; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct JitoNumber { + pub value: [u8; 16], +} diff --git a/clients/rust/jito_tip_router/src/generated/types/mod.rs b/clients/rust/jito_tip_router/src/generated/types/mod.rs index f552bf2..be8e546 100644 --- a/clients/rust/jito_tip_router/src/generated/types/mod.rs +++ b/clients/rust/jito_tip_router/src/generated/types/mod.rs @@ -4,6 +4,7 @@ //! //! +pub(crate) mod r#jito_number; pub(crate) mod r#weight_entry; -pub use self::r#weight_entry::*; +pub use self::{r#jito_number::*, r#weight_entry::*}; diff --git a/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs b/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs index 11a9d11..67e77cf 100644 --- a/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs +++ b/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs @@ -7,6 +7,8 @@ use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::pubkey::Pubkey; +use crate::generated::types::JitoNumber; + #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct WeightEntry { @@ -15,5 +17,5 @@ pub struct WeightEntry { serde(with = "serde_with::As::") )] pub mint: Pubkey, - pub weight: u64, + pub weight: JitoNumber, } diff --git a/core/Cargo.toml b/core/Cargo.toml index fabfd39..1aa25c2 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -21,6 +21,7 @@ jito-vault-sdk = { workspace = true } shank = { workspace = true } solana-program = { workspace = true } spl-associated-token-account = { workspace = true } +spl-math = { workspace = true } spl-token = { workspace = true } thiserror = { workspace = true } diff --git a/core/src/depreciated_weight.rs b/core/src/depreciated_weight.rs deleted file mode 100644 index 224069d..0000000 --- a/core/src/depreciated_weight.rs +++ /dev/null @@ -1,474 +0,0 @@ -use std::u64; - -use bytemuck::{Pod, Zeroable}; -use jito_bytemuck::types::PodU64; -use shank::ShankType; - -use crate::error::WeightTableError; - -#[derive(Debug, Clone, PartialEq, Eq, Copy, Zeroable, ShankType, Pod)] -#[repr(C)] -pub struct Weight { - numerator: PodU64, - denominator: PodU64, -} - -impl Weight { - pub fn numerator(&self) -> u64 { - self.numerator.into() - } - - pub fn denominator(&self) -> u64 { - self.denominator.into() - } - - pub fn new(numerator: u64, denominator: u64) -> Result { - if denominator == 0 { - return Err(WeightTableError::DenominatorIsZero); - } - - Ok(Self { - numerator: PodU64::from(numerator), - denominator: PodU64::from(denominator), - }) - } - - fn is_zero(&self) -> bool { - self.numerator() == 0 - } - - fn greatest_common_denominator(&self) -> Result { - let mut n: u64 = self.numerator(); - let mut d: u64 = self.denominator(); - - if d == 0 { - return Err(WeightTableError::DenominatorIsZero); - } - - if n == 0 { - return Ok(1); - } - - while d != 0 { - if d < n { - std::mem::swap(&mut d, &mut n); - } - d %= n; - } - - Ok(n) - } - - fn simplify(&self) -> Result { - let gcd_value = self.greatest_common_denominator()?; - - if gcd_value == 1 { - return Ok(*self); - } - - Ok(Self { - numerator: PodU64::from(self.numerator() / gcd_value), - denominator: PodU64::from(self.denominator() / gcd_value), - }) - } - - fn compare_weights(&self, other: &Self, compare: F) -> bool - where - F: Fn(u64, u64) -> bool, - { - let a = self.numerator(); - let b = self.denominator(); - let c = other.numerator(); - let d = other.denominator(); - - a.checked_mul(d) - .and_then(|ad| b.checked_mul(c).map(|bc| compare(ad, bc))) - .unwrap_or(false) - } - - pub fn gte(&self, other: &Self) -> bool { - self.compare_weights(other, |ad, bc| ad >= bc) - } - - pub fn gt(&self, other: &Self) -> bool { - self.compare_weights(other, |ad, bc| ad > bc) - } - - pub fn lt(&self, other: &Self) -> bool { - self.compare_weights(other, |ad, bc| ad < bc) - } - - pub fn lte(&self, other: &Self) -> bool { - self.compare_weights(other, |ad, bc| ad <= bc) - } - - pub fn eq(&self, other: &Self) -> bool { - self.compare_weights(other, |ad, bc| ad == bc) - } - - pub fn neq(&self, other: &Self) -> bool { - self.compare_weights(other, |ad, bc| ad != bc) - } - - pub fn checked_add(&self, other: &Self) -> Result { - let a = self.numerator(); - let b = self.denominator(); - let c = other.numerator(); - let d = other.denominator(); - - // Calculate ad and bc - let ad = a - .checked_mul(d) - .ok_or(WeightTableError::ArithmeticOverflow)?; - let bc = b - .checked_mul(c) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - // Calculate numerator (ad + bc) - let numerator = ad - .checked_add(bc) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - // Calculate denominator (bd) - let denominator = b - .checked_mul(d) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - let weight = Self { - numerator: PodU64::from(numerator), - denominator: PodU64::from(denominator), - }; - - weight.simplify() - } - - pub fn checked_sub(&self, other: &Self) -> Result { - let a = self.numerator(); - let b = self.denominator(); - let c = other.numerator(); - let d = other.denominator(); - - // Calculate ad and bc - let ad = a - .checked_mul(d) - .ok_or(WeightTableError::ArithmeticOverflow)?; - let bc = b - .checked_mul(c) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - // Calculate numerator (ad - bc) - let numerator = ad - .checked_sub(bc) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - // Calculate denominator (bd) - let denominator = b - .checked_mul(d) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - // Check if the result is zero - if numerator == 0 { - return Ok(Self::default()); - } - - let weight = Self { - numerator: PodU64::from(numerator), - denominator: PodU64::from(denominator), - }; - - weight.simplify() - } - - pub fn checked_mul(&self, other: &Self) -> Result { - let a = self.numerator(); - let b = self.denominator(); - let c = other.numerator(); - let d = other.denominator(); - - // Calculate numerator (ac) - let numerator = a - .checked_mul(c) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - // Calculate denominator (bd) - let denominator = b - .checked_mul(d) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - if denominator == 0 { - return Err(WeightTableError::DenominatorIsZero); - } - - let weight = Self { - numerator: PodU64::from(numerator), - denominator: PodU64::from(denominator), - }; - - weight.simplify() - } - - pub fn checked_div(&self, other: &Self) -> Result { - if other.is_zero() { - return Err(WeightTableError::DenominatorIsZero); - } - - let a = self.numerator(); - let b = self.denominator(); - let c = other.numerator(); - let d = other.denominator(); - - // Division by a/b / c/d is equivalent to multiplication by a/b * d/c - // So we multiply by the reciprocal - - // Calculate numerator (ad) - let numerator = a - .checked_mul(d) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - // Calculate denominator (bc) - let denominator = b - .checked_mul(c) - .ok_or(WeightTableError::ArithmeticOverflow)?; - - if denominator == 0 { - return Err(WeightTableError::DenominatorIsZero); - } - - let weight = Self { - numerator: PodU64::from(numerator), - denominator: PodU64::from(denominator), - }; - - weight.simplify() - } -} - -impl Default for Weight { - fn default() -> Self { - Self { - numerator: PodU64::from(0), - denominator: PodU64::from(1), - } - } -} - -impl From for Weight { - fn from(weight: u64) -> Self { - Self { - numerator: PodU64::from(weight), - denominator: PodU64::from(1), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_new() { - assert!(Weight::new(1, 2).is_ok()); - assert!(matches!( - Weight::new(1, 0), - Err(WeightTableError::DenominatorIsZero) - )); - } - - #[test] - fn test_is_zero() { - assert!(Weight::new(0, 1).unwrap().is_zero()); - assert!(!Weight::new(1, 2).unwrap().is_zero()); - } - - #[test] - fn test_gcd() { - assert_eq!( - Weight::new(6, 8) - .unwrap() - .greatest_common_denominator() - .unwrap(), - 2 - ); - assert_eq!( - Weight::new(17, 23) - .unwrap() - .greatest_common_denominator() - .unwrap(), - 1 - ); - - let bad_weight = Weight::new(1, 0).unwrap_err(); - assert!(matches!(bad_weight, WeightTableError::DenominatorIsZero)); - } - - #[test] - fn test_simplify() { - let w1 = Weight::new(6, 8).unwrap().simplify().unwrap(); - assert_eq!(w1.numerator(), 3); - assert_eq!(w1.denominator(), 4); - - let w2 = Weight::new(17, 23).unwrap().simplify().unwrap(); - assert_eq!(w2.numerator(), 17); - assert_eq!(w2.denominator(), 23); - } - - #[test] - fn test_comparisons() { - let w1 = Weight::new(1, 2).unwrap(); - let w2 = Weight::new(3, 4).unwrap(); - let w3 = Weight::new(1, 2).unwrap(); - - assert!(w1.lt(&w2)); - assert!(w1.lte(&w2)); - assert!(w2.gt(&w1)); - assert!(w2.gte(&w1)); - assert!(w1.eq(&w3)); - assert!(w1.neq(&w2)); - } - - #[test] - fn test_checked_add() { - let w1 = Weight::new(1, 2).unwrap(); - let w2 = Weight::new(1, 4).unwrap(); - let result = w1.checked_add(&w2).unwrap(); - assert_eq!(result.numerator(), 3); - assert_eq!(result.denominator(), 4); - - // Test overflow - let w_max = Weight::new(u64::MAX, 1).unwrap(); - assert!(matches!( - w_max.checked_add(&w1), - Err(WeightTableError::ArithmeticOverflow) - )); - } - - #[test] - fn test_checked_sub() { - let w1 = Weight::new(3, 4).unwrap(); - let w2 = Weight::new(1, 4).unwrap(); - let result = w1.checked_sub(&w2).unwrap(); - assert_eq!(result.numerator(), 1); - assert_eq!(result.denominator(), 2); - - // Test underflow - let w_min = Weight::new(0, 1).unwrap(); - assert!(matches!( - w_min.checked_sub(&w1), - Err(WeightTableError::ArithmeticOverflow) - )); - } - - #[test] - fn test_checked_mul() { - let w1 = Weight::new(2, 3).unwrap(); - let w2 = Weight::new(3, 4).unwrap(); - let result = w1.checked_mul(&w2).unwrap(); - assert_eq!(result.numerator(), 1); - assert_eq!(result.denominator(), 2); - - // Test overflow - let w_max = Weight::new(u64::MAX, 1).unwrap(); - assert!(matches!( - w_max.checked_mul(&w1), - Err(WeightTableError::ArithmeticOverflow) - )); - } - - #[test] - fn test_checked_div() { - let w1 = Weight::new(2, 3).unwrap(); - let w2 = Weight::new(3, 4).unwrap(); - let result = w1.checked_div(&w2).unwrap(); - assert_eq!(result.numerator(), 8); - assert_eq!(result.denominator(), 9); - - // Test division by zero - let w_zero = Weight::new(0, 1).unwrap(); - assert!(matches!( - w1.checked_div(&w_zero), - Err(WeightTableError::DenominatorIsZero) - )); - - // Test overflow - let w_max = Weight::new(u64::MAX, 1).unwrap(); - let w_min = Weight::new(1, u64::MAX).unwrap(); - assert!(matches!( - w_max.checked_div(&w_min), - Err(WeightTableError::ArithmeticOverflow) - )); - } - - #[test] - fn test_largest_and_smallest_comparison() { - let largest = Weight::new(u64::MAX, 1).unwrap(); - let smallest = Weight::new(1, u64::MAX).unwrap(); - - // Due to overflow protection, these comparisons will return false - assert!(!largest.gt(&smallest)); - assert!(!smallest.lt(&largest)); - assert!(!largest.eq(&smallest)); - } - - #[test] - fn test_large_number_comparison() { - let large1 = Weight::new(u64::MAX / 2, 1).unwrap(); - let large2 = Weight::new(u64::MAX / 2 + 1, 1).unwrap(); - - assert!(large2.gt(&large1)); - assert!(large1.lt(&large2)); - assert!(!large1.eq(&large2)); - } - - #[test] - fn test_small_number_comparison() { - let small1 = Weight::new(1, u64::MAX).unwrap(); - let small2 = Weight::new(2, u64::MAX).unwrap(); - - // Due to precision limitations, these might not compare as expected - assert!(!small2.gt(&small1)); - assert!(!small1.lt(&small2)); - assert!(!small1.eq(&small2)); - } - - #[test] - fn test_precision_limit() { - let w1 = Weight::new(u64::MAX / 2, u64::MAX / 2).unwrap(); - let w2 = Weight::new(u64::MAX / 2 + 1, u64::MAX / 2).unwrap(); - - // Due to overflow protection, these comparisons will return false - assert!(!w2.gt(&w1)); - assert!(!w1.lt(&w2)); - assert!(!w1.eq(&w2)); - } - - #[test] - fn test_overflow_handling() { - let w1 = Weight::new(u64::MAX, 2).unwrap(); - let w2 = Weight::new(u64::MAX - 1, 2).unwrap(); - - // This comparison should return false due to overflow protection - assert!(!w1.gt(&w2)); - assert!(!w1.lt(&w2)); - assert!(!w1.eq(&w2)); - } - - #[test] - fn test_equality_of_simplified_weights() { - let w1 = Weight::new(2, 4).unwrap(); - let w2 = Weight::new(1, 2).unwrap(); - - assert!(w1.eq(&w2)); - assert!(!w1.gt(&w2)); - assert!(!w1.lt(&w2)); - } - - #[test] - fn test_comparison_with_zero() { - let zero = Weight::new(0, 1).unwrap(); - let smallest_positive = Weight::new(1, u64::MAX).unwrap(); - - assert!(smallest_positive.gt(&zero)); - assert!(zero.lt(&smallest_positive)); - assert!(!zero.eq(&smallest_positive)); - } -} diff --git a/core/src/error.rs b/core/src/error.rs index 1e35939..128fac8 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -11,11 +11,19 @@ pub enum TipRouterError { ArithmeticOverflow = 0x2101, #[error("Modulo Overflow")] ModuloOverflow = 0x2102, + #[error("New precise number error")] + NewPreciseNumberError = 0x2103, + #[error("Cast to imprecise number error")] + CastToImpreciseNumberError = 0x2104, #[error("Incorrect weight table admin")] IncorrectWeightTableAdmin = 0x2200, #[error("Cannnot create future weight tables")] CannotCreateFutureWeightTables = 0x2201, + #[error("Weight mints do not match - length")] + WeightMintsDoNotMatchLength = 0x2202, + #[error("Weight mints do not match - mint hash")] + WeightMintsDoNotMatchMintHash = 0x2203, } impl DecodeError for TipRouterError { diff --git a/core/src/instruction.rs b/core/src/instruction.rs index 4280e99..8f5bf06 100644 --- a/core/src/instruction.rs +++ b/core/src/instruction.rs @@ -23,8 +23,7 @@ pub enum WeightTableInstruction { #[account(3, name = "restaking_program_id")] UpdateWeightTable{ ncn_epoch: u64, - weight_numerator: u64, - weight_denominator: u64, + weight: u128, }, #[account(0, name = "ncn")] @@ -33,6 +32,8 @@ pub enum WeightTableInstruction { #[account(3, name = "restaking_program_id")] FinalizeWeightTable{ ncn_epoch: u64, + mint_hash: u64, + mint_count: u8, }, } diff --git a/core/src/jito_number.rs b/core/src/jito_number.rs new file mode 100644 index 0000000..47c53aa --- /dev/null +++ b/core/src/jito_number.rs @@ -0,0 +1,86 @@ +use bytemuck::{Pod, Zeroable}; +use shank::ShankType; +use spl_math::precise_number::PreciseNumber; + +use crate::error::TipRouterError; + +// Weights are stored as the number of tokens +#[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] +#[repr(C)] +pub struct JitoNumber { + value: [u8; 16], // 128 +} + +impl JitoNumber { + pub const PRECISION_FACTOR: u128 = 1_000_000_000; + + const fn _from_u128(value: u128) -> Self { + let value = value.to_le_bytes(); + Self { value } + } + + const fn _to_u128(&self) -> u128 { + u128::from_le_bytes(self.value) + } + + fn _to_precise_number(&self) -> Result { + PreciseNumber::new(self._to_u128()).ok_or(TipRouterError::NewPreciseNumberError) + } + + fn _from_precise_number(precise_number: PreciseNumber) -> Result { + let value = precise_number + .to_imprecise() + .ok_or(TipRouterError::CastToImpreciseNumberError)?; + + Ok(Self::_from_u128(value)) + } + + fn from_token_supply(token_supply: u64) -> Result { + let value = (token_supply as u128) + .checked_mul(Self::PRECISION_FACTOR) + .ok_or(TipRouterError::ArithmeticOverflow)?; + + Ok(Self::_from_u128(value)) + } + + fn to_token_supply(self) -> Result { + let value = self._to_u128(); + let token_supply = value + .checked_div(Self::PRECISION_FACTOR) + .ok_or(TipRouterError::ArithmeticOverflow)?; + + token_supply + .try_into() + .map_err(|_| TipRouterError::ArithmeticOverflow) + } + + pub fn token_supply_to_precise_number( + token_supply: u64, + ) -> Result { + let value = Self::from_token_supply(token_supply)?; + value._to_precise_number() + } + + pub fn precise_number_to_token_supply( + precise_number: PreciseNumber, + ) -> Result { + let value = Self::_from_precise_number(precise_number)?; + value.to_token_supply() + } + + pub const fn from_weight(weight: u128) -> Self { + Self::_from_u128(weight) + } + + pub const fn to_weight(&self) -> u128 { + self._to_u128() + } + + pub fn weight_to_precise_number(&self) -> Result { + self._to_precise_number() + } + + pub fn precise_number_to_weight(precise_number: PreciseNumber) -> Result { + Self::_from_precise_number(precise_number) + } +} diff --git a/core/src/lib.rs b/core/src/lib.rs index a568233..2f29758 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -2,4 +2,5 @@ pub mod discriminators; pub mod error; pub mod instruction; // pub mod depreciated_weight; +pub mod jito_number; pub mod weight_table; diff --git a/core/src/weight_table.rs b/core/src/weight_table.rs index 61bd2ac..99130ba 100644 --- a/core/src/weight_table.rs +++ b/core/src/weight_table.rs @@ -3,7 +3,7 @@ use jito_bytemuck::{types::PodU64, AccountDeserialize, Discriminator}; use shank::{ShankAccount, ShankType}; use solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}; -use crate::{discriminators::Discriminators, error::TipRouterError}; +use crate::{discriminators::Discriminators, error::TipRouterError, jito_number::JitoNumber}; // PDA'd ["WEIGHT_TABLE", NCN, NCN_EPOCH_SLOT] #[derive(Debug, Clone, Copy, Zeroable, ShankType, Pod, AccountDeserialize, ShankAccount)] @@ -11,10 +11,10 @@ use crate::{discriminators::Discriminators, error::TipRouterError}; pub struct WeightTable { /// The NCN on-chain program is the signer to create and update this account, /// this pushes the responsibility of managing the account to the NCN program. - pub ncn: Pubkey, + ncn: Pubkey, /// The NCN epoch for which the weight table is valid - pub ncn_epoch: PodU64, + ncn_epoch: PodU64, /// Slot weight table was created slot_created: PodU64, @@ -23,13 +23,13 @@ pub struct WeightTable { slot_finalized: PodU64, /// Bump seed for the PDA - pub bump: u8, + bump: u8, /// Reserved space reserved: [u8; 128], /// The weight table - pub table: [WeightEntry; 32], + table: [WeightEntry; 32], } impl Discriminator for WeightTable { @@ -75,35 +75,79 @@ impl WeightTable { (pda, bump, seeds) } + pub fn get_mints(&self) -> Vec { + self.table + .iter() + .filter(|entry| !entry.is_empty()) + .map(|entry| entry.mint) + .collect() + } + + pub fn get_mint_hash(mints: Vec) -> u64 { + let mut hash = 0; + + // Makes sure the hash is the same regardless of the order of the mints + let mut sorted_mints = mints; + sorted_mints.sort(); + + for mint in sorted_mints { + let bytes = mint.to_bytes(); + let u64_slice = u64::from_le_bytes(bytes[0..8].try_into().unwrap()); + + hash ^= u64_slice; + } + + hash + } + + pub fn check_mints_okay(&self, mint_hash: u64, mint_count: u8) -> Result<(), TipRouterError> { + if mint_count != self.entry_count() as u8 { + return Err(TipRouterError::WeightMintsDoNotMatchLength); + } + + let table_mint_hash = Self::get_mint_hash(self.get_mints()); + if mint_hash != table_mint_hash { + return Err(TipRouterError::WeightMintsDoNotMatchMintHash); + } + + Ok(()) + } + pub fn entry_count(&self) -> usize { self.table.iter().filter(|entry| !entry.is_empty()).count() } - pub fn find_weight(&self, mint: &Pubkey) -> Option { + pub fn find_weight(&self, mint: &Pubkey) -> Option { self.table .iter() .find(|entry| entry.mint == *mint) .map(|entry| entry.weight) } - pub fn set_weight(&mut self, mint: &Pubkey, weight: PodU64) -> Result<(), TipRouterError> { - let entry = self - .table - .iter_mut() - .find(|entry| entry.mint == *mint || entry.is_empty()); - - match entry { - Some(entry) => { - entry.weight = weight; + pub fn set_weight(&mut self, mint: &Pubkey, weight: JitoNumber) -> Result<(), TipRouterError> { + // First, try to find an existing entry with the given mint + if let Some(entry) = self.table.iter_mut().find(|entry| entry.mint == *mint) { + entry.weight = weight; + return Ok(()); + } - if entry.mint == Pubkey::default() { - entry.mint = *mint; - } - } - None => return Err(TipRouterError::NoMoreTableSlots), + // If no existing entry found, look for the first empty slot + if let Some(entry) = self.table.iter_mut().find(|entry| entry.is_empty()) { + entry.mint = *mint; + entry.weight = weight; + return Ok(()); } - Ok(()) + // If no existing entry and no empty slots, return error + Err(TipRouterError::NoMoreTableSlots) + } + + pub const fn ncn(&self) -> Pubkey { + self.ncn + } + + pub fn ncn_epoch(&self) -> u64 { + self.ncn_epoch.into() } pub fn slot_created(&self) -> u64 { @@ -134,7 +178,7 @@ impl WeightTable { return Err(ProgramError::InvalidAccountOwner); } if weight_table.data_is_empty() { - msg!("Weight table is empty"); + msg!("Weight table account is empty"); return Err(ProgramError::InvalidAccountData); } if expect_writable && !weight_table.is_writable { @@ -158,18 +202,16 @@ impl WeightTable { #[repr(C)] pub struct WeightEntry { pub mint: Pubkey, - pub weight: PodU64, //TODO Change - // pub weight: Weight, + pub weight: JitoNumber, } impl WeightEntry { - pub const fn new(mint: Pubkey, weight: PodU64) -> Self { + pub const fn new(mint: Pubkey, weight: JitoNumber) -> Self { Self { weight, mint } } pub fn is_empty(&self) -> bool { - self.weight.eq(&PodU64::from(0)) - // self.weight.denominator() == 0 || self.mint.eq(&Pubkey::default()) + self.mint.eq(&Pubkey::default()) } } diff --git a/idl/jito_tip_router.json b/idl/jito_tip_router.json index 3c9eabf..61b1bd5 100644 --- a/idl/jito_tip_router.json +++ b/idl/jito_tip_router.json @@ -79,12 +79,8 @@ "type": "u64" }, { - "name": "weightNumerator", - "type": "u64" - }, - { - "name": "weightDenominator", - "type": "u64" + "name": "weight", + "type": "u128" } ], "discriminant": { @@ -120,6 +116,14 @@ { "name": "ncnEpoch", "type": "u64" + }, + { + "name": "mintHash", + "type": "u64" + }, + { + "name": "mintCount", + "type": "u8" } ], "discriminant": { @@ -185,6 +189,23 @@ } ], "types": [ + { + "name": "JitoNumber", + "type": { + "kind": "struct", + "fields": [ + { + "name": "value", + "type": { + "array": [ + "u8", + 16 + ] + } + } + ] + } + }, { "name": "WeightEntry", "type": { @@ -197,7 +218,7 @@ { "name": "weight", "type": { - "defined": "PodU64" + "defined": "JitoNumber" } } ] @@ -225,6 +246,16 @@ "name": "ModuloOverflow", "msg": "Modulo Overflow" }, + { + "code": 8451, + "name": "NewPreciseNumberError", + "msg": "New precise number error" + }, + { + "code": 8452, + "name": "CastToImpreciseNumberError", + "msg": "Cast to imprecise number error" + }, { "code": 8704, "name": "IncorrectWeightTableAdmin", @@ -234,6 +265,16 @@ "code": 8705, "name": "CannotCreateFutureWeightTables", "msg": "Cannnot create future weight tables" + }, + { + "code": 8706, + "name": "WeightMintsDoNotMatchLength", + "msg": "Weight mints do not match - length" + }, + { + "code": 8707, + "name": "WeightMintsDoNotMatchMintHash", + "msg": "Weight mints do not match - mint hash" } ], "metadata": { diff --git a/program/src/finalize_weight_table.rs b/program/src/finalize_weight_table.rs index 8e5a9f1..76583c0 100644 --- a/program/src/finalize_weight_table.rs +++ b/program/src/finalize_weight_table.rs @@ -12,6 +12,8 @@ pub fn process_finalize_weight_table( program_id: &Pubkey, accounts: &[AccountInfo], ncn_epoch: u64, + mint_hash: u64, + mint_count: u8, ) -> ProgramResult { let [ncn, weight_table, weight_table_admin, restaking_program_id] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); @@ -19,10 +21,9 @@ pub fn process_finalize_weight_table( Ncn::load(restaking_program_id.key, ncn, false)?; let ncn_weight_table_admin = { - //TODO switch to weight table admin when that is merged let ncn_data = ncn.data.borrow(); let ncn = Ncn::try_from_slice_unchecked(&ncn_data)?; - ncn.admin + ncn.weight_table_admin }; load_signer(weight_table_admin, true)?; @@ -41,6 +42,8 @@ pub fn process_finalize_weight_table( let mut weight_table_data = weight_table.try_borrow_mut_data()?; let weight_table_account = WeightTable::try_from_slice_unchecked_mut(&mut weight_table_data)?; + weight_table_account.check_mints_okay(mint_hash, mint_count)?; + let current_slot = Clock::get()?.slot; weight_table_account.finalize(current_slot); diff --git a/program/src/lib.rs b/program/src/lib.rs index 39f150a..6f5f139 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -59,26 +59,20 @@ pub fn process_instruction( // ------------------------------------------ // Update // ------------------------------------------ - WeightTableInstruction::UpdateWeightTable { - ncn_epoch, - weight_numerator, - weight_denominator, - } => { + WeightTableInstruction::UpdateWeightTable { ncn_epoch, weight } => { msg!("Instruction: UpdateWeightTable"); - process_update_weight_table( - program_id, - accounts, - ncn_epoch, - weight_numerator, - weight_denominator, - ) + process_update_weight_table(program_id, accounts, ncn_epoch, weight) } // ------------------------------------------ // Finalization // ------------------------------------------ - WeightTableInstruction::FinalizeWeightTable { ncn_epoch } => { + WeightTableInstruction::FinalizeWeightTable { + ncn_epoch, + mint_hash, + mint_count, + } => { msg!("Instruction: FinalizeWeightTable"); - process_finalize_weight_table(program_id, accounts, ncn_epoch) + process_finalize_weight_table(program_id, accounts, ncn_epoch, mint_hash, mint_count) } } } diff --git a/program/src/update_weight_table.rs b/program/src/update_weight_table.rs index aa9b167..38080f5 100644 --- a/program/src/update_weight_table.rs +++ b/program/src/update_weight_table.rs @@ -1,7 +1,9 @@ -use jito_bytemuck::{types::PodU64, AccountDeserialize}; +use jito_bytemuck::AccountDeserialize; use jito_jsm_core::loader::{load_signer, load_token_mint}; use jito_restaking_core::ncn::Ncn; -use jito_tip_router_core::{error::TipRouterError, weight_table::WeightTable}; +use jito_tip_router_core::{ + error::TipRouterError, jito_number::JitoNumber, weight_table::WeightTable, +}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey, @@ -12,8 +14,7 @@ pub fn process_update_weight_table( program_id: &Pubkey, accounts: &[AccountInfo], ncn_epoch: u64, - weight_numerator: u64, - weight_denominator: u64, + weight: u128, ) -> ProgramResult { let [ncn, weight_table, weight_table_admin, mint, restaking_program_id] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); @@ -44,14 +45,7 @@ pub fn process_update_weight_table( let mut weight_table_data = weight_table.try_borrow_mut_data()?; let weight_table_account = WeightTable::try_from_slice_unchecked_mut(&mut weight_table_data)?; - weight_table_account.set_weight( - mint.key, - PodU64::from( - weight_numerator - .checked_div(weight_denominator) - .ok_or(TipRouterError::DenominatorIsZero)?, - ), - )?; + weight_table_account.set_weight(mint.key, JitoNumber::from_weight(weight))?; Ok(()) } From 736e293bd449310cdcb99925477d0276f2b43810 Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Tue, 5 Nov 2024 17:16:50 -0700 Subject: [PATCH 2/5] update --- clients/js/jito_tip_router/types/index.ts | 4 +- ...{jitoNumber.ts => preciseNumberWrapper.ts} | 18 ++-- .../types/preciseTokenSupply.ts | 44 ++++++++++ .../js/jito_tip_router/types/preciseWeight.ts | 41 +++++++++ .../js/jito_tip_router/types/weightEntry.ts | 16 ++-- .../src/generated/types/mod.rs | 8 +- ...to_number.rs => precise_number_wrapper.rs} | 2 +- .../generated/types/precise_token_supply.rs | 15 ++++ .../src/generated/types/precise_weight.rs | 15 ++++ .../src/generated/types/weight_entry.rs | 4 +- core/src/lib.rs | 3 +- .../{jito_number.rs => precise_numbers.rs} | 86 ++++++++++++------- core/src/weight_table.rs | 16 ++-- idl/jito_tip_router.json | 32 ++++++- program/src/update_weight_table.rs | 4 +- 15 files changed, 246 insertions(+), 62 deletions(-) rename clients/js/jito_tip_router/types/{jitoNumber.ts => preciseNumberWrapper.ts} (55%) create mode 100644 clients/js/jito_tip_router/types/preciseTokenSupply.ts create mode 100644 clients/js/jito_tip_router/types/preciseWeight.ts rename clients/rust/jito_tip_router/src/generated/types/{jito_number.rs => precise_number_wrapper.rs} (92%) create mode 100644 clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs create mode 100644 clients/rust/jito_tip_router/src/generated/types/precise_weight.rs rename core/src/{jito_number.rs => precise_numbers.rs} (54%) diff --git a/clients/js/jito_tip_router/types/index.ts b/clients/js/jito_tip_router/types/index.ts index 0c7494d..88270a5 100644 --- a/clients/js/jito_tip_router/types/index.ts +++ b/clients/js/jito_tip_router/types/index.ts @@ -6,5 +6,7 @@ * @see https://github.com/kinobi-so/kinobi */ -export * from './jitoNumber'; +export * from './preciseNumberWrapper'; +export * from './preciseTokenSupply'; +export * from './preciseWeight'; export * from './weightEntry'; diff --git a/clients/js/jito_tip_router/types/jitoNumber.ts b/clients/js/jito_tip_router/types/preciseNumberWrapper.ts similarity index 55% rename from clients/js/jito_tip_router/types/jitoNumber.ts rename to clients/js/jito_tip_router/types/preciseNumberWrapper.ts index 5347032..74a27dd 100644 --- a/clients/js/jito_tip_router/types/jitoNumber.ts +++ b/clients/js/jito_tip_router/types/preciseNumberWrapper.ts @@ -19,22 +19,28 @@ import { type Encoder, } from '@solana/web3.js'; -export type JitoNumber = { value: Array }; +export type PreciseNumberWrapper = { value: Array }; -export type JitoNumberArgs = JitoNumber; +export type PreciseNumberWrapperArgs = PreciseNumberWrapper; -export function getJitoNumberEncoder(): Encoder { +export function getPreciseNumberWrapperEncoder(): Encoder { return getStructEncoder([ ['value', getArrayEncoder(getU8Encoder(), { size: 16 })], ]); } -export function getJitoNumberDecoder(): Decoder { +export function getPreciseNumberWrapperDecoder(): Decoder { return getStructDecoder([ ['value', getArrayDecoder(getU8Decoder(), { size: 16 })], ]); } -export function getJitoNumberCodec(): Codec { - return combineCodec(getJitoNumberEncoder(), getJitoNumberDecoder()); +export function getPreciseNumberWrapperCodec(): Codec< + PreciseNumberWrapperArgs, + PreciseNumberWrapper +> { + return combineCodec( + getPreciseNumberWrapperEncoder(), + getPreciseNumberWrapperDecoder() + ); } diff --git a/clients/js/jito_tip_router/types/preciseTokenSupply.ts b/clients/js/jito_tip_router/types/preciseTokenSupply.ts new file mode 100644 index 0000000..141243e --- /dev/null +++ b/clients/js/jito_tip_router/types/preciseTokenSupply.ts @@ -0,0 +1,44 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/kinobi-so/kinobi + */ + +import { + combineCodec, + getStructDecoder, + getStructEncoder, + type Codec, + type Decoder, + type Encoder, +} from '@solana/web3.js'; +import { + getPreciseNumberWrapperDecoder, + getPreciseNumberWrapperEncoder, + type PreciseNumberWrapper, + type PreciseNumberWrapperArgs, +} from '.'; + +export type PreciseTokenSupply = { number: PreciseNumberWrapper }; + +export type PreciseTokenSupplyArgs = { number: PreciseNumberWrapperArgs }; + +export function getPreciseTokenSupplyEncoder(): Encoder { + return getStructEncoder([['number', getPreciseNumberWrapperEncoder()]]); +} + +export function getPreciseTokenSupplyDecoder(): Decoder { + return getStructDecoder([['number', getPreciseNumberWrapperDecoder()]]); +} + +export function getPreciseTokenSupplyCodec(): Codec< + PreciseTokenSupplyArgs, + PreciseTokenSupply +> { + return combineCodec( + getPreciseTokenSupplyEncoder(), + getPreciseTokenSupplyDecoder() + ); +} diff --git a/clients/js/jito_tip_router/types/preciseWeight.ts b/clients/js/jito_tip_router/types/preciseWeight.ts new file mode 100644 index 0000000..84c502e --- /dev/null +++ b/clients/js/jito_tip_router/types/preciseWeight.ts @@ -0,0 +1,41 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/kinobi-so/kinobi + */ + +import { + combineCodec, + getStructDecoder, + getStructEncoder, + type Codec, + type Decoder, + type Encoder, +} from '@solana/web3.js'; +import { + getPreciseNumberWrapperDecoder, + getPreciseNumberWrapperEncoder, + type PreciseNumberWrapper, + type PreciseNumberWrapperArgs, +} from '.'; + +export type PreciseWeight = { number: PreciseNumberWrapper }; + +export type PreciseWeightArgs = { number: PreciseNumberWrapperArgs }; + +export function getPreciseWeightEncoder(): Encoder { + return getStructEncoder([['number', getPreciseNumberWrapperEncoder()]]); +} + +export function getPreciseWeightDecoder(): Decoder { + return getStructDecoder([['number', getPreciseNumberWrapperDecoder()]]); +} + +export function getPreciseWeightCodec(): Codec< + PreciseWeightArgs, + PreciseWeight +> { + return combineCodec(getPreciseWeightEncoder(), getPreciseWeightDecoder()); +} diff --git a/clients/js/jito_tip_router/types/weightEntry.ts b/clients/js/jito_tip_router/types/weightEntry.ts index bf66fd3..150271c 100644 --- a/clients/js/jito_tip_router/types/weightEntry.ts +++ b/clients/js/jito_tip_router/types/weightEntry.ts @@ -18,27 +18,27 @@ import { type Encoder, } from '@solana/web3.js'; import { - getJitoNumberDecoder, - getJitoNumberEncoder, - type JitoNumber, - type JitoNumberArgs, + getPreciseWeightDecoder, + getPreciseWeightEncoder, + type PreciseWeight, + type PreciseWeightArgs, } from '.'; -export type WeightEntry = { mint: Address; weight: JitoNumber }; +export type WeightEntry = { mint: Address; weight: PreciseWeight }; -export type WeightEntryArgs = { mint: Address; weight: JitoNumberArgs }; +export type WeightEntryArgs = { mint: Address; weight: PreciseWeightArgs }; export function getWeightEntryEncoder(): Encoder { return getStructEncoder([ ['mint', getAddressEncoder()], - ['weight', getJitoNumberEncoder()], + ['weight', getPreciseWeightEncoder()], ]); } export function getWeightEntryDecoder(): Decoder { return getStructDecoder([ ['mint', getAddressDecoder()], - ['weight', getJitoNumberDecoder()], + ['weight', getPreciseWeightDecoder()], ]); } diff --git a/clients/rust/jito_tip_router/src/generated/types/mod.rs b/clients/rust/jito_tip_router/src/generated/types/mod.rs index be8e546..28bbce7 100644 --- a/clients/rust/jito_tip_router/src/generated/types/mod.rs +++ b/clients/rust/jito_tip_router/src/generated/types/mod.rs @@ -4,7 +4,11 @@ //! //! -pub(crate) mod r#jito_number; +pub(crate) mod r#precise_number_wrapper; +pub(crate) mod r#precise_token_supply; +pub(crate) mod r#precise_weight; pub(crate) mod r#weight_entry; -pub use self::{r#jito_number::*, r#weight_entry::*}; +pub use self::{ + r#precise_number_wrapper::*, r#precise_token_supply::*, r#precise_weight::*, r#weight_entry::*, +}; diff --git a/clients/rust/jito_tip_router/src/generated/types/jito_number.rs b/clients/rust/jito_tip_router/src/generated/types/precise_number_wrapper.rs similarity index 92% rename from clients/rust/jito_tip_router/src/generated/types/jito_number.rs rename to clients/rust/jito_tip_router/src/generated/types/precise_number_wrapper.rs index 76e377d..3d7bb91 100644 --- a/clients/rust/jito_tip_router/src/generated/types/jito_number.rs +++ b/clients/rust/jito_tip_router/src/generated/types/precise_number_wrapper.rs @@ -8,6 +8,6 @@ use borsh::{BorshDeserialize, BorshSerialize}; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct JitoNumber { +pub struct PreciseNumberWrapper { pub value: [u8; 16], } diff --git a/clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs b/clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs new file mode 100644 index 0000000..46fc6e5 --- /dev/null +++ b/clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs @@ -0,0 +1,15 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! + +use borsh::{BorshDeserialize, BorshSerialize}; + +use crate::generated::types::PreciseNumberWrapper; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct PreciseTokenSupply { + pub number: PreciseNumberWrapper, +} diff --git a/clients/rust/jito_tip_router/src/generated/types/precise_weight.rs b/clients/rust/jito_tip_router/src/generated/types/precise_weight.rs new file mode 100644 index 0000000..782ac88 --- /dev/null +++ b/clients/rust/jito_tip_router/src/generated/types/precise_weight.rs @@ -0,0 +1,15 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! + +use borsh::{BorshDeserialize, BorshSerialize}; + +use crate::generated::types::PreciseNumberWrapper; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct PreciseWeight { + pub number: PreciseNumberWrapper, +} diff --git a/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs b/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs index 67e77cf..57e8dd3 100644 --- a/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs +++ b/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs @@ -7,7 +7,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::pubkey::Pubkey; -use crate::generated::types::JitoNumber; +use crate::generated::types::PreciseWeight; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -17,5 +17,5 @@ pub struct WeightEntry { serde(with = "serde_with::As::") )] pub mint: Pubkey, - pub weight: JitoNumber, + pub weight: PreciseWeight, } diff --git a/core/src/lib.rs b/core/src/lib.rs index 2f29758..f6896e7 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,6 +1,5 @@ pub mod discriminators; pub mod error; pub mod instruction; -// pub mod depreciated_weight; -pub mod jito_number; +pub mod precise_numbers; pub mod weight_table; diff --git a/core/src/jito_number.rs b/core/src/precise_numbers.rs similarity index 54% rename from core/src/jito_number.rs rename to core/src/precise_numbers.rs index 47c53aa..1394a6a 100644 --- a/core/src/jito_number.rs +++ b/core/src/precise_numbers.rs @@ -4,47 +4,85 @@ use spl_math::precise_number::PreciseNumber; use crate::error::TipRouterError; -// Weights are stored as the number of tokens +// All arithmetic should be done with PreciseNumber, and cast down to the appropriate types only until all +// calculations are complete. + #[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] #[repr(C)] -pub struct JitoNumber { +pub struct PreciseNumberWrapper { value: [u8; 16], // 128 } -impl JitoNumber { - pub const PRECISION_FACTOR: u128 = 1_000_000_000; - - const fn _from_u128(value: u128) -> Self { +impl PreciseNumberWrapper { + const fn from_u128(value: u128) -> Self { let value = value.to_le_bytes(); Self { value } } - const fn _to_u128(&self) -> u128 { + const fn to_u128(&self) -> u128 { u128::from_le_bytes(self.value) } - fn _to_precise_number(&self) -> Result { - PreciseNumber::new(self._to_u128()).ok_or(TipRouterError::NewPreciseNumberError) + fn to_precise_number(&self) -> Result { + PreciseNumber::new(self.to_u128()).ok_or(TipRouterError::NewPreciseNumberError) } - fn _from_precise_number(precise_number: PreciseNumber) -> Result { + fn from_precise_number(precise_number: PreciseNumber) -> Result { let value = precise_number .to_imprecise() .ok_or(TipRouterError::CastToImpreciseNumberError)?; - Ok(Self::_from_u128(value)) + Ok(Self::from_u128(value)) + } +} + +#[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] +#[repr(C)] +pub struct PreciseWeight { + number: PreciseNumberWrapper, // 128 +} + +impl PreciseWeight { + pub const fn from_weight(weight: u128) -> Self { + let number = PreciseNumberWrapper::from_u128(weight); + Self { number } } + pub const fn to_weight(&self) -> u128 { + self.number.to_u128() + } + + pub fn weight_to_precise_number(&self) -> Result { + self.number.to_precise_number() + } + + pub fn precise_number_to_weight(precise_number: PreciseNumber) -> Result { + let number = PreciseNumberWrapper::from_precise_number(precise_number)?; + Ok(Self { number }) + } +} + +#[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] +#[repr(C)] +pub struct PreciseTokenSupply { + number: PreciseNumberWrapper, // 128 +} + +impl PreciseTokenSupply { + pub const PRECISION_FACTOR: u128 = 1_000_000_000; + fn from_token_supply(token_supply: u64) -> Result { let value = (token_supply as u128) .checked_mul(Self::PRECISION_FACTOR) .ok_or(TipRouterError::ArithmeticOverflow)?; - Ok(Self::_from_u128(value)) + let number = PreciseNumberWrapper::from_u128(value); + + Ok(Self { number }) } fn to_token_supply(self) -> Result { - let value = self._to_u128(); + let value = self.number.to_u128(); let token_supply = value .checked_div(Self::PRECISION_FACTOR) .ok_or(TipRouterError::ArithmeticOverflow)?; @@ -58,29 +96,15 @@ impl JitoNumber { token_supply: u64, ) -> Result { let value = Self::from_token_supply(token_supply)?; - value._to_precise_number() + + value.number.to_precise_number() } pub fn precise_number_to_token_supply( precise_number: PreciseNumber, ) -> Result { - let value = Self::_from_precise_number(precise_number)?; + let number = PreciseNumberWrapper::from_precise_number(precise_number)?; + let value = Self { number }; value.to_token_supply() } - - pub const fn from_weight(weight: u128) -> Self { - Self::_from_u128(weight) - } - - pub const fn to_weight(&self) -> u128 { - self._to_u128() - } - - pub fn weight_to_precise_number(&self) -> Result { - self._to_precise_number() - } - - pub fn precise_number_to_weight(precise_number: PreciseNumber) -> Result { - Self::_from_precise_number(precise_number) - } } diff --git a/core/src/weight_table.rs b/core/src/weight_table.rs index 99130ba..21bef02 100644 --- a/core/src/weight_table.rs +++ b/core/src/weight_table.rs @@ -3,7 +3,9 @@ use jito_bytemuck::{types::PodU64, AccountDeserialize, Discriminator}; use shank::{ShankAccount, ShankType}; use solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}; -use crate::{discriminators::Discriminators, error::TipRouterError, jito_number::JitoNumber}; +use crate::{ + discriminators::Discriminators, error::TipRouterError, precise_numbers::PreciseWeight, +}; // PDA'd ["WEIGHT_TABLE", NCN, NCN_EPOCH_SLOT] #[derive(Debug, Clone, Copy, Zeroable, ShankType, Pod, AccountDeserialize, ShankAccount)] @@ -117,14 +119,18 @@ impl WeightTable { self.table.iter().filter(|entry| !entry.is_empty()).count() } - pub fn find_weight(&self, mint: &Pubkey) -> Option { + pub fn find_weight(&self, mint: &Pubkey) -> Option { self.table .iter() .find(|entry| entry.mint == *mint) .map(|entry| entry.weight) } - pub fn set_weight(&mut self, mint: &Pubkey, weight: JitoNumber) -> Result<(), TipRouterError> { + pub fn set_weight( + &mut self, + mint: &Pubkey, + weight: PreciseWeight, + ) -> Result<(), TipRouterError> { // First, try to find an existing entry with the given mint if let Some(entry) = self.table.iter_mut().find(|entry| entry.mint == *mint) { entry.weight = weight; @@ -202,11 +208,11 @@ impl WeightTable { #[repr(C)] pub struct WeightEntry { pub mint: Pubkey, - pub weight: JitoNumber, + pub weight: PreciseWeight, } impl WeightEntry { - pub const fn new(mint: Pubkey, weight: JitoNumber) -> Self { + pub const fn new(mint: Pubkey, weight: PreciseWeight) -> Self { Self { weight, mint } } diff --git a/idl/jito_tip_router.json b/idl/jito_tip_router.json index 61b1bd5..db3914a 100644 --- a/idl/jito_tip_router.json +++ b/idl/jito_tip_router.json @@ -190,7 +190,7 @@ ], "types": [ { - "name": "JitoNumber", + "name": "PreciseNumberWrapper", "type": { "kind": "struct", "fields": [ @@ -206,6 +206,34 @@ ] } }, + { + "name": "PreciseWeight", + "type": { + "kind": "struct", + "fields": [ + { + "name": "number", + "type": { + "defined": "PreciseNumberWrapper" + } + } + ] + } + }, + { + "name": "PreciseTokenSupply", + "type": { + "kind": "struct", + "fields": [ + { + "name": "number", + "type": { + "defined": "PreciseNumberWrapper" + } + } + ] + } + }, { "name": "WeightEntry", "type": { @@ -218,7 +246,7 @@ { "name": "weight", "type": { - "defined": "JitoNumber" + "defined": "PreciseWeight" } } ] diff --git a/program/src/update_weight_table.rs b/program/src/update_weight_table.rs index 38080f5..1d830d0 100644 --- a/program/src/update_weight_table.rs +++ b/program/src/update_weight_table.rs @@ -2,7 +2,7 @@ use jito_bytemuck::AccountDeserialize; use jito_jsm_core::loader::{load_signer, load_token_mint}; use jito_restaking_core::ncn::Ncn; use jito_tip_router_core::{ - error::TipRouterError, jito_number::JitoNumber, weight_table::WeightTable, + error::TipRouterError, precise_numbers::PreciseWeight, weight_table::WeightTable, }; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError, @@ -45,7 +45,7 @@ pub fn process_update_weight_table( let mut weight_table_data = weight_table.try_borrow_mut_data()?; let weight_table_account = WeightTable::try_from_slice_unchecked_mut(&mut weight_table_data)?; - weight_table_account.set_weight(mint.key, JitoNumber::from_weight(weight))?; + weight_table_account.set_weight(mint.key, PreciseWeight::from_weight(weight))?; Ok(()) } From 6851eee99893e63987f55289a51c2a902bcec9fa Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Thu, 7 Nov 2024 14:01:24 -0700 Subject: [PATCH 3/5] better --- Cargo.lock | 22 +- Cargo.toml | 22 +- .../jito_tip_router/accounts/weightTable.ts | 4 - .../jito_tip_router/errors/jitoTipRouter.ts | 32 +- ...ightTable.ts => adminUpdateWeightTable.ts} | 61 ++- .../instructions/finalizeWeightTable.ts | 242 --------- .../js/jito_tip_router/instructions/index.ts | 3 +- .../instructions/initializeWeightTable.ts | 33 +- .../jito_tip_router/programs/jitoTipRouter.ts | 18 +- clients/js/jito_tip_router/types/index.ts | 3 - .../types/preciseNumberWrapper.ts | 46 -- .../types/preciseTokenSupply.ts | 44 -- .../js/jito_tip_router/types/preciseWeight.ts | 41 -- .../js/jito_tip_router/types/weightEntry.ts | 40 +- .../src/generated/accounts/weight_table.rs | 1 - .../src/generated/errors/jito_tip_router.rs | 30 +- ..._table.rs => admin_update_weight_table.rs} | 62 +-- .../instructions/finalize_weight_table.rs | 496 ------------------ .../instructions/initialize_weight_table.rs | 48 +- .../src/generated/instructions/mod.rs | 7 +- .../src/generated/types/mod.rs | 7 +- .../generated/types/precise_number_wrapper.rs | 13 - .../generated/types/precise_token_supply.rs | 15 - .../src/generated/types/precise_weight.rs | 15 - .../src/generated/types/weight_entry.rs | 8 +- core/src/error.rs | 26 +- core/src/instruction.rs | 15 +- core/src/lib.rs | 2 +- core/src/precise_numbers.rs | 110 ---- core/src/weight_entry.rs | 104 ++++ core/src/weight_table.rs | 283 ++++++---- idl/jito_tip_router.json | 147 ++---- ..._table.rs => admin_update_weight_table.rs} | 16 +- program/src/finalize_weight_table.rs | 51 -- program/src/initialize_weight_table.rs | 25 +- program/src/lib.rs | 21 +- scripts/generate-clients.js | 16 + 37 files changed, 611 insertions(+), 1518 deletions(-) rename clients/js/jito_tip_router/instructions/{updateWeightTable.ts => adminUpdateWeightTable.ts} (76%) delete mode 100644 clients/js/jito_tip_router/instructions/finalizeWeightTable.ts delete mode 100644 clients/js/jito_tip_router/types/preciseNumberWrapper.ts delete mode 100644 clients/js/jito_tip_router/types/preciseTokenSupply.ts delete mode 100644 clients/js/jito_tip_router/types/preciseWeight.ts rename clients/rust/jito_tip_router/src/generated/instructions/{update_weight_table.rs => admin_update_weight_table.rs} (89%) delete mode 100644 clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs delete mode 100644 clients/rust/jito_tip_router/src/generated/types/precise_number_wrapper.rs delete mode 100644 clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs delete mode 100644 clients/rust/jito_tip_router/src/generated/types/precise_weight.rs delete mode 100644 core/src/precise_numbers.rs create mode 100644 core/src/weight_entry.rs rename program/src/{update_weight_table.rs => admin_update_weight_table.rs} (77%) delete mode 100644 program/src/finalize_weight_table.rs diff --git a/Cargo.lock b/Cargo.lock index cf2f54e..1ae6b14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2342,7 +2342,7 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jito-account-traits-derive" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "proc-macro2", "quote", @@ -2352,7 +2352,7 @@ dependencies = [ [[package]] name = "jito-bytemuck" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "bytemuck", @@ -2363,7 +2363,7 @@ dependencies = [ [[package]] name = "jito-jsm-core" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "bytemuck", @@ -2379,7 +2379,7 @@ dependencies = [ [[package]] name = "jito-restaking-client" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "anchor-lang", "borsh 0.10.4", @@ -2396,7 +2396,7 @@ dependencies = [ [[package]] name = "jito-restaking-core" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "bytemuck", @@ -2413,7 +2413,7 @@ dependencies = [ [[package]] name = "jito-restaking-program" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "cfg-if", @@ -2435,7 +2435,7 @@ dependencies = [ [[package]] name = "jito-restaking-sdk" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "shank", @@ -2576,7 +2576,7 @@ dependencies = [ [[package]] name = "jito-vault-client" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "anchor-lang", "borsh 0.10.4", @@ -2593,7 +2593,7 @@ dependencies = [ [[package]] name = "jito-vault-core" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "bytemuck", @@ -2611,7 +2611,7 @@ dependencies = [ [[package]] name = "jito-vault-program" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "cfg-if", @@ -2633,7 +2633,7 @@ dependencies = [ [[package]] name = "jito-vault-sdk" version = "0.0.3" -source = "git+https://github.com/jito-foundation/restaking.git#6dab154dbf8a60176a0b510aa74f17140288496e" +source = "git+https://github.com/jito-foundation/restaking.git?rev=eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d#eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" dependencies = [ "borsh 0.10.4", "shank", diff --git a/Cargo.toml b/Cargo.toml index 6d71fef..d8b6127 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,14 +69,14 @@ jito-tip-router-client = { path = "./clients/rust/jito_tip_router", version = "0 jito-tip-router-core = { path = "./core", version = "=0.0.1" } jito-tip-router-program = { path = "./program", version = "=0.0.1" } jito-tip-router-shank-cli = { path = "./shank_cli", version = "=0.0.1" } -jito-bytemuck = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-account-traits-derive = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-jsm-core = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-restaking-client = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-restaking-core = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-restaking-program = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3", features = ["no-entrypoint"] } -jito-restaking-sdk = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-vault-client = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-vault-core = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } -jito-vault-program = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3", features = ["no-entrypoint"] } -jito-vault-sdk = { git = "https://github.com/jito-foundation/restaking.git", version = "=0.0.3" } +jito-bytemuck = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-account-traits-derive = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-jsm-core = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-restaking-client = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-restaking-core = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-restaking-program = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d", features = ["no-entrypoint"] } +jito-restaking-sdk = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-vault-client = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-vault-core = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } +jito-vault-program = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d", features = ["no-entrypoint"] } +jito-vault-sdk = { git = "https://github.com/jito-foundation/restaking.git", rev = "eaf88e7e5ca2845fe3108c4fc4a06a25f9a8514d" } diff --git a/clients/js/jito_tip_router/accounts/weightTable.ts b/clients/js/jito_tip_router/accounts/weightTable.ts index bfccf1d..2e051e9 100644 --- a/clients/js/jito_tip_router/accounts/weightTable.ts +++ b/clients/js/jito_tip_router/accounts/weightTable.ts @@ -46,7 +46,6 @@ export type WeightTable = { ncn: Address; ncnEpoch: bigint; slotCreated: bigint; - slotFinalized: bigint; bump: number; reserved: Array; table: Array; @@ -57,7 +56,6 @@ export type WeightTableArgs = { ncn: Address; ncnEpoch: number | bigint; slotCreated: number | bigint; - slotFinalized: number | bigint; bump: number; reserved: Array; table: Array; @@ -69,7 +67,6 @@ export function getWeightTableEncoder(): Encoder { ['ncn', getAddressEncoder()], ['ncnEpoch', getU64Encoder()], ['slotCreated', getU64Encoder()], - ['slotFinalized', getU64Encoder()], ['bump', getU8Encoder()], ['reserved', getArrayEncoder(getU8Encoder(), { size: 128 })], ['table', getArrayEncoder(getWeightEntryEncoder(), { size: 32 })], @@ -82,7 +79,6 @@ export function getWeightTableDecoder(): Decoder { ['ncn', getAddressDecoder()], ['ncnEpoch', getU64Decoder()], ['slotCreated', getU64Decoder()], - ['slotFinalized', getU64Decoder()], ['bump', getU8Decoder()], ['reserved', getArrayDecoder(getU8Decoder(), { size: 128 })], ['table', getArrayDecoder(getWeightEntryDecoder(), { size: 32 })], diff --git a/clients/js/jito_tip_router/errors/jitoTipRouter.ts b/clients/js/jito_tip_router/errors/jitoTipRouter.ts index 6184f66..02637ce 100644 --- a/clients/js/jito_tip_router/errors/jitoTipRouter.ts +++ b/clients/js/jito_tip_router/errors/jitoTipRouter.ts @@ -14,8 +14,6 @@ import { } from '@solana/web3.js'; import { JITO_TIP_ROUTER_PROGRAM_ADDRESS } from '../programs'; -/** NoMoreTableSlots: No more table slots available */ -export const JITO_TIP_ROUTER_ERROR__NO_MORE_TABLE_SLOTS = 0x2000; // 8192 /** DenominatorIsZero: Zero in the denominator */ export const JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO = 0x2100; // 8448 /** ArithmeticOverflow: Overflow */ @@ -28,24 +26,38 @@ export const JITO_TIP_ROUTER_ERROR__NEW_PRECISE_NUMBER_ERROR = 0x2103; // 8451 export const JITO_TIP_ROUTER_ERROR__CAST_TO_IMPRECISE_NUMBER_ERROR = 0x2104; // 8452 /** IncorrectWeightTableAdmin: Incorrect weight table admin */ export const JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN = 0x2200; // 8704 +/** DuplicateMintsInTable: Duplicate mints in table */ +export const JITO_TIP_ROUTER_ERROR__DUPLICATE_MINTS_IN_TABLE = 0x2201; // 8705 +/** NoMintsInTable: There are no mints in the table */ +export const JITO_TIP_ROUTER_ERROR__NO_MINTS_IN_TABLE = 0x2202; // 8706 +/** TooManyMintsForTable: Too many mints for table */ +export const JITO_TIP_ROUTER_ERROR__TOO_MANY_MINTS_FOR_TABLE = 0x2203; // 8707 +/** WeightTableAlreadyInitialized: Weight table already initialized */ +export const JITO_TIP_ROUTER_ERROR__WEIGHT_TABLE_ALREADY_INITIALIZED = 0x2204; // 8708 /** CannotCreateFutureWeightTables: Cannnot create future weight tables */ -export const JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES = 0x2201; // 8705 +export const JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES = 0x2205; // 8709 /** WeightMintsDoNotMatchLength: Weight mints do not match - length */ -export const JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_LENGTH = 0x2202; // 8706 +export const JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_LENGTH = 0x2206; // 8710 /** WeightMintsDoNotMatchMintHash: Weight mints do not match - mint hash */ -export const JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH = 0x2203; // 8707 +export const JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH = 0x2207; // 8711 +/** InvalidMintForWeightTable: Invalid mint for weight table */ +export const JITO_TIP_ROUTER_ERROR__INVALID_MINT_FOR_WEIGHT_TABLE = 0x2208; // 8712 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__CAST_TO_IMPRECISE_NUMBER_ERROR | typeof JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO + | typeof JITO_TIP_ROUTER_ERROR__DUPLICATE_MINTS_IN_TABLE | typeof JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN + | typeof JITO_TIP_ROUTER_ERROR__INVALID_MINT_FOR_WEIGHT_TABLE | typeof JITO_TIP_ROUTER_ERROR__MODULO_OVERFLOW | typeof JITO_TIP_ROUTER_ERROR__NEW_PRECISE_NUMBER_ERROR - | typeof JITO_TIP_ROUTER_ERROR__NO_MORE_TABLE_SLOTS + | typeof JITO_TIP_ROUTER_ERROR__NO_MINTS_IN_TABLE + | typeof JITO_TIP_ROUTER_ERROR__TOO_MANY_MINTS_FOR_TABLE | typeof JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_LENGTH - | typeof JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH; + | typeof JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH + | typeof JITO_TIP_ROUTER_ERROR__WEIGHT_TABLE_ALREADY_INITIALIZED; let jitoTipRouterErrorMessages: Record | undefined; if (process.env.NODE_ENV !== 'production') { @@ -54,12 +66,16 @@ if (process.env.NODE_ENV !== 'production') { [JITO_TIP_ROUTER_ERROR__CANNOT_CREATE_FUTURE_WEIGHT_TABLES]: `Cannnot create future weight tables`, [JITO_TIP_ROUTER_ERROR__CAST_TO_IMPRECISE_NUMBER_ERROR]: `Cast to imprecise number error`, [JITO_TIP_ROUTER_ERROR__DENOMINATOR_IS_ZERO]: `Zero in the denominator`, + [JITO_TIP_ROUTER_ERROR__DUPLICATE_MINTS_IN_TABLE]: `Duplicate mints in table`, [JITO_TIP_ROUTER_ERROR__INCORRECT_WEIGHT_TABLE_ADMIN]: `Incorrect weight table admin`, + [JITO_TIP_ROUTER_ERROR__INVALID_MINT_FOR_WEIGHT_TABLE]: `Invalid mint for weight table`, [JITO_TIP_ROUTER_ERROR__MODULO_OVERFLOW]: `Modulo Overflow`, [JITO_TIP_ROUTER_ERROR__NEW_PRECISE_NUMBER_ERROR]: `New precise number error`, - [JITO_TIP_ROUTER_ERROR__NO_MORE_TABLE_SLOTS]: `No more table slots available`, + [JITO_TIP_ROUTER_ERROR__NO_MINTS_IN_TABLE]: `There are no mints in the table`, + [JITO_TIP_ROUTER_ERROR__TOO_MANY_MINTS_FOR_TABLE]: `Too many mints for table`, [JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_LENGTH]: `Weight mints do not match - length`, [JITO_TIP_ROUTER_ERROR__WEIGHT_MINTS_DO_NOT_MATCH_MINT_HASH]: `Weight mints do not match - mint hash`, + [JITO_TIP_ROUTER_ERROR__WEIGHT_TABLE_ALREADY_INITIALIZED]: `Weight table already initialized`, }; } diff --git a/clients/js/jito_tip_router/instructions/updateWeightTable.ts b/clients/js/jito_tip_router/instructions/adminUpdateWeightTable.ts similarity index 76% rename from clients/js/jito_tip_router/instructions/updateWeightTable.ts rename to clients/js/jito_tip_router/instructions/adminUpdateWeightTable.ts index 0fd6673..d202730 100644 --- a/clients/js/jito_tip_router/instructions/updateWeightTable.ts +++ b/clients/js/jito_tip_router/instructions/adminUpdateWeightTable.ts @@ -34,13 +34,13 @@ import { import { JITO_TIP_ROUTER_PROGRAM_ADDRESS } from '../programs'; import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; -export const UPDATE_WEIGHT_TABLE_DISCRIMINATOR = 1; +export const ADMIN_UPDATE_WEIGHT_TABLE_DISCRIMINATOR = 1; -export function getUpdateWeightTableDiscriminatorBytes() { - return getU8Encoder().encode(UPDATE_WEIGHT_TABLE_DISCRIMINATOR); +export function getAdminUpdateWeightTableDiscriminatorBytes() { + return getU8Encoder().encode(ADMIN_UPDATE_WEIGHT_TABLE_DISCRIMINATOR); } -export type UpdateWeightTableInstruction< +export type AdminUpdateWeightTableInstruction< TProgram extends string = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, TAccountNcn extends string | IAccountMeta = string, TAccountWeightTable extends string | IAccountMeta = string, @@ -66,29 +66,32 @@ export type UpdateWeightTableInstruction< ] >; -export type UpdateWeightTableInstructionData = { +export type AdminUpdateWeightTableInstructionData = { discriminator: number; ncnEpoch: bigint; weight: bigint; }; -export type UpdateWeightTableInstructionDataArgs = { +export type AdminUpdateWeightTableInstructionDataArgs = { ncnEpoch: number | bigint; weight: number | bigint; }; -export function getUpdateWeightTableInstructionDataEncoder(): Encoder { +export function getAdminUpdateWeightTableInstructionDataEncoder(): Encoder { return transformEncoder( getStructEncoder([ ['discriminator', getU8Encoder()], ['ncnEpoch', getU64Encoder()], ['weight', getU128Encoder()], ]), - (value) => ({ ...value, discriminator: UPDATE_WEIGHT_TABLE_DISCRIMINATOR }) + (value) => ({ + ...value, + discriminator: ADMIN_UPDATE_WEIGHT_TABLE_DISCRIMINATOR, + }) ); } -export function getUpdateWeightTableInstructionDataDecoder(): Decoder { +export function getAdminUpdateWeightTableInstructionDataDecoder(): Decoder { return getStructDecoder([ ['discriminator', getU8Decoder()], ['ncnEpoch', getU64Decoder()], @@ -96,17 +99,17 @@ export function getUpdateWeightTableInstructionDataDecoder(): Decoder { return combineCodec( - getUpdateWeightTableInstructionDataEncoder(), - getUpdateWeightTableInstructionDataDecoder() + getAdminUpdateWeightTableInstructionDataEncoder(), + getAdminUpdateWeightTableInstructionDataDecoder() ); } -export type UpdateWeightTableInput< +export type AdminUpdateWeightTableInput< TAccountNcn extends string = string, TAccountWeightTable extends string = string, TAccountWeightTableAdmin extends string = string, @@ -116,25 +119,25 @@ export type UpdateWeightTableInput< weightTable: Address; weightTableAdmin: TransactionSigner; restakingProgramId: Address; - ncnEpoch: UpdateWeightTableInstructionDataArgs['ncnEpoch']; - weight: UpdateWeightTableInstructionDataArgs['weight']; + ncnEpoch: AdminUpdateWeightTableInstructionDataArgs['ncnEpoch']; + weight: AdminUpdateWeightTableInstructionDataArgs['weight']; }; -export function getUpdateWeightTableInstruction< +export function getAdminUpdateWeightTableInstruction< TAccountNcn extends string, TAccountWeightTable extends string, TAccountWeightTableAdmin extends string, TAccountRestakingProgramId extends string, TProgramAddress extends Address = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, >( - input: UpdateWeightTableInput< + input: AdminUpdateWeightTableInput< TAccountNcn, TAccountWeightTable, TAccountWeightTableAdmin, TAccountRestakingProgramId >, config?: { programAddress?: TProgramAddress } -): UpdateWeightTableInstruction< +): AdminUpdateWeightTableInstruction< TProgramAddress, TAccountNcn, TAccountWeightTable, @@ -175,10 +178,10 @@ export function getUpdateWeightTableInstruction< getAccountMeta(accounts.restakingProgramId), ], programAddress, - data: getUpdateWeightTableInstructionDataEncoder().encode( - args as UpdateWeightTableInstructionDataArgs + data: getAdminUpdateWeightTableInstructionDataEncoder().encode( + args as AdminUpdateWeightTableInstructionDataArgs ), - } as UpdateWeightTableInstruction< + } as AdminUpdateWeightTableInstruction< TProgramAddress, TAccountNcn, TAccountWeightTable, @@ -189,7 +192,7 @@ export function getUpdateWeightTableInstruction< return instruction; } -export type ParsedUpdateWeightTableInstruction< +export type ParsedAdminUpdateWeightTableInstruction< TProgram extends string = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[], > = { @@ -200,17 +203,17 @@ export type ParsedUpdateWeightTableInstruction< weightTableAdmin: TAccountMetas[2]; restakingProgramId: TAccountMetas[3]; }; - data: UpdateWeightTableInstructionData; + data: AdminUpdateWeightTableInstructionData; }; -export function parseUpdateWeightTableInstruction< +export function parseAdminUpdateWeightTableInstruction< TProgram extends string, TAccountMetas extends readonly IAccountMeta[], >( instruction: IInstruction & IInstructionWithAccounts & IInstructionWithData -): ParsedUpdateWeightTableInstruction { +): ParsedAdminUpdateWeightTableInstruction { if (instruction.accounts.length < 4) { // TODO: Coded error. throw new Error('Not enough accounts'); @@ -229,6 +232,8 @@ export function parseUpdateWeightTableInstruction< weightTableAdmin: getNextAccount(), restakingProgramId: getNextAccount(), }, - data: getUpdateWeightTableInstructionDataDecoder().decode(instruction.data), + data: getAdminUpdateWeightTableInstructionDataDecoder().decode( + instruction.data + ), }; } diff --git a/clients/js/jito_tip_router/instructions/finalizeWeightTable.ts b/clients/js/jito_tip_router/instructions/finalizeWeightTable.ts deleted file mode 100644 index ff56556..0000000 --- a/clients/js/jito_tip_router/instructions/finalizeWeightTable.ts +++ /dev/null @@ -1,242 +0,0 @@ -/** - * This code was AUTOGENERATED using the kinobi library. - * Please DO NOT EDIT THIS FILE, instead use visitors - * to add features, then rerun kinobi to update it. - * - * @see https://github.com/kinobi-so/kinobi - */ - -import { - combineCodec, - getStructDecoder, - getStructEncoder, - getU64Decoder, - getU64Encoder, - getU8Decoder, - getU8Encoder, - transformEncoder, - type Address, - type Codec, - type Decoder, - type Encoder, - type IAccountMeta, - type IAccountSignerMeta, - type IInstruction, - type IInstructionWithAccounts, - type IInstructionWithData, - type ReadonlyAccount, - type ReadonlySignerAccount, - type TransactionSigner, - type WritableAccount, -} from '@solana/web3.js'; -import { JITO_TIP_ROUTER_PROGRAM_ADDRESS } from '../programs'; -import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; - -export const FINALIZE_WEIGHT_TABLE_DISCRIMINATOR = 2; - -export function getFinalizeWeightTableDiscriminatorBytes() { - return getU8Encoder().encode(FINALIZE_WEIGHT_TABLE_DISCRIMINATOR); -} - -export type FinalizeWeightTableInstruction< - TProgram extends string = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, - TAccountNcn extends string | IAccountMeta = string, - TAccountWeightTable extends string | IAccountMeta = string, - TAccountWeightTableAdmin extends string | IAccountMeta = string, - TAccountRestakingProgramId extends string | IAccountMeta = string, - TRemainingAccounts extends readonly IAccountMeta[] = [], -> = IInstruction & - IInstructionWithData & - IInstructionWithAccounts< - [ - TAccountNcn extends string ? ReadonlyAccount : TAccountNcn, - TAccountWeightTable extends string - ? WritableAccount - : TAccountWeightTable, - TAccountWeightTableAdmin extends string - ? ReadonlySignerAccount & - IAccountSignerMeta - : TAccountWeightTableAdmin, - TAccountRestakingProgramId extends string - ? ReadonlyAccount - : TAccountRestakingProgramId, - ...TRemainingAccounts, - ] - >; - -export type FinalizeWeightTableInstructionData = { - discriminator: number; - ncnEpoch: bigint; - mintHash: bigint; - mintCount: number; -}; - -export type FinalizeWeightTableInstructionDataArgs = { - ncnEpoch: number | bigint; - mintHash: number | bigint; - mintCount: number; -}; - -export function getFinalizeWeightTableInstructionDataEncoder(): Encoder { - return transformEncoder( - getStructEncoder([ - ['discriminator', getU8Encoder()], - ['ncnEpoch', getU64Encoder()], - ['mintHash', getU64Encoder()], - ['mintCount', getU8Encoder()], - ]), - (value) => ({ - ...value, - discriminator: FINALIZE_WEIGHT_TABLE_DISCRIMINATOR, - }) - ); -} - -export function getFinalizeWeightTableInstructionDataDecoder(): Decoder { - return getStructDecoder([ - ['discriminator', getU8Decoder()], - ['ncnEpoch', getU64Decoder()], - ['mintHash', getU64Decoder()], - ['mintCount', getU8Decoder()], - ]); -} - -export function getFinalizeWeightTableInstructionDataCodec(): Codec< - FinalizeWeightTableInstructionDataArgs, - FinalizeWeightTableInstructionData -> { - return combineCodec( - getFinalizeWeightTableInstructionDataEncoder(), - getFinalizeWeightTableInstructionDataDecoder() - ); -} - -export type FinalizeWeightTableInput< - TAccountNcn extends string = string, - TAccountWeightTable extends string = string, - TAccountWeightTableAdmin extends string = string, - TAccountRestakingProgramId extends string = string, -> = { - ncn: Address; - weightTable: Address; - weightTableAdmin: TransactionSigner; - restakingProgramId: Address; - ncnEpoch: FinalizeWeightTableInstructionDataArgs['ncnEpoch']; - mintHash: FinalizeWeightTableInstructionDataArgs['mintHash']; - mintCount: FinalizeWeightTableInstructionDataArgs['mintCount']; -}; - -export function getFinalizeWeightTableInstruction< - TAccountNcn extends string, - TAccountWeightTable extends string, - TAccountWeightTableAdmin extends string, - TAccountRestakingProgramId extends string, - TProgramAddress extends Address = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, ->( - input: FinalizeWeightTableInput< - TAccountNcn, - TAccountWeightTable, - TAccountWeightTableAdmin, - TAccountRestakingProgramId - >, - config?: { programAddress?: TProgramAddress } -): FinalizeWeightTableInstruction< - TProgramAddress, - TAccountNcn, - TAccountWeightTable, - TAccountWeightTableAdmin, - TAccountRestakingProgramId -> { - // Program address. - const programAddress = - config?.programAddress ?? JITO_TIP_ROUTER_PROGRAM_ADDRESS; - - // Original accounts. - const originalAccounts = { - ncn: { value: input.ncn ?? null, isWritable: false }, - weightTable: { value: input.weightTable ?? null, isWritable: true }, - weightTableAdmin: { - value: input.weightTableAdmin ?? null, - isWritable: false, - }, - restakingProgramId: { - value: input.restakingProgramId ?? null, - isWritable: false, - }, - }; - const accounts = originalAccounts as Record< - keyof typeof originalAccounts, - ResolvedAccount - >; - - // Original args. - const args = { ...input }; - - const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); - const instruction = { - accounts: [ - getAccountMeta(accounts.ncn), - getAccountMeta(accounts.weightTable), - getAccountMeta(accounts.weightTableAdmin), - getAccountMeta(accounts.restakingProgramId), - ], - programAddress, - data: getFinalizeWeightTableInstructionDataEncoder().encode( - args as FinalizeWeightTableInstructionDataArgs - ), - } as FinalizeWeightTableInstruction< - TProgramAddress, - TAccountNcn, - TAccountWeightTable, - TAccountWeightTableAdmin, - TAccountRestakingProgramId - >; - - return instruction; -} - -export type ParsedFinalizeWeightTableInstruction< - TProgram extends string = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, - TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[], -> = { - programAddress: Address; - accounts: { - ncn: TAccountMetas[0]; - weightTable: TAccountMetas[1]; - weightTableAdmin: TAccountMetas[2]; - restakingProgramId: TAccountMetas[3]; - }; - data: FinalizeWeightTableInstructionData; -}; - -export function parseFinalizeWeightTableInstruction< - TProgram extends string, - TAccountMetas extends readonly IAccountMeta[], ->( - instruction: IInstruction & - IInstructionWithAccounts & - IInstructionWithData -): ParsedFinalizeWeightTableInstruction { - if (instruction.accounts.length < 4) { - // TODO: Coded error. - throw new Error('Not enough accounts'); - } - let accountIndex = 0; - const getNextAccount = () => { - const accountMeta = instruction.accounts![accountIndex]!; - accountIndex += 1; - return accountMeta; - }; - return { - programAddress: instruction.programAddress, - accounts: { - ncn: getNextAccount(), - weightTable: getNextAccount(), - weightTableAdmin: getNextAccount(), - restakingProgramId: getNextAccount(), - }, - data: getFinalizeWeightTableInstructionDataDecoder().decode( - instruction.data - ), - }; -} diff --git a/clients/js/jito_tip_router/instructions/index.ts b/clients/js/jito_tip_router/instructions/index.ts index e121ff7..1ae7603 100644 --- a/clients/js/jito_tip_router/instructions/index.ts +++ b/clients/js/jito_tip_router/instructions/index.ts @@ -6,6 +6,5 @@ * @see https://github.com/kinobi-so/kinobi */ -export * from './finalizeWeightTable'; +export * from './adminUpdateWeightTable'; export * from './initializeWeightTable'; -export * from './updateWeightTable'; diff --git a/clients/js/jito_tip_router/instructions/initializeWeightTable.ts b/clients/js/jito_tip_router/instructions/initializeWeightTable.ts index 04154c3..2a98685 100644 --- a/clients/js/jito_tip_router/instructions/initializeWeightTable.ts +++ b/clients/js/jito_tip_router/instructions/initializeWeightTable.ts @@ -46,7 +46,7 @@ export type InitializeWeightTableInstruction< TAccountRestakingConfig extends string | IAccountMeta = string, TAccountNcn extends string | IAccountMeta = string, TAccountWeightTable extends string | IAccountMeta = string, - TAccountWeightTableAdmin extends string | IAccountMeta = string, + TAccountPayer extends string | IAccountMeta = string, TAccountRestakingProgramId extends string | IAccountMeta = string, TAccountSystemProgram extends | string @@ -64,10 +64,10 @@ export type InitializeWeightTableInstruction< ? WritableSignerAccount & IAccountSignerMeta : TAccountWeightTable, - TAccountWeightTableAdmin extends string - ? WritableSignerAccount & - IAccountSignerMeta - : TAccountWeightTableAdmin, + TAccountPayer extends string + ? WritableSignerAccount & + IAccountSignerMeta + : TAccountPayer, TAccountRestakingProgramId extends string ? ReadonlyAccount : TAccountRestakingProgramId, @@ -121,14 +121,14 @@ export type InitializeWeightTableInput< TAccountRestakingConfig extends string = string, TAccountNcn extends string = string, TAccountWeightTable extends string = string, - TAccountWeightTableAdmin extends string = string, + TAccountPayer extends string = string, TAccountRestakingProgramId extends string = string, TAccountSystemProgram extends string = string, > = { restakingConfig: Address; ncn: Address; weightTable: TransactionSigner; - weightTableAdmin: TransactionSigner; + payer: TransactionSigner; restakingProgramId: Address; systemProgram?: Address; firstSlotOfNcnEpoch: InitializeWeightTableInstructionDataArgs['firstSlotOfNcnEpoch']; @@ -138,7 +138,7 @@ export function getInitializeWeightTableInstruction< TAccountRestakingConfig extends string, TAccountNcn extends string, TAccountWeightTable extends string, - TAccountWeightTableAdmin extends string, + TAccountPayer extends string, TAccountRestakingProgramId extends string, TAccountSystemProgram extends string, TProgramAddress extends Address = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, @@ -147,7 +147,7 @@ export function getInitializeWeightTableInstruction< TAccountRestakingConfig, TAccountNcn, TAccountWeightTable, - TAccountWeightTableAdmin, + TAccountPayer, TAccountRestakingProgramId, TAccountSystemProgram >, @@ -157,7 +157,7 @@ export function getInitializeWeightTableInstruction< TAccountRestakingConfig, TAccountNcn, TAccountWeightTable, - TAccountWeightTableAdmin, + TAccountPayer, TAccountRestakingProgramId, TAccountSystemProgram > { @@ -173,10 +173,7 @@ export function getInitializeWeightTableInstruction< }, ncn: { value: input.ncn ?? null, isWritable: false }, weightTable: { value: input.weightTable ?? null, isWritable: true }, - weightTableAdmin: { - value: input.weightTableAdmin ?? null, - isWritable: true, - }, + payer: { value: input.payer ?? null, isWritable: true }, restakingProgramId: { value: input.restakingProgramId ?? null, isWritable: false, @@ -203,7 +200,7 @@ export function getInitializeWeightTableInstruction< getAccountMeta(accounts.restakingConfig), getAccountMeta(accounts.ncn), getAccountMeta(accounts.weightTable), - getAccountMeta(accounts.weightTableAdmin), + getAccountMeta(accounts.payer), getAccountMeta(accounts.restakingProgramId), getAccountMeta(accounts.systemProgram), ], @@ -216,7 +213,7 @@ export function getInitializeWeightTableInstruction< TAccountRestakingConfig, TAccountNcn, TAccountWeightTable, - TAccountWeightTableAdmin, + TAccountPayer, TAccountRestakingProgramId, TAccountSystemProgram >; @@ -233,7 +230,7 @@ export type ParsedInitializeWeightTableInstruction< restakingConfig: TAccountMetas[0]; ncn: TAccountMetas[1]; weightTable: TAccountMetas[2]; - weightTableAdmin: TAccountMetas[3]; + payer: TAccountMetas[3]; restakingProgramId: TAccountMetas[4]; systemProgram: TAccountMetas[5]; }; @@ -264,7 +261,7 @@ export function parseInitializeWeightTableInstruction< restakingConfig: getNextAccount(), ncn: getNextAccount(), weightTable: getNextAccount(), - weightTableAdmin: getNextAccount(), + payer: getNextAccount(), restakingProgramId: getNextAccount(), systemProgram: getNextAccount(), }, diff --git a/clients/js/jito_tip_router/programs/jitoTipRouter.ts b/clients/js/jito_tip_router/programs/jitoTipRouter.ts index c29d1e5..a3febd1 100644 --- a/clients/js/jito_tip_router/programs/jitoTipRouter.ts +++ b/clients/js/jito_tip_router/programs/jitoTipRouter.ts @@ -13,9 +13,8 @@ import { type ReadonlyUint8Array, } from '@solana/web3.js'; import { - type ParsedFinalizeWeightTableInstruction, + type ParsedAdminUpdateWeightTableInstruction, type ParsedInitializeWeightTableInstruction, - type ParsedUpdateWeightTableInstruction, } from '../instructions'; export const JITO_TIP_ROUTER_PROGRAM_ADDRESS = @@ -27,8 +26,7 @@ export enum JitoTipRouterAccount { export enum JitoTipRouterInstruction { InitializeWeightTable, - UpdateWeightTable, - FinalizeWeightTable, + AdminUpdateWeightTable, } export function identifyJitoTipRouterInstruction( @@ -39,10 +37,7 @@ export function identifyJitoTipRouterInstruction( return JitoTipRouterInstruction.InitializeWeightTable; } if (containsBytes(data, getU8Encoder().encode(1), 0)) { - return JitoTipRouterInstruction.UpdateWeightTable; - } - if (containsBytes(data, getU8Encoder().encode(2), 0)) { - return JitoTipRouterInstruction.FinalizeWeightTable; + return JitoTipRouterInstruction.AdminUpdateWeightTable; } throw new Error( 'The provided instruction could not be identified as a jitoTipRouter instruction.' @@ -56,8 +51,5 @@ export type ParsedJitoTipRouterInstruction< instructionType: JitoTipRouterInstruction.InitializeWeightTable; } & ParsedInitializeWeightTableInstruction) | ({ - instructionType: JitoTipRouterInstruction.UpdateWeightTable; - } & ParsedUpdateWeightTableInstruction) - | ({ - instructionType: JitoTipRouterInstruction.FinalizeWeightTable; - } & ParsedFinalizeWeightTableInstruction); + instructionType: JitoTipRouterInstruction.AdminUpdateWeightTable; + } & ParsedAdminUpdateWeightTableInstruction); diff --git a/clients/js/jito_tip_router/types/index.ts b/clients/js/jito_tip_router/types/index.ts index 88270a5..5597466 100644 --- a/clients/js/jito_tip_router/types/index.ts +++ b/clients/js/jito_tip_router/types/index.ts @@ -6,7 +6,4 @@ * @see https://github.com/kinobi-so/kinobi */ -export * from './preciseNumberWrapper'; -export * from './preciseTokenSupply'; -export * from './preciseWeight'; export * from './weightEntry'; diff --git a/clients/js/jito_tip_router/types/preciseNumberWrapper.ts b/clients/js/jito_tip_router/types/preciseNumberWrapper.ts deleted file mode 100644 index 74a27dd..0000000 --- a/clients/js/jito_tip_router/types/preciseNumberWrapper.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** - * This code was AUTOGENERATED using the kinobi library. - * Please DO NOT EDIT THIS FILE, instead use visitors - * to add features, then rerun kinobi to update it. - * - * @see https://github.com/kinobi-so/kinobi - */ - -import { - combineCodec, - getArrayDecoder, - getArrayEncoder, - getStructDecoder, - getStructEncoder, - getU8Decoder, - getU8Encoder, - type Codec, - type Decoder, - type Encoder, -} from '@solana/web3.js'; - -export type PreciseNumberWrapper = { value: Array }; - -export type PreciseNumberWrapperArgs = PreciseNumberWrapper; - -export function getPreciseNumberWrapperEncoder(): Encoder { - return getStructEncoder([ - ['value', getArrayEncoder(getU8Encoder(), { size: 16 })], - ]); -} - -export function getPreciseNumberWrapperDecoder(): Decoder { - return getStructDecoder([ - ['value', getArrayDecoder(getU8Decoder(), { size: 16 })], - ]); -} - -export function getPreciseNumberWrapperCodec(): Codec< - PreciseNumberWrapperArgs, - PreciseNumberWrapper -> { - return combineCodec( - getPreciseNumberWrapperEncoder(), - getPreciseNumberWrapperDecoder() - ); -} diff --git a/clients/js/jito_tip_router/types/preciseTokenSupply.ts b/clients/js/jito_tip_router/types/preciseTokenSupply.ts deleted file mode 100644 index 141243e..0000000 --- a/clients/js/jito_tip_router/types/preciseTokenSupply.ts +++ /dev/null @@ -1,44 +0,0 @@ -/** - * This code was AUTOGENERATED using the kinobi library. - * Please DO NOT EDIT THIS FILE, instead use visitors - * to add features, then rerun kinobi to update it. - * - * @see https://github.com/kinobi-so/kinobi - */ - -import { - combineCodec, - getStructDecoder, - getStructEncoder, - type Codec, - type Decoder, - type Encoder, -} from '@solana/web3.js'; -import { - getPreciseNumberWrapperDecoder, - getPreciseNumberWrapperEncoder, - type PreciseNumberWrapper, - type PreciseNumberWrapperArgs, -} from '.'; - -export type PreciseTokenSupply = { number: PreciseNumberWrapper }; - -export type PreciseTokenSupplyArgs = { number: PreciseNumberWrapperArgs }; - -export function getPreciseTokenSupplyEncoder(): Encoder { - return getStructEncoder([['number', getPreciseNumberWrapperEncoder()]]); -} - -export function getPreciseTokenSupplyDecoder(): Decoder { - return getStructDecoder([['number', getPreciseNumberWrapperDecoder()]]); -} - -export function getPreciseTokenSupplyCodec(): Codec< - PreciseTokenSupplyArgs, - PreciseTokenSupply -> { - return combineCodec( - getPreciseTokenSupplyEncoder(), - getPreciseTokenSupplyDecoder() - ); -} diff --git a/clients/js/jito_tip_router/types/preciseWeight.ts b/clients/js/jito_tip_router/types/preciseWeight.ts deleted file mode 100644 index 84c502e..0000000 --- a/clients/js/jito_tip_router/types/preciseWeight.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * This code was AUTOGENERATED using the kinobi library. - * Please DO NOT EDIT THIS FILE, instead use visitors - * to add features, then rerun kinobi to update it. - * - * @see https://github.com/kinobi-so/kinobi - */ - -import { - combineCodec, - getStructDecoder, - getStructEncoder, - type Codec, - type Decoder, - type Encoder, -} from '@solana/web3.js'; -import { - getPreciseNumberWrapperDecoder, - getPreciseNumberWrapperEncoder, - type PreciseNumberWrapper, - type PreciseNumberWrapperArgs, -} from '.'; - -export type PreciseWeight = { number: PreciseNumberWrapper }; - -export type PreciseWeightArgs = { number: PreciseNumberWrapperArgs }; - -export function getPreciseWeightEncoder(): Encoder { - return getStructEncoder([['number', getPreciseNumberWrapperEncoder()]]); -} - -export function getPreciseWeightDecoder(): Decoder { - return getStructDecoder([['number', getPreciseNumberWrapperDecoder()]]); -} - -export function getPreciseWeightCodec(): Codec< - PreciseWeightArgs, - PreciseWeight -> { - return combineCodec(getPreciseWeightEncoder(), getPreciseWeightDecoder()); -} diff --git a/clients/js/jito_tip_router/types/weightEntry.ts b/clients/js/jito_tip_router/types/weightEntry.ts index 150271c..e16f8f5 100644 --- a/clients/js/jito_tip_router/types/weightEntry.ts +++ b/clients/js/jito_tip_router/types/weightEntry.ts @@ -10,35 +10,55 @@ import { combineCodec, getAddressDecoder, getAddressEncoder, + getArrayDecoder, + getArrayEncoder, getStructDecoder, getStructEncoder, + getU128Decoder, + getU128Encoder, + getU64Decoder, + getU64Encoder, + getU8Decoder, + getU8Encoder, type Address, type Codec, type Decoder, type Encoder, } from '@solana/web3.js'; -import { - getPreciseWeightDecoder, - getPreciseWeightEncoder, - type PreciseWeight, - type PreciseWeightArgs, -} from '.'; -export type WeightEntry = { mint: Address; weight: PreciseWeight }; +export type WeightEntry = { + mint: Address; + weight: bigint; + slotSet: bigint; + slotUpdated: bigint; + reserved: Array; +}; -export type WeightEntryArgs = { mint: Address; weight: PreciseWeightArgs }; +export type WeightEntryArgs = { + mint: Address; + weight: number | bigint; + slotSet: number | bigint; + slotUpdated: number | bigint; + reserved: Array; +}; export function getWeightEntryEncoder(): Encoder { return getStructEncoder([ ['mint', getAddressEncoder()], - ['weight', getPreciseWeightEncoder()], + ['weight', getU128Encoder()], + ['slotSet', getU64Encoder()], + ['slotUpdated', getU64Encoder()], + ['reserved', getArrayEncoder(getU8Encoder(), { size: 128 })], ]); } export function getWeightEntryDecoder(): Decoder { return getStructDecoder([ ['mint', getAddressDecoder()], - ['weight', getPreciseWeightDecoder()], + ['weight', getU128Decoder()], + ['slotSet', getU64Decoder()], + ['slotUpdated', getU64Decoder()], + ['reserved', getArrayDecoder(getU8Decoder(), { size: 128 })], ]); } diff --git a/clients/rust/jito_tip_router/src/generated/accounts/weight_table.rs b/clients/rust/jito_tip_router/src/generated/accounts/weight_table.rs index 3a996b1..72be462 100644 --- a/clients/rust/jito_tip_router/src/generated/accounts/weight_table.rs +++ b/clients/rust/jito_tip_router/src/generated/accounts/weight_table.rs @@ -20,7 +20,6 @@ pub struct WeightTable { pub ncn: Pubkey, pub ncn_epoch: u64, pub slot_created: u64, - pub slot_finalized: u64, pub bump: u8, #[cfg_attr(feature = "serde", serde(with = "serde_with::As::"))] pub reserved: [u8; 128], diff --git a/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs b/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs index 9191ec4..db54832 100644 --- a/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs +++ b/clients/rust/jito_tip_router/src/generated/errors/jito_tip_router.rs @@ -9,9 +9,6 @@ use thiserror::Error; #[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] pub enum JitoTipRouterError { - /// 8192 - No more table slots available - #[error("No more table slots available")] - NoMoreTableSlots = 0x2000, /// 8448 - Zero in the denominator #[error("Zero in the denominator")] DenominatorIsZero = 0x2100, @@ -30,15 +27,30 @@ pub enum JitoTipRouterError { /// 8704 - Incorrect weight table admin #[error("Incorrect weight table admin")] IncorrectWeightTableAdmin = 0x2200, - /// 8705 - Cannnot create future weight tables + /// 8705 - Duplicate mints in table + #[error("Duplicate mints in table")] + DuplicateMintsInTable = 0x2201, + /// 8706 - There are no mints in the table + #[error("There are no mints in the table")] + NoMintsInTable = 0x2202, + /// 8707 - Too many mints for table + #[error("Too many mints for table")] + TooManyMintsForTable = 0x2203, + /// 8708 - Weight table already initialized + #[error("Weight table already initialized")] + WeightTableAlreadyInitialized = 0x2204, + /// 8709 - Cannnot create future weight tables #[error("Cannnot create future weight tables")] - CannotCreateFutureWeightTables = 0x2201, - /// 8706 - Weight mints do not match - length + CannotCreateFutureWeightTables = 0x2205, + /// 8710 - Weight mints do not match - length #[error("Weight mints do not match - length")] - WeightMintsDoNotMatchLength = 0x2202, - /// 8707 - Weight mints do not match - mint hash + WeightMintsDoNotMatchLength = 0x2206, + /// 8711 - Weight mints do not match - mint hash #[error("Weight mints do not match - mint hash")] - WeightMintsDoNotMatchMintHash = 0x2203, + WeightMintsDoNotMatchMintHash = 0x2207, + /// 8712 - Invalid mint for weight table + #[error("Invalid mint for weight table")] + InvalidMintForWeightTable = 0x2208, } impl solana_program::program_error::PrintProgramError for JitoTipRouterError { diff --git a/clients/rust/jito_tip_router/src/generated/instructions/update_weight_table.rs b/clients/rust/jito_tip_router/src/generated/instructions/admin_update_weight_table.rs similarity index 89% rename from clients/rust/jito_tip_router/src/generated/instructions/update_weight_table.rs rename to clients/rust/jito_tip_router/src/generated/instructions/admin_update_weight_table.rs index d2aa817..70fa4f5 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/update_weight_table.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/admin_update_weight_table.rs @@ -7,7 +7,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; /// Accounts. -pub struct UpdateWeightTable { +pub struct AdminUpdateWeightTable { pub ncn: solana_program::pubkey::Pubkey, pub weight_table: solana_program::pubkey::Pubkey, @@ -17,17 +17,17 @@ pub struct UpdateWeightTable { pub restaking_program_id: solana_program::pubkey::Pubkey, } -impl UpdateWeightTable { +impl AdminUpdateWeightTable { pub fn instruction( &self, - args: UpdateWeightTableInstructionArgs, + args: AdminUpdateWeightTableInstructionArgs, ) -> solana_program::instruction::Instruction { self.instruction_with_remaining_accounts(args, &[]) } #[allow(clippy::vec_init_then_push)] pub fn instruction_with_remaining_accounts( &self, - args: UpdateWeightTableInstructionArgs, + args: AdminUpdateWeightTableInstructionArgs, remaining_accounts: &[solana_program::instruction::AccountMeta], ) -> solana_program::instruction::Instruction { let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); @@ -47,7 +47,7 @@ impl UpdateWeightTable { false, )); accounts.extend_from_slice(remaining_accounts); - let mut data = UpdateWeightTableInstructionData::new() + let mut data = AdminUpdateWeightTableInstructionData::new() .try_to_vec() .unwrap(); let mut args = args.try_to_vec().unwrap(); @@ -62,17 +62,17 @@ impl UpdateWeightTable { } #[derive(BorshDeserialize, BorshSerialize)] -pub struct UpdateWeightTableInstructionData { +pub struct AdminUpdateWeightTableInstructionData { discriminator: u8, } -impl UpdateWeightTableInstructionData { +impl AdminUpdateWeightTableInstructionData { pub fn new() -> Self { Self { discriminator: 1 } } } -impl Default for UpdateWeightTableInstructionData { +impl Default for AdminUpdateWeightTableInstructionData { fn default() -> Self { Self::new() } @@ -80,12 +80,12 @@ impl Default for UpdateWeightTableInstructionData { #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct UpdateWeightTableInstructionArgs { +pub struct AdminUpdateWeightTableInstructionArgs { pub ncn_epoch: u64, pub weight: u128, } -/// Instruction builder for `UpdateWeightTable`. +/// Instruction builder for `AdminUpdateWeightTable`. /// /// ### Accounts: /// @@ -94,7 +94,7 @@ pub struct UpdateWeightTableInstructionArgs { /// 2. `[signer]` weight_table_admin /// 3. `[]` restaking_program_id #[derive(Clone, Debug, Default)] -pub struct UpdateWeightTableBuilder { +pub struct AdminUpdateWeightTableBuilder { ncn: Option, weight_table: Option, weight_table_admin: Option, @@ -104,7 +104,7 @@ pub struct UpdateWeightTableBuilder { __remaining_accounts: Vec, } -impl UpdateWeightTableBuilder { +impl AdminUpdateWeightTableBuilder { pub fn new() -> Self { Self::default() } @@ -164,7 +164,7 @@ impl UpdateWeightTableBuilder { } #[allow(clippy::clone_on_copy)] pub fn instruction(&self) -> solana_program::instruction::Instruction { - let accounts = UpdateWeightTable { + let accounts = AdminUpdateWeightTable { ncn: self.ncn.expect("ncn is not set"), weight_table: self.weight_table.expect("weight_table is not set"), weight_table_admin: self @@ -174,7 +174,7 @@ impl UpdateWeightTableBuilder { .restaking_program_id .expect("restaking_program_id is not set"), }; - let args = UpdateWeightTableInstructionArgs { + let args = AdminUpdateWeightTableInstructionArgs { ncn_epoch: self.ncn_epoch.clone().expect("ncn_epoch is not set"), weight: self.weight.clone().expect("weight is not set"), }; @@ -183,8 +183,8 @@ impl UpdateWeightTableBuilder { } } -/// `update_weight_table` CPI accounts. -pub struct UpdateWeightTableCpiAccounts<'a, 'b> { +/// `admin_update_weight_table` CPI accounts. +pub struct AdminUpdateWeightTableCpiAccounts<'a, 'b> { pub ncn: &'b solana_program::account_info::AccountInfo<'a>, pub weight_table: &'b solana_program::account_info::AccountInfo<'a>, @@ -194,8 +194,8 @@ pub struct UpdateWeightTableCpiAccounts<'a, 'b> { pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, } -/// `update_weight_table` CPI instruction. -pub struct UpdateWeightTableCpi<'a, 'b> { +/// `admin_update_weight_table` CPI instruction. +pub struct AdminUpdateWeightTableCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, @@ -207,14 +207,14 @@ pub struct UpdateWeightTableCpi<'a, 'b> { pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, /// The arguments for the instruction. - pub __args: UpdateWeightTableInstructionArgs, + pub __args: AdminUpdateWeightTableInstructionArgs, } -impl<'a, 'b> UpdateWeightTableCpi<'a, 'b> { +impl<'a, 'b> AdminUpdateWeightTableCpi<'a, 'b> { pub fn new( program: &'b solana_program::account_info::AccountInfo<'a>, - accounts: UpdateWeightTableCpiAccounts<'a, 'b>, - args: UpdateWeightTableInstructionArgs, + accounts: AdminUpdateWeightTableCpiAccounts<'a, 'b>, + args: AdminUpdateWeightTableInstructionArgs, ) -> Self { Self { __program: program, @@ -282,7 +282,7 @@ impl<'a, 'b> UpdateWeightTableCpi<'a, 'b> { is_writable: remaining_account.2, }) }); - let mut data = UpdateWeightTableInstructionData::new() + let mut data = AdminUpdateWeightTableInstructionData::new() .try_to_vec() .unwrap(); let mut args = self.__args.try_to_vec().unwrap(); @@ -311,7 +311,7 @@ impl<'a, 'b> UpdateWeightTableCpi<'a, 'b> { } } -/// Instruction builder for `UpdateWeightTable` via CPI. +/// Instruction builder for `AdminUpdateWeightTable` via CPI. /// /// ### Accounts: /// @@ -320,13 +320,13 @@ impl<'a, 'b> UpdateWeightTableCpi<'a, 'b> { /// 2. `[signer]` weight_table_admin /// 3. `[]` restaking_program_id #[derive(Clone, Debug)] -pub struct UpdateWeightTableCpiBuilder<'a, 'b> { - instruction: Box>, +pub struct AdminUpdateWeightTableCpiBuilder<'a, 'b> { + instruction: Box>, } -impl<'a, 'b> UpdateWeightTableCpiBuilder<'a, 'b> { +impl<'a, 'b> AdminUpdateWeightTableCpiBuilder<'a, 'b> { pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self { - let instruction = Box::new(UpdateWeightTableCpiBuilderInstruction { + let instruction = Box::new(AdminUpdateWeightTableCpiBuilderInstruction { __program: program, ncn: None, weight_table: None, @@ -418,7 +418,7 @@ impl<'a, 'b> UpdateWeightTableCpiBuilder<'a, 'b> { &self, signers_seeds: &[&[&[u8]]], ) -> solana_program::entrypoint::ProgramResult { - let args = UpdateWeightTableInstructionArgs { + let args = AdminUpdateWeightTableInstructionArgs { ncn_epoch: self .instruction .ncn_epoch @@ -426,7 +426,7 @@ impl<'a, 'b> UpdateWeightTableCpiBuilder<'a, 'b> { .expect("ncn_epoch is not set"), weight: self.instruction.weight.clone().expect("weight is not set"), }; - let instruction = UpdateWeightTableCpi { + let instruction = AdminUpdateWeightTableCpi { __program: self.instruction.__program, ncn: self.instruction.ncn.expect("ncn is not set"), @@ -455,7 +455,7 @@ impl<'a, 'b> UpdateWeightTableCpiBuilder<'a, 'b> { } #[derive(Clone, Debug)] -struct UpdateWeightTableCpiBuilderInstruction<'a, 'b> { +struct AdminUpdateWeightTableCpiBuilderInstruction<'a, 'b> { __program: &'b solana_program::account_info::AccountInfo<'a>, ncn: Option<&'b solana_program::account_info::AccountInfo<'a>>, weight_table: Option<&'b solana_program::account_info::AccountInfo<'a>>, diff --git a/clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs b/clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs deleted file mode 100644 index f811789..0000000 --- a/clients/rust/jito_tip_router/src/generated/instructions/finalize_weight_table.rs +++ /dev/null @@ -1,496 +0,0 @@ -//! This code was AUTOGENERATED using the kinobi library. -//! Please DO NOT EDIT THIS FILE, instead use visitors -//! to add features, then rerun kinobi to update it. -//! -//! - -use borsh::{BorshDeserialize, BorshSerialize}; - -/// Accounts. -pub struct FinalizeWeightTable { - pub ncn: solana_program::pubkey::Pubkey, - - pub weight_table: solana_program::pubkey::Pubkey, - - pub weight_table_admin: solana_program::pubkey::Pubkey, - - pub restaking_program_id: solana_program::pubkey::Pubkey, -} - -impl FinalizeWeightTable { - pub fn instruction( - &self, - args: FinalizeWeightTableInstructionArgs, - ) -> solana_program::instruction::Instruction { - self.instruction_with_remaining_accounts(args, &[]) - } - #[allow(clippy::vec_init_then_push)] - pub fn instruction_with_remaining_accounts( - &self, - args: FinalizeWeightTableInstructionArgs, - remaining_accounts: &[solana_program::instruction::AccountMeta], - ) -> solana_program::instruction::Instruction { - let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - self.ncn, false, - )); - accounts.push(solana_program::instruction::AccountMeta::new( - self.weight_table, - false, - )); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - self.weight_table_admin, - true, - )); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - self.restaking_program_id, - false, - )); - accounts.extend_from_slice(remaining_accounts); - let mut data = FinalizeWeightTableInstructionData::new() - .try_to_vec() - .unwrap(); - let mut args = args.try_to_vec().unwrap(); - data.append(&mut args); - - solana_program::instruction::Instruction { - program_id: crate::JITO_TIP_ROUTER_ID, - accounts, - data, - } - } -} - -#[derive(BorshDeserialize, BorshSerialize)] -pub struct FinalizeWeightTableInstructionData { - discriminator: u8, -} - -impl FinalizeWeightTableInstructionData { - pub fn new() -> Self { - Self { discriminator: 2 } - } -} - -impl Default for FinalizeWeightTableInstructionData { - fn default() -> Self { - Self::new() - } -} - -#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct FinalizeWeightTableInstructionArgs { - pub ncn_epoch: u64, - pub mint_hash: u64, - pub mint_count: u8, -} - -/// Instruction builder for `FinalizeWeightTable`. -/// -/// ### Accounts: -/// -/// 0. `[]` ncn -/// 1. `[writable]` weight_table -/// 2. `[signer]` weight_table_admin -/// 3. `[]` restaking_program_id -#[derive(Clone, Debug, Default)] -pub struct FinalizeWeightTableBuilder { - ncn: Option, - weight_table: Option, - weight_table_admin: Option, - restaking_program_id: Option, - ncn_epoch: Option, - mint_hash: Option, - mint_count: Option, - __remaining_accounts: Vec, -} - -impl FinalizeWeightTableBuilder { - pub fn new() -> Self { - Self::default() - } - #[inline(always)] - pub fn ncn(&mut self, ncn: solana_program::pubkey::Pubkey) -> &mut Self { - self.ncn = Some(ncn); - self - } - #[inline(always)] - pub fn weight_table(&mut self, weight_table: solana_program::pubkey::Pubkey) -> &mut Self { - self.weight_table = Some(weight_table); - self - } - #[inline(always)] - pub fn weight_table_admin( - &mut self, - weight_table_admin: solana_program::pubkey::Pubkey, - ) -> &mut Self { - self.weight_table_admin = Some(weight_table_admin); - self - } - #[inline(always)] - pub fn restaking_program_id( - &mut self, - restaking_program_id: solana_program::pubkey::Pubkey, - ) -> &mut Self { - self.restaking_program_id = Some(restaking_program_id); - self - } - #[inline(always)] - pub fn ncn_epoch(&mut self, ncn_epoch: u64) -> &mut Self { - self.ncn_epoch = Some(ncn_epoch); - self - } - #[inline(always)] - pub fn mint_hash(&mut self, mint_hash: u64) -> &mut Self { - self.mint_hash = Some(mint_hash); - self - } - #[inline(always)] - pub fn mint_count(&mut self, mint_count: u8) -> &mut Self { - self.mint_count = Some(mint_count); - self - } - /// Add an additional account to the instruction. - #[inline(always)] - pub fn add_remaining_account( - &mut self, - account: solana_program::instruction::AccountMeta, - ) -> &mut Self { - self.__remaining_accounts.push(account); - self - } - /// Add additional accounts to the instruction. - #[inline(always)] - pub fn add_remaining_accounts( - &mut self, - accounts: &[solana_program::instruction::AccountMeta], - ) -> &mut Self { - self.__remaining_accounts.extend_from_slice(accounts); - self - } - #[allow(clippy::clone_on_copy)] - pub fn instruction(&self) -> solana_program::instruction::Instruction { - let accounts = FinalizeWeightTable { - ncn: self.ncn.expect("ncn is not set"), - weight_table: self.weight_table.expect("weight_table is not set"), - weight_table_admin: self - .weight_table_admin - .expect("weight_table_admin is not set"), - restaking_program_id: self - .restaking_program_id - .expect("restaking_program_id is not set"), - }; - let args = FinalizeWeightTableInstructionArgs { - ncn_epoch: self.ncn_epoch.clone().expect("ncn_epoch is not set"), - mint_hash: self.mint_hash.clone().expect("mint_hash is not set"), - mint_count: self.mint_count.clone().expect("mint_count is not set"), - }; - - accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) - } -} - -/// `finalize_weight_table` CPI accounts. -pub struct FinalizeWeightTableCpiAccounts<'a, 'b> { - pub ncn: &'b solana_program::account_info::AccountInfo<'a>, - - pub weight_table: &'b solana_program::account_info::AccountInfo<'a>, - - pub weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, - - pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, -} - -/// `finalize_weight_table` CPI instruction. -pub struct FinalizeWeightTableCpi<'a, 'b> { - /// The program to invoke. - pub __program: &'b solana_program::account_info::AccountInfo<'a>, - - pub ncn: &'b solana_program::account_info::AccountInfo<'a>, - - pub weight_table: &'b solana_program::account_info::AccountInfo<'a>, - - pub weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, - - pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, - /// The arguments for the instruction. - pub __args: FinalizeWeightTableInstructionArgs, -} - -impl<'a, 'b> FinalizeWeightTableCpi<'a, 'b> { - pub fn new( - program: &'b solana_program::account_info::AccountInfo<'a>, - accounts: FinalizeWeightTableCpiAccounts<'a, 'b>, - args: FinalizeWeightTableInstructionArgs, - ) -> Self { - Self { - __program: program, - ncn: accounts.ncn, - weight_table: accounts.weight_table, - weight_table_admin: accounts.weight_table_admin, - restaking_program_id: accounts.restaking_program_id, - __args: args, - } - } - #[inline(always)] - pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult { - self.invoke_signed_with_remaining_accounts(&[], &[]) - } - #[inline(always)] - pub fn invoke_with_remaining_accounts( - &self, - remaining_accounts: &[( - &'b solana_program::account_info::AccountInfo<'a>, - bool, - bool, - )], - ) -> solana_program::entrypoint::ProgramResult { - self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) - } - #[inline(always)] - pub fn invoke_signed( - &self, - signers_seeds: &[&[&[u8]]], - ) -> solana_program::entrypoint::ProgramResult { - self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) - } - #[allow(clippy::clone_on_copy)] - #[allow(clippy::vec_init_then_push)] - pub fn invoke_signed_with_remaining_accounts( - &self, - signers_seeds: &[&[&[u8]]], - remaining_accounts: &[( - &'b solana_program::account_info::AccountInfo<'a>, - bool, - bool, - )], - ) -> solana_program::entrypoint::ProgramResult { - let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - *self.ncn.key, - false, - )); - accounts.push(solana_program::instruction::AccountMeta::new( - *self.weight_table.key, - false, - )); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - *self.weight_table_admin.key, - true, - )); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - *self.restaking_program_id.key, - false, - )); - remaining_accounts.iter().for_each(|remaining_account| { - accounts.push(solana_program::instruction::AccountMeta { - pubkey: *remaining_account.0.key, - is_signer: remaining_account.1, - is_writable: remaining_account.2, - }) - }); - let mut data = FinalizeWeightTableInstructionData::new() - .try_to_vec() - .unwrap(); - let mut args = self.__args.try_to_vec().unwrap(); - data.append(&mut args); - - let instruction = solana_program::instruction::Instruction { - program_id: crate::JITO_TIP_ROUTER_ID, - accounts, - data, - }; - let mut account_infos = Vec::with_capacity(4 + 1 + remaining_accounts.len()); - account_infos.push(self.__program.clone()); - account_infos.push(self.ncn.clone()); - account_infos.push(self.weight_table.clone()); - account_infos.push(self.weight_table_admin.clone()); - account_infos.push(self.restaking_program_id.clone()); - remaining_accounts - .iter() - .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); - - if signers_seeds.is_empty() { - solana_program::program::invoke(&instruction, &account_infos) - } else { - solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds) - } - } -} - -/// Instruction builder for `FinalizeWeightTable` via CPI. -/// -/// ### Accounts: -/// -/// 0. `[]` ncn -/// 1. `[writable]` weight_table -/// 2. `[signer]` weight_table_admin -/// 3. `[]` restaking_program_id -#[derive(Clone, Debug)] -pub struct FinalizeWeightTableCpiBuilder<'a, 'b> { - instruction: Box>, -} - -impl<'a, 'b> FinalizeWeightTableCpiBuilder<'a, 'b> { - pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self { - let instruction = Box::new(FinalizeWeightTableCpiBuilderInstruction { - __program: program, - ncn: None, - weight_table: None, - weight_table_admin: None, - restaking_program_id: None, - ncn_epoch: None, - mint_hash: None, - mint_count: None, - __remaining_accounts: Vec::new(), - }); - Self { instruction } - } - #[inline(always)] - pub fn ncn(&mut self, ncn: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { - self.instruction.ncn = Some(ncn); - self - } - #[inline(always)] - pub fn weight_table( - &mut self, - weight_table: &'b solana_program::account_info::AccountInfo<'a>, - ) -> &mut Self { - self.instruction.weight_table = Some(weight_table); - self - } - #[inline(always)] - pub fn weight_table_admin( - &mut self, - weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, - ) -> &mut Self { - self.instruction.weight_table_admin = Some(weight_table_admin); - self - } - #[inline(always)] - pub fn restaking_program_id( - &mut self, - restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, - ) -> &mut Self { - self.instruction.restaking_program_id = Some(restaking_program_id); - self - } - #[inline(always)] - pub fn ncn_epoch(&mut self, ncn_epoch: u64) -> &mut Self { - self.instruction.ncn_epoch = Some(ncn_epoch); - self - } - #[inline(always)] - pub fn mint_hash(&mut self, mint_hash: u64) -> &mut Self { - self.instruction.mint_hash = Some(mint_hash); - self - } - #[inline(always)] - pub fn mint_count(&mut self, mint_count: u8) -> &mut Self { - self.instruction.mint_count = Some(mint_count); - self - } - /// Add an additional account to the instruction. - #[inline(always)] - pub fn add_remaining_account( - &mut self, - account: &'b solana_program::account_info::AccountInfo<'a>, - is_writable: bool, - is_signer: bool, - ) -> &mut Self { - self.instruction - .__remaining_accounts - .push((account, is_writable, is_signer)); - self - } - /// Add additional accounts to the instruction. - /// - /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, - /// and a `bool` indicating whether the account is a signer or not. - #[inline(always)] - pub fn add_remaining_accounts( - &mut self, - accounts: &[( - &'b solana_program::account_info::AccountInfo<'a>, - bool, - bool, - )], - ) -> &mut Self { - self.instruction - .__remaining_accounts - .extend_from_slice(accounts); - self - } - #[inline(always)] - pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult { - self.invoke_signed(&[]) - } - #[allow(clippy::clone_on_copy)] - #[allow(clippy::vec_init_then_push)] - pub fn invoke_signed( - &self, - signers_seeds: &[&[&[u8]]], - ) -> solana_program::entrypoint::ProgramResult { - let args = FinalizeWeightTableInstructionArgs { - ncn_epoch: self - .instruction - .ncn_epoch - .clone() - .expect("ncn_epoch is not set"), - mint_hash: self - .instruction - .mint_hash - .clone() - .expect("mint_hash is not set"), - mint_count: self - .instruction - .mint_count - .clone() - .expect("mint_count is not set"), - }; - let instruction = FinalizeWeightTableCpi { - __program: self.instruction.__program, - - ncn: self.instruction.ncn.expect("ncn is not set"), - - weight_table: self - .instruction - .weight_table - .expect("weight_table is not set"), - - weight_table_admin: self - .instruction - .weight_table_admin - .expect("weight_table_admin is not set"), - - restaking_program_id: self - .instruction - .restaking_program_id - .expect("restaking_program_id is not set"), - __args: args, - }; - instruction.invoke_signed_with_remaining_accounts( - signers_seeds, - &self.instruction.__remaining_accounts, - ) - } -} - -#[derive(Clone, Debug)] -struct FinalizeWeightTableCpiBuilderInstruction<'a, 'b> { - __program: &'b solana_program::account_info::AccountInfo<'a>, - ncn: Option<&'b solana_program::account_info::AccountInfo<'a>>, - weight_table: Option<&'b solana_program::account_info::AccountInfo<'a>>, - weight_table_admin: Option<&'b solana_program::account_info::AccountInfo<'a>>, - restaking_program_id: Option<&'b solana_program::account_info::AccountInfo<'a>>, - ncn_epoch: Option, - mint_hash: Option, - mint_count: Option, - /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. - __remaining_accounts: Vec<( - &'b solana_program::account_info::AccountInfo<'a>, - bool, - bool, - )>, -} diff --git a/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs b/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs index 5647197..a5c1a41 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs @@ -14,7 +14,7 @@ pub struct InitializeWeightTable { pub weight_table: solana_program::pubkey::Pubkey, - pub weight_table_admin: solana_program::pubkey::Pubkey, + pub payer: solana_program::pubkey::Pubkey, pub restaking_program_id: solana_program::pubkey::Pubkey, @@ -47,8 +47,7 @@ impl InitializeWeightTable { true, )); accounts.push(solana_program::instruction::AccountMeta::new( - self.weight_table_admin, - true, + self.payer, true, )); accounts.push(solana_program::instruction::AccountMeta::new_readonly( self.restaking_program_id, @@ -103,7 +102,7 @@ pub struct InitializeWeightTableInstructionArgs { /// 0. `[]` restaking_config /// 1. `[]` ncn /// 2. `[writable, signer]` weight_table -/// 3. `[writable, signer]` weight_table_admin +/// 3. `[writable, signer]` payer /// 4. `[]` restaking_program_id /// 5. `[optional]` system_program (default to `11111111111111111111111111111111`) #[derive(Clone, Debug, Default)] @@ -111,7 +110,7 @@ pub struct InitializeWeightTableBuilder { restaking_config: Option, ncn: Option, weight_table: Option, - weight_table_admin: Option, + payer: Option, restaking_program_id: Option, system_program: Option, first_slot_of_ncn_epoch: Option, @@ -141,11 +140,8 @@ impl InitializeWeightTableBuilder { self } #[inline(always)] - pub fn weight_table_admin( - &mut self, - weight_table_admin: solana_program::pubkey::Pubkey, - ) -> &mut Self { - self.weight_table_admin = Some(weight_table_admin); + pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); self } #[inline(always)] @@ -192,9 +188,7 @@ impl InitializeWeightTableBuilder { restaking_config: self.restaking_config.expect("restaking_config is not set"), ncn: self.ncn.expect("ncn is not set"), weight_table: self.weight_table.expect("weight_table is not set"), - weight_table_admin: self - .weight_table_admin - .expect("weight_table_admin is not set"), + payer: self.payer.expect("payer is not set"), restaking_program_id: self .restaking_program_id .expect("restaking_program_id is not set"), @@ -218,7 +212,7 @@ pub struct InitializeWeightTableCpiAccounts<'a, 'b> { pub weight_table: &'b solana_program::account_info::AccountInfo<'a>, - pub weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, + pub payer: &'b solana_program::account_info::AccountInfo<'a>, pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, @@ -236,7 +230,7 @@ pub struct InitializeWeightTableCpi<'a, 'b> { pub weight_table: &'b solana_program::account_info::AccountInfo<'a>, - pub weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, + pub payer: &'b solana_program::account_info::AccountInfo<'a>, pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, @@ -256,7 +250,7 @@ impl<'a, 'b> InitializeWeightTableCpi<'a, 'b> { restaking_config: accounts.restaking_config, ncn: accounts.ncn, weight_table: accounts.weight_table, - weight_table_admin: accounts.weight_table_admin, + payer: accounts.payer, restaking_program_id: accounts.restaking_program_id, system_program: accounts.system_program, __args: args, @@ -309,7 +303,7 @@ impl<'a, 'b> InitializeWeightTableCpi<'a, 'b> { true, )); accounts.push(solana_program::instruction::AccountMeta::new( - *self.weight_table_admin.key, + *self.payer.key, true, )); accounts.push(solana_program::instruction::AccountMeta::new_readonly( @@ -343,7 +337,7 @@ impl<'a, 'b> InitializeWeightTableCpi<'a, 'b> { account_infos.push(self.restaking_config.clone()); account_infos.push(self.ncn.clone()); account_infos.push(self.weight_table.clone()); - account_infos.push(self.weight_table_admin.clone()); + account_infos.push(self.payer.clone()); account_infos.push(self.restaking_program_id.clone()); account_infos.push(self.system_program.clone()); remaining_accounts @@ -365,7 +359,7 @@ impl<'a, 'b> InitializeWeightTableCpi<'a, 'b> { /// 0. `[]` restaking_config /// 1. `[]` ncn /// 2. `[writable, signer]` weight_table -/// 3. `[writable, signer]` weight_table_admin +/// 3. `[writable, signer]` payer /// 4. `[]` restaking_program_id /// 5. `[]` system_program #[derive(Clone, Debug)] @@ -380,7 +374,7 @@ impl<'a, 'b> InitializeWeightTableCpiBuilder<'a, 'b> { restaking_config: None, ncn: None, weight_table: None, - weight_table_admin: None, + payer: None, restaking_program_id: None, system_program: None, first_slot_of_ncn_epoch: None, @@ -410,11 +404,8 @@ impl<'a, 'b> InitializeWeightTableCpiBuilder<'a, 'b> { self } #[inline(always)] - pub fn weight_table_admin( - &mut self, - weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, - ) -> &mut Self { - self.instruction.weight_table_admin = Some(weight_table_admin); + pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); self } #[inline(always)] @@ -498,10 +489,7 @@ impl<'a, 'b> InitializeWeightTableCpiBuilder<'a, 'b> { .weight_table .expect("weight_table is not set"), - weight_table_admin: self - .instruction - .weight_table_admin - .expect("weight_table_admin is not set"), + payer: self.instruction.payer.expect("payer is not set"), restaking_program_id: self .instruction @@ -527,7 +515,7 @@ struct InitializeWeightTableCpiBuilderInstruction<'a, 'b> { restaking_config: Option<&'b solana_program::account_info::AccountInfo<'a>>, ncn: Option<&'b solana_program::account_info::AccountInfo<'a>>, weight_table: Option<&'b solana_program::account_info::AccountInfo<'a>>, - weight_table_admin: Option<&'b solana_program::account_info::AccountInfo<'a>>, + payer: Option<&'b solana_program::account_info::AccountInfo<'a>>, restaking_program_id: Option<&'b solana_program::account_info::AccountInfo<'a>>, system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>, first_slot_of_ncn_epoch: Option, diff --git a/clients/rust/jito_tip_router/src/generated/instructions/mod.rs b/clients/rust/jito_tip_router/src/generated/instructions/mod.rs index db9b2e2..d81a5f2 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/mod.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/mod.rs @@ -4,10 +4,7 @@ //! //! -pub(crate) mod r#finalize_weight_table; +pub(crate) mod r#admin_update_weight_table; pub(crate) mod r#initialize_weight_table; -pub(crate) mod r#update_weight_table; -pub use self::{ - r#finalize_weight_table::*, r#initialize_weight_table::*, r#update_weight_table::*, -}; +pub use self::{r#admin_update_weight_table::*, r#initialize_weight_table::*}; diff --git a/clients/rust/jito_tip_router/src/generated/types/mod.rs b/clients/rust/jito_tip_router/src/generated/types/mod.rs index 28bbce7..f552bf2 100644 --- a/clients/rust/jito_tip_router/src/generated/types/mod.rs +++ b/clients/rust/jito_tip_router/src/generated/types/mod.rs @@ -4,11 +4,6 @@ //! //! -pub(crate) mod r#precise_number_wrapper; -pub(crate) mod r#precise_token_supply; -pub(crate) mod r#precise_weight; pub(crate) mod r#weight_entry; -pub use self::{ - r#precise_number_wrapper::*, r#precise_token_supply::*, r#precise_weight::*, r#weight_entry::*, -}; +pub use self::r#weight_entry::*; diff --git a/clients/rust/jito_tip_router/src/generated/types/precise_number_wrapper.rs b/clients/rust/jito_tip_router/src/generated/types/precise_number_wrapper.rs deleted file mode 100644 index 3d7bb91..0000000 --- a/clients/rust/jito_tip_router/src/generated/types/precise_number_wrapper.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! This code was AUTOGENERATED using the kinobi library. -//! Please DO NOT EDIT THIS FILE, instead use visitors -//! to add features, then rerun kinobi to update it. -//! -//! - -use borsh::{BorshDeserialize, BorshSerialize}; - -#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct PreciseNumberWrapper { - pub value: [u8; 16], -} diff --git a/clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs b/clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs deleted file mode 100644 index 46fc6e5..0000000 --- a/clients/rust/jito_tip_router/src/generated/types/precise_token_supply.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! This code was AUTOGENERATED using the kinobi library. -//! Please DO NOT EDIT THIS FILE, instead use visitors -//! to add features, then rerun kinobi to update it. -//! -//! - -use borsh::{BorshDeserialize, BorshSerialize}; - -use crate::generated::types::PreciseNumberWrapper; - -#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct PreciseTokenSupply { - pub number: PreciseNumberWrapper, -} diff --git a/clients/rust/jito_tip_router/src/generated/types/precise_weight.rs b/clients/rust/jito_tip_router/src/generated/types/precise_weight.rs deleted file mode 100644 index 782ac88..0000000 --- a/clients/rust/jito_tip_router/src/generated/types/precise_weight.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! This code was AUTOGENERATED using the kinobi library. -//! Please DO NOT EDIT THIS FILE, instead use visitors -//! to add features, then rerun kinobi to update it. -//! -//! - -use borsh::{BorshDeserialize, BorshSerialize}; - -use crate::generated::types::PreciseNumberWrapper; - -#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct PreciseWeight { - pub number: PreciseNumberWrapper, -} diff --git a/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs b/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs index 57e8dd3..fb3123b 100644 --- a/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs +++ b/clients/rust/jito_tip_router/src/generated/types/weight_entry.rs @@ -7,8 +7,6 @@ use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::pubkey::Pubkey; -use crate::generated::types::PreciseWeight; - #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct WeightEntry { @@ -17,5 +15,9 @@ pub struct WeightEntry { serde(with = "serde_with::As::") )] pub mint: Pubkey, - pub weight: PreciseWeight, + pub weight: u128, + pub slot_set: u64, + pub slot_updated: u64, + #[cfg_attr(feature = "serde", serde(with = "serde_with::As::"))] + pub reserved: [u8; 128], } diff --git a/core/src/error.rs b/core/src/error.rs index 128fac8..707b83b 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -3,27 +3,35 @@ use thiserror::Error; #[derive(Debug, Error, PartialEq, Eq)] pub enum TipRouterError { - #[error("No more table slots available")] - NoMoreTableSlots = 0x2000, #[error("Zero in the denominator")] DenominatorIsZero = 0x2100, #[error("Overflow")] - ArithmeticOverflow = 0x2101, + ArithmeticOverflow, #[error("Modulo Overflow")] - ModuloOverflow = 0x2102, + ModuloOverflow, #[error("New precise number error")] - NewPreciseNumberError = 0x2103, + NewPreciseNumberError, #[error("Cast to imprecise number error")] - CastToImpreciseNumberError = 0x2104, + CastToImpreciseNumberError, #[error("Incorrect weight table admin")] IncorrectWeightTableAdmin = 0x2200, + #[error("Duplicate mints in table")] + DuplicateMintsInTable, + #[error("There are no mints in the table")] + NoMintsInTable, + #[error("Too many mints for table")] + TooManyMintsForTable, + #[error("Weight table already initialized")] + WeightTableAlreadyInitialized, #[error("Cannnot create future weight tables")] - CannotCreateFutureWeightTables = 0x2201, + CannotCreateFutureWeightTables, #[error("Weight mints do not match - length")] - WeightMintsDoNotMatchLength = 0x2202, + WeightMintsDoNotMatchLength, #[error("Weight mints do not match - mint hash")] - WeightMintsDoNotMatchMintHash = 0x2203, + WeightMintsDoNotMatchMintHash, + #[error("Invalid mint for weight table")] + InvalidMintForWeightTable, } impl DecodeError for TipRouterError { diff --git a/core/src/instruction.rs b/core/src/instruction.rs index 8f5bf06..737aed7 100644 --- a/core/src/instruction.rs +++ b/core/src/instruction.rs @@ -9,7 +9,7 @@ pub enum WeightTableInstruction { #[account(0, name = "restaking_config")] #[account(1, name = "ncn")] #[account(2, writable, signer, name = "weight_table")] - #[account(3, writable, signer, name = "weight_table_admin")] + #[account(3, writable, signer, name = "payer")] #[account(4, name = "restaking_program_id")] #[account(5, name = "system_program")] InitializeWeightTable{ @@ -21,19 +21,8 @@ pub enum WeightTableInstruction { #[account(1, writable, name = "weight_table")] #[account(2, signer, name = "weight_table_admin")] #[account(3, name = "restaking_program_id")] - UpdateWeightTable{ + AdminUpdateWeightTable{ ncn_epoch: u64, weight: u128, }, - - #[account(0, name = "ncn")] - #[account(1, writable, name = "weight_table")] - #[account(2, signer, name = "weight_table_admin")] - #[account(3, name = "restaking_program_id")] - FinalizeWeightTable{ - ncn_epoch: u64, - mint_hash: u64, - mint_count: u8, - }, - } diff --git a/core/src/lib.rs b/core/src/lib.rs index f6896e7..c706973 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,5 +1,5 @@ pub mod discriminators; pub mod error; pub mod instruction; -pub mod precise_numbers; +pub mod weight_entry; pub mod weight_table; diff --git a/core/src/precise_numbers.rs b/core/src/precise_numbers.rs deleted file mode 100644 index 1394a6a..0000000 --- a/core/src/precise_numbers.rs +++ /dev/null @@ -1,110 +0,0 @@ -use bytemuck::{Pod, Zeroable}; -use shank::ShankType; -use spl_math::precise_number::PreciseNumber; - -use crate::error::TipRouterError; - -// All arithmetic should be done with PreciseNumber, and cast down to the appropriate types only until all -// calculations are complete. - -#[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] -#[repr(C)] -pub struct PreciseNumberWrapper { - value: [u8; 16], // 128 -} - -impl PreciseNumberWrapper { - const fn from_u128(value: u128) -> Self { - let value = value.to_le_bytes(); - Self { value } - } - - const fn to_u128(&self) -> u128 { - u128::from_le_bytes(self.value) - } - - fn to_precise_number(&self) -> Result { - PreciseNumber::new(self.to_u128()).ok_or(TipRouterError::NewPreciseNumberError) - } - - fn from_precise_number(precise_number: PreciseNumber) -> Result { - let value = precise_number - .to_imprecise() - .ok_or(TipRouterError::CastToImpreciseNumberError)?; - - Ok(Self::from_u128(value)) - } -} - -#[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] -#[repr(C)] -pub struct PreciseWeight { - number: PreciseNumberWrapper, // 128 -} - -impl PreciseWeight { - pub const fn from_weight(weight: u128) -> Self { - let number = PreciseNumberWrapper::from_u128(weight); - Self { number } - } - - pub const fn to_weight(&self) -> u128 { - self.number.to_u128() - } - - pub fn weight_to_precise_number(&self) -> Result { - self.number.to_precise_number() - } - - pub fn precise_number_to_weight(precise_number: PreciseNumber) -> Result { - let number = PreciseNumberWrapper::from_precise_number(precise_number)?; - Ok(Self { number }) - } -} - -#[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] -#[repr(C)] -pub struct PreciseTokenSupply { - number: PreciseNumberWrapper, // 128 -} - -impl PreciseTokenSupply { - pub const PRECISION_FACTOR: u128 = 1_000_000_000; - - fn from_token_supply(token_supply: u64) -> Result { - let value = (token_supply as u128) - .checked_mul(Self::PRECISION_FACTOR) - .ok_or(TipRouterError::ArithmeticOverflow)?; - - let number = PreciseNumberWrapper::from_u128(value); - - Ok(Self { number }) - } - - fn to_token_supply(self) -> Result { - let value = self.number.to_u128(); - let token_supply = value - .checked_div(Self::PRECISION_FACTOR) - .ok_or(TipRouterError::ArithmeticOverflow)?; - - token_supply - .try_into() - .map_err(|_| TipRouterError::ArithmeticOverflow) - } - - pub fn token_supply_to_precise_number( - token_supply: u64, - ) -> Result { - let value = Self::from_token_supply(token_supply)?; - - value.number.to_precise_number() - } - - pub fn precise_number_to_token_supply( - precise_number: PreciseNumber, - ) -> Result { - let number = PreciseNumberWrapper::from_precise_number(precise_number)?; - let value = Self { number }; - value.to_token_supply() - } -} diff --git a/core/src/weight_entry.rs b/core/src/weight_entry.rs new file mode 100644 index 0000000..8a0517c --- /dev/null +++ b/core/src/weight_entry.rs @@ -0,0 +1,104 @@ +use bytemuck::{Pod, Zeroable}; +use jito_bytemuck::types::{PodU128, PodU64}; +use shank::ShankType; +use solana_program::pubkey::Pubkey; +use spl_math::precise_number::PreciseNumber; + +use crate::error::TipRouterError; + +#[derive(Debug, Clone, Copy, Zeroable, ShankType, Pod)] +#[repr(C)] +pub struct WeightEntry { + mint: Pubkey, + weight: PodU128, + slot_set: PodU64, + slot_updated: PodU64, + reserved: [u8; 128], +} + +impl Default for WeightEntry { + fn default() -> Self { + Self { + mint: Pubkey::default(), + weight: PodU128::default(), + slot_set: PodU64::default(), + slot_updated: PodU64::default(), + reserved: [0; 128], + } + } +} + +impl WeightEntry { + // Weights should have a decimal precision of 1e12 + // Meaning something has the exchange rate of 1.5, it should be stored as 1.5 * 1e12 + // This gives us 12 decimal places of precision + pub const DECIMAL_PRECISION: u128 = 1_000_000_000_000; // 1e12 + + pub fn new(mint: Pubkey) -> Self { + Self { + mint, + weight: PodU128::from(0), + slot_set: PodU64::from(0), + slot_updated: PodU64::from(0), + reserved: [0; 128], + } + } + + // Empty entry, no mint + pub fn is_empty(&self) -> bool { + self.mint.eq(&Pubkey::default()) + } + + pub fn is_set(&self) -> bool { + self.slot_set() > 0 + } + + pub fn slot_set(&self) -> u64 { + self.slot_set.into() + } + + pub fn slot_updated(&self) -> u64 { + self.slot_updated.into() + } + + pub const fn mint(&self) -> Pubkey { + self.mint + } + + pub fn weight(&self) -> u128 { + self.weight.into() + } + + pub fn precise_weight(&self) -> Result { + PreciseNumber::new(self.weight.into()).ok_or(TipRouterError::NewPreciseNumberError) + } + + pub fn set_weight(&mut self, weight: u128, current_slot: u64) { + self.weight = PodU128::from(weight); + + if self.slot_set() == 0 { + self.slot_set = PodU64::from(current_slot); + self.slot_updated = PodU64::from(current_slot); + } + + self.slot_updated = PodU64::from(current_slot); + } +} + +#[cfg(test)] +mod tests { + use solana_program::pubkey::Pubkey; + + use super::*; + + #[test] + fn test_weight_entry_new() { + let mint = Pubkey::new_unique(); + let weight_entry = WeightEntry::new(mint); + + assert_eq!(weight_entry.mint(), mint); + assert_eq!(weight_entry.weight(), 0); + assert_eq!(weight_entry.slot_set(), 0); + assert_eq!(weight_entry.slot_updated(), 0); + } +} diff --git a/core/src/weight_table.rs b/core/src/weight_table.rs index 21bef02..9a2ae4a 100644 --- a/core/src/weight_table.rs +++ b/core/src/weight_table.rs @@ -1,11 +1,11 @@ +use std::collections::HashSet; + use bytemuck::{Pod, Zeroable}; use jito_bytemuck::{types::PodU64, AccountDeserialize, Discriminator}; use shank::{ShankAccount, ShankType}; use solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}; -use crate::{ - discriminators::Discriminators, error::TipRouterError, precise_numbers::PreciseWeight, -}; +use crate::{discriminators::Discriminators, error::TipRouterError, weight_entry::WeightEntry}; // PDA'd ["WEIGHT_TABLE", NCN, NCN_EPOCH_SLOT] #[derive(Debug, Clone, Copy, Zeroable, ShankType, Pod, AccountDeserialize, ShankAccount)] @@ -21,9 +21,6 @@ pub struct WeightTable { /// Slot weight table was created slot_created: PodU64, - /// Slot weight table was finalized - slot_finalized: PodU64, - /// Bump seed for the PDA bump: u8, @@ -40,14 +37,12 @@ impl Discriminator for WeightTable { impl WeightTable { pub const MAX_TABLE_ENTRIES: usize = 32; - pub const NOT_FINALIZED: u64 = u64::MAX; pub fn new(ncn: Pubkey, ncn_epoch: u64, slot_created: u64, bump: u8) -> Self { Self { ncn, ncn_epoch: PodU64::from(ncn_epoch), slot_created: PodU64::from(slot_created), - slot_finalized: PodU64::from(Self::NOT_FINALIZED), bump, reserved: [0; 128], table: [WeightEntry::default(); Self::MAX_TABLE_ENTRIES], @@ -77,75 +72,93 @@ impl WeightTable { (pda, bump, seeds) } - pub fn get_mints(&self) -> Vec { - self.table - .iter() - .filter(|entry| !entry.is_empty()) - .map(|entry| entry.mint) - .collect() - } - - pub fn get_mint_hash(mints: Vec) -> u64 { - let mut hash = 0; - - // Makes sure the hash is the same regardless of the order of the mints - let mut sorted_mints = mints; - sorted_mints.sort(); + pub fn initalize_weight_table( + &mut self, + config_supported_mints: &[Pubkey], + ) -> Result<(), TipRouterError> { + if self.initialized() { + return Err(TipRouterError::WeightTableAlreadyInitialized); + } - for mint in sorted_mints { - let bytes = mint.to_bytes(); - let u64_slice = u64::from_le_bytes(bytes[0..8].try_into().unwrap()); + // Check for empty vector + if config_supported_mints.is_empty() { + return Err(TipRouterError::NoMintsInTable); + } - hash ^= u64_slice; + // Check if vector exceeds maximum allowed entries + if config_supported_mints.len() > Self::MAX_TABLE_ENTRIES { + return Err(TipRouterError::TooManyMintsForTable); } - hash - } + // Check for duplicates using nested iterators + let unique_mints: HashSet<_> = config_supported_mints.iter().collect(); - pub fn check_mints_okay(&self, mint_hash: u64, mint_count: u8) -> Result<(), TipRouterError> { - if mint_count != self.entry_count() as u8 { - return Err(TipRouterError::WeightMintsDoNotMatchLength); + println!( + "unique_mints: {:?} {:?}", + unique_mints, config_supported_mints + ); + if unique_mints.len() != config_supported_mints.len() { + return Err(TipRouterError::DuplicateMintsInTable); } - let table_mint_hash = Self::get_mint_hash(self.get_mints()); - if mint_hash != table_mint_hash { - return Err(TipRouterError::WeightMintsDoNotMatchMintHash); - } + // Set table using iterator + self.table + .iter_mut() + .zip(config_supported_mints.iter()) + .for_each(|(entry, &mint)| { + *entry = WeightEntry::new(mint); + }); + + self.check_initialized()?; Ok(()) } - pub fn entry_count(&self) -> usize { - self.table.iter().filter(|entry| !entry.is_empty()).count() + pub fn set_weight( + &mut self, + mint: &Pubkey, + weight: u128, + current_slot: u64, + ) -> Result<(), TipRouterError> { + self.table + .iter_mut() + .find(|entry| entry.mint() == *mint) + .map_or(Err(TipRouterError::InvalidMintForWeightTable), |entry| { + entry.set_weight(weight, current_slot); + Ok(()) + }) } - pub fn find_weight(&self, mint: &Pubkey) -> Option { + pub fn get_weight(&self, mint: &Pubkey) -> Result { self.table .iter() - .find(|entry| entry.mint == *mint) - .map(|entry| entry.weight) + .find(|entry| entry.mint() == *mint) + .map_or(Err(TipRouterError::InvalidMintForWeightTable), |entry| { + Ok(entry.weight()) + }) } - pub fn set_weight( - &mut self, - mint: &Pubkey, - weight: PreciseWeight, - ) -> Result<(), TipRouterError> { - // First, try to find an existing entry with the given mint - if let Some(entry) = self.table.iter_mut().find(|entry| entry.mint == *mint) { - entry.weight = weight; - return Ok(()); - } + pub fn get_mints(&self) -> Vec { + self.table + .iter() + .filter(|entry| !entry.is_empty()) + .map(|entry| entry.mint()) + .collect() + } - // If no existing entry found, look for the first empty slot - if let Some(entry) = self.table.iter_mut().find(|entry| entry.is_empty()) { - entry.mint = *mint; - entry.weight = weight; - return Ok(()); - } + pub fn find_weight(&self, mint: &Pubkey) -> Option { + self.table + .iter() + .find(|entry| entry.mint() == *mint) + .map(|entry| entry.weight()) + } + + pub fn mint_count(&self) -> usize { + self.table.iter().filter(|entry| !entry.is_empty()).count() + } - // If no existing entry and no empty slots, return error - Err(TipRouterError::NoMoreTableSlots) + pub fn weight_count(&self) -> usize { + self.table.iter().filter(|entry| !entry.is_set()).count() } pub const fn ncn(&self) -> Pubkey { @@ -160,16 +173,19 @@ impl WeightTable { self.slot_created.into() } - pub fn slot_finalized(&self) -> u64 { - self.slot_finalized.into() + pub fn initialized(&self) -> bool { + self.mint_count() > 0 } pub fn finalized(&self) -> bool { - self.slot_finalized != PodU64::from(Self::NOT_FINALIZED) + self.initialized() && self.mint_count() == self.weight_count() } - pub fn finalize(&mut self, current_slot: u64) { - self.slot_finalized = PodU64::from(current_slot); + pub fn check_initialized(&self) -> Result<(), TipRouterError> { + if !self.initialized() { + return Err(TipRouterError::NoMintsInTable); + } + Ok(()) } pub fn load( @@ -204,44 +220,135 @@ impl WeightTable { } } -#[derive(Default, Debug, Clone, Copy, Zeroable, ShankType, Pod)] -#[repr(C)] -pub struct WeightEntry { - pub mint: Pubkey, - pub weight: PreciseWeight, -} +#[cfg(test)] +mod tests { + use solana_program::pubkey::Pubkey; + + use super::*; -impl WeightEntry { - pub const fn new(mint: Pubkey, weight: PreciseWeight) -> Self { - Self { weight, mint } + fn get_test_pubkeys(count: usize) -> Vec { + (0..count).map(|_| Pubkey::new_unique()).collect() } - pub fn is_empty(&self) -> bool { - self.mint.eq(&Pubkey::default()) + #[test] + fn test_initialize_table_success() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + assert_eq!(table.mint_count(), 0); + + let mints = get_test_pubkeys(2); + table.initalize_weight_table(&mints).unwrap(); + assert_eq!(table.mint_count(), 2); } -} -#[cfg(test)] -mod tests { - use solana_program::pubkey::Pubkey; + #[test] + fn test_initialize_table_too_many() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let many_mints = get_test_pubkeys(WeightTable::MAX_TABLE_ENTRIES + 1); + assert_eq!( + table.initalize_weight_table(&many_mints), + Err(TipRouterError::TooManyMintsForTable) + ); + } - use super::*; + #[test] + fn test_initialize_table_max() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let max_mints = get_test_pubkeys(WeightTable::MAX_TABLE_ENTRIES); + table.initalize_weight_table(&max_mints).unwrap(); + assert_eq!(table.mint_count(), WeightTable::MAX_TABLE_ENTRIES); + } + + #[test] + fn test_initialize_table_reinitialize() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let first_mints = get_test_pubkeys(2); + table.initalize_weight_table(&first_mints).unwrap(); + let second_mints = get_test_pubkeys(3); + + assert_eq!( + table.initalize_weight_table(&second_mints), + Err(TipRouterError::WeightTableAlreadyInitialized) + ); + } + + #[test] + fn test_set_weight_success() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let mints = get_test_pubkeys(2); + let mint = mints[0]; + + table.initalize_weight_table(&mints).unwrap(); + + table.set_weight(&mint, 100, 1).unwrap(); + assert_eq!(table.get_weight(&mint).unwrap(), 100); + } #[test] - fn test_weight_table_new() { + fn test_set_weight_invalid_mint() { let ncn = Pubkey::new_unique(); - let table = WeightTable::new(ncn, 0, 0, 0); - assert_eq!(table.entry_count(), 0); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let mints = get_test_pubkeys(2); + + table.initalize_weight_table(&mints).unwrap(); + + let invalid_mint = Pubkey::new_unique(); + assert_eq!( + table.set_weight(&invalid_mint, 100, 1), + Err(TipRouterError::InvalidMintForWeightTable) + ); } #[test] - fn test_weight_table_finalize() { - let mut weight_table = WeightTable::new(Pubkey::new_unique(), 0, 0, 0); + fn test_set_weight_update_existing() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let mints = get_test_pubkeys(2); + let mint = mints[0]; + + table.initalize_weight_table(&mints).unwrap(); + + table.set_weight(&mint, 100, 1).unwrap(); + assert_eq!(table.get_weight(&mint).unwrap(), 100); + + table.set_weight(&mint, 200, 2).unwrap(); + assert_eq!(table.get_weight(&mint).unwrap(), 200); + } + + #[test] + fn test_set_weight_multiple_mints() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let mints = get_test_pubkeys(2); + let mint1 = mints[0]; + let mint2 = mints[1]; + + table.initalize_weight_table(&mints).unwrap(); + + table.set_weight(&mint1, 100, 1).unwrap(); + table.set_weight(&mint2, 200, 1).unwrap(); + + assert_eq!(table.get_weight(&mint1).unwrap(), 100); + assert_eq!(table.get_weight(&mint2).unwrap(), 200); + } + + #[test] + fn test_set_weight_different_slots() { + let ncn = Pubkey::new_unique(); + let mut table = WeightTable::new(ncn, 0, 0, 0); + let mints = get_test_pubkeys(2); + let mint = mints[0]; + + table.initalize_weight_table(&mints).unwrap(); - assert!(!weight_table.finalized()); - assert_eq!(weight_table.slot_finalized(), WeightTable::NOT_FINALIZED); + table.set_weight(&mint, 100, 1).unwrap(); + assert_eq!(table.get_weight(&mint).unwrap(), 100); - weight_table.finalize(0); - assert!(weight_table.finalized()); + table.set_weight(&mint, 200, 5).unwrap(); + assert_eq!(table.get_weight(&mint).unwrap(), 200); } } diff --git a/idl/jito_tip_router.json b/idl/jito_tip_router.json index db3914a..edb7a61 100644 --- a/idl/jito_tip_router.json +++ b/idl/jito_tip_router.json @@ -21,7 +21,7 @@ "isSigner": true }, { - "name": "weightTableAdmin", + "name": "payer", "isMut": true, "isSigner": true }, @@ -50,7 +50,7 @@ } }, { - "name": "UpdateWeightTable", + "name": "AdminUpdateWeightTable", "accounts": [ { "name": "ncn", @@ -87,49 +87,6 @@ "type": "u8", "value": 1 } - }, - { - "name": "FinalizeWeightTable", - "accounts": [ - { - "name": "ncn", - "isMut": false, - "isSigner": false - }, - { - "name": "weightTable", - "isMut": true, - "isSigner": false - }, - { - "name": "weightTableAdmin", - "isMut": false, - "isSigner": true - }, - { - "name": "restakingProgramId", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "ncnEpoch", - "type": "u64" - }, - { - "name": "mintHash", - "type": "u64" - }, - { - "name": "mintCount", - "type": "u8" - } - ], - "discriminant": { - "type": "u8", - "value": 2 - } } ], "accounts": [ @@ -154,12 +111,6 @@ "defined": "PodU64" } }, - { - "name": "slotFinalized", - "type": { - "defined": "PodU64" - } - }, { "name": "bump", "type": "u8" @@ -190,63 +141,39 @@ ], "types": [ { - "name": "PreciseNumberWrapper", + "name": "WeightEntry", "type": { "kind": "struct", "fields": [ { - "name": "value", + "name": "mint", + "type": "publicKey" + }, + { + "name": "weight", "type": { - "array": [ - "u8", - 16 - ] + "defined": "PodU128" } - } - ] - } - }, - { - "name": "PreciseWeight", - "type": { - "kind": "struct", - "fields": [ + }, { - "name": "number", + "name": "slotSet", "type": { - "defined": "PreciseNumberWrapper" + "defined": "PodU64" } - } - ] - } - }, - { - "name": "PreciseTokenSupply", - "type": { - "kind": "struct", - "fields": [ + }, { - "name": "number", + "name": "slotUpdated", "type": { - "defined": "PreciseNumberWrapper" + "defined": "PodU64" } - } - ] - } - }, - { - "name": "WeightEntry", - "type": { - "kind": "struct", - "fields": [ - { - "name": "mint", - "type": "publicKey" }, { - "name": "weight", + "name": "reserved", "type": { - "defined": "PreciseWeight" + "array": [ + "u8", + 128 + ] } } ] @@ -254,11 +181,6 @@ } ], "errors": [ - { - "code": 8192, - "name": "NoMoreTableSlots", - "msg": "No more table slots available" - }, { "code": 8448, "name": "DenominatorIsZero", @@ -291,18 +213,43 @@ }, { "code": 8705, + "name": "DuplicateMintsInTable", + "msg": "Duplicate mints in table" + }, + { + "code": 8706, + "name": "NoMintsInTable", + "msg": "There are no mints in the table" + }, + { + "code": 8707, + "name": "TooManyMintsForTable", + "msg": "Too many mints for table" + }, + { + "code": 8708, + "name": "WeightTableAlreadyInitialized", + "msg": "Weight table already initialized" + }, + { + "code": 8709, "name": "CannotCreateFutureWeightTables", "msg": "Cannnot create future weight tables" }, { - "code": 8706, + "code": 8710, "name": "WeightMintsDoNotMatchLength", "msg": "Weight mints do not match - length" }, { - "code": 8707, + "code": 8711, "name": "WeightMintsDoNotMatchMintHash", "msg": "Weight mints do not match - mint hash" + }, + { + "code": 8712, + "name": "InvalidMintForWeightTable", + "msg": "Invalid mint for weight table" } ], "metadata": { diff --git a/program/src/update_weight_table.rs b/program/src/admin_update_weight_table.rs similarity index 77% rename from program/src/update_weight_table.rs rename to program/src/admin_update_weight_table.rs index 1d830d0..d0381c8 100644 --- a/program/src/update_weight_table.rs +++ b/program/src/admin_update_weight_table.rs @@ -1,16 +1,14 @@ use jito_bytemuck::AccountDeserialize; use jito_jsm_core::loader::{load_signer, load_token_mint}; use jito_restaking_core::ncn::Ncn; -use jito_tip_router_core::{ - error::TipRouterError, precise_numbers::PreciseWeight, weight_table::WeightTable, -}; +use jito_tip_router_core::{error::TipRouterError, weight_table::WeightTable}; use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError, - pubkey::Pubkey, + account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, + program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, }; -/// Initializes a Weight Table -pub fn process_update_weight_table( +/// Updates weight table +pub fn process_admin_update_weight_table( program_id: &Pubkey, accounts: &[AccountInfo], ncn_epoch: u64, @@ -45,7 +43,9 @@ pub fn process_update_weight_table( let mut weight_table_data = weight_table.try_borrow_mut_data()?; let weight_table_account = WeightTable::try_from_slice_unchecked_mut(&mut weight_table_data)?; - weight_table_account.set_weight(mint.key, PreciseWeight::from_weight(weight))?; + weight_table_account.check_initialized()?; + + weight_table_account.set_weight(mint.key, weight, Clock::get()?.slot)?; Ok(()) } diff --git a/program/src/finalize_weight_table.rs b/program/src/finalize_weight_table.rs deleted file mode 100644 index 76583c0..0000000 --- a/program/src/finalize_weight_table.rs +++ /dev/null @@ -1,51 +0,0 @@ -use jito_bytemuck::AccountDeserialize; -use jito_jsm_core::loader::load_signer; -use jito_restaking_core::ncn::Ncn; -use jito_tip_router_core::{error::TipRouterError, weight_table::WeightTable}; -use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, - program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, -}; - -/// Initializes a Weight Table -pub fn process_finalize_weight_table( - program_id: &Pubkey, - accounts: &[AccountInfo], - ncn_epoch: u64, - mint_hash: u64, - mint_count: u8, -) -> ProgramResult { - let [ncn, weight_table, weight_table_admin, restaking_program_id] = accounts else { - return Err(ProgramError::NotEnoughAccountKeys); - }; - - Ncn::load(restaking_program_id.key, ncn, false)?; - let ncn_weight_table_admin = { - let ncn_data = ncn.data.borrow(); - let ncn = Ncn::try_from_slice_unchecked(&ncn_data)?; - ncn.weight_table_admin - }; - - load_signer(weight_table_admin, true)?; - WeightTable::load(program_id, weight_table, ncn, ncn_epoch, true)?; - - if restaking_program_id.key.ne(&jito_restaking_program::id()) { - msg!("Incorrect restaking program ID"); - return Err(ProgramError::InvalidAccountData); - } - - if ncn_weight_table_admin.ne(weight_table_admin.key) { - msg!("Vault update delegations ticket is not at the correct PDA"); - return Err(TipRouterError::IncorrectWeightTableAdmin.into()); - } - - let mut weight_table_data = weight_table.try_borrow_mut_data()?; - let weight_table_account = WeightTable::try_from_slice_unchecked_mut(&mut weight_table_data)?; - - weight_table_account.check_mints_okay(mint_hash, mint_count)?; - - let current_slot = Clock::get()?.slot; - weight_table_account.finalize(current_slot); - - Ok(()) -} diff --git a/program/src/initialize_weight_table.rs b/program/src/initialize_weight_table.rs index d64bddc..b9368f2 100644 --- a/program/src/initialize_weight_table.rs +++ b/program/src/initialize_weight_table.rs @@ -5,7 +5,7 @@ use jito_jsm_core::{ create_account, loader::{load_signer, load_system_account, load_system_program}, }; -use jito_restaking_core::{config::Config, ncn::Ncn}; +use jito_restaking_core::config::Config; use jito_tip_router_core::{error::TipRouterError, weight_table::WeightTable}; use solana_program::{ account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, @@ -19,11 +19,12 @@ pub fn process_initialize_weight_table( accounts: &[AccountInfo], first_slot_of_ncn_epoch: Option, ) -> ProgramResult { - let [restaking_config, ncn, weight_table, weight_table_admin, restaking_program_id, system_program] = + let [restaking_config, ncn, weight_table, payer, restaking_program_id, system_program] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; + Config::load(restaking_program_id.key, restaking_config, false)?; let ncn_epoch_length = { let config_data = restaking_config.data.borrow(); @@ -31,28 +32,17 @@ pub fn process_initialize_weight_table( config.epoch_length() }; - Ncn::load(restaking_program_id.key, ncn, false)?; - let ncn_weight_table_admin = { - //TODO switch to weight table admin when that is merged - let ncn_data = ncn.data.borrow(); - let ncn = Ncn::try_from_slice_unchecked(&ncn_data)?; - ncn.admin - }; + //TODO load config and grab st mint list load_system_account(weight_table, true)?; - load_signer(weight_table_admin, true)?; load_system_program(system_program)?; + load_signer(payer, true)?; if restaking_program_id.key.ne(&jito_restaking_program::id()) { msg!("Incorrect restaking program ID"); return Err(ProgramError::InvalidAccountData); } - if ncn_weight_table_admin.ne(weight_table_admin.key) { - msg!("Vault update delegations ticket is not at the correct PDA"); - return Err(TipRouterError::IncorrectWeightTableAdmin.into()); - } - let current_slot = Clock::get()?.slot; let current_ncn_epoch = current_slot .checked_div(ncn_epoch_length) @@ -84,7 +74,7 @@ pub fn process_initialize_weight_table( ncn_epoch ); create_account( - weight_table_admin, + payer, weight_table, system_program, program_id, @@ -99,5 +89,8 @@ pub fn process_initialize_weight_table( *weight_table_account = WeightTable::new(*ncn.key, ncn_epoch, current_slot, weight_table_bump); + //TODO pass in st_mint list from config + weight_table_account.initalize_weight_table(&[])?; + Ok(()) } diff --git a/program/src/lib.rs b/program/src/lib.rs index 6f5f139..1bc49b0 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -1,6 +1,5 @@ -mod finalize_weight_table; +mod admin_update_weight_table; mod initialize_weight_table; -mod update_weight_table; use borsh::BorshDeserialize; use const_str_to_pubkey::str_to_pubkey; @@ -13,9 +12,8 @@ use solana_program::{ use solana_security_txt::security_txt; use crate::{ - finalize_weight_table::process_finalize_weight_table, + admin_update_weight_table::process_admin_update_weight_table, initialize_weight_table::process_initialize_weight_table, - update_weight_table::process_update_weight_table, }; declare_id!(str_to_pubkey(env!("TIP_ROUTER_PROGRAM_ID"))); @@ -59,20 +57,9 @@ pub fn process_instruction( // ------------------------------------------ // Update // ------------------------------------------ - WeightTableInstruction::UpdateWeightTable { ncn_epoch, weight } => { + WeightTableInstruction::AdminUpdateWeightTable { ncn_epoch, weight } => { msg!("Instruction: UpdateWeightTable"); - process_update_weight_table(program_id, accounts, ncn_epoch, weight) - } - // ------------------------------------------ - // Finalization - // ------------------------------------------ - WeightTableInstruction::FinalizeWeightTable { - ncn_epoch, - mint_hash, - mint_count, - } => { - msg!("Instruction: FinalizeWeightTable"); - process_finalize_weight_table(program_id, accounts, ncn_epoch, mint_hash, mint_count) + process_admin_update_weight_table(program_id, accounts, ncn_epoch, weight) } } } diff --git a/scripts/generate-clients.js b/scripts/generate-clients.js index bae2eb4..73a0d1e 100644 --- a/scripts/generate-clients.js +++ b/scripts/generate-clients.js @@ -17,6 +17,22 @@ const jsWeightTableClientDir = path.join(jsClientsDir, "jito_tip_router"); const weightTableRootNode = anchorIdl.rootNodeFromAnchor(require(path.join(idlDir, "jito_tip_router.json"))); const weightTableKinobi = kinobi.createFromRoot(weightTableRootNode); weightTableKinobi.update(kinobi.bottomUpTransformerVisitor([ + { + // PodU128 -> u128 + select: (node) => { + return ( + kinobi.isNode(node, "structFieldTypeNode") && + node.type.name === "podU128" + ); + }, + transform: (node) => { + kinobi.assertIsNode(node, "structFieldTypeNode"); + return { + ...node, + type: kinobi.numberTypeNode("u128"), + }; + }, + }, { // PodU64 -> u64 select: (node) => { From f307d69a22927e980b83fab9b22a1ab884489db4 Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Fri, 8 Nov 2024 08:36:46 -0700 Subject: [PATCH 4/5] okay to review --- .../instructions/adminUpdateWeightTable.ts | 18 ++++++- .../instructions/initializeNCNConfig.ts | 28 +++++----- .../instructions/initializeWeightTable.ts | 6 +-- .../instructions/admin_update_weight_table.rs | 43 ++++++++++++++-- .../instructions/initialize_n_c_n_config.rs | 38 +++++++------- .../instructions/initialize_weight_table.rs | 8 +-- core/src/instruction.rs | 7 +-- core/src/ncn_config.rs | 10 ++-- idl/jito_tip_router.json | 9 +++- .../tests/fixtures/test_builder.rs | 3 -- .../tests/fixtures/tip_router_client.rs | 51 +++++++++++++++++-- .../tip_router/admin_update_weight_table.rs | 37 ++++++++++++++ .../tip_router/initialize_weight_table.rs | 15 +++--- integration_tests/tests/tip_router/mod.rs | 1 + program/src/admin_update_weight_table.rs | 1 - program/src/initialize_weight_table.rs | 2 +- 16 files changed, 204 insertions(+), 73 deletions(-) create mode 100644 integration_tests/tests/tip_router/admin_update_weight_table.rs diff --git a/clients/js/jito_tip_router/instructions/adminUpdateWeightTable.ts b/clients/js/jito_tip_router/instructions/adminUpdateWeightTable.ts index 1d71b79..36e207f 100644 --- a/clients/js/jito_tip_router/instructions/adminUpdateWeightTable.ts +++ b/clients/js/jito_tip_router/instructions/adminUpdateWeightTable.ts @@ -45,6 +45,7 @@ export type AdminUpdateWeightTableInstruction< TAccountNcn extends string | IAccountMeta = string, TAccountWeightTable extends string | IAccountMeta = string, TAccountWeightTableAdmin extends string | IAccountMeta = string, + TAccountMint extends string | IAccountMeta = string, TAccountRestakingProgramId extends string | IAccountMeta = string, TRemainingAccounts extends readonly IAccountMeta[] = [], > = IInstruction & @@ -59,6 +60,9 @@ export type AdminUpdateWeightTableInstruction< ? ReadonlySignerAccount & IAccountSignerMeta : TAccountWeightTableAdmin, + TAccountMint extends string + ? ReadonlyAccount + : TAccountMint, TAccountRestakingProgramId extends string ? ReadonlyAccount : TAccountRestakingProgramId, @@ -113,11 +117,13 @@ export type AdminUpdateWeightTableInput< TAccountNcn extends string = string, TAccountWeightTable extends string = string, TAccountWeightTableAdmin extends string = string, + TAccountMint extends string = string, TAccountRestakingProgramId extends string = string, > = { ncn: Address; weightTable: Address; weightTableAdmin: TransactionSigner; + mint: Address; restakingProgramId: Address; ncnEpoch: AdminUpdateWeightTableInstructionDataArgs['ncnEpoch']; weight: AdminUpdateWeightTableInstructionDataArgs['weight']; @@ -127,6 +133,7 @@ export function getAdminUpdateWeightTableInstruction< TAccountNcn extends string, TAccountWeightTable extends string, TAccountWeightTableAdmin extends string, + TAccountMint extends string, TAccountRestakingProgramId extends string, TProgramAddress extends Address = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, >( @@ -134,6 +141,7 @@ export function getAdminUpdateWeightTableInstruction< TAccountNcn, TAccountWeightTable, TAccountWeightTableAdmin, + TAccountMint, TAccountRestakingProgramId >, config?: { programAddress?: TProgramAddress } @@ -142,6 +150,7 @@ export function getAdminUpdateWeightTableInstruction< TAccountNcn, TAccountWeightTable, TAccountWeightTableAdmin, + TAccountMint, TAccountRestakingProgramId > { // Program address. @@ -156,6 +165,7 @@ export function getAdminUpdateWeightTableInstruction< value: input.weightTableAdmin ?? null, isWritable: false, }, + mint: { value: input.mint ?? null, isWritable: false }, restakingProgramId: { value: input.restakingProgramId ?? null, isWritable: false, @@ -175,6 +185,7 @@ export function getAdminUpdateWeightTableInstruction< getAccountMeta(accounts.ncn), getAccountMeta(accounts.weightTable), getAccountMeta(accounts.weightTableAdmin), + getAccountMeta(accounts.mint), getAccountMeta(accounts.restakingProgramId), ], programAddress, @@ -186,6 +197,7 @@ export function getAdminUpdateWeightTableInstruction< TAccountNcn, TAccountWeightTable, TAccountWeightTableAdmin, + TAccountMint, TAccountRestakingProgramId >; @@ -201,7 +213,8 @@ export type ParsedAdminUpdateWeightTableInstruction< ncn: TAccountMetas[0]; weightTable: TAccountMetas[1]; weightTableAdmin: TAccountMetas[2]; - restakingProgramId: TAccountMetas[3]; + mint: TAccountMetas[3]; + restakingProgramId: TAccountMetas[4]; }; data: AdminUpdateWeightTableInstructionData; }; @@ -214,7 +227,7 @@ export function parseAdminUpdateWeightTableInstruction< IInstructionWithAccounts & IInstructionWithData ): ParsedAdminUpdateWeightTableInstruction { - if (instruction.accounts.length < 4) { + if (instruction.accounts.length < 5) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -230,6 +243,7 @@ export function parseAdminUpdateWeightTableInstruction< ncn: getNextAccount(), weightTable: getNextAccount(), weightTableAdmin: getNextAccount(), + mint: getNextAccount(), restakingProgramId: getNextAccount(), }, data: getAdminUpdateWeightTableInstructionDataDecoder().decode( diff --git a/clients/js/jito_tip_router/instructions/initializeNCNConfig.ts b/clients/js/jito_tip_router/instructions/initializeNCNConfig.ts index eca092d..0f7834e 100644 --- a/clients/js/jito_tip_router/instructions/initializeNCNConfig.ts +++ b/clients/js/jito_tip_router/instructions/initializeNCNConfig.ts @@ -41,7 +41,7 @@ export function getInitializeNCNConfigDiscriminatorBytes() { export type InitializeNCNConfigInstruction< TProgram extends string = typeof JITO_TIP_ROUTER_PROGRAM_ADDRESS, TAccountRestakingConfig extends string | IAccountMeta = string, - TAccountConfig extends string | IAccountMeta = string, + TAccountNcnConfig extends string | IAccountMeta = string, TAccountNcn extends string | IAccountMeta = string, TAccountNcnAdmin extends string | IAccountMeta = string, TAccountFeeWallet extends string | IAccountMeta = string, @@ -58,9 +58,9 @@ export type InitializeNCNConfigInstruction< TAccountRestakingConfig extends string ? ReadonlyAccount : TAccountRestakingConfig, - TAccountConfig extends string - ? WritableAccount - : TAccountConfig, + TAccountNcnConfig extends string + ? WritableAccount + : TAccountNcnConfig, TAccountNcn extends string ? ReadonlyAccount : TAccountNcn, TAccountNcnAdmin extends string ? ReadonlySignerAccount & @@ -131,7 +131,7 @@ export function getInitializeNCNConfigInstructionDataCodec(): Codec< export type InitializeNCNConfigInput< TAccountRestakingConfig extends string = string, - TAccountConfig extends string = string, + TAccountNcnConfig extends string = string, TAccountNcn extends string = string, TAccountNcnAdmin extends string = string, TAccountFeeWallet extends string = string, @@ -140,7 +140,7 @@ export type InitializeNCNConfigInput< TAccountSystemProgram extends string = string, > = { restakingConfig: Address; - config: Address; + ncnConfig: Address; ncn: Address; ncnAdmin: TransactionSigner; feeWallet: Address; @@ -154,7 +154,7 @@ export type InitializeNCNConfigInput< export function getInitializeNCNConfigInstruction< TAccountRestakingConfig extends string, - TAccountConfig extends string, + TAccountNcnConfig extends string, TAccountNcn extends string, TAccountNcnAdmin extends string, TAccountFeeWallet extends string, @@ -165,7 +165,7 @@ export function getInitializeNCNConfigInstruction< >( input: InitializeNCNConfigInput< TAccountRestakingConfig, - TAccountConfig, + TAccountNcnConfig, TAccountNcn, TAccountNcnAdmin, TAccountFeeWallet, @@ -177,7 +177,7 @@ export function getInitializeNCNConfigInstruction< ): InitializeNCNConfigInstruction< TProgramAddress, TAccountRestakingConfig, - TAccountConfig, + TAccountNcnConfig, TAccountNcn, TAccountNcnAdmin, TAccountFeeWallet, @@ -195,7 +195,7 @@ export function getInitializeNCNConfigInstruction< value: input.restakingConfig ?? null, isWritable: false, }, - config: { value: input.config ?? null, isWritable: true }, + ncnConfig: { value: input.ncnConfig ?? null, isWritable: true }, ncn: { value: input.ncn ?? null, isWritable: false }, ncnAdmin: { value: input.ncnAdmin ?? null, isWritable: false }, feeWallet: { value: input.feeWallet ?? null, isWritable: false }, @@ -227,7 +227,7 @@ export function getInitializeNCNConfigInstruction< const instruction = { accounts: [ getAccountMeta(accounts.restakingConfig), - getAccountMeta(accounts.config), + getAccountMeta(accounts.ncnConfig), getAccountMeta(accounts.ncn), getAccountMeta(accounts.ncnAdmin), getAccountMeta(accounts.feeWallet), @@ -242,7 +242,7 @@ export function getInitializeNCNConfigInstruction< } as InitializeNCNConfigInstruction< TProgramAddress, TAccountRestakingConfig, - TAccountConfig, + TAccountNcnConfig, TAccountNcn, TAccountNcnAdmin, TAccountFeeWallet, @@ -261,7 +261,7 @@ export type ParsedInitializeNCNConfigInstruction< programAddress: Address; accounts: { restakingConfig: TAccountMetas[0]; - config: TAccountMetas[1]; + ncnConfig: TAccountMetas[1]; ncn: TAccountMetas[2]; ncnAdmin: TAccountMetas[3]; feeWallet: TAccountMetas[4]; @@ -294,7 +294,7 @@ export function parseInitializeNCNConfigInstruction< programAddress: instruction.programAddress, accounts: { restakingConfig: getNextAccount(), - config: getNextAccount(), + ncnConfig: getNextAccount(), ncn: getNextAccount(), ncnAdmin: getNextAccount(), feeWallet: getNextAccount(), diff --git a/clients/js/jito_tip_router/instructions/initializeWeightTable.ts b/clients/js/jito_tip_router/instructions/initializeWeightTable.ts index 91e21a3..fb1b904 100644 --- a/clients/js/jito_tip_router/instructions/initializeWeightTable.ts +++ b/clients/js/jito_tip_router/instructions/initializeWeightTable.ts @@ -30,6 +30,7 @@ import { type OptionOrNullable, type ReadonlyAccount, type TransactionSigner, + type WritableAccount, type WritableSignerAccount, } from '@solana/web3.js'; import { JITO_TIP_ROUTER_PROGRAM_ADDRESS } from '../programs'; @@ -65,8 +66,7 @@ export type InitializeWeightTableInstruction< : TAccountNcnConfig, TAccountNcn extends string ? ReadonlyAccount : TAccountNcn, TAccountWeightTable extends string - ? WritableSignerAccount & - IAccountSignerMeta + ? WritableAccount : TAccountWeightTable, TAccountPayer extends string ? WritableSignerAccount & @@ -133,7 +133,7 @@ export type InitializeWeightTableInput< restakingConfig: Address; ncnConfig: Address; ncn: Address; - weightTable: TransactionSigner; + weightTable: Address; payer: TransactionSigner; restakingProgramId: Address; systemProgram?: Address; diff --git a/clients/rust/jito_tip_router/src/generated/instructions/admin_update_weight_table.rs b/clients/rust/jito_tip_router/src/generated/instructions/admin_update_weight_table.rs index 0b1ecf1..0df738f 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/admin_update_weight_table.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/admin_update_weight_table.rs @@ -14,6 +14,8 @@ pub struct AdminUpdateWeightTable { pub weight_table_admin: solana_program::pubkey::Pubkey, + pub mint: solana_program::pubkey::Pubkey, + pub restaking_program_id: solana_program::pubkey::Pubkey, } @@ -30,7 +32,7 @@ impl AdminUpdateWeightTable { args: AdminUpdateWeightTableInstructionArgs, remaining_accounts: &[solana_program::instruction::AccountMeta], ) -> solana_program::instruction::Instruction { - let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); accounts.push(solana_program::instruction::AccountMeta::new_readonly( self.ncn, false, )); @@ -42,6 +44,9 @@ impl AdminUpdateWeightTable { self.weight_table_admin, true, )); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + self.mint, false, + )); accounts.push(solana_program::instruction::AccountMeta::new_readonly( self.restaking_program_id, false, @@ -92,12 +97,14 @@ pub struct AdminUpdateWeightTableInstructionArgs { /// 0. `[]` ncn /// 1. `[writable]` weight_table /// 2. `[signer]` weight_table_admin -/// 3. `[]` restaking_program_id +/// 3. `[]` mint +/// 4. `[]` restaking_program_id #[derive(Clone, Debug, Default)] pub struct AdminUpdateWeightTableBuilder { ncn: Option, weight_table: Option, weight_table_admin: Option, + mint: Option, restaking_program_id: Option, ncn_epoch: Option, weight: Option, @@ -127,6 +134,11 @@ impl AdminUpdateWeightTableBuilder { self } #[inline(always)] + pub fn mint(&mut self, mint: solana_program::pubkey::Pubkey) -> &mut Self { + self.mint = Some(mint); + self + } + #[inline(always)] pub fn restaking_program_id( &mut self, restaking_program_id: solana_program::pubkey::Pubkey, @@ -170,6 +182,7 @@ impl AdminUpdateWeightTableBuilder { weight_table_admin: self .weight_table_admin .expect("weight_table_admin is not set"), + mint: self.mint.expect("mint is not set"), restaking_program_id: self .restaking_program_id .expect("restaking_program_id is not set"), @@ -191,6 +204,8 @@ pub struct AdminUpdateWeightTableCpiAccounts<'a, 'b> { pub weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, + pub mint: &'b solana_program::account_info::AccountInfo<'a>, + pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, } @@ -205,6 +220,8 @@ pub struct AdminUpdateWeightTableCpi<'a, 'b> { pub weight_table_admin: &'b solana_program::account_info::AccountInfo<'a>, + pub mint: &'b solana_program::account_info::AccountInfo<'a>, + pub restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, /// The arguments for the instruction. pub __args: AdminUpdateWeightTableInstructionArgs, @@ -221,6 +238,7 @@ impl<'a, 'b> AdminUpdateWeightTableCpi<'a, 'b> { ncn: accounts.ncn, weight_table: accounts.weight_table, weight_table_admin: accounts.weight_table_admin, + mint: accounts.mint, restaking_program_id: accounts.restaking_program_id, __args: args, } @@ -258,7 +276,7 @@ impl<'a, 'b> AdminUpdateWeightTableCpi<'a, 'b> { bool, )], ) -> solana_program::entrypoint::ProgramResult { - let mut accounts = Vec::with_capacity(4 + remaining_accounts.len()); + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); accounts.push(solana_program::instruction::AccountMeta::new_readonly( *self.ncn.key, false, @@ -271,6 +289,10 @@ impl<'a, 'b> AdminUpdateWeightTableCpi<'a, 'b> { *self.weight_table_admin.key, true, )); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + *self.mint.key, + false, + )); accounts.push(solana_program::instruction::AccountMeta::new_readonly( *self.restaking_program_id.key, false, @@ -293,11 +315,12 @@ impl<'a, 'b> AdminUpdateWeightTableCpi<'a, 'b> { accounts, data, }; - let mut account_infos = Vec::with_capacity(4 + 1 + remaining_accounts.len()); + let mut account_infos = Vec::with_capacity(5 + 1 + remaining_accounts.len()); account_infos.push(self.__program.clone()); account_infos.push(self.ncn.clone()); account_infos.push(self.weight_table.clone()); account_infos.push(self.weight_table_admin.clone()); + account_infos.push(self.mint.clone()); account_infos.push(self.restaking_program_id.clone()); remaining_accounts .iter() @@ -318,7 +341,8 @@ impl<'a, 'b> AdminUpdateWeightTableCpi<'a, 'b> { /// 0. `[]` ncn /// 1. `[writable]` weight_table /// 2. `[signer]` weight_table_admin -/// 3. `[]` restaking_program_id +/// 3. `[]` mint +/// 4. `[]` restaking_program_id #[derive(Clone, Debug)] pub struct AdminUpdateWeightTableCpiBuilder<'a, 'b> { instruction: Box>, @@ -331,6 +355,7 @@ impl<'a, 'b> AdminUpdateWeightTableCpiBuilder<'a, 'b> { ncn: None, weight_table: None, weight_table_admin: None, + mint: None, restaking_program_id: None, ncn_epoch: None, weight: None, @@ -360,6 +385,11 @@ impl<'a, 'b> AdminUpdateWeightTableCpiBuilder<'a, 'b> { self } #[inline(always)] + pub fn mint(&mut self, mint: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.mint = Some(mint); + self + } + #[inline(always)] pub fn restaking_program_id( &mut self, restaking_program_id: &'b solana_program::account_info::AccountInfo<'a>, @@ -441,6 +471,8 @@ impl<'a, 'b> AdminUpdateWeightTableCpiBuilder<'a, 'b> { .weight_table_admin .expect("weight_table_admin is not set"), + mint: self.instruction.mint.expect("mint is not set"), + restaking_program_id: self .instruction .restaking_program_id @@ -460,6 +492,7 @@ struct AdminUpdateWeightTableCpiBuilderInstruction<'a, 'b> { ncn: Option<&'b solana_program::account_info::AccountInfo<'a>>, weight_table: Option<&'b solana_program::account_info::AccountInfo<'a>>, weight_table_admin: Option<&'b solana_program::account_info::AccountInfo<'a>>, + mint: Option<&'b solana_program::account_info::AccountInfo<'a>>, restaking_program_id: Option<&'b solana_program::account_info::AccountInfo<'a>>, ncn_epoch: Option, weight: Option, diff --git a/clients/rust/jito_tip_router/src/generated/instructions/initialize_n_c_n_config.rs b/clients/rust/jito_tip_router/src/generated/instructions/initialize_n_c_n_config.rs index 5230bf6..1806829 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/initialize_n_c_n_config.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/initialize_n_c_n_config.rs @@ -10,7 +10,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; pub struct InitializeNCNConfig { pub restaking_config: solana_program::pubkey::Pubkey, - pub config: solana_program::pubkey::Pubkey, + pub ncn_config: solana_program::pubkey::Pubkey, pub ncn: solana_program::pubkey::Pubkey, @@ -44,7 +44,7 @@ impl InitializeNCNConfig { false, )); accounts.push(solana_program::instruction::AccountMeta::new( - self.config, + self.ncn_config, false, )); accounts.push(solana_program::instruction::AccountMeta::new_readonly( @@ -115,7 +115,7 @@ pub struct InitializeNCNConfigInstructionArgs { /// ### Accounts: /// /// 0. `[]` restaking_config -/// 1. `[writable]` config +/// 1. `[writable]` ncn_config /// 2. `[]` ncn /// 3. `[signer]` ncn_admin /// 4. `[]` fee_wallet @@ -125,7 +125,7 @@ pub struct InitializeNCNConfigInstructionArgs { #[derive(Clone, Debug, Default)] pub struct InitializeNCNConfigBuilder { restaking_config: Option, - config: Option, + ncn_config: Option, ncn: Option, ncn_admin: Option, fee_wallet: Option, @@ -151,8 +151,8 @@ impl InitializeNCNConfigBuilder { self } #[inline(always)] - pub fn config(&mut self, config: solana_program::pubkey::Pubkey) -> &mut Self { - self.config = Some(config); + pub fn ncn_config(&mut self, ncn_config: solana_program::pubkey::Pubkey) -> &mut Self { + self.ncn_config = Some(ncn_config); self } #[inline(always)] @@ -229,7 +229,7 @@ impl InitializeNCNConfigBuilder { pub fn instruction(&self) -> solana_program::instruction::Instruction { let accounts = InitializeNCNConfig { restaking_config: self.restaking_config.expect("restaking_config is not set"), - config: self.config.expect("config is not set"), + ncn_config: self.ncn_config.expect("ncn_config is not set"), ncn: self.ncn.expect("ncn is not set"), ncn_admin: self.ncn_admin.expect("ncn_admin is not set"), fee_wallet: self.fee_wallet.expect("fee_wallet is not set"), @@ -260,7 +260,7 @@ impl InitializeNCNConfigBuilder { pub struct InitializeNCNConfigCpiAccounts<'a, 'b> { pub restaking_config: &'b solana_program::account_info::AccountInfo<'a>, - pub config: &'b solana_program::account_info::AccountInfo<'a>, + pub ncn_config: &'b solana_program::account_info::AccountInfo<'a>, pub ncn: &'b solana_program::account_info::AccountInfo<'a>, @@ -282,7 +282,7 @@ pub struct InitializeNCNConfigCpi<'a, 'b> { pub restaking_config: &'b solana_program::account_info::AccountInfo<'a>, - pub config: &'b solana_program::account_info::AccountInfo<'a>, + pub ncn_config: &'b solana_program::account_info::AccountInfo<'a>, pub ncn: &'b solana_program::account_info::AccountInfo<'a>, @@ -308,7 +308,7 @@ impl<'a, 'b> InitializeNCNConfigCpi<'a, 'b> { Self { __program: program, restaking_config: accounts.restaking_config, - config: accounts.config, + ncn_config: accounts.ncn_config, ncn: accounts.ncn, ncn_admin: accounts.ncn_admin, fee_wallet: accounts.fee_wallet, @@ -357,7 +357,7 @@ impl<'a, 'b> InitializeNCNConfigCpi<'a, 'b> { false, )); accounts.push(solana_program::instruction::AccountMeta::new( - *self.config.key, + *self.ncn_config.key, false, )); accounts.push(solana_program::instruction::AccountMeta::new_readonly( @@ -405,7 +405,7 @@ impl<'a, 'b> InitializeNCNConfigCpi<'a, 'b> { let mut account_infos = Vec::with_capacity(8 + 1 + remaining_accounts.len()); account_infos.push(self.__program.clone()); account_infos.push(self.restaking_config.clone()); - account_infos.push(self.config.clone()); + account_infos.push(self.ncn_config.clone()); account_infos.push(self.ncn.clone()); account_infos.push(self.ncn_admin.clone()); account_infos.push(self.fee_wallet.clone()); @@ -429,7 +429,7 @@ impl<'a, 'b> InitializeNCNConfigCpi<'a, 'b> { /// ### Accounts: /// /// 0. `[]` restaking_config -/// 1. `[writable]` config +/// 1. `[writable]` ncn_config /// 2. `[]` ncn /// 3. `[signer]` ncn_admin /// 4. `[]` fee_wallet @@ -446,7 +446,7 @@ impl<'a, 'b> InitializeNCNConfigCpiBuilder<'a, 'b> { let instruction = Box::new(InitializeNCNConfigCpiBuilderInstruction { __program: program, restaking_config: None, - config: None, + ncn_config: None, ncn: None, ncn_admin: None, fee_wallet: None, @@ -469,11 +469,11 @@ impl<'a, 'b> InitializeNCNConfigCpiBuilder<'a, 'b> { self } #[inline(always)] - pub fn config( + pub fn ncn_config( &mut self, - config: &'b solana_program::account_info::AccountInfo<'a>, + ncn_config: &'b solana_program::account_info::AccountInfo<'a>, ) -> &mut Self { - self.instruction.config = Some(config); + self.instruction.ncn_config = Some(ncn_config); self } #[inline(always)] @@ -602,7 +602,7 @@ impl<'a, 'b> InitializeNCNConfigCpiBuilder<'a, 'b> { .restaking_config .expect("restaking_config is not set"), - config: self.instruction.config.expect("config is not set"), + ncn_config: self.instruction.ncn_config.expect("ncn_config is not set"), ncn: self.instruction.ncn.expect("ncn is not set"), @@ -637,7 +637,7 @@ impl<'a, 'b> InitializeNCNConfigCpiBuilder<'a, 'b> { struct InitializeNCNConfigCpiBuilderInstruction<'a, 'b> { __program: &'b solana_program::account_info::AccountInfo<'a>, restaking_config: Option<&'b solana_program::account_info::AccountInfo<'a>>, - config: Option<&'b solana_program::account_info::AccountInfo<'a>>, + ncn_config: Option<&'b solana_program::account_info::AccountInfo<'a>>, ncn: Option<&'b solana_program::account_info::AccountInfo<'a>>, ncn_admin: Option<&'b solana_program::account_info::AccountInfo<'a>>, fee_wallet: Option<&'b solana_program::account_info::AccountInfo<'a>>, diff --git a/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs b/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs index c3a04a2..1c703fc 100644 --- a/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs +++ b/clients/rust/jito_tip_router/src/generated/instructions/initialize_weight_table.rs @@ -50,7 +50,7 @@ impl InitializeWeightTable { )); accounts.push(solana_program::instruction::AccountMeta::new( self.weight_table, - true, + false, )); accounts.push(solana_program::instruction::AccountMeta::new( self.payer, true, @@ -108,7 +108,7 @@ pub struct InitializeWeightTableInstructionArgs { /// 0. `[]` restaking_config /// 1. `[]` ncn_config /// 2. `[]` ncn -/// 3. `[writable, signer]` weight_table +/// 3. `[writable]` weight_table /// 4. `[writable, signer]` payer /// 5. `[]` restaking_program_id /// 6. `[optional]` system_program (default to `11111111111111111111111111111111`) @@ -323,7 +323,7 @@ impl<'a, 'b> InitializeWeightTableCpi<'a, 'b> { )); accounts.push(solana_program::instruction::AccountMeta::new( *self.weight_table.key, - true, + false, )); accounts.push(solana_program::instruction::AccountMeta::new( *self.payer.key, @@ -383,7 +383,7 @@ impl<'a, 'b> InitializeWeightTableCpi<'a, 'b> { /// 0. `[]` restaking_config /// 1. `[]` ncn_config /// 2. `[]` ncn -/// 3. `[writable, signer]` weight_table +/// 3. `[writable]` weight_table /// 4. `[writable, signer]` payer /// 5. `[]` restaking_program_id /// 6. `[]` system_program diff --git a/core/src/instruction.rs b/core/src/instruction.rs index b910e87..169247a 100644 --- a/core/src/instruction.rs +++ b/core/src/instruction.rs @@ -15,7 +15,7 @@ pub enum WeightTableInstruction { /// Initialize the global configuration for this NCN #[account(0, name = "restaking_config")] - #[account(1, writable, name = "config")] + #[account(1, writable, name = "ncn_config")] #[account(2, name = "ncn")] #[account(3, signer, name = "ncn_admin")] #[account(4, name = "fee_wallet")] @@ -55,7 +55,7 @@ pub enum WeightTableInstruction { #[account(0, name = "restaking_config")] #[account(1, name = "ncn_config")] #[account(2, name = "ncn")] - #[account(3, writable, signer, name = "weight_table")] + #[account(3, writable, name = "weight_table")] #[account(4, writable, signer, name = "payer")] #[account(5, name = "restaking_program_id")] #[account(6, name = "system_program")] @@ -67,7 +67,8 @@ pub enum WeightTableInstruction { #[account(0, name = "ncn")] #[account(1, writable, name = "weight_table")] #[account(2, signer, name = "weight_table_admin")] - #[account(3, name = "restaking_program_id")] + #[account(3, name = "mint")] + #[account(4, name = "restaking_program_id")] AdminUpdateWeightTable{ ncn_epoch: u64, weight: u128, diff --git a/core/src/ncn_config.rs b/core/src/ncn_config.rs index 477563e..d7f72bb 100644 --- a/core/src/ncn_config.rs +++ b/core/src/ncn_config.rs @@ -86,26 +86,26 @@ impl NcnConfig { expect_writable: bool, ) -> Result<(), ProgramError> { if ncn_config_account.owner.ne(program_id) { - msg!("Config account has an invalid owner"); + msg!("NCN Config account has an invalid owner"); return Err(ProgramError::InvalidAccountOwner); } if ncn_config_account.data_is_empty() { - msg!("Config account data is empty"); + msg!("NCN Config account data is empty"); return Err(ProgramError::InvalidAccountData); } if expect_writable && !ncn_config_account.is_writable { - msg!("Config account is not writable"); + msg!("NCN Config account is not writable"); return Err(ProgramError::InvalidAccountData); } if ncn_config_account.data.borrow()[0].ne(&Self::DISCRIMINATOR) { - msg!("Config account discriminator is invalid"); + msg!("NCN Config account discriminator is invalid"); return Err(ProgramError::InvalidAccountData); } if ncn_config_account .key .ne(&Self::find_program_address(program_id, ncn).0) { - msg!("Config account is not at the correct PDA"); + msg!("NCN Config account is not at the correct PDA"); return Err(ProgramError::InvalidAccountData); } Ok(()) diff --git a/idl/jito_tip_router.json b/idl/jito_tip_router.json index b534464..54c8f19 100644 --- a/idl/jito_tip_router.json +++ b/idl/jito_tip_router.json @@ -11,7 +11,7 @@ "isSigner": false }, { - "name": "config", + "name": "ncnConfig", "isMut": true, "isSigner": false }, @@ -188,7 +188,7 @@ { "name": "weightTable", "isMut": true, - "isSigner": true + "isSigner": false }, { "name": "payer", @@ -237,6 +237,11 @@ "isMut": false, "isSigner": true }, + { + "name": "mint", + "isMut": false, + "isSigner": false + }, { "name": "restakingProgramId", "isMut": false, diff --git a/integration_tests/tests/fixtures/test_builder.rs b/integration_tests/tests/fixtures/test_builder.rs index 7f0559f..74545ef 100644 --- a/integration_tests/tests/fixtures/test_builder.rs +++ b/integration_tests/tests/fixtures/test_builder.rs @@ -1,10 +1,7 @@ use std::fmt::{Debug, Formatter}; -use jito_bytemuck::{AccountDeserialize, Discriminator}; -use jito_restaking_core::config::Config; use solana_program::clock::Clock; use solana_program_test::{processor, BanksClientError, ProgramTest, ProgramTestContext}; -use solana_sdk::{account::Account, pubkey::Pubkey}; use super::{ restaking_client::{NcnRoot, RestakingProgramClient}, diff --git a/integration_tests/tests/fixtures/tip_router_client.rs b/integration_tests/tests/fixtures/tip_router_client.rs index ac100c2..ce14f56 100644 --- a/integration_tests/tests/fixtures/tip_router_client.rs +++ b/integration_tests/tests/fixtures/tip_router_client.rs @@ -2,8 +2,8 @@ use jito_bytemuck::AccountDeserialize; use jito_restaking_core::config::Config; use jito_tip_router_client::{ instructions::{ - InitializeNCNConfigBuilder, InitializeWeightTableBuilder, SetConfigFeesBuilder, - SetNewAdminBuilder, + AdminUpdateWeightTableBuilder, InitializeNCNConfigBuilder, InitializeWeightTableBuilder, + SetConfigFeesBuilder, SetNewAdminBuilder, }, types::ConfigAdminRole, }; @@ -104,11 +104,11 @@ impl TipRouterClient { block_engine_fee_bps: u64, ) -> TestResult<()> { let restaking_config = Config::find_program_address(&jito_restaking_program::id()).0; - let config_pda = NcnConfig::find_program_address(&jito_tip_router_program::id(), &ncn).0; + let ncn_config = NcnConfig::find_program_address(&jito_tip_router_program::id(), &ncn).0; let ix = InitializeNCNConfigBuilder::new() .restaking_config(restaking_config) - .config(config_pda) + .ncn_config(ncn_config) .ncn(ncn) .ncn_admin(ncn_admin.pubkey()) .fee_wallet(fee_wallet) @@ -264,6 +264,49 @@ impl TipRouterClient { )) .await } + + pub async fn do_admin_update_weight_table( + &mut self, + ncn: Pubkey, + current_slot: u64, + mint: Pubkey, + weight: u128, + ) -> TestResult<()> { + self.admin_update_weight_table(ncn, current_slot, mint, weight) + .await + } + + pub async fn admin_update_weight_table( + &mut self, + ncn: Pubkey, + current_slot: u64, + mint: Pubkey, + weight: u128, + ) -> TestResult<()> { + let restaking_config_account = self.get_restaking_config().await?; + let ncn_epoch = current_slot / restaking_config_account.epoch_length(); + + let weight_table = + WeightTable::find_program_address(&jito_tip_router_program::id(), &ncn, ncn_epoch).0; + + let ix = AdminUpdateWeightTableBuilder::new() + .ncn(ncn) + .weight_table(weight_table) + .weight_table_admin(self.payer.pubkey()) + .mint(mint) + .restaking_program_id(jito_restaking_program::id()) + .weight(weight) + .instruction(); + + let blockhash = self.banks_client.get_latest_blockhash().await?; + self.process_transaction(&Transaction::new_signed_with_payer( + &[ix], + Some(&self.payer.pubkey()), + &[&self.payer], + blockhash, + )) + .await + } } #[inline(always)] diff --git a/integration_tests/tests/tip_router/admin_update_weight_table.rs b/integration_tests/tests/tip_router/admin_update_weight_table.rs new file mode 100644 index 0000000..dc91213 --- /dev/null +++ b/integration_tests/tests/tip_router/admin_update_weight_table.rs @@ -0,0 +1,37 @@ +#[cfg(test)] +mod tests { + + use solana_sdk::pubkey::Pubkey; + + use crate::fixtures::{test_builder::TestBuilder, TestResult}; + + #[tokio::test] + async fn test_admin_update_weight_table() -> TestResult<()> { + let mut fixture = TestBuilder::new().await; + let mut tip_router_client = fixture.tip_router_client(); + let ncn_root = fixture.setup_ncn().await?; + + fixture.warp_slot_incremental(1000).await?; + + let slot = fixture.clock().await.slot; + + //TODO fix when config has mints + tip_router_client + .do_initialize_config(ncn_root.ncn_pubkey, &ncn_root.ncn_admin) + .await?; + + tip_router_client + .do_initialize_weight_table(ncn_root.ncn_pubkey, slot) + .await?; + + let mint = Pubkey::new_unique(); + let weight = 100; + + tip_router_client + .do_admin_update_weight_table(ncn_root.ncn_pubkey, slot, mint, weight) + .await?; + + //TODO add functionality to update weight table + Ok(()) + } +} diff --git a/integration_tests/tests/tip_router/initialize_weight_table.rs b/integration_tests/tests/tip_router/initialize_weight_table.rs index b4bcb1f..86c747f 100644 --- a/integration_tests/tests/tip_router/initialize_weight_table.rs +++ b/integration_tests/tests/tip_router/initialize_weight_table.rs @@ -1,13 +1,7 @@ #[cfg(test)] mod tests { - use jito_tip_router_core::error::TipRouterError; - use solana_program::instruction::InstructionError; - use solana_sdk::signature::{Keypair, Signer}; - use crate::fixtures::{ - assert_ix_error, restaking_client::NcnRoot, test_builder::TestBuilder, - tip_router_client::assert_tip_router_error, TestResult, - }; + use crate::fixtures::{test_builder::TestBuilder, TestResult}; #[tokio::test] async fn test_initialize_weight_table_ok() -> TestResult<()> { @@ -15,8 +9,15 @@ mod tests { let mut tip_router_client = fixture.tip_router_client(); let ncn_root = fixture.setup_ncn().await?; + fixture.warp_slot_incremental(1000).await?; + let slot = fixture.clock().await.slot; + //TODO fix when config has mints + tip_router_client + .do_initialize_config(ncn_root.ncn_pubkey, &ncn_root.ncn_admin) + .await?; + tip_router_client .do_initialize_weight_table(ncn_root.ncn_pubkey, slot) .await?; diff --git a/integration_tests/tests/tip_router/mod.rs b/integration_tests/tests/tip_router/mod.rs index c31dadd..dd9a5a4 100644 --- a/integration_tests/tests/tip_router/mod.rs +++ b/integration_tests/tests/tip_router/mod.rs @@ -1,3 +1,4 @@ +mod admin_update_weight_table; mod initialize_ncn_config; mod initialize_weight_table; mod set_config_fees; diff --git a/program/src/admin_update_weight_table.rs b/program/src/admin_update_weight_table.rs index d0381c8..ea52234 100644 --- a/program/src/admin_update_weight_table.rs +++ b/program/src/admin_update_weight_table.rs @@ -20,7 +20,6 @@ pub fn process_admin_update_weight_table( Ncn::load(restaking_program_id.key, ncn, false)?; let ncn_weight_table_admin = { - //TODO switch to weight table admin when that is merged let ncn_data = ncn.data.borrow(); let ncn = Ncn::try_from_slice_unchecked(&ncn_data)?; ncn.admin diff --git a/program/src/initialize_weight_table.rs b/program/src/initialize_weight_table.rs index b60791e..9ef5ef4 100644 --- a/program/src/initialize_weight_table.rs +++ b/program/src/initialize_weight_table.rs @@ -27,7 +27,7 @@ pub fn process_initialize_weight_table( return Err(ProgramError::NotEnoughAccountKeys); }; - NcnConfig::load(restaking_program_id.key, ncn.key, ncn_config, false)?; + NcnConfig::load(program_id, ncn.key, ncn_config, false)?; Config::load(restaking_program_id.key, restaking_config, false)?; let ncn_epoch_length = { From c83594b6ed83dec18ea08ff236abbfc55ca9fe6f Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Fri, 8 Nov 2024 08:39:21 -0700 Subject: [PATCH 5/5] took out println --- core/src/weight_table.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/weight_table.rs b/core/src/weight_table.rs index 9a2ae4a..8ec499a 100644 --- a/core/src/weight_table.rs +++ b/core/src/weight_table.rs @@ -93,10 +93,6 @@ impl WeightTable { // Check for duplicates using nested iterators let unique_mints: HashSet<_> = config_supported_mints.iter().collect(); - println!( - "unique_mints: {:?} {:?}", - unique_mints, config_supported_mints - ); if unique_mints.len() != config_supported_mints.len() { return Err(TipRouterError::DuplicateMintsInTable); }