@aztec/archiver 0.0.1-commit.2ed92850 → 0.0.1-commit.3469e52

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 (55) hide show
  1. package/README.md +0 -9
  2. package/dest/archiver.d.ts +4 -4
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +20 -19
  5. package/dest/errors.d.ts +1 -6
  6. package/dest/errors.d.ts.map +1 -1
  7. package/dest/errors.js +0 -8
  8. package/dest/factory.d.ts +2 -3
  9. package/dest/factory.d.ts.map +1 -1
  10. package/dest/factory.js +3 -5
  11. package/dest/l1/bin/retrieve-calldata.js +2 -2
  12. package/dest/l1/data_retrieval.d.ts +1 -1
  13. package/dest/l1/data_retrieval.d.ts.map +1 -1
  14. package/dest/l1/data_retrieval.js +2 -2
  15. package/dest/modules/data_source_base.d.ts +17 -16
  16. package/dest/modules/data_source_base.d.ts.map +1 -1
  17. package/dest/modules/data_source_base.js +52 -21
  18. package/dest/modules/data_store_updater.d.ts +19 -23
  19. package/dest/modules/data_store_updater.d.ts.map +1 -1
  20. package/dest/modules/data_store_updater.js +49 -47
  21. package/dest/modules/instrumentation.d.ts +3 -3
  22. package/dest/modules/instrumentation.d.ts.map +1 -1
  23. package/dest/modules/l1_synchronizer.js +7 -7
  24. package/dest/store/block_store.d.ts +19 -33
  25. package/dest/store/block_store.d.ts.map +1 -1
  26. package/dest/store/block_store.js +39 -80
  27. package/dest/store/kv_archiver_store.d.ts +22 -26
  28. package/dest/store/kv_archiver_store.d.ts.map +1 -1
  29. package/dest/store/kv_archiver_store.js +14 -18
  30. package/dest/store/log_store.d.ts +4 -4
  31. package/dest/store/log_store.d.ts.map +1 -1
  32. package/dest/test/fake_l1_state.d.ts +4 -4
  33. package/dest/test/fake_l1_state.d.ts.map +1 -1
  34. package/dest/test/mock_archiver.js +1 -1
  35. package/dest/test/mock_l2_block_source.d.ts +18 -18
  36. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  37. package/dest/test/mock_l2_block_source.js +40 -39
  38. package/dest/test/mock_structs.js +4 -4
  39. package/package.json +13 -13
  40. package/src/archiver.ts +26 -24
  41. package/src/errors.ts +0 -12
  42. package/src/factory.ts +2 -4
  43. package/src/l1/bin/retrieve-calldata.ts +2 -7
  44. package/src/l1/data_retrieval.ts +3 -3
  45. package/src/modules/data_source_base.ts +76 -25
  46. package/src/modules/data_store_updater.ts +55 -59
  47. package/src/modules/instrumentation.ts +2 -2
  48. package/src/modules/l1_synchronizer.ts +9 -9
  49. package/src/store/block_store.ts +56 -103
  50. package/src/store/kv_archiver_store.ts +24 -32
  51. package/src/store/log_store.ts +8 -8
  52. package/src/test/fake_l1_state.ts +2 -2
  53. package/src/test/mock_archiver.ts +1 -1
  54. package/src/test/mock_l2_block_source.ts +60 -50
  55. package/src/test/mock_structs.ts +4 -4
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from '@aztec/foundation/log';
2
- import type { L2Block } from '@aztec/stdlib/block';
2
+ import type { L2BlockNew } from '@aztec/stdlib/block';
3
3
  import {
4
4
  Attributes,
5
5
  type Gauge,
@@ -97,7 +97,7 @@ export class ArchiverInstrumentation {
97
97
  return this.telemetry.isEnabled();
98
98
  }
99
99
 
100
- public processNewBlocks(syncTimePerBlock: number, blocks: L2Block[]) {
100
+ public processNewBlocks(syncTimePerBlock: number, blocks: L2BlockNew[]) {
101
101
  this.syncDurationPerBlock.record(Math.ceil(syncTimePerBlock));
102
102
  this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
103
103
  this.syncBlockCount.add(blocks.length);
@@ -258,7 +258,7 @@ export class ArchiverL1Synchronizer implements Traceable {
258
258
  `Pruning blocks after block ${lastCheckpointedBlockNumber} due to slot ${firstUncheckpointedBlockSlot} not being checkpointed`,
259
259
  { firstUncheckpointedBlockHeader: firstUncheckpointedBlockHeader.toInspect(), slotAtNextL1Block },
260
260
  );
261
- const prunedBlocks = await this.updater.removeUncheckpointedBlocksAfter(lastCheckpointedBlockNumber);
261
+ const prunedBlocks = await this.updater.removeBlocksAfter(lastCheckpointedBlockNumber);
262
262
 
263
263
  if (prunedBlocks.length > 0) {
264
264
  this.events.emit(L2BlockSourceEvents.L2PruneUncheckpointed, {
@@ -331,10 +331,10 @@ export class ArchiverL1Synchronizer implements Traceable {
331
331
  this.log.debug(
332
332
  `L2 prune from ${provenCheckpointNumber + 1} to ${localPendingCheckpointNumber} will occur on next checkpoint submission.`,
333
333
  );
334
- await this.updater.removeCheckpointsAfter(provenCheckpointNumber);
334
+ await this.updater.unwindCheckpoints(localPendingCheckpointNumber, checkpointsToUnwind);
335
335
  this.log.warn(
336
- `Removed ${count(checkpointsToUnwind, 'checkpoint')} after checkpoint ${provenCheckpointNumber} ` +
337
- `due to predicted reorg at L1 block ${currentL1BlockNumber}. ` +
336
+ `Unwound ${count(checkpointsToUnwind, 'checkpoint')} from checkpoint ${localPendingCheckpointNumber} ` +
337
+ `to ${provenCheckpointNumber} due to predicted reorg at L1 block ${currentL1BlockNumber}. ` +
338
338
  `Updated latest checkpoint is ${await this.store.getSynchedCheckpointNumber()}.`,
339
339
  );
340
340
  this.instrumentation.processPrune(timer.ms());
@@ -675,11 +675,11 @@ export class ArchiverL1Synchronizer implements Traceable {
675
675
  tipAfterUnwind--;
676
676
  }
677
677
 
678
- const checkpointsToRemove = localPendingCheckpointNumber - tipAfterUnwind;
679
- await this.updater.removeCheckpointsAfter(CheckpointNumber(tipAfterUnwind));
678
+ const checkpointsToUnwind = localPendingCheckpointNumber - tipAfterUnwind;
679
+ await this.updater.unwindCheckpoints(localPendingCheckpointNumber, checkpointsToUnwind);
680
680
 
681
681
  this.log.warn(
682
- `Removed ${count(checkpointsToRemove, 'checkpoint')} after checkpoint ${tipAfterUnwind} ` +
682
+ `Unwound ${count(checkpointsToUnwind, 'checkpoint')} from checkpoint ${localPendingCheckpointNumber} ` +
683
683
  `due to mismatched checkpoint hashes at L1 block ${currentL1BlockNumber}. ` +
684
684
  `Updated L2 latest checkpoint is ${await this.store.getSynchedCheckpointNumber()}.`,
685
685
  );
@@ -806,8 +806,8 @@ export class ArchiverL1Synchronizer implements Traceable {
806
806
  const updatedValidationResult =
807
807
  rollupStatus.validationResult === initialValidationResult ? undefined : rollupStatus.validationResult;
808
808
  const [processDuration, result] = await elapsed(() =>
809
- execInSpan(this.tracer, 'Archiver.addCheckpoints', () =>
810
- this.updater.addCheckpoints(validCheckpoints, updatedValidationResult),
809
+ execInSpan(this.tracer, 'Archiver.setCheckpointData', () =>
810
+ this.updater.setNewCheckpointData(validCheckpoints, updatedValidationResult),
811
811
  ),
812
812
  );
813
813
  this.instrumentation.processNewBlocks(
@@ -12,14 +12,13 @@ import {
12
12
  Body,
13
13
  CheckpointedL2Block,
14
14
  CommitteeAttestation,
15
- L2Block,
16
15
  L2BlockHash,
16
+ L2BlockNew,
17
17
  type ValidateCheckpointResult,
18
18
  deserializeValidateCheckpointResult,
19
19
  serializeValidateCheckpointResult,
20
20
  } from '@aztec/stdlib/block';
21
21
  import { L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
22
- import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
23
22
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
24
23
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
25
24
  import {
@@ -28,7 +27,6 @@ import {
28
27
  TxEffect,
29
28
  TxHash,
30
29
  TxReceipt,
31
- TxStatus,
32
30
  deserializeIndexedTxEffect,
33
31
  serializeIndexedTxEffect,
34
32
  } from '@aztec/stdlib/tx';
@@ -38,7 +36,6 @@ import {
38
36
  BlockIndexNotSequentialError,
39
37
  BlockNotFoundError,
40
38
  BlockNumberNotSequentialError,
41
- CannotOverwriteCheckpointedBlockError,
42
39
  CheckpointNotFoundError,
43
40
  CheckpointNumberNotConsistentError,
44
41
  CheckpointNumberNotSequentialError,
@@ -78,8 +75,6 @@ export type CheckpointData = {
78
75
  attestations: Buffer[];
79
76
  };
80
77
 
81
- export type RemoveCheckpointsResult = { blocksRemoved: L2Block[] | undefined };
82
-
83
78
  /**
84
79
  * LMDB-based block storage for the archiver.
85
80
  */
@@ -116,10 +111,7 @@ export class BlockStore {
116
111
 
117
112
  #log = createLogger('archiver:block_store');
118
113
 
119
- constructor(
120
- private db: AztecAsyncKVStore,
121
- private l1Constants: Pick<L1RollupConstants, 'epochDuration'>,
122
- ) {
114
+ constructor(private db: AztecAsyncKVStore) {
123
115
  this.#blocks = db.openMap('archiver_blocks');
124
116
  this.#blockTxs = db.openMap('archiver_block_txs');
125
117
  this.#txEffects = db.openMap('archiver_tx_effects');
@@ -133,25 +125,11 @@ export class BlockStore {
133
125
  }
134
126
 
135
127
  /**
136
- * Computes the finalized block number based on the proven block number.
137
- * A block is considered finalized when it's 2 epochs behind the proven block.
138
- * TODO(#13569): Compute proper finalized block number based on L1 finalized block.
139
- * TODO(palla/mbps): Even the provisional computation is wrong, since it should subtract checkpoints, not blocks
140
- * @returns The finalized block number.
141
- */
142
- async getFinalizedL2BlockNumber(): Promise<BlockNumber> {
143
- const provenBlockNumber = await this.getProvenBlockNumber();
144
- return BlockNumber(Math.max(provenBlockNumber - this.l1Constants.epochDuration * 2, 0));
145
- }
146
-
147
- /**
148
- * Append new proposed blocks to the store's list. All blocks must be for the 'current' checkpoint.
149
- * These are uncheckpointed blocks that have been proposed by the sequencer but not yet included in a checkpoint on L1.
150
- * For checkpointed blocks (already published to L1), use addCheckpoints() instead.
151
- * @param blocks - The proposed L2 blocks to be added to the store.
128
+ * Append new blocks to the store's list. All blocks must be for the 'current' checkpoint
129
+ * @param blocks - The L2 blocks to be added to the store.
152
130
  * @returns True if the operation is successful.
153
131
  */
154
- async addProposedBlocks(blocks: L2Block[], opts: { force?: boolean } = {}): Promise<boolean> {
132
+ async addBlocks(blocks: L2BlockNew[], opts: { force?: boolean } = {}): Promise<boolean> {
155
133
  if (blocks.length === 0) {
156
134
  return true;
157
135
  }
@@ -167,12 +145,6 @@ export class BlockStore {
167
145
  const previousBlockNumber = await this.getLatestBlockNumber();
168
146
  const previousCheckpointNumber = await this.getLatestCheckpointNumber();
169
147
 
170
- // Verify we're not overwriting checkpointed blocks
171
- const lastCheckpointedBlockNumber = await this.getCheckpointedL2BlockNumber();
172
- if (!opts.force && firstBlockNumber <= lastCheckpointedBlockNumber) {
173
- throw new CannotOverwriteCheckpointedBlockError(firstBlockNumber, lastCheckpointedBlockNumber);
174
- }
175
-
176
148
  // Check that the first block number is the expected one
177
149
  if (!opts.force && previousBlockNumber !== firstBlockNumber - 1) {
178
150
  throw new InitialBlockNumberNotSequentialError(firstBlockNumber, previousBlockNumber);
@@ -210,7 +182,7 @@ export class BlockStore {
210
182
  }
211
183
 
212
184
  // Iterate over blocks array and insert them, checking that the block numbers and indexes are sequential. Also check they are for the correct checkpoint.
213
- let previousBlock: L2Block | undefined = undefined;
185
+ let previousBlock: L2BlockNew | undefined = undefined;
214
186
  for (const block of blocks) {
215
187
  if (!opts.force && previousBlock) {
216
188
  if (previousBlock.number + 1 !== block.number) {
@@ -269,7 +241,7 @@ export class BlockStore {
269
241
  }
270
242
 
271
243
  let previousBlockNumber: BlockNumber | undefined = undefined;
272
- let previousBlock: L2Block | undefined = undefined;
244
+ let previousBlock: L2BlockNew | undefined = undefined;
273
245
 
274
246
  // If we have a previous checkpoint then we need to get the previous block number
275
247
  if (previousCheckpointData !== undefined) {
@@ -350,7 +322,7 @@ export class BlockStore {
350
322
  });
351
323
  }
352
324
 
353
- private async addBlockToDatabase(block: L2Block, checkpointNumber: number, indexWithinCheckpoint: number) {
325
+ private async addBlockToDatabase(block: L2BlockNew, checkpointNumber: number, indexWithinCheckpoint: number) {
354
326
  const blockHash = L2BlockHash.fromField(await block.hash());
355
327
 
356
328
  await this.#blocks.set(block.number, {
@@ -379,7 +351,7 @@ export class BlockStore {
379
351
  }
380
352
 
381
353
  /** Deletes a block and all associated data (tx effects, indices). */
382
- private async deleteBlock(block: L2Block): Promise<void> {
354
+ private async deleteBlock(block: L2BlockNew): Promise<void> {
383
355
  // Delete the block from the main blocks map
384
356
  await this.#blocks.delete(block.number);
385
357
 
@@ -396,48 +368,51 @@ export class BlockStore {
396
368
  }
397
369
 
398
370
  /**
399
- * Removes all checkpoints with checkpoint number > checkpointNumber.
400
- * Also removes ALL blocks (both checkpointed and uncheckpointed) after the last block of the given checkpoint.
401
- * @param checkpointNumber - Remove all checkpoints strictly after this one.
371
+ * Unwinds checkpoints from the database
372
+ * @param from - The tip of the chain, passed for verification purposes,
373
+ * ensuring that we don't end up deleting something we did not intend
374
+ * @param checkpointsToUnwind - The number of checkpoints we are to unwind
375
+ * @returns True if the operation is successful
402
376
  */
403
- async removeCheckpointsAfter(checkpointNumber: CheckpointNumber): Promise<RemoveCheckpointsResult> {
377
+ async unwindCheckpoints(from: CheckpointNumber, checkpointsToUnwind: number) {
404
378
  return await this.db.transactionAsync(async () => {
405
- const latestCheckpointNumber = await this.getLatestCheckpointNumber();
406
-
407
- if (checkpointNumber >= latestCheckpointNumber) {
408
- this.#log.warn(`No checkpoints to remove after ${checkpointNumber} (latest is ${latestCheckpointNumber})`);
409
- return { blocksRemoved: undefined };
379
+ const last = await this.getLatestCheckpointNumber();
380
+ if (from !== last) {
381
+ throw new Error(`Can only unwind checkpoints from the tip (requested ${from} but current tip is ${last})`);
410
382
  }
411
383
 
412
- // If the proven checkpoint is beyond the target, update it
413
384
  const proven = await this.getProvenCheckpointNumber();
414
- if (proven > checkpointNumber) {
415
- this.#log.warn(`Updating proven checkpoint ${proven} to last valid checkpoint ${checkpointNumber}`);
416
- await this.setProvenCheckpointNumber(checkpointNumber);
385
+ if (from - checkpointsToUnwind < proven) {
386
+ await this.setProvenCheckpointNumber(CheckpointNumber(from - checkpointsToUnwind));
417
387
  }
418
388
 
419
- // Find the last block number to keep (last block of the given checkpoint, or 0 if no checkpoint)
420
- let lastBlockToKeep: BlockNumber;
421
- if (checkpointNumber <= 0) {
422
- lastBlockToKeep = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
423
- } else {
424
- const targetCheckpoint = await this.#checkpoints.getAsync(checkpointNumber);
425
- if (!targetCheckpoint) {
426
- throw new Error(`Target checkpoint ${checkpointNumber} not found in store`);
389
+ for (let i = 0; i < checkpointsToUnwind; i++) {
390
+ const checkpointNumber = from - i;
391
+ const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
392
+
393
+ if (checkpoint === undefined) {
394
+ this.#log.warn(`Cannot remove checkpoint ${checkpointNumber} from the store since we don't have it`);
395
+ continue;
427
396
  }
428
- lastBlockToKeep = BlockNumber(targetCheckpoint.startBlock + targetCheckpoint.numBlocks - 1);
429
- }
397
+ await this.#checkpoints.delete(checkpointNumber);
398
+ const maxBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
430
399
 
431
- // Remove all blocks after lastBlockToKeep (both checkpointed and uncheckpointed)
432
- const blocksRemoved = await this.removeBlocksAfter(lastBlockToKeep);
400
+ for (let blockNumber = checkpoint.startBlock; blockNumber <= maxBlock; blockNumber++) {
401
+ const block = await this.getBlock(BlockNumber(blockNumber));
433
402
 
434
- // Remove all checkpoints after the target
435
- for (let c = latestCheckpointNumber; c > checkpointNumber; c = CheckpointNumber(c - 1)) {
436
- await this.#checkpoints.delete(c);
437
- this.#log.debug(`Removed checkpoint ${c}`);
403
+ if (block === undefined) {
404
+ this.#log.warn(`Cannot remove block ${blockNumber} from the store since we don't have it`);
405
+ continue;
406
+ }
407
+
408
+ await this.deleteBlock(block);
409
+ this.#log.debug(
410
+ `Unwound block ${blockNumber} ${(await block.hash()).toString()} for checkpoint ${checkpointNumber}`,
411
+ );
412
+ }
438
413
  }
439
414
 
440
- return { blocksRemoved };
415
+ return true;
441
416
  });
442
417
  }
443
418
 
@@ -474,7 +449,7 @@ export class BlockStore {
474
449
  return data;
475
450
  }
476
451
 
477
- async getBlocksForCheckpoint(checkpointNumber: CheckpointNumber): Promise<L2Block[] | undefined> {
452
+ async getBlocksForCheckpoint(checkpointNumber: CheckpointNumber): Promise<L2BlockNew[] | undefined> {
478
453
  const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
479
454
  if (!checkpoint) {
480
455
  return undefined;
@@ -497,8 +472,8 @@ export class BlockStore {
497
472
  * @param slotNumber - The slot number to search for.
498
473
  * @returns All blocks with the given slot number, in ascending block number order.
499
474
  */
500
- async getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
501
- const blocks: L2Block[] = [];
475
+ async getBlocksForSlot(slotNumber: SlotNumber): Promise<L2BlockNew[]> {
476
+ const blocks: L2BlockNew[] = [];
502
477
 
503
478
  // Iterate backwards through all blocks and filter by slot number
504
479
  // This is more efficient since we usually query for the most recent slot
@@ -518,13 +493,12 @@ export class BlockStore {
518
493
 
519
494
  /**
520
495
  * Removes all blocks with block number > blockNumber.
521
- * Does not remove any associated checkpoints.
522
496
  * @param blockNumber - The block number to remove after.
523
497
  * @returns The removed blocks (for event emission).
524
498
  */
525
- async removeBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
499
+ async unwindBlocksAfter(blockNumber: BlockNumber): Promise<L2BlockNew[]> {
526
500
  return await this.db.transactionAsync(async () => {
527
- const removedBlocks: L2Block[] = [];
501
+ const removedBlocks: L2BlockNew[] = [];
528
502
 
529
503
  // Get the latest block number to determine the range
530
504
  const latestBlockNumber = await this.getLatestBlockNumber();
@@ -646,7 +620,7 @@ export class BlockStore {
646
620
  * @param limit - The number of blocks to return.
647
621
  * @returns The requested L2 blocks
648
622
  */
649
- async *getBlocks(start: BlockNumber, limit: number): AsyncIterableIterator<L2Block> {
623
+ async *getBlocks(start: BlockNumber, limit: number): AsyncIterableIterator<L2BlockNew> {
650
624
  for await (const [blockNumber, blockStorage] of this.getBlockStorages(start, limit)) {
651
625
  const block = await this.getBlockFromBlockStorage(blockNumber, blockStorage);
652
626
  if (block) {
@@ -660,7 +634,7 @@ export class BlockStore {
660
634
  * @param blockNumber - The number of the block to return.
661
635
  * @returns The requested L2 block.
662
636
  */
663
- async getBlock(blockNumber: BlockNumber): Promise<L2Block | undefined> {
637
+ async getBlock(blockNumber: BlockNumber): Promise<L2BlockNew | undefined> {
664
638
  const blockStorage = await this.#blocks.getAsync(blockNumber);
665
639
  if (!blockStorage || !blockStorage.header) {
666
640
  return Promise.resolve(undefined);
@@ -673,7 +647,7 @@ export class BlockStore {
673
647
  * @param blockHash - The hash of the block to return.
674
648
  * @returns The requested L2 block.
675
649
  */
676
- async getBlockByHash(blockHash: L2BlockHash): Promise<L2Block | undefined> {
650
+ async getBlockByHash(blockHash: L2BlockHash): Promise<L2BlockNew | undefined> {
677
651
  const blockNumber = await this.#blockHashIndex.getAsync(blockHash.toString());
678
652
  if (blockNumber === undefined) {
679
653
  return undefined;
@@ -686,7 +660,7 @@ export class BlockStore {
686
660
  * @param archive - The archive root of the block to return.
687
661
  * @returns The requested L2 block.
688
662
  */
689
- async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
663
+ async getBlockByArchive(archive: Fr): Promise<L2BlockNew | undefined> {
690
664
  const blockNumber = await this.#blockArchiveIndex.getAsync(archive.toString());
691
665
  if (blockNumber === undefined) {
692
666
  return undefined;
@@ -762,7 +736,7 @@ export class BlockStore {
762
736
  private async getBlockFromBlockStorage(
763
737
  blockNumber: number,
764
738
  blockStorage: BlockStorage,
765
- ): Promise<L2Block | undefined> {
739
+ ): Promise<L2BlockNew | undefined> {
766
740
  const header = BlockHeader.fromBuffer(blockStorage.header);
767
741
  const archive = AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive);
768
742
  const blockHash = blockStorage.blockHash;
@@ -786,7 +760,7 @@ export class BlockStore {
786
760
  txEffects.push(deserializeIndexedTxEffect(txEffect).data);
787
761
  }
788
762
  const body = new Body(txEffects);
789
- const block = new L2Block(
763
+ const block = new L2BlockNew(
790
764
  archive,
791
765
  header,
792
766
  body,
@@ -828,34 +802,13 @@ export class BlockStore {
828
802
  return undefined;
829
803
  }
830
804
 
831
- const blockNumber = BlockNumber(txEffect.l2BlockNumber);
832
-
833
- // Use existing archiver methods to determine finalization level
834
- const [provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber] = await Promise.all([
835
- this.getProvenBlockNumber(),
836
- this.getCheckpointedL2BlockNumber(),
837
- this.getFinalizedL2BlockNumber(),
838
- ]);
839
-
840
- let status: TxStatus;
841
- if (blockNumber <= finalizedBlockNumber) {
842
- status = TxStatus.FINALIZED;
843
- } else if (blockNumber <= provenBlockNumber) {
844
- status = TxStatus.PROVEN;
845
- } else if (blockNumber <= checkpointedBlockNumber) {
846
- status = TxStatus.CHECKPOINTED;
847
- } else {
848
- status = TxStatus.PROPOSED;
849
- }
850
-
851
805
  return new TxReceipt(
852
806
  txHash,
853
- status,
854
- TxReceipt.executionResultFromRevertCode(txEffect.data.revertCode),
855
- undefined,
807
+ TxReceipt.statusFromRevertCode(txEffect.data.revertCode),
808
+ '',
856
809
  txEffect.data.transactionFee.toBigInt(),
857
810
  txEffect.l2BlockHash,
858
- blockNumber,
811
+ BlockNumber(txEffect.l2BlockNumber),
859
812
  );
860
813
  }
861
814
 
@@ -6,7 +6,7 @@ import { createLogger } from '@aztec/foundation/log';
6
6
  import type { AztecAsyncKVStore, CustomRange, StoreSize } from '@aztec/kv-store';
7
7
  import { FunctionSelector } from '@aztec/stdlib/abi';
8
8
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
9
- import { CheckpointedL2Block, L2Block, L2BlockHash, type ValidateCheckpointResult } from '@aztec/stdlib/block';
9
+ import { CheckpointedL2Block, L2BlockHash, L2BlockNew, type ValidateCheckpointResult } from '@aztec/stdlib/block';
10
10
  import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
11
11
  import type {
12
12
  ContractClassPublic,
@@ -16,7 +16,6 @@ import type {
16
16
  ExecutablePrivateFunctionWithMembershipProof,
17
17
  UtilityFunctionWithMembershipProof,
18
18
  } from '@aztec/stdlib/contract';
19
- import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
20
19
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
21
20
  import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
22
21
  import type { BlockHeader, TxHash, TxReceipt } from '@aztec/stdlib/tx';
@@ -25,7 +24,7 @@ import type { UInt64 } from '@aztec/stdlib/types';
25
24
  import { join } from 'path';
26
25
 
27
26
  import type { InboxMessage } from '../structs/inbox_message.js';
28
- import { BlockStore, type CheckpointData, type RemoveCheckpointsResult } from './block_store.js';
27
+ import { BlockStore, type CheckpointData } from './block_store.js';
29
28
  import { ContractClassStore } from './contract_class_store.js';
30
29
  import { ContractInstanceStore } from './contract_instance_store.js';
31
30
  import { LogStore } from './log_store.js';
@@ -65,9 +64,8 @@ export class KVArchiverDataStore implements ContractDataSource {
65
64
  constructor(
66
65
  private db: AztecAsyncKVStore,
67
66
  logsMaxPageSize: number = 1000,
68
- l1Constants: Pick<L1RollupConstants, 'epochDuration'>,
69
67
  ) {
70
- this.#blockStore = new BlockStore(db, l1Constants);
68
+ this.#blockStore = new BlockStore(db);
71
69
  this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
72
70
  this.#messageStore = new MessageStore(db);
73
71
  this.#contractClassStore = new ContractClassStore(db);
@@ -103,11 +101,6 @@ export class KVArchiverDataStore implements ContractDataSource {
103
101
  return this.db.close();
104
102
  }
105
103
 
106
- /** Computes the finalized block number based on the proven block number. */
107
- getFinalizedL2BlockNumber(): Promise<BlockNumber> {
108
- return this.#blockStore.getFinalizedL2BlockNumber();
109
- }
110
-
111
104
  /** Looks up a public function name given a selector. */
112
105
  getDebugFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
113
106
  return Promise.resolve(this.functionNames.get(selector.toString()));
@@ -235,14 +228,12 @@ export class KVArchiverDataStore implements ContractDataSource {
235
228
  }
236
229
 
237
230
  /**
238
- * Append new proposed blocks to the store's list.
239
- * These are uncheckpointed blocks that have been proposed by the sequencer but not yet included in a checkpoint on L1.
240
- * For checkpointed blocks (already published to L1), use addCheckpoints() instead.
241
- * @param blocks - The proposed L2 blocks to be added to the store.
231
+ * Append new blocks to the store's list.
232
+ * @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
242
233
  * @returns True if the operation is successful.
243
234
  */
244
- addProposedBlocks(blocks: L2Block[], opts: { force?: boolean; checkpointNumber?: number } = {}): Promise<boolean> {
245
- return this.#blockStore.addProposedBlocks(blocks, opts);
235
+ addBlocks(blocks: L2BlockNew[], opts: { force?: boolean; checkpointNumber?: number } = {}): Promise<boolean> {
236
+ return this.#blockStore.addBlocks(blocks, opts);
246
237
  }
247
238
 
248
239
  /**
@@ -263,12 +254,14 @@ export class KVArchiverDataStore implements ContractDataSource {
263
254
  }
264
255
 
265
256
  /**
266
- * Removes all checkpoints with checkpoint number > checkpointNumber.
267
- * Also removes ALL blocks (both checkpointed and uncheckpointed) after the last block of the given checkpoint.
268
- * @param checkpointNumber - Remove all checkpoints strictly after this one.
257
+ * Unwinds checkpoints from the database
258
+ * @param from - The tip of the chain, passed for verification purposes,
259
+ * ensuring that we don't end up deleting something we did not intend
260
+ * @param checkpointsToUnwind - The number of checkpoints we are to unwind
261
+ * @returns True if the operation is successful
269
262
  */
270
- removeCheckpointsAfter(checkpointNumber: CheckpointNumber): Promise<RemoveCheckpointsResult> {
271
- return this.#blockStore.removeCheckpointsAfter(checkpointNumber);
263
+ unwindCheckpoints(from: CheckpointNumber, checkpointsToUnwind: number): Promise<boolean> {
264
+ return this.#blockStore.unwindCheckpoints(from, checkpointsToUnwind);
272
265
  }
273
266
 
274
267
  /**
@@ -305,21 +298,21 @@ export class KVArchiverDataStore implements ContractDataSource {
305
298
  * Returns the block for the given number, or undefined if not exists.
306
299
  * @param number - The block number to return.
307
300
  */
308
- getBlock(number: BlockNumber): Promise<L2Block | undefined> {
301
+ getBlock(number: BlockNumber): Promise<L2BlockNew | undefined> {
309
302
  return this.#blockStore.getBlock(number);
310
303
  }
311
304
  /**
312
305
  * Returns the block for the given hash, or undefined if not exists.
313
306
  * @param blockHash - The block hash to return.
314
307
  */
315
- getBlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
308
+ getBlockByHash(blockHash: Fr): Promise<L2BlockNew | undefined> {
316
309
  return this.#blockStore.getBlockByHash(L2BlockHash.fromField(blockHash));
317
310
  }
318
311
  /**
319
312
  * Returns the block for the given archive root, or undefined if not exists.
320
313
  * @param archive - The archive root to return.
321
314
  */
322
- getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
315
+ getBlockByArchive(archive: Fr): Promise<L2BlockNew | undefined> {
323
316
  return this.#blockStore.getBlockByArchive(archive);
324
317
  }
325
318
 
@@ -329,7 +322,7 @@ export class KVArchiverDataStore implements ContractDataSource {
329
322
  * @param limit - The number of blocks to return.
330
323
  * @returns The requested L2 blocks.
331
324
  */
332
- getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
325
+ getBlocks(from: BlockNumber, limit: number): Promise<L2BlockNew[]> {
333
326
  return toArray(this.#blockStore.getBlocks(from, limit));
334
327
  }
335
328
 
@@ -392,11 +385,11 @@ export class KVArchiverDataStore implements ContractDataSource {
392
385
  * @param blocks - The blocks for which to add the logs.
393
386
  * @returns True if the operation is successful.
394
387
  */
395
- addLogs(blocks: L2Block[]): Promise<boolean> {
388
+ addLogs(blocks: L2BlockNew[]): Promise<boolean> {
396
389
  return this.#logStore.addLogs(blocks);
397
390
  }
398
391
 
399
- deleteLogs(blocks: L2Block[]): Promise<boolean> {
392
+ deleteLogs(blocks: L2BlockNew[]): Promise<boolean> {
400
393
  return this.#logStore.deleteLogs(blocks);
401
394
  }
402
395
 
@@ -605,7 +598,7 @@ export class KVArchiverDataStore implements ContractDataSource {
605
598
  * @param checkpointNumber Retrieves all blocks for the given checkpoint
606
599
  * @returns The collection of blocks for the requested checkpoint if available (undefined otherwise)
607
600
  */
608
- getBlocksForCheckpoint(checkpointNumber: CheckpointNumber): Promise<L2Block[] | undefined> {
601
+ getBlocksForCheckpoint(checkpointNumber: CheckpointNumber): Promise<L2BlockNew[] | undefined> {
609
602
  return this.#blockStore.getBlocksForCheckpoint(checkpointNumber);
610
603
  }
611
604
 
@@ -623,17 +616,16 @@ export class KVArchiverDataStore implements ContractDataSource {
623
616
  * @param slotNumber - The slot number to search for.
624
617
  * @returns All blocks with the given slot number.
625
618
  */
626
- getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
619
+ getBlocksForSlot(slotNumber: SlotNumber): Promise<L2BlockNew[]> {
627
620
  return this.#blockStore.getBlocksForSlot(slotNumber);
628
621
  }
629
622
 
630
623
  /**
631
624
  * Removes all blocks with block number > blockNumber.
632
- * Does not remove any associated checkpoints.
633
625
  * @param blockNumber - The block number to remove after.
634
626
  * @returns The removed blocks (for event emission).
635
627
  */
636
- removeBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
637
- return this.#blockStore.removeBlocksAfter(blockNumber);
628
+ removeBlocksAfter(blockNumber: BlockNumber): Promise<L2BlockNew[]> {
629
+ return this.#blockStore.unwindBlocksAfter(blockNumber);
638
630
  }
639
631
  }
@@ -6,7 +6,7 @@ import { createLogger } from '@aztec/foundation/log';
6
6
  import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
7
7
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
8
8
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
9
- import { L2Block, L2BlockHash } from '@aztec/stdlib/block';
9
+ import { L2BlockHash, L2BlockNew } from '@aztec/stdlib/block';
10
10
  import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
11
11
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
12
12
  import {
@@ -59,7 +59,7 @@ export class LogStore {
59
59
  * @param block - The L2 block to extract logs from.
60
60
  * @returns An object containing the private and public tagged logs for the block.
61
61
  */
62
- #extractTaggedLogsFromBlock(block: L2Block) {
62
+ #extractTaggedLogsFromBlock(block: L2BlockNew) {
63
63
  // SiloedTag (as string) -> array of log buffers.
64
64
  const privateTaggedLogs = new Map<string, Buffer[]>();
65
65
  // "{contractAddress}_{tag}" (as string) -> array of log buffers.
@@ -120,7 +120,7 @@ export class LogStore {
120
120
  * @returns A map from tag (as string) to an array of serialized private logs belonging to that tag, and a map from
121
121
  * "{contractAddress}_{tag}" (as string) to an array of serialized public logs belonging to that key.
122
122
  */
123
- #extractTaggedLogs(blocks: L2Block[]): {
123
+ #extractTaggedLogs(blocks: L2BlockNew[]): {
124
124
  privateTaggedLogs: Map<string, Buffer[]>;
125
125
  publicTaggedLogs: Map<string, Buffer[]>;
126
126
  } {
@@ -146,7 +146,7 @@ export class LogStore {
146
146
  return { privateTaggedLogs, publicTaggedLogs };
147
147
  }
148
148
 
149
- async #addPrivateLogs(blocks: L2Block[]): Promise<void> {
149
+ async #addPrivateLogs(blocks: L2BlockNew[]): Promise<void> {
150
150
  const newBlocks = await filterAsync(
151
151
  blocks,
152
152
  async block => !(await this.#privateLogKeysByBlock.hasAsync(block.number)),
@@ -181,7 +181,7 @@ export class LogStore {
181
181
  }
182
182
  }
183
183
 
184
- async #addPublicLogs(blocks: L2Block[]): Promise<void> {
184
+ async #addPublicLogs(blocks: L2BlockNew[]): Promise<void> {
185
185
  const newBlocks = await filterAsync(
186
186
  blocks,
187
187
  async block => !(await this.#publicLogKeysByBlock.hasAsync(block.number)),
@@ -229,7 +229,7 @@ export class LogStore {
229
229
  }
230
230
  }
231
231
 
232
- async #addContractClassLogs(blocks: L2Block[]): Promise<void> {
232
+ async #addContractClassLogs(blocks: L2BlockNew[]): Promise<void> {
233
233
  const newBlocks = await filterAsync(
234
234
  blocks,
235
235
  async block => !(await this.#contractClassLogsByBlock.hasAsync(block.number)),
@@ -260,7 +260,7 @@ export class LogStore {
260
260
  * @param blocks - The blocks for which to add the logs.
261
261
  * @returns True if the operation is successful.
262
262
  */
263
- addLogs(blocks: L2Block[]): Promise<boolean> {
263
+ addLogs(blocks: L2BlockNew[]): Promise<boolean> {
264
264
  return this.db.transactionAsync(async () => {
265
265
  await Promise.all([
266
266
  this.#addPrivateLogs(blocks),
@@ -285,7 +285,7 @@ export class LogStore {
285
285
  return L2BlockHash.fromField(blockHash);
286
286
  }
287
287
 
288
- deleteLogs(blocks: L2Block[]): Promise<boolean> {
288
+ deleteLogs(blocks: L2BlockNew[]): Promise<boolean> {
289
289
  return this.db.transactionAsync(async () => {
290
290
  await Promise.all(
291
291
  blocks.map(async block => {
@@ -10,7 +10,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
10
10
  import { EthAddress } from '@aztec/foundation/eth-address';
11
11
  import { createLogger } from '@aztec/foundation/log';
12
12
  import { RollupAbi } from '@aztec/l1-artifacts';
13
- import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2Block } from '@aztec/stdlib/block';
13
+ import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2BlockNew } from '@aztec/stdlib/block';
14
14
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
15
15
  import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
16
16
  import { InboxLeaf } from '@aztec/stdlib/messaging';
@@ -51,7 +51,7 @@ type AddCheckpointOptions = {
51
51
  /** Number of L2 blocks in the checkpoint. Default: 1 */
52
52
  numBlocks?: number;
53
53
  /** Or the actual blocks for the checkpoint */
54
- blocks?: L2Block[];
54
+ blocks?: L2BlockNew[];
55
55
  /** Number of transactions per block. Default: 4 */
56
56
  txsPerBlock?: number;
57
57
  /** Max number of effects per tx (for generating large blobs). Default: undefined */