@aztec/archiver 0.0.1-commit.5de5ca79e → 0.0.1-commit.6201a7b05

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 (99) hide show
  1. package/README.md +12 -6
  2. package/dest/archiver.d.ts +16 -7
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +104 -48
  5. package/dest/config.d.ts +3 -1
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +14 -3
  8. package/dest/errors.d.ts +41 -2
  9. package/dest/errors.d.ts.map +1 -1
  10. package/dest/errors.js +62 -1
  11. package/dest/factory.d.ts +2 -2
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +9 -7
  14. package/dest/index.d.ts +3 -2
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +2 -1
  17. package/dest/l1/calldata_retriever.d.ts +2 -1
  18. package/dest/l1/calldata_retriever.d.ts.map +1 -1
  19. package/dest/l1/calldata_retriever.js +11 -5
  20. package/dest/l1/data_retrieval.d.ts +19 -10
  21. package/dest/l1/data_retrieval.d.ts.map +1 -1
  22. package/dest/l1/data_retrieval.js +25 -32
  23. package/dest/l1/validate_historical_logs.d.ts +23 -0
  24. package/dest/l1/validate_historical_logs.d.ts.map +1 -0
  25. package/dest/l1/validate_historical_logs.js +108 -0
  26. package/dest/modules/data_source_base.d.ts +8 -2
  27. package/dest/modules/data_source_base.d.ts.map +1 -1
  28. package/dest/modules/data_source_base.js +19 -1
  29. package/dest/modules/data_store_updater.d.ts +15 -10
  30. package/dest/modules/data_store_updater.d.ts.map +1 -1
  31. package/dest/modules/data_store_updater.js +71 -68
  32. package/dest/modules/instrumentation.d.ts +7 -2
  33. package/dest/modules/instrumentation.d.ts.map +1 -1
  34. package/dest/modules/instrumentation.js +22 -6
  35. package/dest/modules/l1_synchronizer.d.ts +7 -2
  36. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  37. package/dest/modules/l1_synchronizer.js +261 -143
  38. package/dest/modules/validation.d.ts +4 -3
  39. package/dest/modules/validation.d.ts.map +1 -1
  40. package/dest/modules/validation.js +6 -6
  41. package/dest/store/block_store.d.ts +72 -5
  42. package/dest/store/block_store.d.ts.map +1 -1
  43. package/dest/store/block_store.js +341 -66
  44. package/dest/store/contract_class_store.d.ts +2 -3
  45. package/dest/store/contract_class_store.d.ts.map +1 -1
  46. package/dest/store/contract_class_store.js +7 -67
  47. package/dest/store/contract_instance_store.d.ts +1 -1
  48. package/dest/store/contract_instance_store.d.ts.map +1 -1
  49. package/dest/store/contract_instance_store.js +6 -2
  50. package/dest/store/kv_archiver_store.d.ts +51 -17
  51. package/dest/store/kv_archiver_store.d.ts.map +1 -1
  52. package/dest/store/kv_archiver_store.js +60 -16
  53. package/dest/store/l2_tips_cache.d.ts +2 -1
  54. package/dest/store/l2_tips_cache.d.ts.map +1 -1
  55. package/dest/store/l2_tips_cache.js +27 -7
  56. package/dest/store/log_store.d.ts +1 -1
  57. package/dest/store/log_store.d.ts.map +1 -1
  58. package/dest/store/log_store.js +2 -4
  59. package/dest/store/message_store.d.ts +3 -3
  60. package/dest/store/message_store.d.ts.map +1 -1
  61. package/dest/store/message_store.js +9 -10
  62. package/dest/test/fake_l1_state.d.ts +15 -3
  63. package/dest/test/fake_l1_state.d.ts.map +1 -1
  64. package/dest/test/fake_l1_state.js +80 -18
  65. package/dest/test/mock_l1_to_l2_message_source.d.ts +1 -1
  66. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  67. package/dest/test/mock_l1_to_l2_message_source.js +2 -1
  68. package/dest/test/mock_l2_block_source.d.ts +16 -2
  69. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  70. package/dest/test/mock_l2_block_source.js +50 -3
  71. package/dest/test/noop_l1_archiver.d.ts +1 -1
  72. package/dest/test/noop_l1_archiver.d.ts.map +1 -1
  73. package/dest/test/noop_l1_archiver.js +4 -2
  74. package/package.json +13 -13
  75. package/src/archiver.ts +126 -46
  76. package/src/config.ts +15 -1
  77. package/src/errors.ts +97 -2
  78. package/src/factory.ts +13 -7
  79. package/src/index.ts +2 -1
  80. package/src/l1/calldata_retriever.ts +17 -5
  81. package/src/l1/data_retrieval.ts +36 -45
  82. package/src/l1/validate_historical_logs.ts +140 -0
  83. package/src/modules/data_source_base.ts +32 -1
  84. package/src/modules/data_store_updater.ts +98 -97
  85. package/src/modules/instrumentation.ts +27 -7
  86. package/src/modules/l1_synchronizer.ts +328 -169
  87. package/src/modules/validation.ts +10 -9
  88. package/src/store/block_store.ts +419 -76
  89. package/src/store/contract_class_store.ts +8 -106
  90. package/src/store/contract_instance_store.ts +8 -5
  91. package/src/store/kv_archiver_store.ts +100 -32
  92. package/src/store/l2_tips_cache.ts +58 -13
  93. package/src/store/log_store.ts +2 -5
  94. package/src/store/message_store.ts +10 -12
  95. package/src/structs/inbox_message.ts +1 -1
  96. package/src/test/fake_l1_state.ts +99 -27
  97. package/src/test/mock_l1_to_l2_message_source.ts +1 -0
  98. package/src/test/mock_l2_block_source.ts +58 -2
  99. package/src/test/noop_l1_archiver.ts +3 -1
@@ -19,6 +19,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
19
19
  provenBlockNumber = 0;
20
20
  finalizedBlockNumber = 0;
21
21
  checkpointedBlockNumber = 0;
22
+ proposedCheckpointBlockNumber = 0;
22
23
  log = createLogger('archiver:mock_l2_block_source');
23
24
  /** Creates blocks grouped into single-block checkpoints. */ async createBlocks(numBlocks) {
24
25
  await this.createCheckpoints(numBlocks, 1);
@@ -56,6 +57,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
56
57
  });
57
58
  // Keep tip numbers consistent with remaining blocks.
58
59
  this.checkpointedBlockNumber = Math.min(this.checkpointedBlockNumber, maxBlockNum);
60
+ this.proposedCheckpointBlockNumber = Math.min(this.proposedCheckpointBlockNumber, maxBlockNum);
59
61
  this.provenBlockNumber = Math.min(this.provenBlockNumber, maxBlockNum);
60
62
  this.finalizedBlockNumber = Math.min(this.finalizedBlockNumber, maxBlockNum);
61
63
  this.log.verbose(`Removed ${numBlocks} blocks from the mock L2 block source`);
@@ -69,9 +71,16 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
69
71
  }
70
72
  this.finalizedBlockNumber = finalizedBlockNumber;
71
73
  }
74
+ setProposedCheckpointBlockNumber(blockNumber) {
75
+ this.proposedCheckpointBlockNumber = blockNumber;
76
+ }
72
77
  setCheckpointedBlockNumber(checkpointedBlockNumber) {
73
78
  const prevCheckpointed = this.checkpointedBlockNumber;
74
79
  this.checkpointedBlockNumber = checkpointedBlockNumber;
80
+ // Proposed checkpoint is always at least as advanced as checkpointed
81
+ if (this.proposedCheckpointBlockNumber < checkpointedBlockNumber) {
82
+ this.proposedCheckpointBlockNumber = checkpointedBlockNumber;
83
+ }
75
84
  // Auto-create single-block checkpoints for newly checkpointed blocks that don't have one yet.
76
85
  // This handles blocks added via addProposedBlocks that are now being marked as checkpointed.
77
86
  const newCheckpoints = [];
@@ -124,6 +133,9 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
124
133
  getFinalizedL2BlockNumber() {
125
134
  return Promise.resolve(BlockNumber(this.finalizedBlockNumber));
126
135
  }
136
+ getProposedCheckpointL2BlockNumber() {
137
+ return Promise.resolve(BlockNumber(this.proposedCheckpointBlockNumber));
138
+ }
127
139
  getCheckpointedBlock(number) {
128
140
  if (number > this.checkpointedBlockNumber) {
129
141
  return Promise.resolve(undefined);
@@ -235,6 +247,27 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
235
247
  indexWithinCheckpoint: block.indexWithinCheckpoint
236
248
  };
237
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
+ }
238
271
  async getBlockDataByArchive(archive) {
239
272
  const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
240
273
  if (!block) {
@@ -263,6 +296,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
263
296
  checkpointOutHash: computeCheckpointOutHash(checkpoint.blocks.map((b)=>b.body.txEffects.map((tx)=>tx.l2ToL1Msgs))),
264
297
  startBlock: checkpoint.blocks[0].number,
265
298
  blockCount: checkpoint.blocks.length,
299
+ feeAssetPriceModifier: checkpoint.feeAssetPriceModifier,
266
300
  attestations: [],
267
301
  l1: this.mockL1DataForCheckpoint(checkpoint)
268
302
  })));
@@ -315,16 +349,18 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
315
349
  return undefined;
316
350
  }
317
351
  async getL2Tips() {
318
- const [latest, proven, finalized, checkpointed] = [
352
+ const [latest, proven, finalized, checkpointed, proposedCheckpoint] = [
319
353
  await this.getBlockNumber(),
320
354
  await this.getProvenBlockNumber(),
321
355
  this.finalizedBlockNumber,
322
- this.checkpointedBlockNumber
356
+ this.checkpointedBlockNumber,
357
+ await this.getProposedCheckpointL2BlockNumber()
323
358
  ];
324
359
  const latestBlock = this.l2Blocks[latest - 1];
325
360
  const provenBlock = this.l2Blocks[proven - 1];
326
361
  const finalizedBlock = this.l2Blocks[finalized - 1];
327
362
  const checkpointedBlock = this.l2Blocks[checkpointed - 1];
363
+ const proposedCheckpointBlock = this.l2Blocks[proposedCheckpoint - 1];
328
364
  const latestBlockId = {
329
365
  number: BlockNumber(latest),
330
366
  hash: (await latestBlock?.hash())?.toString()
@@ -341,6 +377,10 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
341
377
  number: BlockNumber(checkpointed),
342
378
  hash: (await checkpointedBlock?.hash())?.toString()
343
379
  };
380
+ const proposedCheckpointBlockId = {
381
+ number: BlockNumber(proposedCheckpoint),
382
+ hash: (await proposedCheckpointBlock?.hash())?.toString()
383
+ };
344
384
  const makeTipId = (blockId)=>({
345
385
  block: blockId,
346
386
  checkpoint: {
@@ -352,7 +392,8 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
352
392
  proposed: latestBlockId,
353
393
  checkpointed: makeTipId(checkpointedBlockId),
354
394
  proven: makeTipId(provenBlockId),
355
- finalized: makeTipId(finalizedBlockId)
395
+ finalized: makeTipId(finalizedBlockId),
396
+ proposedCheckpoint: makeTipId(proposedCheckpointBlockId)
356
397
  };
357
398
  }
358
399
  getSyncedL2EpochNumber() {
@@ -418,6 +459,12 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
418
459
  valid: true
419
460
  });
420
461
  }
462
+ getLastCheckpoint() {
463
+ return Promise.resolve(undefined);
464
+ }
465
+ getLastProposedCheckpoint() {
466
+ return Promise.resolve(undefined);
467
+ }
421
468
  /** Returns checkpoints whose slot falls within the given epoch. */ getCheckpointsInEpoch(epochNumber) {
422
469
  const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
423
470
  const [start, end] = getSlotRangeForEpoch(epochNumber, {
@@ -23,4 +23,4 @@ export declare class NoopL1Archiver extends Archiver {
23
23
  export declare function createNoopL1Archiver(dataStore: KVArchiverDataStore, l1Constants: L1RollupConstants & {
24
24
  genesisArchiveRoot: Fr;
25
25
  }, telemetry?: TelemetryClient): Promise<NoopL1Archiver>;
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9vcF9sMV9hcmNoaXZlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3Qvbm9vcF9sMV9hcmNoaXZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0QsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSXBELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBS2hHLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUV4RSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBeUJ6RTs7OztHQUlHO0FBQ0gscUJBQWEsY0FBZSxTQUFRLFFBQVE7SUFDMUMsWUFDRSxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztRQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtLQUFFLEVBQzNELGVBQWUsRUFBRSx1QkFBdUIsRUF1Q3pDO0lBRUQsbURBQW1EO0lBQ25DLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWhFO0lBRUQsNkVBQTZFO0lBQzdELHFCQUFxQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRXZFO0NBQ0Y7QUFFRCxtRUFBbUU7QUFDbkUsd0JBQXNCLG9CQUFvQixDQUN4QyxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztJQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQzNELFNBQVMsR0FBRSxlQUFzQyxHQUNoRCxPQUFPLENBQUMsY0FBYyxDQUFDLENBR3pCIn0=
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9vcF9sMV9hcmNoaXZlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3Qvbm9vcF9sMV9hcmNoaXZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0QsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSXBELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBS2hHLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUV4RSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBeUJ6RTs7OztHQUlHO0FBQ0gscUJBQWEsY0FBZSxTQUFRLFFBQVE7SUFDMUMsWUFDRSxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztRQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtLQUFFLEVBQzNELGVBQWUsRUFBRSx1QkFBdUIsRUF5Q3pDO0lBRUQsbURBQW1EO0lBQ25DLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWhFO0lBRUQsNkVBQTZFO0lBQzdELHFCQUFxQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRXZFO0NBQ0Y7QUFFRCxtRUFBbUU7QUFDbkUsd0JBQXNCLG9CQUFvQixDQUN4QyxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztJQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQzNELFNBQVMsR0FBRSxlQUFzQyxHQUNoRCxPQUFPLENBQUMsY0FBYyxDQUFDLENBR3pCIn0=
@@ -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,EAuCzC;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,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"}
@@ -42,16 +42,18 @@ import { ArchiverInstrumentation } from '../modules/instrumentation.js';
42
42
  const events = new EventEmitter();
43
43
  const synchronizer = new NoopL1Synchronizer(instrumentation.tracer);
44
44
  super(publicClient, debugClient, rollup, {
45
+ rollupAddress: EthAddress.ZERO,
45
46
  registryAddress: EthAddress.ZERO,
47
+ inboxAddress: EthAddress.ZERO,
46
48
  governanceProposerAddress: EthAddress.ZERO,
47
- slashFactoryAddress: EthAddress.ZERO,
48
49
  slashingProposerAddress: EthAddress.ZERO
49
50
  }, dataStore, {
50
51
  pollingIntervalMs: 1000,
51
52
  batchSize: 100,
52
53
  skipValidateCheckpointAttestations: true,
53
54
  maxAllowedEthClientDriftSeconds: 300,
54
- ethereumAllowNoDebugHosts: true
55
+ ethereumAllowNoDebugHosts: true,
56
+ skipHistoricalLogsCheck: true
55
57
  }, blobClient, instrumentation, {
56
58
  ...l1Constants,
57
59
  l1StartBlockHash: Buffer32.random()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/archiver",
3
- "version": "0.0.1-commit.5de5ca79e",
3
+ "version": "0.0.1-commit.6201a7b05",
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.5de5ca79e",
69
- "@aztec/blob-lib": "0.0.1-commit.5de5ca79e",
70
- "@aztec/constants": "0.0.1-commit.5de5ca79e",
71
- "@aztec/epoch-cache": "0.0.1-commit.5de5ca79e",
72
- "@aztec/ethereum": "0.0.1-commit.5de5ca79e",
73
- "@aztec/foundation": "0.0.1-commit.5de5ca79e",
74
- "@aztec/kv-store": "0.0.1-commit.5de5ca79e",
75
- "@aztec/l1-artifacts": "0.0.1-commit.5de5ca79e",
76
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.5de5ca79e",
77
- "@aztec/protocol-contracts": "0.0.1-commit.5de5ca79e",
78
- "@aztec/stdlib": "0.0.1-commit.5de5ca79e",
79
- "@aztec/telemetry-client": "0.0.1-commit.5de5ca79e",
68
+ "@aztec/blob-client": "0.0.1-commit.6201a7b05",
69
+ "@aztec/blob-lib": "0.0.1-commit.6201a7b05",
70
+ "@aztec/constants": "0.0.1-commit.6201a7b05",
71
+ "@aztec/epoch-cache": "0.0.1-commit.6201a7b05",
72
+ "@aztec/ethereum": "0.0.1-commit.6201a7b05",
73
+ "@aztec/foundation": "0.0.1-commit.6201a7b05",
74
+ "@aztec/kv-store": "0.0.1-commit.6201a7b05",
75
+ "@aztec/l1-artifacts": "0.0.1-commit.6201a7b05",
76
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.6201a7b05",
77
+ "@aztec/protocol-contracts": "0.0.1-commit.6201a7b05",
78
+ "@aztec/stdlib": "0.0.1-commit.6201a7b05",
79
+ "@aztec/telemetry-client": "0.0.1-commit.6201a7b05",
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
@@ -11,7 +11,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
11
11
  import { type Logger, createLogger } from '@aztec/foundation/log';
12
12
  import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise';
13
13
  import { RunningPromise, makeLoggingErrorHandler } from '@aztec/foundation/running-promise';
14
- import { DateProvider } from '@aztec/foundation/timer';
14
+ import { DateProvider, elapsed } from '@aztec/foundation/timer';
15
15
  import {
16
16
  type ArchiverEmitter,
17
17
  L2Block,
@@ -19,18 +19,20 @@ import {
19
19
  type L2Tips,
20
20
  type ValidateCheckpointResult,
21
21
  } from '@aztec/stdlib/block';
22
- import { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
22
+ import { type ProposedCheckpointInput, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
23
23
  import {
24
24
  type L1RollupConstants,
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';
35
+ import { validateAndLogHistoricalLogsAvailability } from './l1/validate_historical_logs.js';
34
36
  import { validateAndLogTraceAvailability } from './l1/validate_trace.js';
35
37
  import { ArchiverDataSourceBase } from './modules/data_source_base.js';
36
38
  import { ArchiverDataStoreUpdater } from './modules/data_store_updater.js';
@@ -44,11 +46,20 @@ export type { ArchiverEmitter };
44
46
 
45
47
  /** Request to add a block to the archiver, queued for processing by the sync loop. */
46
48
  type AddBlockRequest = {
49
+ type: 'block';
47
50
  block: L2Block;
48
51
  resolve: () => void;
49
52
  reject: (err: Error) => void;
50
53
  };
51
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
+
52
63
  export type ArchiverDeps = {
53
64
  telemetry?: TelemetryClient;
54
65
  blobClient: BlobClientInterface;
@@ -74,8 +85,8 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
74
85
  private initialSyncComplete: boolean = false;
75
86
  private initialSyncPromise: PromiseWithResolvers<void>;
76
87
 
77
- /** Queue of blocks to be added to the store, processed by the sync loop. */
78
- 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)[] = [];
79
90
 
80
91
  /** Helper to handle updates to the store */
81
92
  private readonly updater: ArchiverDataStoreUpdater;
@@ -85,13 +96,15 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
85
96
 
86
97
  public readonly tracer: Tracer;
87
98
 
99
+ private readonly instrumentation: ArchiverInstrumentation;
100
+
88
101
  /**
89
102
  * Creates a new instance of the Archiver.
90
103
  * @param publicClient - A client for interacting with the Ethereum node.
91
104
  * @param debugClient - A client for interacting with the Ethereum node for debug/trace methods.
92
105
  * @param rollup - Rollup contract instance.
93
106
  * @param inbox - Inbox contract instance.
94
- * @param l1Addresses - L1 contract addresses (registry, governance proposer, slash factory, slashing proposer).
107
+ * @param l1Addresses - L1 contract addresses (registry, governance proposer, slashing proposer).
95
108
  * @param dataStore - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
96
109
  * @param config - Archiver configuration options.
97
110
  * @param blobClient - Client for retrieving blob data.
@@ -106,8 +119,10 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
106
119
  private readonly rollup: RollupContract,
107
120
  private readonly l1Addresses: Pick<
108
121
  L1ContractAddresses,
109
- 'registryAddress' | 'governanceProposerAddress' | 'slashFactoryAddress'
110
- > & { slashingProposerAddress: EthAddress },
122
+ 'rollupAddress' | 'registryAddress' | 'inboxAddress' | 'governanceProposerAddress'
123
+ > & {
124
+ slashingProposerAddress: EthAddress;
125
+ },
111
126
  readonly dataStore: KVArchiverDataStore,
112
127
  private config: {
113
128
  pollingIntervalMs: number;
@@ -115,6 +130,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
115
130
  skipValidateCheckpointAttestations?: boolean;
116
131
  maxAllowedEthClientDriftSeconds: number;
117
132
  ethereumAllowNoDebugHosts?: boolean;
133
+ skipHistoricalLogsCheck?: boolean;
118
134
  },
119
135
  private readonly blobClient: BlobClientInterface,
120
136
  instrumentation: ArchiverInstrumentation,
@@ -130,6 +146,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
130
146
  super(dataStore, l1Constants);
131
147
 
132
148
  this.tracer = instrumentation.tracer;
149
+ this.instrumentation = instrumentation;
133
150
  this.initialSyncPromise = promiseWithResolvers();
134
151
  this.synchronizer = synchronizer;
135
152
  this.events = events;
@@ -170,6 +187,17 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
170
187
  this.config.ethereumAllowNoDebugHosts ?? false,
171
188
  this.log.getBindings(),
172
189
  );
190
+ await validateAndLogHistoricalLogsAvailability(
191
+ this.publicClient,
192
+ {
193
+ rollupAddress: this.l1Addresses.rollupAddress,
194
+ inboxAddress: this.l1Addresses.inboxAddress,
195
+ registryAddress: this.l1Addresses.registryAddress,
196
+ governanceProposerAddress: this.l1Addresses.governanceProposerAddress,
197
+ },
198
+ this.config.skipHistoricalLogsCheck ?? false,
199
+ this.log.getBindings(),
200
+ );
173
201
 
174
202
  // Log initial state for the archiver
175
203
  const { l1StartBlock } = this.l1Constants;
@@ -191,6 +219,14 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
191
219
  return this.runningPromise.trigger();
192
220
  }
193
221
 
222
+ public trySyncImmediate() {
223
+ try {
224
+ return this.syncImmediate();
225
+ } catch (err) {
226
+ this.log.error(`Failed to trigger immediate archiver sync: ${err}`, err);
227
+ }
228
+ }
229
+
194
230
  /**
195
231
  * Queues a block to be added to the archiver store and triggers processing.
196
232
  * The block will be processed by the sync loop.
@@ -199,58 +235,85 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
199
235
  * @returns A promise that resolves when the block has been added to the store, or rejects on error.
200
236
  */
201
237
  public addBlock(block: L2Block): Promise<void> {
202
- return new Promise<void>((resolve, reject) => {
203
- this.blockQueue.push({ block, resolve, reject });
204
- this.log.debug(`Queued block ${block.number} for processing`);
205
- // Trigger an immediate sync, but don't wait for it - the promise resolves when the block is processed
206
- this.syncImmediate().catch(err => {
207
- this.log.error(`Sync immediate call failed: ${err}`);
208
- });
209
- });
238
+ const promise = promiseWithResolvers<void>();
239
+ this.inboundQueue.push({ block, ...promise, type: 'block' });
240
+ this.log.debug(`Queued block ${block.number} for processing`);
241
+ void this.trySyncImmediate();
242
+ return promise.promise;
210
243
  }
211
244
 
212
245
  /**
213
- * Processes all queued blocks, adding them to the store.
246
+ * Queues a new proposed checkpoint into the archiver store.
247
+ * Checks that the checkpoint is not for an L2 slot already synced from L1.
248
+ * Resolves once the checkpoint has been processed.
249
+ */
250
+ public addProposedCheckpoint(pending: ProposedCheckpointInput): Promise<void> {
251
+ const promise = promiseWithResolvers<void>();
252
+ this.inboundQueue.push({ checkpoint: pending, ...promise, type: 'checkpoint' });
253
+ this.log.debug(`Queued checkpoint ${pending.checkpointNumber} for processing`);
254
+ void this.trySyncImmediate();
255
+ return promise.promise;
256
+ }
257
+
258
+ /**
259
+ * Processes all queued blocks and checkpoints, adding them to the store.
214
260
  * Called at the beginning of each sync iteration.
215
- * Blocks are processed in the order they were queued.
261
+ * Items are processed in the order they were queued.
216
262
  */
217
- private async processQueuedBlocks(): Promise<void> {
218
- if (this.blockQueue.length === 0) {
263
+ private async processInboundQueue(): Promise<void> {
264
+ if (this.inboundQueue.length === 0) {
219
265
  return;
220
266
  }
221
267
 
222
- // Take all blocks from the queue
223
- const queuedItems = this.blockQueue.splice(0, this.blockQueue.length);
224
- this.log.debug(`Processing ${queuedItems.length} queued block(s)`);
268
+ // Take all items from the queue
269
+ const queuedItems = this.inboundQueue.splice(0, this.inboundQueue.length);
270
+ this.log.debug(`Processing ${queuedItems.length} queued inbound items`);
225
271
 
226
272
  // Calculate slot threshold for validation
227
273
  const l1Timestamp = this.synchronizer.getL1Timestamp();
228
274
  const slotAtNextL1Block =
229
275
  l1Timestamp === undefined ? undefined : getSlotAtNextL1Block(l1Timestamp, this.l1Constants);
230
276
 
231
- // Process each block individually to properly resolve/reject each promise
232
- for (const { block, resolve, reject } of queuedItems) {
233
- const blockSlot = block.header.globalVariables.slotNumber;
234
- if (slotAtNextL1Block !== undefined && blockSlot < slotAtNextL1Block) {
277
+ // Helpers for manipulating blocks and checkpoints in the queue
278
+ const getSlot: (item: AddBlockRequest | AddProposedCheckpointRequest) => SlotNumber = item =>
279
+ item.type === 'block' ? item.block.header.globalVariables.slotNumber : item.checkpoint.header.slotNumber;
280
+ const getNumber: (item: AddBlockRequest | AddProposedCheckpointRequest) => number = item =>
281
+ item.type === 'block' ? item.block.number : item.checkpoint.checkpointNumber;
282
+
283
+ // Process each item individually to properly resolve/reject each promise
284
+ for (const item of queuedItems) {
285
+ const { resolve, reject, type } = item;
286
+ const itemSlot = getSlot(item);
287
+ const itemNumber = getNumber(item);
288
+ if (slotAtNextL1Block !== undefined && itemSlot < slotAtNextL1Block) {
289
+ const nextSlotTimestamp = getTimestampForSlot(slotAtNextL1Block, this.l1Constants);
235
290
  this.log.warn(
236
- `Rejecting proposed block ${block.number} for past slot ${blockSlot} (current is ${slotAtNextL1Block})`,
237
- { block: block.toBlockInfo(), l1Timestamp, slotAtNextL1Block },
291
+ `Rejecting proposed ${type} ${itemNumber} for past slot ${itemSlot} (current ${slotAtNextL1Block})`,
292
+ { number: itemNumber, type, l1Timestamp, slotAtNextL1Block, nextSlotTimestamp },
238
293
  );
239
- reject(new Error(`Block ${block.number} is for past slot ${blockSlot} (current is ${slotAtNextL1Block})`));
294
+ reject(new BlockOrCheckpointSlotExpiredError(itemSlot, nextSlotTimestamp, l1Timestamp));
240
295
  continue;
241
296
  }
242
297
 
243
298
  try {
244
- await this.updater.addProposedBlock(block);
245
- this.log.debug(`Added block ${block.number} to store`);
299
+ if (type === 'block') {
300
+ const [durationMs] = await elapsed(() => this.updater.addProposedBlock(item.block));
301
+ this.instrumentation.processNewProposedBlock(durationMs, item.block);
302
+ } else {
303
+ await this.updater.addProposedCheckpoint(item.checkpoint);
304
+ }
305
+ this.log.debug(`Added ${type} ${itemNumber} to store`);
246
306
  resolve();
247
307
  } catch (err: any) {
248
308
  if (err instanceof BlockAlreadyCheckpointedError) {
249
- this.log.debug(`Proposed block ${block.number} matches already checkpointed block, ignoring late proposal`);
309
+ this.log.debug(`Proposed block ${itemNumber} matches already checkpointed block, ignoring late proposal`);
250
310
  resolve();
251
311
  continue;
252
312
  }
253
- this.log.error(`Failed to add block ${block.number} to store: ${err.message}`);
313
+ this.log.error(`Failed to add ${type} ${itemNumber} to store: ${err.message}`, err, {
314
+ number: itemNumber,
315
+ type,
316
+ });
254
317
  reject(err);
255
318
  }
256
319
  }
@@ -266,7 +329,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
266
329
  @trackSpan('Archiver.sync')
267
330
  private async sync() {
268
331
  // Process any queued blocks first, before doing L1 sync
269
- await this.processQueuedBlocks();
332
+ await this.processInboundQueue();
270
333
  // Now perform L1 sync
271
334
  await this.syncFromL1();
272
335
  }
@@ -341,19 +404,33 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
341
404
  return Promise.resolve(this.synchronizer.getL1Timestamp());
342
405
  }
343
406
 
344
- public getSyncedL2SlotNumber(): Promise<SlotNumber | undefined> {
407
+ public async getSyncedL2SlotNumber(): Promise<SlotNumber | undefined> {
408
+ // The synced L2 slot is the latest slot for which we have all L1 data,
409
+ // either because we have seen all L1 blocks for that slot, or because
410
+ // we have seen the corresponding checkpoint.
411
+
412
+ let slotFromL1Sync: SlotNumber | undefined;
345
413
  const l1Timestamp = this.synchronizer.getL1Timestamp();
346
- if (l1Timestamp === undefined) {
347
- return Promise.resolve(undefined);
414
+ if (l1Timestamp !== undefined) {
415
+ const nextL1BlockSlot = getSlotAtNextL1Block(l1Timestamp, this.l1Constants);
416
+ if (Number(nextL1BlockSlot) > 0) {
417
+ slotFromL1Sync = SlotNumber.add(nextL1BlockSlot, -1);
418
+ }
348
419
  }
349
- // The synced slot is the last L2 slot whose all L1 blocks have been processed.
350
- // If the next L1 block (at l1Timestamp + ethereumSlotDuration) falls in slot N,
351
- // then we've fully synced slot N-1.
352
- const nextL1BlockSlot = getSlotAtNextL1Block(l1Timestamp, this.l1Constants);
353
- if (Number(nextL1BlockSlot) === 0) {
354
- return Promise.resolve(undefined);
420
+
421
+ let slotFromCheckpoint: SlotNumber | undefined;
422
+ const latestCheckpointNumber = await this.store.getSynchedCheckpointNumber();
423
+ if (latestCheckpointNumber > 0) {
424
+ const checkpointData = await this.store.getCheckpointData(latestCheckpointNumber);
425
+ if (checkpointData) {
426
+ slotFromCheckpoint = checkpointData.header.slotNumber;
427
+ }
428
+ }
429
+
430
+ if (slotFromL1Sync === undefined && slotFromCheckpoint === undefined) {
431
+ return undefined;
355
432
  }
356
- return Promise.resolve(SlotNumber(nextL1BlockSlot - 1));
433
+ return SlotNumber(Math.max(slotFromL1Sync ?? 0, slotFromCheckpoint ?? 0));
357
434
  }
358
435
 
359
436
  public async getSyncedL2EpochNumber(): Promise<EpochNumber | undefined> {
@@ -472,7 +549,10 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
472
549
  await this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
473
550
  this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
474
551
  await this.store.setCheckpointSynchedL1BlockNumber(targetL1BlockNumber);
475
- await this.store.setMessageSynchedL1Block({ l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash });
552
+ await this.store.setMessageSyncState(
553
+ { l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash },
554
+ undefined,
555
+ );
476
556
  if (targetL2BlockNumber < currentProvenBlock) {
477
557
  this.log.info(`Rolling back proven L2 checkpoint to ${targetCheckpointNumber}`);
478
558
  await this.updater.setProvenCheckpointNumber(targetCheckpointNumber);
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,13 +51,17 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
50
51
  },
51
52
  archiverStoreMapSizeKb: {
52
53
  env: 'ARCHIVER_STORE_MAP_SIZE_KB',
53
- parseEnv: (val: string | undefined) => (val ? +val : undefined),
54
+ ...optionalNumberConfigHelper(),
54
55
  description: 'The maximum possible size of the archiver DB in KB. Overwrites the general dataStoreMapSizeKb.',
55
56
  },
56
57
  skipValidateCheckpointAttestations: {
57
58
  description: 'Skip validating checkpoint attestations (for testing purposes only)',
58
59
  ...booleanConfigHelper(false),
59
60
  },
61
+ skipPromoteProposedCheckpointDuringL1Sync: {
62
+ description: 'Skip promoting proposed checkpoints during L1 sync (for testing purposes only)',
63
+ ...booleanConfigHelper(false),
64
+ },
60
65
  maxAllowedEthClientDriftSeconds: {
61
66
  env: 'MAX_ALLOWED_ETH_CLIENT_DRIFT_SECONDS',
62
67
  description: 'Maximum allowed drift in seconds between the Ethereum client and current time.',
@@ -67,6 +72,13 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
67
72
  description: 'Whether to allow starting the archiver without debug/trace method support on Ethereum hosts',
68
73
  ...booleanConfigHelper(true),
69
74
  },
75
+ archiverSkipHistoricalLogsCheck: {
76
+ env: 'ARCHIVER_SKIP_HISTORICAL_LOGS_CHECK',
77
+ description:
78
+ 'Skip the startup check that probes the L1 RPC for historical Rollup contract logs. ' +
79
+ 'Set to true to bypass the check when the connected RPC node is known to prune old logs.',
80
+ ...booleanConfigHelper(false),
81
+ },
70
82
  ...chainConfigMappings,
71
83
  ...l1ReaderConfigMappings,
72
84
  viemPollingIntervalMS: {
@@ -96,7 +108,9 @@ export function mapArchiverConfig(config: Partial<ArchiverConfig>) {
96
108
  pollingIntervalMs: config.archiverPollingIntervalMS,
97
109
  batchSize: config.archiverBatchSize,
98
110
  skipValidateCheckpointAttestations: config.skipValidateCheckpointAttestations,
111
+ skipPromoteProposedCheckpointDuringL1Sync: config.skipPromoteProposedCheckpointDuringL1Sync,
99
112
  maxAllowedEthClientDriftSeconds: config.maxAllowedEthClientDriftSeconds,
100
113
  ethereumAllowNoDebugHosts: config.ethereumAllowNoDebugHosts,
114
+ skipHistoricalLogsCheck: config.archiverSkipHistoricalLogsCheck,
101
115
  };
102
116
  }