@aztec/archiver 3.0.0-nightly.20251208 → 3.0.0-nightly.20251210

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 (58) hide show
  1. package/dest/archiver/archiver.d.ts +8 -9
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +31 -18
  4. package/dest/archiver/archiver_store.d.ts +8 -8
  5. package/dest/archiver/archiver_store.d.ts.map +1 -1
  6. package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
  7. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  8. package/dest/archiver/archiver_store_test_suite.js +54 -53
  9. package/dest/archiver/data_retrieval.d.ts +2 -2
  10. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  11. package/dest/archiver/data_retrieval.js +7 -6
  12. package/dest/archiver/kv_archiver_store/block_store.d.ts +2 -2
  13. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  14. package/dest/archiver/kv_archiver_store/block_store.js +1 -1
  15. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -2
  16. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  17. package/dest/archiver/kv_archiver_store/contract_class_store.js +1 -1
  18. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +2 -2
  19. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
  20. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +7 -7
  21. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  22. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +6 -6
  23. package/dest/archiver/kv_archiver_store/log_store.d.ts +2 -2
  24. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  25. package/dest/archiver/kv_archiver_store/message_store.d.ts +5 -4
  26. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  27. package/dest/archiver/kv_archiver_store/message_store.js +15 -14
  28. package/dest/archiver/structs/inbox_message.d.ts +4 -4
  29. package/dest/archiver/structs/inbox_message.d.ts.map +1 -1
  30. package/dest/archiver/structs/inbox_message.js +6 -6
  31. package/dest/test/mock_archiver.d.ts +4 -5
  32. package/dest/test/mock_archiver.d.ts.map +1 -1
  33. package/dest/test/mock_archiver.js +5 -9
  34. package/dest/test/mock_l1_to_l2_message_source.d.ts +5 -6
  35. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  36. package/dest/test/mock_l1_to_l2_message_source.js +7 -11
  37. package/dest/test/mock_l2_block_source.d.ts +2 -2
  38. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  39. package/dest/test/mock_l2_block_source.js +1 -1
  40. package/dest/test/mock_structs.d.ts +3 -2
  41. package/dest/test/mock_structs.d.ts.map +1 -1
  42. package/dest/test/mock_structs.js +9 -9
  43. package/package.json +13 -13
  44. package/src/archiver/archiver.ts +34 -20
  45. package/src/archiver/archiver_store.ts +7 -7
  46. package/src/archiver/archiver_store_test_suite.ts +63 -55
  47. package/src/archiver/data_retrieval.ts +7 -6
  48. package/src/archiver/kv_archiver_store/block_store.ts +1 -1
  49. package/src/archiver/kv_archiver_store/contract_class_store.ts +1 -1
  50. package/src/archiver/kv_archiver_store/contract_instance_store.ts +1 -1
  51. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +8 -8
  52. package/src/archiver/kv_archiver_store/log_store.ts +1 -1
  53. package/src/archiver/kv_archiver_store/message_store.ts +20 -17
  54. package/src/archiver/structs/inbox_message.ts +7 -8
  55. package/src/test/mock_archiver.ts +6 -11
  56. package/src/test/mock_l1_to_l2_message_source.ts +6 -11
  57. package/src/test/mock_l2_block_source.ts +1 -1
  58. package/src/test/mock_structs.ts +10 -10
@@ -13,8 +13,8 @@ import { maxBigint } from '@aztec/foundation/bigint';
13
13
  import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
14
14
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
15
15
  import { merge, pick } from '@aztec/foundation/collection';
16
+ import { Fr } from '@aztec/foundation/curves/bn254';
16
17
  import type { EthAddress } from '@aztec/foundation/eth-address';
17
- import { Fr } from '@aztec/foundation/fields';
18
18
  import { type Logger, createLogger } from '@aztec/foundation/log';
19
19
  import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise';
20
20
  import { RunningPromise, makeLoggingErrorHandler } from '@aztec/foundation/running-promise';
@@ -63,7 +63,7 @@ import {
63
63
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
64
64
  import type { L2LogsSource } from '@aztec/stdlib/interfaces/server';
65
65
  import { ContractClassLog, type LogFilter, type PrivateLog, type PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
66
- import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
66
+ import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
67
67
  import type { CheckpointHeader } from '@aztec/stdlib/rollup';
68
68
  import { type BlockHeader, type IndexedTxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
69
69
  import type { UInt64 } from '@aztec/stdlib/types';
@@ -594,7 +594,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
594
594
  // Log stats for messages retrieved (if any).
595
595
  if (messageCount > 0) {
596
596
  this.log.info(
597
- `Retrieved ${messageCount} new L1 to L2 messages up to message with index ${lastMessage?.index} for L2 block ${lastMessage?.l2BlockNumber}`,
597
+ `Retrieved ${messageCount} new L1 to L2 messages up to message with index ${lastMessage?.index} for checkpoint ${lastMessage?.checkpointNumber}`,
598
598
  { lastMessage, messageCount },
599
599
  );
600
600
  }
@@ -916,6 +916,25 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
916
916
  continue;
917
917
  }
918
918
 
919
+ // Check the inHash of the checkpoint against the l1->l2 messages.
920
+ // The messages should've been synced up to the currentL1BlockNumber and must be available for the published
921
+ // checkpoints we just retrieved.
922
+ const l1ToL2Messages = await this.getL1ToL2Messages(published.checkpoint.number);
923
+ const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
924
+ const publishedInHash = published.checkpoint.header.contentCommitment.inHash;
925
+ if (!computedInHash.equals(publishedInHash)) {
926
+ this.log.fatal(`Mismatch inHash for checkpoint ${published.checkpoint.number}`, {
927
+ checkpointHash: published.checkpoint.hash(),
928
+ l1BlockNumber: published.l1.blockNumber,
929
+ computedInHash,
930
+ publishedInHash,
931
+ });
932
+ // Throwing an error since this is most likely caused by a bug.
933
+ throw new Error(
934
+ `Mismatch inHash for checkpoint ${published.checkpoint.number}. Expected ${computedInHash} but got ${publishedInHash}`,
935
+ );
936
+ }
937
+
919
938
  validCheckpoints.push(published);
920
939
  this.log.debug(
921
940
  `Ingesting new checkpoint ${published.checkpoint.number} with ${published.checkpoint.blocks.length} blocks`,
@@ -969,7 +988,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
969
988
  });
970
989
  }
971
990
  lastRetrievedCheckpoint = validCheckpoints.at(-1) ?? lastRetrievedCheckpoint;
972
- lastL1BlockWithCheckpoint = publishedCheckpoints.at(-1)?.l1.blockNumber ?? lastL1BlockWithCheckpoint;
991
+ lastL1BlockWithCheckpoint = retrievedCheckpoints.at(-1)?.l1.blockNumber ?? lastL1BlockWithCheckpoint;
973
992
  } while (searchEndBlock < currentL1BlockNumber);
974
993
 
975
994
  // Important that we update AFTER inserting the blocks.
@@ -1247,12 +1266,6 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1247
1266
  return blocks.map(b => b.toCheckpoint());
1248
1267
  }
1249
1268
 
1250
- public getL1ToL2MessagesForCheckpoint(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
1251
- // TODO: Create dedicated api for checkpoints.
1252
- // This only works when we have one block per checkpoint.
1253
- return this.getL1ToL2Messages(BlockNumber.fromCheckpointNumber(checkpointNumber));
1254
- }
1255
-
1256
1269
  /**
1257
1270
  * Gets up to `limit` amount of L2 blocks starting from `from`.
1258
1271
  * @param from - Number of the first block to return (inclusive).
@@ -1404,12 +1417,12 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1404
1417
  }
1405
1418
 
1406
1419
  /**
1407
- * Gets L1 to L2 message (to be) included in a given block.
1408
- * @param blockNumber - L2 block number to get messages for.
1420
+ * Gets L1 to L2 message (to be) included in a given checkpoint.
1421
+ * @param checkpointNumber - Checkpoint number to get messages for.
1409
1422
  * @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
1410
1423
  */
1411
- getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]> {
1412
- return this.store.getL1ToL2Messages(blockNumber);
1424
+ getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
1425
+ return this.store.getL1ToL2Messages(checkpointNumber);
1413
1426
  }
1414
1427
 
1415
1428
  /**
@@ -1500,11 +1513,12 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1500
1513
  throw new Error(`Target L2 block ${targetL2BlockNumber} not found`);
1501
1514
  }
1502
1515
  const targetL1BlockNumber = targetL2Block.l1.blockNumber;
1516
+ const targetCheckpointNumber = CheckpointNumber.fromBlockNumber(targetL2BlockNumber);
1503
1517
  const targetL1BlockHash = await this.getL1BlockHash(targetL1BlockNumber);
1504
1518
  this.log.info(`Unwinding ${blocksToUnwind} blocks from L2 block ${currentL2Block}`);
1505
1519
  await this.store.unwindBlocks(BlockNumber(currentL2Block), blocksToUnwind);
1506
- this.log.info(`Unwinding L1 to L2 messages to ${targetL2BlockNumber}`);
1507
- await this.store.rollbackL1ToL2MessagesToL2Block(targetL2BlockNumber);
1520
+ this.log.info(`Unwinding L1 to L2 messages to checkpoint ${targetCheckpointNumber}`);
1521
+ await this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
1508
1522
  this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
1509
1523
  await this.store.setBlockSynchedL1BlockNumber(targetL1BlockNumber);
1510
1524
  await this.store.setMessageSynchedL1Block({ l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash });
@@ -1798,8 +1812,8 @@ export class ArchiverStoreHelper
1798
1812
  addL1ToL2Messages(messages: InboxMessage[]): Promise<void> {
1799
1813
  return this.store.addL1ToL2Messages(messages);
1800
1814
  }
1801
- getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]> {
1802
- return this.store.getL1ToL2Messages(blockNumber);
1815
+ getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
1816
+ return this.store.getL1ToL2Messages(checkpointNumber);
1803
1817
  }
1804
1818
  getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined> {
1805
1819
  return this.store.getL1ToL2MessageIndex(l1ToL2Message);
@@ -1858,8 +1872,8 @@ export class ArchiverStoreHelper
1858
1872
  estimateSize(): Promise<{ mappingSize: number; physicalFileSize: number; actualSize: number; numItems: number }> {
1859
1873
  return this.store.estimateSize();
1860
1874
  }
1861
- rollbackL1ToL2MessagesToL2Block(targetBlockNumber: BlockNumber): Promise<void> {
1862
- return this.store.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
1875
+ rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber: CheckpointNumber): Promise<void> {
1876
+ return this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
1863
1877
  }
1864
1878
  iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
1865
1879
  return this.store.iterateL1ToL2Messages(range);
@@ -1,6 +1,6 @@
1
1
  import type { L1BlockId } from '@aztec/ethereum';
2
- import { BlockNumber } from '@aztec/foundation/branded-types';
3
- import type { Fr } from '@aztec/foundation/fields';
2
+ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
3
+ import type { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import type { CustomRange } from '@aztec/kv-store';
5
5
  import type { FunctionSelector } from '@aztec/stdlib/abi';
6
6
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -132,11 +132,11 @@ export interface ArchiverDataStore {
132
132
  addL1ToL2Messages(messages: InboxMessage[]): Promise<void>;
133
133
 
134
134
  /**
135
- * Gets L1 to L2 message (to be) included in a given block.
136
- * @param blockNumber - L2 block number to get messages for.
135
+ * Gets L1 to L2 message (to be) included in a given checkpoint.
136
+ * @param checkpointNumber - Checkpoint number to get messages for.
137
137
  * @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
138
138
  */
139
- getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]>;
139
+ getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]>;
140
140
 
141
141
  /**
142
142
  * Gets the L1 to L2 message index in the L1 to L2 message tree.
@@ -290,8 +290,8 @@ export interface ArchiverDataStore {
290
290
  /** Closes the underlying data store. */
291
291
  close(): Promise<void>;
292
292
 
293
- /** Deletes all L1 to L2 messages up until (excluding) the target L2 block number. */
294
- rollbackL1ToL2MessagesToL2Block(targetBlockNumber: BlockNumber): Promise<void>;
293
+ /** Deletes all L1 to L2 messages up until (excluding) the target checkpoint number. */
294
+ rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber: CheckpointNumber): Promise<void>;
295
295
 
296
296
  /** Returns an async iterator to all L1 to L2 messages on the range. */
297
297
  iterateL1ToL2Messages(range?: CustomRange<bigint>): AsyncIterableIterator<InboxMessage>;
@@ -4,11 +4,11 @@ import {
4
4
  PRIVATE_LOG_SIZE_IN_FIELDS,
5
5
  } from '@aztec/constants';
6
6
  import { makeTuple } from '@aztec/foundation/array';
7
- import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
7
+ import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
8
8
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
9
9
  import { times, timesParallel } from '@aztec/foundation/collection';
10
- import { randomInt } from '@aztec/foundation/crypto';
11
- import { Fr } from '@aztec/foundation/fields';
10
+ import { randomInt } from '@aztec/foundation/crypto/random';
11
+ import { Fr } from '@aztec/foundation/curves/bn254';
12
12
  import { toArray } from '@aztec/foundation/iterable';
13
13
  import { sleep } from '@aztec/foundation/sleep';
14
14
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -20,7 +20,7 @@ import {
20
20
  PublishedL2Block,
21
21
  type ValidateBlockResult,
22
22
  randomBlockInfo,
23
- wrapInBlock,
23
+ wrapDataInBlock,
24
24
  } from '@aztec/stdlib/block';
25
25
  import {
26
26
  type ContractClassPublic,
@@ -413,11 +413,11 @@ export function describeArchiverDataStore(
413
413
  });
414
414
 
415
415
  it.each([
416
- () => wrapInBlock(blocks[0].block.body.txEffects[0], blocks[0].block),
417
- () => wrapInBlock(blocks[9].block.body.txEffects[3], blocks[9].block),
418
- () => wrapInBlock(blocks[3].block.body.txEffects[1], blocks[3].block),
419
- () => wrapInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
420
- () => wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block),
416
+ () => wrapDataInBlock(blocks[0].block.body.txEffects[0], blocks[0].block),
417
+ () => wrapDataInBlock(blocks[9].block.body.txEffects[3], blocks[9].block),
418
+ () => wrapDataInBlock(blocks[3].block.body.txEffects[1], blocks[3].block),
419
+ () => wrapDataInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
420
+ () => wrapDataInBlock(blocks[1].block.body.txEffects[0], blocks[1].block),
421
421
  ])('tries to retrieves a previously stored transaction after deleted', async getExpectedTx => {
422
422
  await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
423
423
 
@@ -431,7 +431,7 @@ export function describeArchiverDataStore(
431
431
  });
432
432
 
433
433
  it('does not fail if the block is unwound while requesting a tx', async () => {
434
- const expectedTx = await wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block);
434
+ const expectedTx = await wrapDataInBlock(blocks[1].block.body.txEffects[0], blocks[1].block);
435
435
  let done = false;
436
436
  void (async () => {
437
437
  while (!done) {
@@ -446,7 +446,7 @@ export function describeArchiverDataStore(
446
446
  });
447
447
 
448
448
  describe('L1 to L2 Messages', () => {
449
- const initialL2BlockNumber = 13;
449
+ const initialCheckpointNumber = CheckpointNumber(13);
450
450
 
451
451
  const checkMessages = async (msgs: InboxMessage[]) => {
452
452
  expect(await store.getLastL1ToL2Message()).toEqual(msgs.at(-1));
@@ -454,46 +454,50 @@ export function describeArchiverDataStore(
454
454
  expect(await store.getTotalL1ToL2MessageCount()).toEqual(BigInt(msgs.length));
455
455
  };
456
456
 
457
- const makeInboxMessagesWithFullBlocks = (blockCount: number, opts: { initialL2BlockNumber?: number } = {}) =>
457
+ const makeInboxMessagesWithFullBlocks = (
458
+ blockCount: number,
459
+ opts: { initialCheckpointNumber?: CheckpointNumber } = {},
460
+ ) =>
458
461
  makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
459
462
  overrideFn: (msg, i) => {
460
- const l2BlockNumber = BlockNumber(
461
- (opts.initialL2BlockNumber ?? initialL2BlockNumber) + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
463
+ const checkpointNumber = CheckpointNumber(
464
+ (opts.initialCheckpointNumber ?? initialCheckpointNumber) +
465
+ Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
462
466
  );
463
467
  const index =
464
- InboxLeaf.smallestIndexFromL2Block(l2BlockNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
465
- return { ...msg, l2BlockNumber, index };
468
+ InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
469
+ return { ...msg, checkpointNumber, index };
466
470
  },
467
471
  });
468
472
 
469
473
  it('stores first message ever', async () => {
470
- const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, l2BlockNumber: BlockNumber(1) });
474
+ const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, checkpointNumber: CheckpointNumber(1) });
471
475
  await store.addL1ToL2Messages([msg]);
472
476
 
473
477
  await checkMessages([msg]);
474
- expect(await store.getL1ToL2Messages(BlockNumber(1))).toEqual([msg.leaf]);
478
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toEqual([msg.leaf]);
475
479
  });
476
480
 
477
481
  it('stores single message', async () => {
478
- const msg = makeInboxMessage(Buffer16.ZERO, { l2BlockNumber: BlockNumber(2) });
482
+ const msg = makeInboxMessage(Buffer16.ZERO, { checkpointNumber: CheckpointNumber(2) });
479
483
  await store.addL1ToL2Messages([msg]);
480
484
 
481
485
  await checkMessages([msg]);
482
- expect(await store.getL1ToL2Messages(BlockNumber(2))).toEqual([msg.leaf]);
486
+ expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toEqual([msg.leaf]);
483
487
  });
484
488
 
485
489
  it('stores and returns messages across different blocks', async () => {
486
- const msgs = makeInboxMessages(5, { initialL2BlockNumber });
490
+ const msgs = makeInboxMessages(5, { initialCheckpointNumber });
487
491
  await store.addL1ToL2Messages(msgs);
488
492
 
489
493
  await checkMessages(msgs);
490
- expect(await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 2))).toEqual(
494
+ expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual(
491
495
  [msgs[2]].map(m => m.leaf),
492
496
  );
493
497
  });
494
498
 
495
499
  it('stores the same messages again', async () => {
496
- const msgs = makeInboxMessages(5, { initialL2BlockNumber });
500
+ const msgs = makeInboxMessages(5, { initialCheckpointNumber });
497
501
  await store.addL1ToL2Messages(msgs);
498
502
  await store.addL1ToL2Messages(msgs.slice(2));
499
503
 
@@ -501,26 +505,29 @@ export function describeArchiverDataStore(
501
505
  });
502
506
 
503
507
  it('stores and returns messages across different blocks with gaps', async () => {
504
- const msgs1 = makeInboxMessages(3, { initialL2BlockNumber: 1 });
505
- const msgs2 = makeInboxMessages(3, { initialL2BlockNumber: 20, initialHash: msgs1.at(-1)!.rollingHash });
508
+ const msgs1 = makeInboxMessages(3, { initialCheckpointNumber: CheckpointNumber(1) });
509
+ const msgs2 = makeInboxMessages(3, {
510
+ initialCheckpointNumber: CheckpointNumber(20),
511
+ initialHash: msgs1.at(-1)!.rollingHash,
512
+ });
506
513
 
507
514
  await store.addL1ToL2Messages(msgs1);
508
515
  await store.addL1ToL2Messages(msgs2);
509
516
 
510
517
  await checkMessages([...msgs1, ...msgs2]);
511
518
 
512
- expect(await store.getL1ToL2Messages(BlockNumber(1))).toEqual([msgs1[0].leaf]);
513
- expect(await store.getL1ToL2Messages(BlockNumber(4))).toEqual([]);
514
- expect(await store.getL1ToL2Messages(BlockNumber(20))).toEqual([msgs2[0].leaf]);
515
- expect(await store.getL1ToL2Messages(BlockNumber(24))).toEqual([]);
519
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toEqual([msgs1[0].leaf]);
520
+ expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toEqual([]);
521
+ expect(await store.getL1ToL2Messages(CheckpointNumber(20))).toEqual([msgs2[0].leaf]);
522
+ expect(await store.getL1ToL2Messages(CheckpointNumber(24))).toEqual([]);
516
523
  });
517
524
 
518
525
  it('stores and returns messages with block numbers larger than a byte', async () => {
519
- const msgs = makeInboxMessages(5, { initialL2BlockNumber: 1000 });
526
+ const msgs = makeInboxMessages(5, { initialCheckpointNumber: CheckpointNumber(1000) });
520
527
  await store.addL1ToL2Messages(msgs);
521
528
 
522
529
  await checkMessages(msgs);
523
- expect(await store.getL1ToL2Messages(BlockNumber(1002))).toEqual([msgs[2]].map(m => m.leaf));
530
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1002))).toEqual([msgs[2]].map(m => m.leaf));
524
531
  });
525
532
 
526
533
  it('stores and returns multiple messages per block', async () => {
@@ -528,7 +535,7 @@ export function describeArchiverDataStore(
528
535
  await store.addL1ToL2Messages(msgs);
529
536
 
530
537
  await checkMessages(msgs);
531
- const blockMessages = await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 1));
538
+ const blockMessages = await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 1));
532
539
  expect(blockMessages).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
533
540
  expect(blockMessages).toEqual(
534
541
  msgs.slice(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2).map(m => m.leaf),
@@ -536,21 +543,21 @@ export function describeArchiverDataStore(
536
543
  });
537
544
 
538
545
  it('stores messages in multiple operations', async () => {
539
- const msgs = makeInboxMessages(20, { initialL2BlockNumber });
546
+ const msgs = makeInboxMessages(20, { initialCheckpointNumber });
540
547
  await store.addL1ToL2Messages(msgs.slice(0, 10));
541
548
  await store.addL1ToL2Messages(msgs.slice(10, 20));
542
549
 
543
- expect(await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 2))).toEqual(
550
+ expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual(
544
551
  [msgs[2]].map(m => m.leaf),
545
552
  );
546
- expect(await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 12))).toEqual(
553
+ expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 12))).toEqual(
547
554
  [msgs[12]].map(m => m.leaf),
548
555
  );
549
556
  await checkMessages(msgs);
550
557
  });
551
558
 
552
559
  it('iterates over messages from start index', async () => {
553
- const msgs = makeInboxMessages(10, { initialL2BlockNumber });
560
+ const msgs = makeInboxMessages(10, { initialCheckpointNumber });
554
561
  await store.addL1ToL2Messages(msgs);
555
562
 
556
563
  const iterated = await toArray(store.iterateL1ToL2Messages({ start: msgs[3].index }));
@@ -558,8 +565,9 @@ export function describeArchiverDataStore(
558
565
  });
559
566
 
560
567
  it('iterates over messages in reverse', async () => {
561
- const msgs = makeInboxMessages(10, { initialL2BlockNumber });
568
+ const msgs = makeInboxMessages(10, { initialCheckpointNumber });
562
569
  await store.addL1ToL2Messages(msgs);
570
+ initialCheckpointNumber;
563
571
 
564
572
  const iterated = await toArray(store.iterateL1ToL2Messages({ reverse: true, end: msgs[3].index }));
565
573
  expect(iterated).toEqual(msgs.slice(0, 4).reverse());
@@ -571,8 +579,8 @@ export function describeArchiverDataStore(
571
579
  });
572
580
 
573
581
  it('throws if block number for the first message is out of order', async () => {
574
- const msgs = makeInboxMessages(4, { initialL2BlockNumber });
575
- msgs[2].l2BlockNumber = BlockNumber(initialL2BlockNumber - 1);
582
+ const msgs = makeInboxMessages(4, { initialCheckpointNumber });
583
+ msgs[2].checkpointNumber = CheckpointNumber(initialCheckpointNumber - 1);
576
584
  await store.addL1ToL2Messages(msgs.slice(0, 2));
577
585
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
578
586
  });
@@ -586,28 +594,28 @@ export function describeArchiverDataStore(
586
594
  it('throws if rolling hash for first message is not correct', async () => {
587
595
  const msgs = makeInboxMessages(4);
588
596
  msgs[2].rollingHash = Buffer16.random();
589
- await store.addL1ToL2Messages(msgs.slice(0, BlockNumber(2)));
597
+ await store.addL1ToL2Messages(msgs.slice(0, CheckpointNumber(2)));
590
598
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
591
599
  });
592
600
 
593
601
  it('throws if index is not in the correct range', async () => {
594
- const msgs = makeInboxMessages(5, { initialL2BlockNumber });
602
+ const msgs = makeInboxMessages(5, { initialCheckpointNumber });
595
603
  msgs.at(-1)!.index += 100n;
596
604
  await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
597
605
  });
598
606
 
599
607
  it('throws if first index in block has gaps', async () => {
600
- const msgs = makeInboxMessages(4, { initialL2BlockNumber });
608
+ const msgs = makeInboxMessages(4, { initialCheckpointNumber });
601
609
  msgs[2].index++;
602
610
  await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
603
611
  });
604
612
 
605
613
  it('throws if index does not follow previous one', async () => {
606
614
  const msgs = makeInboxMessages(2, {
607
- initialL2BlockNumber,
615
+ initialCheckpointNumber,
608
616
  overrideFn: (msg, i) => ({
609
617
  ...msg,
610
- l2BlockNumber: BlockNumber(2),
618
+ checkpointNumber: CheckpointNumber(2),
611
619
  index: BigInt(i + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2),
612
620
  }),
613
621
  });
@@ -616,28 +624,28 @@ export function describeArchiverDataStore(
616
624
  });
617
625
 
618
626
  it('removes messages up to the given block number', async () => {
619
- const msgs = makeInboxMessagesWithFullBlocks(4, { initialL2BlockNumber: 1 });
627
+ const msgs = makeInboxMessagesWithFullBlocks(4, { initialCheckpointNumber: CheckpointNumber(1) });
620
628
 
621
629
  await store.addL1ToL2Messages(msgs);
622
630
  await checkMessages(msgs);
623
631
 
624
- expect(await store.getL1ToL2Messages(BlockNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
625
- expect(await store.getL1ToL2Messages(BlockNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
626
- expect(await store.getL1ToL2Messages(BlockNumber(3))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
627
- expect(await store.getL1ToL2Messages(BlockNumber(4))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
632
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
633
+ expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
634
+ expect(await store.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
635
+ expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
628
636
 
629
- await store.rollbackL1ToL2MessagesToL2Block(BlockNumber(2));
637
+ await store.rollbackL1ToL2MessagesToCheckpoint(CheckpointNumber(2));
630
638
 
631
- expect(await store.getL1ToL2Messages(BlockNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
632
- expect(await store.getL1ToL2Messages(BlockNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
633
- expect(await store.getL1ToL2Messages(BlockNumber(3))).toHaveLength(0);
634
- expect(await store.getL1ToL2Messages(BlockNumber(4))).toHaveLength(0);
639
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
640
+ expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
641
+ expect(await store.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(0);
642
+ expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(0);
635
643
 
636
644
  await checkMessages(msgs.slice(0, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2));
637
645
  });
638
646
 
639
647
  it('removes messages starting with the given index', async () => {
640
- const msgs = makeInboxMessagesWithFullBlocks(4, { initialL2BlockNumber: 1 });
648
+ const msgs = makeInboxMessagesWithFullBlocks(4, { initialCheckpointNumber: CheckpointNumber(1) });
641
649
  await store.addL1ToL2Messages(msgs);
642
650
 
643
651
  await store.removeL1ToL2Messages(msgs[13].index);
@@ -14,11 +14,11 @@ import type {
14
14
  ViemPublicClient,
15
15
  } from '@aztec/ethereum';
16
16
  import { asyncPool } from '@aztec/foundation/async-pool';
17
- import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
17
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
18
18
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
19
+ import { Fr } from '@aztec/foundation/curves/bn254';
19
20
  import type { EthAddress } from '@aztec/foundation/eth-address';
20
21
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
21
- import { Fr } from '@aztec/foundation/fields';
22
22
  import { type Logger, createLogger } from '@aztec/foundation/log';
23
23
  import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
24
24
  import { Body, CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
@@ -72,8 +72,8 @@ export async function retrievedToPublishedCheckpoint({
72
72
  .slice(1)
73
73
  .concat([archiveRoot]);
74
74
 
75
- // `blocksBlobData` is created from `decodeCheckpointBlobDataFromBlobs`. An error will be thrown if it can't read a
76
- // field for the `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists:
75
+ // An error will be thrown from `decodeCheckpointBlobDataFromBlobs` if it can't read a field for the
76
+ // `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists:
77
77
  const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot!;
78
78
 
79
79
  const spongeBlob = SpongeBlob.init();
@@ -127,7 +127,7 @@ export async function retrievedToPublishedCheckpoint({
127
127
 
128
128
  const newArchive = new AppendOnlyTreeSnapshot(newArchiveRoots[i], l2BlockNumber + 1);
129
129
 
130
- l2Blocks.push(new L2BlockNew(newArchive, header, body));
130
+ l2Blocks.push(new L2BlockNew(newArchive, header, body, checkpointNumber, i));
131
131
  }
132
132
 
133
133
  const lastBlock = l2Blocks.at(-1)!;
@@ -404,6 +404,7 @@ async function getCheckpointFromRollupTx(
404
404
  } else {
405
405
  logger.fatal('Unable to sync: failed to decode fetched blob, this blob was likely not created by us');
406
406
  }
407
+ // Throwing an error since this is most likely caused by a bug.
407
408
  throw err;
408
409
  }
409
410
 
@@ -470,7 +471,7 @@ function mapLogsInboxMessage(logs: GetContractEventsReturnType<typeof InboxAbi,
470
471
  leaf: Fr.fromHexString(hash!),
471
472
  l1BlockNumber: log.blockNumber,
472
473
  l1BlockHash: Buffer32.fromString(log.blockHash),
473
- l2BlockNumber: BlockNumber(Number(checkpointNumber!)),
474
+ checkpointNumber: CheckpointNumber.fromBigInt(checkpointNumber!),
474
475
  rollingHash: Buffer16.fromString(rollingHash!),
475
476
  };
476
477
  });
@@ -1,6 +1,6 @@
1
1
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
- import { Fr } from '@aztec/foundation/fields';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { toArray } from '@aztec/foundation/iterable';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import { BufferReader } from '@aztec/foundation/serialize';
@@ -1,4 +1,4 @@
1
- import { Fr } from '@aztec/foundation/fields';
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { toArray } from '@aztec/foundation/iterable';
3
3
  import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/serialize';
4
4
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
@@ -1,4 +1,4 @@
1
- import type { Fr } from '@aztec/foundation/fields';
1
+ import type { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
3
3
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
4
  import {
@@ -1,6 +1,6 @@
1
1
  import type { L1BlockId } from '@aztec/ethereum';
2
- import { BlockNumber } from '@aztec/foundation/branded-types';
3
- import type { Fr } from '@aztec/foundation/fields';
2
+ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
3
+ import type { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { toArray } from '@aztec/foundation/iterable';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import type { AztecAsyncKVStore, CustomRange, StoreSize } from '@aztec/kv-store';
@@ -300,12 +300,12 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
300
300
  }
301
301
 
302
302
  /**
303
- * Gets L1 to L2 message (to be) included in a given block.
304
- * @param blockNumber - L2 block number to get messages for.
303
+ * Gets L1 to L2 message (to be) included in a given checkpoint.
304
+ * @param checkpointNumber - Checkpoint number to get messages for.
305
305
  * @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
306
306
  */
307
- getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]> {
308
- return this.#messageStore.getL1ToL2Messages(blockNumber);
307
+ getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
308
+ return this.#messageStore.getL1ToL2Messages(checkpointNumber);
309
309
  }
310
310
 
311
311
  /**
@@ -401,8 +401,8 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
401
401
  return this.db.estimateSize();
402
402
  }
403
403
 
404
- public rollbackL1ToL2MessagesToL2Block(targetBlockNumber: BlockNumber): Promise<void> {
405
- return this.#messageStore.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
404
+ public rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber: CheckpointNumber): Promise<void> {
405
+ return this.#messageStore.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
406
406
  }
407
407
 
408
408
  public iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
@@ -1,6 +1,6 @@
1
1
  import { INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX } from '@aztec/constants';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
- import type { Fr } from '@aztec/foundation/fields';
3
+ import type { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
5
  import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
6
6
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';