1use std::{cmp::Ordering, fmt::Debug, marker::PhantomData};
2
3use crate::{errors::IndexedMerkleTreeError, HIGHEST_ADDRESS_PLUS_ONE};
4use light_concurrent_merkle_tree::{event::RawIndexedElement, light_hasher::Hasher};
5use light_utils::bigint::bigint_to_be_bytes_array;
6use num_bigint::BigUint;
7use num_traits::Zero;
8use num_traits::{CheckedAdd, CheckedSub, ToBytes, Unsigned};
9
10#[derive(Clone, Debug, Default)]
11pub struct IndexedElement<I>
12where
13 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
14 usize: From<I>,
15{
16 pub index: I,
17 pub value: BigUint,
18 pub next_index: I,
19}
20
21impl<I> From<RawIndexedElement<I>> for IndexedElement<I>
22where
23 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
24 usize: From<I>,
25{
26 fn from(value: RawIndexedElement<I>) -> Self {
27 IndexedElement {
28 index: value.index,
29 value: BigUint::from_bytes_be(&value.value),
30 next_index: value.next_index,
31 }
32 }
33}
34
35impl<I> PartialEq for IndexedElement<I>
36where
37 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
38 usize: From<I>,
39{
40 fn eq(&self, other: &Self) -> bool {
41 self.value == other.value
42 }
43}
44
45impl<I> Eq for IndexedElement<I>
46where
47 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
48 usize: From<I>,
49{
50}
51
52impl<I> PartialOrd for IndexedElement<I>
53where
54 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
55 usize: From<I>,
56{
57 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
58 Some(self.cmp(other))
59 }
60}
61
62impl<I> Ord for IndexedElement<I>
63where
64 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
65 usize: From<I>,
66{
67 fn cmp(&self, other: &Self) -> Ordering {
68 self.value.cmp(&other.value)
69 }
70}
71
72impl<I> IndexedElement<I>
73where
74 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
75 usize: From<I>,
76{
77 pub fn index(&self) -> usize {
78 self.index.into()
79 }
80
81 pub fn next_index(&self) -> usize {
82 self.next_index.into()
83 }
84
85 pub fn hash<H>(&self, next_value: &BigUint) -> Result<[u8; 32], IndexedMerkleTreeError>
86 where
87 H: Hasher,
88 {
89 let hash = H::hashv(&[
90 bigint_to_be_bytes_array::<32>(&self.value)?.as_ref(),
91 self.next_index.to_be_bytes().as_ref(),
92 bigint_to_be_bytes_array::<32>(next_value)?.as_ref(),
93 ])?;
94
95 Ok(hash)
96 }
97
98 pub fn update_from_raw_element(&mut self, raw_element: &RawIndexedElement<I>) {
99 self.index = raw_element.index;
100 self.value = BigUint::from_bytes_be(&raw_element.value);
101 self.next_index = raw_element.next_index;
102 }
103}
104
105#[derive(Clone, Debug)]
106pub struct IndexedElementBundle<I>
107where
108 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
109 usize: From<I>,
110{
111 pub new_low_element: IndexedElement<I>,
112 pub new_element: IndexedElement<I>,
113 pub new_element_next_value: BigUint,
114}
115
116#[derive(Clone, Debug)]
117pub struct IndexedArray<H, I>
118where
119 H: Hasher,
120 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
121 usize: From<I>,
122{
123 pub elements: Vec<IndexedElement<I>>,
124 pub current_node_index: I,
125 pub highest_element_index: I,
126
127 _hasher: PhantomData<H>,
128}
129
130impl<H, I> Default for IndexedArray<H, I>
131where
132 H: Hasher,
133 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
134 usize: From<I>,
135{
136 fn default() -> Self {
137 Self {
138 elements: vec![IndexedElement {
139 index: I::zero(),
140 value: BigUint::zero(),
141 next_index: I::zero(),
142 }],
143 current_node_index: I::zero(),
144 highest_element_index: I::zero(),
145 _hasher: PhantomData,
146 }
147 }
148}
149
150impl<H, I> IndexedArray<H, I>
151where
152 H: Hasher,
153 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
154 usize: From<I>,
155{
156 pub fn get(&self, index: usize) -> Option<&IndexedElement<I>> {
157 self.elements.get(index)
158 }
159
160 pub fn len(&self) -> usize {
161 self.current_node_index.into()
162 }
163
164 pub fn is_empty(&self) -> bool {
165 self.current_node_index == I::zero()
166 }
167
168 pub fn iter(&self) -> IndexingArrayIter<H, I> {
169 IndexingArrayIter {
170 indexing_array: self,
171 front: 0,
172 back: self.current_node_index.into(),
173 }
174 }
175
176 pub fn find_element(&self, value: &BigUint) -> Option<&IndexedElement<I>> {
177 self.elements[..self.len() + 1]
178 .iter()
179 .find(|&node| node.value == *value)
180 }
181
182 pub fn init(&mut self) -> Result<IndexedElementBundle<I>, IndexedMerkleTreeError> {
183 use num_traits::Num;
184 let init_value = BigUint::from_str_radix(HIGHEST_ADDRESS_PLUS_ONE, 10)
185 .map_err(|_| IndexedMerkleTreeError::IntegerOverflow)?;
186 self.append(&init_value)
187 }
188
189 pub fn find_low_element_index_for_nonexistent(
197 &self,
198 value: &BigUint,
199 ) -> Result<I, IndexedMerkleTreeError> {
200 for (i, node) in self.elements.iter().enumerate() {
203 if node.value == *value {
204 return Err(IndexedMerkleTreeError::ElementAlreadyExists);
205 }
206 if self.elements[node.next_index()].value > *value && node.value < *value {
207 return i
208 .try_into()
209 .map_err(|_| IndexedMerkleTreeError::IntegerOverflow);
210 }
211 }
212 Ok(self.highest_element_index)
216 }
217
218 pub fn find_low_element_for_nonexistent(
230 &self,
231 value: &BigUint,
232 ) -> Result<(IndexedElement<I>, BigUint), IndexedMerkleTreeError> {
233 let low_element_index = self.find_low_element_index_for_nonexistent(value)?;
234 let low_element = self.elements[usize::from(low_element_index)].clone();
235 Ok((
236 low_element.clone(),
237 self.elements[low_element.next_index()].value.clone(),
238 ))
239 }
240
241 pub fn find_low_element_index_for_existent(
249 &self,
250 value: &BigUint,
251 ) -> Result<I, IndexedMerkleTreeError> {
252 for (i, node) in self.elements[..self.len() + 1].iter().enumerate() {
253 if self.elements[usize::from(node.next_index)].value == *value {
254 let i = i
255 .try_into()
256 .map_err(|_| IndexedMerkleTreeError::IntegerOverflow)?;
257 return Ok(i);
258 }
259 }
260 Err(IndexedMerkleTreeError::ElementDoesNotExist)
261 }
262
263 pub fn find_low_element_for_existent(
271 &self,
272 value: &BigUint,
273 ) -> Result<IndexedElement<I>, IndexedMerkleTreeError> {
274 let low_element_index = self.find_low_element_index_for_existent(value)?;
275 let low_element = self.elements[usize::from(low_element_index)].clone();
276 Ok(low_element)
277 }
278
279 pub fn hash_element(&self, index: I) -> Result<[u8; 32], IndexedMerkleTreeError> {
285 let element = self
286 .elements
287 .get(usize::from(index))
288 .ok_or(IndexedMerkleTreeError::IndexHigherThanMax)?;
289 let next_element = self
290 .elements
291 .get(usize::from(element.next_index))
292 .ok_or(IndexedMerkleTreeError::IndexHigherThanMax)?;
293 element.hash::<H>(&next_element.value)
294 }
295
296 pub fn new_element_with_low_element_index(
299 &self,
300 low_element_index: I,
301 value: &BigUint,
302 ) -> Result<IndexedElementBundle<I>, IndexedMerkleTreeError> {
303 let mut new_low_element = self.elements[usize::from(low_element_index)].clone();
304
305 let new_element_index = self
306 .current_node_index
307 .checked_add(&I::one())
308 .ok_or(IndexedMerkleTreeError::IntegerOverflow)?;
309 let new_element = IndexedElement {
310 index: new_element_index,
311 value: value.clone(),
312 next_index: new_low_element.next_index,
313 };
314
315 new_low_element.next_index = new_element_index;
316
317 let new_element_next_value = self.elements[usize::from(new_element.next_index)]
318 .value
319 .clone();
320
321 Ok(IndexedElementBundle {
322 new_low_element,
323 new_element,
324 new_element_next_value,
325 })
326 }
327
328 pub fn new_element(
329 &self,
330 value: &BigUint,
331 ) -> Result<IndexedElementBundle<I>, IndexedMerkleTreeError> {
332 let low_element_index = self.find_low_element_index_for_nonexistent(value)?;
333 let element = self.new_element_with_low_element_index(low_element_index, value)?;
334
335 Ok(element)
336 }
337
338 pub fn append_with_low_element_index(
340 &mut self,
341 low_element_index: I,
342 value: &BigUint,
343 ) -> Result<IndexedElementBundle<I>, IndexedMerkleTreeError> {
344 let old_low_element = &self.elements[usize::from(low_element_index)];
347
348 if old_low_element.next_index == I::zero() {
350 if value <= &old_low_element.value {
354 return Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement);
355 }
356 } else {
357 if value <= &old_low_element.value {
360 return Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement);
361 }
362 if value >= &self.elements[usize::from(old_low_element.next_index)].value {
365 return Err(IndexedMerkleTreeError::NewElementGreaterOrEqualToNextElement);
366 }
367 }
368
369 let new_element_bundle =
371 self.new_element_with_low_element_index(low_element_index, value)?;
372
373 if old_low_element.next_index == I::zero() {
382 self.highest_element_index = new_element_bundle.new_element.index;
383 }
384
385 self.current_node_index = new_element_bundle.new_element.index;
387 self.elements.push(new_element_bundle.new_element.clone());
388
389 self.elements[usize::from(low_element_index)] = new_element_bundle.new_low_element.clone();
391
392 Ok(new_element_bundle)
393 }
394
395 pub fn append(
396 &mut self,
397 value: &BigUint,
398 ) -> Result<IndexedElementBundle<I>, IndexedMerkleTreeError> {
399 let low_element_index = self.find_low_element_index_for_nonexistent(value)?;
400 self.append_with_low_element_index(low_element_index, value)
401 }
402
403 pub fn lowest(&self) -> Option<IndexedElement<I>> {
404 if self.current_node_index < I::one() {
405 None
406 } else {
407 self.elements.get(1).cloned()
408 }
409 }
410}
411
412pub struct IndexingArrayIter<'a, H, I>
413where
414 H: Hasher,
415 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
416 usize: From<I>,
417{
418 indexing_array: &'a IndexedArray<H, I>,
419 front: usize,
420 back: usize,
421}
422
423impl<'a, H, I> Iterator for IndexingArrayIter<'a, H, I>
424where
425 H: Hasher,
426 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
427 usize: From<I>,
428{
429 type Item = &'a IndexedElement<I>;
430
431 fn next(&mut self) -> Option<Self::Item> {
432 if self.front <= self.back {
433 let result = self.indexing_array.elements.get(self.front);
434 self.front += 1;
435 result
436 } else {
437 None
438 }
439 }
440}
441
442impl<'a, H, I> DoubleEndedIterator for IndexingArrayIter<'a, H, I>
443where
444 H: Hasher,
445 I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom<usize> + Unsigned,
446 usize: From<I>,
447{
448 fn next_back(&mut self) -> Option<Self::Item> {
449 if self.back >= self.front {
450 let result = self.indexing_array.elements.get(self.back);
451 self.back -= 1;
452 result
453 } else {
454 None
455 }
456 }
457}
458
459#[cfg(test)]
460mod test {
461 use light_concurrent_merkle_tree::light_hasher::Poseidon;
462 use num_bigint::{RandBigInt, ToBigUint};
463 use rand::thread_rng;
464
465 use super::*;
466
467 #[test]
468 fn test_indexed_element_cmp() {
469 let mut rng = thread_rng();
470
471 for _ in 0..1000 {
472 let value = rng.gen_biguint(128);
473 let element_1 = IndexedElement::<u16> {
474 index: 0,
475 value: value.clone(),
476 next_index: 1,
477 };
478 let element_2 = IndexedElement::<u16> {
479 index: 1,
480 value,
481 next_index: 2,
482 };
483 assert_eq!(element_1, element_2);
484 assert_eq!(element_2, element_1);
485 assert!(matches!(element_1.cmp(&element_2), Ordering::Equal));
486 assert!(matches!(element_2.cmp(&element_1), Ordering::Equal));
487
488 let value_higher = rng.gen_biguint(128);
489 if value_higher == 0.to_biguint().unwrap() {
490 continue;
491 }
492 let value_lower = rng.gen_biguint_below(&value_higher);
493 let element_lower = IndexedElement::<u16> {
494 index: 0,
495 value: value_lower,
496 next_index: 1,
497 };
498 let element_higher = IndexedElement::<u16> {
499 index: 1,
500 value: value_higher,
501 next_index: 2,
502 };
503 assert_ne!(element_lower, element_higher);
504 assert_ne!(element_higher, element_lower);
505 assert!(matches!(element_lower.cmp(&element_higher), Ordering::Less));
506 assert!(matches!(
507 element_higher.cmp(&element_lower),
508 Ordering::Greater
509 ));
510 assert!(matches!(
511 element_lower.partial_cmp(&element_higher),
512 Some(Ordering::Less)
513 ));
514 assert!(matches!(
515 element_higher.partial_cmp(&element_lower),
516 Some(Ordering::Greater)
517 ));
518 }
519 }
520
521 #[test]
523 fn test_append() {
524 let mut indexed_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
531
532 let nullifier1 = 30_u32.to_biguint().unwrap();
533 let bundle1 = indexed_array.new_element(&nullifier1).unwrap();
534 assert!(indexed_array.find_element(&nullifier1).is_none());
535 indexed_array.append(&nullifier1).unwrap();
536
537 assert_eq!(
553 indexed_array.find_element(&nullifier1),
554 Some(&bundle1.new_element),
555 );
556 let expected_hash = Poseidon::hashv(&[
557 bigint_to_be_bytes_array::<32>(&nullifier1)
558 .unwrap()
559 .as_ref(),
560 0_usize.to_be_bytes().as_ref(),
561 bigint_to_be_bytes_array::<32>(&(0.to_biguint().unwrap()))
562 .unwrap()
563 .as_ref(),
564 ])
565 .unwrap();
566 assert_eq!(indexed_array.hash_element(1).unwrap(), expected_hash);
567 assert_eq!(
568 indexed_array.elements[0],
569 IndexedElement {
570 index: 0,
571 value: 0_u32.to_biguint().unwrap(),
572 next_index: 1,
573 },
574 );
575 assert_eq!(
576 indexed_array.elements[1],
577 IndexedElement {
578 index: 1,
579 value: 30_u32.to_biguint().unwrap(),
580 next_index: 0,
581 }
582 );
583 assert_eq!(
584 indexed_array.iter().collect::<Vec<_>>().as_slice(),
585 &[
586 &IndexedElement {
587 index: 0,
588 value: 0_u32.to_biguint().unwrap(),
589 next_index: 1,
590 },
591 &IndexedElement {
592 index: 1,
593 value: 30_u32.to_biguint().unwrap(),
594 next_index: 0
595 }
596 ]
597 );
598
599 let nullifier2 = 10_u32.to_biguint().unwrap();
600 let bundle2 = indexed_array.new_element(&nullifier2).unwrap();
601 assert!(indexed_array.find_element(&nullifier2).is_none());
602 indexed_array.append(&nullifier2).unwrap();
603
604 assert_eq!(
623 indexed_array.find_element(&nullifier2),
624 Some(&bundle2.new_element),
625 );
626 let expected_hash = Poseidon::hashv(&[
627 bigint_to_be_bytes_array::<32>(&nullifier2)
628 .unwrap()
629 .as_ref(),
630 1_usize.to_be_bytes().as_ref(),
631 bigint_to_be_bytes_array::<32>(&(30.to_biguint().unwrap()))
632 .unwrap()
633 .as_ref(),
634 ])
635 .unwrap();
636 assert_eq!(indexed_array.hash_element(2).unwrap(), expected_hash);
637 assert_eq!(
638 indexed_array.elements[0],
639 IndexedElement {
640 index: 0,
641 value: 0_u32.to_biguint().unwrap(),
642 next_index: 2,
643 }
644 );
645 assert_eq!(
646 indexed_array.elements[1],
647 IndexedElement {
648 index: 1,
649 value: 30_u32.to_biguint().unwrap(),
650 next_index: 0,
651 }
652 );
653 assert_eq!(
654 indexed_array.elements[2],
655 IndexedElement {
656 index: 2,
657 value: 10_u32.to_biguint().unwrap(),
658 next_index: 1,
659 }
660 );
661 assert_eq!(
662 indexed_array.iter().collect::<Vec<_>>().as_slice(),
663 &[
664 &IndexedElement {
665 index: 0,
666 value: 0_u32.to_biguint().unwrap(),
667 next_index: 2,
668 },
669 &IndexedElement {
670 index: 1,
671 value: 30_u32.to_biguint().unwrap(),
672 next_index: 0,
673 },
674 &IndexedElement {
675 index: 2,
676 value: 10_u32.to_biguint().unwrap(),
677 next_index: 1,
678 }
679 ]
680 );
681
682 let nullifier3 = 20_u32.to_biguint().unwrap();
683 let bundle3 = indexed_array.new_element(&nullifier3).unwrap();
684 assert!(indexed_array.find_element(&nullifier3).is_none());
685 indexed_array.append(&nullifier3).unwrap();
686
687 assert_eq!(
703 indexed_array.find_element(&nullifier3),
704 Some(&bundle3.new_element),
705 );
706 let expected_hash = Poseidon::hashv(&[
707 bigint_to_be_bytes_array::<32>(&nullifier3)
708 .unwrap()
709 .as_ref(),
710 1_usize.to_be_bytes().as_ref(),
711 bigint_to_be_bytes_array::<32>(&(30.to_biguint().unwrap()))
712 .unwrap()
713 .as_ref(),
714 ])
715 .unwrap();
716 assert_eq!(indexed_array.hash_element(3).unwrap(), expected_hash);
717 assert_eq!(
718 indexed_array.elements[0],
719 IndexedElement {
720 index: 0,
721 value: 0_u32.to_biguint().unwrap(),
722 next_index: 2,
723 }
724 );
725 assert_eq!(
726 indexed_array.elements[1],
727 IndexedElement {
728 index: 1,
729 value: 30_u32.to_biguint().unwrap(),
730 next_index: 0,
731 }
732 );
733 assert_eq!(
734 indexed_array.elements[2],
735 IndexedElement {
736 index: 2,
737 value: 10_u32.to_biguint().unwrap(),
738 next_index: 3,
739 }
740 );
741 assert_eq!(
742 indexed_array.elements[3],
743 IndexedElement {
744 index: 3,
745 value: 20_u32.to_biguint().unwrap(),
746 next_index: 1,
747 }
748 );
749 assert_eq!(
750 indexed_array.iter().collect::<Vec<_>>().as_slice(),
751 &[
752 &IndexedElement {
753 index: 0,
754 value: 0_u32.to_biguint().unwrap(),
755 next_index: 2,
756 },
757 &IndexedElement {
758 index: 1,
759 value: 30_u32.to_biguint().unwrap(),
760 next_index: 0,
761 },
762 &IndexedElement {
763 index: 2,
764 value: 10_u32.to_biguint().unwrap(),
765 next_index: 3,
766 },
767 &IndexedElement {
768 index: 2,
769 value: 20_u32.to_biguint().unwrap(),
770 next_index: 1
771 }
772 ]
773 );
774
775 let nullifier4 = 50_u32.to_biguint().unwrap();
776 let bundle4 = indexed_array.new_element(&nullifier4).unwrap();
777 assert!(indexed_array.find_element(&nullifier4).is_none());
778 indexed_array.append(&nullifier4).unwrap();
779
780 assert_eq!(
798 indexed_array.find_element(&nullifier4),
799 Some(&bundle4.new_element),
800 );
801 let expected_hash = Poseidon::hashv(&[
802 bigint_to_be_bytes_array::<32>(&nullifier4)
803 .unwrap()
804 .as_ref(),
805 0_usize.to_be_bytes().as_ref(),
806 bigint_to_be_bytes_array::<32>(&(0.to_biguint().unwrap()))
807 .unwrap()
808 .as_ref(),
809 ])
810 .unwrap();
811 assert_eq!(indexed_array.hash_element(4).unwrap(), expected_hash);
812 assert_eq!(
813 indexed_array.elements[0],
814 IndexedElement {
815 index: 0,
816 value: 0_u32.to_biguint().unwrap(),
817 next_index: 2,
818 }
819 );
820 assert_eq!(
821 indexed_array.elements[1],
822 IndexedElement {
823 index: 1,
824 value: 30_u32.to_biguint().unwrap(),
825 next_index: 4,
826 }
827 );
828 assert_eq!(
829 indexed_array.elements[2],
830 IndexedElement {
831 index: 2,
832 value: 10_u32.to_biguint().unwrap(),
833 next_index: 3,
834 }
835 );
836 assert_eq!(
837 indexed_array.elements[3],
838 IndexedElement {
839 index: 3,
840 value: 20_u32.to_biguint().unwrap(),
841 next_index: 1,
842 }
843 );
844 assert_eq!(
845 indexed_array.elements[4],
846 IndexedElement {
847 index: 4,
848 value: 50_u32.to_biguint().unwrap(),
849 next_index: 0,
850 }
851 );
852 assert_eq!(
853 indexed_array.iter().collect::<Vec<_>>().as_slice(),
854 &[
855 &IndexedElement {
856 index: 0,
857 value: 0_u32.to_biguint().unwrap(),
858 next_index: 2,
859 },
860 &IndexedElement {
861 index: 1,
862 value: 30_u32.to_biguint().unwrap(),
863 next_index: 4,
864 },
865 &IndexedElement {
866 index: 2,
867 value: 10_u32.to_biguint().unwrap(),
868 next_index: 3,
869 },
870 &IndexedElement {
871 index: 3,
872 value: 20_u32.to_biguint().unwrap(),
873 next_index: 1,
874 },
875 &IndexedElement {
876 index: 4,
877 value: 50_u32.to_biguint().unwrap(),
878 next_index: 0,
879 }
880 ]
881 );
882 }
883
884 #[test]
885 fn test_append_with_low_element_index() {
886 let mut indexing_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
893
894 let low_element_index = 0;
895 let nullifier1 = 30_u32.to_biguint().unwrap();
896 indexing_array
897 .append_with_low_element_index(low_element_index, &nullifier1)
898 .unwrap();
899
900 assert_eq!(
916 indexing_array.elements[0],
917 IndexedElement {
918 index: 0,
919 value: 0_u32.to_biguint().unwrap(),
920 next_index: 1,
921 },
922 );
923 assert_eq!(
924 indexing_array.elements[1],
925 IndexedElement {
926 index: 1,
927 value: 30_u32.to_biguint().unwrap(),
928 next_index: 0,
929 }
930 );
931
932 let low_element_index = 0;
933 let nullifier2 = 10_u32.to_biguint().unwrap();
934 indexing_array
935 .append_with_low_element_index(low_element_index, &nullifier2)
936 .unwrap();
937
938 assert_eq!(
957 indexing_array.elements[0],
958 IndexedElement {
959 index: 0,
960 value: 0_u32.to_biguint().unwrap(),
961 next_index: 2,
962 }
963 );
964 assert_eq!(
965 indexing_array.elements[1],
966 IndexedElement {
967 index: 1,
968 value: 30_u32.to_biguint().unwrap(),
969 next_index: 0,
970 }
971 );
972 assert_eq!(
973 indexing_array.elements[2],
974 IndexedElement {
975 index: 2,
976 value: 10_u32.to_biguint().unwrap(),
977 next_index: 1,
978 }
979 );
980
981 let low_element_index = 2;
982 let nullifier3 = 20_u32.to_biguint().unwrap();
983 indexing_array
984 .append_with_low_element_index(low_element_index, &nullifier3)
985 .unwrap();
986
987 assert_eq!(
1003 indexing_array.elements[0],
1004 IndexedElement {
1005 index: 0,
1006 value: 0_u32.to_biguint().unwrap(),
1007 next_index: 2,
1008 }
1009 );
1010 assert_eq!(
1011 indexing_array.elements[1],
1012 IndexedElement {
1013 index: 1,
1014 value: 30_u32.to_biguint().unwrap(),
1015 next_index: 0,
1016 }
1017 );
1018 assert_eq!(
1019 indexing_array.elements[2],
1020 IndexedElement {
1021 index: 2,
1022 value: 10_u32.to_biguint().unwrap(),
1023 next_index: 3,
1024 }
1025 );
1026 assert_eq!(
1027 indexing_array.elements[3],
1028 IndexedElement {
1029 index: 3,
1030 value: 20_u32.to_biguint().unwrap(),
1031 next_index: 1,
1032 }
1033 );
1034
1035 let low_element_index = 1;
1036 let nullifier4 = 50_u32.to_biguint().unwrap();
1037 indexing_array
1038 .append_with_low_element_index(low_element_index, &nullifier4)
1039 .unwrap();
1040
1041 assert_eq!(
1059 indexing_array.elements[0],
1060 IndexedElement {
1061 index: 0,
1062 value: 0_u32.to_biguint().unwrap(),
1063 next_index: 2,
1064 }
1065 );
1066 assert_eq!(
1067 indexing_array.elements[1],
1068 IndexedElement {
1069 index: 1,
1070 value: 30_u32.to_biguint().unwrap(),
1071 next_index: 4,
1072 }
1073 );
1074 assert_eq!(
1075 indexing_array.elements[2],
1076 IndexedElement {
1077 index: 2,
1078 value: 10_u32.to_biguint().unwrap(),
1079 next_index: 3,
1080 }
1081 );
1082 assert_eq!(
1083 indexing_array.elements[3],
1084 IndexedElement {
1085 index: 3,
1086 value: 20_u32.to_biguint().unwrap(),
1087 next_index: 1,
1088 }
1089 );
1090 assert_eq!(
1091 indexing_array.elements[4],
1092 IndexedElement {
1093 index: 4,
1094 value: 50_u32.to_biguint().unwrap(),
1095 next_index: 0,
1096 }
1097 );
1098 }
1099
1100 #[test]
1104 fn test_append_with_low_element_index_invalid() {
1105 let mut indexing_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
1112
1113 let low_element_index = 0;
1121 let nullifier1 = 30_u32.to_biguint().unwrap();
1122 indexing_array
1123 .append_with_low_element_index(low_element_index, &nullifier1)
1124 .unwrap();
1125
1126 let low_element_index = 1;
1130 let nullifier2 = 20_u32.to_biguint().unwrap();
1131 assert!(matches!(
1132 indexing_array.append_with_low_element_index(low_element_index, &nullifier2),
1133 Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement)
1134 ));
1135
1136 let low_element_index = 0;
1140 let nullifier2 = 50_u32.to_biguint().unwrap();
1141 assert!(matches!(
1142 indexing_array.append_with_low_element_index(low_element_index, &nullifier2),
1143 Err(IndexedMerkleTreeError::NewElementGreaterOrEqualToNextElement),
1144 ));
1145
1146 let low_element_index = 1;
1154 let nullifier2 = 50_u32.to_biguint().unwrap();
1155 indexing_array
1156 .append_with_low_element_index(low_element_index, &nullifier2)
1157 .unwrap();
1158
1159 let low_element_index = 2;
1163 let nullifier3 = 40_u32.to_biguint().unwrap();
1164 assert!(matches!(
1165 indexing_array.append_with_low_element_index(low_element_index, &nullifier3),
1166 Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement)
1167 ));
1168 }
1169
1170 #[test]
1173 fn test_find_low_element_for_existent_element() {
1174 let mut indexed_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
1175
1176 let low_element_index = 0;
1178 let nullifier_1 = 40_u32.to_biguint().unwrap();
1179 indexed_array
1180 .append_with_low_element_index(low_element_index, &nullifier_1)
1181 .unwrap();
1182 let low_element_index = 0;
1183 let nullifier_2 = 20_u32.to_biguint().unwrap();
1184 indexed_array
1185 .append_with_low_element_index(low_element_index, &nullifier_2)
1186 .unwrap();
1187
1188 let nonexistent_nullifier = 30_u32.to_biguint().unwrap();
1190 let res = indexed_array.find_low_element_index_for_existent(&nonexistent_nullifier);
1192 assert!(matches!(
1193 res,
1194 Err(IndexedMerkleTreeError::ElementDoesNotExist)
1195 ));
1196 let res = indexed_array.find_low_element_for_existent(&nonexistent_nullifier);
1197 assert!(matches!(
1198 res,
1199 Err(IndexedMerkleTreeError::ElementDoesNotExist)
1200 ));
1201 let low_element_index = indexed_array
1203 .find_low_element_index_for_nonexistent(&nonexistent_nullifier)
1204 .unwrap();
1205 assert_eq!(low_element_index, 2);
1206 let low_element = indexed_array
1207 .find_low_element_for_nonexistent(&nonexistent_nullifier)
1208 .unwrap();
1209 assert_eq!(
1210 low_element,
1211 (
1212 IndexedElement::<usize> {
1213 index: 2,
1214 value: 20_u32.to_biguint().unwrap(),
1215 next_index: 1,
1216 },
1217 40_u32.to_biguint().unwrap(),
1218 )
1219 );
1220
1221 let low_element_index = indexed_array
1224 .find_low_element_index_for_existent(&nullifier_1)
1225 .unwrap();
1226 assert_eq!(low_element_index, 2);
1227 let low_element = indexed_array
1228 .find_low_element_for_existent(&nullifier_1)
1229 .unwrap();
1230 assert_eq!(
1231 low_element,
1232 IndexedElement::<usize> {
1233 index: 2,
1234 value: 20_u32.to_biguint().unwrap(),
1235 next_index: 1,
1236 },
1237 );
1238 let res = indexed_array.find_low_element_index_for_nonexistent(&nullifier_1);
1240 assert!(matches!(
1241 res,
1242 Err(IndexedMerkleTreeError::ElementAlreadyExists)
1243 ));
1244 let res = indexed_array.find_low_element_for_nonexistent(&nullifier_1);
1245 assert!(matches!(
1246 res,
1247 Err(IndexedMerkleTreeError::ElementAlreadyExists)
1248 ));
1249 }
1250}