@aztec/archiver 0.0.1-commit.0dc957cde → 0.0.1-commit.0ec55a70b

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 (83) hide show
  1. package/dest/archiver.d.ts +15 -9
  2. package/dest/archiver.d.ts.map +1 -1
  3. package/dest/archiver.js +85 -53
  4. package/dest/config.d.ts +1 -1
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +2 -2
  7. package/dest/errors.d.ts +16 -5
  8. package/dest/errors.d.ts.map +1 -1
  9. package/dest/errors.js +29 -6
  10. package/dest/factory.d.ts +4 -4
  11. package/dest/factory.d.ts.map +1 -1
  12. package/dest/factory.js +11 -9
  13. package/dest/index.d.ts +8 -2
  14. package/dest/index.d.ts.map +1 -1
  15. package/dest/index.js +7 -1
  16. package/dest/l1/calldata_retriever.d.ts +2 -1
  17. package/dest/l1/calldata_retriever.d.ts.map +1 -1
  18. package/dest/l1/calldata_retriever.js +9 -4
  19. package/dest/modules/contract_data_source_adapter.d.ts +25 -0
  20. package/dest/modules/contract_data_source_adapter.d.ts.map +1 -0
  21. package/dest/modules/contract_data_source_adapter.js +42 -0
  22. package/dest/modules/data_source_base.d.ts +16 -10
  23. package/dest/modules/data_source_base.d.ts.map +1 -1
  24. package/dest/modules/data_source_base.js +71 -60
  25. package/dest/modules/data_store_updater.d.ts +6 -6
  26. package/dest/modules/data_store_updater.d.ts.map +1 -1
  27. package/dest/modules/data_store_updater.js +42 -40
  28. package/dest/modules/l1_synchronizer.d.ts +5 -4
  29. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  30. package/dest/modules/l1_synchronizer.js +79 -54
  31. package/dest/modules/validation.d.ts +4 -3
  32. package/dest/modules/validation.d.ts.map +1 -1
  33. package/dest/modules/validation.js +4 -4
  34. package/dest/store/block_store.d.ts +58 -27
  35. package/dest/store/block_store.d.ts.map +1 -1
  36. package/dest/store/block_store.js +152 -75
  37. package/dest/store/contract_class_store.d.ts +17 -3
  38. package/dest/store/contract_class_store.d.ts.map +1 -1
  39. package/dest/store/contract_class_store.js +17 -1
  40. package/dest/store/contract_instance_store.d.ts +28 -1
  41. package/dest/store/contract_instance_store.d.ts.map +1 -1
  42. package/dest/store/contract_instance_store.js +31 -0
  43. package/dest/store/data_stores.d.ts +68 -0
  44. package/dest/store/data_stores.d.ts.map +1 -0
  45. package/dest/store/data_stores.js +50 -0
  46. package/dest/store/function_names_cache.d.ts +17 -0
  47. package/dest/store/function_names_cache.d.ts.map +1 -0
  48. package/dest/store/function_names_cache.js +30 -0
  49. package/dest/store/l2_tips_cache.js +1 -1
  50. package/dest/test/fake_l1_state.d.ts +2 -1
  51. package/dest/test/fake_l1_state.d.ts.map +1 -1
  52. package/dest/test/fake_l1_state.js +25 -8
  53. package/dest/test/mock_l2_block_source.d.ts +12 -3
  54. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  55. package/dest/test/mock_l2_block_source.js +24 -2
  56. package/dest/test/noop_l1_archiver.d.ts +4 -4
  57. package/dest/test/noop_l1_archiver.d.ts.map +1 -1
  58. package/dest/test/noop_l1_archiver.js +5 -5
  59. package/package.json +13 -13
  60. package/src/archiver.ts +91 -49
  61. package/src/config.ts +2 -1
  62. package/src/errors.ts +41 -8
  63. package/src/factory.ts +10 -10
  64. package/src/index.ts +15 -1
  65. package/src/l1/calldata_retriever.ts +15 -4
  66. package/src/modules/contract_data_source_adapter.ts +59 -0
  67. package/src/modules/data_source_base.ts +75 -57
  68. package/src/modules/data_store_updater.ts +46 -38
  69. package/src/modules/l1_synchronizer.ts +92 -60
  70. package/src/modules/validation.ts +8 -7
  71. package/src/store/block_store.ts +159 -80
  72. package/src/store/contract_class_store.ts +28 -2
  73. package/src/store/contract_instance_store.ts +43 -0
  74. package/src/store/data_stores.ts +108 -0
  75. package/src/store/function_names_cache.ts +37 -0
  76. package/src/store/l2_tips_cache.ts +1 -1
  77. package/src/test/fake_l1_state.ts +24 -14
  78. package/src/test/mock_l2_block_source.ts +23 -2
  79. package/src/test/noop_l1_archiver.ts +6 -6
  80. package/dest/store/kv_archiver_store.d.ts +0 -383
  81. package/dest/store/kv_archiver_store.d.ts.map +0 -1
  82. package/dest/store/kv_archiver_store.js +0 -501
  83. package/src/store/kv_archiver_store.ts +0 -728
@@ -247,6 +247,27 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
247
247
  indexWithinCheckpoint: block.indexWithinCheckpoint
248
248
  };
249
249
  }
250
+ getCheckpointData(_n) {
251
+ return Promise.resolve(undefined);
252
+ }
253
+ getCheckpointDataRange(_from, _limit) {
254
+ return Promise.resolve([]);
255
+ }
256
+ getCheckpointNumberBySlot(_slot) {
257
+ return Promise.resolve(undefined);
258
+ }
259
+ async getBlockDataWithCheckpointContext(number) {
260
+ const data = await this.getBlockData(number);
261
+ if (!data) {
262
+ return undefined;
263
+ }
264
+ return {
265
+ data,
266
+ checkpoint: undefined,
267
+ l1: undefined,
268
+ attestations: []
269
+ };
270
+ }
250
271
  async getBlockDataByArchive(archive) {
251
272
  const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
252
273
  if (!block) {
@@ -275,6 +296,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
275
296
  checkpointOutHash: computeCheckpointOutHash(checkpoint.blocks.map((b)=>b.body.txEffects.map((tx)=>tx.l2ToL1Msgs))),
276
297
  startBlock: checkpoint.blocks[0].number,
277
298
  blockCount: checkpoint.blocks.length,
299
+ feeAssetPriceModifier: checkpoint.feeAssetPriceModifier,
278
300
  attestations: [],
279
301
  l1: this.mockL1DataForCheckpoint(checkpoint)
280
302
  })));
@@ -437,10 +459,10 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
437
459
  valid: true
438
460
  });
439
461
  }
440
- getProposedCheckpoint() {
462
+ getLastCheckpoint() {
441
463
  return Promise.resolve(undefined);
442
464
  }
443
- getProposedCheckpointOnly() {
465
+ getLastProposedCheckpoint() {
444
466
  return Promise.resolve(undefined);
445
467
  }
446
468
  /** Returns checkpoints whose slot falls within the given epoch. */ getCheckpointsInEpoch(epochNumber) {
@@ -4,14 +4,14 @@ import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
4
4
  import { type TelemetryClient } from '@aztec/telemetry-client';
5
5
  import { Archiver } from '../archiver.js';
6
6
  import { ArchiverInstrumentation } from '../modules/instrumentation.js';
7
- import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
7
+ import type { ArchiverDataStores } from '../store/data_stores.js';
8
8
  /**
9
9
  * Archiver with mocked L1 connectivity for testing.
10
10
  * Uses mock L1 clients and a noop synchronizer, enabling tests that
11
11
  * don't require real Ethereum connectivity.
12
12
  */
13
13
  export declare class NoopL1Archiver extends Archiver {
14
- constructor(dataStore: KVArchiverDataStore, l1Constants: L1RollupConstants & {
14
+ constructor(dataStores: ArchiverDataStores, l1Constants: L1RollupConstants & {
15
15
  genesisArchiveRoot: Fr;
16
16
  }, instrumentation: ArchiverInstrumentation);
17
17
  /** Override start to skip L1 validation checks. */
@@ -20,7 +20,7 @@ export declare class NoopL1Archiver extends Archiver {
20
20
  getSyncedL2SlotNumber(): Promise<SlotNumber | undefined>;
21
21
  }
22
22
  /** Creates an archiver with mocked L1 connectivity for testing. */
23
- export declare function createNoopL1Archiver(dataStore: KVArchiverDataStore, l1Constants: L1RollupConstants & {
23
+ export declare function createNoopL1Archiver(dataStores: ArchiverDataStores, l1Constants: L1RollupConstants & {
24
24
  genesisArchiveRoot: Fr;
25
25
  }, telemetry?: TelemetryClient): Promise<NoopL1Archiver>;
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9vcF9sMV9hcmNoaXZlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3Qvbm9vcF9sMV9hcmNoaXZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0QsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSXBELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBS2hHLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUV4RSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBeUJ6RTs7OztHQUlHO0FBQ0gscUJBQWEsY0FBZSxTQUFRLFFBQVE7SUFDMUMsWUFDRSxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztRQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtLQUFFLEVBQzNELGVBQWUsRUFBRSx1QkFBdUIsRUF5Q3pDO0lBRUQsbURBQW1EO0lBQ25DLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWhFO0lBRUQsNkVBQTZFO0lBQzdELHFCQUFxQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRXZFO0NBQ0Y7QUFFRCxtRUFBbUU7QUFDbkUsd0JBQXNCLG9CQUFvQixDQUN4QyxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztJQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQzNELFNBQVMsR0FBRSxlQUFzQyxHQUNoRCxPQUFPLENBQUMsY0FBYyxDQUFDLENBR3pCIn0=
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9vcF9sMV9hcmNoaXZlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3Qvbm9vcF9sMV9hcmNoaXZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0QsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSXBELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBS2hHLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUV4RSxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBeUJsRTs7OztHQUlHO0FBQ0gscUJBQWEsY0FBZSxTQUFRLFFBQVE7SUFDMUMsWUFDRSxVQUFVLEVBQUUsa0JBQWtCLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztRQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtLQUFFLEVBQzNELGVBQWUsRUFBRSx1QkFBdUIsRUF5Q3pDO0lBRUQsbURBQW1EO0lBQ25DLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWhFO0lBRUQsNkVBQTZFO0lBQzdELHFCQUFxQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRXZFO0NBQ0Y7QUFFRCxtRUFBbUU7QUFDbkUsd0JBQXNCLG9CQUFvQixDQUN4QyxVQUFVLEVBQUUsa0JBQWtCLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztJQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQzNELFNBQVMsR0FBRSxlQUFzQyxHQUNoRCxPQUFPLENBQUMsY0FBYyxDQUFDLENBR3pCIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"noop_l1_archiver.d.ts","sourceRoot":"","sources":["../../src/test/noop_l1_archiver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,KAAK,eAAe,EAAmC,MAAM,yBAAyB,CAAC;AAKhG,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAyBzE;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,YACE,SAAS,EAAE,mBAAmB,EAC9B,WAAW,EAAE,iBAAiB,GAAG;QAAE,kBAAkB,EAAE,EAAE,CAAA;KAAE,EAC3D,eAAe,EAAE,uBAAuB,EAyCzC;IAED,mDAAmD;IACnC,KAAK,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;IAED,6EAA6E;IAC7D,qBAAqB,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEvE;CACF;AAED,mEAAmE;AACnE,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,mBAAmB,EAC9B,WAAW,EAAE,iBAAiB,GAAG;IAAE,kBAAkB,EAAE,EAAE,CAAA;CAAE,EAC3D,SAAS,GAAE,eAAsC,GAChD,OAAO,CAAC,cAAc,CAAC,CAGzB"}
1
+ {"version":3,"file":"noop_l1_archiver.d.ts","sourceRoot":"","sources":["../../src/test/noop_l1_archiver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,KAAK,eAAe,EAAmC,MAAM,yBAAyB,CAAC;AAKhG,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAyBlE;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,YACE,UAAU,EAAE,kBAAkB,EAC9B,WAAW,EAAE,iBAAiB,GAAG;QAAE,kBAAkB,EAAE,EAAE,CAAA;KAAE,EAC3D,eAAe,EAAE,uBAAuB,EAyCzC;IAED,mDAAmD;IACnC,KAAK,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;IAED,6EAA6E;IAC7D,qBAAqB,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEvE;CACF;AAED,mEAAmE;AACnE,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,kBAAkB,EAC9B,WAAW,EAAE,iBAAiB,GAAG;IAAE,kBAAkB,EAAE,EAAE,CAAA;CAAE,EAC3D,SAAS,GAAE,eAAsC,GAChD,OAAO,CAAC,cAAc,CAAC,CAGzB"}
@@ -30,7 +30,7 @@ import { ArchiverInstrumentation } from '../modules/instrumentation.js';
30
30
  * Uses mock L1 clients and a noop synchronizer, enabling tests that
31
31
  * don't require real Ethereum connectivity.
32
32
  */ export class NoopL1Archiver extends Archiver {
33
- constructor(dataStore, l1Constants, instrumentation){
33
+ constructor(dataStores, l1Constants, instrumentation){
34
34
  // Create mocks for L1 clients
35
35
  const publicClient = mock();
36
36
  const debugClient = mock();
@@ -47,7 +47,7 @@ import { ArchiverInstrumentation } from '../modules/instrumentation.js';
47
47
  inboxAddress: EthAddress.ZERO,
48
48
  governanceProposerAddress: EthAddress.ZERO,
49
49
  slashingProposerAddress: EthAddress.ZERO
50
- }, dataStore, {
50
+ }, dataStores, {
51
51
  pollingIntervalMs: 1000,
52
52
  batchSize: 100,
53
53
  skipValidateCheckpointAttestations: true,
@@ -68,7 +68,7 @@ import { ArchiverInstrumentation } from '../modules/instrumentation.js';
68
68
  return Promise.resolve(SlotNumber(Number.MAX_SAFE_INTEGER));
69
69
  }
70
70
  }
71
- /** Creates an archiver with mocked L1 connectivity for testing. */ export async function createNoopL1Archiver(dataStore, l1Constants, telemetry = getTelemetryClient()) {
72
- const instrumentation = await ArchiverInstrumentation.new(telemetry, ()=>dataStore.estimateSize());
73
- return new NoopL1Archiver(dataStore, l1Constants, instrumentation);
71
+ /** Creates an archiver with mocked L1 connectivity for testing. */ export async function createNoopL1Archiver(dataStores, l1Constants, telemetry = getTelemetryClient()) {
72
+ const instrumentation = await ArchiverInstrumentation.new(telemetry, ()=>dataStores.db.estimateSize());
73
+ return new NoopL1Archiver(dataStores, l1Constants, instrumentation);
74
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/archiver",
3
- "version": "0.0.1-commit.0dc957cde",
3
+ "version": "0.0.1-commit.0ec55a70b",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -65,18 +65,18 @@
65
65
  ]
66
66
  },
67
67
  "dependencies": {
68
- "@aztec/blob-client": "0.0.1-commit.0dc957cde",
69
- "@aztec/blob-lib": "0.0.1-commit.0dc957cde",
70
- "@aztec/constants": "0.0.1-commit.0dc957cde",
71
- "@aztec/epoch-cache": "0.0.1-commit.0dc957cde",
72
- "@aztec/ethereum": "0.0.1-commit.0dc957cde",
73
- "@aztec/foundation": "0.0.1-commit.0dc957cde",
74
- "@aztec/kv-store": "0.0.1-commit.0dc957cde",
75
- "@aztec/l1-artifacts": "0.0.1-commit.0dc957cde",
76
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.0dc957cde",
77
- "@aztec/protocol-contracts": "0.0.1-commit.0dc957cde",
78
- "@aztec/stdlib": "0.0.1-commit.0dc957cde",
79
- "@aztec/telemetry-client": "0.0.1-commit.0dc957cde",
68
+ "@aztec/blob-client": "0.0.1-commit.0ec55a70b",
69
+ "@aztec/blob-lib": "0.0.1-commit.0ec55a70b",
70
+ "@aztec/constants": "0.0.1-commit.0ec55a70b",
71
+ "@aztec/epoch-cache": "0.0.1-commit.0ec55a70b",
72
+ "@aztec/ethereum": "0.0.1-commit.0ec55a70b",
73
+ "@aztec/foundation": "0.0.1-commit.0ec55a70b",
74
+ "@aztec/kv-store": "0.0.1-commit.0ec55a70b",
75
+ "@aztec/l1-artifacts": "0.0.1-commit.0ec55a70b",
76
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.0ec55a70b",
77
+ "@aztec/protocol-contracts": "0.0.1-commit.0ec55a70b",
78
+ "@aztec/stdlib": "0.0.1-commit.0ec55a70b",
79
+ "@aztec/telemetry-client": "0.0.1-commit.0ec55a70b",
80
80
  "lodash.groupby": "^4.6.0",
81
81
  "lodash.omit": "^4.5.0",
82
82
  "tslib": "^2.5.0",
package/src/archiver.ts CHANGED
@@ -25,19 +25,20 @@ import {
25
25
  getEpochAtSlot,
26
26
  getSlotAtNextL1Block,
27
27
  getSlotRangeForEpoch,
28
+ getTimestampForSlot,
28
29
  getTimestampRangeForEpoch,
29
30
  } from '@aztec/stdlib/epoch-helpers';
30
31
  import { type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
31
32
 
32
33
  import { type ArchiverConfig, mapArchiverConfig } from './config.js';
33
- import { BlockAlreadyCheckpointedError, NoBlobBodiesFoundError } from './errors.js';
34
+ import { BlockAlreadyCheckpointedError, BlockOrCheckpointSlotExpiredError, NoBlobBodiesFoundError } from './errors.js';
34
35
  import { validateAndLogHistoricalLogsAvailability } from './l1/validate_historical_logs.js';
35
36
  import { validateAndLogTraceAvailability } from './l1/validate_trace.js';
36
37
  import { ArchiverDataSourceBase } from './modules/data_source_base.js';
37
38
  import { ArchiverDataStoreUpdater } from './modules/data_store_updater.js';
38
39
  import type { ArchiverInstrumentation } from './modules/instrumentation.js';
39
40
  import type { ArchiverL1Synchronizer } from './modules/l1_synchronizer.js';
40
- import type { KVArchiverDataStore } from './store/kv_archiver_store.js';
41
+ import { type ArchiverDataStores, backupArchiverDataStores, getArchiverSynchPoint } from './store/data_stores.js';
41
42
  import { L2TipsCache } from './store/l2_tips_cache.js';
42
43
 
43
44
  /** Export ArchiverEmitter for use in factory and tests. */
@@ -45,11 +46,20 @@ export type { ArchiverEmitter };
45
46
 
46
47
  /** Request to add a block to the archiver, queued for processing by the sync loop. */
47
48
  type AddBlockRequest = {
49
+ type: 'block';
48
50
  block: L2Block;
49
51
  resolve: () => void;
50
52
  reject: (err: Error) => void;
51
53
  };
52
54
 
55
+ /** Request to add a proposed checkpoint to the archiver, queued for processing by the sync loop. */
56
+ type AddProposedCheckpointRequest = {
57
+ type: 'checkpoint';
58
+ checkpoint: ProposedCheckpointInput;
59
+ resolve: () => void;
60
+ reject: (err: Error) => void;
61
+ };
62
+
53
63
  export type ArchiverDeps = {
54
64
  telemetry?: TelemetryClient;
55
65
  blobClient: BlobClientInterface;
@@ -75,8 +85,8 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
75
85
  private initialSyncComplete: boolean = false;
76
86
  private initialSyncPromise: PromiseWithResolvers<void>;
77
87
 
78
- /** Queue of blocks to be added to the store, processed by the sync loop. */
79
- private blockQueue: AddBlockRequest[] = [];
88
+ /** Queue of blocks and checkpoints to be added to the store, processed by the sync loop. */
89
+ private inboundQueue: (AddBlockRequest | AddProposedCheckpointRequest)[] = [];
80
90
 
81
91
  /** Helper to handle updates to the store */
82
92
  private readonly updater: ArchiverDataStoreUpdater;
@@ -95,7 +105,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
95
105
  * @param rollup - Rollup contract instance.
96
106
  * @param inbox - Inbox contract instance.
97
107
  * @param l1Addresses - L1 contract addresses (registry, governance proposer, slashing proposer).
98
- * @param dataStore - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
108
+ * @param dataStores - Archiver substores for storage & retrieval of blocks, encrypted logs & contract data.
99
109
  * @param config - Archiver configuration options.
100
110
  * @param blobClient - Client for retrieving blob data.
101
111
  * @param dateProvider - Provider for current date/time.
@@ -113,7 +123,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
113
123
  > & {
114
124
  slashingProposerAddress: EthAddress;
115
125
  },
116
- readonly dataStore: KVArchiverDataStore,
126
+ readonly dataStores: ArchiverDataStores,
117
127
  private config: {
118
128
  pollingIntervalMs: number;
119
129
  batchSize: number;
@@ -133,15 +143,15 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
133
143
  l2TipsCache?: L2TipsCache,
134
144
  private readonly log: Logger = createLogger('archiver'),
135
145
  ) {
136
- super(dataStore, l1Constants);
146
+ super(dataStores, l1Constants);
137
147
 
138
148
  this.tracer = instrumentation.tracer;
139
149
  this.instrumentation = instrumentation;
140
150
  this.initialSyncPromise = promiseWithResolvers();
141
151
  this.synchronizer = synchronizer;
142
152
  this.events = events;
143
- this.l2TipsCache = l2TipsCache ?? new L2TipsCache(this.dataStore.blockStore);
144
- this.updater = new ArchiverDataStoreUpdater(this.dataStore, this.l2TipsCache, {
153
+ this.l2TipsCache = l2TipsCache ?? new L2TipsCache(this.dataStores.blocks);
154
+ this.updater = new ArchiverDataStoreUpdater(this.dataStores, this.l2TipsCache, {
145
155
  rollupManaLimit: l1Constants.rollupManaLimit,
146
156
  });
147
157
 
@@ -191,7 +201,9 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
191
201
 
192
202
  // Log initial state for the archiver
193
203
  const { l1StartBlock } = this.l1Constants;
194
- const { blocksSynchedTo = l1StartBlock, messagesSynchedTo = l1StartBlock } = await this.store.getSynchPoint();
204
+ const { blocksSynchedTo = l1StartBlock, messagesSynchedTo = l1StartBlock } = await getArchiverSynchPoint(
205
+ this.stores,
206
+ );
195
207
  const currentL2Checkpoint = await this.getSynchedCheckpointNumber();
196
208
  this.log.info(
197
209
  `Starting archiver sync to rollup contract ${this.rollup.address} from L1 block ${blocksSynchedTo} and L2 checkpoint ${currentL2Checkpoint}`,
@@ -209,6 +221,14 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
209
221
  return this.runningPromise.trigger();
210
222
  }
211
223
 
224
+ public trySyncImmediate() {
225
+ try {
226
+ return this.syncImmediate();
227
+ } catch (err) {
228
+ this.log.error(`Failed to trigger immediate archiver sync: ${err}`, err);
229
+ }
230
+ }
231
+
212
232
  /**
213
233
  * Queues a block to be added to the archiver store and triggers processing.
214
234
  * The block will be processed by the sync loop.
@@ -217,63 +237,85 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
217
237
  * @returns A promise that resolves when the block has been added to the store, or rejects on error.
218
238
  */
219
239
  public addBlock(block: L2Block): Promise<void> {
220
- return new Promise<void>((resolve, reject) => {
221
- this.blockQueue.push({ block, resolve, reject });
222
- this.log.debug(`Queued block ${block.number} for processing`);
223
- // Trigger an immediate sync, but don't wait for it - the promise resolves when the block is processed
224
- this.syncImmediate().catch(err => {
225
- this.log.error(`Sync immediate call failed: ${err}`);
226
- });
227
- });
240
+ const promise = promiseWithResolvers<void>();
241
+ this.inboundQueue.push({ block, ...promise, type: 'block' });
242
+ this.log.debug(`Queued block ${block.number} for processing`);
243
+ void this.trySyncImmediate();
244
+ return promise.promise;
228
245
  }
229
246
 
230
- public async setProposedCheckpoint(pending: ProposedCheckpointInput): Promise<void> {
231
- await this.updater.setProposedCheckpoint(pending);
247
+ /**
248
+ * Queues a new proposed checkpoint into the archiver store.
249
+ * Checks that the checkpoint is not for an L2 slot already synced from L1.
250
+ * Resolves once the checkpoint has been processed.
251
+ */
252
+ public addProposedCheckpoint(pending: ProposedCheckpointInput): Promise<void> {
253
+ const promise = promiseWithResolvers<void>();
254
+ this.inboundQueue.push({ checkpoint: pending, ...promise, type: 'checkpoint' });
255
+ this.log.debug(`Queued checkpoint ${pending.checkpointNumber} for processing`);
256
+ void this.trySyncImmediate();
257
+ return promise.promise;
232
258
  }
233
259
 
234
260
  /**
235
- * Processes all queued blocks, adding them to the store.
261
+ * Processes all queued blocks and checkpoints, adding them to the store.
236
262
  * Called at the beginning of each sync iteration.
237
- * Blocks are processed in the order they were queued.
263
+ * Items are processed in the order they were queued.
238
264
  */
239
- private async processQueuedBlocks(): Promise<void> {
240
- if (this.blockQueue.length === 0) {
265
+ private async processInboundQueue(): Promise<void> {
266
+ if (this.inboundQueue.length === 0) {
241
267
  return;
242
268
  }
243
269
 
244
- // Take all blocks from the queue
245
- const queuedItems = this.blockQueue.splice(0, this.blockQueue.length);
246
- this.log.debug(`Processing ${queuedItems.length} queued block(s)`);
270
+ // Take all items from the queue
271
+ const queuedItems = this.inboundQueue.splice(0, this.inboundQueue.length);
272
+ this.log.debug(`Processing ${queuedItems.length} queued inbound items`);
247
273
 
248
274
  // Calculate slot threshold for validation
249
275
  const l1Timestamp = this.synchronizer.getL1Timestamp();
250
276
  const slotAtNextL1Block =
251
277
  l1Timestamp === undefined ? undefined : getSlotAtNextL1Block(l1Timestamp, this.l1Constants);
252
278
 
253
- // Process each block individually to properly resolve/reject each promise
254
- for (const { block, resolve, reject } of queuedItems) {
255
- const blockSlot = block.header.globalVariables.slotNumber;
256
- if (slotAtNextL1Block !== undefined && blockSlot < slotAtNextL1Block) {
279
+ // Helpers for manipulating blocks and checkpoints in the queue
280
+ const getSlot: (item: AddBlockRequest | AddProposedCheckpointRequest) => SlotNumber = item =>
281
+ item.type === 'block' ? item.block.header.globalVariables.slotNumber : item.checkpoint.header.slotNumber;
282
+ const getNumber: (item: AddBlockRequest | AddProposedCheckpointRequest) => number = item =>
283
+ item.type === 'block' ? item.block.number : item.checkpoint.checkpointNumber;
284
+
285
+ // Process each item individually to properly resolve/reject each promise
286
+ for (const item of queuedItems) {
287
+ const { resolve, reject, type } = item;
288
+ const itemSlot = getSlot(item);
289
+ const itemNumber = getNumber(item);
290
+ if (slotAtNextL1Block !== undefined && itemSlot < slotAtNextL1Block) {
291
+ const nextSlotTimestamp = getTimestampForSlot(slotAtNextL1Block, this.l1Constants);
257
292
  this.log.warn(
258
- `Rejecting proposed block ${block.number} for past slot ${blockSlot} (current is ${slotAtNextL1Block})`,
259
- { block: block.toBlockInfo(), l1Timestamp, slotAtNextL1Block },
293
+ `Rejecting proposed ${type} ${itemNumber} for past slot ${itemSlot} (current ${slotAtNextL1Block})`,
294
+ { number: itemNumber, type, l1Timestamp, slotAtNextL1Block, nextSlotTimestamp },
260
295
  );
261
- reject(new Error(`Block ${block.number} is for past slot ${blockSlot} (current is ${slotAtNextL1Block})`));
296
+ reject(new BlockOrCheckpointSlotExpiredError(itemSlot, nextSlotTimestamp, l1Timestamp));
262
297
  continue;
263
298
  }
264
299
 
265
300
  try {
266
- const [durationMs] = await elapsed(() => this.updater.addProposedBlock(block));
267
- this.instrumentation.processNewProposedBlock(durationMs, block);
268
- this.log.debug(`Added block ${block.number} to store`);
301
+ if (type === 'block') {
302
+ const [durationMs] = await elapsed(() => this.updater.addProposedBlock(item.block));
303
+ this.instrumentation.processNewProposedBlock(durationMs, item.block);
304
+ } else {
305
+ await this.updater.addProposedCheckpoint(item.checkpoint);
306
+ }
307
+ this.log.debug(`Added ${type} ${itemNumber} to store`);
269
308
  resolve();
270
309
  } catch (err: any) {
271
310
  if (err instanceof BlockAlreadyCheckpointedError) {
272
- this.log.debug(`Proposed block ${block.number} matches already checkpointed block, ignoring late proposal`);
311
+ this.log.debug(`Proposed block ${itemNumber} matches already checkpointed block, ignoring late proposal`);
273
312
  resolve();
274
313
  continue;
275
314
  }
276
- this.log.error(`Failed to add block ${block.number} to store: ${err.message}`);
315
+ this.log.error(`Failed to add ${type} ${itemNumber} to store: ${err.message}`, err, {
316
+ number: itemNumber,
317
+ type,
318
+ });
277
319
  reject(err);
278
320
  }
279
321
  }
@@ -289,7 +331,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
289
331
  @trackSpan('Archiver.sync')
290
332
  private async sync() {
291
333
  // Process any queued blocks first, before doing L1 sync
292
- await this.processQueuedBlocks();
334
+ await this.processInboundQueue();
293
335
  // Now perform L1 sync
294
336
  await this.syncFromL1();
295
337
  }
@@ -305,7 +347,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
305
347
  if (currentL1BlockNumber + 1n >= l1BlockNumberAtEnd) {
306
348
  this.log.info(`Initial archiver sync to L1 block ${currentL1BlockNumber} complete`, {
307
349
  l1BlockNumber: currentL1BlockNumber,
308
- syncPoint: await this.store.getSynchPoint(),
350
+ syncPoint: await getArchiverSynchPoint(this.stores),
309
351
  ...(await this.getL2Tips()),
310
352
  });
311
353
  this.runningPromise.setPollingIntervalMS(this.config.pollingIntervalMs);
@@ -337,7 +379,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
337
379
  }
338
380
 
339
381
  public backupTo(destPath: string): Promise<string> {
340
- return this.dataStore.backupTo(destPath);
382
+ return backupArchiverDataStores(this.dataStores, destPath);
341
383
  }
342
384
 
343
385
  public getL1Constants(): Promise<L1RollupConstants> {
@@ -379,9 +421,9 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
379
421
  }
380
422
 
381
423
  let slotFromCheckpoint: SlotNumber | undefined;
382
- const latestCheckpointNumber = await this.store.getSynchedCheckpointNumber();
424
+ const latestCheckpointNumber = await this.stores.blocks.getLatestCheckpointNumber();
383
425
  if (latestCheckpointNumber > 0) {
384
- const checkpointData = await this.store.getCheckpointData(latestCheckpointNumber);
426
+ const checkpointData = await this.stores.blocks.getCheckpointData(latestCheckpointNumber);
385
427
  if (checkpointData) {
386
428
  slotFromCheckpoint = checkpointData.header.slotNumber;
387
429
  }
@@ -470,14 +512,14 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
470
512
  if (targetL2BlockNumber >= currentL2Block) {
471
513
  throw new Error(`Target L2 block ${targetL2BlockNumber} must be less than current L2 block ${currentL2Block}`);
472
514
  }
473
- const targetL2Block = await this.store.getCheckpointedBlock(targetL2BlockNumber);
515
+ const targetL2Block = await this.stores.blocks.getCheckpointedBlock(targetL2BlockNumber);
474
516
  if (!targetL2Block) {
475
517
  throw new Error(`Target L2 block ${targetL2BlockNumber} not found`);
476
518
  }
477
519
  const targetCheckpointNumber = targetL2Block.checkpointNumber;
478
520
 
479
521
  // Rollback operates at checkpoint granularity: the target block must be the last block of its checkpoint.
480
- const checkpointData = await this.store.getCheckpointData(targetCheckpointNumber);
522
+ const checkpointData = await this.stores.blocks.getCheckpointData(targetCheckpointNumber);
481
523
  if (checkpointData) {
482
524
  const lastBlockInCheckpoint = BlockNumber(checkpointData.startBlock + checkpointData.blockCount - 1);
483
525
  if (targetL2BlockNumber !== lastBlockInCheckpoint) {
@@ -506,10 +548,10 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
506
548
  );
507
549
  await this.updater.removeCheckpointsAfter(targetCheckpointNumber);
508
550
  this.log.info(`Rolling back L1 to L2 messages to checkpoint ${targetCheckpointNumber}`);
509
- await this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
551
+ await this.stores.messages.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
510
552
  this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
511
- await this.store.setCheckpointSynchedL1BlockNumber(targetL1BlockNumber);
512
- await this.store.setMessageSyncState(
553
+ await this.stores.blocks.setSynchedL1BlockNumber(targetL1BlockNumber);
554
+ await this.stores.messages.setMessageSyncState(
513
555
  { l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash },
514
556
  undefined,
515
557
  );
package/src/config.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  booleanConfigHelper,
8
8
  getConfigFromMappings,
9
9
  numberConfigHelper,
10
+ optionalNumberConfigHelper,
10
11
  } from '@aztec/foundation/config';
11
12
  import {
12
13
  type ChainConfig,
@@ -50,7 +51,7 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
50
51
  },
51
52
  archiverStoreMapSizeKb: {
52
53
  env: 'ARCHIVER_STORE_MAP_SIZE_KB',
53
- parseEnv: (val: string) => +val,
54
+ ...optionalNumberConfigHelper(),
54
55
  description: 'The maximum possible size of the archiver DB in KB. Overwrites the general dataStoreMapSizeKb.',
55
56
  },
56
57
  skipValidateCheckpointAttestations: {
package/src/errors.ts CHANGED
@@ -1,14 +1,17 @@
1
+ import type { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
1
2
  import type { Fr } from '@aztec/foundation/schemas';
2
3
 
3
4
  export class NoBlobBodiesFoundError extends Error {
4
5
  constructor(l2BlockNum: number) {
5
6
  super(`No blob bodies found for block ${l2BlockNum}`);
7
+ this.name = 'NoBlobBodiesFoundError';
6
8
  }
7
9
  }
8
10
 
9
11
  export class BlockNumberNotSequentialError extends Error {
10
12
  constructor(newBlockNumber: number, previous: number | undefined) {
11
13
  super(`Cannot insert new block ${newBlockNumber} given previous block number is ${previous ?? 'undefined'}`);
14
+ this.name = 'BlockNumberNotSequentialError';
12
15
  }
13
16
  }
14
17
 
@@ -22,18 +25,29 @@ export class InitialCheckpointNumberNotSequentialError extends Error {
22
25
  previousCheckpointNumber ?? 'undefined'
23
26
  }`,
24
27
  );
28
+ this.name = 'InitialCheckpointNumberNotSequentialError';
25
29
  }
26
30
  }
27
31
 
28
- export class CheckpointNumberNotSequentialError extends Error {
32
+ export class BlockCheckpointNumberNotSequentialError extends Error {
29
33
  constructor(
30
- newCheckpointNumber: number,
31
- previous: number | undefined,
32
- source: 'confirmed' | 'proposed' = 'confirmed',
34
+ blockNumber: BlockNumber,
35
+ blockCheckpointNumber: CheckpointNumber,
36
+ previous: CheckpointNumber | undefined,
33
37
  ) {
34
38
  super(
35
- `Cannot insert new checkpoint ${newCheckpointNumber} given previous ${source} checkpoint number is ${previous ?? 'undefined'}`,
39
+ `Cannot insert new block ${blockNumber} for checkpoint ${blockCheckpointNumber} given previous checkpoint number is ${previous ?? 'undefined'}`,
40
+ );
41
+ this.name = 'BlockCheckpointNumberNotSequentialError';
42
+ }
43
+ }
44
+
45
+ export class CheckpointNumberNotSequentialError extends Error {
46
+ constructor(newCheckpointNumber: CheckpointNumber, previous: CheckpointNumber | undefined) {
47
+ super(
48
+ `Cannot insert new checkpoint ${newCheckpointNumber} given previous checkpoint number is ${previous ?? 'undefined'}`,
36
49
  );
50
+ this.name = 'CheckpointNumberNotSequentialError';
37
51
  }
38
52
  }
39
53
 
@@ -42,6 +56,7 @@ export class BlockIndexNotSequentialError extends Error {
42
56
  super(
43
57
  `Cannot insert new block at checkpoint index ${newBlockIndex} given previous block index is ${previousBlockIndex ?? 'undefined'}`,
44
58
  );
59
+ this.name = 'BlockIndexNotSequentialError';
45
60
  }
46
61
  }
47
62
 
@@ -55,18 +70,21 @@ export class BlockArchiveNotConsistentError extends Error {
55
70
  super(
56
71
  `Cannot insert new block number ${newBlockNumber} with archive ${newBlockArchive.toString()} previous block number is ${previousBlockNumber ?? 'undefined'}, previous archive is ${previousBlockArchive?.toString() ?? 'undefined'}`,
57
72
  );
73
+ this.name = 'BlockArchiveNotConsistentError';
58
74
  }
59
75
  }
60
76
 
61
77
  export class CheckpointNotFoundError extends Error {
62
78
  constructor(checkpointNumber: number) {
63
79
  super(`Failed to find expected checkpoint number ${checkpointNumber}`);
80
+ this.name = 'CheckpointNotFoundError';
64
81
  }
65
82
  }
66
83
 
67
84
  export class BlockNotFoundError extends Error {
68
85
  constructor(blockNumber: number) {
69
86
  super(`Failed to find expected block number ${blockNumber}`);
87
+ this.name = 'BlockNotFoundError';
70
88
  }
71
89
  }
72
90
 
@@ -119,19 +137,34 @@ export class ProposedCheckpointStaleError extends Error {
119
137
  }
120
138
  }
121
139
 
122
- /** Thrown when a proposed checkpoint number is not the expected confirmed + 1. */
140
+ /** Thrown when a proposed checkpoint number is not the expected latestTip + 1. */
123
141
  export class ProposedCheckpointNotSequentialError extends Error {
124
142
  constructor(
125
143
  public readonly proposedCheckpointNumber: number,
126
- public readonly confirmedCheckpointNumber: number,
144
+ public readonly latestTipNumber: number,
127
145
  ) {
128
146
  super(
129
- `Proposed checkpoint ${proposedCheckpointNumber} is not sequential: expected ${confirmedCheckpointNumber + 1} (confirmed + 1)`,
147
+ `Proposed checkpoint ${proposedCheckpointNumber} is not sequential: expected ${latestTipNumber + 1} (latest tip + 1, where tip is highest of confirmed or pending)`,
130
148
  );
131
149
  this.name = 'ProposedCheckpointNotSequentialError';
132
150
  }
133
151
  }
134
152
 
153
+ /** Thrown when a proposed checkpoint or block L2 slot has already expired on L1. */
154
+ export class BlockOrCheckpointSlotExpiredError extends Error {
155
+ constructor(
156
+ public readonly slot: number,
157
+ public readonly nextSlotStart: bigint,
158
+ public readonly l1TimestampSynced: bigint | undefined,
159
+ ) {
160
+ super(
161
+ `Checkpoint or block for slot ${slot} is expired: L1 synced to ${l1TimestampSynced} which is past the next slot start ${nextSlotStart}. ` +
162
+ `If the checkpoint still lands via a late L1 tx, the archiver will pick it up via normal L1-sync (not the pending-queue shortcut).`,
163
+ );
164
+ this.name = 'BlockOrCheckpointSlotExpiredError';
165
+ }
166
+ }
167
+
135
168
  /** Thrown when attempting to promote a proposed checkpoint but no proposed checkpoint exists in the store. */
136
169
  export class NoProposedCheckpointToPromoteError extends Error {
137
170
  constructor() {