@aztec/archiver 0.56.0 → 0.58.0

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 (79) hide show
  1. package/README.md +1 -1
  2. package/dest/archiver/archiver.d.ts +27 -22
  3. package/dest/archiver/archiver.d.ts.map +1 -1
  4. package/dest/archiver/archiver.js +421 -115
  5. package/dest/archiver/archiver_store.d.ts +39 -10
  6. package/dest/archiver/archiver_store.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  8. package/dest/archiver/archiver_store_test_suite.js +84 -31
  9. package/dest/archiver/config.js +6 -6
  10. package/dest/archiver/data_retrieval.d.ts +2 -3
  11. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  12. package/dest/archiver/data_retrieval.js +23 -22
  13. package/dest/archiver/epoch_helpers.d.ts +15 -0
  14. package/dest/archiver/epoch_helpers.d.ts.map +1 -0
  15. package/dest/archiver/epoch_helpers.js +23 -0
  16. package/dest/archiver/kv_archiver_store/block_store.d.ts +20 -1
  17. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  18. package/dest/archiver/kv_archiver_store/block_store.js +62 -5
  19. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +3 -3
  20. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  21. package/dest/archiver/kv_archiver_store/contract_class_store.js +12 -5
  22. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +2 -2
  23. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
  24. package/dest/archiver/kv_archiver_store/contract_instance_store.js +5 -2
  25. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +29 -10
  26. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  27. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +57 -17
  28. package/dest/archiver/kv_archiver_store/log_store.d.ts +4 -5
  29. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  30. package/dest/archiver/kv_archiver_store/log_store.js +18 -14
  31. package/dest/archiver/kv_archiver_store/message_store.d.ts +2 -1
  32. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  33. package/dest/archiver/kv_archiver_store/message_store.js +17 -13
  34. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +3 -2
  35. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
  36. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +12 -14
  37. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +23 -23
  38. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
  39. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +130 -70
  40. package/dest/factory.d.ts.map +1 -1
  41. package/dest/factory.js +17 -1
  42. package/dest/index.js +2 -1
  43. package/dest/test/index.d.ts +4 -0
  44. package/dest/test/index.d.ts.map +1 -0
  45. package/dest/test/index.js +4 -0
  46. package/dest/test/mock_archiver.d.ts +22 -0
  47. package/dest/test/mock_archiver.d.ts.map +1 -0
  48. package/dest/test/mock_archiver.js +44 -0
  49. package/dest/test/mock_l1_to_l2_message_source.d.ts +16 -0
  50. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -0
  51. package/dest/test/mock_l1_to_l2_message_source.js +25 -0
  52. package/dest/test/mock_l2_block_source.d.ts +75 -0
  53. package/dest/test/mock_l2_block_source.d.ts.map +1 -0
  54. package/dest/test/mock_l2_block_source.js +154 -0
  55. package/package.json +15 -11
  56. package/src/archiver/archiver.ts +553 -170
  57. package/src/archiver/archiver_store.ts +48 -19
  58. package/src/archiver/archiver_store_test_suite.ts +111 -73
  59. package/src/archiver/config.ts +5 -5
  60. package/src/archiver/data_retrieval.ts +25 -26
  61. package/src/archiver/epoch_helpers.ts +26 -0
  62. package/src/archiver/kv_archiver_store/block_store.ts +70 -2
  63. package/src/archiver/kv_archiver_store/contract_class_store.ts +24 -9
  64. package/src/archiver/kv_archiver_store/contract_instance_store.ts +5 -2
  65. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +71 -29
  66. package/src/archiver/kv_archiver_store/log_store.ts +18 -18
  67. package/src/archiver/kv_archiver_store/message_store.ts +16 -18
  68. package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +13 -19
  69. package/src/archiver/memory_archiver_store/memory_archiver_store.ts +154 -83
  70. package/src/factory.ts +18 -0
  71. package/src/index.ts +1 -0
  72. package/src/test/index.ts +3 -0
  73. package/src/test/mock_archiver.ts +55 -0
  74. package/src/test/mock_l1_to_l2_message_source.ts +31 -0
  75. package/src/test/mock_l2_block_source.ts +190 -0
  76. package/dest/archiver/kv_archiver_store/proven_store.d.ts +0 -14
  77. package/dest/archiver/kv_archiver_store/proven_store.d.ts.map +0 -1
  78. package/dest/archiver/kv_archiver_store/proven_store.js +0 -30
  79. package/src/archiver/kv_archiver_store/proven_store.ts +0 -34
@@ -15,18 +15,21 @@ import {
15
15
  TxReceipt,
16
16
  type UnencryptedL2BlockL2Logs,
17
17
  } from '@aztec/circuit-types';
18
- import { Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
19
- import { type ContractArtifact } from '@aztec/foundation/abi';
20
- import { type AztecAddress } from '@aztec/foundation/aztec-address';
21
18
  import {
22
19
  type ContractClassPublic,
20
+ type ContractClassPublicWithBlockNumber,
23
21
  type ContractInstanceWithAddress,
24
22
  type ExecutablePrivateFunctionWithMembershipProof,
23
+ Fr,
24
+ type Header,
25
+ INITIAL_L2_BLOCK_NUM,
25
26
  type UnconstrainedFunctionWithMembershipProof,
26
- } from '@aztec/types/contracts';
27
+ } from '@aztec/circuits.js';
28
+ import { type ContractArtifact } from '@aztec/foundation/abi';
29
+ import { type AztecAddress } from '@aztec/foundation/aztec-address';
27
30
 
28
31
  import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_store.js';
29
- import { type DataRetrieval, type SingletonDataRetrieval } from '../structs/data_retrieval.js';
32
+ import { type DataRetrieval } from '../structs/data_retrieval.js';
30
33
  import { type L1Published } from '../structs/published.js';
31
34
  import { L1ToL2MessageStore } from './l1_to_l2_message_store.js';
32
35
 
@@ -44,23 +47,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
44
47
  */
45
48
  private txEffects: TxEffect[] = [];
46
49
 
47
- /**
48
- * An array containing all the encrypted logs that have been fetched so far.
49
- * Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
50
- */
51
- private noteEncryptedLogsPerBlock: EncryptedNoteL2BlockL2Logs[] = [];
50
+ private noteEncryptedLogsPerBlock: Map<number, EncryptedNoteL2BlockL2Logs> = new Map();
52
51
 
53
- /**
54
- * An array containing all the encrypted logs that have been fetched so far.
55
- * Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
56
- */
57
- private encryptedLogsPerBlock: EncryptedL2BlockL2Logs[] = [];
52
+ private encryptedLogsPerBlock: Map<number, EncryptedL2BlockL2Logs> = new Map();
58
53
 
59
- /**
60
- * An array containing all the unencrypted logs that have been fetched so far.
61
- * Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
62
- */
63
- private unencryptedLogsPerBlock: UnencryptedL2BlockL2Logs[] = [];
54
+ private unencryptedLogsPerBlock: Map<number, UnencryptedL2BlockL2Logs> = new Map();
64
55
 
65
56
  /**
66
57
  * Contains all L1 to L2 messages.
@@ -69,7 +60,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
69
60
 
70
61
  private contractArtifacts: Map<string, ContractArtifact> = new Map();
71
62
 
72
- private contractClasses: Map<string, ContractClassPublic> = new Map();
63
+ private contractClasses: Map<string, ContractClassPublicWithBlockNumber> = new Map();
73
64
 
74
65
  private privateFunctions: Map<string, ExecutablePrivateFunctionWithMembershipProof[]> = new Map();
75
66
 
@@ -79,9 +70,9 @@ export class MemoryArchiverStore implements ArchiverDataStore {
79
70
 
80
71
  private lastL1BlockNewBlocks: bigint | undefined = undefined;
81
72
  private lastL1BlockNewMessages: bigint | undefined = undefined;
82
- private lastL1BlockNewProvenLogs: bigint | undefined = undefined;
83
73
 
84
74
  private lastProvenL2BlockNumber: number = 0;
75
+ private lastProvenL2EpochNumber: number = 0;
85
76
 
86
77
  constructor(
87
78
  /** The max number of logs that can be obtained in 1 "getUnencryptedLogs" call. */
@@ -129,9 +120,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
129
120
  return Promise.resolve(true);
130
121
  }
131
122
 
132
- public addContractClasses(data: ContractClassPublic[], _blockNumber: number): Promise<boolean> {
123
+ public addContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
133
124
  for (const contractClass of data) {
134
- this.contractClasses.set(contractClass.id.toString(), contractClass);
125
+ if (!this.contractClasses.has(contractClass.id.toString())) {
126
+ this.contractClasses.set(contractClass.id.toString(), {
127
+ ...contractClass,
128
+ l2BlockNumber: blockNumber,
129
+ });
130
+ }
131
+ }
132
+ return Promise.resolve(true);
133
+ }
134
+
135
+ public deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
136
+ for (const contractClass of data) {
137
+ const restored = this.contractClasses.get(contractClass.id.toString());
138
+ if (restored && restored.l2BlockNumber >= blockNumber) {
139
+ this.contractClasses.delete(contractClass.id.toString());
140
+ }
135
141
  }
136
142
  return Promise.resolve(true);
137
143
  }
@@ -143,6 +149,13 @@ export class MemoryArchiverStore implements ArchiverDataStore {
143
149
  return Promise.resolve(true);
144
150
  }
145
151
 
152
+ public deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
153
+ for (const contractInstance of data) {
154
+ this.contractInstances.delete(contractInstance.address.toString());
155
+ }
156
+ return Promise.resolve(true);
157
+ }
158
+
146
159
  /**
147
160
  * Append new blocks to the store's list.
148
161
  * @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
@@ -161,33 +174,58 @@ export class MemoryArchiverStore implements ArchiverDataStore {
161
174
  }
162
175
 
163
176
  /**
164
- * Append new logs to the store's list.
165
- * @param encryptedLogs - The encrypted logs to be added to the store.
166
- * @param unencryptedLogs - The unencrypted logs to be added to the store.
167
- * @param blockNumber - The block for which to add the logs.
168
- * @returns True if the operation is successful.
177
+ * Unwinds blocks from the database
178
+ * @param from - The tip of the chain, passed for verification purposes,
179
+ * ensuring that we don't end up deleting something we did not intend
180
+ * @param blocksToUnwind - The number of blocks we are to unwind
181
+ * @returns True if the operation is successful
169
182
  */
170
- addLogs(
171
- noteEncryptedLogs: EncryptedNoteL2BlockL2Logs,
172
- encryptedLogs: EncryptedL2BlockL2Logs,
173
- unencryptedLogs: UnencryptedL2BlockL2Logs,
174
- blockNumber: number,
175
- ): Promise<boolean> {
176
- if (noteEncryptedLogs) {
177
- this.noteEncryptedLogsPerBlock[blockNumber - INITIAL_L2_BLOCK_NUM] = noteEncryptedLogs;
183
+ public async unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean> {
184
+ const last = await this.getSynchedL2BlockNumber();
185
+ if (from != last) {
186
+ throw new Error(`Can only remove the tip`);
178
187
  }
179
188
 
180
- if (encryptedLogs) {
181
- this.encryptedLogsPerBlock[blockNumber - INITIAL_L2_BLOCK_NUM] = encryptedLogs;
189
+ const stopAt = from - blocksToUnwind;
190
+ while ((await this.getSynchedL2BlockNumber()) > stopAt) {
191
+ const block = this.l2Blocks.pop();
192
+ if (block == undefined) {
193
+ break;
194
+ }
195
+ block.data.body.txEffects.forEach(() => this.txEffects.pop());
182
196
  }
183
197
 
184
- if (unencryptedLogs) {
185
- this.unencryptedLogsPerBlock[blockNumber - INITIAL_L2_BLOCK_NUM] = unencryptedLogs;
186
- }
198
+ return Promise.resolve(true);
199
+ }
200
+
201
+ /**
202
+ * Append new logs to the store's list.
203
+ * @param block - The block for which to add the logs.
204
+ * @returns True if the operation is successful.
205
+ */
206
+ addLogs(blocks: L2Block[]): Promise<boolean> {
207
+ blocks.forEach(block => {
208
+ this.noteEncryptedLogsPerBlock.set(block.number, block.body.noteEncryptedLogs);
209
+ this.encryptedLogsPerBlock.set(block.number, block.body.encryptedLogs);
210
+ this.unencryptedLogsPerBlock.set(block.number, block.body.unencryptedLogs);
211
+ });
212
+ return Promise.resolve(true);
213
+ }
214
+
215
+ deleteLogs(blocks: L2Block[]): Promise<boolean> {
216
+ blocks.forEach(block => {
217
+ this.encryptedLogsPerBlock.delete(block.number);
218
+ this.noteEncryptedLogsPerBlock.delete(block.number);
219
+ this.unencryptedLogsPerBlock.delete(block.number);
220
+ });
187
221
 
188
222
  return Promise.resolve(true);
189
223
  }
190
224
 
225
+ getTotalL1ToL2MessageCount(): Promise<bigint> {
226
+ return Promise.resolve(this.l1ToL2Messages.getTotalL1ToL2MessageCount());
227
+ }
228
+
191
229
  /**
192
230
  * Append L1 to L2 messages to the store.
193
231
  * @param messages - The L1 to L2 messages to be added to the store and the last processed L1 block.
@@ -226,12 +264,15 @@ export class MemoryArchiverStore implements ArchiverDataStore {
226
264
  * @remarks When "from" is smaller than genesis block number, blocks from the beginning are returned.
227
265
  */
228
266
  public getBlocks(from: number, limit: number): Promise<L1Published<L2Block>[]> {
229
- // Return an empty array if we are outside of range
230
267
  if (limit < 1) {
231
268
  return Promise.reject(new Error(`Invalid limit: ${limit}`));
232
269
  }
233
270
 
234
- const fromIndex = Math.max(from - INITIAL_L2_BLOCK_NUM, 0);
271
+ if (from < INITIAL_L2_BLOCK_NUM) {
272
+ return Promise.reject(new Error(`Invalid start: ${from}`));
273
+ }
274
+
275
+ const fromIndex = from - INITIAL_L2_BLOCK_NUM;
235
276
  if (fromIndex >= this.l2Blocks.length) {
236
277
  return Promise.resolve([]);
237
278
  }
@@ -240,6 +281,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
240
281
  return Promise.resolve(this.l2Blocks.slice(fromIndex, toIndex));
241
282
  }
242
283
 
284
+ public async getBlockHeaders(from: number, limit: number): Promise<Header[]> {
285
+ const blocks = await this.getBlocks(from, limit);
286
+ return blocks.map(block => block.data.header);
287
+ }
288
+
243
289
  /**
244
290
  * Gets a tx effect.
245
291
  * @param txHash - The txHash of the tx effect.
@@ -297,9 +343,14 @@ export class MemoryArchiverStore implements ArchiverDataStore {
297
343
  logType: TLogType,
298
344
  ): Promise<L2BlockL2Logs<FromLogType<TLogType>>[]> {
299
345
  if (from < INITIAL_L2_BLOCK_NUM || limit < 1) {
300
- throw new Error(`Invalid limit: ${limit}`);
346
+ return Promise.resolve([]);
301
347
  }
302
- const logs = (() => {
348
+
349
+ if (from > this.l2Blocks.length) {
350
+ return Promise.resolve([]);
351
+ }
352
+
353
+ const logMap = (() => {
303
354
  switch (logType) {
304
355
  case LogType.ENCRYPTED:
305
356
  return this.encryptedLogsPerBlock;
@@ -309,14 +360,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
309
360
  default:
310
361
  return this.unencryptedLogsPerBlock;
311
362
  }
312
- })() as L2BlockL2Logs<FromLogType<TLogType>>[];
363
+ })() as Map<number, L2BlockL2Logs<FromLogType<TLogType>>>;
313
364
 
314
- if (from > logs.length) {
315
- return Promise.resolve([]);
316
- }
317
- const startIndex = from - INITIAL_L2_BLOCK_NUM;
365
+ const startIndex = from;
318
366
  const endIndex = startIndex + limit;
319
- return Promise.resolve(logs.slice(startIndex, endIndex));
367
+ const upper = Math.min(endIndex, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
368
+
369
+ const l = [];
370
+ for (let i = startIndex; i < upper; i++) {
371
+ const log = logMap.get(i);
372
+ if (log) {
373
+ l.push(log);
374
+ } else {
375
+ // I hate typescript sometimes
376
+ l.push(undefined as unknown as L2BlockL2Logs<FromLogType<TLogType>>);
377
+ }
378
+ }
379
+
380
+ return Promise.resolve(l);
320
381
  }
321
382
 
322
383
  /**
@@ -327,37 +388,37 @@ export class MemoryArchiverStore implements ArchiverDataStore {
327
388
  */
328
389
  getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
329
390
  let txHash: TxHash | undefined;
330
- let fromBlockIndex = 0;
331
- let toBlockIndex = this.unencryptedLogsPerBlock.length;
391
+ let fromBlock = 0;
392
+ let toBlock = this.l2Blocks.length + INITIAL_L2_BLOCK_NUM;
332
393
  let txIndexInBlock = 0;
333
394
  let logIndexInTx = 0;
334
395
 
335
396
  if (filter.afterLog) {
336
397
  // Continuation parameter is set --> tx hash is ignored
337
398
  if (filter.fromBlock == undefined || filter.fromBlock <= filter.afterLog.blockNumber) {
338
- fromBlockIndex = filter.afterLog.blockNumber - INITIAL_L2_BLOCK_NUM;
399
+ fromBlock = filter.afterLog.blockNumber;
339
400
  txIndexInBlock = filter.afterLog.txIndex;
340
401
  logIndexInTx = filter.afterLog.logIndex + 1; // We want to start from the next log
341
402
  } else {
342
- fromBlockIndex = filter.fromBlock - INITIAL_L2_BLOCK_NUM;
403
+ fromBlock = filter.fromBlock;
343
404
  }
344
405
  } else {
345
406
  txHash = filter.txHash;
346
407
 
347
408
  if (filter.fromBlock !== undefined) {
348
- fromBlockIndex = filter.fromBlock - INITIAL_L2_BLOCK_NUM;
409
+ fromBlock = filter.fromBlock;
349
410
  }
350
411
  }
351
412
 
352
413
  if (filter.toBlock !== undefined) {
353
- toBlockIndex = filter.toBlock - INITIAL_L2_BLOCK_NUM;
414
+ toBlock = filter.toBlock;
354
415
  }
355
416
 
356
417
  // Ensure the indices are within block array bounds
357
- fromBlockIndex = Math.max(fromBlockIndex, 0);
358
- toBlockIndex = Math.min(toBlockIndex, this.unencryptedLogsPerBlock.length);
418
+ fromBlock = Math.max(fromBlock, INITIAL_L2_BLOCK_NUM);
419
+ toBlock = Math.min(toBlock, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
359
420
 
360
- if (fromBlockIndex > this.unencryptedLogsPerBlock.length || toBlockIndex < fromBlockIndex || toBlockIndex <= 0) {
421
+ if (fromBlock > this.l2Blocks.length || toBlock < fromBlock || toBlock <= 0) {
361
422
  return Promise.resolve({
362
423
  logs: [],
363
424
  maxLogsHit: false,
@@ -368,27 +429,30 @@ export class MemoryArchiverStore implements ArchiverDataStore {
368
429
 
369
430
  const logs: ExtendedUnencryptedL2Log[] = [];
370
431
 
371
- for (; fromBlockIndex < toBlockIndex; fromBlockIndex++) {
372
- const block = this.l2Blocks[fromBlockIndex];
373
- const blockLogs = this.unencryptedLogsPerBlock[fromBlockIndex];
374
- for (; txIndexInBlock < blockLogs.txLogs.length; txIndexInBlock++) {
375
- const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs();
376
- for (; logIndexInTx < txLogs.length; logIndexInTx++) {
377
- const log = txLogs[logIndexInTx];
378
- if (
379
- (!txHash || block.data.body.txEffects[txIndexInBlock].txHash.equals(txHash)) &&
380
- (!contractAddress || log.contractAddress.equals(contractAddress))
381
- ) {
382
- logs.push(new ExtendedUnencryptedL2Log(new LogId(block.data.number, txIndexInBlock, logIndexInTx), log));
383
- if (logs.length === this.maxLogs) {
384
- return Promise.resolve({
385
- logs,
386
- maxLogsHit: true,
387
- });
432
+ for (; fromBlock < toBlock; fromBlock++) {
433
+ const block = this.l2Blocks[fromBlock - INITIAL_L2_BLOCK_NUM];
434
+ const blockLogs = this.unencryptedLogsPerBlock.get(fromBlock);
435
+
436
+ if (blockLogs) {
437
+ for (; txIndexInBlock < blockLogs.txLogs.length; txIndexInBlock++) {
438
+ const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs();
439
+ for (; logIndexInTx < txLogs.length; logIndexInTx++) {
440
+ const log = txLogs[logIndexInTx];
441
+ if (
442
+ (!txHash || block.data.body.txEffects[txIndexInBlock].txHash.equals(txHash)) &&
443
+ (!contractAddress || log.contractAddress.equals(contractAddress))
444
+ ) {
445
+ logs.push(new ExtendedUnencryptedL2Log(new LogId(block.data.number, txIndexInBlock, logIndexInTx), log));
446
+ if (logs.length === this.maxLogs) {
447
+ return Promise.resolve({
448
+ logs,
449
+ maxLogsHit: true,
450
+ });
451
+ }
388
452
  }
389
453
  }
454
+ logIndexInTx = 0;
390
455
  }
391
- logIndexInTx = 0;
392
456
  }
393
457
  txIndexInBlock = 0;
394
458
  }
@@ -414,9 +478,17 @@ export class MemoryArchiverStore implements ArchiverDataStore {
414
478
  return Promise.resolve(this.lastProvenL2BlockNumber);
415
479
  }
416
480
 
417
- public setProvenL2BlockNumber(l2BlockNumber: SingletonDataRetrieval<number>): Promise<void> {
418
- this.lastProvenL2BlockNumber = l2BlockNumber.retrievedData;
419
- this.lastL1BlockNewProvenLogs = l2BlockNumber.lastProcessedL1BlockNumber;
481
+ public getProvenL2EpochNumber(): Promise<number | undefined> {
482
+ return Promise.resolve(this.lastProvenL2EpochNumber);
483
+ }
484
+
485
+ public setProvenL2BlockNumber(l2BlockNumber: number): Promise<void> {
486
+ this.lastProvenL2BlockNumber = l2BlockNumber;
487
+ return Promise.resolve();
488
+ }
489
+
490
+ public setProvenL2EpochNumber(l2EpochNumber: number): Promise<void> {
491
+ this.lastProvenL2EpochNumber = l2EpochNumber;
420
492
  return Promise.resolve();
421
493
  }
422
494
 
@@ -434,7 +506,6 @@ export class MemoryArchiverStore implements ArchiverDataStore {
434
506
  return Promise.resolve({
435
507
  blocksSynchedTo: this.lastL1BlockNewBlocks,
436
508
  messagesSynchedTo: this.lastL1BlockNewMessages,
437
- provenLogsSynchedTo: this.lastL1BlockNewProvenLogs,
438
509
  });
439
510
  }
440
511
 
package/src/factory.ts CHANGED
@@ -1,5 +1,7 @@
1
+ import { type ContractClassPublic } from '@aztec/circuits.js';
1
2
  import { createDebugLogger } from '@aztec/foundation/log';
2
3
  import { createStore } from '@aztec/kv-store/utils';
4
+ import { getCanonicalProtocolContract, protocolContractNames } from '@aztec/protocol-contracts';
3
5
  import { type TelemetryClient } from '@aztec/telemetry-client';
4
6
  import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
5
7
 
@@ -16,8 +18,24 @@ export async function createArchiver(
16
18
  if (!config.archiverUrl) {
17
19
  const store = await createStore('archiver', config, createDebugLogger('aztec:archiver:lmdb'));
18
20
  const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
21
+ await initWithProtocolContracts(archiverStore);
19
22
  return Archiver.createAndSync(config, archiverStore, telemetry, opts.blockUntilSync);
20
23
  } else {
21
24
  return createArchiverClient(config.archiverUrl);
22
25
  }
23
26
  }
27
+
28
+ async function initWithProtocolContracts(store: KVArchiverDataStore) {
29
+ const blockNumber = 0;
30
+ for (const name of protocolContractNames) {
31
+ const contract = getCanonicalProtocolContract(name);
32
+ const contractClassPublic: ContractClassPublic = {
33
+ ...contract.contractClass,
34
+ privateFunctions: [],
35
+ unconstrainedFunctions: [],
36
+ };
37
+ await store.addContractArtifact(contract.address, contract.artifact);
38
+ await store.addContractClasses([contractClassPublic], blockNumber);
39
+ await store.addContractInstances([contract.instance], blockNumber);
40
+ }
41
+ }
package/src/index.ts CHANGED
@@ -25,6 +25,7 @@ async function main() {
25
25
  const config = getArchiverConfigFromEnv();
26
26
  const { l1RpcUrl: rpcUrl, l1Contracts } = config;
27
27
 
28
+ log.info(`Starting archiver in main(): ${JSON.stringify(config)}`);
28
29
  const publicClient = createPublicClient({
29
30
  chain: localhost,
30
31
  transport: http(rpcUrl),
@@ -0,0 +1,3 @@
1
+ export * from './mock_l2_block_source.js';
2
+ export * from './mock_l1_to_l2_message_source.js';
3
+ export * from './mock_archiver.js';
@@ -0,0 +1,55 @@
1
+ import { type L1ToL2MessageSource, type L2Block, type L2BlockSource } from '@aztec/circuit-types';
2
+ import { type Fr } from '@aztec/circuits.js';
3
+
4
+ import { MockL1ToL2MessageSource } from './mock_l1_to_l2_message_source.js';
5
+ import { MockL2BlockSource } from './mock_l2_block_source.js';
6
+
7
+ /**
8
+ * A mocked implementation of the archiver that implements L2BlockSource and L1ToL2MessageSource.
9
+ */
10
+ export class MockArchiver extends MockL2BlockSource implements L2BlockSource, L1ToL2MessageSource {
11
+ private messageSource = new MockL1ToL2MessageSource(0);
12
+
13
+ public setL1ToL2Messages(blockNumber: number, msgs: Fr[]) {
14
+ this.messageSource.setL1ToL2Messages(blockNumber, msgs);
15
+ }
16
+
17
+ getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]> {
18
+ return this.messageSource.getL1ToL2Messages(blockNumber);
19
+ }
20
+
21
+ getL1ToL2MessageIndex(_l1ToL2Message: Fr, _startIndex: bigint): Promise<bigint | undefined> {
22
+ return this.messageSource.getL1ToL2MessageIndex(_l1ToL2Message, _startIndex);
23
+ }
24
+ }
25
+
26
+ /**
27
+ * A mocked implementation of the archiver with a set of precomputed blocks and messages.
28
+ */
29
+ export class MockPrefilledArchiver extends MockArchiver {
30
+ private precomputed: L2Block[];
31
+
32
+ constructor(precomputed: L2Block[], messages: Fr[][]) {
33
+ super();
34
+ this.precomputed = precomputed.slice();
35
+ messages.forEach((msgs, i) => this.setL1ToL2Messages(i + 1, msgs));
36
+ }
37
+
38
+ public setPrefilledBlocks(blocks: L2Block[], messages: Fr[][]) {
39
+ for (const block of blocks) {
40
+ this.precomputed[block.number - 1] = block;
41
+ }
42
+ messages.forEach((msgs, i) => this.setL1ToL2Messages(blocks[i].number, msgs));
43
+ }
44
+
45
+ public override createBlocks(numBlocks: number) {
46
+ if (this.l2Blocks.length + numBlocks > this.precomputed.length) {
47
+ throw new Error(
48
+ `Not enough precomputed blocks to create ${numBlocks} more blocks (already at ${this.l2Blocks.length})`,
49
+ );
50
+ }
51
+
52
+ const fromBlock = this.l2Blocks.length;
53
+ this.addBlocks(this.precomputed.slice(fromBlock, fromBlock + numBlocks));
54
+ }
55
+ }
@@ -0,0 +1,31 @@
1
+ import { type L1ToL2MessageSource } from '@aztec/circuit-types';
2
+ import { type Fr } from '@aztec/circuits.js';
3
+
4
+ /**
5
+ * A mocked implementation of L1ToL2MessageSource to be used in tests.
6
+ */
7
+ export class MockL1ToL2MessageSource implements L1ToL2MessageSource {
8
+ private messagesPerBlock = new Map<number, Fr[]>();
9
+
10
+ constructor(private blockNumber: number) {}
11
+
12
+ public setL1ToL2Messages(blockNumber: number, msgs: Fr[]) {
13
+ this.messagesPerBlock.set(blockNumber, msgs);
14
+ }
15
+
16
+ public setBlockNumber(blockNumber: number) {
17
+ this.blockNumber = blockNumber;
18
+ }
19
+
20
+ getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]> {
21
+ return Promise.resolve(this.messagesPerBlock.get(Number(blockNumber)) ?? []);
22
+ }
23
+
24
+ getL1ToL2MessageIndex(_l1ToL2Message: Fr, _startIndex: bigint): Promise<bigint | undefined> {
25
+ throw new Error('Method not implemented.');
26
+ }
27
+
28
+ getBlockNumber(): Promise<number> {
29
+ return Promise.resolve(this.blockNumber);
30
+ }
31
+ }