manifest/program/instruction_builders/
batch_update_instruction.rs

1#[cfg(feature = "certora")]
2use crate::program::batch_update::{CancelOrderParams, PlaceOrderParams};
3#[cfg(not(feature = "certora"))]
4use crate::{
5    program::{
6        batch_update::{BatchUpdateParams, CancelOrderParams, PlaceOrderParams},
7        ManifestInstruction,
8    },
9    validation::{get_global_address, get_global_vault_address, get_vault_address},
10};
11#[cfg(not(feature = "certora"))]
12use borsh::BorshSerialize;
13use hypertree::DataIndex;
14#[cfg(feature = "certora")]
15use solana_program::{instruction::Instruction, pubkey::Pubkey};
16#[cfg(not(feature = "certora"))]
17use solana_program::{
18    instruction::{AccountMeta, Instruction},
19    pubkey::Pubkey,
20    system_program,
21};
22
23// Token programs are needed for global orders with token22. Only include if
24// this is global or could match with global. Defaults to normal token program.
25#[cfg(not(feature = "certora"))]
26pub fn batch_update_instruction(
27    market: &Pubkey,
28    payer: &Pubkey,
29    trader_index_hint: Option<DataIndex>,
30    cancels: Vec<CancelOrderParams>,
31    orders: Vec<PlaceOrderParams>,
32    base_mint_opt: Option<Pubkey>,
33    base_mint_token_program_opt: Option<Pubkey>,
34    quote_mint_opt: Option<Pubkey>,
35    quote_mint_token_program_opt: Option<Pubkey>,
36) -> Instruction {
37    let mut account_metas: Vec<AccountMeta> = vec![
38        AccountMeta::new(*payer, true),
39        AccountMeta::new(*market, false),
40        AccountMeta::new_readonly(system_program::id(), false),
41    ];
42    for (mint_opt, token_program_opt) in [
43        (base_mint_opt, base_mint_token_program_opt),
44        (quote_mint_opt, quote_mint_token_program_opt),
45    ] {
46        if let Some(mint) = mint_opt {
47            let (global, _) = get_global_address(&mint);
48            let (global_vault, _) = get_global_vault_address(&mint);
49            let (market_vault, _) = get_vault_address(market, &mint);
50            let mut global_account_metas: Vec<AccountMeta> = vec![
51                AccountMeta::new_readonly(mint, false),
52                AccountMeta::new(global, false),
53                AccountMeta::new(global_vault, false),
54                AccountMeta::new(market_vault, false),
55            ];
56            if token_program_opt.is_none()
57                || token_program_opt.is_some_and(|f| f == spl_token::id())
58            {
59                global_account_metas.push(AccountMeta::new_readonly(spl_token::id(), false));
60            } else {
61                global_account_metas.push(AccountMeta::new_readonly(spl_token_2022::id(), false));
62            }
63            account_metas.extend(global_account_metas);
64        }
65    }
66
67    Instruction {
68        program_id: crate::id(),
69        accounts: account_metas,
70        data: [
71            ManifestInstruction::BatchUpdate.to_vec(),
72            BatchUpdateParams::new(trader_index_hint, cancels, orders)
73                .try_to_vec()
74                .unwrap(),
75        ]
76        .concat(),
77    }
78}
79
80#[cfg(feature = "certora")]
81pub fn batch_update_instruction(
82    _market: &Pubkey,
83    _payer: &Pubkey,
84    _trader_index_hint: Option<DataIndex>,
85    _cancels: Vec<CancelOrderParams>,
86    _orders: Vec<PlaceOrderParams>,
87    _base_mint_opt: Option<Pubkey>,
88    _base_mint_token_program_opt: Option<Pubkey>,
89    _quote_mint_opt: Option<Pubkey>,
90    _quote_mint_token_program_opt: Option<Pubkey>,
91) -> Instruction {
92    // Empty intentionally, just here so it compiles.
93    todo!()
94}