@aztec/world-state 0.0.0-test.0 → 0.0.1-commit.24de95ac

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.
Files changed (54) hide show
  1. package/dest/instrumentation/instrumentation.d.ts +5 -3
  2. package/dest/instrumentation/instrumentation.d.ts.map +1 -1
  3. package/dest/instrumentation/instrumentation.js +16 -8
  4. package/dest/native/bench_metrics.d.ts +23 -0
  5. package/dest/native/bench_metrics.d.ts.map +1 -0
  6. package/dest/native/bench_metrics.js +81 -0
  7. package/dest/native/merkle_trees_facade.d.ts +9 -3
  8. package/dest/native/merkle_trees_facade.d.ts.map +1 -1
  9. package/dest/native/merkle_trees_facade.js +38 -7
  10. package/dest/native/message.d.ts +64 -44
  11. package/dest/native/message.d.ts.map +1 -1
  12. package/dest/native/message.js +55 -56
  13. package/dest/native/native_world_state.d.ts +18 -13
  14. package/dest/native/native_world_state.d.ts.map +1 -1
  15. package/dest/native/native_world_state.js +90 -33
  16. package/dest/native/native_world_state_instance.d.ts +10 -3
  17. package/dest/native/native_world_state_instance.d.ts.map +1 -1
  18. package/dest/native/native_world_state_instance.js +21 -3
  19. package/dest/native/world_state_ops_queue.js +1 -1
  20. package/dest/synchronizer/config.d.ts +11 -1
  21. package/dest/synchronizer/config.d.ts.map +1 -1
  22. package/dest/synchronizer/config.js +26 -1
  23. package/dest/synchronizer/errors.d.ts +4 -0
  24. package/dest/synchronizer/errors.d.ts.map +1 -0
  25. package/dest/synchronizer/errors.js +5 -0
  26. package/dest/synchronizer/factory.d.ts +8 -1
  27. package/dest/synchronizer/factory.d.ts.map +1 -1
  28. package/dest/synchronizer/factory.js +9 -4
  29. package/dest/synchronizer/server_world_state_synchronizer.d.ts +13 -6
  30. package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
  31. package/dest/synchronizer/server_world_state_synchronizer.js +78 -38
  32. package/dest/test/utils.d.ts +1 -1
  33. package/dest/test/utils.d.ts.map +1 -1
  34. package/dest/test/utils.js +21 -18
  35. package/dest/testing.d.ts +1 -1
  36. package/dest/testing.d.ts.map +1 -1
  37. package/dest/testing.js +6 -10
  38. package/dest/world-state-db/merkle_tree_db.d.ts +8 -4
  39. package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
  40. package/package.json +21 -22
  41. package/src/instrumentation/instrumentation.ts +22 -10
  42. package/src/native/bench_metrics.ts +91 -0
  43. package/src/native/merkle_trees_facade.ts +44 -13
  44. package/src/native/message.ts +81 -63
  45. package/src/native/native_world_state.ts +98 -42
  46. package/src/native/native_world_state_instance.ts +31 -8
  47. package/src/native/world_state_ops_queue.ts +1 -1
  48. package/src/synchronizer/config.ts +47 -2
  49. package/src/synchronizer/errors.ts +5 -0
  50. package/src/synchronizer/factory.ts +31 -8
  51. package/src/synchronizer/server_world_state_synchronizer.ts +93 -40
  52. package/src/test/utils.ts +46 -31
  53. package/src/testing.ts +3 -7
  54. package/src/world-state-db/merkle_tree_db.ts +9 -4
@@ -1,10 +1,10 @@
1
1
  import { L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/constants';
2
+ import { SHA256Trunc } from '@aztec/foundation/crypto';
2
3
  import type { Fr } from '@aztec/foundation/fields';
3
- import { createLogger } from '@aztec/foundation/log';
4
+ import { type Logger, createLogger } from '@aztec/foundation/log';
4
5
  import { promiseWithResolvers } from '@aztec/foundation/promise';
5
6
  import { elapsed } from '@aztec/foundation/timer';
6
7
  import { MerkleTreeCalculator } from '@aztec/foundation/trees';
7
- import { SHA256Trunc } from '@aztec/merkle-tree';
8
8
  import type {
9
9
  L2Block,
10
10
  L2BlockId,
@@ -22,6 +22,7 @@ import {
22
22
  type WorldStateSynchronizerStatus,
23
23
  } from '@aztec/stdlib/interfaces/server';
24
24
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
25
+ import type { SnapshotDataKeys } from '@aztec/stdlib/snapshots';
25
26
  import type { L2BlockHandledStats } from '@aztec/stdlib/stats';
26
27
  import { MerkleTreeId, type MerkleTreeReadOperations, type MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
27
28
  import { TraceableL2BlockStream, getTelemetryClient } from '@aztec/telemetry-client';
@@ -30,6 +31,9 @@ import { WorldStateInstrumentation } from '../instrumentation/instrumentation.js
30
31
  import type { WorldStateStatusFull } from '../native/message.js';
31
32
  import type { MerkleTreeAdminDatabase } from '../world-state-db/merkle_tree_db.js';
32
33
  import type { WorldStateConfig } from './config.js';
34
+ import { WorldStateSynchronizerError } from './errors.js';
35
+
36
+ export type { SnapshotDataKeys };
33
37
 
34
38
  /**
35
39
  * Synchronizes the world state with the L2 blocks from a L2BlockSource via a block stream.
@@ -49,12 +53,16 @@ export class ServerWorldStateSynchronizer
49
53
  private syncPromise = promiseWithResolvers<void>();
50
54
  protected blockStream: L2BlockStream | undefined;
51
55
 
56
+ // WorldState doesn't track the proven block number, it only tracks the latest tips of the pending chain and the finalized chain
57
+ // store the proven block number here, in the synchronizer, so that we don't end up spamming the logs with 'chain-proved' events
58
+ private provenBlockNumber: bigint | undefined;
59
+
52
60
  constructor(
53
61
  private readonly merkleTreeDb: MerkleTreeAdminDatabase,
54
62
  private readonly l2BlockSource: L2BlockSource & L1ToL2MessageSource,
55
63
  private readonly config: WorldStateConfig,
56
64
  private instrumentation = new WorldStateInstrumentation(getTelemetryClient()),
57
- private readonly log = createLogger('world_state'),
65
+ private readonly log: Logger = createLogger('world_state'),
58
66
  ) {
59
67
  this.merkleTreeCommitted = this.merkleTreeDb.getCommitted();
60
68
  this.historyToKeep = config.worldStateBlockHistory < 1 ? undefined : config.worldStateBlockHistory;
@@ -77,6 +85,14 @@ export class ServerWorldStateSynchronizer
77
85
  return this.merkleTreeDb.fork(blockNumber);
78
86
  }
79
87
 
88
+ public backupTo(dstPath: string, compact?: boolean): Promise<Record<Exclude<SnapshotDataKeys, 'archiver'>, string>> {
89
+ return this.merkleTreeDb.backupTo(dstPath, compact);
90
+ }
91
+
92
+ public clear(): Promise<void> {
93
+ return this.merkleTreeDb.clear();
94
+ }
95
+
80
96
  public async start() {
81
97
  if (this.currentState === WorldStateRunningState.STOPPED) {
82
98
  throw new Error('Synchronizer already stopped');
@@ -131,9 +147,9 @@ export class ServerWorldStateSynchronizer
131
147
  public async status(): Promise<WorldStateSynchronizerStatus> {
132
148
  const summary = await this.merkleTreeDb.getStatusSummary();
133
149
  const status: WorldStateSyncStatus = {
134
- latestBlockNumber: Number(summary.unfinalisedBlockNumber),
135
- latestBlockHash: (await this.getL2BlockHash(Number(summary.unfinalisedBlockNumber))) ?? '',
136
- finalisedBlockNumber: Number(summary.finalisedBlockNumber),
150
+ latestBlockNumber: Number(summary.unfinalizedBlockNumber),
151
+ latestBlockHash: (await this.getL2BlockHash(Number(summary.unfinalizedBlockNumber))) ?? '',
152
+ finalizedBlockNumber: Number(summary.finalizedBlockNumber),
137
153
  oldestHistoricBlockNumber: Number(summary.oldestHistoricalBlock),
138
154
  treesAreSynched: summary.treesAreSynched,
139
155
  };
@@ -147,16 +163,36 @@ export class ServerWorldStateSynchronizer
147
163
  return (await this.getL2Tips()).latest.number;
148
164
  }
149
165
 
166
+ public async stopSync() {
167
+ this.log.debug('Stopping sync...');
168
+ await this.blockStream?.stop();
169
+ this.log.info('Stopped sync');
170
+ }
171
+
172
+ public resumeSync() {
173
+ if (!this.blockStream) {
174
+ throw new Error('Cannot resume sync as block stream is not initialized');
175
+ }
176
+ this.log.debug('Resuming sync...');
177
+ this.blockStream.start();
178
+ this.log.info('Resumed sync');
179
+ }
180
+
150
181
  /**
151
182
  * Forces an immediate sync.
152
- * @param targetBlockNumber - The target block number that we must sync to. Will download unproven blocks if needed to reach it. Throws if cannot be reached.
183
+ * @param targetBlockNumber - The target block number that we must sync to. Will download unproven blocks if needed to reach it.
184
+ * @param skipThrowIfTargetNotReached - Whether to skip throwing if the target block number is not reached.
153
185
  * @returns A promise that resolves with the block number the world state was synced to
154
186
  */
155
- public async syncImmediate(targetBlockNumber?: number): Promise<number> {
156
- if (this.currentState !== WorldStateRunningState.RUNNING || this.blockStream === undefined) {
187
+ public async syncImmediate(targetBlockNumber?: number, skipThrowIfTargetNotReached?: boolean): Promise<number> {
188
+ if (this.currentState !== WorldStateRunningState.RUNNING) {
157
189
  throw new Error(`World State is not running. Unable to perform sync.`);
158
190
  }
159
191
 
192
+ if (this.blockStream === undefined) {
193
+ throw new Error('Block stream is not initialized. Unable to perform sync.');
194
+ }
195
+
160
196
  // If we have been given a block number to sync to and we have reached that number then return
161
197
  const currentBlockNumber = await this.getLatestBlockNumber();
162
198
  if (targetBlockNumber !== undefined && targetBlockNumber <= currentBlockNumber) {
@@ -164,13 +200,32 @@ export class ServerWorldStateSynchronizer
164
200
  }
165
201
  this.log.debug(`World State at ${currentBlockNumber} told to sync to ${targetBlockNumber ?? 'latest'}`);
166
202
 
203
+ // If the archiver is behind the target block, force an archiver sync
204
+ if (targetBlockNumber) {
205
+ const archiverLatestBlock = await this.l2BlockSource.getBlockNumber();
206
+ if (archiverLatestBlock < targetBlockNumber) {
207
+ this.log.debug(`Archiver is at ${archiverLatestBlock} behind target block ${targetBlockNumber}.`);
208
+ await this.l2BlockSource.syncImmediate();
209
+ }
210
+ }
211
+
167
212
  // Force the block stream to sync against the archiver now
168
213
  await this.blockStream.sync();
169
214
 
170
215
  // If we have been given a block number to sync to and we have not reached that number then fail
171
216
  const updatedBlockNumber = await this.getLatestBlockNumber();
172
- if (targetBlockNumber !== undefined && targetBlockNumber > updatedBlockNumber) {
173
- throw new Error(`Unable to sync to block number ${targetBlockNumber} (last synced is ${updatedBlockNumber})`);
217
+ if (!skipThrowIfTargetNotReached && targetBlockNumber !== undefined && targetBlockNumber > updatedBlockNumber) {
218
+ throw new WorldStateSynchronizerError(
219
+ `Unable to sync to block number ${targetBlockNumber} (last synced is ${updatedBlockNumber})`,
220
+ {
221
+ cause: {
222
+ reason: 'block_not_available',
223
+ previousBlockNumber: currentBlockNumber,
224
+ updatedBlockNumber,
225
+ targetBlockNumber,
226
+ },
227
+ },
228
+ );
174
229
  }
175
230
 
176
231
  return updatedBlockNumber;
@@ -195,35 +250,31 @@ export class ServerWorldStateSynchronizer
195
250
  /** Returns the latest L2 block number for each tip of the chain (latest, proven, finalized). */
196
251
  public async getL2Tips(): Promise<L2Tips> {
197
252
  const status = await this.merkleTreeDb.getStatusSummary();
198
- const unfinalisedBlockHash = await this.getL2BlockHash(Number(status.unfinalisedBlockNumber));
199
- const latestBlockId: L2BlockId = { number: Number(status.unfinalisedBlockNumber), hash: unfinalisedBlockHash! };
253
+ const unfinalizedBlockHash = await this.getL2BlockHash(Number(status.unfinalizedBlockNumber));
254
+ const latestBlockId: L2BlockId = { number: Number(status.unfinalizedBlockNumber), hash: unfinalizedBlockHash! };
200
255
 
201
256
  return {
202
257
  latest: latestBlockId,
203
- finalized: { number: Number(status.finalisedBlockNumber), hash: '' },
204
- proven: { number: Number(status.finalisedBlockNumber), hash: '' }, // TODO(palla/reorg): Using finalised as proven for now
258
+ finalized: { number: Number(status.finalizedBlockNumber), hash: '' },
259
+ proven: { number: Number(this.provenBlockNumber ?? status.finalizedBlockNumber), hash: '' }, // TODO(palla/reorg): Using finalized as proven for now
205
260
  };
206
261
  }
207
262
 
208
263
  /** Handles an event emitted by the block stream. */
209
264
  public async handleBlockStreamEvent(event: L2BlockStreamEvent): Promise<void> {
210
- try {
211
- switch (event.type) {
212
- case 'blocks-added':
213
- await this.handleL2Blocks(event.blocks);
214
- break;
215
- case 'chain-pruned':
216
- await this.handleChainPruned(event.blockNumber);
217
- break;
218
- case 'chain-proven':
219
- await this.handleChainProven(event.blockNumber);
220
- break;
221
- case 'chain-finalized':
222
- await this.handleChainFinalized(event.blockNumber);
223
- break;
224
- }
225
- } catch (err) {
226
- this.log.error('Error processing block stream', err);
265
+ switch (event.type) {
266
+ case 'blocks-added':
267
+ await this.handleL2Blocks(event.blocks.map(b => b.block));
268
+ break;
269
+ case 'chain-pruned':
270
+ await this.handleChainPruned(event.block.number);
271
+ break;
272
+ case 'chain-proven':
273
+ await this.handleChainProven(event.block.number);
274
+ break;
275
+ case 'chain-finalized':
276
+ await this.handleChainFinalized(event.block.number);
277
+ break;
227
278
  }
228
279
  }
229
280
 
@@ -235,17 +286,17 @@ export class ServerWorldStateSynchronizer
235
286
  private async handleL2Blocks(l2Blocks: L2Block[]) {
236
287
  this.log.trace(`Handling L2 blocks ${l2Blocks[0].number} to ${l2Blocks.at(-1)!.number}`);
237
288
 
238
- const messagePromises = l2Blocks.map(block => this.l2BlockSource.getL1ToL2Messages(BigInt(block.number)));
289
+ const messagePromises = l2Blocks.map(block => this.l2BlockSource.getL1ToL2Messages(block.number));
239
290
  const l1ToL2Messages: Fr[][] = await Promise.all(messagePromises);
240
291
  let updateStatus: WorldStateStatusFull | undefined = undefined;
241
292
 
242
293
  for (let i = 0; i < l2Blocks.length; i++) {
243
294
  const [duration, result] = await elapsed(() => this.handleL2Block(l2Blocks[i], l1ToL2Messages[i]));
244
- this.log.verbose(`World state updated with L2 block ${l2Blocks[i].number}`, {
295
+ this.log.info(`World state updated with L2 block ${l2Blocks[i].number}`, {
245
296
  eventName: 'l2-block-handled',
246
297
  duration,
247
- unfinalisedBlockNumber: result.summary.unfinalisedBlockNumber,
248
- finalisedBlockNumber: result.summary.finalisedBlockNumber,
298
+ unfinalizedBlockNumber: result.summary.unfinalizedBlockNumber,
299
+ finalizedBlockNumber: result.summary.finalizedBlockNumber,
249
300
  oldestHistoricBlock: result.summary.oldestHistoricalBlock,
250
301
  ...l2Blocks[i].getStats(),
251
302
  } satisfies L2BlockHandledStats);
@@ -288,11 +339,11 @@ export class ServerWorldStateSynchronizer
288
339
 
289
340
  private async handleChainFinalized(blockNumber: number) {
290
341
  this.log.verbose(`Finalized chain is now at block ${blockNumber}`);
291
- const summary = await this.merkleTreeDb.setFinalised(BigInt(blockNumber));
342
+ const summary = await this.merkleTreeDb.setFinalized(BigInt(blockNumber));
292
343
  if (this.historyToKeep === undefined) {
293
344
  return;
294
345
  }
295
- const newHistoricBlock = summary.finalisedBlockNumber - BigInt(this.historyToKeep) + 1n;
346
+ const newHistoricBlock = summary.finalizedBlockNumber - BigInt(this.historyToKeep) + 1n;
296
347
  if (newHistoricBlock <= 1) {
297
348
  return;
298
349
  }
@@ -302,6 +353,7 @@ export class ServerWorldStateSynchronizer
302
353
  }
303
354
 
304
355
  private handleChainProven(blockNumber: number) {
356
+ this.provenBlockNumber = BigInt(blockNumber);
305
357
  this.log.debug(`Proven chain is now at block ${blockNumber}`);
306
358
  return Promise.resolve();
307
359
  }
@@ -310,6 +362,7 @@ export class ServerWorldStateSynchronizer
310
362
  this.log.warn(`Chain pruned to block ${blockNumber}`);
311
363
  const status = await this.merkleTreeDb.unwindBlocks(BigInt(blockNumber));
312
364
  this.latestBlockHashQuery = undefined;
365
+ this.provenBlockNumber = undefined;
313
366
  this.instrumentation.updateWorldStateMetrics(status);
314
367
  }
315
368
 
@@ -328,7 +381,7 @@ export class ServerWorldStateSynchronizer
328
381
  * @param inHash - The inHash of the block.
329
382
  * @throws If the L1 to L2 messages do not hash to the block inHash.
330
383
  */
331
- protected async verifyMessagesHashToInHash(l1ToL2Messages: Fr[], inHash: Buffer) {
384
+ protected async verifyMessagesHashToInHash(l1ToL2Messages: Fr[], inHash: Fr) {
332
385
  const treeCalculator = await MerkleTreeCalculator.create(
333
386
  L1_TO_L2_MSG_SUBTREE_HEIGHT,
334
387
  Buffer.alloc(32),
@@ -337,7 +390,7 @@ export class ServerWorldStateSynchronizer
337
390
 
338
391
  const root = await treeCalculator.computeTreeRoot(l1ToL2Messages.map(msg => msg.toBuffer()));
339
392
 
340
- if (!root.equals(inHash)) {
393
+ if (!root.equals(inHash.toBuffer())) {
341
394
  throw new Error('Obtained L1 to L2 messages failed to be hashed to the block inHash');
342
395
  }
343
396
  }
package/src/test/utils.ts CHANGED
@@ -7,49 +7,64 @@ import {
7
7
  import { padArrayEnd } from '@aztec/foundation/collection';
8
8
  import { Fr } from '@aztec/foundation/fields';
9
9
  import { L2Block } from '@aztec/stdlib/block';
10
- import type { MerkleTreeReadOperations, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
10
+ import type {
11
+ IndexedTreeId,
12
+ MerkleTreeReadOperations,
13
+ MerkleTreeWriteOperations,
14
+ } from '@aztec/stdlib/interfaces/server';
11
15
  import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
12
16
 
13
17
  import type { NativeWorldStateService } from '../native/native_world_state.js';
14
18
 
15
- export async function mockBlock(blockNum: number, size: number, fork: MerkleTreeWriteOperations) {
16
- const l2Block = await L2Block.random(blockNum, size);
17
- const l1ToL2Messages = Array(16).fill(0).map(Fr.random);
19
+ export async function mockBlock(
20
+ blockNum: number,
21
+ size: number,
22
+ fork: MerkleTreeWriteOperations,
23
+ maxEffects: number | undefined = undefined,
24
+ ) {
25
+ const l2Block = await L2Block.random(blockNum, size, maxEffects);
26
+ const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.random);
18
27
 
19
- // Sync the append only trees
20
28
  {
29
+ const insertData = async (
30
+ treeId: IndexedTreeId,
31
+ data: Buffer[][],
32
+ subTreeHeight: number,
33
+ fork: MerkleTreeWriteOperations,
34
+ ) => {
35
+ for (const dataBatch of data) {
36
+ await fork.batchInsert(treeId, dataBatch, subTreeHeight);
37
+ }
38
+ };
39
+
40
+ const publicDataInsert = insertData(
41
+ MerkleTreeId.PUBLIC_DATA_TREE,
42
+ l2Block.body.txEffects.map(txEffect => txEffect.publicDataWrites.map(write => write.toBuffer())),
43
+ 0,
44
+ fork,
45
+ );
46
+ const nullifierInsert = insertData(
47
+ MerkleTreeId.NULLIFIER_TREE,
48
+ l2Block.body.txEffects.map(txEffect =>
49
+ padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(nullifier => nullifier.toBuffer()),
50
+ ),
51
+ NULLIFIER_SUBTREE_HEIGHT,
52
+ fork,
53
+ );
21
54
  const noteHashesPadded = l2Block.body.txEffects.flatMap(txEffect =>
22
55
  padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
23
56
  );
24
- await fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
25
-
26
- const l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
27
- await fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
28
- }
29
-
30
- // Sync the indexed trees
31
- {
32
- // We insert the public data tree leaves with one batch per tx to avoid updating the same key twice
33
- for (const txEffect of l2Block.body.txEffects) {
34
- await fork.batchInsert(
35
- MerkleTreeId.PUBLIC_DATA_TREE,
36
- txEffect.publicDataWrites.map(write => write.toBuffer()),
37
- 0,
38
- );
39
57
 
40
- const nullifiersPadded = padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX);
58
+ const l1ToL2MessagesPadded = padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
41
59
 
42
- await fork.batchInsert(
43
- MerkleTreeId.NULLIFIER_TREE,
44
- nullifiersPadded.map(nullifier => nullifier.toBuffer()),
45
- NULLIFIER_SUBTREE_HEIGHT,
46
- );
47
- }
60
+ const noteHashInsert = fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
61
+ const messageInsert = fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
62
+ await Promise.all([publicDataInsert, nullifierInsert, noteHashInsert, messageInsert]);
48
63
  }
49
64
 
50
65
  const state = await fork.getStateReference();
51
66
  l2Block.header.state = state;
52
- await fork.updateArchive(l2Block.header);
67
+ await fork.updateArchive(l2Block.getBlockHeader());
53
68
 
54
69
  const archiveState = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
55
70
 
@@ -65,7 +80,7 @@ export async function mockEmptyBlock(blockNum: number, fork: MerkleTreeWriteOper
65
80
  const l2Block = L2Block.empty();
66
81
  const l1ToL2Messages = Array(16).fill(0).map(Fr.zero);
67
82
 
68
- l2Block.header.globalVariables.blockNumber = new Fr(blockNum);
83
+ l2Block.header.globalVariables.blockNumber = blockNum;
69
84
 
70
85
  // Sync the append only trees
71
86
  {
@@ -74,7 +89,7 @@ export async function mockEmptyBlock(blockNum: number, fork: MerkleTreeWriteOper
74
89
  );
75
90
  await fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
76
91
 
77
- const l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
92
+ const l1ToL2MessagesPadded = padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
78
93
  await fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
79
94
  }
80
95
 
@@ -100,7 +115,7 @@ export async function mockEmptyBlock(blockNum: number, fork: MerkleTreeWriteOper
100
115
 
101
116
  const state = await fork.getStateReference();
102
117
  l2Block.header.state = state;
103
- await fork.updateArchive(l2Block.header);
118
+ await fork.updateArchive(l2Block.getBlockHeader());
104
119
 
105
120
  const archiveState = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
106
121
 
package/src/testing.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { GENESIS_ARCHIVE_ROOT, GENESIS_BLOCK_HASH } from '@aztec/constants';
1
+ import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
3
  import { computeFeePayerBalanceLeafSlot } from '@aztec/protocol-contracts/fee-juice';
4
4
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -10,7 +10,6 @@ async function generateGenesisValues(prefilledPublicData: PublicDataTreeLeaf[])
10
10
  if (!prefilledPublicData.length) {
11
11
  return {
12
12
  genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT),
13
- genesisBlockHash: new Fr(GENESIS_BLOCK_HASH),
14
13
  };
15
14
  }
16
15
 
@@ -20,14 +19,11 @@ async function generateGenesisValues(prefilledPublicData: PublicDataTreeLeaf[])
20
19
  true /* cleanupTmpDir */,
21
20
  prefilledPublicData,
22
21
  );
23
- const initialHeader = ws.getInitialHeader();
24
- const genesisBlockHash = await initialHeader.hash();
25
22
  const genesisArchiveRoot = new Fr((await ws.getCommitted().getTreeInfo(MerkleTreeId.ARCHIVE)).root);
26
23
  await ws.close();
27
24
 
28
25
  return {
29
26
  genesisArchiveRoot,
30
- genesisBlockHash,
31
27
  };
32
28
  }
33
29
 
@@ -50,11 +46,11 @@ export async function getGenesisValues(
50
46
 
51
47
  prefilledPublicData.sort((a, b) => (b.slot.lt(a.slot) ? 1 : -1));
52
48
 
53
- const { genesisBlockHash, genesisArchiveRoot } = await generateGenesisValues(prefilledPublicData);
49
+ const { genesisArchiveRoot } = await generateGenesisValues(prefilledPublicData);
54
50
 
55
51
  return {
56
52
  genesisArchiveRoot,
57
- genesisBlockHash,
58
53
  prefilledPublicData,
54
+ fundingNeeded: BigInt(initialAccounts.length) * initialAccountFeeJuice.toBigInt(),
59
55
  };
60
56
  }
@@ -39,8 +39,10 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
39
39
  * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
40
40
  * @param block - The L2 block to handle.
41
41
  * @param l1ToL2Messages - The L1 to L2 messages for the block.
42
+ * @param isFirstBlock - Whether the block is the first block in a checkpoint. Temporary hack to only insert l1 to l2
43
+ * messages for the first block in a checkpoint. TODO(#17027) Remove this.
42
44
  */
43
- handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[]): Promise<WorldStateStatusFull>;
45
+ handleL2BlockAndMessages(block: L2Block, l1ToL2Messages: Fr[], isFirstBlock?: boolean): Promise<WorldStateStatusFull>;
44
46
 
45
47
  /**
46
48
  * Gets a handle that allows reading the latest committed state
@@ -62,11 +64,11 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
62
64
  unwindBlocks(toBlockNumber: bigint): Promise<WorldStateStatusFull>;
63
65
 
64
66
  /**
65
- * Advances the finalised block number to be the number provided
66
- * @param toBlockNumber The block number that is now the tip of the finalised chain
67
+ * Advances the finalized block number to be the number provided
68
+ * @param toBlockNumber The block number that is now the tip of the finalized chain
67
69
  * @returns The new WorldStateStatus
68
70
  */
69
- setFinalised(toBlockNumber: bigint): Promise<WorldStateStatusSummary>;
71
+ setFinalized(toBlockNumber: bigint): Promise<WorldStateStatusSummary>;
70
72
 
71
73
  /**
72
74
  * Gets the current status summary of the database.
@@ -76,4 +78,7 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
76
78
 
77
79
  /** Stops the database */
78
80
  close(): Promise<void>;
81
+
82
+ /** Deletes the db. */
83
+ clear(): Promise<void>;
79
84
  }