@aztec/archiver 0.0.1-commit.9ef841308 → 0.0.1-commit.a89ec08

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 (65) hide show
  1. package/dest/archiver.d.ts +2 -1
  2. package/dest/archiver.d.ts.map +1 -1
  3. package/dest/archiver.js +1 -0
  4. package/dest/config.d.ts +3 -3
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +1 -2
  7. package/dest/errors.d.ts +1 -15
  8. package/dest/errors.d.ts.map +1 -1
  9. package/dest/errors.js +0 -18
  10. package/dest/factory.d.ts +2 -2
  11. package/dest/factory.d.ts.map +1 -1
  12. package/dest/factory.js +3 -1
  13. package/dest/l1/calldata_retriever.d.ts +1 -1
  14. package/dest/l1/calldata_retriever.d.ts.map +1 -1
  15. package/dest/l1/calldata_retriever.js +1 -2
  16. package/dest/l1/data_retrieval.d.ts +3 -6
  17. package/dest/l1/data_retrieval.d.ts.map +1 -1
  18. package/dest/l1/data_retrieval.js +6 -12
  19. package/dest/modules/data_source_base.d.ts +3 -3
  20. package/dest/modules/data_source_base.d.ts.map +1 -1
  21. package/dest/modules/data_source_base.js +4 -4
  22. package/dest/modules/data_store_updater.d.ts +6 -3
  23. package/dest/modules/data_store_updater.d.ts.map +1 -1
  24. package/dest/modules/data_store_updater.js +56 -5
  25. package/dest/modules/instrumentation.d.ts +1 -12
  26. package/dest/modules/instrumentation.d.ts.map +1 -1
  27. package/dest/modules/instrumentation.js +0 -10
  28. package/dest/modules/l1_synchronizer.d.ts +1 -1
  29. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  30. package/dest/modules/l1_synchronizer.js +13 -18
  31. package/dest/store/block_store.d.ts +2 -1
  32. package/dest/store/block_store.d.ts.map +1 -1
  33. package/dest/store/block_store.js +50 -5
  34. package/dest/store/contract_class_store.d.ts +3 -2
  35. package/dest/store/contract_class_store.d.ts.map +1 -1
  36. package/dest/store/contract_class_store.js +65 -1
  37. package/dest/store/kv_archiver_store.d.ts +8 -10
  38. package/dest/store/kv_archiver_store.d.ts.map +1 -1
  39. package/dest/store/kv_archiver_store.js +8 -10
  40. package/dest/store/log_store.d.ts +3 -6
  41. package/dest/store/log_store.d.ts.map +1 -1
  42. package/dest/store/log_store.js +6 -45
  43. package/dest/store/message_store.d.ts +1 -5
  44. package/dest/store/message_store.d.ts.map +1 -1
  45. package/dest/store/message_store.js +0 -13
  46. package/dest/test/fake_l1_state.d.ts +8 -1
  47. package/dest/test/fake_l1_state.d.ts.map +1 -1
  48. package/dest/test/fake_l1_state.js +16 -11
  49. package/package.json +13 -13
  50. package/src/archiver.ts +1 -0
  51. package/src/config.ts +1 -8
  52. package/src/errors.ts +0 -30
  53. package/src/factory.ts +3 -1
  54. package/src/l1/calldata_retriever.ts +1 -2
  55. package/src/l1/data_retrieval.ts +9 -17
  56. package/src/modules/data_source_base.ts +3 -8
  57. package/src/modules/data_store_updater.ts +82 -3
  58. package/src/modules/instrumentation.ts +0 -20
  59. package/src/modules/l1_synchronizer.ts +25 -29
  60. package/src/store/block_store.ts +62 -5
  61. package/src/store/contract_class_store.ts +103 -1
  62. package/src/store/kv_archiver_store.ts +15 -12
  63. package/src/store/log_store.ts +15 -60
  64. package/src/store/message_store.ts +0 -19
  65. package/src/test/fake_l1_state.ts +20 -15
@@ -2,7 +2,14 @@ import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { toArray } from '@aztec/foundation/iterable';
3
3
  import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/serialize';
4
4
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
5
- import type { ContractClassPublic, ContractClassPublicWithBlockNumber } from '@aztec/stdlib/contract';
5
+ import { FunctionSelector } from '@aztec/stdlib/abi';
6
+ import type {
7
+ ContractClassPublic,
8
+ ContractClassPublicWithBlockNumber,
9
+ ExecutablePrivateFunctionWithMembershipProof,
10
+ UtilityFunctionWithMembershipProof,
11
+ } from '@aztec/stdlib/contract';
12
+ import { Vector } from '@aztec/stdlib/types';
6
13
 
7
14
  /**
8
15
  * LMDB-based contract class storage for the archiver.
@@ -57,6 +64,37 @@ export class ContractClassStore {
57
64
  async getContractClassIds(): Promise<Fr[]> {
58
65
  return (await toArray(this.#contractClasses.keysAsync())).map(key => Fr.fromHexString(key));
59
66
  }
67
+
68
+ async addFunctions(
69
+ contractClassId: Fr,
70
+ newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
71
+ newUtilityFunctions: UtilityFunctionWithMembershipProof[],
72
+ ): Promise<boolean> {
73
+ await this.db.transactionAsync(async () => {
74
+ const existingClassBuffer = await this.#contractClasses.getAsync(contractClassId.toString());
75
+ if (!existingClassBuffer) {
76
+ throw new Error(`Unknown contract class ${contractClassId} when adding private functions to store`);
77
+ }
78
+
79
+ const existingClass = deserializeContractClassPublic(existingClassBuffer);
80
+ const { privateFunctions: existingPrivateFns, utilityFunctions: existingUtilityFns } = existingClass;
81
+
82
+ const updatedClass: Omit<ContractClassPublicWithBlockNumber, 'id'> = {
83
+ ...existingClass,
84
+ privateFunctions: [
85
+ ...existingPrivateFns,
86
+ ...newPrivateFunctions.filter(newFn => !existingPrivateFns.some(f => f.selector.equals(newFn.selector))),
87
+ ],
88
+ utilityFunctions: [
89
+ ...existingUtilityFns,
90
+ ...newUtilityFunctions.filter(newFn => !existingUtilityFns.some(f => f.selector.equals(newFn.selector))),
91
+ ],
92
+ };
93
+ await this.#contractClasses.set(contractClassId.toString(), serializeContractClassPublic(updatedClass));
94
+ });
95
+
96
+ return true;
97
+ }
60
98
  }
61
99
 
62
100
  function serializeContractClassPublic(contractClass: Omit<ContractClassPublicWithBlockNumber, 'id'>): Buffer {
@@ -64,19 +102,83 @@ function serializeContractClassPublic(contractClass: Omit<ContractClassPublicWit
64
102
  contractClass.l2BlockNumber,
65
103
  numToUInt8(contractClass.version),
66
104
  contractClass.artifactHash,
105
+ contractClass.privateFunctions.length,
106
+ contractClass.privateFunctions.map(serializePrivateFunction),
107
+ contractClass.utilityFunctions.length,
108
+ contractClass.utilityFunctions.map(serializeUtilityFunction),
67
109
  contractClass.packedBytecode.length,
68
110
  contractClass.packedBytecode,
69
111
  contractClass.privateFunctionsRoot,
70
112
  );
71
113
  }
72
114
 
115
+ function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipProof): Buffer {
116
+ return serializeToBuffer(
117
+ fn.selector,
118
+ fn.vkHash,
119
+ fn.bytecode.length,
120
+ fn.bytecode,
121
+ fn.functionMetadataHash,
122
+ fn.artifactMetadataHash,
123
+ fn.utilityFunctionsTreeRoot,
124
+ new Vector(fn.privateFunctionTreeSiblingPath),
125
+ fn.privateFunctionTreeLeafIndex,
126
+ new Vector(fn.artifactTreeSiblingPath),
127
+ fn.artifactTreeLeafIndex,
128
+ );
129
+ }
130
+
131
+ function serializeUtilityFunction(fn: UtilityFunctionWithMembershipProof): Buffer {
132
+ return serializeToBuffer(
133
+ fn.selector,
134
+ fn.bytecode.length,
135
+ fn.bytecode,
136
+ fn.functionMetadataHash,
137
+ fn.artifactMetadataHash,
138
+ fn.privateFunctionsArtifactTreeRoot,
139
+ new Vector(fn.artifactTreeSiblingPath),
140
+ fn.artifactTreeLeafIndex,
141
+ );
142
+ }
143
+
73
144
  function deserializeContractClassPublic(buffer: Buffer): Omit<ContractClassPublicWithBlockNumber, 'id'> {
74
145
  const reader = BufferReader.asReader(buffer);
75
146
  return {
76
147
  l2BlockNumber: reader.readNumber(),
77
148
  version: reader.readUInt8() as 1,
78
149
  artifactHash: reader.readObject(Fr),
150
+ privateFunctions: reader.readVector({ fromBuffer: deserializePrivateFunction }),
151
+ utilityFunctions: reader.readVector({ fromBuffer: deserializeUtilityFunction }),
79
152
  packedBytecode: reader.readBuffer(),
80
153
  privateFunctionsRoot: reader.readObject(Fr),
81
154
  };
82
155
  }
156
+
157
+ function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePrivateFunctionWithMembershipProof {
158
+ const reader = BufferReader.asReader(buffer);
159
+ return {
160
+ selector: reader.readObject(FunctionSelector),
161
+ vkHash: reader.readObject(Fr),
162
+ bytecode: reader.readBuffer(),
163
+ functionMetadataHash: reader.readObject(Fr),
164
+ artifactMetadataHash: reader.readObject(Fr),
165
+ utilityFunctionsTreeRoot: reader.readObject(Fr),
166
+ privateFunctionTreeSiblingPath: reader.readVector(Fr),
167
+ privateFunctionTreeLeafIndex: reader.readNumber(),
168
+ artifactTreeSiblingPath: reader.readVector(Fr),
169
+ artifactTreeLeafIndex: reader.readNumber(),
170
+ };
171
+ }
172
+
173
+ function deserializeUtilityFunction(buffer: Buffer | BufferReader): UtilityFunctionWithMembershipProof {
174
+ const reader = BufferReader.asReader(buffer);
175
+ return {
176
+ selector: reader.readObject(FunctionSelector),
177
+ bytecode: reader.readBuffer(),
178
+ functionMetadataHash: reader.readObject(Fr),
179
+ artifactMetadataHash: reader.readObject(Fr),
180
+ privateFunctionsArtifactTreeRoot: reader.readObject(Fr),
181
+ artifactTreeSiblingPath: reader.readVector(Fr),
182
+ artifactTreeLeafIndex: reader.readNumber(),
183
+ };
184
+ }
@@ -20,6 +20,8 @@ import type {
20
20
  ContractDataSource,
21
21
  ContractInstanceUpdateWithAddress,
22
22
  ContractInstanceWithAddress,
23
+ ExecutablePrivateFunctionWithMembershipProof,
24
+ UtilityFunctionWithMembershipProof,
23
25
  } from '@aztec/stdlib/contract';
24
26
  import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
25
27
  import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
@@ -36,7 +38,7 @@ import { ContractInstanceStore } from './contract_instance_store.js';
36
38
  import { LogStore } from './log_store.js';
37
39
  import { MessageStore } from './message_store.js';
38
40
 
39
- export const ARCHIVER_DB_VERSION = 6;
41
+ export const ARCHIVER_DB_VERSION = 5;
40
42
  export const MAX_FUNCTION_SIGNATURES = 1000;
41
43
  export const MAX_FUNCTION_NAME_LEN = 256;
42
44
 
@@ -188,6 +190,15 @@ export class KVArchiverDataStore implements ContractDataSource {
188
190
  return this.#contractClassStore.getBytecodeCommitment(contractClassId);
189
191
  }
190
192
 
193
+ /** Adds private functions to a contract class. */
194
+ addFunctions(
195
+ contractClassId: Fr,
196
+ privateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
197
+ utilityFunctions: UtilityFunctionWithMembershipProof[],
198
+ ): Promise<boolean> {
199
+ return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
200
+ }
201
+
191
202
  /**
192
203
  * Add new contract instances from an L2 block to the store's list.
193
204
  * @param data - List of contract instances to be added.
@@ -459,11 +470,10 @@ export class KVArchiverDataStore implements ContractDataSource {
459
470
  * array implies no logs match that tag.
460
471
  * @param tags - The tags to search for.
461
472
  * @param page - The page number (0-indexed) for pagination. Returns at most 10 logs per tag per page.
462
- * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
463
473
  */
464
- getPrivateLogsByTags(tags: SiloedTag[], page?: number, upToBlockNumber?: BlockNumber): Promise<TxScopedL2Log[][]> {
474
+ getPrivateLogsByTags(tags: SiloedTag[], page?: number): Promise<TxScopedL2Log[][]> {
465
475
  try {
466
- return this.#logStore.getPrivateLogsByTags(tags, page, upToBlockNumber);
476
+ return this.#logStore.getPrivateLogsByTags(tags, page);
467
477
  } catch (err) {
468
478
  return Promise.reject(err);
469
479
  }
@@ -475,16 +485,14 @@ export class KVArchiverDataStore implements ContractDataSource {
475
485
  * @param contractAddress - The contract address to search logs for.
476
486
  * @param tags - The tags to search for.
477
487
  * @param page - The page number (0-indexed) for pagination. Returns at most 10 logs per tag per page.
478
- * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
479
488
  */
480
489
  getPublicLogsByTagsFromContract(
481
490
  contractAddress: AztecAddress,
482
491
  tags: Tag[],
483
492
  page?: number,
484
- upToBlockNumber?: BlockNumber,
485
493
  ): Promise<TxScopedL2Log[][]> {
486
494
  try {
487
- return this.#logStore.getPublicLogsByTagsFromContract(contractAddress, tags, page, upToBlockNumber);
495
+ return this.#logStore.getPublicLogsByTagsFromContract(contractAddress, tags, page);
488
496
  } catch (err) {
489
497
  return Promise.reject(err);
490
498
  }
@@ -591,11 +599,6 @@ export class KVArchiverDataStore implements ContractDataSource {
591
599
  return this.#messageStore.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
592
600
  }
593
601
 
594
- /** Persists the inbox tree-in-progress checkpoint number from L1 state. */
595
- public setInboxTreeInProgress(value: bigint): Promise<void> {
596
- return this.#messageStore.setInboxTreeInProgress(value);
597
- }
598
-
599
602
  /** Returns an async iterator to all L1 to L2 messages on the range. */
600
603
  public iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
601
604
  return this.#messageStore.iterateL1ToL2Messages(range);
@@ -22,7 +22,6 @@ import {
22
22
  } from '@aztec/stdlib/logs';
23
23
  import { TxHash } from '@aztec/stdlib/tx';
24
24
 
25
- import { OutOfOrderLogInsertionError } from '../errors.js';
26
25
  import type { BlockStore } from './block_store.js';
27
26
 
28
27
  /**
@@ -166,21 +165,10 @@ export class LogStore {
166
165
 
167
166
  for (const taggedLogBuffer of currentPrivateTaggedLogs) {
168
167
  if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
169
- const newLogs = privateTaggedLogs.get(taggedLogBuffer.tag)!;
170
- if (newLogs.length === 0) {
171
- continue;
172
- }
173
- const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1)!);
174
- const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
175
- if (lastExisting.blockNumber > firstNew.blockNumber) {
176
- throw new OutOfOrderLogInsertionError(
177
- 'private',
178
- taggedLogBuffer.tag,
179
- lastExisting.blockNumber,
180
- firstNew.blockNumber,
181
- );
182
- }
183
- privateTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
168
+ privateTaggedLogs.set(
169
+ taggedLogBuffer.tag,
170
+ taggedLogBuffer.logBuffers!.concat(privateTaggedLogs.get(taggedLogBuffer.tag)!),
171
+ );
184
172
  }
185
173
  }
186
174
 
@@ -212,21 +200,10 @@ export class LogStore {
212
200
 
213
201
  for (const taggedLogBuffer of currentPublicTaggedLogs) {
214
202
  if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
215
- const newLogs = publicTaggedLogs.get(taggedLogBuffer.tag)!;
216
- if (newLogs.length === 0) {
217
- continue;
218
- }
219
- const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1)!);
220
- const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
221
- if (lastExisting.blockNumber > firstNew.blockNumber) {
222
- throw new OutOfOrderLogInsertionError(
223
- 'public',
224
- taggedLogBuffer.tag,
225
- lastExisting.blockNumber,
226
- firstNew.blockNumber,
227
- );
228
- }
229
- publicTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
203
+ publicTaggedLogs.set(
204
+ taggedLogBuffer.tag,
205
+ taggedLogBuffer.logBuffers!.concat(publicTaggedLogs.get(taggedLogBuffer.tag)!),
206
+ );
230
207
  }
231
208
  }
232
209
 
@@ -376,30 +353,17 @@ export class LogStore {
376
353
  * array implies no logs match that tag.
377
354
  * @param tags - The tags to search for.
378
355
  * @param page - The page number (0-indexed) for pagination.
379
- * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
380
356
  * @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
381
357
  * MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
382
358
  */
383
- async getPrivateLogsByTags(
384
- tags: SiloedTag[],
385
- page: number = 0,
386
- upToBlockNumber?: BlockNumber,
387
- ): Promise<TxScopedL2Log[][]> {
359
+ async getPrivateLogsByTags(tags: SiloedTag[], page: number = 0): Promise<TxScopedL2Log[][]> {
388
360
  const logs = await Promise.all(tags.map(tag => this.#privateLogsByTag.getAsync(tag.toString())));
389
-
390
361
  const start = page * MAX_LOGS_PER_TAG;
391
362
  const end = start + MAX_LOGS_PER_TAG;
392
363
 
393
- return logs.map(logBuffers => {
394
- const deserialized = logBuffers?.slice(start, end).map(buf => TxScopedL2Log.fromBuffer(buf)) ?? [];
395
- if (upToBlockNumber !== undefined) {
396
- const cutoff = deserialized.findIndex(log => log.blockNumber > upToBlockNumber);
397
- if (cutoff !== -1) {
398
- return deserialized.slice(0, cutoff);
399
- }
400
- }
401
- return deserialized;
402
- });
364
+ return logs.map(
365
+ logBuffers => logBuffers?.slice(start, end).map(logBuffer => TxScopedL2Log.fromBuffer(logBuffer)) ?? [],
366
+ );
403
367
  }
404
368
 
405
369
  /**
@@ -408,7 +372,6 @@ export class LogStore {
408
372
  * @param contractAddress - The contract address to search logs for.
409
373
  * @param tags - The tags to search for.
410
374
  * @param page - The page number (0-indexed) for pagination.
411
- * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
412
375
  * @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
413
376
  * MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
414
377
  */
@@ -416,7 +379,6 @@ export class LogStore {
416
379
  contractAddress: AztecAddress,
417
380
  tags: Tag[],
418
381
  page: number = 0,
419
- upToBlockNumber?: BlockNumber,
420
382
  ): Promise<TxScopedL2Log[][]> {
421
383
  const logs = await Promise.all(
422
384
  tags.map(tag => {
@@ -427,16 +389,9 @@ export class LogStore {
427
389
  const start = page * MAX_LOGS_PER_TAG;
428
390
  const end = start + MAX_LOGS_PER_TAG;
429
391
 
430
- return logs.map(logBuffers => {
431
- const deserialized = logBuffers?.slice(start, end).map(buf => TxScopedL2Log.fromBuffer(buf)) ?? [];
432
- if (upToBlockNumber !== undefined) {
433
- const cutoff = deserialized.findIndex(log => log.blockNumber > upToBlockNumber);
434
- if (cutoff !== -1) {
435
- return deserialized.slice(0, cutoff);
436
- }
437
- }
438
- return deserialized;
439
- });
392
+ return logs.map(
393
+ logBuffers => logBuffers?.slice(start, end).map(logBuffer => TxScopedL2Log.fromBuffer(logBuffer)) ?? [],
394
+ );
440
395
  }
441
396
 
442
397
  /**
@@ -14,7 +14,6 @@ import {
14
14
  } from '@aztec/kv-store';
15
15
  import { InboxLeaf } from '@aztec/stdlib/messaging';
16
16
 
17
- import { L1ToL2MessagesNotReadyError } from '../errors.js';
18
17
  import {
19
18
  type InboxMessage,
20
19
  deserializeInboxMessage,
@@ -41,8 +40,6 @@ export class MessageStore {
41
40
  #lastSynchedL1Block: AztecAsyncSingleton<Buffer>;
42
41
  /** Stores total messages stored */
43
42
  #totalMessageCount: AztecAsyncSingleton<bigint>;
44
- /** Stores the checkpoint number whose message tree is currently being filled on L1. */
45
- #inboxTreeInProgress: AztecAsyncSingleton<bigint>;
46
43
 
47
44
  #log = createLogger('archiver:message_store');
48
45
 
@@ -51,7 +48,6 @@ export class MessageStore {
51
48
  this.#l1ToL2MessageIndices = db.openMap('archiver_l1_to_l2_message_indices');
52
49
  this.#lastSynchedL1Block = db.openSingleton('archiver_last_l1_block_id');
53
50
  this.#totalMessageCount = db.openSingleton('archiver_l1_to_l2_message_count');
54
- this.#inboxTreeInProgress = db.openSingleton('archiver_inbox_tree_in_progress');
55
51
  }
56
52
 
57
53
  public async getTotalL1ToL2MessageCount(): Promise<bigint> {
@@ -189,22 +185,7 @@ export class MessageStore {
189
185
  return msg ? deserializeInboxMessage(msg) : undefined;
190
186
  }
191
187
 
192
- /** Returns the inbox tree-in-progress checkpoint number from L1, or undefined if not yet set. */
193
- public getInboxTreeInProgress(): Promise<bigint | undefined> {
194
- return this.#inboxTreeInProgress.getAsync();
195
- }
196
-
197
- /** Persists the inbox tree-in-progress checkpoint number from L1 state. */
198
- public async setInboxTreeInProgress(value: bigint): Promise<void> {
199
- await this.#inboxTreeInProgress.set(value);
200
- }
201
-
202
188
  public async getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
203
- const treeInProgress = await this.#inboxTreeInProgress.getAsync();
204
- if (treeInProgress !== undefined && BigInt(checkpointNumber) >= treeInProgress) {
205
- throw new L1ToL2MessagesNotReadyError(checkpointNumber, treeInProgress);
206
- }
207
-
208
189
  const messages: Fr[] = [];
209
190
 
210
191
  const [startIndex, endIndex] = InboxLeaf.indexRangeForCheckpoint(checkpointNumber);
@@ -1,6 +1,5 @@
1
1
  import type { BlobClientInterface } from '@aztec/blob-client/client';
2
2
  import { type Blob, getBlobsPerL1Block, getPrefixedEthBlobCommitments } from '@aztec/blob-lib';
3
- import { INITIAL_CHECKPOINT_NUMBER } from '@aztec/constants';
4
3
  import type { CheckpointProposedLog, InboxContract, MessageSentLog, RollupContract } from '@aztec/ethereum/contracts';
5
4
  import { MULTI_CALL_3_ADDRESS } from '@aztec/ethereum/contracts';
6
5
  import type { ViemPublicClient } from '@aztec/ethereum/types';
@@ -332,6 +331,21 @@ export class FakeL1State {
332
331
  this.updatePendingCheckpointNumber();
333
332
  }
334
333
 
334
+ /**
335
+ * Moves a checkpoint to a different L1 block number (simulates L1 reorg that
336
+ * re-includes the same checkpoint transaction in a different block).
337
+ * The checkpoint content stays the same — only the L1 metadata changes.
338
+ * Auto-updates pending status.
339
+ */
340
+ moveCheckpointToL1Block(checkpointNumber: CheckpointNumber, newL1BlockNumber: bigint): void {
341
+ for (const cpData of this.checkpoints) {
342
+ if (cpData.checkpointNumber === checkpointNumber) {
343
+ cpData.l1BlockNumber = newL1BlockNumber;
344
+ }
345
+ }
346
+ this.updatePendingCheckpointNumber();
347
+ }
348
+
335
349
  /**
336
350
  * Removes messages after a given total index (simulates L1 reorg).
337
351
  * Auto-updates rolling hash.
@@ -451,22 +465,13 @@ export class FakeL1State {
451
465
  createMockInboxContract(_publicClient: MockProxy<ViemPublicClient>): MockProxy<InboxContract> {
452
466
  const mockInbox = mock<InboxContract>();
453
467
 
454
- mockInbox.getState.mockImplementation(() => {
455
- // treeInProgress must be > any sealed checkpoint. On L1, a checkpoint can only be proposed
456
- // after its messages are sealed, so treeInProgress > checkpointNumber for all published checkpoints.
457
- const maxFromMessages =
458
- this.messages.length > 0 ? Math.max(...this.messages.map(m => Number(m.checkpointNumber))) + 1 : 0;
459
- const maxFromCheckpoints =
460
- this.checkpoints.length > 0
461
- ? Math.max(...this.checkpoints.filter(cp => !cp.pruned).map(cp => Number(cp.checkpointNumber))) + 1
462
- : 0;
463
- const treeInProgress = Math.max(maxFromMessages, maxFromCheckpoints, INITIAL_CHECKPOINT_NUMBER);
464
- return Promise.resolve({
468
+ mockInbox.getState.mockImplementation(() =>
469
+ Promise.resolve({
465
470
  messagesRollingHash: this.messagesRollingHash,
466
471
  totalMessagesInserted: BigInt(this.messages.length),
467
- treeInProgress: BigInt(treeInProgress),
468
- });
469
- });
472
+ treeInProgress: 0n,
473
+ }),
474
+ );
470
475
 
471
476
  // Mock the wrapper methods for fetching message events
472
477
  mockInbox.getMessageSentEvents.mockImplementation((fromBlock: bigint, toBlock: bigint) =>