@aztec/merkle-tree 0.16.4 → 0.16.5
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/package.json +3 -3
- package/src/index.ts +0 -15
- package/src/interfaces/append_only_tree.ts +0 -13
- package/src/interfaces/indexed_tree.ts +0 -92
- package/src/interfaces/merkle_tree.ts +0 -60
- package/src/interfaces/update_only_tree.ts +0 -14
- package/src/load_tree.ts +0 -26
- package/src/new_tree.ts +0 -28
- package/src/pedersen.ts +0 -25
- package/src/snapshots/append_only_snapshot.ts +0 -243
- package/src/snapshots/base_full_snapshot.ts +0 -232
- package/src/snapshots/full_snapshot.ts +0 -26
- package/src/snapshots/indexed_tree_snapshot.ts +0 -108
- package/src/snapshots/snapshot_builder.ts +0 -84
- package/src/snapshots/snapshot_builder_test_suite.ts +0 -218
- package/src/sparse_tree/sparse_tree.ts +0 -48
- package/src/standard_indexed_tree/standard_indexed_tree.ts +0 -612
- package/src/standard_indexed_tree/test/standard_indexed_tree_with_append.ts +0 -66
- package/src/standard_tree/standard_tree.ts +0 -37
- package/src/tree_base.ts +0 -311
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { StandardIndexedTree } from '../../index.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A testing utility which is here to store the original implementation of StandardIndexedTree.appendLeaves method
|
|
5
|
-
* that was replaced by the more efficient batchInsert method. We keep the original implementation around as it useful
|
|
6
|
-
* for testing that the more complex batchInsert method works correctly.
|
|
7
|
-
*/
|
|
8
|
-
export class StandardIndexedTreeWithAppend extends StandardIndexedTree {
|
|
9
|
-
/**
|
|
10
|
-
* Appends the given leaves to the tree.
|
|
11
|
-
* @param leaves - The leaves to append.
|
|
12
|
-
* @returns Empty promise.
|
|
13
|
-
* @remarks This method is inefficient and is here mostly for testing. Use batchInsert instead.
|
|
14
|
-
*/
|
|
15
|
-
public async appendLeaves(leaves: Buffer[]): Promise<void> {
|
|
16
|
-
for (const leaf of leaves) {
|
|
17
|
-
await this.appendLeaf(leaf);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Appends the given leaf to the tree.
|
|
23
|
-
* @param leaf - The leaf to append.
|
|
24
|
-
* @returns Empty promise.
|
|
25
|
-
*/
|
|
26
|
-
private async appendLeaf(leaf: Buffer): Promise<void> {
|
|
27
|
-
const newLeaf = this.leafFactory.fromBuffer(leaf);
|
|
28
|
-
|
|
29
|
-
// Special case when appending zero
|
|
30
|
-
if (newLeaf.getKey() === 0n) {
|
|
31
|
-
const newSize = (this.cachedSize ?? this.size) + 1n;
|
|
32
|
-
if (newSize - 1n > this.maxIndex) {
|
|
33
|
-
throw Error(`Can't append beyond max index. Max index: ${this.maxIndex}`);
|
|
34
|
-
}
|
|
35
|
-
this.cachedSize = newSize;
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const lowLeafIndex = await this.findIndexOfPreviousKey(newLeaf.getKey(), true);
|
|
40
|
-
if (lowLeafIndex === undefined) {
|
|
41
|
-
throw new Error(`Previous leaf not found!`);
|
|
42
|
-
}
|
|
43
|
-
const lowLeafPreimage = (await this.getLatestLeafPreimageCopy(lowLeafIndex.index, true))!;
|
|
44
|
-
|
|
45
|
-
const newLeafPreimage = this.leafPreimageFactory.fromLeaf(
|
|
46
|
-
newLeaf,
|
|
47
|
-
lowLeafPreimage.getNextKey(),
|
|
48
|
-
lowLeafPreimage.getNextIndex(),
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
if (lowLeafIndex.alreadyPresent) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
// insert a new leaf at the highest index and update the values of our previous leaf copy
|
|
55
|
-
const currentSize = this.getNumLeaves(true);
|
|
56
|
-
const newLowLeafPreimage = this.leafPreimageFactory.fromLeaf(
|
|
57
|
-
lowLeafPreimage.asLeaf(),
|
|
58
|
-
newLeaf.getKey(),
|
|
59
|
-
BigInt(currentSize),
|
|
60
|
-
);
|
|
61
|
-
this.cachedLeafPreimages[Number(currentSize)] = newLeafPreimage;
|
|
62
|
-
this.cachedLeafPreimages[Number(lowLeafIndex.index)] = newLowLeafPreimage;
|
|
63
|
-
await this.updateLeaf(newLowLeafPreimage, BigInt(lowLeafIndex.index));
|
|
64
|
-
await this.updateLeaf(newLeafPreimage, this.getNumLeaves(true));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { AppendOnlySnapshotBuilder, TreeSnapshot } from '../index.js';
|
|
2
|
-
import { AppendOnlyTree } from '../interfaces/append_only_tree.js';
|
|
3
|
-
import { TreeBase } from '../tree_base.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A Merkle tree implementation that uses a LevelDB database to store the tree.
|
|
7
|
-
*/
|
|
8
|
-
export class StandardTree extends TreeBase implements AppendOnlyTree {
|
|
9
|
-
#snapshotBuilder = new AppendOnlySnapshotBuilder(this.db, this, this.hasher);
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Appends the given leaves to the tree.
|
|
13
|
-
* @param leaves - The leaves to append.
|
|
14
|
-
* @returns Empty promise.
|
|
15
|
-
*/
|
|
16
|
-
public async appendLeaves(leaves: Buffer[]): Promise<void> {
|
|
17
|
-
await super.appendLeaves(leaves);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
public snapshot(block: number): Promise<TreeSnapshot> {
|
|
21
|
-
return this.#snapshotBuilder.snapshot(block);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public getSnapshot(block: number): Promise<TreeSnapshot> {
|
|
25
|
-
return this.#snapshotBuilder.getSnapshot(block);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public async findLeafIndex(value: Buffer, includeUncommitted: boolean): Promise<bigint | undefined> {
|
|
29
|
-
for (let i = 0n; i < this.getNumLeaves(includeUncommitted); i++) {
|
|
30
|
-
const currentValue = await this.getLeafValue(i, includeUncommitted);
|
|
31
|
-
if (currentValue && currentValue.equals(value)) {
|
|
32
|
-
return i;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
}
|
package/src/tree_base.ts
DELETED
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
import { toBigIntLE, toBufferLE } from '@aztec/foundation/bigint-buffer';
|
|
2
|
-
import { Hasher, SiblingPath } from '@aztec/types';
|
|
3
|
-
|
|
4
|
-
import { LevelUp, LevelUpChain } from 'levelup';
|
|
5
|
-
|
|
6
|
-
import { MerkleTree } from './interfaces/merkle_tree.js';
|
|
7
|
-
|
|
8
|
-
const MAX_DEPTH = 254;
|
|
9
|
-
|
|
10
|
-
const indexToKeyHash = (name: string, level: number, index: bigint) => `${name}:${level}:${index}`;
|
|
11
|
-
const encodeMeta = (root: Buffer, depth: number, size: bigint) => {
|
|
12
|
-
const data = Buffer.alloc(36);
|
|
13
|
-
root.copy(data);
|
|
14
|
-
data.writeUInt32LE(depth, 32);
|
|
15
|
-
return Buffer.concat([data, toBufferLE(size, 32)]);
|
|
16
|
-
};
|
|
17
|
-
export const decodeMeta = (meta: Buffer) => {
|
|
18
|
-
const root = meta.subarray(0, 32);
|
|
19
|
-
const depth = meta.readUInt32LE(32);
|
|
20
|
-
const size = toBigIntLE(meta.subarray(36));
|
|
21
|
-
return {
|
|
22
|
-
root,
|
|
23
|
-
depth,
|
|
24
|
-
size,
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const INITIAL_LEAF = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex');
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* A Merkle tree implementation that uses a LevelDB database to store the tree.
|
|
32
|
-
*/
|
|
33
|
-
export abstract class TreeBase implements MerkleTree {
|
|
34
|
-
protected readonly maxIndex: bigint;
|
|
35
|
-
protected cachedSize?: bigint;
|
|
36
|
-
private root!: Buffer;
|
|
37
|
-
private zeroHashes: Buffer[] = [];
|
|
38
|
-
private cache: { [key: string]: Buffer } = {};
|
|
39
|
-
|
|
40
|
-
public constructor(
|
|
41
|
-
protected db: LevelUp,
|
|
42
|
-
protected hasher: Hasher,
|
|
43
|
-
private name: string,
|
|
44
|
-
private depth: number,
|
|
45
|
-
protected size: bigint = 0n,
|
|
46
|
-
root?: Buffer,
|
|
47
|
-
) {
|
|
48
|
-
if (!(depth >= 1 && depth <= MAX_DEPTH)) {
|
|
49
|
-
throw Error('Invalid depth');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Compute the zero values at each layer.
|
|
53
|
-
let current = INITIAL_LEAF;
|
|
54
|
-
for (let i = depth - 1; i >= 0; --i) {
|
|
55
|
-
this.zeroHashes[i] = current;
|
|
56
|
-
current = hasher.hash(current, current);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
this.root = root ? root : current;
|
|
60
|
-
this.maxIndex = 2n ** BigInt(depth) - 1n;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Returns the root of the tree.
|
|
65
|
-
* @param includeUncommitted - If true, root incorporating uncommitted changes is returned.
|
|
66
|
-
* @returns The root of the tree.
|
|
67
|
-
*/
|
|
68
|
-
public getRoot(includeUncommitted: boolean): Buffer {
|
|
69
|
-
return !includeUncommitted ? this.root : this.cache[indexToKeyHash(this.name, 0, 0n)] ?? this.root;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Returns the number of leaves in the tree.
|
|
74
|
-
* @param includeUncommitted - If true, the returned number of leaves includes uncommitted changes.
|
|
75
|
-
* @returns The number of leaves in the tree.
|
|
76
|
-
*/
|
|
77
|
-
public getNumLeaves(includeUncommitted: boolean) {
|
|
78
|
-
return !includeUncommitted ? this.size : this.cachedSize ?? this.size;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Returns the name of the tree.
|
|
83
|
-
* @returns The name of the tree.
|
|
84
|
-
*/
|
|
85
|
-
public getName(): string {
|
|
86
|
-
return this.name;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Returns the depth of the tree.
|
|
91
|
-
* @returns The depth of the tree.
|
|
92
|
-
*/
|
|
93
|
-
public getDepth(): number {
|
|
94
|
-
return this.depth;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Returns a sibling path for the element at the given index.
|
|
99
|
-
* @param index - The index of the element.
|
|
100
|
-
* @param includeUncommitted - Indicates whether to get a sibling path incorporating uncommitted changes.
|
|
101
|
-
* @returns A sibling path for the element at the given index.
|
|
102
|
-
* Note: The sibling path is an array of sibling hashes, with the lowest hash (leaf hash) first, and the highest hash last.
|
|
103
|
-
*/
|
|
104
|
-
public async getSiblingPath<N extends number>(index: bigint, includeUncommitted: boolean): Promise<SiblingPath<N>> {
|
|
105
|
-
const path: Buffer[] = [];
|
|
106
|
-
let level = this.depth;
|
|
107
|
-
while (level > 0) {
|
|
108
|
-
const isRight = index & 0x01n;
|
|
109
|
-
const sibling = await this.getLatestValueAtIndex(level, isRight ? index - 1n : index + 1n, includeUncommitted);
|
|
110
|
-
path.push(sibling);
|
|
111
|
-
level -= 1;
|
|
112
|
-
index >>= 1n;
|
|
113
|
-
}
|
|
114
|
-
return new SiblingPath<N>(this.depth as N, path);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Commits the changes to the database.
|
|
119
|
-
* @returns Empty promise.
|
|
120
|
-
*/
|
|
121
|
-
public async commit(): Promise<void> {
|
|
122
|
-
const batch = this.db.batch();
|
|
123
|
-
const keys = Object.getOwnPropertyNames(this.cache);
|
|
124
|
-
for (const key of keys) {
|
|
125
|
-
batch.put(key, this.cache[key]);
|
|
126
|
-
}
|
|
127
|
-
this.size = this.getNumLeaves(true);
|
|
128
|
-
this.root = this.getRoot(true);
|
|
129
|
-
await this.writeMeta(batch);
|
|
130
|
-
await batch.write();
|
|
131
|
-
this.clearCache();
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Rolls back the not-yet-committed changes.
|
|
136
|
-
* @returns Empty promise.
|
|
137
|
-
*/
|
|
138
|
-
public rollback(): Promise<void> {
|
|
139
|
-
this.clearCache();
|
|
140
|
-
return Promise.resolve();
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Gets the value at the given index.
|
|
145
|
-
* @param index - The index of the leaf.
|
|
146
|
-
* @param includeUncommitted - Indicates whether to include uncommitted changes.
|
|
147
|
-
* @returns Leaf value at the given index or undefined.
|
|
148
|
-
*/
|
|
149
|
-
public getLeafValue(index: bigint, includeUncommitted: boolean): Promise<Buffer | undefined> {
|
|
150
|
-
return this.getLatestValueAtIndex(this.depth, index, includeUncommitted);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
public getNode(level: number, index: bigint): Promise<Buffer | undefined> {
|
|
154
|
-
if (level < 0 || level > this.depth) {
|
|
155
|
-
throw Error('Invalid level: ' + level);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (index < 0 || index >= 2n ** BigInt(level)) {
|
|
159
|
-
throw Error('Invalid index: ' + index);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return this.dbGet(indexToKeyHash(this.name, level, index));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
public getZeroHash(level: number): Buffer {
|
|
166
|
-
if (level <= 0 || level > this.depth) {
|
|
167
|
-
throw new Error('Invalid level');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return this.zeroHashes[level - 1];
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Clears the cache.
|
|
175
|
-
*/
|
|
176
|
-
private clearCache() {
|
|
177
|
-
this.cache = {};
|
|
178
|
-
this.cachedSize = undefined;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Adds a leaf and all the hashes above it to the cache.
|
|
183
|
-
* @param leaf - Leaf to add to cache.
|
|
184
|
-
* @param index - Index of the leaf (used to derive the cache key).
|
|
185
|
-
*/
|
|
186
|
-
protected async addLeafToCacheAndHashToRoot(leaf: Buffer, index: bigint) {
|
|
187
|
-
const key = indexToKeyHash(this.name, this.depth, index);
|
|
188
|
-
let current = leaf;
|
|
189
|
-
this.cache[key] = current;
|
|
190
|
-
let level = this.depth;
|
|
191
|
-
while (level > 0) {
|
|
192
|
-
const isRight = index & 0x01n;
|
|
193
|
-
const sibling = await this.getLatestValueAtIndex(level, isRight ? index - 1n : index + 1n, true);
|
|
194
|
-
const lhs = isRight ? sibling : current;
|
|
195
|
-
const rhs = isRight ? current : sibling;
|
|
196
|
-
current = this.hasher.hash(lhs, rhs);
|
|
197
|
-
level -= 1;
|
|
198
|
-
index >>= 1n;
|
|
199
|
-
const cacheKey = indexToKeyHash(this.name, level, index);
|
|
200
|
-
this.cache[cacheKey] = current;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Returns the latest value at the given index.
|
|
206
|
-
* @param level - The level of the tree.
|
|
207
|
-
* @param index - The index of the element.
|
|
208
|
-
* @param includeUncommitted - Indicates, whether to get include uncommitted changes.
|
|
209
|
-
* @returns The latest value at the given index.
|
|
210
|
-
* Note: If the value is not in the cache, it will be fetched from the database.
|
|
211
|
-
*/
|
|
212
|
-
private async getLatestValueAtIndex(level: number, index: bigint, includeUncommitted: boolean): Promise<Buffer> {
|
|
213
|
-
const key = indexToKeyHash(this.name, level, index);
|
|
214
|
-
if (includeUncommitted && this.cache[key] !== undefined) {
|
|
215
|
-
return this.cache[key];
|
|
216
|
-
}
|
|
217
|
-
const committed = await this.dbGet(key);
|
|
218
|
-
if (committed !== undefined) {
|
|
219
|
-
return committed;
|
|
220
|
-
}
|
|
221
|
-
return this.zeroHashes[level - 1];
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Gets a value from db by key.
|
|
226
|
-
* @param key - The key to by which to get the value.
|
|
227
|
-
* @returns A value from the db based on the key.
|
|
228
|
-
*/
|
|
229
|
-
private async dbGet(key: string): Promise<Buffer | undefined> {
|
|
230
|
-
return await this.db.get(key).catch(() => {});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Initializes the tree.
|
|
235
|
-
* @param prefilledSize - A number of leaves that are prefilled with values.
|
|
236
|
-
* @returns Empty promise.
|
|
237
|
-
*/
|
|
238
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
239
|
-
public async init(prefilledSize: number): Promise<void> {
|
|
240
|
-
// prefilledSize is used only by Indexed Tree.
|
|
241
|
-
await this.writeMeta();
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Writes meta data to the provided batch.
|
|
246
|
-
* @param batch - The batch to which to write the meta data.
|
|
247
|
-
*/
|
|
248
|
-
protected async writeMeta(batch?: LevelUpChain<string, Buffer>) {
|
|
249
|
-
const data = encodeMeta(this.getRoot(true), this.depth, this.getNumLeaves(true));
|
|
250
|
-
if (batch) {
|
|
251
|
-
batch.put(this.name, data);
|
|
252
|
-
} else {
|
|
253
|
-
await this.db.put(this.name, data);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Appends the given leaves to the tree.
|
|
259
|
-
* @param leaves - The leaves to append.
|
|
260
|
-
* @returns Empty promise.
|
|
261
|
-
*
|
|
262
|
-
* @remarks The batch insertion algorithm works as follows:
|
|
263
|
-
* 1. Insert all the leaves,
|
|
264
|
-
* 2. start iterating over levels from the bottom up,
|
|
265
|
-
* 3. on each level iterate over all the affected nodes (i.e. nodes whose preimages have changed),
|
|
266
|
-
* 4. fetch the preimage, hash it and insert the updated value.
|
|
267
|
-
* @remarks This algorithm is optimal when it comes to the number of hashing operations. It might not be optimal when
|
|
268
|
-
* it comes to the number of database reads, but that should be irrelevant given that most of the time
|
|
269
|
-
* `getLatestValueAtIndex` will return a value from cache (because at least one of the 2 children was
|
|
270
|
-
* touched in previous iteration).
|
|
271
|
-
*/
|
|
272
|
-
protected async appendLeaves(leaves: Buffer[]): Promise<void> {
|
|
273
|
-
const numLeaves = this.getNumLeaves(true);
|
|
274
|
-
if (numLeaves + BigInt(leaves.length) - 1n > this.maxIndex) {
|
|
275
|
-
throw Error(`Can't append beyond max index. Max index: ${this.maxIndex}`);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// 1. Insert all the leaves
|
|
279
|
-
let firstIndex = numLeaves;
|
|
280
|
-
let level = this.depth;
|
|
281
|
-
for (let i = 0; i < leaves.length; i++) {
|
|
282
|
-
const cacheKey = indexToKeyHash(this.name, level, firstIndex + BigInt(i));
|
|
283
|
-
this.cache[cacheKey] = leaves[i];
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
let lastIndex = firstIndex + BigInt(leaves.length);
|
|
287
|
-
// 2. Iterate over all the levels from the bottom up
|
|
288
|
-
while (level > 0) {
|
|
289
|
-
firstIndex >>= 1n;
|
|
290
|
-
lastIndex >>= 1n;
|
|
291
|
-
// 3.Iterate over all the affected nodes at this level and update them
|
|
292
|
-
for (let index = firstIndex; index <= lastIndex; index++) {
|
|
293
|
-
const lhs = await this.getLatestValueAtIndex(level, index * 2n, true);
|
|
294
|
-
const rhs = await this.getLatestValueAtIndex(level, index * 2n + 1n, true);
|
|
295
|
-
const cacheKey = indexToKeyHash(this.name, level - 1, index);
|
|
296
|
-
this.cache[cacheKey] = this.hasher.hash(lhs, rhs);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
level -= 1;
|
|
300
|
-
}
|
|
301
|
-
this.cachedSize = numLeaves + BigInt(leaves.length);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Returns the index of a leaf given its value, or undefined if no leaf with that value is found.
|
|
306
|
-
* @param value - The leaf value to look for.
|
|
307
|
-
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
308
|
-
* @returns The index of the first leaf found with a given value (undefined if not found).
|
|
309
|
-
*/
|
|
310
|
-
abstract findLeafIndex(value: Buffer, includeUncommitted: boolean): Promise<bigint | undefined>;
|
|
311
|
-
}
|