@aztec/world-state 0.14.1 → 0.15.0
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/world-state-db/index.d.ts +1 -190
- package/dest/world-state-db/index.d.ts.map +1 -1
- package/dest/world-state-db/index.js +2 -30
- package/dest/world-state-db/merkle_tree_db.d.ts +192 -0
- package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -0
- package/dest/world-state-db/merkle_tree_db.js +30 -0
- package/dest/world-state-db/merkle_trees.d.ts +3 -4
- package/dest/world-state-db/merkle_trees.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.js +11 -13
- package/package.json +5 -5
- package/src/world-state-db/index.ts +1 -243
- package/src/world-state-db/merkle_tree_db.ts +242 -0
- package/src/world-state-db/merkle_trees.ts +9 -13
|
@@ -1,193 +1,4 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import { LeafData, LowLeafWitnessData } from '@aztec/merkle-tree';
|
|
4
|
-
import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types';
|
|
5
1
|
export * from './merkle_trees.js';
|
|
2
|
+
export * from './merkle_tree_db.js';
|
|
6
3
|
export { LeafData } from '@aztec/merkle-tree';
|
|
7
|
-
/**
|
|
8
|
-
* Type alias for the nullifier tree ID.
|
|
9
|
-
*/
|
|
10
|
-
export type IndexedTreeId = MerkleTreeId.NULLIFIER_TREE;
|
|
11
|
-
/**
|
|
12
|
-
* Type alias for the public data tree ID.
|
|
13
|
-
*/
|
|
14
|
-
export type PublicTreeId = MerkleTreeId.PUBLIC_DATA_TREE;
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* @remarks Short explanation:
|
|
18
|
-
* The nullifier tree must be initially padded as the pre-populated 0 index prevents efficient subtree insertion.
|
|
19
|
-
* Padding with some values solves this issue.
|
|
20
|
-
*
|
|
21
|
-
* @remarks Thorough explanation:
|
|
22
|
-
* There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
|
|
23
|
-
* prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
|
|
24
|
-
* leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
|
|
25
|
-
*
|
|
26
|
-
* Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
|
|
27
|
-
* 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
|
|
28
|
-
* more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
|
|
29
|
-
*/
|
|
30
|
-
export declare const INITIAL_NULLIFIER_TREE_SIZE: number;
|
|
31
|
-
/**
|
|
32
|
-
* Defines tree information.
|
|
33
|
-
*/
|
|
34
|
-
export interface TreeInfo {
|
|
35
|
-
/**
|
|
36
|
-
* The tree ID.
|
|
37
|
-
*/
|
|
38
|
-
treeId: MerkleTreeId;
|
|
39
|
-
/**
|
|
40
|
-
* The tree root.
|
|
41
|
-
*/
|
|
42
|
-
root: Buffer;
|
|
43
|
-
/**
|
|
44
|
-
* The number of leaves in the tree.
|
|
45
|
-
*/
|
|
46
|
-
size: bigint;
|
|
47
|
-
/**
|
|
48
|
-
* The depth of the tree.
|
|
49
|
-
*/
|
|
50
|
-
depth: number;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Adds a last boolean flag in each function on the type.
|
|
54
|
-
*/
|
|
55
|
-
type WithIncludeUncommitted<F> = F extends (...args: [...infer Rest]) => infer Return ? (...args: [...Rest, boolean]) => Return : F;
|
|
56
|
-
/**
|
|
57
|
-
* The current roots of the commitment trees
|
|
58
|
-
*/
|
|
59
|
-
export type CurrentTreeRoots = {
|
|
60
|
-
/** Note Hash Tree root. */
|
|
61
|
-
noteHashTreeRoot: Buffer;
|
|
62
|
-
/** Contract data tree root. */
|
|
63
|
-
contractDataTreeRoot: Buffer;
|
|
64
|
-
/** L1 to L2 Messages data tree root. */
|
|
65
|
-
l1Tol2MessagesTreeRoot: Buffer;
|
|
66
|
-
/** Nullifier data tree root. */
|
|
67
|
-
nullifierTreeRoot: Buffer;
|
|
68
|
-
/** Blocks tree root. */
|
|
69
|
-
blocksTreeRoot: Buffer;
|
|
70
|
-
/** Public data tree root */
|
|
71
|
-
publicDataTreeRoot: Buffer;
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* Defines the names of the setters on Merkle Trees.
|
|
75
|
-
*/
|
|
76
|
-
type MerkleTreeSetters = 'appendLeaves' | 'updateLeaf' | 'commit' | 'rollback' | 'handleL2Block' | 'batchInsert';
|
|
77
|
-
/**
|
|
78
|
-
* Defines the interface for operations on a set of Merkle Trees configuring whether to return committed or uncommitted data.
|
|
79
|
-
*/
|
|
80
|
-
export type MerkleTreeDb = {
|
|
81
|
-
[Property in keyof MerkleTreeOperations as Exclude<Property, MerkleTreeSetters>]: WithIncludeUncommitted<MerkleTreeOperations[Property]>;
|
|
82
|
-
} & Pick<MerkleTreeOperations, MerkleTreeSetters>;
|
|
83
|
-
/**
|
|
84
|
-
* Defines the interface for operations on a set of Merkle Trees.
|
|
85
|
-
*/
|
|
86
|
-
export interface MerkleTreeOperations {
|
|
87
|
-
/**
|
|
88
|
-
* Appends leaves to a given tree.
|
|
89
|
-
* @param treeId - The tree to be updated.
|
|
90
|
-
* @param leaves - The set of leaves to be appended.
|
|
91
|
-
*/
|
|
92
|
-
appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise<void>;
|
|
93
|
-
/**
|
|
94
|
-
* Returns information about the given tree.
|
|
95
|
-
* @param treeId - The tree to be queried.
|
|
96
|
-
*/
|
|
97
|
-
getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo>;
|
|
98
|
-
/**
|
|
99
|
-
* Gets the current roots of the commitment trees.
|
|
100
|
-
*/
|
|
101
|
-
getTreeRoots(): Promise<CurrentTreeRoots>;
|
|
102
|
-
/**
|
|
103
|
-
* Gets sibling path for a leaf.
|
|
104
|
-
* @param treeId - The tree to be queried for a sibling path.
|
|
105
|
-
* @param index - The index of the leaf for which a sibling path should be returned.
|
|
106
|
-
*/
|
|
107
|
-
getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>>;
|
|
108
|
-
/**
|
|
109
|
-
* Returns the previous index for a given value in an indexed tree.
|
|
110
|
-
* @param treeId - The tree for which the previous value index is required.
|
|
111
|
-
* @param value - The value to be queried.
|
|
112
|
-
*/
|
|
113
|
-
getPreviousValueIndex(treeId: IndexedTreeId, value: bigint): Promise<{
|
|
114
|
-
/**
|
|
115
|
-
* The index of the found leaf.
|
|
116
|
-
*/
|
|
117
|
-
index: number;
|
|
118
|
-
/**
|
|
119
|
-
* A flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
120
|
-
*/
|
|
121
|
-
alreadyPresent: boolean;
|
|
122
|
-
}>;
|
|
123
|
-
/**
|
|
124
|
-
* Returns the data at a specific leaf.
|
|
125
|
-
* @param treeId - The tree for which leaf data should be returned.
|
|
126
|
-
* @param index - The index of the leaf required.
|
|
127
|
-
*/
|
|
128
|
-
getLeafData(treeId: IndexedTreeId, index: number): Promise<LeafData | undefined>;
|
|
129
|
-
/**
|
|
130
|
-
* Update the leaf data at the given index.
|
|
131
|
-
* @param treeId - The tree for which leaf data should be edited.
|
|
132
|
-
* @param leaf - The updated leaf value.
|
|
133
|
-
* @param index - The index of the leaf to be updated.
|
|
134
|
-
*/
|
|
135
|
-
updateLeaf(treeId: IndexedTreeId | PublicTreeId, leaf: LeafData | Buffer, index: bigint): Promise<void>;
|
|
136
|
-
/**
|
|
137
|
-
* Returns the index containing a leaf value.
|
|
138
|
-
* @param treeId - The tree for which the index should be returned.
|
|
139
|
-
* @param value - The value to search for in the tree.
|
|
140
|
-
*/
|
|
141
|
-
findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined>;
|
|
142
|
-
/**
|
|
143
|
-
* Gets the value for a leaf in the tree.
|
|
144
|
-
* @param treeId - The tree for which the index should be returned.
|
|
145
|
-
* @param index - The index of the leaf.
|
|
146
|
-
*/
|
|
147
|
-
getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined>;
|
|
148
|
-
/**
|
|
149
|
-
* Inserts the new block hash into the new block hashes tree.
|
|
150
|
-
* This includes all of the current roots of all of the data trees and the current blocks global vars.
|
|
151
|
-
* @param globalVariablesHash - The global variables hash to insert into the block hash.
|
|
152
|
-
*/
|
|
153
|
-
updateHistoricBlocksTree(globalVariablesHash: Fr): Promise<void>;
|
|
154
|
-
/**
|
|
155
|
-
* Updates the latest global variables hash
|
|
156
|
-
* @param globalVariablesHash - The latest global variables hash
|
|
157
|
-
*/
|
|
158
|
-
updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise<void>;
|
|
159
|
-
/**
|
|
160
|
-
* Gets the global variables hash from the previous block
|
|
161
|
-
*/
|
|
162
|
-
getLatestGlobalVariablesHash(): Promise<Fr>;
|
|
163
|
-
/**
|
|
164
|
-
* Batch insert multiple leaves into the tree.
|
|
165
|
-
* @param leaves - Leaves to insert into the tree.
|
|
166
|
-
* @param treeId - The tree on which to insert.
|
|
167
|
-
* @param subtreeHeight - Height of the subtree.
|
|
168
|
-
* @returns The witness data for the leaves to be updated when inserting the new ones.
|
|
169
|
-
*/
|
|
170
|
-
batchInsert(treeId: MerkleTreeId, leaves: Buffer[], subtreeHeight: number): Promise<[LowLeafWitnessData<number>[], SiblingPath<number>] | [undefined, SiblingPath<number>]>;
|
|
171
|
-
/**
|
|
172
|
-
* Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree).
|
|
173
|
-
* @param block - The L2 block to handle.
|
|
174
|
-
*/
|
|
175
|
-
handleL2Block(block: L2Block): Promise<HandleL2BlockResult>;
|
|
176
|
-
/**
|
|
177
|
-
* Commits pending changes to the underlying store.
|
|
178
|
-
*/
|
|
179
|
-
commit(): Promise<void>;
|
|
180
|
-
/**
|
|
181
|
-
* Rolls back pending changes.
|
|
182
|
-
*/
|
|
183
|
-
rollback(): Promise<void>;
|
|
184
|
-
}
|
|
185
|
-
/** Return type for handleL2Block */
|
|
186
|
-
export type HandleL2BlockResult = {
|
|
187
|
-
/** Whether the block processed was emitted by our sequencer */ isBlockOurs: boolean;
|
|
188
|
-
};
|
|
189
|
-
/**
|
|
190
|
-
* Outputs a tree leaves using for debugging purposes.
|
|
191
|
-
*/
|
|
192
|
-
export declare function inspectTree(db: MerkleTreeOperations, treeId: MerkleTreeId, log?: import("@aztec/foundation/log").DebugLogger): Promise<void>;
|
|
193
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/world-state-db/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/world-state-db/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -1,31 +1,3 @@
|
|
|
1
|
-
import { MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js';
|
|
2
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
1
|
export * from './merkle_trees.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* @remarks Short explanation:
|
|
7
|
-
* The nullifier tree must be initially padded as the pre-populated 0 index prevents efficient subtree insertion.
|
|
8
|
-
* Padding with some values solves this issue.
|
|
9
|
-
*
|
|
10
|
-
* @remarks Thorough explanation:
|
|
11
|
-
* There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
|
|
12
|
-
* prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
|
|
13
|
-
* leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
|
|
14
|
-
*
|
|
15
|
-
* Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
|
|
16
|
-
* 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
|
|
17
|
-
* more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
|
|
18
|
-
*/
|
|
19
|
-
export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NEW_NULLIFIERS_PER_TX;
|
|
20
|
-
/**
|
|
21
|
-
* Outputs a tree leaves using for debugging purposes.
|
|
22
|
-
*/
|
|
23
|
-
export async function inspectTree(db, treeId, log = createDebugLogger('aztec:inspect-tree')) {
|
|
24
|
-
const info = await db.getTreeInfo(treeId);
|
|
25
|
-
const output = [`Tree id=${treeId} size=${info.size} root=0x${info.root.toString('hex')}`];
|
|
26
|
-
for (let i = 0; i < info.size; i++) {
|
|
27
|
-
output.push(` Leaf ${i}: ${await db.getLeafValue(treeId, BigInt(i)).then(x => x?.toString('hex') ?? '[undefined]')}`);
|
|
28
|
-
}
|
|
29
|
-
log(output.join('\n'));
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd29ybGQtc3RhdGUtZGIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFL0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFJMUQsY0FBYyxtQkFBbUIsQ0FBQztBQWFsQzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLENBQUMsR0FBRyx5QkFBeUIsQ0FBQztBQWtNekU7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFdBQVcsQ0FDL0IsRUFBd0IsRUFDeEIsTUFBb0IsRUFDcEIsR0FBRyxHQUFHLGlCQUFpQixDQUFDLG9CQUFvQixDQUFDO0lBRTdDLE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxNQUFNLE1BQU0sR0FBRyxDQUFDLFdBQVcsTUFBTSxTQUFTLElBQUksQ0FBQyxJQUFJLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzNGLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ2xDLE1BQU0sQ0FBQyxJQUFJLENBQ1QsU0FBUyxDQUFDLEtBQUssTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxFQUFFLENBQ3pHLENBQUM7S0FDSDtJQUNELEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDekIsQ0FBQyJ9
|
|
2
|
+
export * from './merkle_tree_db.js';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd29ybGQtc3RhdGUtZGIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLHFCQUFxQixDQUFDIn0=
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { LeafData, LowLeafWitnessData } from '@aztec/merkle-tree';
|
|
4
|
+
import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types';
|
|
5
|
+
/**
|
|
6
|
+
* Type alias for the nullifier tree ID.
|
|
7
|
+
*/
|
|
8
|
+
export type IndexedTreeId = MerkleTreeId.NULLIFIER_TREE;
|
|
9
|
+
/**
|
|
10
|
+
* Type alias for the public data tree ID.
|
|
11
|
+
*/
|
|
12
|
+
export type PublicTreeId = MerkleTreeId.PUBLIC_DATA_TREE;
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @remarks Short explanation:
|
|
16
|
+
* The nullifier tree must be initially padded as the pre-populated 0 index prevents efficient subtree insertion.
|
|
17
|
+
* Padding with some values solves this issue.
|
|
18
|
+
*
|
|
19
|
+
* @remarks Thorough explanation:
|
|
20
|
+
* There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
|
|
21
|
+
* prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
|
|
22
|
+
* leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
|
|
23
|
+
*
|
|
24
|
+
* Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
|
|
25
|
+
* 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
|
|
26
|
+
* more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
|
|
27
|
+
*/
|
|
28
|
+
export declare const INITIAL_NULLIFIER_TREE_SIZE: number;
|
|
29
|
+
/**
|
|
30
|
+
* Defines tree information.
|
|
31
|
+
*/
|
|
32
|
+
export interface TreeInfo {
|
|
33
|
+
/**
|
|
34
|
+
* The tree ID.
|
|
35
|
+
*/
|
|
36
|
+
treeId: MerkleTreeId;
|
|
37
|
+
/**
|
|
38
|
+
* The tree root.
|
|
39
|
+
*/
|
|
40
|
+
root: Buffer;
|
|
41
|
+
/**
|
|
42
|
+
* The number of leaves in the tree.
|
|
43
|
+
*/
|
|
44
|
+
size: bigint;
|
|
45
|
+
/**
|
|
46
|
+
* The depth of the tree.
|
|
47
|
+
*/
|
|
48
|
+
depth: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Adds a last boolean flag in each function on the type.
|
|
52
|
+
*/
|
|
53
|
+
type WithIncludeUncommitted<F> = F extends (...args: [...infer Rest]) => infer Return ? (...args: [...Rest, boolean]) => Return : F;
|
|
54
|
+
/**
|
|
55
|
+
* The current roots of the commitment trees
|
|
56
|
+
*/
|
|
57
|
+
export type CurrentTreeRoots = {
|
|
58
|
+
/** Note Hash Tree root. */
|
|
59
|
+
noteHashTreeRoot: Buffer;
|
|
60
|
+
/** Contract data tree root. */
|
|
61
|
+
contractDataTreeRoot: Buffer;
|
|
62
|
+
/** L1 to L2 Messages data tree root. */
|
|
63
|
+
l1Tol2MessagesTreeRoot: Buffer;
|
|
64
|
+
/** Nullifier data tree root. */
|
|
65
|
+
nullifierTreeRoot: Buffer;
|
|
66
|
+
/** Blocks tree root. */
|
|
67
|
+
blocksTreeRoot: Buffer;
|
|
68
|
+
/** Public data tree root */
|
|
69
|
+
publicDataTreeRoot: Buffer;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Defines the names of the setters on Merkle Trees.
|
|
73
|
+
*/
|
|
74
|
+
type MerkleTreeSetters = 'appendLeaves' | 'updateLeaf' | 'commit' | 'rollback' | 'handleL2Block' | 'batchInsert';
|
|
75
|
+
/**
|
|
76
|
+
* Defines the interface for operations on a set of Merkle Trees configuring whether to return committed or uncommitted data.
|
|
77
|
+
*/
|
|
78
|
+
export type MerkleTreeDb = {
|
|
79
|
+
[Property in keyof MerkleTreeOperations as Exclude<Property, MerkleTreeSetters>]: WithIncludeUncommitted<MerkleTreeOperations[Property]>;
|
|
80
|
+
} & Pick<MerkleTreeOperations, MerkleTreeSetters>;
|
|
81
|
+
/**
|
|
82
|
+
* Defines the interface for operations on a set of Merkle Trees.
|
|
83
|
+
*/
|
|
84
|
+
export interface MerkleTreeOperations {
|
|
85
|
+
/**
|
|
86
|
+
* Appends leaves to a given tree.
|
|
87
|
+
* @param treeId - The tree to be updated.
|
|
88
|
+
* @param leaves - The set of leaves to be appended.
|
|
89
|
+
*/
|
|
90
|
+
appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Returns information about the given tree.
|
|
93
|
+
* @param treeId - The tree to be queried.
|
|
94
|
+
*/
|
|
95
|
+
getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo>;
|
|
96
|
+
/**
|
|
97
|
+
* Gets the current roots of the commitment trees.
|
|
98
|
+
*/
|
|
99
|
+
getTreeRoots(): Promise<CurrentTreeRoots>;
|
|
100
|
+
/**
|
|
101
|
+
* Gets sibling path for a leaf.
|
|
102
|
+
* @param treeId - The tree to be queried for a sibling path.
|
|
103
|
+
* @param index - The index of the leaf for which a sibling path should be returned.
|
|
104
|
+
*/
|
|
105
|
+
getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>>;
|
|
106
|
+
/**
|
|
107
|
+
* Returns the previous index for a given value in an indexed tree.
|
|
108
|
+
* @param treeId - The tree for which the previous value index is required.
|
|
109
|
+
* @param value - The value to be queried.
|
|
110
|
+
*/
|
|
111
|
+
getPreviousValueIndex(treeId: IndexedTreeId, value: bigint): Promise<{
|
|
112
|
+
/**
|
|
113
|
+
* The index of the found leaf.
|
|
114
|
+
*/
|
|
115
|
+
index: number;
|
|
116
|
+
/**
|
|
117
|
+
* A flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
118
|
+
*/
|
|
119
|
+
alreadyPresent: boolean;
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* Returns the data at a specific leaf.
|
|
123
|
+
* @param treeId - The tree for which leaf data should be returned.
|
|
124
|
+
* @param index - The index of the leaf required.
|
|
125
|
+
*/
|
|
126
|
+
getLeafData(treeId: IndexedTreeId, index: number): Promise<LeafData | undefined>;
|
|
127
|
+
/**
|
|
128
|
+
* Update the leaf data at the given index.
|
|
129
|
+
* @param treeId - The tree for which leaf data should be edited.
|
|
130
|
+
* @param leaf - The updated leaf value.
|
|
131
|
+
* @param index - The index of the leaf to be updated.
|
|
132
|
+
*/
|
|
133
|
+
updateLeaf(treeId: IndexedTreeId | PublicTreeId, leaf: LeafData | Buffer, index: bigint): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Returns the index containing a leaf value.
|
|
136
|
+
* @param treeId - The tree for which the index should be returned.
|
|
137
|
+
* @param value - The value to search for in the tree.
|
|
138
|
+
*/
|
|
139
|
+
findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined>;
|
|
140
|
+
/**
|
|
141
|
+
* Gets the value for a leaf in the tree.
|
|
142
|
+
* @param treeId - The tree for which the index should be returned.
|
|
143
|
+
* @param index - The index of the leaf.
|
|
144
|
+
*/
|
|
145
|
+
getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined>;
|
|
146
|
+
/**
|
|
147
|
+
* Inserts the new block hash into the new block hashes tree.
|
|
148
|
+
* This includes all of the current roots of all of the data trees and the current blocks global vars.
|
|
149
|
+
* @param globalVariablesHash - The global variables hash to insert into the block hash.
|
|
150
|
+
*/
|
|
151
|
+
updateHistoricBlocksTree(globalVariablesHash: Fr): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* Updates the latest global variables hash
|
|
154
|
+
* @param globalVariablesHash - The latest global variables hash
|
|
155
|
+
*/
|
|
156
|
+
updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Gets the global variables hash from the previous block
|
|
159
|
+
*/
|
|
160
|
+
getLatestGlobalVariablesHash(): Promise<Fr>;
|
|
161
|
+
/**
|
|
162
|
+
* Batch insert multiple leaves into the tree.
|
|
163
|
+
* @param leaves - Leaves to insert into the tree.
|
|
164
|
+
* @param treeId - The tree on which to insert.
|
|
165
|
+
* @param subtreeHeight - Height of the subtree.
|
|
166
|
+
* @returns The witness data for the leaves to be updated when inserting the new ones.
|
|
167
|
+
*/
|
|
168
|
+
batchInsert(treeId: MerkleTreeId, leaves: Buffer[], subtreeHeight: number): Promise<[LowLeafWitnessData<number>[], SiblingPath<number>] | [undefined, SiblingPath<number>]>;
|
|
169
|
+
/**
|
|
170
|
+
* Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree).
|
|
171
|
+
* @param block - The L2 block to handle.
|
|
172
|
+
*/
|
|
173
|
+
handleL2Block(block: L2Block): Promise<HandleL2BlockResult>;
|
|
174
|
+
/**
|
|
175
|
+
* Commits pending changes to the underlying store.
|
|
176
|
+
*/
|
|
177
|
+
commit(): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* Rolls back pending changes.
|
|
180
|
+
*/
|
|
181
|
+
rollback(): Promise<void>;
|
|
182
|
+
}
|
|
183
|
+
/** Return type for handleL2Block */
|
|
184
|
+
export type HandleL2BlockResult = {
|
|
185
|
+
/** Whether the block processed was emitted by our sequencer */ isBlockOurs: boolean;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Outputs a tree leaves using for debugging purposes.
|
|
189
|
+
*/
|
|
190
|
+
export declare function inspectTree(db: MerkleTreeOperations, treeId: MerkleTreeId, log?: import("@aztec/foundation/log").DebugLogger): Promise<void>;
|
|
191
|
+
export {};
|
|
192
|
+
//# sourceMappingURL=merkle_tree_db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merkle_tree_db.d.ts","sourceRoot":"","sources":["../../src/world-state-db/merkle_tree_db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js';
|
|
2
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @remarks Short explanation:
|
|
6
|
+
* The nullifier tree must be initially padded as the pre-populated 0 index prevents efficient subtree insertion.
|
|
7
|
+
* Padding with some values solves this issue.
|
|
8
|
+
*
|
|
9
|
+
* @remarks Thorough explanation:
|
|
10
|
+
* There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
|
|
11
|
+
* prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
|
|
12
|
+
* leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
|
|
13
|
+
*
|
|
14
|
+
* Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
|
|
15
|
+
* 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
|
|
16
|
+
* more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
|
|
17
|
+
*/
|
|
18
|
+
export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NEW_NULLIFIERS_PER_TX;
|
|
19
|
+
/**
|
|
20
|
+
* Outputs a tree leaves using for debugging purposes.
|
|
21
|
+
*/
|
|
22
|
+
export async function inspectTree(db, treeId, log = createDebugLogger('aztec:inspect-tree')) {
|
|
23
|
+
const info = await db.getTreeInfo(treeId);
|
|
24
|
+
const output = [`Tree id=${treeId} size=${info.size} root=0x${info.root.toString('hex')}`];
|
|
25
|
+
for (let i = 0; i < info.size; i++) {
|
|
26
|
+
output.push(` Leaf ${i}: ${await db.getLeafValue(treeId, BigInt(i)).then(x => x?.toString('hex') ?? '[undefined]')}`);
|
|
27
|
+
}
|
|
28
|
+
log(output.join('\n'));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVya2xlX3RyZWVfZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd29ybGQtc3RhdGUtZGIvbWVya2xlX3RyZWVfZGIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFL0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFjMUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxDQUFDLEdBQUcseUJBQXlCLENBQUM7QUFrTXpFOztHQUVHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQy9CLEVBQXdCLEVBQ3hCLE1BQW9CLEVBQ3BCLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyxvQkFBb0IsQ0FBQztJQUU3QyxNQUFNLElBQUksR0FBRyxNQUFNLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxXQUFXLE1BQU0sU0FBUyxJQUFJLENBQUMsSUFBSSxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMzRixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNsQyxNQUFNLENBQUMsSUFBSSxDQUNULFNBQVMsQ0FBQyxLQUFLLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxhQUFhLENBQUMsRUFBRSxDQUN6RyxDQUFDO0tBQ0g7SUFDRCxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLENBQUMifQ==
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import { Fr, GlobalVariables } from '@aztec/circuits.js';
|
|
3
|
-
import { IWasmModule } from '@aztec/foundation/wasm';
|
|
4
3
|
import { LeafData, LowLeafWitnessData } from '@aztec/merkle-tree';
|
|
5
4
|
import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types';
|
|
6
5
|
import { default as levelup } from 'levelup';
|
|
7
|
-
import { CurrentTreeRoots, HandleL2BlockResult, IndexedTreeId, MerkleTreeDb, MerkleTreeOperations, PublicTreeId, TreeInfo } from './
|
|
6
|
+
import { CurrentTreeRoots, HandleL2BlockResult, IndexedTreeId, MerkleTreeDb, MerkleTreeOperations, PublicTreeId, TreeInfo } from './merkle_tree_db.js';
|
|
8
7
|
/**
|
|
9
8
|
* Data necessary to reinitialize the merkle trees from Db.
|
|
10
9
|
*/
|
|
@@ -29,14 +28,14 @@ export declare class MerkleTrees implements MerkleTreeDb {
|
|
|
29
28
|
* @param optionalWasm - WASM instance to use for hashing (if not provided PrimitivesWasm will be used).
|
|
30
29
|
* @param fromDbOptions - Options to initialize the trees from the database.
|
|
31
30
|
*/
|
|
32
|
-
init(
|
|
31
|
+
init(fromDbOptions?: FromDbOptions): Promise<void>;
|
|
33
32
|
/**
|
|
34
33
|
* Method to asynchronously create and initialize a MerkleTrees instance.
|
|
35
34
|
* @param db - The db instance to use for data persistance.
|
|
36
35
|
* @param wasm - WASM instance to use for hashing (if not provided PrimitivesWasm will be used).
|
|
37
36
|
* @returns - A fully initialized MerkleTrees instance.
|
|
38
37
|
*/
|
|
39
|
-
static new(db: levelup.LevelUp
|
|
38
|
+
static new(db: levelup.LevelUp): Promise<MerkleTrees>;
|
|
40
39
|
/**
|
|
41
40
|
* Stops the job queue (waits for all jobs to finish).
|
|
42
41
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merkle_trees.d.ts","sourceRoot":"","sources":["../../src/world-state-db/merkle_trees.ts"],"names":[],"mappings":";AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"merkle_trees.d.ts","sourceRoot":"","sources":["../../src/world-state-db/merkle_trees.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CONTRACT_TREE_HEIGHT,
|
|
1
|
+
import { CONTRACT_TREE_HEIGHT, Fr, GlobalVariables, HISTORIC_BLOCKS_TREE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, } from '@aztec/circuits.js';
|
|
2
2
|
import { computeBlockHash, computeGlobalsHash } from '@aztec/circuits.js/abis';
|
|
3
3
|
import { Committable } from '@aztec/foundation/committable';
|
|
4
4
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
@@ -6,7 +6,7 @@ import { createDebugLogger } from '@aztec/foundation/log';
|
|
|
6
6
|
import { Pedersen, SparseTree, StandardIndexedTree, StandardTree, loadTree, newTree, } from '@aztec/merkle-tree';
|
|
7
7
|
import { MerkleTreeId } from '@aztec/types';
|
|
8
8
|
import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js';
|
|
9
|
-
import { INITIAL_NULLIFIER_TREE_SIZE, } from './
|
|
9
|
+
import { INITIAL_NULLIFIER_TREE_SIZE, } from './merkle_tree_db.js';
|
|
10
10
|
/**
|
|
11
11
|
* A convenience class for managing multiple merkle trees.
|
|
12
12
|
*/
|
|
@@ -23,11 +23,10 @@ export class MerkleTrees {
|
|
|
23
23
|
* @param optionalWasm - WASM instance to use for hashing (if not provided PrimitivesWasm will be used).
|
|
24
24
|
* @param fromDbOptions - Options to initialize the trees from the database.
|
|
25
25
|
*/
|
|
26
|
-
async init(
|
|
26
|
+
async init(fromDbOptions) {
|
|
27
27
|
const fromDb = fromDbOptions !== undefined;
|
|
28
28
|
const initializeTree = fromDb ? loadTree : newTree;
|
|
29
|
-
const
|
|
30
|
-
const hasher = new Pedersen(wasm);
|
|
29
|
+
const hasher = new Pedersen();
|
|
31
30
|
const contractTree = await initializeTree(StandardTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.CONTRACT_TREE]}`, CONTRACT_TREE_HEIGHT);
|
|
32
31
|
const nullifierTree = await initializeTree(StandardIndexedTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.NULLIFIER_TREE]}`, NULLIFIER_TREE_HEIGHT, INITIAL_NULLIFIER_TREE_SIZE);
|
|
33
32
|
const noteHashTree = await initializeTree(StandardTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.NOTE_HASH_TREE]}`, NOTE_HASH_TREE_HEIGHT);
|
|
@@ -38,13 +37,13 @@ export class MerkleTrees {
|
|
|
38
37
|
this.jobQueue.start();
|
|
39
38
|
// The first leaf in the blocks tree contains the empty roots of the other trees and empty global variables.
|
|
40
39
|
if (!fromDb) {
|
|
41
|
-
const initialGlobalVariablesHash = computeGlobalsHash(
|
|
40
|
+
const initialGlobalVariablesHash = computeGlobalsHash(GlobalVariables.empty());
|
|
42
41
|
await this._updateLatestGlobalVariablesHash(initialGlobalVariablesHash);
|
|
43
42
|
await this._updateHistoricBlocksTree(initialGlobalVariablesHash, true);
|
|
44
43
|
await this._commit();
|
|
45
44
|
}
|
|
46
45
|
else {
|
|
47
|
-
await this._updateLatestGlobalVariablesHash(computeGlobalsHash(
|
|
46
|
+
await this._updateLatestGlobalVariablesHash(computeGlobalsHash(fromDbOptions.globalVariables));
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
/**
|
|
@@ -53,9 +52,9 @@ export class MerkleTrees {
|
|
|
53
52
|
* @param wasm - WASM instance to use for hashing (if not provided PrimitivesWasm will be used).
|
|
54
53
|
* @returns - A fully initialized MerkleTrees instance.
|
|
55
54
|
*/
|
|
56
|
-
static async new(db
|
|
55
|
+
static async new(db) {
|
|
57
56
|
const merkleTrees = new MerkleTrees(db);
|
|
58
|
-
await merkleTrees.init(
|
|
57
|
+
await merkleTrees.init();
|
|
59
58
|
return merkleTrees;
|
|
60
59
|
}
|
|
61
60
|
/**
|
|
@@ -128,8 +127,7 @@ export class MerkleTrees {
|
|
|
128
127
|
}
|
|
129
128
|
async _getCurrentBlockHash(globalsHash, includeUncommitted) {
|
|
130
129
|
const roots = (await this._getAllTreeRoots(includeUncommitted)).map(root => Fr.fromBuffer(root));
|
|
131
|
-
|
|
132
|
-
return computeBlockHash(wasm, globalsHash, roots[0], roots[1], roots[2], roots[3], roots[4]);
|
|
130
|
+
return computeBlockHash(globalsHash, roots[0], roots[1], roots[2], roots[3], roots[4]);
|
|
133
131
|
}
|
|
134
132
|
_getAllTreeRoots(includeUncommitted) {
|
|
135
133
|
const roots = [
|
|
@@ -391,7 +389,7 @@ export class MerkleTrees {
|
|
|
391
389
|
await this._updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, newValue.toBuffer(), leafIndex.value);
|
|
392
390
|
}
|
|
393
391
|
// Sync and add the block to the historic blocks tree
|
|
394
|
-
const globalVariablesHash = computeGlobalsHash(
|
|
392
|
+
const globalVariablesHash = computeGlobalsHash(l2Block.globalVariables);
|
|
395
393
|
await this._updateLatestGlobalVariablesHash(globalVariablesHash);
|
|
396
394
|
this.log(`Synced global variables with hash ${globalVariablesHash}`);
|
|
397
395
|
const blockHash = await this._getCurrentBlockHash(globalVariablesHash, true);
|
|
@@ -414,4 +412,4 @@ export class MerkleTrees {
|
|
|
414
412
|
return { isBlockOurs: ourBlock };
|
|
415
413
|
}
|
|
416
414
|
}
|
|
417
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVya2xlX3RyZWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dvcmxkLXN0YXRlLWRiL21lcmtsZV90cmVlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLFlBQVksRUFDWixFQUFFLEVBQ0YsZUFBZSxFQUNmLDJCQUEyQixFQUMzQix3QkFBd0IsRUFDeEIscUJBQXFCLEVBQ3JCLHdCQUF3QixFQUN4QixxQkFBcUIsRUFDckIsdUJBQXVCLEdBQ3hCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDL0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzVELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRCxPQUFPLEVBS0wsUUFBUSxFQUNSLFVBQVUsRUFDVixtQkFBbUIsRUFDbkIsWUFBWSxFQUVaLFFBQVEsRUFDUixPQUFPLEdBQ1IsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQVcsWUFBWSxFQUFlLE1BQU0sY0FBYyxDQUFDO0FBSWxFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGlEQUFpRCxDQUFDO0FBQzdGLE9BQU8sRUFHTCwyQkFBMkIsR0FNNUIsTUFBTSxZQUFZLENBQUM7QUFZcEI7O0dBRUc7QUFDSCxNQUFNLE9BQU8sV0FBVztJQUt0QixZQUFvQixFQUFtQixFQUFVLE1BQU0saUJBQWlCLENBQUMsb0JBQW9CLENBQUM7UUFBMUUsT0FBRSxHQUFGLEVBQUUsQ0FBaUI7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUEwQztRQUp0RixVQUFLLEdBQXdDLEVBQUUsQ0FBQztRQUVoRCxhQUFRLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUduQyxJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxXQUFXLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQTBCLEVBQUUsYUFBNkI7UUFDekUsTUFBTSxNQUFNLEdBQUcsYUFBYSxLQUFLLFNBQVMsQ0FBQztRQUMzQyxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBRW5ELE1BQU0sSUFBSSxHQUFHLFlBQVksSUFBSSxDQUFDLE1BQU0sWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDeEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsTUFBTSxZQUFZLEdBQW1CLE1BQU0sY0FBYyxDQUN2RCxZQUFZLEVBQ1osSUFBSSxDQUFDLEVBQUUsRUFDUCxNQUFNLEVBQ04sR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEVBQzdDLG9CQUFvQixDQUNyQixDQUFDO1FBQ0YsTUFBTSxhQUFhLEdBQUcsTUFBTSxjQUFjLENBQ3hDLG1CQUFtQixFQUNuQixJQUFJLENBQUMsRUFBRSxFQUNQLE1BQU0sRUFDTixHQUFHLFlBQVksQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLEVBQUUsRUFDOUMscUJBQXFCLEVBQ3JCLDJCQUEyQixDQUM1QixDQUFDO1FBQ0YsTUFBTSxZQUFZLEdBQW1CLE1BQU0sY0FBYyxDQUN2RCxZQUFZLEVBQ1osSUFBSSxDQUFDLEVBQUUsRUFDUCxNQUFNLEVBQ04sR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQzlDLHFCQUFxQixDQUN0QixDQUFDO1FBQ0YsTUFBTSxjQUFjLEdBQW1CLE1BQU0sY0FBYyxDQUN6RCxVQUFVLEVBQ1YsSUFBSSxDQUFDLEVBQUUsRUFDUCxNQUFNLEVBQ04sR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFDaEQsdUJBQXVCLENBQ3hCLENBQUM7UUFDRixNQUFNLGtCQUFrQixHQUFtQixNQUFNLGNBQWMsQ0FDN0QsWUFBWSxFQUNaLElBQUksQ0FBQyxFQUFFLEVBQ1AsTUFBTSxFQUNOLEdBQUcsWUFBWSxDQUFDLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLEVBQ3RELHdCQUF3QixDQUN6QixDQUFDO1FBQ0YsTUFBTSxrQkFBa0IsR0FBbUIsTUFBTSxjQUFjLENBQzdELFlBQVksRUFDWixJQUFJLENBQUMsRUFBRSxFQUNQLE1BQU0sRUFDTixHQUFHLFlBQVksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFDM0MsMkJBQTJCLENBQzVCLENBQUM7UUFDRixJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFFakgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUV0Qiw0R0FBNEc7UUFDNUcsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE1BQU0sMEJBQTBCLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3JGLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxDQUFDLDBCQUEwQixDQUFDLENBQUM7WUFDeEUsTUFBTSxJQUFJLENBQUMseUJBQXlCLENBQUMsMEJBQTBCLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDdkUsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDdEI7YUFBTTtZQUNMLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztTQUN0RztJQUNILENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQW1CLEVBQUUsSUFBa0I7UUFDN0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDeEMsTUFBTSxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdCLE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7O09BR0c7SUFDSSxRQUFRO1FBQ2IsT0FBTyxJQUFJLDBCQUEwQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksV0FBVztRQUNoQixPQUFPLElBQUksMEJBQTBCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxXQUFlLEVBQUUsa0JBQTJCO1FBQ2hGLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsV0FBVyxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQztJQUNoRyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLCtCQUErQixDQUFDLG1CQUF1QjtRQUNsRSxPQUFPLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO0lBQ2xHLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsNEJBQTRCLENBQUMsa0JBQTJCO1FBQ25FLE9BQU8sTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7SUFDeEYsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFvQixFQUFFLGtCQUEyQjtRQUN4RSxPQUFPLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsWUFBWSxDQUFDLGtCQUEyQjtRQUNuRCxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdkcsT0FBTztZQUNMLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDMUIsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUMzQixvQkFBb0IsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzlCLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDaEMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUM1QixjQUFjLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztTQUN6QixDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxXQUFlLEVBQUUsa0JBQTJCO1FBQzdFLE1BQU0sS0FBSyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNqRyxNQUFNLElBQUksR0FBRyxNQUFNLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN0QyxPQUFPLGdCQUFnQixDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9GLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxrQkFBMkI7UUFDbEQsTUFBTSxLQUFLLEdBQUc7WUFDWixZQUFZLENBQUMsY0FBYztZQUMzQixZQUFZLENBQUMsY0FBYztZQUMzQixZQUFZLENBQUMsYUFBYTtZQUMxQixZQUFZLENBQUMsc0JBQXNCO1lBQ25DLFlBQVksQ0FBQyxnQkFBZ0I7WUFDN0IsWUFBWSxDQUFDLFdBQVc7U0FDekIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7UUFFNUQsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxLQUFLLENBQUMsWUFBWSxDQUN2QixNQUFvQixFQUNwQixLQUFhLEVBQ2Isa0JBQTJCO1FBRTNCLE9BQU8sTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7SUFDbEcsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxjQUFjLENBQ3pCLE1BQW9CLEVBQ3BCLEtBQWEsRUFDYixrQkFBMkI7UUFFM0IsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQW9CLEVBQUUsTUFBZ0I7UUFDOUQsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLE1BQU07UUFDakIsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVEOzs7T0FHRztJQUNJLEtBQUssQ0FBQyxRQUFRO1FBQ25CLE9BQU8sTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxLQUFLLENBQUMscUJBQXFCLENBQ2hDLE1BQXFCLEVBQ3JCLEtBQWEsRUFDYixrQkFBMkI7UUFXM0IsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQ2pDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUNsRyxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxXQUFXLENBQ3RCLE1BQXFCLEVBQ3JCLEtBQWEsRUFDYixrQkFBMkI7UUFFM0IsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQ2pDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUMvRixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxhQUFhLENBQ3hCLE1BQW9CLEVBQ3BCLEtBQWEsRUFDYixrQkFBMkI7UUFFM0IsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNoQyxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUMvRCxNQUFNLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUM7Z0JBQ3BFLElBQUksWUFBWSxJQUFJLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUU7b0JBQzlDLE9BQU8sQ0FBQyxDQUFDO2lCQUNWO2FBQ0Y7WUFDRCxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQW9DLEVBQUUsSUFBdUIsRUFBRSxLQUFhO1FBQ2xHLE9BQU8sTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFjO1FBQ3ZDLE9BQU8sTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksS0FBSyxDQUFDLFdBQVcsQ0FLdEIsTUFBb0IsRUFDcEIsTUFBZ0IsRUFDaEIsYUFBNEI7UUFLNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQXdCLENBQUM7UUFDdkQsSUFBSSxDQUFDLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxFQUFFO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQztTQUMvRDtRQUNELE9BQU8sTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxLQUFLLENBQUMsV0FBVyxDQUFJLEVBQW9CO1FBQy9DLE9BQU8sTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRU8sZ0NBQWdDLENBQUMsbUJBQXVCO1FBQzlELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUN4RCxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8sdUJBQXVCLENBQUMsa0JBQTJCO1FBQ3pELE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRU8sS0FBSyxDQUFDLHlCQUF5QixDQUFDLFdBQWUsRUFBRSxrQkFBMkI7UUFDbEYsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFDbkYsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLFlBQVksQ0FBQyxNQUFvQixFQUFFLGtCQUEyQjtRQUNwRSxNQUFNLFFBQVEsR0FBRztZQUNmLE1BQU07WUFDTixJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUM7WUFDcEQsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLGtCQUFrQixDQUFDO1lBQ3pELEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRTtTQUN6QixDQUFDO1FBQ2QsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssZUFBZSxDQUFDLE1BQXFCO1FBQzNDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQWdCLENBQUM7SUFDM0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLGVBQWUsQ0FDckIsTUFBb0IsRUFDcEIsS0FBYSxFQUNiLGtCQUEyQjtRQUUzQixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxjQUFjLENBQUksS0FBSyxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQW9CLEVBQUUsTUFBZ0I7UUFDaEUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLEVBQUU7WUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1NBQ2hFO1FBQ0QsT0FBTyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXLENBQ3ZCLE1BQW9DLEVBQ3BDLElBQXVCLEVBQ3ZCLEtBQWE7UUFFYixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsRUFBRTtZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7U0FDOUQ7UUFDRCxPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVEOzs7T0FHRztJQUNLLEtBQUssQ0FBQyxPQUFPO1FBQ25CLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUM3QixNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztTQUNyQjtRQUNELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxDQUFDLFNBQVM7UUFDckIsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQzdCLE1BQU0sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ3ZCO1FBQ0QsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzVDLENBQUM7SUFFRDs7O09BR0c7SUFDSyxLQUFLLENBQUMsY0FBYyxDQUFDLE9BQWdCO1FBQzNDLE1BQU0sbUJBQW1CLEdBQUc7WUFDMUIsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxhQUFhLENBQUM7WUFDbEUsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxjQUFjLENBQUM7WUFDcEUsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxjQUFjLENBQUM7WUFDbkUsQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsWUFBWSxDQUFDLGdCQUFnQixDQUFDO1lBQzlELENBQUMsT0FBTyxDQUFDLDZCQUE2QixDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsc0JBQXNCLENBQUM7WUFDakYsQ0FBQyxPQUFPLENBQUMsNkJBQTZCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxXQUFXLENBQUM7U0FDOUQsQ0FBQztRQUNYLE1BQU0sV0FBVyxHQUFHLENBQUMsSUFBUSxFQUFFLE1BQW9CLEVBQUUsRUFBRTtZQUNyRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsRCxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxRQUFRLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNsRixJQUFJLFFBQVEsRUFBRTtZQUNaLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxPQUFPLENBQUMsTUFBTSxrQ0FBa0MsQ0FBQyxDQUFDO1lBQ3BFLE1BQU0sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ3RCO2FBQU07WUFDTCxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsT0FBTyxDQUFDLE1BQU0sd0VBQXdFLENBQUMsQ0FBQztZQUMxRyxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUV2Qiw2QkFBNkI7WUFDN0IsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUMzQixDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQztnQkFDbEQsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxjQUFjLENBQUM7Z0JBQ3JELENBQUMsWUFBWSxDQUFDLHNCQUFzQixFQUFFLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQzthQUN4RCxFQUFFO2dCQUNWLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FDdEIsSUFBSSxFQUNKLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FDaEMsQ0FBQzthQUNIO1lBRUQseUJBQXlCO1lBQ3pCLE1BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUF5QixDQUFDLFdBQVcsQ0FDaEYsT0FBTyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsRUFDOUMsd0JBQXdCLENBQ3pCLENBQUM7WUFFRiw0QkFBNEI7WUFDNUIsS0FBSyxNQUFNLFNBQVMsSUFBSSxPQUFPLENBQUMsbUJBQW1CLEVBQUU7Z0JBQ25ELElBQUksU0FBUyxDQUFDLE9BQU8sRUFBRTtvQkFBRSxTQUFTO2dCQUNsQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLFNBQVMsQ0FBQztnQkFDMUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxRQUFRLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzdGO1lBRUQscURBQXFEO1lBQ3JELE1BQU0sbUJBQW1CLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxZQUFZLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ2xHLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDakUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1lBRXJFLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzdFLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUUzRSxNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUN0QjtRQUVELEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxtQkFBbUIsRUFBRTtZQUNoRCxNQUFNLFFBQVEsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNwRCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2hDLGdGQUFnRjtZQUNoRixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUU7Z0JBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQ2Isb0JBQW9CLFFBQVEsNENBQTRDLFNBQVMsT0FBTyxPQUFPLEVBQUUsQ0FDbEcsQ0FBQzthQUNIO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxRQUFRLHNCQUFzQixJQUFJLENBQUMsSUFBSSxTQUFTLE9BQU8sRUFBRSxDQUFDLENBQUM7YUFDN0U7U0FDRjtRQUVELE9BQU8sRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFDbkMsQ0FBQztDQUNGIn0=
|
|
415
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVya2xlX3RyZWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dvcmxkLXN0YXRlLWRiL21lcmtsZV90cmVlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLEVBQUUsRUFDRixlQUFlLEVBQ2YsMkJBQTJCLEVBQzNCLHdCQUF3QixFQUN4QixxQkFBcUIsRUFDckIsd0JBQXdCLEVBQ3hCLHFCQUFxQixFQUNyQix1QkFBdUIsR0FDeEIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzFELE9BQU8sRUFLTCxRQUFRLEVBQ1IsVUFBVSxFQUNWLG1CQUFtQixFQUNuQixZQUFZLEVBRVosUUFBUSxFQUNSLE9BQU8sR0FDUixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBVyxZQUFZLEVBQWUsTUFBTSxjQUFjLENBQUM7QUFJbEUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0saURBQWlELENBQUM7QUFDN0YsT0FBTyxFQUdMLDJCQUEyQixHQU01QixNQUFNLHFCQUFxQixDQUFDO0FBWTdCOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFLdEIsWUFBb0IsRUFBbUIsRUFBVSxNQUFNLGlCQUFpQixDQUFDLG9CQUFvQixDQUFDO1FBQTFFLE9BQUUsR0FBRixFQUFFLENBQWlCO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBMEM7UUFKdEYsVUFBSyxHQUF3QyxFQUFFLENBQUM7UUFFaEQsYUFBUSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFHbkMsSUFB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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/world-state",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"typedocOptions": {
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"rootDir": "./src"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@aztec/circuits.js": "0.
|
|
34
|
-
"@aztec/foundation": "0.
|
|
35
|
-
"@aztec/merkle-tree": "0.
|
|
36
|
-
"@aztec/types": "0.
|
|
33
|
+
"@aztec/circuits.js": "0.15.0",
|
|
34
|
+
"@aztec/foundation": "0.15.0",
|
|
35
|
+
"@aztec/merkle-tree": "0.15.0",
|
|
36
|
+
"@aztec/types": "0.15.0",
|
|
37
37
|
"levelup": "^5.1.1",
|
|
38
38
|
"lodash.times": "^4.3.2",
|
|
39
39
|
"memdown": "^6.1.1",
|
|
@@ -1,245 +1,3 @@
|
|
|
1
|
-
import { MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js';
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
|
-
import { LeafData, LowLeafWitnessData } from '@aztec/merkle-tree';
|
|
5
|
-
import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types';
|
|
6
|
-
|
|
7
1
|
export * from './merkle_trees.js';
|
|
2
|
+
export * from './merkle_tree_db.js';
|
|
8
3
|
export { LeafData } from '@aztec/merkle-tree';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Type alias for the nullifier tree ID.
|
|
12
|
-
*/
|
|
13
|
-
export type IndexedTreeId = MerkleTreeId.NULLIFIER_TREE;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Type alias for the public data tree ID.
|
|
17
|
-
*/
|
|
18
|
-
export type PublicTreeId = MerkleTreeId.PUBLIC_DATA_TREE;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
* @remarks Short explanation:
|
|
23
|
-
* The nullifier tree must be initially padded as the pre-populated 0 index prevents efficient subtree insertion.
|
|
24
|
-
* Padding with some values solves this issue.
|
|
25
|
-
*
|
|
26
|
-
* @remarks Thorough explanation:
|
|
27
|
-
* There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
|
|
28
|
-
* prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
|
|
29
|
-
* leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
|
|
30
|
-
*
|
|
31
|
-
* Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
|
|
32
|
-
* 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
|
|
33
|
-
* more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
|
|
34
|
-
*/
|
|
35
|
-
export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NEW_NULLIFIERS_PER_TX;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Defines tree information.
|
|
39
|
-
*/
|
|
40
|
-
export interface TreeInfo {
|
|
41
|
-
/**
|
|
42
|
-
* The tree ID.
|
|
43
|
-
*/
|
|
44
|
-
treeId: MerkleTreeId;
|
|
45
|
-
/**
|
|
46
|
-
* The tree root.
|
|
47
|
-
*/
|
|
48
|
-
root: Buffer;
|
|
49
|
-
/**
|
|
50
|
-
* The number of leaves in the tree.
|
|
51
|
-
*/
|
|
52
|
-
size: bigint;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The depth of the tree.
|
|
56
|
-
*/
|
|
57
|
-
depth: number;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Adds a last boolean flag in each function on the type.
|
|
62
|
-
*/
|
|
63
|
-
type WithIncludeUncommitted<F> = F extends (...args: [...infer Rest]) => infer Return
|
|
64
|
-
? (...args: [...Rest, boolean]) => Return
|
|
65
|
-
: F;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The current roots of the commitment trees
|
|
69
|
-
*/
|
|
70
|
-
export type CurrentTreeRoots = {
|
|
71
|
-
/** Note Hash Tree root. */
|
|
72
|
-
noteHashTreeRoot: Buffer;
|
|
73
|
-
/** Contract data tree root. */
|
|
74
|
-
contractDataTreeRoot: Buffer;
|
|
75
|
-
/** L1 to L2 Messages data tree root. */
|
|
76
|
-
l1Tol2MessagesTreeRoot: Buffer;
|
|
77
|
-
/** Nullifier data tree root. */
|
|
78
|
-
nullifierTreeRoot: Buffer;
|
|
79
|
-
/** Blocks tree root. */
|
|
80
|
-
blocksTreeRoot: Buffer;
|
|
81
|
-
/** Public data tree root */
|
|
82
|
-
publicDataTreeRoot: Buffer;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Defines the names of the setters on Merkle Trees.
|
|
87
|
-
*/
|
|
88
|
-
type MerkleTreeSetters = 'appendLeaves' | 'updateLeaf' | 'commit' | 'rollback' | 'handleL2Block' | 'batchInsert';
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Defines the interface for operations on a set of Merkle Trees configuring whether to return committed or uncommitted data.
|
|
92
|
-
*/
|
|
93
|
-
export type MerkleTreeDb = {
|
|
94
|
-
[Property in keyof MerkleTreeOperations as Exclude<Property, MerkleTreeSetters>]: WithIncludeUncommitted<
|
|
95
|
-
MerkleTreeOperations[Property]
|
|
96
|
-
>;
|
|
97
|
-
} & Pick<MerkleTreeOperations, MerkleTreeSetters>;
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Defines the interface for operations on a set of Merkle Trees.
|
|
101
|
-
*/
|
|
102
|
-
export interface MerkleTreeOperations {
|
|
103
|
-
/**
|
|
104
|
-
* Appends leaves to a given tree.
|
|
105
|
-
* @param treeId - The tree to be updated.
|
|
106
|
-
* @param leaves - The set of leaves to be appended.
|
|
107
|
-
*/
|
|
108
|
-
appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise<void>;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Returns information about the given tree.
|
|
112
|
-
* @param treeId - The tree to be queried.
|
|
113
|
-
*/
|
|
114
|
-
getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo>;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Gets the current roots of the commitment trees.
|
|
118
|
-
*/
|
|
119
|
-
getTreeRoots(): Promise<CurrentTreeRoots>;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Gets sibling path for a leaf.
|
|
123
|
-
* @param treeId - The tree to be queried for a sibling path.
|
|
124
|
-
* @param index - The index of the leaf for which a sibling path should be returned.
|
|
125
|
-
*/
|
|
126
|
-
getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>>;
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Returns the previous index for a given value in an indexed tree.
|
|
130
|
-
* @param treeId - The tree for which the previous value index is required.
|
|
131
|
-
* @param value - The value to be queried.
|
|
132
|
-
*/
|
|
133
|
-
getPreviousValueIndex(
|
|
134
|
-
treeId: IndexedTreeId,
|
|
135
|
-
value: bigint,
|
|
136
|
-
): Promise<{
|
|
137
|
-
/**
|
|
138
|
-
* The index of the found leaf.
|
|
139
|
-
*/
|
|
140
|
-
index: number;
|
|
141
|
-
/**
|
|
142
|
-
* A flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
143
|
-
*/
|
|
144
|
-
alreadyPresent: boolean;
|
|
145
|
-
}>;
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Returns the data at a specific leaf.
|
|
149
|
-
* @param treeId - The tree for which leaf data should be returned.
|
|
150
|
-
* @param index - The index of the leaf required.
|
|
151
|
-
*/
|
|
152
|
-
getLeafData(treeId: IndexedTreeId, index: number): Promise<LeafData | undefined>;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Update the leaf data at the given index.
|
|
156
|
-
* @param treeId - The tree for which leaf data should be edited.
|
|
157
|
-
* @param leaf - The updated leaf value.
|
|
158
|
-
* @param index - The index of the leaf to be updated.
|
|
159
|
-
*/
|
|
160
|
-
updateLeaf(treeId: IndexedTreeId | PublicTreeId, leaf: LeafData | Buffer, index: bigint): Promise<void>;
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Returns the index containing a leaf value.
|
|
164
|
-
* @param treeId - The tree for which the index should be returned.
|
|
165
|
-
* @param value - The value to search for in the tree.
|
|
166
|
-
*/
|
|
167
|
-
findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined>;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Gets the value for a leaf in the tree.
|
|
171
|
-
* @param treeId - The tree for which the index should be returned.
|
|
172
|
-
* @param index - The index of the leaf.
|
|
173
|
-
*/
|
|
174
|
-
getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined>;
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Inserts the new block hash into the new block hashes tree.
|
|
178
|
-
* This includes all of the current roots of all of the data trees and the current blocks global vars.
|
|
179
|
-
* @param globalVariablesHash - The global variables hash to insert into the block hash.
|
|
180
|
-
*/
|
|
181
|
-
updateHistoricBlocksTree(globalVariablesHash: Fr): Promise<void>;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Updates the latest global variables hash
|
|
185
|
-
* @param globalVariablesHash - The latest global variables hash
|
|
186
|
-
*/
|
|
187
|
-
updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise<void>;
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Gets the global variables hash from the previous block
|
|
191
|
-
*/
|
|
192
|
-
getLatestGlobalVariablesHash(): Promise<Fr>;
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Batch insert multiple leaves into the tree.
|
|
196
|
-
* @param leaves - Leaves to insert into the tree.
|
|
197
|
-
* @param treeId - The tree on which to insert.
|
|
198
|
-
* @param subtreeHeight - Height of the subtree.
|
|
199
|
-
* @returns The witness data for the leaves to be updated when inserting the new ones.
|
|
200
|
-
*/
|
|
201
|
-
batchInsert(
|
|
202
|
-
treeId: MerkleTreeId,
|
|
203
|
-
leaves: Buffer[],
|
|
204
|
-
subtreeHeight: number,
|
|
205
|
-
): Promise<[LowLeafWitnessData<number>[], SiblingPath<number>] | [undefined, SiblingPath<number>]>;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree).
|
|
209
|
-
* @param block - The L2 block to handle.
|
|
210
|
-
*/
|
|
211
|
-
handleL2Block(block: L2Block): Promise<HandleL2BlockResult>;
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Commits pending changes to the underlying store.
|
|
215
|
-
*/
|
|
216
|
-
commit(): Promise<void>;
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Rolls back pending changes.
|
|
220
|
-
*/
|
|
221
|
-
rollback(): Promise<void>;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/** Return type for handleL2Block */
|
|
225
|
-
export type HandleL2BlockResult = {
|
|
226
|
-
/** Whether the block processed was emitted by our sequencer */ isBlockOurs: boolean;
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Outputs a tree leaves using for debugging purposes.
|
|
231
|
-
*/
|
|
232
|
-
export async function inspectTree(
|
|
233
|
-
db: MerkleTreeOperations,
|
|
234
|
-
treeId: MerkleTreeId,
|
|
235
|
-
log = createDebugLogger('aztec:inspect-tree'),
|
|
236
|
-
) {
|
|
237
|
-
const info = await db.getTreeInfo(treeId);
|
|
238
|
-
const output = [`Tree id=${treeId} size=${info.size} root=0x${info.root.toString('hex')}`];
|
|
239
|
-
for (let i = 0; i < info.size; i++) {
|
|
240
|
-
output.push(
|
|
241
|
-
` Leaf ${i}: ${await db.getLeafValue(treeId, BigInt(i)).then(x => x?.toString('hex') ?? '[undefined]')}`,
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
log(output.join('\n'));
|
|
245
|
-
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js';
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
|
+
import { LeafData, LowLeafWitnessData } from '@aztec/merkle-tree';
|
|
5
|
+
import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Type alias for the nullifier tree ID.
|
|
9
|
+
*/
|
|
10
|
+
export type IndexedTreeId = MerkleTreeId.NULLIFIER_TREE;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Type alias for the public data tree ID.
|
|
14
|
+
*/
|
|
15
|
+
export type PublicTreeId = MerkleTreeId.PUBLIC_DATA_TREE;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @remarks Short explanation:
|
|
20
|
+
* The nullifier tree must be initially padded as the pre-populated 0 index prevents efficient subtree insertion.
|
|
21
|
+
* Padding with some values solves this issue.
|
|
22
|
+
*
|
|
23
|
+
* @remarks Thorough explanation:
|
|
24
|
+
* There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
|
|
25
|
+
* prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
|
|
26
|
+
* leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
|
|
27
|
+
*
|
|
28
|
+
* Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
|
|
29
|
+
* 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
|
|
30
|
+
* more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
|
|
31
|
+
*/
|
|
32
|
+
export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NEW_NULLIFIERS_PER_TX;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Defines tree information.
|
|
36
|
+
*/
|
|
37
|
+
export interface TreeInfo {
|
|
38
|
+
/**
|
|
39
|
+
* The tree ID.
|
|
40
|
+
*/
|
|
41
|
+
treeId: MerkleTreeId;
|
|
42
|
+
/**
|
|
43
|
+
* The tree root.
|
|
44
|
+
*/
|
|
45
|
+
root: Buffer;
|
|
46
|
+
/**
|
|
47
|
+
* The number of leaves in the tree.
|
|
48
|
+
*/
|
|
49
|
+
size: bigint;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The depth of the tree.
|
|
53
|
+
*/
|
|
54
|
+
depth: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Adds a last boolean flag in each function on the type.
|
|
59
|
+
*/
|
|
60
|
+
type WithIncludeUncommitted<F> = F extends (...args: [...infer Rest]) => infer Return
|
|
61
|
+
? (...args: [...Rest, boolean]) => Return
|
|
62
|
+
: F;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The current roots of the commitment trees
|
|
66
|
+
*/
|
|
67
|
+
export type CurrentTreeRoots = {
|
|
68
|
+
/** Note Hash Tree root. */
|
|
69
|
+
noteHashTreeRoot: Buffer;
|
|
70
|
+
/** Contract data tree root. */
|
|
71
|
+
contractDataTreeRoot: Buffer;
|
|
72
|
+
/** L1 to L2 Messages data tree root. */
|
|
73
|
+
l1Tol2MessagesTreeRoot: Buffer;
|
|
74
|
+
/** Nullifier data tree root. */
|
|
75
|
+
nullifierTreeRoot: Buffer;
|
|
76
|
+
/** Blocks tree root. */
|
|
77
|
+
blocksTreeRoot: Buffer;
|
|
78
|
+
/** Public data tree root */
|
|
79
|
+
publicDataTreeRoot: Buffer;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Defines the names of the setters on Merkle Trees.
|
|
84
|
+
*/
|
|
85
|
+
type MerkleTreeSetters = 'appendLeaves' | 'updateLeaf' | 'commit' | 'rollback' | 'handleL2Block' | 'batchInsert';
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Defines the interface for operations on a set of Merkle Trees configuring whether to return committed or uncommitted data.
|
|
89
|
+
*/
|
|
90
|
+
export type MerkleTreeDb = {
|
|
91
|
+
[Property in keyof MerkleTreeOperations as Exclude<Property, MerkleTreeSetters>]: WithIncludeUncommitted<
|
|
92
|
+
MerkleTreeOperations[Property]
|
|
93
|
+
>;
|
|
94
|
+
} & Pick<MerkleTreeOperations, MerkleTreeSetters>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Defines the interface for operations on a set of Merkle Trees.
|
|
98
|
+
*/
|
|
99
|
+
export interface MerkleTreeOperations {
|
|
100
|
+
/**
|
|
101
|
+
* Appends leaves to a given tree.
|
|
102
|
+
* @param treeId - The tree to be updated.
|
|
103
|
+
* @param leaves - The set of leaves to be appended.
|
|
104
|
+
*/
|
|
105
|
+
appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise<void>;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Returns information about the given tree.
|
|
109
|
+
* @param treeId - The tree to be queried.
|
|
110
|
+
*/
|
|
111
|
+
getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Gets the current roots of the commitment trees.
|
|
115
|
+
*/
|
|
116
|
+
getTreeRoots(): Promise<CurrentTreeRoots>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Gets sibling path for a leaf.
|
|
120
|
+
* @param treeId - The tree to be queried for a sibling path.
|
|
121
|
+
* @param index - The index of the leaf for which a sibling path should be returned.
|
|
122
|
+
*/
|
|
123
|
+
getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Returns the previous index for a given value in an indexed tree.
|
|
127
|
+
* @param treeId - The tree for which the previous value index is required.
|
|
128
|
+
* @param value - The value to be queried.
|
|
129
|
+
*/
|
|
130
|
+
getPreviousValueIndex(
|
|
131
|
+
treeId: IndexedTreeId,
|
|
132
|
+
value: bigint,
|
|
133
|
+
): Promise<{
|
|
134
|
+
/**
|
|
135
|
+
* The index of the found leaf.
|
|
136
|
+
*/
|
|
137
|
+
index: number;
|
|
138
|
+
/**
|
|
139
|
+
* A flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
140
|
+
*/
|
|
141
|
+
alreadyPresent: boolean;
|
|
142
|
+
}>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Returns the data at a specific leaf.
|
|
146
|
+
* @param treeId - The tree for which leaf data should be returned.
|
|
147
|
+
* @param index - The index of the leaf required.
|
|
148
|
+
*/
|
|
149
|
+
getLeafData(treeId: IndexedTreeId, index: number): Promise<LeafData | undefined>;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Update the leaf data at the given index.
|
|
153
|
+
* @param treeId - The tree for which leaf data should be edited.
|
|
154
|
+
* @param leaf - The updated leaf value.
|
|
155
|
+
* @param index - The index of the leaf to be updated.
|
|
156
|
+
*/
|
|
157
|
+
updateLeaf(treeId: IndexedTreeId | PublicTreeId, leaf: LeafData | Buffer, index: bigint): Promise<void>;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns the index containing a leaf value.
|
|
161
|
+
* @param treeId - The tree for which the index should be returned.
|
|
162
|
+
* @param value - The value to search for in the tree.
|
|
163
|
+
*/
|
|
164
|
+
findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined>;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Gets the value for a leaf in the tree.
|
|
168
|
+
* @param treeId - The tree for which the index should be returned.
|
|
169
|
+
* @param index - The index of the leaf.
|
|
170
|
+
*/
|
|
171
|
+
getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined>;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Inserts the new block hash into the new block hashes tree.
|
|
175
|
+
* This includes all of the current roots of all of the data trees and the current blocks global vars.
|
|
176
|
+
* @param globalVariablesHash - The global variables hash to insert into the block hash.
|
|
177
|
+
*/
|
|
178
|
+
updateHistoricBlocksTree(globalVariablesHash: Fr): Promise<void>;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Updates the latest global variables hash
|
|
182
|
+
* @param globalVariablesHash - The latest global variables hash
|
|
183
|
+
*/
|
|
184
|
+
updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise<void>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Gets the global variables hash from the previous block
|
|
188
|
+
*/
|
|
189
|
+
getLatestGlobalVariablesHash(): Promise<Fr>;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Batch insert multiple leaves into the tree.
|
|
193
|
+
* @param leaves - Leaves to insert into the tree.
|
|
194
|
+
* @param treeId - The tree on which to insert.
|
|
195
|
+
* @param subtreeHeight - Height of the subtree.
|
|
196
|
+
* @returns The witness data for the leaves to be updated when inserting the new ones.
|
|
197
|
+
*/
|
|
198
|
+
batchInsert(
|
|
199
|
+
treeId: MerkleTreeId,
|
|
200
|
+
leaves: Buffer[],
|
|
201
|
+
subtreeHeight: number,
|
|
202
|
+
): Promise<[LowLeafWitnessData<number>[], SiblingPath<number>] | [undefined, SiblingPath<number>]>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree).
|
|
206
|
+
* @param block - The L2 block to handle.
|
|
207
|
+
*/
|
|
208
|
+
handleL2Block(block: L2Block): Promise<HandleL2BlockResult>;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Commits pending changes to the underlying store.
|
|
212
|
+
*/
|
|
213
|
+
commit(): Promise<void>;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Rolls back pending changes.
|
|
217
|
+
*/
|
|
218
|
+
rollback(): Promise<void>;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Return type for handleL2Block */
|
|
222
|
+
export type HandleL2BlockResult = {
|
|
223
|
+
/** Whether the block processed was emitted by our sequencer */ isBlockOurs: boolean;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Outputs a tree leaves using for debugging purposes.
|
|
228
|
+
*/
|
|
229
|
+
export async function inspectTree(
|
|
230
|
+
db: MerkleTreeOperations,
|
|
231
|
+
treeId: MerkleTreeId,
|
|
232
|
+
log = createDebugLogger('aztec:inspect-tree'),
|
|
233
|
+
) {
|
|
234
|
+
const info = await db.getTreeInfo(treeId);
|
|
235
|
+
const output = [`Tree id=${treeId} size=${info.size} root=0x${info.root.toString('hex')}`];
|
|
236
|
+
for (let i = 0; i < info.size; i++) {
|
|
237
|
+
output.push(
|
|
238
|
+
` Leaf ${i}: ${await db.getLeafValue(treeId, BigInt(i)).then(x => x?.toString('hex') ?? '[undefined]')}`,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
log(output.join('\n'));
|
|
242
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CONTRACT_TREE_HEIGHT,
|
|
3
|
-
CircuitsWasm,
|
|
4
3
|
Fr,
|
|
5
4
|
GlobalVariables,
|
|
6
5
|
HISTORIC_BLOCKS_TREE_HEIGHT,
|
|
@@ -14,7 +13,6 @@ import { computeBlockHash, computeGlobalsHash } from '@aztec/circuits.js/abis';
|
|
|
14
13
|
import { Committable } from '@aztec/foundation/committable';
|
|
15
14
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
16
15
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
17
|
-
import { IWasmModule } from '@aztec/foundation/wasm';
|
|
18
16
|
import {
|
|
19
17
|
AppendOnlyTree,
|
|
20
18
|
IndexedTree,
|
|
@@ -42,7 +40,7 @@ import {
|
|
|
42
40
|
MerkleTreeOperations,
|
|
43
41
|
PublicTreeId,
|
|
44
42
|
TreeInfo,
|
|
45
|
-
} from './
|
|
43
|
+
} from './merkle_tree_db.js';
|
|
46
44
|
|
|
47
45
|
/**
|
|
48
46
|
* Data necessary to reinitialize the merkle trees from Db.
|
|
@@ -71,12 +69,11 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
71
69
|
* @param optionalWasm - WASM instance to use for hashing (if not provided PrimitivesWasm will be used).
|
|
72
70
|
* @param fromDbOptions - Options to initialize the trees from the database.
|
|
73
71
|
*/
|
|
74
|
-
public async init(
|
|
72
|
+
public async init(fromDbOptions?: FromDbOptions) {
|
|
75
73
|
const fromDb = fromDbOptions !== undefined;
|
|
76
74
|
const initializeTree = fromDb ? loadTree : newTree;
|
|
77
75
|
|
|
78
|
-
const
|
|
79
|
-
const hasher = new Pedersen(wasm);
|
|
76
|
+
const hasher = new Pedersen();
|
|
80
77
|
const contractTree: AppendOnlyTree = await initializeTree(
|
|
81
78
|
StandardTree,
|
|
82
79
|
this.db,
|
|
@@ -126,12 +123,12 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
126
123
|
|
|
127
124
|
// The first leaf in the blocks tree contains the empty roots of the other trees and empty global variables.
|
|
128
125
|
if (!fromDb) {
|
|
129
|
-
const initialGlobalVariablesHash = computeGlobalsHash(
|
|
126
|
+
const initialGlobalVariablesHash = computeGlobalsHash(GlobalVariables.empty());
|
|
130
127
|
await this._updateLatestGlobalVariablesHash(initialGlobalVariablesHash);
|
|
131
128
|
await this._updateHistoricBlocksTree(initialGlobalVariablesHash, true);
|
|
132
129
|
await this._commit();
|
|
133
130
|
} else {
|
|
134
|
-
await this._updateLatestGlobalVariablesHash(computeGlobalsHash(
|
|
131
|
+
await this._updateLatestGlobalVariablesHash(computeGlobalsHash(fromDbOptions.globalVariables));
|
|
135
132
|
}
|
|
136
133
|
}
|
|
137
134
|
|
|
@@ -141,9 +138,9 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
141
138
|
* @param wasm - WASM instance to use for hashing (if not provided PrimitivesWasm will be used).
|
|
142
139
|
* @returns - A fully initialized MerkleTrees instance.
|
|
143
140
|
*/
|
|
144
|
-
public static async new(db: levelup.LevelUp
|
|
141
|
+
public static async new(db: levelup.LevelUp) {
|
|
145
142
|
const merkleTrees = new MerkleTrees(db);
|
|
146
|
-
await merkleTrees.init(
|
|
143
|
+
await merkleTrees.init();
|
|
147
144
|
return merkleTrees;
|
|
148
145
|
}
|
|
149
146
|
|
|
@@ -226,8 +223,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
226
223
|
|
|
227
224
|
private async _getCurrentBlockHash(globalsHash: Fr, includeUncommitted: boolean): Promise<Fr> {
|
|
228
225
|
const roots = (await this._getAllTreeRoots(includeUncommitted)).map(root => Fr.fromBuffer(root));
|
|
229
|
-
|
|
230
|
-
return computeBlockHash(wasm, globalsHash, roots[0], roots[1], roots[2], roots[3], roots[4]);
|
|
226
|
+
return computeBlockHash(globalsHash, roots[0], roots[1], roots[2], roots[3], roots[4]);
|
|
231
227
|
}
|
|
232
228
|
|
|
233
229
|
private _getAllTreeRoots(includeUncommitted: boolean): Promise<Buffer[]> {
|
|
@@ -574,7 +570,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
574
570
|
}
|
|
575
571
|
|
|
576
572
|
// Sync and add the block to the historic blocks tree
|
|
577
|
-
const globalVariablesHash = computeGlobalsHash(
|
|
573
|
+
const globalVariablesHash = computeGlobalsHash(l2Block.globalVariables);
|
|
578
574
|
await this._updateLatestGlobalVariablesHash(globalVariablesHash);
|
|
579
575
|
this.log(`Synced global variables with hash ${globalVariablesHash}`);
|
|
580
576
|
|