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