light_indexed_merkle_tree/
array.rs

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    /// Returns the index of the low element for the given `value`, which is
194    /// not yet the part of the array.
195    ///
196    /// Low element is the greatest element which still has lower value than
197    /// the provided one.
198    ///
199    /// Low elements are used in non-membership proofs.
200    pub fn find_low_element_index_for_nonexistent(
201        &self,
202        value: &BigUint,
203    ) -> Result<I, IndexedMerkleTreeError> {
204        // Try to find element whose next element is higher than the provided
205        // value.
206        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        // If no such element was found, it means that our value is going to be
217        // the greatest in the array. This means that the currently greatest
218        // element is going to be the low element of our value.
219        Ok(self.highest_element_index)
220    }
221
222    /// Returns the:
223    ///
224    /// * Low element for the given value.
225    /// * Next value for that low element.
226    ///
227    /// For the given `value`, which is not yet the part of the array.
228    ///
229    /// Low element is the greatest element which still has lower value than
230    /// the provided one.
231    ///
232    /// Low elements are used in non-membership proofs.
233    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    /// Returns the index of the low element for the given `value`, which is
246    /// already the part of the array.
247    ///
248    /// Low element is the greatest element which still has lower value than
249    /// the provided one.
250    ///
251    /// Low elements are used in non-membership proofs.
252    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    /// Returns the low element for the given `value`, which is already the
268    /// part of the array.
269    ///
270    /// Low element is the greatest element which still has lower value than
271    /// the provided one.
272    ///
273    /// Low elements are used in non-membership proofs.
274    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    /// Returns the hash of the given element. That hash consists of:
284    ///
285    /// * The value of the given element.
286    /// * The `next_index` of the given element.
287    /// * The value of the element pointed by `next_index`.
288    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    /// Returns an updated low element and a new element, created based on the
301    /// provided `low_element_index` and `value`.
302    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    /// Appends the given `value` to the indexing array.
343    pub fn append_with_low_element_index(
344        &mut self,
345        low_element_index: I,
346        value: &BigUint,
347    ) -> Result<IndexedElementBundle<I>, IndexedMerkleTreeError> {
348        // TOD0: add length check, and add field to with tree height here
349
350        let old_low_element = &self.elements[usize::from(low_element_index)];
351
352        // Check that the `value` belongs to the range of `old_low_element`.
353        if old_low_element.next_index == I::zero() {
354            // In this case, the `old_low_element` is the greatest element.
355            // The value of `new_element` needs to be greater than the value of
356            // `old_low_element` (and therefore, be the greatest).
357            if value <= &old_low_element.value {
358                return Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement);
359            }
360        } else {
361            // The value of `new_element` needs to be greater than the value of
362            // `old_low_element` (and therefore, be the greatest).
363            if value <= &old_low_element.value {
364                return Err(IndexedMerkleTreeError::LowElementGreaterOrEqualToNewElement);
365            }
366            // The value of `new_element` needs to be lower than the value of
367            // next element pointed by `old_low_element`.
368            if value >= &self.elements[usize::from(old_low_element.next_index)].value {
369                return Err(IndexedMerkleTreeError::NewElementGreaterOrEqualToNextElement);
370            }
371        }
372
373        // Create new node.
374        let new_element_bundle =
375            self.new_element_with_low_element_index(low_element_index, value)?;
376
377        // If the old low element wasn't pointing to any element, it means that:
378        //
379        // * It used to be the highest element.
380        // * Our new element, which we are appending, is going the be the
381        //   highest element.
382        //
383        // Therefore, we need to save the new element index as the highest
384        // index.
385        if old_low_element.next_index == I::zero() {
386            self.highest_element_index = new_element_bundle.new_element.index;
387        }
388
389        // Insert new node.
390        self.current_node_index = new_element_bundle.new_element.index;
391        self.elements.push(new_element_bundle.new_element.clone());
392
393        // Update low element.
394        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    /// Tests the insertion of elements to the indexing array.
526    #[test]
527    fn test_append() {
528        // The initial state of the array looks like:
529        //
530        // ```
531        // value      = [0] [0] [0] [0] [0] [0] [0] [0]
532        // next_index = [0] [0] [0] [0] [0] [0] [0] [0]
533        // ```
534        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        // After adding a new value 30, it should look like:
542        //
543        // ```
544        // value      = [ 0] [30] [0] [0] [0] [0] [0] [0]
545        // next_index = [ 1] [ 0] [0] [0] [0] [0] [0] [0]
546        // ```
547        //
548        // Because:
549        //
550        // * Low element is the first node, with index 0 and value 0. There is
551        //   no node with value greater as 30, so we found it as a one pointing to
552        //   node 0 (which will always have value 0).
553        // * The new nullifier is inserted in index 1.
554        // * `next_*` fields of the low nullifier are updated to point to the new
555        //   nullifier.
556        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        // After adding an another value 10, it should look like:
609        //
610        // ```
611        // value      = [ 0] [30] [10] [0] [0] [0] [0] [0]
612        // next_index = [ 2] [ 0] [ 1] [0] [0] [0] [0] [0]
613        // ```
614        //
615        // Because:
616        //
617        // * Low nullifier is still the node 0, but this time for differen reason -
618        //   its `next_index` 2 contains value 30, whish is greater than 10.
619        // * The new nullifier is inserted as node 2.
620        // * Low nullifier is pointing to the index 1. We assign the 1st nullifier
621        //   as the next nullifier of our new nullifier. Therefore, our new nullifier
622        //   looks like: `[value = 10, next_index = 1]`.
623        // * Low nullifier is updated to point to the new nullifier. Therefore,
624        //   after update it looks like: `[value = 0, next_index = 2]`.
625        // * The previously inserted nullifier, the node 1, remains unchanged.
626        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        // After adding an another value 20, it should look like:
692        //
693        // ```
694        // value      = [ 0] [30] [10] [20] [0] [0] [0] [0]
695        // next_index = [ 2] [ 0] [ 3] [ 1] [0] [0] [0] [0]
696        // ```
697        //
698        // Because:
699        // * Low nullifier is the node 2.
700        // * The new nullifier is inserted as node 3.
701        // * Low nullifier is pointing to the node 2. We assign the 1st nullifier
702        //   as the next nullifier of our new nullifier. Therefore, our new
703        //   nullifier looks like:
704        // * Low nullifier is updated to point to the new nullifier. Therefore,
705        //   after update it looks like: `[value = 10, next_index = 3]`.
706        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        // After adding an another value 50, it should look like:
785        //
786        // ```
787        // value      = [ 0]  [30] [10] [20] [50] [0] [0] [0]
788        // next_index = [ 2]  [ 4] [ 3] [ 1] [0 ] [0] [0] [0]
789        // ```
790        //
791        // Because:
792        //
793        // * Low nullifier is the node 1 - there is no node with value greater
794        //   than 50, so we found it as a one having 0 as the `next_value`.
795        // * The new nullifier is inserted as node 4.
796        // * Low nullifier is not pointing to any node. So our new nullifier
797        //   is not going to point to any other node either. Therefore, the new
798        //   nullifier looks like: `[value = 50, next_index = 0]`.
799        // * Low nullifier is updated to point to the new nullifier. Therefore,
800        //   after update it looks like: `[value = 30, next_index = 4]`.
801        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        // The initial state of the array looks like:
891        //
892        // ```
893        // value      = [0] [0] [0] [0] [0] [0] [0] [0]
894        // next_index = [0] [0] [0] [0] [0] [0] [0] [0]
895        // ```
896        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        // After adding a new value 30, it should look like:
905        //
906        // ```
907        // value      = [ 0] [30] [0] [0] [0] [0] [0] [0]
908        // next_index = [ 1] [ 0] [0] [0] [0] [0] [0] [0]
909        // ```
910        //
911        // Because:
912        //
913        // * Low element is the first node, with index 0 and value 0. There is
914        //   no node with value greater as 30, so we found it as a one pointing to
915        //   node 0 (which will always have value 0).
916        // * The new nullifier is inserted in index 1.
917        // * `next_*` fields of the low nullifier are updated to point to the new
918        //   nullifier.
919        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        // After adding an another value 10, it should look like:
943        //
944        // ```
945        // value      = [ 0] [30] [10] [0] [0] [0] [0] [0]
946        // next_index = [ 2] [ 0] [ 1] [0] [0] [0] [0] [0]
947        // ```
948        //
949        // Because:
950        //
951        // * Low nullifier is still the node 0, but this time for differen reason -
952        //   its `next_index` 2 contains value 30, whish is greater than 10.
953        // * The new nullifier is inserted as node 2.
954        // * Low nullifier is pointing to the index 1. We assign the 1st nullifier
955        //   as the next nullifier of our new nullifier. Therefore, our new nullifier
956        //   looks like: `[value = 10, next_index = 1]`.
957        // * Low nullifier is updated to point to the new nullifier. Therefore,
958        //   after update it looks like: `[value = 0, next_index = 2]`.
959        // * The previously inserted nullifier, the node 1, remains unchanged.
960        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        // After adding an another value 20, it should look like:
992        //
993        // ```
994        // value      = [ 0] [30] [10] [20] [0] [0] [0] [0]
995        // next_index = [ 2] [ 0] [ 3] [ 1] [0] [0] [0] [0]
996        // ```
997        //
998        // Because:
999        // * Low nullifier is the node 2.
1000        // * The new nullifier is inserted as node 3.
1001        // * Low nullifier is pointing to the node 2. We assign the 1st nullifier
1002        //   as the next nullifier of our new nullifier. Therefore, our new
1003        //   nullifier looks like:
1004        // * Low nullifier is updated to point to the new nullifier. Therefore,
1005        //   after update it looks like: `[value = 10, next_index = 3]`.
1006        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        // After adding an another value 50, it should look like:
1046        //
1047        // ```
1048        // value      = [ 0]  [30] [10] [20] [50] [0] [0] [0]
1049        // next_index = [ 2]  [ 4] [ 3] [ 1] [0 ] [0] [0] [0]
1050        // ```
1051        //
1052        // Because:
1053        //
1054        // * Low nullifier is the node 1 - there is no node with value greater
1055        //   than 50, so we found it as a one having 0 as the `next_value`.
1056        // * The new nullifier is inserted as node 4.
1057        // * Low nullifier is not pointing to any node. So our new nullifier
1058        //   is not going to point to any other node either. Therefore, the new
1059        //   nullifier looks like: `[value = 50, next_index = 0]`.
1060        // * Low nullifier is updated to point to the new nullifier. Therefore,
1061        //   after update it looks like: `[value = 30, next_index = 4]`.
1062        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    /// Tries to violate the integrity of the array by pointing to invalid low
1105    /// nullifiers. Tests whether the range check works correctly and disallows
1106    /// the invalid appends from happening.
1107    #[test]
1108    fn test_append_with_low_element_index_invalid() {
1109        // The initial state of the array looks like:
1110        //
1111        // ```
1112        // value      = [0] [0] [0] [0] [0] [0] [0] [0]
1113        // next_index = [0] [0] [0] [0] [0] [0] [0] [0]
1114        // ```
1115        let mut indexing_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
1116
1117        // Append nullifier 30. The low nullifier is at index 0. The array
1118        // should look like:
1119        //
1120        // ```
1121        // value      = [ 0] [30] [0] [0] [0] [0] [0] [0]
1122        // next_index = [ 1] [ 0] [0] [0] [0] [0] [0] [0]
1123        // ```
1124        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        // Try appending nullifier 20, while pointing to index 1 as low
1131        // nullifier.
1132        // Therefore, the new element is lower than the supposed low element.
1133        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        // Try appending nullifier 50, while pointing to index 0 as low
1141        // nullifier.
1142        // Therefore, the new element is greater than next element.
1143        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        // Append nullifier 50 correctly, with 0 as low nullifier. The array
1151        // should look like:
1152        //
1153        // ```
1154        // value      = [ 0] [30] [50] [0] [0] [0] [0] [0]
1155        // next_index = [ 1] [ 2] [ 0] [0] [0] [0] [0] [0]
1156        // ```
1157        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        // Try appending nullifier 40, while pointint to index 2 (value 50) as
1164        // low nullifier.
1165        // Therefore, the pointed low element is greater than the new element.
1166        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    /// Tests whether `find_*_for_existent` elements return `None` when a
1175    /// nonexistent is provided.
1176    #[test]
1177    fn test_find_low_element_for_existent_element() {
1178        let mut indexed_array: IndexedArray<Poseidon, usize> = IndexedArray::default();
1179
1180        // Append nullifiers 40 and 20.
1181        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        // Try finding a low element for nonexistent nullifier 30.
1193        let nonexistent_nullifier = 30_u32.to_biguint().unwrap();
1194        // `*_existent` methods should fail.
1195        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        // `*_nonexistent` methods should succeed.
1206        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        // Try finding a low element of existent nullifier 40.
1226        // `_existent` methods should succeed.
1227        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        // `*_nonexistent` methods should fail.
1243        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}