light_indexed_merkle_tree/
array.rs

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    /// Returns the index of the low element for the given `value`, which is
190    /// not yet the part of the array.
191    ///
192    /// Low element is the greatest element which still has lower value than
193    /// the provided one.
194    ///
195    /// Low elements are used in non-membership proofs.
196    pub fn find_low_element_index_for_nonexistent(
197        &self,
198        value: &BigUint,
199    ) -> Result<I, IndexedMerkleTreeError> {
200        // Try to find element whose next element is higher than the provided
201        // value.
202        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        // If no such element was found, it means that our value is going to be
213        // the greatest in the array. This means that the currently greatest
214        // element is going to be the low element of our value.
215        Ok(self.highest_element_index)
216    }
217
218    /// Returns the:
219    ///
220    /// * Low element for the given value.
221    /// * Next value for that low element.
222    ///
223    /// For the given `value`, which is not yet the part of the array.
224    ///
225    /// Low element is the greatest element which still has lower value than
226    /// the provided one.
227    ///
228    /// Low elements are used in non-membership proofs.
229    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    /// Returns the index of the low element for the given `value`, which is
242    /// already the part of the array.
243    ///
244    /// Low element is the greatest element which still has lower value than
245    /// the provided one.
246    ///
247    /// Low elements are used in non-membership proofs.
248    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    /// Returns the low element for the given `value`, which is already the
264    /// part of the array.
265    ///
266    /// Low element is the greatest element which still has lower value than
267    /// the provided one.
268    ///
269    /// Low elements are used in non-membership proofs.
270    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    /// Returns the hash of the given element. That hash consists of:
280    ///
281    /// * The value of the given element.
282    /// * The `next_index` of the given element.
283    /// * The value of the element pointed by `next_index`.
284    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    /// Returns an updated low element and a new element, created based on the
297    /// provided `low_element_index` and `value`.
298    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    /// Appends the given `value` to the indexing array.
339    pub fn append_with_low_element_index(
340        &mut self,
341        low_element_index: I,
342        value: &BigUint,
343    ) -> Result<IndexedElementBundle<I>, IndexedMerkleTreeError> {
344        // TOD0: add length check, and add field to with tree height here
345
346        let old_low_element = &self.elements[usize::from(low_element_index)];
347
348        // Check that the `value` belongs to the range of `old_low_element`.
349        if old_low_element.next_index == I::zero() {
350            // In this case, the `old_low_element` is the greatest element.
351            // The value of `new_element` needs to be greater than the value of
352            // `old_low_element` (and therefore, be the greatest).
353            if value <= &old_low_element.value {
354                return Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement);
355            }
356        } else {
357            // The value of `new_element` needs to be greater than the value of
358            // `old_low_element` (and therefore, be the greatest).
359            if value <= &old_low_element.value {
360                return Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement);
361            }
362            // The value of `new_element` needs to be lower than the value of
363            // next element pointed by `old_low_element`.
364            if value >= &self.elements[usize::from(old_low_element.next_index)].value {
365                return Err(IndexedMerkleTreeError::NewElementGreaterOrEqualToNextElement);
366            }
367        }
368
369        // Create new node.
370        let new_element_bundle =
371            self.new_element_with_low_element_index(low_element_index, value)?;
372
373        // If the old low element wasn't pointing to any element, it means that:
374        //
375        // * It used to be the highest element.
376        // * Our new element, which we are appending, is going the be the
377        //   highest element.
378        //
379        // Therefore, we need to save the new element index as the highest
380        // index.
381        if old_low_element.next_index == I::zero() {
382            self.highest_element_index = new_element_bundle.new_element.index;
383        }
384
385        // Insert new node.
386        self.current_node_index = new_element_bundle.new_element.index;
387        self.elements.push(new_element_bundle.new_element.clone());
388
389        // Update low element.
390        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    /// Tests the insertion of elements to the indexing array.
522    #[test]
523    fn test_append() {
524        // The initial state of the array looks like:
525        //
526        // ```
527        // value      = [0] [0] [0] [0] [0] [0] [0] [0]
528        // next_index = [0] [0] [0] [0] [0] [0] [0] [0]
529        // ```
530        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        // After adding a new value 30, it should look like:
538        //
539        // ```
540        // value      = [ 0] [30] [0] [0] [0] [0] [0] [0]
541        // next_index = [ 1] [ 0] [0] [0] [0] [0] [0] [0]
542        // ```
543        //
544        // Because:
545        //
546        // * Low element is the first node, with index 0 and value 0. There is
547        //   no node with value greater as 30, so we found it as a one pointing to
548        //   node 0 (which will always have value 0).
549        // * The new nullifier is inserted in index 1.
550        // * `next_*` fields of the low nullifier are updated to point to the new
551        //   nullifier.
552        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        // After adding an another value 10, it should look like:
605        //
606        // ```
607        // value      = [ 0] [30] [10] [0] [0] [0] [0] [0]
608        // next_index = [ 2] [ 0] [ 1] [0] [0] [0] [0] [0]
609        // ```
610        //
611        // Because:
612        //
613        // * Low nullifier is still the node 0, but this time for differen reason -
614        //   its `next_index` 2 contains value 30, whish is greater than 10.
615        // * The new nullifier is inserted as node 2.
616        // * Low nullifier is pointing to the index 1. We assign the 1st nullifier
617        //   as the next nullifier of our new nullifier. Therefore, our new nullifier
618        //   looks like: `[value = 10, next_index = 1]`.
619        // * Low nullifier is updated to point to the new nullifier. Therefore,
620        //   after update it looks like: `[value = 0, next_index = 2]`.
621        // * The previously inserted nullifier, the node 1, remains unchanged.
622        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        // After adding an another value 20, it should look like:
688        //
689        // ```
690        // value      = [ 0] [30] [10] [20] [0] [0] [0] [0]
691        // next_index = [ 2] [ 0] [ 3] [ 1] [0] [0] [0] [0]
692        // ```
693        //
694        // Because:
695        // * Low nullifier is the node 2.
696        // * The new nullifier is inserted as node 3.
697        // * Low nullifier is pointing to the node 2. We assign the 1st nullifier
698        //   as the next nullifier of our new nullifier. Therefore, our new
699        //   nullifier looks like:
700        // * Low nullifier is updated to point to the new nullifier. Therefore,
701        //   after update it looks like: `[value = 10, next_index = 3]`.
702        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        // After adding an another value 50, it should look like:
781        //
782        // ```
783        // value      = [ 0]  [30] [10] [20] [50] [0] [0] [0]
784        // next_index = [ 2]  [ 4] [ 3] [ 1] [0 ] [0] [0] [0]
785        // ```
786        //
787        // Because:
788        //
789        // * Low nullifier is the node 1 - there is no node with value greater
790        //   than 50, so we found it as a one having 0 as the `next_value`.
791        // * The new nullifier is inserted as node 4.
792        // * Low nullifier is not pointing to any node. So our new nullifier
793        //   is not going to point to any other node either. Therefore, the new
794        //   nullifier looks like: `[value = 50, next_index = 0]`.
795        // * Low nullifier is updated to point to the new nullifier. Therefore,
796        //   after update it looks like: `[value = 30, next_index = 4]`.
797        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        // The initial state of the array looks like:
887        //
888        // ```
889        // value      = [0] [0] [0] [0] [0] [0] [0] [0]
890        // next_index = [0] [0] [0] [0] [0] [0] [0] [0]
891        // ```
892        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        // After adding a new value 30, it should look like:
901        //
902        // ```
903        // value      = [ 0] [30] [0] [0] [0] [0] [0] [0]
904        // next_index = [ 1] [ 0] [0] [0] [0] [0] [0] [0]
905        // ```
906        //
907        // Because:
908        //
909        // * Low element is the first node, with index 0 and value 0. There is
910        //   no node with value greater as 30, so we found it as a one pointing to
911        //   node 0 (which will always have value 0).
912        // * The new nullifier is inserted in index 1.
913        // * `next_*` fields of the low nullifier are updated to point to the new
914        //   nullifier.
915        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        // After adding an another value 10, it should look like:
939        //
940        // ```
941        // value      = [ 0] [30] [10] [0] [0] [0] [0] [0]
942        // next_index = [ 2] [ 0] [ 1] [0] [0] [0] [0] [0]
943        // ```
944        //
945        // Because:
946        //
947        // * Low nullifier is still the node 0, but this time for differen reason -
948        //   its `next_index` 2 contains value 30, whish is greater than 10.
949        // * The new nullifier is inserted as node 2.
950        // * Low nullifier is pointing to the index 1. We assign the 1st nullifier
951        //   as the next nullifier of our new nullifier. Therefore, our new nullifier
952        //   looks like: `[value = 10, next_index = 1]`.
953        // * Low nullifier is updated to point to the new nullifier. Therefore,
954        //   after update it looks like: `[value = 0, next_index = 2]`.
955        // * The previously inserted nullifier, the node 1, remains unchanged.
956        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        // After adding an another value 20, it should look like:
988        //
989        // ```
990        // value      = [ 0] [30] [10] [20] [0] [0] [0] [0]
991        // next_index = [ 2] [ 0] [ 3] [ 1] [0] [0] [0] [0]
992        // ```
993        //
994        // Because:
995        // * Low nullifier is the node 2.
996        // * The new nullifier is inserted as node 3.
997        // * Low nullifier is pointing to the node 2. We assign the 1st nullifier
998        //   as the next nullifier of our new nullifier. Therefore, our new
999        //   nullifier looks like:
1000        // * Low nullifier is updated to point to the new nullifier. Therefore,
1001        //   after update it looks like: `[value = 10, next_index = 3]`.
1002        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        // After adding an another value 50, it should look like:
1042        //
1043        // ```
1044        // value      = [ 0]  [30] [10] [20] [50] [0] [0] [0]
1045        // next_index = [ 2]  [ 4] [ 3] [ 1] [0 ] [0] [0] [0]
1046        // ```
1047        //
1048        // Because:
1049        //
1050        // * Low nullifier is the node 1 - there is no node with value greater
1051        //   than 50, so we found it as a one having 0 as the `next_value`.
1052        // * The new nullifier is inserted as node 4.
1053        // * Low nullifier is not pointing to any node. So our new nullifier
1054        //   is not going to point to any other node either. Therefore, the new
1055        //   nullifier looks like: `[value = 50, next_index = 0]`.
1056        // * Low nullifier is updated to point to the new nullifier. Therefore,
1057        //   after update it looks like: `[value = 30, next_index = 4]`.
1058        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    /// Tries to violate the integrity of the array by pointing to invalid low
1101    /// nullifiers. Tests whether the range check works correctly and disallows
1102    /// the invalid appends from happening.
1103    #[test]
1104    fn test_append_with_low_element_index_invalid() {
1105        // The initial state of the array looks like:
1106        //
1107        // ```
1108        // value      = [0] [0] [0] [0] [0] [0] [0] [0]
1109        // next_index = [0] [0] [0] [0] [0] [0] [0] [0]
1110        // ```
1111        let mut indexing_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
1112
1113        // Append nullifier 30. The low nullifier is at index 0. The array
1114        // should look like:
1115        //
1116        // ```
1117        // value      = [ 0] [30] [0] [0] [0] [0] [0] [0]
1118        // next_index = [ 1] [ 0] [0] [0] [0] [0] [0] [0]
1119        // ```
1120        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        // Try appending nullifier 20, while pointing to index 1 as low
1127        // nullifier.
1128        // Therefore, the new element is lower than the supposed low element.
1129        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        // Try appending nullifier 50, while pointing to index 0 as low
1137        // nullifier.
1138        // Therefore, the new element is greater than next element.
1139        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        // Append nullifier 50 correctly, with 0 as low nullifier. The array
1147        // should look like:
1148        //
1149        // ```
1150        // value      = [ 0] [30] [50] [0] [0] [0] [0] [0]
1151        // next_index = [ 1] [ 2] [ 0] [0] [0] [0] [0] [0]
1152        // ```
1153        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        // Try appending nullifier 40, while pointint to index 2 (value 50) as
1160        // low nullifier.
1161        // Therefore, the pointed low element is greater than the new element.
1162        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    /// Tests whether `find_*_for_existent` elements return `None` when a
1171    /// nonexistent is provided.
1172    #[test]
1173    fn test_find_low_element_for_existent_element() {
1174        let mut indexed_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
1175
1176        // Append nullifiers 40 and 20.
1177        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        // Try finding a low element for nonexistent nullifier 30.
1189        let nonexistent_nullifier = 30_u32.to_biguint().unwrap();
1190        // `*_existent` methods should fail.
1191        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        // `*_nonexistent` methods should succeed.
1202        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        // Try finding a low element of existent nullifier 40.
1222        // `_existent` methods should succeed.
1223        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        // `*_nonexistent` methods should fail.
1239        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}