@aztec/archiver 3.0.0-nightly.20251202 → 3.0.0-nightly.20251204

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 (51) hide show
  1. package/dest/archiver/archiver.d.ts +25 -23
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +32 -19
  4. package/dest/archiver/archiver_store.d.ts +16 -15
  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 +81 -81
  9. package/dest/archiver/data_retrieval.d.ts +1 -1
  10. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  11. package/dest/archiver/data_retrieval.js +2 -2
  12. package/dest/archiver/kv_archiver_store/block_store.d.ts +9 -8
  13. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  14. package/dest/archiver/kv_archiver_store/block_store.js +8 -7
  15. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +17 -16
  16. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  17. package/dest/archiver/kv_archiver_store/log_store.d.ts +1 -1
  18. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  19. package/dest/archiver/kv_archiver_store/log_store.js +3 -2
  20. package/dest/archiver/structs/inbox_message.d.ts +3 -3
  21. package/dest/archiver/structs/inbox_message.d.ts.map +1 -1
  22. package/dest/archiver/structs/inbox_message.js +2 -1
  23. package/dest/factory.d.ts +1 -1
  24. package/dest/factory.d.ts.map +1 -1
  25. package/dest/factory.js +3 -2
  26. package/dest/test/mock_archiver.d.ts +3 -1
  27. package/dest/test/mock_archiver.d.ts.map +1 -1
  28. package/dest/test/mock_archiver.js +4 -0
  29. package/dest/test/mock_l1_to_l2_message_source.d.ts +4 -2
  30. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  31. package/dest/test/mock_l1_to_l2_message_source.js +7 -2
  32. package/dest/test/mock_l2_block_source.d.ts +8 -5
  33. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  34. package/dest/test/mock_l2_block_source.js +15 -6
  35. package/dest/test/mock_structs.d.ts +1 -1
  36. package/dest/test/mock_structs.d.ts.map +1 -1
  37. package/dest/test/mock_structs.js +3 -2
  38. package/package.json +13 -13
  39. package/src/archiver/archiver.ts +58 -53
  40. package/src/archiver/archiver_store.ts +19 -14
  41. package/src/archiver/archiver_store_test_suite.ts +107 -76
  42. package/src/archiver/data_retrieval.ts +2 -2
  43. package/src/archiver/kv_archiver_store/block_store.ts +17 -16
  44. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +16 -15
  45. package/src/archiver/kv_archiver_store/log_store.ts +3 -2
  46. package/src/archiver/structs/inbox_message.ts +4 -4
  47. package/src/factory.ts +3 -2
  48. package/src/test/mock_archiver.ts +6 -0
  49. package/src/test/mock_l1_to_l2_message_source.ts +9 -3
  50. package/src/test/mock_l2_block_source.ts +19 -8
  51. package/src/test/mock_structs.ts +3 -2
@@ -4,7 +4,7 @@ import {
4
4
  PRIVATE_LOG_SIZE_IN_FIELDS,
5
5
  } from '@aztec/constants';
6
6
  import { makeTuple } from '@aztec/foundation/array';
7
- import { EpochNumber } from '@aztec/foundation/branded-types';
7
+ import { BlockNumber, 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
10
  import { randomInt } from '@aztec/foundation/crypto';
@@ -90,7 +90,7 @@ export function describeArchiverDataStore(
90
90
 
91
91
  beforeEach(async () => {
92
92
  store = await getStore();
93
- blocks = await timesParallel(10, async i => makePublished(await L2Block.random(i + 1), i + 10));
93
+ blocks = await timesParallel(10, async i => makePublished(await L2Block.random(BlockNumber(i + 1)), i + 10));
94
94
  });
95
95
 
96
96
  describe('addBlocks', () => {
@@ -104,15 +104,18 @@ export function describeArchiverDataStore(
104
104
  });
105
105
 
106
106
  it('throws an error if the previous block does not exist in the store', async () => {
107
- const block = makePublished(await L2Block.random(2), 2);
107
+ const block = makePublished(await L2Block.random(BlockNumber(2)), 2);
108
108
  await expect(store.addBlocks([block])).rejects.toThrow(InitialBlockNumberNotSequentialError);
109
- await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
109
+ await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
110
110
  });
111
111
 
112
112
  it('throws an error if there is a gap in the blocks being added', async () => {
113
- const blocks = [makePublished(await L2Block.random(1), 1), makePublished(await L2Block.random(3), 3)];
113
+ const blocks = [
114
+ makePublished(await L2Block.random(BlockNumber(1)), 1),
115
+ makePublished(await L2Block.random(BlockNumber(3)), 3),
116
+ ];
114
117
  await expect(store.addBlocks(blocks)).rejects.toThrow(BlockNumberNotSequentialError);
115
- await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
118
+ await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
116
119
  });
117
120
  });
118
121
 
@@ -130,18 +133,22 @@ export function describeArchiverDataStore(
130
133
  });
131
134
 
132
135
  it('can unwind multiple empty blocks', async () => {
133
- const emptyBlocks = await timesParallel(10, async i => makePublished(await L2Block.random(i + 1, 0), i + 10));
136
+ const emptyBlocks = await timesParallel(10, async i =>
137
+ makePublished(await L2Block.random(BlockNumber(i + 1), 0), i + 10),
138
+ );
134
139
  await store.addBlocks(emptyBlocks);
135
140
  expect(await store.getSynchedL2BlockNumber()).toBe(10);
136
141
 
137
- await store.unwindBlocks(10, 3);
142
+ await store.unwindBlocks(BlockNumber(10), 3);
138
143
  expect(await store.getSynchedL2BlockNumber()).toBe(7);
139
- expect((await store.getPublishedBlocks(1, 10)).map(b => b.block.number)).toEqual([1, 2, 3, 4, 5, 6, 7]);
144
+ expect((await store.getPublishedBlocks(BlockNumber(1), 10)).map(b => b.block.number)).toEqual([
145
+ 1, 2, 3, 4, 5, 6, 7,
146
+ ]);
140
147
  });
141
148
 
142
149
  it('refuses to unwind blocks if the tip is not the last block', async () => {
143
150
  await store.addBlocks(blocks);
144
- await expect(store.unwindBlocks(5, 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
151
+ await expect(store.unwindBlocks(BlockNumber(5), 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
145
152
  });
146
153
 
147
154
  it('unwound blocks and headers cannot be retrieved by hash or archive', async () => {
@@ -173,32 +180,37 @@ export function describeArchiverDataStore(
173
180
  });
174
181
 
175
182
  it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks) => {
176
- expectBlocksEqual(await store.getPublishedBlocks(start, limit), getExpectedBlocks());
183
+ expectBlocksEqual(await store.getPublishedBlocks(BlockNumber(start), limit), getExpectedBlocks());
177
184
  });
178
185
 
179
186
  it('returns an empty array if no blocks are found', async () => {
180
- await expect(store.getPublishedBlocks(12, 1)).resolves.toEqual([]);
187
+ await expect(store.getPublishedBlocks(BlockNumber(12), 1)).resolves.toEqual([]);
181
188
  });
182
189
 
183
190
  it('throws an error if limit is invalid', async () => {
184
- await expect(store.getPublishedBlocks(1, 0)).rejects.toThrow('Invalid limit: 0');
191
+ await expect(store.getPublishedBlocks(BlockNumber(1), 0)).rejects.toThrow('Invalid limit: 0');
185
192
  });
186
193
 
187
194
  it('throws an error if `from` it is out of range', async () => {
188
- await expect(store.getPublishedBlocks(INITIAL_L2_BLOCK_NUM - 100, 1)).rejects.toThrow('Invalid start: -99');
195
+ await expect(store.getPublishedBlocks((INITIAL_L2_BLOCK_NUM - 100) as BlockNumber, 1)).rejects.toThrow(
196
+ 'Invalid start: -99',
197
+ );
189
198
  });
190
199
 
191
200
  it('throws an error if unexpected initial block number is found', async () => {
192
- await store.addBlocks([makePublished(await L2Block.random(21), 31)], { force: true });
193
- await expect(store.getPublishedBlocks(20, 1)).rejects.toThrow(`mismatch`);
201
+ await store.addBlocks([makePublished(await L2Block.random(BlockNumber(21)), 31)], { force: true });
202
+ await expect(store.getPublishedBlocks(BlockNumber(20), 1)).rejects.toThrow(`mismatch`);
194
203
  });
195
204
 
196
205
  it('throws an error if a gap is found', async () => {
197
206
  await store.addBlocks(
198
- [makePublished(await L2Block.random(20), 30), makePublished(await L2Block.random(22), 32)],
207
+ [
208
+ makePublished(await L2Block.random(BlockNumber(20)), 30),
209
+ makePublished(await L2Block.random(BlockNumber(22)), 32),
210
+ ],
199
211
  { force: true },
200
212
  );
201
- await expect(store.getPublishedBlocks(20, 2)).rejects.toThrow(`mismatch`);
213
+ await expect(store.getPublishedBlocks(BlockNumber(20), 2)).rejects.toThrow(`mismatch`);
202
214
  });
203
215
  });
204
216
 
@@ -346,18 +358,18 @@ export function describeArchiverDataStore(
346
358
  await store.addBlocks([blocks[0]]);
347
359
  await expect(store.addLogs([block])).resolves.toEqual(true);
348
360
 
349
- expect((await store.getPrivateLogs(1, 1)).length).toEqual(
361
+ expect((await store.getPrivateLogs(BlockNumber(1), 1)).length).toEqual(
350
362
  block.body.txEffects.map(txEffect => txEffect.privateLogs).flat().length,
351
363
  );
352
- expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(
364
+ expect((await store.getPublicLogs({ fromBlock: BlockNumber(1) })).logs.length).toEqual(
353
365
  block.body.txEffects.map(txEffect => txEffect.publicLogs).flat().length,
354
366
  );
355
367
 
356
368
  // This one is a pain for memory as we would never want to just delete memory in the middle.
357
369
  await store.deleteLogs([block]);
358
370
 
359
- expect((await store.getPrivateLogs(1, 1)).length).toEqual(0);
360
- expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(0);
371
+ expect((await store.getPrivateLogs(BlockNumber(1), 1)).length).toEqual(0);
372
+ expect((await store.getPublicLogs({ fromBlock: BlockNumber(1) })).logs.length).toEqual(0);
361
373
  });
362
374
  });
363
375
 
@@ -367,7 +379,7 @@ export function describeArchiverDataStore(
367
379
  await store.addBlocks([blocks[0]]);
368
380
  await store.addLogs([block]);
369
381
 
370
- const privateLogs = await store.getPrivateLogs(1, 1);
382
+ const privateLogs = await store.getPrivateLogs(BlockNumber(1), 1);
371
383
  expect(privateLogs).toEqual(block.body.txEffects.map(txEffect => txEffect.privateLogs).flat());
372
384
  });
373
385
  });
@@ -407,7 +419,7 @@ export function describeArchiverDataStore(
407
419
  () => wrapInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
408
420
  () => wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block),
409
421
  ])('tries to retrieves a previously stored transaction after deleted', async getExpectedTx => {
410
- await store.unwindBlocks(blocks.length, blocks.length);
422
+ await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
411
423
 
412
424
  const expectedTx = await getExpectedTx();
413
425
  const actualTx = await store.getTxEffect(expectedTx.data.txHash);
@@ -427,7 +439,7 @@ export function describeArchiverDataStore(
427
439
  await sleep(1);
428
440
  }
429
441
  })();
430
- await store.unwindBlocks(blocks.length, blocks.length);
442
+ await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
431
443
  done = true;
432
444
  expect(await store.getTxEffect(expectedTx.data.txHash)).toEqual(undefined);
433
445
  });
@@ -445,8 +457,9 @@ export function describeArchiverDataStore(
445
457
  const makeInboxMessagesWithFullBlocks = (blockCount: number, opts: { initialL2BlockNumber?: number } = {}) =>
446
458
  makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
447
459
  overrideFn: (msg, i) => {
448
- const l2BlockNumber =
449
- (opts.initialL2BlockNumber ?? initialL2BlockNumber) + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
460
+ const l2BlockNumber = BlockNumber(
461
+ (opts.initialL2BlockNumber ?? initialL2BlockNumber) + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
462
+ );
450
463
  const index =
451
464
  InboxLeaf.smallestIndexFromL2Block(l2BlockNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
452
465
  return { ...msg, l2BlockNumber, index };
@@ -454,19 +467,19 @@ export function describeArchiverDataStore(
454
467
  });
455
468
 
456
469
  it('stores first message ever', async () => {
457
- const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, l2BlockNumber: 1 });
470
+ const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, l2BlockNumber: BlockNumber(1) });
458
471
  await store.addL1ToL2Messages([msg]);
459
472
 
460
473
  await checkMessages([msg]);
461
- expect(await store.getL1ToL2Messages(1)).toEqual([msg.leaf]);
474
+ expect(await store.getL1ToL2Messages(BlockNumber(1))).toEqual([msg.leaf]);
462
475
  });
463
476
 
464
477
  it('stores single message', async () => {
465
- const msg = makeInboxMessage(Buffer16.ZERO, { l2BlockNumber: 2 });
478
+ const msg = makeInboxMessage(Buffer16.ZERO, { l2BlockNumber: BlockNumber(2) });
466
479
  await store.addL1ToL2Messages([msg]);
467
480
 
468
481
  await checkMessages([msg]);
469
- expect(await store.getL1ToL2Messages(2)).toEqual([msg.leaf]);
482
+ expect(await store.getL1ToL2Messages(BlockNumber(2))).toEqual([msg.leaf]);
470
483
  });
471
484
 
472
485
  it('stores and returns messages across different blocks', async () => {
@@ -474,7 +487,9 @@ export function describeArchiverDataStore(
474
487
  await store.addL1ToL2Messages(msgs);
475
488
 
476
489
  await checkMessages(msgs);
477
- expect(await store.getL1ToL2Messages(initialL2BlockNumber + 2)).toEqual([msgs[2]].map(m => m.leaf));
490
+ expect(await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 2))).toEqual(
491
+ [msgs[2]].map(m => m.leaf),
492
+ );
478
493
  });
479
494
 
480
495
  it('stores the same messages again', async () => {
@@ -494,10 +509,10 @@ export function describeArchiverDataStore(
494
509
 
495
510
  await checkMessages([...msgs1, ...msgs2]);
496
511
 
497
- expect(await store.getL1ToL2Messages(1)).toEqual([msgs1[0].leaf]);
498
- expect(await store.getL1ToL2Messages(4)).toEqual([]);
499
- expect(await store.getL1ToL2Messages(20)).toEqual([msgs2[0].leaf]);
500
- expect(await store.getL1ToL2Messages(24)).toEqual([]);
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([]);
501
516
  });
502
517
 
503
518
  it('stores and returns messages with block numbers larger than a byte', async () => {
@@ -505,7 +520,7 @@ export function describeArchiverDataStore(
505
520
  await store.addL1ToL2Messages(msgs);
506
521
 
507
522
  await checkMessages(msgs);
508
- expect(await store.getL1ToL2Messages(1002)).toEqual([msgs[2]].map(m => m.leaf));
523
+ expect(await store.getL1ToL2Messages(BlockNumber(1002))).toEqual([msgs[2]].map(m => m.leaf));
509
524
  });
510
525
 
511
526
  it('stores and returns multiple messages per block', async () => {
@@ -513,7 +528,7 @@ export function describeArchiverDataStore(
513
528
  await store.addL1ToL2Messages(msgs);
514
529
 
515
530
  await checkMessages(msgs);
516
- const blockMessages = await store.getL1ToL2Messages(initialL2BlockNumber + 1);
531
+ const blockMessages = await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 1));
517
532
  expect(blockMessages).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
518
533
  expect(blockMessages).toEqual(
519
534
  msgs.slice(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2).map(m => m.leaf),
@@ -525,8 +540,12 @@ export function describeArchiverDataStore(
525
540
  await store.addL1ToL2Messages(msgs.slice(0, 10));
526
541
  await store.addL1ToL2Messages(msgs.slice(10, 20));
527
542
 
528
- expect(await store.getL1ToL2Messages(initialL2BlockNumber + 2)).toEqual([msgs[2]].map(m => m.leaf));
529
- expect(await store.getL1ToL2Messages(initialL2BlockNumber + 12)).toEqual([msgs[12]].map(m => m.leaf));
543
+ expect(await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 2))).toEqual(
544
+ [msgs[2]].map(m => m.leaf),
545
+ );
546
+ expect(await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 12))).toEqual(
547
+ [msgs[12]].map(m => m.leaf),
548
+ );
530
549
  await checkMessages(msgs);
531
550
  });
532
551
 
@@ -553,7 +572,7 @@ export function describeArchiverDataStore(
553
572
 
554
573
  it('throws if block number for the first message is out of order', async () => {
555
574
  const msgs = makeInboxMessages(4, { initialL2BlockNumber });
556
- msgs[2].l2BlockNumber = initialL2BlockNumber - 1;
575
+ msgs[2].l2BlockNumber = BlockNumber(initialL2BlockNumber - 1);
557
576
  await store.addL1ToL2Messages(msgs.slice(0, 2));
558
577
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
559
578
  });
@@ -567,7 +586,7 @@ export function describeArchiverDataStore(
567
586
  it('throws if rolling hash for first message is not correct', async () => {
568
587
  const msgs = makeInboxMessages(4);
569
588
  msgs[2].rollingHash = Buffer16.random();
570
- await store.addL1ToL2Messages(msgs.slice(0, 2));
589
+ await store.addL1ToL2Messages(msgs.slice(0, BlockNumber(2)));
571
590
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
572
591
  });
573
592
 
@@ -588,7 +607,7 @@ export function describeArchiverDataStore(
588
607
  initialL2BlockNumber,
589
608
  overrideFn: (msg, i) => ({
590
609
  ...msg,
591
- l2BlockNumber: 2,
610
+ l2BlockNumber: BlockNumber(2),
592
611
  index: BigInt(i + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2),
593
612
  }),
594
613
  });
@@ -602,17 +621,17 @@ export function describeArchiverDataStore(
602
621
  await store.addL1ToL2Messages(msgs);
603
622
  await checkMessages(msgs);
604
623
 
605
- expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
606
- expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
607
- expect(await store.getL1ToL2Messages(3)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
608
- expect(await store.getL1ToL2Messages(4)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
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);
609
628
 
610
- await store.rollbackL1ToL2MessagesToL2Block(2);
629
+ await store.rollbackL1ToL2MessagesToL2Block(BlockNumber(2));
611
630
 
612
- expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
613
- expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
614
- expect(await store.getL1ToL2Messages(3)).toHaveLength(0);
615
- expect(await store.getL1ToL2Messages(4)).toHaveLength(0);
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);
616
635
 
617
636
  await checkMessages(msgs.slice(0, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2));
618
637
  });
@@ -638,7 +657,7 @@ export function describeArchiverDataStore(
638
657
  originalContractClassId: classId,
639
658
  });
640
659
  contractInstance = { ...randomInstance, address: await AztecAddress.random() };
641
- await store.addContractInstances([contractInstance], blockNum);
660
+ await store.addContractInstances([contractInstance], BlockNumber(blockNum));
642
661
  });
643
662
 
644
663
  it('returns previously stored contract instances', async () => {
@@ -652,7 +671,7 @@ export function describeArchiverDataStore(
652
671
  });
653
672
 
654
673
  it('returns undefined if previously stored contract instances was deleted', async () => {
655
- await store.deleteContractInstances([contractInstance], blockNum);
674
+ await store.deleteContractInstances([contractInstance], BlockNumber(blockNum));
656
675
  await expect(store.getContractInstance(contractInstance.address, timestamp)).resolves.toBeUndefined();
657
676
  });
658
677
  });
@@ -671,7 +690,7 @@ export function describeArchiverDataStore(
671
690
  originalContractClassId: classId,
672
691
  });
673
692
  contractInstance = { ...randomInstance, address: await AztecAddress.random() };
674
- await store.addContractInstances([contractInstance], 1);
693
+ await store.addContractInstances([contractInstance], BlockNumber(1));
675
694
  await store.addContractInstanceUpdates(
676
695
  [
677
696
  {
@@ -713,7 +732,7 @@ export function describeArchiverDataStore(
713
732
  ...randomInstance,
714
733
  address: await AztecAddress.random(),
715
734
  };
716
- await store.addContractInstances([otherContractInstance], 1);
735
+ await store.addContractInstances([otherContractInstance], BlockNumber(1));
717
736
 
718
737
  const fetchedInstance = await store.getContractInstance(otherContractInstance.address, timestampOfChange + 1n);
719
738
  expect(fetchedInstance?.originalContractClassId).toEqual(otherClassId);
@@ -731,7 +750,7 @@ export function describeArchiverDataStore(
731
750
  ...randomInstance,
732
751
  address: await AztecAddress.random(),
733
752
  };
734
- await store.addContractInstances([otherContractInstance], 1);
753
+ await store.addContractInstances([otherContractInstance], BlockNumber(1));
735
754
  await store.addContractInstanceUpdates(
736
755
  [
737
756
  {
@@ -759,7 +778,7 @@ export function describeArchiverDataStore(
759
778
  await store.addContractClasses(
760
779
  [contractClass],
761
780
  [await computePublicBytecodeCommitment(contractClass.packedBytecode)],
762
- blockNum,
781
+ BlockNumber(blockNum),
763
782
  );
764
783
  });
765
784
 
@@ -768,7 +787,7 @@ export function describeArchiverDataStore(
768
787
  });
769
788
 
770
789
  it('returns undefined if the initial deployed contract class was deleted', async () => {
771
- await store.deleteContractClasses([contractClass], blockNum);
790
+ await store.deleteContractClasses([contractClass], BlockNumber(blockNum));
772
791
  await expect(store.getContractClass(contractClass.id)).resolves.toBeUndefined();
773
792
  });
774
793
 
@@ -776,9 +795,9 @@ export function describeArchiverDataStore(
776
795
  await store.addContractClasses(
777
796
  [contractClass],
778
797
  [await computePublicBytecodeCommitment(contractClass.packedBytecode)],
779
- blockNum + 1,
798
+ BlockNumber(blockNum + 1),
780
799
  );
781
- await store.deleteContractClasses([contractClass], blockNum + 1);
800
+ await store.deleteContractClasses([contractClass], BlockNumber(blockNum + 1));
782
801
  await expect(store.getContractClass(contractClass.id)).resolves.toMatchObject(contractClass);
783
802
  });
784
803
 
@@ -858,8 +877,8 @@ export function describeArchiverDataStore(
858
877
  };
859
878
 
860
879
  const mockBlockWithLogs = async (blockNumber: number): Promise<PublishedL2Block> => {
861
- const block = await L2Block.random(blockNumber);
862
- block.header.globalVariables.blockNumber = blockNumber;
880
+ const block = await L2Block.random(BlockNumber(blockNumber));
881
+ block.header.globalVariables.blockNumber = BlockNumber(blockNumber);
863
882
 
864
883
  block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex: number) => {
865
884
  const txEffect = await TxEffect.random();
@@ -991,7 +1010,7 @@ export function describeArchiverDataStore(
991
1010
  beforeEach(async () => {
992
1011
  blocks = await timesParallel(numBlocks, async (index: number) =>
993
1012
  PublishedL2Block.fromFields({
994
- block: await L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls, numPublicLogs),
1013
+ block: await L2Block.random(BlockNumber(index + 1), txsPerBlock, numPublicFunctionCalls, numPublicLogs),
995
1014
  l1: { blockNumber: BigInt(index), blockHash: makeBlockHash(index), timestamp: BigInt(index) },
996
1015
  attestations: times(3, CommitteeAttestation.random),
997
1016
  }),
@@ -1008,7 +1027,7 @@ export function describeArchiverDataStore(
1008
1027
  const targetTxHash = blocks[targetBlockIndex].block.body.txEffects[targetTxIndex].txHash;
1009
1028
 
1010
1029
  await Promise.all([
1011
- store.unwindBlocks(blocks.length, blocks.length),
1030
+ store.unwindBlocks(BlockNumber(blocks.length), blocks.length),
1012
1031
  store.deleteLogs(blocks.map(b => b.block)),
1013
1032
  ]);
1014
1033
 
@@ -1083,7 +1102,7 @@ export function describeArchiverDataStore(
1083
1102
  const targetTxIndex = randomInt(txsPerBlock);
1084
1103
  const targetLogIndex = randomInt(numPublicLogs);
1085
1104
 
1086
- const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
1105
+ const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
1087
1106
 
1088
1107
  const response = await store.getPublicLogs({ afterLog });
1089
1108
  const logs = response.logs;
@@ -1105,42 +1124,54 @@ export function describeArchiverDataStore(
1105
1124
  it('"txHash" filter param is ignored when "afterLog" is set', async () => {
1106
1125
  // Get random txHash
1107
1126
  const txHash = TxHash.random();
1108
- const afterLog = new LogId(1, 0, 0);
1127
+ const afterLog = new LogId(BlockNumber(1), 0, 0);
1109
1128
 
1110
1129
  const response = await store.getPublicLogs({ txHash, afterLog });
1111
1130
  expect(response.logs.length).toBeGreaterThan(1);
1112
1131
  });
1113
1132
 
1114
1133
  it('intersecting works', async () => {
1115
- let logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: -5 })).logs;
1134
+ let logs = (await store.getPublicLogs({ fromBlock: -10 as BlockNumber, toBlock: -5 as BlockNumber })).logs;
1116
1135
  expect(logs.length).toBe(0);
1117
1136
 
1118
1137
  // "fromBlock" gets correctly trimmed to range and "toBlock" is exclusive
1119
- logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: 5 })).logs;
1138
+ logs = (await store.getPublicLogs({ fromBlock: -10 as BlockNumber, toBlock: BlockNumber(5) })).logs;
1120
1139
  let blockNumbers = new Set(logs.map(log => log.id.blockNumber));
1121
1140
  expect(blockNumbers).toEqual(new Set([1, 2, 3, 4]));
1122
1141
 
1123
1142
  // "toBlock" should be exclusive
1124
- logs = (await store.getPublicLogs({ fromBlock: 1, toBlock: 1 })).logs;
1143
+ logs = (await store.getPublicLogs({ fromBlock: BlockNumber(1), toBlock: BlockNumber(1) })).logs;
1125
1144
  expect(logs.length).toBe(0);
1126
1145
 
1127
- logs = (await store.getPublicLogs({ fromBlock: 10, toBlock: 5 })).logs;
1146
+ logs = (await store.getPublicLogs({ fromBlock: BlockNumber(10), toBlock: BlockNumber(5) })).logs;
1128
1147
  expect(logs.length).toBe(0);
1129
1148
 
1130
1149
  // both "fromBlock" and "toBlock" get correctly capped to range and logs from all blocks are returned
1131
- logs = (await store.getPublicLogs({ fromBlock: -100, toBlock: +100 })).logs;
1150
+ logs = (await store.getPublicLogs({ fromBlock: -100 as BlockNumber, toBlock: +100 })).logs;
1132
1151
  blockNumbers = new Set(logs.map(log => log.id.blockNumber));
1133
1152
  expect(blockNumbers.size).toBe(numBlocks);
1134
1153
 
1135
1154
  // intersecting with "afterLog" works
1136
- logs = (await store.getPublicLogs({ fromBlock: 2, toBlock: 5, afterLog: new LogId(4, 0, 0) })).logs;
1155
+ logs = (
1156
+ await store.getPublicLogs({
1157
+ fromBlock: BlockNumber(2),
1158
+ toBlock: BlockNumber(5),
1159
+ afterLog: new LogId(BlockNumber(4), 0, 0),
1160
+ })
1161
+ ).logs;
1137
1162
  blockNumbers = new Set(logs.map(log => log.id.blockNumber));
1138
1163
  expect(blockNumbers).toEqual(new Set([4]));
1139
1164
 
1140
- logs = (await store.getPublicLogs({ toBlock: 5, afterLog: new LogId(5, 1, 0) })).logs;
1165
+ logs = (await store.getPublicLogs({ toBlock: BlockNumber(5), afterLog: new LogId(BlockNumber(5), 1, 0) })).logs;
1141
1166
  expect(logs.length).toBe(0);
1142
1167
 
1143
- logs = (await store.getPublicLogs({ fromBlock: 2, toBlock: 5, afterLog: new LogId(100, 0, 0) })).logs;
1168
+ logs = (
1169
+ await store.getPublicLogs({
1170
+ fromBlock: BlockNumber(2),
1171
+ toBlock: BlockNumber(5),
1172
+ afterLog: new LogId(BlockNumber(100), 0, 0),
1173
+ })
1174
+ ).logs;
1144
1175
  expect(logs.length).toBe(0);
1145
1176
  });
1146
1177
 
@@ -1150,7 +1181,7 @@ export function describeArchiverDataStore(
1150
1181
  const targetTxIndex = randomInt(txsPerBlock);
1151
1182
  const targetLogIndex = randomInt(numPublicLogs);
1152
1183
 
1153
- const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
1184
+ const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
1154
1185
 
1155
1186
  const response = await store.getPublicLogs({ afterLog, fromBlock: afterLog.blockNumber });
1156
1187
  const logs = response.logs;
@@ -14,7 +14,7 @@ import type {
14
14
  ViemPublicClient,
15
15
  } from '@aztec/ethereum';
16
16
  import { asyncPool } from '@aztec/foundation/async-pool';
17
- import { CheckpointNumber } from '@aztec/foundation/branded-types';
17
+ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
18
18
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
19
19
  import type { EthAddress } from '@aztec/foundation/eth-address';
20
20
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
@@ -470,7 +470,7 @@ function mapLogsInboxMessage(logs: GetContractEventsReturnType<typeof InboxAbi,
470
470
  leaf: Fr.fromHexString(hash!),
471
471
  l1BlockNumber: log.blockNumber,
472
472
  l1BlockHash: Buffer32.fromString(log.blockHash),
473
- l2BlockNumber: Number(checkpointNumber!),
473
+ l2BlockNumber: BlockNumber(Number(checkpointNumber!)),
474
474
  rollingHash: Buffer16.fromString(rollingHash!),
475
475
  };
476
476
  });
@@ -1,4 +1,5 @@
1
1
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
3
  import { Fr } from '@aztec/foundation/fields';
3
4
  import { toArray } from '@aztec/foundation/iterable';
4
5
  import { createLogger } from '@aztec/foundation/log';
@@ -158,7 +159,7 @@ export class BlockStore {
158
159
  * @param blocksToUnwind - The number of blocks we are to unwind
159
160
  * @returns True if the operation is successful
160
161
  */
161
- async unwindBlocks(from: number, blocksToUnwind: number) {
162
+ async unwindBlocks(from: BlockNumber, blocksToUnwind: number) {
162
163
  return await this.db.transactionAsync(async () => {
163
164
  const last = await this.getSynchedL2BlockNumber();
164
165
  if (from !== last) {
@@ -167,12 +168,12 @@ export class BlockStore {
167
168
 
168
169
  const proven = await this.getProvenL2BlockNumber();
169
170
  if (from - blocksToUnwind < proven) {
170
- await this.setProvenL2BlockNumber(from - blocksToUnwind);
171
+ await this.setProvenL2BlockNumber(BlockNumber(from - blocksToUnwind));
171
172
  }
172
173
 
173
174
  for (let i = 0; i < blocksToUnwind; i++) {
174
175
  const blockNumber = from - i;
175
- const block = await this.getBlock(blockNumber);
176
+ const block = await this.getBlock(BlockNumber(blockNumber));
176
177
 
177
178
  if (block === undefined) {
178
179
  this.#log.warn(`Cannot remove block ${blockNumber} from the store since we don't have it`);
@@ -200,7 +201,7 @@ export class BlockStore {
200
201
  * @param limit - The number of blocks to return.
201
202
  * @returns The requested L2 blocks
202
203
  */
203
- async *getBlocks(start: number, limit: number): AsyncIterableIterator<PublishedL2Block> {
204
+ async *getBlocks(start: BlockNumber, limit: number): AsyncIterableIterator<PublishedL2Block> {
204
205
  for await (const [blockNumber, blockStorage] of this.getBlockStorages(start, limit)) {
205
206
  const block = await this.getBlockFromBlockStorage(blockNumber, blockStorage);
206
207
  if (block) {
@@ -214,7 +215,7 @@ export class BlockStore {
214
215
  * @param blockNumber - The number of the block to return.
215
216
  * @returns The requested L2 block.
216
217
  */
217
- async getBlock(blockNumber: number): Promise<PublishedL2Block | undefined> {
218
+ async getBlock(blockNumber: BlockNumber): Promise<PublishedL2Block | undefined> {
218
219
  const blockStorage = await this.#blocks.getAsync(blockNumber);
219
220
  if (!blockStorage || !blockStorage.header) {
220
221
  return Promise.resolve(undefined);
@@ -232,7 +233,7 @@ export class BlockStore {
232
233
  if (blockNumber === undefined) {
233
234
  return undefined;
234
235
  }
235
- return this.getBlock(blockNumber);
236
+ return this.getBlock(BlockNumber(blockNumber));
236
237
  }
237
238
 
238
239
  /**
@@ -245,7 +246,7 @@ export class BlockStore {
245
246
  if (blockNumber === undefined) {
246
247
  return undefined;
247
248
  }
248
- return this.getBlock(blockNumber);
249
+ return this.getBlock(BlockNumber(blockNumber));
249
250
  }
250
251
 
251
252
  /**
@@ -288,7 +289,7 @@ export class BlockStore {
288
289
  * @param limit - The number of blocks to return.
289
290
  * @returns The requested L2 block headers
290
291
  */
291
- async *getBlockHeaders(start: number, limit: number): AsyncIterableIterator<BlockHeader> {
292
+ async *getBlockHeaders(start: BlockNumber, limit: number): AsyncIterableIterator<BlockHeader> {
292
293
  for await (const [blockNumber, blockStorage] of this.getBlockStorages(start, limit)) {
293
294
  const header = L2BlockHeader.fromBuffer(blockStorage.header).toBlockHeader();
294
295
  if (header.getBlockNumber() !== blockNumber) {
@@ -300,7 +301,7 @@ export class BlockStore {
300
301
  }
301
302
  }
302
303
 
303
- private async *getBlockStorages(start: number, limit: number) {
304
+ private async *getBlockStorages(start: BlockNumber, limit: number) {
304
305
  let expectedBlockNumber = start;
305
306
  for await (const [blockNumber, blockStorage] of this.#blocks.entriesAsync(this.#computeBlockRange(start, limit))) {
306
307
  if (blockNumber !== expectedBlockNumber) {
@@ -382,7 +383,7 @@ export class BlockStore {
382
383
  '',
383
384
  txEffect.data.transactionFee.toBigInt(),
384
385
  txEffect.l2BlockHash,
385
- txEffect.l2BlockNumber,
386
+ BlockNumber(txEffect.l2BlockNumber),
386
387
  );
387
388
  }
388
389
 
@@ -413,9 +414,9 @@ export class BlockStore {
413
414
  * Gets the number of the latest L2 block processed.
414
415
  * @returns The number of the latest L2 block processed.
415
416
  */
416
- async getSynchedL2BlockNumber(): Promise<number> {
417
+ async getSynchedL2BlockNumber(): Promise<BlockNumber> {
417
418
  const [lastBlockNumber] = await toArray(this.#blocks.keysAsync({ reverse: true, limit: 1 }));
418
- return typeof lastBlockNumber === 'number' ? lastBlockNumber : INITIAL_L2_BLOCK_NUM - 1;
419
+ return typeof lastBlockNumber === 'number' ? BlockNumber(lastBlockNumber) : BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
419
420
  }
420
421
 
421
422
  /**
@@ -430,19 +431,19 @@ export class BlockStore {
430
431
  return this.#lastSynchedL1Block.set(l1BlockNumber);
431
432
  }
432
433
 
433
- async getProvenL2BlockNumber(): Promise<number> {
434
+ async getProvenL2BlockNumber(): Promise<BlockNumber> {
434
435
  const [latestBlockNumber, provenBlockNumber] = await Promise.all([
435
436
  this.getSynchedL2BlockNumber(),
436
437
  this.#lastProvenL2Block.getAsync(),
437
438
  ]);
438
- return (provenBlockNumber ?? 0) > latestBlockNumber ? latestBlockNumber : (provenBlockNumber ?? 0);
439
+ return (provenBlockNumber ?? 0) > latestBlockNumber ? latestBlockNumber : BlockNumber(provenBlockNumber ?? 0);
439
440
  }
440
441
 
441
- setProvenL2BlockNumber(blockNumber: number) {
442
+ setProvenL2BlockNumber(blockNumber: BlockNumber) {
442
443
  return this.#lastProvenL2Block.set(blockNumber);
443
444
  }
444
445
 
445
- #computeBlockRange(start: number, limit: number): Required<Pick<Range<number>, 'start' | 'limit'>> {
446
+ #computeBlockRange(start: BlockNumber, limit: number): Required<Pick<Range<number>, 'start' | 'limit'>> {
446
447
  if (limit < 1) {
447
448
  throw new Error(`Invalid limit: ${limit}`);
448
449
  }