light_system_program/invoke/
nullify_state.rs1use account_compression::utils::constants::CPI_AUTHORITY_PDA_SEED;
2use anchor_lang::{prelude::*, solana_program::pubkey::Pubkey, Bumps, InstructionData};
3use light_macros::heap_neutral;
4
5use crate::{
6 constants::CPI_AUTHORITY_PDA_BUMP,
7 invoke::InstructionDataInvoke,
8 invoke_cpi::verify_signer::check_program_owner_state_merkle_tree,
9 sdk::accounts::{InvokeAccounts, SignerAccounts},
10};
11
12#[heap_neutral]
16pub fn insert_nullifiers<
17 'a,
18 'b,
19 'c: 'info,
20 'info,
21 A: InvokeAccounts<'info> + SignerAccounts<'info> + Bumps,
22>(
23 inputs: &'a InstructionDataInvoke,
24 ctx: &'a Context<'a, 'b, 'c, 'info, A>,
25 nullifiers: &'a [[u8; 32]],
26 invoking_program: &Option<Pubkey>,
27) -> Result<Option<(u8, u64)>> {
28 light_heap::bench_sbf_start!("cpda_insert_nullifiers_prep_accs");
29 let mut account_infos = vec![
30 ctx.accounts.get_fee_payer().to_account_info(),
31 ctx.accounts
32 .get_account_compression_authority()
33 .to_account_info(),
34 ctx.accounts.get_registered_program_pda().to_account_info(),
35 ctx.accounts.get_system_program().to_account_info(),
36 ];
37 let mut accounts = vec![
38 AccountMeta {
39 pubkey: account_infos[0].key(),
40 is_signer: true,
41 is_writable: true,
42 },
43 AccountMeta::new_readonly(account_infos[1].key(), true),
44 AccountMeta::new_readonly(account_infos[2].key(), false),
45 AccountMeta::new_readonly(account_infos[3].key(), false),
46 ];
47 let mut network_fee_bundle = None;
54 for account in inputs.input_compressed_accounts_with_merkle_context.iter() {
55 let account_info =
56 &ctx.remaining_accounts[account.merkle_context.nullifier_queue_pubkey_index as usize];
57 accounts.push(AccountMeta {
58 pubkey: account_info.key(),
59 is_signer: false,
60 is_writable: true,
61 });
62 account_infos.push(account_info.clone());
63 let (_, network_fee, _) = check_program_owner_state_merkle_tree(
64 &ctx.remaining_accounts[account.merkle_context.merkle_tree_pubkey_index as usize],
65 invoking_program,
66 )?;
67 if network_fee_bundle.is_none() && network_fee.is_some() {
68 network_fee_bundle = Some((
69 account.merkle_context.nullifier_queue_pubkey_index,
70 network_fee.unwrap(),
71 ));
72 }
73 let account_info =
74 &ctx.remaining_accounts[account.merkle_context.merkle_tree_pubkey_index as usize];
75 accounts.push(AccountMeta {
76 pubkey: account_info.key(),
77 is_signer: false,
78 is_writable: false,
79 });
80 account_infos.push(account_info.clone());
81 }
82
83 light_heap::bench_sbf_end!("cpda_insert_nullifiers_prep_accs");
84 light_heap::bench_sbf_start!("cpda_instruction_data");
85
86 let instruction_data = account_compression::instruction::InsertIntoNullifierQueues {
87 nullifiers: nullifiers.to_vec(),
88 };
89
90 let data = instruction_data.data();
91 light_heap::bench_sbf_end!("cpda_instruction_data");
92 let bump = &[CPI_AUTHORITY_PDA_BUMP];
93 let seeds = &[&[CPI_AUTHORITY_PDA_SEED, bump][..]];
94 let instruction = anchor_lang::solana_program::instruction::Instruction {
95 program_id: account_compression::ID,
96 accounts,
97 data,
98 };
99 anchor_lang::solana_program::program::invoke_signed(
100 &instruction,
101 account_infos.as_slice(),
102 seeds,
103 )?;
104 Ok(network_fee_bundle)
105}