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