light_program_test/accounts/
address_tree.rs1use 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}