@aztec/archiver 4.0.0-nightly.20260113 → 4.0.0-nightly.20260115

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 (174) hide show
  1. package/README.md +139 -22
  2. package/dest/archiver.d.ts +134 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +767 -0
  5. package/dest/{archiver/config.d.ts → config.d.ts} +9 -1
  6. package/dest/config.d.ts.map +1 -0
  7. package/dest/{archiver/config.js → config.js} +9 -0
  8. package/dest/{archiver/errors.d.ts → errors.d.ts} +1 -1
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/factory.d.ts +5 -6
  11. package/dest/factory.d.ts.map +1 -1
  12. package/dest/factory.js +82 -5
  13. package/dest/index.d.ts +10 -4
  14. package/dest/index.d.ts.map +1 -1
  15. package/dest/index.js +8 -3
  16. package/dest/interfaces.d.ts +9 -0
  17. package/dest/interfaces.d.ts.map +1 -0
  18. package/dest/interfaces.js +3 -0
  19. package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.d.ts +1 -1
  20. package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
  21. package/dest/{archiver/l1 → l1}/calldata_retriever.d.ts +2 -2
  22. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  23. package/dest/l1/data_retrieval.d.ts +88 -0
  24. package/dest/l1/data_retrieval.d.ts.map +1 -0
  25. package/dest/{archiver/l1 → l1}/data_retrieval.js +32 -51
  26. package/dest/{archiver/l1 → l1}/debug_tx.d.ts +1 -1
  27. package/dest/l1/debug_tx.d.ts.map +1 -0
  28. package/dest/{archiver/l1 → l1}/spire_proposer.d.ts +1 -1
  29. package/dest/l1/spire_proposer.d.ts.map +1 -0
  30. package/dest/{archiver/l1 → l1}/trace_tx.d.ts +1 -1
  31. package/dest/l1/trace_tx.d.ts.map +1 -0
  32. package/dest/l1/types.d.ts +12 -0
  33. package/dest/l1/types.d.ts.map +1 -0
  34. package/dest/{archiver/l1 → l1}/validate_trace.d.ts +1 -1
  35. package/dest/l1/validate_trace.d.ts.map +1 -0
  36. package/dest/modules/data_source_base.d.ts +83 -0
  37. package/dest/modules/data_source_base.d.ts.map +1 -0
  38. package/dest/modules/data_source_base.js +301 -0
  39. package/dest/modules/data_store_updater.d.ts +46 -0
  40. package/dest/modules/data_store_updater.d.ts.map +1 -0
  41. package/dest/modules/data_store_updater.js +216 -0
  42. package/dest/modules/instrumentation.d.ts +37 -0
  43. package/dest/modules/instrumentation.d.ts.map +1 -0
  44. package/dest/modules/l1_synchronizer.d.ts +67 -0
  45. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  46. package/dest/modules/l1_synchronizer.js +1064 -0
  47. package/dest/{archiver → modules}/validation.d.ts +1 -1
  48. package/dest/modules/validation.d.ts.map +1 -0
  49. package/dest/{archiver/kv_archiver_store → store}/block_store.d.ts +2 -2
  50. package/dest/store/block_store.d.ts.map +1 -0
  51. package/dest/{archiver/kv_archiver_store → store}/block_store.js +1 -1
  52. package/dest/store/contract_class_store.d.ts +18 -0
  53. package/dest/store/contract_class_store.d.ts.map +1 -0
  54. package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +1 -1
  55. package/dest/store/contract_instance_store.d.ts +24 -0
  56. package/dest/store/contract_instance_store.d.ts.map +1 -0
  57. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
  58. package/dest/{archiver/archiver_store.d.ts → store/kv_archiver_store.d.ts} +143 -139
  59. package/dest/store/kv_archiver_store.d.ts.map +1 -0
  60. package/dest/{archiver/kv_archiver_store → store}/kv_archiver_store.js +157 -49
  61. package/dest/{archiver/kv_archiver_store → store}/log_store.d.ts +1 -1
  62. package/dest/store/log_store.d.ts.map +1 -0
  63. package/dest/{archiver/kv_archiver_store → store}/message_store.d.ts +1 -1
  64. package/dest/store/message_store.d.ts.map +1 -0
  65. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  66. package/dest/structs/data_retrieval.d.ts.map +1 -0
  67. package/dest/structs/inbox_message.d.ts +15 -0
  68. package/dest/structs/inbox_message.d.ts.map +1 -0
  69. package/dest/{archiver/structs → structs}/published.d.ts +1 -1
  70. package/dest/structs/published.d.ts.map +1 -0
  71. package/dest/test/fake_l1_state.d.ts +173 -0
  72. package/dest/test/fake_l1_state.d.ts.map +1 -0
  73. package/dest/test/fake_l1_state.js +364 -0
  74. package/dest/test/index.d.ts +2 -1
  75. package/dest/test/index.d.ts.map +1 -1
  76. package/dest/test/index.js +1 -0
  77. package/dest/test/mock_structs.d.ts +76 -2
  78. package/dest/test/mock_structs.d.ts.map +1 -1
  79. package/dest/test/mock_structs.js +133 -2
  80. package/package.json +15 -17
  81. package/src/archiver.ts +522 -0
  82. package/src/{archiver/config.ts → config.ts} +11 -0
  83. package/src/factory.ts +118 -6
  84. package/src/index.ts +10 -3
  85. package/src/interfaces.ts +9 -0
  86. package/src/{archiver/l1 → l1}/calldata_retriever.ts +1 -1
  87. package/src/{archiver/l1 → l1}/data_retrieval.ts +52 -69
  88. package/src/modules/data_source_base.ts +439 -0
  89. package/src/modules/data_store_updater.ts +318 -0
  90. package/src/modules/l1_synchronizer.ts +870 -0
  91. package/src/{archiver/kv_archiver_store → store}/block_store.ts +1 -1
  92. package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +1 -1
  93. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +1 -1
  94. package/src/{archiver/kv_archiver_store → store}/kv_archiver_store.ts +170 -8
  95. package/src/test/fake_l1_state.ts +561 -0
  96. package/src/test/index.ts +1 -0
  97. package/src/test/mock_structs.ts +247 -2
  98. package/dest/archiver/archiver.d.ts +0 -307
  99. package/dest/archiver/archiver.d.ts.map +0 -1
  100. package/dest/archiver/archiver.js +0 -2102
  101. package/dest/archiver/archiver_store.d.ts.map +0 -1
  102. package/dest/archiver/archiver_store.js +0 -4
  103. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  104. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  105. package/dest/archiver/archiver_store_test_suite.js +0 -2770
  106. package/dest/archiver/config.d.ts.map +0 -1
  107. package/dest/archiver/errors.d.ts.map +0 -1
  108. package/dest/archiver/index.d.ts +0 -7
  109. package/dest/archiver/index.d.ts.map +0 -1
  110. package/dest/archiver/index.js +0 -4
  111. package/dest/archiver/instrumentation.d.ts +0 -37
  112. package/dest/archiver/instrumentation.d.ts.map +0 -1
  113. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  114. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  115. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  116. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  117. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  118. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -159
  119. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  120. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  121. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  122. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
  123. package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
  124. package/dest/archiver/l1/data_retrieval.d.ts +0 -90
  125. package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
  126. package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
  127. package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
  128. package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
  129. package/dest/archiver/l1/types.d.ts +0 -12
  130. package/dest/archiver/l1/types.d.ts.map +0 -1
  131. package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
  132. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  133. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  134. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  135. package/dest/archiver/structs/published.d.ts.map +0 -1
  136. package/dest/archiver/validation.d.ts.map +0 -1
  137. package/dest/rpc/index.d.ts +0 -9
  138. package/dest/rpc/index.d.ts.map +0 -1
  139. package/dest/rpc/index.js +0 -15
  140. package/src/archiver/archiver.ts +0 -2265
  141. package/src/archiver/archiver_store.ts +0 -380
  142. package/src/archiver/archiver_store_test_suite.ts +0 -2842
  143. package/src/archiver/index.ts +0 -6
  144. package/src/rpc/index.ts +0 -16
  145. /package/dest/{archiver/errors.js → errors.js} +0 -0
  146. /package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.js +0 -0
  147. /package/dest/{archiver/l1 → l1}/calldata_retriever.js +0 -0
  148. /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
  149. /package/dest/{archiver/l1 → l1}/spire_proposer.js +0 -0
  150. /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
  151. /package/dest/{archiver/l1 → l1}/types.js +0 -0
  152. /package/dest/{archiver/l1 → l1}/validate_trace.js +0 -0
  153. /package/dest/{archiver → modules}/instrumentation.js +0 -0
  154. /package/dest/{archiver → modules}/validation.js +0 -0
  155. /package/dest/{archiver/kv_archiver_store → store}/log_store.js +0 -0
  156. /package/dest/{archiver/kv_archiver_store → store}/message_store.js +0 -0
  157. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  158. /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
  159. /package/dest/{archiver/structs → structs}/published.js +0 -0
  160. /package/src/{archiver/errors.ts → errors.ts} +0 -0
  161. /package/src/{archiver/l1 → l1}/README.md +0 -0
  162. /package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +0 -0
  163. /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
  164. /package/src/{archiver/l1 → l1}/spire_proposer.ts +0 -0
  165. /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
  166. /package/src/{archiver/l1 → l1}/types.ts +0 -0
  167. /package/src/{archiver/l1 → l1}/validate_trace.ts +0 -0
  168. /package/src/{archiver → modules}/instrumentation.ts +0 -0
  169. /package/src/{archiver → modules}/validation.ts +0 -0
  170. /package/src/{archiver/kv_archiver_store → store}/log_store.ts +0 -0
  171. /package/src/{archiver/kv_archiver_store → store}/message_store.ts +0 -0
  172. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
  173. /package/src/{archiver/structs → structs}/inbox_message.ts +0 -0
  174. /package/src/{archiver/structs → structs}/published.ts +0 -0
@@ -0,0 +1,439 @@
1
+ import { BlockNumber, CheckpointNumber, type EpochNumber, type SlotNumber } from '@aztec/foundation/branded-types';
2
+ import type { Fr } from '@aztec/foundation/curves/bn254';
3
+ import type { EthAddress } from '@aztec/foundation/eth-address';
4
+ import { isDefined } from '@aztec/foundation/types';
5
+ import type { FunctionSelector } from '@aztec/stdlib/abi';
6
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
+ import {
8
+ type CheckpointedL2Block,
9
+ CommitteeAttestation,
10
+ L2Block,
11
+ type L2BlockNew,
12
+ type L2Tips,
13
+ PublishedL2Block,
14
+ } from '@aztec/stdlib/block';
15
+ import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
16
+ import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
17
+ import { type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
18
+ import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
19
+ import type { L2LogsSource } from '@aztec/stdlib/interfaces/server';
20
+ import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
21
+ import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
22
+ import type { CheckpointHeader } from '@aztec/stdlib/rollup';
23
+ import type { BlockHeader, IndexedTxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
24
+ import type { UInt64 } from '@aztec/stdlib/types';
25
+
26
+ import type { ArchiverDataSource } from '../interfaces.js';
27
+ import type { CheckpointData } from '../store/block_store.js';
28
+ import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
29
+ import type { ValidateCheckpointResult } from './validation.js';
30
+
31
+ /**
32
+ * Abstract base class implementing ArchiverDataSource using a KVArchiverDataStore.
33
+ * Provides implementations for all store-delegating methods and declares abstract methods
34
+ * for L1-dependent functionality that subclasses must implement.
35
+ */
36
+ export abstract class ArchiverDataSourceBase
37
+ implements ArchiverDataSource, L2LogsSource, ContractDataSource, L1ToL2MessageSource
38
+ {
39
+ constructor(
40
+ protected readonly store: KVArchiverDataStore,
41
+ protected readonly l1Constants?: L1RollupConstants,
42
+ ) {}
43
+
44
+ abstract getRollupAddress(): Promise<EthAddress>;
45
+
46
+ abstract getRegistryAddress(): Promise<EthAddress>;
47
+
48
+ abstract getL1Constants(): Promise<L1RollupConstants>;
49
+
50
+ abstract getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }>;
51
+
52
+ abstract getL1Timestamp(): Promise<bigint | undefined>;
53
+
54
+ abstract getL2Tips(): Promise<L2Tips>;
55
+
56
+ abstract getL2SlotNumber(): Promise<SlotNumber | undefined>;
57
+
58
+ abstract getL2EpochNumber(): Promise<EpochNumber | undefined>;
59
+
60
+ abstract isEpochComplete(epochNumber: EpochNumber): Promise<boolean>;
61
+
62
+ abstract syncImmediate(): Promise<void>;
63
+
64
+ public getCheckpointNumber(): Promise<CheckpointNumber> {
65
+ return this.store.getSynchedCheckpointNumber();
66
+ }
67
+
68
+ public getSynchedCheckpointNumber(): Promise<CheckpointNumber> {
69
+ return this.store.getSynchedCheckpointNumber();
70
+ }
71
+
72
+ public getProvenCheckpointNumber(): Promise<CheckpointNumber> {
73
+ return this.store.getProvenCheckpointNumber();
74
+ }
75
+
76
+ public getBlockNumber(): Promise<BlockNumber> {
77
+ return this.store.getLatestBlockNumber();
78
+ }
79
+
80
+ public getProvenBlockNumber(): Promise<BlockNumber> {
81
+ return this.store.getProvenBlockNumber();
82
+ }
83
+
84
+ public async getBlockHeader(number: BlockNumber | 'latest'): Promise<BlockHeader | undefined> {
85
+ const blockNumber = number === 'latest' ? await this.store.getLatestBlockNumber() : number;
86
+ if (blockNumber === 0) {
87
+ return undefined;
88
+ }
89
+ const headers = await this.store.getBlockHeaders(blockNumber, 1);
90
+ return headers.length === 0 ? undefined : headers[0];
91
+ }
92
+
93
+ public getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
94
+ return this.store.getCheckpointedBlock(number);
95
+ }
96
+
97
+ public getCheckpointedBlockNumber(): Promise<BlockNumber> {
98
+ return this.store.getCheckpointedL2BlockNumber();
99
+ }
100
+
101
+ public async getCheckpointHeader(number: CheckpointNumber | 'latest'): Promise<CheckpointHeader | undefined> {
102
+ if (number === 'latest') {
103
+ number = await this.store.getSynchedCheckpointNumber();
104
+ }
105
+ if (number === 0) {
106
+ return undefined;
107
+ }
108
+ const checkpoint = await this.store.getCheckpointData(number);
109
+ if (!checkpoint) {
110
+ return undefined;
111
+ }
112
+ return checkpoint.header;
113
+ }
114
+
115
+ public async getLastBlockNumberInCheckpoint(checkpointNumber: CheckpointNumber): Promise<BlockNumber | undefined> {
116
+ const checkpointData = await this.store.getCheckpointData(checkpointNumber);
117
+ if (!checkpointData) {
118
+ return undefined;
119
+ }
120
+ return BlockNumber(checkpointData.startBlock + checkpointData.numBlocks - 1);
121
+ }
122
+
123
+ public async getCheckpointedBlocks(
124
+ from: BlockNumber,
125
+ limit: number,
126
+ proven?: boolean,
127
+ ): Promise<CheckpointedL2Block[]> {
128
+ const blocks = await this.store.getCheckpointedBlocks(from, limit);
129
+
130
+ if (proven === true) {
131
+ const provenBlockNumber = await this.store.getProvenBlockNumber();
132
+ return blocks.filter(b => b.block.number <= provenBlockNumber);
133
+ }
134
+ return blocks;
135
+ }
136
+
137
+ public getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
138
+ return this.store.getBlockHeaderByHash(blockHash);
139
+ }
140
+
141
+ public getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
142
+ return this.store.getBlockHeaderByArchive(archive);
143
+ }
144
+
145
+ public async getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
146
+ // If the number provided is -ve, then return the latest block.
147
+ if (number < 0) {
148
+ number = await this.store.getLatestBlockNumber();
149
+ }
150
+ if (number === 0) {
151
+ return undefined;
152
+ }
153
+ const publishedBlock = await this.store.getBlock(number);
154
+ return publishedBlock;
155
+ }
156
+
157
+ public getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined> {
158
+ return this.store.getTxEffect(txHash);
159
+ }
160
+
161
+ public getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined> {
162
+ return this.store.getSettledTxReceipt(txHash);
163
+ }
164
+
165
+ public isPendingChainInvalid(): Promise<boolean> {
166
+ return this.getPendingChainValidationStatus().then(status => !status.valid);
167
+ }
168
+
169
+ public async getPendingChainValidationStatus(): Promise<ValidateCheckpointResult> {
170
+ return (await this.store.getPendingChainValidationStatus()) ?? { valid: true };
171
+ }
172
+
173
+ public async getL2BlocksNew(from: BlockNumber, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
174
+ const blocks = await this.store.getBlocks(from, limit);
175
+
176
+ if (proven === true) {
177
+ const provenBlockNumber = await this.store.getProvenBlockNumber();
178
+ return blocks.filter(b => b.number <= provenBlockNumber);
179
+ }
180
+ return blocks;
181
+ }
182
+
183
+ public getPrivateLogsByTags(tags: SiloedTag[]): Promise<TxScopedL2Log[][]> {
184
+ return this.store.getPrivateLogsByTags(tags);
185
+ }
186
+
187
+ public getPublicLogsByTagsFromContract(contractAddress: AztecAddress, tags: Tag[]): Promise<TxScopedL2Log[][]> {
188
+ return this.store.getPublicLogsByTagsFromContract(contractAddress, tags);
189
+ }
190
+
191
+ public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
192
+ return this.store.getPublicLogs(filter);
193
+ }
194
+
195
+ public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
196
+ return this.store.getContractClassLogs(filter);
197
+ }
198
+
199
+ public getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
200
+ return this.store.getContractClass(id);
201
+ }
202
+
203
+ public getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
204
+ return this.store.getBytecodeCommitment(id);
205
+ }
206
+
207
+ public async getContract(
208
+ address: AztecAddress,
209
+ maybeTimestamp?: UInt64,
210
+ ): Promise<ContractInstanceWithAddress | undefined> {
211
+ let timestamp;
212
+ if (maybeTimestamp === undefined) {
213
+ const latestBlockHeader = await this.getBlockHeader('latest');
214
+ // If we get undefined block header, it means that the archiver has not yet synced any block so we default to 0.
215
+ timestamp = latestBlockHeader ? latestBlockHeader.globalVariables.timestamp : 0n;
216
+ } else {
217
+ timestamp = maybeTimestamp;
218
+ }
219
+
220
+ return this.store.getContractInstance(address, timestamp);
221
+ }
222
+
223
+ public getContractClassIds(): Promise<Fr[]> {
224
+ return this.store.getContractClassIds();
225
+ }
226
+
227
+ public getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
228
+ return this.store.getDebugFunctionName(address, selector);
229
+ }
230
+
231
+ public registerContractFunctionSignatures(signatures: string[]): Promise<void> {
232
+ return this.store.registerContractFunctionSignatures(signatures);
233
+ }
234
+
235
+ public getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
236
+ return this.store.getL1ToL2Messages(checkpointNumber);
237
+ }
238
+
239
+ public getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined> {
240
+ return this.store.getL1ToL2MessageIndex(l1ToL2Message);
241
+ }
242
+
243
+ public async getPublishedCheckpoints(
244
+ checkpointNumber: CheckpointNumber,
245
+ limit: number,
246
+ ): Promise<PublishedCheckpoint[]> {
247
+ const checkpoints = await this.store.getRangeOfCheckpoints(checkpointNumber, limit);
248
+ const blocks = (
249
+ await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
250
+ ).filter(isDefined);
251
+
252
+ const fullCheckpoints: PublishedCheckpoint[] = [];
253
+ for (let i = 0; i < checkpoints.length; i++) {
254
+ const blocksForCheckpoint = blocks[i];
255
+ const checkpoint = checkpoints[i];
256
+ const fullCheckpoint = new Checkpoint(
257
+ checkpoint.archive,
258
+ checkpoint.header,
259
+ blocksForCheckpoint,
260
+ checkpoint.checkpointNumber,
261
+ );
262
+ const publishedCheckpoint = new PublishedCheckpoint(
263
+ fullCheckpoint,
264
+ checkpoint.l1,
265
+ checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
266
+ );
267
+ fullCheckpoints.push(publishedCheckpoint);
268
+ }
269
+ return fullCheckpoints;
270
+ }
271
+
272
+ public async getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2Block[]> {
273
+ if (!this.l1Constants) {
274
+ throw new Error('L1 constants not set');
275
+ }
276
+
277
+ const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
278
+ const blocks: L2Block[] = [];
279
+
280
+ // Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
281
+ // We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
282
+ let checkpoint = await this.store.getCheckpointData(await this.store.getSynchedCheckpointNumber());
283
+ const slot = (b: CheckpointData) => b.header.slotNumber;
284
+ while (checkpoint && slot(checkpoint) >= start) {
285
+ if (slot(checkpoint) <= end) {
286
+ // push the blocks on backwards
287
+ const endBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
288
+ for (let i = endBlock; i >= checkpoint.startBlock; i--) {
289
+ const block = await this.getBlock(BlockNumber(i));
290
+ if (block) {
291
+ blocks.push(block);
292
+ }
293
+ }
294
+ }
295
+ checkpoint = await this.store.getCheckpointData(CheckpointNumber(checkpoint.checkpointNumber - 1));
296
+ }
297
+
298
+ return blocks.reverse();
299
+ }
300
+
301
+ public async getBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
302
+ if (!this.l1Constants) {
303
+ throw new Error('L1 constants not set');
304
+ }
305
+
306
+ const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
307
+ const blocks: BlockHeader[] = [];
308
+
309
+ // Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
310
+ // We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
311
+ let checkpoint = await this.store.getCheckpointData(await this.store.getSynchedCheckpointNumber());
312
+ const slot = (b: CheckpointData) => b.header.slotNumber;
313
+ while (checkpoint && slot(checkpoint) >= start) {
314
+ if (slot(checkpoint) <= end) {
315
+ // push the blocks on backwards
316
+ const endBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
317
+ for (let i = endBlock; i >= checkpoint.startBlock; i--) {
318
+ const block = await this.getBlockHeader(BlockNumber(i));
319
+ if (block) {
320
+ blocks.push(block);
321
+ }
322
+ }
323
+ }
324
+ checkpoint = await this.store.getCheckpointData(CheckpointNumber(checkpoint.checkpointNumber - 1));
325
+ }
326
+ return blocks.reverse();
327
+ }
328
+
329
+ public async getCheckpointsForEpoch(epochNumber: EpochNumber): Promise<Checkpoint[]> {
330
+ if (!this.l1Constants) {
331
+ throw new Error('L1 constants not set');
332
+ }
333
+
334
+ const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
335
+ const checkpoints: Checkpoint[] = [];
336
+
337
+ // Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
338
+ // We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
339
+ let checkpointData = await this.store.getCheckpointData(await this.store.getSynchedCheckpointNumber());
340
+ const slot = (b: CheckpointData) => b.header.slotNumber;
341
+ while (checkpointData && slot(checkpointData) >= start) {
342
+ if (slot(checkpointData) <= end) {
343
+ // push the checkpoints on backwards
344
+ const [checkpoint] = await this.getPublishedCheckpoints(checkpointData.checkpointNumber, 1);
345
+ checkpoints.push(checkpoint.checkpoint);
346
+ }
347
+ checkpointData = await this.store.getCheckpointData(CheckpointNumber(checkpointData.checkpointNumber - 1));
348
+ }
349
+
350
+ return checkpoints.reverse();
351
+ }
352
+
353
+ public async getPublishedBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<PublishedL2Block[]> {
354
+ const checkpoints = await this.store.getRangeOfCheckpoints(CheckpointNumber(from), limit);
355
+ const provenCheckpointNumber = await this.store.getProvenCheckpointNumber();
356
+ const blocks = (
357
+ await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
358
+ ).filter(isDefined);
359
+
360
+ const olbBlocks: PublishedL2Block[] = [];
361
+ for (let i = 0; i < checkpoints.length; i++) {
362
+ const blockForCheckpoint = blocks[i][0];
363
+ const checkpoint = checkpoints[i];
364
+ if (checkpoint.checkpointNumber > provenCheckpointNumber && proven === true) {
365
+ // this checkpointisn't proven and we only want proven
366
+ continue;
367
+ }
368
+ const oldCheckpoint = new Checkpoint(
369
+ blockForCheckpoint.archive,
370
+ checkpoint.header,
371
+ [blockForCheckpoint],
372
+ checkpoint.checkpointNumber,
373
+ );
374
+ const oldBlock = L2Block.fromCheckpoint(oldCheckpoint);
375
+ const publishedBlock = new PublishedL2Block(
376
+ oldBlock,
377
+ checkpoint.l1,
378
+ checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
379
+ );
380
+ olbBlocks.push(publishedBlock);
381
+ }
382
+ return olbBlocks;
383
+ }
384
+
385
+ public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
386
+ // If the number provided is -ve, then return the latest block.
387
+ if (number < 0) {
388
+ number = await this.store.getLatestBlockNumber();
389
+ }
390
+ if (number === 0) {
391
+ return undefined;
392
+ }
393
+ const publishedBlocks = await this.getPublishedBlocks(number, 1);
394
+ if (publishedBlocks.length === 0) {
395
+ return undefined;
396
+ }
397
+ return publishedBlocks[0].block;
398
+ }
399
+
400
+ public async getBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<L2Block[]> {
401
+ const publishedBlocks = await this.getPublishedBlocks(from, limit, proven);
402
+ return publishedBlocks.map(x => x.block);
403
+ }
404
+
405
+ public async getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
406
+ const checkpointedBlock = await this.store.getCheckpointedBlockByHash(blockHash);
407
+ return this.buildOldBlockFromCheckpointedBlock(checkpointedBlock);
408
+ }
409
+
410
+ public async getPublishedBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined> {
411
+ const checkpointedBlock = await this.store.getCheckpointedBlockByArchive(archive);
412
+ return this.buildOldBlockFromCheckpointedBlock(checkpointedBlock);
413
+ }
414
+
415
+ private async buildOldBlockFromCheckpointedBlock(
416
+ checkpointedBlock: CheckpointedL2Block | undefined,
417
+ ): Promise<PublishedL2Block | undefined> {
418
+ if (!checkpointedBlock) {
419
+ return undefined;
420
+ }
421
+ const checkpoint = await this.store.getCheckpointData(checkpointedBlock.checkpointNumber);
422
+ if (!checkpoint) {
423
+ return checkpoint;
424
+ }
425
+ const fullCheckpoint = new Checkpoint(
426
+ checkpointedBlock?.block.archive,
427
+ checkpoint?.header,
428
+ [checkpointedBlock.block],
429
+ checkpoint.checkpointNumber,
430
+ );
431
+ const oldBlock = L2Block.fromCheckpoint(fullCheckpoint);
432
+ const published = new PublishedL2Block(
433
+ oldBlock,
434
+ checkpoint.l1,
435
+ checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
436
+ );
437
+ return published;
438
+ }
439
+ }