@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.
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/instrumentation/instrumentation.d.ts +4 -3
- package/dest/instrumentation/instrumentation.d.ts.map +1 -1
- package/dest/instrumentation/instrumentation.js +21 -50
- package/dest/native/fork_checkpoint.d.ts +7 -1
- package/dest/native/fork_checkpoint.d.ts.map +1 -1
- package/dest/native/fork_checkpoint.js +15 -3
- package/dest/native/index.d.ts +2 -1
- package/dest/native/index.d.ts.map +1 -1
- package/dest/native/index.js +1 -0
- package/dest/native/ipc_world_state_instance.d.ts +89 -0
- package/dest/native/ipc_world_state_instance.d.ts.map +1 -0
- package/dest/native/ipc_world_state_instance.js +661 -0
- package/dest/native/merkle_trees_facade.d.ts +18 -9
- package/dest/native/merkle_trees_facade.d.ts.map +1 -1
- package/dest/native/merkle_trees_facade.js +90 -113
- package/dest/native/message.d.ts +15 -222
- package/dest/native/message.d.ts.map +1 -1
- package/dest/native/message.js +1 -43
- package/dest/native/native_world_state.d.ts +26 -12
- package/dest/native/native_world_state.d.ts.map +1 -1
- package/dest/native/native_world_state.js +126 -62
- package/dest/native/native_world_state_instance.d.ts +56 -42
- package/dest/native/native_world_state_instance.d.ts.map +1 -1
- package/dest/native/native_world_state_instance.js +1 -203
- package/dest/native/world_state_operation.d.ts +7 -0
- package/dest/native/world_state_operation.d.ts.map +1 -0
- package/dest/native/world_state_operation.js +5 -0
- package/dest/synchronizer/config.d.ts +3 -5
- package/dest/synchronizer/config.d.ts.map +1 -1
- package/dest/synchronizer/config.js +15 -18
- package/dest/synchronizer/errors.d.ts +8 -1
- package/dest/synchronizer/errors.d.ts.map +1 -1
- package/dest/synchronizer/errors.js +8 -1
- package/dest/synchronizer/factory.d.ts +6 -5
- package/dest/synchronizer/factory.d.ts.map +1 -1
- package/dest/synchronizer/factory.js +7 -6
- package/dest/synchronizer/index.d.ts +2 -1
- package/dest/synchronizer/index.d.ts.map +1 -1
- package/dest/synchronizer/index.js +1 -0
- package/dest/synchronizer/server_world_state_synchronizer.d.ts +16 -10
- package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/server_world_state_synchronizer.js +170 -57
- package/dest/test/utils.d.ts +11 -17
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +49 -81
- package/dest/testing.d.ts +5 -4
- package/dest/testing.d.ts.map +1 -1
- package/dest/testing.js +15 -8
- package/dest/world-state-db/merkle_tree_db.d.ts +7 -18
- package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
- package/package.json +14 -12
- package/src/index.ts +1 -0
- package/src/instrumentation/instrumentation.ts +23 -59
- package/src/native/fork_checkpoint.ts +19 -3
- package/src/native/index.ts +1 -0
- package/src/native/ipc_world_state_instance.ts +834 -0
- package/src/native/merkle_trees_facade.ts +119 -106
- package/src/native/message.ts +14 -287
- package/src/native/native_world_state.ts +159 -99
- package/src/native/native_world_state_instance.ts +94 -279
- package/src/native/world_state_operation.ts +33 -0
- package/src/synchronizer/config.ts +16 -23
- package/src/synchronizer/errors.ts +8 -0
- package/src/synchronizer/factory.ts +18 -11
- package/src/synchronizer/index.ts +1 -0
- package/src/synchronizer/server_world_state_synchronizer.ts +203 -78
- package/src/test/utils.ts +79 -128
- package/src/testing.ts +13 -11
- package/src/world-state-db/merkle_tree_db.ts +10 -22
- package/dest/native/world_state_ops_queue.d.ts +0 -19
- package/dest/native/world_state_ops_queue.d.ts.map +0 -1
- package/dest/native/world_state_ops_queue.js +0 -146
- package/dest/synchronizer/utils.d.ts +0 -11
- package/dest/synchronizer/utils.d.ts.map +0 -1
- package/dest/synchronizer/utils.js +0 -59
- package/src/native/world_state_ops_queue.ts +0 -190
- package/src/synchronizer/utils.ts +0 -83
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { fromEntries, padArrayEnd } from '@aztec/foundation/collection';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import type { L2BlockNew } from '@aztec/stdlib/block';
|
|
9
|
-
import { DatabaseVersionManager } from '@aztec/stdlib/database-version';
|
|
6
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
7
|
+
import type { L2Block } from '@aztec/stdlib/block';
|
|
8
|
+
import { DatabaseVersionManager } from '@aztec/stdlib/database-version/manager';
|
|
10
9
|
import type {
|
|
11
10
|
IndexedTreeId,
|
|
12
11
|
MerkleTreeReadOperations,
|
|
@@ -14,21 +13,21 @@ import type {
|
|
|
14
13
|
} from '@aztec/stdlib/interfaces/server';
|
|
15
14
|
import type { SnapshotDataKeys } from '@aztec/stdlib/snapshots';
|
|
16
15
|
import { MerkleTreeId, NullifierLeaf, type NullifierLeafPreimage, PublicDataTreeLeaf } from '@aztec/stdlib/trees';
|
|
17
|
-
import { BlockHeader, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
18
|
-
import { WorldStateRevision } from '@aztec/stdlib/world-state';
|
|
16
|
+
import { BlockHeader, GlobalVariables, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
17
|
+
import { EMPTY_GENESIS_DATA, type GenesisData, WorldStateRevision } from '@aztec/stdlib/world-state';
|
|
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 {
|
|
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
|
|
@@ -50,34 +49,49 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
50
49
|
private cachedStatusSummary: WorldStateStatusSummary | undefined;
|
|
51
50
|
|
|
52
51
|
protected constructor(
|
|
53
|
-
protected instance:
|
|
52
|
+
protected instance: NativeWorldStateInstance,
|
|
54
53
|
protected readonly worldStateInstrumentation: WorldStateInstrumentation,
|
|
55
|
-
protected readonly log: Logger
|
|
54
|
+
protected readonly log: Logger,
|
|
55
|
+
private readonly genesis: GenesisData = EMPTY_GENESIS_DATA,
|
|
56
56
|
private readonly cleanup = () => Promise.resolve(),
|
|
57
|
+
/** Factory to recreate a fresh IpcWorldState after clear(). */
|
|
58
|
+
private readonly recreateInstance?: () => Promise<NativeWorldStateInstance>,
|
|
57
59
|
) {}
|
|
58
60
|
|
|
59
61
|
static async new(
|
|
60
62
|
rollupAddress: EthAddress,
|
|
61
63
|
dataDir: string,
|
|
62
64
|
wsTreeMapSizes: WorldStateTreeMapSizes,
|
|
63
|
-
|
|
65
|
+
genesis: GenesisData = EMPTY_GENESIS_DATA,
|
|
64
66
|
instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
|
|
65
|
-
|
|
67
|
+
bindings?: LoggerBindings,
|
|
66
68
|
cleanup = () => Promise.resolve(),
|
|
67
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
|
+
|
|
76
|
+
const log = createLogger('world-state:database', bindings);
|
|
68
77
|
const worldStateDirectory = join(dataDir, WORLD_STATE_DIR);
|
|
69
|
-
|
|
78
|
+
|
|
70
79
|
const versionManager = new DatabaseVersionManager({
|
|
71
80
|
schemaVersion: WORLD_STATE_DB_VERSION,
|
|
72
81
|
rollupAddress,
|
|
73
82
|
dataDirectory: worldStateDirectory,
|
|
74
|
-
onOpen: (dir
|
|
75
|
-
return Promise.resolve(new NativeWorldState(dir, wsTreeMapSizes, prefilledPublicData, instrumentation));
|
|
76
|
-
},
|
|
83
|
+
onOpen: dir => IpcWorldState.spawn(dir, wsTreeMapSizes, genesis, instrumentation, bindings),
|
|
77
84
|
});
|
|
78
85
|
|
|
79
86
|
const [instance] = await versionManager.open();
|
|
80
|
-
|
|
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);
|
|
81
95
|
try {
|
|
82
96
|
await worldState.init();
|
|
83
97
|
} catch (e) {
|
|
@@ -89,14 +103,19 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
89
103
|
}
|
|
90
104
|
|
|
91
105
|
static async tmp(
|
|
92
|
-
rollupAddress = EthAddress.ZERO,
|
|
93
106
|
cleanupTmpDir = true,
|
|
94
|
-
|
|
107
|
+
genesis: GenesisData = EMPTY_GENESIS_DATA,
|
|
95
108
|
instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
|
|
109
|
+
bindings?: LoggerBindings,
|
|
110
|
+
threads?: number,
|
|
96
111
|
): Promise<NativeWorldStateService> {
|
|
97
|
-
const log = createLogger('world-state:database');
|
|
112
|
+
const log = createLogger('world-state:database', bindings);
|
|
98
113
|
const dataDir = await mkdtemp(join(tmpdir(), 'aztec-world-state-'));
|
|
99
|
-
|
|
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;
|
|
100
119
|
const worldStateTreeMapSizes: WorldStateTreeMapSizes = {
|
|
101
120
|
archiveTreeMapSizeKb: dbMapSizeKb,
|
|
102
121
|
nullifierTreeMapSizeKb: dbMapSizeKb,
|
|
@@ -106,7 +125,15 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
106
125
|
};
|
|
107
126
|
log.debug(`Created temporary world state database at: ${dataDir} with tree map size: ${dbMapSizeKb}`);
|
|
108
127
|
|
|
109
|
-
|
|
128
|
+
const instance = await IpcWorldState.spawn(
|
|
129
|
+
dataDir,
|
|
130
|
+
worldStateTreeMapSizes,
|
|
131
|
+
genesis,
|
|
132
|
+
instrumentation,
|
|
133
|
+
bindings,
|
|
134
|
+
threads,
|
|
135
|
+
);
|
|
136
|
+
|
|
110
137
|
const cleanup = async () => {
|
|
111
138
|
if (cleanupTmpDir) {
|
|
112
139
|
await rm(dataDir, { recursive: true, force: true, maxRetries: 3 });
|
|
@@ -116,7 +143,47 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
116
143
|
}
|
|
117
144
|
};
|
|
118
145
|
|
|
119
|
-
|
|
146
|
+
const recreateInstance = async () => {
|
|
147
|
+
await rm(dataDir, { recursive: true, force: true, maxRetries: 3 });
|
|
148
|
+
await mkdir(dataDir, { recursive: true });
|
|
149
|
+
return IpcWorldState.spawn(dataDir, worldStateTreeMapSizes, genesis, instrumentation, bindings, threads);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const worldState = new this(instance, instrumentation, log, genesis, cleanup, recreateInstance);
|
|
153
|
+
try {
|
|
154
|
+
await worldState.init();
|
|
155
|
+
} catch (e) {
|
|
156
|
+
log.error(`Error initializing tmp world state: ${e}`);
|
|
157
|
+
throw e;
|
|
158
|
+
}
|
|
159
|
+
return worldState;
|
|
160
|
+
}
|
|
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;
|
|
120
187
|
}
|
|
121
188
|
|
|
122
189
|
protected async init() {
|
|
@@ -140,11 +207,24 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
140
207
|
assert.strictEqual(initialHeaderIndex, 0n, 'Invalid initial archive state');
|
|
141
208
|
}
|
|
142
209
|
|
|
143
|
-
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');
|
|
144
215
|
await this.instance.close();
|
|
145
216
|
this.cachedStatusSummary = undefined;
|
|
146
|
-
|
|
147
|
-
|
|
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');
|
|
148
228
|
}
|
|
149
229
|
|
|
150
230
|
public getCommitted(): MerkleTreeReadOperations {
|
|
@@ -159,20 +239,23 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
159
239
|
);
|
|
160
240
|
}
|
|
161
241
|
|
|
162
|
-
public async fork(
|
|
163
|
-
|
|
242
|
+
public async fork(
|
|
243
|
+
blockNumber?: BlockNumber,
|
|
244
|
+
opts: { closeDelayMs?: number } = {},
|
|
245
|
+
): Promise<MerkleTreeWriteOperations> {
|
|
246
|
+
const forkId = await this.instance.createFork({
|
|
164
247
|
latest: blockNumber === undefined,
|
|
165
248
|
blockNumber: blockNumber ?? BlockNumber.ZERO,
|
|
166
|
-
canonical: true,
|
|
167
249
|
});
|
|
168
250
|
return new MerkleTreesForkFacade(
|
|
169
251
|
this.instance,
|
|
170
252
|
this.initialHeader!,
|
|
171
253
|
new WorldStateRevision(
|
|
172
|
-
/*forkId=*/
|
|
173
|
-
/* blockNumber=*/
|
|
254
|
+
/*forkId=*/ forkId,
|
|
255
|
+
/* blockNumber=*/ WorldStateRevision.LATEST,
|
|
174
256
|
/* includeUncommitted=*/ true,
|
|
175
257
|
),
|
|
258
|
+
opts,
|
|
176
259
|
);
|
|
177
260
|
}
|
|
178
261
|
|
|
@@ -180,11 +263,8 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
180
263
|
return this.initialHeader!;
|
|
181
264
|
}
|
|
182
265
|
|
|
183
|
-
public async handleL2BlockAndMessages(
|
|
184
|
-
l2Block
|
|
185
|
-
l1ToL2Messages: Fr[],
|
|
186
|
-
isFirstBlock: boolean,
|
|
187
|
-
): Promise<WorldStateStatusFull> {
|
|
266
|
+
public async handleL2BlockAndMessages(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatusFull> {
|
|
267
|
+
const isFirstBlock = l2Block.indexWithinCheckpoint === 0;
|
|
188
268
|
if (!isFirstBlock && l1ToL2Messages.length > 0) {
|
|
189
269
|
throw new Error(
|
|
190
270
|
`L1 to L2 messages must be empty for non-first blocks, but got ${l1ToL2Messages.length} messages for block ${l2Block.number}.`,
|
|
@@ -215,35 +295,44 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
215
295
|
});
|
|
216
296
|
|
|
217
297
|
try {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this.deleteCachedSummary.bind(this),
|
|
232
|
-
);
|
|
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);
|
|
233
311
|
} catch (err) {
|
|
312
|
+
this.deleteCachedSummary();
|
|
234
313
|
this.worldStateInstrumentation.incCriticalErrors('synch_pending_block');
|
|
235
314
|
throw err;
|
|
236
315
|
}
|
|
237
316
|
}
|
|
238
317
|
|
|
239
318
|
public async close(): Promise<void> {
|
|
240
|
-
|
|
241
|
-
|
|
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();
|
|
242
328
|
}
|
|
243
329
|
|
|
244
330
|
private async buildInitialHeader(): Promise<BlockHeader> {
|
|
245
331
|
const state = await this.getInitialStateReference();
|
|
246
|
-
return BlockHeader.empty({
|
|
332
|
+
return BlockHeader.empty({
|
|
333
|
+
state,
|
|
334
|
+
globalVariables: GlobalVariables.empty({ timestamp: this.genesis.genesisTimestamp }),
|
|
335
|
+
});
|
|
247
336
|
}
|
|
248
337
|
|
|
249
338
|
private sanitizeAndCacheSummaryFromFull(response: WorldStateStatusFull) {
|
|
@@ -258,7 +347,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
258
347
|
return sanitized;
|
|
259
348
|
}
|
|
260
349
|
|
|
261
|
-
private deleteCachedSummary(
|
|
350
|
+
private deleteCachedSummary() {
|
|
262
351
|
this.cachedStatusSummary = undefined;
|
|
263
352
|
}
|
|
264
353
|
|
|
@@ -269,16 +358,9 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
269
358
|
*/
|
|
270
359
|
public async setFinalized(toBlockNumber: BlockNumber) {
|
|
271
360
|
try {
|
|
272
|
-
await this.instance.
|
|
273
|
-
WorldStateMessageType.FINALIZE_BLOCKS,
|
|
274
|
-
{
|
|
275
|
-
toBlockNumber,
|
|
276
|
-
canonical: true,
|
|
277
|
-
},
|
|
278
|
-
this.sanitizeAndCacheSummary.bind(this),
|
|
279
|
-
this.deleteCachedSummary.bind(this),
|
|
280
|
-
);
|
|
361
|
+
this.sanitizeAndCacheSummary(await this.instance.finalizeBlocks(toBlockNumber));
|
|
281
362
|
} catch (err) {
|
|
363
|
+
this.deleteCachedSummary();
|
|
282
364
|
this.worldStateInstrumentation.incCriticalErrors('finalize_block');
|
|
283
365
|
throw err;
|
|
284
366
|
}
|
|
@@ -292,16 +374,9 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
292
374
|
*/
|
|
293
375
|
public async removeHistoricalBlocks(toBlockNumber: BlockNumber) {
|
|
294
376
|
try {
|
|
295
|
-
return await this.instance.
|
|
296
|
-
WorldStateMessageType.REMOVE_HISTORICAL_BLOCKS,
|
|
297
|
-
{
|
|
298
|
-
toBlockNumber,
|
|
299
|
-
canonical: true,
|
|
300
|
-
},
|
|
301
|
-
this.sanitizeAndCacheSummaryFromFull.bind(this),
|
|
302
|
-
this.deleteCachedSummary.bind(this),
|
|
303
|
-
);
|
|
377
|
+
return this.sanitizeAndCacheSummaryFromFull(await this.instance.removeHistoricalBlocks(toBlockNumber));
|
|
304
378
|
} catch (err) {
|
|
379
|
+
this.deleteCachedSummary();
|
|
305
380
|
this.worldStateInstrumentation.incCriticalErrors('prune_historical_block');
|
|
306
381
|
throw err;
|
|
307
382
|
}
|
|
@@ -314,16 +389,9 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
314
389
|
*/
|
|
315
390
|
public async unwindBlocks(toBlockNumber: BlockNumber) {
|
|
316
391
|
try {
|
|
317
|
-
return await this.instance.
|
|
318
|
-
WorldStateMessageType.UNWIND_BLOCKS,
|
|
319
|
-
{
|
|
320
|
-
toBlockNumber,
|
|
321
|
-
canonical: true,
|
|
322
|
-
},
|
|
323
|
-
this.sanitizeAndCacheSummaryFromFull.bind(this),
|
|
324
|
-
this.deleteCachedSummary.bind(this),
|
|
325
|
-
);
|
|
392
|
+
return this.sanitizeAndCacheSummaryFromFull(await this.instance.unwindBlocks(toBlockNumber));
|
|
326
393
|
} catch (err) {
|
|
394
|
+
this.deleteCachedSummary();
|
|
327
395
|
this.worldStateInstrumentation.incCriticalErrors('prune_pending_block');
|
|
328
396
|
throw err;
|
|
329
397
|
}
|
|
@@ -333,11 +401,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
333
401
|
if (this.cachedStatusSummary !== undefined) {
|
|
334
402
|
return { ...this.cachedStatusSummary };
|
|
335
403
|
}
|
|
336
|
-
return await this.instance.
|
|
337
|
-
WorldStateMessageType.GET_STATUS,
|
|
338
|
-
{ canonical: true },
|
|
339
|
-
this.sanitizeAndCacheSummary.bind(this),
|
|
340
|
-
);
|
|
404
|
+
return this.sanitizeAndCacheSummary(await this.instance.getStatus());
|
|
341
405
|
}
|
|
342
406
|
|
|
343
407
|
updateLeaf<ID extends IndexedTreeId>(
|
|
@@ -349,14 +413,14 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
349
413
|
}
|
|
350
414
|
|
|
351
415
|
private async getInitialStateReference(): Promise<StateReference> {
|
|
352
|
-
const
|
|
416
|
+
const state = await this.instance.getInitialStateReference();
|
|
353
417
|
|
|
354
418
|
return new StateReference(
|
|
355
|
-
treeStateReferenceToSnapshot(
|
|
419
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
|
|
356
420
|
new PartialStateReference(
|
|
357
|
-
treeStateReferenceToSnapshot(
|
|
358
|
-
treeStateReferenceToSnapshot(
|
|
359
|
-
treeStateReferenceToSnapshot(
|
|
421
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.NOTE_HASH_TREE]),
|
|
422
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.NULLIFIER_TREE]),
|
|
423
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.PUBLIC_DATA_TREE]),
|
|
360
424
|
),
|
|
361
425
|
);
|
|
362
426
|
}
|
|
@@ -365,11 +429,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
365
429
|
dstPath: string,
|
|
366
430
|
compact: boolean = true,
|
|
367
431
|
): Promise<Record<Exclude<SnapshotDataKeys, 'archiver'>, string>> {
|
|
368
|
-
await this.instance.
|
|
369
|
-
dstPath,
|
|
370
|
-
compact,
|
|
371
|
-
canonical: true,
|
|
372
|
-
});
|
|
432
|
+
await this.instance.copyStores(dstPath, compact);
|
|
373
433
|
return fromEntries(NATIVE_WORLD_STATE_DBS.map(([name, dir]) => [name, join(dstPath, dir, 'data.mdb')] as const));
|
|
374
434
|
}
|
|
375
435
|
}
|