@aztec/world-state 0.0.1-commit.b655e406 → 0.0.1-commit.b8a057fa

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 (80) hide show
  1. package/dest/index.d.ts +2 -1
  2. package/dest/index.d.ts.map +1 -1
  3. package/dest/index.js +1 -0
  4. package/dest/instrumentation/instrumentation.d.ts +4 -3
  5. package/dest/instrumentation/instrumentation.d.ts.map +1 -1
  6. package/dest/instrumentation/instrumentation.js +21 -50
  7. package/dest/native/bench_metrics.d.ts +1 -1
  8. package/dest/native/bench_metrics.d.ts.map +1 -1
  9. package/dest/native/fork_checkpoint.d.ts +7 -1
  10. package/dest/native/fork_checkpoint.d.ts.map +1 -1
  11. package/dest/native/fork_checkpoint.js +15 -3
  12. package/dest/native/index.d.ts +2 -1
  13. package/dest/native/index.d.ts.map +1 -1
  14. package/dest/native/index.js +1 -0
  15. package/dest/native/ipc_world_state_instance.d.ts +89 -0
  16. package/dest/native/ipc_world_state_instance.d.ts.map +1 -0
  17. package/dest/native/ipc_world_state_instance.js +661 -0
  18. package/dest/native/merkle_trees_facade.d.ts +18 -8
  19. package/dest/native/merkle_trees_facade.d.ts.map +1 -1
  20. package/dest/native/merkle_trees_facade.js +90 -111
  21. package/dest/native/message.d.ts +22 -228
  22. package/dest/native/message.d.ts.map +1 -1
  23. package/dest/native/message.js +14 -55
  24. package/dest/native/native_world_state.d.ts +30 -15
  25. package/dest/native/native_world_state.d.ts.map +1 -1
  26. package/dest/native/native_world_state.js +133 -66
  27. package/dest/native/native_world_state_instance.d.ts +56 -33
  28. package/dest/native/native_world_state_instance.d.ts.map +1 -1
  29. package/dest/native/native_world_state_instance.js +1 -182
  30. package/dest/native/world_state_operation.d.ts +7 -0
  31. package/dest/native/world_state_operation.d.ts.map +1 -0
  32. package/dest/native/world_state_operation.js +5 -0
  33. package/dest/synchronizer/config.d.ts +3 -5
  34. package/dest/synchronizer/config.d.ts.map +1 -1
  35. package/dest/synchronizer/config.js +15 -18
  36. package/dest/synchronizer/errors.d.ts +8 -1
  37. package/dest/synchronizer/errors.d.ts.map +1 -1
  38. package/dest/synchronizer/errors.js +8 -1
  39. package/dest/synchronizer/factory.d.ts +6 -5
  40. package/dest/synchronizer/factory.d.ts.map +1 -1
  41. package/dest/synchronizer/factory.js +7 -6
  42. package/dest/synchronizer/index.d.ts +2 -1
  43. package/dest/synchronizer/index.d.ts.map +1 -1
  44. package/dest/synchronizer/index.js +1 -0
  45. package/dest/synchronizer/server_world_state_synchronizer.d.ts +20 -32
  46. package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
  47. package/dest/synchronizer/server_world_state_synchronizer.js +181 -85
  48. package/dest/test/index.d.ts +1 -1
  49. package/dest/test/utils.d.ts +12 -5
  50. package/dest/test/utils.d.ts.map +1 -1
  51. package/dest/test/utils.js +59 -50
  52. package/dest/testing.d.ts +5 -4
  53. package/dest/testing.d.ts.map +1 -1
  54. package/dest/testing.js +15 -8
  55. package/dest/world-state-db/index.d.ts +1 -1
  56. package/dest/world-state-db/merkle_tree_db.d.ts +9 -19
  57. package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
  58. package/package.json +16 -13
  59. package/src/index.ts +1 -0
  60. package/src/instrumentation/instrumentation.ts +23 -59
  61. package/src/native/fork_checkpoint.ts +19 -3
  62. package/src/native/index.ts +1 -0
  63. package/src/native/ipc_world_state_instance.ts +834 -0
  64. package/src/native/merkle_trees_facade.ts +118 -104
  65. package/src/native/message.ts +33 -305
  66. package/src/native/native_world_state.ts +179 -108
  67. package/src/native/native_world_state_instance.ts +94 -251
  68. package/src/native/world_state_operation.ts +33 -0
  69. package/src/synchronizer/config.ts +16 -23
  70. package/src/synchronizer/errors.ts +8 -0
  71. package/src/synchronizer/factory.ts +18 -11
  72. package/src/synchronizer/index.ts +1 -0
  73. package/src/synchronizer/server_world_state_synchronizer.ts +219 -111
  74. package/src/test/utils.ts +96 -92
  75. package/src/testing.ts +13 -11
  76. package/src/world-state-db/merkle_tree_db.ts +12 -19
  77. package/dest/native/world_state_ops_queue.d.ts +0 -19
  78. package/dest/native/world_state_ops_queue.d.ts.map +0 -1
  79. package/dest/native/world_state_ops_queue.js +0 -146
  80. package/src/native/world_state_ops_queue.ts +0 -190
@@ -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,
@@ -25,7 +29,6 @@ import assert from 'assert';
25
29
  import {
26
30
  type SerializedIndexedLeaf,
27
31
  type SerializedLeafValue,
28
- WorldStateMessageType,
29
32
  blockStateReference,
30
33
  treeStateReferenceToSnapshot,
31
34
  } from './message.js';
@@ -46,6 +49,10 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
46
49
  return this.revision;
47
50
  }
48
51
 
52
+ getIpcPath(): string {
53
+ return this.instance.getIpcPath();
54
+ }
55
+
49
56
  findLeafIndices(treeId: MerkleTreeId, values: MerkleTreeLeafType<MerkleTreeId>[]): Promise<(bigint | undefined)[]> {
50
57
  return this.findLeafIndicesAfter(treeId, values, 0n);
51
58
  }
@@ -54,13 +61,13 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
54
61
  treeId: MerkleTreeId,
55
62
  values: MerkleTreeLeafType<MerkleTreeId>[],
56
63
  ): Promise<({ path: SiblingPath<N>; index: bigint } | undefined)[]> {
57
- const response = await this.instance.call(WorldStateMessageType.FIND_SIBLING_PATHS, {
58
- leaves: values.map(leaf => serializeLeaf(hydrateLeaf(treeId, leaf))),
59
- revision: this.revision,
64
+ const paths = await this.instance.findSiblingPaths(
60
65
  treeId,
61
- });
66
+ this.revision,
67
+ values.map(leaf => serializeLeaf(hydrateLeaf(treeId, leaf))),
68
+ );
62
69
 
63
- return response.paths.map(path => {
70
+ return paths.map(path => {
64
71
  if (!path) {
65
72
  return undefined;
66
73
  }
@@ -73,14 +80,14 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
73
80
  leaves: MerkleTreeLeafType<MerkleTreeId>[],
74
81
  startIndex: bigint,
75
82
  ): Promise<(bigint | undefined)[]> {
76
- const response = await this.instance.call(WorldStateMessageType.FIND_LEAF_INDICES, {
77
- leaves: leaves.map(leaf => serializeLeaf(hydrateLeaf(treeId, leaf))),
78
- revision: this.revision,
83
+ const indices = await this.instance.findLeafIndices(
79
84
  treeId,
85
+ this.revision,
86
+ leaves.map(leaf => serializeLeaf(hydrateLeaf(treeId, leaf))),
80
87
  startIndex,
81
- });
88
+ );
82
89
 
83
- return response.indices.map(index => {
90
+ return indices.map(index => {
84
91
  if (typeof index === 'number' || typeof index === 'bigint') {
85
92
  return BigInt(index);
86
93
  } else {
@@ -90,11 +97,7 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
90
97
  }
91
98
 
92
99
  async getLeafPreimage(treeId: IndexedTreeId, leafIndex: bigint): Promise<IndexedTreeLeafPreimage | undefined> {
93
- const resp = await this.instance.call(WorldStateMessageType.GET_LEAF_PREIMAGE, {
94
- leafIndex,
95
- revision: this.revision,
96
- treeId,
97
- });
100
+ const resp = await this.instance.getLeafPreimage(treeId, this.revision, leafIndex);
98
101
 
99
102
  return resp ? deserializeIndexedLeaf(resp) : undefined;
100
103
  }
@@ -103,11 +106,7 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
103
106
  treeId: ID,
104
107
  leafIndex: bigint,
105
108
  ): Promise<MerkleTreeLeafType<ID> | undefined> {
106
- const resp = await this.instance.call(WorldStateMessageType.GET_LEAF_VALUE, {
107
- leafIndex,
108
- revision: this.revision,
109
- treeId,
110
- });
109
+ const resp = await this.instance.getLeafValue(treeId, this.revision, leafIndex);
111
110
 
112
111
  if (!resp) {
113
112
  return undefined;
@@ -115,7 +114,7 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
115
114
 
116
115
  const leaf = deserializeLeafValue(resp);
117
116
  if (leaf instanceof Fr) {
118
- return leaf as any;
117
+ return treeId === MerkleTreeId.ARCHIVE ? (new BlockHash(leaf) as any) : (leaf as any);
119
118
  } else {
120
119
  return leaf.toBuffer() as any;
121
120
  }
@@ -125,11 +124,7 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
125
124
  treeId: IndexedTreeId,
126
125
  value: bigint,
127
126
  ): Promise<{ index: bigint; alreadyPresent: boolean } | undefined> {
128
- const resp = await this.instance.call(WorldStateMessageType.FIND_LOW_LEAF, {
129
- key: new Fr(value),
130
- revision: this.revision,
131
- treeId,
132
- });
127
+ const resp = await this.instance.findLowLeaf(treeId, this.revision, new Fr(value));
133
128
  return {
134
129
  alreadyPresent: resp.alreadyPresent,
135
130
  index: BigInt(resp.index),
@@ -137,91 +132,79 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
137
132
  }
138
133
 
139
134
  async getSiblingPath<N extends number>(treeId: MerkleTreeId, leafIndex: bigint): Promise<SiblingPath<N>> {
140
- const siblingPath = await this.instance.call(WorldStateMessageType.GET_SIBLING_PATH, {
141
- leafIndex,
142
- revision: this.revision,
143
- treeId,
144
- });
135
+ const siblingPath = await this.instance.getSiblingPath(treeId, this.revision, leafIndex);
145
136
 
146
137
  return new SiblingPath(siblingPath.length, siblingPath) as any;
147
138
  }
148
139
 
149
140
  async getStateReference(): Promise<StateReference> {
150
- const resp = await this.instance.call(WorldStateMessageType.GET_STATE_REFERENCE, {
151
- revision: this.revision,
152
- });
141
+ const state = await this.instance.getStateReference(this.revision);
153
142
 
154
143
  return new StateReference(
155
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
144
+ treeStateReferenceToSnapshot(state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
156
145
  new PartialStateReference(
157
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.NOTE_HASH_TREE]),
158
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.NULLIFIER_TREE]),
159
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.PUBLIC_DATA_TREE]),
146
+ treeStateReferenceToSnapshot(state[MerkleTreeId.NOTE_HASH_TREE]),
147
+ treeStateReferenceToSnapshot(state[MerkleTreeId.NULLIFIER_TREE]),
148
+ treeStateReferenceToSnapshot(state[MerkleTreeId.PUBLIC_DATA_TREE]),
160
149
  ),
161
150
  );
162
151
  }
163
152
 
164
153
  async getInitialStateReference(): Promise<StateReference> {
165
- const resp = await this.instance.call(WorldStateMessageType.GET_INITIAL_STATE_REFERENCE, { canonical: true });
154
+ const state = await this.instance.getInitialStateReference();
166
155
 
167
156
  return new StateReference(
168
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
157
+ treeStateReferenceToSnapshot(state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
169
158
  new PartialStateReference(
170
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.NOTE_HASH_TREE]),
171
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.NULLIFIER_TREE]),
172
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.PUBLIC_DATA_TREE]),
159
+ treeStateReferenceToSnapshot(state[MerkleTreeId.NOTE_HASH_TREE]),
160
+ treeStateReferenceToSnapshot(state[MerkleTreeId.NULLIFIER_TREE]),
161
+ treeStateReferenceToSnapshot(state[MerkleTreeId.PUBLIC_DATA_TREE]),
173
162
  ),
174
163
  );
175
164
  }
176
165
 
177
166
  async getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo> {
178
- const resp = await this.instance.call(WorldStateMessageType.GET_TREE_INFO, {
179
- treeId: treeId,
180
- revision: this.revision,
181
- });
182
-
183
- return {
184
- depth: resp.depth,
185
- root: resp.root,
186
- size: BigInt(resp.size),
187
- treeId,
188
- };
167
+ return await this.instance.getTreeInfo(treeId, this.revision);
189
168
  }
190
169
 
191
170
  async getBlockNumbersForLeafIndices<ID extends MerkleTreeId>(
192
171
  treeId: ID,
193
172
  leafIndices: bigint[],
194
- ): Promise<(bigint | undefined)[]> {
195
- const response = await this.instance.call(WorldStateMessageType.GET_BLOCK_NUMBERS_FOR_LEAF_INDICES, {
196
- treeId,
197
- revision: this.revision,
198
- leafIndices,
199
- });
173
+ ): Promise<(BlockNumber | undefined)[]> {
174
+ const blockNumbers = await this.instance.getBlockNumbersForLeafIndices(treeId, this.revision, leafIndices);
200
175
 
201
- return response.blockNumbers.map(x => (x === undefined || x === null ? undefined : BigInt(x)));
176
+ return blockNumbers.map(x => (x === undefined || x === null ? undefined : BlockNumber(Number(x))));
202
177
  }
203
178
  }
204
179
 
205
180
  export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTreeWriteOperations {
206
- constructor(instance: NativeWorldStateInstance, initialHeader: BlockHeader, revision: WorldStateRevision) {
181
+ private log = createLogger('world-state:merkle-trees-fork-facade');
182
+ private closePromise: Promise<void> | undefined;
183
+
184
+ constructor(
185
+ instance: NativeWorldStateInstance,
186
+ initialHeader: BlockHeader,
187
+ revision: WorldStateRevision,
188
+ private opts: { closeDelayMs?: number },
189
+ ) {
207
190
  assert.notEqual(revision.forkId, 0, 'Fork ID must be set');
208
191
  assert.equal(revision.includeUncommitted, true, 'Fork must include uncommitted data');
209
192
  super(instance, initialHeader, revision);
210
193
  }
211
194
  async updateArchive(header: BlockHeader): Promise<void> {
212
- await this.instance.call(WorldStateMessageType.UPDATE_ARCHIVE, {
213
- forkId: this.revision.forkId,
214
- blockHeaderHash: (await header.hash()).toBuffer(),
215
- blockStateRef: blockStateReference(header.state),
216
- });
195
+ await this.instance.updateArchive(
196
+ this.revision.forkId,
197
+ blockStateReference(header.state),
198
+ (await header.hash()).toBuffer(),
199
+ );
217
200
  }
218
201
 
219
202
  async appendLeaves<ID extends MerkleTreeId>(treeId: ID, leaves: MerkleTreeLeafType<ID>[]): Promise<void> {
220
- await this.instance.call(WorldStateMessageType.APPEND_LEAVES, {
221
- leaves: leaves.map(leaf => leaf as any),
222
- forkId: this.revision.forkId,
203
+ await this.instance.appendLeaves(
223
204
  treeId,
224
- });
205
+ this.revision.forkId,
206
+ leaves.map(leaf => serializeLeaf(hydrateLeaf(treeId, leaf as any))),
207
+ );
225
208
  }
226
209
 
227
210
  async batchInsert<TreeHeight extends number, SubtreeSiblingPathHeight extends number, ID extends IndexedTreeId>(
@@ -230,24 +213,19 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
230
213
  subtreeHeight: number,
231
214
  ): Promise<BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>> {
232
215
  const leaves = rawLeaves.map((leaf: Buffer) => hydrateLeaf(treeId, leaf)).map(serializeLeaf);
233
- const resp = await this.instance.call(WorldStateMessageType.BATCH_INSERT, {
234
- leaves,
235
- treeId,
236
- forkId: this.revision.forkId,
237
- subtreeDepth: subtreeHeight,
238
- });
216
+ const resp = await this.instance.batchInsert(treeId, this.revision.forkId, leaves, subtreeHeight);
239
217
 
240
218
  return {
241
219
  newSubtreeSiblingPath: new SiblingPath<SubtreeSiblingPathHeight>(
242
- resp.subtree_path.length as any,
243
- resp.subtree_path,
220
+ resp.subtreePath.length as any,
221
+ resp.subtreePath,
244
222
  ),
245
- sortedNewLeaves: resp.sorted_leaves
223
+ sortedNewLeaves: resp.sortedLeaves
246
224
  .map(([leaf]) => leaf)
247
225
  .map(deserializeLeafValue)
248
226
  .map(serializeToBuffer),
249
- sortedNewLeavesIndexes: resp.sorted_leaves.map(([, index]) => index),
250
- lowLeavesWitnessData: resp.low_leaf_witness_data.map(data => ({
227
+ sortedNewLeavesIndexes: resp.sortedLeaves.map(([, index]) => index),
228
+ lowLeavesWitnessData: resp.lowLeafWitnessData.map(data => ({
251
229
  index: BigInt(data.index),
252
230
  leafPreimage: deserializeIndexedLeaf(data.leaf),
253
231
  siblingPath: new SiblingPath<TreeHeight>(data.path.length as any, data.path),
@@ -260,19 +238,15 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
260
238
  rawLeaves: Buffer[],
261
239
  ): Promise<SequentialInsertionResult<TreeHeight>> {
262
240
  const leaves = rawLeaves.map((leaf: Buffer) => hydrateLeaf(treeId, leaf)).map(serializeLeaf);
263
- const resp = await this.instance.call(WorldStateMessageType.SEQUENTIAL_INSERT, {
264
- leaves,
265
- treeId,
266
- forkId: this.revision.forkId,
267
- });
241
+ const resp = await this.instance.sequentialInsert(treeId, this.revision.forkId, leaves);
268
242
 
269
243
  return {
270
- lowLeavesWitnessData: resp.low_leaf_witness_data.map(data => ({
244
+ lowLeavesWitnessData: resp.lowLeafWitnessData.map(data => ({
271
245
  index: BigInt(data.index),
272
246
  leafPreimage: deserializeIndexedLeaf(data.leaf),
273
247
  siblingPath: new SiblingPath<TreeHeight>(data.path.length as any, data.path),
274
248
  })),
275
- insertionWitnessData: resp.insertion_witness_data.map(data => ({
249
+ insertionWitnessData: resp.insertionWitnessData.map(data => ({
276
250
  index: BigInt(data.index),
277
251
  leafPreimage: deserializeIndexedLeaf(data.leaf),
278
252
  siblingPath: new SiblingPath<TreeHeight>(data.path.length as any, data.path),
@@ -280,40 +254,78 @@ export class MerkleTreesForkFacade extends MerkleTreesFacade implements MerkleTr
280
254
  };
281
255
  }
282
256
 
283
- public async close(): Promise<void> {
257
+ public close(): Promise<void> {
284
258
  assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
285
- await this.instance.call(WorldStateMessageType.DELETE_FORK, { forkId: this.revision.forkId });
259
+ // Share the in-flight close promise across duplicate dispose calls so DELETE_FORK is sent at most once.
260
+ if (this.closePromise) {
261
+ return this.closePromise;
262
+ }
263
+ this.closePromise = this.doClose();
264
+ return this.closePromise;
286
265
  }
287
266
 
288
- public async createCheckpoint(): Promise<void> {
267
+ private async doClose(): Promise<void> {
268
+ try {
269
+ await this.instance.deleteFork(this.revision.forkId);
270
+ } catch (err: any) {
271
+ // Ignore errors due to native instance being closed during shutdown.
272
+ // This can happen when validators are still processing block proposals while the node is stopping.
273
+ if (err?.message === 'Native instance is closed' || err?.message === 'IPC instance is closed') {
274
+ return;
275
+ }
276
+ // Ignore "Fork not found": the native fork was already destroyed by a pending-chain unwind or a
277
+ // historical prune (both call C++ remove_forks_for_block). Fork IDs are monotonic and never reused,
278
+ // so swallowing this on close cannot mask a deletion of a different fork.
279
+ if (err?.message === 'Fork not found') {
280
+ return;
281
+ }
282
+ throw err;
283
+ }
284
+ }
285
+
286
+ async [Symbol.asyncDispose](): Promise<void> {
287
+ if (this.opts.closeDelayMs) {
288
+ void sleep(this.opts.closeDelayMs)
289
+ .then(() => this.close())
290
+ .catch(err => {
291
+ this.log.warn('Error closing MerkleTreesForkFacade after delay', { err });
292
+ });
293
+ } else {
294
+ await this.close();
295
+ }
296
+ }
297
+
298
+ public async createCheckpoint(): Promise<number> {
289
299
  assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
290
- await this.instance.call(WorldStateMessageType.CREATE_CHECKPOINT, { forkId: this.revision.forkId });
300
+ return await this.instance.createCheckpoint(this.revision.forkId);
291
301
  }
292
302
 
293
303
  public async commitCheckpoint(): Promise<void> {
294
304
  assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
295
- await this.instance.call(WorldStateMessageType.COMMIT_CHECKPOINT, { forkId: this.revision.forkId });
305
+ await this.instance.commitCheckpoint(this.revision.forkId);
296
306
  }
297
307
 
298
308
  public async revertCheckpoint(): Promise<void> {
299
309
  assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
300
- await this.instance.call(WorldStateMessageType.REVERT_CHECKPOINT, { forkId: this.revision.forkId });
310
+ await this.instance.revertCheckpoint(this.revision.forkId);
301
311
  }
302
312
 
303
- public async commitAllCheckpoints(): Promise<void> {
313
+ public async commitAllCheckpointsTo(depth: number): Promise<void> {
304
314
  assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
305
- await this.instance.call(WorldStateMessageType.COMMIT_ALL_CHECKPOINTS, { forkId: this.revision.forkId });
315
+ await this.instance.commitAllCheckpoints(this.revision.forkId, depth);
306
316
  }
307
317
 
308
- public async revertAllCheckpoints(): Promise<void> {
318
+ public async revertAllCheckpointsTo(depth: number): Promise<void> {
309
319
  assert.notEqual(this.revision.forkId, 0, 'Fork ID must be set');
310
- await this.instance.call(WorldStateMessageType.REVERT_ALL_CHECKPOINTS, { forkId: this.revision.forkId });
320
+ await this.instance.revertAllCheckpoints(this.revision.forkId, depth);
311
321
  }
312
322
  }
313
323
 
314
- function hydrateLeaf<ID extends MerkleTreeId>(treeId: ID, leaf: Fr | Buffer) {
324
+ function hydrateLeaf(treeId: MerkleTreeId, leaf: Fr | BlockHash | Buffer) {
315
325
  if (leaf instanceof Fr) {
316
326
  return leaf;
327
+ } else if (leaf instanceof BlockHash) {
328
+ return leaf.toFr();
317
329
  } else if (treeId === MerkleTreeId.NULLIFIER_TREE) {
318
330
  return NullifierLeaf.fromBuffer(leaf);
319
331
  } else if (treeId === MerkleTreeId.PUBLIC_DATA_TREE) {
@@ -323,8 +335,10 @@ function hydrateLeaf<ID extends MerkleTreeId>(treeId: ID, leaf: Fr | Buffer) {
323
335
  }
324
336
  }
325
337
 
326
- export function serializeLeaf(leaf: Fr | NullifierLeaf | PublicDataTreeLeaf): SerializedLeafValue {
327
- if (leaf instanceof Fr) {
338
+ export function serializeLeaf(leaf: Fr | BlockHash | NullifierLeaf | PublicDataTreeLeaf): SerializedLeafValue {
339
+ if (leaf instanceof BlockHash) {
340
+ return leaf.toBuffer();
341
+ } else if (leaf instanceof Fr) {
328
342
  return leaf.toBuffer();
329
343
  } else if (leaf instanceof NullifierLeaf) {
330
344
  return { nullifier: leaf.nullifier.toBuffer() };