@aztec/world-state 0.20.0 → 0.22.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/synchronizer/server_world_state_synchronizer.d.ts +4 -8
- package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/server_world_state_synchronizer.js +8 -38
- package/dest/world-state-db/merkle_tree_operations.d.ts +11 -35
- package/dest/world-state-db/merkle_tree_operations.d.ts.map +1 -1
- package/dest/world-state-db/merkle_tree_operations.js +1 -1
- package/dest/world-state-db/merkle_tree_operations_facade.d.ts +13 -19
- package/dest/world-state-db/merkle_tree_operations_facade.d.ts.map +1 -1
- package/dest/world-state-db/merkle_tree_operations_facade.js +15 -21
- package/dest/world-state-db/merkle_tree_snapshot_operations_facade.d.ts +5 -7
- package/dest/world-state-db/merkle_tree_snapshot_operations_facade.d.ts.map +1 -1
- package/dest/world-state-db/merkle_tree_snapshot_operations_facade.js +7 -16
- package/dest/world-state-db/merkle_trees.d.ts +17 -92
- package/dest/world-state-db/merkle_trees.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.js +193 -253
- package/package.json +7 -8
|
@@ -1,80 +1,53 @@
|
|
|
1
|
+
var _MerkleTrees_instances, _MerkleTrees_init, _MerkleTrees_updateArchive, _MerkleTrees_getTreeInfo, _MerkleTrees_getIndexedTree, _MerkleTrees_appendLeaves, _MerkleTrees_updateLeaf, _MerkleTrees_commit, _MerkleTrees_rollback, _MerkleTrees_snapshot, _MerkleTrees_handleL2Block, _MerkleTrees_isDbPopulated;
|
|
2
|
+
import { __classPrivateFieldGet } from "tslib";
|
|
1
3
|
import { MerkleTreeId } from '@aztec/circuit-types';
|
|
2
|
-
import { ARCHIVE_HEIGHT, CONTRACT_TREE_HEIGHT, Fr, GlobalVariables, L1_TO_L2_MSG_TREE_HEIGHT, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NOTE_HASH_TREE_HEIGHT, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, NullifierLeaf, NullifierLeafPreimage, PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, PublicDataTreeLeaf, PublicDataTreeLeafPreimage, } from '@aztec/circuits.js';
|
|
3
|
-
import { computeBlockHash, computeGlobalsHash } from '@aztec/circuits.js/abis';
|
|
4
|
-
import { Committable } from '@aztec/foundation/committable';
|
|
4
|
+
import { ARCHIVE_HEIGHT, AppendOnlyTreeSnapshot, CONTRACT_TREE_HEIGHT, Fr, GlobalVariables, Header, L1_TO_L2_MSG_TREE_HEIGHT, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NOTE_HASH_TREE_HEIGHT, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, NullifierLeaf, NullifierLeafPreimage, PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, PartialStateReference, PublicDataTreeLeaf, PublicDataTreeLeafPreimage, StateReference, } from '@aztec/circuits.js';
|
|
5
5
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
6
6
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
7
|
-
import { Pedersen, StandardIndexedTree, StandardTree, loadTree, newTree, } from '@aztec/merkle-tree';
|
|
7
|
+
import { Pedersen, StandardIndexedTree, StandardTree, getTreeMeta, loadTree, newTree, } from '@aztec/merkle-tree';
|
|
8
8
|
import { INITIAL_NULLIFIER_TREE_SIZE, INITIAL_PUBLIC_DATA_TREE_SIZE } from './merkle_tree_db.js';
|
|
9
9
|
import { MerkleTreeOperationsFacade } from './merkle_tree_operations_facade.js';
|
|
10
|
-
const LAST_GLOBAL_VARS_HASH = 'lastGlobalVarsHash';
|
|
11
10
|
/**
|
|
12
11
|
* The nullifier tree is an indexed tree.
|
|
13
12
|
*/
|
|
14
13
|
class NullifierTree extends StandardIndexedTree {
|
|
15
|
-
constructor(
|
|
16
|
-
super(
|
|
14
|
+
constructor(store, hasher, name, depth, size = 0n, root) {
|
|
15
|
+
super(store, hasher, name, depth, size, NullifierLeafPreimage, NullifierLeaf, root);
|
|
17
16
|
}
|
|
18
17
|
}
|
|
19
18
|
/**
|
|
20
19
|
* The public data tree is an indexed tree.
|
|
21
20
|
*/
|
|
22
21
|
class PublicDataTree extends StandardIndexedTree {
|
|
23
|
-
constructor(
|
|
24
|
-
super(
|
|
22
|
+
constructor(store, hasher, name, depth, size = 0n, root) {
|
|
23
|
+
super(store, hasher, name, depth, size, PublicDataTreeLeafPreimage, PublicDataTreeLeaf, root);
|
|
25
24
|
}
|
|
26
25
|
}
|
|
27
26
|
/**
|
|
28
27
|
* A convenience class for managing multiple merkle trees.
|
|
29
28
|
*/
|
|
30
29
|
export class MerkleTrees {
|
|
31
|
-
constructor(
|
|
32
|
-
this
|
|
30
|
+
constructor(store, log) {
|
|
31
|
+
_MerkleTrees_instances.add(this);
|
|
32
|
+
this.store = store;
|
|
33
33
|
this.log = log;
|
|
34
34
|
this.trees = [];
|
|
35
35
|
this.jobQueue = new SerialQueue();
|
|
36
|
-
this.latestGlobalVariablesHash = new Committable(Fr.ZERO);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* initializes the collection of Merkle Trees.
|
|
40
|
-
* @param fromDbOptions - Options to initialize the trees from the database.
|
|
41
|
-
*/
|
|
42
|
-
async init(fromDbOptions) {
|
|
43
|
-
const fromDb = fromDbOptions !== undefined;
|
|
44
|
-
const initializeTree = fromDb ? loadTree : newTree;
|
|
45
|
-
const hasher = new Pedersen();
|
|
46
|
-
const contractTree = await initializeTree(StandardTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.CONTRACT_TREE]}`, CONTRACT_TREE_HEIGHT);
|
|
47
|
-
const nullifierTree = await initializeTree(NullifierTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.NULLIFIER_TREE]}`, NULLIFIER_TREE_HEIGHT, INITIAL_NULLIFIER_TREE_SIZE);
|
|
48
|
-
const noteHashTree = await initializeTree(StandardTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.NOTE_HASH_TREE]}`, NOTE_HASH_TREE_HEIGHT);
|
|
49
|
-
const publicDataTree = await initializeTree(PublicDataTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.PUBLIC_DATA_TREE]}`, PUBLIC_DATA_TREE_HEIGHT, INITIAL_PUBLIC_DATA_TREE_SIZE);
|
|
50
|
-
const l1Tol2MessageTree = await initializeTree(StandardTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]}`, L1_TO_L2_MSG_TREE_HEIGHT);
|
|
51
|
-
const archive = await initializeTree(StandardTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.ARCHIVE]}`, ARCHIVE_HEIGHT);
|
|
52
|
-
this.trees = [contractTree, nullifierTree, noteHashTree, publicDataTree, l1Tol2MessageTree, archive];
|
|
53
|
-
this.jobQueue.start();
|
|
54
|
-
// The first leaf in the blocks tree contains the empty roots of the other trees and empty global variables.
|
|
55
|
-
if (!fromDb) {
|
|
56
|
-
const initialGlobalVariablesHash = computeGlobalsHash(GlobalVariables.empty());
|
|
57
|
-
await this._updateLatestGlobalVariablesHash(initialGlobalVariablesHash);
|
|
58
|
-
await this._updateArchive(initialGlobalVariablesHash, true);
|
|
59
|
-
await this._commit();
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
await this._updateLatestGlobalVariablesHash(fromDbOptions.globalVariablesHash);
|
|
63
|
-
// make the restored global variables hash and tree roots current
|
|
64
|
-
await this._commit();
|
|
65
|
-
}
|
|
66
36
|
}
|
|
67
37
|
/**
|
|
68
38
|
* Method to asynchronously create and initialize a MerkleTrees instance.
|
|
69
|
-
* @param
|
|
39
|
+
* @param store - The db instance to use for data persistance.
|
|
70
40
|
* @returns - A fully initialized MerkleTrees instance.
|
|
71
41
|
*/
|
|
72
|
-
static async new(
|
|
73
|
-
const merkleTrees = new MerkleTrees(
|
|
74
|
-
|
|
75
|
-
await merkleTrees.init(globalVariablesHash ? { globalVariablesHash: Fr.fromBuffer(globalVariablesHash) } : undefined);
|
|
42
|
+
static async new(store, log = createDebugLogger('aztec:merkle_trees')) {
|
|
43
|
+
const merkleTrees = new MerkleTrees(store, log);
|
|
44
|
+
await __classPrivateFieldGet(merkleTrees, _MerkleTrees_instances, "m", _MerkleTrees_init).call(merkleTrees);
|
|
76
45
|
return merkleTrees;
|
|
77
46
|
}
|
|
47
|
+
async buildInitialHeader(includeUncommitted) {
|
|
48
|
+
const state = await this.getStateReference(includeUncommitted);
|
|
49
|
+
return new Header(AppendOnlyTreeSnapshot.zero(), Buffer.alloc(32, 0), state, GlobalVariables.empty());
|
|
50
|
+
}
|
|
78
51
|
/**
|
|
79
52
|
* Stops the job queue (waits for all jobs to finish).
|
|
80
53
|
*/
|
|
@@ -96,27 +69,12 @@ export class MerkleTrees {
|
|
|
96
69
|
return new MerkleTreeOperationsFacade(this, false);
|
|
97
70
|
}
|
|
98
71
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* @param globalsHash - The current global variables hash.
|
|
102
|
-
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
103
|
-
*/
|
|
104
|
-
async updateArchive(globalsHash, includeUncommitted) {
|
|
105
|
-
await this.synchronize(() => this._updateArchive(globalsHash, includeUncommitted));
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Updates the latest global variables hash
|
|
109
|
-
* @param globalVariablesHash - The latest global variables hash
|
|
110
|
-
*/
|
|
111
|
-
async updateLatestGlobalVariablesHash(globalVariablesHash) {
|
|
112
|
-
return await this.synchronize(() => this._updateLatestGlobalVariablesHash(globalVariablesHash));
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Gets the global variables hash from the previous block
|
|
72
|
+
* Updates the archive with the new block/header hash.
|
|
73
|
+
* @param header - The header whose hash to insert into the archive.
|
|
116
74
|
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
117
75
|
*/
|
|
118
|
-
async
|
|
119
|
-
|
|
76
|
+
async updateArchive(header, includeUncommitted) {
|
|
77
|
+
await this.synchronize(() => __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_updateArchive).call(this, header, includeUncommitted));
|
|
120
78
|
}
|
|
121
79
|
/**
|
|
122
80
|
* Gets the tree info for the specified tree.
|
|
@@ -125,38 +83,20 @@ export class MerkleTrees {
|
|
|
125
83
|
* @returns The tree info for the specified tree.
|
|
126
84
|
*/
|
|
127
85
|
async getTreeInfo(treeId, includeUncommitted) {
|
|
128
|
-
return await this.synchronize(() => this.
|
|
86
|
+
return await this.synchronize(() => __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_getTreeInfo).call(this, treeId, includeUncommitted));
|
|
129
87
|
}
|
|
130
88
|
/**
|
|
131
|
-
* Get the current
|
|
89
|
+
* Get the current state reference
|
|
132
90
|
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
133
|
-
* @returns The current
|
|
91
|
+
* @returns The current state reference
|
|
134
92
|
*/
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
nullifierTreeRoot: roots[1],
|
|
140
|
-
contractDataTreeRoot: roots[2],
|
|
141
|
-
l1Tol2MessageTreeRoot: roots[3],
|
|
142
|
-
publicDataTreeRoot: roots[4],
|
|
143
|
-
archiveRoot: roots[5],
|
|
93
|
+
getStateReference(includeUncommitted) {
|
|
94
|
+
const getAppendOnlyTreeSnapshot = (treeId) => {
|
|
95
|
+
const tree = this.trees[treeId];
|
|
96
|
+
return new AppendOnlyTreeSnapshot(Fr.fromBuffer(tree.getRoot(includeUncommitted)), Number(tree.getNumLeaves(includeUncommitted)));
|
|
144
97
|
};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const roots = (await this._getAllTreeRoots(includeUncommitted)).map(root => Fr.fromBuffer(root));
|
|
148
|
-
return computeBlockHash(globalsHash, roots[0], roots[1], roots[2], roots[3], roots[4]);
|
|
149
|
-
}
|
|
150
|
-
_getAllTreeRoots(includeUncommitted) {
|
|
151
|
-
const roots = [
|
|
152
|
-
MerkleTreeId.NOTE_HASH_TREE,
|
|
153
|
-
MerkleTreeId.NULLIFIER_TREE,
|
|
154
|
-
MerkleTreeId.CONTRACT_TREE,
|
|
155
|
-
MerkleTreeId.L1_TO_L2_MESSAGE_TREE,
|
|
156
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
157
|
-
MerkleTreeId.ARCHIVE,
|
|
158
|
-
].map(tree => this.trees[tree].getRoot(includeUncommitted));
|
|
159
|
-
return Promise.resolve(roots);
|
|
98
|
+
const state = new StateReference(getAppendOnlyTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE), new PartialStateReference(getAppendOnlyTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE), getAppendOnlyTreeSnapshot(MerkleTreeId.NULLIFIER_TREE), getAppendOnlyTreeSnapshot(MerkleTreeId.CONTRACT_TREE), getAppendOnlyTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)));
|
|
99
|
+
return Promise.resolve(state);
|
|
160
100
|
}
|
|
161
101
|
/**
|
|
162
102
|
* Gets the value at the given index.
|
|
@@ -166,7 +106,7 @@ export class MerkleTrees {
|
|
|
166
106
|
* @returns Leaf value at the given index (undefined if not found).
|
|
167
107
|
*/
|
|
168
108
|
async getLeafValue(treeId, index, includeUncommitted) {
|
|
169
|
-
return await this.synchronize(() => this.trees[treeId].getLeafValue(index, includeUncommitted));
|
|
109
|
+
return await this.synchronize(() => Promise.resolve(this.trees[treeId].getLeafValue(index, includeUncommitted)));
|
|
170
110
|
}
|
|
171
111
|
/**
|
|
172
112
|
* Gets the sibling path for a leaf in a tree.
|
|
@@ -176,7 +116,7 @@ export class MerkleTrees {
|
|
|
176
116
|
* @returns The sibling path for the leaf.
|
|
177
117
|
*/
|
|
178
118
|
async getSiblingPath(treeId, index, includeUncommitted) {
|
|
179
|
-
return await this.synchronize(() => this.
|
|
119
|
+
return await this.synchronize(() => this.trees[treeId].getSiblingPath(index, includeUncommitted));
|
|
180
120
|
}
|
|
181
121
|
/**
|
|
182
122
|
* Appends leaves to a tree.
|
|
@@ -185,21 +125,21 @@ export class MerkleTrees {
|
|
|
185
125
|
* @returns Empty promise.
|
|
186
126
|
*/
|
|
187
127
|
async appendLeaves(treeId, leaves) {
|
|
188
|
-
return await this.synchronize(() => this.
|
|
128
|
+
return await this.synchronize(() => __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_appendLeaves).call(this, treeId, leaves));
|
|
189
129
|
}
|
|
190
130
|
/**
|
|
191
131
|
* Commits all pending updates.
|
|
192
132
|
* @returns Empty promise.
|
|
193
133
|
*/
|
|
194
134
|
async commit() {
|
|
195
|
-
return await this.synchronize(() => this.
|
|
135
|
+
return await this.synchronize(() => __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_commit).call(this));
|
|
196
136
|
}
|
|
197
137
|
/**
|
|
198
138
|
* Rolls back all pending updates.
|
|
199
139
|
* @returns Empty promise.
|
|
200
140
|
*/
|
|
201
141
|
async rollback() {
|
|
202
|
-
return await this.synchronize(() => this.
|
|
142
|
+
return await this.synchronize(() => __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_rollback).call(this));
|
|
203
143
|
}
|
|
204
144
|
/**
|
|
205
145
|
* Finds the index of the largest leaf whose value is less than or equal to the provided value.
|
|
@@ -209,7 +149,7 @@ export class MerkleTrees {
|
|
|
209
149
|
* @returns The found leaf index and a flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
210
150
|
*/
|
|
211
151
|
async getPreviousValueIndex(treeId, value, includeUncommitted) {
|
|
212
|
-
return await this.synchronize(() => this.
|
|
152
|
+
return await this.synchronize(() => Promise.resolve(__classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_getIndexedTree).call(this, treeId).findIndexOfPreviousKey(value, includeUncommitted)));
|
|
213
153
|
}
|
|
214
154
|
/**
|
|
215
155
|
* Gets the leaf data at a given index and tree.
|
|
@@ -219,7 +159,7 @@ export class MerkleTrees {
|
|
|
219
159
|
* @returns Leaf preimage.
|
|
220
160
|
*/
|
|
221
161
|
async getLeafPreimage(treeId, index, includeUncommitted) {
|
|
222
|
-
return await this.synchronize(() => this.
|
|
162
|
+
return await this.synchronize(() => Promise.resolve(__classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_getIndexedTree).call(this, treeId).getLatestLeafPreimageCopy(index, includeUncommitted)));
|
|
223
163
|
}
|
|
224
164
|
/**
|
|
225
165
|
* Returns the index of a leaf given its value, or undefined if no leaf with that value is found.
|
|
@@ -229,9 +169,9 @@ export class MerkleTrees {
|
|
|
229
169
|
* @returns The index of the first leaf found with a given value (undefined if not found).
|
|
230
170
|
*/
|
|
231
171
|
async findLeafIndex(treeId, value, includeUncommitted) {
|
|
232
|
-
return await this.synchronize(
|
|
172
|
+
return await this.synchronize(() => {
|
|
233
173
|
const tree = this.trees[treeId];
|
|
234
|
-
return
|
|
174
|
+
return Promise.resolve(tree.findLeafIndex(value, includeUncommitted));
|
|
235
175
|
});
|
|
236
176
|
}
|
|
237
177
|
/**
|
|
@@ -242,7 +182,7 @@ export class MerkleTrees {
|
|
|
242
182
|
* @returns Empty promise.
|
|
243
183
|
*/
|
|
244
184
|
async updateLeaf(treeId, leaf, index) {
|
|
245
|
-
return await this.synchronize(() => this.
|
|
185
|
+
return await this.synchronize(() => __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_updateLeaf).call(this, treeId, leaf, index));
|
|
246
186
|
}
|
|
247
187
|
/**
|
|
248
188
|
* Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree).
|
|
@@ -250,7 +190,7 @@ export class MerkleTrees {
|
|
|
250
190
|
* @returns Whether the block handled was produced by this same node.
|
|
251
191
|
*/
|
|
252
192
|
async handleL2Block(block) {
|
|
253
|
-
return await this.synchronize(() => this.
|
|
193
|
+
return await this.synchronize(() => __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_handleL2Block).call(this, block));
|
|
254
194
|
}
|
|
255
195
|
/**
|
|
256
196
|
* Batch insert multiple leaves into the tree.
|
|
@@ -274,164 +214,164 @@ export class MerkleTrees {
|
|
|
274
214
|
async synchronize(fn) {
|
|
275
215
|
return await this.jobQueue.put(fn);
|
|
276
216
|
}
|
|
277
|
-
|
|
278
|
-
this.
|
|
279
|
-
return Promise.resolve();
|
|
280
|
-
}
|
|
281
|
-
_getGlobalVariablesHash(includeUncommitted) {
|
|
282
|
-
return Promise.resolve(this.latestGlobalVariablesHash.get(includeUncommitted));
|
|
283
|
-
}
|
|
284
|
-
async _updateArchive(globalsHash, includeUncommitted) {
|
|
285
|
-
const blockHash = await this._getCurrentBlockHash(globalsHash, includeUncommitted);
|
|
286
|
-
await this._appendLeaves(MerkleTreeId.ARCHIVE, [blockHash.toBuffer()]);
|
|
217
|
+
getSnapshot(blockNumber) {
|
|
218
|
+
return Promise.all(this.trees.map(tree => tree.getSnapshot(blockNumber)));
|
|
287
219
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
220
|
+
}
|
|
221
|
+
_MerkleTrees_instances = new WeakSet(), _MerkleTrees_init =
|
|
222
|
+
/**
|
|
223
|
+
* Initializes the collection of Merkle Trees.
|
|
224
|
+
*/
|
|
225
|
+
async function _MerkleTrees_init() {
|
|
226
|
+
const fromDb = __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_isDbPopulated).call(this);
|
|
227
|
+
const initializeTree = fromDb ? loadTree : newTree;
|
|
228
|
+
const hasher = new Pedersen();
|
|
229
|
+
const contractTree = await initializeTree(StandardTree, this.store, hasher, `${MerkleTreeId[MerkleTreeId.CONTRACT_TREE]}`, CONTRACT_TREE_HEIGHT);
|
|
230
|
+
const nullifierTree = await initializeTree(NullifierTree, this.store, hasher, `${MerkleTreeId[MerkleTreeId.NULLIFIER_TREE]}`, NULLIFIER_TREE_HEIGHT, INITIAL_NULLIFIER_TREE_SIZE);
|
|
231
|
+
const noteHashTree = await initializeTree(StandardTree, this.store, hasher, `${MerkleTreeId[MerkleTreeId.NOTE_HASH_TREE]}`, NOTE_HASH_TREE_HEIGHT);
|
|
232
|
+
const publicDataTree = await initializeTree(PublicDataTree, this.store, hasher, `${MerkleTreeId[MerkleTreeId.PUBLIC_DATA_TREE]}`, PUBLIC_DATA_TREE_HEIGHT, INITIAL_PUBLIC_DATA_TREE_SIZE);
|
|
233
|
+
const l1Tol2MessageTree = await initializeTree(StandardTree, this.store, hasher, `${MerkleTreeId[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]}`, L1_TO_L2_MSG_TREE_HEIGHT);
|
|
234
|
+
const archive = await initializeTree(StandardTree, this.store, hasher, `${MerkleTreeId[MerkleTreeId.ARCHIVE]}`, ARCHIVE_HEIGHT);
|
|
235
|
+
this.trees = [contractTree, nullifierTree, noteHashTree, publicDataTree, l1Tol2MessageTree, archive];
|
|
236
|
+
this.jobQueue.start();
|
|
237
|
+
if (!fromDb) {
|
|
238
|
+
// We are not initializing from db so we need to populate the first leaf of the archive tree which is a hash of
|
|
239
|
+
// the initial header.
|
|
240
|
+
const initialHeder = await this.buildInitialHeader(true);
|
|
241
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_updateArchive).call(this, initialHeder, true);
|
|
242
|
+
}
|
|
243
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_commit).call(this);
|
|
244
|
+
}, _MerkleTrees_updateArchive = async function _MerkleTrees_updateArchive(header, includeUncommitted) {
|
|
245
|
+
const state = await this.getStateReference(includeUncommitted);
|
|
246
|
+
// This method should be called only when the block builder already updated the state so we sanity check that it's
|
|
247
|
+
// the case here.
|
|
248
|
+
if (!state.toBuffer().equals(header.state.toBuffer())) {
|
|
249
|
+
throw new Error('State in header does not match current state');
|
|
250
|
+
}
|
|
251
|
+
const blockHash = header.hash();
|
|
252
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_appendLeaves).call(this, MerkleTreeId.ARCHIVE, [blockHash.toBuffer()]);
|
|
253
|
+
}, _MerkleTrees_getTreeInfo = function _MerkleTrees_getTreeInfo(treeId, includeUncommitted) {
|
|
254
|
+
const treeInfo = {
|
|
255
|
+
treeId,
|
|
256
|
+
root: this.trees[treeId].getRoot(includeUncommitted),
|
|
257
|
+
size: this.trees[treeId].getNumLeaves(includeUncommitted),
|
|
258
|
+
depth: this.trees[treeId].getDepth(),
|
|
259
|
+
};
|
|
260
|
+
return Promise.resolve(treeInfo);
|
|
261
|
+
}, _MerkleTrees_getIndexedTree = function _MerkleTrees_getIndexedTree(treeId) {
|
|
262
|
+
return this.trees[treeId];
|
|
263
|
+
}, _MerkleTrees_appendLeaves =
|
|
264
|
+
/**
|
|
265
|
+
* Appends leaves to a tree.
|
|
266
|
+
* @param treeId - Id of the tree to append leaves to.
|
|
267
|
+
* @param leaves - Leaves to append.
|
|
268
|
+
* @returns Empty promise.
|
|
269
|
+
*/
|
|
270
|
+
async function _MerkleTrees_appendLeaves(treeId, leaves) {
|
|
271
|
+
const tree = this.trees[treeId];
|
|
272
|
+
if (!('appendLeaves' in tree)) {
|
|
273
|
+
throw new Error('Tree does not support `appendLeaves` method');
|
|
274
|
+
}
|
|
275
|
+
return await tree.appendLeaves(leaves);
|
|
276
|
+
}, _MerkleTrees_updateLeaf = async function _MerkleTrees_updateLeaf(treeId, leaf, index) {
|
|
277
|
+
const tree = this.trees[treeId];
|
|
278
|
+
if (!('updateLeaf' in tree)) {
|
|
279
|
+
throw new Error('Tree does not support `updateLeaf` method');
|
|
280
|
+
}
|
|
281
|
+
return await tree.updateLeaf(leaf, index);
|
|
282
|
+
}, _MerkleTrees_commit =
|
|
283
|
+
/**
|
|
284
|
+
* Commits all pending updates.
|
|
285
|
+
* @returns Empty promise.
|
|
286
|
+
*/
|
|
287
|
+
async function _MerkleTrees_commit() {
|
|
288
|
+
for (const tree of this.trees) {
|
|
289
|
+
await tree.commit();
|
|
302
290
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
291
|
+
}, _MerkleTrees_rollback =
|
|
292
|
+
/**
|
|
293
|
+
* Rolls back all pending updates.
|
|
294
|
+
* @returns Empty promise.
|
|
295
|
+
*/
|
|
296
|
+
async function _MerkleTrees_rollback() {
|
|
297
|
+
for (const tree of this.trees) {
|
|
298
|
+
await tree.rollback();
|
|
310
299
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
* @param index - Index of the leaf to get the sibling path for.
|
|
315
|
-
* @param includeUncommitted - Indicates whether to include uncommitted updates in the sibling path.
|
|
316
|
-
* @returns Promise containing the sibling path for the leaf.
|
|
317
|
-
*/
|
|
318
|
-
_getSiblingPath(treeId, index, includeUncommitted) {
|
|
319
|
-
return Promise.resolve(this.trees[treeId].getSiblingPath(index, includeUncommitted));
|
|
300
|
+
}, _MerkleTrees_snapshot = async function _MerkleTrees_snapshot(blockNumber) {
|
|
301
|
+
for (const tree of this.trees) {
|
|
302
|
+
await tree.snapshot(blockNumber);
|
|
320
303
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
304
|
+
}, _MerkleTrees_handleL2Block =
|
|
305
|
+
/**
|
|
306
|
+
* Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree).
|
|
307
|
+
* @param l2Block - The L2 block to handle.
|
|
308
|
+
*/
|
|
309
|
+
async function _MerkleTrees_handleL2Block(l2Block) {
|
|
310
|
+
const treeRootWithIdPairs = [
|
|
311
|
+
[l2Block.header.state.partial.contractTree.root, MerkleTreeId.CONTRACT_TREE],
|
|
312
|
+
[l2Block.header.state.partial.nullifierTree.root, MerkleTreeId.NULLIFIER_TREE],
|
|
313
|
+
[l2Block.header.state.partial.noteHashTree.root, MerkleTreeId.NOTE_HASH_TREE],
|
|
314
|
+
[l2Block.header.state.partial.publicDataTree.root, MerkleTreeId.PUBLIC_DATA_TREE],
|
|
315
|
+
[l2Block.header.state.l1ToL2MessageTree.root, MerkleTreeId.L1_TO_L2_MESSAGE_TREE],
|
|
316
|
+
[l2Block.archive.root, MerkleTreeId.ARCHIVE],
|
|
317
|
+
];
|
|
318
|
+
const compareRoot = (root, treeId) => {
|
|
319
|
+
const treeRoot = this.trees[treeId].getRoot(true);
|
|
320
|
+
return treeRoot.equals(root.toBuffer());
|
|
321
|
+
};
|
|
322
|
+
const ourBlock = treeRootWithIdPairs.every(([root, id]) => compareRoot(root, id));
|
|
323
|
+
if (ourBlock) {
|
|
324
|
+
this.log(`Block ${l2Block.number} is ours, committing world state`);
|
|
325
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_commit).call(this);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
this.log(`Block ${l2Block.number} is not ours, rolling back world state and committing state from chain`);
|
|
329
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_rollback).call(this);
|
|
330
|
+
// Sync the append only trees
|
|
331
|
+
for (const [tree, leaves] of [
|
|
332
|
+
[MerkleTreeId.CONTRACT_TREE, l2Block.newContracts],
|
|
333
|
+
[MerkleTreeId.NOTE_HASH_TREE, l2Block.newCommitments],
|
|
334
|
+
[MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l2Block.newL1ToL2Messages],
|
|
335
|
+
]) {
|
|
336
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_appendLeaves).call(this, tree, leaves.map(fr => fr.toBuffer()));
|
|
331
337
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
+
// Sync the indexed trees
|
|
339
|
+
await this.trees[MerkleTreeId.NULLIFIER_TREE].batchInsert(l2Block.newNullifiers.map(fr => fr.toBuffer()), NULLIFIER_SUBTREE_HEIGHT);
|
|
340
|
+
const publicDataTree = this.trees[MerkleTreeId.PUBLIC_DATA_TREE];
|
|
341
|
+
// We insert the public data tree leaves with one batch per tx to avoid updating the same key twice
|
|
342
|
+
for (let i = 0; i < l2Block.newPublicDataWrites.length / MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; i++) {
|
|
343
|
+
await publicDataTree.batchInsert(l2Block.newPublicDataWrites
|
|
344
|
+
.slice(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * i, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * (i + 1))
|
|
345
|
+
.map(write => new PublicDataTreeLeaf(write.leafIndex, write.newValue).toBuffer()), PUBLIC_DATA_SUBTREE_HEIGHT);
|
|
338
346
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
347
|
+
// The last thing remaining is to update the archive
|
|
348
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_updateArchive).call(this, l2Block.header, true);
|
|
349
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_commit).call(this);
|
|
350
|
+
}
|
|
351
|
+
for (const [root, treeId] of treeRootWithIdPairs) {
|
|
352
|
+
const treeName = MerkleTreeId[treeId];
|
|
353
|
+
const info = await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_getTreeInfo).call(this, treeId, false);
|
|
354
|
+
const syncedStr = '0x' + info.root.toString('hex');
|
|
355
|
+
const rootStr = root.toString();
|
|
356
|
+
// Sanity check that the rebuilt trees match the roots published by the L2 block
|
|
357
|
+
if (!info.root.equals(root.toBuffer())) {
|
|
358
|
+
throw new Error(`Synced tree root ${treeName} does not match published L2 block root: ${syncedStr} != ${rootStr}`);
|
|
348
359
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Rolls back all pending updates.
|
|
354
|
-
* @returns Empty promise.
|
|
355
|
-
*/
|
|
356
|
-
async _rollback() {
|
|
357
|
-
for (const tree of this.trees) {
|
|
358
|
-
await tree.rollback();
|
|
360
|
+
else {
|
|
361
|
+
this.log(`Tree ${treeName} synched with size ${info.size} root ${rootStr}`);
|
|
359
362
|
}
|
|
360
|
-
this.latestGlobalVariablesHash.rollback();
|
|
361
363
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
364
|
+
await __classPrivateFieldGet(this, _MerkleTrees_instances, "m", _MerkleTrees_snapshot).call(this, l2Block.number);
|
|
365
|
+
return { isBlockOurs: ourBlock };
|
|
366
|
+
}, _MerkleTrees_isDbPopulated = function _MerkleTrees_isDbPopulated() {
|
|
367
|
+
try {
|
|
368
|
+
getTreeMeta(this.store, MerkleTreeId[MerkleTreeId.NULLIFIER_TREE]);
|
|
369
|
+
// Tree meta was found --> db is populated
|
|
370
|
+
return true;
|
|
369
371
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
*/
|
|
374
|
-
async _handleL2Block(l2Block) {
|
|
375
|
-
const treeRootWithIdPairs = [
|
|
376
|
-
[l2Block.header.state.partial.contractTree.root, MerkleTreeId.CONTRACT_TREE],
|
|
377
|
-
[l2Block.header.state.partial.nullifierTree.root, MerkleTreeId.NULLIFIER_TREE],
|
|
378
|
-
[l2Block.header.state.partial.noteHashTree.root, MerkleTreeId.NOTE_HASH_TREE],
|
|
379
|
-
[l2Block.header.state.partial.publicDataTree.root, MerkleTreeId.PUBLIC_DATA_TREE],
|
|
380
|
-
[l2Block.header.state.l1ToL2MessageTree.root, MerkleTreeId.L1_TO_L2_MESSAGE_TREE],
|
|
381
|
-
[l2Block.archive.root, MerkleTreeId.ARCHIVE],
|
|
382
|
-
];
|
|
383
|
-
const compareRoot = (root, treeId) => {
|
|
384
|
-
const treeRoot = this.trees[treeId].getRoot(true);
|
|
385
|
-
return treeRoot.equals(root.toBuffer());
|
|
386
|
-
};
|
|
387
|
-
const ourBlock = treeRootWithIdPairs.every(([root, id]) => compareRoot(root, id));
|
|
388
|
-
if (ourBlock) {
|
|
389
|
-
this.log(`Block ${l2Block.number} is ours, committing world state`);
|
|
390
|
-
await this._commit();
|
|
391
|
-
}
|
|
392
|
-
else {
|
|
393
|
-
this.log(`Block ${l2Block.number} is not ours, rolling back world state and committing state from chain`);
|
|
394
|
-
await this._rollback();
|
|
395
|
-
// Sync the append only trees
|
|
396
|
-
for (const [tree, leaves] of [
|
|
397
|
-
[MerkleTreeId.CONTRACT_TREE, l2Block.newContracts],
|
|
398
|
-
[MerkleTreeId.NOTE_HASH_TREE, l2Block.newCommitments],
|
|
399
|
-
[MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l2Block.newL1ToL2Messages],
|
|
400
|
-
]) {
|
|
401
|
-
await this._appendLeaves(tree, leaves.map(fr => fr.toBuffer()));
|
|
402
|
-
}
|
|
403
|
-
// Sync the indexed trees
|
|
404
|
-
await this.trees[MerkleTreeId.NULLIFIER_TREE].batchInsert(l2Block.newNullifiers.map(fr => fr.toBuffer()), NULLIFIER_SUBTREE_HEIGHT);
|
|
405
|
-
const publicDataTree = this.trees[MerkleTreeId.PUBLIC_DATA_TREE];
|
|
406
|
-
// We insert the public data tree leaves with one batch per tx to avoid updating the same key twice
|
|
407
|
-
for (let i = 0; i < l2Block.newPublicDataWrites.length / MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; i++) {
|
|
408
|
-
await publicDataTree.batchInsert(l2Block.newPublicDataWrites
|
|
409
|
-
.slice(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * i, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * (i + 1))
|
|
410
|
-
.map(write => new PublicDataTreeLeaf(write.leafIndex, write.newValue).toBuffer()), PUBLIC_DATA_SUBTREE_HEIGHT);
|
|
411
|
-
}
|
|
412
|
-
// Sync and add the block to the blocks tree
|
|
413
|
-
const globalVariablesHash = computeGlobalsHash(l2Block.header.globalVariables);
|
|
414
|
-
await this._updateLatestGlobalVariablesHash(globalVariablesHash);
|
|
415
|
-
this.log(`Synced global variables with hash ${globalVariablesHash}`);
|
|
416
|
-
const blockHash = await this._getCurrentBlockHash(globalVariablesHash, true);
|
|
417
|
-
await this._appendLeaves(MerkleTreeId.ARCHIVE, [blockHash.toBuffer()]);
|
|
418
|
-
await this._commit();
|
|
419
|
-
}
|
|
420
|
-
for (const [root, treeId] of treeRootWithIdPairs) {
|
|
421
|
-
const treeName = MerkleTreeId[treeId];
|
|
422
|
-
const info = await this._getTreeInfo(treeId, false);
|
|
423
|
-
const syncedStr = '0x' + info.root.toString('hex');
|
|
424
|
-
const rootStr = root.toString();
|
|
425
|
-
// Sanity check that the rebuilt trees match the roots published by the L2 block
|
|
426
|
-
if (!info.root.equals(root.toBuffer())) {
|
|
427
|
-
throw new Error(`Synced tree root ${treeName} does not match published L2 block root: ${syncedStr} != ${rootStr}`);
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
this.log(`Tree ${treeName} synched with size ${info.size} root ${rootStr}`);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
await this._snapshot(l2Block.number);
|
|
434
|
-
return { isBlockOurs: ourBlock };
|
|
372
|
+
catch (e) {
|
|
373
|
+
// Tree meta was not found --> db is not populated
|
|
374
|
+
return false;
|
|
435
375
|
}
|
|
436
|
-
}
|
|
437
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVya2xlX3RyZWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dvcmxkLXN0YXRlLWRiL21lcmtsZV90cmVlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVcsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0QsT0FBTyxFQUNMLGNBQWMsRUFDZCxvQkFBb0IsRUFDcEIsRUFBRSxFQUNGLGVBQWUsRUFDZix3QkFBd0IsRUFDeEIsc0NBQXNDLEVBQ3RDLHFCQUFxQixFQUNyQix3QkFBd0IsRUFDeEIscUJBQXFCLEVBQ3JCLGFBQWEsRUFDYixxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLHVCQUF1QixFQUN2QixrQkFBa0IsRUFDbEIsMEJBQTBCLEdBQzNCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDL0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzVELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRCxPQUFPLEVBSUwsUUFBUSxFQUNSLG1CQUFtQixFQUNuQixZQUFZLEVBRVosUUFBUSxFQUNSLE9BQU8sR0FDUixNQUFNLG9CQUFvQixDQUFDO0FBTTVCLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSw2QkFBNkIsRUFBZ0IsTUFBTSxxQkFBcUIsQ0FBQztBQVEvRyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQVloRixNQUFNLHFCQUFxQixHQUFHLG9CQUFvQixDQUFDO0FBRW5EOztHQUVHO0FBQ0gsTUFBTSxhQUFjLFNBQVEsbUJBQW1CO0lBQzdDLFlBQVksRUFBbUIsRUFBRSxNQUFjLEVBQUUsSUFBWSxFQUFFLEtBQWEsRUFBRSxPQUFlLEVB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
|
|
376
|
+
};
|
|
377
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVya2xlX3RyZWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dvcmxkLXN0YXRlLWRiL21lcmtsZV90cmVlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBVyxZQUFZLEVBQWUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxRSxPQUFPLEVBQ0wsY0FBYyxFQUNkLHNCQUFzQixFQUN0QixvQkFBb0IsRUFDcEIsRUFBRSxFQUNGLGVBQWUsRUFDZixNQUFNLEVBQ04sd0JBQXdCLEVBQ3hCLHNDQUFzQyxFQUN0QyxxQkFBcUIsRUFDckIsd0JBQXdCLEVBQ3hCLHFCQUFxQixFQUNyQixhQUFhLEVBQ2IscUJBQXFCLEVBQ3JCLDBCQUEwQixFQUMxQix1QkFBdUIsRUFDdkIscUJBQXFCLEVBQ3JCLGtCQUFrQixFQUNsQiwwQkFBMEIsRUFDMUIsY0FBYyxHQUNmLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBZSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBR3ZFLE9BQU8sRUFJTCxRQUFRLEVBQ1IsbUJBQW1CLEVBQ25CLFlBQVksRUFFWixXQUFXLEVBQ1gsUUFBUSxFQUNSLE9BQU8sR0FDUixNQUFNLG9CQUFvQixDQUFDO0FBRzVCLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSw2QkFBNkIsRUFBZ0IsTUFBTSxxQkFBcUIsQ0FBQztBQUUvRyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUVoRjs7R0FFRztBQUNILE1BQU0sYUFBYyxTQUFRLG1CQUFtQjtJQUM3QyxZQUFZLEtBQW1CLEVBQUUsTUFBYyxFQUFFLElBQVksRUFBRSxLQUFhLEVBQUUsT0FBZSxFQUFFLEVBQUUsSUFBYTtRQUM1RyxLQUFLLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFB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
|