@aztec/archiver 0.0.1-commit.9b94fc1 → 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 (51) hide show
  1. package/dest/archiver/archiver.d.ts +35 -32
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +60 -34
  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 +4 -3
  10. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  11. package/dest/archiver/data_retrieval.js +4 -3
  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 +14 -5
  27. package/dest/test/mock_archiver.d.ts.map +1 -1
  28. package/dest/test/mock_archiver.js +19 -10
  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 +9 -5
  33. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  34. package/dest/test/mock_l2_block_source.js +19 -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 +15 -15
  39. package/src/archiver/archiver.ts +101 -79
  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 +7 -6
  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 +5 -4
  47. package/src/factory.ts +3 -2
  48. package/src/test/mock_archiver.ts +22 -11
  49. package/src/test/mock_l1_to_l2_message_source.ts +9 -3
  50. package/src/test/mock_l2_block_source.ts +24 -8
  51. package/src/test/mock_structs.ts +3 -2
@@ -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
  }
@@ -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 { toArray } from '@aztec/foundation/iterable';
4
5
  import { createLogger } from '@aztec/foundation/log';
@@ -65,7 +66,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
65
66
  return this.db.transactionAsync(callback);
66
67
  }
67
68
 
68
- public getBlockNumber(): Promise<number> {
69
+ public getBlockNumber(): Promise<BlockNumber> {
69
70
  return this.getSynchedL2BlockNumber();
70
71
  }
71
72
 
@@ -124,7 +125,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
124
125
  async addContractClasses(
125
126
  data: ContractClassPublic[],
126
127
  bytecodeCommitments: Fr[],
127
- blockNumber: number,
128
+ blockNumber: BlockNumber,
128
129
  ): Promise<boolean> {
129
130
  return (
130
131
  await Promise.all(
@@ -133,7 +134,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
133
134
  ).every(Boolean);
134
135
  }
135
136
 
136
- async deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
137
+ async deleteContractClasses(data: ContractClassPublic[], blockNumber: BlockNumber): Promise<boolean> {
137
138
  return (await Promise.all(data.map(c => this.#contractClassStore.deleteContractClasses(c, blockNumber)))).every(
138
139
  Boolean,
139
140
  );
@@ -151,13 +152,13 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
151
152
  return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
152
153
  }
153
154
 
154
- async addContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise<boolean> {
155
+ async addContractInstances(data: ContractInstanceWithAddress[], blockNumber: BlockNumber): Promise<boolean> {
155
156
  return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c, blockNumber)))).every(
156
157
  Boolean,
157
158
  );
158
159
  }
159
160
 
160
- async deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
161
+ async deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: BlockNumber): Promise<boolean> {
161
162
  return (await Promise.all(data.map(c => this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
162
163
  }
163
164
 
@@ -196,11 +197,11 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
196
197
  * @param blocksToUnwind - The number of blocks we are to unwind
197
198
  * @returns True if the operation is successful
198
199
  */
199
- unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean> {
200
+ unwindBlocks(from: BlockNumber, blocksToUnwind: number): Promise<boolean> {
200
201
  return this.#blockStore.unwindBlocks(from, blocksToUnwind);
201
202
  }
202
203
 
203
- getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
204
+ getPublishedBlock(number: BlockNumber): Promise<PublishedL2Block | undefined> {
204
205
  return this.#blockStore.getBlock(number);
205
206
  }
206
207
 
@@ -219,7 +220,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
219
220
  * @param limit - The number of blocks to return.
220
221
  * @returns The requested L2 blocks
221
222
  */
222
- getPublishedBlocks(start: number, limit: number): Promise<PublishedL2Block[]> {
223
+ getPublishedBlocks(start: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
223
224
  return toArray(this.#blockStore.getBlocks(start, limit));
224
225
  }
225
226
 
@@ -230,7 +231,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
230
231
  * @param limit - The number of blocks to return.
231
232
  * @returns The requested L2 blocks
232
233
  */
233
- getBlockHeaders(start: number, limit: number): Promise<BlockHeader[]> {
234
+ getBlockHeaders(start: BlockNumber, limit: number): Promise<BlockHeader[]> {
234
235
  return toArray(this.#blockStore.getBlockHeaders(start, limit));
235
236
  }
236
237
 
@@ -303,7 +304,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
303
304
  * @param blockNumber - L2 block number to get messages for.
304
305
  * @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
305
306
  */
306
- getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
307
+ getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]> {
307
308
  return this.#messageStore.getL1ToL2Messages(blockNumber);
308
309
  }
309
310
 
@@ -313,7 +314,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
313
314
  * @param limit - The maximum number of blocks to retrieve logs from.
314
315
  * @returns An array of private logs from the specified range of blocks.
315
316
  */
316
- getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
317
+ getPrivateLogs(from: BlockNumber, limit: number): Promise<PrivateLog[]> {
317
318
  return this.#logStore.getPrivateLogs(from, limit);
318
319
  }
319
320
 
@@ -362,15 +363,15 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
362
363
  * Gets the number of the latest L2 block processed.
363
364
  * @returns The number of the latest L2 block processed.
364
365
  */
365
- getSynchedL2BlockNumber(): Promise<number> {
366
+ getSynchedL2BlockNumber(): Promise<BlockNumber> {
366
367
  return this.#blockStore.getSynchedL2BlockNumber();
367
368
  }
368
369
 
369
- getProvenL2BlockNumber(): Promise<number> {
370
+ getProvenL2BlockNumber(): Promise<BlockNumber> {
370
371
  return this.#blockStore.getProvenL2BlockNumber();
371
372
  }
372
373
 
373
- async setProvenL2BlockNumber(blockNumber: number) {
374
+ async setProvenL2BlockNumber(blockNumber: BlockNumber) {
374
375
  await this.#blockStore.setProvenL2BlockNumber(blockNumber);
375
376
  }
376
377
 
@@ -400,7 +401,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
400
401
  return this.db.estimateSize();
401
402
  }
402
403
 
403
- public rollbackL1ToL2MessagesToL2Block(targetBlockNumber: number): Promise<void> {
404
+ public rollbackL1ToL2MessagesToL2Block(targetBlockNumber: BlockNumber): Promise<void> {
404
405
  return this.#messageStore.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
405
406
  }
406
407
 
@@ -1,4 +1,5 @@
1
1
  import { INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX } from '@aztec/constants';
2
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
3
  import type { Fr } from '@aztec/foundation/fields';
3
4
  import { createLogger } from '@aztec/foundation/log';
4
5
  import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
@@ -389,9 +390,9 @@ export class LogStore {
389
390
  const log = txLogs[logIndex];
390
391
  if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
391
392
  if (log instanceof ContractClassLog) {
392
- results.push(new ExtendedContractClassLog(new LogId(blockNumber, txIndex, logIndex), log));
393
+ results.push(new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), txIndex, logIndex), log));
393
394
  } else {
394
- results.push(new ExtendedPublicLog(new LogId(blockNumber, txIndex, logIndex), log));
395
+ results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), txIndex, logIndex), log));
395
396
  }
396
397
 
397
398
  if (results.length >= this.#logsMaxPageSize) {
@@ -1,14 +1,15 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
2
3
  import { keccak256 } from '@aztec/foundation/crypto';
3
4
  import { Fr } from '@aztec/foundation/fields';
4
5
  import { BufferReader, bigintToUInt64BE, numToUInt32BE, serializeToBuffer } from '@aztec/foundation/serialize';
5
- import type { UInt32 } from '@aztec/stdlib/types';
6
6
 
7
7
  export type InboxMessage = {
8
8
  index: bigint;
9
9
  leaf: Fr;
10
- l2BlockNumber: UInt32;
11
- l1BlockNumber: bigint;
10
+ // TODO: should be checkpointNumber
11
+ l2BlockNumber: BlockNumber;
12
+ l1BlockNumber: bigint; // L1 block number - NOT Aztec L2
12
13
  l1BlockHash: Buffer32;
13
14
  rollingHash: Buffer16;
14
15
  };
@@ -35,7 +36,7 @@ export function deserializeInboxMessage(buffer: Buffer): InboxMessage {
35
36
  const leaf = reader.readObject(Fr);
36
37
  const l1BlockHash = reader.readObject(Buffer32);
37
38
  const l1BlockNumber = BigInt(reader.readNumber());
38
- const l2BlockNumber = reader.readNumber();
39
+ const l2BlockNumber = BlockNumber(reader.readNumber());
39
40
  const rollingHash = reader.readObject(Buffer16);
40
41
  return { index, leaf, l1BlockHash, l1BlockNumber, l2BlockNumber, rollingHash };
41
42
  }
package/src/factory.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import { createLogger } from '@aztec/foundation/log';
2
3
  import type { DataStoreConfig } from '@aztec/kv-store/config';
3
4
  import { createStore } from '@aztec/kv-store/lmdb-v2';
@@ -59,7 +60,7 @@ async function registerProtocolContracts(store: KVArchiverDataStore) {
59
60
 
60
61
  await store.registerContractFunctionSignatures(publicFunctionSignatures);
61
62
  const bytecodeCommitment = await computePublicBytecodeCommitment(contractClassPublic.packedBytecode);
62
- await store.addContractClasses([contractClassPublic], [bytecodeCommitment], blockNumber);
63
- await store.addContractInstances([contract.instance], blockNumber);
63
+ await store.addContractClasses([contractClassPublic], [bytecodeCommitment], BlockNumber(blockNumber));
64
+ await store.addContractInstances([contract.instance], BlockNumber(blockNumber));
64
65
  }
65
66
  }
@@ -1,5 +1,7 @@
1
+ import type { CheckpointNumber } from '@aztec/foundation/branded-types';
1
2
  import type { Fr } from '@aztec/foundation/fields';
2
- import type { L2Block, L2BlockSource } from '@aztec/stdlib/block';
3
+ import { L2Block, type L2BlockSource } from '@aztec/stdlib/block';
4
+ import type { Checkpoint } from '@aztec/stdlib/checkpoint';
3
5
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
4
6
 
5
7
  import { MockL1ToL2MessageSource } from './mock_l1_to_l2_message_source.js';
@@ -22,36 +24,45 @@ export class MockArchiver extends MockL2BlockSource implements L2BlockSource, L1
22
24
  getL1ToL2MessageIndex(_l1ToL2Message: Fr): Promise<bigint | undefined> {
23
25
  return this.messageSource.getL1ToL2MessageIndex(_l1ToL2Message);
24
26
  }
27
+
28
+ getL1ToL2MessagesForCheckpoint(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
29
+ // TODO: Implement this properly. This only works when we have one block per checkpoint.
30
+ return this.messageSource.getL1ToL2Messages(checkpointNumber);
31
+ }
25
32
  }
26
33
 
27
34
  /**
28
35
  * A mocked implementation of the archiver with a set of precomputed blocks and messages.
29
36
  */
30
37
  export class MockPrefilledArchiver extends MockArchiver {
31
- private precomputed: L2Block[];
38
+ private prefilled: Checkpoint[] = [];
32
39
 
33
- constructor(precomputed: L2Block[], messages: Fr[][]) {
40
+ constructor(prefilled: { checkpoint: Checkpoint; messages: Fr[] }[]) {
34
41
  super();
35
- this.precomputed = precomputed.slice();
36
- messages.forEach((msgs, i) => this.setL1ToL2Messages(i + 1, msgs));
42
+ this.setPrefilled(prefilled);
37
43
  }
38
44
 
39
- public setPrefilledBlocks(blocks: L2Block[], messages: Fr[][]) {
40
- for (const block of blocks) {
41
- this.precomputed[block.number - 1] = block;
45
+ public setPrefilled(prefilled: { checkpoint: Checkpoint; messages: Fr[] }[]) {
46
+ for (const { checkpoint, messages } of prefilled) {
47
+ this.prefilled[checkpoint.number - 1] = checkpoint;
48
+ if (checkpoint.blocks.length !== 1) {
49
+ throw new Error('Prefilled checkpoint must only have 1 block at the moment.');
50
+ }
51
+ this.setL1ToL2Messages(checkpoint.blocks[0].number, messages);
42
52
  }
43
- messages.forEach((msgs, i) => this.setL1ToL2Messages(blocks[i].number, msgs));
44
53
  }
45
54
 
46
55
  public override createBlocks(numBlocks: number) {
47
- if (this.l2Blocks.length + numBlocks > this.precomputed.length) {
56
+ const flattenedBlocks = this.prefilled.flatMap(c => c.blocks);
57
+ if (this.l2Blocks.length + numBlocks > flattenedBlocks.length) {
48
58
  throw new Error(
49
59
  `Not enough precomputed blocks to create ${numBlocks} more blocks (already at ${this.l2Blocks.length})`,
50
60
  );
51
61
  }
52
62
 
53
63
  const fromBlock = this.l2Blocks.length;
54
- this.addBlocks(this.precomputed.slice(fromBlock, fromBlock + numBlocks));
64
+ // TODO: Add L2 blocks and checkpoints separately once archiver has the apis for that.
65
+ this.addBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).map(c => L2Block.fromCheckpoint(c)));
55
66
  return Promise.resolve();
56
67
  }
57
68
  }
@@ -1,3 +1,4 @@
1
+ import { BlockNumber, type CheckpointNumber } from '@aztec/foundation/branded-types';
1
2
  import { Fr } from '@aztec/foundation/fields';
2
3
  import type { L2Tips } from '@aztec/stdlib/block';
3
4
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
@@ -18,6 +19,11 @@ export class MockL1ToL2MessageSource implements L1ToL2MessageSource {
18
19
  this.blockNumber = blockNumber;
19
20
  }
20
21
 
22
+ getL1ToL2MessagesForCheckpoint(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
23
+ // TODO: Implement this properly. This only works when we have one block per checkpoint.
24
+ return this.getL1ToL2Messages(checkpointNumber);
25
+ }
26
+
21
27
  getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
22
28
  return Promise.resolve(this.messagesPerBlock.get(blockNumber) ?? []);
23
29
  }
@@ -26,13 +32,13 @@ export class MockL1ToL2MessageSource implements L1ToL2MessageSource {
26
32
  throw new Error('Method not implemented.');
27
33
  }
28
34
 
29
- getBlockNumber(): Promise<number> {
30
- return Promise.resolve(this.blockNumber);
35
+ getBlockNumber() {
36
+ return Promise.resolve(BlockNumber(this.blockNumber));
31
37
  }
32
38
 
33
39
  getL2Tips(): Promise<L2Tips> {
34
40
  const number = this.blockNumber;
35
- const tip = { number, hash: new Fr(number).toString() };
41
+ const tip = { number: BlockNumber(number), hash: new Fr(number).toString() };
36
42
  return Promise.resolve({
37
43
  latest: tip,
38
44
  proven: tip,
@@ -1,6 +1,6 @@
1
1
  import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
2
2
  import { DefaultL1ContractsConfig } from '@aztec/ethereum';
3
- import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
4
4
  import { Buffer32 } from '@aztec/foundation/buffer';
5
5
  import { EthAddress } from '@aztec/foundation/eth-address';
6
6
  import { Fr } from '@aztec/foundation/fields';
@@ -15,6 +15,7 @@ import {
15
15
  PublishedL2Block,
16
16
  type ValidateBlockResult,
17
17
  } from '@aztec/stdlib/block';
18
+ import type { Checkpoint } from '@aztec/stdlib/checkpoint';
18
19
  import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
19
20
  import { EmptyL1RollupConstants, type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
20
21
  import { type BlockHeader, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
@@ -34,7 +35,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
34
35
  public async createBlocks(numBlocks: number) {
35
36
  for (let i = 0; i < numBlocks; i++) {
36
37
  const blockNum = this.l2Blocks.length + 1;
37
- const block = await L2Block.random(blockNum);
38
+ const block = await L2Block.random(BlockNumber(blockNum));
38
39
  this.l2Blocks.push(block);
39
40
  }
40
41
 
@@ -83,11 +84,11 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
83
84
  * @returns In this mock instance, returns the number of L2 blocks that we've mocked.
84
85
  */
85
86
  public getBlockNumber() {
86
- return Promise.resolve(this.l2Blocks.length);
87
+ return Promise.resolve(BlockNumber(this.l2Blocks.length));
87
88
  }
88
89
 
89
- public getProvenBlockNumber(): Promise<number> {
90
- return Promise.resolve(this.provenBlockNumber);
90
+ public getProvenBlockNumber() {
91
+ return Promise.resolve(BlockNumber(this.provenBlockNumber));
91
92
  }
92
93
 
93
94
  /**
@@ -113,6 +114,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
113
114
  );
114
115
  }
115
116
 
117
+ public async getPublishedCheckpoints(from: CheckpointNumber, limit: number) {
118
+ // TODO: Implement this properly. This only works when we have one block per checkpoint.
119
+ return (await this.getPublishedBlocks(from, limit)).map(block => block.toPublishedCheckpoint());
120
+ }
121
+
122
+ public async getCheckpointByArchive(archive: Fr): Promise<Checkpoint | undefined> {
123
+ // TODO: Implement this properly. This only works when we have one block per checkpoint.
124
+ return (await this.getPublishedBlockByArchive(archive))?.block.toCheckpoint();
125
+ }
126
+
116
127
  public async getPublishedBlocks(from: number, limit: number, proven?: boolean) {
117
128
  const blocks = await this.getBlocks(from, limit, proven);
118
129
  return blocks.map(block =>
@@ -183,6 +194,11 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
183
194
  return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number - 1 : -1)?.getBlockHeader());
184
195
  }
185
196
 
197
+ getCheckpointsForEpoch(epochNumber: EpochNumber): Promise<Checkpoint[]> {
198
+ // TODO: Implement this properly. This only works when we have one block per checkpoint.
199
+ return this.getBlocksForEpoch(epochNumber).then(blocks => blocks.map(b => b.toCheckpoint()));
200
+ }
201
+
186
202
  getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2Block[]> {
187
203
  const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
188
204
  const [start, end] = getSlotRangeForEpoch(epochNumber, { epochDuration });
@@ -255,15 +271,15 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
255
271
 
256
272
  return {
257
273
  latest: {
258
- number: latest,
274
+ number: BlockNumber(latest),
259
275
  hash: (await latestBlock?.hash())?.toString(),
260
276
  },
261
277
  proven: {
262
- number: proven,
278
+ number: BlockNumber(proven),
263
279
  hash: (await provenBlock?.hash())?.toString(),
264
280
  },
265
281
  finalized: {
266
- number: finalized,
282
+ number: BlockNumber(finalized),
267
283
  hash: (await finalizedBlock?.hash())?.toString(),
268
284
  },
269
285
  };
@@ -1,3 +1,4 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
2
3
  import { randomBigInt, randomInt } from '@aztec/foundation/crypto';
3
4
  import { Fr } from '@aztec/foundation/fields';
@@ -19,7 +20,7 @@ export function makeInboxMessage(
19
20
  return {
20
21
  index,
21
22
  leaf,
22
- l2BlockNumber,
23
+ l2BlockNumber: BlockNumber(l2BlockNumber),
23
24
  l1BlockNumber,
24
25
  l1BlockHash,
25
26
  rollingHash,
@@ -39,7 +40,7 @@ export function makeInboxMessages(
39
40
  let rollingHash = initialHash;
40
41
  for (let i = 0; i < count; i++) {
41
42
  const leaf = Fr.random();
42
- const l2BlockNumber = i + initialL2BlockNumber;
43
+ const l2BlockNumber = BlockNumber(i + initialL2BlockNumber);
43
44
  const message = overrideFn(makeInboxMessage(rollingHash, { leaf, l2BlockNumber }), i);
44
45
  rollingHash = message.rollingHash;
45
46
  messages.push(message);