@aztec/world-state 0.0.1-commit.3100065 → 0.0.1-commit.321f6a9

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 (45) 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 +4 -9
  7. package/dest/native/index.d.ts +2 -1
  8. package/dest/native/index.d.ts.map +1 -1
  9. package/dest/native/index.js +1 -0
  10. package/dest/native/ipc_world_state_instance.d.ts +61 -22
  11. package/dest/native/ipc_world_state_instance.d.ts.map +1 -1
  12. package/dest/native/ipc_world_state_instance.js +530 -495
  13. package/dest/native/merkle_trees_facade.d.ts +4 -3
  14. package/dest/native/merkle_trees_facade.d.ts.map +1 -1
  15. package/dest/native/merkle_trees_facade.js +37 -109
  16. package/dest/native/message.d.ts +14 -233
  17. package/dest/native/message.d.ts.map +1 -1
  18. package/dest/native/message.js +0 -42
  19. package/dest/native/native_world_state.d.ts +14 -28
  20. package/dest/native/native_world_state.d.ts.map +1 -1
  21. package/dest/native/native_world_state.js +105 -99
  22. package/dest/native/native_world_state_instance.d.ts +56 -43
  23. package/dest/native/native_world_state_instance.d.ts.map +1 -1
  24. package/dest/native/native_world_state_instance.js +1 -223
  25. package/dest/native/world_state_operation.d.ts +7 -0
  26. package/dest/native/world_state_operation.d.ts.map +1 -0
  27. package/dest/native/world_state_operation.js +5 -0
  28. package/dest/synchronizer/factory.d.ts +1 -1
  29. package/dest/synchronizer/factory.d.ts.map +1 -1
  30. package/dest/synchronizer/factory.js +1 -1
  31. package/package.json +11 -10
  32. package/src/index.ts +1 -0
  33. package/src/instrumentation/instrumentation.ts +6 -18
  34. package/src/native/index.ts +1 -0
  35. package/src/native/ipc_world_state_instance.ts +625 -503
  36. package/src/native/merkle_trees_facade.ts +59 -104
  37. package/src/native/message.ts +13 -300
  38. package/src/native/native_world_state.ts +136 -156
  39. package/src/native/native_world_state_instance.ts +94 -308
  40. package/src/native/world_state_operation.ts +33 -0
  41. package/src/synchronizer/factory.ts +0 -1
  42. package/dest/native/world_state_ops_queue.d.ts +0 -19
  43. package/dest/native/world_state_ops_queue.d.ts.map +0 -1
  44. package/dest/native/world_state_ops_queue.js +0 -146
  45. package/src/native/world_state_ops_queue.ts +0 -190
@@ -3,7 +3,6 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
3
3
  import { fromEntries, padArrayEnd } from '@aztec/foundation/collection';
4
4
  import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import { EthAddress } from '@aztec/foundation/eth-address';
6
- import { tryRmDir } from '@aztec/foundation/fs';
7
6
  import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
8
7
  import type { L2Block } from '@aztec/stdlib/block';
9
8
  import { DatabaseVersionManager } from '@aztec/stdlib/database-version/manager';
@@ -19,16 +18,16 @@ import { EMPTY_GENESIS_DATA, type GenesisData, WorldStateRevision } from '@aztec
19
18
  import { getTelemetryClient } from '@aztec/telemetry-client';
20
19
 
21
20
  import assert from 'assert/strict';
22
- import { mkdtemp, rm } from 'fs/promises';
21
+ import { mkdir, mkdtemp, rm } from 'fs/promises';
23
22
  import { tmpdir } from 'os';
24
23
  import { join } from 'path';
25
24
 
26
25
  import { WorldStateInstrumentation } from '../instrumentation/instrumentation.js';
27
26
  import type { WorldStateTreeMapSizes } from '../synchronizer/factory.js';
28
27
  import type { MerkleTreeAdminDatabase as MerkleTreeDatabase } from '../world-state-db/merkle_tree_db.js';
28
+ import { IpcWorldState } from './ipc_world_state_instance.js';
29
29
  import { MerkleTreesFacade, MerkleTreesForkFacade, serializeLeaf } from './merkle_trees_facade.js';
30
30
  import {
31
- WorldStateMessageType,
32
31
  type WorldStateStatusFull,
33
32
  type WorldStateStatusSummary,
34
33
  blockStateReference,
@@ -36,7 +35,7 @@ import {
36
35
  sanitizeSummary,
37
36
  treeStateReferenceToSnapshot,
38
37
  } from './message.js';
39
- import { NativeWorldState } from './native_world_state_instance.js';
38
+ import type { NativeWorldStateInstance } from './native_world_state_instance.js';
40
39
 
41
40
  // The current version of the world state database schema
42
41
  // Increment this when making incompatible changes to the database schema
@@ -44,47 +43,21 @@ export const WORLD_STATE_DB_VERSION = 2; // The initial version
44
43
 
45
44
  export const WORLD_STATE_DIR = 'world_state';
46
45
 
47
- const DEFAULT_TMP_TREE_MAP_SIZE_KB = 10 * 1024 * 1024;
48
-
49
- /**
50
- * Sets up a fresh `mkdtemp` directory + default `WorldStateTreeMapSizes` shared by both
51
- * the `.tmp` (fsync-on) and `.ephemeral` (fsync-off) factories. Returns the raw tmpdir,
52
- * the tree map sizes, and the package logger.
53
- */
54
- async function createTmpWorldStateDir(
55
- bindings?: LoggerBindings,
56
- ): Promise<{ dataDir: string; wsTreeMapSizes: WorldStateTreeMapSizes; log: Logger }> {
57
- const log = createLogger('world-state:database', bindings);
58
- const dataDir = await mkdtemp(join(tmpdir(), 'aztec-world-state-'));
59
- const wsTreeMapSizes: WorldStateTreeMapSizes = {
60
- archiveTreeMapSizeKb: DEFAULT_TMP_TREE_MAP_SIZE_KB,
61
- nullifierTreeMapSizeKb: DEFAULT_TMP_TREE_MAP_SIZE_KB,
62
- noteHashTreeMapSizeKb: DEFAULT_TMP_TREE_MAP_SIZE_KB,
63
- messageTreeMapSizeKb: DEFAULT_TMP_TREE_MAP_SIZE_KB,
64
- publicDataTreeMapSizeKb: DEFAULT_TMP_TREE_MAP_SIZE_KB,
65
- };
66
- log.debug(`Created temporary world state database at: ${dataDir} (map size ${DEFAULT_TMP_TREE_MAP_SIZE_KB} KB)`);
67
- return { dataDir, wsTreeMapSizes, log };
68
- }
69
-
70
46
  export class NativeWorldStateService implements MerkleTreeDatabase {
71
47
  protected initialHeader: BlockHeader | undefined;
72
48
  // This is read heavily and only changes when data is persisted, so we cache it
73
49
  private cachedStatusSummary: WorldStateStatusSummary | undefined;
74
50
 
75
51
  protected constructor(
76
- protected instance: NativeWorldState,
52
+ protected instance: NativeWorldStateInstance,
77
53
  protected readonly worldStateInstrumentation: WorldStateInstrumentation,
78
54
  protected readonly log: Logger,
79
55
  private readonly genesis: GenesisData = EMPTY_GENESIS_DATA,
80
56
  private readonly cleanup = () => Promise.resolve(),
57
+ /** Factory to recreate a fresh IpcWorldState after clear(). */
58
+ private readonly recreateInstance?: () => Promise<NativeWorldStateInstance>,
81
59
  ) {}
82
60
 
83
- /**
84
- * Opens a persistent world state at `dataDir`. Goes through `DatabaseVersionManager` so the
85
- * caller's rollup address is bound to the on-disk schema and incompatible versions surface
86
- * loudly. The LMDB envs commit with full fsync.
87
- */
88
61
  static async new(
89
62
  rollupAddress: EthAddress,
90
63
  dataDir: string,
@@ -94,28 +67,31 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
94
67
  bindings?: LoggerBindings,
95
68
  cleanup = () => Promise.resolve(),
96
69
  ): Promise<NativeWorldStateService> {
70
+ for (const [key, value] of Object.entries(wsTreeMapSizes)) {
71
+ if (value <= 0) {
72
+ throw new Error(`Map size must be a positive number, got ${value} for ${key}`);
73
+ }
74
+ }
75
+
97
76
  const log = createLogger('world-state:database', bindings);
98
77
  const worldStateDirectory = join(dataDir, WORLD_STATE_DIR);
78
+
99
79
  const versionManager = new DatabaseVersionManager({
100
80
  schemaVersion: WORLD_STATE_DB_VERSION,
101
81
  rollupAddress,
102
82
  dataDirectory: worldStateDirectory,
103
- onOpen: (dir: string) =>
104
- Promise.resolve(
105
- new NativeWorldState(
106
- dir,
107
- wsTreeMapSizes,
108
- genesis,
109
- instrumentation,
110
- bindings,
111
- undefined,
112
- /*ephemeral=*/ false,
113
- ),
114
- ),
83
+ onOpen: dir => IpcWorldState.spawn(dir, wsTreeMapSizes, genesis, instrumentation, bindings),
115
84
  });
116
85
 
117
86
  const [instance] = await versionManager.open();
118
- const worldState = new this(instance, instrumentation, log, genesis, cleanup);
87
+
88
+ const recreateInstance = async () => {
89
+ await rm(worldStateDirectory, { recursive: true, force: true, maxRetries: 3 });
90
+ await mkdir(worldStateDirectory, { recursive: true });
91
+ return IpcWorldState.spawn(worldStateDirectory, wsTreeMapSizes, genesis, instrumentation, bindings);
92
+ };
93
+
94
+ const worldState = new this(instance, instrumentation, log, genesis, cleanup, recreateInstance);
119
95
  try {
120
96
  await worldState.init();
121
97
  } catch (e) {
@@ -126,23 +102,38 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
126
102
  return worldState;
127
103
  }
128
104
 
129
- /**
130
- * Opens a world state in a fresh tmpdir with full fsync semantics. Use when you need the
131
- * on-disk file to remain crash-recoverable (e.g. for snapshot/backup tests) but don't
132
- * want a persistent dataDir. Pass `cleanupTmpDir=false` to keep the directory after
133
- * close for inspection.
134
- *
135
- * If you don't care about crash-recoverability — i.e. you just want a fast scratch
136
- * database for tests — use {@link ephemeral} instead.
137
- */
138
105
  static async tmp(
139
- rollupAddress = EthAddress.ZERO,
140
106
  cleanupTmpDir = true,
141
107
  genesis: GenesisData = EMPTY_GENESIS_DATA,
142
108
  instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
143
109
  bindings?: LoggerBindings,
110
+ threads?: number,
144
111
  ): Promise<NativeWorldStateService> {
145
- const { dataDir, wsTreeMapSizes, log } = await createTmpWorldStateDir(bindings);
112
+ const log = createLogger('world-state:database', bindings);
113
+ const dataDir = await mkdtemp(join(tmpdir(), 'aztec-world-state-'));
114
+ // Temporary (test/dev) world states are small and short-lived. Keep the LMDB
115
+ // map sizes in the MB range: with the IPC backend each tmp() spawns a separate
116
+ // aztec-wsdb that maps these per tree, and oversized maps add real cold-start
117
+ // I/O under parallel CI load. 256 MB/tree is ample for tests.
118
+ const dbMapSizeKb = 256 * 1024;
119
+ const worldStateTreeMapSizes: WorldStateTreeMapSizes = {
120
+ archiveTreeMapSizeKb: dbMapSizeKb,
121
+ nullifierTreeMapSizeKb: dbMapSizeKb,
122
+ noteHashTreeMapSizeKb: dbMapSizeKb,
123
+ messageTreeMapSizeKb: dbMapSizeKb,
124
+ publicDataTreeMapSizeKb: dbMapSizeKb,
125
+ };
126
+ log.debug(`Created temporary world state database at: ${dataDir} with tree map size: ${dbMapSizeKb}`);
127
+
128
+ const instance = await IpcWorldState.spawn(
129
+ dataDir,
130
+ worldStateTreeMapSizes,
131
+ genesis,
132
+ instrumentation,
133
+ bindings,
134
+ threads,
135
+ );
136
+
146
137
  const cleanup = async () => {
147
138
  if (cleanupTmpDir) {
148
139
  await rm(dataDir, { recursive: true, force: true, maxRetries: 3 });
@@ -151,47 +142,50 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
151
142
  log.debug(`Leaving temporary world state database: ${dataDir}`);
152
143
  }
153
144
  };
154
- return this.new(rollupAddress, dataDir, wsTreeMapSizes, genesis, instrumentation, bindings, cleanup);
155
- }
156
145
 
157
- /**
158
- * Opens a fully-ephemeral world state. The directory is created in `os.tmpdir()`, the LMDB
159
- * envs open with `MDB_NOSYNC | MDB_NOMETASYNC` so commits never block on fsync, and the
160
- * directory is removed on dispose. A crash mid-write leaves the env unrecoverable.
161
- *
162
- * For unit tests and other isolated runs. Use {@link tmp} when you need fsync semantics in a
163
- * tmp dir, and {@link new} for a persistent store. Skips {@link DatabaseVersionManager} —
164
- * there is no on-disk schema to bind to and no rollup address is taken.
165
- */
166
- static async ephemeral(
167
- genesis: GenesisData = EMPTY_GENESIS_DATA,
168
- instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
169
- bindings?: LoggerBindings,
170
- ): Promise<NativeWorldStateService> {
171
- const { dataDir, wsTreeMapSizes, log } = await createTmpWorldStateDir(bindings);
172
- const cleanup = async () => {
146
+ const recreateInstance = async () => {
173
147
  await rm(dataDir, { recursive: true, force: true, maxRetries: 3 });
174
- log.debug(`Deleted ephemeral world state database: ${dataDir}`);
148
+ await mkdir(dataDir, { recursive: true });
149
+ return IpcWorldState.spawn(dataDir, worldStateTreeMapSizes, genesis, instrumentation, bindings, threads);
175
150
  };
176
- const instance = new NativeWorldState(
177
- join(dataDir, WORLD_STATE_DIR),
178
- wsTreeMapSizes,
179
- genesis,
180
- instrumentation,
181
- bindings,
182
- undefined,
183
- /*ephemeral=*/ true,
184
- );
185
- const worldState = new this(instance, instrumentation, log, genesis, cleanup);
151
+
152
+ const worldState = new this(instance, instrumentation, log, genesis, cleanup, recreateInstance);
186
153
  try {
187
154
  await worldState.init();
188
155
  } catch (e) {
189
- log.error(`Error initializing ephemeral world state: ${e}`);
156
+ log.error(`Error initializing tmp world state: ${e}`);
190
157
  throw e;
191
158
  }
192
159
  return worldState;
193
160
  }
194
161
 
162
+ static ephemeral(
163
+ genesis: GenesisData = EMPTY_GENESIS_DATA,
164
+ instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
165
+ bindings?: LoggerBindings,
166
+ ): Promise<NativeWorldStateService> {
167
+ // The TXE spins up one tiny, short-lived world state per test, many concurrently. Cap the wsdb thread
168
+ // usage to the minimum: a single tree-op thread instead of one per core (the C++ IPC dispatcher pool
169
+ // still floors at 2). This avoids ~32 threads per wsdb multiplied across dozens of concurrent test
170
+ // world states — the trees are cache-sized (see tmp's map-size note), so extra threads buy nothing.
171
+ return this.tmp(/*cleanupTmpDir=*/ true, genesis, instrumentation, bindings, /*threads=*/ 1);
172
+ }
173
+
174
+ static async fromIpc(
175
+ wsdbBackend: ConstructorParameters<typeof IpcWorldState>[0],
176
+ instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
177
+ bindings?: LoggerBindings,
178
+ genesis: GenesisData = EMPTY_GENESIS_DATA,
179
+ cleanup = () => Promise.resolve(),
180
+ recreateInstance?: () => Promise<NativeWorldStateInstance>,
181
+ ): Promise<NativeWorldStateService> {
182
+ const log = createLogger('world-state:database', bindings);
183
+ const instance = new IpcWorldState(wsdbBackend, instrumentation, bindings);
184
+ const worldState = new this(instance, instrumentation, log, genesis, cleanup, recreateInstance);
185
+ await worldState.init();
186
+ return worldState;
187
+ }
188
+
195
189
  protected async init() {
196
190
  const status = await this.getStatusSummary();
197
191
  if (!status.treesAreSynched) {
@@ -213,11 +207,24 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
213
207
  assert.strictEqual(initialHeaderIndex, 0n, 'Invalid initial archive state');
214
208
  }
215
209
 
216
- public async clear() {
210
+ public async clear(): Promise<void> {
211
+ if (!this.recreateInstance) {
212
+ throw new Error('clear() is not available for externally-managed IPC backends');
213
+ }
214
+ this.log.warn('Clearing world state: shutting down WSDB, deleting data, and recreating');
217
215
  await this.instance.close();
218
216
  this.cachedStatusSummary = undefined;
219
- await tryRmDir(this.instance.getDataDir(), this.log);
220
- this.instance = this.instance.clone();
217
+ this.instance = await this.recreateInstance();
218
+ await this.init();
219
+ this.log.info('World state cleared and reinitialized from genesis');
220
+ }
221
+
222
+ /** Returns the IPC path of the underlying IPC backend, if available. */
223
+ public getIpcPath(): string {
224
+ if (this.instance instanceof IpcWorldState) {
225
+ return this.instance.getIpcPath();
226
+ }
227
+ throw new Error('getIpcPath() is only available with IPC world state');
221
228
  }
222
229
 
223
230
  public getCommitted(): MerkleTreeReadOperations {
@@ -236,16 +243,15 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
236
243
  blockNumber?: BlockNumber,
237
244
  opts: { closeDelayMs?: number } = {},
238
245
  ): Promise<MerkleTreeWriteOperations> {
239
- const resp = await this.instance.call(WorldStateMessageType.CREATE_FORK, {
246
+ const forkId = await this.instance.createFork({
240
247
  latest: blockNumber === undefined,
241
248
  blockNumber: blockNumber ?? BlockNumber.ZERO,
242
- canonical: true,
243
249
  });
244
250
  return new MerkleTreesForkFacade(
245
251
  this.instance,
246
252
  this.initialHeader!,
247
253
  new WorldStateRevision(
248
- /*forkId=*/ resp.forkId,
254
+ /*forkId=*/ forkId,
249
255
  /* blockNumber=*/ WorldStateRevision.LATEST,
250
256
  /* includeUncommitted=*/ true,
251
257
  ),
@@ -289,33 +295,36 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
289
295
  });
290
296
 
291
297
  try {
292
- return await this.instance.call(
293
- WorldStateMessageType.SYNC_BLOCK,
294
- {
295
- blockNumber: l2Block.number,
296
- blockHeaderHash: (await l2Block.hash()).toBuffer(),
297
- // Forwarded so the native sync verifies the archive root against canonical and rejects a divergent tree.
298
- expectedArchiveRoot: l2Block.archive.root.toBuffer(),
299
- expectedPreviousArchiveRoot: l2Block.header.lastArchive.root.toBuffer(),
300
- paddedL1ToL2Messages: paddedL1ToL2Messages.map(serializeLeaf),
301
- paddedNoteHashes: paddedNoteHashes.map(serializeLeaf),
302
- paddedNullifiers: paddedNullifiers.map(serializeLeaf),
303
- publicDataWrites: publicDataWrites.map(serializeLeaf),
304
- blockStateRef: blockStateReference(l2Block.header.state),
305
- canonical: true,
306
- },
307
- this.sanitizeAndCacheSummaryFromFull.bind(this),
308
- this.deleteCachedSummary.bind(this),
309
- );
298
+ const status = await this.instance.syncBlock({
299
+ blockNumber: l2Block.number,
300
+ blockHeaderHash: (await l2Block.hash()).toBuffer(),
301
+ // Forwarded so the native sync verifies the archive root against canonical and rejects a divergent tree.
302
+ expectedArchiveRoot: l2Block.archive.root.toBuffer(),
303
+ expectedPreviousArchiveRoot: l2Block.header.lastArchive.root.toBuffer(),
304
+ paddedL1ToL2Messages: paddedL1ToL2Messages.map(serializeLeaf),
305
+ paddedNoteHashes: paddedNoteHashes.map(serializeLeaf),
306
+ paddedNullifiers: paddedNullifiers.map(serializeLeaf),
307
+ publicDataWrites: publicDataWrites.map(serializeLeaf),
308
+ blockStateRef: blockStateReference(l2Block.header.state),
309
+ });
310
+ return this.sanitizeAndCacheSummaryFromFull(status);
310
311
  } catch (err) {
312
+ this.deleteCachedSummary();
311
313
  this.worldStateInstrumentation.incCriticalErrors('synch_pending_block');
312
314
  throw err;
313
315
  }
314
316
  }
315
317
 
316
318
  public async close(): Promise<void> {
317
- await this.instance.close();
318
- await this.cleanup();
319
+ try {
320
+ await this.instance.close();
321
+ } finally {
322
+ await this.cleanup();
323
+ }
324
+ }
325
+
326
+ async [Symbol.asyncDispose](): Promise<void> {
327
+ await this.close();
319
328
  }
320
329
 
321
330
  private async buildInitialHeader(): Promise<BlockHeader> {
@@ -338,7 +347,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
338
347
  return sanitized;
339
348
  }
340
349
 
341
- private deleteCachedSummary(_: string) {
350
+ private deleteCachedSummary() {
342
351
  this.cachedStatusSummary = undefined;
343
352
  }
344
353
 
@@ -349,16 +358,9 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
349
358
  */
350
359
  public async setFinalized(toBlockNumber: BlockNumber) {
351
360
  try {
352
- await this.instance.call(
353
- WorldStateMessageType.FINALIZE_BLOCKS,
354
- {
355
- toBlockNumber,
356
- canonical: true,
357
- },
358
- this.sanitizeAndCacheSummary.bind(this),
359
- this.deleteCachedSummary.bind(this),
360
- );
361
+ this.sanitizeAndCacheSummary(await this.instance.finalizeBlocks(toBlockNumber));
361
362
  } catch (err) {
363
+ this.deleteCachedSummary();
362
364
  this.worldStateInstrumentation.incCriticalErrors('finalize_block');
363
365
  throw err;
364
366
  }
@@ -372,16 +374,9 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
372
374
  */
373
375
  public async removeHistoricalBlocks(toBlockNumber: BlockNumber) {
374
376
  try {
375
- return await this.instance.call(
376
- WorldStateMessageType.REMOVE_HISTORICAL_BLOCKS,
377
- {
378
- toBlockNumber,
379
- canonical: true,
380
- },
381
- this.sanitizeAndCacheSummaryFromFull.bind(this),
382
- this.deleteCachedSummary.bind(this),
383
- );
377
+ return this.sanitizeAndCacheSummaryFromFull(await this.instance.removeHistoricalBlocks(toBlockNumber));
384
378
  } catch (err) {
379
+ this.deleteCachedSummary();
385
380
  this.worldStateInstrumentation.incCriticalErrors('prune_historical_block');
386
381
  throw err;
387
382
  }
@@ -394,16 +389,9 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
394
389
  */
395
390
  public async unwindBlocks(toBlockNumber: BlockNumber) {
396
391
  try {
397
- return await this.instance.call(
398
- WorldStateMessageType.UNWIND_BLOCKS,
399
- {
400
- toBlockNumber,
401
- canonical: true,
402
- },
403
- this.sanitizeAndCacheSummaryFromFull.bind(this),
404
- this.deleteCachedSummary.bind(this),
405
- );
392
+ return this.sanitizeAndCacheSummaryFromFull(await this.instance.unwindBlocks(toBlockNumber));
406
393
  } catch (err) {
394
+ this.deleteCachedSummary();
407
395
  this.worldStateInstrumentation.incCriticalErrors('prune_pending_block');
408
396
  throw err;
409
397
  }
@@ -413,11 +401,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
413
401
  if (this.cachedStatusSummary !== undefined) {
414
402
  return { ...this.cachedStatusSummary };
415
403
  }
416
- return await this.instance.call(
417
- WorldStateMessageType.GET_STATUS,
418
- { canonical: true },
419
- this.sanitizeAndCacheSummary.bind(this),
420
- );
404
+ return this.sanitizeAndCacheSummary(await this.instance.getStatus());
421
405
  }
422
406
 
423
407
  updateLeaf<ID extends IndexedTreeId>(
@@ -429,14 +413,14 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
429
413
  }
430
414
 
431
415
  private async getInitialStateReference(): Promise<StateReference> {
432
- const resp = await this.instance.call(WorldStateMessageType.GET_INITIAL_STATE_REFERENCE, { canonical: true });
416
+ const state = await this.instance.getInitialStateReference();
433
417
 
434
418
  return new StateReference(
435
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
419
+ treeStateReferenceToSnapshot(state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
436
420
  new PartialStateReference(
437
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.NOTE_HASH_TREE]),
438
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.NULLIFIER_TREE]),
439
- treeStateReferenceToSnapshot(resp.state[MerkleTreeId.PUBLIC_DATA_TREE]),
421
+ treeStateReferenceToSnapshot(state[MerkleTreeId.NOTE_HASH_TREE]),
422
+ treeStateReferenceToSnapshot(state[MerkleTreeId.NULLIFIER_TREE]),
423
+ treeStateReferenceToSnapshot(state[MerkleTreeId.PUBLIC_DATA_TREE]),
440
424
  ),
441
425
  );
442
426
  }
@@ -445,11 +429,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
445
429
  dstPath: string,
446
430
  compact: boolean = true,
447
431
  ): Promise<Record<Exclude<SnapshotDataKeys, 'archiver'>, string>> {
448
- await this.instance.call(WorldStateMessageType.COPY_STORES, {
449
- dstPath,
450
- compact,
451
- canonical: true,
452
- });
432
+ await this.instance.copyStores(dstPath, compact);
453
433
  return fromEntries(NATIVE_WORLD_STATE_DBS.map(([name, dir]) => [name, join(dstPath, dir, 'data.mdb')] as const));
454
434
  }
455
435
  }