@aztec/merkle-tree 0.16.1 → 0.16.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.
- package/dest/index.d.ts +5 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +6 -2
- package/dest/interfaces/append_only_tree.d.ts +2 -1
- package/dest/interfaces/append_only_tree.d.ts.map +1 -1
- package/dest/interfaces/indexed_tree.d.ts +38 -17
- package/dest/interfaces/indexed_tree.d.ts.map +1 -1
- package/dest/interfaces/merkle_tree.d.ts +7 -0
- package/dest/interfaces/merkle_tree.d.ts.map +1 -1
- package/dest/interfaces/update_only_tree.d.ts +3 -3
- package/dest/interfaces/update_only_tree.d.ts.map +1 -1
- package/dest/load_tree.d.ts +2 -1
- package/dest/load_tree.d.ts.map +1 -1
- package/dest/load_tree.js +1 -2
- package/dest/new_tree.d.ts +1 -1
- package/dest/new_tree.d.ts.map +1 -1
- package/dest/new_tree.js +2 -2
- package/dest/snapshots/append_only_snapshot.d.ts +30 -0
- package/dest/snapshots/append_only_snapshot.d.ts.map +1 -0
- package/dest/snapshots/append_only_snapshot.js +200 -0
- package/dest/snapshots/base_full_snapshot.d.ts +50 -0
- package/dest/snapshots/base_full_snapshot.d.ts.map +1 -0
- package/dest/snapshots/base_full_snapshot.js +179 -0
- package/dest/snapshots/full_snapshot.d.ts +22 -0
- package/dest/snapshots/full_snapshot.d.ts.map +1 -0
- package/dest/snapshots/full_snapshot.js +21 -0
- package/dest/snapshots/indexed_tree_snapshot.d.ts +15 -0
- package/dest/snapshots/indexed_tree_snapshot.d.ts.map +1 -0
- package/dest/snapshots/indexed_tree_snapshot.js +75 -0
- package/dest/snapshots/snapshot_builder.d.ts +76 -0
- package/dest/snapshots/snapshot_builder.d.ts.map +1 -0
- package/dest/snapshots/snapshot_builder.js +2 -0
- package/dest/snapshots/snapshot_builder_test_suite.d.ts +5 -0
- package/dest/snapshots/snapshot_builder_test_suite.d.ts.map +1 -0
- package/dest/snapshots/snapshot_builder_test_suite.js +163 -0
- package/dest/sparse_tree/sparse_tree.d.ts +5 -0
- package/dest/sparse_tree/sparse_tree.d.ts.map +1 -1
- package/dest/sparse_tree/sparse_tree.js +18 -1
- package/dest/standard_indexed_tree/standard_indexed_tree.d.ts +111 -81
- package/dest/standard_indexed_tree/standard_indexed_tree.d.ts.map +1 -1
- package/dest/standard_indexed_tree/standard_indexed_tree.js +225 -259
- package/dest/standard_indexed_tree/test/standard_indexed_tree_with_append.d.ts.map +1 -1
- package/dest/standard_indexed_tree/test/standard_indexed_tree_with_append.js +13 -19
- package/dest/standard_tree/standard_tree.d.ts +5 -0
- package/dest/standard_tree/standard_tree.d.ts.map +1 -1
- package/dest/standard_tree/standard_tree.js +24 -1
- package/dest/tree_base.d.ts +9 -4
- package/dest/tree_base.d.ts.map +1 -1
- package/dest/tree_base.js +16 -7
- package/package.json +4 -3
- package/src/index.ts +5 -1
- package/src/interfaces/append_only_tree.ts +2 -1
- package/src/interfaces/indexed_tree.ts +50 -28
- package/src/interfaces/merkle_tree.ts +8 -0
- package/src/interfaces/update_only_tree.ts +3 -4
- package/src/load_tree.ts +2 -2
- package/src/new_tree.ts +2 -2
- package/src/snapshots/append_only_snapshot.ts +243 -0
- package/src/snapshots/base_full_snapshot.ts +232 -0
- package/src/snapshots/full_snapshot.ts +26 -0
- package/src/snapshots/indexed_tree_snapshot.ts +108 -0
- package/src/snapshots/snapshot_builder.ts +84 -0
- package/src/snapshots/snapshot_builder_test_suite.ts +218 -0
- package/src/sparse_tree/sparse_tree.ts +16 -0
- package/src/standard_indexed_tree/standard_indexed_tree.ts +325 -304
- package/src/standard_indexed_tree/test/standard_indexed_tree_with_append.ts +23 -21
- package/src/standard_tree/standard_tree.ts +21 -0
- package/src/tree_base.ts +28 -7
package/dest/index.d.ts
CHANGED
|
@@ -4,9 +4,13 @@ export * from './interfaces/merkle_tree.js';
|
|
|
4
4
|
export * from './interfaces/update_only_tree.js';
|
|
5
5
|
export * from './pedersen.js';
|
|
6
6
|
export * from './sparse_tree/sparse_tree.js';
|
|
7
|
-
export
|
|
7
|
+
export { StandardIndexedTree } from './standard_indexed_tree/standard_indexed_tree.js';
|
|
8
8
|
export * from './standard_tree/standard_tree.js';
|
|
9
9
|
export { INITIAL_LEAF } from './tree_base.js';
|
|
10
10
|
export { newTree } from './new_tree.js';
|
|
11
11
|
export { loadTree } from './load_tree.js';
|
|
12
|
+
export * from './snapshots/snapshot_builder.js';
|
|
13
|
+
export * from './snapshots/full_snapshot.js';
|
|
14
|
+
export * from './snapshots/append_only_snapshot.js';
|
|
15
|
+
export * from './snapshots/indexed_tree_snapshot.js';
|
|
12
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dest/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,eAAe,CAAC;AAC9B,cAAc,8BAA8B,CAAC;AAC7C,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,eAAe,CAAC;AAC9B,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AACvF,cAAc,kCAAkC,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC"}
|
package/dest/index.js
CHANGED
|
@@ -4,9 +4,13 @@ export * from './interfaces/merkle_tree.js';
|
|
|
4
4
|
export * from './interfaces/update_only_tree.js';
|
|
5
5
|
export * from './pedersen.js';
|
|
6
6
|
export * from './sparse_tree/sparse_tree.js';
|
|
7
|
-
export
|
|
7
|
+
export { StandardIndexedTree } from './standard_indexed_tree/standard_indexed_tree.js';
|
|
8
8
|
export * from './standard_tree/standard_tree.js';
|
|
9
9
|
export { INITIAL_LEAF } from './tree_base.js';
|
|
10
10
|
export { newTree } from './new_tree.js';
|
|
11
11
|
export { loadTree } from './load_tree.js';
|
|
12
|
-
|
|
12
|
+
export * from './snapshots/snapshot_builder.js';
|
|
13
|
+
export * from './snapshots/full_snapshot.js';
|
|
14
|
+
export * from './snapshots/append_only_snapshot.js';
|
|
15
|
+
export * from './snapshots/indexed_tree_snapshot.js';
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxrQ0FBa0MsQ0FBQztBQUNqRCxjQUFjLDhCQUE4QixDQUFDO0FBQzdDLGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsY0FBYyxrQ0FBa0MsQ0FBQztBQUNqRCxjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLDhCQUE4QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQ3ZGLGNBQWMsa0NBQWtDLENBQUM7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDeEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLHFDQUFxQyxDQUFDO0FBQ3BELGNBQWMsc0NBQXNDLENBQUMifQ==
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { TreeSnapshotBuilder } from '../snapshots/snapshot_builder.js';
|
|
2
3
|
import { MerkleTree } from './merkle_tree.js';
|
|
3
4
|
/**
|
|
4
5
|
* A Merkle tree that supports only appending leaves and not updating existing leaves.
|
|
5
6
|
*/
|
|
6
|
-
export interface AppendOnlyTree extends MerkleTree {
|
|
7
|
+
export interface AppendOnlyTree extends MerkleTree, TreeSnapshotBuilder {
|
|
7
8
|
/**
|
|
8
9
|
* Appends a set of leaf values to the tree.
|
|
9
10
|
* @param leaves - The set of leaves to be appended.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"append_only_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/append_only_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,UAAU;
|
|
1
|
+
{"version":3,"file":"append_only_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/append_only_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,UAAU,EAAE,mBAAmB;IACrE;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C"}
|
|
@@ -1,23 +1,44 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
|
|
2
3
|
import { SiblingPath } from '@aztec/types';
|
|
3
|
-
import { LowLeafWitnessData } from '../index.js';
|
|
4
4
|
import { AppendOnlyTree } from './append_only_tree.js';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* All of the data to be return during batch insertion.
|
|
7
7
|
*/
|
|
8
|
-
export interface
|
|
8
|
+
export interface LowLeafWitnessData<N extends number> {
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Preimage of the low nullifier that proves non membership.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
leafPreimage: IndexedTreeLeafPreimage;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Sibling path to prove membership of low nullifier.
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
siblingPath: SiblingPath<N>;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* The index of low nullifier.
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
index: bigint;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The result of a batch insertion in an indexed merkle tree.
|
|
24
|
+
*/
|
|
25
|
+
export interface BatchInsertionResult<TreeHeight extends number, SubtreeSiblingPathHeight extends number> {
|
|
26
|
+
/**
|
|
27
|
+
* Data for the leaves to be updated when inserting the new ones.
|
|
28
|
+
*/
|
|
29
|
+
lowLeavesWitnessData?: LowLeafWitnessData<TreeHeight>[];
|
|
30
|
+
/**
|
|
31
|
+
* Sibling path "pointing to" where the new subtree should be inserted into the tree.
|
|
32
|
+
*/
|
|
33
|
+
newSubtreeSiblingPath: SiblingPath<SubtreeSiblingPathHeight>;
|
|
34
|
+
/**
|
|
35
|
+
* The new leaves being inserted in high to low order. This order corresponds with the order of the low leaves witness.
|
|
36
|
+
*/
|
|
37
|
+
sortedNewLeaves: Buffer[];
|
|
38
|
+
/**
|
|
39
|
+
* The indexes of the sorted new leaves to the original ones.
|
|
40
|
+
*/
|
|
41
|
+
sortedNewLeavesIndexes: number[];
|
|
21
42
|
}
|
|
22
43
|
/**
|
|
23
44
|
* Indexed merkle tree.
|
|
@@ -29,29 +50,29 @@ export interface IndexedTree extends AppendOnlyTree {
|
|
|
29
50
|
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
|
|
30
51
|
* @returns The found leaf index and a flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
31
52
|
*/
|
|
32
|
-
|
|
53
|
+
findIndexOfPreviousKey(newValue: bigint, includeUncommitted: boolean): Promise<{
|
|
33
54
|
/**
|
|
34
55
|
* The index of the found leaf.
|
|
35
56
|
*/
|
|
36
|
-
index:
|
|
57
|
+
index: bigint;
|
|
37
58
|
/**
|
|
38
59
|
* A flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
39
60
|
*/
|
|
40
61
|
alreadyPresent: boolean;
|
|
41
|
-
}
|
|
62
|
+
} | undefined>;
|
|
42
63
|
/**
|
|
43
|
-
* Gets the latest
|
|
44
|
-
* @param index - Index of the leaf of which to obtain the
|
|
64
|
+
* Gets the latest LeafPreimage copy.
|
|
65
|
+
* @param index - Index of the leaf of which to obtain the LeafPreimage copy.
|
|
45
66
|
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
|
|
46
|
-
* @returns A copy of the leaf
|
|
67
|
+
* @returns A copy of the leaf preimage at the given index or undefined if the leaf was not found.
|
|
47
68
|
*/
|
|
48
|
-
|
|
69
|
+
getLatestLeafPreimageCopy(index: bigint, includeUncommitted: boolean): Promise<IndexedTreeLeafPreimage | undefined>;
|
|
49
70
|
/**
|
|
50
71
|
* Batch insert multiple leaves into the tree.
|
|
51
72
|
* @param leaves - Leaves to insert into the tree.
|
|
52
73
|
* @param subtreeHeight - Height of the subtree.
|
|
53
74
|
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
|
|
54
75
|
*/
|
|
55
|
-
batchInsert<TreeHeight extends number, SubtreeHeight extends number, SubtreeSiblingPathHeight extends number>(leaves: Buffer[], subtreeHeight: SubtreeHeight, includeUncommitted: boolean): Promise<
|
|
76
|
+
batchInsert<TreeHeight extends number, SubtreeHeight extends number, SubtreeSiblingPathHeight extends number>(leaves: Buffer[], subtreeHeight: SubtreeHeight, includeUncommitted: boolean): Promise<BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>>;
|
|
56
77
|
}
|
|
57
78
|
//# sourceMappingURL=indexed_tree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexed_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/indexed_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"indexed_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/indexed_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM;IAClD;;OAEG;IACH,YAAY,EAAE,uBAAuB,CAAC;IACtC;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,UAAU,SAAS,MAAM,EAAE,wBAAwB,SAAS,MAAM;IACtG;;OAEG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;IACxD;;OAEG;IACH,qBAAqB,EAAE,WAAW,CAAC,wBAAwB,CAAC,CAAC;IAC7D;;OAEG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;;OAEG;IACH,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD;;;;;OAKG;IACH,sBAAsB,CACpB,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,OAAO,GAC1B,OAAO,CACN;QACE;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,cAAc,EAAE,OAAO,CAAC;KACzB,GACD,SAAS,CACZ,CAAC;IAEF;;;;;OAKG;IACH,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;IAEpH;;;;;OAKG;IACH,WAAW,CAAC,UAAU,SAAS,MAAM,EAAE,aAAa,SAAS,MAAM,EAAE,wBAAwB,SAAS,MAAM,EAC1G,MAAM,EAAE,MAAM,EAAE,EAChB,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,OAAO,GAC1B,OAAO,CAAC,oBAAoB,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC;CACxE"}
|
|
@@ -43,5 +43,12 @@ export interface MerkleTree extends SiblingPathSource {
|
|
|
43
43
|
* @param includeUncommitted - Set to true to include uncommitted updates in the data set.
|
|
44
44
|
*/
|
|
45
45
|
getLeafValue(index: bigint, includeUncommitted: boolean): Promise<Buffer | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* Returns the index of a leaf given its value, or undefined if no leaf with that value is found.
|
|
48
|
+
* @param leaf - The leaf value to look for.
|
|
49
|
+
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
50
|
+
* @returns The index of the first leaf found with a given value (undefined if not found).
|
|
51
|
+
*/
|
|
52
|
+
findLeafIndex(leaf: Buffer, includeUncommitted: boolean): Promise<bigint | undefined>;
|
|
46
53
|
}
|
|
47
54
|
//# sourceMappingURL=merkle_tree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merkle_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/merkle_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACvG;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,iBAAiB;IACnD;;;OAGG;IACH,OAAO,CAAC,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAC;IAE7C;;;OAGG;IACH,YAAY,CAAC,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAC;IAElD;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACvF"}
|
|
1
|
+
{"version":3,"file":"merkle_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/merkle_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACvG;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,iBAAiB;IACnD;;;OAGG;IACH,OAAO,CAAC,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAC;IAE7C;;;OAGG;IACH,YAAY,CAAC,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAC;IAElD;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEtF;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACvF"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import {
|
|
2
|
+
import { TreeSnapshotBuilder } from '../snapshots/snapshot_builder.js';
|
|
3
3
|
import { MerkleTree } from './merkle_tree.js';
|
|
4
4
|
/**
|
|
5
5
|
* A Merkle tree that supports updates at arbitrary indices but not appending.
|
|
6
6
|
*/
|
|
7
|
-
export interface UpdateOnlyTree extends MerkleTree {
|
|
7
|
+
export interface UpdateOnlyTree extends MerkleTree, TreeSnapshotBuilder {
|
|
8
8
|
/**
|
|
9
9
|
* Updates a leaf at a given index in the tree.
|
|
10
10
|
* @param leaf - The leaf value to be updated.
|
|
11
11
|
* @param index - The leaf to be updated.
|
|
12
12
|
*/
|
|
13
|
-
updateLeaf(leaf: Buffer
|
|
13
|
+
updateLeaf(leaf: Buffer, index: bigint): Promise<void>;
|
|
14
14
|
}
|
|
15
15
|
//# sourceMappingURL=update_only_tree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update_only_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/update_only_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"update_only_tree.d.ts","sourceRoot":"","sources":["../../src/interfaces/update_only_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,UAAU,EAAE,mBAAmB;IACrE;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD"}
|
package/dest/load_tree.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
1
2
|
import { Hasher } from '@aztec/types';
|
|
2
3
|
import { LevelUp } from 'levelup';
|
|
3
4
|
import { TreeBase } from './tree_base.js';
|
|
@@ -9,5 +10,5 @@ import { TreeBase } from './tree_base.js';
|
|
|
9
10
|
* @param name - Name of the tree.
|
|
10
11
|
* @returns The newly created tree.
|
|
11
12
|
*/
|
|
12
|
-
export declare function loadTree<T extends TreeBase>(c: new (
|
|
13
|
+
export declare function loadTree<T extends TreeBase>(c: new (db: LevelUp, hasher: Hasher, name: string, depth: number, size: bigint, root: Buffer) => T, db: LevelUp, hasher: Hasher, name: string): Promise<T>;
|
|
13
14
|
//# sourceMappingURL=load_tree.d.ts.map
|
package/dest/load_tree.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load_tree.d.ts","sourceRoot":"","sources":["../src/load_tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAc,MAAM,gBAAgB,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAC/C,CAAC,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"load_tree.d.ts","sourceRoot":"","sources":["../src/load_tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAc,MAAM,gBAAgB,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAC/C,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,EAClG,EAAE,EAAE,OAAO,EACX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,CAAC,CAMZ"}
|
package/dest/load_tree.js
CHANGED
|
@@ -11,7 +11,6 @@ export async function loadTree(c, db, hasher, name) {
|
|
|
11
11
|
const meta = await db.get(name);
|
|
12
12
|
const { root, depth, size } = decodeMeta(meta);
|
|
13
13
|
const tree = new c(db, hasher, name, depth, size, root);
|
|
14
|
-
await tree.initFromDb();
|
|
15
14
|
return tree;
|
|
16
15
|
}
|
|
17
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZF90cmVlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvYWRfdHJlZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQVksVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsUUFBUSxDQUM1QixDQUFrRyxFQUNsRyxFQUFXLEVBQ1gsTUFBYyxFQUNkLElBQVk7SUFFWixNQUFNLElBQUksR0FBVyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEMsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRS9DLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDeEQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIn0=
|
package/dest/new_tree.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ import { TreeBase } from './tree_base.js';
|
|
|
11
11
|
* @param prefilledSize - A number of leaves that are prefilled with values.
|
|
12
12
|
* @returns The newly created tree.
|
|
13
13
|
*/
|
|
14
|
-
export declare function newTree<T extends TreeBase>(c: new (
|
|
14
|
+
export declare function newTree<T extends TreeBase>(c: new (db: LevelUp, hasher: Hasher, name: string, depth: number, size: bigint) => T, db: LevelUp, hasher: Hasher, name: string, depth: number, prefilledSize?: number): Promise<T>;
|
|
15
15
|
//# sourceMappingURL=new_tree.d.ts.map
|
package/dest/new_tree.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new_tree.d.ts","sourceRoot":"","sources":["../src/new_tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,CAAC,SAAS,QAAQ,EAC9C,CAAC,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"new_tree.d.ts","sourceRoot":"","sources":["../src/new_tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,CAAC,SAAS,QAAQ,EAC9C,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,EACpF,EAAE,EAAE,OAAO,EACX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,aAAa,SAAI,GAChB,OAAO,CAAC,CAAC,CAAC,CAIZ"}
|
package/dest/new_tree.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* @returns The newly created tree.
|
|
10
10
|
*/
|
|
11
11
|
export async function newTree(c, db, hasher, name, depth, prefilledSize = 1) {
|
|
12
|
-
const tree = new c(db, hasher, name, depth, 0n
|
|
12
|
+
const tree = new c(db, hasher, name, depth, 0n);
|
|
13
13
|
await tree.init(prefilledSize);
|
|
14
14
|
return tree;
|
|
15
15
|
}
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3X3RyZWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV3X3RyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUE7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxPQUFPLENBQzNCLENBQW9GLEVBQ3BGLEVBQVcsRUFDWCxNQUFjLEVBQ2QsSUFBWSxFQUNaLEtBQWEsRUFDYixhQUFhLEdBQUcsQ0FBQztJQUVqQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDaEQsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQy9CLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyJ9
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Hasher } from '@aztec/types';
|
|
2
|
+
import { LevelUp } from 'levelup';
|
|
3
|
+
import { AppendOnlyTree } from '../interfaces/append_only_tree.js';
|
|
4
|
+
import { TreeBase } from '../tree_base.js';
|
|
5
|
+
import { TreeSnapshot, TreeSnapshotBuilder } from './snapshot_builder.js';
|
|
6
|
+
/**
|
|
7
|
+
* A more space-efficient way of storing snapshots of AppendOnlyTrees that trades space need for slower
|
|
8
|
+
* sibling path reads.
|
|
9
|
+
*
|
|
10
|
+
* Complexity:
|
|
11
|
+
*
|
|
12
|
+
* N - count of non-zero nodes in tree
|
|
13
|
+
* M - count of snapshots
|
|
14
|
+
* H - tree height
|
|
15
|
+
*
|
|
16
|
+
* Space complexity: O(N + M) (N nodes - stores the last snapshot for each node and M - ints, for each snapshot stores up to which leaf its written to)
|
|
17
|
+
* Sibling path access:
|
|
18
|
+
* Best case: O(H) database reads + O(1) hashes
|
|
19
|
+
* Worst case: O(H) database reads + O(H) hashes
|
|
20
|
+
*/
|
|
21
|
+
export declare class AppendOnlySnapshotBuilder implements TreeSnapshotBuilder {
|
|
22
|
+
#private;
|
|
23
|
+
private db;
|
|
24
|
+
private tree;
|
|
25
|
+
private hasher;
|
|
26
|
+
constructor(db: LevelUp, tree: TreeBase & AppendOnlyTree, hasher: Hasher);
|
|
27
|
+
getSnapshot(block: number): Promise<TreeSnapshot>;
|
|
28
|
+
snapshot(block: number): Promise<TreeSnapshot>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=append_only_snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"append_only_snapshot.d.ts","sourceRoot":"","sources":["../../src/snapshots/append_only_snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAe,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAc1E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;;IACvD,OAAO,CAAC,EAAE;IAAW,OAAO,CAAC,IAAI;IAA6B,OAAO,CAAC,MAAM;gBAApE,EAAE,EAAE,OAAO,EAAU,IAAI,EAAE,QAAQ,GAAG,cAAc,EAAU,MAAM,EAAE,MAAM;IAC1F,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAUjD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA2ErD"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
var _AppendOnlySnapshotBuilder_instances, _AppendOnlySnapshotBuilder_getSnapshotMeta, _AppendOnlySnapshot_instances, _AppendOnlySnapshot_getHistoricalNodeValue, _AppendOnlySnapshot_getBlockNumberThatModifiedNode;
|
|
2
|
+
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
+
import { SiblingPath } from '@aztec/types';
|
|
4
|
+
// stores the last block that modified this node
|
|
5
|
+
const nodeModifiedAtBlockKey = (treeName, level, index) => `snapshot:node:${treeName}:${level}:${index}:block`;
|
|
6
|
+
// stores the value of the node at the above block
|
|
7
|
+
const historicalNodeKey = (treeName, level, index) => `snapshot:node:${treeName}:${level}:${index}:value`;
|
|
8
|
+
// metadata for a snapshot
|
|
9
|
+
const snapshotRootKey = (treeName, block) => `snapshot:root:${treeName}:${block}`;
|
|
10
|
+
const snapshotNumLeavesKey = (treeName, block) => `snapshot:numLeaves:${treeName}:${block}`;
|
|
11
|
+
/**
|
|
12
|
+
* A more space-efficient way of storing snapshots of AppendOnlyTrees that trades space need for slower
|
|
13
|
+
* sibling path reads.
|
|
14
|
+
*
|
|
15
|
+
* Complexity:
|
|
16
|
+
*
|
|
17
|
+
* N - count of non-zero nodes in tree
|
|
18
|
+
* M - count of snapshots
|
|
19
|
+
* H - tree height
|
|
20
|
+
*
|
|
21
|
+
* Space complexity: O(N + M) (N nodes - stores the last snapshot for each node and M - ints, for each snapshot stores up to which leaf its written to)
|
|
22
|
+
* Sibling path access:
|
|
23
|
+
* Best case: O(H) database reads + O(1) hashes
|
|
24
|
+
* Worst case: O(H) database reads + O(H) hashes
|
|
25
|
+
*/
|
|
26
|
+
export class AppendOnlySnapshotBuilder {
|
|
27
|
+
constructor(db, tree, hasher) {
|
|
28
|
+
_AppendOnlySnapshotBuilder_instances.add(this);
|
|
29
|
+
this.db = db;
|
|
30
|
+
this.tree = tree;
|
|
31
|
+
this.hasher = hasher;
|
|
32
|
+
}
|
|
33
|
+
async getSnapshot(block) {
|
|
34
|
+
const meta = await __classPrivateFieldGet(this, _AppendOnlySnapshotBuilder_instances, "m", _AppendOnlySnapshotBuilder_getSnapshotMeta).call(this, block);
|
|
35
|
+
if (typeof meta === 'undefined') {
|
|
36
|
+
throw new Error(`Snapshot for tree ${this.tree.getName()} at block ${block} does not exist`);
|
|
37
|
+
}
|
|
38
|
+
return new AppendOnlySnapshot(this.db, block, meta.numLeaves, meta.root, this.tree, this.hasher);
|
|
39
|
+
}
|
|
40
|
+
async snapshot(block) {
|
|
41
|
+
const meta = await __classPrivateFieldGet(this, _AppendOnlySnapshotBuilder_instances, "m", _AppendOnlySnapshotBuilder_getSnapshotMeta).call(this, block);
|
|
42
|
+
if (typeof meta !== 'undefined') {
|
|
43
|
+
// no-op, we already have a snapshot
|
|
44
|
+
return new AppendOnlySnapshot(this.db, block, meta.numLeaves, meta.root, this.tree, this.hasher);
|
|
45
|
+
}
|
|
46
|
+
const batch = this.db.batch();
|
|
47
|
+
const root = this.tree.getRoot(false);
|
|
48
|
+
const depth = this.tree.getDepth();
|
|
49
|
+
const treeName = this.tree.getName();
|
|
50
|
+
const queue = [[root, 0, 0n]];
|
|
51
|
+
// walk the tree in BF and store latest nodes
|
|
52
|
+
while (queue.length > 0) {
|
|
53
|
+
const [node, level, index] = queue.shift();
|
|
54
|
+
const historicalValue = await this.db.get(historicalNodeKey(treeName, level, index)).catch(() => undefined);
|
|
55
|
+
if (!historicalValue || !node.equals(historicalValue)) {
|
|
56
|
+
// we've never seen this node before or it's different than before
|
|
57
|
+
// update the historical tree and tag it with the block that modified it
|
|
58
|
+
batch.put(nodeModifiedAtBlockKey(treeName, level, index), String(block));
|
|
59
|
+
batch.put(historicalNodeKey(treeName, level, index), node);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// if this node hasn't changed, that means, nothing below it has changed either
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (level + 1 > depth) {
|
|
66
|
+
// short circuit if we've reached the leaf level
|
|
67
|
+
// otherwise getNode might throw if we ask for the children of a leaf
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// these could be undefined because zero hashes aren't stored in the tree
|
|
71
|
+
const [lhs, rhs] = await Promise.all([
|
|
72
|
+
this.tree.getNode(level + 1, 2n * index),
|
|
73
|
+
this.tree.getNode(level + 1, 2n * index + 1n),
|
|
74
|
+
]);
|
|
75
|
+
if (lhs) {
|
|
76
|
+
queue.push([lhs, level + 1, 2n * index]);
|
|
77
|
+
}
|
|
78
|
+
if (rhs) {
|
|
79
|
+
queue.push([rhs, level + 1, 2n * index + 1n]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const numLeaves = this.tree.getNumLeaves(false);
|
|
83
|
+
batch.put(snapshotNumLeavesKey(treeName, block), String(numLeaves));
|
|
84
|
+
batch.put(snapshotRootKey(treeName, block), root);
|
|
85
|
+
await batch.write();
|
|
86
|
+
return new AppendOnlySnapshot(this.db, block, numLeaves, root, this.tree, this.hasher);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
_AppendOnlySnapshotBuilder_instances = new WeakSet(), _AppendOnlySnapshotBuilder_getSnapshotMeta = async function _AppendOnlySnapshotBuilder_getSnapshotMeta(block) {
|
|
90
|
+
try {
|
|
91
|
+
const treeName = this.tree.getName();
|
|
92
|
+
const root = await this.db.get(snapshotRootKey(treeName, block));
|
|
93
|
+
const numLeaves = BigInt(await this.db.get(snapshotNumLeavesKey(treeName, block)));
|
|
94
|
+
return { root, numLeaves };
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* a
|
|
102
|
+
*/
|
|
103
|
+
class AppendOnlySnapshot {
|
|
104
|
+
constructor(db, block, leafCount, historicalRoot, tree, hasher) {
|
|
105
|
+
_AppendOnlySnapshot_instances.add(this);
|
|
106
|
+
this.db = db;
|
|
107
|
+
this.block = block;
|
|
108
|
+
this.leafCount = leafCount;
|
|
109
|
+
this.historicalRoot = historicalRoot;
|
|
110
|
+
this.tree = tree;
|
|
111
|
+
this.hasher = hasher;
|
|
112
|
+
}
|
|
113
|
+
async getSiblingPath(index) {
|
|
114
|
+
const path = [];
|
|
115
|
+
const depth = this.tree.getDepth();
|
|
116
|
+
let level = depth;
|
|
117
|
+
while (level > 0) {
|
|
118
|
+
const isRight = index & 0x01n;
|
|
119
|
+
const siblingIndex = isRight ? index - 1n : index + 1n;
|
|
120
|
+
const sibling = await __classPrivateFieldGet(this, _AppendOnlySnapshot_instances, "m", _AppendOnlySnapshot_getHistoricalNodeValue).call(this, level, siblingIndex);
|
|
121
|
+
path.push(sibling);
|
|
122
|
+
level -= 1;
|
|
123
|
+
index >>= 1n;
|
|
124
|
+
}
|
|
125
|
+
return new SiblingPath(depth, path);
|
|
126
|
+
}
|
|
127
|
+
getDepth() {
|
|
128
|
+
return this.tree.getDepth();
|
|
129
|
+
}
|
|
130
|
+
getNumLeaves() {
|
|
131
|
+
return this.leafCount;
|
|
132
|
+
}
|
|
133
|
+
getRoot() {
|
|
134
|
+
// we could recompute it, but it's way cheaper to just store the root
|
|
135
|
+
return this.historicalRoot;
|
|
136
|
+
}
|
|
137
|
+
async getLeafValue(index) {
|
|
138
|
+
const leafLevel = this.getDepth();
|
|
139
|
+
const blockNumber = await __classPrivateFieldGet(this, _AppendOnlySnapshot_instances, "m", _AppendOnlySnapshot_getBlockNumberThatModifiedNode).call(this, leafLevel, index);
|
|
140
|
+
// leaf hasn't been set yet
|
|
141
|
+
if (typeof blockNumber === 'undefined') {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
// leaf was set some time in the past
|
|
145
|
+
if (blockNumber <= this.block) {
|
|
146
|
+
return this.db.get(historicalNodeKey(this.tree.getName(), leafLevel, index));
|
|
147
|
+
}
|
|
148
|
+
// leaf has been set but in a block in the future
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
async findLeafIndex(value) {
|
|
152
|
+
const numLeaves = this.getNumLeaves();
|
|
153
|
+
for (let i = 0n; i < numLeaves; i++) {
|
|
154
|
+
const currentValue = await this.getLeafValue(i);
|
|
155
|
+
if (currentValue && currentValue.equals(value)) {
|
|
156
|
+
return i;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
_AppendOnlySnapshot_instances = new WeakSet(), _AppendOnlySnapshot_getHistoricalNodeValue = async function _AppendOnlySnapshot_getHistoricalNodeValue(level, index) {
|
|
163
|
+
const blockNumber = await __classPrivateFieldGet(this, _AppendOnlySnapshot_instances, "m", _AppendOnlySnapshot_getBlockNumberThatModifiedNode).call(this, level, index);
|
|
164
|
+
// node has never been set
|
|
165
|
+
if (typeof blockNumber === 'undefined') {
|
|
166
|
+
return this.tree.getZeroHash(level);
|
|
167
|
+
}
|
|
168
|
+
// node was set some time in the past
|
|
169
|
+
if (blockNumber <= this.block) {
|
|
170
|
+
return this.db.get(historicalNodeKey(this.tree.getName(), level, index));
|
|
171
|
+
}
|
|
172
|
+
// the node has been modified since this snapshot was taken
|
|
173
|
+
// because we're working with an AppendOnly tree, historical leaves never change
|
|
174
|
+
// so what we do instead is rebuild this Merkle path up using zero hashes as needed
|
|
175
|
+
// worst case this will do O(H) hashes
|
|
176
|
+
//
|
|
177
|
+
// we first check if this subtree was touched by the block
|
|
178
|
+
// compare how many leaves this block added to the leaf interval of this subtree
|
|
179
|
+
// if they don't intersect then the whole subtree was a hash of zero
|
|
180
|
+
// if they do then we need to rebuild the merkle tree
|
|
181
|
+
const depth = this.tree.getDepth();
|
|
182
|
+
const leafStart = index * 2n ** BigInt(depth - level);
|
|
183
|
+
if (leafStart >= this.leafCount) {
|
|
184
|
+
return this.tree.getZeroHash(level);
|
|
185
|
+
}
|
|
186
|
+
const [lhs, rhs] = await Promise.all([
|
|
187
|
+
__classPrivateFieldGet(this, _AppendOnlySnapshot_instances, "m", _AppendOnlySnapshot_getHistoricalNodeValue).call(this, level + 1, 2n * index),
|
|
188
|
+
__classPrivateFieldGet(this, _AppendOnlySnapshot_instances, "m", _AppendOnlySnapshot_getHistoricalNodeValue).call(this, level + 1, 2n * index + 1n),
|
|
189
|
+
]);
|
|
190
|
+
return this.hasher.hash(lhs, rhs);
|
|
191
|
+
}, _AppendOnlySnapshot_getBlockNumberThatModifiedNode = async function _AppendOnlySnapshot_getBlockNumberThatModifiedNode(level, index) {
|
|
192
|
+
try {
|
|
193
|
+
const value = await this.db.get(nodeModifiedAtBlockKey(this.tree.getName(), level, index));
|
|
194
|
+
return parseInt(value.toString(), 10);
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwZW5kX29ubHlfc25hcHNob3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc25hcHNob3RzL2FwcGVuZF9vbmx5X3NuYXBzaG90LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsT0FBTyxFQUFVLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQVFuRCxnREFBZ0Q7QUFDaEQsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLFFBQWdCLEVBQUUsS0FBYSxFQUFFLEtBQWEsRUFBRSxFQUFFLENBQ2hGLGlCQUFpQixRQUFRLElBQUksS0FBSyxJQUFJLEtBQUssUUFBUSxDQUFDO0FBRXRELGtEQUFrRDtBQUNsRCxNQUFNLGlCQUFpQixHQUFHLENBQUMsUUFBZ0IsRUFBRSxLQUFhLEVBQUUsS0FBYSxFQUFFLEVBQUUsQ0FDM0UsaUJBQWlCLFFBQVEsSUFBSSxLQUFLLElBQUksS0FBSyxRQUFRLENBQUM7QUFFdEQsMEJBQTBCO0FBQzFCLE1BQU0sZUFBZSxHQUFHLENBQUMsUUFBZ0IsRUFBRSxLQUFhLEVBQUUsRUFBRSxDQUFDLGlCQUFpQixRQUFRLElBQUksS0FBSyxFQUFFLENBQUM7QUFDbEcsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLFFBQWdCLEVBQUUsS0FBYSxFQUFFLEVBQUUsQ0FBQyxzQkFBc0IsUUFBUSxJQUFJLEtBQUssRUFBRSxDQUFDO0FBRTVHOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxPQUFPLHlCQUF5QjtJQUNwQyxZQUFvQixFQUFXLEVBQVUsSUFBK0IsRUFBVSxNQUFjOztRQUE1RSxPQUFFLEdBQUYsRUFBRSxDQUFTO1FBQVUsU0FBSSxHQUFKLElBQUksQ0FBMkI7UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQUcsQ0FBQztJQUNwRyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQWE7UUFDN0IsTUFBTSxJQUFJLEdBQUcsTUFBTSx1QkFBQSxJQUFJLHdGQUFpQixNQUFyQixJQUFJLEVBQWtCLEtBQUssQ0FB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
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { SiblingPath } from '@aztec/types';
|
|
3
|
+
import { LevelUp, LevelUpChain } from 'levelup';
|
|
4
|
+
import { TreeBase } from '../tree_base.js';
|
|
5
|
+
import { TreeSnapshot, TreeSnapshotBuilder } from './snapshot_builder.js';
|
|
6
|
+
/**
|
|
7
|
+
* Builds a full snapshot of a tree. This implementation works for any Merkle tree and stores
|
|
8
|
+
* it in a database in a similar way to how a tree is stored in memory, using pointers.
|
|
9
|
+
*
|
|
10
|
+
* Sharing the same database between versions and trees is recommended as the trees would share
|
|
11
|
+
* structure.
|
|
12
|
+
*
|
|
13
|
+
* Implement the protected method `handleLeaf` to store any additional data you need for each leaf.
|
|
14
|
+
*
|
|
15
|
+
* Complexity:
|
|
16
|
+
* N - count of non-zero nodes in tree
|
|
17
|
+
* M - count of snapshots
|
|
18
|
+
* H - tree height
|
|
19
|
+
* Worst case space complexity: O(N * M)
|
|
20
|
+
* Sibling path access: O(H) database reads
|
|
21
|
+
*/
|
|
22
|
+
export declare abstract class BaseFullTreeSnapshotBuilder<T extends TreeBase, S extends TreeSnapshot> implements TreeSnapshotBuilder<S> {
|
|
23
|
+
#private;
|
|
24
|
+
protected db: LevelUp;
|
|
25
|
+
protected tree: T;
|
|
26
|
+
constructor(db: LevelUp, tree: T);
|
|
27
|
+
snapshot(block: number): Promise<S>;
|
|
28
|
+
protected handleLeaf(_index: bigint, _node: Buffer, _batch: LevelUpChain): Promise<void>;
|
|
29
|
+
getSnapshot(version: number): Promise<S>;
|
|
30
|
+
protected abstract openSnapshot(root: Buffer, numLeaves: bigint): S;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A source of sibling paths from a snapshot tree
|
|
34
|
+
*/
|
|
35
|
+
export declare class BaseFullTreeSnapshot implements TreeSnapshot {
|
|
36
|
+
#private;
|
|
37
|
+
protected db: LevelUp;
|
|
38
|
+
protected historicRoot: Buffer;
|
|
39
|
+
protected numLeaves: bigint;
|
|
40
|
+
protected tree: TreeBase;
|
|
41
|
+
constructor(db: LevelUp, historicRoot: Buffer, numLeaves: bigint, tree: TreeBase);
|
|
42
|
+
getSiblingPath<N extends number>(index: bigint): Promise<SiblingPath<N>>;
|
|
43
|
+
getLeafValue(index: bigint): Promise<Buffer | undefined>;
|
|
44
|
+
getDepth(): number;
|
|
45
|
+
getRoot(): Buffer;
|
|
46
|
+
getNumLeaves(): bigint;
|
|
47
|
+
protected pathFromRootToLeaf(leafIndex: bigint): AsyncGenerator<Buffer[], void, unknown>;
|
|
48
|
+
findLeafIndex(value: Buffer): Promise<bigint | undefined>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=base_full_snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base_full_snapshot.d.ts","sourceRoot":"","sources":["../../src/snapshots/base_full_snapshot.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAU1E;;;;;;;;;;;;;;;GAeG;AACH,8BAAsB,2BAA2B,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,YAAY,CAC1F,YAAW,mBAAmB,CAAC,CAAC,CAAC;;IAErB,SAAS,CAAC,EAAE,EAAE,OAAO;IAAE,SAAS,CAAC,IAAI,EAAE,CAAC;gBAA9B,EAAE,EAAE,OAAO,EAAY,IAAI,EAAE,CAAC;IAE9C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IA+DzC,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY;IAIlE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAU9C,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC;CAoBpE;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,YAAY;;IAErD,SAAS,CAAC,EAAE,EAAE,OAAO;IACrB,SAAS,CAAC,YAAY,EAAE,MAAM;IAC9B,SAAS,CAAC,SAAS,EAAE,MAAM;IAC3B,SAAS,CAAC,IAAI,EAAE,QAAQ;gBAHd,EAAE,EAAE,OAAO,EACX,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,QAAQ;IAGpB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAcxE,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAS9D,QAAQ,IAAI,MAAM;IAIlB,OAAO,IAAI,MAAM;IAIjB,YAAY,IAAI,MAAM;cAIL,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAwC/C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAUhE"}
|