@aztec/archiver 0.0.1-commit.d431d1c → 0.0.1-commit.e3c1de76

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 (75) hide show
  1. package/README.md +9 -0
  2. package/dest/archiver.d.ts +6 -5
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +34 -22
  5. package/dest/errors.d.ts +6 -1
  6. package/dest/errors.d.ts.map +1 -1
  7. package/dest/errors.js +8 -0
  8. package/dest/factory.d.ts +5 -2
  9. package/dest/factory.d.ts.map +1 -1
  10. package/dest/factory.js +7 -6
  11. package/dest/l1/bin/retrieve-calldata.js +2 -2
  12. package/dest/l1/data_retrieval.d.ts +1 -1
  13. package/dest/l1/data_retrieval.d.ts.map +1 -1
  14. package/dest/l1/data_retrieval.js +2 -2
  15. package/dest/l1/validate_trace.d.ts +6 -3
  16. package/dest/l1/validate_trace.d.ts.map +1 -1
  17. package/dest/l1/validate_trace.js +13 -9
  18. package/dest/modules/data_source_base.d.ts +17 -18
  19. package/dest/modules/data_source_base.d.ts.map +1 -1
  20. package/dest/modules/data_source_base.js +21 -52
  21. package/dest/modules/data_store_updater.d.ts +23 -19
  22. package/dest/modules/data_store_updater.d.ts.map +1 -1
  23. package/dest/modules/data_store_updater.js +47 -49
  24. package/dest/modules/instrumentation.d.ts +3 -3
  25. package/dest/modules/instrumentation.d.ts.map +1 -1
  26. package/dest/modules/instrumentation.js +17 -10
  27. package/dest/modules/l1_synchronizer.d.ts +1 -1
  28. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  29. package/dest/modules/l1_synchronizer.js +9 -10
  30. package/dest/store/block_store.d.ts +35 -21
  31. package/dest/store/block_store.d.ts.map +1 -1
  32. package/dest/store/block_store.js +81 -40
  33. package/dest/store/contract_class_store.d.ts +1 -1
  34. package/dest/store/contract_class_store.d.ts.map +1 -1
  35. package/dest/store/contract_class_store.js +11 -7
  36. package/dest/store/kv_archiver_store.d.ts +28 -24
  37. package/dest/store/kv_archiver_store.d.ts.map +1 -1
  38. package/dest/store/kv_archiver_store.js +20 -17
  39. package/dest/store/log_store.d.ts +4 -4
  40. package/dest/store/log_store.d.ts.map +1 -1
  41. package/dest/store/log_store.js +2 -2
  42. package/dest/test/fake_l1_state.d.ts +4 -4
  43. package/dest/test/fake_l1_state.d.ts.map +1 -1
  44. package/dest/test/index.js +3 -1
  45. package/dest/test/mock_archiver.js +1 -1
  46. package/dest/test/mock_l2_block_source.d.ts +20 -20
  47. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  48. package/dest/test/mock_l2_block_source.js +40 -41
  49. package/dest/test/mock_structs.d.ts +3 -2
  50. package/dest/test/mock_structs.d.ts.map +1 -1
  51. package/dest/test/mock_structs.js +11 -9
  52. package/dest/test/noop_l1_archiver.d.ts +23 -0
  53. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  54. package/dest/test/noop_l1_archiver.js +68 -0
  55. package/package.json +14 -13
  56. package/src/archiver.ts +46 -28
  57. package/src/errors.ts +12 -0
  58. package/src/factory.ts +7 -5
  59. package/src/l1/bin/retrieve-calldata.ts +7 -2
  60. package/src/l1/data_retrieval.ts +3 -3
  61. package/src/l1/validate_trace.ts +24 -6
  62. package/src/modules/data_source_base.ts +26 -77
  63. package/src/modules/data_store_updater.ts +59 -55
  64. package/src/modules/instrumentation.ts +17 -12
  65. package/src/modules/l1_synchronizer.ts +11 -12
  66. package/src/store/block_store.ts +107 -60
  67. package/src/store/contract_class_store.ts +11 -7
  68. package/src/store/kv_archiver_store.ts +36 -28
  69. package/src/store/log_store.ts +12 -12
  70. package/src/test/fake_l1_state.ts +2 -2
  71. package/src/test/index.ts +3 -0
  72. package/src/test/mock_archiver.ts +1 -1
  73. package/src/test/mock_l2_block_source.ts +54 -64
  74. package/src/test/mock_structs.ts +26 -10
  75. package/src/test/noop_l1_archiver.ts +109 -0
@@ -6,7 +6,7 @@ import { createLogger } from '@aztec/foundation/log';
6
6
  import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
7
7
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
8
8
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
9
- import { L2BlockHash, L2BlockNew } from '@aztec/stdlib/block';
9
+ import { BlockHash, L2Block } from '@aztec/stdlib/block';
10
10
  import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
11
11
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
12
12
  import {
@@ -59,7 +59,7 @@ export class LogStore {
59
59
  * @param block - The L2 block to extract logs from.
60
60
  * @returns An object containing the private and public tagged logs for the block.
61
61
  */
62
- #extractTaggedLogsFromBlock(block: L2BlockNew) {
62
+ #extractTaggedLogsFromBlock(block: L2Block) {
63
63
  // SiloedTag (as string) -> array of log buffers.
64
64
  const privateTaggedLogs = new Map<string, Buffer[]>();
65
65
  // "{contractAddress}_{tag}" (as string) -> array of log buffers.
@@ -120,7 +120,7 @@ export class LogStore {
120
120
  * @returns A map from tag (as string) to an array of serialized private logs belonging to that tag, and a map from
121
121
  * "{contractAddress}_{tag}" (as string) to an array of serialized public logs belonging to that key.
122
122
  */
123
- #extractTaggedLogs(blocks: L2BlockNew[]): {
123
+ #extractTaggedLogs(blocks: L2Block[]): {
124
124
  privateTaggedLogs: Map<string, Buffer[]>;
125
125
  publicTaggedLogs: Map<string, Buffer[]>;
126
126
  } {
@@ -146,7 +146,7 @@ export class LogStore {
146
146
  return { privateTaggedLogs, publicTaggedLogs };
147
147
  }
148
148
 
149
- async #addPrivateLogs(blocks: L2BlockNew[]): Promise<void> {
149
+ async #addPrivateLogs(blocks: L2Block[]): Promise<void> {
150
150
  const newBlocks = await filterAsync(
151
151
  blocks,
152
152
  async block => !(await this.#privateLogKeysByBlock.hasAsync(block.number)),
@@ -181,7 +181,7 @@ export class LogStore {
181
181
  }
182
182
  }
183
183
 
184
- async #addPublicLogs(blocks: L2BlockNew[]): Promise<void> {
184
+ async #addPublicLogs(blocks: L2Block[]): Promise<void> {
185
185
  const newBlocks = await filterAsync(
186
186
  blocks,
187
187
  async block => !(await this.#publicLogKeysByBlock.hasAsync(block.number)),
@@ -229,7 +229,7 @@ export class LogStore {
229
229
  }
230
230
  }
231
231
 
232
- async #addContractClassLogs(blocks: L2BlockNew[]): Promise<void> {
232
+ async #addContractClassLogs(blocks: L2Block[]): Promise<void> {
233
233
  const newBlocks = await filterAsync(
234
234
  blocks,
235
235
  async block => !(await this.#contractClassLogsByBlock.hasAsync(block.number)),
@@ -260,7 +260,7 @@ export class LogStore {
260
260
  * @param blocks - The blocks for which to add the logs.
261
261
  * @returns True if the operation is successful.
262
262
  */
263
- addLogs(blocks: L2BlockNew[]): Promise<boolean> {
263
+ addLogs(blocks: L2Block[]): Promise<boolean> {
264
264
  return this.db.transactionAsync(async () => {
265
265
  await Promise.all([
266
266
  this.#addPrivateLogs(blocks),
@@ -271,21 +271,21 @@ export class LogStore {
271
271
  });
272
272
  }
273
273
 
274
- #packWithBlockHash(blockHash: Fr, data: Buffer<ArrayBufferLike>[]): Buffer<ArrayBufferLike> {
274
+ #packWithBlockHash(blockHash: BlockHash, data: Buffer<ArrayBufferLike>[]): Buffer<ArrayBufferLike> {
275
275
  return Buffer.concat([blockHash.toBuffer(), ...data]);
276
276
  }
277
277
 
278
- #unpackBlockHash(reader: BufferReader): L2BlockHash {
278
+ #unpackBlockHash(reader: BufferReader): BlockHash {
279
279
  const blockHash = reader.remainingBytes() > 0 ? reader.readObject(Fr) : undefined;
280
280
 
281
281
  if (!blockHash) {
282
282
  throw new Error('Failed to read block hash from log entry buffer');
283
283
  }
284
284
 
285
- return L2BlockHash.fromField(blockHash);
285
+ return new BlockHash(blockHash);
286
286
  }
287
287
 
288
- deleteLogs(blocks: L2BlockNew[]): Promise<boolean> {
288
+ deleteLogs(blocks: L2Block[]): Promise<boolean> {
289
289
  return this.db.transactionAsync(async () => {
290
290
  await Promise.all(
291
291
  blocks.map(async block => {
@@ -543,7 +543,7 @@ export class LogStore {
543
543
  #accumulateLogs(
544
544
  results: (ExtendedContractClassLog | ExtendedPublicLog)[],
545
545
  blockNumber: number,
546
- blockHash: L2BlockHash,
546
+ blockHash: BlockHash,
547
547
  txIndex: number,
548
548
  txLogs: (ContractClassLog | PublicLog)[],
549
549
  filter: LogFilter = {},
@@ -10,7 +10,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
10
10
  import { EthAddress } from '@aztec/foundation/eth-address';
11
11
  import { createLogger } from '@aztec/foundation/log';
12
12
  import { RollupAbi } from '@aztec/l1-artifacts';
13
- import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2BlockNew } from '@aztec/stdlib/block';
13
+ import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2Block } from '@aztec/stdlib/block';
14
14
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
15
15
  import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
16
16
  import { InboxLeaf } from '@aztec/stdlib/messaging';
@@ -51,7 +51,7 @@ type AddCheckpointOptions = {
51
51
  /** Number of L2 blocks in the checkpoint. Default: 1 */
52
52
  numBlocks?: number;
53
53
  /** Or the actual blocks for the checkpoint */
54
- blocks?: L2BlockNew[];
54
+ blocks?: L2Block[];
55
55
  /** Number of transactions per block. Default: 4 */
56
56
  txsPerBlock?: number;
57
57
  /** Max number of effects per tx (for generating large blobs). Default: undefined */
package/src/test/index.ts CHANGED
@@ -2,3 +2,6 @@ export * from './mock_structs.js';
2
2
  export * from './mock_l2_block_source.js';
3
3
  export * from './mock_l1_to_l2_message_source.js';
4
4
  export * from './mock_archiver.js';
5
+ // NOTE: noop_l1_archiver.js is intentionally NOT exported here because it imports
6
+ // jest-mock-extended, which depends on @jest/globals and can only run inside Jest.
7
+ // Import it directly: import { NoopL1Archiver } from '@aztec/archiver/test/noop-l1';
@@ -57,7 +57,7 @@ export class MockPrefilledArchiver extends MockArchiver {
57
57
 
58
58
  const fromBlock = this.l2Blocks.length;
59
59
  // TODO: Add L2 blocks and checkpoints separately once archiver has the apis for that.
60
- this.addBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).flatMap(c => c.blocks));
60
+ this.addProposedBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).flatMap(c => c.blocks));
61
61
  return Promise.resolve();
62
62
  }
63
63
  }
@@ -8,9 +8,9 @@ import { createLogger } from '@aztec/foundation/log';
8
8
  import type { FunctionSelector } from '@aztec/stdlib/abi';
9
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
10
10
  import {
11
+ BlockHash,
11
12
  CheckpointedL2Block,
12
- L2BlockHash,
13
- L2BlockNew,
13
+ L2Block,
14
14
  type L2BlockSource,
15
15
  type L2Tips,
16
16
  type ValidateCheckpointResult,
@@ -18,14 +18,14 @@ import {
18
18
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
19
19
  import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
20
20
  import { EmptyL1RollupConstants, type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
21
- import { type BlockHeader, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
21
+ import { type BlockHeader, TxExecutionResult, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
22
22
  import type { UInt64 } from '@aztec/stdlib/types';
23
23
 
24
24
  /**
25
25
  * A mocked implementation of L2BlockSource to be used in tests.
26
26
  */
27
27
  export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
28
- protected l2Blocks: L2BlockNew[] = [];
28
+ protected l2Blocks: L2Block[] = [];
29
29
 
30
30
  private provenBlockNumber: number = 0;
31
31
  private finalizedBlockNumber: number = 0;
@@ -36,16 +36,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
36
36
  public async createBlocks(numBlocks: number) {
37
37
  for (let i = 0; i < numBlocks; i++) {
38
38
  const blockNum = this.l2Blocks.length + 1;
39
- const block = await L2BlockNew.random(BlockNumber(blockNum), { slotNumber: SlotNumber(blockNum) });
39
+ const block = await L2Block.random(BlockNumber(blockNum), { slotNumber: SlotNumber(blockNum) });
40
40
  this.l2Blocks.push(block);
41
41
  }
42
42
 
43
43
  this.log.verbose(`Created ${numBlocks} blocks in the mock L2 block source`);
44
44
  }
45
45
 
46
- public addBlocks(blocks: L2BlockNew[]) {
46
+ public addProposedBlocks(blocks: L2Block[]) {
47
47
  this.l2Blocks.push(...blocks);
48
- this.log.verbose(`Added ${blocks.length} blocks to the mock L2 block source`);
48
+ this.log.verbose(`Added ${blocks.length} proposed blocks to the mock L2 block source`);
49
49
  }
50
50
 
51
51
  public removeBlocks(numBlocks: number) {
@@ -96,6 +96,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
96
96
  return Promise.resolve(BlockNumber(this.provenBlockNumber));
97
97
  }
98
98
 
99
+ public getCheckpointedL2BlockNumber() {
100
+ return Promise.resolve(BlockNumber(this.checkpointedBlockNumber));
101
+ }
102
+
103
+ public getFinalizedL2BlockNumber() {
104
+ return Promise.resolve(BlockNumber(this.finalizedBlockNumber));
105
+ }
106
+
99
107
  public getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
100
108
  if (number > this.checkpointedBlockNumber) {
101
109
  return Promise.resolve(undefined);
@@ -105,7 +113,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
105
113
  return Promise.resolve(undefined);
106
114
  }
107
115
  const checkpointedBlock = new CheckpointedL2Block(
108
- CheckpointNumber(number),
116
+ CheckpointNumber.fromBlockNumber(number),
109
117
  block,
110
118
  new L1PublishedData(BigInt(number), BigInt(number), `0x${number.toString(16).padStart(64, '0')}`),
111
119
  [],
@@ -113,11 +121,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
113
121
  return Promise.resolve(checkpointedBlock);
114
122
  }
115
123
 
116
- public async getCheckpointedBlocks(
117
- from: BlockNumber,
118
- limit: number,
119
- _proven?: boolean,
120
- ): Promise<CheckpointedL2Block[]> {
124
+ public async getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
121
125
  const result: CheckpointedL2Block[] = [];
122
126
  for (let i = 0; i < limit; i++) {
123
127
  const blockNum = from + i;
@@ -137,7 +141,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
137
141
  * @param number - The block number to return (inclusive).
138
142
  * @returns The requested L2 block.
139
143
  */
140
- public getBlock(number: number): Promise<L2BlockNew | undefined> {
144
+ public getBlock(number: number): Promise<L2Block | undefined> {
141
145
  const block = this.l2Blocks[number - 1];
142
146
  return Promise.resolve(block);
143
147
  }
@@ -147,7 +151,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
147
151
  * @param number - The block number to return.
148
152
  * @returns The requested L2 block.
149
153
  */
150
- public getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
154
+ public getL2Block(number: BlockNumber): Promise<L2Block | undefined> {
151
155
  const block = this.l2Blocks[number - 1];
152
156
  return Promise.resolve(block);
153
157
  }
@@ -158,20 +162,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
158
162
  * @param limit - The maximum number of blocks to return.
159
163
  * @returns The requested mocked L2 blocks.
160
164
  */
161
- public getBlocks(from: number, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
162
- return Promise.resolve(
163
- this.l2Blocks
164
- .slice(from - 1, from - 1 + limit)
165
- .filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber),
166
- );
165
+ public getBlocks(from: number, limit: number): Promise<L2Block[]> {
166
+ return Promise.resolve(this.l2Blocks.slice(from - 1, from - 1 + limit));
167
167
  }
168
168
 
169
- public getPublishedCheckpoints(from: CheckpointNumber, limit: number) {
169
+ public getCheckpoints(from: CheckpointNumber, limit: number) {
170
170
  // TODO(mbps): Implement this properly. This only works when we have one block per checkpoint.
171
171
  const blocks = this.l2Blocks.slice(from - 1, from - 1 + limit);
172
172
  return Promise.all(
173
173
  blocks.map(async block => {
174
- // Create a checkpoint from the block - manually construct since L2BlockNew doesn't have toCheckpoint()
174
+ // Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
175
175
  const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
176
176
  checkpoint.blocks = [block];
177
177
  return new PublishedCheckpoint(
@@ -189,39 +189,18 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
189
189
  if (!block) {
190
190
  return undefined;
191
191
  }
192
- // Create a checkpoint from the block - manually construct since L2BlockNew doesn't have toCheckpoint()
192
+ // Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
193
193
  const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
194
194
  checkpoint.blocks = [block];
195
195
  return checkpoint;
196
196
  }
197
197
 
198
- public getPublishedBlocks(from: number, limit: number, proven?: boolean): Promise<CheckpointedL2Block[]> {
199
- const blocks = this.l2Blocks
200
- .slice(from - 1, from - 1 + limit)
201
- .filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber);
202
- return Promise.resolve(
203
- blocks.map(block =>
204
- CheckpointedL2Block.fromFields({
205
- checkpointNumber: CheckpointNumber(block.number),
206
- block,
207
- l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
208
- attestations: [],
209
- }),
210
- ),
211
- );
212
- }
213
-
214
- getL2BlocksNew(from: BlockNumber, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
215
- // getBlocks already returns L2BlockNew[], so just return directly
216
- return this.getBlocks(from, limit, proven);
217
- }
218
-
219
- public async getPublishedBlockByHash(blockHash: Fr): Promise<CheckpointedL2Block | undefined> {
198
+ public async getCheckpointedBlockByHash(blockHash: BlockHash): Promise<CheckpointedL2Block | undefined> {
220
199
  for (const block of this.l2Blocks) {
221
200
  const hash = await block.hash();
222
201
  if (hash.equals(blockHash)) {
223
202
  return CheckpointedL2Block.fromFields({
224
- checkpointNumber: CheckpointNumber(block.number),
203
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
225
204
  block,
226
205
  l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
227
206
  attestations: [],
@@ -231,14 +210,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
231
210
  return undefined;
232
211
  }
233
212
 
234
- public getPublishedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
213
+ public getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
235
214
  const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
236
215
  if (!block) {
237
216
  return Promise.resolve(undefined);
238
217
  }
239
218
  return Promise.resolve(
240
219
  CheckpointedL2Block.fromFields({
241
- checkpointNumber: CheckpointNumber(block.number),
220
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
242
221
  block,
243
222
  l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
244
223
  attestations: [],
@@ -246,7 +225,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
246
225
  );
247
226
  }
248
227
 
249
- public async getL2BlockNewByHash(blockHash: Fr): Promise<L2BlockNew | undefined> {
228
+ public async getL2BlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
250
229
  for (const block of this.l2Blocks) {
251
230
  const hash = await block.hash();
252
231
  if (hash.equals(blockHash)) {
@@ -256,12 +235,12 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
256
235
  return undefined;
257
236
  }
258
237
 
259
- public getL2BlockNewByArchive(archive: Fr): Promise<L2BlockNew | undefined> {
238
+ public getL2BlockByArchive(archive: Fr): Promise<L2Block | undefined> {
260
239
  const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
261
240
  return Promise.resolve(block);
262
241
  }
263
242
 
264
- public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
243
+ public async getBlockHeaderByHash(blockHash: BlockHash): Promise<BlockHeader | undefined> {
265
244
  for (const block of this.l2Blocks) {
266
245
  const hash = await block.hash();
267
246
  if (hash.equals(blockHash)) {
@@ -288,7 +267,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
288
267
  const slot = b.header.globalVariables.slotNumber;
289
268
  return slot >= start && slot <= end;
290
269
  });
291
- // Create checkpoints from blocks - manually construct since L2BlockNew doesn't have toCheckpoint()
270
+ // Create checkpoints from blocks - manually construct since L2Block doesn't have toCheckpoint()
292
271
  return Promise.all(
293
272
  blocks.map(async block => {
294
273
  const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
@@ -298,24 +277,33 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
298
277
  );
299
278
  }
300
279
 
301
- getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2BlockNew[]> {
280
+ getCheckpointedBlocksForEpoch(epochNumber: EpochNumber): Promise<CheckpointedL2Block[]> {
302
281
  const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
303
282
  const [start, end] = getSlotRangeForEpoch(epochNumber, { epochDuration });
304
283
  const blocks = this.l2Blocks.filter(b => {
305
284
  const slot = b.header.globalVariables.slotNumber;
306
285
  return slot >= start && slot <= end;
307
286
  });
308
- return Promise.resolve(blocks);
287
+ return Promise.resolve(
288
+ blocks.map(block =>
289
+ CheckpointedL2Block.fromFields({
290
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
291
+ block,
292
+ l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
293
+ attestations: [],
294
+ }),
295
+ ),
296
+ );
309
297
  }
310
298
 
311
- getBlocksForSlot(slotNumber: SlotNumber): Promise<L2BlockNew[]> {
299
+ getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
312
300
  const blocks = this.l2Blocks.filter(b => b.header.globalVariables.slotNumber === slotNumber);
313
301
  return Promise.resolve(blocks);
314
302
  }
315
303
 
316
- async getBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
317
- const blocks = await this.getBlocksForEpoch(epochNumber);
318
- return blocks.map(b => b.header);
304
+ async getCheckpointedBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
305
+ const checkpointedBlocks = await this.getCheckpointedBlocksForEpoch(epochNumber);
306
+ return checkpointedBlocks.map(b => b.block.header);
319
307
  }
320
308
 
321
309
  /**
@@ -334,7 +322,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
334
322
  return {
335
323
  data: txEffect,
336
324
  l2BlockNumber: block.number,
337
- l2BlockHash: L2BlockHash.fromField(await block.hash()),
325
+ l2BlockHash: await block.hash(),
338
326
  txIndexInBlock: block.body.txEffects.indexOf(txEffect),
339
327
  };
340
328
  }
@@ -348,12 +336,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
348
336
  for (const block of this.l2Blocks) {
349
337
  for (const txEffect of block.body.txEffects) {
350
338
  if (txEffect.txHash.equals(txHash)) {
339
+ // In mock, assume all txs are checkpointed with successful execution
351
340
  return new TxReceipt(
352
341
  txHash,
353
- TxStatus.SUCCESS,
354
- '',
342
+ TxStatus.CHECKPOINTED,
343
+ TxExecutionResult.SUCCESS,
344
+ undefined,
355
345
  txEffect.transactionFee.toBigInt(),
356
- L2BlockHash.fromField(await block.hash()),
346
+ await block.hash(),
357
347
  block.number,
358
348
  );
359
349
  }
@@ -394,7 +384,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
394
384
 
395
385
  const makeTipId = (blockId: typeof latestBlockId) => ({
396
386
  block: blockId,
397
- checkpoint: { number: CheckpointNumber(blockId.number), hash: blockId.hash },
387
+ checkpoint: { number: CheckpointNumber.fromBlockNumber(blockId.number), hash: blockId.hash },
398
388
  });
399
389
 
400
390
  return {
@@ -12,7 +12,7 @@ import type { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'
12
12
  import { Fr } from '@aztec/foundation/curves/bn254';
13
13
  import { EthAddress } from '@aztec/foundation/eth-address';
14
14
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
15
- import { CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
15
+ import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
16
16
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
17
17
  import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs';
18
18
  import { InboxLeaf } from '@aztec/stdlib/messaging';
@@ -46,24 +46,40 @@ export function makeInboxMessage(
46
46
  }
47
47
 
48
48
  export function makeInboxMessages(
49
- count: number,
49
+ totalCount: number,
50
50
  opts: {
51
51
  initialHash?: Buffer16;
52
52
  initialCheckpointNumber?: CheckpointNumber;
53
+ messagesPerCheckpoint?: number;
53
54
  overrideFn?: (msg: InboxMessage, index: number) => InboxMessage;
54
55
  } = {},
55
56
  ): InboxMessage[] {
56
- const { initialHash = Buffer16.ZERO, overrideFn = msg => msg, initialCheckpointNumber = 1 } = opts;
57
+ const {
58
+ initialHash = Buffer16.ZERO,
59
+ overrideFn = msg => msg,
60
+ initialCheckpointNumber = CheckpointNumber(1),
61
+ messagesPerCheckpoint = 1,
62
+ } = opts;
63
+
57
64
  const messages: InboxMessage[] = [];
58
65
  let rollingHash = initialHash;
59
- for (let i = 0; i < count; i++) {
66
+ for (let i = 0; i < totalCount; i++) {
67
+ const msgIndex = i % messagesPerCheckpoint;
68
+ const checkpointNumber = CheckpointNumber.fromBigInt(
69
+ BigInt(initialCheckpointNumber) + BigInt(i) / BigInt(messagesPerCheckpoint),
70
+ );
60
71
  const leaf = Fr.random();
61
- const checkpointNumber = CheckpointNumber(i + initialCheckpointNumber);
62
- const message = overrideFn(makeInboxMessage(rollingHash, { leaf, checkpointNumber }), i);
72
+ const message = overrideFn(
73
+ makeInboxMessage(rollingHash, {
74
+ leaf,
75
+ checkpointNumber,
76
+ index: InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(msgIndex),
77
+ }),
78
+ i,
79
+ );
63
80
  rollingHash = message.rollingHash;
64
81
  messages.push(message);
65
82
  }
66
-
67
83
  return messages;
68
84
  }
69
85
 
@@ -268,8 +284,8 @@ export async function makeCheckpointWithLogs(
268
284
  ): Promise<PublishedCheckpoint> {
269
285
  const { previousArchive, numTxsPerBlock = 4, privateLogs, publicLogs } = options;
270
286
 
271
- const block = await L2BlockNew.random(BlockNumber(blockNumber), {
272
- checkpointNumber: CheckpointNumber(blockNumber),
287
+ const block = await L2Block.random(BlockNumber(blockNumber), {
288
+ checkpointNumber: CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)),
273
289
  indexWithinCheckpoint: IndexWithinCheckpoint(0),
274
290
  state: makeStateForBlock(blockNumber, numTxsPerBlock),
275
291
  ...(previousArchive ? { lastArchive: previousArchive } : {}),
@@ -289,7 +305,7 @@ export async function makeCheckpointWithLogs(
289
305
  AppendOnlyTreeSnapshot.random(),
290
306
  CheckpointHeader.random(),
291
307
  [block],
292
- CheckpointNumber(blockNumber),
308
+ CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)),
293
309
  );
294
310
  return makePublishedCheckpoint(checkpoint, blockNumber);
295
311
  }
@@ -0,0 +1,109 @@
1
+ import type { BlobClientInterface } from '@aztec/blob-client/client';
2
+ import type { RollupContract } from '@aztec/ethereum/contracts';
3
+ import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
4
+ import { Buffer32 } from '@aztec/foundation/buffer';
5
+ import { Fr } from '@aztec/foundation/curves/bn254';
6
+ import { EthAddress } from '@aztec/foundation/eth-address';
7
+ import type { FunctionsOf } from '@aztec/foundation/types';
8
+ import type { ArchiverEmitter } from '@aztec/stdlib/block';
9
+ import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
10
+ import { type TelemetryClient, type Tracer, getTelemetryClient } from '@aztec/telemetry-client';
11
+
12
+ import { mock } from 'jest-mock-extended';
13
+ import { EventEmitter } from 'node:events';
14
+
15
+ import { Archiver } from '../archiver.js';
16
+ import { ArchiverInstrumentation } from '../modules/instrumentation.js';
17
+ import type { ArchiverL1Synchronizer } from '../modules/l1_synchronizer.js';
18
+ import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
19
+
20
+ /** Noop L1 synchronizer for testing without L1 connectivity. */
21
+ class NoopL1Synchronizer implements FunctionsOf<ArchiverL1Synchronizer> {
22
+ public readonly tracer: Tracer;
23
+
24
+ constructor(tracer: Tracer) {
25
+ this.tracer = tracer;
26
+ }
27
+
28
+ setConfig(_config: unknown) {}
29
+ getL1BlockNumber(): bigint | undefined {
30
+ return 0n;
31
+ }
32
+ getL1Timestamp(): bigint | undefined {
33
+ return 0n;
34
+ }
35
+ testEthereumNodeSynced(): Promise<void> {
36
+ return Promise.resolve();
37
+ }
38
+ syncFromL1(_initialSyncComplete: boolean): Promise<void> {
39
+ return Promise.resolve();
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Archiver with mocked L1 connectivity for testing.
45
+ * Uses mock L1 clients and a noop synchronizer, enabling tests that
46
+ * don't require real Ethereum connectivity.
47
+ */
48
+ export class NoopL1Archiver extends Archiver {
49
+ constructor(
50
+ dataStore: KVArchiverDataStore,
51
+ l1Constants: L1RollupConstants & { genesisArchiveRoot: Fr },
52
+ instrumentation: ArchiverInstrumentation,
53
+ ) {
54
+ // Create mocks for L1 clients
55
+ const publicClient = mock<ViemPublicClient>();
56
+ const debugClient = mock<ViemPublicDebugClient>();
57
+ const rollup = mock<RollupContract>();
58
+ const blobClient = mock<BlobClientInterface>();
59
+
60
+ // Mock methods called during start()
61
+ blobClient.testSources.mockResolvedValue();
62
+ publicClient.getBlockNumber.mockResolvedValue(1n);
63
+
64
+ const events = new EventEmitter() as ArchiverEmitter;
65
+ const synchronizer = new NoopL1Synchronizer(instrumentation.tracer);
66
+
67
+ super(
68
+ publicClient,
69
+ debugClient,
70
+ rollup,
71
+ {
72
+ registryAddress: EthAddress.ZERO,
73
+ governanceProposerAddress: EthAddress.ZERO,
74
+ slashFactoryAddress: EthAddress.ZERO,
75
+ slashingProposerAddress: EthAddress.ZERO,
76
+ },
77
+ dataStore,
78
+ {
79
+ pollingIntervalMs: 1000,
80
+ batchSize: 100,
81
+ skipValidateCheckpointAttestations: true,
82
+ maxAllowedEthClientDriftSeconds: 300,
83
+ ethereumAllowNoDebugHosts: true, // Skip trace validation
84
+ },
85
+ blobClient,
86
+ instrumentation,
87
+ { ...l1Constants, l1StartBlockHash: Buffer32.random() },
88
+ synchronizer as ArchiverL1Synchronizer,
89
+ events,
90
+ );
91
+ }
92
+
93
+ /** Override start to skip L1 validation checks. */
94
+ public override start(_blockUntilSynced?: boolean): Promise<void> {
95
+ // Just start the running promise without L1 checks
96
+ this.runningPromise.start();
97
+ return Promise.resolve();
98
+ }
99
+ }
100
+
101
+ /** Creates an archiver with mocked L1 connectivity for testing. */
102
+ export async function createNoopL1Archiver(
103
+ dataStore: KVArchiverDataStore,
104
+ l1Constants: L1RollupConstants & { genesisArchiveRoot: Fr },
105
+ telemetry: TelemetryClient = getTelemetryClient(),
106
+ ): Promise<NoopL1Archiver> {
107
+ const instrumentation = await ArchiverInstrumentation.new(telemetry, () => dataStore.estimateSize());
108
+ return new NoopL1Archiver(dataStore, l1Constants, instrumentation);
109
+ }