@aztec/world-state 0.0.1-commit.d3ec352c → 0.0.1-commit.d58ff9d0

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