|
| 1 | +//! Compute unit benchmarks for executor-quoter-router using mollusk-svm. |
| 2 | +//! |
| 3 | +//! Run with: cargo bench |
| 4 | +//! Output: target/benches/executor_quoter_router_compute_units.md |
| 5 | +//! |
| 6 | +//! Note: Only the Initialize instruction is benchmarked here. |
| 7 | +//! - UpdateQuoterContract requires secp256k1 syscalls (sol_secp256k1_recover) |
| 8 | +//! - QuoteExecution/RequestExecution require CPI to executor-quoter and executor programs |
| 9 | +
|
| 10 | +use mollusk_svm::program::keyed_account_for_system_program; |
| 11 | +use mollusk_svm::Mollusk; |
| 12 | +use mollusk_svm_bencher::MolluskComputeUnitBencher; |
| 13 | +use solana_sdk::{ |
| 14 | + account::AccountSharedData, |
| 15 | + instruction::{AccountMeta, Instruction}, |
| 16 | + pubkey::Pubkey, |
| 17 | + system_program, |
| 18 | +}; |
| 19 | + |
| 20 | +// Router Program ID |
| 21 | +const PROGRAM_ID: Pubkey = Pubkey::new_from_array([ |
| 22 | + 0xda, 0x0f, 0x39, 0x58, 0xba, 0x11, 0x3d, 0xfa, 0x31, 0xe1, 0xda, 0xc7, 0x67, 0xe7, 0x47, 0xce, |
| 23 | + 0xc9, 0x03, 0xf4, 0x56, 0x9c, 0x89, 0x97, 0x1f, 0x47, 0x27, 0x2e, 0xb0, 0x7e, 0x3d, 0xd5, 0xf9, |
| 24 | +]); |
| 25 | + |
| 26 | +// Executor Program ID |
| 27 | +const EXECUTOR_PROGRAM_ID: Pubkey = Pubkey::new_from_array([ |
| 28 | + 0x09, 0xb9, 0x69, 0x71, 0x58, 0x3b, 0x59, 0x03, 0xe0, 0x28, 0x1d, 0xa9, 0x65, 0x48, 0xd5, 0xd2, |
| 29 | + 0x3c, 0x65, 0x1f, 0x7a, 0x9c, 0xcd, 0xe3, 0xea, 0xd5, 0x2b, 0x42, 0xf6, 0xb7, 0xda, 0xc2, 0xd2, |
| 30 | +]); |
| 31 | + |
| 32 | +// PDA seeds |
| 33 | +const CONFIG_SEED: &[u8] = b"config"; |
| 34 | + |
| 35 | +// Instruction discriminators |
| 36 | +const IX_INITIALIZE: u8 = 0; |
| 37 | + |
| 38 | +// Wormhole chain ID for Solana |
| 39 | +const SOLANA_CHAIN_ID: u16 = 1; |
| 40 | + |
| 41 | +fn derive_config_pda() -> (Pubkey, u8) { |
| 42 | + Pubkey::find_program_address(&[CONFIG_SEED], &PROGRAM_ID) |
| 43 | +} |
| 44 | + |
| 45 | +/// Create a funded payer account |
| 46 | +fn create_payer_account() -> AccountSharedData { |
| 47 | + AccountSharedData::new(1_000_000_000, 0, &system_program::ID) |
| 48 | +} |
| 49 | + |
| 50 | +/// Build Initialize instruction data |
| 51 | +fn build_initialize_data(executor_program_id: &Pubkey, our_chain: u16, bump: u8) -> Vec<u8> { |
| 52 | + let mut data = vec![IX_INITIALIZE]; |
| 53 | + data.extend_from_slice(executor_program_id.as_ref()); |
| 54 | + data.extend_from_slice(&our_chain.to_le_bytes()); |
| 55 | + data.push(bump); |
| 56 | + data.push(0); // padding |
| 57 | + data |
| 58 | +} |
| 59 | + |
| 60 | +fn main() { |
| 61 | + // Initialize Mollusk with the program |
| 62 | + let mollusk = Mollusk::new(&PROGRAM_ID, "executor_quoter_router"); |
| 63 | + |
| 64 | + // Get the system program keyed account for CPI |
| 65 | + let system_program_account = keyed_account_for_system_program(); |
| 66 | + |
| 67 | + // Set up common accounts |
| 68 | + let payer = Pubkey::new_unique(); |
| 69 | + let (config_pda, config_bump) = derive_config_pda(); |
| 70 | + |
| 71 | + // Benchmark: Initialize |
| 72 | + let init_ix = Instruction::new_with_bytes( |
| 73 | + PROGRAM_ID, |
| 74 | + &build_initialize_data(&EXECUTOR_PROGRAM_ID, SOLANA_CHAIN_ID, config_bump), |
| 75 | + vec![ |
| 76 | + AccountMeta::new(payer, true), |
| 77 | + AccountMeta::new(config_pda, false), |
| 78 | + AccountMeta::new_readonly(system_program::ID, false), |
| 79 | + ], |
| 80 | + ); |
| 81 | + let init_accounts = vec![ |
| 82 | + (payer, create_payer_account()), |
| 83 | + (config_pda, AccountSharedData::new(0, 0, &system_program::ID)), |
| 84 | + system_program_account, |
| 85 | + ]; |
| 86 | + |
| 87 | + // Run benchmarks |
| 88 | + // Note: Additional instructions (UpdateQuoterContract, QuoteExecution, RequestExecution) |
| 89 | + // are not benchmarked here due to: |
| 90 | + // - UpdateQuoterContract: requires sol_secp256k1_recover syscall |
| 91 | + // - QuoteExecution: requires CPI to executor-quoter program |
| 92 | + // - RequestExecution: requires CPI to both executor-quoter and executor programs |
| 93 | + // |
| 94 | + // For these instructions, use the integration tests with solana-program-test instead. |
| 95 | + MolluskComputeUnitBencher::new(mollusk) |
| 96 | + .bench(("initialize", &init_ix, &init_accounts)) |
| 97 | + .must_pass(true) |
| 98 | + .out_dir("target/benches") |
| 99 | + .execute(); |
| 100 | +} |
0 commit comments