@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 type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
2
+ import { GENESIS_BLOCK_HEADER_HASH } from '@aztec/constants';
2
3
  import { EpochCache } from '@aztec/epoch-cache';
3
4
  import {
4
5
  BlockTagTooOldError,
@@ -9,7 +10,7 @@ import {
9
10
  createEthereumChain,
10
11
  } from '@aztec/ethereum';
11
12
  import { maxBigint } from '@aztec/foundation/bigint';
12
- import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
13
+ import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
13
14
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
14
15
  import { merge, pick } from '@aztec/foundation/collection';
15
16
  import type { EthAddress } from '@aztec/foundation/eth-address';
@@ -35,7 +36,6 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
35
36
  import {
36
37
  type ArchiverEmitter,
37
38
  L2Block,
38
- type L2BlockId,
39
39
  type L2BlockSource,
40
40
  L2BlockSourceEvents,
41
41
  type L2Tips,
@@ -114,9 +114,9 @@ function mapArchiverConfig(config: Partial<ArchiverConfig>) {
114
114
  }
115
115
 
116
116
  type RollupStatus = {
117
- provenCheckpointNumber: number;
117
+ provenCheckpointNumber: CheckpointNumber;
118
118
  provenArchive: Hex;
119
- pendingCheckpointNumber: number;
119
+ pendingCheckpointNumber: CheckpointNumber;
120
120
  pendingArchive: Hex;
121
121
  validationResult: ValidateBlockResult | undefined;
122
122
  lastRetrievedCheckpoint?: PublishedCheckpoint;
@@ -455,7 +455,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
455
455
 
456
456
  /** Checks if there'd be a reorg for the next checkpoint submission and start pruning now. */
457
457
  private async handleEpochPrune(
458
- provenCheckpointNumber: number,
458
+ provenCheckpointNumber: CheckpointNumber,
459
459
  currentL1BlockNumber: bigint,
460
460
  currentL1Timestamp: bigint,
461
461
  ) {
@@ -465,9 +465,9 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
465
465
 
466
466
  if (canPrune) {
467
467
  const timer = new Timer();
468
- const pruneFrom = provenCheckpointNumber + 1;
468
+ const pruneFrom = CheckpointNumber(provenCheckpointNumber + 1);
469
469
 
470
- const header = await this.getCheckpointHeader(Number(pruneFrom));
470
+ const header = await this.getCheckpointHeader(pruneFrom);
471
471
  if (header === undefined) {
472
472
  throw new Error(`Missing checkpoint header ${pruneFrom}`);
473
473
  }
@@ -477,7 +477,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
477
477
 
478
478
  const checkpointsToUnwind = localPendingCheckpointNumber - provenCheckpointNumber;
479
479
 
480
- const checkpoints = await this.getCheckpoints(Number(provenCheckpointNumber) + 1, Number(checkpointsToUnwind));
480
+ const checkpoints = await this.getCheckpoints(pruneFrom, checkpointsToUnwind);
481
481
 
482
482
  // Emit an event for listening services to react to the chain prune
483
483
  this.emit(L2BlockSourceEvents.L2PruneDetected, {
@@ -681,9 +681,9 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
681
681
  rollupPendingCheckpointNumber,
682
682
  pendingArchive,
683
683
  archiveForLocalPendingCheckpointNumber,
684
- ] = await this.rollup.status(BigInt(localPendingCheckpointNumber), { blockNumber: currentL1BlockNumber });
685
- const provenCheckpointNumber = Number(rollupProvenCheckpointNumber);
686
- const pendingCheckpointNumber = Number(rollupPendingCheckpointNumber);
684
+ ] = await this.rollup.status(localPendingCheckpointNumber, { blockNumber: currentL1BlockNumber });
685
+ const provenCheckpointNumber = CheckpointNumber.fromBigInt(rollupProvenCheckpointNumber);
686
+ const pendingCheckpointNumber = CheckpointNumber.fromBigInt(rollupPendingCheckpointNumber);
687
687
  const rollupStatus = {
688
688
  provenCheckpointNumber,
689
689
  provenArchive,
@@ -747,7 +747,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
747
747
 
748
748
  this.emit(L2BlockSourceEvents.L2BlockProven, {
749
749
  type: L2BlockSourceEvents.L2BlockProven,
750
- blockNumber: BigInt(lastProvenBlockNumber),
750
+ blockNumber: lastProvenBlockNumber,
751
751
  slotNumber: provenSlotNumber,
752
752
  epochNumber: provenEpochNumber,
753
753
  });
@@ -812,7 +812,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
812
812
  break;
813
813
  }
814
814
 
815
- const archiveAtContract = await this.rollup.archiveAt(BigInt(candidateCheckpoint.number));
815
+ const archiveAtContract = await this.rollup.archiveAt(candidateCheckpoint.number);
816
816
  this.log.trace(
817
817
  `Checking local checkpoint ${candidateCheckpoint.number} with archive ${candidateCheckpoint.archive.root}`,
818
818
  {
@@ -940,7 +940,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
940
940
  if (err instanceof InitialBlockNumberNotSequentialError) {
941
941
  const { previousBlockNumber, newBlockNumber } = err;
942
942
  const previousBlock = previousBlockNumber
943
- ? await this.store.getPublishedBlock(previousBlockNumber)
943
+ ? await this.store.getPublishedBlock(BlockNumber(previousBlockNumber))
944
944
  : undefined;
945
945
  const updatedL1SyncPoint = previousBlock?.l1.blockNumber ?? this.l1constants.l1StartBlock;
946
946
  await this.store.setBlockSynchedL1BlockNumber(updatedL1SyncPoint);
@@ -1094,7 +1094,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1094
1094
  if (slot(block) <= end) {
1095
1095
  blocks.push(block);
1096
1096
  }
1097
- block = await this.getBlock(block.number - 1);
1097
+ block = await this.getBlock(BlockNumber(block.number - 1));
1098
1098
  }
1099
1099
 
1100
1100
  return blocks.reverse();
@@ -1113,7 +1113,8 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1113
1113
  if (slot(header) <= end) {
1114
1114
  blocks.push(header);
1115
1115
  }
1116
- header = await this.getBlockHeader(--number);
1116
+ number = BlockNumber(number - 1);
1117
+ header = await this.getBlockHeader(number);
1117
1118
  }
1118
1119
  return blocks.reverse();
1119
1120
  }
@@ -1151,17 +1152,27 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1151
1152
  return this.initialSyncComplete;
1152
1153
  }
1153
1154
 
1154
- public async getPublishedCheckpoints(from: number, limit: number, proven?: boolean): Promise<PublishedCheckpoint[]> {
1155
- const blocks = await this.getPublishedBlocks(from, limit, proven);
1155
+ public async getPublishedCheckpoints(
1156
+ from: CheckpointNumber,
1157
+ limit: number,
1158
+ proven?: boolean,
1159
+ ): Promise<PublishedCheckpoint[]> {
1160
+ // TODO: Implement this properly. This only works when we have one block per checkpoint.
1161
+ const blocks = await this.getPublishedBlocks(BlockNumber(from), limit, proven);
1156
1162
  return blocks.map(b => b.toPublishedCheckpoint());
1157
1163
  }
1158
1164
 
1159
- public async getCheckpoints(from: number, limit: number, proven?: boolean): Promise<Checkpoint[]> {
1165
+ public async getCheckpointByArchive(archive: Fr): Promise<Checkpoint | undefined> {
1166
+ // TODO: Implement this properly. This only works when we have one block per checkpoint.
1167
+ return (await this.getPublishedBlockByArchive(archive))?.block.toCheckpoint();
1168
+ }
1169
+
1170
+ public async getCheckpoints(from: CheckpointNumber, limit: number, proven?: boolean): Promise<Checkpoint[]> {
1160
1171
  const published = await this.getPublishedCheckpoints(from, limit, proven);
1161
1172
  return published.map(p => p.checkpoint);
1162
1173
  }
1163
1174
 
1164
- public async getCheckpoint(number: number): Promise<Checkpoint | undefined> {
1175
+ public async getCheckpoint(number: CheckpointNumber): Promise<Checkpoint | undefined> {
1165
1176
  if (number < 0) {
1166
1177
  number = await this.getSynchedCheckpointNumber();
1167
1178
  }
@@ -1172,7 +1183,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1172
1183
  return published[0]?.checkpoint;
1173
1184
  }
1174
1185
 
1175
- public async getCheckpointHeader(number: number | 'latest'): Promise<CheckpointHeader | undefined> {
1186
+ public async getCheckpointHeader(number: CheckpointNumber | 'latest'): Promise<CheckpointHeader | undefined> {
1176
1187
  if (number === 'latest') {
1177
1188
  number = await this.getSynchedCheckpointNumber();
1178
1189
  }
@@ -1183,45 +1194,65 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1183
1194
  return checkpoint?.header;
1184
1195
  }
1185
1196
 
1186
- public getCheckpointNumber(): Promise<number> {
1197
+ public getCheckpointNumber(): Promise<CheckpointNumber> {
1187
1198
  return this.getSynchedCheckpointNumber();
1188
1199
  }
1189
1200
 
1190
- public getSynchedCheckpointNumber(): Promise<number> {
1191
- // TODO: Checkpoint number will no longer be the same as the block number once we support multiple blocks per checkpoint.
1192
- return this.store.getSynchedL2BlockNumber();
1201
+ public async getSynchedCheckpointNumber(): Promise<CheckpointNumber> {
1202
+ // TODO: Create store and apis for checkpoints.
1203
+ // Checkpoint number will no longer be the same as the block number once we support multiple blocks per checkpoint.
1204
+ return CheckpointNumber(await this.store.getSynchedL2BlockNumber());
1193
1205
  }
1194
1206
 
1195
- public getProvenCheckpointNumber(): Promise<number> {
1196
- // TODO: Proven checkpoint number will no longer be the same as the proven block number once we support multiple blocks per checkpoint.
1197
- return this.store.getProvenL2BlockNumber();
1207
+ public async getProvenCheckpointNumber(): Promise<CheckpointNumber> {
1208
+ // TODO: Create store and apis for checkpoints.
1209
+ // Proven checkpoint number will no longer be the same as the proven block number once we support multiple blocks per checkpoint.
1210
+ return CheckpointNumber(await this.store.getProvenL2BlockNumber());
1198
1211
  }
1199
1212
 
1200
- public setProvenCheckpointNumber(checkpointNumber: number): Promise<void> {
1201
- // TODO: Proven checkpoint number will no longer be the same as the proven block number once we support multiple blocks per checkpoint.
1202
- return this.store.setProvenL2BlockNumber(checkpointNumber);
1213
+ public setProvenCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<void> {
1214
+ // TODO: Create store and apis for checkpoints.
1215
+ // Proven checkpoint number will no longer be the same as the proven block number once we support multiple blocks per checkpoint.
1216
+ return this.store.setProvenL2BlockNumber(BlockNumber.fromCheckpointNumber(checkpointNumber));
1203
1217
  }
1204
1218
 
1205
- public unwindCheckpoints(from: number, checkpointsToUnwind: number): Promise<boolean> {
1206
- // TODO: This only works if we have one block per checkpoint.
1207
- return this.store.unwindBlocks(from, checkpointsToUnwind);
1219
+ public unwindCheckpoints(from: CheckpointNumber, checkpointsToUnwind: number): Promise<boolean> {
1220
+ // TODO: Create store and apis for checkpoints.
1221
+ // This only works when we have one block per checkpoint.
1222
+ return this.store.unwindBlocks(BlockNumber.fromCheckpointNumber(from), checkpointsToUnwind);
1208
1223
  }
1209
1224
 
1210
- public getLastBlockNumberInCheckpoint(checkpointNumber: number): Promise<number> {
1211
- // TODO: Checkpoint number will no longer be the same as the block number once we support multiple blocks per checkpoint.
1212
- return Promise.resolve(checkpointNumber);
1225
+ public getLastBlockNumberInCheckpoint(checkpointNumber: CheckpointNumber): Promise<BlockNumber> {
1226
+ // TODO: Create store and apis for checkpoints.
1227
+ // Checkpoint number will no longer be the same as the block number once we support multiple blocks per checkpoint.
1228
+ return Promise.resolve(BlockNumber.fromCheckpointNumber(checkpointNumber));
1213
1229
  }
1214
1230
 
1215
1231
  public addCheckpoints(
1216
1232
  checkpoints: PublishedCheckpoint[],
1217
1233
  pendingChainValidationStatus?: ValidateBlockResult,
1218
1234
  ): Promise<boolean> {
1235
+ // TODO: Create store and apis for checkpoints.
1236
+ // This only works when we have one block per checkpoint.
1219
1237
  return this.store.addBlocks(
1220
1238
  checkpoints.map(p => PublishedL2Block.fromPublishedCheckpoint(p)),
1221
1239
  pendingChainValidationStatus,
1222
1240
  );
1223
1241
  }
1224
1242
 
1243
+ public async getCheckpointsForEpoch(epochNumber: EpochNumber): Promise<Checkpoint[]> {
1244
+ // TODO: Create store and apis for checkpoints.
1245
+ // This only works when we have one block per checkpoint.
1246
+ const blocks = await this.getBlocksForEpoch(epochNumber);
1247
+ return blocks.map(b => b.toCheckpoint());
1248
+ }
1249
+
1250
+ public getL1ToL2MessagesForCheckpoint(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
1251
+ // TODO: Create dedicated api for checkpoints.
1252
+ // This only works when we have one block per checkpoint.
1253
+ return this.getL1ToL2Messages(BlockNumber.fromCheckpointNumber(checkpointNumber));
1254
+ }
1255
+
1225
1256
  /**
1226
1257
  * Gets up to `limit` amount of L2 blocks starting from `from`.
1227
1258
  * @param from - Number of the first block to return (inclusive).
@@ -1229,12 +1260,12 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1229
1260
  * @param proven - If true, only return blocks that have been proven.
1230
1261
  * @returns The requested L2 blocks.
1231
1262
  */
1232
- public getBlocks(from: number, limit: number, proven?: boolean): Promise<L2Block[]> {
1263
+ public getBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<L2Block[]> {
1233
1264
  return this.getPublishedBlocks(from, limit, proven).then(blocks => blocks.map(b => b.block));
1234
1265
  }
1235
1266
 
1236
1267
  /** Equivalent to getBlocks but includes publish data. */
1237
- public async getPublishedBlocks(from: number, limit: number, proven?: boolean): Promise<PublishedL2Block[]> {
1268
+ public async getPublishedBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<PublishedL2Block[]> {
1238
1269
  const limitWithProven = proven
1239
1270
  ? Math.min(limit, Math.max((await this.store.getProvenL2BlockNumber()) - from + 1, 0))
1240
1271
  : limit;
@@ -1262,7 +1293,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1262
1293
  * @param number - The block number to return.
1263
1294
  * @returns The requested L2 block.
1264
1295
  */
1265
- public async getBlock(number: number): Promise<L2Block | undefined> {
1296
+ public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
1266
1297
  // If the number provided is -ve, then return the latest block.
1267
1298
  if (number < 0) {
1268
1299
  number = await this.store.getSynchedL2BlockNumber();
@@ -1274,7 +1305,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1274
1305
  return publishedBlock?.block;
1275
1306
  }
1276
1307
 
1277
- public async getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
1308
+ public async getBlockHeader(number: BlockNumber | 'latest'): Promise<BlockHeader | undefined> {
1278
1309
  if (number === 'latest') {
1279
1310
  number = await this.store.getSynchedL2BlockNumber();
1280
1311
  }
@@ -1299,7 +1330,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1299
1330
  * @param limit - The maximum number of blocks to retrieve logs from.
1300
1331
  * @returns An array of private logs from the specified range of blocks.
1301
1332
  */
1302
- public getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
1333
+ public getPrivateLogs(from: BlockNumber, limit: number): Promise<PrivateLog[]> {
1303
1334
  return this.store.getPrivateLogs(from, limit);
1304
1335
  }
1305
1336
 
@@ -1335,16 +1366,16 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1335
1366
  * Gets the number of the latest L2 block processed by the block source implementation.
1336
1367
  * @returns The number of the latest L2 block processed by the block source implementation.
1337
1368
  */
1338
- public getBlockNumber(): Promise<number> {
1369
+ public getBlockNumber(): Promise<BlockNumber> {
1339
1370
  return this.store.getSynchedL2BlockNumber();
1340
1371
  }
1341
1372
 
1342
- public getProvenBlockNumber(): Promise<number> {
1373
+ public getProvenBlockNumber(): Promise<BlockNumber> {
1343
1374
  return this.store.getProvenL2BlockNumber();
1344
1375
  }
1345
1376
 
1346
1377
  /** Forcefully updates the last proven block number. Use for testing. */
1347
- public setProvenBlockNumber(blockNumber: number): Promise<void> {
1378
+ public setProvenBlockNumber(blockNumber: BlockNumber): Promise<void> {
1348
1379
  return this.store.setProvenL2BlockNumber(blockNumber);
1349
1380
  }
1350
1381
 
@@ -1377,7 +1408,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1377
1408
  * @param blockNumber - L2 block number to get messages for.
1378
1409
  * @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
1379
1410
  */
1380
- getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
1411
+ getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]> {
1381
1412
  return this.store.getL1ToL2Messages(blockNumber);
1382
1413
  }
1383
1414
 
@@ -1419,7 +1450,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1419
1450
  // TODO(#13569): Compute proper finalized block number based on L1 finalized block.
1420
1451
  // We just force it 2 epochs worth of proven data for now.
1421
1452
  // NOTE: update end-to-end/src/e2e_epochs/epochs_empty_blocks.test.ts as that uses finalized blocks in computations
1422
- const finalizedBlockNumber = Math.max(provenBlockNumber - this.l1constants.epochDuration * 2, 0);
1453
+ const finalizedBlockNumber = BlockNumber(Math.max(provenBlockNumber - this.l1constants.epochDuration * 2, 0));
1423
1454
 
1424
1455
  const [latestBlockHeader, provenBlockHeader, finalizedBlockHeader] = await Promise.all([
1425
1456
  latestBlockNumber > 0 ? this.getBlockHeader(latestBlockNumber) : undefined,
@@ -1443,27 +1474,18 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1443
1474
  );
1444
1475
  }
1445
1476
 
1446
- const latestBlockHeaderHash = await latestBlockHeader?.hash();
1447
- const provenBlockHeaderHash = await provenBlockHeader?.hash();
1448
- const finalizedBlockHeaderHash = await finalizedBlockHeader?.hash();
1477
+ const latestBlockHeaderHash = (await latestBlockHeader?.hash()) ?? GENESIS_BLOCK_HEADER_HASH;
1478
+ const provenBlockHeaderHash = (await provenBlockHeader?.hash()) ?? GENESIS_BLOCK_HEADER_HASH;
1479
+ const finalizedBlockHeaderHash = (await finalizedBlockHeader?.hash()) ?? GENESIS_BLOCK_HEADER_HASH;
1449
1480
 
1450
1481
  return {
1451
- latest: {
1452
- number: latestBlockNumber,
1453
- hash: latestBlockHeaderHash?.toString(),
1454
- } as L2BlockId,
1455
- proven: {
1456
- number: provenBlockNumber,
1457
- hash: provenBlockHeaderHash?.toString(),
1458
- } as L2BlockId,
1459
- finalized: {
1460
- number: finalizedBlockNumber,
1461
- hash: finalizedBlockHeaderHash?.toString(),
1462
- } as L2BlockId,
1482
+ latest: { number: latestBlockNumber, hash: latestBlockHeaderHash.toString() },
1483
+ proven: { number: provenBlockNumber, hash: provenBlockHeaderHash.toString() },
1484
+ finalized: { number: finalizedBlockNumber, hash: finalizedBlockHeaderHash.toString() },
1463
1485
  };
1464
1486
  }
1465
1487
 
1466
- public async rollbackTo(targetL2BlockNumber: number): Promise<void> {
1488
+ public async rollbackTo(targetL2BlockNumber: BlockNumber): Promise<void> {
1467
1489
  const currentBlocks = await this.getL2Tips();
1468
1490
  const currentL2Block = currentBlocks.latest.number;
1469
1491
  const currentProvenBlock = currentBlocks.proven.number;
@@ -1480,7 +1502,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1480
1502
  const targetL1BlockNumber = targetL2Block.l1.blockNumber;
1481
1503
  const targetL1BlockHash = await this.getL1BlockHash(targetL1BlockNumber);
1482
1504
  this.log.info(`Unwinding ${blocksToUnwind} blocks from L2 block ${currentL2Block}`);
1483
- await this.store.unwindBlocks(currentL2Block, blocksToUnwind);
1505
+ await this.store.unwindBlocks(BlockNumber(currentL2Block), blocksToUnwind);
1484
1506
  this.log.info(`Unwinding L1 to L2 messages to ${targetL2BlockNumber}`);
1485
1507
  await this.store.rollbackL1ToL2MessagesToL2Block(targetL2BlockNumber);
1486
1508
  this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
@@ -1488,7 +1510,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
1488
1510
  await this.store.setMessageSynchedL1Block({ l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash });
1489
1511
  if (targetL2BlockNumber < currentProvenBlock) {
1490
1512
  this.log.info(`Clearing proven L2 block number`);
1491
- await this.store.setProvenL2BlockNumber(0);
1513
+ await this.store.setProvenL2BlockNumber(BlockNumber.ZERO);
1492
1514
  }
1493
1515
  // TODO(palla/reorg): Set the finalized block when we add support for it.
1494
1516
  // if (targetL2BlockNumber < currentFinalizedBlock) {
@@ -1536,7 +1558,7 @@ export class ArchiverStoreHelper
1536
1558
  * Extracts and stores contract classes out of ContractClassPublished events emitted by the class registry contract.
1537
1559
  * @param allLogs - All logs emitted in a bunch of blocks.
1538
1560
  */
1539
- async #updatePublishedContractClasses(allLogs: ContractClassLog[], blockNum: number, operation: Operation) {
1561
+ async #updatePublishedContractClasses(allLogs: ContractClassLog[], blockNum: BlockNumber, operation: Operation) {
1540
1562
  const contractClassPublishedEvents = allLogs
1541
1563
  .filter(log => ContractClassPublishedEvent.isContractClassPublishedEvent(log))
1542
1564
  .map(log => ContractClassPublishedEvent.fromLog(log));
@@ -1561,7 +1583,7 @@ export class ArchiverStoreHelper
1561
1583
  * Extracts and stores contract instances out of ContractInstancePublished events emitted by the canonical deployer contract.
1562
1584
  * @param allLogs - All logs emitted in a bunch of blocks.
1563
1585
  */
1564
- async #updateDeployedContractInstances(allLogs: PrivateLog[], blockNum: number, operation: Operation) {
1586
+ async #updateDeployedContractInstances(allLogs: PrivateLog[], blockNum: BlockNumber, operation: Operation) {
1565
1587
  const contractInstances = allLogs
1566
1588
  .filter(log => ContractInstancePublishedEvent.isContractInstancePublishedEvent(log))
1567
1589
  .map(log => ContractInstancePublishedEvent.fromLog(log))
@@ -1614,7 +1636,7 @@ export class ArchiverStoreHelper
1614
1636
  * @param _blockNum - The block number
1615
1637
  * @returns
1616
1638
  */
1617
- async #storeBroadcastedIndividualFunctions(allLogs: ContractClassLog[], _blockNum: number) {
1639
+ async #storeBroadcastedIndividualFunctions(allLogs: ContractClassLog[], _blockNum: BlockNumber) {
1618
1640
  // Filter out private and utility function broadcast events
1619
1641
  const privateFnEvents = allLogs
1620
1642
  .filter(log => PrivateFunctionBroadcastedEvent.isPrivateFunctionBroadcastedEvent(log))
@@ -1704,7 +1726,7 @@ export class ArchiverStoreHelper
1704
1726
  });
1705
1727
  }
1706
1728
 
1707
- public async unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean> {
1729
+ public async unwindBlocks(from: BlockNumber, blocksToUnwind: number): Promise<boolean> {
1708
1730
  const last = await this.getSynchedL2BlockNumber();
1709
1731
  if (from != last) {
1710
1732
  throw new Error(`Cannot unwind blocks from block ${from} when the last block is ${last}`);
@@ -1714,7 +1736,7 @@ export class ArchiverStoreHelper
1714
1736
  }
1715
1737
 
1716
1738
  // from - blocksToUnwind = the new head, so + 1 for what we need to remove
1717
- const blocks = await this.getPublishedBlocks(from - blocksToUnwind + 1, blocksToUnwind);
1739
+ const blocks = await this.getPublishedBlocks(BlockNumber(from - blocksToUnwind + 1), blocksToUnwind);
1718
1740
 
1719
1741
  const opResults = await Promise.all([
1720
1742
  // Prune rolls back to the last proven block, which is by definition valid
@@ -1746,10 +1768,10 @@ export class ArchiverStoreHelper
1746
1768
  return opResults.every(Boolean);
1747
1769
  }
1748
1770
 
1749
- getPublishedBlocks(from: number, limit: number): Promise<PublishedL2Block[]> {
1771
+ getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
1750
1772
  return this.store.getPublishedBlocks(from, limit);
1751
1773
  }
1752
- getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
1774
+ getPublishedBlock(number: BlockNumber): Promise<PublishedL2Block | undefined> {
1753
1775
  return this.store.getPublishedBlock(number);
1754
1776
  }
1755
1777
  getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
@@ -1758,7 +1780,7 @@ export class ArchiverStoreHelper
1758
1780
  getPublishedBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined> {
1759
1781
  return this.store.getPublishedBlockByArchive(archive);
1760
1782
  }
1761
- getBlockHeaders(from: number, limit: number): Promise<BlockHeader[]> {
1783
+ getBlockHeaders(from: BlockNumber, limit: number): Promise<BlockHeader[]> {
1762
1784
  return this.store.getBlockHeaders(from, limit);
1763
1785
  }
1764
1786
  getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
@@ -1776,13 +1798,13 @@ export class ArchiverStoreHelper
1776
1798
  addL1ToL2Messages(messages: InboxMessage[]): Promise<void> {
1777
1799
  return this.store.addL1ToL2Messages(messages);
1778
1800
  }
1779
- getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
1801
+ getL1ToL2Messages(blockNumber: BlockNumber): Promise<Fr[]> {
1780
1802
  return this.store.getL1ToL2Messages(blockNumber);
1781
1803
  }
1782
1804
  getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined> {
1783
1805
  return this.store.getL1ToL2MessageIndex(l1ToL2Message);
1784
1806
  }
1785
- getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
1807
+ getPrivateLogs(from: BlockNumber, limit: number): Promise<PrivateLog[]> {
1786
1808
  return this.store.getPrivateLogs(from, limit);
1787
1809
  }
1788
1810
  getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
@@ -1794,13 +1816,13 @@ export class ArchiverStoreHelper
1794
1816
  getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
1795
1817
  return this.store.getContractClassLogs(filter);
1796
1818
  }
1797
- getSynchedL2BlockNumber(): Promise<number> {
1819
+ getSynchedL2BlockNumber(): Promise<BlockNumber> {
1798
1820
  return this.store.getSynchedL2BlockNumber();
1799
1821
  }
1800
- getProvenL2BlockNumber(): Promise<number> {
1822
+ getProvenL2BlockNumber(): Promise<BlockNumber> {
1801
1823
  return this.store.getProvenL2BlockNumber();
1802
1824
  }
1803
- setProvenL2BlockNumber(l2BlockNumber: number): Promise<void> {
1825
+ setProvenL2BlockNumber(l2BlockNumber: BlockNumber): Promise<void> {
1804
1826
  return this.store.setProvenL2BlockNumber(l2BlockNumber);
1805
1827
  }
1806
1828
  setBlockSynchedL1BlockNumber(l1BlockNumber: bigint): Promise<void> {
@@ -1836,7 +1858,7 @@ export class ArchiverStoreHelper
1836
1858
  estimateSize(): Promise<{ mappingSize: number; physicalFileSize: number; actualSize: number; numItems: number }> {
1837
1859
  return this.store.estimateSize();
1838
1860
  }
1839
- rollbackL1ToL2MessagesToL2Block(targetBlockNumber: number): Promise<void> {
1861
+ rollbackL1ToL2MessagesToL2Block(targetBlockNumber: BlockNumber): Promise<void> {
1840
1862
  return this.store.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
1841
1863
  }
1842
1864
  iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
@@ -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>;