@aztec/archiver 0.0.1-commit.7d4e6cd → 0.0.1-commit.9372f48

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 (191) hide show
  1. package/README.md +156 -22
  2. package/dest/archiver.d.ts +136 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +781 -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/errors.d.ts +41 -0
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/{archiver/errors.js → errors.js} +8 -0
  11. package/dest/factory.d.ts +9 -7
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +89 -11
  14. package/dest/index.d.ts +10 -4
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +8 -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/{archiver/l1 → l1}/bin/retrieve-calldata.d.ts +1 -1
  21. package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
  22. package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.js +2 -2
  23. package/dest/{archiver/l1 → l1}/calldata_retriever.d.ts +2 -2
  24. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  25. package/dest/l1/data_retrieval.d.ts +88 -0
  26. package/dest/l1/data_retrieval.d.ts.map +1 -0
  27. package/dest/{archiver/l1 → l1}/data_retrieval.js +36 -55
  28. package/dest/{archiver/l1 → l1}/debug_tx.d.ts +1 -1
  29. package/dest/l1/debug_tx.d.ts.map +1 -0
  30. package/dest/{archiver/l1 → l1}/spire_proposer.d.ts +1 -1
  31. package/dest/l1/spire_proposer.d.ts.map +1 -0
  32. package/dest/{archiver/l1 → l1}/trace_tx.d.ts +1 -1
  33. package/dest/l1/trace_tx.d.ts.map +1 -0
  34. package/dest/l1/types.d.ts +12 -0
  35. package/dest/l1/types.d.ts.map +1 -0
  36. package/dest/{archiver/l1 → l1}/validate_trace.d.ts +6 -3
  37. package/dest/l1/validate_trace.d.ts.map +1 -0
  38. package/dest/{archiver/l1 → l1}/validate_trace.js +13 -9
  39. package/dest/modules/data_source_base.d.ts +84 -0
  40. package/dest/modules/data_source_base.d.ts.map +1 -0
  41. package/dest/modules/data_source_base.js +260 -0
  42. package/dest/modules/data_store_updater.d.ts +73 -0
  43. package/dest/modules/data_store_updater.d.ts.map +1 -0
  44. package/dest/modules/data_store_updater.js +302 -0
  45. package/dest/modules/instrumentation.d.ts +37 -0
  46. package/dest/modules/instrumentation.d.ts.map +1 -0
  47. package/dest/{archiver → modules}/instrumentation.js +17 -10
  48. package/dest/modules/l1_synchronizer.d.ts +75 -0
  49. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  50. package/dest/modules/l1_synchronizer.js +1112 -0
  51. package/dest/{archiver → modules}/validation.d.ts +1 -1
  52. package/dest/modules/validation.d.ts.map +1 -0
  53. package/dest/{archiver → modules}/validation.js +6 -0
  54. package/dest/store/block_store.d.ts +192 -0
  55. package/dest/store/block_store.d.ts.map +1 -0
  56. package/dest/{archiver/kv_archiver_store → store}/block_store.js +142 -47
  57. package/dest/store/contract_class_store.d.ts +18 -0
  58. package/dest/store/contract_class_store.d.ts.map +1 -0
  59. package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +12 -8
  60. package/dest/store/contract_instance_store.d.ts +24 -0
  61. package/dest/store/contract_instance_store.d.ts.map +1 -0
  62. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
  63. package/dest/store/kv_archiver_store.d.ts +340 -0
  64. package/dest/store/kv_archiver_store.d.ts.map +1 -0
  65. package/dest/store/kv_archiver_store.js +446 -0
  66. package/dest/store/log_store.d.ts +54 -0
  67. package/dest/store/log_store.d.ts.map +1 -0
  68. package/dest/{archiver/kv_archiver_store → store}/log_store.js +91 -56
  69. package/dest/{archiver/kv_archiver_store → store}/message_store.d.ts +1 -1
  70. package/dest/store/message_store.d.ts.map +1 -0
  71. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  72. package/dest/structs/data_retrieval.d.ts.map +1 -0
  73. package/dest/structs/inbox_message.d.ts +15 -0
  74. package/dest/structs/inbox_message.d.ts.map +1 -0
  75. package/dest/{archiver/structs → structs}/published.d.ts +1 -1
  76. package/dest/structs/published.d.ts.map +1 -0
  77. package/dest/test/fake_l1_state.d.ts +190 -0
  78. package/dest/test/fake_l1_state.d.ts.map +1 -0
  79. package/dest/test/fake_l1_state.js +383 -0
  80. package/dest/test/index.d.ts +2 -1
  81. package/dest/test/index.d.ts.map +1 -1
  82. package/dest/test/index.js +4 -1
  83. package/dest/test/mock_archiver.d.ts +2 -2
  84. package/dest/test/mock_archiver.d.ts.map +1 -1
  85. package/dest/test/mock_archiver.js +1 -2
  86. package/dest/test/mock_l2_block_source.d.ts +20 -17
  87. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  88. package/dest/test/mock_l2_block_source.js +108 -48
  89. package/dest/test/mock_structs.d.ts +78 -3
  90. package/dest/test/mock_structs.d.ts.map +1 -1
  91. package/dest/test/mock_structs.js +140 -7
  92. package/dest/test/noop_l1_archiver.d.ts +23 -0
  93. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  94. package/dest/test/noop_l1_archiver.js +68 -0
  95. package/package.json +16 -17
  96. package/src/archiver.ts +543 -0
  97. package/src/{archiver/config.ts → config.ts} +11 -0
  98. package/src/{archiver/errors.ts → errors.ts} +12 -0
  99. package/src/factory.ts +125 -11
  100. package/src/index.ts +10 -3
  101. package/src/interfaces.ts +9 -0
  102. package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +7 -2
  103. package/src/{archiver/l1 → l1}/calldata_retriever.ts +1 -1
  104. package/src/{archiver/l1 → l1}/data_retrieval.ts +57 -74
  105. package/src/{archiver/l1 → l1}/validate_trace.ts +24 -6
  106. package/src/modules/data_source_base.ts +367 -0
  107. package/src/modules/data_store_updater.ts +423 -0
  108. package/src/{archiver → modules}/instrumentation.ts +17 -12
  109. package/src/modules/l1_synchronizer.ts +930 -0
  110. package/src/{archiver → modules}/validation.ts +5 -0
  111. package/src/{archiver/kv_archiver_store → store}/block_store.ts +179 -63
  112. package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +12 -8
  113. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +1 -1
  114. package/src/{archiver/kv_archiver_store → store}/kv_archiver_store.ts +234 -37
  115. package/src/{archiver/kv_archiver_store → store}/log_store.ts +149 -90
  116. package/src/test/fake_l1_state.ts +599 -0
  117. package/src/test/index.ts +4 -0
  118. package/src/test/mock_archiver.ts +2 -2
  119. package/src/test/mock_l2_block_source.ts +114 -66
  120. package/src/test/mock_structs.ts +269 -8
  121. package/src/test/noop_l1_archiver.ts +109 -0
  122. package/dest/archiver/archiver.d.ts +0 -307
  123. package/dest/archiver/archiver.d.ts.map +0 -1
  124. package/dest/archiver/archiver.js +0 -2102
  125. package/dest/archiver/archiver_store.d.ts +0 -315
  126. package/dest/archiver/archiver_store.d.ts.map +0 -1
  127. package/dest/archiver/archiver_store.js +0 -4
  128. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  129. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  130. package/dest/archiver/archiver_store_test_suite.js +0 -2770
  131. package/dest/archiver/config.d.ts.map +0 -1
  132. package/dest/archiver/errors.d.ts +0 -36
  133. package/dest/archiver/errors.d.ts.map +0 -1
  134. package/dest/archiver/index.d.ts +0 -7
  135. package/dest/archiver/index.d.ts.map +0 -1
  136. package/dest/archiver/index.js +0 -4
  137. package/dest/archiver/instrumentation.d.ts +0 -37
  138. package/dest/archiver/instrumentation.d.ts.map +0 -1
  139. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -164
  140. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  141. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  142. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  143. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  144. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  145. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -159
  146. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  147. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -316
  148. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -45
  149. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  150. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  151. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
  152. package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
  153. package/dest/archiver/l1/data_retrieval.d.ts +0 -90
  154. package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
  155. package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
  156. package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
  157. package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
  158. package/dest/archiver/l1/types.d.ts +0 -12
  159. package/dest/archiver/l1/types.d.ts.map +0 -1
  160. package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
  161. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  162. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  163. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  164. package/dest/archiver/structs/published.d.ts.map +0 -1
  165. package/dest/archiver/validation.d.ts.map +0 -1
  166. package/dest/rpc/index.d.ts +0 -9
  167. package/dest/rpc/index.d.ts.map +0 -1
  168. package/dest/rpc/index.js +0 -15
  169. package/src/archiver/archiver.ts +0 -2265
  170. package/src/archiver/archiver_store.ts +0 -380
  171. package/src/archiver/archiver_store_test_suite.ts +0 -2842
  172. package/src/archiver/index.ts +0 -6
  173. package/src/rpc/index.ts +0 -16
  174. /package/dest/{archiver/l1 → l1}/calldata_retriever.js +0 -0
  175. /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
  176. /package/dest/{archiver/l1 → l1}/spire_proposer.js +0 -0
  177. /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
  178. /package/dest/{archiver/l1 → l1}/types.js +0 -0
  179. /package/dest/{archiver/kv_archiver_store → store}/message_store.js +0 -0
  180. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  181. /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
  182. /package/dest/{archiver/structs → structs}/published.js +0 -0
  183. /package/src/{archiver/l1 → l1}/README.md +0 -0
  184. /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
  185. /package/src/{archiver/l1 → l1}/spire_proposer.ts +0 -0
  186. /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
  187. /package/src/{archiver/l1 → l1}/types.ts +0 -0
  188. /package/src/{archiver/kv_archiver_store → store}/message_store.ts +0 -0
  189. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
  190. /package/src/{archiver/structs → structs}/inbox_message.ts +0 -0
  191. /package/src/{archiver/structs → structs}/published.ts +0 -0
@@ -8,19 +8,17 @@ import { createLogger } from '@aztec/foundation/log';
8
8
  import type { FunctionSelector } from '@aztec/stdlib/abi';
9
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
10
10
  import {
11
+ BlockHash,
11
12
  CheckpointedL2Block,
12
13
  L2Block,
13
- L2BlockHash,
14
- L2BlockNew,
15
14
  type L2BlockSource,
16
15
  type L2Tips,
17
- PublishedL2Block,
18
16
  type ValidateCheckpointResult,
19
17
  } from '@aztec/stdlib/block';
20
- import { type Checkpoint, L1PublishedData } from '@aztec/stdlib/checkpoint';
18
+ import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
21
19
  import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
22
20
  import { EmptyL1RollupConstants, type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
23
- import { type BlockHeader, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
21
+ import { type BlockHeader, TxExecutionResult, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
24
22
  import type { UInt64 } from '@aztec/stdlib/types';
25
23
 
26
24
  /**
@@ -38,16 +36,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
38
36
  public async createBlocks(numBlocks: number) {
39
37
  for (let i = 0; i < numBlocks; i++) {
40
38
  const blockNum = this.l2Blocks.length + 1;
41
- const block = await L2Block.random(BlockNumber(blockNum));
39
+ const block = await L2Block.random(BlockNumber(blockNum), { slotNumber: SlotNumber(blockNum) });
42
40
  this.l2Blocks.push(block);
43
41
  }
44
42
 
45
43
  this.log.verbose(`Created ${numBlocks} blocks in the mock L2 block source`);
46
44
  }
47
45
 
48
- public addBlocks(blocks: L2Block[]) {
46
+ public addProposedBlocks(blocks: L2Block[]) {
49
47
  this.l2Blocks.push(...blocks);
50
- this.log.verbose(`Added ${blocks.length} blocks to the mock L2 block source`);
48
+ this.log.verbose(`Added ${blocks.length} proposed blocks to the mock L2 block source`);
51
49
  }
52
50
 
53
51
  public removeBlocks(numBlocks: number) {
@@ -98,6 +96,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
98
96
  return Promise.resolve(BlockNumber(this.provenBlockNumber));
99
97
  }
100
98
 
99
+ public getCheckpointedL2BlockNumber() {
100
+ return Promise.resolve(BlockNumber(this.checkpointedBlockNumber));
101
+ }
102
+
103
+ public getFinalizedL2BlockNumber() {
104
+ return Promise.resolve(BlockNumber(this.finalizedBlockNumber));
105
+ }
106
+
101
107
  public getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
102
108
  if (number > this.checkpointedBlockNumber) {
103
109
  return Promise.resolve(undefined);
@@ -107,19 +113,15 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
107
113
  return Promise.resolve(undefined);
108
114
  }
109
115
  const checkpointedBlock = new CheckpointedL2Block(
110
- CheckpointNumber(number),
111
- block.toL2Block(),
116
+ CheckpointNumber.fromBlockNumber(number),
117
+ block,
112
118
  new L1PublishedData(BigInt(number), BigInt(number), `0x${number.toString(16).padStart(64, '0')}`),
113
119
  [],
114
120
  );
115
121
  return Promise.resolve(checkpointedBlock);
116
122
  }
117
123
 
118
- public async getCheckpointedBlocks(
119
- from: BlockNumber,
120
- limit: number,
121
- _proven?: boolean,
122
- ): Promise<CheckpointedL2Block[]> {
124
+ public async getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
123
125
  const result: CheckpointedL2Block[] = [];
124
126
  for (let i = 0; i < limit; i++) {
125
127
  const blockNum = from + i;
@@ -139,8 +141,9 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
139
141
  * @param number - The block number to return (inclusive).
140
142
  * @returns The requested L2 block.
141
143
  */
142
- public getBlock(number: number) {
143
- return Promise.resolve(this.l2Blocks[number - 1]);
144
+ public getBlock(number: number): Promise<L2Block | undefined> {
145
+ const block = this.l2Blocks[number - 1];
146
+ return Promise.resolve(block);
144
147
  }
145
148
 
146
149
  /**
@@ -148,9 +151,9 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
148
151
  * @param number - The block number to return.
149
152
  * @returns The requested L2 block.
150
153
  */
151
- public getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
154
+ public getL2Block(number: BlockNumber): Promise<L2Block | undefined> {
152
155
  const block = this.l2Blocks[number - 1];
153
- return Promise.resolve(block?.toL2Block());
156
+ return Promise.resolve(block);
154
157
  }
155
158
 
156
159
  /**
@@ -159,45 +162,45 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
159
162
  * @param limit - The maximum number of blocks to return.
160
163
  * @returns The requested mocked L2 blocks.
161
164
  */
162
- public getBlocks(from: number, limit: number, proven?: boolean) {
163
- return Promise.resolve(
164
- this.l2Blocks
165
- .slice(from - 1, from - 1 + limit)
166
- .filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber),
167
- );
168
- }
169
-
170
- public async getPublishedCheckpoints(from: CheckpointNumber, limit: number) {
171
- // TODO: Implement this properly. This only works when we have one block per checkpoint.
172
- return (await this.getPublishedBlocks(from, limit)).map(block => block.toPublishedCheckpoint());
173
- }
174
-
175
- public async getCheckpointByArchive(archive: Fr): Promise<Checkpoint | undefined> {
176
- // TODO: Implement this properly. This only works when we have one block per checkpoint.
177
- return (await this.getPublishedBlockByArchive(archive))?.block.toCheckpoint();
178
- }
179
-
180
- public async getPublishedBlocks(from: number, limit: number, proven?: boolean) {
181
- const blocks = await this.getBlocks(from, limit, proven);
182
- return blocks.map(block =>
183
- PublishedL2Block.fromFields({
184
- block,
185
- l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
186
- attestations: [],
165
+ public getBlocks(from: number, limit: number): Promise<L2Block[]> {
166
+ return Promise.resolve(this.l2Blocks.slice(from - 1, from - 1 + limit));
167
+ }
168
+
169
+ public getCheckpoints(from: CheckpointNumber, limit: number) {
170
+ // TODO(mbps): Implement this properly. This only works when we have one block per checkpoint.
171
+ const blocks = this.l2Blocks.slice(from - 1, from - 1 + limit);
172
+ return Promise.all(
173
+ blocks.map(async block => {
174
+ // Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
175
+ const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
176
+ checkpoint.blocks = [block];
177
+ return new PublishedCheckpoint(
178
+ checkpoint,
179
+ new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
180
+ [],
181
+ );
187
182
  }),
188
183
  );
189
184
  }
190
185
 
191
- async getL2BlocksNew(from: BlockNumber, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
192
- const blocks = await this.getBlocks(from, limit, proven);
193
- return blocks.map(x => x.toL2Block());
186
+ public async getCheckpointByArchive(archive: Fr): Promise<Checkpoint | undefined> {
187
+ // TODO(mbps): Implement this properly. This only works when we have one block per checkpoint.
188
+ const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
189
+ if (!block) {
190
+ return undefined;
191
+ }
192
+ // Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
193
+ const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
194
+ checkpoint.blocks = [block];
195
+ return checkpoint;
194
196
  }
195
197
 
196
- public async getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
198
+ public async getCheckpointedBlockByHash(blockHash: BlockHash): Promise<CheckpointedL2Block | undefined> {
197
199
  for (const block of this.l2Blocks) {
198
200
  const hash = await block.hash();
199
201
  if (hash.equals(blockHash)) {
200
- return PublishedL2Block.fromFields({
202
+ return CheckpointedL2Block.fromFields({
203
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
201
204
  block,
202
205
  l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
203
206
  attestations: [],
@@ -207,13 +210,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
207
210
  return undefined;
208
211
  }
209
212
 
210
- public getPublishedBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined> {
213
+ public getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
211
214
  const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
212
215
  if (!block) {
213
216
  return Promise.resolve(undefined);
214
217
  }
215
218
  return Promise.resolve(
216
- PublishedL2Block.fromFields({
219
+ CheckpointedL2Block.fromFields({
220
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
217
221
  block,
218
222
  l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
219
223
  attestations: [],
@@ -221,11 +225,26 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
221
225
  );
222
226
  }
223
227
 
224
- public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
228
+ public async getL2BlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
225
229
  for (const block of this.l2Blocks) {
226
230
  const hash = await block.hash();
227
231
  if (hash.equals(blockHash)) {
228
- return block.getBlockHeader();
232
+ return block;
233
+ }
234
+ }
235
+ return undefined;
236
+ }
237
+
238
+ public getL2BlockByArchive(archive: Fr): Promise<L2Block | undefined> {
239
+ const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
240
+ return Promise.resolve(block);
241
+ }
242
+
243
+ public async getBlockHeaderByHash(blockHash: BlockHash): Promise<BlockHeader | undefined> {
244
+ for (const block of this.l2Blocks) {
245
+ const hash = await block.hash();
246
+ if (hash.equals(blockHash)) {
247
+ return block.header;
229
248
  }
230
249
  }
231
250
  return undefined;
@@ -233,31 +252,58 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
233
252
 
234
253
  public getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
235
254
  const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
236
- return Promise.resolve(block?.getBlockHeader());
255
+ return Promise.resolve(block?.header);
237
256
  }
238
257
 
239
258
  getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
240
- return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number - 1 : -1)?.getBlockHeader());
259
+ return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number - 1 : -1)?.header);
241
260
  }
242
261
 
243
262
  getCheckpointsForEpoch(epochNumber: EpochNumber): Promise<Checkpoint[]> {
244
- // TODO: Implement this properly. This only works when we have one block per checkpoint.
245
- return this.getBlocksForEpoch(epochNumber).then(blocks => blocks.map(b => b.toCheckpoint()));
263
+ // TODO(mbps): Implement this properly. This only works when we have one block per checkpoint.
264
+ const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
265
+ const [start, end] = getSlotRangeForEpoch(epochNumber, { epochDuration });
266
+ const blocks = this.l2Blocks.filter(b => {
267
+ const slot = b.header.globalVariables.slotNumber;
268
+ return slot >= start && slot <= end;
269
+ });
270
+ // Create checkpoints from blocks - manually construct since L2Block doesn't have toCheckpoint()
271
+ return Promise.all(
272
+ blocks.map(async block => {
273
+ const checkpoint = await Checkpoint.random(block.checkpointNumber, { numBlocks: 1 });
274
+ checkpoint.blocks = [block];
275
+ return checkpoint;
276
+ }),
277
+ );
246
278
  }
247
279
 
248
- getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2Block[]> {
280
+ getCheckpointedBlocksForEpoch(epochNumber: EpochNumber): Promise<CheckpointedL2Block[]> {
249
281
  const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
250
282
  const [start, end] = getSlotRangeForEpoch(epochNumber, { epochDuration });
251
283
  const blocks = this.l2Blocks.filter(b => {
252
284
  const slot = b.header.globalVariables.slotNumber;
253
285
  return slot >= start && slot <= end;
254
286
  });
287
+ return Promise.resolve(
288
+ blocks.map(block =>
289
+ CheckpointedL2Block.fromFields({
290
+ checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
291
+ block,
292
+ l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
293
+ attestations: [],
294
+ }),
295
+ ),
296
+ );
297
+ }
298
+
299
+ getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
300
+ const blocks = this.l2Blocks.filter(b => b.header.globalVariables.slotNumber === slotNumber);
255
301
  return Promise.resolve(blocks);
256
302
  }
257
303
 
258
- async getBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
259
- const blocks = await this.getBlocksForEpoch(epochNumber);
260
- return blocks.map(b => b.getBlockHeader());
304
+ async getCheckpointedBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
305
+ const checkpointedBlocks = await this.getCheckpointedBlocksForEpoch(epochNumber);
306
+ return checkpointedBlocks.map(b => b.block.header);
261
307
  }
262
308
 
263
309
  /**
@@ -276,7 +322,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
276
322
  return {
277
323
  data: txEffect,
278
324
  l2BlockNumber: block.number,
279
- l2BlockHash: L2BlockHash.fromField(await block.hash()),
325
+ l2BlockHash: await block.hash(),
280
326
  txIndexInBlock: block.body.txEffects.indexOf(txEffect),
281
327
  };
282
328
  }
@@ -290,12 +336,14 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
290
336
  for (const block of this.l2Blocks) {
291
337
  for (const txEffect of block.body.txEffects) {
292
338
  if (txEffect.txHash.equals(txHash)) {
339
+ // In mock, assume all txs are checkpointed with successful execution
293
340
  return new TxReceipt(
294
341
  txHash,
295
- TxStatus.SUCCESS,
296
- '',
342
+ TxStatus.CHECKPOINTED,
343
+ TxExecutionResult.SUCCESS,
344
+ undefined,
297
345
  txEffect.transactionFee.toBigInt(),
298
- L2BlockHash.fromField(await block.hash()),
346
+ await block.hash(),
299
347
  block.number,
300
348
  );
301
349
  }
@@ -336,7 +384,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
336
384
 
337
385
  const makeTipId = (blockId: typeof latestBlockId) => ({
338
386
  block: blockId,
339
- checkpoint: { number: CheckpointNumber(blockId.number), hash: blockId.hash },
387
+ checkpoint: { number: CheckpointNumber.fromBlockNumber(blockId.number), hash: blockId.hash },
340
388
  });
341
389
 
342
390
  return {
@@ -1,10 +1,28 @@
1
- import { CheckpointNumber } from '@aztec/foundation/branded-types';
1
+ import {
2
+ MAX_NOTE_HASHES_PER_TX,
3
+ NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
4
+ PRIVATE_LOG_SIZE_IN_FIELDS,
5
+ } from '@aztec/constants';
6
+ import { makeTuple } from '@aztec/foundation/array';
7
+ import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
2
8
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
9
+ import { times, timesParallel } from '@aztec/foundation/collection';
3
10
  import { randomBigInt, randomInt } from '@aztec/foundation/crypto/random';
11
+ import type { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
4
12
  import { Fr } from '@aztec/foundation/curves/bn254';
13
+ import { EthAddress } from '@aztec/foundation/eth-address';
14
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
15
+ import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
16
+ import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
17
+ import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs';
5
18
  import { InboxLeaf } from '@aztec/stdlib/messaging';
19
+ import { orderAttestations } from '@aztec/stdlib/p2p';
20
+ import { CheckpointHeader } from '@aztec/stdlib/rollup';
21
+ import { makeCheckpointAttestationFromCheckpoint } from '@aztec/stdlib/testing';
22
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
23
+ import { PartialStateReference, StateReference, TxEffect } from '@aztec/stdlib/tx';
6
24
 
7
- import { type InboxMessage, updateRollingHash } from '../archiver/structs/inbox_message.js';
25
+ import { type InboxMessage, updateRollingHash } from '../structs/inbox_message.js';
8
26
 
9
27
  export function makeInboxMessage(
10
28
  previousRollingHash = Buffer16.ZERO,
@@ -28,23 +46,266 @@ export function makeInboxMessage(
28
46
  }
29
47
 
30
48
  export function makeInboxMessages(
31
- count: number,
49
+ totalCount: number,
32
50
  opts: {
33
51
  initialHash?: Buffer16;
34
52
  initialCheckpointNumber?: CheckpointNumber;
53
+ messagesPerCheckpoint?: number;
35
54
  overrideFn?: (msg: InboxMessage, index: number) => InboxMessage;
36
55
  } = {},
37
56
  ): InboxMessage[] {
38
- const { initialHash = Buffer16.ZERO, overrideFn = msg => msg, initialCheckpointNumber = 1 } = opts;
57
+ const {
58
+ initialHash = Buffer16.ZERO,
59
+ overrideFn = msg => msg,
60
+ initialCheckpointNumber = CheckpointNumber(1),
61
+ messagesPerCheckpoint = 1,
62
+ } = opts;
63
+
39
64
  const messages: InboxMessage[] = [];
40
65
  let rollingHash = initialHash;
41
- for (let i = 0; i < count; i++) {
66
+ for (let i = 0; i < totalCount; i++) {
67
+ const msgIndex = i % messagesPerCheckpoint;
68
+ const checkpointNumber = CheckpointNumber.fromBigInt(
69
+ BigInt(initialCheckpointNumber) + BigInt(i) / BigInt(messagesPerCheckpoint),
70
+ );
42
71
  const leaf = Fr.random();
43
- const checkpointNumber = CheckpointNumber(i + initialCheckpointNumber);
44
- const message = overrideFn(makeInboxMessage(rollingHash, { leaf, checkpointNumber }), i);
72
+ const message = overrideFn(
73
+ makeInboxMessage(rollingHash, {
74
+ leaf,
75
+ checkpointNumber,
76
+ index: InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(msgIndex),
77
+ }),
78
+ i,
79
+ );
45
80
  rollingHash = message.rollingHash;
46
81
  messages.push(message);
47
82
  }
48
-
49
83
  return messages;
50
84
  }
85
+
86
+ /** Creates inbox messages distributed across multiple blocks with proper checkpoint numbering. */
87
+ export function makeInboxMessagesWithFullBlocks(
88
+ blockCount: number,
89
+ opts: { initialCheckpointNumber?: CheckpointNumber } = {},
90
+ ): InboxMessage[] {
91
+ const { initialCheckpointNumber = CheckpointNumber(13) } = opts;
92
+ return makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
93
+ overrideFn: (msg, i) => {
94
+ const checkpointNumber = CheckpointNumber(
95
+ initialCheckpointNumber + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
96
+ );
97
+ const index =
98
+ InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
99
+ return { ...msg, checkpointNumber, index };
100
+ },
101
+ });
102
+ }
103
+
104
+ /** Creates a deterministic block hash from a block number. */
105
+ export function makeBlockHash(blockNumber: number): `0x${string}` {
106
+ return `0x${blockNumber.toString(16).padStart(64, '0')}`;
107
+ }
108
+
109
+ /**
110
+ * Creates a StateReference with properly calculated noteHashTree.nextAvailableLeafIndex.
111
+ * This ensures LogStore's dataStartIndexForBlock calculation doesn't produce negative values.
112
+ */
113
+ export function makeStateForBlock(blockNumber: number, txsPerBlock: number): StateReference {
114
+ const noteHashIndex = blockNumber * txsPerBlock * MAX_NOTE_HASHES_PER_TX;
115
+ return new StateReference(
116
+ AppendOnlyTreeSnapshot.random(),
117
+ new PartialStateReference(
118
+ new AppendOnlyTreeSnapshot(Fr.random(), noteHashIndex),
119
+ AppendOnlyTreeSnapshot.random(),
120
+ AppendOnlyTreeSnapshot.random(),
121
+ ),
122
+ );
123
+ }
124
+
125
+ /** Creates L1PublishedData with deterministic values based on l1BlockNumber. */
126
+ export function makeL1PublishedData(l1BlockNumber: number): L1PublishedData {
127
+ return new L1PublishedData(BigInt(l1BlockNumber), BigInt(l1BlockNumber * 1000), makeBlockHash(l1BlockNumber));
128
+ }
129
+
130
+ /** Wraps a Checkpoint with L1 published data and random attestations. */
131
+ export function makePublishedCheckpoint(
132
+ checkpoint: Checkpoint,
133
+ l1BlockNumber: number,
134
+ attestationCount = 3,
135
+ ): PublishedCheckpoint {
136
+ return new PublishedCheckpoint(
137
+ checkpoint,
138
+ makeL1PublishedData(l1BlockNumber),
139
+ times(attestationCount, CommitteeAttestation.random),
140
+ );
141
+ }
142
+
143
+ export interface MakeChainedCheckpointsOptions {
144
+ /** Number of L2 blocks per checkpoint. Default: 1 */
145
+ blocksPerCheckpoint?: number;
146
+ /** Number of transactions per block. Default: 4 */
147
+ txsPerBlock?: number;
148
+ /** Starting checkpoint number. Default: CheckpointNumber(1) */
149
+ startCheckpointNumber?: CheckpointNumber;
150
+ /** Starting block number. Default: 1 */
151
+ startBlockNumber?: number;
152
+ /** Starting L1 block number. Default: 10 */
153
+ startL1BlockNumber?: number;
154
+ /** Previous archive to chain from. Default: undefined */
155
+ previousArchive?: AppendOnlyTreeSnapshot;
156
+ /** Optional function to provide per-checkpoint overrides */
157
+ makeCheckpointOptions?: (cpNumber: CheckpointNumber) => Partial<Parameters<typeof Checkpoint.random>[1]>;
158
+ }
159
+
160
+ /**
161
+ * Creates multiple checkpoints with properly chained archives.
162
+ * Each checkpoint's blocks have their lastArchive set to the previous block's archive,
163
+ * ensuring archive chain continuity for testing.
164
+ */
165
+ export async function makeChainedCheckpoints(
166
+ count: number,
167
+ options: MakeChainedCheckpointsOptions = {},
168
+ ): Promise<PublishedCheckpoint[]> {
169
+ const {
170
+ blocksPerCheckpoint = 1,
171
+ txsPerBlock = 4,
172
+ startCheckpointNumber = CheckpointNumber(1),
173
+ startBlockNumber = 1,
174
+ startL1BlockNumber = 10,
175
+ makeCheckpointOptions,
176
+ } = options;
177
+
178
+ let previousArchive = options.previousArchive;
179
+ const checkpoints: PublishedCheckpoint[] = [];
180
+
181
+ for (let i = 0; i < count; i++) {
182
+ const cpNumber = CheckpointNumber(startCheckpointNumber + i);
183
+ const blockStart = startBlockNumber + i * blocksPerCheckpoint;
184
+ const customOptions = makeCheckpointOptions?.(cpNumber) ?? {};
185
+
186
+ const checkpoint = await Checkpoint.random(cpNumber, {
187
+ numBlocks: blocksPerCheckpoint,
188
+ startBlockNumber: blockStart,
189
+ previousArchive,
190
+ txsPerBlock,
191
+ state: makeStateForBlock(blockStart, txsPerBlock),
192
+ txOptions: { numPublicCallsPerTx: 2, numPublicLogsPerCall: 2 },
193
+ ...customOptions,
194
+ });
195
+
196
+ previousArchive = checkpoint.blocks.at(-1)!.archive;
197
+ checkpoints.push(makePublishedCheckpoint(checkpoint, startL1BlockNumber + i * 10));
198
+ }
199
+
200
+ return checkpoints;
201
+ }
202
+
203
+ /**
204
+ * Creates a PublishedCheckpoint with attestations signed by the provided signers.
205
+ * Useful for testing attestation validation.
206
+ */
207
+ export function makeSignedPublishedCheckpoint(
208
+ checkpoint: Checkpoint,
209
+ signers: Secp256k1Signer[],
210
+ committee: EthAddress[],
211
+ l1BlockNumber = 1,
212
+ ): PublishedCheckpoint {
213
+ const attestations = signers.map(signer => makeCheckpointAttestationFromCheckpoint(checkpoint, signer));
214
+ const committeeAttestations = orderAttestations(attestations, committee);
215
+ return new PublishedCheckpoint(checkpoint, makeL1PublishedData(l1BlockNumber), committeeAttestations);
216
+ }
217
+
218
+ /** Creates a deterministic SiloedTag for private log testing. */
219
+ export function makePrivateLogTag(blockNumber: number, txIndex: number, logIndex: number): SiloedTag {
220
+ return new SiloedTag(
221
+ blockNumber === 1 && txIndex === 0 && logIndex === 0
222
+ ? Fr.ZERO
223
+ : new Fr(blockNumber * 100 + txIndex * 10 + logIndex),
224
+ );
225
+ }
226
+
227
+ /** Creates a PrivateLog with fields derived from the tag. */
228
+ export function makePrivateLog(tag: SiloedTag): PrivateLog {
229
+ return PrivateLog.from({
230
+ fields: makeTuple(PRIVATE_LOG_SIZE_IN_FIELDS, i => (!i ? tag.value : new Fr(tag.value.toBigInt() + BigInt(i)))),
231
+ emittedLength: PRIVATE_LOG_SIZE_IN_FIELDS,
232
+ });
233
+ }
234
+
235
+ /** Creates multiple private logs for a transaction. */
236
+ export function mockPrivateLogs(blockNumber: number, txIndex: number, numLogsPerTx: number): PrivateLog[] {
237
+ return times(numLogsPerTx, logIndex => {
238
+ const tag = makePrivateLogTag(blockNumber, txIndex, logIndex);
239
+ return makePrivateLog(tag);
240
+ });
241
+ }
242
+
243
+ /** Creates a deterministic Tag for public log testing. */
244
+ export function makePublicLogTag(blockNumber: number, txIndex: number, logIndex: number): Tag {
245
+ return new Tag(
246
+ blockNumber === 1 && txIndex === 0 && logIndex === 0
247
+ ? Fr.ZERO
248
+ : new Fr((blockNumber * 100 + txIndex * 10 + logIndex) * 123),
249
+ );
250
+ }
251
+
252
+ /** Creates a PublicLog with fields derived from the tag. */
253
+ export function makePublicLog(tag: Tag, contractAddress: AztecAddress = AztecAddress.fromNumber(543254)): PublicLog {
254
+ return PublicLog.from({
255
+ contractAddress,
256
+ fields: new Array(10).fill(null).map((_, i) => (!i ? tag.value : new Fr(tag.value.toBigInt() + BigInt(i)))),
257
+ });
258
+ }
259
+
260
+ /** Creates multiple public logs for a transaction. */
261
+ export function makePublicLogs(
262
+ blockNumber: number,
263
+ txIndex: number,
264
+ numLogsPerTx: number,
265
+ contractAddress: AztecAddress = AztecAddress.fromNumber(543254),
266
+ ): PublicLog[] {
267
+ return times(numLogsPerTx, logIndex => {
268
+ const tag = makePublicLogTag(blockNumber, txIndex, logIndex);
269
+ return makePublicLog(tag, contractAddress);
270
+ });
271
+ }
272
+
273
+ export interface MockCheckpointWithLogsOptions {
274
+ previousArchive?: AppendOnlyTreeSnapshot;
275
+ numTxsPerBlock?: number;
276
+ privateLogs?: { numLogsPerTx: number };
277
+ publicLogs?: { numLogsPerTx: number; contractAddress?: AztecAddress };
278
+ }
279
+
280
+ /** Creates a checkpoint with specified logs on each tx effect. */
281
+ export async function makeCheckpointWithLogs(
282
+ blockNumber: number,
283
+ options: MockCheckpointWithLogsOptions = {},
284
+ ): Promise<PublishedCheckpoint> {
285
+ const { previousArchive, numTxsPerBlock = 4, privateLogs, publicLogs } = options;
286
+
287
+ const block = await L2Block.random(BlockNumber(blockNumber), {
288
+ checkpointNumber: CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)),
289
+ indexWithinCheckpoint: IndexWithinCheckpoint(0),
290
+ state: makeStateForBlock(blockNumber, numTxsPerBlock),
291
+ ...(previousArchive ? { lastArchive: previousArchive } : {}),
292
+ });
293
+ block.header.globalVariables.blockNumber = BlockNumber(blockNumber);
294
+
295
+ block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex: number) => {
296
+ const txEffect = await TxEffect.random();
297
+ txEffect.privateLogs = privateLogs ? mockPrivateLogs(blockNumber, txIndex, privateLogs.numLogsPerTx) : [];
298
+ txEffect.publicLogs = publicLogs
299
+ ? makePublicLogs(blockNumber, txIndex, publicLogs.numLogsPerTx, publicLogs.contractAddress)
300
+ : [];
301
+ return txEffect;
302
+ });
303
+
304
+ const checkpoint = new Checkpoint(
305
+ AppendOnlyTreeSnapshot.random(),
306
+ CheckpointHeader.random(),
307
+ [block],
308
+ CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)),
309
+ );
310
+ return makePublishedCheckpoint(checkpoint, blockNumber);
311
+ }