@aztec/merkle-tree 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/.tsbuildinfo +1 -0
  2. package/dest/index.d.ts +12 -0
  3. package/dest/index.d.ts.map +1 -0
  4. package/dest/index.js +12 -0
  5. package/dest/interfaces/append_only_tree.d.ts +13 -0
  6. package/dest/interfaces/append_only_tree.d.ts.map +1 -0
  7. package/dest/interfaces/append_only_tree.js +2 -0
  8. package/dest/interfaces/indexed_tree.d.ts +57 -0
  9. package/dest/interfaces/indexed_tree.d.ts.map +1 -0
  10. package/dest/interfaces/indexed_tree.js +2 -0
  11. package/dest/interfaces/merkle_tree.d.ts +47 -0
  12. package/dest/interfaces/merkle_tree.d.ts.map +1 -0
  13. package/dest/interfaces/merkle_tree.js +2 -0
  14. package/dest/interfaces/update_only_tree.d.ts +15 -0
  15. package/dest/interfaces/update_only_tree.d.ts.map +1 -0
  16. package/dest/interfaces/update_only_tree.js +2 -0
  17. package/dest/load_tree.d.ts +13 -0
  18. package/dest/load_tree.d.ts.map +1 -0
  19. package/dest/load_tree.js +17 -0
  20. package/dest/new_tree.d.ts +15 -0
  21. package/dest/new_tree.d.ts.map +1 -0
  22. package/dest/new_tree.js +16 -0
  23. package/dest/pedersen.d.ts +15 -0
  24. package/dest/pedersen.d.ts.map +1 -0
  25. package/dest/pedersen.js +22 -0
  26. package/dest/sparse_tree/sparse_tree.d.ts +15 -0
  27. package/dest/sparse_tree/sparse_tree.d.ts.map +1 -0
  28. package/dest/sparse_tree/sparse_tree.js +31 -0
  29. package/dest/sparse_tree/sparse_tree.test.d.ts +2 -0
  30. package/dest/sparse_tree/sparse_tree.test.d.ts.map +1 -0
  31. package/dest/sparse_tree/sparse_tree.test.js +133 -0
  32. package/dest/standard_indexed_tree/standard_indexed_tree.d.ts +245 -0
  33. package/dest/standard_indexed_tree/standard_indexed_tree.d.ts.map +1 -0
  34. package/dest/standard_indexed_tree/standard_indexed_tree.js +488 -0
  35. package/dest/standard_indexed_tree/test/standard_indexed_tree.test.d.ts +2 -0
  36. package/dest/standard_indexed_tree/test/standard_indexed_tree.test.d.ts.map +1 -0
  37. package/dest/standard_indexed_tree/test/standard_indexed_tree.test.js +336 -0
  38. package/dest/standard_indexed_tree/test/standard_indexed_tree_with_append.d.ts +23 -0
  39. package/dest/standard_indexed_tree/test/standard_indexed_tree_with_append.d.ts.map +1 -0
  40. package/dest/standard_indexed_tree/test/standard_indexed_tree_with_append.js +59 -0
  41. package/dest/standard_tree/standard_tree.d.ts +15 -0
  42. package/dest/standard_tree/standard_tree.d.ts.map +1 -0
  43. package/dest/standard_tree/standard_tree.js +15 -0
  44. package/dest/standard_tree/standard_tree.test.d.ts +2 -0
  45. package/dest/standard_tree/standard_tree.test.d.ts.map +1 -0
  46. package/dest/standard_tree/standard_tree.test.js +58 -0
  47. package/dest/test/standard_based_test_suite.d.ts +6 -0
  48. package/dest/test/standard_based_test_suite.d.ts.map +1 -0
  49. package/dest/test/standard_based_test_suite.js +87 -0
  50. package/dest/test/test_suite.d.ts +6 -0
  51. package/dest/test/test_suite.d.ts.map +1 -0
  52. package/dest/test/test_suite.js +119 -0
  53. package/dest/test/utils/append_leaves.d.ts +5 -0
  54. package/dest/test/utils/append_leaves.d.ts.map +1 -0
  55. package/dest/test/utils/append_leaves.js +14 -0
  56. package/dest/test/utils/create_mem_down.d.ts +3 -0
  57. package/dest/test/utils/create_mem_down.d.ts.map +1 -0
  58. package/dest/test/utils/create_mem_down.js +3 -0
  59. package/dest/test/utils/pedersen_with_counter.d.ts +24 -0
  60. package/dest/test/utils/pedersen_with_counter.d.ts.map +1 -0
  61. package/dest/test/utils/pedersen_with_counter.js +31 -0
  62. package/dest/tree_base.d.ts +130 -0
  63. package/dest/tree_base.d.ts.map +1 -0
  64. package/dest/tree_base.js +257 -0
  65. package/package.json +4 -4
  66. package/Dockerfile +0 -15
@@ -0,0 +1,31 @@
1
+ import { INITIAL_LEAF, TreeBase } from '../tree_base.js';
2
+ /**
3
+ * A Merkle tree implementation that uses a LevelDB database to store the tree.
4
+ */
5
+ export class SparseTree extends TreeBase {
6
+ /**
7
+ * Updates a leaf in the tree.
8
+ * @param leaf - New contents of the leaf.
9
+ * @param index - Index of the leaf to be updated.
10
+ */
11
+ async updateLeaf(leaf, index) {
12
+ if (index > this.maxIndex) {
13
+ throw Error(`Index out of bounds. Index ${index}, max index: ${this.maxIndex}.`);
14
+ }
15
+ const insertingZeroElement = leaf.equals(INITIAL_LEAF);
16
+ const originallyZeroElement = (await this.getLeafValue(index, true))?.equals(INITIAL_LEAF);
17
+ if (insertingZeroElement && originallyZeroElement) {
18
+ return;
19
+ }
20
+ await this.addLeafToCacheAndHashToRoot(leaf, index);
21
+ if (insertingZeroElement) {
22
+ // Deleting element (originally non-zero and new value is zero)
23
+ this.cachedSize = (this.cachedSize ?? this.size) - 1n;
24
+ }
25
+ else if (originallyZeroElement) {
26
+ // Inserting new element (originally zero and new value is non-zero)
27
+ this.cachedSize = (this.cachedSize ?? this.size) + 1n;
28
+ }
29
+ }
30
+ }
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhcnNlX3RyZWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3BhcnNlX3RyZWUvc3BhcnNlX3RyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV6RDs7R0FFRztBQUNILE1BQU0sT0FBTyxVQUFXLFNBQVEsUUFBUTtJQUN0Qzs7OztPQUlHO0lBQ0ksS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFZLEVBQUUsS0FBYTtRQUNqRCxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ3pCLE1BQU0sS0FBSyxDQUFDLDhCQUE4QixLQUFLLGdCQUFnQixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztTQUNsRjtRQUVELE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN2RCxNQUFNLHFCQUFxQixHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMzRixJQUFJLG9CQUFvQixJQUFJLHFCQUFxQixFQUFFO1lBQ2pELE9BQU87U0FDUjtRQUNELE1BQU0sSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNwRCxJQUFJLG9CQUFvQixFQUFFO1lBQ3hCLCtEQUErRDtZQUMvRCxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1NBQ3ZEO2FBQU0sSUFBSSxxQkFBcUIsRUFBRTtZQUNoQyxvRUFBb0U7WUFDcEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUN2RDtJQUNILENBQUM7Q0FDRiJ9
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sparse_tree.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparse_tree.test.d.ts","sourceRoot":"","sources":["../../src/sparse_tree/sparse_tree.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,133 @@
1
+ import { CircuitsWasm } from '@aztec/circuits.js';
2
+ import { createDebugLogger } from '@aztec/foundation/log';
3
+ import { SiblingPath } from '@aztec/types';
4
+ import { randomBytes } from 'crypto';
5
+ import { default as levelup } from 'levelup';
6
+ import { INITIAL_LEAF, newTree } from '../index.js';
7
+ import { loadTree } from '../load_tree.js';
8
+ import { Pedersen } from '../pedersen.js';
9
+ import { standardBasedTreeTestSuite } from '../test/standard_based_test_suite.js';
10
+ import { treeTestSuite } from '../test/test_suite.js';
11
+ import { createMemDown } from '../test/utils/create_mem_down.js';
12
+ import { SparseTree } from './sparse_tree.js';
13
+ const log = createDebugLogger('aztec:sparse_tree_test');
14
+ const createDb = async (levelUp, hasher, name, depth) => {
15
+ return await newTree(SparseTree, levelUp, hasher, name, depth);
16
+ };
17
+ const createFromName = async (levelUp, hasher, name) => {
18
+ return await loadTree(SparseTree, levelUp, hasher, name);
19
+ };
20
+ const TEST_TREE_DEPTH = 3;
21
+ treeTestSuite('SparseTree', createDb, createFromName);
22
+ standardBasedTreeTestSuite('SparseTree', createDb);
23
+ describe('SparseTreeSpecific', () => {
24
+ let wasm;
25
+ let pedersen;
26
+ beforeEach(async () => {
27
+ wasm = await CircuitsWasm.get();
28
+ pedersen = new Pedersen(wasm);
29
+ });
30
+ it('throws when index is bigger than (2^DEPTH - 1) ', async () => {
31
+ const db = levelup(createMemDown());
32
+ const depth = 32;
33
+ const tree = await createDb(db, pedersen, 'test', depth);
34
+ const index = 2n ** BigInt(depth);
35
+ await expect(tree.updateLeaf(Buffer.alloc(32), index)).rejects.toThrow();
36
+ });
37
+ it('updating non-empty leaf does not change tree size', async () => {
38
+ const depth = 32;
39
+ const maxIndex = 2 ** depth - 1;
40
+ const db = levelup(createMemDown());
41
+ const tree = await createDb(db, pedersen, 'test', depth);
42
+ const randomIndex = BigInt(Math.floor(Math.random() * maxIndex));
43
+ expect(tree.getNumLeaves(false)).toEqual(0n);
44
+ // Insert a leaf
45
+ await tree.updateLeaf(randomBytes(32), randomIndex);
46
+ expect(tree.getNumLeaves(true)).toEqual(1n);
47
+ // Update a leaf
48
+ await tree.updateLeaf(randomBytes(32), randomIndex);
49
+ expect(tree.getNumLeaves(true)).toEqual(1n);
50
+ });
51
+ it('deleting leaf decrements tree size', async () => {
52
+ const depth = 254;
53
+ const maxIndex = 2 ** depth - 1;
54
+ const db = levelup(createMemDown());
55
+ const tree = await createDb(db, pedersen, 'test', depth);
56
+ const randomIndex = BigInt(Math.floor(Math.random() * maxIndex));
57
+ expect(tree.getNumLeaves(false)).toEqual(0n);
58
+ // Insert a leaf
59
+ await tree.updateLeaf(randomBytes(32), randomIndex);
60
+ expect(tree.getNumLeaves(true)).toEqual(1n);
61
+ // Delete a leaf
62
+ await tree.updateLeaf(INITIAL_LEAF, randomIndex);
63
+ expect(tree.getNumLeaves(true)).toEqual(0n);
64
+ });
65
+ it('should have correct root and sibling path after in a "non-append-only" way', async () => {
66
+ const db = levelup(createMemDown());
67
+ const tree = await createDb(db, pedersen, 'test', 3);
68
+ const level2ZeroHash = pedersen.compress(INITIAL_LEAF, INITIAL_LEAF);
69
+ const level1ZeroHash = pedersen.compress(level2ZeroHash, level2ZeroHash);
70
+ expect(tree.getNumLeaves(false)).toEqual(0n);
71
+ expect(tree.getRoot(false)).toEqual(pedersen.compress(level1ZeroHash, level1ZeroHash));
72
+ // Insert leaf at index 3
73
+ let level1LeftHash;
74
+ const leafAtIndex3 = randomBytes(32);
75
+ {
76
+ await tree.updateLeaf(leafAtIndex3, 3n);
77
+ expect(tree.getNumLeaves(true)).toEqual(1n);
78
+ const level2Hash = pedersen.compress(INITIAL_LEAF, leafAtIndex3);
79
+ level1LeftHash = pedersen.compress(level2ZeroHash, level2Hash);
80
+ const root = pedersen.compress(level1LeftHash, level1ZeroHash);
81
+ expect(tree.getRoot(true)).toEqual(root);
82
+ expect(await tree.getSiblingPath(3n, true)).toEqual(new SiblingPath(TEST_TREE_DEPTH, [INITIAL_LEAF, level2ZeroHash, level1ZeroHash]));
83
+ }
84
+ // Insert leaf at index 6
85
+ let level1RightHash;
86
+ {
87
+ const leafAtIndex6 = randomBytes(32);
88
+ await tree.updateLeaf(leafAtIndex6, 6n);
89
+ expect(tree.getNumLeaves(true)).toEqual(2n);
90
+ const level2Hash = pedersen.compress(leafAtIndex6, INITIAL_LEAF);
91
+ level1RightHash = pedersen.compress(level2ZeroHash, level2Hash);
92
+ const root = pedersen.compress(level1LeftHash, level1RightHash);
93
+ expect(tree.getRoot(true)).toEqual(root);
94
+ expect(await tree.getSiblingPath(6n, true)).toEqual(new SiblingPath(TEST_TREE_DEPTH, [INITIAL_LEAF, level2ZeroHash, level1LeftHash]));
95
+ }
96
+ // Insert leaf at index 2
97
+ const leafAtIndex2 = randomBytes(32);
98
+ {
99
+ await tree.updateLeaf(leafAtIndex2, 2n);
100
+ expect(tree.getNumLeaves(true)).toEqual(3n);
101
+ const level2Hash = pedersen.compress(leafAtIndex2, leafAtIndex3);
102
+ level1LeftHash = pedersen.compress(level2ZeroHash, level2Hash);
103
+ const root = pedersen.compress(level1LeftHash, level1RightHash);
104
+ expect(tree.getRoot(true)).toEqual(root);
105
+ expect(await tree.getSiblingPath(2n, true)).toEqual(new SiblingPath(TEST_TREE_DEPTH, [leafAtIndex3, level2ZeroHash, level1RightHash]));
106
+ }
107
+ // Updating leaf at index 3
108
+ {
109
+ const updatedLeafAtIndex3 = randomBytes(32);
110
+ await tree.updateLeaf(updatedLeafAtIndex3, 3n);
111
+ expect(tree.getNumLeaves(true)).toEqual(3n);
112
+ const level2Hash = pedersen.compress(leafAtIndex2, updatedLeafAtIndex3);
113
+ level1LeftHash = pedersen.compress(level2ZeroHash, level2Hash);
114
+ const root = pedersen.compress(level1LeftHash, level1RightHash);
115
+ expect(tree.getRoot(true)).toEqual(root);
116
+ expect(await tree.getSiblingPath(3n, true)).toEqual(new SiblingPath(TEST_TREE_DEPTH, [leafAtIndex2, level2ZeroHash, level1RightHash]));
117
+ }
118
+ });
119
+ // This one is a performance measurement and is enabled only to check regression in performance.
120
+ it.skip('measures time of inserting 1000 leaves at random positions for depth 254', async () => {
121
+ const depth = 254;
122
+ const maxIndex = 2 ** depth - 1;
123
+ const db = levelup(createMemDown());
124
+ const tree = await createDb(db, pedersen, 'test', depth);
125
+ const leaves = Array.from({ length: 1000 }).map(() => randomBytes(32));
126
+ const indices = Array.from({ length: 1000 }).map(() => BigInt(Math.floor(Math.random() * maxIndex)));
127
+ const start = Date.now();
128
+ await Promise.all(leaves.map((leaf, i) => tree.updateLeaf(leaf, indices[i])));
129
+ const end = Date.now();
130
+ log(`Inserting 1000 leaves at random positions for depth 254 took ${end - start}ms`);
131
+ }, 300000);
132
+ });
133
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhcnNlX3RyZWUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zcGFyc2VfdHJlZS9zcGFyc2VfdHJlZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRCxPQUFPLEVBQVUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRW5ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDckMsT0FBTyxFQUFFLE9BQU8sSUFBSSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFcEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNsRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU5QyxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBRXhELE1BQU0sUUFBUSxHQUFHLEtBQUssRUFDcEIsT0FBd0IsRUFDeEIsTUFBYyxFQUNkLElBQVksRUFDWixLQUFhLEVBQ1ksRUFBRTtJQUMzQixPQUFPLE1BQU0sT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNqRSxDQUFDLENBQUM7QUFFRixN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QUFDLENBQUM7UUFFaEMsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDcEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFekQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFN0MsZ0JBQWdCO1FBQ2hCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDcEQsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFNUMsZ0JBQWdCO1FBQ2hCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDakQsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNEVBQTRFLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDMUYsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDcEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFckQsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDckUs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
@@ -0,0 +1,245 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import { SiblingPath } from '@aztec/types';
3
+ import { IndexedTree, LeafData } from '../interfaces/indexed_tree.js';
4
+ import { TreeBase } from '../tree_base.js';
5
+ /**
6
+ * All of the data to be return during batch insertion.
7
+ */
8
+ export interface LowLeafWitnessData<N extends number> {
9
+ /**
10
+ * Preimage of the low nullifier that proves non membership.
11
+ */
12
+ leafData: LeafData;
13
+ /**
14
+ * Sibling path to prove membership of low nullifier.
15
+ */
16
+ siblingPath: SiblingPath<N>;
17
+ /**
18
+ * The index of low nullifier.
19
+ */
20
+ index: bigint;
21
+ }
22
+ /**
23
+ * Indexed merkle tree.
24
+ */
25
+ export declare class StandardIndexedTree extends TreeBase implements IndexedTree {
26
+ protected leaves: LeafData[];
27
+ protected cachedLeaves: {
28
+ [key: number]: LeafData;
29
+ };
30
+ /**
31
+ * Appends the given leaves to the tree.
32
+ * @param _leaves - The leaves to append.
33
+ * @returns Empty promise.
34
+ * @remarks Use batchInsert method instead.
35
+ */
36
+ appendLeaves(_leaves: Buffer[]): Promise<void>;
37
+ /**
38
+ * Commits the changes to the database.
39
+ * @returns Empty promise.
40
+ */
41
+ commit(): Promise<void>;
42
+ /**
43
+ * Rolls back the not-yet-committed changes.
44
+ * @returns Empty promise.
45
+ */
46
+ rollback(): Promise<void>;
47
+ /**
48
+ * Gets the value of the leaf at the given index.
49
+ * @param index - Index of the leaf of which to obtain the value.
50
+ * @param includeUncommitted - Indicates whether to include uncommitted leaves in the computation.
51
+ * @returns The value of the leaf at the given index or undefined if the leaf is empty.
52
+ */
53
+ getLeafValue(index: bigint, includeUncommitted: boolean): Promise<Buffer | undefined>;
54
+ /**
55
+ * Finds the index of the largest leaf whose value is less than or equal to the provided value.
56
+ * @param newValue - The new value to be inserted into the tree.
57
+ * @param includeUncommitted - If true, the uncommitted changes are included in the search.
58
+ * @returns The found leaf index and a flag indicating if the corresponding leaf's value is equal to `newValue`.
59
+ */
60
+ findIndexOfPreviousValue(newValue: bigint, includeUncommitted: boolean): {
61
+ /**
62
+ * The index of the found leaf.
63
+ */
64
+ index: number;
65
+ /**
66
+ * A flag indicating if the corresponding leaf's value is equal to `newValue`.
67
+ */
68
+ alreadyPresent: boolean;
69
+ };
70
+ /**
71
+ * Gets the latest LeafData copy.
72
+ * @param index - Index of the leaf of which to obtain the LeafData copy.
73
+ * @param includeUncommitted - If true, the uncommitted changes are included in the search.
74
+ * @returns A copy of the leaf data at the given index or undefined if the leaf was not found.
75
+ */
76
+ getLatestLeafDataCopy(index: number, includeUncommitted: boolean): LeafData | undefined;
77
+ /**
78
+ * Finds the index of the minimum value in an array.
79
+ * @param values - The collection of values to be searched.
80
+ * @returns The index of the minimum value in the array.
81
+ */
82
+ private findMinIndex;
83
+ /**
84
+ * Initializes the tree.
85
+ * @param prefilledSize - A number of leaves that are prefilled with values.
86
+ * @returns Empty promise.
87
+ *
88
+ * @remarks Explanation of pre-filling:
89
+ * There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
90
+ * prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
91
+ * leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
92
+ *
93
+ * Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
94
+ * 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
95
+ * more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
96
+ */
97
+ init(prefilledSize: number): Promise<void>;
98
+ /**
99
+ * Loads Merkle tree data from a database and assigns them to this object.
100
+ */
101
+ initFromDb(): Promise<void>;
102
+ /**
103
+ * Commits all the leaves to the database and removes them from a cache.
104
+ */
105
+ private commitLeaves;
106
+ /**
107
+ * Clears the cache.
108
+ */
109
+ private clearCachedLeaves;
110
+ /**
111
+ * Updates a leaf in the tree.
112
+ * @param leaf - New contents of the leaf.
113
+ * @param index - Index of the leaf to be updated.
114
+ */
115
+ protected updateLeaf(leaf: LeafData, index: bigint): Promise<void>;
116
+ /**
117
+ *
118
+ * Each base rollup needs to provide non membership / inclusion proofs for each of the nullifier.
119
+ * This method will return membership proofs and perform partial node updates that will
120
+ * allow the circuit to incrementally update the tree and perform a batch insertion.
121
+ *
122
+ * This offers massive circuit performance savings over doing incremental insertions.
123
+ *
124
+ * A description of the algorithm can be found here: https://colab.research.google.com/drive/1A0gizduSi4FIiIJZ8OylwIpO9-OTqV-R
125
+ *
126
+ * WARNING: This function has side effects, it will insert values into the tree.
127
+ *
128
+ * Assumptions:
129
+ * 1. There are 8 nullifiers provided and they are either unique or empty. (denoted as 0)
130
+ * 2. If kc 0 has 1 nullifier, and kc 1 has 3 nullifiers the layout will assume to be the sparse
131
+ * nullifier layout: [kc0-0, 0, 0, 0, kc1-0, kc1-1, kc1-2, 0]
132
+ *
133
+ * Algorithm overview
134
+ *
135
+ * In general, if we want to batch insert items, we first need to update their low nullifier to point to them,
136
+ * then batch insert all of the values at once in the final step.
137
+ * To update a low nullifier, we provide an insertion proof that the low nullifier currently exists to the
138
+ * circuit, then update the low nullifier.
139
+ * Updating this low nullifier will in turn change the root of the tree. Therefore future low nullifier insertion proofs
140
+ * must be given against this new root.
141
+ * As a result, each low nullifier membership proof will be provided against an intermediate tree state, each with differing
142
+ * roots.
143
+ *
144
+ * This become tricky when two items that are being batch inserted need to update the same low nullifier, or need to use
145
+ * a value that is part of the same batch insertion as their low nullifier. In this case a zero low nullifier path is given
146
+ * to the circuit, and it must determine from the set of batch inserted values if the insertion is valid.
147
+ *
148
+ * The following example will illustrate attempting to insert 2,3,20,19 into a tree already containing 0,5,10,15
149
+ *
150
+ * The example will explore two cases. In each case the values low nullifier will exist within the batch insertion,
151
+ * One where the low nullifier comes before the item in the set (2,3), and one where it comes after (20,19).
152
+ *
153
+ * The original tree: Pending insertion subtree
154
+ *
155
+ * index 0 2 3 4 - - - -
156
+ * ------------------------------------- ----------------------------
157
+ * val 0 5 10 15 - - - -
158
+ * nextIdx 1 2 3 0 - - - -
159
+ * nextVal 5 10 15 0 - - - -
160
+ *
161
+ *
162
+ * Inserting 2: (happy path)
163
+ * 1. Find the low nullifier (0) - provide inclusion proof
164
+ * 2. Update its pointers
165
+ * 3. Insert 2 into the pending subtree
166
+ *
167
+ * index 0 2 3 4 5 - - -
168
+ * ------------------------------------- ----------------------------
169
+ * val 0 5 10 15 2 - - -
170
+ * nextIdx 5 2 3 0 2 - - -
171
+ * nextVal 2 10 15 0 5 - - -
172
+ *
173
+ * Inserting 3: The low nullifier exists within the insertion current subtree
174
+ * 1. When looking for the low nullifier for 3, we will receive 0 again as we have not inserted 2 into the main tree
175
+ * This is problematic, as we cannot use either 0 or 2 as our inclusion proof.
176
+ * Why cant we?
177
+ * - Index 0 has a val 0 and nextVal of 2. This is NOT enough to prove non inclusion of 2.
178
+ * - Our existing tree is in a state where we cannot prove non inclusion of 3.
179
+ * We do not provide a non inclusion proof to out circuit, but prompt it to look within the insertion subtree.
180
+ * 2. Update pending insertion subtree
181
+ * 3. Insert 3 into pending subtree
182
+ *
183
+ * (no inclusion proof provided)
184
+ * index 0 2 3 4 5 6 - -
185
+ * ------------------------------------- ----------------------------
186
+ * val 0 5 10 15 2 3 - -
187
+ * nextIdx 5 2 3 0 6 2 - -
188
+ * nextVal 2 10 15 0 3 5 - -
189
+ *
190
+ * Inserting 20: (happy path)
191
+ * 1. Find the low nullifier (15) - provide inclusion proof
192
+ * 2. Update its pointers
193
+ * 3. Insert 20 into the pending subtree
194
+ *
195
+ * index 0 2 3 4 5 6 7 -
196
+ * ------------------------------------- ----------------------------
197
+ * val 0 5 10 15 2 3 20 -
198
+ * nextIdx 5 2 3 7 6 2 0 -
199
+ * nextVal 2 10 15 20 3 5 0 -
200
+ *
201
+ * Inserting 19:
202
+ * 1. In this case we can find a low nullifier, but we are updating a low nullifier that has already been updated
203
+ * We can provide an inclusion proof of this intermediate tree state.
204
+ * 2. Update its pointers
205
+ * 3. Insert 19 into the pending subtree
206
+ *
207
+ * index 0 2 3 4 5 6 7 8
208
+ * ------------------------------------- ----------------------------
209
+ * val 0 5 10 15 2 3 20 19
210
+ * nextIdx 5 2 3 8 6 2 0 7
211
+ * nextVal 2 10 15 19 3 5 0 20
212
+ *
213
+ * Perform subtree insertion
214
+ *
215
+ * index 0 2 3 4 5 6 7 8
216
+ * ---------------------------------------------------------------------
217
+ * val 0 5 10 15 2 3 20 19
218
+ * nextIdx 5 2 3 8 6 2 0 7
219
+ * nextVal 2 10 15 19 3 5 0 20
220
+ *
221
+ * TODO: this implementation will change once the zero value is changed from h(0,0,0). Changes incoming over the next sprint
222
+ * @param leaves - Values to insert into the tree.
223
+ * @param subtreeHeight - Height of the subtree.
224
+ * @returns The data for the leaves to be updated when inserting the new ones.
225
+ */
226
+ batchInsert<TreeHeight extends number, SubtreeHeight extends number, SubtreeSiblingPathHeight extends number>(leaves: Buffer[], subtreeHeight: SubtreeHeight): Promise<[LowLeafWitnessData<TreeHeight>[], SiblingPath<SubtreeSiblingPathHeight>] | [undefined, SiblingPath<SubtreeSiblingPathHeight>]>;
227
+ getSubtreeSiblingPath<SubtreeHeight extends number, SubtreeSiblingPathHeight extends number>(subtreeHeight: SubtreeHeight, includeUncommitted: boolean): Promise<SiblingPath<SubtreeSiblingPathHeight>>;
228
+ /**
229
+ * Encodes leaves and appends them to a tree.
230
+ * @param leaves - Leaves to encode.
231
+ * @param hash0Leaf - Indicates whether 0 value leaf should be hashed. See {@link encodeLeaf}.
232
+ * @returns Empty promise
233
+ */
234
+ private encodeAndAppendLeaves;
235
+ /**
236
+ * Encode a leaf into a buffer.
237
+ * @param leaf - Leaf to encode.
238
+ * @param hash0Leaf - Indicates whether 0 value leaf should be hashed. Not hashing 0 value can represent a forced
239
+ * null leaf insertion. Detecting this case by checking for 0 value is safe as in the case of
240
+ * nullifier it is improbable that a valid nullifier would be 0.
241
+ * @returns Leaf encoded in a buffer.
242
+ */
243
+ private encodeLeaf;
244
+ }
245
+ //# sourceMappingURL=standard_indexed_tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard_indexed_tree.d.ts","sourceRoot":"","sources":["../../src/standard_indexed_tree/standard_indexed_tree.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAc3C;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM;IAClD;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;IACnB;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAkCD;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,QAAS,YAAW,WAAW;IACtE,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAM;IAClC,SAAS,CAAC,YAAY,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,CAAM;IAEzD;;;;;OAKG;IACI,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD;;;OAGG;IACU,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAKpC;;;OAGG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtC;;;;;OAKG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAM5F;;;;;OAKG;IACH,wBAAwB,CACtB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,OAAO,GAC1B;QACD;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,cAAc,EAAE,OAAO,CAAC;KACzB;IAuBD;;;;;OAKG;IACI,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS;IAW9F;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAapB;;;;;;;;;;;;;OAaG;IACU,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BvD;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BxC;;OAEG;YACW,YAAY;IAY1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;;;OAIG;cACa,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM;IAgBxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6GG;IACU,WAAW,CACtB,UAAU,SAAS,MAAM,EACzB,aAAa,SAAS,MAAM,EAC5B,wBAAwB,SAAS,MAAM,EAEvC,MAAM,EAAE,MAAM,EAAE,EAChB,aAAa,EAAE,aAAa,GAC3B,OAAO,CACN,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,wBAAwB,CAAC,CAAC,GACzE,CAAC,SAAS,EAAE,WAAW,CAAC,wBAAwB,CAAC,CAAC,CACrD;IA8GK,qBAAqB,CAAC,aAAa,SAAS,MAAM,EAAE,wBAAwB,SAAS,MAAM,EAC/F,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,OAAO,GAC1B,OAAO,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;IAQjD;;;;;OAKG;YACW,qBAAqB;IAWnC;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU;CAWnB"}