light_program_test/accounts/
address_tree.rs

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