@aztec/archiver 0.0.1-commit.d431d1c → 0.0.1-commit.d6f2b3f94

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 (75) hide show
  1. package/README.md +9 -0
  2. package/dest/archiver.d.ts +6 -5
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +34 -22
  5. package/dest/errors.d.ts +6 -1
  6. package/dest/errors.d.ts.map +1 -1
  7. package/dest/errors.js +8 -0
  8. package/dest/factory.d.ts +5 -2
  9. package/dest/factory.d.ts.map +1 -1
  10. package/dest/factory.js +11 -8
  11. package/dest/l1/bin/retrieve-calldata.js +17 -18
  12. package/dest/l1/data_retrieval.d.ts +1 -1
  13. package/dest/l1/data_retrieval.d.ts.map +1 -1
  14. package/dest/l1/data_retrieval.js +3 -3
  15. package/dest/l1/validate_trace.d.ts +6 -3
  16. package/dest/l1/validate_trace.d.ts.map +1 -1
  17. package/dest/l1/validate_trace.js +13 -9
  18. package/dest/modules/data_source_base.d.ts +17 -18
  19. package/dest/modules/data_source_base.d.ts.map +1 -1
  20. package/dest/modules/data_source_base.js +21 -52
  21. package/dest/modules/data_store_updater.d.ts +23 -19
  22. package/dest/modules/data_store_updater.d.ts.map +1 -1
  23. package/dest/modules/data_store_updater.js +47 -49
  24. package/dest/modules/instrumentation.d.ts +3 -3
  25. package/dest/modules/instrumentation.d.ts.map +1 -1
  26. package/dest/modules/instrumentation.js +17 -10
  27. package/dest/modules/l1_synchronizer.d.ts +1 -1
  28. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  29. package/dest/modules/l1_synchronizer.js +9 -10
  30. package/dest/store/block_store.d.ts +35 -21
  31. package/dest/store/block_store.d.ts.map +1 -1
  32. package/dest/store/block_store.js +81 -40
  33. package/dest/store/contract_class_store.d.ts +1 -1
  34. package/dest/store/contract_class_store.d.ts.map +1 -1
  35. package/dest/store/contract_class_store.js +11 -7
  36. package/dest/store/kv_archiver_store.d.ts +28 -24
  37. package/dest/store/kv_archiver_store.d.ts.map +1 -1
  38. package/dest/store/kv_archiver_store.js +20 -17
  39. package/dest/store/log_store.d.ts +4 -4
  40. package/dest/store/log_store.d.ts.map +1 -1
  41. package/dest/store/log_store.js +57 -37
  42. package/dest/test/fake_l1_state.d.ts +4 -4
  43. package/dest/test/fake_l1_state.d.ts.map +1 -1
  44. package/dest/test/index.js +3 -1
  45. package/dest/test/mock_archiver.js +1 -1
  46. package/dest/test/mock_l2_block_source.d.ts +20 -20
  47. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  48. package/dest/test/mock_l2_block_source.js +40 -41
  49. package/dest/test/mock_structs.d.ts +3 -2
  50. package/dest/test/mock_structs.d.ts.map +1 -1
  51. package/dest/test/mock_structs.js +11 -9
  52. package/dest/test/noop_l1_archiver.d.ts +23 -0
  53. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  54. package/dest/test/noop_l1_archiver.js +68 -0
  55. package/package.json +14 -13
  56. package/src/archiver.ts +46 -28
  57. package/src/errors.ts +12 -0
  58. package/src/factory.ts +23 -13
  59. package/src/l1/bin/retrieve-calldata.ts +16 -17
  60. package/src/l1/data_retrieval.ts +4 -4
  61. package/src/l1/validate_trace.ts +24 -6
  62. package/src/modules/data_source_base.ts +26 -77
  63. package/src/modules/data_store_updater.ts +59 -55
  64. package/src/modules/instrumentation.ts +17 -12
  65. package/src/modules/l1_synchronizer.ts +11 -12
  66. package/src/store/block_store.ts +107 -60
  67. package/src/store/contract_class_store.ts +11 -7
  68. package/src/store/kv_archiver_store.ts +36 -28
  69. package/src/store/log_store.ts +105 -43
  70. package/src/test/fake_l1_state.ts +2 -2
  71. package/src/test/index.ts +3 -0
  72. package/src/test/mock_archiver.ts +1 -1
  73. package/src/test/mock_l2_block_source.ts +54 -64
  74. package/src/test/mock_structs.ts +26 -10
  75. package/src/test/noop_l1_archiver.ts +109 -0
@@ -6,7 +6,7 @@ import { createLogger } from '@aztec/foundation/log';
6
6
  import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
7
7
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
8
8
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
9
- import { L2BlockHash, L2BlockNew } from '@aztec/stdlib/block';
9
+ import { BlockHash, L2Block } from '@aztec/stdlib/block';
10
10
  import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
11
11
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
12
12
  import {
@@ -20,6 +20,7 @@ import {
20
20
  Tag,
21
21
  TxScopedL2Log,
22
22
  } from '@aztec/stdlib/logs';
23
+ import { TxHash } from '@aztec/stdlib/tx';
23
24
 
24
25
  import type { BlockStore } from './block_store.js';
25
26
 
@@ -59,7 +60,7 @@ export class LogStore {
59
60
  * @param block - The L2 block to extract logs from.
60
61
  * @returns An object containing the private and public tagged logs for the block.
61
62
  */
62
- #extractTaggedLogsFromBlock(block: L2BlockNew) {
63
+ #extractTaggedLogsFromBlock(block: L2Block) {
63
64
  // SiloedTag (as string) -> array of log buffers.
64
65
  const privateTaggedLogs = new Map<string, Buffer[]>();
65
66
  // "{contractAddress}_{tag}" (as string) -> array of log buffers.
@@ -120,7 +121,7 @@ export class LogStore {
120
121
  * @returns A map from tag (as string) to an array of serialized private logs belonging to that tag, and a map from
121
122
  * "{contractAddress}_{tag}" (as string) to an array of serialized public logs belonging to that key.
122
123
  */
123
- #extractTaggedLogs(blocks: L2BlockNew[]): {
124
+ #extractTaggedLogs(blocks: L2Block[]): {
124
125
  privateTaggedLogs: Map<string, Buffer[]>;
125
126
  publicTaggedLogs: Map<string, Buffer[]>;
126
127
  } {
@@ -146,7 +147,7 @@ export class LogStore {
146
147
  return { privateTaggedLogs, publicTaggedLogs };
147
148
  }
148
149
 
149
- async #addPrivateLogs(blocks: L2BlockNew[]): Promise<void> {
150
+ async #addPrivateLogs(blocks: L2Block[]): Promise<void> {
150
151
  const newBlocks = await filterAsync(
151
152
  blocks,
152
153
  async block => !(await this.#privateLogKeysByBlock.hasAsync(block.number)),
@@ -181,7 +182,7 @@ export class LogStore {
181
182
  }
182
183
  }
183
184
 
184
- async #addPublicLogs(blocks: L2BlockNew[]): Promise<void> {
185
+ async #addPublicLogs(blocks: L2Block[]): Promise<void> {
185
186
  const newBlocks = await filterAsync(
186
187
  blocks,
187
188
  async block => !(await this.#publicLogKeysByBlock.hasAsync(block.number)),
@@ -219,6 +220,7 @@ export class LogStore {
219
220
  .map((txEffect, txIndex) =>
220
221
  [
221
222
  numToUInt32BE(txIndex),
223
+ txEffect.txHash.toBuffer(),
222
224
  numToUInt32BE(txEffect.publicLogs.length),
223
225
  txEffect.publicLogs.map(log => log.toBuffer()),
224
226
  ].flat(),
@@ -229,7 +231,7 @@ export class LogStore {
229
231
  }
230
232
  }
231
233
 
232
- async #addContractClassLogs(blocks: L2BlockNew[]): Promise<void> {
234
+ async #addContractClassLogs(blocks: L2Block[]): Promise<void> {
233
235
  const newBlocks = await filterAsync(
234
236
  blocks,
235
237
  async block => !(await this.#contractClassLogsByBlock.hasAsync(block.number)),
@@ -242,6 +244,7 @@ export class LogStore {
242
244
  .map((txEffect, txIndex) =>
243
245
  [
244
246
  numToUInt32BE(txIndex),
247
+ txEffect.txHash.toBuffer(),
245
248
  numToUInt32BE(txEffect.contractClassLogs.length),
246
249
  txEffect.contractClassLogs.map(log => log.toBuffer()),
247
250
  ].flat(),
@@ -260,7 +263,7 @@ export class LogStore {
260
263
  * @param blocks - The blocks for which to add the logs.
261
264
  * @returns True if the operation is successful.
262
265
  */
263
- addLogs(blocks: L2BlockNew[]): Promise<boolean> {
266
+ addLogs(blocks: L2Block[]): Promise<boolean> {
264
267
  return this.db.transactionAsync(async () => {
265
268
  await Promise.all([
266
269
  this.#addPrivateLogs(blocks),
@@ -271,21 +274,21 @@ export class LogStore {
271
274
  });
272
275
  }
273
276
 
274
- #packWithBlockHash(blockHash: Fr, data: Buffer<ArrayBufferLike>[]): Buffer<ArrayBufferLike> {
277
+ #packWithBlockHash(blockHash: BlockHash, data: Buffer<ArrayBufferLike>[]): Buffer<ArrayBufferLike> {
275
278
  return Buffer.concat([blockHash.toBuffer(), ...data]);
276
279
  }
277
280
 
278
- #unpackBlockHash(reader: BufferReader): L2BlockHash {
281
+ #unpackBlockHash(reader: BufferReader): BlockHash {
279
282
  const blockHash = reader.remainingBytes() > 0 ? reader.readObject(Fr) : undefined;
280
283
 
281
284
  if (!blockHash) {
282
285
  throw new Error('Failed to read block hash from log entry buffer');
283
286
  }
284
287
 
285
- return L2BlockHash.fromField(blockHash);
288
+ return new BlockHash(blockHash);
286
289
  }
287
290
 
288
- deleteLogs(blocks: L2BlockNew[]): Promise<boolean> {
291
+ deleteLogs(blocks: L2Block[]): Promise<boolean> {
289
292
  return this.db.transactionAsync(async () => {
290
293
  await Promise.all(
291
294
  blocks.map(async block => {
@@ -386,24 +389,33 @@ export class LogStore {
386
389
  }
387
390
 
388
391
  const buffer = (await this.#publicLogsByBlock.getAsync(blockNumber)) ?? Buffer.alloc(0);
389
- const publicLogsInBlock: [PublicLog[]] = [[]];
392
+ const publicLogsInBlock: { txHash: TxHash; logs: PublicLog[] }[] = [];
390
393
  const reader = new BufferReader(buffer);
391
394
 
392
395
  const blockHash = this.#unpackBlockHash(reader);
393
396
 
394
397
  while (reader.remainingBytes() > 0) {
395
398
  const indexOfTx = reader.readNumber();
399
+ const txHash = reader.readObject(TxHash);
396
400
  const numLogsInTx = reader.readNumber();
397
- publicLogsInBlock[indexOfTx] = [];
401
+ publicLogsInBlock[indexOfTx] = { txHash, logs: [] };
398
402
  for (let i = 0; i < numLogsInTx; i++) {
399
- publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
403
+ publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
400
404
  }
401
405
  }
402
406
 
403
- const txLogs = publicLogsInBlock[txIndex];
407
+ const txData = publicLogsInBlock[txIndex];
404
408
 
405
409
  const logs: ExtendedPublicLog[] = [];
406
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
410
+ const maxLogsHit = this.#accumulatePublicLogs(
411
+ logs,
412
+ blockNumber,
413
+ blockHash,
414
+ txIndex,
415
+ txData.txHash,
416
+ txData.logs,
417
+ filter,
418
+ );
407
419
 
408
420
  return { logs, maxLogsHit };
409
421
  }
@@ -424,22 +436,31 @@ export class LogStore {
424
436
 
425
437
  let maxLogsHit = false;
426
438
  loopOverBlocks: for await (const [blockNumber, logBuffer] of this.#publicLogsByBlock.entriesAsync({ start, end })) {
427
- const publicLogsInBlock: [PublicLog[]] = [[]];
439
+ const publicLogsInBlock: { txHash: TxHash; logs: PublicLog[] }[] = [];
428
440
  const reader = new BufferReader(logBuffer);
429
441
 
430
442
  const blockHash = this.#unpackBlockHash(reader);
431
443
 
432
444
  while (reader.remainingBytes() > 0) {
433
445
  const indexOfTx = reader.readNumber();
446
+ const txHash = reader.readObject(TxHash);
434
447
  const numLogsInTx = reader.readNumber();
435
- publicLogsInBlock[indexOfTx] = [];
448
+ publicLogsInBlock[indexOfTx] = { txHash, logs: [] };
436
449
  for (let i = 0; i < numLogsInTx; i++) {
437
- publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
450
+ publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
438
451
  }
439
452
  }
440
453
  for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < publicLogsInBlock.length; txIndex++) {
441
- const txLogs = publicLogsInBlock[txIndex];
442
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
454
+ const txData = publicLogsInBlock[txIndex];
455
+ maxLogsHit = this.#accumulatePublicLogs(
456
+ logs,
457
+ blockNumber,
458
+ blockHash,
459
+ txIndex,
460
+ txData.txHash,
461
+ txData.logs,
462
+ filter,
463
+ );
443
464
  if (maxLogsHit) {
444
465
  this.#log.debug(`Max logs hit at block ${blockNumber}`);
445
466
  break loopOverBlocks;
@@ -475,24 +496,33 @@ export class LogStore {
475
496
  return { logs: [], maxLogsHit: false };
476
497
  }
477
498
  const contractClassLogsBuffer = (await this.#contractClassLogsByBlock.getAsync(blockNumber)) ?? Buffer.alloc(0);
478
- const contractClassLogsInBlock: [ContractClassLog[]] = [[]];
499
+ const contractClassLogsInBlock: { txHash: TxHash; logs: ContractClassLog[] }[] = [];
479
500
 
480
501
  const reader = new BufferReader(contractClassLogsBuffer);
481
502
  const blockHash = this.#unpackBlockHash(reader);
482
503
 
483
504
  while (reader.remainingBytes() > 0) {
484
505
  const indexOfTx = reader.readNumber();
506
+ const txHash = reader.readObject(TxHash);
485
507
  const numLogsInTx = reader.readNumber();
486
- contractClassLogsInBlock[indexOfTx] = [];
508
+ contractClassLogsInBlock[indexOfTx] = { txHash, logs: [] };
487
509
  for (let i = 0; i < numLogsInTx; i++) {
488
- contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
510
+ contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
489
511
  }
490
512
  }
491
513
 
492
- const txLogs = contractClassLogsInBlock[txIndex];
514
+ const txData = contractClassLogsInBlock[txIndex];
493
515
 
494
516
  const logs: ExtendedContractClassLog[] = [];
495
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
517
+ const maxLogsHit = this.#accumulateContractClassLogs(
518
+ logs,
519
+ blockNumber,
520
+ blockHash,
521
+ txIndex,
522
+ txData.txHash,
523
+ txData.logs,
524
+ filter,
525
+ );
496
526
 
497
527
  return { logs, maxLogsHit };
498
528
  }
@@ -516,20 +546,29 @@ export class LogStore {
516
546
  start,
517
547
  end,
518
548
  })) {
519
- const contractClassLogsInBlock: [ContractClassLog[]] = [[]];
549
+ const contractClassLogsInBlock: { txHash: TxHash; logs: ContractClassLog[] }[] = [];
520
550
  const reader = new BufferReader(logBuffer);
521
551
  const blockHash = this.#unpackBlockHash(reader);
522
552
  while (reader.remainingBytes() > 0) {
523
553
  const indexOfTx = reader.readNumber();
554
+ const txHash = reader.readObject(TxHash);
524
555
  const numLogsInTx = reader.readNumber();
525
- contractClassLogsInBlock[indexOfTx] = [];
556
+ contractClassLogsInBlock[indexOfTx] = { txHash, logs: [] };
526
557
  for (let i = 0; i < numLogsInTx; i++) {
527
- contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
558
+ contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
528
559
  }
529
560
  }
530
561
  for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < contractClassLogsInBlock.length; txIndex++) {
531
- const txLogs = contractClassLogsInBlock[txIndex];
532
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
562
+ const txData = contractClassLogsInBlock[txIndex];
563
+ maxLogsHit = this.#accumulateContractClassLogs(
564
+ logs,
565
+ blockNumber,
566
+ blockHash,
567
+ txIndex,
568
+ txData.txHash,
569
+ txData.logs,
570
+ filter,
571
+ );
533
572
  if (maxLogsHit) {
534
573
  this.#log.debug(`Max logs hit at block ${blockNumber}`);
535
574
  break loopOverBlocks;
@@ -540,12 +579,13 @@ export class LogStore {
540
579
  return { logs, maxLogsHit };
541
580
  }
542
581
 
543
- #accumulateLogs(
544
- results: (ExtendedContractClassLog | ExtendedPublicLog)[],
582
+ #accumulatePublicLogs(
583
+ results: ExtendedPublicLog[],
545
584
  blockNumber: number,
546
- blockHash: L2BlockHash,
585
+ blockHash: BlockHash,
547
586
  txIndex: number,
548
- txLogs: (ContractClassLog | PublicLog)[],
587
+ txHash: TxHash,
588
+ txLogs: PublicLog[],
549
589
  filter: LogFilter = {},
550
590
  ): boolean {
551
591
  let maxLogsHit = false;
@@ -553,15 +593,37 @@ export class LogStore {
553
593
  for (; logIndex < txLogs.length; logIndex++) {
554
594
  const log = txLogs[logIndex];
555
595
  if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
556
- if (log instanceof ContractClassLog) {
557
- results.push(
558
- new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log),
559
- );
560
- } else if (log instanceof PublicLog) {
561
- results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
562
- } else {
563
- throw new Error('Unknown log type');
596
+ results.push(
597
+ new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log),
598
+ );
599
+
600
+ if (results.length >= this.#logsMaxPageSize) {
601
+ maxLogsHit = true;
602
+ break;
564
603
  }
604
+ }
605
+ }
606
+
607
+ return maxLogsHit;
608
+ }
609
+
610
+ #accumulateContractClassLogs(
611
+ results: ExtendedContractClassLog[],
612
+ blockNumber: number,
613
+ blockHash: BlockHash,
614
+ txIndex: number,
615
+ txHash: TxHash,
616
+ txLogs: ContractClassLog[],
617
+ filter: LogFilter = {},
618
+ ): boolean {
619
+ let maxLogsHit = false;
620
+ let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
621
+ for (; logIndex < txLogs.length; logIndex++) {
622
+ const log = txLogs[logIndex];
623
+ if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
624
+ results.push(
625
+ new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log),
626
+ );
565
627
 
566
628
  if (results.length >= this.#logsMaxPageSize) {
567
629
  maxLogsHit = true;
@@ -10,7 +10,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
10
10
  import { EthAddress } from '@aztec/foundation/eth-address';
11
11
  import { createLogger } from '@aztec/foundation/log';
12
12
  import { RollupAbi } from '@aztec/l1-artifacts';
13
- import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2BlockNew } from '@aztec/stdlib/block';
13
+ import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2Block } from '@aztec/stdlib/block';
14
14
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
15
15
  import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
16
16
  import { InboxLeaf } from '@aztec/stdlib/messaging';
@@ -51,7 +51,7 @@ type AddCheckpointOptions = {
51
51
  /** Number of L2 blocks in the checkpoint. Default: 1 */
52
52
  numBlocks?: number;
53
53
  /** Or the actual blocks for the checkpoint */
54
- blocks?: L2BlockNew[];
54
+ blocks?: L2Block[];
55
55
  /** Number of transactions per block. Default: 4 */
56
56
  txsPerBlock?: number;
57
57
  /** Max number of effects per tx (for generating large blobs). Default: undefined */
package/src/test/index.ts CHANGED
@@ -2,3 +2,6 @@ export * from './mock_structs.js';
2
2
  export * from './mock_l2_block_source.js';
3
3
  export * from './mock_l1_to_l2_message_source.js';
4
4
  export * from './mock_archiver.js';
5
+ // NOTE: noop_l1_archiver.js is intentionally NOT exported here because it imports
6
+ // jest-mock-extended, which depends on @jest/globals and can only run inside Jest.
7
+ // Import it directly: import { NoopL1Archiver } from '@aztec/archiver/test/noop-l1';
@@ -57,7 +57,7 @@ export class MockPrefilledArchiver extends MockArchiver {
57
57
 
58
58
  const fromBlock = this.l2Blocks.length;
59
59
  // TODO: Add L2 blocks and checkpoints separately once archiver has the apis for that.
60
- this.addBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).flatMap(c => c.blocks));
60
+ this.addProposedBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).flatMap(c => c.blocks));
61
61
  return Promise.resolve();
62
62
  }
63
63
  }
@@ -8,9 +8,9 @@ import { createLogger } from '@aztec/foundation/log';
8
8
  import type { FunctionSelector } from '@aztec/stdlib/abi';
9
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
10
10
  import {
11
+ BlockHash,
11
12
  CheckpointedL2Block,
12
- L2BlockHash,
13
- L2BlockNew,
13
+ L2Block,
14
14
  type L2BlockSource,
15
15
  type L2Tips,
16
16
  type ValidateCheckpointResult,
@@ -18,14 +18,14 @@ import {
18
18
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
19
19
  import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
20
20
  import { EmptyL1RollupConstants, type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
21
- import { type BlockHeader, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
21
+ import { type BlockHeader, TxExecutionResult, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
22
22
  import type { UInt64 } from '@aztec/stdlib/types';
23
23
 
24
24
  /**
25
25
  * A mocked implementation of L2BlockSource to be used in tests.
26
26
  */
27
27
  export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
28
- protected l2Blocks: L2BlockNew[] = [];
28
+ protected l2Blocks: L2Block[] = [];
29
29
 
30
30
  private provenBlockNumber: number = 0;
31
31
  private finalizedBlockNumber: number = 0;
@@ -36,16 +36,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
36
36
  public async createBlocks(numBlocks: number) {
37
37
  for (let i = 0; i < numBlocks; i++) {
38
38
  const blockNum = this.l2Blocks.length + 1;
39
- const block = await L2BlockNew.random(BlockNumber(blockNum), { slotNumber: SlotNumber(blockNum) });
39
+ const block = await L2Block.random(BlockNumber(blockNum), { slotNumber: SlotNumber(blockNum) });
40
40
  this.l2Blocks.push(block);
41
41
  }
42
42
 
43
43
  this.log.verbose(`Created ${numBlocks} blocks in the mock L2 block source`);
44
44
  }
45
45
 
46
- public addBlocks(blocks: L2BlockNew[]) {
46
+ public addProposedBlocks(blocks: L2Block[]) {
47
47
  this.l2Blocks.push(...blocks);
48
- this.log.verbose(`Added ${blocks.length} blocks to the mock L2 block source`);
48
+ this.log.verbose(`Added ${blocks.length} proposed blocks to the mock L2 block source`);
49
49
  }
50
50
 
51
51
  public removeBlocks(numBlocks: number) {
@@ -96,6 +96,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
96
96
  return Promise.resolve(BlockNumber(this.provenBlockNumber));
97
97
  }
98
98
 
99
+ public getCheckpointedL2BlockNumber() {
100
+ return Promise.resolve(BlockNumber(this.checkpointedBlockNumber));
101
+ }
102
+
103
+ public getFinalizedL2BlockNumber() {
104
+ return Promise.resolve(BlockNumber(this.finalizedBlockNumber));
105
+ }
106
+
99
107
  public getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
100
108
  if (number > this.checkpointedBlockNumber) {
101
109
  return Promise.resolve(undefined);
@@ -105,7 +113,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
105
113
  return Promise.resolve(undefined);
106
114
  }
107
115
  const checkpointedBlock = new CheckpointedL2Block(
108
- CheckpointNumber(number),
116
+ CheckpointNumber.fromBlockNumber(number),
109
117
  block,
110
118
  new L1PublishedData(BigInt(number), BigInt(number), `0x${number.toString(16).padStart(64, '0')}`),
111
119
  [],
@@ -113,11 +121,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
113
121
  return Promise.resolve(checkpointedBlock);
114
122
  }
115
123
 
116
- public async getCheckpointedBlocks(
117
- from: BlockNumber,
118
- limit: number,
119
- _proven?: boolean,
120
- ): Promise<CheckpointedL2Block[]> {
124
+ public async getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
121
125
  const result: CheckpointedL2Block[] = [];
122
126
  for (let i = 0; i < limit; i++) {
123
127
  const blockNum = from + i;
@@ -137,7 +141,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
137
141
  * @param number - The block number to return (inclusive).
138
142
  * @returns The requested L2 block.
139
143
  */
140
- public getBlock(number: number): Promise<L2BlockNew | undefined> {
144
+ public getBlock(number: number): Promise<L2Block | undefined> {
141
145
  const block = this.l2Blocks[number - 1];
142
146
  return Promise.resolve(block);
143
147
  }
@@ -147,7 +151,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
147
151
  * @param number - The block number to return.
148
152
  * @returns The requested L2 block.
149
153
  */
150
- public getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
154
+ public getL2Block(number: BlockNumber): Promise<L2Block | undefined> {
151
155
  const block = this.l2Blocks[number - 1];
152
156
  return Promise.resolve(block);
153
157
  }
@@ -158,20 +162,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
158
162
  * @param limit - The maximum number of blocks to return.
159
163
  * @returns The requested mocked L2 blocks.
160
164
  */
161
- public getBlocks(from: number, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
162
- return Promise.resolve(
163
- this.l2Blocks
164
- .slice(from - 1, from - 1 + limit)
165
- .filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber),
166
- );
165
+ public getBlocks(from: number, limit: number): Promise<L2Block[]> {
166
+ return Promise.resolve(this.l2Blocks.slice(from - 1, from - 1 + limit));
167
167
  }
168
168
 
169
- public getPublishedCheckpoints(from: CheckpointNumber, limit: number) {
169
+ public getCheckpoints(from: CheckpointNumber, limit: number) {
170
170
  // TODO(mbps): Implement this properly. This only works when we have one block per checkpoint.
171
171
  const blocks = this.l2Blocks.slice(from - 1, from - 1 + limit);
172
172
  return Promise.all(
173
173
  blocks.map(async block => {
174
- // Create a checkpoint from the block - manually construct since L2BlockNew doesn't have toCheckpoint()
174
+ // Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
175
175
  const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
176
176
  checkpoint.blocks = [block];
177
177
  return new PublishedCheckpoint(
@@ -189,39 +189,18 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
189
189
  if (!block) {
190
190
  return undefined;
191
191
  }
192
- // Create a checkpoint from the block - manually construct since L2BlockNew doesn't have toCheckpoint()
192
+ // Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
193
193
  const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
194
194
  checkpoint.blocks = [block];
195
195
  return checkpoint;
196
196
  }
197
197
 
198
- public getPublishedBlocks(from: number, limit: number, proven?: boolean): Promise<CheckpointedL2Block[]> {
199
- const blocks = this.l2Blocks
200
- .slice(from - 1, from - 1 + limit)
201
- .filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber);
202
- return Promise.resolve(
203
- blocks.map(block =>
204
- CheckpointedL2Block.fromFields({
205
- checkpointNumber: CheckpointNumber(block.number),
206
- block,
207
- l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
208
- attestations: [],
209
- }),
210
- ),
211
- );
212
- }
213
-
214
- getL2BlocksNew(from: BlockNumber, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
215
- // getBlocks already returns L2BlockNew[], so just return directly
216
- return this.getBlocks(from, limit, proven);
217
- }
218
-
219
- public async getPublishedBlockByHash(blockHash: Fr): Promise<CheckpointedL2Block | undefined> {
198
+ public async getCheckpointedBlockByHash(blockHash: BlockHash): Promise<CheckpointedL2Block | undefined> {
220
199
  for (const block of this.l2Blocks) {
221
200
  const hash = await block.hash();
222
201
  if (hash.equals(blockHash)) {
223
202
  return CheckpointedL2Block.fromFields({
224
- checkpointNumber: CheckpointNumber(block.number),
203
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
225
204
  block,
226
205
  l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
227
206
  attestations: [],
@@ -231,14 +210,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
231
210
  return undefined;
232
211
  }
233
212
 
234
- public getPublishedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
213
+ public getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
235
214
  const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
236
215
  if (!block) {
237
216
  return Promise.resolve(undefined);
238
217
  }
239
218
  return Promise.resolve(
240
219
  CheckpointedL2Block.fromFields({
241
- checkpointNumber: CheckpointNumber(block.number),
220
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
242
221
  block,
243
222
  l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
244
223
  attestations: [],
@@ -246,7 +225,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
246
225
  );
247
226
  }
248
227
 
249
- public async getL2BlockNewByHash(blockHash: Fr): Promise<L2BlockNew | undefined> {
228
+ public async getL2BlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
250
229
  for (const block of this.l2Blocks) {
251
230
  const hash = await block.hash();
252
231
  if (hash.equals(blockHash)) {
@@ -256,12 +235,12 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
256
235
  return undefined;
257
236
  }
258
237
 
259
- public getL2BlockNewByArchive(archive: Fr): Promise<L2BlockNew | undefined> {
238
+ public getL2BlockByArchive(archive: Fr): Promise<L2Block | undefined> {
260
239
  const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
261
240
  return Promise.resolve(block);
262
241
  }
263
242
 
264
- public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
243
+ public async getBlockHeaderByHash(blockHash: BlockHash): Promise<BlockHeader | undefined> {
265
244
  for (const block of this.l2Blocks) {
266
245
  const hash = await block.hash();
267
246
  if (hash.equals(blockHash)) {
@@ -288,7 +267,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
288
267
  const slot = b.header.globalVariables.slotNumber;
289
268
  return slot >= start && slot <= end;
290
269
  });
291
- // Create checkpoints from blocks - manually construct since L2BlockNew doesn't have toCheckpoint()
270
+ // Create checkpoints from blocks - manually construct since L2Block doesn't have toCheckpoint()
292
271
  return Promise.all(
293
272
  blocks.map(async block => {
294
273
  const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
@@ -298,24 +277,33 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
298
277
  );
299
278
  }
300
279
 
301
- getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2BlockNew[]> {
280
+ getCheckpointedBlocksForEpoch(epochNumber: EpochNumber): Promise<CheckpointedL2Block[]> {
302
281
  const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
303
282
  const [start, end] = getSlotRangeForEpoch(epochNumber, { epochDuration });
304
283
  const blocks = this.l2Blocks.filter(b => {
305
284
  const slot = b.header.globalVariables.slotNumber;
306
285
  return slot >= start && slot <= end;
307
286
  });
308
- return Promise.resolve(blocks);
287
+ return Promise.resolve(
288
+ blocks.map(block =>
289
+ CheckpointedL2Block.fromFields({
290
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
291
+ block,
292
+ l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
293
+ attestations: [],
294
+ }),
295
+ ),
296
+ );
309
297
  }
310
298
 
311
- getBlocksForSlot(slotNumber: SlotNumber): Promise<L2BlockNew[]> {
299
+ getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
312
300
  const blocks = this.l2Blocks.filter(b => b.header.globalVariables.slotNumber === slotNumber);
313
301
  return Promise.resolve(blocks);
314
302
  }
315
303
 
316
- async getBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
317
- const blocks = await this.getBlocksForEpoch(epochNumber);
318
- return blocks.map(b => b.header);
304
+ async getCheckpointedBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
305
+ const checkpointedBlocks = await this.getCheckpointedBlocksForEpoch(epochNumber);
306
+ return checkpointedBlocks.map(b => b.block.header);
319
307
  }
320
308
 
321
309
  /**
@@ -334,7 +322,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
334
322
  return {
335
323
  data: txEffect,
336
324
  l2BlockNumber: block.number,
337
- l2BlockHash: L2BlockHash.fromField(await block.hash()),
325
+ l2BlockHash: await block.hash(),
338
326
  txIndexInBlock: block.body.txEffects.indexOf(txEffect),
339
327
  };
340
328
  }
@@ -348,12 +336,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
348
336
  for (const block of this.l2Blocks) {
349
337
  for (const txEffect of block.body.txEffects) {
350
338
  if (txEffect.txHash.equals(txHash)) {
339
+ // In mock, assume all txs are checkpointed with successful execution
351
340
  return new TxReceipt(
352
341
  txHash,
353
- TxStatus.SUCCESS,
354
- '',
342
+ TxStatus.CHECKPOINTED,
343
+ TxExecutionResult.SUCCESS,
344
+ undefined,
355
345
  txEffect.transactionFee.toBigInt(),
356
- L2BlockHash.fromField(await block.hash()),
346
+ await block.hash(),
357
347
  block.number,
358
348
  );
359
349
  }
@@ -394,7 +384,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
394
384
 
395
385
  const makeTipId = (blockId: typeof latestBlockId) => ({
396
386
  block: blockId,
397
- checkpoint: { number: CheckpointNumber(blockId.number), hash: blockId.hash },
387
+ checkpoint: { number: CheckpointNumber.fromBlockNumber(blockId.number), hash: blockId.hash },
398
388
  });
399
389
 
400
390
  return {