@aztec/archiver 0.0.1-commit.03f7ef2 → 0.0.1-commit.04d373f

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 (235) hide show
  1. package/README.md +164 -22
  2. package/dest/archiver.d.ts +158 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +881 -0
  5. package/dest/config.d.ts +33 -0
  6. package/dest/config.d.ts.map +1 -0
  7. package/dest/config.js +79 -0
  8. package/dest/errors.d.ts +87 -0
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/errors.js +129 -0
  11. package/dest/factory.d.ts +16 -10
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +112 -20
  14. package/dest/index.d.ts +19 -4
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +17 -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 +35 -32
  23. package/dest/l1/calldata_retriever.d.ts +136 -0
  24. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  25. package/dest/l1/calldata_retriever.js +412 -0
  26. package/dest/l1/data_retrieval.d.ts +97 -0
  27. package/dest/l1/data_retrieval.d.ts.map +1 -0
  28. package/dest/{archiver/l1 → l1}/data_retrieval.js +65 -89
  29. package/dest/{archiver/l1 → l1}/debug_tx.d.ts +1 -1
  30. package/dest/l1/debug_tx.d.ts.map +1 -0
  31. package/dest/{archiver/l1 → l1}/spire_proposer.d.ts +5 -5
  32. package/dest/l1/spire_proposer.d.ts.map +1 -0
  33. package/dest/{archiver/l1 → l1}/spire_proposer.js +9 -17
  34. package/dest/l1/trace_tx.d.ts +43 -0
  35. package/dest/l1/trace_tx.d.ts.map +1 -0
  36. package/dest/l1/types.d.ts +12 -0
  37. package/dest/l1/types.d.ts.map +1 -0
  38. package/dest/l1/validate_historical_logs.d.ts +23 -0
  39. package/dest/l1/validate_historical_logs.d.ts.map +1 -0
  40. package/dest/l1/validate_historical_logs.js +108 -0
  41. package/dest/{archiver/l1 → l1}/validate_trace.d.ts +6 -3
  42. package/dest/l1/validate_trace.d.ts.map +1 -0
  43. package/dest/{archiver/l1 → l1}/validate_trace.js +14 -10
  44. package/dest/modules/contract_data_source_adapter.d.ts +25 -0
  45. package/dest/modules/contract_data_source_adapter.d.ts.map +1 -0
  46. package/dest/modules/contract_data_source_adapter.js +40 -0
  47. package/dest/modules/data_source_base.d.ts +113 -0
  48. package/dest/modules/data_source_base.d.ts.map +1 -0
  49. package/dest/modules/data_source_base.js +351 -0
  50. package/dest/modules/data_store_updater.d.ts +105 -0
  51. package/dest/modules/data_store_updater.d.ts.map +1 -0
  52. package/dest/modules/data_store_updater.js +392 -0
  53. package/dest/modules/instrumentation.d.ts +55 -0
  54. package/dest/modules/instrumentation.d.ts.map +1 -0
  55. package/dest/modules/instrumentation.js +145 -0
  56. package/dest/modules/l1_synchronizer.d.ts +77 -0
  57. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  58. package/dest/modules/l1_synchronizer.js +1344 -0
  59. package/dest/modules/validation.d.ts +18 -0
  60. package/dest/modules/validation.d.ts.map +1 -0
  61. package/dest/{archiver → modules}/validation.js +13 -7
  62. package/dest/store/block_store.d.ts +300 -0
  63. package/dest/store/block_store.d.ts.map +1 -0
  64. package/dest/store/block_store.js +1219 -0
  65. package/dest/store/contract_class_store.d.ts +31 -0
  66. package/dest/store/contract_class_store.d.ts.map +1 -0
  67. package/dest/store/contract_class_store.js +80 -0
  68. package/dest/store/contract_instance_store.d.ts +51 -0
  69. package/dest/store/contract_instance_store.d.ts.map +1 -0
  70. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +38 -3
  71. package/dest/store/data_stores.d.ts +68 -0
  72. package/dest/store/data_stores.d.ts.map +1 -0
  73. package/dest/store/data_stores.js +54 -0
  74. package/dest/store/function_names_cache.d.ts +17 -0
  75. package/dest/store/function_names_cache.d.ts.map +1 -0
  76. package/dest/store/function_names_cache.js +30 -0
  77. package/dest/store/l2_tips_cache.d.ts +25 -0
  78. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  79. package/dest/store/l2_tips_cache.js +26 -0
  80. package/dest/store/log_store.d.ts +59 -0
  81. package/dest/store/log_store.d.ts.map +1 -0
  82. package/dest/store/log_store.js +310 -0
  83. package/dest/store/log_store_codec.d.ts +70 -0
  84. package/dest/store/log_store_codec.d.ts.map +1 -0
  85. package/dest/store/log_store_codec.js +101 -0
  86. package/dest/store/message_store.d.ts +50 -0
  87. package/dest/store/message_store.d.ts.map +1 -0
  88. package/dest/{archiver/kv_archiver_store → store}/message_store.js +51 -9
  89. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  90. package/dest/structs/data_retrieval.d.ts.map +1 -0
  91. package/dest/structs/inbox_message.d.ts +15 -0
  92. package/dest/structs/inbox_message.d.ts.map +1 -0
  93. package/dest/{archiver/structs → structs}/published.d.ts +1 -1
  94. package/dest/structs/published.d.ts.map +1 -0
  95. package/dest/test/fake_l1_state.d.ts +214 -0
  96. package/dest/test/fake_l1_state.d.ts.map +1 -0
  97. package/dest/test/fake_l1_state.js +517 -0
  98. package/dest/test/index.d.ts +2 -1
  99. package/dest/test/index.d.ts.map +1 -1
  100. package/dest/test/index.js +4 -1
  101. package/dest/test/mock_archiver.d.ts +2 -2
  102. package/dest/test/mock_archiver.d.ts.map +1 -1
  103. package/dest/test/mock_archiver.js +3 -3
  104. package/dest/test/mock_l1_to_l2_message_source.d.ts +2 -2
  105. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  106. package/dest/test/mock_l1_to_l2_message_source.js +14 -4
  107. package/dest/test/mock_l2_block_source.d.ts +68 -40
  108. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  109. package/dest/test/mock_l2_block_source.js +356 -131
  110. package/dest/test/mock_structs.d.ts +81 -3
  111. package/dest/test/mock_structs.d.ts.map +1 -1
  112. package/dest/test/mock_structs.js +152 -7
  113. package/dest/test/noop_l1_archiver.d.ts +29 -0
  114. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  115. package/dest/test/noop_l1_archiver.js +85 -0
  116. package/package.json +17 -18
  117. package/src/archiver.ts +681 -0
  118. package/src/{archiver/config.ts → config.ts} +45 -14
  119. package/src/errors.ts +203 -0
  120. package/src/factory.ts +175 -22
  121. package/src/index.ts +27 -3
  122. package/src/interfaces.ts +9 -0
  123. package/src/l1/README.md +55 -0
  124. package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +45 -33
  125. package/src/l1/calldata_retriever.ts +522 -0
  126. package/src/{archiver/l1 → l1}/data_retrieval.ts +106 -134
  127. package/src/{archiver/l1 → l1}/spire_proposer.ts +7 -15
  128. package/src/l1/validate_historical_logs.ts +140 -0
  129. package/src/{archiver/l1 → l1}/validate_trace.ts +25 -7
  130. package/src/modules/contract_data_source_adapter.ts +55 -0
  131. package/src/modules/data_source_base.ts +493 -0
  132. package/src/modules/data_store_updater.ts +518 -0
  133. package/src/modules/instrumentation.ts +204 -0
  134. package/src/modules/l1_synchronizer.ts +1257 -0
  135. package/src/{archiver → modules}/validation.ts +21 -15
  136. package/src/store/block_store.ts +1590 -0
  137. package/src/store/contract_class_store.ts +108 -0
  138. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +52 -6
  139. package/src/store/data_stores.ts +104 -0
  140. package/src/store/function_names_cache.ts +37 -0
  141. package/src/store/l2_tips_cache.ts +35 -0
  142. package/src/store/log_store.ts +379 -0
  143. package/src/store/log_store_codec.ts +132 -0
  144. package/src/{archiver/kv_archiver_store → store}/message_store.ts +60 -10
  145. package/src/{archiver/structs → structs}/inbox_message.ts +1 -1
  146. package/src/test/fake_l1_state.ts +770 -0
  147. package/src/test/index.ts +4 -0
  148. package/src/test/mock_archiver.ts +4 -3
  149. package/src/test/mock_l1_to_l2_message_source.ts +11 -4
  150. package/src/test/mock_l2_block_source.ts +434 -144
  151. package/src/test/mock_structs.ts +283 -8
  152. package/src/test/noop_l1_archiver.ts +139 -0
  153. package/dest/archiver/archiver.d.ts +0 -304
  154. package/dest/archiver/archiver.d.ts.map +0 -1
  155. package/dest/archiver/archiver.js +0 -1645
  156. package/dest/archiver/archiver_store.d.ts +0 -308
  157. package/dest/archiver/archiver_store.d.ts.map +0 -1
  158. package/dest/archiver/archiver_store.js +0 -4
  159. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  160. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  161. package/dest/archiver/archiver_store_test_suite.js +0 -2790
  162. package/dest/archiver/config.d.ts +0 -22
  163. package/dest/archiver/config.d.ts.map +0 -1
  164. package/dest/archiver/config.js +0 -62
  165. package/dest/archiver/errors.d.ts +0 -36
  166. package/dest/archiver/errors.d.ts.map +0 -1
  167. package/dest/archiver/errors.js +0 -54
  168. package/dest/archiver/index.d.ts +0 -7
  169. package/dest/archiver/index.d.ts.map +0 -1
  170. package/dest/archiver/index.js +0 -4
  171. package/dest/archiver/instrumentation.d.ts +0 -37
  172. package/dest/archiver/instrumentation.d.ts.map +0 -1
  173. package/dest/archiver/instrumentation.js +0 -151
  174. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -157
  175. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  176. package/dest/archiver/kv_archiver_store/block_store.js +0 -607
  177. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  178. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  179. package/dest/archiver/kv_archiver_store/contract_class_store.js +0 -120
  180. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  181. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  182. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -158
  183. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  184. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -313
  185. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -45
  186. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  187. package/dest/archiver/kv_archiver_store/log_store.js +0 -404
  188. package/dest/archiver/kv_archiver_store/message_store.d.ts +0 -40
  189. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  190. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
  191. package/dest/archiver/l1/calldata_retriever.d.ts +0 -112
  192. package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
  193. package/dest/archiver/l1/calldata_retriever.js +0 -471
  194. package/dest/archiver/l1/data_retrieval.d.ts +0 -90
  195. package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
  196. package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
  197. package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
  198. package/dest/archiver/l1/trace_tx.d.ts +0 -97
  199. package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
  200. package/dest/archiver/l1/types.d.ts +0 -12
  201. package/dest/archiver/l1/types.d.ts.map +0 -1
  202. package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
  203. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  204. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  205. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  206. package/dest/archiver/structs/published.d.ts.map +0 -1
  207. package/dest/archiver/validation.d.ts +0 -17
  208. package/dest/archiver/validation.d.ts.map +0 -1
  209. package/dest/rpc/index.d.ts +0 -9
  210. package/dest/rpc/index.d.ts.map +0 -1
  211. package/dest/rpc/index.js +0 -15
  212. package/src/archiver/archiver.ts +0 -2157
  213. package/src/archiver/archiver_store.ts +0 -372
  214. package/src/archiver/archiver_store_test_suite.ts +0 -2863
  215. package/src/archiver/errors.ts +0 -90
  216. package/src/archiver/index.ts +0 -6
  217. package/src/archiver/instrumentation.ts +0 -201
  218. package/src/archiver/kv_archiver_store/block_store.ts +0 -822
  219. package/src/archiver/kv_archiver_store/contract_class_store.ts +0 -176
  220. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +0 -438
  221. package/src/archiver/kv_archiver_store/log_store.ts +0 -522
  222. package/src/archiver/l1/README.md +0 -98
  223. package/src/archiver/l1/calldata_retriever.ts +0 -641
  224. package/src/rpc/index.ts +0 -16
  225. /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
  226. /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
  227. /package/dest/{archiver/l1 → l1}/types.js +0 -0
  228. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  229. /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
  230. /package/dest/{archiver/structs → structs}/published.js +0 -0
  231. /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
  232. /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
  233. /package/src/{archiver/l1 → l1}/types.ts +0 -0
  234. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
  235. /package/src/{archiver/structs → structs}/published.ts +0 -0
@@ -1,6 +1,12 @@
1
1
  import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
2
2
  import { DefaultL1ContractsConfig } from '@aztec/ethereum/config';
3
- import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import {
4
+ BlockNumber,
5
+ CheckpointNumber,
6
+ EpochNumber,
7
+ IndexWithinCheckpoint,
8
+ SlotNumber,
9
+ } from '@aztec/foundation/branded-types';
4
10
  import { Buffer32 } from '@aztec/foundation/buffer';
5
11
  import { Fr } from '@aztec/foundation/curves/bn254';
6
12
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -8,18 +14,40 @@ import { createLogger } from '@aztec/foundation/log';
8
14
  import type { FunctionSelector } from '@aztec/stdlib/abi';
9
15
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
10
16
  import {
17
+ type BlockData,
18
+ type BlockHash,
19
+ type BlockQuery,
20
+ type BlockTag,
21
+ type BlocksQuery,
22
+ Body,
23
+ type CheckpointQuery,
24
+ type CheckpointsQuery,
25
+ GENESIS_BLOCK_HEADER_HASH,
26
+ GENESIS_CHECKPOINT_HEADER_HASH,
11
27
  L2Block,
12
- L2BlockHash,
13
- L2BlockNew,
14
28
  type L2BlockSource,
15
29
  type L2Tips,
16
- PublishedL2Block,
17
- type ValidateBlockResult,
30
+ type ProposedCheckpointQuery,
31
+ type ValidateCheckpointResult,
18
32
  } from '@aztec/stdlib/block';
19
- import { type Checkpoint, L1PublishedData } from '@aztec/stdlib/checkpoint';
33
+ import {
34
+ Checkpoint,
35
+ type CheckpointData,
36
+ L1PublishedData,
37
+ type ProposedCheckpointData,
38
+ PublishedCheckpoint,
39
+ } from '@aztec/stdlib/checkpoint';
20
40
  import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
21
- import { EmptyL1RollupConstants, type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
22
- import { type BlockHeader, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
41
+ import {
42
+ EmptyL1RollupConstants,
43
+ type L1RollupConstants,
44
+ getEpochAtSlot,
45
+ getSlotRangeForEpoch,
46
+ } from '@aztec/stdlib/epoch-helpers';
47
+ import { computeCheckpointOutHash } from '@aztec/stdlib/messaging';
48
+ import { CheckpointHeader } from '@aztec/stdlib/rollup';
49
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
50
+ import { BlockHeader, TxExecutionResult, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
23
51
  import type { UInt64 } from '@aztec/stdlib/types';
24
52
 
25
53
  /**
@@ -27,29 +55,123 @@ import type { UInt64 } from '@aztec/stdlib/types';
27
55
  */
28
56
  export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
29
57
  protected l2Blocks: L2Block[] = [];
58
+ protected checkpointList: Checkpoint[] = [];
30
59
 
31
60
  private provenBlockNumber: number = 0;
32
61
  private finalizedBlockNumber: number = 0;
62
+ private checkpointedBlockNumber: number = 0;
63
+ private proposedCheckpointBlockNumber: number = 0;
64
+
65
+ private initialHeader: BlockHeader = BlockHeader.empty();
66
+ private initialHeaderHash: BlockHash = GENESIS_BLOCK_HEADER_HASH;
67
+ private genesisArchiveRoot?: Fr;
68
+ private genesisBlock?: L2Block;
33
69
 
34
70
  private log = createLogger('archiver:mock_l2_block_source');
35
71
 
72
+ /** Returns the initial header used to synthesize block 0. */
73
+ public getInitialHeader(): BlockHeader {
74
+ return this.initialHeader;
75
+ }
76
+
77
+ /**
78
+ * Sets the initial header used to synthesize block 0. Tests that wire up a real
79
+ * world-state should call this with `worldState.getInitialHeader()` so the L2BlockStream
80
+ * agrees on the genesis hash on both sides. Precomputes and caches the header hash so
81
+ * `getGenesisBlockHash()` can return synchronously.
82
+ */
83
+ public async setInitialHeader(header: BlockHeader): Promise<void> {
84
+ this.initialHeader = header;
85
+ this.initialHeaderHash = await header.hash();
86
+ this.genesisBlock = undefined;
87
+ }
88
+
89
+ /**
90
+ * Returns the precomputed hash of the genesis block header. Defaults to the static
91
+ * {@link GENESIS_BLOCK_HEADER_HASH} unless {@link setInitialHeader} has been called with a
92
+ * custom header.
93
+ */
94
+ public getGenesisBlockHash(): BlockHash {
95
+ return this.initialHeaderHash;
96
+ }
97
+
98
+ /**
99
+ * Sets the post-genesis archive root used to synthesize block 0. Mirrors the real archiver,
100
+ * whose synthetic block 0 carries `new AppendOnlyTreeSnapshot(genesisArchiveRoot, 1)` rather
101
+ * than `AppendOnlyTreeSnapshot.empty()`. Tests wiring up a real world-state should set this so
102
+ * archive-based block lookups against the mock match production semantics.
103
+ */
104
+ public setGenesisArchiveRoot(root: Fr): void {
105
+ this.genesisArchiveRoot = root;
106
+ this.genesisBlock = undefined;
107
+ }
108
+
109
+ private getGenesisBlock(): L2Block {
110
+ if (this.genesisBlock) {
111
+ return this.genesisBlock;
112
+ }
113
+ const archive = this.genesisArchiveRoot
114
+ ? new AppendOnlyTreeSnapshot(this.genesisArchiveRoot, 1)
115
+ : AppendOnlyTreeSnapshot.empty();
116
+ return (this.genesisBlock = new L2Block(
117
+ archive,
118
+ this.initialHeader,
119
+ Body.empty(),
120
+ CheckpointNumber.ZERO,
121
+ IndexWithinCheckpoint(0),
122
+ ));
123
+ }
124
+
125
+ /** Creates blocks grouped into single-block checkpoints. */
36
126
  public async createBlocks(numBlocks: number) {
37
- for (let i = 0; i < numBlocks; i++) {
38
- const blockNum = this.l2Blocks.length + 1;
39
- const block = await L2Block.random(BlockNumber(blockNum));
40
- this.l2Blocks.push(block);
127
+ await this.createCheckpoints(numBlocks, 1);
128
+ }
129
+
130
+ public getCheckpointNumber(): Promise<CheckpointNumber> {
131
+ return Promise.resolve(
132
+ this.checkpointList.length === 0 ? CheckpointNumber.ZERO : CheckpointNumber(this.checkpointList.length),
133
+ );
134
+ }
135
+
136
+ /** Creates checkpoints, each containing `blocksPerCheckpoint` blocks. */
137
+ public async createCheckpoints(numCheckpoints: number, blocksPerCheckpoint: number = 1) {
138
+ for (let c = 0; c < numCheckpoints; c++) {
139
+ const checkpointNum = CheckpointNumber(this.checkpointList.length + 1);
140
+ const startBlockNum = this.l2Blocks.length + 1;
141
+ const slotNumber = SlotNumber(Number(checkpointNum));
142
+ const checkpoint = await Checkpoint.random(checkpointNum, {
143
+ numBlocks: blocksPerCheckpoint,
144
+ startBlockNumber: startBlockNum,
145
+ slotNumber,
146
+ checkpointNumber: checkpointNum,
147
+ });
148
+ this.checkpointList.push(checkpoint);
149
+ this.l2Blocks.push(...checkpoint.blocks);
41
150
  }
42
151
 
43
- this.log.verbose(`Created ${numBlocks} blocks in the mock L2 block source`);
152
+ this.log.verbose(
153
+ `Created ${numCheckpoints} checkpoints with ${blocksPerCheckpoint} blocks each in the mock L2 block source`,
154
+ );
44
155
  }
45
156
 
46
- public addBlocks(blocks: L2Block[]) {
157
+ public addProposedBlocks(blocks: L2Block[]) {
47
158
  this.l2Blocks.push(...blocks);
48
- this.log.verbose(`Added ${blocks.length} blocks to the mock L2 block source`);
159
+ this.log.verbose(`Added ${blocks.length} proposed blocks to the mock L2 block source`);
49
160
  }
50
161
 
51
162
  public removeBlocks(numBlocks: number) {
52
163
  this.l2Blocks = this.l2Blocks.slice(0, -numBlocks);
164
+ const maxBlockNum = this.l2Blocks.length;
165
+ // Remove any checkpoint whose last block is beyond the remaining blocks.
166
+ this.checkpointList = this.checkpointList.filter(c => {
167
+ const lastBlockNum = c.blocks[0].number + c.blocks.length - 1;
168
+ return lastBlockNum <= maxBlockNum;
169
+ });
170
+ // Keep tip numbers consistent with remaining blocks.
171
+ this.checkpointedBlockNumber = Math.min(this.checkpointedBlockNumber, maxBlockNum);
172
+ this.proposedCheckpointBlockNumber = Math.min(this.proposedCheckpointBlockNumber, maxBlockNum);
173
+ this.provenBlockNumber = Math.min(this.provenBlockNumber, maxBlockNum);
174
+ this.finalizedBlockNumber = Math.min(this.finalizedBlockNumber, maxBlockNum);
53
175
  this.log.verbose(`Removed ${numBlocks} blocks from the mock L2 block source`);
54
176
  }
55
177
 
@@ -64,6 +186,44 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
64
186
  this.finalizedBlockNumber = finalizedBlockNumber;
65
187
  }
66
188
 
189
+ public setProposedCheckpointBlockNumber(blockNumber: number) {
190
+ this.proposedCheckpointBlockNumber = blockNumber;
191
+ }
192
+
193
+ public setCheckpointedBlockNumber(checkpointedBlockNumber: number) {
194
+ const prevCheckpointed = this.checkpointedBlockNumber;
195
+ this.checkpointedBlockNumber = checkpointedBlockNumber;
196
+ // Proposed checkpoint is always at least as advanced as checkpointed
197
+ if (this.proposedCheckpointBlockNumber < checkpointedBlockNumber) {
198
+ this.proposedCheckpointBlockNumber = checkpointedBlockNumber;
199
+ }
200
+ // Auto-create single-block checkpoints for newly checkpointed blocks that don't have one yet.
201
+ // This handles blocks added via addProposedBlocks that are now being marked as checkpointed.
202
+ const newCheckpoints: Checkpoint[] = [];
203
+ for (let blockNum = prevCheckpointed + 1; blockNum <= checkpointedBlockNumber; blockNum++) {
204
+ const block = this.l2Blocks[blockNum - 1];
205
+ if (!block) {
206
+ continue;
207
+ }
208
+ if (this.checkpointList.some(c => c.blocks.some(b => b.number === block.number))) {
209
+ continue;
210
+ }
211
+ const checkpointNum = CheckpointNumber(this.checkpointList.length + newCheckpoints.length + 1);
212
+ const checkpoint = new Checkpoint(
213
+ block.archive,
214
+ CheckpointHeader.random({ slotNumber: block.header.globalVariables.slotNumber }),
215
+ [block],
216
+ checkpointNum,
217
+ );
218
+ newCheckpoints.push(checkpoint);
219
+ }
220
+ // Insert new checkpoints in order by number.
221
+ if (newCheckpoints.length > 0) {
222
+ this.checkpointList.push(...newCheckpoints);
223
+ this.checkpointList.sort((a, b) => a.number - b.number);
224
+ }
225
+ }
226
+
67
227
  /**
68
228
  * Method to fetch the rollup contract address at the base-layer.
69
229
  * @returns The rollup address.
@@ -84,140 +244,112 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
84
244
  * Gets the number of the latest L2 block processed by the block source implementation.
85
245
  * @returns In this mock instance, returns the number of L2 blocks that we've mocked.
86
246
  */
87
- public getBlockNumber() {
88
- return Promise.resolve(BlockNumber(this.l2Blocks.length));
89
- }
90
-
91
- public getProvenBlockNumber() {
92
- return Promise.resolve(BlockNumber(this.provenBlockNumber));
93
- }
94
-
95
- public getCheckpointedBlock(_number: BlockNumber) {
96
- // In this mock, we don't track checkpointed blocks separately
97
- return Promise.resolve(undefined);
247
+ public getBlockNumber(): Promise<BlockNumber>;
248
+ public getBlockNumber(query: BlockQuery): Promise<BlockNumber | undefined>;
249
+ public async getBlockNumber(query?: BlockQuery): Promise<BlockNumber | undefined> {
250
+ if (!query) {
251
+ return BlockNumber(this.l2Blocks.length);
252
+ }
253
+ if ('number' in query) {
254
+ return query.number;
255
+ }
256
+ if ('tag' in query) {
257
+ return BlockNumber(this.resolveBlockTag(query.tag));
258
+ }
259
+ const block = await this.getBlock(query);
260
+ return block ? block.header.globalVariables.blockNumber : undefined;
98
261
  }
99
262
 
100
- /**
101
- * Gets an l2 block.
102
- * @param number - The block number to return (inclusive).
103
- * @returns The requested L2 block.
104
- */
105
- public getBlock(number: number) {
106
- return Promise.resolve(this.l2Blocks[number - 1]);
263
+ public getProposedCheckpointL2BlockNumber() {
264
+ return Promise.resolve(BlockNumber(this.proposedCheckpointBlockNumber));
107
265
  }
108
266
 
109
- /**
110
- * Gets an L2 block (new format).
111
- * @param number - The block number to return.
112
- * @returns The requested L2 block.
113
- */
114
- public getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
115
- const block = this.l2Blocks[number - 1];
116
- return Promise.resolve(block?.toL2Block());
267
+ public getCheckpoint(query: CheckpointQuery): Promise<PublishedCheckpoint | undefined> {
268
+ const checkpoint = this.resolveCheckpointQuery(query);
269
+ if (!checkpoint) {
270
+ return Promise.resolve(undefined);
271
+ }
272
+ return Promise.resolve(new PublishedCheckpoint(checkpoint, this.mockL1DataForCheckpoint(checkpoint), []));
117
273
  }
118
274
 
119
- /**
120
- * Gets up to `limit` amount of L2 blocks starting from `from`.
121
- * @param from - Number of the first block to return (inclusive).
122
- * @param limit - The maximum number of blocks to return.
123
- * @returns The requested mocked L2 blocks.
124
- */
125
- public getBlocks(from: number, limit: number, proven?: boolean) {
275
+ public getCheckpoints(query: CheckpointsQuery): Promise<PublishedCheckpoint[]> {
276
+ const checkpoints = this.resolveCheckpointsQuery(query);
126
277
  return Promise.resolve(
127
- this.l2Blocks
128
- .slice(from - 1, from - 1 + limit)
129
- .filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber),
278
+ checkpoints.map(checkpoint => new PublishedCheckpoint(checkpoint, this.mockL1DataForCheckpoint(checkpoint), [])),
130
279
  );
131
280
  }
132
281
 
133
- public async getPublishedCheckpoints(from: CheckpointNumber, limit: number) {
134
- // TODO: Implement this properly. This only works when we have one block per checkpoint.
135
- return (await this.getPublishedBlocks(from, limit)).map(block => block.toPublishedCheckpoint());
282
+ public getCheckpointByArchive(archive: Fr): Promise<Checkpoint | undefined> {
283
+ const checkpoint = this.checkpointList.find(c => c.archive.root.equals(archive));
284
+ return Promise.resolve(checkpoint);
136
285
  }
137
286
 
138
- public async getCheckpointByArchive(archive: Fr): Promise<Checkpoint | undefined> {
139
- // TODO: Implement this properly. This only works when we have one block per checkpoint.
140
- return (await this.getPublishedBlockByArchive(archive))?.block.toCheckpoint();
287
+ public getCheckpointData(query: CheckpointQuery): Promise<CheckpointData | undefined> {
288
+ const checkpoint = this.resolveCheckpointQuery(query);
289
+ if (!checkpoint) {
290
+ return Promise.resolve(undefined);
291
+ }
292
+ return Promise.resolve(this.checkpointToData(checkpoint));
141
293
  }
142
294
 
143
- public async getPublishedBlocks(from: number, limit: number, proven?: boolean) {
144
- const blocks = await this.getBlocks(from, limit, proven);
145
- return blocks.map(block =>
146
- PublishedL2Block.fromFields({
147
- block,
148
- l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
149
- attestations: [],
150
- }),
151
- );
295
+ public getCheckpointsData(query: CheckpointsQuery): Promise<CheckpointData[]> {
296
+ const checkpoints = this.resolveCheckpointsQuery(query);
297
+ return Promise.resolve(checkpoints.map(c => this.checkpointToData(c)));
152
298
  }
153
299
 
154
- public async getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
155
- for (const block of this.l2Blocks) {
156
- const hash = await block.hash();
157
- if (hash.equals(blockHash)) {
158
- return PublishedL2Block.fromFields({
159
- block,
160
- l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
161
- attestations: [],
162
- });
163
- }
164
- }
165
- return undefined;
300
+ private checkpointToData(checkpoint: Checkpoint): CheckpointData {
301
+ return {
302
+ checkpointNumber: checkpoint.number,
303
+ header: checkpoint.header,
304
+ archive: checkpoint.archive,
305
+ checkpointOutHash: computeCheckpointOutHash(
306
+ checkpoint.blocks.map(b => b.body.txEffects.map(tx => tx.l2ToL1Msgs)),
307
+ ),
308
+ startBlock: checkpoint.blocks[0].number,
309
+ blockCount: checkpoint.blocks.length,
310
+ feeAssetPriceModifier: checkpoint.feeAssetPriceModifier,
311
+ attestations: [],
312
+ l1: this.mockL1DataForCheckpoint(checkpoint),
313
+ };
166
314
  }
167
315
 
168
- public getPublishedBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined> {
169
- const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
170
- if (!block) {
171
- return Promise.resolve(undefined);
316
+ private resolveCheckpointQuery(query: CheckpointQuery): Checkpoint | undefined {
317
+ if ('number' in query) {
318
+ return this.checkpointList[query.number - 1];
172
319
  }
173
- return Promise.resolve(
174
- PublishedL2Block.fromFields({
175
- block,
176
- l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
177
- attestations: [],
178
- }),
179
- );
180
- }
181
-
182
- public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
183
- for (const block of this.l2Blocks) {
184
- const hash = await block.hash();
185
- if (hash.equals(blockHash)) {
186
- return block.getBlockHeader();
320
+ if ('slot' in query) {
321
+ return this.checkpointList.find(c => c.header.slotNumber === query.slot);
322
+ }
323
+ switch (query.tag) {
324
+ case 'checkpointed':
325
+ return this.checkpointList[this.checkpointList.length - 1];
326
+ case 'proven': {
327
+ const provenCheckpoint = this.checkpointList.filter(c =>
328
+ c.blocks.some(b => b.number <= this.provenBlockNumber),
329
+ );
330
+ return provenCheckpoint.at(-1);
331
+ }
332
+ case 'finalized': {
333
+ const finalizedCheckpoint = this.checkpointList.filter(c =>
334
+ c.blocks.some(b => b.number <= this.finalizedBlockNumber),
335
+ );
336
+ return finalizedCheckpoint.at(-1);
187
337
  }
188
338
  }
189
- return undefined;
190
- }
191
-
192
- public getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
193
- const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
194
- return Promise.resolve(block?.getBlockHeader());
195
- }
196
-
197
- getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
198
- return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number - 1 : -1)?.getBlockHeader());
199
339
  }
200
340
 
201
- getCheckpointsForEpoch(epochNumber: EpochNumber): Promise<Checkpoint[]> {
202
- // TODO: Implement this properly. This only works when we have one block per checkpoint.
203
- return this.getBlocksForEpoch(epochNumber).then(blocks => blocks.map(b => b.toCheckpoint()));
341
+ private resolveCheckpointsQuery(query: CheckpointsQuery): Checkpoint[] {
342
+ if ('from' in query) {
343
+ return this.checkpointList.slice(query.from - 1, query.from - 1 + query.limit);
344
+ }
345
+ return this.getCheckpointsInEpoch(query.epoch);
204
346
  }
205
347
 
206
- getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2Block[]> {
207
- const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
208
- const [start, end] = getSlotRangeForEpoch(epochNumber, { epochDuration });
209
- const blocks = this.l2Blocks.filter(b => {
210
- const slot = b.header.globalVariables.slotNumber;
211
- return slot >= start && slot <= end;
212
- });
348
+ getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
349
+ const blocks = this.l2Blocks.filter(b => b.header.globalVariables.slotNumber === slotNumber);
213
350
  return Promise.resolve(blocks);
214
351
  }
215
352
 
216
- async getBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
217
- const blocks = await this.getBlocksForEpoch(epochNumber);
218
- return blocks.map(b => b.getBlockHeader());
219
- }
220
-
221
353
  /**
222
354
  * Gets a tx effect.
223
355
  * @param txHash - The hash of the tx corresponding to the tx effect.
@@ -234,8 +366,8 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
234
366
  return {
235
367
  data: txEffect,
236
368
  l2BlockNumber: block.number,
237
- l2BlockHash: L2BlockHash.fromField(await block.hash()),
238
- txIndexInBlock: block.body.txEffects.indexOf(txEffect),
369
+ l2BlockHash: await block.hash(),
370
+ txIndexInBlock: block.body.txEffects.findIndex(t => t.txHash.equals(txHash)),
239
371
  };
240
372
  }
241
373
 
@@ -248,13 +380,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
248
380
  for (const block of this.l2Blocks) {
249
381
  for (const txEffect of block.body.txEffects) {
250
382
  if (txEffect.txHash.equals(txHash)) {
383
+ // In mock, assume all txs are checkpointed with successful execution
251
384
  return new TxReceipt(
252
385
  txHash,
253
- TxStatus.SUCCESS,
254
- '',
386
+ TxStatus.CHECKPOINTED,
387
+ TxExecutionResult.SUCCESS,
388
+ undefined,
255
389
  txEffect.transactionFee.toBigInt(),
256
- L2BlockHash.fromField(await block.hash()),
390
+ await block.hash(),
257
391
  block.number,
392
+ getEpochAtSlot(block.slot, EmptyL1RollupConstants),
258
393
  );
259
394
  }
260
395
  }
@@ -263,37 +398,77 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
263
398
  }
264
399
 
265
400
  async getL2Tips(): Promise<L2Tips> {
266
- const [latest, proven, finalized] = [
401
+ const [latest, proven, finalized, checkpointed, proposedCheckpoint] = [
267
402
  await this.getBlockNumber(),
268
- await this.getProvenBlockNumber(),
403
+ this.provenBlockNumber,
269
404
  this.finalizedBlockNumber,
405
+ this.checkpointedBlockNumber,
406
+ await this.getProposedCheckpointL2BlockNumber(),
270
407
  ] as const;
271
408
 
272
409
  const latestBlock = this.l2Blocks[latest - 1];
273
410
  const provenBlock = this.l2Blocks[proven - 1];
274
411
  const finalizedBlock = this.l2Blocks[finalized - 1];
412
+ const checkpointedBlock = this.l2Blocks[checkpointed - 1];
413
+ const proposedCheckpointBlock = this.l2Blocks[proposedCheckpoint - 1];
414
+
415
+ // For genesis tips (block number 0) report the dynamic initial header hash so consumers
416
+ // running L2BlockStream against this mock agree at block 0 with their local tip store.
417
+ const genesisHash = (await this.initialHeader.hash()).toString();
418
+ const tipHash = async (block: L2Block | undefined, number: number): Promise<string> => {
419
+ if (block) {
420
+ return (await block.hash()).toString();
421
+ }
422
+ return number === 0 ? genesisHash : '';
423
+ };
424
+
425
+ const latestBlockId = {
426
+ number: BlockNumber(latest),
427
+ hash: await tipHash(latestBlock, latest),
428
+ };
429
+ const provenBlockId = {
430
+ number: BlockNumber(proven),
431
+ hash: await tipHash(provenBlock, proven),
432
+ };
433
+ const finalizedBlockId = {
434
+ number: BlockNumber(finalized),
435
+ hash: await tipHash(finalizedBlock, finalized),
436
+ };
437
+ const checkpointedBlockId = {
438
+ number: BlockNumber(checkpointed),
439
+ hash: await tipHash(checkpointedBlock, checkpointed),
440
+ };
441
+ const proposedCheckpointBlockId = {
442
+ number: BlockNumber(proposedCheckpoint),
443
+ hash: await tipHash(proposedCheckpointBlock, proposedCheckpoint),
444
+ };
445
+
446
+ const makeTipId = (blockId: typeof latestBlockId) => {
447
+ const checkpointNumber = this.findCheckpointNumberForBlock(blockId.number) ?? CheckpointNumber(0);
448
+ // Match production semantics: checkpoint 0 is fully synthetic (no real checkpoint header
449
+ // exists at 0), so its hash stays at the protocol constant `GENESIS_CHECKPOINT_HEADER_HASH`
450
+ // even though the block-0 hash is dynamic. See L2TipsCache for the production path.
451
+ const hash = checkpointNumber === 0 ? GENESIS_CHECKPOINT_HEADER_HASH.toString() : blockId.hash;
452
+ return {
453
+ block: blockId,
454
+ checkpoint: { number: checkpointNumber, hash },
455
+ };
456
+ };
275
457
 
276
458
  return {
277
- latest: {
278
- number: BlockNumber(latest),
279
- hash: (await latestBlock?.hash())?.toString(),
280
- },
281
- proven: {
282
- number: BlockNumber(proven),
283
- hash: (await provenBlock?.hash())?.toString(),
284
- },
285
- finalized: {
286
- number: BlockNumber(finalized),
287
- hash: (await finalizedBlock?.hash())?.toString(),
288
- },
459
+ proposed: latestBlockId,
460
+ checkpointed: makeTipId(checkpointedBlockId),
461
+ proven: makeTipId(provenBlockId),
462
+ finalized: makeTipId(finalizedBlockId),
463
+ proposedCheckpoint: makeTipId(proposedCheckpointBlockId),
289
464
  };
290
465
  }
291
466
 
292
- getL2EpochNumber(): Promise<EpochNumber> {
467
+ getSyncedL2EpochNumber(): Promise<EpochNumber> {
293
468
  throw new Error('Method not implemented.');
294
469
  }
295
470
 
296
- getL2SlotNumber(): Promise<SlotNumber> {
471
+ getSyncedL2SlotNumber(): Promise<SlotNumber> {
297
472
  throw new Error('Method not implemented.');
298
473
  }
299
474
 
@@ -305,8 +480,12 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
305
480
  return Promise.resolve(EmptyL1RollupConstants);
306
481
  }
307
482
 
483
+ isPruneDueAtSlot(_slot: SlotNumber): Promise<boolean> {
484
+ return Promise.resolve(false);
485
+ }
486
+
308
487
  getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
309
- return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
488
+ return Promise.resolve({ genesisArchiveRoot: this.genesisArchiveRoot ?? new Fr(GENESIS_ARCHIVE_ROOT) });
310
489
  }
311
490
 
312
491
  getL1Timestamp(): Promise<bigint> {
@@ -359,11 +538,122 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
359
538
  return Promise.resolve();
360
539
  }
361
540
 
541
+ async getBlock(query: BlockQuery): Promise<L2Block | undefined> {
542
+ if ('number' in query) {
543
+ if (query.number === 0) {
544
+ return this.getGenesisBlock();
545
+ }
546
+ return this.l2Blocks[query.number - 1];
547
+ }
548
+ if ('hash' in query) {
549
+ const genesis = this.getGenesisBlock();
550
+ if ((await genesis.hash()).equals(query.hash)) {
551
+ return genesis;
552
+ }
553
+ for (const b of this.l2Blocks) {
554
+ const hash = await b.hash();
555
+ if (hash.equals(query.hash)) {
556
+ return b;
557
+ }
558
+ }
559
+ return undefined;
560
+ }
561
+ if ('archive' in query) {
562
+ const genesis = this.getGenesisBlock();
563
+ if (genesis.archive.root.equals(query.archive)) {
564
+ return genesis;
565
+ }
566
+ return this.l2Blocks.find(b => b.archive.root.equals(query.archive));
567
+ }
568
+ const number = this.resolveBlockTag(query.tag);
569
+ if (number === 0) {
570
+ return this.getGenesisBlock();
571
+ }
572
+ return this.l2Blocks[number - 1];
573
+ }
574
+
575
+ private resolveBlockTag(tag: BlockTag): number {
576
+ switch (tag) {
577
+ case 'latest':
578
+ case 'proposed':
579
+ return this.l2Blocks.length;
580
+ case 'checkpointed':
581
+ return this.checkpointedBlockNumber;
582
+ case 'proven':
583
+ return this.provenBlockNumber;
584
+ case 'finalized':
585
+ return this.finalizedBlockNumber;
586
+ }
587
+ }
588
+
589
+ getBlocks(query: BlocksQuery): Promise<L2Block[]> {
590
+ let blocks: L2Block[];
591
+ if ('from' in query) {
592
+ blocks = this.l2Blocks.slice(query.from - 1, query.from - 1 + query.limit);
593
+ } else {
594
+ const epochCheckpoints = this.getCheckpointsInEpoch(query.epoch);
595
+ blocks = epochCheckpoints.flatMap(c => c.blocks);
596
+ }
597
+ if (query.onlyCheckpointed) {
598
+ blocks = blocks.filter(b => b.header.globalVariables.blockNumber <= this.checkpointedBlockNumber);
599
+ }
600
+ return Promise.resolve(blocks);
601
+ }
602
+
603
+ async getBlockData(query: BlockQuery): Promise<BlockData | undefined> {
604
+ const block = await this.getBlock(query);
605
+ if (!block) {
606
+ return undefined;
607
+ }
608
+ return {
609
+ header: block.header,
610
+ archive: block.archive,
611
+ blockHash: await block.hash(),
612
+ checkpointNumber: block.checkpointNumber,
613
+ indexWithinCheckpoint: block.indexWithinCheckpoint,
614
+ };
615
+ }
616
+
617
+ async getBlocksData(query: BlocksQuery): Promise<BlockData[]> {
618
+ const blocks = await this.getBlocks(query);
619
+ return Promise.all(
620
+ blocks.map(async block => ({
621
+ header: block.header,
622
+ archive: block.archive,
623
+ blockHash: await block.hash(),
624
+ checkpointNumber: block.checkpointNumber,
625
+ indexWithinCheckpoint: block.indexWithinCheckpoint,
626
+ })),
627
+ );
628
+ }
629
+
362
630
  isPendingChainInvalid(): Promise<boolean> {
363
631
  return Promise.resolve(false);
364
632
  }
365
633
 
366
- getPendingChainValidationStatus(): Promise<ValidateBlockResult> {
634
+ getPendingChainValidationStatus(): Promise<ValidateCheckpointResult> {
367
635
  return Promise.resolve({ valid: true });
368
636
  }
637
+
638
+ getProposedCheckpointData(_query?: ProposedCheckpointQuery): Promise<ProposedCheckpointData | undefined> {
639
+ return Promise.resolve(undefined);
640
+ }
641
+
642
+ /** Returns checkpoints whose slot falls within the given epoch. */
643
+ private getCheckpointsInEpoch(epochNumber: EpochNumber): Checkpoint[] {
644
+ const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
645
+ const [start, end] = getSlotRangeForEpoch(epochNumber, { epochDuration });
646
+ return this.checkpointList.filter(c => c.header.slotNumber >= start && c.header.slotNumber <= end);
647
+ }
648
+
649
+ /** Creates a mock L1PublishedData for a checkpoint. */
650
+ private mockL1DataForCheckpoint(checkpoint: Checkpoint): L1PublishedData {
651
+ return new L1PublishedData(BigInt(checkpoint.number), BigInt(checkpoint.number), Buffer32.random().toString());
652
+ }
653
+
654
+ /** Finds the checkpoint number for a block, or undefined if the block is not in any checkpoint. */
655
+ private findCheckpointNumberForBlock(blockNumber: BlockNumber): CheckpointNumber | undefined {
656
+ const checkpoint = this.checkpointList.find(c => c.blocks.some(b => b.number === blockNumber));
657
+ return checkpoint?.number;
658
+ }
369
659
  }