light_program_test/accounts/
address_tree.rs

1use account_compression::{
2    instruction::InitializeAddressMerkleTreeAndQueue, AddressMerkleTreeConfig, AddressQueueConfig,
3};
4use anchor_lang::InstructionData;
5use light_client::rpc::{errors::RpcError, Rpc};
6use solana_sdk::{
7    compute_budget::ComputeBudgetInstruction,
8    instruction::{AccountMeta, Instruction},
9    pubkey::Pubkey,
10    signature::{Keypair, Signature, Signer},
11    transaction::Transaction,
12};
13
14use crate::utils::create_account::create_account_instruction;
15
16#[allow(clippy::too_many_arguments)]
17pub fn create_initialize_address_merkle_tree_and_queue_instruction(
18    index: u64,
19    payer: Pubkey,
20    registered_program_pda: Option<Pubkey>,
21    program_owner: Option<Pubkey>,
22    forester: Option<Pubkey>,
23    merkle_tree_pubkey: Pubkey,
24    queue_pubkey: Pubkey,
25    address_merkle_tree_config: AddressMerkleTreeConfig,
26    address_queue_config: AddressQueueConfig,
27) -> Instruction {
28    let instruction_data = InitializeAddressMerkleTreeAndQueue {
29        index,
30        program_owner,
31        forester,
32        address_merkle_tree_config,
33        address_queue_config,
34    };
35    let registered_program = match registered_program_pda {
36        Some(registered_program_pda) => AccountMeta::new(registered_program_pda, false),
37        None => AccountMeta::new(account_compression::ID, false),
38    };
39    Instruction {
40        program_id: account_compression::ID,
41        accounts: vec![
42            AccountMeta::new(payer, true),
43            AccountMeta::new(merkle_tree_pubkey, false),
44            AccountMeta::new(queue_pubkey, false),
45            registered_program,
46        ],
47        data: instruction_data.data(),
48    }
49}
50
51#[allow(clippy::too_many_arguments)]
52#[inline(never)]
53pub async fn create_address_merkle_tree_and_queue_account<R: Rpc>(
54    payer: &Keypair,
55    registry: bool,
56    context: &mut R,
57    address_merkle_tree_keypair: &Keypair,
58    address_queue_keypair: &Keypair,
59    program_owner: Option<Pubkey>,
60    forester: Option<Pubkey>,
61    merkle_tree_config: &AddressMerkleTreeConfig,
62    queue_config: &AddressQueueConfig,
63    index: u64,
64) -> Result<Signature, RpcError> {
65    use light_registry::account_compression_cpi::sdk::create_initialize_address_merkle_tree_and_queue_instruction as create_initialize_address_merkle_tree_and_queue_instruction_registry;
66
67    let size =
68        account_compression::state::QueueAccount::size(queue_config.capacity as usize).unwrap();
69    let account_create_ix = create_account_instruction(
70        &payer.pubkey(),
71        size,
72        context
73            .get_minimum_balance_for_rent_exemption(size)
74            .await
75            .unwrap(),
76        &account_compression::ID,
77        Some(address_queue_keypair),
78    );
79
80    let size = account_compression::state::AddressMerkleTreeAccount::size(
81        merkle_tree_config.height as usize,
82        merkle_tree_config.changelog_size as usize,
83        merkle_tree_config.roots_size as usize,
84        merkle_tree_config.canopy_depth as usize,
85        merkle_tree_config.address_changelog_size as usize,
86    );
87    let mt_account_create_ix = create_account_instruction(
88        &payer.pubkey(),
89        size,
90        context
91            .get_minimum_balance_for_rent_exemption(size)
92            .await
93            .unwrap(),
94        &account_compression::ID,
95        Some(address_merkle_tree_keypair),
96    );
97    let instruction = if registry {
98        create_initialize_address_merkle_tree_and_queue_instruction_registry(
99            payer.pubkey(),
100            forester,
101            program_owner,
102            address_merkle_tree_keypair.pubkey(),
103            address_queue_keypair.pubkey(),
104            merkle_tree_config.clone(),
105            queue_config.clone(),
106        )
107    } else {
108        create_initialize_address_merkle_tree_and_queue_instruction(
109            index,
110            payer.pubkey(),
111            None,
112            program_owner,
113            forester,
114            address_merkle_tree_keypair.pubkey(),
115            address_queue_keypair.pubkey(),
116            merkle_tree_config.clone(),
117            queue_config.clone(),
118        )
119    };
120
121    let transaction = Transaction::new_signed_with_payer(
122        &[
123            ComputeBudgetInstruction::set_compute_unit_limit(500_000),
124            account_create_ix,
125            mt_account_create_ix,
126            instruction,
127        ],
128        Some(&payer.pubkey()),
129        &vec![&payer, &address_queue_keypair, &address_merkle_tree_keypair],
130        context.get_latest_blockhash().await?.0,
131    );
132    let result = context.process_transaction(transaction).await;
133    #[allow(clippy::question_mark)]
134    if let Err(e) = result {
135        return Err(e);
136    }
137    result
138}