Struct IndexedMerkleTree

Source
#[repr(C)]
pub struct IndexedMerkleTree<H, I, const HEIGHT: usize, const NET_HEIGHT: usize>{ pub merkle_tree: ConcurrentMerkleTree<H, HEIGHT>, pub indexed_changelog: CyclicBoundedVec<IndexedChangelogEntry<I, NET_HEIGHT>>, /* private fields */ }

Fields§

§merkle_tree: ConcurrentMerkleTree<H, HEIGHT>§indexed_changelog: CyclicBoundedVec<IndexedChangelogEntry<I, NET_HEIGHT>>

Implementations§

Source§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

Source

pub fn non_dyn_fields_size() -> usize

Size of the struct without dynamically sized fields (BoundedVec, CyclicBoundedVec).

Source

pub fn size_in_account( height: usize, changelog_size: usize, roots_size: usize, canopy_depth: usize, indexed_changelog_size: usize, ) -> usize

Source

pub fn new( height: usize, changelog_size: usize, roots_size: usize, canopy_depth: usize, indexed_changelog_size: usize, ) -> Result<Self, ConcurrentMerkleTreeError>

Source

pub fn init(&mut self) -> Result<(), IndexedMerkleTreeError>

Source

pub fn add_highest_element(&mut self) -> Result<(), IndexedMerkleTreeError>

Add the hightest element with a maximum value allowed by the prime field.

Initializing an indexed Merkle tree not only with the lowest element (mandatory for the IMT algorithm to work), but also the highest element, makes non-inclusion proofs easier - there is no special case needed for the first insertion.

However, it comes with a tradeoff - the space available in the tree becomes lower by 1.

Source

pub fn indexed_changelog_index(&self) -> usize

Source

pub fn validate_proof( &self, leaf: &[u8; 32], leaf_index: usize, proof: &BoundedVec<[u8; 32]>, ) -> Result<(), IndexedMerkleTreeError>

Checks whether the given Merkle proof for the given node (with index i) is valid. The proof is valid when computing parent node hashes using the whole path of the proof gives the same result as the given root.

Source

pub fn patch_elements_and_proof( &mut self, indexed_changelog_index: usize, changelog_index: &mut usize, new_element: &mut IndexedElement<I>, low_element: &mut IndexedElement<I>, low_element_next_value: &mut BigUint, low_leaf_proof: &mut BoundedVec<[u8; 32]>, ) -> Result<(), IndexedMerkleTreeError>

Iterates over indexed changelog and every time an entry corresponding to the provided low_element is found, it patches:

  • Changelog index - indexed changelog entries contain corresponding changelog indices.
  • New element - changes might impact the next_index field, which in such case is updated.
  • Low element - it might completely change if a change introduced an element in our range.
  • Merkle proof.
Source

pub fn update( &mut self, changelog_index: usize, indexed_changelog_index: usize, new_element_value: BigUint, low_element: IndexedElement<I>, low_element_next_value: BigUint, low_leaf_proof: &mut BoundedVec<[u8; 32]>, ) -> Result<IndexedMerkleTreeUpdate<I>, IndexedMerkleTreeError>

Methods from Deref<Target = ConcurrentMerkleTree<H, HEIGHT>>§

Source

pub fn init(&mut self) -> Result<(), ConcurrentMerkleTreeError>

Initializes the Merkle tree.

Source

pub fn changelog_index(&self) -> usize

Returns the index of the current changelog entry.

Source

pub fn root_index(&self) -> usize

Returns the index of the current root in the tree’s root buffer.

Source

pub fn root(&self) -> [u8; 32]

Returns the current root.

Source

pub fn current_index(&self) -> usize

Source

pub fn next_index(&self) -> usize

Source

pub fn inc_next_index(&mut self) -> Result<(), ConcurrentMerkleTreeError>

Source

pub fn sequence_number(&self) -> usize

Source

pub fn inc_sequence_number(&mut self) -> Result<(), ConcurrentMerkleTreeError>

Source

pub fn rightmost_leaf(&self) -> [u8; 32]

Source

pub fn update_proof_from_canopy( &self, leaf_index: usize, proof: &mut BoundedVec<[u8; 32]>, ) -> Result<(), ConcurrentMerkleTreeError>

Source

pub fn changelog_entries( &self, changelog_index: usize, ) -> Result<Skip<CyclicBoundedVecIterator<'_, ChangelogEntry<HEIGHT>>>, ConcurrentMerkleTreeError>

Returns an iterator with changelog entries newer than the requested changelog_index.

Source

pub fn update_proof_from_changelog( &self, changelog_index: usize, leaf_index: usize, proof: &mut BoundedVec<[u8; 32]>, ) -> Result<(), ConcurrentMerkleTreeError>

Updates the given Merkle proof.

The update is performed by checking whether there are any new changelog entries and whether they contain changes which affect the current proof. To be precise, for each changelog entry, it’s done in the following steps:

  • Check if the changelog entry was directly updating the leaf_index we are trying to update.
    • If no (we check that condition first, since it’s more likely), it means that there is a change affecting the proof, but not the leaf. Check which element from our proof was affected by the change (using the critbit_index method) and update it (copy the new element from the changelog to our updated proof).
    • If yes, it means that the same leaf we want to update was already updated. In such case, updating the proof is not possible.
Source

pub fn validate_proof( &self, leaf: &[u8; 32], leaf_index: usize, proof: &BoundedVec<[u8; 32]>, ) -> Result<(), ConcurrentMerkleTreeError>

Checks whether the given Merkle proof for the given node (with index i) is valid. The proof is valid when computing parent node hashes using the whole path of the proof gives the same result as the given root.

Source

pub fn update( &mut self, changelog_index: usize, old_leaf: &[u8; 32], new_leaf: &[u8; 32], leaf_index: usize, proof: &mut BoundedVec<[u8; 32]>, ) -> Result<(usize, usize), ConcurrentMerkleTreeError>

Replaces the old_leaf under the leaf_index with a new_leaf, using the given proof and changelog_index (pointing to the changelog entry which was the newest at the time of preparing the proof).

Source

pub fn append( &mut self, leaf: &[u8; 32], ) -> Result<(usize, usize), ConcurrentMerkleTreeError>

Appends a new leaf to the tree.

Source

pub fn append_with_proof( &mut self, leaf: &[u8; 32], proof: &mut BoundedVec<[u8; 32]>, ) -> Result<(usize, usize), ConcurrentMerkleTreeError>

Appends a new leaf to the tree. Saves Merkle proof to the provided proof reference.

Source

pub fn append_batch( &mut self, leaves: &[&[u8; 32]], ) -> Result<(usize, usize), ConcurrentMerkleTreeError>

Appends a batch of new leaves to the tree.

Source

pub fn append_batch_with_proofs( &mut self, leaves: &[&[u8; 32]], proofs: &mut [&mut BoundedVec<[u8; 32]>], ) -> Result<(usize, usize), ConcurrentMerkleTreeError>

Appends a batch of new leaves to the tree. Saves Merkle proofs to the provided proofs slice.

Trait Implementations§

Source§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Debug for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Deref for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

Source§

type Target = ConcurrentMerkleTree<H, HEIGHT>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> DerefMut for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> PartialEq for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Freeze for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>
where usize: Sized,

§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> RefUnwindSafe for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> !Send for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> !Sync for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Unpin for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>
where usize: Sized, I: Unpin, H: Unpin,

§

impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> UnwindSafe for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V