light_sdk/instruction/
tree_info.rs

1pub use light_compressed_account::compressed_account::{MerkleContext, PackedMerkleContext};
2use light_sdk_types::instruction::PackedAddressTreeInfo;
3
4use super::PackedAccounts;
5use crate::{AccountInfo, AnchorDeserialize, AnchorSerialize, Pubkey};
6
7#[derive(Debug, Clone, Copy, AnchorDeserialize, AnchorSerialize, PartialEq, Default)]
8pub struct AddressTreeInfo {
9    pub tree: Pubkey,
10    pub queue: Pubkey,
11}
12
13#[deprecated(since = "0.13.0", note = "please use PackedStateTreeInfo")]
14pub fn pack_merkle_contexts<'a, I>(
15    merkle_contexts: I,
16    remaining_accounts: &'a mut PackedAccounts,
17) -> impl Iterator<Item = PackedMerkleContext> + 'a
18where
19    I: Iterator<Item = &'a MerkleContext> + 'a,
20{
21    #[allow(deprecated)]
22    merkle_contexts.map(|x| pack_merkle_context(x, remaining_accounts))
23}
24
25#[deprecated(since = "0.13.0", note = "please use PackedStateTreeInfo")]
26pub fn pack_merkle_context(
27    merkle_context: &MerkleContext,
28    remaining_accounts: &mut PackedAccounts,
29) -> PackedMerkleContext {
30    let MerkleContext {
31        merkle_tree_pubkey,
32        queue_pubkey,
33        leaf_index,
34        prove_by_index,
35        ..
36    } = merkle_context;
37    let merkle_tree_pubkey_index =
38        remaining_accounts.insert_or_get(merkle_tree_pubkey.to_bytes().into());
39    let queue_pubkey_index = remaining_accounts.insert_or_get(queue_pubkey.to_bytes().into());
40
41    PackedMerkleContext {
42        merkle_tree_pubkey_index,
43        queue_pubkey_index,
44        leaf_index: *leaf_index,
45        prove_by_index: *prove_by_index,
46    }
47}
48
49/// Returns an iterator of [`PackedAddressTreeInfo`] and fills up
50/// `remaining_accounts` based on the given `merkle_contexts`.
51pub fn pack_address_tree_infos<'a>(
52    address_tree_infos: &'a [AddressTreeInfo],
53    root_index: &'a [u16],
54    remaining_accounts: &'a mut PackedAccounts,
55) -> impl Iterator<Item = PackedAddressTreeInfo> + 'a {
56    address_tree_infos
57        .iter()
58        .zip(root_index)
59        .map(move |(x, root_index)| pack_address_tree_info(x, remaining_accounts, *root_index))
60}
61
62/// Returns a [`PackedAddressTreeInfo`] and fills up `remaining_accounts`
63/// based on the given `merkle_context`.
64/// Packs Merkle tree account first.
65/// Packs queue account second.
66pub fn pack_address_tree_info(
67    address_tree_info: &AddressTreeInfo,
68    remaining_accounts: &mut PackedAccounts,
69    root_index: u16,
70) -> PackedAddressTreeInfo {
71    let AddressTreeInfo { tree, queue } = address_tree_info;
72    let address_merkle_tree_pubkey_index = remaining_accounts.insert_or_get(*tree);
73    let address_queue_pubkey_index = remaining_accounts.insert_or_get(*queue);
74
75    PackedAddressTreeInfo {
76        address_merkle_tree_pubkey_index,
77        address_queue_pubkey_index,
78        root_index,
79    }
80}
81
82pub fn unpack_address_tree_infos(
83    address_tree_infos: &[PackedAddressTreeInfo],
84    remaining_accounts: &[AccountInfo],
85) -> Vec<AddressTreeInfo> {
86    let mut result = Vec::with_capacity(address_tree_infos.len());
87    for x in address_tree_infos {
88        let address_merkle_tree_pubkey =
89            *remaining_accounts[x.address_merkle_tree_pubkey_index as usize].key;
90        let address_queue_pubkey = *remaining_accounts[x.address_queue_pubkey_index as usize].key;
91        result.push(AddressTreeInfo {
92            tree: address_merkle_tree_pubkey,
93            queue: address_queue_pubkey,
94        });
95    }
96    result
97}
98
99pub fn unpack_address_tree_info(
100    address_tree_info: PackedAddressTreeInfo,
101    remaining_accounts: &[AccountInfo],
102) -> AddressTreeInfo {
103    unpack_address_tree_infos(&[address_tree_info], remaining_accounts)[0]
104}
105
106#[cfg(test)]
107mod test {
108
109    use light_compressed_account::Pubkey;
110
111    use super::*;
112
113    #[test]
114    fn test_pack_merkle_context() {
115        let mut remaining_accounts = PackedAccounts::default();
116
117        let merkle_tree_pubkey = Pubkey::new_unique();
118        let queue_pubkey = Pubkey::new_unique();
119        let merkle_context = MerkleContext {
120            merkle_tree_pubkey,
121            queue_pubkey,
122            leaf_index: 69,
123            prove_by_index: false,
124            ..Default::default()
125        };
126
127        #[allow(deprecated)]
128        let packed_merkle_context = pack_merkle_context(&merkle_context, &mut remaining_accounts);
129        assert_eq!(
130            packed_merkle_context,
131            PackedMerkleContext {
132                merkle_tree_pubkey_index: 0,
133                queue_pubkey_index: 1,
134                leaf_index: 69,
135                prove_by_index: false,
136            }
137        )
138    }
139
140    #[test]
141    fn test_pack_merkle_contexts() {
142        let mut remaining_accounts = PackedAccounts::default();
143        use light_compressed_account::Pubkey;
144        let merkle_contexts = &[
145            MerkleContext {
146                merkle_tree_pubkey: Pubkey::new_unique(),
147                queue_pubkey: Pubkey::new_unique(),
148                leaf_index: 10,
149                prove_by_index: false,
150                ..Default::default()
151            },
152            MerkleContext {
153                merkle_tree_pubkey: Pubkey::new_unique(),
154                queue_pubkey: Pubkey::new_unique(),
155                leaf_index: 11,
156                prove_by_index: true,
157                ..Default::default()
158            },
159            MerkleContext {
160                merkle_tree_pubkey: Pubkey::new_unique(),
161                queue_pubkey: Pubkey::new_unique(),
162                leaf_index: 12,
163                prove_by_index: false,
164                ..Default::default()
165            },
166        ];
167
168        #[allow(deprecated)]
169        let packed_merkle_contexts =
170            pack_merkle_contexts(merkle_contexts.iter(), &mut remaining_accounts);
171        assert_eq!(
172            packed_merkle_contexts.collect::<Vec<_>>(),
173            &[
174                PackedMerkleContext {
175                    merkle_tree_pubkey_index: 0,
176                    queue_pubkey_index: 1,
177                    leaf_index: 10,
178                    prove_by_index: false
179                },
180                PackedMerkleContext {
181                    merkle_tree_pubkey_index: 2,
182                    queue_pubkey_index: 3,
183                    leaf_index: 11,
184                    prove_by_index: true
185                },
186                PackedMerkleContext {
187                    merkle_tree_pubkey_index: 4,
188                    queue_pubkey_index: 5,
189                    leaf_index: 12,
190                    prove_by_index: false,
191                }
192            ]
193        );
194    }
195
196    #[test]
197    fn test_pack_address_tree_info() {
198        use solana_pubkey::Pubkey;
199        let mut remaining_accounts = PackedAccounts::default();
200
201        let address_tree_info = AddressTreeInfo {
202            tree: Pubkey::new_unique(),
203            queue: Pubkey::new_unique(),
204        };
205
206        let packed_address_tree_info =
207            pack_address_tree_info(&address_tree_info, &mut remaining_accounts, 2);
208        assert_eq!(
209            packed_address_tree_info,
210            PackedAddressTreeInfo {
211                address_merkle_tree_pubkey_index: 0,
212                address_queue_pubkey_index: 1,
213                root_index: 2,
214            }
215        )
216    }
217
218    #[test]
219    fn test_pack_address_tree_infos() {
220        let mut remaining_accounts = PackedAccounts::default();
221        use solana_pubkey::Pubkey;
222        let address_tree_infos = [
223            AddressTreeInfo {
224                tree: Pubkey::new_unique(),
225                queue: Pubkey::new_unique(),
226            },
227            AddressTreeInfo {
228                tree: Pubkey::new_unique(),
229                queue: Pubkey::new_unique(),
230            },
231            AddressTreeInfo {
232                tree: Pubkey::new_unique(),
233                queue: Pubkey::new_unique(),
234            },
235        ];
236
237        let packed_address_tree_infos =
238            pack_address_tree_infos(&address_tree_infos, &[6, 7, 8], &mut remaining_accounts);
239        assert_eq!(
240            packed_address_tree_infos.collect::<Vec<_>>(),
241            &[
242                PackedAddressTreeInfo {
243                    address_merkle_tree_pubkey_index: 0,
244                    address_queue_pubkey_index: 1,
245                    root_index: 6,
246                },
247                PackedAddressTreeInfo {
248                    address_merkle_tree_pubkey_index: 2,
249                    address_queue_pubkey_index: 3,
250                    root_index: 7,
251                },
252                PackedAddressTreeInfo {
253                    address_merkle_tree_pubkey_index: 4,
254                    address_queue_pubkey_index: 5,
255                    root_index: 8,
256                }
257            ]
258        );
259    }
260}