@aztec/world-state 0.62.0 → 0.63.0
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/native/message.d.ts +96 -10
- package/dest/native/message.d.ts.map +1 -1
- package/dest/native/message.js +116 -1
- package/dest/native/native_world_state.d.ts +9 -7
- package/dest/native/native_world_state.d.ts.map +1 -1
- package/dest/native/native_world_state.js +55 -24
- package/dest/native/native_world_state_instance.d.ts +1 -1
- package/dest/native/native_world_state_instance.d.ts.map +1 -1
- package/dest/native/native_world_state_instance.js +4 -4
- package/dest/native/world_state_version.d.ts +15 -0
- package/dest/native/world_state_version.d.ts.map +1 -0
- package/dest/native/world_state_version.js +38 -0
- package/dest/synchronizer/config.d.ts +4 -0
- package/dest/synchronizer/config.d.ts.map +1 -1
- package/dest/synchronizer/config.js +10 -1
- package/dest/synchronizer/factory.d.ts +2 -2
- package/dest/synchronizer/factory.d.ts.map +1 -1
- package/dest/synchronizer/factory.js +8 -4
- package/dest/synchronizer/server_world_state_synchronizer.js +3 -3
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +4 -4
- package/dest/world-state-db/merkle_tree_db.d.ts +7 -7
- package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.d.ts +6 -6
- package/dest/world-state-db/merkle_trees.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.js +7 -6
- package/package.json +8 -8
- package/src/native/message.ts +216 -10
- package/src/native/native_world_state.ts +58 -24
- package/src/native/native_world_state_instance.ts +3 -2
- package/src/native/world_state_version.ts +41 -0
- package/src/synchronizer/config.ts +15 -0
- package/src/synchronizer/factory.ts +17 -5
- package/src/synchronizer/server_world_state_synchronizer.ts +4 -4
- package/src/test/utils.ts +2 -3
- package/src/world-state-db/merkle_tree_db.ts +7 -7
- package/src/world-state-db/merkle_trees.ts +15 -10
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/circuits.js';
|
|
2
|
+
|
|
3
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
4
|
+
|
|
5
|
+
export class WorldStateVersion {
|
|
6
|
+
constructor(readonly version: number, readonly rollupAddress: EthAddress) {}
|
|
7
|
+
|
|
8
|
+
static async readVersion(filename: string) {
|
|
9
|
+
const versionData = await readFile(filename, 'utf-8').catch(() => undefined);
|
|
10
|
+
if (versionData === undefined) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const versionJSON = JSON.parse(versionData);
|
|
14
|
+
if (versionJSON.version === undefined || versionJSON.rollupAddress === undefined) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return WorldStateVersion.fromJSON(versionJSON);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public async writeVersionFile(filename: string) {
|
|
21
|
+
const data = JSON.stringify(this.toJSON());
|
|
22
|
+
await writeFile(filename, data, 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
toJSON() {
|
|
26
|
+
return {
|
|
27
|
+
version: this.version,
|
|
28
|
+
rollupAddress: this.rollupAddress.toChecksumString(),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static fromJSON(obj: any): WorldStateVersion {
|
|
33
|
+
const version = obj.version;
|
|
34
|
+
const rollupAddress = EthAddress.fromString(obj.rollupAddress);
|
|
35
|
+
return new WorldStateVersion(version, rollupAddress);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static empty() {
|
|
39
|
+
return new WorldStateVersion(0, EthAddress.ZERO);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -10,6 +10,12 @@ export interface WorldStateConfig {
|
|
|
10
10
|
|
|
11
11
|
/** Size of the batch for each get-blocks request from the synchronizer to the archiver. */
|
|
12
12
|
worldStateBlockRequestBatchSize?: number;
|
|
13
|
+
|
|
14
|
+
/** The maximum size of the combined world state db in KB, optional, will inherit from the general dataStoreMapSizeKB if not specified*/
|
|
15
|
+
worldStateDbMapSizeKb?: number;
|
|
16
|
+
|
|
17
|
+
/** Optional directory for the world state DB, if unspecified will default to the general data directory */
|
|
18
|
+
worldStateDataDirectory?: string;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
export const worldStateConfigMappings: ConfigMappingsType<WorldStateConfig> = {
|
|
@@ -29,6 +35,15 @@ export const worldStateConfigMappings: ConfigMappingsType<WorldStateConfig> = {
|
|
|
29
35
|
parseEnv: (val: string | undefined) => (val ? +val : undefined),
|
|
30
36
|
description: 'Size of the batch for each get-blocks request from the synchronizer to the archiver.',
|
|
31
37
|
},
|
|
38
|
+
worldStateDbMapSizeKb: {
|
|
39
|
+
env: 'WS_DB_MAP_SIZE_KB',
|
|
40
|
+
parseEnv: (val: string | undefined) => (val ? +val : undefined),
|
|
41
|
+
description: 'The maximum possible size of the world state DB',
|
|
42
|
+
},
|
|
43
|
+
worldStateDataDirectory: {
|
|
44
|
+
env: 'WS_DATA_DIRECTORY',
|
|
45
|
+
description: 'Optional directory for the world state database',
|
|
46
|
+
},
|
|
32
47
|
};
|
|
33
48
|
|
|
34
49
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type L1ToL2MessageSource, type L2BlockSource } from '@aztec/circuit-types';
|
|
2
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
-
import { type DataStoreConfig
|
|
3
|
+
import { type DataStoreConfig } from '@aztec/kv-store/config';
|
|
4
|
+
import { createStore } from '@aztec/kv-store/utils';
|
|
4
5
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
5
6
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
6
7
|
|
|
@@ -18,14 +19,25 @@ export async function createWorldStateSynchronizer(
|
|
|
18
19
|
return new ServerWorldStateSynchronizer(merkleTrees, l2BlockSource, config);
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export async function createWorldState(
|
|
22
|
+
export async function createWorldState(
|
|
23
|
+
config: WorldStateConfig & DataStoreConfig,
|
|
24
|
+
client: TelemetryClient = new NoopTelemetryClient(),
|
|
25
|
+
) {
|
|
26
|
+
const newConfig = {
|
|
27
|
+
dataDirectory: config.worldStateDataDirectory ?? config.dataDirectory,
|
|
28
|
+
dataStoreMapSizeKB: config.worldStateDbMapSizeKb ?? config.dataStoreMapSizeKB,
|
|
29
|
+
} as DataStoreConfig;
|
|
22
30
|
const merkleTrees = ['true', '1'].includes(process.env.USE_LEGACY_WORLD_STATE ?? '')
|
|
23
31
|
? await MerkleTrees.new(
|
|
24
|
-
await createStore('world-state',
|
|
32
|
+
await createStore('world-state', newConfig, createDebugLogger('aztec:world-state:lmdb')),
|
|
25
33
|
client,
|
|
26
34
|
)
|
|
27
|
-
:
|
|
28
|
-
? await NativeWorldStateService.new(
|
|
35
|
+
: newConfig.dataDirectory
|
|
36
|
+
? await NativeWorldStateService.new(
|
|
37
|
+
config.l1Contracts.rollupAddress,
|
|
38
|
+
newConfig.dataDirectory,
|
|
39
|
+
newConfig.dataStoreMapSizeKB,
|
|
40
|
+
)
|
|
29
41
|
: await NativeWorldStateService.tmp(
|
|
30
42
|
config.l1Contracts.rollupAddress,
|
|
31
43
|
!['true', '1'].includes(process.env.DEBUG_WORLD_STATE!),
|
|
@@ -24,7 +24,7 @@ import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
|
24
24
|
import { elapsed } from '@aztec/foundation/timer';
|
|
25
25
|
import { SHA256Trunc } from '@aztec/merkle-tree';
|
|
26
26
|
|
|
27
|
-
import { type
|
|
27
|
+
import { type WorldStateStatusSummary } from '../native/message.js';
|
|
28
28
|
import { type MerkleTreeAdminDatabase } from '../world-state-db/merkle_tree_db.js';
|
|
29
29
|
import { type WorldStateConfig } from './config.js';
|
|
30
30
|
|
|
@@ -163,7 +163,7 @@ export class ServerWorldStateSynchronizer
|
|
|
163
163
|
|
|
164
164
|
/** Returns the latest L2 block number for each tip of the chain (latest, proven, finalized). */
|
|
165
165
|
public async getL2Tips(): Promise<L2Tips> {
|
|
166
|
-
const status = await this.merkleTreeDb.
|
|
166
|
+
const status = await this.merkleTreeDb.getStatusSummary();
|
|
167
167
|
const unfinalisedBlockHash = await this.getL2BlockHash(Number(status.unfinalisedBlockNumber));
|
|
168
168
|
const latestBlockId: L2BlockId = { number: Number(status.unfinalisedBlockNumber), hash: unfinalisedBlockHash! };
|
|
169
169
|
|
|
@@ -225,7 +225,7 @@ export class ServerWorldStateSynchronizer
|
|
|
225
225
|
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
226
226
|
* @returns Whether the block handled was produced by this same node.
|
|
227
227
|
*/
|
|
228
|
-
private async handleL2Block(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<
|
|
228
|
+
private async handleL2Block(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatusSummary> {
|
|
229
229
|
// First we check that the L1 to L2 messages hash to the block inHash.
|
|
230
230
|
// Note that we cannot optimize this check by checking the root of the subtree after inserting the messages
|
|
231
231
|
// to the real L1_TO_L2_MESSAGE_TREE (like we do in merkleTreeDb.handleL2BlockAndMessages(...)) because that
|
|
@@ -240,7 +240,7 @@ export class ServerWorldStateSynchronizer
|
|
|
240
240
|
this.syncPromise.resolve();
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
return result;
|
|
243
|
+
return result.summary;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
private async handleChainFinalized(blockNumber: number) {
|
package/src/test/utils.ts
CHANGED
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
MerkleTreeId,
|
|
4
4
|
type MerkleTreeReadOperations,
|
|
5
5
|
type MerkleTreeWriteOperations,
|
|
6
|
-
PublicDataWrite,
|
|
7
6
|
TxEffect,
|
|
8
7
|
} from '@aztec/circuit-types';
|
|
9
8
|
import {
|
|
@@ -15,7 +14,7 @@ import {
|
|
|
15
14
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
16
15
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
17
16
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
18
|
-
|
|
17
|
+
PublicDataWrite,
|
|
19
18
|
} from '@aztec/circuits.js';
|
|
20
19
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
21
20
|
|
|
@@ -54,7 +53,7 @@ export async function mockBlock(blockNum: number, size: number, fork: MerkleTree
|
|
|
54
53
|
|
|
55
54
|
await fork.batchInsert(
|
|
56
55
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
57
|
-
publicDataWrites.map(write =>
|
|
56
|
+
publicDataWrites.map(write => write.toBuffer()),
|
|
58
57
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
59
58
|
);
|
|
60
59
|
|
|
@@ -3,7 +3,7 @@ import { type MerkleTreeReadOperations, type MerkleTreeWriteOperations } from '@
|
|
|
3
3
|
import { type Fr, MAX_NULLIFIERS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/circuits.js';
|
|
4
4
|
import { type IndexedTreeSnapshot, type TreeSnapshot } from '@aztec/merkle-tree';
|
|
5
5
|
|
|
6
|
-
import { type
|
|
6
|
+
import { type WorldStateStatusFull, type WorldStateStatusSummary } from '../native/message.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
@@ -38,7 +38,7 @@ export interface MerkleTreeAdminDatabase {
|
|
|
38
38
|
* @param block - The L2 block to handle.
|
|
39
39
|
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
40
40
|
*/
|
|
41
|
-
handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<
|
|
41
|
+
handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatusFull>;
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Gets a handle that allows reading the latest committed state
|
|
@@ -62,27 +62,27 @@ export interface MerkleTreeAdminDatabase {
|
|
|
62
62
|
* @param toBlockNumber The block number of the new oldest historical block
|
|
63
63
|
* @returns The new WorldStateStatus
|
|
64
64
|
*/
|
|
65
|
-
removeHistoricalBlocks(toBlockNumber: bigint): Promise<
|
|
65
|
+
removeHistoricalBlocks(toBlockNumber: bigint): Promise<WorldStateStatusFull>;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* Removes all pending blocks down to but not including the given block number
|
|
69
69
|
* @param toBlockNumber The block number of the new tip of the pending chain,
|
|
70
70
|
* @returns The new WorldStateStatus
|
|
71
71
|
*/
|
|
72
|
-
unwindBlocks(toBlockNumber: bigint): Promise<
|
|
72
|
+
unwindBlocks(toBlockNumber: bigint): Promise<WorldStateStatusFull>;
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Advances the finalised block number to be the number provided
|
|
76
76
|
* @param toBlockNumber The block number that is now the tip of the finalised chain
|
|
77
77
|
* @returns The new WorldStateStatus
|
|
78
78
|
*/
|
|
79
|
-
setFinalised(toBlockNumber: bigint): Promise<
|
|
79
|
+
setFinalised(toBlockNumber: bigint): Promise<WorldStateStatusSummary>;
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
|
-
* Gets the current status of the database.
|
|
82
|
+
* Gets the current status summary of the database.
|
|
83
83
|
* @returns The current WorldStateStatus.
|
|
84
84
|
*/
|
|
85
|
-
|
|
85
|
+
getStatusSummary(): Promise<WorldStateStatusSummary>;
|
|
86
86
|
|
|
87
87
|
/** Stops the database */
|
|
88
88
|
close(): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type L2Block, MerkleTreeId,
|
|
1
|
+
import { type L2Block, MerkleTreeId, type SiblingPath, TxEffect } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
3
|
type BatchInsertionResult,
|
|
4
4
|
type IndexedTreeId,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
PartialStateReference,
|
|
28
28
|
PublicDataTreeLeaf,
|
|
29
29
|
PublicDataTreeLeafPreimage,
|
|
30
|
+
PublicDataWrite,
|
|
30
31
|
StateReference,
|
|
31
32
|
} from '@aztec/circuits.js';
|
|
32
33
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
@@ -50,7 +51,11 @@ import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
|
50
51
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
51
52
|
import { type Hasher } from '@aztec/types/interfaces';
|
|
52
53
|
|
|
53
|
-
import {
|
|
54
|
+
import {
|
|
55
|
+
type WorldStateStatusFull,
|
|
56
|
+
type WorldStateStatusSummary,
|
|
57
|
+
buildEmptyWorldStateStatusFull,
|
|
58
|
+
} from '../native/message.js';
|
|
54
59
|
import {
|
|
55
60
|
INITIAL_NULLIFIER_TREE_SIZE,
|
|
56
61
|
INITIAL_PUBLIC_DATA_TREE_SIZE,
|
|
@@ -197,19 +202,19 @@ export class MerkleTrees implements MerkleTreeAdminDatabase {
|
|
|
197
202
|
}
|
|
198
203
|
}
|
|
199
204
|
|
|
200
|
-
public removeHistoricalBlocks(_toBlockNumber: bigint): Promise<
|
|
205
|
+
public removeHistoricalBlocks(_toBlockNumber: bigint): Promise<WorldStateStatusFull> {
|
|
201
206
|
throw new Error('Method not implemented.');
|
|
202
207
|
}
|
|
203
208
|
|
|
204
|
-
public unwindBlocks(_toBlockNumber: bigint): Promise<
|
|
209
|
+
public unwindBlocks(_toBlockNumber: bigint): Promise<WorldStateStatusFull> {
|
|
205
210
|
throw new Error('Method not implemented.');
|
|
206
211
|
}
|
|
207
212
|
|
|
208
|
-
public setFinalised(_toBlockNumber: bigint): Promise<
|
|
213
|
+
public setFinalised(_toBlockNumber: bigint): Promise<WorldStateStatusSummary> {
|
|
209
214
|
throw new Error('Method not implemented.');
|
|
210
215
|
}
|
|
211
216
|
|
|
212
|
-
public
|
|
217
|
+
public getStatusSummary(): Promise<WorldStateStatusSummary> {
|
|
213
218
|
throw new Error('Method not implemented.');
|
|
214
219
|
}
|
|
215
220
|
|
|
@@ -466,7 +471,7 @@ export class MerkleTrees implements MerkleTreeAdminDatabase {
|
|
|
466
471
|
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
467
472
|
* @returns Whether the block handled was produced by this same node.
|
|
468
473
|
*/
|
|
469
|
-
public async handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<
|
|
474
|
+
public async handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatusFull> {
|
|
470
475
|
return await this.synchronize(() => this.#handleL2BlockAndMessages(block, l1ToL2Messages));
|
|
471
476
|
}
|
|
472
477
|
|
|
@@ -616,7 +621,7 @@ export class MerkleTrees implements MerkleTreeAdminDatabase {
|
|
|
616
621
|
* @param l2Block - The L2 block to handle.
|
|
617
622
|
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
618
623
|
*/
|
|
619
|
-
async #handleL2BlockAndMessages(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<
|
|
624
|
+
async #handleL2BlockAndMessages(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatusFull> {
|
|
620
625
|
const timer = new Timer();
|
|
621
626
|
|
|
622
627
|
const treeRootWithIdPairs = [
|
|
@@ -678,7 +683,7 @@ export class MerkleTrees implements MerkleTreeAdminDatabase {
|
|
|
678
683
|
);
|
|
679
684
|
|
|
680
685
|
await publicDataTree.batchInsert(
|
|
681
|
-
publicDataWrites.map(write =>
|
|
686
|
+
publicDataWrites.map(write => write.toBuffer()),
|
|
682
687
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
683
688
|
);
|
|
684
689
|
}
|
|
@@ -709,7 +714,7 @@ export class MerkleTrees implements MerkleTreeAdminDatabase {
|
|
|
709
714
|
|
|
710
715
|
this.metrics.recordDbSize(this.store.estimateSize().bytes);
|
|
711
716
|
this.metrics.recordSyncDuration('commit', timer);
|
|
712
|
-
return
|
|
717
|
+
return buildEmptyWorldStateStatusFull();
|
|
713
718
|
}
|
|
714
719
|
|
|
715
720
|
#isDbPopulated(): boolean {
|