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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +139 -22
  2. package/dest/archiver.d.ts +134 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +767 -0
  5. package/dest/{archiver/config.d.ts → config.d.ts} +9 -1
  6. package/dest/config.d.ts.map +1 -0
  7. package/dest/{archiver/config.js → config.js} +9 -0
  8. package/dest/{archiver/errors.d.ts → errors.d.ts} +1 -1
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/factory.d.ts +5 -6
  11. package/dest/factory.d.ts.map +1 -1
  12. package/dest/factory.js +82 -5
  13. package/dest/index.d.ts +10 -4
  14. package/dest/index.d.ts.map +1 -1
  15. package/dest/index.js +8 -3
  16. package/dest/interfaces.d.ts +9 -0
  17. package/dest/interfaces.d.ts.map +1 -0
  18. package/dest/interfaces.js +3 -0
  19. package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.d.ts +1 -1
  20. package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
  21. package/dest/{archiver/l1 → l1}/calldata_retriever.d.ts +2 -2
  22. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  23. package/dest/l1/data_retrieval.d.ts +88 -0
  24. package/dest/l1/data_retrieval.d.ts.map +1 -0
  25. package/dest/{archiver/l1 → l1}/data_retrieval.js +32 -51
  26. package/dest/{archiver/l1 → l1}/debug_tx.d.ts +1 -1
  27. package/dest/l1/debug_tx.d.ts.map +1 -0
  28. package/dest/{archiver/l1 → l1}/spire_proposer.d.ts +1 -1
  29. package/dest/l1/spire_proposer.d.ts.map +1 -0
  30. package/dest/{archiver/l1 → l1}/trace_tx.d.ts +1 -1
  31. package/dest/l1/trace_tx.d.ts.map +1 -0
  32. package/dest/l1/types.d.ts +12 -0
  33. package/dest/l1/types.d.ts.map +1 -0
  34. package/dest/{archiver/l1 → l1}/validate_trace.d.ts +1 -1
  35. package/dest/l1/validate_trace.d.ts.map +1 -0
  36. package/dest/modules/data_source_base.d.ts +83 -0
  37. package/dest/modules/data_source_base.d.ts.map +1 -0
  38. package/dest/modules/data_source_base.js +301 -0
  39. package/dest/modules/data_store_updater.d.ts +46 -0
  40. package/dest/modules/data_store_updater.d.ts.map +1 -0
  41. package/dest/modules/data_store_updater.js +216 -0
  42. package/dest/modules/instrumentation.d.ts +37 -0
  43. package/dest/modules/instrumentation.d.ts.map +1 -0
  44. package/dest/modules/l1_synchronizer.d.ts +67 -0
  45. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  46. package/dest/modules/l1_synchronizer.js +1064 -0
  47. package/dest/{archiver → modules}/validation.d.ts +1 -1
  48. package/dest/modules/validation.d.ts.map +1 -0
  49. package/dest/{archiver/kv_archiver_store → store}/block_store.d.ts +2 -2
  50. package/dest/store/block_store.d.ts.map +1 -0
  51. package/dest/{archiver/kv_archiver_store → store}/block_store.js +1 -1
  52. package/dest/store/contract_class_store.d.ts +18 -0
  53. package/dest/store/contract_class_store.d.ts.map +1 -0
  54. package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +1 -1
  55. package/dest/store/contract_instance_store.d.ts +24 -0
  56. package/dest/store/contract_instance_store.d.ts.map +1 -0
  57. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
  58. package/dest/{archiver/archiver_store.d.ts → store/kv_archiver_store.d.ts} +143 -139
  59. package/dest/store/kv_archiver_store.d.ts.map +1 -0
  60. package/dest/{archiver/kv_archiver_store → store}/kv_archiver_store.js +157 -49
  61. package/dest/{archiver/kv_archiver_store → store}/log_store.d.ts +1 -1
  62. package/dest/store/log_store.d.ts.map +1 -0
  63. package/dest/{archiver/kv_archiver_store → store}/message_store.d.ts +1 -1
  64. package/dest/store/message_store.d.ts.map +1 -0
  65. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  66. package/dest/structs/data_retrieval.d.ts.map +1 -0
  67. package/dest/structs/inbox_message.d.ts +15 -0
  68. package/dest/structs/inbox_message.d.ts.map +1 -0
  69. package/dest/{archiver/structs → structs}/published.d.ts +1 -1
  70. package/dest/structs/published.d.ts.map +1 -0
  71. package/dest/test/fake_l1_state.d.ts +173 -0
  72. package/dest/test/fake_l1_state.d.ts.map +1 -0
  73. package/dest/test/fake_l1_state.js +364 -0
  74. package/dest/test/index.d.ts +2 -1
  75. package/dest/test/index.d.ts.map +1 -1
  76. package/dest/test/index.js +1 -0
  77. package/dest/test/mock_structs.d.ts +76 -2
  78. package/dest/test/mock_structs.d.ts.map +1 -1
  79. package/dest/test/mock_structs.js +133 -2
  80. package/package.json +15 -17
  81. package/src/archiver.ts +522 -0
  82. package/src/{archiver/config.ts → config.ts} +11 -0
  83. package/src/factory.ts +118 -6
  84. package/src/index.ts +10 -3
  85. package/src/interfaces.ts +9 -0
  86. package/src/{archiver/l1 → l1}/calldata_retriever.ts +1 -1
  87. package/src/{archiver/l1 → l1}/data_retrieval.ts +52 -69
  88. package/src/modules/data_source_base.ts +439 -0
  89. package/src/modules/data_store_updater.ts +318 -0
  90. package/src/modules/l1_synchronizer.ts +870 -0
  91. package/src/{archiver/kv_archiver_store → store}/block_store.ts +1 -1
  92. package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +1 -1
  93. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +1 -1
  94. package/src/{archiver/kv_archiver_store → store}/kv_archiver_store.ts +170 -8
  95. package/src/test/fake_l1_state.ts +561 -0
  96. package/src/test/index.ts +1 -0
  97. package/src/test/mock_structs.ts +247 -2
  98. package/dest/archiver/archiver.d.ts +0 -307
  99. package/dest/archiver/archiver.d.ts.map +0 -1
  100. package/dest/archiver/archiver.js +0 -2102
  101. package/dest/archiver/archiver_store.d.ts.map +0 -1
  102. package/dest/archiver/archiver_store.js +0 -4
  103. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  104. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  105. package/dest/archiver/archiver_store_test_suite.js +0 -2770
  106. package/dest/archiver/config.d.ts.map +0 -1
  107. package/dest/archiver/errors.d.ts.map +0 -1
  108. package/dest/archiver/index.d.ts +0 -7
  109. package/dest/archiver/index.d.ts.map +0 -1
  110. package/dest/archiver/index.js +0 -4
  111. package/dest/archiver/instrumentation.d.ts +0 -37
  112. package/dest/archiver/instrumentation.d.ts.map +0 -1
  113. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  114. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  115. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  116. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  117. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  118. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -159
  119. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  120. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  121. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  122. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
  123. package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
  124. package/dest/archiver/l1/data_retrieval.d.ts +0 -90
  125. package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
  126. package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
  127. package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
  128. package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
  129. package/dest/archiver/l1/types.d.ts +0 -12
  130. package/dest/archiver/l1/types.d.ts.map +0 -1
  131. package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
  132. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  133. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  134. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  135. package/dest/archiver/structs/published.d.ts.map +0 -1
  136. package/dest/archiver/validation.d.ts.map +0 -1
  137. package/dest/rpc/index.d.ts +0 -9
  138. package/dest/rpc/index.d.ts.map +0 -1
  139. package/dest/rpc/index.js +0 -15
  140. package/src/archiver/archiver.ts +0 -2265
  141. package/src/archiver/archiver_store.ts +0 -380
  142. package/src/archiver/archiver_store_test_suite.ts +0 -2842
  143. package/src/archiver/index.ts +0 -6
  144. package/src/rpc/index.ts +0 -16
  145. /package/dest/{archiver/errors.js → errors.js} +0 -0
  146. /package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.js +0 -0
  147. /package/dest/{archiver/l1 → l1}/calldata_retriever.js +0 -0
  148. /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
  149. /package/dest/{archiver/l1 → l1}/spire_proposer.js +0 -0
  150. /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
  151. /package/dest/{archiver/l1 → l1}/types.js +0 -0
  152. /package/dest/{archiver/l1 → l1}/validate_trace.js +0 -0
  153. /package/dest/{archiver → modules}/instrumentation.js +0 -0
  154. /package/dest/{archiver → modules}/validation.js +0 -0
  155. /package/dest/{archiver/kv_archiver_store → store}/log_store.js +0 -0
  156. /package/dest/{archiver/kv_archiver_store → store}/message_store.js +0 -0
  157. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  158. /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
  159. /package/dest/{archiver/structs → structs}/published.js +0 -0
  160. /package/src/{archiver/errors.ts → errors.ts} +0 -0
  161. /package/src/{archiver/l1 → l1}/README.md +0 -0
  162. /package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +0 -0
  163. /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
  164. /package/src/{archiver/l1 → l1}/spire_proposer.ts +0 -0
  165. /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
  166. /package/src/{archiver/l1 → l1}/types.ts +0 -0
  167. /package/src/{archiver/l1 → l1}/validate_trace.ts +0 -0
  168. /package/src/{archiver → modules}/instrumentation.ts +0 -0
  169. /package/src/{archiver → modules}/validation.ts +0 -0
  170. /package/src/{archiver/kv_archiver_store → store}/log_store.ts +0 -0
  171. /package/src/{archiver/kv_archiver_store → store}/message_store.ts +0 -0
  172. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
  173. /package/src/{archiver/structs → structs}/inbox_message.ts +0 -0
  174. /package/src/{archiver/structs → structs}/published.ts +0 -0
@@ -0,0 +1,364 @@
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 { InboxLeaf } from '@aztec/stdlib/messaging';
9
+ import { makeAndSignCommitteeAttestationsAndSigners, makeCheckpointAttestationFromCheckpoint, mockCheckpointAndMessages } from '@aztec/stdlib/testing';
10
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
11
+ import { mock } from 'jest-mock-extended';
12
+ import { encodeFunctionData, multicall3Abi, toHex } from 'viem';
13
+ import { updateRollingHash } from '../structs/inbox_message.js';
14
+ /**
15
+ * Stateful fake for L1 data used by the archiver.
16
+ *
17
+ * This class simulates the L1 blockchain state that the archiver reads from:
18
+ * - RollupContract: status(), archiveAt(), getVersion(), getTargetCommitteeSize(), CheckpointProposed events
19
+ * - InboxContract: getState(), MessageSent events
20
+ * - PublicClient: getBlockNumber(), getBlock(), getTransaction()
21
+ * - BlobClient: getBlobSidecar()
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const fake = new FakeL1State(config);
26
+ *
27
+ * // Add checkpoint (creates messages automatically)
28
+ * const { checkpoint, messages } = await fake.addCheckpoint(CheckpointNumber(1), { l1BlockNumber: 101n });
29
+ * fake.setL1BlockNumber(105n);
30
+ *
31
+ * // Status auto-updated
32
+ * expect(fake.getRollupStatus().pendingCheckpointNumber).toEqual(CheckpointNumber(1));
33
+ * ```
34
+ */ export class FakeL1State {
35
+ config;
36
+ log;
37
+ l1BlockNumber;
38
+ checkpoints;
39
+ messages;
40
+ messagesRollingHash;
41
+ lastArchive;
42
+ provenCheckpointNumber;
43
+ targetCommitteeSize;
44
+ version;
45
+ // Computed from checkpoints based on L1 block visibility
46
+ pendingCheckpointNumber;
47
+ constructor(config){
48
+ this.config = config;
49
+ this.log = createLogger('archiver:test:fake-l1');
50
+ this.checkpoints = [];
51
+ this.messages = [];
52
+ this.messagesRollingHash = Buffer16.ZERO;
53
+ this.provenCheckpointNumber = CheckpointNumber(0);
54
+ this.targetCommitteeSize = 0;
55
+ this.version = 1n;
56
+ this.pendingCheckpointNumber = CheckpointNumber(0);
57
+ this.l1BlockNumber = config.l1StartBlock;
58
+ this.lastArchive = new AppendOnlyTreeSnapshot(config.genesisArchiveRoot, 1);
59
+ }
60
+ /**
61
+ * Adds messages for a checkpoint. Returns the message leaves.
62
+ * Auto-updates rolling hash.
63
+ *
64
+ * Note: For most use cases, use `addCheckpoint` which creates both checkpoint and messages.
65
+ * Use this method only when you need to add messages without creating a checkpoint (e.g., for reorg tests).
66
+ */ addMessages(checkpointNumber, l1BlockNumber, messageLeaves) {
67
+ messageLeaves.forEach((leaf, i)=>{
68
+ const index = InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i);
69
+ this.messagesRollingHash = updateRollingHash(this.messagesRollingHash, leaf);
70
+ this.messages.push({
71
+ l1BlockNumber,
72
+ checkpointNumber,
73
+ index,
74
+ leaf,
75
+ rollingHash: this.messagesRollingHash
76
+ });
77
+ });
78
+ }
79
+ /**
80
+ * Creates and adds a checkpoint with its L1-to-L2 messages.
81
+ * Returns both the checkpoint and the message leaves.
82
+ * Auto-chains from lastArchive, auto-updates pending status if L1 block >= checkpoint's L1 block.
83
+ */ async addCheckpoint(checkpointNumber, options) {
84
+ this.log.warn(`Adding checkpoint ${checkpointNumber}`);
85
+ const { l1BlockNumber, numBlocks = 1, txsPerBlock = 4, maxEffects, signers = [], slotNumber, previousArchive = this.lastArchive, timestamp, numL1ToL2Messages = 3, messagesL1BlockNumber = l1BlockNumber - 3n } = options;
86
+ // Create the checkpoint using the stdlib helper
87
+ // Only pass slotNumber and timestamp if they're defined to avoid overwriting defaults
88
+ const { checkpoint, messages, lastArchive } = await mockCheckpointAndMessages(checkpointNumber, {
89
+ startBlockNumber: this.getNextBlockNumber(checkpointNumber),
90
+ numBlocks,
91
+ numTxsPerBlock: txsPerBlock,
92
+ numL1ToL2Messages,
93
+ previousArchive,
94
+ ...slotNumber !== undefined ? {
95
+ slotNumber
96
+ } : {},
97
+ ...timestamp !== undefined ? {
98
+ timestamp
99
+ } : {},
100
+ ...maxEffects !== undefined ? {
101
+ maxEffects
102
+ } : {}
103
+ });
104
+ // Store the messages internally so they match the checkpoint's inHash
105
+ this.addMessages(checkpointNumber, messagesL1BlockNumber, messages);
106
+ // Create the transaction and blobs
107
+ const tx = this.makeRollupTx(checkpoint, signers);
108
+ const blobHashes = this.makeVersionedBlobHashes(checkpoint);
109
+ const blobs = this.makeBlobsFromCheckpoint(checkpoint);
110
+ // Store the checkpoint data
111
+ this.checkpoints.push({
112
+ checkpointNumber,
113
+ checkpoint,
114
+ l1BlockNumber,
115
+ tx,
116
+ blobHashes,
117
+ blobs,
118
+ signers
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
+ /**
130
+ * Sets the current L1 block number.
131
+ * Auto-updates pending checkpoint number based on visible checkpoints.
132
+ */ setL1BlockNumber(blockNumber) {
133
+ this.l1BlockNumber = blockNumber;
134
+ this.updatePendingCheckpointNumber();
135
+ }
136
+ /** Marks a checkpoint as proven. Updates provenCheckpointNumber. */ markCheckpointAsProven(checkpointNumber) {
137
+ this.provenCheckpointNumber = checkpointNumber;
138
+ }
139
+ /** Sets the target committee size for attestation validation. */ setTargetCommitteeSize(size) {
140
+ this.targetCommitteeSize = size;
141
+ }
142
+ /**
143
+ * Removes all entries for a checkpoint number (simulates L1 reorg or prune).
144
+ * Note: Does NOT remove messages for this checkpoint (use numL1ToL2Messages: 0 when re-adding).
145
+ * Auto-updates pending status.
146
+ */ removeCheckpoint(checkpointNumber) {
147
+ this.checkpoints = this.checkpoints.filter((cpData)=>cpData.checkpointNumber !== checkpointNumber);
148
+ this.updatePendingCheckpointNumber();
149
+ }
150
+ /**
151
+ * Removes messages after a given total index (simulates L1 reorg).
152
+ * Auto-updates rolling hash.
153
+ */ removeMessagesAfter(totalIndex) {
154
+ this.messages = this.messages.slice(0, totalIndex);
155
+ // Recalculate rolling hash
156
+ this.messagesRollingHash = this.messages.reduce((hash, msg)=>updateRollingHash(hash, msg.leaf), Buffer16.ZERO);
157
+ }
158
+ /**
159
+ * Simulates a pruned checkpoint by marking all entries with this number as pruned.
160
+ * The event will still be returned, but archiveAt() will return the previous checkpoint's archive
161
+ * (or genesis if no previous checkpoint), causing a mismatch that the archiver will detect.
162
+ */ markCheckpointAsPruned(checkpointNumber) {
163
+ for (const cpData of this.checkpoints){
164
+ if (cpData.checkpointNumber === checkpointNumber) {
165
+ cpData.pruned = true;
166
+ }
167
+ }
168
+ this.updatePendingCheckpointNumber();
169
+ }
170
+ /**
171
+ * Moves messages at a given L1 block to a new L1 block.
172
+ * Useful for simulating partial message visibility (messages at higher L1 blocks won't be fetched).
173
+ */ moveMessagesToL1Block(fromL1Block, toL1Block) {
174
+ this.messages.forEach((msg)=>{
175
+ if (msg.l1BlockNumber === fromL1Block) {
176
+ msg.l1BlockNumber = toL1Block;
177
+ }
178
+ });
179
+ }
180
+ /**
181
+ * Moves a specific message (by index in the messages array) to a new L1 block.
182
+ */ moveMessageAtIndexToL1Block(index, toL1Block) {
183
+ if (this.messages[index]) {
184
+ this.messages[index].l1BlockNumber = toL1Block;
185
+ }
186
+ }
187
+ /** Gets current rollup status. */ getRollupStatus() {
188
+ return {
189
+ provenCheckpointNumber: this.provenCheckpointNumber,
190
+ pendingCheckpointNumber: this.pendingCheckpointNumber,
191
+ provenArchive: this.getArchiveAt(this.provenCheckpointNumber),
192
+ pendingArchive: this.getArchiveAt(this.pendingCheckpointNumber)
193
+ };
194
+ }
195
+ /** Gets the last archive (for manual chaining if needed). */ getLastArchive() {
196
+ return this.lastArchive;
197
+ }
198
+ /** Gets the latest checkpoint entry by number (returns the last added one). */ getCheckpoint(checkpointNumber) {
199
+ return this.checkpoints.findLast((cpData)=>cpData.checkpointNumber === checkpointNumber)?.checkpoint;
200
+ }
201
+ /** Gets messages for a checkpoint. */ getMessages(checkpointNumber) {
202
+ return this.messages.filter((m)=>m.checkpointNumber === checkpointNumber).map((m)=>m.leaf);
203
+ }
204
+ /** Gets the blobs for a checkpoint. */ getCheckpointBlobs(checkpointNumber) {
205
+ return this.checkpoints.findLast((cpData)=>cpData.checkpointNumber === checkpointNumber)?.blobs ?? [];
206
+ }
207
+ /** Creates mock RollupContract that reads from this fake state. */ createMockRollupContract(_publicClient) {
208
+ const mockRollup = mock();
209
+ mockRollup.getVersion.mockImplementation(()=>Promise.resolve(this.version));
210
+ mockRollup.getTargetCommitteeSize.mockImplementation(()=>Promise.resolve(this.targetCommitteeSize));
211
+ mockRollup.archiveAt.mockImplementation((cpNum)=>Promise.resolve(this.getArchiveAt(cpNum)));
212
+ mockRollup.status.mockImplementation((localCheckpointNum)=>{
213
+ const status = this.getRollupStatus();
214
+ return Promise.resolve({
215
+ provenCheckpointNumber: status.provenCheckpointNumber,
216
+ provenArchive: status.provenArchive,
217
+ pendingCheckpointNumber: status.pendingCheckpointNumber,
218
+ pendingArchive: status.pendingArchive,
219
+ archiveOfMyCheckpoint: this.getArchiveAt(localCheckpointNum)
220
+ });
221
+ });
222
+ // Mock the wrapper method for fetching checkpoint events
223
+ mockRollup.getCheckpointProposedEvents.mockImplementation((fromBlock, toBlock)=>Promise.resolve(this.getCheckpointProposedLogs(fromBlock, toBlock)));
224
+ Object.defineProperty(mockRollup, 'address', {
225
+ get: ()=>this.config.rollupAddress.toString()
226
+ });
227
+ return mockRollup;
228
+ }
229
+ /** Creates mock InboxContract that reads from this fake state. */ createMockInboxContract(_publicClient) {
230
+ const mockInbox = mock();
231
+ mockInbox.getState.mockImplementation(()=>Promise.resolve({
232
+ messagesRollingHash: this.messagesRollingHash,
233
+ totalMessagesInserted: BigInt(this.messages.length),
234
+ treeInProgress: 0n
235
+ }));
236
+ // Mock the wrapper methods for fetching message events
237
+ mockInbox.getMessageSentEvents.mockImplementation((fromBlock, toBlock)=>Promise.resolve(this.getMessageSentLogs(fromBlock, toBlock)));
238
+ mockInbox.getMessageSentEventByHash.mockImplementation((hash, fromBlock, toBlock)=>Promise.resolve(this.getMessageSentLogs(fromBlock, toBlock, hash)));
239
+ return mockInbox;
240
+ }
241
+ /** Creates mock PublicClient that reads from this fake state. */ createMockPublicClient() {
242
+ const publicClient = mock();
243
+ publicClient.getChainId.mockResolvedValue(1);
244
+ publicClient.getBlockNumber.mockImplementation(()=>Promise.resolve(this.l1BlockNumber));
245
+ // Use async function pattern that existing test uses for getBlock
246
+ publicClient.getBlock.mockImplementation(async (args = {})=>{
247
+ const blockNum = args.blockNumber ?? await publicClient.getBlockNumber();
248
+ return {
249
+ number: blockNum,
250
+ timestamp: BigInt(blockNum) * BigInt(this.config.ethereumSlotDuration) + this.config.l1GenesisTime,
251
+ hash: Buffer32.fromBigInt(blockNum).toString()
252
+ };
253
+ });
254
+ // Use the same pattern as existing test for getTransaction
255
+ publicClient.getTransaction.mockImplementation((args)=>Promise.resolve(args.hash ? this.checkpoints.find((cpData)=>cpData.tx.hash === args.hash)?.tx : undefined));
256
+ return publicClient;
257
+ }
258
+ /** Creates mock BlobClient that reads from this fake state. */ createMockBlobClient() {
259
+ const blobClient = mock();
260
+ // The blockId is the transaction's blockHash, which we set to the checkpoint's archive root
261
+ blobClient.getBlobSidecar.mockImplementation((blockId)=>Promise.resolve(this.checkpoints.find((cpData)=>cpData.checkpoint.archive.root.toString() === blockId)?.blobs ?? []));
262
+ blobClient.testSources.mockResolvedValue(undefined);
263
+ return blobClient;
264
+ }
265
+ updatePendingCheckpointNumber() {
266
+ this.pendingCheckpointNumber = this.checkpoints.filter((cpData)=>cpData.l1BlockNumber <= this.l1BlockNumber && !cpData.pruned).reduce((max, cpData)=>cpData.checkpointNumber > max ? cpData.checkpointNumber : max, CheckpointNumber(0));
267
+ }
268
+ getArchiveAt(checkpointNumber) {
269
+ if (checkpointNumber === 0) {
270
+ return this.config.genesisArchiveRoot;
271
+ }
272
+ // Find the latest non-pruned entry for this checkpoint number
273
+ const entries = this.checkpoints.filter((cpData)=>cpData.checkpointNumber === checkpointNumber);
274
+ const latestEntry = entries.at(-1);
275
+ if (!latestEntry || latestEntry.pruned) {
276
+ // For pruned or missing checkpoints, return the previous non-pruned checkpoint's archive
277
+ return this.getArchiveAt(CheckpointNumber(checkpointNumber - 1));
278
+ }
279
+ return latestEntry.checkpoint.archive.root;
280
+ }
281
+ getNextBlockNumber(checkpointNumber) {
282
+ 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);
283
+ return lastBlockNumber + 1;
284
+ }
285
+ getCheckpointProposedLogs(fromBlock, toBlock) {
286
+ return this.checkpoints.filter((cpData)=>cpData.l1BlockNumber >= fromBlock && cpData.l1BlockNumber <= toBlock).map((cpData)=>({
287
+ l1BlockNumber: cpData.l1BlockNumber,
288
+ l1BlockHash: Buffer32.fromBigInt(cpData.l1BlockNumber),
289
+ l1TransactionHash: cpData.tx.hash,
290
+ args: {
291
+ checkpointNumber: cpData.checkpointNumber,
292
+ archive: cpData.checkpoint.archive.root,
293
+ versionedBlobHashes: cpData.blobHashes.map((h)=>Buffer.from(h.slice(2), 'hex')),
294
+ // These are intentionally undefined to skip hash validation in the archiver
295
+ // (validation is skipped when these fields are falsy)
296
+ payloadDigest: undefined,
297
+ attestationsHash: undefined
298
+ }
299
+ }));
300
+ }
301
+ getMessageSentLogs(fromBlock, toBlock, hashFilter) {
302
+ return this.messages.filter((msg)=>(!hashFilter || msg.leaf.toString() === hashFilter) && (!fromBlock || msg.l1BlockNumber >= fromBlock) && (!toBlock || msg.l1BlockNumber <= toBlock)).map((msg)=>({
303
+ l1BlockNumber: msg.l1BlockNumber,
304
+ l1BlockHash: Buffer32.fromBigInt(msg.l1BlockNumber),
305
+ l1TransactionHash: `0x${msg.l1BlockNumber.toString(16)}`,
306
+ args: {
307
+ checkpointNumber: msg.checkpointNumber,
308
+ index: msg.index,
309
+ leaf: msg.leaf,
310
+ rollingHash: msg.rollingHash
311
+ }
312
+ }));
313
+ }
314
+ makeRollupTx(checkpoint, signers) {
315
+ const attestations = signers.map((signer)=>makeCheckpointAttestationFromCheckpoint(checkpoint, signer)).map((attestation)=>CommitteeAttestation.fromSignature(attestation.signature)).map((committeeAttestation)=>committeeAttestation.toViem());
316
+ const header = checkpoint.header.toViem();
317
+ const blobInput = getPrefixedEthBlobCommitments(getBlobsPerL1Block(checkpoint.toBlobFields()));
318
+ const archive = toHex(checkpoint.archive.root.toBuffer());
319
+ const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations.map((attestation)=>CommitteeAttestation.fromViem(attestation)));
320
+ const attestationsAndSignersSignature = makeAndSignCommitteeAttestationsAndSigners(attestationsAndSigners, signers[0]);
321
+ const rollupInput = encodeFunctionData({
322
+ abi: RollupAbi,
323
+ functionName: 'propose',
324
+ args: [
325
+ {
326
+ header,
327
+ archive,
328
+ oracleInput: {
329
+ feeAssetPriceModifier: 0n
330
+ }
331
+ },
332
+ attestationsAndSigners.getPackedAttestations(),
333
+ attestationsAndSigners.getSigners().map((signer)=>signer.toString()),
334
+ attestationsAndSignersSignature.toViemSignature(),
335
+ blobInput
336
+ ]
337
+ });
338
+ const multiCallInput = encodeFunctionData({
339
+ abi: multicall3Abi,
340
+ functionName: 'aggregate3',
341
+ args: [
342
+ [
343
+ {
344
+ target: this.config.rollupAddress.toString(),
345
+ callData: rollupInput,
346
+ allowFailure: false
347
+ }
348
+ ]
349
+ ]
350
+ });
351
+ return {
352
+ input: multiCallInput,
353
+ hash: archive,
354
+ blockHash: archive,
355
+ to: MULTI_CALL_3_ADDRESS
356
+ };
357
+ }
358
+ makeVersionedBlobHashes(checkpoint) {
359
+ return getBlobsPerL1Block(checkpoint.toBlobFields()).map((b)=>`0x${b.getEthVersionedBlobHash().toString('hex')}`);
360
+ }
361
+ makeBlobsFromCheckpoint(checkpoint) {
362
+ return getBlobsPerL1Block(checkpoint.toBlobFields());
363
+ }
364
+ }
@@ -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,4 @@
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';
@@ -1,10 +1,84 @@
1
1
  import { CheckpointNumber } from '@aztec/foundation/branded-types';
2
2
  import { Buffer16 } from '@aztec/foundation/buffer';
3
- import { type InboxMessage } from '../archiver/structs/inbox_message.js';
3
+ import type { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
4
+ import { EthAddress } from '@aztec/foundation/eth-address';
5
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
+ import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
7
+ import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs';
8
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
9
+ import { StateReference } from '@aztec/stdlib/tx';
10
+ import { type InboxMessage } from '../structs/inbox_message.js';
4
11
  export declare function makeInboxMessage(previousRollingHash?: Buffer16, overrides?: Partial<InboxMessage>): InboxMessage;
5
12
  export declare function makeInboxMessages(count: number, opts?: {
6
13
  initialHash?: Buffer16;
7
14
  initialCheckpointNumber?: CheckpointNumber;
8
15
  overrideFn?: (msg: InboxMessage, index: number) => InboxMessage;
9
16
  }): InboxMessage[];
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9ja19zdHJ1Y3RzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC9tb2NrX3N0cnVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbkUsT0FBTyxFQUFFLFFBQVEsRUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBSzlELE9BQU8sRUFBRSxLQUFLLFlBQVksRUFBcUIsTUFBTSxzQ0FBc0MsQ0FBQztBQUU1Rix3QkFBZ0IsZ0JBQWdCLENBQzlCLG1CQUFtQixXQUFnQixFQUNuQyxTQUFTLEdBQUUsT0FBTyxDQUFDLFlBQVksQ0FBTSxHQUNwQyxZQUFZLENBZ0JkO0FBRUQsd0JBQWdCLGlCQUFpQixDQUMvQixLQUFLLEVBQUUsTUFBTSxFQUNiLElBQUksR0FBRTtJQUNKLFdBQVcsQ0FBQyxFQUFFLFFBQVEsQ0FBQztJQUN2Qix1QkFBdUIsQ0FBQyxFQUFFLGdCQUFnQixDQUFDO0lBQzNDLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxLQUFLLFlBQVksQ0FBQztDQUM1RCxHQUNMLFlBQVksRUFBRSxDQWFoQiJ9
17
+ /** Creates inbox messages distributed across multiple blocks with proper checkpoint numbering. */
18
+ export declare function makeInboxMessagesWithFullBlocks(blockCount: number, opts?: {
19
+ initialCheckpointNumber?: CheckpointNumber;
20
+ }): InboxMessage[];
21
+ /** Creates a deterministic block hash from a block number. */
22
+ export declare function makeBlockHash(blockNumber: number): `0x${string}`;
23
+ /**
24
+ * Creates a StateReference with properly calculated noteHashTree.nextAvailableLeafIndex.
25
+ * This ensures LogStore's dataStartIndexForBlock calculation doesn't produce negative values.
26
+ */
27
+ export declare function makeStateForBlock(blockNumber: number, txsPerBlock: number): StateReference;
28
+ /** Creates L1PublishedData with deterministic values based on l1BlockNumber. */
29
+ export declare function makeL1PublishedData(l1BlockNumber: number): L1PublishedData;
30
+ /** Wraps a Checkpoint with L1 published data and random attestations. */
31
+ export declare function makePublishedCheckpoint(checkpoint: Checkpoint, l1BlockNumber: number, attestationCount?: number): PublishedCheckpoint;
32
+ export interface MakeChainedCheckpointsOptions {
33
+ /** Number of L2 blocks per checkpoint. Default: 1 */
34
+ blocksPerCheckpoint?: number;
35
+ /** Number of transactions per block. Default: 4 */
36
+ txsPerBlock?: number;
37
+ /** Starting checkpoint number. Default: CheckpointNumber(1) */
38
+ startCheckpointNumber?: CheckpointNumber;
39
+ /** Starting block number. Default: 1 */
40
+ startBlockNumber?: number;
41
+ /** Starting L1 block number. Default: 10 */
42
+ startL1BlockNumber?: number;
43
+ /** Previous archive to chain from. Default: undefined */
44
+ previousArchive?: AppendOnlyTreeSnapshot;
45
+ /** Optional function to provide per-checkpoint overrides */
46
+ makeCheckpointOptions?: (cpNumber: CheckpointNumber) => Partial<Parameters<typeof Checkpoint.random>[1]>;
47
+ }
48
+ /**
49
+ * Creates multiple checkpoints with properly chained archives.
50
+ * Each checkpoint's blocks have their lastArchive set to the previous block's archive,
51
+ * ensuring archive chain continuity for testing.
52
+ */
53
+ export declare function makeChainedCheckpoints(count: number, options?: MakeChainedCheckpointsOptions): Promise<PublishedCheckpoint[]>;
54
+ /**
55
+ * Creates a PublishedCheckpoint with attestations signed by the provided signers.
56
+ * Useful for testing attestation validation.
57
+ */
58
+ export declare function makeSignedPublishedCheckpoint(checkpoint: Checkpoint, signers: Secp256k1Signer[], committee: EthAddress[], l1BlockNumber?: number): PublishedCheckpoint;
59
+ /** Creates a deterministic SiloedTag for private log testing. */
60
+ export declare function makePrivateLogTag(blockNumber: number, txIndex: number, logIndex: number): SiloedTag;
61
+ /** Creates a PrivateLog with fields derived from the tag. */
62
+ export declare function makePrivateLog(tag: SiloedTag): PrivateLog;
63
+ /** Creates multiple private logs for a transaction. */
64
+ export declare function mockPrivateLogs(blockNumber: number, txIndex: number, numLogsPerTx: number): PrivateLog[];
65
+ /** Creates a deterministic Tag for public log testing. */
66
+ export declare function makePublicLogTag(blockNumber: number, txIndex: number, logIndex: number): Tag;
67
+ /** Creates a PublicLog with fields derived from the tag. */
68
+ export declare function makePublicLog(tag: Tag, contractAddress?: AztecAddress): PublicLog;
69
+ /** Creates multiple public logs for a transaction. */
70
+ export declare function makePublicLogs(blockNumber: number, txIndex: number, numLogsPerTx: number, contractAddress?: AztecAddress): PublicLog[];
71
+ export interface MockCheckpointWithLogsOptions {
72
+ previousArchive?: AppendOnlyTreeSnapshot;
73
+ numTxsPerBlock?: number;
74
+ privateLogs?: {
75
+ numLogsPerTx: number;
76
+ };
77
+ publicLogs?: {
78
+ numLogsPerTx: number;
79
+ contractAddress?: AztecAddress;
80
+ };
81
+ }
82
+ /** Creates a checkpoint with specified logs on each tx effect. */
83
+ export declare function makeCheckpointWithLogs(blockNumber: number, options?: MockCheckpointWithLogsOptions): Promise<PublishedCheckpoint>;
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9ja19zdHJ1Y3RzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC9tb2NrX3N0cnVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFlLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEYsT0FBTyxFQUFFLFFBQVEsRUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBRzlELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBRWpGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFM0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RixPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFLM0UsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDN0QsT0FBTyxFQUF5QixjQUFjLEVBQVksTUFBTSxrQkFBa0IsQ0FBQztBQUVuRixPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQXFCLE1BQU0sNkJBQTZCLENBQUM7QUFFbkYsd0JBQWdCLGdCQUFnQixDQUM5QixtQkFBbUIsV0FBZ0IsRUFDbkMsU0FBUyxHQUFFLE9BQU8sQ0FBQyxZQUFZLENBQU0sR0FDcEMsWUFBWSxDQWdCZDtBQUVELHdCQUFnQixpQkFBaUIsQ0FDL0IsS0FBSyxFQUFFLE1BQU0sRUFDYixJQUFJLEdBQUU7SUFDSixXQUFXLENBQUMsRUFBRSxRQUFRLENBQUM7SUFDdkIsdUJBQXVCLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQztJQUMzQyxVQUFVLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sS0FBSyxZ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
@@ -1 +1 @@
1
- {"version":3,"file":"mock_structs.d.ts","sourceRoot":"","sources":["../../src/test/mock_structs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAK9D,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,sCAAsC,CAAC;AAE5F,wBAAgB,gBAAgB,CAC9B,mBAAmB,WAAgB,EACnC,SAAS,GAAE,OAAO,CAAC,YAAY,CAAM,GACpC,YAAY,CAgBd;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IACJ,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,uBAAuB,CAAC,EAAE,gBAAgB,CAAC;IAC3C,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC;CAC5D,GACL,YAAY,EAAE,CAahB"}
1
+ {"version":3,"file":"mock_structs.d.ts","sourceRoot":"","sources":["../../src/test/mock_structs.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,21 @@
1
- import { CheckpointNumber } from '@aztec/foundation/branded-types';
1
+ import { MAX_NOTE_HASHES_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
2
+ import { makeTuple } from '@aztec/foundation/array';
3
+ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
2
4
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
5
+ import { times, timesParallel } from '@aztec/foundation/collection';
3
6
  import { randomBigInt, randomInt } from '@aztec/foundation/crypto/random';
4
7
  import { Fr } from '@aztec/foundation/curves/bn254';
8
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
9
+ import { CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
10
+ import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
11
+ import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs';
5
12
  import { InboxLeaf } from '@aztec/stdlib/messaging';
6
- import { updateRollingHash } from '../archiver/structs/inbox_message.js';
13
+ import { orderAttestations } from '@aztec/stdlib/p2p';
14
+ import { CheckpointHeader } from '@aztec/stdlib/rollup';
15
+ import { makeCheckpointAttestationFromCheckpoint } from '@aztec/stdlib/testing';
16
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
17
+ import { PartialStateReference, StateReference, TxEffect } from '@aztec/stdlib/tx';
18
+ import { updateRollingHash } from '../structs/inbox_message.js';
7
19
  export function makeInboxMessage(previousRollingHash = Buffer16.ZERO, overrides = {}) {
8
20
  const { checkpointNumber = CheckpointNumber(randomInt(100) + 1) } = overrides;
9
21
  const { l1BlockNumber = randomBigInt(100n) + 1n } = overrides;
@@ -36,3 +48,122 @@ export function makeInboxMessages(count, opts = {}) {
36
48
  }
37
49
  return messages;
38
50
  }
51
+ /** Creates inbox messages distributed across multiple blocks with proper checkpoint numbering. */ export function makeInboxMessagesWithFullBlocks(blockCount, opts = {}) {
52
+ const { initialCheckpointNumber = CheckpointNumber(13) } = opts;
53
+ return makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
54
+ overrideFn: (msg, i)=>{
55
+ const checkpointNumber = CheckpointNumber(initialCheckpointNumber + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP));
56
+ const index = InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
57
+ return {
58
+ ...msg,
59
+ checkpointNumber,
60
+ index
61
+ };
62
+ }
63
+ });
64
+ }
65
+ /** Creates a deterministic block hash from a block number. */ export function makeBlockHash(blockNumber) {
66
+ return `0x${blockNumber.toString(16).padStart(64, '0')}`;
67
+ }
68
+ /**
69
+ * Creates a StateReference with properly calculated noteHashTree.nextAvailableLeafIndex.
70
+ * This ensures LogStore's dataStartIndexForBlock calculation doesn't produce negative values.
71
+ */ export function makeStateForBlock(blockNumber, txsPerBlock) {
72
+ const noteHashIndex = blockNumber * txsPerBlock * MAX_NOTE_HASHES_PER_TX;
73
+ return new StateReference(AppendOnlyTreeSnapshot.random(), new PartialStateReference(new AppendOnlyTreeSnapshot(Fr.random(), noteHashIndex), AppendOnlyTreeSnapshot.random(), AppendOnlyTreeSnapshot.random()));
74
+ }
75
+ /** Creates L1PublishedData with deterministic values based on l1BlockNumber. */ export function makeL1PublishedData(l1BlockNumber) {
76
+ return new L1PublishedData(BigInt(l1BlockNumber), BigInt(l1BlockNumber * 1000), makeBlockHash(l1BlockNumber));
77
+ }
78
+ /** Wraps a Checkpoint with L1 published data and random attestations. */ export function makePublishedCheckpoint(checkpoint, l1BlockNumber, attestationCount = 3) {
79
+ return new PublishedCheckpoint(checkpoint, makeL1PublishedData(l1BlockNumber), times(attestationCount, CommitteeAttestation.random));
80
+ }
81
+ /**
82
+ * Creates multiple checkpoints with properly chained archives.
83
+ * Each checkpoint's blocks have their lastArchive set to the previous block's archive,
84
+ * ensuring archive chain continuity for testing.
85
+ */ export async function makeChainedCheckpoints(count, options = {}) {
86
+ const { blocksPerCheckpoint = 1, txsPerBlock = 4, startCheckpointNumber = CheckpointNumber(1), startBlockNumber = 1, startL1BlockNumber = 10, makeCheckpointOptions } = options;
87
+ let previousArchive = options.previousArchive;
88
+ const checkpoints = [];
89
+ for(let i = 0; i < count; i++){
90
+ const cpNumber = CheckpointNumber(startCheckpointNumber + i);
91
+ const blockStart = startBlockNumber + i * blocksPerCheckpoint;
92
+ const customOptions = makeCheckpointOptions?.(cpNumber) ?? {};
93
+ const checkpoint = await Checkpoint.random(cpNumber, {
94
+ numBlocks: blocksPerCheckpoint,
95
+ startBlockNumber: blockStart,
96
+ previousArchive,
97
+ txsPerBlock,
98
+ state: makeStateForBlock(blockStart, txsPerBlock),
99
+ txOptions: {
100
+ numPublicCallsPerTx: 2,
101
+ numPublicLogsPerCall: 2
102
+ },
103
+ ...customOptions
104
+ });
105
+ previousArchive = checkpoint.blocks.at(-1).archive;
106
+ checkpoints.push(makePublishedCheckpoint(checkpoint, startL1BlockNumber + i * 10));
107
+ }
108
+ return checkpoints;
109
+ }
110
+ /**
111
+ * Creates a PublishedCheckpoint with attestations signed by the provided signers.
112
+ * Useful for testing attestation validation.
113
+ */ export function makeSignedPublishedCheckpoint(checkpoint, signers, committee, l1BlockNumber = 1) {
114
+ const attestations = signers.map((signer)=>makeCheckpointAttestationFromCheckpoint(checkpoint, signer));
115
+ const committeeAttestations = orderAttestations(attestations, committee);
116
+ return new PublishedCheckpoint(checkpoint, makeL1PublishedData(l1BlockNumber), committeeAttestations);
117
+ }
118
+ /** Creates a deterministic SiloedTag for private log testing. */ export function makePrivateLogTag(blockNumber, txIndex, logIndex) {
119
+ return new SiloedTag(blockNumber === 1 && txIndex === 0 && logIndex === 0 ? Fr.ZERO : new Fr(blockNumber * 100 + txIndex * 10 + logIndex));
120
+ }
121
+ /** Creates a PrivateLog with fields derived from the tag. */ export function makePrivateLog(tag) {
122
+ return PrivateLog.from({
123
+ fields: makeTuple(PRIVATE_LOG_SIZE_IN_FIELDS, (i)=>!i ? tag.value : new Fr(tag.value.toBigInt() + BigInt(i))),
124
+ emittedLength: PRIVATE_LOG_SIZE_IN_FIELDS
125
+ });
126
+ }
127
+ /** Creates multiple private logs for a transaction. */ export function mockPrivateLogs(blockNumber, txIndex, numLogsPerTx) {
128
+ return times(numLogsPerTx, (logIndex)=>{
129
+ const tag = makePrivateLogTag(blockNumber, txIndex, logIndex);
130
+ return makePrivateLog(tag);
131
+ });
132
+ }
133
+ /** Creates a deterministic Tag for public log testing. */ export function makePublicLogTag(blockNumber, txIndex, logIndex) {
134
+ return new Tag(blockNumber === 1 && txIndex === 0 && logIndex === 0 ? Fr.ZERO : new Fr((blockNumber * 100 + txIndex * 10 + logIndex) * 123));
135
+ }
136
+ /** Creates a PublicLog with fields derived from the tag. */ export function makePublicLog(tag, contractAddress = AztecAddress.fromNumber(543254)) {
137
+ return PublicLog.from({
138
+ contractAddress,
139
+ fields: new Array(10).fill(null).map((_, i)=>!i ? tag.value : new Fr(tag.value.toBigInt() + BigInt(i)))
140
+ });
141
+ }
142
+ /** Creates multiple public logs for a transaction. */ export function makePublicLogs(blockNumber, txIndex, numLogsPerTx, contractAddress = AztecAddress.fromNumber(543254)) {
143
+ return times(numLogsPerTx, (logIndex)=>{
144
+ const tag = makePublicLogTag(blockNumber, txIndex, logIndex);
145
+ return makePublicLog(tag, contractAddress);
146
+ });
147
+ }
148
+ /** Creates a checkpoint with specified logs on each tx effect. */ export async function makeCheckpointWithLogs(blockNumber, options = {}) {
149
+ const { previousArchive, numTxsPerBlock = 4, privateLogs, publicLogs } = options;
150
+ const block = await L2BlockNew.random(BlockNumber(blockNumber), {
151
+ checkpointNumber: CheckpointNumber(blockNumber),
152
+ indexWithinCheckpoint: 0,
153
+ state: makeStateForBlock(blockNumber, numTxsPerBlock),
154
+ ...previousArchive ? {
155
+ lastArchive: previousArchive
156
+ } : {}
157
+ });
158
+ block.header.globalVariables.blockNumber = BlockNumber(blockNumber);
159
+ block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex)=>{
160
+ const txEffect = await TxEffect.random();
161
+ txEffect.privateLogs = privateLogs ? mockPrivateLogs(blockNumber, txIndex, privateLogs.numLogsPerTx) : [];
162
+ txEffect.publicLogs = publicLogs ? makePublicLogs(blockNumber, txIndex, publicLogs.numLogsPerTx, publicLogs.contractAddress) : [];
163
+ return txEffect;
164
+ });
165
+ const checkpoint = new Checkpoint(AppendOnlyTreeSnapshot.random(), CheckpointHeader.random(), [
166
+ block
167
+ ], CheckpointNumber(blockNumber));
168
+ return makePublishedCheckpoint(checkpoint, blockNumber);
169
+ }