@aztec/world-state 0.1.0-alpha43 → 0.1.0-alpha44
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/.tsbuildinfo +1 -1
- package/dest/merkle-tree/merkle_tree_operations_facade.d.ts +14 -5
- package/dest/merkle-tree/merkle_tree_operations_facade.d.ts.map +1 -1
- package/dest/merkle-tree/merkle_tree_operations_facade.js +20 -6
- package/dest/synchroniser/server_world_state_synchroniser.d.ts +14 -5
- package/dest/synchroniser/server_world_state_synchroniser.d.ts.map +1 -1
- package/dest/synchroniser/server_world_state_synchroniser.js +54 -13
- package/dest/synchroniser/server_world_state_synchroniser.test.js +109 -2
- package/dest/synchroniser/world_state_synchroniser.d.ts +6 -5
- package/dest/synchroniser/world_state_synchroniser.d.ts.map +1 -1
- package/dest/synchroniser/world_state_synchroniser.js +1 -1
- package/dest/world-state-db/index.d.ts +14 -5
- package/dest/world-state-db/index.d.ts.map +1 -1
- package/dest/world-state-db/index.js +1 -1
- package/dest/world-state-db/merkle_trees.d.ts +20 -6
- package/dest/world-state-db/merkle_trees.d.ts.map +1 -1
- package/dest/world-state-db/merkle_trees.js +51 -16
- package/package.json +5 -5
- package/src/merkle-tree/merkle_tree_operations_facade.ts +23 -7
- package/src/synchroniser/server_world_state_synchroniser.test.ts +144 -3
- package/src/synchroniser/server_world_state_synchroniser.ts +60 -13
- package/src/synchroniser/world_state_synchroniser.ts +7 -7
- package/src/world-state-db/index.ts +17 -5
- package/src/world-state-db/merkle_trees.ts +60 -16
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
2
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { L2Block, L2BlockDownloader, L2BlockSource } from '@aztec/types';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { MerkleTreeOperations, MerkleTrees } from '../index.js';
|
|
6
6
|
import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js';
|
|
7
|
-
import {
|
|
7
|
+
import { WorldStateConfig } from './config.js';
|
|
8
8
|
import { WorldStateRunningState, WorldStateStatus, WorldStateSynchroniser } from './world_state_synchroniser.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -19,19 +19,17 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser {
|
|
|
19
19
|
private l2BlockDownloader: L2BlockDownloader;
|
|
20
20
|
private syncPromise: Promise<void> = Promise.resolve();
|
|
21
21
|
private syncResolve?: () => void = undefined;
|
|
22
|
+
private jobQueue = new SerialQueue();
|
|
22
23
|
private stopping = false;
|
|
23
24
|
private runningPromise: Promise<void> = Promise.resolve();
|
|
24
25
|
private currentState: WorldStateRunningState = WorldStateRunningState.IDLE;
|
|
25
26
|
|
|
26
|
-
/** The latest Global Variables hash for the HEAD of the chain. */
|
|
27
|
-
public latestGlobalVariablesHash: Fr = Fr.ZERO;
|
|
28
|
-
|
|
29
27
|
constructor(
|
|
30
|
-
private merkleTreeDb:
|
|
28
|
+
private merkleTreeDb: MerkleTrees,
|
|
31
29
|
private l2BlockSource: L2BlockSource,
|
|
30
|
+
config: WorldStateConfig,
|
|
32
31
|
private log = createDebugLogger('aztec:world_state'),
|
|
33
32
|
) {
|
|
34
|
-
const config = getConfigEnvVars();
|
|
35
33
|
this.l2BlockDownloader = new L2BlockDownloader(
|
|
36
34
|
l2BlockSource,
|
|
37
35
|
config.l2QueueSize,
|
|
@@ -57,7 +55,6 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser {
|
|
|
57
55
|
|
|
58
56
|
// get the current latest block number
|
|
59
57
|
this.latestBlockNumberAtStart = await this.l2BlockSource.getBlockHeight();
|
|
60
|
-
this.latestGlobalVariablesHash = await computeGlobalVariablesHash();
|
|
61
58
|
|
|
62
59
|
const blockToDownloadFrom = this.currentL2BlockNum + 1;
|
|
63
60
|
|
|
@@ -78,10 +75,10 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser {
|
|
|
78
75
|
// start looking for further blocks
|
|
79
76
|
const blockProcess = async () => {
|
|
80
77
|
while (!this.stopping) {
|
|
81
|
-
|
|
82
|
-
await this.handleL2Blocks(blocks);
|
|
78
|
+
await this.jobQueue.put(() => this.collectAndProcessBlocks());
|
|
83
79
|
}
|
|
84
80
|
};
|
|
81
|
+
this.jobQueue.start();
|
|
85
82
|
this.runningPromise = blockProcess();
|
|
86
83
|
this.l2BlockDownloader.start(blockToDownloadFrom);
|
|
87
84
|
this.log(`Started block downloader from block ${blockToDownloadFrom}`);
|
|
@@ -92,6 +89,8 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser {
|
|
|
92
89
|
this.log('Stopping world state...');
|
|
93
90
|
this.stopping = true;
|
|
94
91
|
await this.l2BlockDownloader.stop();
|
|
92
|
+
await this.jobQueue.cancel();
|
|
93
|
+
await this.merkleTreeDb.stop();
|
|
95
94
|
await this.runningPromise;
|
|
96
95
|
this.setCurrentState(WorldStateRunningState.STOPPED);
|
|
97
96
|
}
|
|
@@ -104,6 +103,56 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser {
|
|
|
104
103
|
return Promise.resolve(status);
|
|
105
104
|
}
|
|
106
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Forces an immediate sync
|
|
108
|
+
* @param blockHeight - The minimum block height that we must sync to
|
|
109
|
+
* @returns A promise that resolves once the sync has completed.
|
|
110
|
+
*/
|
|
111
|
+
public async syncImmediate(blockHeight?: number): Promise<void> {
|
|
112
|
+
if (this.currentState !== WorldStateRunningState.RUNNING) {
|
|
113
|
+
throw new Error(`World State is not running, unable to perform sync`);
|
|
114
|
+
}
|
|
115
|
+
// If we have been given a block height to sync to and we have reached that height
|
|
116
|
+
// then return.
|
|
117
|
+
if (blockHeight !== undefined && blockHeight <= this.currentL2BlockNum) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const blockToSyncTo = blockHeight === undefined ? 'latest' : `${blockHeight}`;
|
|
121
|
+
this.log(`World State at block ${this.currentL2BlockNum}, told to sync to block ${blockToSyncTo}...`);
|
|
122
|
+
// ensure any outstanding block updates are completed first.
|
|
123
|
+
await this.jobQueue.syncPoint();
|
|
124
|
+
while (true) {
|
|
125
|
+
// Check the block height again
|
|
126
|
+
if (blockHeight !== undefined && blockHeight <= this.currentL2BlockNum) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// Poll for more blocks
|
|
130
|
+
const numBlocks = await this.l2BlockDownloader.pollImmediate();
|
|
131
|
+
this.log(`Block download immediate poll yielded ${numBlocks} blocks`);
|
|
132
|
+
if (numBlocks) {
|
|
133
|
+
// More blocks were received, process them and go round again
|
|
134
|
+
await this.jobQueue.put(() => this.collectAndProcessBlocks());
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// No blocks are available, if we have been given a block height then we can't achieve it
|
|
138
|
+
if (blockHeight !== undefined) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Unable to sync to block height ${blockHeight}, currently synced to block ${this.currentL2BlockNum}`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Checks for the availability of new blocks and processes them.
|
|
149
|
+
*/
|
|
150
|
+
private async collectAndProcessBlocks() {
|
|
151
|
+
// This request for blocks will timeout after 1 second if no blocks are received
|
|
152
|
+
const blocks = await this.l2BlockDownloader.getL2Blocks(1);
|
|
153
|
+
await this.handleL2Blocks(blocks);
|
|
154
|
+
}
|
|
155
|
+
|
|
107
156
|
/**
|
|
108
157
|
* Handles a list of L2 blocks (i.e. Inserts the new commitments into the merkle tree).
|
|
109
158
|
* @param l2Blocks - The L2 blocks to handle.
|
|
@@ -121,8 +170,6 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser {
|
|
|
121
170
|
private async handleL2Block(l2Block: L2Block) {
|
|
122
171
|
await this.merkleTreeDb.handleL2Block(l2Block);
|
|
123
172
|
this.currentL2BlockNum = l2Block.number;
|
|
124
|
-
this.latestGlobalVariablesHash = await computeGlobalVariablesHash(l2Block.globalVariables);
|
|
125
|
-
this.log(`Synced global variables with hash ${this.latestGlobalVariablesHash.toString()}`);
|
|
126
173
|
if (
|
|
127
174
|
this.currentState === WorldStateRunningState.SYNCHING &&
|
|
128
175
|
this.currentL2BlockNum >= this.latestBlockNumberAtStart
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Fr } from '@aztec/circuits.js';
|
|
2
|
-
|
|
3
1
|
import { MerkleTreeOperations } from '../index.js';
|
|
4
2
|
|
|
5
3
|
/**
|
|
@@ -47,6 +45,13 @@ export interface WorldStateSynchroniser {
|
|
|
47
45
|
*/
|
|
48
46
|
stop(): Promise<void>;
|
|
49
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Forces an immediate sync to an optionally provided minimum block height
|
|
50
|
+
* @param blockHeight - The minimum block height that we must sync to
|
|
51
|
+
* @returns A promise that resolves once the sync has completed.
|
|
52
|
+
*/
|
|
53
|
+
syncImmediate(blockHeight?: number): Promise<void>;
|
|
54
|
+
|
|
50
55
|
/**
|
|
51
56
|
* Returns an instance of MerkleTreeOperations that will include uncommitted data.
|
|
52
57
|
* @returns An instance of MerkleTreeOperations that will include uncommitted data.
|
|
@@ -58,9 +63,4 @@ export interface WorldStateSynchroniser {
|
|
|
58
63
|
* @returns An instance of MerkleTreeOperations that will not include uncommitted data.
|
|
59
64
|
*/
|
|
60
65
|
getCommitted(): MerkleTreeOperations;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* The latest Global Variables hash for the HEAD of the chain.
|
|
64
|
-
*/
|
|
65
|
-
latestGlobalVariablesHash: Fr;
|
|
66
66
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js';
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
4
|
import { LeafData, LowLeafWitnessData } from '@aztec/merkle-tree';
|
|
4
5
|
import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types';
|
|
@@ -115,14 +116,14 @@ export interface MerkleTreeOperations {
|
|
|
115
116
|
/**
|
|
116
117
|
* Gets the current roots of the commitment trees.
|
|
117
118
|
*/
|
|
118
|
-
getTreeRoots(): CurrentTreeRoots
|
|
119
|
+
getTreeRoots(): Promise<CurrentTreeRoots>;
|
|
119
120
|
|
|
120
121
|
/**
|
|
121
122
|
* Gets sibling path for a leaf.
|
|
122
123
|
* @param treeId - The tree to be queried for a sibling path.
|
|
123
124
|
* @param index - The index of the leaf for which a sibling path should be returned.
|
|
124
125
|
*/
|
|
125
|
-
getSiblingPath(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<
|
|
126
|
+
getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>>;
|
|
126
127
|
|
|
127
128
|
/**
|
|
128
129
|
* Returns the previous index for a given value in an indexed tree.
|
|
@@ -175,9 +176,20 @@ export interface MerkleTreeOperations {
|
|
|
175
176
|
/**
|
|
176
177
|
* Inserts the new block hash into the new block hashes tree.
|
|
177
178
|
* This includes all of the current roots of all of the data trees and the current blocks global vars.
|
|
178
|
-
* @param
|
|
179
|
+
* @param globalVariablesHash - The global variables hash to insert into the block hash.
|
|
179
180
|
*/
|
|
180
|
-
updateHistoricBlocksTree(
|
|
181
|
+
updateHistoricBlocksTree(globalVariablesHash: Fr): Promise<void>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Updates the latest global variables hash
|
|
185
|
+
* @param globalVariablesHash - The latest global variables hash
|
|
186
|
+
*/
|
|
187
|
+
updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise<void>;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Gets the global variables hash from the previous block
|
|
191
|
+
*/
|
|
192
|
+
getLatestGlobalVariablesHash(): Promise<Fr>;
|
|
181
193
|
|
|
182
194
|
/**
|
|
183
195
|
* Batch insert multiple leaves into the tree.
|
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
PRIVATE_DATA_TREE_HEIGHT,
|
|
11
11
|
PUBLIC_DATA_TREE_HEIGHT,
|
|
12
12
|
} from '@aztec/circuits.js';
|
|
13
|
-
import {
|
|
13
|
+
import { computeBlockHash } from '@aztec/circuits.js/abis';
|
|
14
|
+
import { Committable } from '@aztec/foundation/committable';
|
|
14
15
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
15
16
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
16
17
|
import { IWasmModule } from '@aztec/foundation/wasm';
|
|
@@ -31,6 +32,7 @@ import { L2Block, MerkleTreeId, SiblingPath, merkleTreeIds } from '@aztec/types'
|
|
|
31
32
|
import { default as levelup } from 'levelup';
|
|
32
33
|
|
|
33
34
|
import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js';
|
|
35
|
+
import { computeGlobalVariablesHash } from '../utils.js';
|
|
34
36
|
import {
|
|
35
37
|
CurrentTreeRoots,
|
|
36
38
|
INITIAL_NULLIFIER_TREE_SIZE,
|
|
@@ -46,9 +48,12 @@ import {
|
|
|
46
48
|
*/
|
|
47
49
|
export class MerkleTrees implements MerkleTreeDb {
|
|
48
50
|
private trees: (AppendOnlyTree | UpdateOnlyTree)[] = [];
|
|
51
|
+
private latestGlobalVariablesHash: Committable<Fr>;
|
|
49
52
|
private jobQueue = new SerialQueue();
|
|
50
53
|
|
|
51
|
-
constructor(private db: levelup.LevelUp, private log = createDebugLogger('aztec:merkle_trees')) {
|
|
54
|
+
constructor(private db: levelup.LevelUp, private log = createDebugLogger('aztec:merkle_trees')) {
|
|
55
|
+
this.latestGlobalVariablesHash = new Committable(Fr.zero());
|
|
56
|
+
}
|
|
52
57
|
|
|
53
58
|
/**
|
|
54
59
|
* Initialises the collection of Merkle Trees.
|
|
@@ -105,8 +110,10 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
105
110
|
this.jobQueue.start();
|
|
106
111
|
|
|
107
112
|
// The first leaf in the blocks tree contains the empty roots of the other trees and empty global variables.
|
|
108
|
-
await
|
|
109
|
-
await
|
|
113
|
+
const initialGlobalVariablesHash = await computeGlobalVariablesHash(GlobalVariables.empty());
|
|
114
|
+
await this._updateLatestGlobalVariablesHash(initialGlobalVariablesHash);
|
|
115
|
+
await this._updateHistoricBlocksTree(initialGlobalVariablesHash, true);
|
|
116
|
+
await this._commit();
|
|
110
117
|
}
|
|
111
118
|
|
|
112
119
|
/**
|
|
@@ -147,12 +154,27 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
147
154
|
/**
|
|
148
155
|
* Inserts into the roots trees (CONTRACT_TREE_ROOTS_TREE, PRIVATE_DATA_TREE_ROOTS_TREE, L1_TO_L2_MESSAGES_TREE_ROOTS_TREE)
|
|
149
156
|
* the current roots of the corresponding trees (CONTRACT_TREE, PRIVATE_DATA_TREE, L1_TO_L2_MESSAGES_TREE).
|
|
150
|
-
* @param
|
|
157
|
+
* @param globalsHash - The current global variables hash.
|
|
158
|
+
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
159
|
+
*/
|
|
160
|
+
public async updateHistoricBlocksTree(globalsHash: Fr, includeUncommitted: boolean) {
|
|
161
|
+
await this.synchronise(() => this._updateHistoricBlocksTree(globalsHash, includeUncommitted));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Updates the latest global variables hash
|
|
166
|
+
* @param globalVariablesHash - The latest global variables hash
|
|
167
|
+
*/
|
|
168
|
+
public async updateLatestGlobalVariablesHash(globalVariablesHash: Fr) {
|
|
169
|
+
return await this.synchronise(() => this._updateLatestGlobalVariablesHash(globalVariablesHash));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Gets the global variables hash from the previous block
|
|
151
174
|
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
152
175
|
*/
|
|
153
|
-
public async
|
|
154
|
-
|
|
155
|
-
await this.appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]);
|
|
176
|
+
public async getLatestGlobalVariablesHash(includeUncommitted: boolean): Promise<Fr> {
|
|
177
|
+
return await this.synchronise(() => this._getGlobalVariablesHash(includeUncommitted));
|
|
156
178
|
}
|
|
157
179
|
|
|
158
180
|
/**
|
|
@@ -170,8 +192,8 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
170
192
|
* @param includeUncommitted - Indicates whether to include uncommitted data.
|
|
171
193
|
* @returns The current roots of the trees.
|
|
172
194
|
*/
|
|
173
|
-
public getTreeRoots(includeUncommitted: boolean): CurrentTreeRoots {
|
|
174
|
-
const roots = this.
|
|
195
|
+
public async getTreeRoots(includeUncommitted: boolean): Promise<CurrentTreeRoots> {
|
|
196
|
+
const roots = await this.synchronise(() => Promise.resolve(this._getAllTreeRoots(includeUncommitted)));
|
|
175
197
|
|
|
176
198
|
return {
|
|
177
199
|
privateDataTreeRoot: roots[0],
|
|
@@ -183,14 +205,14 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
183
205
|
};
|
|
184
206
|
}
|
|
185
207
|
|
|
186
|
-
async
|
|
187
|
-
const roots = this.
|
|
208
|
+
private async _getCurrentBlockHash(globalsHash: Fr, includeUncommitted: boolean): Promise<Fr> {
|
|
209
|
+
const roots = (await this._getAllTreeRoots(includeUncommitted)).map(root => Fr.fromBuffer(root));
|
|
188
210
|
const wasm = await CircuitsWasm.get();
|
|
189
|
-
return
|
|
211
|
+
return computeBlockHash(wasm, globalsHash, roots[0], roots[1], roots[2], roots[3], roots[4]);
|
|
190
212
|
}
|
|
191
213
|
|
|
192
|
-
|
|
193
|
-
|
|
214
|
+
private _getAllTreeRoots(includeUncommitted: boolean): Promise<Buffer[]> {
|
|
215
|
+
const roots = [
|
|
194
216
|
MerkleTreeId.PRIVATE_DATA_TREE,
|
|
195
217
|
MerkleTreeId.NULLIFIER_TREE,
|
|
196
218
|
MerkleTreeId.CONTRACT_TREE,
|
|
@@ -198,6 +220,8 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
198
220
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
199
221
|
MerkleTreeId.BLOCKS_TREE,
|
|
200
222
|
].map(tree => this.trees[tree].getRoot(includeUncommitted));
|
|
223
|
+
|
|
224
|
+
return Promise.resolve(roots);
|
|
201
225
|
}
|
|
202
226
|
|
|
203
227
|
/**
|
|
@@ -377,6 +401,20 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
377
401
|
return await this.jobQueue.put(fn);
|
|
378
402
|
}
|
|
379
403
|
|
|
404
|
+
private _updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise<void> {
|
|
405
|
+
this.latestGlobalVariablesHash.set(globalVariablesHash);
|
|
406
|
+
return Promise.resolve();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
private _getGlobalVariablesHash(includeUncommitted: boolean): Promise<Fr> {
|
|
410
|
+
return Promise.resolve(this.latestGlobalVariablesHash.get(includeUncommitted));
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
private async _updateHistoricBlocksTree(globalsHash: Fr, includeUncommitted: boolean) {
|
|
414
|
+
const blockHash = await this._getCurrentBlockHash(globalsHash, includeUncommitted);
|
|
415
|
+
await this._appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]);
|
|
416
|
+
}
|
|
417
|
+
|
|
380
418
|
/**
|
|
381
419
|
* Returns the tree info for the specified tree id.
|
|
382
420
|
* @param treeId - Id of the tree to get information from.
|
|
@@ -451,6 +489,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
451
489
|
for (const tree of this.trees) {
|
|
452
490
|
await tree.commit();
|
|
453
491
|
}
|
|
492
|
+
this.latestGlobalVariablesHash.commit();
|
|
454
493
|
}
|
|
455
494
|
|
|
456
495
|
/**
|
|
@@ -461,6 +500,7 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
461
500
|
for (const tree of this.trees) {
|
|
462
501
|
await tree.rollback();
|
|
463
502
|
}
|
|
503
|
+
this.latestGlobalVariablesHash.rollback();
|
|
464
504
|
}
|
|
465
505
|
|
|
466
506
|
/**
|
|
@@ -514,7 +554,11 @@ export class MerkleTrees implements MerkleTreeDb {
|
|
|
514
554
|
}
|
|
515
555
|
|
|
516
556
|
// Sync and add the block to the historic blocks tree
|
|
517
|
-
const
|
|
557
|
+
const globalVariablesHash = await computeGlobalVariablesHash(l2Block.globalVariables);
|
|
558
|
+
await this._updateLatestGlobalVariablesHash(globalVariablesHash);
|
|
559
|
+
this.log(`Synced global variables with hash ${this.latestGlobalVariablesHash.toString()}`);
|
|
560
|
+
|
|
561
|
+
const blockHash = await this._getCurrentBlockHash(globalVariablesHash, true);
|
|
518
562
|
await this._appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]);
|
|
519
563
|
|
|
520
564
|
await this._commit();
|