@aztec/world-state 0.57.0 → 0.59.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/README.md +1 -1
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/native/merkle_trees_facade.d.ts +34 -0
- package/dest/native/merkle_trees_facade.d.ts.map +1 -0
- package/dest/native/merkle_trees_facade.js +193 -0
- package/dest/native/message.d.ts +78 -19
- package/dest/native/message.d.ts.map +1 -1
- package/dest/native/message.js +27 -26
- package/dest/native/native_world_state.d.ts +39 -38
- package/dest/native/native_world_state.d.ts.map +1 -1
- package/dest/native/native_world_state.js +108 -254
- package/dest/native/native_world_state_instance.d.ts +40 -0
- package/dest/native/native_world_state_instance.d.ts.map +1 -0
- package/dest/native/native_world_state_instance.js +183 -0
- package/dest/synchronizer/config.d.ts +2 -2
- package/dest/synchronizer/config.d.ts.map +1 -1
- package/dest/synchronizer/config.js +6 -7
- package/dest/synchronizer/factory.d.ts +3 -0
- package/dest/synchronizer/factory.d.ts.map +1 -1
- package/dest/synchronizer/factory.js +13 -4
- package/dest/synchronizer/server_world_state_synchronizer.d.ts +41 -41
- package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/server_world_state_synchronizer.js +126 -151
- package/dest/test/utils.d.ts +14 -0
- package/dest/test/utils.d.ts.map +1 -0
- package/dest/test/utils.js +67 -0
- package/dest/world-state-db/index.d.ts +1 -1
- package/dest/world-state-db/index.d.ts.map +1 -1
- package/dest/world-state-db/merkle_tree_db.d.ts +42 -32
- package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
- package/dest/world-state-db/merkle_tree_db.js +1 -1
- package/dest/world-state-db/merkle_tree_operations_facade.d.ts +8 -37
- package/dest/world-state-db/merkle_tree_operations_facade.d.ts.map +1 -1
- package/dest/world-state-db/merkle_tree_operations_facade.js +6 -45
- package/dest/world-state-db/merkle_tree_snapshot_operations_facade.d.ts +4 -13
- package/dest/world-state-db/merkle_tree_snapshot_operations_facade.d.ts.map +1 -1
- package/dest/world-state-db/merkle_tree_snapshot_operations_facade.js +2 -29
- package/dest/world-state-db/merkle_trees.d.ts +17 -19
- package/dest/world-state-db/merkle_trees.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.js +39 -36
- package/package.json +15 -12
- package/src/index.ts +1 -0
- package/src/native/merkle_trees_facade.ts +279 -0
- package/src/native/message.ts +97 -20
- package/src/native/native_world_state.ts +125 -346
- package/src/native/native_world_state_instance.ts +262 -0
- package/src/synchronizer/config.ts +8 -9
- package/src/synchronizer/factory.ts +20 -3
- package/src/synchronizer/server_world_state_synchronizer.ts +149 -178
- package/src/test/utils.ts +123 -0
- package/src/world-state-db/index.ts +1 -1
- package/src/world-state-db/merkle_tree_db.ts +55 -49
- package/src/world-state-db/merkle_tree_operations_facade.ts +10 -55
- package/src/world-state-db/merkle_tree_snapshot_operations_facade.ts +7 -46
- package/src/world-state-db/merkle_trees.ts +50 -45
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { type MerkleTreeId } from '@aztec/circuit-types';
|
|
2
|
-
import { type
|
|
1
|
+
import { type L2Block, type MerkleTreeId } from '@aztec/circuit-types';
|
|
2
|
+
import { type MerkleTreeReadOperations, type MerkleTreeWriteOperations } from '@aztec/circuit-types/interfaces';
|
|
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 WorldStateStatus } from '../native/message.js';
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
9
|
*
|
|
8
10
|
* @remarks Short explanation:
|
|
@@ -22,20 +24,6 @@ export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NULLIFIERS_PER_TX;
|
|
|
22
24
|
|
|
23
25
|
export const INITIAL_PUBLIC_DATA_TREE_SIZE = 2 * MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX;
|
|
24
26
|
|
|
25
|
-
/**
|
|
26
|
-
* Adds a last boolean flag in each function on the type.
|
|
27
|
-
*/
|
|
28
|
-
type WithIncludeUncommitted<F> = F extends (...args: [...infer Rest]) => infer Return
|
|
29
|
-
? (...args: [...Rest, boolean]) => Return
|
|
30
|
-
: F;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Defines the names of the setters on Merkle Trees.
|
|
34
|
-
*/
|
|
35
|
-
type MerkleTreeSetters = 'appendLeaves' | 'updateLeaf' | 'batchInsert';
|
|
36
|
-
|
|
37
|
-
type MerkleTreeAdmin = 'commit' | 'rollback' | 'handleL2BlockAndMessages';
|
|
38
|
-
|
|
39
27
|
export type TreeSnapshots = {
|
|
40
28
|
[MerkleTreeId.NULLIFIER_TREE]: IndexedTreeSnapshot;
|
|
41
29
|
[MerkleTreeId.NOTE_HASH_TREE]: TreeSnapshot<Fr>;
|
|
@@ -44,40 +32,58 @@ export type TreeSnapshots = {
|
|
|
44
32
|
[MerkleTreeId.ARCHIVE]: TreeSnapshot<Fr>;
|
|
45
33
|
};
|
|
46
34
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
35
|
+
export interface MerkleTreeAdminDatabase {
|
|
36
|
+
/**
|
|
37
|
+
* Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
|
|
38
|
+
* @param block - The L2 block to handle.
|
|
39
|
+
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
40
|
+
*/
|
|
41
|
+
handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatus>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Gets a handle that allows reading the latest committed state
|
|
45
|
+
*/
|
|
46
|
+
getCommitted(): MerkleTreeReadOperations;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Gets a handle that allows reading the state as it was at the given block number
|
|
50
|
+
* @param blockNumber - The block number to get the snapshot for
|
|
51
|
+
*/
|
|
52
|
+
getSnapshot(blockNumber: number): MerkleTreeReadOperations;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Forks the database at its current state.
|
|
56
|
+
* @param blockNumber - The block number to fork at. If not provided, the current block number is used.
|
|
57
|
+
*/
|
|
58
|
+
fork(blockNumber?: number): Promise<MerkleTreeWriteOperations>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Removes all historical snapshots up to but not including the given block number
|
|
62
|
+
* @param toBlockNumber The block number of the new oldest historical block
|
|
63
|
+
* @returns The new WorldStateStatus
|
|
64
|
+
*/
|
|
65
|
+
removeHistoricalBlocks(toBlockNumber: bigint): Promise<WorldStateStatus>;
|
|
59
66
|
|
|
60
|
-
/**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} & Pick<MerkleTreeAdminOperations, MerkleTreeSetters | MerkleTreeAdmin> & {
|
|
67
|
-
/**
|
|
68
|
-
* Returns a snapshot of the current state of the trees.
|
|
69
|
-
* @param block - The block number to take the snapshot at.
|
|
70
|
-
*/
|
|
71
|
-
getSnapshot(block: number): Promise<TreeSnapshots>;
|
|
67
|
+
/**
|
|
68
|
+
* Removes all pending blocks down to but not including the given block number
|
|
69
|
+
* @param toBlockNumber The block number of the new tip of the pending chain,
|
|
70
|
+
* @returns The new WorldStateStatus
|
|
71
|
+
*/
|
|
72
|
+
unwindBlocks(toBlockNumber: bigint): Promise<WorldStateStatus>;
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Advances the finalised block number to be the number provided
|
|
76
|
+
* @param toBlockNumber The block number that is now the tip of the finalised chain
|
|
77
|
+
* @returns The new WorldStateStatus
|
|
78
|
+
*/
|
|
79
|
+
setFinalised(toBlockNumber: bigint): Promise<WorldStateStatus>;
|
|
77
80
|
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Gets the current status of the database.
|
|
83
|
+
* @returns The current WorldStateStatus.
|
|
84
|
+
*/
|
|
85
|
+
getStatus(): Promise<WorldStateStatus>;
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
/** Stops the database */
|
|
88
|
+
close(): Promise<void>;
|
|
89
|
+
}
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import { type BatchInsertionResult, type
|
|
1
|
+
import { type BatchInsertionResult, type MerkleTreeId, type SiblingPath } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
|
-
type HandleL2BlockAndMessagesResult,
|
|
4
3
|
type IndexedTreeId,
|
|
5
|
-
type MerkleTreeAdminOperations,
|
|
6
4
|
type MerkleTreeLeafType,
|
|
7
|
-
type
|
|
5
|
+
type MerkleTreeWriteOperations,
|
|
8
6
|
type TreeInfo,
|
|
9
7
|
} from '@aztec/circuit-types/interfaces';
|
|
10
|
-
import { type
|
|
8
|
+
import { type Header, type StateReference } from '@aztec/circuits.js';
|
|
11
9
|
import { type IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
|
|
12
10
|
|
|
13
|
-
import { type
|
|
11
|
+
import { type MerkleTrees } from './merkle_trees.js';
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* Wraps a MerkleTreeDbOperations to call all functions with a preset includeUncommitted flag.
|
|
17
15
|
*/
|
|
18
|
-
export class
|
|
19
|
-
constructor(protected trees:
|
|
16
|
+
export class MerkleTreeReadOperationsFacade implements MerkleTreeWriteOperations {
|
|
17
|
+
constructor(protected trees: MerkleTrees, protected includeUncommitted: boolean) {}
|
|
20
18
|
|
|
21
19
|
/**
|
|
22
20
|
* Returns the tree info for the specified tree id.
|
|
@@ -41,7 +39,7 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations {
|
|
|
41
39
|
* @returns The initial header.
|
|
42
40
|
*/
|
|
43
41
|
getInitialHeader(): Header {
|
|
44
|
-
return this.trees.getInitialHeader(
|
|
42
|
+
return this.trees.getInitialHeader();
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
/**
|
|
@@ -91,17 +89,6 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations {
|
|
|
91
89
|
return this.trees.getPreviousValueIndex(treeId, value, this.includeUncommitted);
|
|
92
90
|
}
|
|
93
91
|
|
|
94
|
-
/**
|
|
95
|
-
* Updates a leaf in a tree at a given index.
|
|
96
|
-
* @param treeId - The ID of the tree.
|
|
97
|
-
* @param leaf - The new leaf value.
|
|
98
|
-
* @param index - The index to insert into.
|
|
99
|
-
* @returns Empty promise.
|
|
100
|
-
*/
|
|
101
|
-
updateLeaf<ID extends IndexedTreeId>(treeId: ID, leaf: NullifierLeafPreimage, index: bigint): Promise<void> {
|
|
102
|
-
return this.trees.updateLeaf(treeId, leaf, index);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
92
|
/**
|
|
106
93
|
* Gets the leaf data at a given index and tree.
|
|
107
94
|
* @param treeId - The ID of the tree get the leaf from.
|
|
@@ -162,7 +149,7 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations {
|
|
|
162
149
|
* @param header - The header to insert into the archive.
|
|
163
150
|
*/
|
|
164
151
|
public updateArchive(header: Header): Promise<void> {
|
|
165
|
-
return this.trees.updateArchive(header
|
|
152
|
+
return this.trees.updateArchive(header);
|
|
166
153
|
}
|
|
167
154
|
|
|
168
155
|
/**
|
|
@@ -179,40 +166,8 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations {
|
|
|
179
166
|
): Promise<BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>> {
|
|
180
167
|
return this.trees.batchInsert(treeId, leaves, subtreeHeight);
|
|
181
168
|
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export class MerkleTreeAdminOperationsFacade extends MerkleTreeOperationsFacade implements MerkleTreeAdminOperations {
|
|
185
|
-
constructor(protected override trees: MerkleTreeAdminDb, includeUncommitted: boolean) {
|
|
186
|
-
super(trees, includeUncommitted);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
|
|
191
|
-
* @param block - The L2 block to handle.
|
|
192
|
-
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
193
|
-
* @returns Whether the block handled was produced by this same node.
|
|
194
|
-
*/
|
|
195
|
-
public handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<HandleL2BlockAndMessagesResult> {
|
|
196
|
-
return this.trees.handleL2BlockAndMessages(block, l1ToL2Messages);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Commits all pending updates.
|
|
201
|
-
* @returns Empty promise.
|
|
202
|
-
*/
|
|
203
|
-
public async commit(): Promise<void> {
|
|
204
|
-
return await this.trees.commit();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Rolls back all pending updates.
|
|
209
|
-
* @returns Empty promise.
|
|
210
|
-
*/
|
|
211
|
-
public async rollback(): Promise<void> {
|
|
212
|
-
return await this.trees.rollback();
|
|
213
|
-
}
|
|
214
169
|
|
|
215
|
-
|
|
216
|
-
return
|
|
170
|
+
close(): Promise<void> {
|
|
171
|
+
return Promise.resolve();
|
|
217
172
|
}
|
|
218
173
|
}
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
import { MerkleTreeId, type SiblingPath } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
|
-
type BatchInsertionResult,
|
|
4
|
-
type HandleL2BlockAndMessagesResult,
|
|
5
3
|
type IndexedTreeId,
|
|
6
4
|
type MerkleTreeLeafType,
|
|
7
|
-
type
|
|
5
|
+
type MerkleTreeReadOperations,
|
|
8
6
|
type TreeInfo,
|
|
9
7
|
} from '@aztec/circuit-types/interfaces';
|
|
10
8
|
import { AppendOnlyTreeSnapshot, Fr, type Header, PartialStateReference, StateReference } from '@aztec/circuits.js';
|
|
11
9
|
import { type IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
|
|
12
10
|
import { type IndexedTreeSnapshot } from '@aztec/merkle-tree';
|
|
13
11
|
|
|
14
|
-
import { type
|
|
12
|
+
import { type TreeSnapshots } from './merkle_tree_db.js';
|
|
13
|
+
import { type MerkleTrees } from './merkle_trees.js';
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Merkle tree operations on readonly tree snapshots.
|
|
18
17
|
*/
|
|
19
|
-
export class MerkleTreeSnapshotOperationsFacade implements
|
|
20
|
-
#treesDb:
|
|
18
|
+
export class MerkleTreeSnapshotOperationsFacade implements MerkleTreeReadOperations {
|
|
19
|
+
#treesDb: MerkleTrees;
|
|
21
20
|
#blockNumber: number;
|
|
22
21
|
#treeSnapshots: TreeSnapshots = {} as any;
|
|
23
22
|
|
|
24
|
-
constructor(trees:
|
|
23
|
+
constructor(trees: MerkleTrees, blockNumber: number) {
|
|
25
24
|
this.#treesDb = trees;
|
|
26
25
|
this.#blockNumber = blockNumber;
|
|
27
26
|
}
|
|
@@ -31,7 +30,7 @@ export class MerkleTreeSnapshotOperationsFacade implements MerkleTreeOperations
|
|
|
31
30
|
return this.#treeSnapshots[treeId];
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
this.#treeSnapshots = await this.#treesDb.
|
|
33
|
+
this.#treeSnapshots = await this.#treesDb.getTreeSnapshots(this.#blockNumber);
|
|
35
34
|
return this.#treeSnapshots[treeId]!;
|
|
36
35
|
}
|
|
37
36
|
|
|
@@ -133,44 +132,6 @@ export class MerkleTreeSnapshotOperationsFacade implements MerkleTreeOperations
|
|
|
133
132
|
);
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
appendLeaves(): Promise<void> {
|
|
137
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
batchInsert<TreeHeight extends number, SubtreeSiblingPathHeight extends number>(): Promise<
|
|
141
|
-
BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>
|
|
142
|
-
> {
|
|
143
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
updateArchive(): Promise<void> {
|
|
147
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
commit(): Promise<void> {
|
|
151
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
handleL2BlockAndMessages(): Promise<HandleL2BlockAndMessagesResult> {
|
|
155
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
rollback(): Promise<void> {
|
|
159
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
delete(): Promise<void> {
|
|
163
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
updateHistoricArchive(): Promise<void> {
|
|
167
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
updateLeaf(): Promise<void> {
|
|
171
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
135
|
getInitialHeader(): Header {
|
|
175
136
|
throw new Error('Getting initial header not supported on snapshot.');
|
|
176
137
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type L2Block, MerkleTreeId, PublicDataWrite, type SiblingPath, TxEffect } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
3
|
type BatchInsertionResult,
|
|
4
|
-
type HandleL2BlockAndMessagesResult,
|
|
5
4
|
type IndexedTreeId,
|
|
6
|
-
type MerkleTreeAdminOperations,
|
|
7
5
|
type MerkleTreeLeafType,
|
|
6
|
+
type MerkleTreeReadOperations,
|
|
7
|
+
type MerkleTreeWriteOperations,
|
|
8
8
|
type TreeInfo,
|
|
9
9
|
} from '@aztec/circuit-types/interfaces';
|
|
10
10
|
import {
|
|
@@ -42,7 +42,6 @@ import {
|
|
|
42
42
|
Poseidon,
|
|
43
43
|
StandardIndexedTree,
|
|
44
44
|
StandardTree,
|
|
45
|
-
type UpdateOnlyTree,
|
|
46
45
|
getTreeMeta,
|
|
47
46
|
loadTree,
|
|
48
47
|
newTree,
|
|
@@ -51,14 +50,16 @@ import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
|
51
50
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
52
51
|
import { type Hasher } from '@aztec/types/interfaces';
|
|
53
52
|
|
|
53
|
+
import { type WorldStateStatus } from '../native/message.js';
|
|
54
54
|
import {
|
|
55
55
|
INITIAL_NULLIFIER_TREE_SIZE,
|
|
56
56
|
INITIAL_PUBLIC_DATA_TREE_SIZE,
|
|
57
|
-
type
|
|
57
|
+
type MerkleTreeAdminDatabase,
|
|
58
58
|
type TreeSnapshots,
|
|
59
59
|
} from './merkle_tree_db.js';
|
|
60
60
|
import { type MerkleTreeMap } from './merkle_tree_map.js';
|
|
61
|
-
import {
|
|
61
|
+
import { MerkleTreeReadOperationsFacade } from './merkle_tree_operations_facade.js';
|
|
62
|
+
import { MerkleTreeSnapshotOperationsFacade } from './merkle_tree_snapshot_operations_facade.js';
|
|
62
63
|
import { WorldStateMetrics } from './metrics.js';
|
|
63
64
|
|
|
64
65
|
/**
|
|
@@ -98,7 +99,7 @@ class PublicDataTree extends StandardIndexedTree {
|
|
|
98
99
|
/**
|
|
99
100
|
* A convenience class for managing multiple merkle trees.
|
|
100
101
|
*/
|
|
101
|
-
export class MerkleTrees implements
|
|
102
|
+
export class MerkleTrees implements MerkleTreeAdminDatabase {
|
|
102
103
|
// gets initialized in #init
|
|
103
104
|
private trees: MerkleTreeMap = null as any;
|
|
104
105
|
private jobQueue = new SerialQueue();
|
|
@@ -189,35 +190,54 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
189
190
|
// and persist the initial header state reference so we can later load it when requested.
|
|
190
191
|
const initialState = await this.getStateReference(true);
|
|
191
192
|
await this.#saveInitialStateReference(initialState);
|
|
192
|
-
await this.#updateArchive(this.getInitialHeader()
|
|
193
|
+
await this.#updateArchive(this.getInitialHeader());
|
|
193
194
|
|
|
194
195
|
// And commit anything we did to initialize this set of trees
|
|
195
196
|
await this.#commit();
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
public
|
|
200
|
+
public removeHistoricalBlocks(_toBlockNumber: bigint): Promise<WorldStateStatus> {
|
|
201
|
+
throw new Error('Method not implemented.');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public unwindBlocks(_toBlockNumber: bigint): Promise<WorldStateStatus> {
|
|
205
|
+
throw new Error('Method not implemented.');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
public setFinalised(_toBlockNumber: bigint): Promise<WorldStateStatus> {
|
|
209
|
+
throw new Error('Method not implemented.');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public getStatus(): Promise<WorldStateStatus> {
|
|
213
|
+
throw new Error('Method not implemented.');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
public async fork(blockNumber?: number): Promise<MerkleTreeWriteOperations> {
|
|
217
|
+
if (blockNumber) {
|
|
218
|
+
throw new Error('Block number forking is not supported in js world state');
|
|
219
|
+
}
|
|
200
220
|
const [ms, db] = await elapsed(async () => {
|
|
201
221
|
const forked = await this.store.fork();
|
|
202
222
|
return MerkleTrees.new(forked, this.telemetryClient, this.log);
|
|
203
223
|
});
|
|
204
224
|
|
|
205
225
|
this.metrics.recordForkDuration(ms);
|
|
206
|
-
return db;
|
|
226
|
+
return new MerkleTreeReadOperationsFacade(db, true);
|
|
207
227
|
}
|
|
208
228
|
|
|
209
229
|
// REFACTOR: We're hiding the `commit` operations in the tree behind a type check only, but
|
|
210
230
|
// we should make sure it's not accidentally called elsewhere by splitting this class into one
|
|
211
231
|
// that can work on a read-only store and one that actually writes to the store. This implies
|
|
212
232
|
// having read-only versions of the kv-stores, all kv-containers, and all trees.
|
|
213
|
-
public async ephemeralFork(): Promise<
|
|
233
|
+
public async ephemeralFork(): Promise<MerkleTreeWriteOperations> {
|
|
214
234
|
const forked = new MerkleTrees(
|
|
215
235
|
this.store,
|
|
216
236
|
this.telemetryClient,
|
|
217
237
|
createDebugLogger('aztec:merkle_trees:ephemeral_fork'),
|
|
218
238
|
);
|
|
219
239
|
await forked.#init(true);
|
|
220
|
-
return forked;
|
|
240
|
+
return new MerkleTreeReadOperationsFacade(forked, true);
|
|
221
241
|
}
|
|
222
242
|
|
|
223
243
|
public async delete() {
|
|
@@ -231,7 +251,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
231
251
|
/**
|
|
232
252
|
* Stops the job queue (waits for all jobs to finish).
|
|
233
253
|
*/
|
|
234
|
-
public async
|
|
254
|
+
public async close() {
|
|
235
255
|
await this.jobQueue.end();
|
|
236
256
|
}
|
|
237
257
|
|
|
@@ -239,16 +259,20 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
239
259
|
* Gets a view of this db that returns uncommitted data.
|
|
240
260
|
* @returns - A facade for this instance.
|
|
241
261
|
*/
|
|
242
|
-
public
|
|
243
|
-
return new
|
|
262
|
+
public getLatest(): Promise<MerkleTreeWriteOperations> {
|
|
263
|
+
return Promise.resolve(new MerkleTreeReadOperationsFacade(this, true));
|
|
244
264
|
}
|
|
245
265
|
|
|
246
266
|
/**
|
|
247
267
|
* Gets a view of this db that returns committed data only.
|
|
248
268
|
* @returns - A facade for this instance.
|
|
249
269
|
*/
|
|
250
|
-
public
|
|
251
|
-
return new
|
|
270
|
+
public getCommitted(): MerkleTreeReadOperations {
|
|
271
|
+
return new MerkleTreeReadOperationsFacade(this, false);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
public getSnapshot(blockNumber: number): MerkleTreeReadOperations {
|
|
275
|
+
return new MerkleTreeSnapshotOperationsFacade(this, blockNumber);
|
|
252
276
|
}
|
|
253
277
|
|
|
254
278
|
/**
|
|
@@ -256,8 +280,8 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
256
280
|
* @param header - The header whose hash to insert into the archive.
|
|
257
281
|
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
258
282
|
*/
|
|
259
|
-
public async updateArchive(header: Header
|
|
260
|
-
await this.synchronize(() => this.#updateArchive(header
|
|
283
|
+
public async updateArchive(header: Header) {
|
|
284
|
+
await this.synchronize(() => this.#updateArchive(header));
|
|
261
285
|
}
|
|
262
286
|
|
|
263
287
|
/**
|
|
@@ -436,24 +460,13 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
436
460
|
});
|
|
437
461
|
}
|
|
438
462
|
|
|
439
|
-
/**
|
|
440
|
-
* Updates a leaf in a tree at a given index.
|
|
441
|
-
* @param treeId - The ID of the tree.
|
|
442
|
-
* @param leaf - The new leaf value.
|
|
443
|
-
* @param index - The index to insert into.
|
|
444
|
-
* @returns Empty promise.
|
|
445
|
-
*/
|
|
446
|
-
public async updateLeaf(treeId: IndexedTreeId, leaf: Buffer, index: bigint): Promise<void> {
|
|
447
|
-
return await this.synchronize(() => this.#updateLeaf(treeId, leaf, index));
|
|
448
|
-
}
|
|
449
|
-
|
|
450
463
|
/**
|
|
451
464
|
* Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
|
|
452
465
|
* @param block - The L2 block to handle.
|
|
453
466
|
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
454
467
|
* @returns Whether the block handled was produced by this same node.
|
|
455
468
|
*/
|
|
456
|
-
public async handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<
|
|
469
|
+
public async handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatus> {
|
|
457
470
|
return await this.synchronize(() => this.#handleL2BlockAndMessages(block, l1ToL2Messages));
|
|
458
471
|
}
|
|
459
472
|
|
|
@@ -501,8 +514,8 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
501
514
|
return StateReference.fromBuffer(serialized);
|
|
502
515
|
}
|
|
503
516
|
|
|
504
|
-
async #updateArchive(header: Header
|
|
505
|
-
const state = await this.getStateReference(
|
|
517
|
+
async #updateArchive(header: Header) {
|
|
518
|
+
const state = await this.getStateReference(true);
|
|
506
519
|
|
|
507
520
|
// This method should be called only when the block builder already updated the state so we sanity check that it's
|
|
508
521
|
// the case here.
|
|
@@ -554,14 +567,6 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
554
567
|
return await tree.appendLeaves(leaves as any[]);
|
|
555
568
|
}
|
|
556
569
|
|
|
557
|
-
async #updateLeaf(treeId: IndexedTreeId, leaf: MerkleTreeLeafType<typeof treeId>, index: bigint): Promise<void> {
|
|
558
|
-
const tree = this.trees[treeId];
|
|
559
|
-
if (!('updateLeaf' in tree)) {
|
|
560
|
-
throw new Error('Tree does not support `updateLeaf` method');
|
|
561
|
-
}
|
|
562
|
-
return await (tree as UpdateOnlyTree<typeof leaf>).updateLeaf(leaf, index);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
570
|
/**
|
|
566
571
|
* Commits all pending updates.
|
|
567
572
|
* @returns Empty promise.
|
|
@@ -582,7 +587,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
582
587
|
}
|
|
583
588
|
}
|
|
584
589
|
|
|
585
|
-
public async
|
|
590
|
+
public async getTreeSnapshots(blockNumber: number): Promise<TreeSnapshots> {
|
|
586
591
|
const snapshots = await Promise.all([
|
|
587
592
|
this.trees[MerkleTreeId.NULLIFIER_TREE].getSnapshot(blockNumber),
|
|
588
593
|
this.trees[MerkleTreeId.NOTE_HASH_TREE].getSnapshot(blockNumber),
|
|
@@ -611,7 +616,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
611
616
|
* @param l2Block - The L2 block to handle.
|
|
612
617
|
* @param l1ToL2Messages - The L1 to L2 messages for the block.
|
|
613
618
|
*/
|
|
614
|
-
async #handleL2BlockAndMessages(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<
|
|
619
|
+
async #handleL2BlockAndMessages(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatus> {
|
|
615
620
|
const timer = new Timer();
|
|
616
621
|
|
|
617
622
|
const treeRootWithIdPairs = [
|
|
@@ -680,7 +685,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
680
685
|
}
|
|
681
686
|
|
|
682
687
|
// The last thing remaining is to update the archive
|
|
683
|
-
await this.#updateArchive(l2Block.header
|
|
688
|
+
await this.#updateArchive(l2Block.header);
|
|
684
689
|
|
|
685
690
|
await this.#commit();
|
|
686
691
|
}
|
|
@@ -703,8 +708,8 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
703
708
|
await this.#snapshot(l2Block.number);
|
|
704
709
|
|
|
705
710
|
this.metrics.recordDbSize(this.store.estimateSize().bytes);
|
|
706
|
-
this.metrics.recordSyncDuration(
|
|
707
|
-
return {
|
|
711
|
+
this.metrics.recordSyncDuration('commit', timer);
|
|
712
|
+
return { unfinalisedBlockNumber: 0n, finalisedBlockNumber: 0n, oldestHistoricalBlock: 0n } as WorldStateStatus;
|
|
708
713
|
}
|
|
709
714
|
|
|
710
715
|
#isDbPopulated(): boolean {
|