Optional
root: FieldPrivate
cachedProtected
Optional
cachedProtected
dbProtected
hasherProtected
Readonly
maxProtected
sizePrivate
_updateProtected
addPrivate
appendEach base rollup needs to provide non membership / inclusion proofs for each of the nullifier. This method will return membership proofs and perform partial node updates that will allow the circuit to incrementally update the tree and perform a batch insertion.
This offers massive circuit performance savings over doing incremental insertions.
A description of the algorithm can be found here: https://colab.research.google.com/drive/1A0gizduSi4FIiIJZ8OylwIpO9-OTqV-R
WARNING: This function has side effects, it will insert values into the tree.
Assumptions:
Algorithm overview
In general, if we want to batch insert items, we first to update their low nullifier to point to them, then batch insert all of the values as at once in the final step. To update a low nullifier, we provide an insertion proof that the low nullifier currently exists to the circuit, then update the low nullifier. Updating this low nullifier will in turn change the root of the tree. Therefore future low nullifier insertion proofs must be given against this new root. As a result, each low nullifier membership proof will be provided against an intermediate tree state, each with differing roots.
This become tricky when two items that are being batch inserted need to update the same low nullifier, or need to use a value that is part of the same batch insertion as their low nullifier. In this case a zero low nullifier path is given to the circuit, and it must determine from the set of batch inserted values if the insertion is valid.
The following example will illustrate attempting to insert 2,3,20,19 into a tree already containing 0,5,10,15
The example will explore two cases. In each case the values low nullifier will exist within the batch insertion, One where the low nullifier comes before the item in the set (2,3), and one where it comes after (20,19).
The original tree: Pending insertion subtree
index 0 2 3 4 - - - -
val 0 5 10 15 - - - - nextIdx 1 2 3 0 - - - - nextVal 5 10 15 0 - - - -
Inserting 2: (happy path)
index 0 2 3 4 5 - - -
val 0 5 10 15 2 - - - nextIdx 5 2 3 0 2 - - - nextVal 2 10 15 0 5 - - -
Inserting 3: The low nullifier exists within the insertion current subtree
(no inclusion proof provided) index 0 2 3 4 5 6 - -
val 0 5 10 15 2 3 - - nextIdx 5 2 3 0 6 2 - - nextVal 2 10 15 0 3 5 - -
Inserting 20: (happy path)
index 0 2 3 4 5 6 7 -
val 0 5 10 15 2 3 20 - nextIdx 5 2 3 7 6 2 0 - nextVal 2 10 15 20 3 5 0 -
Inserting 19:
index 0 2 3 4 5 6 7 8
val 0 5 10 15 2 3 20 19 nextIdx 5 2 3 8 6 2 0 7 nextVal 2 10 15 19 3 5 0 20
Perform subtree insertion
val 0 5 10 15 2 3 20 19 nextIdx 5 2 3 8 6 2 0 7 nextVal 2 10 15 19 3 5 0 20
TODO: this implementation will change once the zero value is changed from h(0,0,0). Changes incoming over the next sprint
Values to insert into the tree.
Height of the tree.
Height of the subtree.
The data for the leaves to be updated when inserting the new ones.
Private
clearPrivate
commitFinds the index of the largest leaf whose value is less than or equal to the provided value.
The new value to be inserted into the tree.
If true, the uncommitted changes are included in the search.
The found leaf index and a flag indicating if the corresponding leaf's value is equal to newValue
.
A flag indicating if the corresponding leaf's value is equal to newValue
.
The index of the found leaf.
Private
find!! MUST call 'findIndexOfPreviousValue(*)' to find the 'index' FIRST, and later call this method. By coldStar1993#6265 !! Gets the latest LeafData copy.
Index of the leaf of which to obtain the LeafData copy.
If true, the uncommitted changes are included in the search.
A copy of the leaf data at the given index or undefined if the leaf was not found.
!! MUST call 'findIndexOfPreviousValue(*)' to find the 'index' FIRST, and later call this method. By coldStar1993#6265 !! Gets the value of the leaf at the given index.
Index of the leaf of which to obtain the value.
Indicates whether to include uncommitted leaves in the computation.
The value of the leaf at the given index or undefined if the leaf is empty.
obtain the current pure leaf value on underlying (Standard) merkle tree. it maybe the default value: Field('0') if 'index' beyond 'getNumLeaves(includeUncommitted)', or else the hash of coorresponding leafData.
Returns a sibling path for the element at the given index.
The index of the element.
Indicates whether to get a sibling path incorporating uncommitted changes.
A sibling path for the element at the given index. Note: The sibling path is an array of sibling hashes, with the lowest hash (leaf hash) first, and the highest hash last.
Exposes the underlying tree's update leaf method.
The hash to set at the leaf.
The index of the element.
Exposes the underlying tree's update leaf method.
The hash to set at the leaf.
The index of the element.
Protected
write
Indexed merkle tree.