@aztec/archiver 0.0.1-commit.e558bd1c → 0.0.1-commit.e5a3663dd

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 (126) hide show
  1. package/README.md +12 -6
  2. package/dest/archiver.d.ts +26 -15
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +161 -153
  5. package/dest/config.d.ts +5 -3
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +16 -4
  8. package/dest/errors.d.ts +61 -10
  9. package/dest/errors.d.ts.map +1 -1
  10. package/dest/errors.js +88 -14
  11. package/dest/factory.d.ts +6 -7
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +40 -32
  14. package/dest/index.d.ts +11 -3
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +10 -2
  17. package/dest/l1/bin/retrieve-calldata.js +32 -28
  18. package/dest/l1/calldata_retriever.d.ts +74 -50
  19. package/dest/l1/calldata_retriever.d.ts.map +1 -1
  20. package/dest/l1/calldata_retriever.js +197 -260
  21. package/dest/l1/data_retrieval.d.ts +26 -17
  22. package/dest/l1/data_retrieval.d.ts.map +1 -1
  23. package/dest/l1/data_retrieval.js +42 -47
  24. package/dest/l1/spire_proposer.d.ts +5 -5
  25. package/dest/l1/spire_proposer.d.ts.map +1 -1
  26. package/dest/l1/spire_proposer.js +9 -17
  27. package/dest/l1/validate_historical_logs.d.ts +23 -0
  28. package/dest/l1/validate_historical_logs.d.ts.map +1 -0
  29. package/dest/l1/validate_historical_logs.js +108 -0
  30. package/dest/modules/contract_data_source_adapter.d.ts +25 -0
  31. package/dest/modules/contract_data_source_adapter.d.ts.map +1 -0
  32. package/dest/modules/contract_data_source_adapter.js +42 -0
  33. package/dest/modules/data_source_base.d.ts +27 -14
  34. package/dest/modules/data_source_base.d.ts.map +1 -1
  35. package/dest/modules/data_source_base.js +98 -125
  36. package/dest/modules/data_store_updater.d.ts +37 -17
  37. package/dest/modules/data_store_updater.d.ts.map +1 -1
  38. package/dest/modules/data_store_updater.js +155 -112
  39. package/dest/modules/instrumentation.d.ts +21 -3
  40. package/dest/modules/instrumentation.d.ts.map +1 -1
  41. package/dest/modules/instrumentation.js +41 -8
  42. package/dest/modules/l1_synchronizer.d.ts +13 -11
  43. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  44. package/dest/modules/l1_synchronizer.js +355 -182
  45. package/dest/modules/validation.d.ts +4 -3
  46. package/dest/modules/validation.d.ts.map +1 -1
  47. package/dest/modules/validation.js +6 -6
  48. package/dest/store/block_store.d.ts +107 -31
  49. package/dest/store/block_store.d.ts.map +1 -1
  50. package/dest/store/block_store.js +477 -141
  51. package/dest/store/contract_class_store.d.ts +17 -4
  52. package/dest/store/contract_class_store.d.ts.map +1 -1
  53. package/dest/store/contract_class_store.js +24 -68
  54. package/dest/store/contract_instance_store.d.ts +28 -1
  55. package/dest/store/contract_instance_store.d.ts.map +1 -1
  56. package/dest/store/contract_instance_store.js +37 -2
  57. package/dest/store/data_stores.d.ts +68 -0
  58. package/dest/store/data_stores.d.ts.map +1 -0
  59. package/dest/store/data_stores.js +50 -0
  60. package/dest/store/function_names_cache.d.ts +17 -0
  61. package/dest/store/function_names_cache.d.ts.map +1 -0
  62. package/dest/store/function_names_cache.js +30 -0
  63. package/dest/store/l2_tips_cache.d.ts +20 -0
  64. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  65. package/dest/store/l2_tips_cache.js +109 -0
  66. package/dest/store/log_store.d.ts +6 -3
  67. package/dest/store/log_store.d.ts.map +1 -1
  68. package/dest/store/log_store.js +95 -20
  69. package/dest/store/message_store.d.ts +11 -1
  70. package/dest/store/message_store.d.ts.map +1 -1
  71. package/dest/store/message_store.js +51 -9
  72. package/dest/test/fake_l1_state.d.ts +25 -1
  73. package/dest/test/fake_l1_state.d.ts.map +1 -1
  74. package/dest/test/fake_l1_state.js +166 -32
  75. package/dest/test/mock_archiver.d.ts +1 -1
  76. package/dest/test/mock_archiver.d.ts.map +1 -1
  77. package/dest/test/mock_archiver.js +3 -2
  78. package/dest/test/mock_l1_to_l2_message_source.d.ts +1 -1
  79. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  80. package/dest/test/mock_l1_to_l2_message_source.js +2 -1
  81. package/dest/test/mock_l2_block_source.d.ts +35 -5
  82. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  83. package/dest/test/mock_l2_block_source.js +182 -89
  84. package/dest/test/mock_structs.d.ts +4 -1
  85. package/dest/test/mock_structs.d.ts.map +1 -1
  86. package/dest/test/mock_structs.js +13 -1
  87. package/dest/test/noop_l1_archiver.d.ts +7 -4
  88. package/dest/test/noop_l1_archiver.d.ts.map +1 -1
  89. package/dest/test/noop_l1_archiver.js +14 -8
  90. package/package.json +13 -13
  91. package/src/archiver.ts +199 -174
  92. package/src/config.ts +23 -2
  93. package/src/errors.ts +133 -22
  94. package/src/factory.ts +53 -30
  95. package/src/index.ts +18 -2
  96. package/src/l1/README.md +25 -68
  97. package/src/l1/bin/retrieve-calldata.ts +40 -27
  98. package/src/l1/calldata_retriever.ts +261 -379
  99. package/src/l1/data_retrieval.ts +58 -69
  100. package/src/l1/spire_proposer.ts +7 -15
  101. package/src/l1/validate_historical_logs.ts +140 -0
  102. package/src/modules/contract_data_source_adapter.ts +59 -0
  103. package/src/modules/data_source_base.ts +142 -144
  104. package/src/modules/data_store_updater.ts +187 -141
  105. package/src/modules/instrumentation.ts +56 -9
  106. package/src/modules/l1_synchronizer.ts +463 -218
  107. package/src/modules/validation.ts +10 -9
  108. package/src/store/block_store.ts +587 -177
  109. package/src/store/contract_class_store.ts +31 -103
  110. package/src/store/contract_instance_store.ts +51 -5
  111. package/src/store/data_stores.ts +108 -0
  112. package/src/store/function_names_cache.ts +37 -0
  113. package/src/store/l2_tips_cache.ts +134 -0
  114. package/src/store/log_store.ts +128 -32
  115. package/src/store/message_store.ts +60 -10
  116. package/src/structs/inbox_message.ts +1 -1
  117. package/src/test/fake_l1_state.ts +213 -42
  118. package/src/test/mock_archiver.ts +3 -2
  119. package/src/test/mock_l1_to_l2_message_source.ts +1 -0
  120. package/src/test/mock_l2_block_source.ts +230 -82
  121. package/src/test/mock_structs.ts +20 -6
  122. package/src/test/noop_l1_archiver.ts +16 -8
  123. package/dest/store/kv_archiver_store.d.ts +0 -340
  124. package/dest/store/kv_archiver_store.d.ts.map +0 -1
  125. package/dest/store/kv_archiver_store.js +0 -446
  126. package/src/store/kv_archiver_store.ts +0 -639
@@ -1,11 +1,18 @@
1
+ import { range } from '@aztec/foundation/array';
1
2
  import { BlockNumber, CheckpointNumber, type EpochNumber, type SlotNumber } from '@aztec/foundation/branded-types';
2
3
  import type { Fr } from '@aztec/foundation/curves/bn254';
3
4
  import type { EthAddress } from '@aztec/foundation/eth-address';
4
5
  import { isDefined } from '@aztec/foundation/types';
5
6
  import type { FunctionSelector } from '@aztec/stdlib/abi';
6
7
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
- import { type BlockHash, CheckpointedL2Block, CommitteeAttestation, L2Block, type L2Tips } from '@aztec/stdlib/block';
8
- import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
8
+ import { type BlockData, type BlockHash, CheckpointedL2Block, L2Block, type L2Tips } from '@aztec/stdlib/block';
9
+ import {
10
+ Checkpoint,
11
+ type CheckpointData,
12
+ type CommonCheckpointData,
13
+ type ProposedCheckpointData,
14
+ PublishedCheckpoint,
15
+ } from '@aztec/stdlib/checkpoint';
9
16
  import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
10
17
  import { type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
11
18
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
@@ -17,20 +24,19 @@ import type { BlockHeader, IndexedTxEffect, TxHash, TxReceipt } from '@aztec/std
17
24
  import type { UInt64 } from '@aztec/stdlib/types';
18
25
 
19
26
  import type { ArchiverDataSource } from '../interfaces.js';
20
- import type { CheckpointData } from '../store/block_store.js';
21
- import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
27
+ import type { ArchiverDataStores } from '../store/data_stores.js';
22
28
  import type { ValidateCheckpointResult } from './validation.js';
23
29
 
24
30
  /**
25
- * Abstract base class implementing ArchiverDataSource using a KVArchiverDataStore.
26
- * Provides implementations for all store-delegating methods and declares abstract methods
27
- * for L1-dependent functionality that subclasses must implement.
31
+ * Abstract base class implementing ArchiverDataSource using a bundle of archiver substores.
32
+ * Provides implementations for all read-side methods and declares abstract methods for
33
+ * L1-dependent functionality that subclasses must implement.
28
34
  */
29
35
  export abstract class ArchiverDataSourceBase
30
36
  implements ArchiverDataSource, L2LogsSource, ContractDataSource, L1ToL2MessageSource
31
37
  {
32
38
  constructor(
33
- protected readonly store: KVArchiverDataStore,
39
+ protected readonly stores: ArchiverDataStores,
34
40
  protected readonly l1Constants?: L1RollupConstants,
35
41
  ) {}
36
42
 
@@ -46,63 +52,63 @@ export abstract class ArchiverDataSourceBase
46
52
 
47
53
  abstract getL2Tips(): Promise<L2Tips>;
48
54
 
49
- abstract getL2SlotNumber(): Promise<SlotNumber | undefined>;
55
+ abstract getSyncedL2SlotNumber(): Promise<SlotNumber | undefined>;
50
56
 
51
- abstract getL2EpochNumber(): Promise<EpochNumber | undefined>;
57
+ abstract getSyncedL2EpochNumber(): Promise<EpochNumber | undefined>;
52
58
 
53
59
  abstract isEpochComplete(epochNumber: EpochNumber): Promise<boolean>;
54
60
 
55
61
  abstract syncImmediate(): Promise<void>;
56
62
 
57
63
  public getCheckpointNumber(): Promise<CheckpointNumber> {
58
- return this.store.getSynchedCheckpointNumber();
64
+ return this.stores.blocks.getLatestCheckpointNumber();
59
65
  }
60
66
 
61
67
  public getSynchedCheckpointNumber(): Promise<CheckpointNumber> {
62
- return this.store.getSynchedCheckpointNumber();
68
+ return this.stores.blocks.getLatestCheckpointNumber();
63
69
  }
64
70
 
65
71
  public getProvenCheckpointNumber(): Promise<CheckpointNumber> {
66
- return this.store.getProvenCheckpointNumber();
72
+ return this.stores.blocks.getProvenCheckpointNumber();
67
73
  }
68
74
 
69
75
  public getBlockNumber(): Promise<BlockNumber> {
70
- return this.store.getLatestBlockNumber();
76
+ return this.stores.blocks.getLatestL2BlockNumber();
71
77
  }
72
78
 
73
79
  public getProvenBlockNumber(): Promise<BlockNumber> {
74
- return this.store.getProvenBlockNumber();
80
+ return this.stores.blocks.getProvenBlockNumber();
75
81
  }
76
82
 
77
83
  public async getBlockHeader(number: BlockNumber | 'latest'): Promise<BlockHeader | undefined> {
78
- const blockNumber = number === 'latest' ? await this.store.getLatestBlockNumber() : number;
84
+ const blockNumber = number === 'latest' ? await this.stores.blocks.getLatestL2BlockNumber() : number;
79
85
  if (blockNumber === 0) {
80
86
  return undefined;
81
87
  }
82
- const headers = await this.store.getBlockHeaders(blockNumber, 1);
88
+ const headers = await this.stores.blocks.getBlockHeaders(blockNumber, 1);
83
89
  return headers.length === 0 ? undefined : headers[0];
84
90
  }
85
91
 
86
92
  public getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
87
- return this.store.getCheckpointedBlock(number);
93
+ return this.stores.blocks.getCheckpointedBlock(number);
88
94
  }
89
95
 
90
96
  public getCheckpointedL2BlockNumber(): Promise<BlockNumber> {
91
- return this.store.getCheckpointedL2BlockNumber();
97
+ return this.stores.blocks.getCheckpointedL2BlockNumber();
92
98
  }
93
99
 
94
100
  public getFinalizedL2BlockNumber(): Promise<BlockNumber> {
95
- return this.store.getFinalizedL2BlockNumber();
101
+ return this.stores.blocks.getFinalizedL2BlockNumber();
96
102
  }
97
103
 
98
104
  public async getCheckpointHeader(number: CheckpointNumber | 'latest'): Promise<CheckpointHeader | undefined> {
99
105
  if (number === 'latest') {
100
- number = await this.store.getSynchedCheckpointNumber();
106
+ number = await this.stores.blocks.getLatestCheckpointNumber();
101
107
  }
102
108
  if (number === 0) {
103
109
  return undefined;
104
110
  }
105
- const checkpoint = await this.store.getCheckpointData(number);
111
+ const checkpoint = await this.stores.blocks.getCheckpointData(number);
106
112
  if (!checkpoint) {
107
113
  return undefined;
108
114
  }
@@ -110,43 +116,74 @@ export abstract class ArchiverDataSourceBase
110
116
  }
111
117
 
112
118
  public async getLastBlockNumberInCheckpoint(checkpointNumber: CheckpointNumber): Promise<BlockNumber | undefined> {
113
- const checkpointData = await this.store.getCheckpointData(checkpointNumber);
119
+ const checkpointData = await this.stores.blocks.getCheckpointData(checkpointNumber);
114
120
  if (!checkpointData) {
115
121
  return undefined;
116
122
  }
117
- return BlockNumber(checkpointData.startBlock + checkpointData.numBlocks - 1);
123
+ return BlockNumber(checkpointData.startBlock + checkpointData.blockCount - 1);
118
124
  }
119
125
 
120
126
  public getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
121
- return this.store.getCheckpointedBlocks(from, limit);
127
+ return this.stores.blocks.getCheckpointedBlocks(from, limit);
128
+ }
129
+
130
+ public getCheckpointData(checkpointNumber: CheckpointNumber): Promise<CheckpointData | undefined> {
131
+ return this.stores.blocks.getCheckpointData(checkpointNumber);
132
+ }
133
+
134
+ public getCheckpointDataRange(from: CheckpointNumber, limit: number): Promise<CheckpointData[]> {
135
+ return this.stores.blocks.getRangeOfCheckpoints(from, limit);
136
+ }
137
+
138
+ public getCheckpointNumberBySlot(slot: SlotNumber): Promise<CheckpointNumber | undefined> {
139
+ return this.stores.blocks.getCheckpointNumberBySlot(slot);
140
+ }
141
+
142
+ public getBlockDataWithCheckpointContext(blockNumber: BlockNumber) {
143
+ return this.stores.blocks.getBlockDataWithCheckpointContext(blockNumber);
122
144
  }
123
145
 
124
146
  public getBlockHeaderByHash(blockHash: BlockHash): Promise<BlockHeader | undefined> {
125
- return this.store.getBlockHeaderByHash(blockHash);
147
+ return this.stores.blocks.getBlockHeaderByHash(blockHash);
126
148
  }
127
149
 
128
150
  public getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
129
- return this.store.getBlockHeaderByArchive(archive);
151
+ return this.stores.blocks.getBlockHeaderByArchive(archive);
152
+ }
153
+
154
+ public getBlockData(number: BlockNumber): Promise<BlockData | undefined> {
155
+ return this.stores.blocks.getBlockData(number);
156
+ }
157
+
158
+ public getBlockDataByArchive(archive: Fr): Promise<BlockData | undefined> {
159
+ return this.stores.blocks.getBlockDataByArchive(archive);
130
160
  }
131
161
 
132
162
  public async getL2Block(number: BlockNumber): Promise<L2Block | undefined> {
133
163
  // If the number provided is -ve, then return the latest block.
134
164
  if (number < 0) {
135
- number = await this.store.getLatestBlockNumber();
165
+ number = await this.stores.blocks.getLatestL2BlockNumber();
136
166
  }
137
167
  if (number === 0) {
138
168
  return undefined;
139
169
  }
140
- const publishedBlock = await this.store.getBlock(number);
141
- return publishedBlock;
170
+ return this.stores.blocks.getBlock(number);
142
171
  }
143
172
 
144
173
  public getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined> {
145
- return this.store.getTxEffect(txHash);
174
+ return this.stores.blocks.getTxEffect(txHash);
146
175
  }
147
176
 
148
177
  public getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined> {
149
- return this.store.getSettledTxReceipt(txHash);
178
+ return this.stores.blocks.getSettledTxReceipt(txHash, this.l1Constants);
179
+ }
180
+
181
+ public getLastCheckpoint(): Promise<CommonCheckpointData | undefined> {
182
+ return this.stores.blocks.getLastCheckpoint();
183
+ }
184
+
185
+ public getLastProposedCheckpoint(): Promise<ProposedCheckpointData | undefined> {
186
+ return this.stores.blocks.getLastProposedCheckpoint();
150
187
  }
151
188
 
152
189
  public isPendingChainInvalid(): Promise<boolean> {
@@ -154,35 +191,40 @@ export abstract class ArchiverDataSourceBase
154
191
  }
155
192
 
156
193
  public async getPendingChainValidationStatus(): Promise<ValidateCheckpointResult> {
157
- return (await this.store.getPendingChainValidationStatus()) ?? { valid: true };
194
+ return (await this.stores.blocks.getPendingChainValidationStatus()) ?? { valid: true };
158
195
  }
159
196
 
160
- public getPrivateLogsByTags(tags: SiloedTag[], page?: number): Promise<TxScopedL2Log[][]> {
161
- return this.store.getPrivateLogsByTags(tags, page);
197
+ public getPrivateLogsByTags(
198
+ tags: SiloedTag[],
199
+ page?: number,
200
+ upToBlockNumber?: BlockNumber,
201
+ ): Promise<TxScopedL2Log[][]> {
202
+ return this.stores.logs.getPrivateLogsByTags(tags, page, upToBlockNumber);
162
203
  }
163
204
 
164
205
  public getPublicLogsByTagsFromContract(
165
206
  contractAddress: AztecAddress,
166
207
  tags: Tag[],
167
208
  page?: number,
209
+ upToBlockNumber?: BlockNumber,
168
210
  ): Promise<TxScopedL2Log[][]> {
169
- return this.store.getPublicLogsByTagsFromContract(contractAddress, tags, page);
211
+ return this.stores.logs.getPublicLogsByTagsFromContract(contractAddress, tags, page, upToBlockNumber);
170
212
  }
171
213
 
172
214
  public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
173
- return this.store.getPublicLogs(filter);
215
+ return this.stores.logs.getPublicLogs(filter);
174
216
  }
175
217
 
176
218
  public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
177
- return this.store.getContractClassLogs(filter);
219
+ return this.stores.logs.getContractClassLogs(filter);
178
220
  }
179
221
 
180
222
  public getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
181
- return this.store.getContractClass(id);
223
+ return this.stores.contractClasses.getContractClass(id);
182
224
  }
183
225
 
184
226
  public getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
185
- return this.store.getBytecodeCommitment(id);
227
+ return this.stores.contractClasses.getBytecodeCommitment(id);
186
228
  }
187
229
 
188
230
  public async getContract(
@@ -198,170 +240,126 @@ export abstract class ArchiverDataSourceBase
198
240
  timestamp = maybeTimestamp;
199
241
  }
200
242
 
201
- return this.store.getContractInstance(address, timestamp);
243
+ return this.stores.contractInstances.getContractInstance(address, timestamp);
202
244
  }
203
245
 
204
246
  public getContractClassIds(): Promise<Fr[]> {
205
- return this.store.getContractClassIds();
247
+ return this.stores.contractClasses.getContractClassIds();
206
248
  }
207
249
 
208
- public getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
209
- return this.store.getDebugFunctionName(address, selector);
250
+ /** Looks up a public function name given a selector. */
251
+ public getDebugFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
252
+ return Promise.resolve(this.stores.functionNames.get(selector));
210
253
  }
211
254
 
255
+ /** Register public function signatures so they can be looked up by selector. */
212
256
  public registerContractFunctionSignatures(signatures: string[]): Promise<void> {
213
- return this.store.registerContractFunctionSignatures(signatures);
257
+ return this.stores.functionNames.register(signatures);
214
258
  }
215
259
 
216
260
  public getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
217
- return this.store.getL1ToL2Messages(checkpointNumber);
261
+ return this.stores.messages.getL1ToL2Messages(checkpointNumber);
218
262
  }
219
263
 
220
264
  public getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined> {
221
- return this.store.getL1ToL2MessageIndex(l1ToL2Message);
265
+ return this.stores.messages.getL1ToL2MessageIndex(l1ToL2Message);
222
266
  }
223
267
 
224
268
  public async getCheckpoints(checkpointNumber: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
225
- const checkpoints = await this.store.getRangeOfCheckpoints(checkpointNumber, limit);
226
- const blocks = (
227
- await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
228
- ).filter(isDefined);
229
-
230
- const fullCheckpoints: PublishedCheckpoint[] = [];
231
- for (let i = 0; i < checkpoints.length; i++) {
232
- const blocksForCheckpoint = blocks[i];
233
- const checkpoint = checkpoints[i];
234
- const fullCheckpoint = new Checkpoint(
235
- checkpoint.archive,
236
- checkpoint.header,
237
- blocksForCheckpoint,
238
- checkpoint.checkpointNumber,
239
- );
240
- const publishedCheckpoint = new PublishedCheckpoint(
241
- fullCheckpoint,
242
- checkpoint.l1,
243
- checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
244
- );
245
- fullCheckpoints.push(publishedCheckpoint);
269
+ const checkpoints = await this.stores.blocks.getRangeOfCheckpoints(checkpointNumber, limit);
270
+ return Promise.all(checkpoints.map(ch => this.getPublishedCheckpointFromCheckpointData(ch)));
271
+ }
272
+
273
+ private async getPublishedCheckpointFromCheckpointData(checkpoint: CheckpointData): Promise<PublishedCheckpoint> {
274
+ const blocksForCheckpoint = await this.stores.blocks.getBlocksForCheckpoint(checkpoint.checkpointNumber);
275
+ if (!blocksForCheckpoint) {
276
+ throw new Error(`Blocks for checkpoint ${checkpoint.checkpointNumber} not found`);
246
277
  }
247
- return fullCheckpoints;
278
+ const fullCheckpoint = new Checkpoint(
279
+ checkpoint.archive,
280
+ checkpoint.header,
281
+ blocksForCheckpoint,
282
+ checkpoint.checkpointNumber,
283
+ checkpoint.feeAssetPriceModifier,
284
+ );
285
+ return new PublishedCheckpoint(fullCheckpoint, checkpoint.l1, checkpoint.attestations);
248
286
  }
249
287
 
250
288
  public getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
251
- return this.store.getBlocksForSlot(slotNumber);
289
+ return this.stores.blocks.getBlocksForSlot(slotNumber);
252
290
  }
253
291
 
254
292
  public async getCheckpointedBlocksForEpoch(epochNumber: EpochNumber): Promise<CheckpointedL2Block[]> {
255
- if (!this.l1Constants) {
256
- throw new Error('L1 constants not set');
257
- }
258
-
259
- const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
260
- const blocks: CheckpointedL2Block[] = [];
261
-
262
- // Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
263
- // We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
264
- let checkpoint = await this.store.getCheckpointData(await this.store.getSynchedCheckpointNumber());
265
- const slot = (b: CheckpointData) => b.header.slotNumber;
266
- while (checkpoint && slot(checkpoint) >= start) {
267
- if (slot(checkpoint) <= end) {
268
- // push the blocks on backwards
269
- const endBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
270
- for (let i = endBlock; i >= checkpoint.startBlock; i--) {
271
- const checkpointedBlock = await this.getCheckpointedBlock(BlockNumber(i));
272
- if (checkpointedBlock) {
273
- blocks.push(checkpointedBlock);
274
- }
275
- }
276
- }
277
- checkpoint = await this.store.getCheckpointData(CheckpointNumber(checkpoint.checkpointNumber - 1));
278
- }
279
-
280
- return blocks.reverse();
293
+ const checkpointsData = await this.getCheckpointsDataForEpoch(epochNumber);
294
+ const blocks = await Promise.all(
295
+ checkpointsData.flatMap(checkpoint =>
296
+ range(checkpoint.blockCount, checkpoint.startBlock).map(blockNumber =>
297
+ this.getCheckpointedBlock(BlockNumber(blockNumber)),
298
+ ),
299
+ ),
300
+ );
301
+ return blocks.filter(isDefined);
281
302
  }
282
303
 
283
304
  public async getCheckpointedBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
284
- if (!this.l1Constants) {
285
- throw new Error('L1 constants not set');
286
- }
287
-
288
- const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
289
- const blocks: BlockHeader[] = [];
290
-
291
- // Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
292
- // We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
293
- let checkpoint = await this.store.getCheckpointData(await this.store.getSynchedCheckpointNumber());
294
- const slot = (b: CheckpointData) => b.header.slotNumber;
295
- while (checkpoint && slot(checkpoint) >= start) {
296
- if (slot(checkpoint) <= end) {
297
- // push the blocks on backwards
298
- const endBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
299
- for (let i = endBlock; i >= checkpoint.startBlock; i--) {
300
- const block = await this.getBlockHeader(BlockNumber(i));
301
- if (block) {
302
- blocks.push(block);
303
- }
304
- }
305
- }
306
- checkpoint = await this.store.getCheckpointData(CheckpointNumber(checkpoint.checkpointNumber - 1));
307
- }
308
- return blocks.reverse();
305
+ const checkpointsData = await this.getCheckpointsDataForEpoch(epochNumber);
306
+ const blocks = await Promise.all(
307
+ checkpointsData.flatMap(checkpoint =>
308
+ range(checkpoint.blockCount, checkpoint.startBlock).map(blockNumber =>
309
+ this.getBlockHeader(BlockNumber(blockNumber)),
310
+ ),
311
+ ),
312
+ );
313
+ return blocks.filter(isDefined);
309
314
  }
310
315
 
311
316
  public async getCheckpointsForEpoch(epochNumber: EpochNumber): Promise<Checkpoint[]> {
317
+ const checkpointsData = await this.getCheckpointsDataForEpoch(epochNumber);
318
+ return Promise.all(
319
+ checkpointsData.map(data => this.getPublishedCheckpointFromCheckpointData(data).then(p => p.checkpoint)),
320
+ );
321
+ }
322
+
323
+ /** Returns checkpoint data for all checkpoints whose slot falls within the given epoch. */
324
+ public getCheckpointsDataForEpoch(epochNumber: EpochNumber): Promise<CheckpointData[]> {
312
325
  if (!this.l1Constants) {
313
326
  throw new Error('L1 constants not set');
314
327
  }
315
328
 
316
329
  const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
317
- const checkpoints: Checkpoint[] = [];
318
-
319
- // Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
320
- // We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
321
- let checkpointData = await this.store.getCheckpointData(await this.store.getSynchedCheckpointNumber());
322
- const slot = (b: CheckpointData) => b.header.slotNumber;
323
- while (checkpointData && slot(checkpointData) >= start) {
324
- if (slot(checkpointData) <= end) {
325
- // push the checkpoints on backwards
326
- const [checkpoint] = await this.getCheckpoints(checkpointData.checkpointNumber, 1);
327
- checkpoints.push(checkpoint.checkpoint);
328
- }
329
- checkpointData = await this.store.getCheckpointData(CheckpointNumber(checkpointData.checkpointNumber - 1));
330
- }
331
-
332
- return checkpoints.reverse();
330
+ return this.stores.blocks.getCheckpointDataForSlotRange(start, end);
333
331
  }
334
332
 
335
333
  public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
336
334
  // If the number provided is -ve, then return the latest block.
337
335
  if (number < 0) {
338
- number = await this.store.getLatestBlockNumber();
336
+ number = await this.stores.blocks.getLatestL2BlockNumber();
339
337
  }
340
338
  if (number === 0) {
341
339
  return undefined;
342
340
  }
343
- return this.store.getBlock(number);
341
+ return this.stores.blocks.getBlock(number);
344
342
  }
345
343
 
346
344
  public getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
347
- return this.store.getBlocks(from, limit);
345
+ return this.stores.blocks.getBlocks(from, limit);
348
346
  }
349
347
 
350
348
  public getCheckpointedBlockByHash(blockHash: BlockHash): Promise<CheckpointedL2Block | undefined> {
351
- return this.store.getCheckpointedBlockByHash(blockHash);
349
+ return this.stores.blocks.getCheckpointedBlockByHash(blockHash);
352
350
  }
353
351
 
354
352
  public getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
355
- return this.store.getCheckpointedBlockByArchive(archive);
353
+ return this.stores.blocks.getCheckpointedBlockByArchive(archive);
356
354
  }
357
355
 
358
356
  public async getL2BlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
359
- const checkpointedBlock = await this.store.getCheckpointedBlockByHash(blockHash);
357
+ const checkpointedBlock = await this.stores.blocks.getCheckpointedBlockByHash(blockHash);
360
358
  return checkpointedBlock?.block;
361
359
  }
362
360
 
363
361
  public async getL2BlockByArchive(archive: Fr): Promise<L2Block | undefined> {
364
- const checkpointedBlock = await this.store.getCheckpointedBlockByArchive(archive);
362
+ const checkpointedBlock = await this.stores.blocks.getCheckpointedBlockByArchive(archive);
365
363
  return checkpointedBlock?.block;
366
364
  }
367
365
  }