@aztec/world-state 0.16.4 → 0.16.6
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/merkle-tree/merkle_tree_operations_facade.d.ts +4 -5
- package/dest/merkle-tree/merkle_tree_operations_facade.d.ts.map +1 -1
- package/dest/merkle-tree/merkle_tree_operations_facade.js +6 -7
- package/dest/merkle-tree/merkle_tree_snapshot_operations_facade.d.ts +2 -2
- package/dest/merkle-tree/merkle_tree_snapshot_operations_facade.d.ts.map +1 -1
- package/dest/merkle-tree/merkle_tree_snapshot_operations_facade.js +5 -5
- package/dest/world-state-db/merkle_tree_db.d.ts +4 -4
- package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.d.ts +2 -2
- package/dest/world-state-db/merkle_trees.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.js +13 -13
- package/package.json +5 -5
- package/src/index.ts +0 -3
- package/src/merkle-tree/merkle_tree_operations_facade.ts +0 -190
- package/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts +0 -143
- package/src/synchronizer/config.ts +0 -27
- package/src/synchronizer/index.ts +0 -2
- package/src/synchronizer/server_world_state_synchronizer.ts +0 -248
- package/src/synchronizer/world_state_synchronizer.ts +0 -73
- package/src/world-state-db/index.ts +0 -2
- package/src/world-state-db/merkle_tree_db.ts +0 -252
- package/src/world-state-db/merkle_trees.ts +0 -619
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Fr } from '@aztec/circuits.js';
|
|
2
|
-
import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
|
|
3
|
-
import { BatchInsertionResult, IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree';
|
|
4
|
-
import { MerkleTreeId, SiblingPath } from '@aztec/types';
|
|
5
|
-
|
|
6
|
-
import { CurrentTreeRoots, HandleL2BlockResult, MerkleTreeDb, MerkleTreeOperations, TreeInfo } from '../index.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Merkle tree operations on readonly tree snapshots.
|
|
10
|
-
*/
|
|
11
|
-
export class MerkleTreeSnapshotOperationsFacade implements MerkleTreeOperations {
|
|
12
|
-
#treesDb: MerkleTreeDb;
|
|
13
|
-
#blockNumber: number;
|
|
14
|
-
#treeSnapshots: ReadonlyArray<TreeSnapshot | IndexedTreeSnapshot> = [];
|
|
15
|
-
|
|
16
|
-
constructor(trees: MerkleTreeDb, blockNumber: number) {
|
|
17
|
-
this.#treesDb = trees;
|
|
18
|
-
this.#blockNumber = blockNumber;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async #getTreeSnapshot(merkleTreeId: number): Promise<TreeSnapshot | IndexedTreeSnapshot> {
|
|
22
|
-
if (this.#treeSnapshots[merkleTreeId]) {
|
|
23
|
-
return this.#treeSnapshots[merkleTreeId];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
this.#treeSnapshots = await this.#treesDb.getSnapshot(this.#blockNumber);
|
|
27
|
-
return this.#treeSnapshots[merkleTreeId]!;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined> {
|
|
31
|
-
const tree = await this.#getTreeSnapshot(treeId);
|
|
32
|
-
return tree.findLeafIndex(value);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
getLatestGlobalVariablesHash(): Promise<Fr> {
|
|
36
|
-
return Promise.reject(new Error('not implemented'));
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async getLeafPreimage(
|
|
40
|
-
treeId: MerkleTreeId.NULLIFIER_TREE,
|
|
41
|
-
index: bigint,
|
|
42
|
-
): Promise<IndexedTreeLeafPreimage | undefined> {
|
|
43
|
-
const snapshot = (await this.#getTreeSnapshot(treeId)) as IndexedTreeSnapshot;
|
|
44
|
-
return snapshot.getLatestLeafPreimageCopy(BigInt(index));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined> {
|
|
48
|
-
const snapshot = await this.#getTreeSnapshot(treeId);
|
|
49
|
-
return snapshot.getLeafValue(BigInt(index));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
getPreviousValueIndex(
|
|
53
|
-
_treeId: MerkleTreeId.NULLIFIER_TREE,
|
|
54
|
-
_value: bigint,
|
|
55
|
-
): Promise<
|
|
56
|
-
| {
|
|
57
|
-
/**
|
|
58
|
-
* The index of the found leaf.
|
|
59
|
-
*/
|
|
60
|
-
index: bigint;
|
|
61
|
-
/**
|
|
62
|
-
* A flag indicating if the corresponding leaf's value is equal to `newValue`.
|
|
63
|
-
*/
|
|
64
|
-
alreadyPresent: boolean;
|
|
65
|
-
}
|
|
66
|
-
| undefined
|
|
67
|
-
> {
|
|
68
|
-
return Promise.reject(new Error('not implemented'));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>> {
|
|
72
|
-
const snapshot = await this.#getTreeSnapshot(treeId);
|
|
73
|
-
return snapshot.getSiblingPath(index);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo> {
|
|
77
|
-
const snapshot = await this.#getTreeSnapshot(treeId);
|
|
78
|
-
return {
|
|
79
|
-
depth: snapshot.getDepth(),
|
|
80
|
-
root: snapshot.getRoot(),
|
|
81
|
-
size: snapshot.getNumLeaves(),
|
|
82
|
-
treeId,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async getTreeRoots(): Promise<CurrentTreeRoots> {
|
|
87
|
-
const snapshots = await Promise.all([
|
|
88
|
-
this.#getTreeSnapshot(MerkleTreeId.CONTRACT_TREE),
|
|
89
|
-
this.#getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE),
|
|
90
|
-
this.#getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE),
|
|
91
|
-
this.#getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE),
|
|
92
|
-
this.#getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE),
|
|
93
|
-
this.#getTreeSnapshot(MerkleTreeId.BLOCKS_TREE),
|
|
94
|
-
]);
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
blocksTreeRoot: snapshots[MerkleTreeId.BLOCKS_TREE].getRoot(),
|
|
98
|
-
contractDataTreeRoot: snapshots[MerkleTreeId.CONTRACT_TREE].getRoot(),
|
|
99
|
-
l1Tol2MessagesTreeRoot: snapshots[MerkleTreeId.L1_TO_L2_MESSAGES_TREE].getRoot(),
|
|
100
|
-
noteHashTreeRoot: snapshots[MerkleTreeId.NOTE_HASH_TREE].getRoot(),
|
|
101
|
-
nullifierTreeRoot: snapshots[MerkleTreeId.NULLIFIER_TREE].getRoot(),
|
|
102
|
-
publicDataTreeRoot: snapshots[MerkleTreeId.PUBLIC_DATA_TREE].getRoot(),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
appendLeaves(): Promise<void> {
|
|
107
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
batchInsert<TreeHeight extends number, SubtreeSiblingPathHeight extends number>(): Promise<
|
|
111
|
-
BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>
|
|
112
|
-
> {
|
|
113
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
updateBlocksTree(): Promise<void> {
|
|
117
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
commit(): Promise<void> {
|
|
121
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
handleL2Block(): Promise<HandleL2BlockResult> {
|
|
125
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
rollback(): Promise<void> {
|
|
129
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
updateHistoricBlocksTree(): Promise<void> {
|
|
133
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
updateLatestGlobalVariablesHash(): Promise<void> {
|
|
137
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
updateLeaf(): Promise<void> {
|
|
141
|
-
return Promise.reject(new Error('Tree snapshot operations are read-only'));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* World State synchronizer configuration values.
|
|
3
|
-
*/
|
|
4
|
-
export interface WorldStateConfig {
|
|
5
|
-
/**
|
|
6
|
-
* The frequency in which to check.
|
|
7
|
-
*/
|
|
8
|
-
worldStateBlockCheckIntervalMS: number;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Size of queue of L2 blocks to store.
|
|
12
|
-
*/
|
|
13
|
-
l2QueueSize: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Returns the configuration values for the world state synchronizer.
|
|
18
|
-
* @returns The configuration values for the world state synchronizer.
|
|
19
|
-
*/
|
|
20
|
-
export function getConfigEnvVars(): WorldStateConfig {
|
|
21
|
-
const { WS_BLOCK_CHECK_INTERVAL_MS, WS_L2_BLOCK_QUEUE_SIZE } = process.env;
|
|
22
|
-
const envVars: WorldStateConfig = {
|
|
23
|
-
worldStateBlockCheckIntervalMS: WS_BLOCK_CHECK_INTERVAL_MS ? +WS_BLOCK_CHECK_INTERVAL_MS : 100,
|
|
24
|
-
l2QueueSize: WS_L2_BLOCK_QUEUE_SIZE ? +WS_L2_BLOCK_QUEUE_SIZE : 1000,
|
|
25
|
-
};
|
|
26
|
-
return envVars;
|
|
27
|
-
}
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
2
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
-
import { elapsed } from '@aztec/foundation/timer';
|
|
4
|
-
import { L2Block, L2BlockDownloader, L2BlockSource } from '@aztec/types';
|
|
5
|
-
import { L2BlockHandledStats } from '@aztec/types/stats';
|
|
6
|
-
|
|
7
|
-
import { LevelUp } from 'levelup';
|
|
8
|
-
|
|
9
|
-
import { HandleL2BlockResult, MerkleTreeOperations, MerkleTrees } from '../index.js';
|
|
10
|
-
import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js';
|
|
11
|
-
import { MerkleTreeSnapshotOperationsFacade } from '../merkle-tree/merkle_tree_snapshot_operations_facade.js';
|
|
12
|
-
import { WorldStateConfig } from './config.js';
|
|
13
|
-
import { WorldStateRunningState, WorldStateStatus, WorldStateSynchronizer } from './world_state_synchronizer.js';
|
|
14
|
-
|
|
15
|
-
const DB_KEY_BLOCK_NUMBER = 'latestBlockNumber';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Synchronizes the world state with the L2 blocks from a L2BlockSource.
|
|
19
|
-
* The synchronizer will download the L2 blocks from the L2BlockSource and insert the new commitments into the merkle
|
|
20
|
-
* tree.
|
|
21
|
-
*/
|
|
22
|
-
export class ServerWorldStateSynchronizer implements WorldStateSynchronizer {
|
|
23
|
-
private currentL2BlockNum = 0;
|
|
24
|
-
private latestBlockNumberAtStart = 0;
|
|
25
|
-
|
|
26
|
-
private l2BlockDownloader: L2BlockDownloader;
|
|
27
|
-
private syncPromise: Promise<void> = Promise.resolve();
|
|
28
|
-
private syncResolve?: () => void = undefined;
|
|
29
|
-
private jobQueue = new SerialQueue();
|
|
30
|
-
private stopping = false;
|
|
31
|
-
private runningPromise: Promise<void> = Promise.resolve();
|
|
32
|
-
private currentState: WorldStateRunningState = WorldStateRunningState.IDLE;
|
|
33
|
-
|
|
34
|
-
private constructor(
|
|
35
|
-
private db: LevelUp,
|
|
36
|
-
private merkleTreeDb: MerkleTrees,
|
|
37
|
-
private l2BlockSource: L2BlockSource,
|
|
38
|
-
config: WorldStateConfig,
|
|
39
|
-
private log = createDebugLogger('aztec:world_state'),
|
|
40
|
-
) {
|
|
41
|
-
this.l2BlockDownloader = new L2BlockDownloader(
|
|
42
|
-
l2BlockSource,
|
|
43
|
-
config.l2QueueSize,
|
|
44
|
-
config.worldStateBlockCheckIntervalMS,
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public getLatest(): MerkleTreeOperations {
|
|
49
|
-
return new MerkleTreeOperationsFacade(this.merkleTreeDb, true);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public getCommitted(): MerkleTreeOperations {
|
|
53
|
-
return new MerkleTreeOperationsFacade(this.merkleTreeDb, false);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
public getSnapshot(blockNumber: number): MerkleTreeOperations {
|
|
57
|
-
return new MerkleTreeSnapshotOperationsFacade(this.merkleTreeDb, blockNumber);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public static async new(
|
|
61
|
-
db: LevelUp,
|
|
62
|
-
merkleTreeDb: MerkleTrees,
|
|
63
|
-
l2BlockSource: L2BlockSource,
|
|
64
|
-
config: WorldStateConfig,
|
|
65
|
-
log = createDebugLogger('aztec:world_state'),
|
|
66
|
-
) {
|
|
67
|
-
const server = new ServerWorldStateSynchronizer(db, merkleTreeDb, l2BlockSource, config, log);
|
|
68
|
-
await server.#init();
|
|
69
|
-
return server;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async #init() {
|
|
73
|
-
await this.restoreCurrentL2BlockNumber();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
public async start() {
|
|
77
|
-
if (this.currentState === WorldStateRunningState.STOPPED) {
|
|
78
|
-
throw new Error('Synchronizer already stopped');
|
|
79
|
-
}
|
|
80
|
-
if (this.currentState !== WorldStateRunningState.IDLE) {
|
|
81
|
-
return this.syncPromise;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// get the current latest block number
|
|
85
|
-
this.latestBlockNumberAtStart = await this.l2BlockSource.getBlockNumber();
|
|
86
|
-
|
|
87
|
-
const blockToDownloadFrom = this.currentL2BlockNum + 1;
|
|
88
|
-
|
|
89
|
-
// if there are blocks to be retrieved, go to a synching state
|
|
90
|
-
if (blockToDownloadFrom <= this.latestBlockNumberAtStart) {
|
|
91
|
-
this.setCurrentState(WorldStateRunningState.SYNCHING);
|
|
92
|
-
this.syncPromise = new Promise(resolve => {
|
|
93
|
-
this.syncResolve = resolve;
|
|
94
|
-
});
|
|
95
|
-
this.log(`Starting sync from ${blockToDownloadFrom}, latest block ${this.latestBlockNumberAtStart}`);
|
|
96
|
-
} else {
|
|
97
|
-
// if no blocks to be retrieved, go straight to running
|
|
98
|
-
this.setCurrentState(WorldStateRunningState.RUNNING);
|
|
99
|
-
this.syncPromise = Promise.resolve();
|
|
100
|
-
this.log(`Next block ${blockToDownloadFrom} already beyond latest block at ${this.latestBlockNumberAtStart}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// start looking for further blocks
|
|
104
|
-
const blockProcess = async () => {
|
|
105
|
-
while (!this.stopping) {
|
|
106
|
-
await this.jobQueue.put(() => this.collectAndProcessBlocks());
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
this.jobQueue.start();
|
|
110
|
-
this.runningPromise = blockProcess();
|
|
111
|
-
this.l2BlockDownloader.start(blockToDownloadFrom);
|
|
112
|
-
this.log(`Started block downloader from block ${blockToDownloadFrom}`);
|
|
113
|
-
return this.syncPromise;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
public async stop() {
|
|
117
|
-
this.log('Stopping world state...');
|
|
118
|
-
this.stopping = true;
|
|
119
|
-
await this.l2BlockDownloader.stop();
|
|
120
|
-
await this.jobQueue.cancel();
|
|
121
|
-
await this.merkleTreeDb.stop();
|
|
122
|
-
await this.runningPromise;
|
|
123
|
-
await this.commitCurrentL2BlockNumber();
|
|
124
|
-
this.setCurrentState(WorldStateRunningState.STOPPED);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
public status(): Promise<WorldStateStatus> {
|
|
128
|
-
const status = {
|
|
129
|
-
syncedToL2Block: this.currentL2BlockNum,
|
|
130
|
-
state: this.currentState,
|
|
131
|
-
} as WorldStateStatus;
|
|
132
|
-
return Promise.resolve(status);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Forces an immediate sync
|
|
137
|
-
* @param minBlockNumber - The minimum block number that we must sync to
|
|
138
|
-
* @returns A promise that resolves with the block number the world state was synced to
|
|
139
|
-
*/
|
|
140
|
-
public async syncImmediate(minBlockNumber?: number): Promise<number> {
|
|
141
|
-
if (this.currentState !== WorldStateRunningState.RUNNING) {
|
|
142
|
-
throw new Error(`World State is not running, unable to perform sync`);
|
|
143
|
-
}
|
|
144
|
-
// If we have been given a block number to sync to and we have reached that number
|
|
145
|
-
// then return.
|
|
146
|
-
if (minBlockNumber !== undefined && minBlockNumber <= this.currentL2BlockNum) {
|
|
147
|
-
return this.currentL2BlockNum;
|
|
148
|
-
}
|
|
149
|
-
const blockToSyncTo = minBlockNumber === undefined ? 'latest' : `${minBlockNumber}`;
|
|
150
|
-
this.log(`World State at block ${this.currentL2BlockNum}, told to sync to block ${blockToSyncTo}...`);
|
|
151
|
-
// ensure any outstanding block updates are completed first.
|
|
152
|
-
await this.jobQueue.syncPoint();
|
|
153
|
-
while (true) {
|
|
154
|
-
// Check the block number again
|
|
155
|
-
if (minBlockNumber !== undefined && minBlockNumber <= this.currentL2BlockNum) {
|
|
156
|
-
return this.currentL2BlockNum;
|
|
157
|
-
}
|
|
158
|
-
// Poll for more blocks
|
|
159
|
-
const numBlocks = await this.l2BlockDownloader.pollImmediate();
|
|
160
|
-
this.log(`Block download immediate poll yielded ${numBlocks} blocks`);
|
|
161
|
-
if (numBlocks) {
|
|
162
|
-
// More blocks were received, process them and go round again
|
|
163
|
-
await this.jobQueue.put(() => this.collectAndProcessBlocks());
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
// No blocks are available, if we have been given a block number then we can't achieve it
|
|
167
|
-
if (minBlockNumber !== undefined) {
|
|
168
|
-
throw new Error(
|
|
169
|
-
`Unable to sync to block number ${minBlockNumber}, currently synced to block ${this.currentL2BlockNum}`,
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
return this.currentL2BlockNum;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Checks for the availability of new blocks and processes them.
|
|
178
|
-
*/
|
|
179
|
-
private async collectAndProcessBlocks() {
|
|
180
|
-
// This request for blocks will timeout after 1 second if no blocks are received
|
|
181
|
-
const blocks = await this.l2BlockDownloader.getBlocks(1);
|
|
182
|
-
await this.handleL2Blocks(blocks);
|
|
183
|
-
await this.commitCurrentL2BlockNumber();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Handles a list of L2 blocks (i.e. Inserts the new commitments into the merkle tree).
|
|
188
|
-
* @param l2Blocks - The L2 blocks to handle.
|
|
189
|
-
* @returns Whether the block handled was produced by this same node.
|
|
190
|
-
*/
|
|
191
|
-
private async handleL2Blocks(l2Blocks: L2Block[]) {
|
|
192
|
-
for (const l2Block of l2Blocks) {
|
|
193
|
-
const [duration, result] = await elapsed(() => this.handleL2Block(l2Block));
|
|
194
|
-
this.log(`Handled new L2 block`, {
|
|
195
|
-
eventName: 'l2-block-handled',
|
|
196
|
-
duration,
|
|
197
|
-
isBlockOurs: result.isBlockOurs,
|
|
198
|
-
...l2Block.getStats(),
|
|
199
|
-
} satisfies L2BlockHandledStats);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree).
|
|
205
|
-
* @param l2Block - The L2 block to handle.
|
|
206
|
-
*/
|
|
207
|
-
private async handleL2Block(l2Block: L2Block): Promise<HandleL2BlockResult> {
|
|
208
|
-
const result = await this.merkleTreeDb.handleL2Block(l2Block);
|
|
209
|
-
this.currentL2BlockNum = l2Block.number;
|
|
210
|
-
if (
|
|
211
|
-
this.currentState === WorldStateRunningState.SYNCHING &&
|
|
212
|
-
this.currentL2BlockNum >= this.latestBlockNumberAtStart
|
|
213
|
-
) {
|
|
214
|
-
this.setCurrentState(WorldStateRunningState.RUNNING);
|
|
215
|
-
if (this.syncResolve !== undefined) {
|
|
216
|
-
this.syncResolve();
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return result;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Method to set the value of the current state.
|
|
224
|
-
* @param newState - New state value.
|
|
225
|
-
*/
|
|
226
|
-
private setCurrentState(newState: WorldStateRunningState) {
|
|
227
|
-
this.currentState = newState;
|
|
228
|
-
this.log(`Moved to state ${WorldStateRunningState[this.currentState]}`);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
private async commitCurrentL2BlockNumber() {
|
|
232
|
-
const hex = this.currentL2BlockNum.toString(16);
|
|
233
|
-
const encoded = Buffer.from(hex.length % 2 === 1 ? '0' + hex : hex, 'hex');
|
|
234
|
-
|
|
235
|
-
await this.db.put(DB_KEY_BLOCK_NUMBER, encoded);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
private async restoreCurrentL2BlockNumber() {
|
|
239
|
-
try {
|
|
240
|
-
const encoded: Buffer = await this.db.get(DB_KEY_BLOCK_NUMBER);
|
|
241
|
-
this.currentL2BlockNum = parseInt(encoded.toString('hex'), 16);
|
|
242
|
-
this.log.debug(`Restored current L2 block number ${this.currentL2BlockNum} from db`);
|
|
243
|
-
} catch (err) {
|
|
244
|
-
this.log.debug('No current L2 block number found in db, starting from 0');
|
|
245
|
-
this.currentL2BlockNum = 0;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { MerkleTreeOperations } from '../index.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Defines the possible states of the world state synchronizer.
|
|
5
|
-
*/
|
|
6
|
-
export enum WorldStateRunningState {
|
|
7
|
-
IDLE,
|
|
8
|
-
SYNCHING,
|
|
9
|
-
RUNNING,
|
|
10
|
-
STOPPED,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Defines the status of the world state synchronizer.
|
|
15
|
-
*/
|
|
16
|
-
export interface WorldStateStatus {
|
|
17
|
-
/**
|
|
18
|
-
* The current state of the world state synchronizer.
|
|
19
|
-
*/
|
|
20
|
-
state: WorldStateRunningState;
|
|
21
|
-
/**
|
|
22
|
-
* The block number that the world state synchronizer is synced to.
|
|
23
|
-
*/
|
|
24
|
-
syncedToL2Block: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Defines the interface for a world state synchronizer.
|
|
29
|
-
*/
|
|
30
|
-
export interface WorldStateSynchronizer {
|
|
31
|
-
/**
|
|
32
|
-
* Starts the synchronizer.
|
|
33
|
-
* @returns A promise that resolves once the initial sync is completed.
|
|
34
|
-
*/
|
|
35
|
-
start(): void;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Returns the current status of the synchronizer.
|
|
39
|
-
* @returns The current status of the synchronizer.
|
|
40
|
-
*/
|
|
41
|
-
status(): Promise<WorldStateStatus>;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Stops the synchronizer.
|
|
45
|
-
*/
|
|
46
|
-
stop(): Promise<void>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Forces an immediate sync to an optionally provided minimum block number
|
|
50
|
-
* @param minBlockNumber - The minimum block number that we must sync to
|
|
51
|
-
* @returns A promise that resolves with the block number the world state was synced to
|
|
52
|
-
*/
|
|
53
|
-
syncImmediate(minBlockNumber?: number): Promise<number>;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Returns an instance of MerkleTreeOperations that will include uncommitted data.
|
|
57
|
-
* @returns An instance of MerkleTreeOperations that will include uncommitted data.
|
|
58
|
-
*/
|
|
59
|
-
getLatest(): MerkleTreeOperations;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Returns an instance of MerkleTreeOperations that will not include uncommitted data.
|
|
63
|
-
* @returns An instance of MerkleTreeOperations that will not include uncommitted data.
|
|
64
|
-
*/
|
|
65
|
-
getCommitted(): MerkleTreeOperations;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Returns a readonly instance of MerkleTreeOperations where the state is as it was at the given block number
|
|
69
|
-
* @param block - The block number to look at
|
|
70
|
-
* @returns An instance of MerkleTreeOperations
|
|
71
|
-
*/
|
|
72
|
-
getSnapshot(block: number): MerkleTreeOperations;
|
|
73
|
-
}
|