@aztec/world-state 0.0.1-commit.b655e406 → 0.0.1-commit.b8a057fa
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/bench_metrics.d.ts +1 -1
- package/dest/native/bench_metrics.d.ts.map +1 -1
- 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 -8
- package/dest/native/merkle_trees_facade.d.ts.map +1 -1
- package/dest/native/merkle_trees_facade.js +90 -111
- package/dest/native/message.d.ts +22 -228
- package/dest/native/message.d.ts.map +1 -1
- package/dest/native/message.js +14 -55
- package/dest/native/native_world_state.d.ts +30 -15
- package/dest/native/native_world_state.d.ts.map +1 -1
- package/dest/native/native_world_state.js +133 -66
- package/dest/native/native_world_state_instance.d.ts +56 -33
- package/dest/native/native_world_state_instance.d.ts.map +1 -1
- package/dest/native/native_world_state_instance.js +1 -182
- 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 +20 -32
- package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/server_world_state_synchronizer.js +181 -85
- package/dest/test/index.d.ts +1 -1
- package/dest/test/utils.d.ts +12 -5
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +59 -50
- 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/index.d.ts +1 -1
- package/dest/world-state-db/merkle_tree_db.d.ts +9 -19
- package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
- package/package.json +16 -13
- 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 +118 -104
- package/src/native/message.ts +33 -305
- package/src/native/native_world_state.ts +179 -108
- package/src/native/native_world_state_instance.ts +94 -251
- 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 +219 -111
- package/src/test/utils.ts +96 -92
- package/src/testing.ts +13 -11
- package/src/world-state-db/merkle_tree_db.ts +12 -19
- 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/src/native/world_state_ops_queue.ts +0 -190
|
@@ -1,11 +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
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import { fromEntries, padArrayEnd } from '@aztec/foundation/collection';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
-
import {
|
|
5
|
-
import { tryRmDir } from '@aztec/foundation/fs';
|
|
6
|
-
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
6
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
7
7
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
8
|
-
import { DatabaseVersionManager } from '@aztec/stdlib/database-version';
|
|
8
|
+
import { DatabaseVersionManager } from '@aztec/stdlib/database-version/manager';
|
|
9
9
|
import type {
|
|
10
10
|
IndexedTreeId,
|
|
11
11
|
MerkleTreeReadOperations,
|
|
@@ -13,21 +13,21 @@ import type {
|
|
|
13
13
|
} from '@aztec/stdlib/interfaces/server';
|
|
14
14
|
import type { SnapshotDataKeys } from '@aztec/stdlib/snapshots';
|
|
15
15
|
import { MerkleTreeId, NullifierLeaf, type NullifierLeafPreimage, PublicDataTreeLeaf } from '@aztec/stdlib/trees';
|
|
16
|
-
import { BlockHeader, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
17
|
-
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';
|
|
18
18
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
19
19
|
|
|
20
20
|
import assert from 'assert/strict';
|
|
21
|
-
import { mkdtemp, rm } from 'fs/promises';
|
|
21
|
+
import { mkdir, mkdtemp, rm } from 'fs/promises';
|
|
22
22
|
import { tmpdir } from 'os';
|
|
23
23
|
import { join } from 'path';
|
|
24
24
|
|
|
25
25
|
import { WorldStateInstrumentation } from '../instrumentation/instrumentation.js';
|
|
26
26
|
import type { WorldStateTreeMapSizes } from '../synchronizer/factory.js';
|
|
27
27
|
import type { MerkleTreeAdminDatabase as MerkleTreeDatabase } from '../world-state-db/merkle_tree_db.js';
|
|
28
|
+
import { IpcWorldState } from './ipc_world_state_instance.js';
|
|
28
29
|
import { MerkleTreesFacade, MerkleTreesForkFacade, serializeLeaf } from './merkle_trees_facade.js';
|
|
29
30
|
import {
|
|
30
|
-
WorldStateMessageType,
|
|
31
31
|
type WorldStateStatusFull,
|
|
32
32
|
type WorldStateStatusSummary,
|
|
33
33
|
blockStateReference,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
sanitizeSummary,
|
|
36
36
|
treeStateReferenceToSnapshot,
|
|
37
37
|
} from './message.js';
|
|
38
|
-
import {
|
|
38
|
+
import type { NativeWorldStateInstance } from './native_world_state_instance.js';
|
|
39
39
|
|
|
40
40
|
// The current version of the world state database schema
|
|
41
41
|
// Increment this when making incompatible changes to the database schema
|
|
@@ -49,34 +49,49 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
49
49
|
private cachedStatusSummary: WorldStateStatusSummary | undefined;
|
|
50
50
|
|
|
51
51
|
protected constructor(
|
|
52
|
-
protected instance:
|
|
52
|
+
protected instance: NativeWorldStateInstance,
|
|
53
53
|
protected readonly worldStateInstrumentation: WorldStateInstrumentation,
|
|
54
|
-
protected readonly log: Logger
|
|
54
|
+
protected readonly log: Logger,
|
|
55
|
+
private readonly genesis: GenesisData = EMPTY_GENESIS_DATA,
|
|
55
56
|
private readonly cleanup = () => Promise.resolve(),
|
|
57
|
+
/** Factory to recreate a fresh IpcWorldState after clear(). */
|
|
58
|
+
private readonly recreateInstance?: () => Promise<NativeWorldStateInstance>,
|
|
56
59
|
) {}
|
|
57
60
|
|
|
58
61
|
static async new(
|
|
59
62
|
rollupAddress: EthAddress,
|
|
60
63
|
dataDir: string,
|
|
61
64
|
wsTreeMapSizes: WorldStateTreeMapSizes,
|
|
62
|
-
|
|
65
|
+
genesis: GenesisData = EMPTY_GENESIS_DATA,
|
|
63
66
|
instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
|
|
64
|
-
|
|
67
|
+
bindings?: LoggerBindings,
|
|
65
68
|
cleanup = () => Promise.resolve(),
|
|
66
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);
|
|
67
77
|
const worldStateDirectory = join(dataDir, WORLD_STATE_DIR);
|
|
68
|
-
|
|
78
|
+
|
|
69
79
|
const versionManager = new DatabaseVersionManager({
|
|
70
80
|
schemaVersion: WORLD_STATE_DB_VERSION,
|
|
71
81
|
rollupAddress,
|
|
72
82
|
dataDirectory: worldStateDirectory,
|
|
73
|
-
onOpen: (dir
|
|
74
|
-
return Promise.resolve(new NativeWorldState(dir, wsTreeMapSizes, prefilledPublicData, instrumentation));
|
|
75
|
-
},
|
|
83
|
+
onOpen: dir => IpcWorldState.spawn(dir, wsTreeMapSizes, genesis, instrumentation, bindings),
|
|
76
84
|
});
|
|
77
85
|
|
|
78
86
|
const [instance] = await versionManager.open();
|
|
79
|
-
|
|
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);
|
|
80
95
|
try {
|
|
81
96
|
await worldState.init();
|
|
82
97
|
} catch (e) {
|
|
@@ -88,14 +103,19 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
88
103
|
}
|
|
89
104
|
|
|
90
105
|
static async tmp(
|
|
91
|
-
rollupAddress = EthAddress.ZERO,
|
|
92
106
|
cleanupTmpDir = true,
|
|
93
|
-
|
|
107
|
+
genesis: GenesisData = EMPTY_GENESIS_DATA,
|
|
94
108
|
instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
|
|
109
|
+
bindings?: LoggerBindings,
|
|
110
|
+
threads?: number,
|
|
95
111
|
): Promise<NativeWorldStateService> {
|
|
96
|
-
const log = createLogger('world-state:database');
|
|
112
|
+
const log = createLogger('world-state:database', bindings);
|
|
97
113
|
const dataDir = await mkdtemp(join(tmpdir(), 'aztec-world-state-'));
|
|
98
|
-
|
|
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;
|
|
99
119
|
const worldStateTreeMapSizes: WorldStateTreeMapSizes = {
|
|
100
120
|
archiveTreeMapSizeKb: dbMapSizeKb,
|
|
101
121
|
nullifierTreeMapSizeKb: dbMapSizeKb,
|
|
@@ -105,7 +125,15 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
105
125
|
};
|
|
106
126
|
log.debug(`Created temporary world state database at: ${dataDir} with tree map size: ${dbMapSizeKb}`);
|
|
107
127
|
|
|
108
|
-
|
|
128
|
+
const instance = await IpcWorldState.spawn(
|
|
129
|
+
dataDir,
|
|
130
|
+
worldStateTreeMapSizes,
|
|
131
|
+
genesis,
|
|
132
|
+
instrumentation,
|
|
133
|
+
bindings,
|
|
134
|
+
threads,
|
|
135
|
+
);
|
|
136
|
+
|
|
109
137
|
const cleanup = async () => {
|
|
110
138
|
if (cleanupTmpDir) {
|
|
111
139
|
await rm(dataDir, { recursive: true, force: true, maxRetries: 3 });
|
|
@@ -115,7 +143,47 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
115
143
|
}
|
|
116
144
|
};
|
|
117
145
|
|
|
118
|
-
|
|
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;
|
|
119
187
|
}
|
|
120
188
|
|
|
121
189
|
protected async init() {
|
|
@@ -139,18 +207,31 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
139
207
|
assert.strictEqual(initialHeaderIndex, 0n, 'Invalid initial archive state');
|
|
140
208
|
}
|
|
141
209
|
|
|
142
|
-
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');
|
|
143
215
|
await this.instance.close();
|
|
144
216
|
this.cachedStatusSummary = undefined;
|
|
145
|
-
|
|
146
|
-
|
|
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');
|
|
147
228
|
}
|
|
148
229
|
|
|
149
230
|
public getCommitted(): MerkleTreeReadOperations {
|
|
150
231
|
return new MerkleTreesFacade(this.instance, this.initialHeader!, WorldStateRevision.empty());
|
|
151
232
|
}
|
|
152
233
|
|
|
153
|
-
public getSnapshot(blockNumber:
|
|
234
|
+
public getSnapshot(blockNumber: BlockNumber): MerkleTreeReadOperations {
|
|
154
235
|
return new MerkleTreesFacade(
|
|
155
236
|
this.instance,
|
|
156
237
|
this.initialHeader!,
|
|
@@ -158,16 +239,23 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
158
239
|
);
|
|
159
240
|
}
|
|
160
241
|
|
|
161
|
-
public async fork(
|
|
162
|
-
|
|
242
|
+
public async fork(
|
|
243
|
+
blockNumber?: BlockNumber,
|
|
244
|
+
opts: { closeDelayMs?: number } = {},
|
|
245
|
+
): Promise<MerkleTreeWriteOperations> {
|
|
246
|
+
const forkId = await this.instance.createFork({
|
|
163
247
|
latest: blockNumber === undefined,
|
|
164
|
-
blockNumber: blockNumber ??
|
|
165
|
-
canonical: true,
|
|
248
|
+
blockNumber: blockNumber ?? BlockNumber.ZERO,
|
|
166
249
|
});
|
|
167
250
|
return new MerkleTreesForkFacade(
|
|
168
251
|
this.instance,
|
|
169
252
|
this.initialHeader!,
|
|
170
|
-
new WorldStateRevision(
|
|
253
|
+
new WorldStateRevision(
|
|
254
|
+
/*forkId=*/ forkId,
|
|
255
|
+
/* blockNumber=*/ WorldStateRevision.LATEST,
|
|
256
|
+
/* includeUncommitted=*/ true,
|
|
257
|
+
),
|
|
258
|
+
opts,
|
|
171
259
|
);
|
|
172
260
|
}
|
|
173
261
|
|
|
@@ -175,21 +263,24 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
175
263
|
return this.initialHeader!;
|
|
176
264
|
}
|
|
177
265
|
|
|
178
|
-
public async handleL2BlockAndMessages(
|
|
179
|
-
l2Block
|
|
180
|
-
l1ToL2Messages
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
);
|
|
266
|
+
public async handleL2BlockAndMessages(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatusFull> {
|
|
267
|
+
const isFirstBlock = l2Block.indexWithinCheckpoint === 0;
|
|
268
|
+
if (!isFirstBlock && l1ToL2Messages.length > 0) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
`L1 to L2 messages must be empty for non-first blocks, but got ${l1ToL2Messages.length} messages for block ${l2Block.number}.`,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// We have to pad the given l1 to l2 messages, and the note hashes and nullifiers within tx effects, because that's
|
|
275
|
+
// how the trees are built by circuits.
|
|
189
276
|
const paddedL1ToL2Messages = isFirstBlock
|
|
190
277
|
? padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP)
|
|
191
278
|
: [];
|
|
192
279
|
|
|
280
|
+
const paddedNoteHashes = l2Block.body.txEffects.flatMap(txEffect =>
|
|
281
|
+
padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
|
|
282
|
+
);
|
|
283
|
+
|
|
193
284
|
const paddedNullifiers = l2Block.body.txEffects
|
|
194
285
|
.flatMap(txEffect => padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX))
|
|
195
286
|
.map(nullifier => new NullifierLeaf(nullifier));
|
|
@@ -204,35 +295,44 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
204
295
|
});
|
|
205
296
|
|
|
206
297
|
try {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
this.deleteCachedSummary.bind(this),
|
|
221
|
-
);
|
|
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);
|
|
222
311
|
} catch (err) {
|
|
312
|
+
this.deleteCachedSummary();
|
|
223
313
|
this.worldStateInstrumentation.incCriticalErrors('synch_pending_block');
|
|
224
314
|
throw err;
|
|
225
315
|
}
|
|
226
316
|
}
|
|
227
317
|
|
|
228
318
|
public async close(): Promise<void> {
|
|
229
|
-
|
|
230
|
-
|
|
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();
|
|
231
328
|
}
|
|
232
329
|
|
|
233
330
|
private async buildInitialHeader(): Promise<BlockHeader> {
|
|
234
331
|
const state = await this.getInitialStateReference();
|
|
235
|
-
return BlockHeader.empty({
|
|
332
|
+
return BlockHeader.empty({
|
|
333
|
+
state,
|
|
334
|
+
globalVariables: GlobalVariables.empty({ timestamp: this.genesis.genesisTimestamp }),
|
|
335
|
+
});
|
|
236
336
|
}
|
|
237
337
|
|
|
238
338
|
private sanitizeAndCacheSummaryFromFull(response: WorldStateStatusFull) {
|
|
@@ -247,7 +347,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
247
347
|
return sanitized;
|
|
248
348
|
}
|
|
249
349
|
|
|
250
|
-
private deleteCachedSummary(
|
|
350
|
+
private deleteCachedSummary() {
|
|
251
351
|
this.cachedStatusSummary = undefined;
|
|
252
352
|
}
|
|
253
353
|
|
|
@@ -256,18 +356,11 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
256
356
|
* @param toBlockNumber The block number that is now the tip of the finalized chain
|
|
257
357
|
* @returns The new WorldStateStatus
|
|
258
358
|
*/
|
|
259
|
-
public async setFinalized(toBlockNumber:
|
|
359
|
+
public async setFinalized(toBlockNumber: BlockNumber) {
|
|
260
360
|
try {
|
|
261
|
-
await this.instance.
|
|
262
|
-
WorldStateMessageType.FINALIZE_BLOCKS,
|
|
263
|
-
{
|
|
264
|
-
toBlockNumber,
|
|
265
|
-
canonical: true,
|
|
266
|
-
},
|
|
267
|
-
this.sanitizeAndCacheSummary.bind(this),
|
|
268
|
-
this.deleteCachedSummary.bind(this),
|
|
269
|
-
);
|
|
361
|
+
this.sanitizeAndCacheSummary(await this.instance.finalizeBlocks(toBlockNumber));
|
|
270
362
|
} catch (err) {
|
|
363
|
+
this.deleteCachedSummary();
|
|
271
364
|
this.worldStateInstrumentation.incCriticalErrors('finalize_block');
|
|
272
365
|
throw err;
|
|
273
366
|
}
|
|
@@ -279,18 +372,11 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
279
372
|
* @param toBlockNumber The block number of the new oldest historical block
|
|
280
373
|
* @returns The new WorldStateStatus
|
|
281
374
|
*/
|
|
282
|
-
public async removeHistoricalBlocks(toBlockNumber:
|
|
375
|
+
public async removeHistoricalBlocks(toBlockNumber: BlockNumber) {
|
|
283
376
|
try {
|
|
284
|
-
return await this.instance.
|
|
285
|
-
WorldStateMessageType.REMOVE_HISTORICAL_BLOCKS,
|
|
286
|
-
{
|
|
287
|
-
toBlockNumber,
|
|
288
|
-
canonical: true,
|
|
289
|
-
},
|
|
290
|
-
this.sanitizeAndCacheSummaryFromFull.bind(this),
|
|
291
|
-
this.deleteCachedSummary.bind(this),
|
|
292
|
-
);
|
|
377
|
+
return this.sanitizeAndCacheSummaryFromFull(await this.instance.removeHistoricalBlocks(toBlockNumber));
|
|
293
378
|
} catch (err) {
|
|
379
|
+
this.deleteCachedSummary();
|
|
294
380
|
this.worldStateInstrumentation.incCriticalErrors('prune_historical_block');
|
|
295
381
|
throw err;
|
|
296
382
|
}
|
|
@@ -301,18 +387,11 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
301
387
|
* @param toBlockNumber The block number of the new tip of the pending chain,
|
|
302
388
|
* @returns The new WorldStateStatus
|
|
303
389
|
*/
|
|
304
|
-
public async unwindBlocks(toBlockNumber:
|
|
390
|
+
public async unwindBlocks(toBlockNumber: BlockNumber) {
|
|
305
391
|
try {
|
|
306
|
-
return await this.instance.
|
|
307
|
-
WorldStateMessageType.UNWIND_BLOCKS,
|
|
308
|
-
{
|
|
309
|
-
toBlockNumber,
|
|
310
|
-
canonical: true,
|
|
311
|
-
},
|
|
312
|
-
this.sanitizeAndCacheSummaryFromFull.bind(this),
|
|
313
|
-
this.deleteCachedSummary.bind(this),
|
|
314
|
-
);
|
|
392
|
+
return this.sanitizeAndCacheSummaryFromFull(await this.instance.unwindBlocks(toBlockNumber));
|
|
315
393
|
} catch (err) {
|
|
394
|
+
this.deleteCachedSummary();
|
|
316
395
|
this.worldStateInstrumentation.incCriticalErrors('prune_pending_block');
|
|
317
396
|
throw err;
|
|
318
397
|
}
|
|
@@ -322,11 +401,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
322
401
|
if (this.cachedStatusSummary !== undefined) {
|
|
323
402
|
return { ...this.cachedStatusSummary };
|
|
324
403
|
}
|
|
325
|
-
return await this.instance.
|
|
326
|
-
WorldStateMessageType.GET_STATUS,
|
|
327
|
-
{ canonical: true },
|
|
328
|
-
this.sanitizeAndCacheSummary.bind(this),
|
|
329
|
-
);
|
|
404
|
+
return this.sanitizeAndCacheSummary(await this.instance.getStatus());
|
|
330
405
|
}
|
|
331
406
|
|
|
332
407
|
updateLeaf<ID extends IndexedTreeId>(
|
|
@@ -338,14 +413,14 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
338
413
|
}
|
|
339
414
|
|
|
340
415
|
private async getInitialStateReference(): Promise<StateReference> {
|
|
341
|
-
const
|
|
416
|
+
const state = await this.instance.getInitialStateReference();
|
|
342
417
|
|
|
343
418
|
return new StateReference(
|
|
344
|
-
treeStateReferenceToSnapshot(
|
|
419
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]),
|
|
345
420
|
new PartialStateReference(
|
|
346
|
-
treeStateReferenceToSnapshot(
|
|
347
|
-
treeStateReferenceToSnapshot(
|
|
348
|
-
treeStateReferenceToSnapshot(
|
|
421
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.NOTE_HASH_TREE]),
|
|
422
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.NULLIFIER_TREE]),
|
|
423
|
+
treeStateReferenceToSnapshot(state[MerkleTreeId.PUBLIC_DATA_TREE]),
|
|
349
424
|
),
|
|
350
425
|
);
|
|
351
426
|
}
|
|
@@ -354,11 +429,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase {
|
|
|
354
429
|
dstPath: string,
|
|
355
430
|
compact: boolean = true,
|
|
356
431
|
): Promise<Record<Exclude<SnapshotDataKeys, 'archiver'>, string>> {
|
|
357
|
-
await this.instance.
|
|
358
|
-
dstPath,
|
|
359
|
-
compact,
|
|
360
|
-
canonical: true,
|
|
361
|
-
});
|
|
432
|
+
await this.instance.copyStores(dstPath, compact);
|
|
362
433
|
return fromEntries(NATIVE_WORLD_STATE_DBS.map(([name, dir]) => [name, join(dstPath, dir, 'data.mdb')] as const));
|
|
363
434
|
}
|
|
364
435
|
}
|