@aztec/merkle-tree 0.16.1 → 0.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/index.d.ts +5 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +6 -2
- package/dest/interfaces/append_only_tree.d.ts +2 -1
- package/dest/interfaces/append_only_tree.d.ts.map +1 -1
- package/dest/interfaces/indexed_tree.d.ts +38 -17
- package/dest/interfaces/indexed_tree.d.ts.map +1 -1
- package/dest/interfaces/merkle_tree.d.ts +7 -0
- package/dest/interfaces/merkle_tree.d.ts.map +1 -1
- package/dest/interfaces/update_only_tree.d.ts +3 -3
- package/dest/interfaces/update_only_tree.d.ts.map +1 -1
- package/dest/load_tree.d.ts +2 -1
- package/dest/load_tree.d.ts.map +1 -1
- package/dest/load_tree.js +1 -2
- package/dest/new_tree.d.ts +1 -1
- package/dest/new_tree.d.ts.map +1 -1
- package/dest/new_tree.js +2 -2
- package/dest/snapshots/append_only_snapshot.d.ts +30 -0
- package/dest/snapshots/append_only_snapshot.d.ts.map +1 -0
- package/dest/snapshots/append_only_snapshot.js +200 -0
- package/dest/snapshots/base_full_snapshot.d.ts +50 -0
- package/dest/snapshots/base_full_snapshot.d.ts.map +1 -0
- package/dest/snapshots/base_full_snapshot.js +179 -0
- package/dest/snapshots/full_snapshot.d.ts +22 -0
- package/dest/snapshots/full_snapshot.d.ts.map +1 -0
- package/dest/snapshots/full_snapshot.js +21 -0
- package/dest/snapshots/indexed_tree_snapshot.d.ts +15 -0
- package/dest/snapshots/indexed_tree_snapshot.d.ts.map +1 -0
- package/dest/snapshots/indexed_tree_snapshot.js +75 -0
- package/dest/snapshots/snapshot_builder.d.ts +76 -0
- package/dest/snapshots/snapshot_builder.d.ts.map +1 -0
- package/dest/snapshots/snapshot_builder.js +2 -0
- package/dest/snapshots/snapshot_builder_test_suite.d.ts +5 -0
- package/dest/snapshots/snapshot_builder_test_suite.d.ts.map +1 -0
- package/dest/snapshots/snapshot_builder_test_suite.js +163 -0
- package/dest/sparse_tree/sparse_tree.d.ts +5 -0
- package/dest/sparse_tree/sparse_tree.d.ts.map +1 -1
- package/dest/sparse_tree/sparse_tree.js +18 -1
- package/dest/standard_indexed_tree/standard_indexed_tree.d.ts +111 -81
- package/dest/standard_indexed_tree/standard_indexed_tree.d.ts.map +1 -1
- package/dest/standard_indexed_tree/standard_indexed_tree.js +225 -259
- package/dest/standard_indexed_tree/test/standard_indexed_tree_with_append.d.ts.map +1 -1
- package/dest/standard_indexed_tree/test/standard_indexed_tree_with_append.js +13 -19
- package/dest/standard_tree/standard_tree.d.ts +5 -0
- package/dest/standard_tree/standard_tree.d.ts.map +1 -1
- package/dest/standard_tree/standard_tree.js +24 -1
- package/dest/tree_base.d.ts +9 -4
- package/dest/tree_base.d.ts.map +1 -1
- package/dest/tree_base.js +16 -7
- package/package.json +4 -3
- package/src/index.ts +5 -1
- package/src/interfaces/append_only_tree.ts +2 -1
- package/src/interfaces/indexed_tree.ts +50 -28
- package/src/interfaces/merkle_tree.ts +8 -0
- package/src/interfaces/update_only_tree.ts +3 -4
- package/src/load_tree.ts +2 -2
- package/src/new_tree.ts +2 -2
- package/src/snapshots/append_only_snapshot.ts +243 -0
- package/src/snapshots/base_full_snapshot.ts +232 -0
- package/src/snapshots/full_snapshot.ts +26 -0
- package/src/snapshots/indexed_tree_snapshot.ts +108 -0
- package/src/snapshots/snapshot_builder.ts +84 -0
- package/src/snapshots/snapshot_builder_test_suite.ts +218 -0
- package/src/sparse_tree/sparse_tree.ts +16 -0
- package/src/standard_indexed_tree/standard_indexed_tree.ts +325 -304
- package/src/standard_indexed_tree/test/standard_indexed_tree_with_append.ts +23 -21
- package/src/standard_tree/standard_tree.ts +21 -0
- package/src/tree_base.ts +28 -7
|
@@ -1,57 +1,39 @@
|
|
|
1
|
+
var _StandardIndexedTree_snapshotBuilder;
|
|
2
|
+
import { __classPrivateFieldGet } from "tslib";
|
|
1
3
|
import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer';
|
|
2
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
5
|
import { SiblingPath } from '@aztec/types';
|
|
6
|
+
import { IndexedTreeSnapshotBuilder, } from '../index.js';
|
|
4
7
|
import { TreeBase } from '../tree_base.js';
|
|
5
8
|
const log = createDebugLogger('aztec:standard-indexed-tree');
|
|
6
|
-
const
|
|
7
|
-
return `${name}:
|
|
9
|
+
export const buildDbKeyForPreimage = (name, index) => {
|
|
10
|
+
return `${name}:leaf_by_index:${toBufferBE(index, 32).toString('hex')}`;
|
|
8
11
|
};
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
return toBigIntBE(Buffer.from(index, 'hex'));
|
|
12
|
-
};
|
|
13
|
-
const zeroLeaf = {
|
|
14
|
-
value: 0n,
|
|
15
|
-
nextValue: 0n,
|
|
16
|
-
nextIndex: 0n,
|
|
12
|
+
export const buildDbKeyForLeafIndex = (name, key) => {
|
|
13
|
+
return `${name}:leaf_index_by_leaf_key:${toBufferBE(key, 32).toString('hex')}`;
|
|
17
14
|
};
|
|
18
15
|
/**
|
|
19
16
|
* Pre-compute empty witness.
|
|
20
17
|
* @param treeHeight - Height of tree for sibling path.
|
|
21
18
|
* @returns An empty witness.
|
|
22
19
|
*/
|
|
23
|
-
function getEmptyLowLeafWitness(treeHeight) {
|
|
20
|
+
function getEmptyLowLeafWitness(treeHeight, leafPreimageFactory) {
|
|
24
21
|
return {
|
|
25
|
-
|
|
22
|
+
leafPreimage: leafPreimageFactory.empty(),
|
|
26
23
|
index: 0n,
|
|
27
24
|
siblingPath: new SiblingPath(treeHeight, Array(treeHeight).fill(toBufferBE(0n, 32))),
|
|
28
25
|
};
|
|
29
26
|
}
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
31
|
-
const encodeTreeValue = (leafData) => {
|
|
32
|
-
const valueAsBuffer = toBufferBE(leafData.value, 32);
|
|
33
|
-
const indexAsBuffer = toBufferBE(leafData.nextIndex, 32);
|
|
34
|
-
const nextValueAsBuffer = toBufferBE(leafData.nextValue, 32);
|
|
35
|
-
return Buffer.concat([valueAsBuffer, indexAsBuffer, nextValueAsBuffer]);
|
|
36
|
-
};
|
|
37
|
-
const decodeTreeValue = (buf) => {
|
|
38
|
-
const value = toBigIntBE(buf.subarray(0, 32));
|
|
39
|
-
const nextIndex = toBigIntBE(buf.subarray(32, 64));
|
|
40
|
-
const nextValue = toBigIntBE(buf.subarray(64, 96));
|
|
41
|
-
return {
|
|
42
|
-
value,
|
|
43
|
-
nextIndex,
|
|
44
|
-
nextValue,
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
27
|
/**
|
|
48
|
-
*
|
|
28
|
+
* Standard implementation of an indexed tree.
|
|
49
29
|
*/
|
|
50
30
|
export class StandardIndexedTree extends TreeBase {
|
|
51
|
-
constructor() {
|
|
52
|
-
super(
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
31
|
+
constructor(db, hasher, name, depth, size = 0n, leafPreimageFactory, leafFactory, root) {
|
|
32
|
+
super(db, hasher, name, depth, size, root);
|
|
33
|
+
this.leafPreimageFactory = leafPreimageFactory;
|
|
34
|
+
this.leafFactory = leafFactory;
|
|
35
|
+
_StandardIndexedTree_snapshotBuilder.set(this, new IndexedTreeSnapshotBuilder(this.db, this, this.leafPreimageFactory));
|
|
36
|
+
this.cachedLeafPreimages = {};
|
|
55
37
|
}
|
|
56
38
|
/**
|
|
57
39
|
* Appends the given leaves to the tree.
|
|
@@ -84,74 +66,119 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
84
66
|
* @param includeUncommitted - Indicates whether to include uncommitted leaves in the computation.
|
|
85
67
|
* @returns The value of the leaf at the given index or undefined if the leaf is empty.
|
|
86
68
|
*/
|
|
87
|
-
getLeafValue(index, includeUncommitted) {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
return Promise.resolve(undefined);
|
|
91
|
-
}
|
|
92
|
-
return Promise.resolve(toBufferBE(leaf.value, 32));
|
|
69
|
+
async getLeafValue(index, includeUncommitted) {
|
|
70
|
+
const preimage = await this.getLatestLeafPreimageCopy(index, includeUncommitted);
|
|
71
|
+
return preimage && preimage.toBuffer();
|
|
93
72
|
}
|
|
94
73
|
/**
|
|
95
74
|
* Finds the index of the largest leaf whose value is less than or equal to the provided value.
|
|
96
|
-
* @param
|
|
75
|
+
* @param newKey - The new key to be inserted into the tree.
|
|
97
76
|
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
|
|
98
77
|
* @returns The found leaf index and a flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
99
78
|
*/
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
diff.push(newValue);
|
|
112
|
-
}
|
|
113
|
-
else if (storedLeaf.value === newValue) {
|
|
114
|
-
return { index: i, alreadyPresent: true };
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
diff.push(newValue - storedLeaf.value);
|
|
79
|
+
async findIndexOfPreviousKey(newKey, includeUncommitted) {
|
|
80
|
+
let lowLeafIndex = await this.getDbLowLeafIndex(newKey);
|
|
81
|
+
let lowLeafPreimage = lowLeafIndex !== undefined ? await this.getDbPreimage(lowLeafIndex) : undefined;
|
|
82
|
+
if (includeUncommitted) {
|
|
83
|
+
const cachedLowLeafIndex = this.getCachedLowLeafIndex(newKey);
|
|
84
|
+
if (cachedLowLeafIndex !== undefined) {
|
|
85
|
+
const cachedLowLeafPreimage = this.getCachedPreimage(cachedLowLeafIndex);
|
|
86
|
+
if (!lowLeafPreimage || cachedLowLeafPreimage.getKey() > lowLeafPreimage.getKey()) {
|
|
87
|
+
lowLeafIndex = cachedLowLeafIndex;
|
|
88
|
+
lowLeafPreimage = cachedLowLeafPreimage;
|
|
89
|
+
}
|
|
118
90
|
}
|
|
119
91
|
}
|
|
120
|
-
|
|
121
|
-
|
|
92
|
+
if (lowLeafIndex === undefined || !lowLeafPreimage) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
index: lowLeafIndex,
|
|
97
|
+
alreadyPresent: lowLeafPreimage.getKey() === newKey,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
getCachedLowLeafIndex(key) {
|
|
101
|
+
const indexes = Object.getOwnPropertyNames(this.cachedLeafPreimages);
|
|
102
|
+
const lowLeafIndexes = indexes
|
|
103
|
+
.map(index => ({
|
|
104
|
+
index: BigInt(index),
|
|
105
|
+
key: this.cachedLeafPreimages[index].getKey(),
|
|
106
|
+
}))
|
|
107
|
+
.filter(({ key: candidateKey }) => candidateKey <= key)
|
|
108
|
+
.sort((a, b) => Number(b.key - a.key));
|
|
109
|
+
return lowLeafIndexes[0]?.index;
|
|
110
|
+
}
|
|
111
|
+
getCachedLeafIndex(key) {
|
|
112
|
+
const index = Object.keys(this.cachedLeafPreimages).find(index => {
|
|
113
|
+
return this.cachedLeafPreimages[index].getKey() === key;
|
|
114
|
+
});
|
|
115
|
+
if (index) {
|
|
116
|
+
return BigInt(index);
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
async getDbLowLeafIndex(key) {
|
|
121
|
+
return await new Promise((resolve, reject) => {
|
|
122
|
+
let lowLeafIndex;
|
|
123
|
+
this.db
|
|
124
|
+
.createReadStream({
|
|
125
|
+
gte: buildDbKeyForLeafIndex(this.getName(), 0n),
|
|
126
|
+
lte: buildDbKeyForLeafIndex(this.getName(), key),
|
|
127
|
+
limit: 1,
|
|
128
|
+
reverse: true,
|
|
129
|
+
})
|
|
130
|
+
.on('data', data => {
|
|
131
|
+
lowLeafIndex = toBigIntBE(data.value);
|
|
132
|
+
})
|
|
133
|
+
.on('close', function () { })
|
|
134
|
+
.on('end', function () {
|
|
135
|
+
resolve(lowLeafIndex);
|
|
136
|
+
})
|
|
137
|
+
.on('error', function () {
|
|
138
|
+
log.error('stream error');
|
|
139
|
+
reject();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
async getDbPreimage(index) {
|
|
144
|
+
const dbPreimage = await this.db
|
|
145
|
+
.get(buildDbKeyForPreimage(this.getName(), index))
|
|
146
|
+
.then(data => this.leafPreimageFactory.fromBuffer(data))
|
|
147
|
+
.catch(() => undefined);
|
|
148
|
+
return dbPreimage;
|
|
149
|
+
}
|
|
150
|
+
getCachedPreimage(index) {
|
|
151
|
+
return this.cachedLeafPreimages[index.toString()];
|
|
122
152
|
}
|
|
123
153
|
/**
|
|
124
|
-
* Gets the latest
|
|
125
|
-
* @param index - Index of the leaf of which to obtain the
|
|
154
|
+
* Gets the latest LeafPreimage copy.
|
|
155
|
+
* @param index - Index of the leaf of which to obtain the LeafPreimage copy.
|
|
126
156
|
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
|
|
127
|
-
* @returns A copy of the leaf
|
|
157
|
+
* @returns A copy of the leaf preimage at the given index or undefined if the leaf was not found.
|
|
128
158
|
*/
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
nextIndex: leaf.nextIndex,
|
|
135
|
-
nextValue: leaf.nextValue,
|
|
136
|
-
}
|
|
137
|
-
: undefined;
|
|
159
|
+
async getLatestLeafPreimageCopy(index, includeUncommitted) {
|
|
160
|
+
const preimage = !includeUncommitted
|
|
161
|
+
? await this.getDbPreimage(index)
|
|
162
|
+
: this.getCachedPreimage(index) ?? (await this.getDbPreimage(index));
|
|
163
|
+
return preimage && this.leafPreimageFactory.clone(preimage);
|
|
138
164
|
}
|
|
139
165
|
/**
|
|
140
|
-
*
|
|
141
|
-
* @param
|
|
142
|
-
* @
|
|
166
|
+
* Returns the index of a leaf given its value, or undefined if no leaf with that value is found.
|
|
167
|
+
* @param value - The leaf value to look for.
|
|
168
|
+
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
169
|
+
* @returns The index of the first leaf found with a given value (undefined if not found).
|
|
143
170
|
*/
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
async findLeafIndex(value, includeUncommitted) {
|
|
172
|
+
const leaf = this.leafFactory.fromBuffer(value);
|
|
173
|
+
let index = await this.db
|
|
174
|
+
.get(buildDbKeyForLeafIndex(this.getName(), leaf.getKey()))
|
|
175
|
+
.then(data => toBigIntBE(data))
|
|
176
|
+
.catch(() => undefined);
|
|
177
|
+
if (includeUncommitted && index === undefined) {
|
|
178
|
+
const cachedIndex = this.getCachedLeafIndex(leaf.getKey());
|
|
179
|
+
index = cachedIndex;
|
|
153
180
|
}
|
|
154
|
-
return
|
|
181
|
+
return index;
|
|
155
182
|
}
|
|
156
183
|
/**
|
|
157
184
|
* Initializes the tree.
|
|
@@ -173,59 +200,26 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
173
200
|
}
|
|
174
201
|
const leaves = [];
|
|
175
202
|
for (let i = 0n; i < prefilledSize; i++) {
|
|
176
|
-
const newLeaf =
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
nextValue: i + 1n,
|
|
180
|
-
};
|
|
181
|
-
leaves.push(newLeaf);
|
|
203
|
+
const newLeaf = this.leafFactory.buildDummy(i);
|
|
204
|
+
const newLeafPreimage = this.leafPreimageFactory.fromLeaf(newLeaf, i + 1n, i + 1n);
|
|
205
|
+
leaves.push(newLeafPreimage);
|
|
182
206
|
}
|
|
183
|
-
// Make the first leaf have 0 value
|
|
184
|
-
leaves[0].value = 0n;
|
|
185
207
|
// Make the last leaf point to the first leaf
|
|
186
|
-
leaves[prefilledSize - 1]
|
|
187
|
-
leaves[prefilledSize - 1].nextValue = 0n;
|
|
208
|
+
leaves[prefilledSize - 1] = this.leafPreimageFactory.fromLeaf(leaves[prefilledSize - 1].asLeaf(), 0n, 0n);
|
|
188
209
|
await this.encodeAndAppendLeaves(leaves, true);
|
|
189
210
|
await this.commit();
|
|
190
211
|
}
|
|
191
|
-
/**
|
|
192
|
-
* Loads Merkle tree data from a database and assigns them to this object.
|
|
193
|
-
*/
|
|
194
|
-
async initFromDb() {
|
|
195
|
-
const startingIndex = 0n;
|
|
196
|
-
const values = [];
|
|
197
|
-
const promise = new Promise((resolve, reject) => {
|
|
198
|
-
this.db
|
|
199
|
-
.createReadStream({
|
|
200
|
-
gte: indexToKeyLeaf(this.getName(), startingIndex),
|
|
201
|
-
lte: indexToKeyLeaf(this.getName(), 2n ** BigInt(this.getDepth())),
|
|
202
|
-
})
|
|
203
|
-
.on('data', function (data) {
|
|
204
|
-
const index = keyLeafToIndex(data.key.toString('utf-8'));
|
|
205
|
-
values[Number(index)] = decodeTreeValue(data.value);
|
|
206
|
-
})
|
|
207
|
-
.on('close', function () { })
|
|
208
|
-
.on('end', function () {
|
|
209
|
-
resolve();
|
|
210
|
-
})
|
|
211
|
-
.on('error', function () {
|
|
212
|
-
log.error('stream error');
|
|
213
|
-
reject();
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
await promise;
|
|
217
|
-
this.leaves = values;
|
|
218
|
-
}
|
|
219
212
|
/**
|
|
220
213
|
* Commits all the leaves to the database and removes them from a cache.
|
|
221
214
|
*/
|
|
222
215
|
async commitLeaves() {
|
|
223
216
|
const batch = this.db.batch();
|
|
224
|
-
const keys = Object.getOwnPropertyNames(this.
|
|
217
|
+
const keys = Object.getOwnPropertyNames(this.cachedLeafPreimages);
|
|
225
218
|
for (const key of keys) {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
this.
|
|
219
|
+
const leaf = this.cachedLeafPreimages[key];
|
|
220
|
+
const index = BigInt(key);
|
|
221
|
+
batch.put(buildDbKeyForPreimage(this.getName(), index), leaf.toBuffer());
|
|
222
|
+
batch.put(buildDbKeyForLeafIndex(this.getName(), leaf.getKey()), toBufferBE(index, 32));
|
|
229
223
|
}
|
|
230
224
|
await batch.write();
|
|
231
225
|
this.clearCachedLeaves();
|
|
@@ -234,18 +228,19 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
234
228
|
* Clears the cache.
|
|
235
229
|
*/
|
|
236
230
|
clearCachedLeaves() {
|
|
237
|
-
this.
|
|
231
|
+
this.cachedLeafPreimages = {};
|
|
238
232
|
}
|
|
239
233
|
/**
|
|
240
234
|
* Updates a leaf in the tree.
|
|
241
|
-
* @param
|
|
235
|
+
* @param preimage - New contents of the leaf.
|
|
242
236
|
* @param index - Index of the leaf to be updated.
|
|
243
237
|
*/
|
|
244
|
-
async updateLeaf(
|
|
238
|
+
async updateLeaf(preimage, index) {
|
|
245
239
|
if (index > this.maxIndex) {
|
|
246
240
|
throw Error(`Index out of bounds. Index ${index}, max index: ${this.maxIndex}.`);
|
|
247
241
|
}
|
|
248
|
-
|
|
242
|
+
this.cachedLeafPreimages[index.toString()] = preimage;
|
|
243
|
+
const encodedLeaf = this.encodeLeaf(preimage, true);
|
|
249
244
|
await this.addLeafToCacheAndHashToRoot(encodedLeaf, index);
|
|
250
245
|
const numLeaves = this.getNumLeaves(true);
|
|
251
246
|
if (index >= numLeaves) {
|
|
@@ -262,8 +257,6 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
262
257
|
*
|
|
263
258
|
* This offers massive circuit performance savings over doing incremental insertions.
|
|
264
259
|
*
|
|
265
|
-
* A description of the algorithm can be found here: https://colab.research.google.com/drive/1A0gizduSi4FIiIJZ8OylwIpO9-OTqV-R
|
|
266
|
-
*
|
|
267
260
|
* WARNING: This function has side effects, it will insert values into the tree.
|
|
268
261
|
*
|
|
269
262
|
* Assumptions:
|
|
@@ -283,81 +276,78 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
283
276
|
* roots.
|
|
284
277
|
*
|
|
285
278
|
* This become tricky when two items that are being batch inserted need to update the same low nullifier, or need to use
|
|
286
|
-
* a value that is part of the same batch insertion as their low nullifier.
|
|
287
|
-
*
|
|
279
|
+
* a value that is part of the same batch insertion as their low nullifier. What we do to avoid this case is to
|
|
280
|
+
* update the existing leaves in the tree with the nullifiers in high to low order, ensuring that this case never occurs.
|
|
281
|
+
* The circuit has to sort the nullifiers (or take a hint of the sorted nullifiers and prove that it's a valid permutation).
|
|
282
|
+
* Then we just batch insert the new nullifiers in the original order.
|
|
288
283
|
*
|
|
289
284
|
* The following example will illustrate attempting to insert 2,3,20,19 into a tree already containing 0,5,10,15
|
|
290
285
|
*
|
|
291
286
|
* The example will explore two cases. In each case the values low nullifier will exist within the batch insertion,
|
|
292
287
|
* One where the low nullifier comes before the item in the set (2,3), and one where it comes after (20,19).
|
|
293
288
|
*
|
|
289
|
+
* First, we sort the nullifiers high to low, that's 20,19,3,2
|
|
290
|
+
*
|
|
294
291
|
* The original tree: Pending insertion subtree
|
|
295
292
|
*
|
|
296
|
-
* index 0 2 3
|
|
293
|
+
* index 0 1 2 3 - - - -
|
|
297
294
|
* ------------------------------------- ----------------------------
|
|
298
295
|
* val 0 5 10 15 - - - -
|
|
299
296
|
* nextIdx 1 2 3 0 - - - -
|
|
300
297
|
* nextVal 5 10 15 0 - - - -
|
|
301
298
|
*
|
|
302
299
|
*
|
|
303
|
-
* Inserting
|
|
304
|
-
* 1. Find the low nullifier (
|
|
300
|
+
* Inserting 20:
|
|
301
|
+
* 1. Find the low nullifier (3) - provide inclusion proof
|
|
305
302
|
* 2. Update its pointers
|
|
306
|
-
* 3. Insert
|
|
303
|
+
* 3. Insert 20 into the pending subtree
|
|
307
304
|
*
|
|
308
|
-
* index 0 2 3
|
|
305
|
+
* index 0 1 2 3 - - 6 -
|
|
309
306
|
* ------------------------------------- ----------------------------
|
|
310
|
-
* val 0 5 10 15
|
|
311
|
-
* nextIdx
|
|
312
|
-
* nextVal
|
|
307
|
+
* val 0 5 10 15 - - 20 -
|
|
308
|
+
* nextIdx 1 2 3 6 - - 0 -
|
|
309
|
+
* nextVal 5 10 15 20 - - 0 -
|
|
313
310
|
*
|
|
314
|
-
* Inserting
|
|
315
|
-
* 1.
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* - Index 0 has a val 0 and nextVal of 2. This is NOT enough to prove non inclusion of 2.
|
|
319
|
-
* - Our existing tree is in a state where we cannot prove non inclusion of 3.
|
|
320
|
-
* We do not provide a non inclusion proof to out circuit, but prompt it to look within the insertion subtree.
|
|
321
|
-
* 2. Update pending insertion subtree
|
|
322
|
-
* 3. Insert 3 into pending subtree
|
|
311
|
+
* Inserting 19:
|
|
312
|
+
* 1. Find the low nullifier (3) - provide inclusion proof
|
|
313
|
+
* 2. Update its pointers
|
|
314
|
+
* 3. Insert 19 into the pending subtree
|
|
323
315
|
*
|
|
324
|
-
*
|
|
325
|
-
* index 0 2 3 4 5 6 - -
|
|
316
|
+
* index 0 1 2 3 - - 6 7
|
|
326
317
|
* ------------------------------------- ----------------------------
|
|
327
|
-
* val 0 5 10 15
|
|
328
|
-
* nextIdx
|
|
329
|
-
* nextVal
|
|
318
|
+
* val 0 5 10 15 - - 20 19
|
|
319
|
+
* nextIdx 1 2 3 7 - - 0 6
|
|
320
|
+
* nextVal 5 10 15 19 - - 0 20
|
|
330
321
|
*
|
|
331
|
-
* Inserting
|
|
332
|
-
* 1. Find the low nullifier (
|
|
322
|
+
* Inserting 3:
|
|
323
|
+
* 1. Find the low nullifier (0) - provide inclusion proof
|
|
333
324
|
* 2. Update its pointers
|
|
334
|
-
* 3. Insert
|
|
325
|
+
* 3. Insert 3 into the pending subtree
|
|
335
326
|
*
|
|
336
|
-
* index 0 2 3
|
|
327
|
+
* index 0 1 2 3 - 5 6 7
|
|
337
328
|
* ------------------------------------- ----------------------------
|
|
338
|
-
* val 0 5 10 15
|
|
339
|
-
* nextIdx 5 2 3 7
|
|
340
|
-
* nextVal
|
|
329
|
+
* val 0 5 10 15 - 3 20 19
|
|
330
|
+
* nextIdx 5 2 3 7 - 1 0 6
|
|
331
|
+
* nextVal 3 10 15 19 - 5 0 20
|
|
341
332
|
*
|
|
342
|
-
* Inserting
|
|
343
|
-
* 1.
|
|
344
|
-
* We can provide an inclusion proof of this intermediate tree state.
|
|
333
|
+
* Inserting 2:
|
|
334
|
+
* 1. Find the low nullifier (0) - provide inclusion proof
|
|
345
335
|
* 2. Update its pointers
|
|
346
|
-
* 3. Insert
|
|
336
|
+
* 3. Insert 2 into the pending subtree
|
|
347
337
|
*
|
|
348
|
-
* index 0 2 3
|
|
338
|
+
* index 0 1 2 3 4 5 6 7
|
|
349
339
|
* ------------------------------------- ----------------------------
|
|
350
|
-
* val 0 5 10 15 2 3 20
|
|
351
|
-
* nextIdx
|
|
352
|
-
* nextVal 2 10 15 19 3 5 0
|
|
340
|
+
* val 0 5 10 15 2 3 20 19
|
|
341
|
+
* nextIdx 4 2 3 7 5 1 0 6
|
|
342
|
+
* nextVal 2 10 15 19 3 5 0 20
|
|
353
343
|
*
|
|
354
344
|
* Perform subtree insertion
|
|
355
345
|
*
|
|
356
|
-
* index 0 2 3 4 5 6 7
|
|
346
|
+
* index 0 1 2 3 4 5 6 7
|
|
357
347
|
* ---------------------------------------------------------------------
|
|
358
|
-
* val 0 5 10 15 2 3 20
|
|
359
|
-
* nextIdx
|
|
360
|
-
* nextVal 2 10 15 19 3 5 0
|
|
348
|
+
* val 0 5 10 15 2 3 20 19
|
|
349
|
+
* nextIdx 4 2 3 7 5 1 0 6
|
|
350
|
+
* nextVal 2 10 15 19 3 5 0 20
|
|
361
351
|
*
|
|
362
352
|
* TODO: this implementation will change once the zero value is changed from h(0,0,0). Changes incoming over the next sprint
|
|
363
353
|
* @param leaves - Values to insert into the tree.
|
|
@@ -365,92 +355,61 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
365
355
|
* @returns The data for the leaves to be updated when inserting the new ones.
|
|
366
356
|
*/
|
|
367
357
|
async batchInsert(leaves, subtreeHeight) {
|
|
368
|
-
|
|
369
|
-
const touched = new Map();
|
|
370
|
-
const emptyLowLeafWitness = getEmptyLowLeafWitness(this.getDepth());
|
|
358
|
+
const emptyLowLeafWitness = getEmptyLowLeafWitness(this.getDepth(), this.leafPreimageFactory);
|
|
371
359
|
// Accumulators
|
|
372
|
-
const lowLeavesWitnesses =
|
|
373
|
-
const pendingInsertionSubtree =
|
|
360
|
+
const lowLeavesWitnesses = leaves.map(() => emptyLowLeafWitness);
|
|
361
|
+
const pendingInsertionSubtree = leaves.map(() => this.leafPreimageFactory.empty());
|
|
374
362
|
// Start info
|
|
375
363
|
const startInsertionIndex = this.getNumLeaves(true);
|
|
364
|
+
const leavesToInsert = leaves.map(leaf => this.leafFactory.fromBuffer(leaf));
|
|
365
|
+
const sortedDescendingLeafTuples = leavesToInsert
|
|
366
|
+
.map((leaf, index) => ({ leaf, index }))
|
|
367
|
+
.sort((a, b) => Number(b.leaf.getKey() - a.leaf.getKey()));
|
|
368
|
+
const sortedDescendingLeaves = sortedDescendingLeafTuples.map(leafTuple => leafTuple.leaf);
|
|
376
369
|
// Get insertion path for each leaf
|
|
377
|
-
for (let i = 0; i <
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
if (
|
|
381
|
-
pendingInsertionSubtree.push(zeroLeaf);
|
|
382
|
-
lowLeavesWitnesses.push(emptyLowLeafWitness);
|
|
370
|
+
for (let i = 0; i < leavesToInsert.length; i++) {
|
|
371
|
+
const newLeaf = sortedDescendingLeaves[i];
|
|
372
|
+
const originalIndex = leavesToInsert.indexOf(newLeaf);
|
|
373
|
+
if (newLeaf.isEmpty()) {
|
|
383
374
|
continue;
|
|
384
375
|
}
|
|
385
|
-
const indexOfPrevious = this.
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if (pendingInsertionSubtree[j].value === 0n) {
|
|
393
|
-
continue;
|
|
394
|
-
}
|
|
395
|
-
if (pendingInsertionSubtree[j].value < newValue &&
|
|
396
|
-
(pendingInsertionSubtree[j].nextValue > newValue || pendingInsertionSubtree[j].nextValue === 0n)) {
|
|
397
|
-
// add the new value to the pending low nullifiers
|
|
398
|
-
const currentLowLeaf = {
|
|
399
|
-
value: newValue,
|
|
400
|
-
nextValue: pendingInsertionSubtree[j].nextValue,
|
|
401
|
-
nextIndex: pendingInsertionSubtree[j].nextIndex,
|
|
402
|
-
};
|
|
403
|
-
pendingInsertionSubtree.push(currentLowLeaf);
|
|
404
|
-
// Update the pending low leaf to point at the new value
|
|
405
|
-
pendingInsertionSubtree[j].nextValue = newValue;
|
|
406
|
-
pendingInsertionSubtree[j].nextIndex = startInsertionIndex + BigInt(i);
|
|
407
|
-
break;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
// Any node updated in this space will need to calculate its low nullifier from a previously inserted value
|
|
411
|
-
lowLeavesWitnesses.push(emptyLowLeafWitness);
|
|
412
|
-
}
|
|
413
|
-
else {
|
|
414
|
-
// Update the touched mapping
|
|
415
|
-
if (prevNodes) {
|
|
416
|
-
prevNodes.push(newValue);
|
|
417
|
-
touched.set(indexOfPrevious.index, prevNodes);
|
|
418
|
-
}
|
|
419
|
-
else {
|
|
420
|
-
touched.set(indexOfPrevious.index, [newValue]);
|
|
421
|
-
}
|
|
422
|
-
// get the low leaf
|
|
423
|
-
const lowLeaf = this.getLatestLeafDataCopy(indexOfPrevious.index, true);
|
|
424
|
-
if (lowLeaf === undefined) {
|
|
425
|
-
return [undefined, await this.getSubtreeSiblingPath(subtreeHeight, true)];
|
|
426
|
-
}
|
|
427
|
-
const siblingPath = await this.getSiblingPath(BigInt(indexOfPrevious.index), true);
|
|
428
|
-
const witness = {
|
|
429
|
-
leafData: { ...lowLeaf },
|
|
430
|
-
index: BigInt(indexOfPrevious.index),
|
|
431
|
-
siblingPath,
|
|
432
|
-
};
|
|
433
|
-
// Update the running paths
|
|
434
|
-
lowLeavesWitnesses.push(witness);
|
|
435
|
-
const currentLowLeaf = {
|
|
436
|
-
value: newValue,
|
|
437
|
-
nextValue: lowLeaf.nextValue,
|
|
438
|
-
nextIndex: lowLeaf.nextIndex,
|
|
376
|
+
const indexOfPrevious = await this.findIndexOfPreviousKey(newLeaf.getKey(), true);
|
|
377
|
+
if (indexOfPrevious === undefined) {
|
|
378
|
+
return {
|
|
379
|
+
lowLeavesWitnessData: undefined,
|
|
380
|
+
sortedNewLeaves: sortedDescendingLeafTuples.map(leafTuple => leafTuple.leaf.toBuffer()),
|
|
381
|
+
sortedNewLeavesIndexes: sortedDescendingLeafTuples.map(leafTuple => leafTuple.index),
|
|
382
|
+
newSubtreeSiblingPath: await this.getSubtreeSiblingPath(subtreeHeight, true),
|
|
439
383
|
};
|
|
440
|
-
pendingInsertionSubtree.push(currentLowLeaf);
|
|
441
|
-
lowLeaf.nextValue = newValue;
|
|
442
|
-
lowLeaf.nextIndex = startInsertionIndex + BigInt(i);
|
|
443
|
-
const lowLeafIndex = indexOfPrevious.index;
|
|
444
|
-
this.cachedLeaves[lowLeafIndex] = lowLeaf;
|
|
445
|
-
await this.updateLeaf(lowLeaf, BigInt(lowLeafIndex));
|
|
446
384
|
}
|
|
385
|
+
// get the low leaf (existence checked in getting index)
|
|
386
|
+
const lowLeafPreimage = (await this.getLatestLeafPreimageCopy(indexOfPrevious.index, true));
|
|
387
|
+
const siblingPath = await this.getSiblingPath(BigInt(indexOfPrevious.index), true);
|
|
388
|
+
const witness = {
|
|
389
|
+
leafPreimage: lowLeafPreimage,
|
|
390
|
+
index: BigInt(indexOfPrevious.index),
|
|
391
|
+
siblingPath,
|
|
392
|
+
};
|
|
393
|
+
// Update the running paths
|
|
394
|
+
lowLeavesWitnesses[i] = witness;
|
|
395
|
+
const currentPendingPreimageLeaf = this.leafPreimageFactory.fromLeaf(newLeaf, lowLeafPreimage.getNextKey(), lowLeafPreimage.getNextIndex());
|
|
396
|
+
pendingInsertionSubtree[originalIndex] = currentPendingPreimageLeaf;
|
|
397
|
+
const newLowLeafPreimage = this.leafPreimageFactory.fromLeaf(lowLeafPreimage.asLeaf(), newLeaf.getKey(), startInsertionIndex + BigInt(originalIndex));
|
|
398
|
+
const lowLeafIndex = indexOfPrevious.index;
|
|
399
|
+
this.cachedLeafPreimages[lowLeafIndex.toString()] = newLowLeafPreimage;
|
|
400
|
+
await this.updateLeaf(newLowLeafPreimage, lowLeafIndex);
|
|
447
401
|
}
|
|
448
402
|
const newSubtreeSiblingPath = await this.getSubtreeSiblingPath(subtreeHeight, true);
|
|
449
403
|
// Perform batch insertion of new pending values
|
|
450
404
|
// Note: In this case we set `hash0Leaf` param to false because batch insertion algorithm use forced null leaf
|
|
451
405
|
// inclusion. See {@link encodeLeaf} for a more through param explanation.
|
|
452
406
|
await this.encodeAndAppendLeaves(pendingInsertionSubtree, false);
|
|
453
|
-
return
|
|
407
|
+
return {
|
|
408
|
+
lowLeavesWitnessData: lowLeavesWitnesses,
|
|
409
|
+
sortedNewLeaves: sortedDescendingLeafTuples.map(leafTuple => leafTuple.leaf.toBuffer()),
|
|
410
|
+
sortedNewLeavesIndexes: sortedDescendingLeafTuples.map(leafTuple => leafTuple.index),
|
|
411
|
+
newSubtreeSiblingPath,
|
|
412
|
+
};
|
|
454
413
|
}
|
|
455
414
|
async getSubtreeSiblingPath(subtreeHeight, includeUncommitted) {
|
|
456
415
|
const nextAvailableLeafIndex = this.getNumLeaves(includeUncommitted);
|
|
@@ -458,19 +417,25 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
458
417
|
// Drop the first subtreeHeight items since we only care about the path to the subtree root
|
|
459
418
|
return fullSiblingPath.getSubtreeSiblingPath(subtreeHeight);
|
|
460
419
|
}
|
|
420
|
+
snapshot(blockNumber) {
|
|
421
|
+
return __classPrivateFieldGet(this, _StandardIndexedTree_snapshotBuilder, "f").snapshot(blockNumber);
|
|
422
|
+
}
|
|
423
|
+
getSnapshot(block) {
|
|
424
|
+
return __classPrivateFieldGet(this, _StandardIndexedTree_snapshotBuilder, "f").getSnapshot(block);
|
|
425
|
+
}
|
|
461
426
|
/**
|
|
462
427
|
* Encodes leaves and appends them to a tree.
|
|
463
|
-
* @param
|
|
428
|
+
* @param preimages - Leaves to encode.
|
|
464
429
|
* @param hash0Leaf - Indicates whether 0 value leaf should be hashed. See {@link encodeLeaf}.
|
|
465
430
|
* @returns Empty promise
|
|
466
431
|
*/
|
|
467
|
-
async encodeAndAppendLeaves(
|
|
468
|
-
const startInsertionIndex =
|
|
469
|
-
const
|
|
470
|
-
this.
|
|
471
|
-
return this.encodeLeaf(
|
|
432
|
+
async encodeAndAppendLeaves(preimages, hash0Leaf) {
|
|
433
|
+
const startInsertionIndex = this.getNumLeaves(true);
|
|
434
|
+
const hashedLeaves = preimages.map((preimage, i) => {
|
|
435
|
+
this.cachedLeafPreimages[(startInsertionIndex + BigInt(i)).toString()] = preimage;
|
|
436
|
+
return this.encodeLeaf(preimage, hash0Leaf);
|
|
472
437
|
});
|
|
473
|
-
await super.appendLeaves(
|
|
438
|
+
await super.appendLeaves(hashedLeaves);
|
|
474
439
|
}
|
|
475
440
|
/**
|
|
476
441
|
* Encode a leaf into a buffer.
|
|
@@ -482,13 +447,14 @@ export class StandardIndexedTree extends TreeBase {
|
|
|
482
447
|
*/
|
|
483
448
|
encodeLeaf(leaf, hash0Leaf) {
|
|
484
449
|
let encodedLeaf;
|
|
485
|
-
if (!hash0Leaf && leaf.
|
|
450
|
+
if (!hash0Leaf && leaf.getKey() == 0n) {
|
|
486
451
|
encodedLeaf = toBufferBE(0n, 32);
|
|
487
452
|
}
|
|
488
453
|
else {
|
|
489
|
-
encodedLeaf = this.hasher.hashInputs(
|
|
454
|
+
encodedLeaf = this.hasher.hashInputs(leaf.toHashInputs());
|
|
490
455
|
}
|
|
491
456
|
return encodedLeaf;
|
|
492
457
|
}
|
|
493
458
|
}
|
|
494
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmRfaW5kZXhlZF90cmVlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0YW5kYXJkX2luZGV4ZWRfdHJlZS9zdGFuZGFyZF9pbmRleGVkX3RyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRzNDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUzQyxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0FBRTdELE1BQU0sY0FBYyxHQUFHLENBQUMsSUFBWSxFQUFFLEtBQWEsRUFBRSxFQUFFO0lBQ3JELE9BQU8sR0FBRyxJQUFJLFNBQVMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztBQUNqRSxDQUFDLENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxDQUFDLEdBQVcsRUFBVSxFQUFFO0lBQzdDLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEMsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUMvQyxDQUFDLENBQUM7QUFFRixNQUFNLFFBQVEsR0FBYTtJQUN6QixLQUFLLEVBQUUsRUFBRTtJQUNULFNBQVMsRUFBRSxFQUFFO0lBQ2IsU0FBUyxFQUFFLEVBQUU7Q0FDZCxDQUFDO0FBb0JGOzs7O0dBSUc7QUFDSCxTQUFTLHNCQUFzQixDQUFtQixVQUFhO0lBQzdELE9BQU87UUFDTCxRQUFRLEVB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
|
|
459
|
+
_StandardIndexedTree_snapshotBuilder = new WeakMap();
|
|
460
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmRfaW5kZXhlZF90cmVlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0YW5kYXJkX2luZGV4ZWRfdHJlZS9zdGFuZGFyZF9pbmRleGVkX3RyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFELE9BQU8sRUFBVSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFJbkQsT0FBTyxFQUlMLDBCQUEwQixHQUUzQixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0MsTUFBTSxHQUFHLEdBQUcsaUJBQWlCLENBQUMsNkJBQTZCLENBQUMsQ0FBQztBQTZDN0QsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxJQUFZLEVBQUUsS0FBYSxFQUFFLEVBQUU7SUFDbkUsT0FBTyxHQUFHLElBQUksa0JBQWtCLFVBQVUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7QUFDMUUsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxJQUFZLEVBQUUsR0FBVyxFQUFFLEVBQUU7SUFDbEUsT0FBTyxHQUFHLElBQUksMkJBQTJCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7QUFDakYsQ0FBQyxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILFNBQVMsc0JBQXNCLENBQzdCLFVBQWEsRUFDYixtQkFBb0M7SUFFcEMsT0FBTztRQUNMLFlBQVksRUFBRSxtQkFBbUIsQ0FBQyxLQUFLLEVBQUU7UUFDekMsS0FBSyxFQUFFLEVBQUU7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
|