1use std::fmt::Debug;
2
3#[cfg(feature = "devenv")]
4use light_batched_merkle_tree::constants::DEFAULT_BATCH_ROOT_HISTORY_LEN;
5use light_client::{
6 fee::FeeConfig,
7 indexer::{AddressMerkleTreeAccounts, IndexerError},
8};
9use light_hasher::Poseidon;
10use light_indexed_merkle_tree::{
11 array::{IndexedArray, IndexedElement, IndexedElementBundle},
12 reference::IndexedMerkleTree,
13};
14use light_prover_client::proof_types::non_inclusion::v2::NonInclusionMerkleProofInputs;
15use light_sdk::constants::STATE_MERKLE_TREE_ROOTS;
16use num_bigint::{BigInt, BigUint};
17use num_traits::ops::bytes::FromBytes;
18
19#[cfg(not(feature = "devenv"))]
20use super::test_indexer::DEFAULT_BATCH_ROOT_HISTORY_LEN;
21
22#[derive(Debug, Clone)]
23pub enum IndexedMerkleTreeVersion {
24 V1(Box<IndexedMerkleTree<Poseidon, usize>>),
25 V2(Box<light_merkle_tree_reference::indexed::IndexedMerkleTree<Poseidon, usize>>),
26}
27
28#[derive(Debug, Clone)]
29pub struct AddressMerkleTreeBundle {
30 pub rollover_fee: i64,
31 pub merkle_tree: IndexedMerkleTreeVersion,
32 indexed_array: Box<IndexedArray<Poseidon, usize>>,
33 pub accounts: AddressMerkleTreeAccounts,
34 pub queue_elements: Vec<[u8; 32]>,
35}
36
37impl AddressMerkleTreeBundle {
38 pub fn new_v1(accounts: AddressMerkleTreeAccounts) -> Result<Self, IndexerError> {
39 let height = 26;
40 let canopy = 10;
41 let mut merkle_tree = IndexedMerkleTree::<Poseidon, usize>::new(height, canopy)
42 .map_err(|_| IndexerError::InvalidResponseData)?;
43 merkle_tree.merkle_tree.root_history_array_len = Some(STATE_MERKLE_TREE_ROOTS);
44 let mut merkle_tree = Box::new(merkle_tree);
45 merkle_tree.init()?;
46 let mut indexed_array = Box::<IndexedArray<Poseidon, usize>>::default();
47 indexed_array.init()?;
48 Ok(AddressMerkleTreeBundle {
49 merkle_tree: IndexedMerkleTreeVersion::V1(merkle_tree),
50 indexed_array,
51 accounts,
52 rollover_fee: FeeConfig::default().address_queue_rollover as i64,
53 queue_elements: vec![],
54 })
55 }
56
57 pub fn new_v2(accounts: AddressMerkleTreeAccounts) -> Result<Self, IndexerError> {
58 let height = 40;
59 let canopy = 0;
60 let mut merkle_tree = light_merkle_tree_reference::indexed::IndexedMerkleTree::<
61 Poseidon,
62 usize,
63 >::new(height, canopy)
64 .map_err(|_| IndexerError::InvalidResponseData)?;
65 merkle_tree.merkle_tree.root_history_array_len =
66 Some(DEFAULT_BATCH_ROOT_HISTORY_LEN as usize);
67 let merkle_tree = IndexedMerkleTreeVersion::V2(Box::new(merkle_tree));
68
69 Ok(AddressMerkleTreeBundle {
70 merkle_tree,
71 indexed_array: Box::default(),
72 accounts,
73 rollover_fee: FeeConfig::default().address_queue_rollover as i64,
74 queue_elements: vec![],
75 })
76 }
77
78 pub fn get_v1_indexed_merkle_tree(&self) -> Option<&IndexedMerkleTree<Poseidon, usize>> {
79 match &self.merkle_tree {
80 IndexedMerkleTreeVersion::V1(tree) => Some(tree),
81 _ => None,
82 }
83 }
84
85 pub fn get_v1_indexed_merkle_tree_mut(
86 &mut self,
87 ) -> Option<&mut IndexedMerkleTree<Poseidon, usize>> {
88 match &mut self.merkle_tree {
89 IndexedMerkleTreeVersion::V1(tree) => Some(tree),
90 _ => None,
91 }
92 }
93
94 pub fn get_v2_indexed_merkle_tree(
95 &self,
96 ) -> Option<&light_merkle_tree_reference::indexed::IndexedMerkleTree<Poseidon, usize>> {
97 match &self.merkle_tree {
98 IndexedMerkleTreeVersion::V2(tree) => Some(tree),
99 _ => None,
100 }
101 }
102
103 pub fn get_v2_indexed_merkle_tree_mut(
104 &mut self,
105 ) -> Option<&mut light_merkle_tree_reference::indexed::IndexedMerkleTree<Poseidon, usize>> {
106 match &mut self.merkle_tree {
107 IndexedMerkleTreeVersion::V2(tree) => Some(tree),
108 _ => None,
109 }
110 }
111
112 pub fn get_subtrees(&self) -> Vec<[u8; 32]> {
113 match &self.merkle_tree {
114 IndexedMerkleTreeVersion::V1(tree) => tree.merkle_tree.get_subtrees(),
115 IndexedMerkleTreeVersion::V2(tree) => tree.merkle_tree.get_subtrees(),
116 }
117 }
118
119 pub fn root(&self) -> [u8; 32] {
120 match &self.merkle_tree {
121 IndexedMerkleTreeVersion::V1(tree) => tree.merkle_tree.root(),
122 IndexedMerkleTreeVersion::V2(tree) => tree.merkle_tree.root(),
123 }
124 }
125
126 pub fn find_low_element_for_nonexistent(
127 &self,
128 value: &BigUint,
129 ) -> Result<(IndexedElement<usize>, BigUint), IndexerError> {
130 match &self.merkle_tree {
131 IndexedMerkleTreeVersion::V1(_) => Ok(self
132 .indexed_array
133 .find_low_element_for_nonexistent(value)
134 .map_err(|_| IndexerError::InvalidResponseData)?),
135 IndexedMerkleTreeVersion::V2(tree) => {
136 let (indexed_element, next_value) = tree
137 .indexed_array
138 .find_low_element_for_nonexistent(value)
139 .map_err(|_| IndexerError::InvalidResponseData)?;
140 Ok((
141 IndexedElement {
142 index: indexed_element.index,
143 value: indexed_element.value.clone(),
144 next_index: indexed_element.next_index,
145 },
146 next_value,
147 ))
148 }
149 }
150 }
151
152 pub fn new_element_with_low_element_index(
153 &self,
154 index: usize,
155 value: &BigUint,
156 ) -> Result<IndexedElementBundle<usize>, IndexerError> {
157 match &self.merkle_tree {
158 IndexedMerkleTreeVersion::V1(_) => Ok(self
159 .indexed_array
160 .new_element_with_low_element_index(index, value)
161 .map_err(|_| IndexerError::InvalidResponseData)?),
162 IndexedMerkleTreeVersion::V2(tree) => {
163 let res = tree
164 .indexed_array
165 .new_element_with_low_element_index(index, value)
166 .map_err(|_| IndexerError::InvalidResponseData)?;
167 Ok(IndexedElementBundle {
168 new_element: IndexedElement {
169 index: res.new_element.index,
170 value: res.new_element.value.clone(),
171 next_index: res.new_element.next_index,
172 },
173 new_low_element: IndexedElement {
174 index: res.new_low_element.index,
175 value: res.new_low_element.value.clone(),
176 next_index: res.new_low_element.next_index,
177 },
178 new_element_next_value: res.new_element_next_value.clone(),
179 })
180 }
181 }
182 }
183
184 pub fn get_proof_of_leaf(
185 &self,
186 index: usize,
187 full: bool,
188 ) -> Result<Vec<[u8; 32]>, IndexerError> {
189 match &self.merkle_tree {
190 IndexedMerkleTreeVersion::V1(tree) => Ok(tree
191 .get_proof_of_leaf(index, full)
192 .map_err(|_| IndexerError::InvalidResponseData)?
193 .to_vec()),
194 IndexedMerkleTreeVersion::V2(tree) => Ok(tree
195 .get_proof_of_leaf(index, full)
196 .map_err(|_| IndexerError::InvalidResponseData)?),
197 }
198 }
199
200 pub fn append(&mut self, value: &BigUint) -> Result<(), IndexerError> {
201 match &mut self.merkle_tree {
202 IndexedMerkleTreeVersion::V1(tree) => {
203 tree.append(value, &mut self.indexed_array)
204 .map_err(|_| IndexerError::InvalidResponseData)?;
205 Ok(())
206 }
207 IndexedMerkleTreeVersion::V2(tree) => {
208 tree.append(value)
209 .map_err(|_| IndexerError::InvalidResponseData)?;
210 Ok(())
211 }
212 }
213 }
214
215 pub fn get_non_inclusion_proof_inputs(
216 &self,
217 value: &[u8; 32],
218 ) -> Result<NonInclusionMerkleProofInputs, IndexerError> {
219 match &self.merkle_tree {
220 IndexedMerkleTreeVersion::V1(tree) => Ok(get_non_inclusion_proof_inputs(
221 value,
222 tree,
223 &self.indexed_array,
224 )),
225 IndexedMerkleTreeVersion::V2(merkle_tree) => {
226 let non_inclusion_proof = merkle_tree
227 .get_non_inclusion_proof(&BigUint::from_be_bytes(value))
228 .map_err(|_| IndexerError::InvalidResponseData)?;
229 let proof = non_inclusion_proof
230 .merkle_proof
231 .iter()
232 .map(|x| BigInt::from_be_bytes(x))
233 .collect();
234 Ok(NonInclusionMerkleProofInputs {
235 root: BigInt::from_be_bytes(merkle_tree.root().as_slice()),
236 value: BigInt::from_be_bytes(value),
237 leaf_lower_range_value: BigInt::from_be_bytes(
238 &non_inclusion_proof.leaf_lower_range_value,
239 ),
240 leaf_higher_range_value: BigInt::from_be_bytes(
241 &non_inclusion_proof.leaf_higher_range_value,
242 ),
243 merkle_proof_hashed_indexed_element_leaf: proof,
244 index_hashed_indexed_element_leaf: BigInt::from(non_inclusion_proof.leaf_index),
245 next_index: BigInt::from(non_inclusion_proof.next_index),
246 })
247 }
248 }
249 }
250
251 pub fn right_most_index(&self) -> usize {
252 match &self.merkle_tree {
253 IndexedMerkleTreeVersion::V1(tree) => tree.merkle_tree.rightmost_index,
254 IndexedMerkleTreeVersion::V2(tree) => tree.merkle_tree.rightmost_index,
255 }
256 }
257
258 pub fn append_with_low_element_index(
259 &mut self,
260 index: usize,
261 value: &BigUint,
262 ) -> Result<IndexedElementBundle<usize>, IndexerError> {
263 match &mut self.merkle_tree {
264 IndexedMerkleTreeVersion::V1(_) => Ok(self
265 .indexed_array
266 .append_with_low_element_index(index, value)
267 .map_err(|_| IndexerError::InvalidResponseData)?),
268 IndexedMerkleTreeVersion::V2(_) => {
269 unimplemented!("append_with_low_element_index")
270 }
271 }
272 }
273
274 pub fn sequence_number(&self) -> u64 {
275 match &self.merkle_tree {
276 IndexedMerkleTreeVersion::V1(tree) => tree.merkle_tree.sequence_number as u64,
277 IndexedMerkleTreeVersion::V2(tree) => tree.merkle_tree.sequence_number as u64,
278 }
279 }
280
281 pub fn height(&self) -> usize {
282 match &self.merkle_tree {
283 IndexedMerkleTreeVersion::V1(tree) => tree.merkle_tree.height,
284 IndexedMerkleTreeVersion::V2(tree) => tree.merkle_tree.height,
285 }
286 }
287
288 pub fn get_path_of_leaf(
289 &self,
290 index: usize,
291 full: bool,
292 ) -> Result<Vec<[u8; 32]>, IndexerError> {
293 match &self.merkle_tree {
294 IndexedMerkleTreeVersion::V1(tree) => Ok(tree
295 .get_path_of_leaf(index, full)
296 .map_err(|_| IndexerError::InvalidResponseData)?
297 .to_vec()),
298 IndexedMerkleTreeVersion::V2(tree) => Ok(tree
299 .get_path_of_leaf(index, full)
300 .map_err(|_| IndexerError::InvalidResponseData)?),
301 }
302 }
303
304 pub fn indexed_array_v1(&self) -> Option<&IndexedArray<Poseidon, usize>> {
305 println!(
306 "indexed_array_v2: merkle_tree pubkey: {:?}",
307 self.accounts.merkle_tree
308 );
309 match &self.merkle_tree {
310 IndexedMerkleTreeVersion::V1(_) => Some(&self.indexed_array),
311 _ => None,
312 }
313 }
314
315 pub fn indexed_array_v2(
316 &self,
317 ) -> Option<&light_indexed_array::array::IndexedArray<Poseidon, usize>> {
318 println!(
319 "indexed_array_v2: merkle_tree pubkey: {:?}",
320 self.accounts.merkle_tree
321 );
322 match &self.merkle_tree {
323 IndexedMerkleTreeVersion::V2(tree) => Some(&tree.indexed_array),
324 _ => None,
325 }
326 }
327
328 pub fn update(
329 &mut self,
330 new_low_element: &IndexedElement<usize>,
331 new_element: &IndexedElement<usize>,
332 new_element_next_value: &BigUint,
333 ) -> Result<(), IndexerError> {
334 match &mut self.merkle_tree {
335 IndexedMerkleTreeVersion::V1(tree) => {
336 Ok(tree.update(new_low_element, new_element, new_element_next_value)?)
337 }
338 IndexedMerkleTreeVersion::V2(tree) => {
339 let new_low_element = light_indexed_array::array::IndexedElement::<usize> {
340 index: new_low_element.index,
341 value: new_low_element.value.clone(),
342 next_index: new_low_element.next_index,
343 };
344 let new_element = light_indexed_array::array::IndexedElement::<usize> {
345 index: new_element.index,
346 value: new_element.value.clone(),
347 next_index: new_element.next_index,
348 };
349 tree.update(&new_low_element, &new_element, new_element_next_value)
350 .unwrap();
351 Ok(())
352 }
353 }
354 }
355}
356
357pub fn get_non_inclusion_proof_inputs(
359 value: &[u8; 32],
360 merkle_tree: &light_indexed_merkle_tree::reference::IndexedMerkleTree<
361 light_hasher::Poseidon,
362 usize,
363 >,
364 indexed_array: &IndexedArray<light_hasher::Poseidon, usize>,
365) -> NonInclusionMerkleProofInputs {
366 let non_inclusion_proof = merkle_tree
367 .get_non_inclusion_proof(&BigUint::from_be_bytes(value), indexed_array)
368 .unwrap();
369 let proof = non_inclusion_proof
370 .merkle_proof
371 .iter()
372 .map(|x| BigInt::from_be_bytes(x))
373 .collect();
374 NonInclusionMerkleProofInputs {
375 root: BigInt::from_be_bytes(merkle_tree.root().as_slice()),
376 value: BigInt::from_be_bytes(value),
377 leaf_lower_range_value: BigInt::from_be_bytes(&non_inclusion_proof.leaf_lower_range_value),
378 leaf_higher_range_value: BigInt::from_be_bytes(
379 &non_inclusion_proof.leaf_higher_range_value,
380 ),
381 merkle_proof_hashed_indexed_element_leaf: proof,
382 index_hashed_indexed_element_leaf: BigInt::from(non_inclusion_proof.leaf_index),
383 next_index: BigInt::from(non_inclusion_proof.next_index),
384 }
385}