@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.
Files changed (69) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/instrumentation/instrumentation.d.ts +6 -4
  3. package/dest/instrumentation/instrumentation.d.ts.map +1 -1
  4. package/dest/instrumentation/instrumentation.js +25 -41
  5. package/dest/native/bench_metrics.d.ts +23 -0
  6. package/dest/native/bench_metrics.d.ts.map +1 -0
  7. package/dest/native/bench_metrics.js +81 -0
  8. package/dest/native/fork_checkpoint.d.ts +7 -1
  9. package/dest/native/fork_checkpoint.d.ts.map +1 -1
  10. package/dest/native/fork_checkpoint.js +15 -3
  11. package/dest/native/index.d.ts +1 -1
  12. package/dest/native/ipc_world_state_instance.d.ts +45 -0
  13. package/dest/native/ipc_world_state_instance.d.ts.map +1 -0
  14. package/dest/native/ipc_world_state_instance.js +750 -0
  15. package/dest/native/merkle_trees_facade.d.ts +25 -9
  16. package/dest/native/merkle_trees_facade.d.ts.map +1 -1
  17. package/dest/native/merkle_trees_facade.js +109 -25
  18. package/dest/native/message.d.ts +87 -58
  19. package/dest/native/message.d.ts.map +1 -1
  20. package/dest/native/message.js +61 -61
  21. package/dest/native/native_world_state.d.ts +41 -21
  22. package/dest/native/native_world_state.d.ts.map +1 -1
  23. package/dest/native/native_world_state.js +177 -50
  24. package/dest/native/native_world_state_instance.d.ts +23 -25
  25. package/dest/native/native_world_state_instance.d.ts.map +1 -1
  26. package/dest/native/native_world_state_instance.js +8 -163
  27. package/dest/native/world_state_ops_queue.d.ts +1 -1
  28. package/dest/native/world_state_ops_queue.d.ts.map +1 -1
  29. package/dest/native/world_state_ops_queue.js +6 -6
  30. package/dest/synchronizer/config.d.ts +14 -6
  31. package/dest/synchronizer/config.d.ts.map +1 -1
  32. package/dest/synchronizer/config.js +36 -14
  33. package/dest/synchronizer/errors.d.ts +4 -0
  34. package/dest/synchronizer/errors.d.ts.map +1 -0
  35. package/dest/synchronizer/errors.js +5 -0
  36. package/dest/synchronizer/factory.d.ts +13 -5
  37. package/dest/synchronizer/factory.d.ts.map +1 -1
  38. package/dest/synchronizer/factory.js +15 -9
  39. package/dest/synchronizer/index.d.ts +1 -1
  40. package/dest/synchronizer/server_world_state_synchronizer.d.ts +21 -31
  41. package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
  42. package/dest/synchronizer/server_world_state_synchronizer.js +220 -96
  43. package/dest/test/index.d.ts +1 -1
  44. package/dest/test/utils.d.ts +12 -5
  45. package/dest/test/utils.d.ts.map +1 -1
  46. package/dest/test/utils.js +54 -47
  47. package/dest/testing.d.ts +6 -5
  48. package/dest/testing.d.ts.map +1 -1
  49. package/dest/testing.js +15 -15
  50. package/dest/world-state-db/index.d.ts +1 -1
  51. package/dest/world-state-db/merkle_tree_db.d.ts +12 -18
  52. package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
  53. package/package.json +27 -25
  54. package/src/instrumentation/instrumentation.ts +31 -43
  55. package/src/native/bench_metrics.ts +91 -0
  56. package/src/native/fork_checkpoint.ts +19 -3
  57. package/src/native/ipc_world_state_instance.ts +863 -0
  58. package/src/native/merkle_trees_facade.ts +127 -33
  59. package/src/native/message.ts +109 -80
  60. package/src/native/native_world_state.ts +207 -64
  61. package/src/native/native_world_state_instance.ts +28 -223
  62. package/src/native/world_state_ops_queue.ts +6 -6
  63. package/src/synchronizer/config.ts +58 -20
  64. package/src/synchronizer/errors.ts +5 -0
  65. package/src/synchronizer/factory.ts +48 -18
  66. package/src/synchronizer/server_world_state_synchronizer.ts +249 -121
  67. package/src/test/utils.ts +92 -82
  68. package/src/testing.ts +11 -16
  69. package/src/world-state-db/merkle_tree_db.ts +16 -18
@@ -1,6 +1,10 @@
1
- import { Fr } from '@aztec/foundation/fields';
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<(bigint | undefined)[]> {
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 : BigInt(x)));
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
- constructor(instance: NativeWorldStateInstance, initialHeader: BlockHeader, revision: WorldStateRevision) {
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.subtree_path.length as any,
221
- resp.subtree_path,
258
+ resp.subtreePath.length as any,
259
+ resp.subtreePath,
222
260
  ),
223
- sortedNewLeaves: resp.sorted_leaves
261
+ sortedNewLeaves: resp.sortedLeaves
224
262
  .map(([leaf]) => leaf)
225
263
  .map(deserializeLeafValue)
226
264
  .map(serializeToBuffer),
227
- sortedNewLeavesIndexes: resp.sorted_leaves.map(([, index]) => index),
228
- lowLeavesWitnessData: resp.low_leaf_witness_data.map(data => ({
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.low_leaf_witness_data.map(data => ({
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.insertion_witness_data.map(data => ({
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 async close(): Promise<void> {
299
+ public close(): Promise<void> {
262
300
  assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
263
- await this.instance.call(WorldStateMessageType.DELETE_FORK, { forkId: this.revision.forkId });
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
- public async createCheckpoint(): Promise<void> {
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<ID extends MerkleTreeId>(treeId: ID, leaf: Fr | Buffer) {
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 Fr) {
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 { value: leaf.nullifier.toBuffer() };
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.value));
405
+ return new NullifierLeaf(Fr.fromBuffer(leaf.nullifier));
311
406
  }
312
407
  }
313
408
 
314
- function deserializeIndexedLeaf(leaf: SerializedIndexedLeaf): IndexedTreeLeafPreimage {
315
- if ('slot' in leaf.value) {
409
+ function deserializeIndexedLeaf(leafPreimage: SerializedIndexedLeaf): IndexedTreeLeafPreimage {
410
+ if ('slot' in leafPreimage.leaf) {
316
411
  return new PublicDataTreeLeafPreimage(
317
- Fr.fromBuffer(leaf.value.slot),
318
- Fr.fromBuffer(leaf.value.value),
319
- Fr.fromBuffer(leaf.nextValue),
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 ('value' in leaf.value) {
416
+ } else if ('nullifier' in leafPreimage.leaf) {
323
417
  return new NullifierLeafPreimage(
324
- Fr.fromBuffer(leaf.value.value),
325
- Fr.fromBuffer(leaf.nextValue),
326
- BigInt(leaf.nextIndex),
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');
@@ -1,8 +1,10 @@
1
- import { Fr } from '@aztec/foundation/fields';
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
- FINALISE_BLOCKS,
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
- unfinalisedBlockNumber: bigint;
54
- /** Last block number that is finalised and cannot be unwound. */
55
- finalisedBlockNumber: bigint;
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: bigint;
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: bigint;
79
- /** The current unfinalised block number of the tree */
80
- unfinalisedBlockHeight: bigint;
81
- /** The current finalised block number of the tree */
82
- finalisedBlockHeight: bigint;
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
- unfinalisedBlockHeight: 0n,
168
- finalisedBlockHeight: 0n,
169
- oldestHistoricBlock: 0n,
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
- unfinalisedBlockNumber: 0n,
199
- finalisedBlockNumber: 0n,
200
- oldestHistoricalBlock: 0n,
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 sanitiseSummary(summary: WorldStateStatusSummary) {
214
- summary.finalisedBlockNumber = BigInt(summary.finalisedBlockNumber);
215
- summary.unfinalisedBlockNumber = BigInt(summary.unfinalisedBlockNumber);
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 sanitiseDBStats(stats: DBStats) {
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 sanitiseMeta(meta: TreeMeta) {
236
+ export function sanitizeMeta(meta: TreeMeta) {
227
237
  meta.committedSize = BigInt(meta.committedSize);
228
- meta.finalisedBlockHeight = BigInt(meta.finalisedBlockHeight);
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.unfinalisedBlockHeight = BigInt(meta.unfinalisedBlockHeight);
242
+ meta.unfinalizedBlockHeight = BlockNumber.fromBigInt(BigInt(meta.unfinalizedBlockHeight));
233
243
  return meta;
234
244
  }
235
245
 
236
- export function sanitiseTreeDBStats(stats: TreeDBStats) {
237
- stats.blocksDBStats = sanitiseDBStats(stats.blocksDBStats);
238
- stats.leafIndicesDBStats = sanitiseDBStats(stats.leafIndicesDBStats);
239
- stats.leafPreimagesDBStats = sanitiseDBStats(stats.leafPreimagesDBStats);
240
- stats.blockIndicesDBStats = sanitiseDBStats(stats.blockIndicesDBStats);
241
- stats.nodesDBStats = sanitiseDBStats(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 sanitiseWorldStateDBStats(stats: WorldStateDBStats) {
247
- stats.archiveTreeStats = sanitiseTreeDBStats(stats.archiveTreeStats);
248
- stats.messageTreeStats = sanitiseTreeDBStats(stats.messageTreeStats);
249
- stats.noteHashTreeStats = sanitiseTreeDBStats(stats.noteHashTreeStats);
250
- stats.nullifierTreeStats = sanitiseTreeDBStats(stats.nullifierTreeStats);
251
- stats.publicDataTreeStats = sanitiseTreeDBStats(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 sanitiseWorldStateTreeMeta(meta: WorldStateMeta) {
256
- meta.archiveTreeMeta = sanitiseMeta(meta.archiveTreeMeta);
257
- meta.messageTreeMeta = sanitiseMeta(meta.messageTreeMeta);
258
- meta.noteHashTreeMeta = sanitiseMeta(meta.noteHashTreeMeta);
259
- meta.nullifierTreeMeta = sanitiseMeta(meta.nullifierTreeMeta);
260
- meta.publicDataTreeMeta = sanitiseMeta(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 sanitiseFullStatus(status: WorldStateStatusFull) {
265
- status.dbStats = sanitiseWorldStateDBStats(status.dbStats);
266
- status.summary = sanitiseSummary(status.summary);
267
- status.meta = sanitiseWorldStateTreeMeta(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
- | { value: Buffer } // NullifierLeaf
310
+ | { nullifier: Buffer } // NullifierLeaf
290
311
  | { value: Buffer; slot: Buffer }; // PublicDataTreeLeaf
291
312
 
292
313
  export type SerializedIndexedLeaf = {
293
- value: Exclude<SerializedLeafValue, Buffer>;
314
+ leaf: Exclude<SerializedLeafValue, Buffer>;
294
315
  nextIndex: bigint | number;
295
- nextValue: Buffer; // Fr
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: bigint;
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
- low_leaf_witness_data: ReadonlyArray<{
393
+ lowLeafWitnessData: ReadonlyArray<{
363
394
  leaf: SerializedIndexedLeaf;
364
395
  index: bigint | number;
365
396
  path: Tuple<Buffer, number>;
366
397
  }>;
367
- sorted_leaves: ReadonlyArray<[SerializedLeafValue, UInt32]>;
368
- subtree_path: Tuple<Buffer, number>;
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
- low_leaf_witness_data: ReadonlyArray<{
405
+ lowLeafWitnessData: ReadonlyArray<{
375
406
  leaf: SerializedIndexedLeaf;
376
407
  index: bigint | number;
377
408
  path: Tuple<Buffer, number>;
378
409
  }>;
379
- insertion_witness_data: ReadonlyArray<{
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: number;
423
+ blockNumber: BlockNumber;
393
424
  blockStateRef: BlockStateReference;
394
- blockHeaderHash: Fr;
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: number;
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.FINALISE_BLOCKS]: BlockShiftRequest;
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.FINALISE_BLOCKS]: WorldStateStatusSummary;
537
+ [WorldStateMessageType.FINALIZE_BLOCKS]: WorldStateStatusSummary;
496
538
 
497
539
  [WorldStateMessageType.GET_STATUS]: WorldStateStatusSummary;
498
540
 
499
- [WorldStateMessageType.CREATE_CHECKPOINT]: void;
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.CLOSE]: void;
504
- };
547
+ [WorldStateMessageType.COPY_STORES]: void;
505
548
 
506
- export type WorldStateRevision = {
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>;