@aztec/archiver 0.0.1-commit.b655e406 → 0.0.1-commit.d3ec352c

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 (81) hide show
  1. package/dest/archiver/archiver.d.ts +53 -40
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +333 -221
  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 +85 -84
  9. package/dest/archiver/config.d.ts +1 -1
  10. package/dest/archiver/config.d.ts.map +1 -1
  11. package/dest/archiver/config.js +5 -0
  12. package/dest/archiver/data_retrieval.d.ts +18 -17
  13. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  14. package/dest/archiver/data_retrieval.js +111 -86
  15. package/dest/archiver/errors.d.ts +1 -1
  16. package/dest/archiver/errors.d.ts.map +1 -1
  17. package/dest/archiver/index.d.ts +1 -1
  18. package/dest/archiver/instrumentation.d.ts +3 -3
  19. package/dest/archiver/instrumentation.d.ts.map +1 -1
  20. package/dest/archiver/kv_archiver_store/block_store.d.ts +9 -8
  21. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  22. package/dest/archiver/kv_archiver_store/block_store.js +8 -7
  23. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +1 -1
  24. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  25. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +1 -1
  26. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
  27. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +18 -17
  28. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  29. package/dest/archiver/kv_archiver_store/log_store.d.ts +1 -1
  30. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  31. package/dest/archiver/kv_archiver_store/log_store.js +3 -2
  32. package/dest/archiver/kv_archiver_store/message_store.d.ts +1 -1
  33. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  34. package/dest/archiver/structs/data_retrieval.d.ts +1 -1
  35. package/dest/archiver/structs/inbox_message.d.ts +3 -3
  36. package/dest/archiver/structs/inbox_message.d.ts.map +1 -1
  37. package/dest/archiver/structs/inbox_message.js +2 -1
  38. package/dest/archiver/structs/published.d.ts +3 -2
  39. package/dest/archiver/structs/published.d.ts.map +1 -1
  40. package/dest/archiver/validation.d.ts +10 -4
  41. package/dest/archiver/validation.d.ts.map +1 -1
  42. package/dest/archiver/validation.js +29 -21
  43. package/dest/factory.d.ts +1 -1
  44. package/dest/factory.d.ts.map +1 -1
  45. package/dest/factory.js +3 -2
  46. package/dest/index.d.ts +2 -2
  47. package/dest/index.d.ts.map +1 -1
  48. package/dest/index.js +1 -1
  49. package/dest/rpc/index.d.ts +2 -2
  50. package/dest/test/index.d.ts +1 -1
  51. package/dest/test/mock_archiver.d.ts +14 -5
  52. package/dest/test/mock_archiver.d.ts.map +1 -1
  53. package/dest/test/mock_archiver.js +19 -10
  54. package/dest/test/mock_l1_to_l2_message_source.d.ts +4 -2
  55. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  56. package/dest/test/mock_l1_to_l2_message_source.js +7 -2
  57. package/dest/test/mock_l2_block_source.d.ts +14 -9
  58. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  59. package/dest/test/mock_l2_block_source.js +20 -7
  60. package/dest/test/mock_structs.d.ts +1 -1
  61. package/dest/test/mock_structs.d.ts.map +1 -1
  62. package/dest/test/mock_structs.js +3 -2
  63. package/package.json +17 -17
  64. package/src/archiver/archiver.ts +448 -290
  65. package/src/archiver/archiver_store.ts +19 -14
  66. package/src/archiver/archiver_store_test_suite.ts +111 -79
  67. package/src/archiver/config.ts +5 -0
  68. package/src/archiver/data_retrieval.ts +157 -125
  69. package/src/archiver/instrumentation.ts +2 -2
  70. package/src/archiver/kv_archiver_store/block_store.ts +17 -16
  71. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +16 -15
  72. package/src/archiver/kv_archiver_store/log_store.ts +3 -2
  73. package/src/archiver/structs/inbox_message.ts +5 -4
  74. package/src/archiver/structs/published.ts +2 -1
  75. package/src/archiver/validation.ts +52 -27
  76. package/src/factory.ts +3 -2
  77. package/src/index.ts +1 -1
  78. package/src/test/mock_archiver.ts +22 -11
  79. package/src/test/mock_l1_to_l2_message_source.ts +9 -3
  80. package/src/test/mock_l2_block_source.ts +30 -13
  81. package/src/test/mock_structs.ts +3 -2
@@ -1,4 +1,5 @@
1
1
  import type { L1BlockId } from '@aztec/ethereum';
2
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
3
  import type { Fr } from '@aztec/foundation/fields';
3
4
  import type { CustomRange } from '@aztec/kv-store';
4
5
  import type { FunctionSelector } from '@aztec/stdlib/abi';
@@ -53,13 +54,13 @@ export interface ArchiverDataStore {
53
54
  * @param blocksToUnwind - The number of blocks we are to unwind
54
55
  * @returns True if the operation is successful
55
56
  */
56
- unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean>;
57
+ unwindBlocks(from: BlockNumber, blocksToUnwind: number): Promise<boolean>;
57
58
 
58
59
  /**
59
60
  * Returns the block for the given number, or undefined if not exists.
60
61
  * @param number - The block number to return.
61
62
  */
62
- getPublishedBlock(number: number): Promise<PublishedL2Block | undefined>;
63
+ getPublishedBlock(number: BlockNumber): Promise<PublishedL2Block | undefined>;
63
64
 
64
65
  /**
65
66
  * Returns the block for the given hash, or undefined if not exists.
@@ -79,7 +80,7 @@ export interface ArchiverDataStore {
79
80
  * @param limit - The number of blocks to return.
80
81
  * @returns The requested L2 blocks.
81
82
  */
82
- getPublishedBlocks(from: number, limit: number): Promise<PublishedL2Block[]>;
83
+ getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]>;
83
84
 
84
85
  /**
85
86
  * Gets up to `limit` amount of L2 block headers starting from `from`.
@@ -87,7 +88,7 @@ export interface ArchiverDataStore {
87
88
  * @param limit - The number of blocks to return.
88
89
  * @returns The requested L2 block headers.
89
90
  */
90
- getBlockHeaders(from: number, limit: number): Promise<BlockHeader[]>;
91
+ getBlockHeaders(from: BlockNumber, limit: number): Promise<BlockHeader[]>;
91
92
 
92
93
  /**
93
94
  * Returns the block header for the given hash, or undefined if not exists.
@@ -135,7 +136,7 @@ export interface ArchiverDataStore {
135
136
  * @param blockNumber - L2 block number to get messages for.
136
137
  * @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
137
138
  */
138
- getL1ToL2Messages(blockNumber: number): Promise<Fr[]>;
139
+ getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]>;
139
140
 
140
141
  /**
141
142
  * Gets the L1 to L2 message index in the L1 to L2 message tree.
@@ -156,7 +157,7 @@ export interface ArchiverDataStore {
156
157
  * @param limit - The maximum number of blocks to retrieve logs from.
157
158
  * @returns An array of private logs from the specified range of blocks.
158
159
  */
159
- getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]>;
160
+ getPrivateLogs(from: BlockNumber, limit: number): Promise<PrivateLog[]>;
160
161
 
161
162
  /**
162
163
  * Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
@@ -185,19 +186,19 @@ export interface ArchiverDataStore {
185
186
  * Gets the number of the latest L2 block processed.
186
187
  * @returns The number of the latest L2 block processed.
187
188
  */
188
- getSynchedL2BlockNumber(): Promise<number>;
189
+ getSynchedL2BlockNumber(): Promise<BlockNumber>;
189
190
 
190
191
  /**
191
192
  * Gets the number of the latest proven L2 block processed.
192
193
  * @returns The number of the latest proven L2 block processed.
193
194
  */
194
- getProvenL2BlockNumber(): Promise<number>;
195
+ getProvenL2BlockNumber(): Promise<BlockNumber>;
195
196
 
196
197
  /**
197
198
  * Stores the number of the latest proven L2 block processed.
198
199
  * @param l2BlockNumber - The number of the latest proven L2 block processed.
199
200
  */
200
- setProvenL2BlockNumber(l2BlockNumber: number): Promise<void>;
201
+ setProvenL2BlockNumber(l2BlockNumber: BlockNumber): Promise<void>;
201
202
 
202
203
  /**
203
204
  * Stores the l1 block number that blocks have been synched until
@@ -221,9 +222,13 @@ export interface ArchiverDataStore {
221
222
  * @param blockNumber - Number of the L2 block the contracts were registered in.
222
223
  * @returns True if the operation is successful.
223
224
  */
224
- addContractClasses(data: ContractClassPublic[], bytecodeCommitments: Fr[], blockNumber: number): Promise<boolean>;
225
+ addContractClasses(
226
+ data: ContractClassPublic[],
227
+ bytecodeCommitments: Fr[],
228
+ blockNumber: BlockNumber,
229
+ ): Promise<boolean>;
225
230
 
226
- deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean>;
231
+ deleteContractClasses(data: ContractClassPublic[], blockNumber: BlockNumber): Promise<boolean>;
227
232
 
228
233
  getBytecodeCommitment(contractClassId: Fr): Promise<Fr | undefined>;
229
234
 
@@ -239,8 +244,8 @@ export interface ArchiverDataStore {
239
244
  * @param blockNumber - Number of the L2 block the instances were deployed in.
240
245
  * @returns True if the operation is successful.
241
246
  */
242
- addContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise<boolean>;
243
- deleteContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise<boolean>;
247
+ addContractInstances(data: ContractInstanceWithAddress[], blockNumber: BlockNumber): Promise<boolean>;
248
+ deleteContractInstances(data: ContractInstanceWithAddress[], blockNumber: BlockNumber): Promise<boolean>;
244
249
 
245
250
  /**
246
251
  * Add new contract instance updates
@@ -286,7 +291,7 @@ export interface ArchiverDataStore {
286
291
  close(): Promise<void>;
287
292
 
288
293
  /** Deletes all L1 to L2 messages up until (excluding) the target L2 block number. */
289
- rollbackL1ToL2MessagesToL2Block(targetBlockNumber: number): Promise<void>;
294
+ rollbackL1ToL2MessagesToL2Block(targetBlockNumber: BlockNumber): Promise<void>;
290
295
 
291
296
  /** Returns an async iterator to all L1 to L2 messages on the range. */
292
297
  iterateL1ToL2Messages(range?: CustomRange<bigint>): AsyncIterableIterator<InboxMessage>;
@@ -4,6 +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 { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
7
8
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
8
9
  import { times, timesParallel } from '@aztec/foundation/collection';
9
10
  import { randomInt } from '@aztec/foundation/crypto';
@@ -89,7 +90,7 @@ export function describeArchiverDataStore(
89
90
 
90
91
  beforeEach(async () => {
91
92
  store = await getStore();
92
- 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));
93
94
  });
94
95
 
95
96
  describe('addBlocks', () => {
@@ -103,15 +104,18 @@ export function describeArchiverDataStore(
103
104
  });
104
105
 
105
106
  it('throws an error if the previous block does not exist in the store', async () => {
106
- const block = makePublished(await L2Block.random(2), 2);
107
+ const block = makePublished(await L2Block.random(BlockNumber(2)), 2);
107
108
  await expect(store.addBlocks([block])).rejects.toThrow(InitialBlockNumberNotSequentialError);
108
- await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
109
+ await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
109
110
  });
110
111
 
111
112
  it('throws an error if there is a gap in the blocks being added', async () => {
112
- 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
+ ];
113
117
  await expect(store.addBlocks(blocks)).rejects.toThrow(BlockNumberNotSequentialError);
114
- await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
118
+ await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
115
119
  });
116
120
  });
117
121
 
@@ -129,18 +133,22 @@ export function describeArchiverDataStore(
129
133
  });
130
134
 
131
135
  it('can unwind multiple empty blocks', async () => {
132
- 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
+ );
133
139
  await store.addBlocks(emptyBlocks);
134
140
  expect(await store.getSynchedL2BlockNumber()).toBe(10);
135
141
 
136
- await store.unwindBlocks(10, 3);
142
+ await store.unwindBlocks(BlockNumber(10), 3);
137
143
  expect(await store.getSynchedL2BlockNumber()).toBe(7);
138
- 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
+ ]);
139
147
  });
140
148
 
141
149
  it('refuses to unwind blocks if the tip is not the last block', async () => {
142
150
  await store.addBlocks(blocks);
143
- 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);
144
152
  });
145
153
 
146
154
  it('unwound blocks and headers cannot be retrieved by hash or archive', async () => {
@@ -172,32 +180,37 @@ export function describeArchiverDataStore(
172
180
  });
173
181
 
174
182
  it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks) => {
175
- expectBlocksEqual(await store.getPublishedBlocks(start, limit), getExpectedBlocks());
183
+ expectBlocksEqual(await store.getPublishedBlocks(BlockNumber(start), limit), getExpectedBlocks());
176
184
  });
177
185
 
178
186
  it('returns an empty array if no blocks are found', async () => {
179
- await expect(store.getPublishedBlocks(12, 1)).resolves.toEqual([]);
187
+ await expect(store.getPublishedBlocks(BlockNumber(12), 1)).resolves.toEqual([]);
180
188
  });
181
189
 
182
190
  it('throws an error if limit is invalid', async () => {
183
- await expect(store.getPublishedBlocks(1, 0)).rejects.toThrow('Invalid limit: 0');
191
+ await expect(store.getPublishedBlocks(BlockNumber(1), 0)).rejects.toThrow('Invalid limit: 0');
184
192
  });
185
193
 
186
194
  it('throws an error if `from` it is out of range', async () => {
187
- 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
+ );
188
198
  });
189
199
 
190
200
  it('throws an error if unexpected initial block number is found', async () => {
191
- await store.addBlocks([makePublished(await L2Block.random(21), 31)], { force: true });
192
- 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`);
193
203
  });
194
204
 
195
205
  it('throws an error if a gap is found', async () => {
196
206
  await store.addBlocks(
197
- [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
+ ],
198
211
  { force: true },
199
212
  );
200
- await expect(store.getPublishedBlocks(20, 2)).rejects.toThrow(`mismatch`);
213
+ await expect(store.getPublishedBlocks(BlockNumber(20), 2)).rejects.toThrow(`mismatch`);
201
214
  });
202
215
  });
203
216
 
@@ -345,18 +358,18 @@ export function describeArchiverDataStore(
345
358
  await store.addBlocks([blocks[0]]);
346
359
  await expect(store.addLogs([block])).resolves.toEqual(true);
347
360
 
348
- expect((await store.getPrivateLogs(1, 1)).length).toEqual(
361
+ expect((await store.getPrivateLogs(BlockNumber(1), 1)).length).toEqual(
349
362
  block.body.txEffects.map(txEffect => txEffect.privateLogs).flat().length,
350
363
  );
351
- expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(
364
+ expect((await store.getPublicLogs({ fromBlock: BlockNumber(1) })).logs.length).toEqual(
352
365
  block.body.txEffects.map(txEffect => txEffect.publicLogs).flat().length,
353
366
  );
354
367
 
355
368
  // This one is a pain for memory as we would never want to just delete memory in the middle.
356
369
  await store.deleteLogs([block]);
357
370
 
358
- expect((await store.getPrivateLogs(1, 1)).length).toEqual(0);
359
- 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);
360
373
  });
361
374
  });
362
375
 
@@ -366,7 +379,7 @@ export function describeArchiverDataStore(
366
379
  await store.addBlocks([blocks[0]]);
367
380
  await store.addLogs([block]);
368
381
 
369
- const privateLogs = await store.getPrivateLogs(1, 1);
382
+ const privateLogs = await store.getPrivateLogs(BlockNumber(1), 1);
370
383
  expect(privateLogs).toEqual(block.body.txEffects.map(txEffect => txEffect.privateLogs).flat());
371
384
  });
372
385
  });
@@ -406,7 +419,7 @@ export function describeArchiverDataStore(
406
419
  () => wrapInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
407
420
  () => wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block),
408
421
  ])('tries to retrieves a previously stored transaction after deleted', async getExpectedTx => {
409
- await store.unwindBlocks(blocks.length, blocks.length);
422
+ await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
410
423
 
411
424
  const expectedTx = await getExpectedTx();
412
425
  const actualTx = await store.getTxEffect(expectedTx.data.txHash);
@@ -426,7 +439,7 @@ export function describeArchiverDataStore(
426
439
  await sleep(1);
427
440
  }
428
441
  })();
429
- await store.unwindBlocks(blocks.length, blocks.length);
442
+ await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
430
443
  done = true;
431
444
  expect(await store.getTxEffect(expectedTx.data.txHash)).toEqual(undefined);
432
445
  });
@@ -444,8 +457,9 @@ export function describeArchiverDataStore(
444
457
  const makeInboxMessagesWithFullBlocks = (blockCount: number, opts: { initialL2BlockNumber?: number } = {}) =>
445
458
  makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
446
459
  overrideFn: (msg, i) => {
447
- const l2BlockNumber =
448
- (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
+ );
449
463
  const index =
450
464
  InboxLeaf.smallestIndexFromL2Block(l2BlockNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
451
465
  return { ...msg, l2BlockNumber, index };
@@ -453,19 +467,19 @@ export function describeArchiverDataStore(
453
467
  });
454
468
 
455
469
  it('stores first message ever', async () => {
456
- const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, l2BlockNumber: 1 });
470
+ const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, l2BlockNumber: BlockNumber(1) });
457
471
  await store.addL1ToL2Messages([msg]);
458
472
 
459
473
  await checkMessages([msg]);
460
- expect(await store.getL1ToL2Messages(1)).toEqual([msg.leaf]);
474
+ expect(await store.getL1ToL2Messages(BlockNumber(1))).toEqual([msg.leaf]);
461
475
  });
462
476
 
463
477
  it('stores single message', async () => {
464
- const msg = makeInboxMessage(Buffer16.ZERO, { l2BlockNumber: 2 });
478
+ const msg = makeInboxMessage(Buffer16.ZERO, { l2BlockNumber: BlockNumber(2) });
465
479
  await store.addL1ToL2Messages([msg]);
466
480
 
467
481
  await checkMessages([msg]);
468
- expect(await store.getL1ToL2Messages(2)).toEqual([msg.leaf]);
482
+ expect(await store.getL1ToL2Messages(BlockNumber(2))).toEqual([msg.leaf]);
469
483
  });
470
484
 
471
485
  it('stores and returns messages across different blocks', async () => {
@@ -473,7 +487,9 @@ export function describeArchiverDataStore(
473
487
  await store.addL1ToL2Messages(msgs);
474
488
 
475
489
  await checkMessages(msgs);
476
- 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
+ );
477
493
  });
478
494
 
479
495
  it('stores the same messages again', async () => {
@@ -493,10 +509,10 @@ export function describeArchiverDataStore(
493
509
 
494
510
  await checkMessages([...msgs1, ...msgs2]);
495
511
 
496
- expect(await store.getL1ToL2Messages(1)).toEqual([msgs1[0].leaf]);
497
- expect(await store.getL1ToL2Messages(4)).toEqual([]);
498
- expect(await store.getL1ToL2Messages(20)).toEqual([msgs2[0].leaf]);
499
- 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([]);
500
516
  });
501
517
 
502
518
  it('stores and returns messages with block numbers larger than a byte', async () => {
@@ -504,7 +520,7 @@ export function describeArchiverDataStore(
504
520
  await store.addL1ToL2Messages(msgs);
505
521
 
506
522
  await checkMessages(msgs);
507
- 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));
508
524
  });
509
525
 
510
526
  it('stores and returns multiple messages per block', async () => {
@@ -512,7 +528,7 @@ export function describeArchiverDataStore(
512
528
  await store.addL1ToL2Messages(msgs);
513
529
 
514
530
  await checkMessages(msgs);
515
- const blockMessages = await store.getL1ToL2Messages(initialL2BlockNumber + 1);
531
+ const blockMessages = await store.getL1ToL2Messages(BlockNumber(initialL2BlockNumber + 1));
516
532
  expect(blockMessages).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
517
533
  expect(blockMessages).toEqual(
518
534
  msgs.slice(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2).map(m => m.leaf),
@@ -524,8 +540,12 @@ export function describeArchiverDataStore(
524
540
  await store.addL1ToL2Messages(msgs.slice(0, 10));
525
541
  await store.addL1ToL2Messages(msgs.slice(10, 20));
526
542
 
527
- expect(await store.getL1ToL2Messages(initialL2BlockNumber + 2)).toEqual([msgs[2]].map(m => m.leaf));
528
- 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
+ );
529
549
  await checkMessages(msgs);
530
550
  });
531
551
 
@@ -552,7 +572,7 @@ export function describeArchiverDataStore(
552
572
 
553
573
  it('throws if block number for the first message is out of order', async () => {
554
574
  const msgs = makeInboxMessages(4, { initialL2BlockNumber });
555
- msgs[2].l2BlockNumber = initialL2BlockNumber - 1;
575
+ msgs[2].l2BlockNumber = BlockNumber(initialL2BlockNumber - 1);
556
576
  await store.addL1ToL2Messages(msgs.slice(0, 2));
557
577
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
558
578
  });
@@ -566,7 +586,7 @@ export function describeArchiverDataStore(
566
586
  it('throws if rolling hash for first message is not correct', async () => {
567
587
  const msgs = makeInboxMessages(4);
568
588
  msgs[2].rollingHash = Buffer16.random();
569
- await store.addL1ToL2Messages(msgs.slice(0, 2));
589
+ await store.addL1ToL2Messages(msgs.slice(0, BlockNumber(2)));
570
590
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
571
591
  });
572
592
 
@@ -587,7 +607,7 @@ export function describeArchiverDataStore(
587
607
  initialL2BlockNumber,
588
608
  overrideFn: (msg, i) => ({
589
609
  ...msg,
590
- l2BlockNumber: 2,
610
+ l2BlockNumber: BlockNumber(2),
591
611
  index: BigInt(i + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2),
592
612
  }),
593
613
  });
@@ -601,17 +621,17 @@ export function describeArchiverDataStore(
601
621
  await store.addL1ToL2Messages(msgs);
602
622
  await checkMessages(msgs);
603
623
 
604
- expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
605
- expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
606
- expect(await store.getL1ToL2Messages(3)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
607
- 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);
608
628
 
609
- await store.rollbackL1ToL2MessagesToL2Block(2);
629
+ await store.rollbackL1ToL2MessagesToL2Block(BlockNumber(2));
610
630
 
611
- expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
612
- expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
613
- expect(await store.getL1ToL2Messages(3)).toHaveLength(0);
614
- 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);
615
635
 
616
636
  await checkMessages(msgs.slice(0, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2));
617
637
  });
@@ -637,7 +657,7 @@ export function describeArchiverDataStore(
637
657
  originalContractClassId: classId,
638
658
  });
639
659
  contractInstance = { ...randomInstance, address: await AztecAddress.random() };
640
- await store.addContractInstances([contractInstance], blockNum);
660
+ await store.addContractInstances([contractInstance], BlockNumber(blockNum));
641
661
  });
642
662
 
643
663
  it('returns previously stored contract instances', async () => {
@@ -651,7 +671,7 @@ export function describeArchiverDataStore(
651
671
  });
652
672
 
653
673
  it('returns undefined if previously stored contract instances was deleted', async () => {
654
- await store.deleteContractInstances([contractInstance], blockNum);
674
+ await store.deleteContractInstances([contractInstance], BlockNumber(blockNum));
655
675
  await expect(store.getContractInstance(contractInstance.address, timestamp)).resolves.toBeUndefined();
656
676
  });
657
677
  });
@@ -670,7 +690,7 @@ export function describeArchiverDataStore(
670
690
  originalContractClassId: classId,
671
691
  });
672
692
  contractInstance = { ...randomInstance, address: await AztecAddress.random() };
673
- await store.addContractInstances([contractInstance], 1);
693
+ await store.addContractInstances([contractInstance], BlockNumber(1));
674
694
  await store.addContractInstanceUpdates(
675
695
  [
676
696
  {
@@ -712,7 +732,7 @@ export function describeArchiverDataStore(
712
732
  ...randomInstance,
713
733
  address: await AztecAddress.random(),
714
734
  };
715
- await store.addContractInstances([otherContractInstance], 1);
735
+ await store.addContractInstances([otherContractInstance], BlockNumber(1));
716
736
 
717
737
  const fetchedInstance = await store.getContractInstance(otherContractInstance.address, timestampOfChange + 1n);
718
738
  expect(fetchedInstance?.originalContractClassId).toEqual(otherClassId);
@@ -730,7 +750,7 @@ export function describeArchiverDataStore(
730
750
  ...randomInstance,
731
751
  address: await AztecAddress.random(),
732
752
  };
733
- await store.addContractInstances([otherContractInstance], 1);
753
+ await store.addContractInstances([otherContractInstance], BlockNumber(1));
734
754
  await store.addContractInstanceUpdates(
735
755
  [
736
756
  {
@@ -758,7 +778,7 @@ export function describeArchiverDataStore(
758
778
  await store.addContractClasses(
759
779
  [contractClass],
760
780
  [await computePublicBytecodeCommitment(contractClass.packedBytecode)],
761
- blockNum,
781
+ BlockNumber(blockNum),
762
782
  );
763
783
  });
764
784
 
@@ -767,7 +787,7 @@ export function describeArchiverDataStore(
767
787
  });
768
788
 
769
789
  it('returns undefined if the initial deployed contract class was deleted', async () => {
770
- await store.deleteContractClasses([contractClass], blockNum);
790
+ await store.deleteContractClasses([contractClass], BlockNumber(blockNum));
771
791
  await expect(store.getContractClass(contractClass.id)).resolves.toBeUndefined();
772
792
  });
773
793
 
@@ -775,9 +795,9 @@ export function describeArchiverDataStore(
775
795
  await store.addContractClasses(
776
796
  [contractClass],
777
797
  [await computePublicBytecodeCommitment(contractClass.packedBytecode)],
778
- blockNum + 1,
798
+ BlockNumber(blockNum + 1),
779
799
  );
780
- await store.deleteContractClasses([contractClass], blockNum + 1);
800
+ await store.deleteContractClasses([contractClass], BlockNumber(blockNum + 1));
781
801
  await expect(store.getContractClass(contractClass.id)).resolves.toMatchObject(contractClass);
782
802
  });
783
803
 
@@ -857,8 +877,8 @@ export function describeArchiverDataStore(
857
877
  };
858
878
 
859
879
  const mockBlockWithLogs = async (blockNumber: number): Promise<PublishedL2Block> => {
860
- const block = await L2Block.random(blockNumber);
861
- block.header.globalVariables.blockNumber = blockNumber;
880
+ const block = await L2Block.random(BlockNumber(blockNumber));
881
+ block.header.globalVariables.blockNumber = BlockNumber(blockNumber);
862
882
 
863
883
  block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex: number) => {
864
884
  const txEffect = await TxEffect.random();
@@ -990,7 +1010,7 @@ export function describeArchiverDataStore(
990
1010
  beforeEach(async () => {
991
1011
  blocks = await timesParallel(numBlocks, async (index: number) =>
992
1012
  PublishedL2Block.fromFields({
993
- block: await L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls, numPublicLogs),
1013
+ block: await L2Block.random(BlockNumber(index + 1), txsPerBlock, numPublicFunctionCalls, numPublicLogs),
994
1014
  l1: { blockNumber: BigInt(index), blockHash: makeBlockHash(index), timestamp: BigInt(index) },
995
1015
  attestations: times(3, CommitteeAttestation.random),
996
1016
  }),
@@ -1007,7 +1027,7 @@ export function describeArchiverDataStore(
1007
1027
  const targetTxHash = blocks[targetBlockIndex].block.body.txEffects[targetTxIndex].txHash;
1008
1028
 
1009
1029
  await Promise.all([
1010
- store.unwindBlocks(blocks.length, blocks.length),
1030
+ store.unwindBlocks(BlockNumber(blocks.length), blocks.length),
1011
1031
  store.deleteLogs(blocks.map(b => b.block)),
1012
1032
  ]);
1013
1033
 
@@ -1082,7 +1102,7 @@ export function describeArchiverDataStore(
1082
1102
  const targetTxIndex = randomInt(txsPerBlock);
1083
1103
  const targetLogIndex = randomInt(numPublicLogs);
1084
1104
 
1085
- const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
1105
+ const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
1086
1106
 
1087
1107
  const response = await store.getPublicLogs({ afterLog });
1088
1108
  const logs = response.logs;
@@ -1104,42 +1124,54 @@ export function describeArchiverDataStore(
1104
1124
  it('"txHash" filter param is ignored when "afterLog" is set', async () => {
1105
1125
  // Get random txHash
1106
1126
  const txHash = TxHash.random();
1107
- const afterLog = new LogId(1, 0, 0);
1127
+ const afterLog = new LogId(BlockNumber(1), 0, 0);
1108
1128
 
1109
1129
  const response = await store.getPublicLogs({ txHash, afterLog });
1110
1130
  expect(response.logs.length).toBeGreaterThan(1);
1111
1131
  });
1112
1132
 
1113
1133
  it('intersecting works', async () => {
1114
- 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;
1115
1135
  expect(logs.length).toBe(0);
1116
1136
 
1117
1137
  // "fromBlock" gets correctly trimmed to range and "toBlock" is exclusive
1118
- logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: 5 })).logs;
1138
+ logs = (await store.getPublicLogs({ fromBlock: -10 as BlockNumber, toBlock: BlockNumber(5) })).logs;
1119
1139
  let blockNumbers = new Set(logs.map(log => log.id.blockNumber));
1120
1140
  expect(blockNumbers).toEqual(new Set([1, 2, 3, 4]));
1121
1141
 
1122
1142
  // "toBlock" should be exclusive
1123
- logs = (await store.getPublicLogs({ fromBlock: 1, toBlock: 1 })).logs;
1143
+ logs = (await store.getPublicLogs({ fromBlock: BlockNumber(1), toBlock: BlockNumber(1) })).logs;
1124
1144
  expect(logs.length).toBe(0);
1125
1145
 
1126
- logs = (await store.getPublicLogs({ fromBlock: 10, toBlock: 5 })).logs;
1146
+ logs = (await store.getPublicLogs({ fromBlock: BlockNumber(10), toBlock: BlockNumber(5) })).logs;
1127
1147
  expect(logs.length).toBe(0);
1128
1148
 
1129
1149
  // both "fromBlock" and "toBlock" get correctly capped to range and logs from all blocks are returned
1130
- logs = (await store.getPublicLogs({ fromBlock: -100, toBlock: +100 })).logs;
1150
+ logs = (await store.getPublicLogs({ fromBlock: -100 as BlockNumber, toBlock: +100 })).logs;
1131
1151
  blockNumbers = new Set(logs.map(log => log.id.blockNumber));
1132
1152
  expect(blockNumbers.size).toBe(numBlocks);
1133
1153
 
1134
1154
  // intersecting with "afterLog" works
1135
- 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;
1136
1162
  blockNumbers = new Set(logs.map(log => log.id.blockNumber));
1137
1163
  expect(blockNumbers).toEqual(new Set([4]));
1138
1164
 
1139
- 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;
1140
1166
  expect(logs.length).toBe(0);
1141
1167
 
1142
- 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;
1143
1175
  expect(logs.length).toBe(0);
1144
1176
  });
1145
1177
 
@@ -1149,7 +1181,7 @@ export function describeArchiverDataStore(
1149
1181
  const targetTxIndex = randomInt(txsPerBlock);
1150
1182
  const targetLogIndex = randomInt(numPublicLogs);
1151
1183
 
1152
- const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
1184
+ const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
1153
1185
 
1154
1186
  const response = await store.getPublicLogs({ afterLog, fromBlock: afterLog.blockNumber });
1155
1187
  const logs = response.logs;
@@ -1189,7 +1221,7 @@ export function describeArchiverDataStore(
1189
1221
  valid: false,
1190
1222
  block: randomBlockInfo(1),
1191
1223
  committee: [EthAddress.random(), EthAddress.random()],
1192
- epoch: 123n,
1224
+ epoch: EpochNumber(123),
1193
1225
  seed: 456n,
1194
1226
  attestors: [EthAddress.random()],
1195
1227
  attestations: [CommitteeAttestation.random()],
@@ -1208,7 +1240,7 @@ export function describeArchiverDataStore(
1208
1240
  block: randomBlockInfo(2),
1209
1241
  committee: [EthAddress.random()],
1210
1242
  attestors: [EthAddress.random()],
1211
- epoch: 789n,
1243
+ epoch: EpochNumber(789),
1212
1244
  seed: 101n,
1213
1245
  attestations: [CommitteeAttestation.random()],
1214
1246
  reason: 'invalid-attestation',
@@ -1227,7 +1259,7 @@ export function describeArchiverDataStore(
1227
1259
  valid: false,
1228
1260
  block: randomBlockInfo(3),
1229
1261
  committee: [EthAddress.random()],
1230
- epoch: 999n,
1262
+ epoch: EpochNumber(999),
1231
1263
  seed: 888n,
1232
1264
  attestors: [EthAddress.random()],
1233
1265
  attestations: [CommitteeAttestation.random()],
@@ -1246,7 +1278,7 @@ export function describeArchiverDataStore(
1246
1278
  valid: false,
1247
1279
  block: randomBlockInfo(4),
1248
1280
  committee: [],
1249
- epoch: 0n,
1281
+ epoch: EpochNumber(0),
1250
1282
  seed: 0n,
1251
1283
  attestors: [],
1252
1284
  attestations: [],
@@ -50,6 +50,11 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
50
50
  description: 'Whether to skip validating block attestations (use only for testing).',
51
51
  ...booleanConfigHelper(false),
52
52
  },
53
+ maxAllowedEthClientDriftSeconds: {
54
+ env: 'MAX_ALLOWED_ETH_CLIENT_DRIFT_SECONDS',
55
+ description: 'Maximum allowed drift in seconds between the Ethereum client and current time.',
56
+ ...numberConfigHelper(300),
57
+ },
53
58
  ...chainConfigMappings,
54
59
  ...l1ReaderConfigMappings,
55
60
  viemPollingIntervalMS: {