@aztec/archiver 0.0.1-commit.96dac018d → 0.0.1-commit.993d240

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 (121) hide show
  1. package/README.md +19 -11
  2. package/dest/archiver.d.ts +36 -17
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +257 -75
  5. package/dest/config.d.ts +6 -3
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +23 -15
  8. package/dest/errors.d.ts +55 -9
  9. package/dest/errors.d.ts.map +1 -1
  10. package/dest/errors.js +81 -14
  11. package/dest/factory.d.ts +13 -9
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +47 -35
  14. package/dest/index.d.ts +11 -3
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +10 -2
  17. package/dest/l1/calldata_retriever.d.ts +2 -1
  18. package/dest/l1/calldata_retriever.d.ts.map +1 -1
  19. package/dest/l1/calldata_retriever.js +15 -5
  20. package/dest/l1/data_retrieval.d.ts +24 -12
  21. package/dest/l1/data_retrieval.d.ts.map +1 -1
  22. package/dest/l1/data_retrieval.js +36 -37
  23. package/dest/l1/trace_tx.d.ts +12 -66
  24. package/dest/l1/trace_tx.d.ts.map +1 -1
  25. package/dest/l1/validate_historical_logs.d.ts +23 -0
  26. package/dest/l1/validate_historical_logs.d.ts.map +1 -0
  27. package/dest/l1/validate_historical_logs.js +108 -0
  28. package/dest/modules/contract_data_source_adapter.d.ts +25 -0
  29. package/dest/modules/contract_data_source_adapter.d.ts.map +1 -0
  30. package/dest/modules/contract_data_source_adapter.js +40 -0
  31. package/dest/modules/data_source_base.d.ts +70 -46
  32. package/dest/modules/data_source_base.d.ts.map +1 -1
  33. package/dest/modules/data_source_base.js +270 -135
  34. package/dest/modules/data_store_updater.d.ts +42 -17
  35. package/dest/modules/data_store_updater.d.ts.map +1 -1
  36. package/dest/modules/data_store_updater.js +191 -122
  37. package/dest/modules/instrumentation.d.ts +7 -2
  38. package/dest/modules/instrumentation.d.ts.map +1 -1
  39. package/dest/modules/instrumentation.js +25 -7
  40. package/dest/modules/l1_synchronizer.d.ts +12 -6
  41. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  42. package/dest/modules/l1_synchronizer.js +432 -205
  43. package/dest/modules/validation.d.ts +4 -3
  44. package/dest/modules/validation.d.ts.map +1 -1
  45. package/dest/modules/validation.js +6 -6
  46. package/dest/store/block_store.d.ts +174 -70
  47. package/dest/store/block_store.d.ts.map +1 -1
  48. package/dest/store/block_store.js +696 -250
  49. package/dest/store/contract_class_store.d.ts +17 -4
  50. package/dest/store/contract_class_store.d.ts.map +1 -1
  51. package/dest/store/contract_class_store.js +24 -68
  52. package/dest/store/contract_instance_store.d.ts +28 -1
  53. package/dest/store/contract_instance_store.d.ts.map +1 -1
  54. package/dest/store/contract_instance_store.js +37 -2
  55. package/dest/store/data_stores.d.ts +68 -0
  56. package/dest/store/data_stores.d.ts.map +1 -0
  57. package/dest/store/data_stores.js +54 -0
  58. package/dest/store/function_names_cache.d.ts +17 -0
  59. package/dest/store/function_names_cache.d.ts.map +1 -0
  60. package/dest/store/function_names_cache.js +30 -0
  61. package/dest/store/l2_tips_cache.d.ts +13 -7
  62. package/dest/store/l2_tips_cache.d.ts.map +1 -1
  63. package/dest/store/l2_tips_cache.js +13 -76
  64. package/dest/store/log_store.d.ts +42 -37
  65. package/dest/store/log_store.d.ts.map +1 -1
  66. package/dest/store/log_store.js +262 -408
  67. package/dest/store/log_store_codec.d.ts +70 -0
  68. package/dest/store/log_store_codec.d.ts.map +1 -0
  69. package/dest/store/log_store_codec.js +101 -0
  70. package/dest/store/message_store.d.ts +11 -1
  71. package/dest/store/message_store.d.ts.map +1 -1
  72. package/dest/store/message_store.js +51 -9
  73. package/dest/test/fake_l1_state.d.ts +20 -1
  74. package/dest/test/fake_l1_state.d.ts.map +1 -1
  75. package/dest/test/fake_l1_state.js +114 -18
  76. package/dest/test/mock_l1_to_l2_message_source.d.ts +1 -1
  77. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  78. package/dest/test/mock_l1_to_l2_message_source.js +2 -1
  79. package/dest/test/mock_l2_block_source.d.ts +52 -46
  80. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  81. package/dest/test/mock_l2_block_source.js +246 -170
  82. package/dest/test/mock_structs.d.ts +4 -1
  83. package/dest/test/mock_structs.d.ts.map +1 -1
  84. package/dest/test/mock_structs.js +13 -1
  85. package/dest/test/noop_l1_archiver.d.ts +12 -6
  86. package/dest/test/noop_l1_archiver.d.ts.map +1 -1
  87. package/dest/test/noop_l1_archiver.js +26 -9
  88. package/package.json +14 -14
  89. package/src/archiver.ts +313 -75
  90. package/src/config.ts +32 -12
  91. package/src/errors.ts +122 -21
  92. package/src/factory.ts +54 -29
  93. package/src/index.ts +18 -2
  94. package/src/l1/calldata_retriever.ts +16 -5
  95. package/src/l1/data_retrieval.ts +52 -53
  96. package/src/l1/validate_historical_logs.ts +140 -0
  97. package/src/modules/contract_data_source_adapter.ts +55 -0
  98. package/src/modules/data_source_base.ts +336 -171
  99. package/src/modules/data_store_updater.ts +224 -154
  100. package/src/modules/instrumentation.ts +28 -8
  101. package/src/modules/l1_synchronizer.ts +572 -248
  102. package/src/modules/validation.ts +10 -9
  103. package/src/store/block_store.ts +865 -290
  104. package/src/store/contract_class_store.ts +31 -103
  105. package/src/store/contract_instance_store.ts +51 -5
  106. package/src/store/data_stores.ts +104 -0
  107. package/src/store/function_names_cache.ts +37 -0
  108. package/src/store/l2_tips_cache.ts +16 -70
  109. package/src/store/log_store.ts +301 -559
  110. package/src/store/log_store_codec.ts +132 -0
  111. package/src/store/message_store.ts +60 -10
  112. package/src/structs/inbox_message.ts +1 -1
  113. package/src/test/fake_l1_state.ts +142 -29
  114. package/src/test/mock_l1_to_l2_message_source.ts +1 -0
  115. package/src/test/mock_l2_block_source.ts +309 -205
  116. package/src/test/mock_structs.ts +20 -6
  117. package/src/test/noop_l1_archiver.ts +39 -9
  118. package/dest/store/kv_archiver_store.d.ts +0 -354
  119. package/dest/store/kv_archiver_store.d.ts.map +0 -1
  120. package/dest/store/kv_archiver_store.js +0 -464
  121. package/src/store/kv_archiver_store.ts +0 -671
@@ -1,16 +1,17 @@
1
1
  import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
2
2
  import { DefaultL1ContractsConfig } from '@aztec/ethereum/config';
3
- import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
4
4
  import { Buffer32 } from '@aztec/foundation/buffer';
5
5
  import { Fr } from '@aztec/foundation/curves/bn254';
6
6
  import { EthAddress } from '@aztec/foundation/eth-address';
7
7
  import { createLogger } from '@aztec/foundation/log';
8
- import { CheckpointedL2Block } from '@aztec/stdlib/block';
8
+ import { Body, GENESIS_BLOCK_HEADER_HASH, GENESIS_CHECKPOINT_HEADER_HASH, L2Block } from '@aztec/stdlib/block';
9
9
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
10
- import { EmptyL1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
10
+ import { EmptyL1RollupConstants, getEpochAtSlot, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
11
11
  import { computeCheckpointOutHash } from '@aztec/stdlib/messaging';
12
12
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
13
- import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
13
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
14
+ import { BlockHeader, TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
14
15
  /**
15
16
  * A mocked implementation of L2BlockSource to be used in tests.
16
17
  */ export class MockL2BlockSource {
@@ -19,10 +20,54 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
19
20
  provenBlockNumber = 0;
20
21
  finalizedBlockNumber = 0;
21
22
  checkpointedBlockNumber = 0;
23
+ proposedCheckpointBlockNumber = 0;
24
+ initialHeader = BlockHeader.empty();
25
+ initialHeaderHash = GENESIS_BLOCK_HEADER_HASH;
26
+ genesisArchiveRoot;
27
+ genesisBlock;
22
28
  log = createLogger('archiver:mock_l2_block_source');
29
+ /** Returns the initial header used to synthesize block 0. */ getInitialHeader() {
30
+ return this.initialHeader;
31
+ }
32
+ /**
33
+ * Sets the initial header used to synthesize block 0. Tests that wire up a real
34
+ * world-state should call this with `worldState.getInitialHeader()` so the L2BlockStream
35
+ * agrees on the genesis hash on both sides. Precomputes and caches the header hash so
36
+ * `getGenesisBlockHash()` can return synchronously.
37
+ */ async setInitialHeader(header) {
38
+ this.initialHeader = header;
39
+ this.initialHeaderHash = await header.hash();
40
+ this.genesisBlock = undefined;
41
+ }
42
+ /**
43
+ * Returns the precomputed hash of the genesis block header. Defaults to the static
44
+ * {@link GENESIS_BLOCK_HEADER_HASH} unless {@link setInitialHeader} has been called with a
45
+ * custom header.
46
+ */ getGenesisBlockHash() {
47
+ return this.initialHeaderHash;
48
+ }
49
+ /**
50
+ * Sets the post-genesis archive root used to synthesize block 0. Mirrors the real archiver,
51
+ * whose synthetic block 0 carries `new AppendOnlyTreeSnapshot(genesisArchiveRoot, 1)` rather
52
+ * than `AppendOnlyTreeSnapshot.empty()`. Tests wiring up a real world-state should set this so
53
+ * archive-based block lookups against the mock match production semantics.
54
+ */ setGenesisArchiveRoot(root) {
55
+ this.genesisArchiveRoot = root;
56
+ this.genesisBlock = undefined;
57
+ }
58
+ getGenesisBlock() {
59
+ if (this.genesisBlock) {
60
+ return this.genesisBlock;
61
+ }
62
+ const archive = this.genesisArchiveRoot ? new AppendOnlyTreeSnapshot(this.genesisArchiveRoot, 1) : AppendOnlyTreeSnapshot.empty();
63
+ return this.genesisBlock = new L2Block(archive, this.initialHeader, Body.empty(), CheckpointNumber.ZERO, IndexWithinCheckpoint(0));
64
+ }
23
65
  /** Creates blocks grouped into single-block checkpoints. */ async createBlocks(numBlocks) {
24
66
  await this.createCheckpoints(numBlocks, 1);
25
67
  }
68
+ getCheckpointNumber() {
69
+ return Promise.resolve(this.checkpointList.length === 0 ? CheckpointNumber.ZERO : CheckpointNumber(this.checkpointList.length));
70
+ }
26
71
  /** Creates checkpoints, each containing `blocksPerCheckpoint` blocks. */ async createCheckpoints(numCheckpoints, blocksPerCheckpoint = 1) {
27
72
  for(let c = 0; c < numCheckpoints; c++){
28
73
  const checkpointNum = CheckpointNumber(this.checkpointList.length + 1);
@@ -53,6 +98,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
53
98
  });
54
99
  // Keep tip numbers consistent with remaining blocks.
55
100
  this.checkpointedBlockNumber = Math.min(this.checkpointedBlockNumber, maxBlockNum);
101
+ this.proposedCheckpointBlockNumber = Math.min(this.proposedCheckpointBlockNumber, maxBlockNum);
56
102
  this.provenBlockNumber = Math.min(this.provenBlockNumber, maxBlockNum);
57
103
  this.finalizedBlockNumber = Math.min(this.finalizedBlockNumber, maxBlockNum);
58
104
  this.log.verbose(`Removed ${numBlocks} blocks from the mock L2 block source`);
@@ -66,9 +112,16 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
66
112
  }
67
113
  this.finalizedBlockNumber = finalizedBlockNumber;
68
114
  }
115
+ setProposedCheckpointBlockNumber(blockNumber) {
116
+ this.proposedCheckpointBlockNumber = blockNumber;
117
+ }
69
118
  setCheckpointedBlockNumber(checkpointedBlockNumber) {
70
119
  const prevCheckpointed = this.checkpointedBlockNumber;
71
120
  this.checkpointedBlockNumber = checkpointedBlockNumber;
121
+ // Proposed checkpoint is always at least as advanced as checkpointed
122
+ if (this.proposedCheckpointBlockNumber < checkpointedBlockNumber) {
123
+ this.proposedCheckpointBlockNumber = checkpointedBlockNumber;
124
+ }
72
125
  // Auto-create single-block checkpoints for newly checkpointed blocks that don't have one yet.
73
126
  // This handles blocks added via addProposedBlocks that are now being marked as checkpointed.
74
127
  const newCheckpoints = [];
@@ -106,176 +159,93 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
106
159
  */ getRegistryAddress() {
107
160
  return Promise.resolve(EthAddress.random());
108
161
  }
109
- /**
110
- * Gets the number of the latest L2 block processed by the block source implementation.
111
- * @returns In this mock instance, returns the number of L2 blocks that we've mocked.
112
- */ getBlockNumber() {
113
- return Promise.resolve(BlockNumber(this.l2Blocks.length));
114
- }
115
- getProvenBlockNumber() {
116
- return Promise.resolve(BlockNumber(this.provenBlockNumber));
117
- }
118
- getCheckpointedL2BlockNumber() {
119
- return Promise.resolve(BlockNumber(this.checkpointedBlockNumber));
120
- }
121
- getFinalizedL2BlockNumber() {
122
- return Promise.resolve(BlockNumber(this.finalizedBlockNumber));
123
- }
124
- getCheckpointedBlock(number) {
125
- if (number > this.checkpointedBlockNumber) {
126
- return Promise.resolve(undefined);
162
+ async getBlockNumber(query) {
163
+ if (!query) {
164
+ return BlockNumber(this.l2Blocks.length);
127
165
  }
128
- const block = this.l2Blocks[number - 1];
129
- if (!block) {
130
- return Promise.resolve(undefined);
166
+ if ('number' in query) {
167
+ return query.number;
131
168
  }
132
- return Promise.resolve(this.toCheckpointedBlock(block));
133
- }
134
- async getCheckpointedBlocks(from, limit) {
135
- const result = [];
136
- for(let i = 0; i < limit; i++){
137
- const blockNum = from + i;
138
- if (blockNum > this.checkpointedBlockNumber) {
139
- break;
140
- }
141
- const block = await this.getCheckpointedBlock(BlockNumber(blockNum));
142
- if (block) {
143
- result.push(block);
144
- }
169
+ if ('tag' in query) {
170
+ return BlockNumber(this.resolveBlockTag(query.tag));
145
171
  }
146
- return result;
172
+ const block = await this.getBlock(query);
173
+ return block ? block.header.globalVariables.blockNumber : undefined;
147
174
  }
148
- /**
149
- * Gets an l2 block.
150
- * @param number - The block number to return (inclusive).
151
- * @returns The requested L2 block.
152
- */ getBlock(number) {
153
- const block = this.l2Blocks[number - 1];
154
- return Promise.resolve(block);
175
+ getProposedCheckpointL2BlockNumber() {
176
+ return Promise.resolve(BlockNumber(this.proposedCheckpointBlockNumber));
155
177
  }
156
- /**
157
- * Gets an L2 block (new format).
158
- * @param number - The block number to return.
159
- * @returns The requested L2 block.
160
- */ getL2Block(number) {
161
- const block = this.l2Blocks[number - 1];
162
- return Promise.resolve(block);
178
+ getCheckpoint(query) {
179
+ const checkpoint = this.resolveCheckpointQuery(query);
180
+ if (!checkpoint) {
181
+ return Promise.resolve(undefined);
182
+ }
183
+ return Promise.resolve(new PublishedCheckpoint(checkpoint, this.mockL1DataForCheckpoint(checkpoint), []));
163
184
  }
164
- /**
165
- * Gets up to `limit` amount of L2 blocks starting from `from`.
166
- * @param from - Number of the first block to return (inclusive).
167
- * @param limit - The maximum number of blocks to return.
168
- * @returns The requested mocked L2 blocks.
169
- */ getBlocks(from, limit) {
170
- return Promise.resolve(this.l2Blocks.slice(from - 1, from - 1 + limit));
171
- }
172
- getCheckpoints(from, limit) {
173
- const checkpoints = this.checkpointList.slice(from - 1, from - 1 + limit);
185
+ getCheckpoints(query) {
186
+ const checkpoints = this.resolveCheckpointsQuery(query);
174
187
  return Promise.resolve(checkpoints.map((checkpoint)=>new PublishedCheckpoint(checkpoint, this.mockL1DataForCheckpoint(checkpoint), [])));
175
188
  }
176
189
  getCheckpointByArchive(archive) {
177
190
  const checkpoint = this.checkpointList.find((c)=>c.archive.root.equals(archive));
178
191
  return Promise.resolve(checkpoint);
179
192
  }
180
- async getCheckpointedBlockByHash(blockHash) {
181
- for (const block of this.l2Blocks){
182
- const hash = await block.hash();
183
- if (hash.equals(blockHash)) {
184
- return this.toCheckpointedBlock(block);
185
- }
186
- }
187
- return undefined;
188
- }
189
- getCheckpointedBlockByArchive(archive) {
190
- const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
191
- if (!block) {
193
+ getCheckpointData(query) {
194
+ const checkpoint = this.resolveCheckpointQuery(query);
195
+ if (!checkpoint) {
192
196
  return Promise.resolve(undefined);
193
197
  }
194
- return Promise.resolve(this.toCheckpointedBlock(block));
195
- }
196
- async getL2BlockByHash(blockHash) {
197
- for (const block of this.l2Blocks){
198
- const hash = await block.hash();
199
- if (hash.equals(blockHash)) {
200
- return block;
201
- }
202
- }
203
- return undefined;
198
+ return Promise.resolve(this.checkpointToData(checkpoint));
204
199
  }
205
- getL2BlockByArchive(archive) {
206
- const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
207
- return Promise.resolve(block);
200
+ getCheckpointsData(query) {
201
+ const checkpoints = this.resolveCheckpointsQuery(query);
202
+ return Promise.resolve(checkpoints.map((c)=>this.checkpointToData(c)));
208
203
  }
209
- async getBlockHeaderByHash(blockHash) {
210
- for (const block of this.l2Blocks){
211
- const hash = await block.hash();
212
- if (hash.equals(blockHash)) {
213
- return block.header;
214
- }
215
- }
216
- return undefined;
217
- }
218
- getBlockHeaderByArchive(archive) {
219
- const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
220
- return Promise.resolve(block?.header);
221
- }
222
- async getBlockData(number) {
223
- const block = this.l2Blocks[number - 1];
224
- if (!block) {
225
- return undefined;
226
- }
204
+ checkpointToData(checkpoint) {
227
205
  return {
228
- header: block.header,
229
- archive: block.archive,
230
- blockHash: await block.hash(),
231
- checkpointNumber: block.checkpointNumber,
232
- indexWithinCheckpoint: block.indexWithinCheckpoint
206
+ checkpointNumber: checkpoint.number,
207
+ header: checkpoint.header,
208
+ archive: checkpoint.archive,
209
+ checkpointOutHash: computeCheckpointOutHash(checkpoint.blocks.map((b)=>b.body.txEffects.map((tx)=>tx.l2ToL1Msgs))),
210
+ startBlock: checkpoint.blocks[0].number,
211
+ blockCount: checkpoint.blocks.length,
212
+ feeAssetPriceModifier: checkpoint.feeAssetPriceModifier,
213
+ attestations: [],
214
+ l1: this.mockL1DataForCheckpoint(checkpoint)
233
215
  };
234
216
  }
235
- async getBlockDataByArchive(archive) {
236
- const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
237
- if (!block) {
238
- return undefined;
217
+ resolveCheckpointQuery(query) {
218
+ if ('number' in query) {
219
+ return this.checkpointList[query.number - 1];
220
+ }
221
+ if ('slot' in query) {
222
+ return this.checkpointList.find((c)=>c.header.slotNumber === query.slot);
223
+ }
224
+ switch(query.tag){
225
+ case 'checkpointed':
226
+ return this.checkpointList[this.checkpointList.length - 1];
227
+ case 'proven':
228
+ {
229
+ const provenCheckpoint = this.checkpointList.filter((c)=>c.blocks.some((b)=>b.number <= this.provenBlockNumber));
230
+ return provenCheckpoint.at(-1);
231
+ }
232
+ case 'finalized':
233
+ {
234
+ const finalizedCheckpoint = this.checkpointList.filter((c)=>c.blocks.some((b)=>b.number <= this.finalizedBlockNumber));
235
+ return finalizedCheckpoint.at(-1);
236
+ }
239
237
  }
240
- return {
241
- header: block.header,
242
- archive: block.archive,
243
- blockHash: await block.hash(),
244
- checkpointNumber: block.checkpointNumber,
245
- indexWithinCheckpoint: block.indexWithinCheckpoint
246
- };
247
- }
248
- getBlockHeader(number) {
249
- return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number - 1 : -1)?.header);
250
- }
251
- getCheckpointsForEpoch(epochNumber) {
252
- return Promise.resolve(this.getCheckpointsInEpoch(epochNumber));
253
- }
254
- getCheckpointsDataForEpoch(epochNumber) {
255
- const checkpoints = this.getCheckpointsInEpoch(epochNumber);
256
- return Promise.resolve(checkpoints.map((checkpoint)=>({
257
- checkpointNumber: checkpoint.number,
258
- header: checkpoint.header,
259
- archive: checkpoint.archive,
260
- checkpointOutHash: computeCheckpointOutHash(checkpoint.blocks.map((b)=>b.body.txEffects.map((tx)=>tx.l2ToL1Msgs))),
261
- startBlock: checkpoint.blocks[0].number,
262
- blockCount: checkpoint.blocks.length,
263
- attestations: [],
264
- l1: this.mockL1DataForCheckpoint(checkpoint)
265
- })));
266
238
  }
267
- getCheckpointedBlocksForEpoch(epochNumber) {
268
- const checkpoints = this.getCheckpointsInEpoch(epochNumber);
269
- return Promise.resolve(checkpoints.flatMap((checkpoint)=>checkpoint.blocks.map((block)=>this.toCheckpointedBlock(block))));
239
+ resolveCheckpointsQuery(query) {
240
+ if ('from' in query) {
241
+ return this.checkpointList.slice(query.from - 1, query.from - 1 + query.limit);
242
+ }
243
+ return this.getCheckpointsInEpoch(query.epoch);
270
244
  }
271
245
  getBlocksForSlot(slotNumber) {
272
246
  const blocks = this.l2Blocks.filter((b)=>b.header.globalVariables.slotNumber === slotNumber);
273
247
  return Promise.resolve(blocks);
274
248
  }
275
- async getCheckpointedBlockHeadersForEpoch(epochNumber) {
276
- const checkpointedBlocks = await this.getCheckpointedBlocksForEpoch(epochNumber);
277
- return checkpointedBlocks.map((b)=>b.block.header);
278
- }
279
249
  /**
280
250
  * Gets a tx effect.
281
251
  * @param txHash - The hash of the tx corresponding to the tx effect.
@@ -293,7 +263,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
293
263
  data: txEffect,
294
264
  l2BlockNumber: block.number,
295
265
  l2BlockHash: await block.hash(),
296
- txIndexInBlock: block.body.txEffects.indexOf(txEffect)
266
+ txIndexInBlock: block.body.txEffects.findIndex((t)=>t.txHash.equals(txHash))
297
267
  };
298
268
  }
299
269
  /**
@@ -305,57 +275,80 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
305
275
  for (const txEffect of block.body.txEffects){
306
276
  if (txEffect.txHash.equals(txHash)) {
307
277
  // In mock, assume all txs are checkpointed with successful execution
308
- return new TxReceipt(txHash, TxStatus.CHECKPOINTED, TxExecutionResult.SUCCESS, undefined, txEffect.transactionFee.toBigInt(), await block.hash(), block.number);
278
+ return new TxReceipt(txHash, TxStatus.CHECKPOINTED, TxExecutionResult.SUCCESS, undefined, txEffect.transactionFee.toBigInt(), await block.hash(), block.number, getEpochAtSlot(block.slot, EmptyL1RollupConstants));
309
279
  }
310
280
  }
311
281
  }
312
282
  return undefined;
313
283
  }
314
284
  async getL2Tips() {
315
- const [latest, proven, finalized, checkpointed] = [
285
+ const [latest, proven, finalized, checkpointed, proposedCheckpoint] = [
316
286
  await this.getBlockNumber(),
317
- await this.getProvenBlockNumber(),
287
+ this.provenBlockNumber,
318
288
  this.finalizedBlockNumber,
319
- this.checkpointedBlockNumber
289
+ this.checkpointedBlockNumber,
290
+ await this.getProposedCheckpointL2BlockNumber()
320
291
  ];
321
292
  const latestBlock = this.l2Blocks[latest - 1];
322
293
  const provenBlock = this.l2Blocks[proven - 1];
323
294
  const finalizedBlock = this.l2Blocks[finalized - 1];
324
295
  const checkpointedBlock = this.l2Blocks[checkpointed - 1];
296
+ const proposedCheckpointBlock = this.l2Blocks[proposedCheckpoint - 1];
297
+ // For genesis tips (block number 0) report the dynamic initial header hash so consumers
298
+ // running L2BlockStream against this mock agree at block 0 with their local tip store.
299
+ const genesisHash = (await this.initialHeader.hash()).toString();
300
+ const tipHash = async (block, number)=>{
301
+ if (block) {
302
+ return (await block.hash()).toString();
303
+ }
304
+ return number === 0 ? genesisHash : '';
305
+ };
325
306
  const latestBlockId = {
326
307
  number: BlockNumber(latest),
327
- hash: (await latestBlock?.hash())?.toString()
308
+ hash: await tipHash(latestBlock, latest)
328
309
  };
329
310
  const provenBlockId = {
330
311
  number: BlockNumber(proven),
331
- hash: (await provenBlock?.hash())?.toString()
312
+ hash: await tipHash(provenBlock, proven)
332
313
  };
333
314
  const finalizedBlockId = {
334
315
  number: BlockNumber(finalized),
335
- hash: (await finalizedBlock?.hash())?.toString()
316
+ hash: await tipHash(finalizedBlock, finalized)
336
317
  };
337
318
  const checkpointedBlockId = {
338
319
  number: BlockNumber(checkpointed),
339
- hash: (await checkpointedBlock?.hash())?.toString()
320
+ hash: await tipHash(checkpointedBlock, checkpointed)
321
+ };
322
+ const proposedCheckpointBlockId = {
323
+ number: BlockNumber(proposedCheckpoint),
324
+ hash: await tipHash(proposedCheckpointBlock, proposedCheckpoint)
340
325
  };
341
- const makeTipId = (blockId)=>({
326
+ const makeTipId = (blockId)=>{
327
+ const checkpointNumber = this.findCheckpointNumberForBlock(blockId.number) ?? CheckpointNumber(0);
328
+ // Match production semantics: checkpoint 0 is fully synthetic (no real checkpoint header
329
+ // exists at 0), so its hash stays at the protocol constant `GENESIS_CHECKPOINT_HEADER_HASH`
330
+ // even though the block-0 hash is dynamic. See L2TipsCache for the production path.
331
+ const hash = checkpointNumber === 0 ? GENESIS_CHECKPOINT_HEADER_HASH.toString() : blockId.hash;
332
+ return {
342
333
  block: blockId,
343
334
  checkpoint: {
344
- number: this.findCheckpointNumberForBlock(blockId.number) ?? CheckpointNumber(0),
345
- hash: blockId.hash
335
+ number: checkpointNumber,
336
+ hash
346
337
  }
347
- });
338
+ };
339
+ };
348
340
  return {
349
341
  proposed: latestBlockId,
350
342
  checkpointed: makeTipId(checkpointedBlockId),
351
343
  proven: makeTipId(provenBlockId),
352
- finalized: makeTipId(finalizedBlockId)
344
+ finalized: makeTipId(finalizedBlockId),
345
+ proposedCheckpoint: makeTipId(proposedCheckpointBlockId)
353
346
  };
354
347
  }
355
- getL2EpochNumber() {
348
+ getSyncedL2EpochNumber() {
356
349
  throw new Error('Method not implemented.');
357
350
  }
358
- getL2SlotNumber() {
351
+ getSyncedL2SlotNumber() {
359
352
  throw new Error('Method not implemented.');
360
353
  }
361
354
  isEpochComplete(_epochNumber) {
@@ -364,9 +357,12 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
364
357
  getL1Constants() {
365
358
  return Promise.resolve(EmptyL1RollupConstants);
366
359
  }
360
+ isPruneDueAtSlot(_slot) {
361
+ return Promise.resolve(false);
362
+ }
367
363
  getGenesisValues() {
368
364
  return Promise.resolve({
369
- genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT)
365
+ genesisArchiveRoot: this.genesisArchiveRoot ?? new Fr(GENESIS_ARCHIVE_ROOT)
370
366
  });
371
367
  }
372
368
  getL1Timestamp() {
@@ -407,6 +403,88 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
407
403
  syncImmediate() {
408
404
  return Promise.resolve();
409
405
  }
406
+ async getBlock(query) {
407
+ if ('number' in query) {
408
+ if (query.number === 0) {
409
+ return this.getGenesisBlock();
410
+ }
411
+ return this.l2Blocks[query.number - 1];
412
+ }
413
+ if ('hash' in query) {
414
+ const genesis = this.getGenesisBlock();
415
+ if ((await genesis.hash()).equals(query.hash)) {
416
+ return genesis;
417
+ }
418
+ for (const b of this.l2Blocks){
419
+ const hash = await b.hash();
420
+ if (hash.equals(query.hash)) {
421
+ return b;
422
+ }
423
+ }
424
+ return undefined;
425
+ }
426
+ if ('archive' in query) {
427
+ const genesis = this.getGenesisBlock();
428
+ if (genesis.archive.root.equals(query.archive)) {
429
+ return genesis;
430
+ }
431
+ return this.l2Blocks.find((b)=>b.archive.root.equals(query.archive));
432
+ }
433
+ const number = this.resolveBlockTag(query.tag);
434
+ if (number === 0) {
435
+ return this.getGenesisBlock();
436
+ }
437
+ return this.l2Blocks[number - 1];
438
+ }
439
+ resolveBlockTag(tag) {
440
+ switch(tag){
441
+ case 'latest':
442
+ case 'proposed':
443
+ return this.l2Blocks.length;
444
+ case 'checkpointed':
445
+ return this.checkpointedBlockNumber;
446
+ case 'proven':
447
+ return this.provenBlockNumber;
448
+ case 'finalized':
449
+ return this.finalizedBlockNumber;
450
+ }
451
+ }
452
+ getBlocks(query) {
453
+ let blocks;
454
+ if ('from' in query) {
455
+ blocks = this.l2Blocks.slice(query.from - 1, query.from - 1 + query.limit);
456
+ } else {
457
+ const epochCheckpoints = this.getCheckpointsInEpoch(query.epoch);
458
+ blocks = epochCheckpoints.flatMap((c)=>c.blocks);
459
+ }
460
+ if (query.onlyCheckpointed) {
461
+ blocks = blocks.filter((b)=>b.header.globalVariables.blockNumber <= this.checkpointedBlockNumber);
462
+ }
463
+ return Promise.resolve(blocks);
464
+ }
465
+ async getBlockData(query) {
466
+ const block = await this.getBlock(query);
467
+ if (!block) {
468
+ return undefined;
469
+ }
470
+ return {
471
+ header: block.header,
472
+ archive: block.archive,
473
+ blockHash: await block.hash(),
474
+ checkpointNumber: block.checkpointNumber,
475
+ indexWithinCheckpoint: block.indexWithinCheckpoint
476
+ };
477
+ }
478
+ async getBlocksData(query) {
479
+ const blocks = await this.getBlocks(query);
480
+ return Promise.all(blocks.map(async (block)=>({
481
+ header: block.header,
482
+ archive: block.archive,
483
+ blockHash: await block.hash(),
484
+ checkpointNumber: block.checkpointNumber,
485
+ indexWithinCheckpoint: block.indexWithinCheckpoint
486
+ })));
487
+ }
410
488
  isPendingChainInvalid() {
411
489
  return Promise.resolve(false);
412
490
  }
@@ -415,6 +493,9 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
415
493
  valid: true
416
494
  });
417
495
  }
496
+ getProposedCheckpointData(_query) {
497
+ return Promise.resolve(undefined);
498
+ }
418
499
  /** Returns checkpoints whose slot falls within the given epoch. */ getCheckpointsInEpoch(epochNumber) {
419
500
  const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
420
501
  const [start, end] = getSlotRangeForEpoch(epochNumber, {
@@ -425,11 +506,6 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
425
506
  /** Creates a mock L1PublishedData for a checkpoint. */ mockL1DataForCheckpoint(checkpoint) {
426
507
  return new L1PublishedData(BigInt(checkpoint.number), BigInt(checkpoint.number), Buffer32.random().toString());
427
508
  }
428
- /** Creates a CheckpointedL2Block from a block using stored checkpoint info. */ toCheckpointedBlock(block) {
429
- const checkpoint = this.checkpointList.find((c)=>c.blocks.some((b)=>b.number === block.number));
430
- const checkpointNumber = checkpoint?.number ?? block.checkpointNumber;
431
- return new CheckpointedL2Block(checkpointNumber, block, new L1PublishedData(BigInt(block.number), BigInt(block.number), `0x${block.number.toString(16).padStart(64, '0')}`), []);
432
- }
433
509
  /** Finds the checkpoint number for a block, or undefined if the block is not in any checkpoint. */ findCheckpointNumberForBlock(blockNumber) {
434
510
  const checkpoint = this.checkpointList.find((c)=>c.blocks.some((b)=>b.number === blockNumber));
435
511
  return checkpoint?.number;
@@ -3,6 +3,7 @@ import { Buffer16 } from '@aztec/foundation/buffer';
3
3
  import type { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
+ import { L2Block } from '@aztec/stdlib/block';
6
7
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
7
8
  import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs';
8
9
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
@@ -28,6 +29,8 @@ export declare function makeBlockHash(blockNumber: number): `0x${string}`;
28
29
  export declare function makeStateForBlock(blockNumber: number, txsPerBlock: number): StateReference;
29
30
  /** Creates L1PublishedData with deterministic values based on l1BlockNumber. */
30
31
  export declare function makeL1PublishedData(l1BlockNumber: number): L1PublishedData;
32
+ /** Creates a Checkpoint from a list of blocks with a header that matches the blocks' structure. */
33
+ export declare function makeCheckpoint(blocks: L2Block[], checkpointNumber?: CheckpointNumber): Checkpoint;
31
34
  /** Wraps a Checkpoint with L1 published data and random attestations. */
32
35
  export declare function makePublishedCheckpoint(checkpoint: Checkpoint, l1BlockNumber: number, attestationCount?: number): PublishedCheckpoint;
33
36
  export interface MakeChainedCheckpointsOptions {
@@ -82,4 +85,4 @@ export interface MockCheckpointWithLogsOptions {
82
85
  }
83
86
  /** Creates a checkpoint with specified logs on each tx effect. */
84
87
  export declare function makeCheckpointWithLogs(blockNumber: number, options?: MockCheckpointWithLogsOptions): Promise<PublishedCheckpoint>;
85
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9ja19zdHJ1Y3RzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC9tb2NrX3N0cnVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFlLGdCQUFnQixFQUF5QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxRQUFRLEVBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUc5RCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUVqRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRTNELE9BQU8sRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBSzNFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdELE9BQU8sRUFBeUIsY0FBYyxFQUFZLE1BQU0sa0JBQWtCLENBQUM7QUFFbkYsT0FBTyxFQUFFLEtBQUssWUFBWSxFQUFxQixNQUFNLDZCQUE2QixDQUFDO0FBRW5GLHdCQUFnQixnQkFBZ0IsQ0FDOUIsbUJBQW1CLFdBQWdCLEVBQ25DLFNBQVMsR0FBRSxPQUFPLENBQUMsWUFBWSxDQUFNLEdBQ3BDLFlBQVksQ0FnQmQ7QUFFRCx3QkFBZ0IsaUJBQWlCLENBQy9CLFVBQVUsRUFBRSxNQUFNLEVBQ2xCLElBQUksR0FBRTtJQUNKLFdBQVcsQ0FBQyxFQUFFLFFBQVEsQ0FBQztJQUN2Qix1QkFBdUIsQ0FBQyxFQUFFLGdCQUFnQixDQUFDO0lBQzNDLHFCQUFxQixDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQy9CLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxF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
88
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9ja19zdHJ1Y3RzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC9tb2NrX3N0cnVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFlLGdCQUFnQixFQUF5QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxRQUFRLEVBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUc5RCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUVqRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBd0IsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RixPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFLM0UsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDN0QsT0FBTyxFQUF5QixjQUFjLEVBQVksTUFBTSxrQkFBa0IsQ0FBQztBQUVuRixPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQXFCLE1BQU0sNkJBQTZCLENBQUM7QUFFbkYsd0JBQWdCLGdCQUFnQixDQUM5QixtQkFBbUIsV0FBZ0IsRUFDbkMsU0FBUyxHQUFFLE9BQU8sQ0FBQyxZQUFZLENBQU0sR0FDcEMsWUFBWSxDQWdCZDtBQUVELHdCQUFnQixpQkFBaUIsQ0FDL0IsVUFBVSxFQUFFLE1BQU0sRUFDbEIsSUFBSSxHQUFFO0lBQ0osV0FBVyxDQUFDLEVBQUUsUUFBUSxDQUFDO0lBQ3ZCLHVCQUF1QixDQUFDLEVBQUUsZ0JBQWdCLENBQUM7SUFDM0MscUJBQXFCLENBQUMsRUFB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
@@ -1 +1 @@
1
- {"version":3,"file":"mock_structs.d.ts","sourceRoot":"","sources":["../../src/test/mock_structs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock_structs.d.ts","sourceRoot":"","sources":["../../src/test/mock_structs.ts"],"names":[],"mappings":"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"}
@@ -77,6 +77,18 @@ export function makeInboxMessages(totalCount, opts = {}) {
77
77
  /** Creates L1PublishedData with deterministic values based on l1BlockNumber. */ export function makeL1PublishedData(l1BlockNumber) {
78
78
  return new L1PublishedData(BigInt(l1BlockNumber), BigInt(l1BlockNumber * 1000), makeBlockHash(l1BlockNumber));
79
79
  }
80
+ /** Creates a Checkpoint from a list of blocks with a header that matches the blocks' structure. */ export function makeCheckpoint(blocks, checkpointNumber = CheckpointNumber(1)) {
81
+ const firstBlock = blocks[0];
82
+ const { slotNumber, timestamp, coinbase, feeRecipient, gasFees } = firstBlock.header.globalVariables;
83
+ return new Checkpoint(blocks.at(-1).archive, CheckpointHeader.random({
84
+ lastArchiveRoot: firstBlock.header.lastArchive.root,
85
+ slotNumber,
86
+ timestamp,
87
+ coinbase,
88
+ feeRecipient,
89
+ gasFees
90
+ }), blocks, checkpointNumber);
91
+ }
80
92
  /** Wraps a Checkpoint with L1 published data and random attestations. */ export function makePublishedCheckpoint(checkpoint, l1BlockNumber, attestationCount = 3) {
81
93
  return new PublishedCheckpoint(checkpoint, makeL1PublishedData(l1BlockNumber), times(attestationCount, CommitteeAttestation.random));
82
94
  }
@@ -164,7 +176,7 @@ export function makeInboxMessages(totalCount, opts = {}) {
164
176
  txEffect.publicLogs = publicLogs ? makePublicLogs(blockNumber, txIndex, publicLogs.numLogsPerTx, publicLogs.contractAddress) : [];
165
177
  return txEffect;
166
178
  });
167
- const checkpoint = new Checkpoint(AppendOnlyTreeSnapshot.random(), CheckpointHeader.random(), [
179
+ const checkpoint = makeCheckpoint([
168
180
  block
169
181
  ], CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)));
170
182
  return makePublishedCheckpoint(checkpoint, blockNumber);