@aztec/archiver 0.0.1-commit.9593d84 → 0.0.1-commit.96dac018d

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 (209) hide show
  1. package/README.md +156 -22
  2. package/dest/archiver.d.ts +139 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +699 -0
  5. package/dest/config.d.ts +30 -0
  6. package/dest/config.d.ts.map +1 -0
  7. package/dest/{archiver/config.js → config.js} +21 -5
  8. package/dest/errors.d.ts +41 -0
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/errors.js +62 -0
  11. package/dest/factory.d.ts +9 -7
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +94 -13
  14. package/dest/index.d.ts +11 -4
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +9 -3
  17. package/dest/interfaces.d.ts +9 -0
  18. package/dest/interfaces.d.ts.map +1 -0
  19. package/dest/interfaces.js +3 -0
  20. package/dest/l1/bin/retrieve-calldata.d.ts +3 -0
  21. package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
  22. package/dest/l1/bin/retrieve-calldata.js +152 -0
  23. package/dest/l1/calldata_retriever.d.ts +135 -0
  24. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  25. package/dest/l1/calldata_retriever.js +402 -0
  26. package/dest/l1/data_retrieval.d.ts +85 -0
  27. package/dest/l1/data_retrieval.d.ts.map +1 -0
  28. package/dest/{archiver → l1}/data_retrieval.js +75 -153
  29. package/dest/l1/debug_tx.d.ts +19 -0
  30. package/dest/l1/debug_tx.d.ts.map +1 -0
  31. package/dest/l1/debug_tx.js +73 -0
  32. package/dest/l1/spire_proposer.d.ts +70 -0
  33. package/dest/l1/spire_proposer.d.ts.map +1 -0
  34. package/dest/l1/spire_proposer.js +149 -0
  35. package/dest/l1/trace_tx.d.ts +97 -0
  36. package/dest/l1/trace_tx.d.ts.map +1 -0
  37. package/dest/l1/trace_tx.js +91 -0
  38. package/dest/l1/types.d.ts +12 -0
  39. package/dest/l1/types.d.ts.map +1 -0
  40. package/dest/l1/types.js +3 -0
  41. package/dest/l1/validate_trace.d.ts +32 -0
  42. package/dest/l1/validate_trace.d.ts.map +1 -0
  43. package/dest/l1/validate_trace.js +154 -0
  44. package/dest/modules/data_source_base.d.ts +89 -0
  45. package/dest/modules/data_source_base.d.ts.map +1 -0
  46. package/dest/modules/data_source_base.js +216 -0
  47. package/dest/modules/data_store_updater.d.ts +80 -0
  48. package/dest/modules/data_store_updater.d.ts.map +1 -0
  49. package/dest/modules/data_store_updater.js +323 -0
  50. package/dest/modules/instrumentation.d.ts +50 -0
  51. package/dest/modules/instrumentation.d.ts.map +1 -0
  52. package/dest/{archiver → modules}/instrumentation.js +49 -62
  53. package/dest/modules/l1_synchronizer.d.ts +71 -0
  54. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  55. package/dest/modules/l1_synchronizer.js +1117 -0
  56. package/dest/modules/validation.d.ts +17 -0
  57. package/dest/modules/validation.d.ts.map +1 -0
  58. package/dest/{archiver → modules}/validation.js +7 -1
  59. package/dest/store/block_store.d.ts +196 -0
  60. package/dest/store/block_store.d.ts.map +1 -0
  61. package/dest/store/block_store.js +773 -0
  62. package/dest/store/contract_class_store.d.ts +18 -0
  63. package/dest/store/contract_class_store.d.ts.map +1 -0
  64. package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +13 -9
  65. package/dest/store/contract_instance_store.d.ts +24 -0
  66. package/dest/store/contract_instance_store.d.ts.map +1 -0
  67. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
  68. package/dest/store/kv_archiver_store.d.ts +354 -0
  69. package/dest/store/kv_archiver_store.d.ts.map +1 -0
  70. package/dest/store/kv_archiver_store.js +464 -0
  71. package/dest/store/l2_tips_cache.d.ts +19 -0
  72. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  73. package/dest/store/l2_tips_cache.js +89 -0
  74. package/dest/store/log_store.d.ts +54 -0
  75. package/dest/store/log_store.d.ts.map +1 -0
  76. package/dest/store/log_store.js +456 -0
  77. package/dest/store/message_store.d.ts +40 -0
  78. package/dest/store/message_store.d.ts.map +1 -0
  79. package/dest/{archiver/kv_archiver_store → store}/message_store.js +15 -14
  80. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  81. package/dest/structs/data_retrieval.d.ts.map +1 -0
  82. package/dest/structs/inbox_message.d.ts +15 -0
  83. package/dest/structs/inbox_message.d.ts.map +1 -0
  84. package/dest/{archiver/structs → structs}/inbox_message.js +6 -5
  85. package/dest/structs/published.d.ts +2 -0
  86. package/dest/structs/published.d.ts.map +1 -0
  87. package/dest/test/fake_l1_state.d.ts +195 -0
  88. package/dest/test/fake_l1_state.d.ts.map +1 -0
  89. package/dest/test/fake_l1_state.js +421 -0
  90. package/dest/test/index.d.ts +2 -1
  91. package/dest/test/index.d.ts.map +1 -1
  92. package/dest/test/index.js +4 -1
  93. package/dest/test/mock_archiver.d.ts +16 -8
  94. package/dest/test/mock_archiver.d.ts.map +1 -1
  95. package/dest/test/mock_archiver.js +19 -14
  96. package/dest/test/mock_l1_to_l2_message_source.d.ts +7 -6
  97. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  98. package/dest/test/mock_l1_to_l2_message_source.js +21 -11
  99. package/dest/test/mock_l2_block_source.d.ts +51 -18
  100. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  101. package/dest/test/mock_l2_block_source.js +245 -82
  102. package/dest/test/mock_structs.d.ts +80 -4
  103. package/dest/test/mock_structs.d.ts.map +1 -1
  104. package/dest/test/mock_structs.js +145 -11
  105. package/dest/test/noop_l1_archiver.d.ts +23 -0
  106. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  107. package/dest/test/noop_l1_archiver.js +68 -0
  108. package/package.json +20 -20
  109. package/src/archiver.ts +443 -0
  110. package/src/{archiver/config.ts → config.ts} +28 -12
  111. package/src/errors.ts +102 -0
  112. package/src/factory.ts +142 -13
  113. package/src/index.ts +11 -3
  114. package/src/interfaces.ts +9 -0
  115. package/src/l1/README.md +55 -0
  116. package/src/l1/bin/retrieve-calldata.ts +194 -0
  117. package/src/l1/calldata_retriever.ts +511 -0
  118. package/src/{archiver → l1}/data_retrieval.ts +133 -224
  119. package/src/l1/debug_tx.ts +99 -0
  120. package/src/l1/spire_proposer.ts +152 -0
  121. package/src/l1/trace_tx.ts +128 -0
  122. package/src/l1/types.ts +13 -0
  123. package/src/l1/validate_trace.ts +229 -0
  124. package/src/modules/data_source_base.ts +328 -0
  125. package/src/modules/data_store_updater.ts +448 -0
  126. package/src/{archiver → modules}/instrumentation.ts +63 -66
  127. package/src/modules/l1_synchronizer.ts +933 -0
  128. package/src/{archiver → modules}/validation.ts +11 -6
  129. package/src/store/block_store.ts +1015 -0
  130. package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +13 -9
  131. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +2 -2
  132. package/src/store/kv_archiver_store.ts +671 -0
  133. package/src/store/l2_tips_cache.ts +89 -0
  134. package/src/store/log_store.ts +637 -0
  135. package/src/{archiver/kv_archiver_store → store}/message_store.ts +21 -18
  136. package/src/{archiver/structs → structs}/inbox_message.ts +8 -8
  137. package/src/{archiver/structs → structs}/published.ts +0 -1
  138. package/src/test/fake_l1_state.ts +657 -0
  139. package/src/test/fixtures/debug_traceTransaction-multicall3.json +88 -0
  140. package/src/test/fixtures/debug_traceTransaction-multiplePropose.json +153 -0
  141. package/src/test/fixtures/debug_traceTransaction-proxied.json +122 -0
  142. package/src/test/fixtures/trace_transaction-multicall3.json +65 -0
  143. package/src/test/fixtures/trace_transaction-multiplePropose.json +319 -0
  144. package/src/test/fixtures/trace_transaction-proxied.json +128 -0
  145. package/src/test/fixtures/trace_transaction-randomRevert.json +216 -0
  146. package/src/test/index.ts +4 -0
  147. package/src/test/mock_archiver.ts +23 -16
  148. package/src/test/mock_l1_to_l2_message_source.ts +18 -11
  149. package/src/test/mock_l2_block_source.ts +296 -90
  150. package/src/test/mock_structs.ts +275 -13
  151. package/src/test/noop_l1_archiver.ts +109 -0
  152. package/dest/archiver/archiver.d.ts +0 -287
  153. package/dest/archiver/archiver.d.ts.map +0 -1
  154. package/dest/archiver/archiver.js +0 -1408
  155. package/dest/archiver/archiver_store.d.ts +0 -255
  156. package/dest/archiver/archiver_store.d.ts.map +0 -1
  157. package/dest/archiver/archiver_store.js +0 -4
  158. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  159. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  160. package/dest/archiver/archiver_store_test_suite.js +0 -1289
  161. package/dest/archiver/config.d.ts +0 -21
  162. package/dest/archiver/config.d.ts.map +0 -1
  163. package/dest/archiver/data_retrieval.d.ts +0 -79
  164. package/dest/archiver/data_retrieval.d.ts.map +0 -1
  165. package/dest/archiver/errors.d.ts +0 -12
  166. package/dest/archiver/errors.d.ts.map +0 -1
  167. package/dest/archiver/errors.js +0 -17
  168. package/dest/archiver/index.d.ts +0 -7
  169. package/dest/archiver/index.d.ts.map +0 -1
  170. package/dest/archiver/index.js +0 -4
  171. package/dest/archiver/instrumentation.d.ts +0 -35
  172. package/dest/archiver/instrumentation.d.ts.map +0 -1
  173. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -124
  174. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  175. package/dest/archiver/kv_archiver_store/block_store.js +0 -370
  176. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  177. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  178. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  179. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  180. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -168
  181. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  182. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -296
  183. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -49
  184. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  185. package/dest/archiver/kv_archiver_store/log_store.js +0 -336
  186. package/dest/archiver/kv_archiver_store/message_store.d.ts +0 -39
  187. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  188. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  189. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  190. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  191. package/dest/archiver/structs/published.d.ts +0 -3
  192. package/dest/archiver/structs/published.d.ts.map +0 -1
  193. package/dest/archiver/validation.d.ts +0 -17
  194. package/dest/archiver/validation.d.ts.map +0 -1
  195. package/dest/rpc/index.d.ts +0 -9
  196. package/dest/rpc/index.d.ts.map +0 -1
  197. package/dest/rpc/index.js +0 -15
  198. package/src/archiver/archiver.ts +0 -1858
  199. package/src/archiver/archiver_store.ts +0 -305
  200. package/src/archiver/archiver_store_test_suite.ts +0 -1264
  201. package/src/archiver/errors.ts +0 -26
  202. package/src/archiver/index.ts +0 -6
  203. package/src/archiver/kv_archiver_store/block_store.ts +0 -481
  204. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +0 -422
  205. package/src/archiver/kv_archiver_store/log_store.ts +0 -406
  206. package/src/rpc/index.ts +0 -16
  207. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  208. /package/dest/{archiver/structs → structs}/published.js +0 -0
  209. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
@@ -0,0 +1,195 @@
1
+ import type { BlobClientInterface } from '@aztec/blob-client/client';
2
+ import { type Blob } from '@aztec/blob-lib';
3
+ import type { InboxContract, RollupContract } from '@aztec/ethereum/contracts';
4
+ import type { ViemPublicClient } from '@aztec/ethereum/types';
5
+ import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
6
+ import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
7
+ import { Fr } from '@aztec/foundation/curves/bn254';
8
+ import { EthAddress } from '@aztec/foundation/eth-address';
9
+ import { L2Block } from '@aztec/stdlib/block';
10
+ import { Checkpoint } from '@aztec/stdlib/checkpoint';
11
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
12
+ import { type MockProxy } from 'jest-mock-extended';
13
+ /** Configuration for the fake L1 state. */
14
+ export type FakeL1StateConfig = {
15
+ /** Genesis archive root. */
16
+ genesisArchiveRoot: Fr;
17
+ /** L1 start block number. */
18
+ l1StartBlock: bigint;
19
+ /** L1 genesis time in seconds. */
20
+ l1GenesisTime: bigint;
21
+ /** Ethereum slot duration in seconds. */
22
+ ethereumSlotDuration: number;
23
+ /** Rollup address for mock contracts. */
24
+ rollupAddress: EthAddress;
25
+ /** Inbox address for mock contracts. */
26
+ inboxAddress: EthAddress;
27
+ /** Aztec slot duration in seconds */
28
+ slotDuration: number;
29
+ };
30
+ /** Options for adding a checkpoint. */
31
+ type AddCheckpointOptions = {
32
+ /** L1 block number where checkpoint was proposed. */
33
+ l1BlockNumber: bigint;
34
+ /** Number of L2 blocks in the checkpoint. Default: 1 */
35
+ numBlocks?: number;
36
+ /** Or the actual blocks for the checkpoint */
37
+ blocks?: L2Block[];
38
+ /** Number of transactions per block. Default: 4 */
39
+ txsPerBlock?: number;
40
+ /** Max number of effects per tx (for generating large blobs). Default: undefined */
41
+ maxEffects?: number;
42
+ /** Signers for attestations. Default: none */
43
+ signers?: Secp256k1Signer[];
44
+ /** Override slot number. */
45
+ slotNumber?: SlotNumber;
46
+ /** Override previous archive. */
47
+ previousArchive?: AppendOnlyTreeSnapshot;
48
+ /** Timestamp for the checkpoint. */
49
+ timestamp?: bigint;
50
+ /** Number of L1-to-L2 messages. Default: 3 */
51
+ numL1ToL2Messages?: number;
52
+ /** L1 block number where messages were sent. Default: l1BlockNumber - 3 */
53
+ messagesL1BlockNumber?: bigint;
54
+ };
55
+ /** Result from adding a checkpoint. */
56
+ type AddCheckpointResult = {
57
+ /** The checkpoint that was created. */
58
+ checkpoint: Checkpoint;
59
+ /** The L1-to-L2 messages for this checkpoint. */
60
+ messages: Fr[];
61
+ };
62
+ /**
63
+ * Stateful fake for L1 data used by the archiver.
64
+ *
65
+ * This class simulates the L1 blockchain state that the archiver reads from:
66
+ * - RollupContract: status(), archiveAt(), getVersion(), getTargetCommitteeSize(), CheckpointProposed events
67
+ * - InboxContract: getState(), MessageSent events
68
+ * - PublicClient: getBlockNumber(), getBlock(), getTransaction()
69
+ * - BlobClient: getBlobSidecar()
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * const fake = new FakeL1State(config);
74
+ *
75
+ * // Add checkpoint (creates messages automatically)
76
+ * const { checkpoint, messages } = await fake.addCheckpoint(CheckpointNumber(1), { l1BlockNumber: 101n });
77
+ * fake.setL1BlockNumber(105n);
78
+ *
79
+ * // Status auto-updated
80
+ * expect(fake.getRollupStatus().pendingCheckpointNumber).toEqual(CheckpointNumber(1));
81
+ * ```
82
+ */
83
+ export declare class FakeL1State {
84
+ private readonly config;
85
+ private readonly log;
86
+ private l1BlockNumber;
87
+ private checkpoints;
88
+ private messages;
89
+ private messagesRollingHash;
90
+ private lastArchive;
91
+ private provenCheckpointNumber;
92
+ private targetCommitteeSize;
93
+ private version;
94
+ private canPruneResult;
95
+ private pendingCheckpointNumber;
96
+ constructor(config: FakeL1StateConfig);
97
+ /**
98
+ * Adds messages for a checkpoint. Returns the message leaves.
99
+ * Auto-updates rolling hash.
100
+ *
101
+ * Note: For most use cases, use `addCheckpoint` which creates both checkpoint and messages.
102
+ * Use this method only when you need to add messages without creating a checkpoint (e.g., for reorg tests).
103
+ */
104
+ addMessages(checkpointNumber: CheckpointNumber, l1BlockNumber: bigint, messageLeaves: Fr[]): void;
105
+ /**
106
+ * Creates blocks for a checkpoint without adding them to L1 state.
107
+ * Useful for creating blocks to pass to addBlock() for testing provisional block handling.
108
+ * Returns the blocks directly.
109
+ */
110
+ makeBlocks(checkpointNumber: CheckpointNumber, options: Partial<AddCheckpointOptions>): Promise<L2Block[]>;
111
+ /**
112
+ * Creates and adds a checkpoint with its L1-to-L2 messages.
113
+ * Returns both the checkpoint and the message leaves.
114
+ * Auto-chains from lastArchive, auto-updates pending status if L1 block >= checkpoint's L1 block.
115
+ */
116
+ addCheckpoint(checkpointNumber: CheckpointNumber, options: AddCheckpointOptions): Promise<AddCheckpointResult>;
117
+ /** Creates a checkpoint and messages without adding them to L1 state. */
118
+ private makeCheckpointAndMessages;
119
+ /** Returns the L2 slot at the given L1 block (assuming all L1 blocks are mined) */
120
+ getL2SlotAtL1Block(l1BlockNumber: bigint): SlotNumber;
121
+ /** Returns the timestamp at the given L1 block (assuming all L1 blocks are mined) */
122
+ getTimestampAtL1Block(l1BlockNumber: bigint): bigint;
123
+ /**
124
+ * Sets the current L1 block number.
125
+ * Auto-updates pending checkpoint number based on visible checkpoints.
126
+ */
127
+ setL1BlockNumber(blockNumber: bigint): void;
128
+ /** Marks a checkpoint as proven. Updates provenCheckpointNumber. */
129
+ markCheckpointAsProven(checkpointNumber: CheckpointNumber): void;
130
+ /** Sets the target committee size for attestation validation. */
131
+ setTargetCommitteeSize(size: number): void;
132
+ /** Sets whether the rollup contract would allow pruning at the next block. */
133
+ setCanPrune(value: boolean): void;
134
+ /**
135
+ * Removes all entries for a checkpoint number (simulates L1 reorg or prune).
136
+ * Note: Does NOT remove messages for this checkpoint (use numL1ToL2Messages: 0 when re-adding).
137
+ * Auto-updates pending status.
138
+ */
139
+ removeCheckpoint(checkpointNumber: CheckpointNumber): void;
140
+ /**
141
+ * Removes messages after a given total index (simulates L1 reorg).
142
+ * Auto-updates rolling hash.
143
+ */
144
+ removeMessagesAfter(totalIndex: number): void;
145
+ /**
146
+ * Simulates a pruned checkpoint by marking all entries with this number as pruned.
147
+ * The event will still be returned, but archiveAt() will return the previous checkpoint's archive
148
+ * (or genesis if no previous checkpoint), causing a mismatch that the archiver will detect.
149
+ */
150
+ markCheckpointAsPruned(checkpointNumber: CheckpointNumber): void;
151
+ /**
152
+ * Moves messages at a given L1 block to a new L1 block.
153
+ * Useful for simulating partial message visibility (messages at higher L1 blocks won't be fetched).
154
+ */
155
+ moveMessagesToL1Block(fromL1Block: bigint, toL1Block: bigint): void;
156
+ /**
157
+ * Moves a specific message (by index in the messages array) to a new L1 block.
158
+ */
159
+ moveMessageAtIndexToL1Block(index: number, toL1Block: bigint): void;
160
+ /** Gets current rollup status. */
161
+ getRollupStatus(): {
162
+ provenCheckpointNumber: CheckpointNumber;
163
+ pendingCheckpointNumber: CheckpointNumber;
164
+ provenArchive: Fr;
165
+ pendingArchive: Fr;
166
+ };
167
+ /** Gets the last archive (for manual chaining if needed). */
168
+ getLastArchive(): AppendOnlyTreeSnapshot;
169
+ /** Gets the latest checkpoint entry by number (returns the last added one). */
170
+ getCheckpoint(checkpointNumber: CheckpointNumber): Checkpoint | undefined;
171
+ /** Gets messages for a checkpoint. */
172
+ getMessages(checkpointNumber: CheckpointNumber): Fr[];
173
+ /** Gets the blobs for a checkpoint. */
174
+ getCheckpointBlobs(checkpointNumber: CheckpointNumber): Blob[];
175
+ /** Creates mock RollupContract that reads from this fake state. */
176
+ createMockRollupContract(_publicClient: MockProxy<ViemPublicClient>): MockProxy<RollupContract>;
177
+ /** Creates mock InboxContract that reads from this fake state. */
178
+ createMockInboxContract(_publicClient: MockProxy<ViemPublicClient>): MockProxy<InboxContract>;
179
+ /** Creates mock PublicClient that reads from this fake state. */
180
+ createMockPublicClient(): MockProxy<ViemPublicClient>;
181
+ /** Creates mock BlobClient that reads from this fake state. */
182
+ createMockBlobClient(): MockProxy<BlobClientInterface>;
183
+ private updatePendingCheckpointNumber;
184
+ private getArchiveAt;
185
+ private getNextBlockNumber;
186
+ private getCheckpointProposedLogs;
187
+ private getMessageSentLogs;
188
+ private makeRollupTx;
189
+ /** Extracts the CommitteeAttestations struct definition from RollupAbi for hash computation. */
190
+ private getCommitteeAttestationsStructDef;
191
+ private makeVersionedBlobHashes;
192
+ private makeBlobsFromCheckpoint;
193
+ }
194
+ export {};
195
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFrZV9sMV9zdGF0ZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvZmFrZV9sMV9zdGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBcUQsTUFBTSxpQkFBaUIsQ0FBQztBQUMvRixPQUFPLEtBQUssRUFBeUIsYUFBYSxFQUFrQixjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV0SCxPQUFPLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlELE9BQU8sRUFBb0IsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFHM0QsT0FBTyxFQUF5RCxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFTdEQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFN0QsT0FBTyxFQUFFLEtBQUssU0FBUyxFQUFRLE1BQU0sb0JBQW9CLENBQUM7QUFjMUQsMkNBQTJDO0FBQzNDLE1BQU0sTUFBTSxpQkFBaUIsR0FBRztJQUM5Qiw0QkFBNEI7SUFDNUIsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO0lBQ3ZCLDZCQUE2QjtJQUM3QixZQUFZLEVBQUUsTUFBTSxDQUFDO0lBQ3JCLGtDQUFrQztJQUNsQyxhQUFhLEVBQUUsTUFBTSxDQUFDO0lBQ3RCLHlDQUF5QztJQUN6QyxvQkFBb0IsRUFBRSxNQUFNLENBQUM7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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake_l1_state.d.ts","sourceRoot":"","sources":["../../src/test/fake_l1_state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,IAAI,EAAqD,MAAM,iBAAiB,CAAC;AAC/F,OAAO,KAAK,EAAyB,aAAa,EAAkB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEtH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAoB,gBAAgB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEjG,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAAyD,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAStD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,KAAK,SAAS,EAAQ,MAAM,oBAAoB,CAAC;AAc1D,2CAA2C;AAC3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,4BAA4B;IAC5B,kBAAkB,EAAE,EAAE,CAAC;IACvB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,aAAa,EAAE,UAAU,CAAC;IAC1B,wCAAwC;IACxC,YAAY,EAAE,UAAU,CAAC;IACzB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,uCAAuC;AACvC,KAAK,oBAAoB,GAAG;IAC1B,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,4BAA4B;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,iCAAiC;IACjC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,uCAAuC;AACvC,KAAK,mBAAmB,GAAG;IACzB,uCAAuC;IACvC,UAAU,EAAE,UAAU,CAAC;IACvB,iDAAiD;IACjD,QAAQ,EAAE,EAAE,EAAE,CAAC;CAChB,CAAC;AA4BF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,WAAW;IAeV,OAAO,CAAC,QAAQ,CAAC,MAAM;IAdnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyC;IAC7D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,sBAAsB,CAAyC;IACvE,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,cAAc,CAAkB;IAGxC,OAAO,CAAC,uBAAuB,CAAyC;IAExE,YAA6B,MAAM,EAAE,iBAAiB,EAGrD;IAED;;;;;;OAMG;IACH,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,GAAG,IAAI,CAahG;IAED;;;;OAIG;IACU,UAAU,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,sBAEjG;IAED;;;;OAIG;IACU,aAAa,CACxB,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAuC9B;IAED,yEAAyE;IACzE,OAAO,CAAC,yBAAyB;IA0BjC,mFAAmF;IAC5E,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAG3D;IAED,qFAAqF;IAC9E,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAG1D;IAED;;;OAGG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG1C;IAED,oEAAoE;IACpE,sBAAsB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAE/D;IAED,iEAAiE;IACjE,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzC;IAED,8EAA8E;IAC9E,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEhC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAGzD;IAED;;;OAGG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAI5C;IAED;;;;OAIG;IACH,sBAAsB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAO/D;IAED;;;OAGG;IACH,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAMlE;IAED;;OAEG;IACH,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAIlE;IAED,kCAAkC;IAClC,eAAe,IAAI;QACjB,sBAAsB,EAAE,gBAAgB,CAAC;QACzC,uBAAuB,EAAE,gBAAgB,CAAC;QAC1C,aAAa,EAAE,EAAE,CAAC;QAClB,cAAc,EAAE,EAAE,CAAC;KACpB,CAOA;IAED,6DAA6D;IAC7D,cAAc,IAAI,sBAAsB,CAEvC;IAED,+EAA+E;IAC/E,aAAa,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,UAAU,GAAG,SAAS,CAExE;IAED,sCAAsC;IACtC,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,EAAE,EAAE,CAEpD;IAED,uCAAuC;IACvC,kBAAkB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,EAAE,CAE7D;IAED,mEAAmE;IACnE,wBAAwB,CAAC,aAAa,EAAE,SAAS,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC,cAAc,CAAC,CA2B9F;IAED,kEAAkE;IAClE,uBAAuB,CAAC,aAAa,EAAE,SAAS,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC,aAAa,CAAC,CAqB5F;IAED,iEAAiE;IACjE,sBAAsB,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAyBpD;IAED,+DAA+D;IAC/D,oBAAoB,IAAI,SAAS,CAAC,mBAAmB,CAAC,CAarD;IAED,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,kBAAkB;YAqBZ,YAAY;IAyE1B,gGAAgG;IAChG,OAAO,CAAC,iCAAiC;YAkB3B,uBAAuB;YAMvB,uBAAuB;CAGtC"}
@@ -0,0 +1,421 @@
1
+ import { getBlobsPerL1Block, getPrefixedEthBlobCommitments } from '@aztec/blob-lib';
2
+ import { MULTI_CALL_3_ADDRESS } from '@aztec/ethereum/contracts';
3
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
4
+ import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
5
+ import { createLogger } from '@aztec/foundation/log';
6
+ import { RollupAbi } from '@aztec/l1-artifacts';
7
+ import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
8
+ import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
9
+ import { InboxLeaf } from '@aztec/stdlib/messaging';
10
+ import { ConsensusPayload, SignatureDomainSeparator } from '@aztec/stdlib/p2p';
11
+ import { makeAndSignCommitteeAttestationsAndSigners, makeCheckpointAttestationFromCheckpoint, mockCheckpointAndMessages } from '@aztec/stdlib/testing';
12
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
13
+ import { mock } from 'jest-mock-extended';
14
+ import { encodeAbiParameters, encodeFunctionData, keccak256, multicall3Abi, toHex } from 'viem';
15
+ import { updateRollingHash } from '../structs/inbox_message.js';
16
+ /**
17
+ * Stateful fake for L1 data used by the archiver.
18
+ *
19
+ * This class simulates the L1 blockchain state that the archiver reads from:
20
+ * - RollupContract: status(), archiveAt(), getVersion(), getTargetCommitteeSize(), CheckpointProposed events
21
+ * - InboxContract: getState(), MessageSent events
22
+ * - PublicClient: getBlockNumber(), getBlock(), getTransaction()
23
+ * - BlobClient: getBlobSidecar()
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const fake = new FakeL1State(config);
28
+ *
29
+ * // Add checkpoint (creates messages automatically)
30
+ * const { checkpoint, messages } = await fake.addCheckpoint(CheckpointNumber(1), { l1BlockNumber: 101n });
31
+ * fake.setL1BlockNumber(105n);
32
+ *
33
+ * // Status auto-updated
34
+ * expect(fake.getRollupStatus().pendingCheckpointNumber).toEqual(CheckpointNumber(1));
35
+ * ```
36
+ */ export class FakeL1State {
37
+ config;
38
+ log;
39
+ l1BlockNumber;
40
+ checkpoints;
41
+ messages;
42
+ messagesRollingHash;
43
+ lastArchive;
44
+ provenCheckpointNumber;
45
+ targetCommitteeSize;
46
+ version;
47
+ canPruneResult;
48
+ // Computed from checkpoints based on L1 block visibility
49
+ pendingCheckpointNumber;
50
+ constructor(config){
51
+ this.config = config;
52
+ this.log = createLogger('archiver:test:fake-l1');
53
+ this.checkpoints = [];
54
+ this.messages = [];
55
+ this.messagesRollingHash = Buffer16.ZERO;
56
+ this.provenCheckpointNumber = CheckpointNumber(0);
57
+ this.targetCommitteeSize = 0;
58
+ this.version = 1n;
59
+ this.canPruneResult = false;
60
+ this.pendingCheckpointNumber = CheckpointNumber(0);
61
+ this.l1BlockNumber = config.l1StartBlock;
62
+ this.lastArchive = new AppendOnlyTreeSnapshot(config.genesisArchiveRoot, 1);
63
+ }
64
+ /**
65
+ * Adds messages for a checkpoint. Returns the message leaves.
66
+ * Auto-updates rolling hash.
67
+ *
68
+ * Note: For most use cases, use `addCheckpoint` which creates both checkpoint and messages.
69
+ * Use this method only when you need to add messages without creating a checkpoint (e.g., for reorg tests).
70
+ */ addMessages(checkpointNumber, l1BlockNumber, messageLeaves) {
71
+ messageLeaves.forEach((leaf, i)=>{
72
+ const index = InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i);
73
+ this.messagesRollingHash = updateRollingHash(this.messagesRollingHash, leaf);
74
+ this.messages.push({
75
+ l1BlockNumber,
76
+ checkpointNumber,
77
+ index,
78
+ leaf,
79
+ rollingHash: this.messagesRollingHash
80
+ });
81
+ });
82
+ }
83
+ /**
84
+ * Creates blocks for a checkpoint without adding them to L1 state.
85
+ * Useful for creating blocks to pass to addBlock() for testing provisional block handling.
86
+ * Returns the blocks directly.
87
+ */ async makeBlocks(checkpointNumber, options) {
88
+ return (await this.makeCheckpointAndMessages(checkpointNumber, options)).checkpoint.blocks;
89
+ }
90
+ /**
91
+ * Creates and adds a checkpoint with its L1-to-L2 messages.
92
+ * Returns both the checkpoint and the message leaves.
93
+ * Auto-chains from lastArchive, auto-updates pending status if L1 block >= checkpoint's L1 block.
94
+ */ async addCheckpoint(checkpointNumber, options) {
95
+ this.log.warn(`Adding checkpoint ${checkpointNumber}`);
96
+ const { l1BlockNumber, signers = [], messagesL1BlockNumber = l1BlockNumber - 3n } = options;
97
+ // Create the checkpoint using the stdlib helper
98
+ const { checkpoint, messages, lastArchive } = await this.makeCheckpointAndMessages(checkpointNumber, {
99
+ ...options,
100
+ numL1ToL2Messages: options.numL1ToL2Messages ?? 3
101
+ });
102
+ // Store the messages internally so they match the checkpoint's inHash
103
+ this.addMessages(checkpointNumber, messagesL1BlockNumber, messages);
104
+ // Create the transaction, blobs, and event hashes
105
+ const { tx, attestationsHash, payloadDigest } = await this.makeRollupTx(checkpoint, signers);
106
+ const blobHashes = await this.makeVersionedBlobHashes(checkpoint);
107
+ const blobs = await this.makeBlobsFromCheckpoint(checkpoint);
108
+ // Store the checkpoint data
109
+ this.checkpoints.push({
110
+ checkpointNumber,
111
+ checkpoint,
112
+ l1BlockNumber,
113
+ tx,
114
+ blobHashes,
115
+ blobs,
116
+ signers,
117
+ attestationsHash,
118
+ payloadDigest
119
+ });
120
+ // Update last archive for auto-chaining
121
+ this.lastArchive = lastArchive ?? checkpoint.blocks.at(-1).archive;
122
+ // Auto-update pending checkpoint number
123
+ this.updatePendingCheckpointNumber();
124
+ return {
125
+ checkpoint,
126
+ messages
127
+ };
128
+ }
129
+ /** Creates a checkpoint and messages without adding them to L1 state. */ makeCheckpointAndMessages(checkpointNumber, options) {
130
+ const { numBlocks = 1, txsPerBlock = 4, maxEffects, slotNumber, previousArchive = this.lastArchive, timestamp, l1BlockNumber, numL1ToL2Messages = 0, blocks } = options;
131
+ return mockCheckpointAndMessages(checkpointNumber, {
132
+ startBlockNumber: this.getNextBlockNumber(checkpointNumber),
133
+ numBlocks,
134
+ blocks,
135
+ numTxsPerBlock: txsPerBlock,
136
+ numL1ToL2Messages,
137
+ previousArchive,
138
+ slotNumber: slotNumber ?? (l1BlockNumber !== undefined ? this.getL2SlotAtL1Block(l1BlockNumber) : undefined),
139
+ timestamp: timestamp ?? (l1BlockNumber !== undefined ? this.getTimestampAtL1Block(l1BlockNumber) : undefined),
140
+ ...maxEffects !== undefined ? {
141
+ maxEffects
142
+ } : {}
143
+ });
144
+ }
145
+ /** Returns the L2 slot at the given L1 block (assuming all L1 blocks are mined) */ getL2SlotAtL1Block(l1BlockNumber) {
146
+ const timestamp = this.getTimestampAtL1Block(l1BlockNumber);
147
+ return getSlotAtTimestamp(timestamp, this.config);
148
+ }
149
+ /** Returns the timestamp at the given L1 block (assuming all L1 blocks are mined) */ getTimestampAtL1Block(l1BlockNumber) {
150
+ const { l1GenesisTime, l1StartBlock, ethereumSlotDuration } = this.config;
151
+ return l1GenesisTime + (l1BlockNumber - l1StartBlock) * BigInt(ethereumSlotDuration);
152
+ }
153
+ /**
154
+ * Sets the current L1 block number.
155
+ * Auto-updates pending checkpoint number based on visible checkpoints.
156
+ */ setL1BlockNumber(blockNumber) {
157
+ this.l1BlockNumber = blockNumber;
158
+ this.updatePendingCheckpointNumber();
159
+ }
160
+ /** Marks a checkpoint as proven. Updates provenCheckpointNumber. */ markCheckpointAsProven(checkpointNumber) {
161
+ this.provenCheckpointNumber = checkpointNumber;
162
+ }
163
+ /** Sets the target committee size for attestation validation. */ setTargetCommitteeSize(size) {
164
+ this.targetCommitteeSize = size;
165
+ }
166
+ /** Sets whether the rollup contract would allow pruning at the next block. */ setCanPrune(value) {
167
+ this.canPruneResult = value;
168
+ }
169
+ /**
170
+ * Removes all entries for a checkpoint number (simulates L1 reorg or prune).
171
+ * Note: Does NOT remove messages for this checkpoint (use numL1ToL2Messages: 0 when re-adding).
172
+ * Auto-updates pending status.
173
+ */ removeCheckpoint(checkpointNumber) {
174
+ this.checkpoints = this.checkpoints.filter((cpData)=>cpData.checkpointNumber !== checkpointNumber);
175
+ this.updatePendingCheckpointNumber();
176
+ }
177
+ /**
178
+ * Removes messages after a given total index (simulates L1 reorg).
179
+ * Auto-updates rolling hash.
180
+ */ removeMessagesAfter(totalIndex) {
181
+ this.messages = this.messages.slice(0, totalIndex);
182
+ // Recalculate rolling hash
183
+ this.messagesRollingHash = this.messages.reduce((hash, msg)=>updateRollingHash(hash, msg.leaf), Buffer16.ZERO);
184
+ }
185
+ /**
186
+ * Simulates a pruned checkpoint by marking all entries with this number as pruned.
187
+ * The event will still be returned, but archiveAt() will return the previous checkpoint's archive
188
+ * (or genesis if no previous checkpoint), causing a mismatch that the archiver will detect.
189
+ */ markCheckpointAsPruned(checkpointNumber) {
190
+ for (const cpData of this.checkpoints){
191
+ if (cpData.checkpointNumber === checkpointNumber) {
192
+ cpData.pruned = true;
193
+ }
194
+ }
195
+ this.updatePendingCheckpointNumber();
196
+ }
197
+ /**
198
+ * Moves messages at a given L1 block to a new L1 block.
199
+ * Useful for simulating partial message visibility (messages at higher L1 blocks won't be fetched).
200
+ */ moveMessagesToL1Block(fromL1Block, toL1Block) {
201
+ this.messages.forEach((msg)=>{
202
+ if (msg.l1BlockNumber === fromL1Block) {
203
+ msg.l1BlockNumber = toL1Block;
204
+ }
205
+ });
206
+ }
207
+ /**
208
+ * Moves a specific message (by index in the messages array) to a new L1 block.
209
+ */ moveMessageAtIndexToL1Block(index, toL1Block) {
210
+ if (this.messages[index]) {
211
+ this.messages[index].l1BlockNumber = toL1Block;
212
+ }
213
+ }
214
+ /** Gets current rollup status. */ getRollupStatus() {
215
+ return {
216
+ provenCheckpointNumber: this.provenCheckpointNumber,
217
+ pendingCheckpointNumber: this.pendingCheckpointNumber,
218
+ provenArchive: this.getArchiveAt(this.provenCheckpointNumber),
219
+ pendingArchive: this.getArchiveAt(this.pendingCheckpointNumber)
220
+ };
221
+ }
222
+ /** Gets the last archive (for manual chaining if needed). */ getLastArchive() {
223
+ return this.lastArchive;
224
+ }
225
+ /** Gets the latest checkpoint entry by number (returns the last added one). */ getCheckpoint(checkpointNumber) {
226
+ return this.checkpoints.findLast((cpData)=>cpData.checkpointNumber === checkpointNumber)?.checkpoint;
227
+ }
228
+ /** Gets messages for a checkpoint. */ getMessages(checkpointNumber) {
229
+ return this.messages.filter((m)=>m.checkpointNumber === checkpointNumber).map((m)=>m.leaf);
230
+ }
231
+ /** Gets the blobs for a checkpoint. */ getCheckpointBlobs(checkpointNumber) {
232
+ return this.checkpoints.findLast((cpData)=>cpData.checkpointNumber === checkpointNumber)?.blobs ?? [];
233
+ }
234
+ /** Creates mock RollupContract that reads from this fake state. */ createMockRollupContract(_publicClient) {
235
+ const mockRollup = mock();
236
+ mockRollup.getVersion.mockImplementation(()=>Promise.resolve(this.version));
237
+ mockRollup.getTargetCommitteeSize.mockImplementation(()=>Promise.resolve(this.targetCommitteeSize));
238
+ mockRollup.archiveAt.mockImplementation((cpNum)=>Promise.resolve(this.getArchiveAt(cpNum)));
239
+ mockRollup.status.mockImplementation((localCheckpointNum)=>{
240
+ const status = this.getRollupStatus();
241
+ return Promise.resolve({
242
+ provenCheckpointNumber: status.provenCheckpointNumber,
243
+ provenArchive: status.provenArchive,
244
+ pendingCheckpointNumber: status.pendingCheckpointNumber,
245
+ pendingArchive: status.pendingArchive,
246
+ archiveOfMyCheckpoint: this.getArchiveAt(localCheckpointNum)
247
+ });
248
+ });
249
+ mockRollup.canPruneAtTime.mockImplementation(()=>Promise.resolve(this.canPruneResult));
250
+ // Mock the wrapper method for fetching checkpoint events
251
+ mockRollup.getCheckpointProposedEvents.mockImplementation((fromBlock, toBlock)=>Promise.resolve(this.getCheckpointProposedLogs(fromBlock, toBlock)));
252
+ Object.defineProperty(mockRollup, 'address', {
253
+ get: ()=>this.config.rollupAddress.toString()
254
+ });
255
+ return mockRollup;
256
+ }
257
+ /** Creates mock InboxContract that reads from this fake state. */ createMockInboxContract(_publicClient) {
258
+ const mockInbox = mock();
259
+ mockInbox.getState.mockImplementation(()=>Promise.resolve({
260
+ messagesRollingHash: this.messagesRollingHash,
261
+ totalMessagesInserted: BigInt(this.messages.length),
262
+ treeInProgress: 0n
263
+ }));
264
+ // Mock the wrapper methods for fetching message events
265
+ mockInbox.getMessageSentEvents.mockImplementation((fromBlock, toBlock)=>Promise.resolve(this.getMessageSentLogs(fromBlock, toBlock)));
266
+ mockInbox.getMessageSentEventByHash.mockImplementation((hash, fromBlock, toBlock)=>Promise.resolve(this.getMessageSentLogs(fromBlock, toBlock, hash)));
267
+ return mockInbox;
268
+ }
269
+ /** Creates mock PublicClient that reads from this fake state. */ createMockPublicClient() {
270
+ const publicClient = mock();
271
+ publicClient.getChainId.mockResolvedValue(1);
272
+ publicClient.getBlockNumber.mockImplementation(()=>Promise.resolve(this.l1BlockNumber));
273
+ // Use async function pattern that existing test uses for getBlock
274
+ publicClient.getBlock.mockImplementation(async (args = {})=>{
275
+ const blockNum = args.blockNumber ?? await publicClient.getBlockNumber();
276
+ return {
277
+ number: blockNum,
278
+ timestamp: BigInt(blockNum) * BigInt(this.config.ethereumSlotDuration) + this.config.l1GenesisTime,
279
+ hash: Buffer32.fromBigInt(blockNum).toString()
280
+ };
281
+ });
282
+ // Use the same pattern as existing test for getTransaction
283
+ publicClient.getTransaction.mockImplementation((args)=>Promise.resolve(args.hash ? this.checkpoints.find((cpData)=>cpData.tx.hash === args.hash)?.tx : undefined));
284
+ return publicClient;
285
+ }
286
+ /** Creates mock BlobClient that reads from this fake state. */ createMockBlobClient() {
287
+ const blobClient = mock();
288
+ // The blockId is the transaction's blockHash, which we set to the checkpoint's archive root
289
+ blobClient.getBlobSidecar.mockImplementation((blockId)=>Promise.resolve(this.checkpoints.find((cpData)=>cpData.checkpoint.archive.root.toString() === blockId)?.blobs ?? []));
290
+ blobClient.testSources.mockResolvedValue(undefined);
291
+ return blobClient;
292
+ }
293
+ updatePendingCheckpointNumber() {
294
+ this.pendingCheckpointNumber = this.checkpoints.filter((cpData)=>cpData.l1BlockNumber <= this.l1BlockNumber && !cpData.pruned).reduce((max, cpData)=>cpData.checkpointNumber > max ? cpData.checkpointNumber : max, CheckpointNumber(0));
295
+ }
296
+ getArchiveAt(checkpointNumber) {
297
+ if (checkpointNumber === 0) {
298
+ return this.config.genesisArchiveRoot;
299
+ }
300
+ // Find the latest non-pruned entry for this checkpoint number
301
+ const entries = this.checkpoints.filter((cpData)=>cpData.checkpointNumber === checkpointNumber);
302
+ const latestEntry = entries.at(-1);
303
+ if (!latestEntry || latestEntry.pruned) {
304
+ // For pruned or missing checkpoints, return the previous non-pruned checkpoint's archive
305
+ return this.getArchiveAt(CheckpointNumber(checkpointNumber - 1));
306
+ }
307
+ return latestEntry.checkpoint.archive.root;
308
+ }
309
+ getNextBlockNumber(checkpointNumber) {
310
+ const lastBlockNumber = this.checkpoints.filter((cpData)=>cpData.checkpointNumber < checkpointNumber).flatMap((cpData)=>cpData.checkpoint.blocks.map((b)=>b.number)).reduce((max, num)=>Math.max(max, num), 0);
311
+ return lastBlockNumber + 1;
312
+ }
313
+ getCheckpointProposedLogs(fromBlock, toBlock) {
314
+ return this.checkpoints.filter((cpData)=>cpData.l1BlockNumber >= fromBlock && cpData.l1BlockNumber <= toBlock).map((cpData)=>({
315
+ l1BlockNumber: cpData.l1BlockNumber,
316
+ l1BlockHash: Buffer32.fromBigInt(cpData.l1BlockNumber),
317
+ l1TransactionHash: cpData.tx.hash,
318
+ args: {
319
+ checkpointNumber: cpData.checkpointNumber,
320
+ archive: cpData.checkpoint.archive.root,
321
+ versionedBlobHashes: cpData.blobHashes.map((h)=>Buffer.from(h.slice(2), 'hex')),
322
+ attestationsHash: cpData.attestationsHash,
323
+ payloadDigest: cpData.payloadDigest
324
+ }
325
+ }));
326
+ }
327
+ getMessageSentLogs(fromBlock, toBlock, hashFilter) {
328
+ return this.messages.filter((msg)=>(!hashFilter || msg.leaf.toString() === hashFilter) && (!fromBlock || msg.l1BlockNumber >= fromBlock) && (!toBlock || msg.l1BlockNumber <= toBlock)).map((msg)=>({
329
+ l1BlockNumber: msg.l1BlockNumber,
330
+ l1BlockHash: Buffer32.fromBigInt(msg.l1BlockNumber),
331
+ l1TransactionHash: `0x${msg.l1BlockNumber.toString(16)}`,
332
+ args: {
333
+ checkpointNumber: msg.checkpointNumber,
334
+ index: msg.index,
335
+ leaf: msg.leaf,
336
+ rollingHash: msg.rollingHash
337
+ }
338
+ }));
339
+ }
340
+ async makeRollupTx(checkpoint, signers) {
341
+ const attestations = signers.map((signer)=>makeCheckpointAttestationFromCheckpoint(checkpoint, signer)).map((attestation)=>CommitteeAttestation.fromSignature(attestation.signature)).map((committeeAttestation)=>committeeAttestation.toViem());
342
+ const header = checkpoint.header.toViem();
343
+ const blobInput = getPrefixedEthBlobCommitments(await getBlobsPerL1Block(checkpoint.toBlobFields()));
344
+ const archive = toHex(checkpoint.archive.root.toBuffer());
345
+ const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations.map((attestation)=>CommitteeAttestation.fromViem(attestation)));
346
+ const attestationsAndSignersSignature = makeAndSignCommitteeAttestationsAndSigners(attestationsAndSigners, signers[0]);
347
+ const packedAttestations = attestationsAndSigners.getPackedAttestations();
348
+ const rollupInput = encodeFunctionData({
349
+ abi: RollupAbi,
350
+ functionName: 'propose',
351
+ args: [
352
+ {
353
+ header,
354
+ archive,
355
+ oracleInput: {
356
+ feeAssetPriceModifier: 0n
357
+ }
358
+ },
359
+ packedAttestations,
360
+ attestationsAndSigners.getSigners().map((signer)=>signer.toString()),
361
+ attestationsAndSignersSignature.toViemSignature(),
362
+ blobInput
363
+ ]
364
+ });
365
+ const multiCallInput = encodeFunctionData({
366
+ abi: multicall3Abi,
367
+ functionName: 'aggregate3',
368
+ args: [
369
+ [
370
+ {
371
+ target: this.config.rollupAddress.toString(),
372
+ callData: rollupInput,
373
+ allowFailure: false
374
+ }
375
+ ]
376
+ ]
377
+ });
378
+ // Compute attestationsHash (same logic as CalldataRetriever)
379
+ const attestationsHash = Buffer32.fromString(keccak256(encodeAbiParameters([
380
+ this.getCommitteeAttestationsStructDef()
381
+ ], [
382
+ packedAttestations
383
+ ])));
384
+ // Compute payloadDigest (same logic as CalldataRetriever)
385
+ const consensusPayload = ConsensusPayload.fromCheckpoint(checkpoint);
386
+ const payloadToSign = consensusPayload.getPayloadToSign(SignatureDomainSeparator.checkpointAttestation);
387
+ const payloadDigest = Buffer32.fromString(keccak256(payloadToSign));
388
+ const tx = {
389
+ input: multiCallInput,
390
+ hash: archive,
391
+ blockHash: archive,
392
+ to: MULTI_CALL_3_ADDRESS
393
+ };
394
+ return {
395
+ tx,
396
+ attestationsHash,
397
+ payloadDigest
398
+ };
399
+ }
400
+ /** Extracts the CommitteeAttestations struct definition from RollupAbi for hash computation. */ getCommitteeAttestationsStructDef() {
401
+ const proposeFunction = RollupAbi.find((item)=>item.type === 'function' && item.name === 'propose');
402
+ if (!proposeFunction) {
403
+ throw new Error('propose function not found in RollupAbi');
404
+ }
405
+ const attestationsParam = proposeFunction.inputs.find((param)=>param.name === '_attestations');
406
+ if (!attestationsParam) {
407
+ throw new Error('_attestations parameter not found in propose function');
408
+ }
409
+ const tupleParam = attestationsParam;
410
+ return {
411
+ type: 'tuple',
412
+ components: tupleParam.components || []
413
+ };
414
+ }
415
+ async makeVersionedBlobHashes(checkpoint) {
416
+ return (await getBlobsPerL1Block(checkpoint.toBlobFields())).map((b)=>`0x${b.getEthVersionedBlobHash().toString('hex')}`);
417
+ }
418
+ async makeBlobsFromCheckpoint(checkpoint) {
419
+ return await getBlobsPerL1Block(checkpoint.toBlobFields());
420
+ }
421
+ }
@@ -1,4 +1,5 @@
1
+ export * from './mock_structs.js';
1
2
  export * from './mock_l2_block_source.js';
2
3
  export * from './mock_l1_to_l2_message_source.js';
3
4
  export * from './mock_archiver.js';
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYyxtQ0FBbUMsQ0FBQztBQUNsRCxjQUFjLG9CQUFvQixDQUFDIn0=
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYywyQkFBMkIsQ0FBQztBQUMxQyxjQUFjLG1DQUFtQyxDQUFDO0FBQ2xELGNBQWMsb0JBQW9CLENBQUMifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC"}
@@ -1,3 +1,6 @@
1
+ export * from './mock_structs.js';
1
2
  export * from './mock_l2_block_source.js';
2
3
  export * from './mock_l1_to_l2_message_source.js';
3
- export * from './mock_archiver.js';
4
+ export * from './mock_archiver.js'; // NOTE: noop_l1_archiver.js is intentionally NOT exported here because it imports
5
+ // jest-mock-extended, which depends on @jest/globals and can only run inside Jest.
6
+ // Import it directly: import { NoopL1Archiver } from '@aztec/archiver/test/noop-l1';