@aztec/world-state 0.0.1-commit.3469e52 → 0.0.1-commit.350e0a4d

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