@aztec/archiver 0.0.1-commit.fcb71a6 → 0.0.1-commit.ff7989d6c

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 (200) hide show
  1. package/README.md +156 -22
  2. package/dest/archiver.d.ts +139 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +699 -0
  5. package/dest/{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} +11 -2
  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 +94 -11
  14. package/dest/index.d.ts +11 -4
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +9 -3
  17. package/dest/interfaces.d.ts +9 -0
  18. package/dest/interfaces.d.ts.map +1 -0
  19. package/dest/interfaces.js +3 -0
  20. package/dest/{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 +17 -18
  23. package/dest/{archiver/l1 → l1}/calldata_retriever.d.ts +9 -3
  24. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  25. package/dest/{archiver/l1 → l1}/calldata_retriever.js +19 -6
  26. package/dest/l1/data_retrieval.d.ts +89 -0
  27. package/dest/l1/data_retrieval.d.ts.map +1 -0
  28. package/dest/{archiver/l1 → l1}/data_retrieval.js +39 -57
  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 +1 -1
  32. package/dest/l1/spire_proposer.d.ts.map +1 -0
  33. package/dest/{archiver/l1 → l1}/trace_tx.d.ts +1 -1
  34. package/dest/l1/trace_tx.d.ts.map +1 -0
  35. package/dest/l1/types.d.ts +12 -0
  36. package/dest/l1/types.d.ts.map +1 -0
  37. package/dest/{archiver/l1 → l1}/validate_trace.d.ts +6 -3
  38. package/dest/l1/validate_trace.d.ts.map +1 -0
  39. package/dest/{archiver/l1 → l1}/validate_trace.js +14 -10
  40. package/dest/modules/data_source_base.d.ts +89 -0
  41. package/dest/modules/data_source_base.d.ts.map +1 -0
  42. package/dest/modules/data_source_base.js +216 -0
  43. package/dest/modules/data_store_updater.d.ts +80 -0
  44. package/dest/modules/data_store_updater.d.ts.map +1 -0
  45. package/dest/modules/data_store_updater.js +323 -0
  46. package/dest/modules/instrumentation.d.ts +39 -0
  47. package/dest/modules/instrumentation.d.ts.map +1 -0
  48. package/dest/{archiver → modules}/instrumentation.js +33 -67
  49. package/dest/modules/l1_synchronizer.d.ts +76 -0
  50. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  51. package/dest/modules/l1_synchronizer.js +1112 -0
  52. package/dest/modules/validation.d.ts +17 -0
  53. package/dest/modules/validation.d.ts.map +1 -0
  54. package/dest/{archiver → modules}/validation.js +7 -1
  55. package/dest/store/block_store.d.ts +196 -0
  56. package/dest/store/block_store.d.ts.map +1 -0
  57. package/dest/{archiver/kv_archiver_store → store}/block_store.js +228 -62
  58. package/dest/store/contract_class_store.d.ts +18 -0
  59. package/dest/store/contract_class_store.d.ts.map +1 -0
  60. package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +12 -8
  61. package/dest/store/contract_instance_store.d.ts +24 -0
  62. package/dest/store/contract_instance_store.d.ts.map +1 -0
  63. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
  64. package/dest/store/kv_archiver_store.d.ts +354 -0
  65. package/dest/store/kv_archiver_store.d.ts.map +1 -0
  66. package/dest/store/kv_archiver_store.js +464 -0
  67. package/dest/store/l2_tips_cache.d.ts +19 -0
  68. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  69. package/dest/store/l2_tips_cache.js +89 -0
  70. package/dest/store/log_store.d.ts +54 -0
  71. package/dest/store/log_store.d.ts.map +1 -0
  72. package/dest/{archiver/kv_archiver_store → store}/log_store.js +146 -91
  73. package/dest/{archiver/kv_archiver_store → store}/message_store.d.ts +1 -1
  74. package/dest/store/message_store.d.ts.map +1 -0
  75. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  76. package/dest/structs/data_retrieval.d.ts.map +1 -0
  77. package/dest/structs/inbox_message.d.ts +15 -0
  78. package/dest/structs/inbox_message.d.ts.map +1 -0
  79. package/dest/{archiver/structs → structs}/published.d.ts +1 -1
  80. package/dest/structs/published.d.ts.map +1 -0
  81. package/dest/test/fake_l1_state.d.ts +193 -0
  82. package/dest/test/fake_l1_state.d.ts.map +1 -0
  83. package/dest/test/fake_l1_state.js +389 -0
  84. package/dest/test/index.d.ts +2 -1
  85. package/dest/test/index.d.ts.map +1 -1
  86. package/dest/test/index.js +4 -1
  87. package/dest/test/mock_archiver.d.ts +2 -2
  88. package/dest/test/mock_archiver.d.ts.map +1 -1
  89. package/dest/test/mock_archiver.js +3 -3
  90. package/dest/test/mock_l1_to_l2_message_source.d.ts +2 -2
  91. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  92. package/dest/test/mock_l1_to_l2_message_source.js +12 -3
  93. package/dest/test/mock_l2_block_source.d.ts +39 -17
  94. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  95. package/dest/test/mock_l2_block_source.js +232 -83
  96. package/dest/test/mock_structs.d.ts +78 -3
  97. package/dest/test/mock_structs.d.ts.map +1 -1
  98. package/dest/test/mock_structs.js +140 -7
  99. package/dest/test/noop_l1_archiver.d.ts +23 -0
  100. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  101. package/dest/test/noop_l1_archiver.js +68 -0
  102. package/package.json +16 -17
  103. package/src/archiver.ts +443 -0
  104. package/src/{archiver/config.ts → config.ts} +13 -2
  105. package/src/{archiver/errors.ts → errors.ts} +12 -0
  106. package/src/factory.ts +140 -11
  107. package/src/index.ts +11 -3
  108. package/src/interfaces.ts +9 -0
  109. package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +16 -17
  110. package/src/{archiver/l1 → l1}/calldata_retriever.ts +28 -6
  111. package/src/{archiver/l1 → l1}/data_retrieval.ts +60 -74
  112. package/src/{archiver/l1 → l1}/validate_trace.ts +25 -7
  113. package/src/modules/data_source_base.ts +328 -0
  114. package/src/modules/data_store_updater.ts +448 -0
  115. package/src/{archiver → modules}/instrumentation.ts +33 -70
  116. package/src/modules/l1_synchronizer.ts +932 -0
  117. package/src/{archiver → modules}/validation.ts +11 -6
  118. package/src/{archiver/kv_archiver_store → store}/block_store.ts +293 -100
  119. package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +12 -8
  120. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +1 -1
  121. package/src/{archiver/kv_archiver_store → store}/kv_archiver_store.ts +273 -40
  122. package/src/store/l2_tips_cache.ts +89 -0
  123. package/src/{archiver/kv_archiver_store → store}/log_store.ts +242 -121
  124. package/src/test/fake_l1_state.ts +607 -0
  125. package/src/test/index.ts +4 -0
  126. package/src/test/mock_archiver.ts +4 -3
  127. package/src/test/mock_l1_to_l2_message_source.ts +10 -4
  128. package/src/test/mock_l2_block_source.ts +276 -90
  129. package/src/test/mock_structs.ts +269 -8
  130. package/src/test/noop_l1_archiver.ts +109 -0
  131. package/dest/archiver/archiver.d.ts +0 -304
  132. package/dest/archiver/archiver.d.ts.map +0 -1
  133. package/dest/archiver/archiver.js +0 -1645
  134. package/dest/archiver/archiver_store.d.ts +0 -308
  135. package/dest/archiver/archiver_store.d.ts.map +0 -1
  136. package/dest/archiver/archiver_store.js +0 -4
  137. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  138. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  139. package/dest/archiver/archiver_store_test_suite.js +0 -2770
  140. package/dest/archiver/config.d.ts.map +0 -1
  141. package/dest/archiver/errors.d.ts +0 -36
  142. package/dest/archiver/errors.d.ts.map +0 -1
  143. package/dest/archiver/index.d.ts +0 -7
  144. package/dest/archiver/index.d.ts.map +0 -1
  145. package/dest/archiver/index.js +0 -4
  146. package/dest/archiver/instrumentation.d.ts +0 -37
  147. package/dest/archiver/instrumentation.d.ts.map +0 -1
  148. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -157
  149. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  150. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  151. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  152. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  153. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  154. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -158
  155. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  156. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -313
  157. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -45
  158. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  159. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  160. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
  161. package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
  162. package/dest/archiver/l1/data_retrieval.d.ts +0 -90
  163. package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
  164. package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
  165. package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
  166. package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
  167. package/dest/archiver/l1/types.d.ts +0 -12
  168. package/dest/archiver/l1/types.d.ts.map +0 -1
  169. package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
  170. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  171. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  172. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  173. package/dest/archiver/structs/published.d.ts.map +0 -1
  174. package/dest/archiver/validation.d.ts +0 -17
  175. package/dest/archiver/validation.d.ts.map +0 -1
  176. package/dest/rpc/index.d.ts +0 -9
  177. package/dest/rpc/index.d.ts.map +0 -1
  178. package/dest/rpc/index.js +0 -15
  179. package/src/archiver/archiver.ts +0 -2157
  180. package/src/archiver/archiver_store.ts +0 -372
  181. package/src/archiver/archiver_store_test_suite.ts +0 -2843
  182. package/src/archiver/index.ts +0 -6
  183. package/src/rpc/index.ts +0 -16
  184. /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
  185. /package/dest/{archiver/l1 → l1}/spire_proposer.js +0 -0
  186. /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
  187. /package/dest/{archiver/l1 → l1}/types.js +0 -0
  188. /package/dest/{archiver/kv_archiver_store → store}/message_store.js +0 -0
  189. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  190. /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
  191. /package/dest/{archiver/structs → structs}/published.js +0 -0
  192. /package/src/{archiver/l1 → l1}/README.md +0 -0
  193. /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
  194. /package/src/{archiver/l1 → l1}/spire_proposer.ts +0 -0
  195. /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
  196. /package/src/{archiver/l1 → l1}/types.ts +0 -0
  197. /package/src/{archiver/kv_archiver_store → store}/message_store.ts +0 -0
  198. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
  199. /package/src/{archiver/structs → structs}/inbox_message.ts +0 -0
  200. /package/src/{archiver/structs → structs}/published.ts +0 -0
@@ -1,23 +1,26 @@
1
1
  import { INITIAL_CHECKPOINT_NUMBER, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
- import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
2
+ import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
4
  import { toArray } from '@aztec/foundation/iterable';
4
5
  import { createLogger } from '@aztec/foundation/log';
5
6
  import { BufferReader } from '@aztec/foundation/serialize';
6
7
  import { bufferToHex } from '@aztec/foundation/string';
7
8
  import { isDefined } from '@aztec/foundation/types';
8
- import { Body, CheckpointedL2Block, CommitteeAttestation, L2BlockHash, L2BlockNew, deserializeValidateBlockResult, serializeValidateBlockResult } from '@aztec/stdlib/block';
9
+ import { Body, CheckpointedL2Block, CommitteeAttestation, L2Block, deserializeValidateCheckpointResult, serializeValidateCheckpointResult } from '@aztec/stdlib/block';
9
10
  import { L1PublishedData } from '@aztec/stdlib/checkpoint';
10
11
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
11
12
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
12
- import { BlockHeader, TxHash, TxReceipt, deserializeIndexedTxEffect, serializeIndexedTxEffect } from '@aztec/stdlib/tx';
13
- import { BlockArchiveNotConsistentError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CheckpointNotFoundError, CheckpointNumberNotConsistentError, CheckpointNumberNotSequentialError, InitialBlockNumberNotSequentialError, InitialCheckpointNumberNotSequentialError } from '../errors.js';
13
+ import { BlockHeader, TxHash, TxReceipt, TxStatus, deserializeIndexedTxEffect, serializeIndexedTxEffect } from '@aztec/stdlib/tx';
14
+ import { BlockArchiveNotConsistentError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CannotOverwriteCheckpointedBlockError, CheckpointNotFoundError, CheckpointNumberNotConsistentError, CheckpointNumberNotSequentialError, InitialBlockNumberNotSequentialError, InitialCheckpointNumberNotSequentialError } from '../errors.js';
14
15
  export { TxReceipt } from '@aztec/stdlib/tx';
15
16
  /**
16
- * LMDB implementation of the ArchiverDataStore interface.
17
+ * LMDB-based block storage for the archiver.
17
18
  */ export class BlockStore {
18
19
  db;
20
+ l1Constants;
19
21
  /** Map block number to block data */ #blocks;
20
22
  /** Map checkpoint number to checkpoint data */ #checkpoints;
23
+ /** Map slot number to checkpoint number, for looking up checkpoints by slot range. */ #slotToCheckpoint;
21
24
  /** Map block hash to list of tx hashes */ #blockTxs;
22
25
  /** Tx hash to serialized IndexedTxEffect */ #txEffects;
23
26
  /** Stores L1 block number in which the last processed L2 block was included */ #lastSynchedL1Block;
@@ -27,8 +30,9 @@ export { TxReceipt } from '@aztec/stdlib/tx';
27
30
  /** Index mapping block hash to block number */ #blockHashIndex;
28
31
  /** Index mapping block archive to block number */ #blockArchiveIndex;
29
32
  #log;
30
- constructor(db){
33
+ constructor(db, l1Constants){
31
34
  this.db = db;
35
+ this.l1Constants = l1Constants;
32
36
  this.#log = createLogger('archiver:block_store');
33
37
  this.#blocks = db.openMap('archiver_blocks');
34
38
  this.#blockTxs = db.openMap('archiver_block_txs');
@@ -40,12 +44,25 @@ export { TxReceipt } from '@aztec/stdlib/tx';
40
44
  this.#lastProvenCheckpoint = db.openSingleton('archiver_last_proven_l2_checkpoint');
41
45
  this.#pendingChainValidationStatus = db.openSingleton('archiver_pending_chain_validation_status');
42
46
  this.#checkpoints = db.openMap('archiver_checkpoints');
47
+ this.#slotToCheckpoint = db.openMap('archiver_slot_to_checkpoint');
43
48
  }
44
49
  /**
45
- * Append new blocks to the store's list. All blocks must be for the 'current' checkpoint
46
- * @param blocks - The L2 blocks to be added to the store.
50
+ * Computes the finalized block number based on the proven block number.
51
+ * A block is considered finalized when it's 2 epochs behind the proven block.
52
+ * TODO(#13569): Compute proper finalized block number based on L1 finalized block.
53
+ * TODO(palla/mbps): Even the provisional computation is wrong, since it should subtract checkpoints, not blocks
54
+ * @returns The finalized block number.
55
+ */ async getFinalizedL2BlockNumber() {
56
+ const provenBlockNumber = await this.getProvenBlockNumber();
57
+ return BlockNumber(Math.max(provenBlockNumber - this.l1Constants.epochDuration * 2, 0));
58
+ }
59
+ /**
60
+ * Append new proposed blocks to the store's list. All blocks must be for the 'current' checkpoint.
61
+ * These are uncheckpointed blocks that have been proposed by the sequencer but not yet included in a checkpoint on L1.
62
+ * For checkpointed blocks (already published to L1), use addCheckpoints() instead.
63
+ * @param blocks - The proposed L2 blocks to be added to the store.
47
64
  * @returns True if the operation is successful.
48
- */ async addBlocks(blocks, opts = {}) {
65
+ */ async addProposedBlocks(blocks, opts = {}) {
49
66
  if (blocks.length === 0) {
50
67
  return true;
51
68
  }
@@ -58,6 +75,11 @@ export { TxReceipt } from '@aztec/stdlib/tx';
58
75
  // Extract the latest block and checkpoint numbers
59
76
  const previousBlockNumber = await this.getLatestBlockNumber();
60
77
  const previousCheckpointNumber = await this.getLatestCheckpointNumber();
78
+ // Verify we're not overwriting checkpointed blocks
79
+ const lastCheckpointedBlockNumber = await this.getCheckpointedL2BlockNumber();
80
+ if (!opts.force && firstBlockNumber <= lastCheckpointedBlockNumber) {
81
+ throw new CannotOverwriteCheckpointedBlockError(firstBlockNumber, lastCheckpointedBlockNumber);
82
+ }
61
83
  // Check that the first block number is the expected one
62
84
  if (!opts.force && previousBlockNumber !== firstBlockNumber - 1) {
63
85
  throw new InitialBlockNumberNotSequentialError(firstBlockNumber, previousBlockNumber);
@@ -135,7 +157,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
135
157
  let previousBlock = undefined;
136
158
  // If we have a previous checkpoint then we need to get the previous block number
137
159
  if (previousCheckpointData !== undefined) {
138
- previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.numBlocks - 1);
160
+ previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.blockCount - 1);
139
161
  previousBlock = await this.getBlock(previousBlockNumber);
140
162
  if (previousBlock === undefined) {
141
163
  // We should be able to get the required previous block
@@ -180,19 +202,22 @@ export { TxReceipt } from '@aztec/stdlib/tx';
180
202
  await this.#checkpoints.set(checkpoint.checkpoint.number, {
181
203
  header: checkpoint.checkpoint.header.toBuffer(),
182
204
  archive: checkpoint.checkpoint.archive.toBuffer(),
205
+ checkpointOutHash: checkpoint.checkpoint.getCheckpointOutHash().toBuffer(),
183
206
  l1: checkpoint.l1.toBuffer(),
184
207
  attestations: checkpoint.attestations.map((attestation)=>attestation.toBuffer()),
185
208
  checkpointNumber: checkpoint.checkpoint.number,
186
209
  startBlock: checkpoint.checkpoint.blocks[0].number,
187
- numBlocks: checkpoint.checkpoint.blocks.length
210
+ blockCount: checkpoint.checkpoint.blocks.length
188
211
  });
212
+ // Update slot-to-checkpoint index
213
+ await this.#slotToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, checkpoint.checkpoint.number);
189
214
  }
190
215
  await this.#lastSynchedL1Block.set(checkpoints[checkpoints.length - 1].l1.blockNumber);
191
216
  return true;
192
217
  });
193
218
  }
194
219
  async addBlockToDatabase(block, checkpointNumber, indexWithinCheckpoint) {
195
- const blockHash = L2BlockHash.fromField(await block.hash());
220
+ const blockHash = await block.hash();
196
221
  await this.#blocks.set(block.number, {
197
222
  header: block.header.toBuffer(),
198
223
  blockHash: blockHash.toBuffer(),
@@ -214,48 +239,63 @@ export { TxReceipt } from '@aztec/stdlib/tx';
214
239
  await this.#blockHashIndex.set(blockHash.toString(), block.number);
215
240
  await this.#blockArchiveIndex.set(block.archive.root.toString(), block.number);
216
241
  }
242
+ /** Deletes a block and all associated data (tx effects, indices). */ async deleteBlock(block) {
243
+ // Delete the block from the main blocks map
244
+ await this.#blocks.delete(block.number);
245
+ // Delete all tx effects for this block
246
+ await Promise.all(block.body.txEffects.map((tx)=>this.#txEffects.delete(tx.txHash.toString())));
247
+ // Delete block txs mapping
248
+ const blockHash = (await block.hash()).toString();
249
+ await this.#blockTxs.delete(blockHash);
250
+ // Clean up indices
251
+ await this.#blockHashIndex.delete(blockHash);
252
+ await this.#blockArchiveIndex.delete(block.archive.root.toString());
253
+ }
217
254
  /**
218
- * Unwinds checkpoints from the database
219
- * @param from - The tip of the chain, passed for verification purposes,
220
- * ensuring that we don't end up deleting something we did not intend
221
- * @param checkpointsToUnwind - The number of checkpoints we are to unwind
222
- * @returns True if the operation is successful
223
- */ async unwindCheckpoints(from, checkpointsToUnwind) {
255
+ * Removes all checkpoints with checkpoint number > checkpointNumber.
256
+ * Also removes ALL blocks (both checkpointed and uncheckpointed) after the last block of the given checkpoint.
257
+ * @param checkpointNumber - Remove all checkpoints strictly after this one.
258
+ */ async removeCheckpointsAfter(checkpointNumber) {
224
259
  return await this.db.transactionAsync(async ()=>{
225
- const last = await this.getLatestCheckpointNumber();
226
- if (from !== last) {
227
- throw new Error(`Can only unwind checkpoints from the tip (requested ${from} but current tip is ${last})`);
260
+ const latestCheckpointNumber = await this.getLatestCheckpointNumber();
261
+ if (checkpointNumber >= latestCheckpointNumber) {
262
+ this.#log.warn(`No checkpoints to remove after ${checkpointNumber} (latest is ${latestCheckpointNumber})`);
263
+ return {
264
+ blocksRemoved: undefined
265
+ };
228
266
  }
267
+ // If the proven checkpoint is beyond the target, update it
229
268
  const proven = await this.getProvenCheckpointNumber();
230
- if (from - checkpointsToUnwind < proven) {
231
- await this.setProvenCheckpointNumber(CheckpointNumber(from - checkpointsToUnwind));
269
+ if (proven > checkpointNumber) {
270
+ this.#log.warn(`Updating proven checkpoint ${proven} to last valid checkpoint ${checkpointNumber}`);
271
+ await this.setProvenCheckpointNumber(checkpointNumber);
232
272
  }
233
- for(let i = 0; i < checkpointsToUnwind; i++){
234
- const checkpointNumber = from - i;
235
- const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
236
- if (checkpoint === undefined) {
237
- this.#log.warn(`Cannot remove checkpoint ${checkpointNumber} from the store since we don't have it`);
238
- continue;
273
+ // Find the last block number to keep (last block of the given checkpoint, or 0 if no checkpoint)
274
+ let lastBlockToKeep;
275
+ if (checkpointNumber <= 0) {
276
+ lastBlockToKeep = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
277
+ } else {
278
+ const targetCheckpoint = await this.#checkpoints.getAsync(checkpointNumber);
279
+ if (!targetCheckpoint) {
280
+ throw new Error(`Target checkpoint ${checkpointNumber} not found in store`);
239
281
  }
240
- await this.#checkpoints.delete(checkpointNumber);
241
- const maxBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
242
- for(let blockNumber = checkpoint.startBlock; blockNumber <= maxBlock; blockNumber++){
243
- const block = await this.getBlock(BlockNumber(blockNumber));
244
- if (block === undefined) {
245
- this.#log.warn(`Cannot remove block ${blockNumber} from the store since we don't have it`);
246
- continue;
247
- }
248
- await this.#blocks.delete(block.number);
249
- await Promise.all(block.body.txEffects.map((tx)=>this.#txEffects.delete(tx.txHash.toString())));
250
- const blockHash = (await block.hash()).toString();
251
- await this.#blockTxs.delete(blockHash);
252
- // Clean up indices
253
- await this.#blockHashIndex.delete(blockHash);
254
- await this.#blockArchiveIndex.delete(block.archive.root.toString());
255
- this.#log.debug(`Unwound block ${blockNumber} ${blockHash} for checkpoint ${checkpointNumber}`);
282
+ lastBlockToKeep = BlockNumber(targetCheckpoint.startBlock + targetCheckpoint.blockCount - 1);
283
+ }
284
+ // Remove all blocks after lastBlockToKeep (both checkpointed and uncheckpointed)
285
+ const blocksRemoved = await this.removeBlocksAfter(lastBlockToKeep);
286
+ // Remove all checkpoints after the target
287
+ for(let c = latestCheckpointNumber; c > checkpointNumber; c = CheckpointNumber(c - 1)){
288
+ const checkpointStorage = await this.#checkpoints.getAsync(c);
289
+ if (checkpointStorage) {
290
+ const slotNumber = CheckpointHeader.fromBuffer(checkpointStorage.header).slotNumber;
291
+ await this.#slotToCheckpoint.delete(slotNumber);
256
292
  }
293
+ await this.#checkpoints.delete(c);
294
+ this.#log.debug(`Removed checkpoint ${c}`);
257
295
  }
258
- return true;
296
+ return {
297
+ blocksRemoved
298
+ };
259
299
  });
260
300
  }
261
301
  async getCheckpointData(checkpointNumber) {
@@ -276,17 +316,30 @@ export { TxReceipt } from '@aztec/stdlib/tx';
276
316
  }
277
317
  return checkpoints;
278
318
  }
319
+ /** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */ async getCheckpointDataForSlotRange(startSlot, endSlot) {
320
+ const result = [];
321
+ for await (const [, checkpointNumber] of this.#slotToCheckpoint.entriesAsync({
322
+ start: startSlot,
323
+ end: endSlot + 1
324
+ })){
325
+ const checkpointStorage = await this.#checkpoints.getAsync(checkpointNumber);
326
+ if (checkpointStorage) {
327
+ result.push(this.checkpointDataFromCheckpointStorage(checkpointStorage));
328
+ }
329
+ }
330
+ return result;
331
+ }
279
332
  checkpointDataFromCheckpointStorage(checkpointStorage) {
280
- const data = {
333
+ return {
281
334
  header: CheckpointHeader.fromBuffer(checkpointStorage.header),
282
335
  archive: AppendOnlyTreeSnapshot.fromBuffer(checkpointStorage.archive),
336
+ checkpointOutHash: Fr.fromBuffer(checkpointStorage.checkpointOutHash),
283
337
  checkpointNumber: CheckpointNumber(checkpointStorage.checkpointNumber),
284
- startBlock: checkpointStorage.startBlock,
285
- numBlocks: checkpointStorage.numBlocks,
338
+ startBlock: BlockNumber(checkpointStorage.startBlock),
339
+ blockCount: checkpointStorage.blockCount,
286
340
  l1: L1PublishedData.fromBuffer(checkpointStorage.l1),
287
- attestations: checkpointStorage.attestations
341
+ attestations: checkpointStorage.attestations.map((buf)=>CommitteeAttestation.fromBuffer(buf))
288
342
  };
289
- return data;
290
343
  }
291
344
  async getBlocksForCheckpoint(checkpointNumber) {
292
345
  const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
@@ -295,11 +348,58 @@ export { TxReceipt } from '@aztec/stdlib/tx';
295
348
  }
296
349
  const blocksForCheckpoint = await toArray(this.#blocks.entriesAsync({
297
350
  start: checkpoint.startBlock,
298
- end: checkpoint.startBlock + checkpoint.numBlocks
351
+ end: checkpoint.startBlock + checkpoint.blockCount
299
352
  }));
300
353
  const converted = await Promise.all(blocksForCheckpoint.map((x)=>this.getBlockFromBlockStorage(x[0], x[1])));
301
354
  return converted.filter(isDefined);
302
355
  }
356
+ /**
357
+ * Gets all blocks that have the given slot number.
358
+ * Iterates backwards through blocks for efficiency since we usually query for the last slot.
359
+ * @param slotNumber - The slot number to search for.
360
+ * @returns All blocks with the given slot number, in ascending block number order.
361
+ */ async getBlocksForSlot(slotNumber) {
362
+ const blocks = [];
363
+ // Iterate backwards through all blocks and filter by slot number
364
+ // This is more efficient since we usually query for the most recent slot
365
+ for await (const [blockNumber, blockStorage] of this.#blocks.entriesAsync({
366
+ reverse: true
367
+ })){
368
+ const block = await this.getBlockFromBlockStorage(blockNumber, blockStorage);
369
+ const blockSlot = block?.header.globalVariables.slotNumber;
370
+ if (block && blockSlot === slotNumber) {
371
+ blocks.push(block);
372
+ } else if (blockSlot && blockSlot < slotNumber) {
373
+ break; // Blocks are stored in slot ascending order, so we can stop searching
374
+ }
375
+ }
376
+ // Reverse to return blocks in ascending order (block number order)
377
+ return blocks.reverse();
378
+ }
379
+ /**
380
+ * Removes all blocks with block number > blockNumber.
381
+ * Does not remove any associated checkpoints.
382
+ * @param blockNumber - The block number to remove after.
383
+ * @returns The removed blocks (for event emission).
384
+ */ async removeBlocksAfter(blockNumber) {
385
+ return await this.db.transactionAsync(async ()=>{
386
+ const removedBlocks = [];
387
+ // Get the latest block number to determine the range
388
+ const latestBlockNumber = await this.getLatestBlockNumber();
389
+ // Iterate from blockNumber + 1 to latestBlockNumber
390
+ for(let bn = blockNumber + 1; bn <= latestBlockNumber; bn++){
391
+ const block = await this.getBlock(BlockNumber(bn));
392
+ if (block === undefined) {
393
+ this.#log.warn(`Cannot remove block ${bn} from the store since we don't have it`);
394
+ continue;
395
+ }
396
+ removedBlocks.push(block);
397
+ await this.deleteBlock(block);
398
+ this.#log.debug(`Removed block ${bn} ${(await block.hash()).toString()}`);
399
+ }
400
+ return removedBlocks;
401
+ });
402
+ }
303
403
  async getProvenBlockNumber() {
304
404
  const provenCheckpointNumber = await this.getProvenCheckpointNumber();
305
405
  if (provenCheckpointNumber === INITIAL_CHECKPOINT_NUMBER - 1) {
@@ -309,7 +409,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
309
409
  if (!checkpointStorage) {
310
410
  throw new CheckpointNotFoundError(provenCheckpointNumber);
311
411
  } else {
312
- return BlockNumber(checkpointStorage.startBlock + checkpointStorage.numBlocks - 1);
412
+ return BlockNumber(checkpointStorage.startBlock + checkpointStorage.blockCount - 1);
313
413
  }
314
414
  }
315
415
  async getLatestBlockNumber() {
@@ -344,6 +444,25 @@ export { TxReceipt } from '@aztec/stdlib/tx';
344
444
  }
345
445
  return new CheckpointedL2Block(CheckpointNumber(checkpoint.checkpointNumber), block, L1PublishedData.fromBuffer(checkpoint.l1), checkpoint.attestations.map((buf)=>CommitteeAttestation.fromBuffer(buf)));
346
446
  }
447
+ /**
448
+ * Gets up to `limit` amount of Checkpointed L2 blocks starting from `from`.
449
+ * @param start - Number of the first block to return (inclusive).
450
+ * @param limit - The number of blocks to return.
451
+ * @returns The requested L2 blocks
452
+ */ async *getCheckpointedBlocks(start, limit) {
453
+ const checkpointCache = new Map();
454
+ for await (const [blockNumber, blockStorage] of this.getBlockStorages(start, limit)){
455
+ const block = await this.getBlockFromBlockStorage(blockNumber, blockStorage);
456
+ if (block) {
457
+ const checkpoint = checkpointCache.get(CheckpointNumber(blockStorage.checkpointNumber)) ?? await this.#checkpoints.getAsync(blockStorage.checkpointNumber);
458
+ if (checkpoint) {
459
+ checkpointCache.set(CheckpointNumber(blockStorage.checkpointNumber), checkpoint);
460
+ const checkpointedBlock = new CheckpointedL2Block(CheckpointNumber(checkpoint.checkpointNumber), block, L1PublishedData.fromBuffer(checkpoint.l1), checkpoint.attestations.map((buf)=>CommitteeAttestation.fromBuffer(buf)));
461
+ yield checkpointedBlock;
462
+ }
463
+ }
464
+ }
465
+ }
347
466
  async getCheckpointedBlockByHash(blockHash) {
348
467
  const blockNumber = await this.#blockHashIndex.getAsync(blockHash.toString());
349
468
  if (blockNumber === undefined) {
@@ -372,6 +491,28 @@ export { TxReceipt } from '@aztec/stdlib/tx';
372
491
  }
373
492
  }
374
493
  /**
494
+ * Gets block metadata (without tx data) by block number.
495
+ * @param blockNumber - The number of the block to return.
496
+ * @returns The requested block data.
497
+ */ async getBlockData(blockNumber) {
498
+ const blockStorage = await this.#blocks.getAsync(blockNumber);
499
+ if (!blockStorage || !blockStorage.header) {
500
+ return undefined;
501
+ }
502
+ return this.getBlockDataFromBlockStorage(blockStorage);
503
+ }
504
+ /**
505
+ * Gets block metadata (without tx data) by archive root.
506
+ * @param archive - The archive root of the block to return.
507
+ * @returns The requested block data.
508
+ */ async getBlockDataByArchive(archive) {
509
+ const blockNumber = await this.#blockArchiveIndex.getAsync(archive.toString());
510
+ if (blockNumber === undefined) {
511
+ return undefined;
512
+ }
513
+ return this.getBlockData(BlockNumber(blockNumber));
514
+ }
515
+ /**
375
516
  * Gets an L2 block.
376
517
  * @param blockNumber - The number of the block to return.
377
518
  * @returns The requested L2 block.
@@ -461,11 +602,19 @@ export { TxReceipt } from '@aztec/stdlib/tx';
461
602
  ];
462
603
  }
463
604
  }
605
+ getBlockDataFromBlockStorage(blockStorage) {
606
+ return {
607
+ header: BlockHeader.fromBuffer(blockStorage.header),
608
+ archive: AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive),
609
+ blockHash: Fr.fromBuffer(blockStorage.blockHash),
610
+ checkpointNumber: CheckpointNumber(blockStorage.checkpointNumber),
611
+ indexWithinCheckpoint: IndexWithinCheckpoint(blockStorage.indexWithinCheckpoint)
612
+ };
613
+ }
464
614
  async getBlockFromBlockStorage(blockNumber, blockStorage) {
465
- const header = BlockHeader.fromBuffer(blockStorage.header);
466
- const archive = AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive);
467
- const blockHash = blockStorage.blockHash;
468
- const blockHashString = bufferToHex(blockHash);
615
+ const { header, archive, blockHash, checkpointNumber, indexWithinCheckpoint } = this.getBlockDataFromBlockStorage(blockStorage);
616
+ header.setHash(blockHash);
617
+ const blockHashString = bufferToHex(blockStorage.blockHash);
469
618
  const blockTxsBuffer = await this.#blockTxs.getAsync(blockHashString);
470
619
  if (blockTxsBuffer === undefined) {
471
620
  this.#log.warn(`Could not find body for block ${header.globalVariables.blockNumber} ${blockHash}`);
@@ -483,7 +632,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
483
632
  txEffects.push(deserializeIndexedTxEffect(txEffect).data);
484
633
  }
485
634
  const body = new Body(txEffects);
486
- const block = new L2BlockNew(archive, header, body, CheckpointNumber(blockStorage.checkpointNumber), blockStorage.indexWithinCheckpoint);
635
+ const block = new L2Block(archive, header, body, checkpointNumber, indexWithinCheckpoint);
487
636
  if (block.number !== blockNumber) {
488
637
  throw new Error(`Block number mismatch when retrieving block from archive (expected ${blockNumber} but got ${block.number} with hash ${blockHashString})`);
489
638
  }
@@ -509,7 +658,24 @@ export { TxReceipt } from '@aztec/stdlib/tx';
509
658
  if (!txEffect) {
510
659
  return undefined;
511
660
  }
512
- return new TxReceipt(txHash, TxReceipt.statusFromRevertCode(txEffect.data.revertCode), '', txEffect.data.transactionFee.toBigInt(), txEffect.l2BlockHash, BlockNumber(txEffect.l2BlockNumber));
661
+ const blockNumber = BlockNumber(txEffect.l2BlockNumber);
662
+ // Use existing archiver methods to determine finalization level
663
+ const [provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber] = await Promise.all([
664
+ this.getProvenBlockNumber(),
665
+ this.getCheckpointedL2BlockNumber(),
666
+ this.getFinalizedL2BlockNumber()
667
+ ]);
668
+ let status;
669
+ if (blockNumber <= finalizedBlockNumber) {
670
+ status = TxStatus.FINALIZED;
671
+ } else if (blockNumber <= provenBlockNumber) {
672
+ status = TxStatus.PROVEN;
673
+ } else if (blockNumber <= checkpointedBlockNumber) {
674
+ status = TxStatus.CHECKPOINTED;
675
+ } else {
676
+ status = TxStatus.PROPOSED;
677
+ }
678
+ return new TxReceipt(txHash, status, TxReceipt.executionResultFromRevertCode(txEffect.data.revertCode), undefined, txEffect.data.transactionFee.toBigInt(), txEffect.l2BlockHash, blockNumber);
513
679
  }
514
680
  /**
515
681
  * Looks up which block included the requested tx effect.
@@ -542,7 +708,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
542
708
  if (!checkpoint) {
543
709
  return BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
544
710
  }
545
- return BlockNumber(checkpoint.startBlock + checkpoint.numBlocks - 1);
711
+ return BlockNumber(checkpoint.startBlock + checkpoint.blockCount - 1);
546
712
  }
547
713
  async getLatestL2BlockNumber() {
548
714
  const [lastBlockNumber] = await toArray(this.#blocks.keysAsync({
@@ -591,14 +757,14 @@ export { TxReceipt } from '@aztec/stdlib/tx';
591
757
  if (!buffer) {
592
758
  return undefined;
593
759
  }
594
- return deserializeValidateBlockResult(buffer);
760
+ return deserializeValidateCheckpointResult(buffer);
595
761
  }
596
762
  /**
597
763
  * Sets the pending chain validation status.
598
764
  * @param status - The validation status to store.
599
765
  */ async setPendingChainValidationStatus(status) {
600
766
  if (status) {
601
- const buffer = serializeValidateBlockResult(status);
767
+ const buffer = serializeValidateCheckpointResult(status);
602
768
  await this.#pendingChainValidationStatus.set(buffer);
603
769
  } else {
604
770
  await this.#pendingChainValidationStatus.delete();
@@ -0,0 +1,18 @@
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
+ import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
+ import type { ContractClassPublic, ExecutablePrivateFunctionWithMembershipProof, UtilityFunctionWithMembershipProof } from '@aztec/stdlib/contract';
4
+ /**
5
+ * LMDB-based contract class storage for the archiver.
6
+ */
7
+ export declare class ContractClassStore {
8
+ #private;
9
+ private db;
10
+ constructor(db: AztecAsyncKVStore);
11
+ addContractClass(contractClass: ContractClassPublic, bytecodeCommitment: Fr, blockNumber: number): Promise<void>;
12
+ deleteContractClasses(contractClass: ContractClassPublic, blockNumber: number): Promise<void>;
13
+ getContractClass(id: Fr): Promise<ContractClassPublic | undefined>;
14
+ getBytecodeCommitment(id: Fr): Promise<Fr | undefined>;
15
+ getContractClassIds(): Promise<Fr[]>;
16
+ addFunctions(contractClassId: Fr, newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[], newUtilityFunctions: UtilityFunctionWithMembershipProof[]): Promise<boolean>;
17
+ }
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfY2xhc3Nfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9jb250cmFjdF9jbGFzc19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQWlCLE1BQU0saUJBQWlCLENBQUM7QUFFeEUsT0FBTyxLQUFLLEVBQ1YsbUJBQW1CLEVBRW5CLDRDQUE0QyxFQUM1QyxrQ0FBa0MsRUFDbkMsTUFBTSx3QkFBd0IsQ0FBQztBQUdoQzs7R0FFRztBQUNILHFCQUFhLGtCQUFrQjs7SUFJakIsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUd4QztJQUVLLGdCQUFnQixDQUNwQixhQUFhLEVBQUUsbUJBQW1CLEVBQ2xDLGtCQUFrQixFQUFFLEVBQUUsRUFDdEIsV0FBVyxFQUFFLE1BQU0sR0FDbEIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVFmO0lBRUsscUJBQXFCLENBQUMsYUFBYSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVFsRztJQUVLLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxDQUd2RTtJQUVLLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FHM0Q7SUFFSyxtQkFBbUIsSUFBSSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FFekM7SUFFSyxZQUFZLENBQ2hCLGVBQWUsRUFBRSxFQUFFLEVBQ25CLG1CQUFtQixFQUFFLDRDQUE0QyxFQUFFLEVBQ25FLG1CQUFtQixFQUFFLGtDQUFrQyxFQUFFLEdBQ3hELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0F5QmxCO0NBQ0YifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract_class_store.d.ts","sourceRoot":"","sources":["../../src/store/contract_class_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AAExE,OAAO,KAAK,EACV,mBAAmB,EAEnB,4CAA4C,EAC5C,kCAAkC,EACnC,MAAM,wBAAwB,CAAC;AAGhC;;GAEG;AACH,qBAAa,kBAAkB;;IAIjB,OAAO,CAAC,EAAE;IAAtB,YAAoB,EAAE,EAAE,iBAAiB,EAGxC;IAEK,gBAAgB,CACpB,aAAa,EAAE,mBAAmB,EAClC,kBAAkB,EAAE,EAAE,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf;IAEK,qBAAqB,CAAC,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlG;IAEK,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAGvE;IAEK,qBAAqB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,CAG3D;IAEK,mBAAmB,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC,CAEzC;IAEK,YAAY,CAChB,eAAe,EAAE,EAAE,EACnB,mBAAmB,EAAE,4CAA4C,EAAE,EACnE,mBAAmB,EAAE,kCAAkC,EAAE,GACxD,OAAO,CAAC,OAAO,CAAC,CAyBlB;CACF"}
@@ -4,7 +4,7 @@ import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/s
4
4
  import { FunctionSelector } from '@aztec/stdlib/abi';
5
5
  import { Vector } from '@aztec/stdlib/types';
6
6
  /**
7
- * LMDB implementation of the ArchiverDataStore interface.
7
+ * LMDB-based contract class storage for the archiver.
8
8
  */ export class ContractClassStore {
9
9
  db;
10
10
  #contractClasses;
@@ -15,17 +15,21 @@ import { Vector } from '@aztec/stdlib/types';
15
15
  this.#bytecodeCommitments = db.openMap('archiver_bytecode_commitments');
16
16
  }
17
17
  async addContractClass(contractClass, bytecodeCommitment, blockNumber) {
18
- await this.#contractClasses.setIfNotExists(contractClass.id.toString(), serializeContractClassPublic({
19
- ...contractClass,
20
- l2BlockNumber: blockNumber
21
- }));
22
- await this.#bytecodeCommitments.setIfNotExists(contractClass.id.toString(), bytecodeCommitment.toBuffer());
18
+ await this.db.transactionAsync(async ()=>{
19
+ await this.#contractClasses.setIfNotExists(contractClass.id.toString(), serializeContractClassPublic({
20
+ ...contractClass,
21
+ l2BlockNumber: blockNumber
22
+ }));
23
+ await this.#bytecodeCommitments.setIfNotExists(contractClass.id.toString(), bytecodeCommitment.toBuffer());
24
+ });
23
25
  }
24
26
  async deleteContractClasses(contractClass, blockNumber) {
25
27
  const restoredContractClass = await this.#contractClasses.getAsync(contractClass.id.toString());
26
28
  if (restoredContractClass && deserializeContractClassPublic(restoredContractClass).l2BlockNumber >= blockNumber) {
27
- await this.#contractClasses.delete(contractClass.id.toString());
28
- await this.#bytecodeCommitments.delete(contractClass.id.toString());
29
+ await this.db.transactionAsync(async ()=>{
30
+ await this.#contractClasses.delete(contractClass.id.toString());
31
+ await this.#bytecodeCommitments.delete(contractClass.id.toString());
32
+ });
29
33
  }
30
34
  }
31
35
  async getContractClass(id) {
@@ -0,0 +1,24 @@
1
+ import type { Fr } from '@aztec/foundation/curves/bn254';
2
+ import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
+ import { type ContractInstanceUpdateWithAddress, type ContractInstanceWithAddress } from '@aztec/stdlib/contract';
5
+ import type { UInt64 } from '@aztec/stdlib/types';
6
+ type ContractInstanceUpdateKey = [string, string] | [string, string, number];
7
+ /**
8
+ * LMDB-based contract instance storage for the archiver.
9
+ */
10
+ export declare class ContractInstanceStore {
11
+ #private;
12
+ private db;
13
+ constructor(db: AztecAsyncKVStore);
14
+ addContractInstance(contractInstance: ContractInstanceWithAddress, blockNumber: number): Promise<void>;
15
+ deleteContractInstance(contractInstance: ContractInstanceWithAddress): Promise<void>;
16
+ getUpdateKey(contractAddress: AztecAddress, timestamp: UInt64, logIndex?: number): ContractInstanceUpdateKey;
17
+ addContractInstanceUpdate(contractInstanceUpdate: ContractInstanceUpdateWithAddress, timestamp: UInt64, logIndex: number): Promise<void>;
18
+ deleteContractInstanceUpdate(contractInstanceUpdate: ContractInstanceUpdateWithAddress, timestamp: UInt64, logIndex: number): Promise<void>;
19
+ getCurrentContractInstanceClassId(address: AztecAddress, timestamp: UInt64, originalClassId: Fr): Promise<Fr>;
20
+ getContractInstance(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined>;
21
+ getContractInstanceDeploymentBlockNumber(address: AztecAddress): Promise<number | undefined>;
22
+ }
23
+ export {};
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfaW5zdGFuY2Vfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9jb250cmFjdF9pbnN0YW5jZV9zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsS0FBSyxpQ0FBaUMsRUFDdEMsS0FBSywyQkFBMkIsRUFHakMsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVsRCxLQUFLLHlCQUF5QixHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUU3RTs7R0FFRztBQUNILHFCQUFhLHFCQUFxQjs7SUFLcEIsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUl4QztJQUVELG1CQUFtQixDQUFDLGdCQUFnQixFQUFFLDJCQUEyQixFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVFyRztJQUVELHNCQUFzQixDQUFDLGdCQUFnQixFQUFFLDJCQUEyQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FLbkY7SUFFRCxZQUFZLENBQUMsZUFBZSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFFLE1BQU0sR0FBRyx5QkFBeUIsQ0FNM0c7SUFFRCx5QkFBeUIsQ0FDdkIsc0JBQXNCLEVBQUUsaUNBQWlDLEVBQ3pELFNBQVMsRUFBRSxNQUFNLEVBQ2pCLFFBQVEsRUFBRSxNQUFNLEdBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUtmO0lBRUQsNEJBQTRCLENBQzFCLHNCQUFzQixFQUFFLGlDQUFpQyxFQUN6RCxTQUFTLEVBQUUsTUFBTSxFQUNqQixRQUFRLEVBQUUsTUFBTSxHQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFZjtJQUVLLGlDQUFpQyxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FvQmxIO0lBRUssbUJBQW1CLENBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQ3JCLFNBQVMsRUFBRSxNQUFNLEdBQ2hCLE9BQU8sQ0FBQywyQkFBMkIsR0FBRyxTQUFTLENBQUMsQ0FhbEQ7SUFFRCx3Q0FBd0MsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNGO0NBQ0YifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract_instance_store.d.ts","sourceRoot":"","sources":["../../src/store/contract_instance_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,KAAK,iCAAiC,EACtC,KAAK,2BAA2B,EAGjC,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,KAAK,yBAAyB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE7E;;GAEG;AACH,qBAAa,qBAAqB;;IAKpB,OAAO,CAAC,EAAE;IAAtB,YAAoB,EAAE,EAAE,iBAAiB,EAIxC;IAED,mBAAmB,CAAC,gBAAgB,EAAE,2BAA2B,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQrG;IAED,sBAAsB,CAAC,gBAAgB,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnF;IAED,YAAY,CAAC,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,yBAAyB,CAM3G;IAED,yBAAyB,CACvB,sBAAsB,EAAE,iCAAiC,EACzD,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAKf;IAED,4BAA4B,CAC1B,sBAAsB,EAAE,iCAAiC,EACzD,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAEf;IAEK,iCAAiC,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAoBlH;IAEK,mBAAmB,CACvB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAalD;IAED,wCAAwC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3F;CACF"}
@@ -1,6 +1,6 @@
1
1
  import { SerializableContractInstance, SerializableContractInstanceUpdate } from '@aztec/stdlib/contract';
2
2
  /**
3
- * LMDB implementation of the ArchiverDataStore interface.
3
+ * LMDB-based contract instance storage for the archiver.
4
4
  */ export class ContractInstanceStore {
5
5
  db;
6
6
  #contractInstances;