@aztec/world-state 0.0.0-test.1 → 0.0.1-commit.017a351
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 +1 -1
- package/dest/instrumentation/instrumentation.d.ts +6 -4
- package/dest/instrumentation/instrumentation.d.ts.map +1 -1
- package/dest/instrumentation/instrumentation.js +25 -41
- package/dest/native/bench_metrics.d.ts +23 -0
- package/dest/native/bench_metrics.d.ts.map +1 -0
- package/dest/native/bench_metrics.js +81 -0
- package/dest/native/fork_checkpoint.d.ts +7 -1
- package/dest/native/fork_checkpoint.d.ts.map +1 -1
- package/dest/native/fork_checkpoint.js +15 -3
- package/dest/native/index.d.ts +1 -1
- package/dest/native/ipc_world_state_instance.d.ts +45 -0
- package/dest/native/ipc_world_state_instance.d.ts.map +1 -0
- package/dest/native/ipc_world_state_instance.js +750 -0
- package/dest/native/merkle_trees_facade.d.ts +25 -9
- package/dest/native/merkle_trees_facade.d.ts.map +1 -1
- package/dest/native/merkle_trees_facade.js +109 -25
- package/dest/native/message.d.ts +87 -58
- package/dest/native/message.d.ts.map +1 -1
- package/dest/native/message.js +61 -61
- package/dest/native/native_world_state.d.ts +41 -21
- package/dest/native/native_world_state.d.ts.map +1 -1
- package/dest/native/native_world_state.js +177 -50
- package/dest/native/native_world_state_instance.d.ts +23 -25
- package/dest/native/native_world_state_instance.d.ts.map +1 -1
- package/dest/native/native_world_state_instance.js +8 -163
- package/dest/native/world_state_ops_queue.d.ts +1 -1
- package/dest/native/world_state_ops_queue.d.ts.map +1 -1
- package/dest/native/world_state_ops_queue.js +6 -6
- package/dest/synchronizer/config.d.ts +14 -6
- package/dest/synchronizer/config.d.ts.map +1 -1
- package/dest/synchronizer/config.js +36 -14
- package/dest/synchronizer/errors.d.ts +4 -0
- package/dest/synchronizer/errors.d.ts.map +1 -0
- package/dest/synchronizer/errors.js +5 -0
- package/dest/synchronizer/factory.d.ts +13 -5
- package/dest/synchronizer/factory.d.ts.map +1 -1
- package/dest/synchronizer/factory.js +15 -9
- package/dest/synchronizer/index.d.ts +1 -1
- package/dest/synchronizer/server_world_state_synchronizer.d.ts +21 -31
- package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/server_world_state_synchronizer.js +220 -96
- package/dest/test/index.d.ts +1 -1
- package/dest/test/utils.d.ts +12 -5
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +54 -47
- package/dest/testing.d.ts +6 -5
- package/dest/testing.d.ts.map +1 -1
- package/dest/testing.js +15 -15
- package/dest/world-state-db/index.d.ts +1 -1
- package/dest/world-state-db/merkle_tree_db.d.ts +12 -18
- package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
- package/package.json +27 -25
- package/src/instrumentation/instrumentation.ts +31 -43
- package/src/native/bench_metrics.ts +91 -0
- package/src/native/fork_checkpoint.ts +19 -3
- package/src/native/ipc_world_state_instance.ts +863 -0
- package/src/native/merkle_trees_facade.ts +127 -33
- package/src/native/message.ts +109 -80
- package/src/native/native_world_state.ts +207 -64
- package/src/native/native_world_state_instance.ts +28 -223
- package/src/native/world_state_ops_queue.ts +6 -6
- package/src/synchronizer/config.ts +58 -20
- package/src/synchronizer/errors.ts +5 -0
- package/src/synchronizer/factory.ts +48 -18
- package/src/synchronizer/server_world_state_synchronizer.ts +249 -121
- package/src/test/utils.ts +92 -82
- package/src/testing.ts +11 -16
- package/src/world-state-db/merkle_tree_db.ts +16 -18
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
4
|
import { serializeToBuffer } from '@aztec/foundation/serialize';
|
|
5
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
3
6
|
import { type IndexedTreeLeafPreimage, SiblingPath } from '@aztec/foundation/trees';
|
|
7
|
+
import { BlockHash } from '@aztec/stdlib/block';
|
|
4
8
|
import type {
|
|
5
9
|
BatchInsertionResult,
|
|
6
10
|
IndexedTreeId,
|
|
@@ -18,6 +22,7 @@ import {
|
|
|
18
22
|
PublicDataTreeLeafPreimage,
|
|
19
23
|
} from '@aztec/stdlib/trees';
|
|
20
24
|
import { type BlockHeader, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
25
|
+
import type { WorldStateRevision } from '@aztec/stdlib/world-state';
|
|
21
26
|
|
|
22
27
|
import assert from 'assert';
|
|
23
28
|
|
|
@@ -25,7 +30,6 @@ import {
|
|
|
25
30
|
type SerializedIndexedLeaf,
|
|
26
31
|
type SerializedLeafValue,
|
|
27
32
|
WorldStateMessageType,
|
|
28
|
-
type WorldStateRevision,
|
|
29
33
|
blockStateReference,
|
|
30
34
|
treeStateReferenceToSnapshot,
|
|
31
35
|
} from './message.js';
|
|
@@ -42,10 +46,36 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
|
|
|
42
46
|
return this.initialHeader;
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
getRevision(): WorldStateRevision {
|
|
50
|
+
return this.revision;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getSocketPath(): string {
|
|
54
|
+
return this.instance.getSocketPath();
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
findLeafIndices(treeId: MerkleTreeId, values: MerkleTreeLeafType<MerkleTreeId>[]): Promise<(bigint | undefined)[]> {
|
|
46
58
|
return this.findLeafIndicesAfter(treeId, values, 0n);
|
|
47
59
|
}
|
|
48
60
|
|
|
61
|
+
async findSiblingPaths<N extends number>(
|
|
62
|
+
treeId: MerkleTreeId,
|
|
63
|
+
values: MerkleTreeLeafType<MerkleTreeId>[],
|
|
64
|
+
): Promise<({ path: SiblingPath<N>; index: bigint } | undefined)[]> {
|
|
65
|
+
const response = await this.instance.call(WorldStateMessageType.FIND_SIBLING_PATHS, {
|
|
66
|
+
leaves: values.map(leaf => serializeLeaf(hydrateLeaf(treeId, leaf))),
|
|
67
|
+
revision: this.revision,
|
|
68
|
+
treeId,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return response.paths.map(path => {
|
|
72
|
+
if (!path) {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
return { path: new SiblingPath<N>(path.path.length as N, path.path), index: BigInt(path.index) };
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
49
79
|
async findLeafIndicesAfter(
|
|
50
80
|
treeId: MerkleTreeId,
|
|
51
81
|
leaves: MerkleTreeLeafType<MerkleTreeId>[],
|
|
@@ -93,7 +123,7 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
|
|
|
93
123
|
|
|
94
124
|
const leaf = deserializeLeafValue(resp);
|
|
95
125
|
if (leaf instanceof Fr) {
|
|
96
|
-
return leaf as any;
|
|
126
|
+
return treeId === MerkleTreeId.ARCHIVE ? (new BlockHash(leaf) as any) : (leaf as any);
|
|
97
127
|
} else {
|
|
98
128
|
return leaf.toBuffer() as any;
|
|
99
129
|
}
|
|
@@ -169,19 +199,27 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
|
|
|
169
199
|
async getBlockNumbersForLeafIndices<ID extends MerkleTreeId>(
|
|
170
200
|
treeId: ID,
|
|
171
201
|
leafIndices: bigint[],
|
|
172
|
-
): Promise<(
|
|
202
|
+
): Promise<(BlockNumber | undefined)[]> {
|
|
173
203
|
const response = await this.instance.call(WorldStateMessageType.GET_BLOCK_NUMBERS_FOR_LEAF_INDICES, {
|
|
174
204
|
treeId,
|
|
175
205
|
revision: this.revision,
|
|
176
206
|
leafIndices,
|
|
177
207
|
});
|
|
178
208
|
|
|
179
|
-
return response.blockNumbers.map(x => (x === undefined || x === null ? undefined :
|
|
209
|
+
return response.blockNumbers.map(x => (x === undefined || x === null ? undefined : BlockNumber(Number(x))));
|
|
180
210
|
}
|
|
181
211
|
}
|
|
182
212
|
|
|
183
213
|
export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTreeWriteOperations {
|
|
184
|
-
|
|
214
|
+
private log = createLogger('world-state:merkle-trees-fork-facade');
|
|
215
|
+
private closePromise: Promise<void> | undefined;
|
|
216
|
+
|
|
217
|
+
constructor(
|
|
218
|
+
instance: NativeWorldStateInstance,
|
|
219
|
+
initialHeader: BlockHeader,
|
|
220
|
+
revision: WorldStateRevision,
|
|
221
|
+
private opts: { closeDelayMs?: number },
|
|
222
|
+
) {
|
|
185
223
|
assert.notEqual(revision.forkId, 0, 'Fork ID must be set');
|
|
186
224
|
assert.equal(revision.includeUncommitted, true, 'Fork must include uncommitted data');
|
|
187
225
|
super(instance, initialHeader, revision);
|
|
@@ -196,7 +234,7 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
|
|
|
196
234
|
|
|
197
235
|
async appendLeaves<ID extends MerkleTreeId>(treeId: ID, leaves: MerkleTreeLeafType<ID>[]): Promise<void> {
|
|
198
236
|
await this.instance.call(WorldStateMessageType.APPEND_LEAVES, {
|
|
199
|
-
leaves: leaves.map(leaf => leaf as any),
|
|
237
|
+
leaves: leaves.map(leaf => serializeLeaf(hydrateLeaf(treeId, leaf as any))),
|
|
200
238
|
forkId: this.revision.forkId,
|
|
201
239
|
treeId,
|
|
202
240
|
});
|
|
@@ -217,15 +255,15 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
|
|
|
217
255
|
|
|
218
256
|
return {
|
|
219
257
|
newSubtreeSiblingPath: new SiblingPath<SubtreeSiblingPathHeight>(
|
|
220
|
-
resp.
|
|
221
|
-
resp.
|
|
258
|
+
resp.subtreePath.length as any,
|
|
259
|
+
resp.subtreePath,
|
|
222
260
|
),
|
|
223
|
-
sortedNewLeaves: resp.
|
|
261
|
+
sortedNewLeaves: resp.sortedLeaves
|
|
224
262
|
.map(([leaf]) => leaf)
|
|
225
263
|
.map(deserializeLeafValue)
|
|
226
264
|
.map(serializeToBuffer),
|
|
227
|
-
sortedNewLeavesIndexes: resp.
|
|
228
|
-
lowLeavesWitnessData: resp.
|
|
265
|
+
sortedNewLeavesIndexes: resp.sortedLeaves.map(([, index]) => index),
|
|
266
|
+
lowLeavesWitnessData: resp.lowLeafWitnessData.map(data => ({
|
|
229
267
|
index: BigInt(data.index),
|
|
230
268
|
leafPreimage: deserializeIndexedLeaf(data.leaf),
|
|
231
269
|
siblingPath: new SiblingPath<TreeHeight>(data.path.length as any, data.path),
|
|
@@ -245,12 +283,12 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
|
|
|
245
283
|
});
|
|
246
284
|
|
|
247
285
|
return {
|
|
248
|
-
lowLeavesWitnessData: resp.
|
|
286
|
+
lowLeavesWitnessData: resp.lowLeafWitnessData.map(data => ({
|
|
249
287
|
index: BigInt(data.index),
|
|
250
288
|
leafPreimage: deserializeIndexedLeaf(data.leaf),
|
|
251
289
|
siblingPath: new SiblingPath<TreeHeight>(data.path.length as any, data.path),
|
|
252
290
|
})),
|
|
253
|
-
insertionWitnessData: resp.
|
|
291
|
+
insertionWitnessData: resp.insertionWitnessData.map(data => ({
|
|
254
292
|
index: BigInt(data.index),
|
|
255
293
|
leafPreimage: deserializeIndexedLeaf(data.leaf),
|
|
256
294
|
siblingPath: new SiblingPath<TreeHeight>(data.path.length as any, data.path),
|
|
@@ -258,14 +296,51 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
|
|
|
258
296
|
};
|
|
259
297
|
}
|
|
260
298
|
|
|
261
|
-
public
|
|
299
|
+
public close(): Promise<void> {
|
|
262
300
|
assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
|
|
263
|
-
|
|
301
|
+
// Share the in-flight close promise across duplicate dispose calls so DELETE_FORK is sent at most once.
|
|
302
|
+
if (this.closePromise) {
|
|
303
|
+
return this.closePromise;
|
|
304
|
+
}
|
|
305
|
+
this.closePromise = this.doClose();
|
|
306
|
+
return this.closePromise;
|
|
264
307
|
}
|
|
265
308
|
|
|
266
|
-
|
|
309
|
+
private async doClose(): Promise<void> {
|
|
310
|
+
try {
|
|
311
|
+
await this.instance.call(WorldStateMessageType.DELETE_FORK, { forkId: this.revision.forkId });
|
|
312
|
+
} catch (err: any) {
|
|
313
|
+
// Ignore errors due to native instance being closed during shutdown.
|
|
314
|
+
// This can happen when validators are still processing block proposals while the node is stopping.
|
|
315
|
+
if (err?.message === 'Native instance is closed') {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
// Ignore "Fork not found": the native fork was already destroyed by a pending-chain unwind or a
|
|
319
|
+
// historical prune (both call C++ remove_forks_for_block). Fork IDs are monotonic and never reused,
|
|
320
|
+
// so swallowing this on close cannot mask a deletion of a different fork.
|
|
321
|
+
if (err?.message === 'Fork not found') {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
throw err;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async [Symbol.asyncDispose](): Promise<void> {
|
|
329
|
+
if (this.opts.closeDelayMs) {
|
|
330
|
+
void sleep(this.opts.closeDelayMs)
|
|
331
|
+
.then(() => this.close())
|
|
332
|
+
.catch(err => {
|
|
333
|
+
this.log.warn('Error closing MerkleTreesForkFacade after delay', { err });
|
|
334
|
+
});
|
|
335
|
+
} else {
|
|
336
|
+
await this.close();
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
public async createCheckpoint(): Promise<number> {
|
|
267
341
|
assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
|
|
268
|
-
await this.instance.call(WorldStateMessageType.CREATE_CHECKPOINT, { forkId: this.revision.forkId });
|
|
342
|
+
const resp = await this.instance.call(WorldStateMessageType.CREATE_CHECKPOINT, { forkId: this.revision.forkId });
|
|
343
|
+
return resp.depth;
|
|
269
344
|
}
|
|
270
345
|
|
|
271
346
|
public async commitCheckpoint(): Promise<void> {
|
|
@@ -277,11 +352,29 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
|
|
|
277
352
|
assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
|
|
278
353
|
await this.instance.call(WorldStateMessageType.REVERT_CHECKPOINT, { forkId: this.revision.forkId });
|
|
279
354
|
}
|
|
355
|
+
|
|
356
|
+
public async commitAllCheckpointsTo(depth: number): Promise<void> {
|
|
357
|
+
assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
|
|
358
|
+
await this.instance.call(WorldStateMessageType.COMMIT_ALL_CHECKPOINTS, {
|
|
359
|
+
forkId: this.revision.forkId,
|
|
360
|
+
depth,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
public async revertAllCheckpointsTo(depth: number): Promise<void> {
|
|
365
|
+
assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
|
|
366
|
+
await this.instance.call(WorldStateMessageType.REVERT_ALL_CHECKPOINTS, {
|
|
367
|
+
forkId: this.revision.forkId,
|
|
368
|
+
depth,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
280
371
|
}
|
|
281
372
|
|
|
282
|
-
function hydrateLeaf
|
|
373
|
+
function hydrateLeaf(treeId: MerkleTreeId, leaf: Fr | BlockHash | Buffer) {
|
|
283
374
|
if (leaf instanceof Fr) {
|
|
284
375
|
return leaf;
|
|
376
|
+
} else if (leaf instanceof BlockHash) {
|
|
377
|
+
return leaf.toFr();
|
|
285
378
|
} else if (treeId === MerkleTreeId.NULLIFIER_TREE) {
|
|
286
379
|
return NullifierLeaf.fromBuffer(leaf);
|
|
287
380
|
} else if (treeId === MerkleTreeId.PUBLIC_DATA_TREE) {
|
|
@@ -291,11 +384,13 @@ function hydrateLeaf<ID extends MerkleTreeId>(treeId: ID, leaf: Fr | Buffer) {
|
|
|
291
384
|
}
|
|
292
385
|
}
|
|
293
386
|
|
|
294
|
-
export function serializeLeaf(leaf: Fr | NullifierLeaf | PublicDataTreeLeaf): SerializedLeafValue {
|
|
295
|
-
if (leaf instanceof
|
|
387
|
+
export function serializeLeaf(leaf: Fr | BlockHash | NullifierLeaf | PublicDataTreeLeaf): SerializedLeafValue {
|
|
388
|
+
if (leaf instanceof BlockHash) {
|
|
389
|
+
return leaf.toBuffer();
|
|
390
|
+
} else if (leaf instanceof Fr) {
|
|
296
391
|
return leaf.toBuffer();
|
|
297
392
|
} else if (leaf instanceof NullifierLeaf) {
|
|
298
|
-
return {
|
|
393
|
+
return { nullifier: leaf.nullifier.toBuffer() };
|
|
299
394
|
} else {
|
|
300
395
|
return { value: leaf.value.toBuffer(), slot: leaf.slot.toBuffer() };
|
|
301
396
|
}
|
|
@@ -307,23 +402,22 @@ function deserializeLeafValue(leaf: SerializedLeafValue): Fr | NullifierLeaf | P
|
|
|
307
402
|
} else if ('slot' in leaf) {
|
|
308
403
|
return new PublicDataTreeLeaf(Fr.fromBuffer(leaf.slot), Fr.fromBuffer(leaf.value));
|
|
309
404
|
} else {
|
|
310
|
-
return new NullifierLeaf(Fr.fromBuffer(leaf.
|
|
405
|
+
return new NullifierLeaf(Fr.fromBuffer(leaf.nullifier));
|
|
311
406
|
}
|
|
312
407
|
}
|
|
313
408
|
|
|
314
|
-
function deserializeIndexedLeaf(
|
|
315
|
-
if ('slot' in leaf
|
|
409
|
+
function deserializeIndexedLeaf(leafPreimage: SerializedIndexedLeaf): IndexedTreeLeafPreimage {
|
|
410
|
+
if ('slot' in leafPreimage.leaf) {
|
|
316
411
|
return new PublicDataTreeLeafPreimage(
|
|
317
|
-
Fr.fromBuffer(leaf.
|
|
318
|
-
Fr.fromBuffer(
|
|
319
|
-
|
|
320
|
-
BigInt(leaf.nextIndex),
|
|
412
|
+
new PublicDataTreeLeaf(Fr.fromBuffer(leafPreimage.leaf.slot), Fr.fromBuffer(leafPreimage.leaf.value)),
|
|
413
|
+
Fr.fromBuffer(leafPreimage.nextKey),
|
|
414
|
+
BigInt(leafPreimage.nextIndex),
|
|
321
415
|
);
|
|
322
|
-
} else if ('
|
|
416
|
+
} else if ('nullifier' in leafPreimage.leaf) {
|
|
323
417
|
return new NullifierLeafPreimage(
|
|
324
|
-
Fr.fromBuffer(leaf.
|
|
325
|
-
Fr.fromBuffer(
|
|
326
|
-
BigInt(
|
|
418
|
+
new NullifierLeaf(Fr.fromBuffer(leafPreimage.leaf.nullifier)),
|
|
419
|
+
Fr.fromBuffer(leafPreimage.nextKey),
|
|
420
|
+
BigInt(leafPreimage.nextIndex),
|
|
327
421
|
);
|
|
328
422
|
} else {
|
|
329
423
|
throw new Error('Invalid leaf type');
|
package/src/native/message.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
3
|
import type { Tuple } from '@aztec/foundation/serialize';
|
|
3
4
|
import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
|
|
4
5
|
import type { StateReference } from '@aztec/stdlib/tx';
|
|
5
6
|
import type { UInt32 } from '@aztec/stdlib/types';
|
|
7
|
+
import type { WorldStateRevision } from '@aztec/stdlib/world-state';
|
|
6
8
|
|
|
7
9
|
export enum WorldStateMessageType {
|
|
8
10
|
GET_TREE_INFO = 100,
|
|
@@ -16,6 +18,7 @@ export enum WorldStateMessageType {
|
|
|
16
18
|
|
|
17
19
|
FIND_LEAF_INDICES,
|
|
18
20
|
FIND_LOW_LEAF,
|
|
21
|
+
FIND_SIBLING_PATHS,
|
|
19
22
|
|
|
20
23
|
APPEND_LEAVES,
|
|
21
24
|
BATCH_INSERT,
|
|
@@ -31,7 +34,7 @@ export enum WorldStateMessageType {
|
|
|
31
34
|
CREATE_FORK,
|
|
32
35
|
DELETE_FORK,
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
FINALIZE_BLOCKS,
|
|
35
38
|
UNWIND_BLOCKS,
|
|
36
39
|
REMOVE_HISTORICAL_BLOCKS,
|
|
37
40
|
|
|
@@ -40,6 +43,10 @@ export enum WorldStateMessageType {
|
|
|
40
43
|
CREATE_CHECKPOINT,
|
|
41
44
|
COMMIT_CHECKPOINT,
|
|
42
45
|
REVERT_CHECKPOINT,
|
|
46
|
+
COMMIT_ALL_CHECKPOINTS,
|
|
47
|
+
REVERT_ALL_CHECKPOINTS,
|
|
48
|
+
|
|
49
|
+
COPY_STORES,
|
|
43
50
|
|
|
44
51
|
CLOSE = 999,
|
|
45
52
|
}
|
|
@@ -50,11 +57,11 @@ interface WithTreeId {
|
|
|
50
57
|
|
|
51
58
|
export interface WorldStateStatusSummary {
|
|
52
59
|
/** Last block number that can still be unwound. */
|
|
53
|
-
|
|
54
|
-
/** Last block number that is
|
|
55
|
-
|
|
60
|
+
unfinalizedBlockNumber: BlockNumber;
|
|
61
|
+
/** Last block number that is finalized and cannot be unwound. */
|
|
62
|
+
finalizedBlockNumber: BlockNumber;
|
|
56
63
|
/** Oldest block still available for historical queries and forks. */
|
|
57
|
-
oldestHistoricalBlock:
|
|
64
|
+
oldestHistoricalBlock: BlockNumber;
|
|
58
65
|
/** Whether the trees are in sync with each other */
|
|
59
66
|
treesAreSynched: boolean;
|
|
60
67
|
}
|
|
@@ -75,11 +82,11 @@ export interface TreeMeta {
|
|
|
75
82
|
/** The tree's initial root value */
|
|
76
83
|
initialRoot: Fr;
|
|
77
84
|
/** The current oldest historical block number of the tree */
|
|
78
|
-
oldestHistoricBlock:
|
|
79
|
-
/** The current
|
|
80
|
-
|
|
81
|
-
/** The current
|
|
82
|
-
|
|
85
|
+
oldestHistoricBlock: BlockNumber;
|
|
86
|
+
/** The current unfinalized block number of the tree */
|
|
87
|
+
unfinalizedBlockHeight: BlockNumber;
|
|
88
|
+
/** The current finalized block number of the tree */
|
|
89
|
+
finalizedBlockHeight: BlockNumber;
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
export interface DBStats {
|
|
@@ -94,6 +101,8 @@ export interface DBStats {
|
|
|
94
101
|
export interface TreeDBStats {
|
|
95
102
|
/** The configured max size of the DB mapping file (effectively the max possible size of the DB) */
|
|
96
103
|
mapSize: bigint;
|
|
104
|
+
/** The physical file size of the database on disk */
|
|
105
|
+
physicalFileSize: bigint;
|
|
97
106
|
/** Stats for the 'blocks' DB */
|
|
98
107
|
blocksDBStats: DBStats;
|
|
99
108
|
/** Stats for the 'nodes' DB */
|
|
@@ -149,6 +158,7 @@ export function buildEmptyDBStats() {
|
|
|
149
158
|
export function buildEmptyTreeDBStats() {
|
|
150
159
|
return {
|
|
151
160
|
mapSize: 0n,
|
|
161
|
+
physicalFileSize: 0n,
|
|
152
162
|
blocksDBStats: buildEmptyDBStats(),
|
|
153
163
|
nodesDBStats: buildEmptyDBStats(),
|
|
154
164
|
leafIndicesDBStats: buildEmptyDBStats(),
|
|
@@ -164,9 +174,9 @@ export function buildEmptyTreeMeta() {
|
|
|
164
174
|
depth: 0,
|
|
165
175
|
size: 0n,
|
|
166
176
|
committedSize: 0n,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
oldestHistoricBlock:
|
|
177
|
+
unfinalizedBlockHeight: BlockNumber.ZERO,
|
|
178
|
+
finalizedBlockHeight: BlockNumber.ZERO,
|
|
179
|
+
oldestHistoricBlock: BlockNumber.ZERO,
|
|
170
180
|
root: Fr.ZERO,
|
|
171
181
|
initialRoot: Fr.ZERO,
|
|
172
182
|
initialSize: 0n,
|
|
@@ -195,9 +205,9 @@ export function buildEmptyWorldStateDBStats() {
|
|
|
195
205
|
|
|
196
206
|
export function buildEmptyWorldStateSummary() {
|
|
197
207
|
return {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
oldestHistoricalBlock:
|
|
208
|
+
unfinalizedBlockNumber: BlockNumber.ZERO,
|
|
209
|
+
finalizedBlockNumber: BlockNumber.ZERO,
|
|
210
|
+
oldestHistoricalBlock: BlockNumber.ZERO,
|
|
201
211
|
treesAreSynched: true,
|
|
202
212
|
} as WorldStateStatusSummary;
|
|
203
213
|
}
|
|
@@ -210,61 +220,62 @@ export function buildEmptyWorldStateStatusFull() {
|
|
|
210
220
|
} as WorldStateStatusFull;
|
|
211
221
|
}
|
|
212
222
|
|
|
213
|
-
export function
|
|
214
|
-
summary.
|
|
215
|
-
summary.
|
|
216
|
-
summary.oldestHistoricalBlock = BigInt(summary.oldestHistoricalBlock);
|
|
223
|
+
export function sanitizeSummary(summary: WorldStateStatusSummary) {
|
|
224
|
+
summary.finalizedBlockNumber = BlockNumber.fromBigInt(BigInt(summary.finalizedBlockNumber));
|
|
225
|
+
summary.unfinalizedBlockNumber = BlockNumber.fromBigInt(BigInt(summary.unfinalizedBlockNumber));
|
|
226
|
+
summary.oldestHistoricalBlock = BlockNumber.fromBigInt(BigInt(summary.oldestHistoricalBlock));
|
|
217
227
|
return summary;
|
|
218
228
|
}
|
|
219
229
|
|
|
220
|
-
export function
|
|
230
|
+
export function sanitizeDBStats(stats: DBStats) {
|
|
221
231
|
stats.numDataItems = BigInt(stats.numDataItems);
|
|
222
232
|
stats.totalUsedSize = BigInt(stats.totalUsedSize);
|
|
223
233
|
return stats;
|
|
224
234
|
}
|
|
225
235
|
|
|
226
|
-
export function
|
|
236
|
+
export function sanitizeMeta(meta: TreeMeta) {
|
|
227
237
|
meta.committedSize = BigInt(meta.committedSize);
|
|
228
|
-
meta.
|
|
238
|
+
meta.finalizedBlockHeight = BlockNumber.fromBigInt(BigInt(meta.finalizedBlockHeight));
|
|
229
239
|
meta.initialSize = BigInt(meta.initialSize);
|
|
230
|
-
meta.oldestHistoricBlock = BigInt(meta.oldestHistoricBlock);
|
|
240
|
+
meta.oldestHistoricBlock = BlockNumber.fromBigInt(BigInt(meta.oldestHistoricBlock));
|
|
231
241
|
meta.size = BigInt(meta.size);
|
|
232
|
-
meta.
|
|
242
|
+
meta.unfinalizedBlockHeight = BlockNumber.fromBigInt(BigInt(meta.unfinalizedBlockHeight));
|
|
233
243
|
return meta;
|
|
234
244
|
}
|
|
235
245
|
|
|
236
|
-
export function
|
|
237
|
-
stats.blocksDBStats =
|
|
238
|
-
stats.leafIndicesDBStats =
|
|
239
|
-
stats.leafPreimagesDBStats =
|
|
240
|
-
stats.blockIndicesDBStats =
|
|
241
|
-
stats.nodesDBStats =
|
|
246
|
+
export function sanitizeTreeDBStats(stats: TreeDBStats) {
|
|
247
|
+
stats.blocksDBStats = sanitizeDBStats(stats.blocksDBStats);
|
|
248
|
+
stats.leafIndicesDBStats = sanitizeDBStats(stats.leafIndicesDBStats);
|
|
249
|
+
stats.leafPreimagesDBStats = sanitizeDBStats(stats.leafPreimagesDBStats);
|
|
250
|
+
stats.blockIndicesDBStats = sanitizeDBStats(stats.blockIndicesDBStats);
|
|
251
|
+
stats.nodesDBStats = sanitizeDBStats(stats.nodesDBStats);
|
|
242
252
|
stats.mapSize = BigInt(stats.mapSize);
|
|
253
|
+
stats.physicalFileSize = BigInt(stats.physicalFileSize);
|
|
243
254
|
return stats;
|
|
244
255
|
}
|
|
245
256
|
|
|
246
|
-
export function
|
|
247
|
-
stats.archiveTreeStats =
|
|
248
|
-
stats.messageTreeStats =
|
|
249
|
-
stats.noteHashTreeStats =
|
|
250
|
-
stats.nullifierTreeStats =
|
|
251
|
-
stats.publicDataTreeStats =
|
|
257
|
+
export function sanitizeWorldStateDBStats(stats: WorldStateDBStats) {
|
|
258
|
+
stats.archiveTreeStats = sanitizeTreeDBStats(stats.archiveTreeStats);
|
|
259
|
+
stats.messageTreeStats = sanitizeTreeDBStats(stats.messageTreeStats);
|
|
260
|
+
stats.noteHashTreeStats = sanitizeTreeDBStats(stats.noteHashTreeStats);
|
|
261
|
+
stats.nullifierTreeStats = sanitizeTreeDBStats(stats.nullifierTreeStats);
|
|
262
|
+
stats.publicDataTreeStats = sanitizeTreeDBStats(stats.publicDataTreeStats);
|
|
252
263
|
return stats;
|
|
253
264
|
}
|
|
254
265
|
|
|
255
|
-
export function
|
|
256
|
-
meta.archiveTreeMeta =
|
|
257
|
-
meta.messageTreeMeta =
|
|
258
|
-
meta.noteHashTreeMeta =
|
|
259
|
-
meta.nullifierTreeMeta =
|
|
260
|
-
meta.publicDataTreeMeta =
|
|
266
|
+
export function sanitizeWorldStateTreeMeta(meta: WorldStateMeta) {
|
|
267
|
+
meta.archiveTreeMeta = sanitizeMeta(meta.archiveTreeMeta);
|
|
268
|
+
meta.messageTreeMeta = sanitizeMeta(meta.messageTreeMeta);
|
|
269
|
+
meta.noteHashTreeMeta = sanitizeMeta(meta.noteHashTreeMeta);
|
|
270
|
+
meta.nullifierTreeMeta = sanitizeMeta(meta.nullifierTreeMeta);
|
|
271
|
+
meta.publicDataTreeMeta = sanitizeMeta(meta.publicDataTreeMeta);
|
|
261
272
|
return meta;
|
|
262
273
|
}
|
|
263
274
|
|
|
264
|
-
export function
|
|
265
|
-
status.dbStats =
|
|
266
|
-
status.summary =
|
|
267
|
-
status.meta =
|
|
275
|
+
export function sanitizeFullStatus(status: WorldStateStatusFull) {
|
|
276
|
+
status.dbStats = sanitizeWorldStateDBStats(status.dbStats);
|
|
277
|
+
status.summary = sanitizeSummary(status.summary);
|
|
278
|
+
status.meta = sanitizeWorldStateTreeMeta(status.meta);
|
|
268
279
|
return status;
|
|
269
280
|
}
|
|
270
281
|
|
|
@@ -272,6 +283,16 @@ interface WithForkId {
|
|
|
272
283
|
forkId: number;
|
|
273
284
|
}
|
|
274
285
|
|
|
286
|
+
interface CreateCheckpointResponse {
|
|
287
|
+
depth: number;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Request to commit/revert all checkpoints down to a target depth. The resulting depth after the operation equals the given depth. */
|
|
291
|
+
interface CheckpointDepthRequest extends WithForkId {
|
|
292
|
+
/** The target depth after the operation. All checkpoints above this depth are committed/reverted. */
|
|
293
|
+
depth: number;
|
|
294
|
+
}
|
|
295
|
+
|
|
275
296
|
interface WithWorldStateRevision {
|
|
276
297
|
revision: WorldStateRevision;
|
|
277
298
|
}
|
|
@@ -286,13 +307,13 @@ interface WithLeafIndex {
|
|
|
286
307
|
|
|
287
308
|
export type SerializedLeafValue =
|
|
288
309
|
| Buffer // Fr
|
|
289
|
-
| {
|
|
310
|
+
| { nullifier: Buffer } // NullifierLeaf
|
|
290
311
|
| { value: Buffer; slot: Buffer }; // PublicDataTreeLeaf
|
|
291
312
|
|
|
292
313
|
export type SerializedIndexedLeaf = {
|
|
293
|
-
|
|
314
|
+
leaf: Exclude<SerializedLeafValue, Buffer>;
|
|
294
315
|
nextIndex: bigint | number;
|
|
295
|
-
|
|
316
|
+
nextKey: Buffer; // Fr
|
|
296
317
|
};
|
|
297
318
|
|
|
298
319
|
interface WithLeafValues {
|
|
@@ -300,7 +321,7 @@ interface WithLeafValues {
|
|
|
300
321
|
}
|
|
301
322
|
|
|
302
323
|
interface BlockShiftRequest extends WithCanonicalForkId {
|
|
303
|
-
toBlockNumber:
|
|
324
|
+
toBlockNumber: BlockNumber;
|
|
304
325
|
}
|
|
305
326
|
|
|
306
327
|
interface WithLeaves {
|
|
@@ -344,6 +365,16 @@ interface FindLeafIndicesResponse {
|
|
|
344
365
|
indices: bigint[];
|
|
345
366
|
}
|
|
346
367
|
|
|
368
|
+
interface FindSiblingPathsRequest extends WithTreeId, WithLeafValues, WithWorldStateRevision {}
|
|
369
|
+
|
|
370
|
+
interface SiblingPathAndIndex {
|
|
371
|
+
index: bigint;
|
|
372
|
+
path: Buffer[];
|
|
373
|
+
}
|
|
374
|
+
interface FindSiblingPathsResponse {
|
|
375
|
+
paths: (SiblingPathAndIndex | undefined)[];
|
|
376
|
+
}
|
|
377
|
+
|
|
347
378
|
interface FindLowLeafRequest extends WithTreeId, WithWorldStateRevision {
|
|
348
379
|
key: Fr;
|
|
349
380
|
}
|
|
@@ -359,24 +390,24 @@ interface BatchInsertRequest extends WithTreeId, WithForkId, WithLeaves {
|
|
|
359
390
|
}
|
|
360
391
|
|
|
361
392
|
interface BatchInsertResponse {
|
|
362
|
-
|
|
393
|
+
lowLeafWitnessData: ReadonlyArray<{
|
|
363
394
|
leaf: SerializedIndexedLeaf;
|
|
364
395
|
index: bigint | number;
|
|
365
396
|
path: Tuple<Buffer, number>;
|
|
366
397
|
}>;
|
|
367
|
-
|
|
368
|
-
|
|
398
|
+
sortedLeaves: ReadonlyArray<[SerializedLeafValue, UInt32]>;
|
|
399
|
+
subtreePath: Tuple<Buffer, number>;
|
|
369
400
|
}
|
|
370
401
|
|
|
371
402
|
interface SequentialInsertRequest extends WithTreeId, WithForkId, WithLeaves {}
|
|
372
403
|
|
|
373
404
|
interface SequentialInsertResponse {
|
|
374
|
-
|
|
405
|
+
lowLeafWitnessData: ReadonlyArray<{
|
|
375
406
|
leaf: SerializedIndexedLeaf;
|
|
376
407
|
index: bigint | number;
|
|
377
408
|
path: Tuple<Buffer, number>;
|
|
378
409
|
}>;
|
|
379
|
-
|
|
410
|
+
insertionWitnessData: ReadonlyArray<{
|
|
380
411
|
leaf: SerializedIndexedLeaf;
|
|
381
412
|
index: bigint | number;
|
|
382
413
|
path: Tuple<Buffer, number>;
|
|
@@ -389,9 +420,9 @@ interface UpdateArchiveRequest extends WithForkId {
|
|
|
389
420
|
}
|
|
390
421
|
|
|
391
422
|
interface SyncBlockRequest extends WithCanonicalForkId {
|
|
392
|
-
blockNumber:
|
|
423
|
+
blockNumber: BlockNumber;
|
|
393
424
|
blockStateRef: BlockStateReference;
|
|
394
|
-
blockHeaderHash:
|
|
425
|
+
blockHeaderHash: Buffer;
|
|
395
426
|
paddedNoteHashes: readonly SerializedLeafValue[];
|
|
396
427
|
paddedL1ToL2Messages: readonly SerializedLeafValue[];
|
|
397
428
|
paddedNullifiers: readonly SerializedLeafValue[];
|
|
@@ -400,7 +431,7 @@ interface SyncBlockRequest extends WithCanonicalForkId {
|
|
|
400
431
|
|
|
401
432
|
interface CreateForkRequest extends WithCanonicalForkId {
|
|
402
433
|
latest: boolean;
|
|
403
|
-
blockNumber:
|
|
434
|
+
blockNumber: BlockNumber;
|
|
404
435
|
}
|
|
405
436
|
|
|
406
437
|
interface CreateForkResponse {
|
|
@@ -409,6 +440,11 @@ interface CreateForkResponse {
|
|
|
409
440
|
|
|
410
441
|
interface DeleteForkRequest extends WithForkId {}
|
|
411
442
|
|
|
443
|
+
interface CopyStoresRequest extends WithCanonicalForkId {
|
|
444
|
+
dstPath: string;
|
|
445
|
+
compact: boolean;
|
|
446
|
+
}
|
|
447
|
+
|
|
412
448
|
export type WorldStateRequestCategories = WithForkId | WithWorldStateRevision | WithCanonicalForkId;
|
|
413
449
|
|
|
414
450
|
export function isWithForkId(body: WorldStateRequestCategories): body is WithForkId {
|
|
@@ -435,6 +471,7 @@ export type WorldStateRequest = {
|
|
|
435
471
|
|
|
436
472
|
[WorldStateMessageType.FIND_LEAF_INDICES]: FindLeafIndicesRequest;
|
|
437
473
|
[WorldStateMessageType.FIND_LOW_LEAF]: FindLowLeafRequest;
|
|
474
|
+
[WorldStateMessageType.FIND_SIBLING_PATHS]: FindSiblingPathsRequest;
|
|
438
475
|
|
|
439
476
|
[WorldStateMessageType.APPEND_LEAVES]: AppendLeavesRequest;
|
|
440
477
|
[WorldStateMessageType.BATCH_INSERT]: BatchInsertRequest;
|
|
@@ -452,13 +489,17 @@ export type WorldStateRequest = {
|
|
|
452
489
|
|
|
453
490
|
[WorldStateMessageType.REMOVE_HISTORICAL_BLOCKS]: BlockShiftRequest;
|
|
454
491
|
[WorldStateMessageType.UNWIND_BLOCKS]: BlockShiftRequest;
|
|
455
|
-
[WorldStateMessageType.
|
|
492
|
+
[WorldStateMessageType.FINALIZE_BLOCKS]: BlockShiftRequest;
|
|
456
493
|
|
|
457
494
|
[WorldStateMessageType.GET_STATUS]: WithCanonicalForkId;
|
|
458
495
|
|
|
459
496
|
[WorldStateMessageType.CREATE_CHECKPOINT]: WithForkId;
|
|
460
497
|
[WorldStateMessageType.COMMIT_CHECKPOINT]: WithForkId;
|
|
461
498
|
[WorldStateMessageType.REVERT_CHECKPOINT]: WithForkId;
|
|
499
|
+
[WorldStateMessageType.COMMIT_ALL_CHECKPOINTS]: CheckpointDepthRequest;
|
|
500
|
+
[WorldStateMessageType.REVERT_ALL_CHECKPOINTS]: CheckpointDepthRequest;
|
|
501
|
+
|
|
502
|
+
[WorldStateMessageType.COPY_STORES]: CopyStoresRequest;
|
|
462
503
|
|
|
463
504
|
[WorldStateMessageType.CLOSE]: WithCanonicalForkId;
|
|
464
505
|
};
|
|
@@ -475,6 +516,7 @@ export type WorldStateResponse = {
|
|
|
475
516
|
|
|
476
517
|
[WorldStateMessageType.FIND_LEAF_INDICES]: FindLeafIndicesResponse;
|
|
477
518
|
[WorldStateMessageType.FIND_LOW_LEAF]: FindLowLeafResponse;
|
|
519
|
+
[WorldStateMessageType.FIND_SIBLING_PATHS]: FindSiblingPathsResponse;
|
|
478
520
|
|
|
479
521
|
[WorldStateMessageType.APPEND_LEAVES]: void;
|
|
480
522
|
[WorldStateMessageType.BATCH_INSERT]: BatchInsertResponse;
|
|
@@ -492,33 +534,20 @@ export type WorldStateResponse = {
|
|
|
492
534
|
|
|
493
535
|
[WorldStateMessageType.REMOVE_HISTORICAL_BLOCKS]: WorldStateStatusFull;
|
|
494
536
|
[WorldStateMessageType.UNWIND_BLOCKS]: WorldStateStatusFull;
|
|
495
|
-
[WorldStateMessageType.
|
|
537
|
+
[WorldStateMessageType.FINALIZE_BLOCKS]: WorldStateStatusSummary;
|
|
496
538
|
|
|
497
539
|
[WorldStateMessageType.GET_STATUS]: WorldStateStatusSummary;
|
|
498
540
|
|
|
499
|
-
[WorldStateMessageType.CREATE_CHECKPOINT]:
|
|
541
|
+
[WorldStateMessageType.CREATE_CHECKPOINT]: CreateCheckpointResponse;
|
|
500
542
|
[WorldStateMessageType.COMMIT_CHECKPOINT]: void;
|
|
501
543
|
[WorldStateMessageType.REVERT_CHECKPOINT]: void;
|
|
544
|
+
[WorldStateMessageType.COMMIT_ALL_CHECKPOINTS]: void;
|
|
545
|
+
[WorldStateMessageType.REVERT_ALL_CHECKPOINTS]: void;
|
|
502
546
|
|
|
503
|
-
[WorldStateMessageType.
|
|
504
|
-
};
|
|
547
|
+
[WorldStateMessageType.COPY_STORES]: void;
|
|
505
548
|
|
|
506
|
-
|
|
507
|
-
forkId: number;
|
|
508
|
-
blockNumber: number;
|
|
509
|
-
includeUncommitted: boolean;
|
|
549
|
+
[WorldStateMessageType.CLOSE]: void;
|
|
510
550
|
};
|
|
511
|
-
export function worldStateRevision(
|
|
512
|
-
includeUncommitted: boolean,
|
|
513
|
-
forkId: number | undefined,
|
|
514
|
-
blockNumber: number | undefined,
|
|
515
|
-
): WorldStateRevision {
|
|
516
|
-
return {
|
|
517
|
-
forkId: forkId ?? 0,
|
|
518
|
-
blockNumber: blockNumber ?? 0,
|
|
519
|
-
includeUncommitted,
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
551
|
|
|
523
552
|
type TreeStateReference = readonly [Buffer, number | bigint];
|
|
524
553
|
type BlockStateReference = Map<Exclude<MerkleTreeId, MerkleTreeId.ARCHIVE>, TreeStateReference>;
|