@aztec/archiver 0.0.1-commit.3469e52 → 0.0.1-commit.35158ae7e

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 (107) hide show
  1. package/README.md +9 -0
  2. package/dest/archiver.d.ts +12 -9
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +98 -124
  5. package/dest/config.d.ts +3 -3
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +2 -1
  8. package/dest/errors.d.ts +26 -9
  9. package/dest/errors.d.ts.map +1 -1
  10. package/dest/errors.js +34 -13
  11. package/dest/factory.d.ts +4 -2
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +29 -23
  14. package/dest/index.d.ts +2 -1
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +1 -0
  17. package/dest/l1/bin/retrieve-calldata.js +35 -32
  18. package/dest/l1/calldata_retriever.d.ts +73 -50
  19. package/dest/l1/calldata_retriever.d.ts.map +1 -1
  20. package/dest/l1/calldata_retriever.js +190 -259
  21. package/dest/l1/data_retrieval.d.ts +9 -9
  22. package/dest/l1/data_retrieval.d.ts.map +1 -1
  23. package/dest/l1/data_retrieval.js +24 -22
  24. package/dest/l1/spire_proposer.d.ts +5 -5
  25. package/dest/l1/spire_proposer.d.ts.map +1 -1
  26. package/dest/l1/spire_proposer.js +9 -17
  27. package/dest/l1/validate_trace.d.ts +6 -3
  28. package/dest/l1/validate_trace.d.ts.map +1 -1
  29. package/dest/l1/validate_trace.js +13 -9
  30. package/dest/modules/data_source_base.d.ts +27 -23
  31. package/dest/modules/data_source_base.d.ts.map +1 -1
  32. package/dest/modules/data_source_base.js +49 -124
  33. package/dest/modules/data_store_updater.d.ts +42 -26
  34. package/dest/modules/data_store_updater.d.ts.map +1 -1
  35. package/dest/modules/data_store_updater.js +149 -129
  36. package/dest/modules/instrumentation.d.ts +17 -4
  37. package/dest/modules/instrumentation.d.ts.map +1 -1
  38. package/dest/modules/instrumentation.js +36 -12
  39. package/dest/modules/l1_synchronizer.d.ts +5 -8
  40. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  41. package/dest/modules/l1_synchronizer.js +59 -25
  42. package/dest/store/block_store.d.ts +49 -32
  43. package/dest/store/block_store.d.ts.map +1 -1
  44. package/dest/store/block_store.js +188 -95
  45. package/dest/store/contract_class_store.d.ts +2 -3
  46. package/dest/store/contract_class_store.d.ts.map +1 -1
  47. package/dest/store/contract_class_store.js +16 -72
  48. package/dest/store/contract_instance_store.d.ts +1 -1
  49. package/dest/store/contract_instance_store.d.ts.map +1 -1
  50. package/dest/store/contract_instance_store.js +6 -2
  51. package/dest/store/kv_archiver_store.d.ts +64 -36
  52. package/dest/store/kv_archiver_store.d.ts.map +1 -1
  53. package/dest/store/kv_archiver_store.js +63 -29
  54. package/dest/store/l2_tips_cache.d.ts +19 -0
  55. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  56. package/dest/store/l2_tips_cache.js +89 -0
  57. package/dest/store/log_store.d.ts +9 -6
  58. package/dest/store/log_store.d.ts.map +1 -1
  59. package/dest/store/log_store.js +150 -53
  60. package/dest/store/message_store.d.ts +5 -1
  61. package/dest/store/message_store.d.ts.map +1 -1
  62. package/dest/store/message_store.js +14 -1
  63. package/dest/test/fake_l1_state.d.ts +16 -4
  64. package/dest/test/fake_l1_state.d.ts.map +1 -1
  65. package/dest/test/fake_l1_state.js +95 -23
  66. package/dest/test/index.js +3 -1
  67. package/dest/test/mock_archiver.d.ts +1 -1
  68. package/dest/test/mock_archiver.d.ts.map +1 -1
  69. package/dest/test/mock_archiver.js +3 -2
  70. package/dest/test/mock_l2_block_source.d.ts +39 -23
  71. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  72. package/dest/test/mock_l2_block_source.js +157 -112
  73. package/dest/test/mock_structs.d.ts +6 -2
  74. package/dest/test/mock_structs.d.ts.map +1 -1
  75. package/dest/test/mock_structs.js +24 -10
  76. package/dest/test/noop_l1_archiver.d.ts +26 -0
  77. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  78. package/dest/test/noop_l1_archiver.js +72 -0
  79. package/package.json +14 -13
  80. package/src/archiver.ts +126 -151
  81. package/src/config.ts +8 -1
  82. package/src/errors.ts +52 -24
  83. package/src/factory.ts +46 -22
  84. package/src/index.ts +1 -0
  85. package/src/l1/README.md +25 -68
  86. package/src/l1/bin/retrieve-calldata.ts +45 -33
  87. package/src/l1/calldata_retriever.ts +249 -379
  88. package/src/l1/data_retrieval.ts +27 -29
  89. package/src/l1/spire_proposer.ts +7 -15
  90. package/src/l1/validate_trace.ts +24 -6
  91. package/src/modules/data_source_base.ts +84 -169
  92. package/src/modules/data_store_updater.ts +166 -161
  93. package/src/modules/instrumentation.ts +46 -14
  94. package/src/modules/l1_synchronizer.ts +72 -36
  95. package/src/store/block_store.ts +239 -140
  96. package/src/store/contract_class_store.ts +16 -110
  97. package/src/store/contract_instance_store.ts +8 -5
  98. package/src/store/kv_archiver_store.ts +104 -53
  99. package/src/store/l2_tips_cache.ts +89 -0
  100. package/src/store/log_store.ts +231 -70
  101. package/src/store/message_store.ts +20 -1
  102. package/src/test/fake_l1_state.ts +127 -28
  103. package/src/test/index.ts +3 -0
  104. package/src/test/mock_archiver.ts +3 -2
  105. package/src/test/mock_l2_block_source.ts +211 -129
  106. package/src/test/mock_structs.ts +45 -15
  107. package/src/test/noop_l1_archiver.ts +115 -0
@@ -6,12 +6,13 @@ import { createLogger } from '@aztec/foundation/log';
6
6
  import { BufferReader } from '@aztec/foundation/serialize';
7
7
  import { bufferToHex } from '@aztec/foundation/string';
8
8
  import { isDefined } from '@aztec/foundation/types';
9
- import { Body, CheckpointedL2Block, CommitteeAttestation, L2BlockHash, L2BlockNew, deserializeValidateCheckpointResult, serializeValidateCheckpointResult } from '@aztec/stdlib/block';
9
+ import { Body, CheckpointedL2Block, CommitteeAttestation, L2Block, deserializeValidateCheckpointResult, serializeValidateCheckpointResult } from '@aztec/stdlib/block';
10
10
  import { L1PublishedData } from '@aztec/stdlib/checkpoint';
11
+ import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
11
12
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
12
13
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
13
- import { BlockHeader, TxHash, TxReceipt, deserializeIndexedTxEffect, serializeIndexedTxEffect } from '@aztec/stdlib/tx';
14
- import { BlockArchiveNotConsistentError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CheckpointNotFoundError, CheckpointNumberNotConsistentError, CheckpointNumberNotSequentialError, InitialBlockNumberNotSequentialError, InitialCheckpointNumberNotSequentialError } from '../errors.js';
14
+ import { BlockHeader, TxHash, TxReceipt, TxStatus, deserializeIndexedTxEffect, serializeIndexedTxEffect } from '@aztec/stdlib/tx';
15
+ import { BlockAlreadyCheckpointedError, BlockArchiveNotConsistentError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CannotOverwriteCheckpointedBlockError, CheckpointNotFoundError, CheckpointNumberNotSequentialError, InitialCheckpointNumberNotSequentialError } from '../errors.js';
15
16
  export { TxReceipt } from '@aztec/stdlib/tx';
16
17
  /**
17
18
  * LMDB-based block storage for the archiver.
@@ -19,10 +20,12 @@ export { TxReceipt } from '@aztec/stdlib/tx';
19
20
  db;
20
21
  /** Map block number to block data */ #blocks;
21
22
  /** Map checkpoint number to checkpoint data */ #checkpoints;
23
+ /** Map slot number to checkpoint number, for looking up checkpoints by slot range. */ #slotToCheckpoint;
22
24
  /** Map block hash to list of tx hashes */ #blockTxs;
23
25
  /** Tx hash to serialized IndexedTxEffect */ #txEffects;
24
26
  /** Stores L1 block number in which the last processed L2 block was included */ #lastSynchedL1Block;
25
27
  /** Stores last proven checkpoint */ #lastProvenCheckpoint;
28
+ /** Stores last finalized checkpoint (proven at or before the finalized L1 block) */ #lastFinalizedCheckpoint;
26
29
  /** Stores the pending chain validation status */ #pendingChainValidationStatus;
27
30
  /** Index mapping a contract's address (as a string) to its location in a block */ #contractIndex;
28
31
  /** Index mapping block hash to block number */ #blockHashIndex;
@@ -39,72 +42,78 @@ export { TxReceipt } from '@aztec/stdlib/tx';
39
42
  this.#blockArchiveIndex = db.openMap('archiver_block_archive_index');
40
43
  this.#lastSynchedL1Block = db.openSingleton('archiver_last_synched_l1_block');
41
44
  this.#lastProvenCheckpoint = db.openSingleton('archiver_last_proven_l2_checkpoint');
45
+ this.#lastFinalizedCheckpoint = db.openSingleton('archiver_last_finalized_l2_checkpoint');
42
46
  this.#pendingChainValidationStatus = db.openSingleton('archiver_pending_chain_validation_status');
43
47
  this.#checkpoints = db.openMap('archiver_checkpoints');
48
+ this.#slotToCheckpoint = db.openMap('archiver_slot_to_checkpoint');
44
49
  }
45
50
  /**
46
- * Append new blocks to the store's list. All blocks must be for the 'current' checkpoint
47
- * @param blocks - The L2 blocks to be added to the store.
48
- * @returns True if the operation is successful.
49
- */ async addBlocks(blocks, opts = {}) {
50
- if (blocks.length === 0) {
51
- return true;
51
+ * Returns the finalized L2 block number. An L2 block is finalized when it was proven
52
+ * in an L1 block that has itself been finalized on Ethereum.
53
+ * @returns The finalized block number.
54
+ */ async getFinalizedL2BlockNumber() {
55
+ const finalizedCheckpointNumber = await this.getFinalizedCheckpointNumber();
56
+ if (finalizedCheckpointNumber === INITIAL_CHECKPOINT_NUMBER - 1) {
57
+ return BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
52
58
  }
59
+ const checkpointStorage = await this.#checkpoints.getAsync(finalizedCheckpointNumber);
60
+ if (!checkpointStorage) {
61
+ throw new CheckpointNotFoundError(finalizedCheckpointNumber);
62
+ }
63
+ return BlockNumber(checkpointStorage.startBlock + checkpointStorage.blockCount - 1);
64
+ }
65
+ /**
66
+ * Append a new proposed block to the store.
67
+ * This is an uncheckpointed block that has been proposed by the sequencer but not yet included in a checkpoint on L1.
68
+ * For checkpointed blocks (already published to L1), use addCheckpoints() instead.
69
+ * @param block - The proposed L2 block to be added to the store.
70
+ * @returns True if the operation is successful.
71
+ */ async addProposedBlock(block, opts = {}) {
53
72
  return await this.db.transactionAsync(async ()=>{
54
- // Check that the block immediately before the first block to be added is present in the store.
55
- const firstBlockNumber = blocks[0].number;
56
- const firstBlockCheckpointNumber = blocks[0].checkpointNumber;
57
- const firstBlockIndex = blocks[0].indexWithinCheckpoint;
58
- const firstBlockLastArchive = blocks[0].header.lastArchive.root;
73
+ const blockNumber = block.number;
74
+ const blockCheckpointNumber = block.checkpointNumber;
75
+ const blockIndex = block.indexWithinCheckpoint;
76
+ const blockLastArchive = block.header.lastArchive.root;
59
77
  // Extract the latest block and checkpoint numbers
60
78
  const previousBlockNumber = await this.getLatestBlockNumber();
61
79
  const previousCheckpointNumber = await this.getLatestCheckpointNumber();
62
- // Check that the first block number is the expected one
63
- if (!opts.force && previousBlockNumber !== firstBlockNumber - 1) {
64
- throw new InitialBlockNumberNotSequentialError(firstBlockNumber, previousBlockNumber);
80
+ // Verify we're not overwriting checkpointed blocks
81
+ const lastCheckpointedBlockNumber = await this.getCheckpointedL2BlockNumber();
82
+ if (!opts.force && blockNumber <= lastCheckpointedBlockNumber) {
83
+ // Check if the proposed block matches the already-checkpointed one
84
+ const existingBlock = await this.getBlock(BlockNumber(blockNumber));
85
+ if (existingBlock && existingBlock.archive.root.equals(block.archive.root)) {
86
+ throw new BlockAlreadyCheckpointedError(blockNumber);
87
+ }
88
+ throw new CannotOverwriteCheckpointedBlockError(blockNumber, lastCheckpointedBlockNumber);
89
+ }
90
+ // Check that the block number is the expected one
91
+ if (!opts.force && previousBlockNumber !== blockNumber - 1) {
92
+ throw new BlockNumberNotSequentialError(blockNumber, previousBlockNumber);
65
93
  }
66
94
  // The same check as above but for checkpoints
67
- if (!opts.force && previousCheckpointNumber !== firstBlockCheckpointNumber - 1) {
68
- throw new InitialCheckpointNumberNotSequentialError(firstBlockCheckpointNumber, previousCheckpointNumber);
95
+ if (!opts.force && previousCheckpointNumber !== blockCheckpointNumber - 1) {
96
+ throw new CheckpointNumberNotSequentialError(blockCheckpointNumber, previousCheckpointNumber);
69
97
  }
70
98
  // Extract the previous block if there is one and see if it is for the same checkpoint or not
71
99
  const previousBlockResult = await this.getBlock(previousBlockNumber);
72
- let expectedFirstblockIndex = 0;
100
+ let expectedBlockIndex = 0;
73
101
  let previousBlockIndex = undefined;
74
102
  if (previousBlockResult !== undefined) {
75
- if (previousBlockResult.checkpointNumber === firstBlockCheckpointNumber) {
103
+ if (previousBlockResult.checkpointNumber === blockCheckpointNumber) {
76
104
  // The previous block is for the same checkpoint, therefore our index should follow it
77
105
  previousBlockIndex = previousBlockResult.indexWithinCheckpoint;
78
- expectedFirstblockIndex = previousBlockIndex + 1;
106
+ expectedBlockIndex = previousBlockIndex + 1;
79
107
  }
80
- if (!previousBlockResult.archive.root.equals(firstBlockLastArchive)) {
81
- throw new BlockArchiveNotConsistentError(firstBlockNumber, previousBlockResult.number, firstBlockLastArchive, previousBlockResult.archive.root);
108
+ if (!previousBlockResult.archive.root.equals(blockLastArchive)) {
109
+ throw new BlockArchiveNotConsistentError(blockNumber, previousBlockResult.number, blockLastArchive, previousBlockResult.archive.root);
82
110
  }
83
111
  }
84
- // Now check that the first block has the expected index value
85
- if (!opts.force && expectedFirstblockIndex !== firstBlockIndex) {
86
- throw new BlockIndexNotSequentialError(firstBlockIndex, previousBlockIndex);
87
- }
88
- // Iterate over blocks array and insert them, checking that the block numbers and indexes are sequential. Also check they are for the correct checkpoint.
89
- let previousBlock = undefined;
90
- for (const block of blocks){
91
- if (!opts.force && previousBlock) {
92
- if (previousBlock.number + 1 !== block.number) {
93
- throw new BlockNumberNotSequentialError(block.number, previousBlock.number);
94
- }
95
- if (previousBlock.indexWithinCheckpoint + 1 !== block.indexWithinCheckpoint) {
96
- throw new BlockIndexNotSequentialError(block.indexWithinCheckpoint, previousBlock.indexWithinCheckpoint);
97
- }
98
- if (!previousBlock.archive.root.equals(block.header.lastArchive.root)) {
99
- throw new BlockArchiveNotConsistentError(block.number, previousBlock.number, block.header.lastArchive.root, previousBlock.archive.root);
100
- }
101
- }
102
- if (!opts.force && firstBlockCheckpointNumber !== block.checkpointNumber) {
103
- throw new CheckpointNumberNotConsistentError(block.checkpointNumber, firstBlockCheckpointNumber);
104
- }
105
- previousBlock = block;
106
- await this.addBlockToDatabase(block, block.checkpointNumber, block.indexWithinCheckpoint);
112
+ // Now check that the block has the expected index value
113
+ if (!opts.force && expectedBlockIndex !== blockIndex) {
114
+ throw new BlockIndexNotSequentialError(blockIndex, previousBlockIndex);
107
115
  }
116
+ await this.addBlockToDatabase(block, block.checkpointNumber, block.indexWithinCheckpoint);
108
117
  return true;
109
118
  });
110
119
  }
@@ -136,7 +145,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
136
145
  let previousBlock = undefined;
137
146
  // If we have a previous checkpoint then we need to get the previous block number
138
147
  if (previousCheckpointData !== undefined) {
139
- previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.numBlocks - 1);
148
+ previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.blockCount - 1);
140
149
  previousBlock = await this.getBlock(previousBlockNumber);
141
150
  if (previousBlock === undefined) {
142
151
  // We should be able to get the required previous block
@@ -181,19 +190,22 @@ export { TxReceipt } from '@aztec/stdlib/tx';
181
190
  await this.#checkpoints.set(checkpoint.checkpoint.number, {
182
191
  header: checkpoint.checkpoint.header.toBuffer(),
183
192
  archive: checkpoint.checkpoint.archive.toBuffer(),
193
+ checkpointOutHash: checkpoint.checkpoint.getCheckpointOutHash().toBuffer(),
184
194
  l1: checkpoint.l1.toBuffer(),
185
195
  attestations: checkpoint.attestations.map((attestation)=>attestation.toBuffer()),
186
196
  checkpointNumber: checkpoint.checkpoint.number,
187
197
  startBlock: checkpoint.checkpoint.blocks[0].number,
188
- numBlocks: checkpoint.checkpoint.blocks.length
198
+ blockCount: checkpoint.checkpoint.blocks.length
189
199
  });
200
+ // Update slot-to-checkpoint index
201
+ await this.#slotToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, checkpoint.checkpoint.number);
190
202
  }
191
203
  await this.#lastSynchedL1Block.set(checkpoints[checkpoints.length - 1].l1.blockNumber);
192
204
  return true;
193
205
  });
194
206
  }
195
207
  async addBlockToDatabase(block, checkpointNumber, indexWithinCheckpoint) {
196
- const blockHash = L2BlockHash.fromField(await block.hash());
208
+ const blockHash = await block.hash();
197
209
  await this.#blocks.set(block.number, {
198
210
  header: block.header.toBuffer(),
199
211
  blockHash: blockHash.toBuffer(),
@@ -228,41 +240,50 @@ export { TxReceipt } from '@aztec/stdlib/tx';
228
240
  await this.#blockArchiveIndex.delete(block.archive.root.toString());
229
241
  }
230
242
  /**
231
- * Unwinds checkpoints from the database
232
- * @param from - The tip of the chain, passed for verification purposes,
233
- * ensuring that we don't end up deleting something we did not intend
234
- * @param checkpointsToUnwind - The number of checkpoints we are to unwind
235
- * @returns True if the operation is successful
236
- */ async unwindCheckpoints(from, checkpointsToUnwind) {
243
+ * Removes all checkpoints with checkpoint number > checkpointNumber.
244
+ * Also removes ALL blocks (both checkpointed and uncheckpointed) after the last block of the given checkpoint.
245
+ * @param checkpointNumber - Remove all checkpoints strictly after this one.
246
+ */ async removeCheckpointsAfter(checkpointNumber) {
237
247
  return await this.db.transactionAsync(async ()=>{
238
- const last = await this.getLatestCheckpointNumber();
239
- if (from !== last) {
240
- throw new Error(`Can only unwind checkpoints from the tip (requested ${from} but current tip is ${last})`);
248
+ const latestCheckpointNumber = await this.getLatestCheckpointNumber();
249
+ if (checkpointNumber >= latestCheckpointNumber) {
250
+ this.#log.warn(`No checkpoints to remove after ${checkpointNumber} (latest is ${latestCheckpointNumber})`);
251
+ return {
252
+ blocksRemoved: undefined
253
+ };
241
254
  }
255
+ // If the proven checkpoint is beyond the target, update it
242
256
  const proven = await this.getProvenCheckpointNumber();
243
- if (from - checkpointsToUnwind < proven) {
244
- await this.setProvenCheckpointNumber(CheckpointNumber(from - checkpointsToUnwind));
257
+ if (proven > checkpointNumber) {
258
+ this.#log.warn(`Updating proven checkpoint ${proven} to last valid checkpoint ${checkpointNumber}`);
259
+ await this.setProvenCheckpointNumber(checkpointNumber);
245
260
  }
246
- for(let i = 0; i < checkpointsToUnwind; i++){
247
- const checkpointNumber = from - i;
248
- const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
249
- if (checkpoint === undefined) {
250
- this.#log.warn(`Cannot remove checkpoint ${checkpointNumber} from the store since we don't have it`);
251
- continue;
261
+ // Find the last block number to keep (last block of the given checkpoint, or 0 if no checkpoint)
262
+ let lastBlockToKeep;
263
+ if (checkpointNumber <= 0) {
264
+ lastBlockToKeep = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
265
+ } else {
266
+ const targetCheckpoint = await this.#checkpoints.getAsync(checkpointNumber);
267
+ if (!targetCheckpoint) {
268
+ throw new Error(`Target checkpoint ${checkpointNumber} not found in store`);
252
269
  }
253
- await this.#checkpoints.delete(checkpointNumber);
254
- const maxBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
255
- for(let blockNumber = checkpoint.startBlock; blockNumber <= maxBlock; blockNumber++){
256
- const block = await this.getBlock(BlockNumber(blockNumber));
257
- if (block === undefined) {
258
- this.#log.warn(`Cannot remove block ${blockNumber} from the store since we don't have it`);
259
- continue;
260
- }
261
- await this.deleteBlock(block);
262
- this.#log.debug(`Unwound block ${blockNumber} ${(await block.hash()).toString()} for checkpoint ${checkpointNumber}`);
270
+ lastBlockToKeep = BlockNumber(targetCheckpoint.startBlock + targetCheckpoint.blockCount - 1);
271
+ }
272
+ // Remove all blocks after lastBlockToKeep (both checkpointed and uncheckpointed)
273
+ const blocksRemoved = await this.removeBlocksAfter(lastBlockToKeep);
274
+ // Remove all checkpoints after the target
275
+ for(let c = latestCheckpointNumber; c > checkpointNumber; c = CheckpointNumber(c - 1)){
276
+ const checkpointStorage = await this.#checkpoints.getAsync(c);
277
+ if (checkpointStorage) {
278
+ const slotNumber = CheckpointHeader.fromBuffer(checkpointStorage.header).slotNumber;
279
+ await this.#slotToCheckpoint.delete(slotNumber);
263
280
  }
281
+ await this.#checkpoints.delete(c);
282
+ this.#log.debug(`Removed checkpoint ${c}`);
264
283
  }
265
- return true;
284
+ return {
285
+ blocksRemoved
286
+ };
266
287
  });
267
288
  }
268
289
  async getCheckpointData(checkpointNumber) {
@@ -283,17 +304,30 @@ export { TxReceipt } from '@aztec/stdlib/tx';
283
304
  }
284
305
  return checkpoints;
285
306
  }
307
+ /** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */ async getCheckpointDataForSlotRange(startSlot, endSlot) {
308
+ const result = [];
309
+ for await (const [, checkpointNumber] of this.#slotToCheckpoint.entriesAsync({
310
+ start: startSlot,
311
+ end: endSlot + 1
312
+ })){
313
+ const checkpointStorage = await this.#checkpoints.getAsync(checkpointNumber);
314
+ if (checkpointStorage) {
315
+ result.push(this.checkpointDataFromCheckpointStorage(checkpointStorage));
316
+ }
317
+ }
318
+ return result;
319
+ }
286
320
  checkpointDataFromCheckpointStorage(checkpointStorage) {
287
- const data = {
321
+ return {
288
322
  header: CheckpointHeader.fromBuffer(checkpointStorage.header),
289
323
  archive: AppendOnlyTreeSnapshot.fromBuffer(checkpointStorage.archive),
324
+ checkpointOutHash: Fr.fromBuffer(checkpointStorage.checkpointOutHash),
290
325
  checkpointNumber: CheckpointNumber(checkpointStorage.checkpointNumber),
291
- startBlock: checkpointStorage.startBlock,
292
- numBlocks: checkpointStorage.numBlocks,
326
+ startBlock: BlockNumber(checkpointStorage.startBlock),
327
+ blockCount: checkpointStorage.blockCount,
293
328
  l1: L1PublishedData.fromBuffer(checkpointStorage.l1),
294
- attestations: checkpointStorage.attestations
329
+ attestations: checkpointStorage.attestations.map((buf)=>CommitteeAttestation.fromBuffer(buf))
295
330
  };
296
- return data;
297
331
  }
298
332
  async getBlocksForCheckpoint(checkpointNumber) {
299
333
  const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
@@ -302,7 +336,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
302
336
  }
303
337
  const blocksForCheckpoint = await toArray(this.#blocks.entriesAsync({
304
338
  start: checkpoint.startBlock,
305
- end: checkpoint.startBlock + checkpoint.numBlocks
339
+ end: checkpoint.startBlock + checkpoint.blockCount
306
340
  }));
307
341
  const converted = await Promise.all(blocksForCheckpoint.map((x)=>this.getBlockFromBlockStorage(x[0], x[1])));
308
342
  return converted.filter(isDefined);
@@ -332,9 +366,10 @@ export { TxReceipt } from '@aztec/stdlib/tx';
332
366
  }
333
367
  /**
334
368
  * Removes all blocks with block number > blockNumber.
369
+ * Does not remove any associated checkpoints.
335
370
  * @param blockNumber - The block number to remove after.
336
371
  * @returns The removed blocks (for event emission).
337
- */ async unwindBlocksAfter(blockNumber) {
372
+ */ async removeBlocksAfter(blockNumber) {
338
373
  return await this.db.transactionAsync(async ()=>{
339
374
  const removedBlocks = [];
340
375
  // Get the latest block number to determine the range
@@ -362,7 +397,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
362
397
  if (!checkpointStorage) {
363
398
  throw new CheckpointNotFoundError(provenCheckpointNumber);
364
399
  } else {
365
- return BlockNumber(checkpointStorage.startBlock + checkpointStorage.numBlocks - 1);
400
+ return BlockNumber(checkpointStorage.startBlock + checkpointStorage.blockCount - 1);
366
401
  }
367
402
  }
368
403
  async getLatestBlockNumber() {
@@ -444,6 +479,28 @@ export { TxReceipt } from '@aztec/stdlib/tx';
444
479
  }
445
480
  }
446
481
  /**
482
+ * Gets block metadata (without tx data) by block number.
483
+ * @param blockNumber - The number of the block to return.
484
+ * @returns The requested block data.
485
+ */ async getBlockData(blockNumber) {
486
+ const blockStorage = await this.#blocks.getAsync(blockNumber);
487
+ if (!blockStorage || !blockStorage.header) {
488
+ return undefined;
489
+ }
490
+ return this.getBlockDataFromBlockStorage(blockStorage);
491
+ }
492
+ /**
493
+ * Gets block metadata (without tx data) by archive root.
494
+ * @param archive - The archive root of the block to return.
495
+ * @returns The requested block data.
496
+ */ async getBlockDataByArchive(archive) {
497
+ const blockNumber = await this.#blockArchiveIndex.getAsync(archive.toString());
498
+ if (blockNumber === undefined) {
499
+ return undefined;
500
+ }
501
+ return this.getBlockData(BlockNumber(blockNumber));
502
+ }
503
+ /**
447
504
  * Gets an L2 block.
448
505
  * @param blockNumber - The number of the block to return.
449
506
  * @returns The requested L2 block.
@@ -533,12 +590,19 @@ export { TxReceipt } from '@aztec/stdlib/tx';
533
590
  ];
534
591
  }
535
592
  }
593
+ getBlockDataFromBlockStorage(blockStorage) {
594
+ return {
595
+ header: BlockHeader.fromBuffer(blockStorage.header),
596
+ archive: AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive),
597
+ blockHash: Fr.fromBuffer(blockStorage.blockHash),
598
+ checkpointNumber: CheckpointNumber(blockStorage.checkpointNumber),
599
+ indexWithinCheckpoint: IndexWithinCheckpoint(blockStorage.indexWithinCheckpoint)
600
+ };
601
+ }
536
602
  async getBlockFromBlockStorage(blockNumber, blockStorage) {
537
- const header = BlockHeader.fromBuffer(blockStorage.header);
538
- const archive = AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive);
539
- const blockHash = blockStorage.blockHash;
540
- header.setHash(Fr.fromBuffer(blockHash));
541
- const blockHashString = bufferToHex(blockHash);
603
+ const { header, archive, blockHash, checkpointNumber, indexWithinCheckpoint } = this.getBlockDataFromBlockStorage(blockStorage);
604
+ header.setHash(blockHash);
605
+ const blockHashString = bufferToHex(blockStorage.blockHash);
542
606
  const blockTxsBuffer = await this.#blockTxs.getAsync(blockHashString);
543
607
  if (blockTxsBuffer === undefined) {
544
608
  this.#log.warn(`Could not find body for block ${header.globalVariables.blockNumber} ${blockHash}`);
@@ -556,7 +620,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
556
620
  txEffects.push(deserializeIndexedTxEffect(txEffect).data);
557
621
  }
558
622
  const body = new Body(txEffects);
559
- const block = new L2BlockNew(archive, header, body, CheckpointNumber(blockStorage.checkpointNumber), IndexWithinCheckpoint(blockStorage.indexWithinCheckpoint));
623
+ const block = new L2Block(archive, header, body, checkpointNumber, indexWithinCheckpoint);
560
624
  if (block.number !== blockNumber) {
561
625
  throw new Error(`Block number mismatch when retrieving block from archive (expected ${blockNumber} but got ${block.number} with hash ${blockHashString})`);
562
626
  }
@@ -577,12 +641,31 @@ export { TxReceipt } from '@aztec/stdlib/tx';
577
641
  * Gets a receipt of a settled tx.
578
642
  * @param txHash - The hash of a tx we try to get the receipt for.
579
643
  * @returns The requested tx receipt (or undefined if not found).
580
- */ async getSettledTxReceipt(txHash) {
644
+ */ async getSettledTxReceipt(txHash, l1Constants) {
581
645
  const txEffect = await this.getTxEffect(txHash);
582
646
  if (!txEffect) {
583
647
  return undefined;
584
648
  }
585
- return new TxReceipt(txHash, TxReceipt.statusFromRevertCode(txEffect.data.revertCode), '', txEffect.data.transactionFee.toBigInt(), txEffect.l2BlockHash, BlockNumber(txEffect.l2BlockNumber));
649
+ const blockNumber = BlockNumber(txEffect.l2BlockNumber);
650
+ // Use existing archiver methods to determine finalization level
651
+ const [provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber, blockData] = await Promise.all([
652
+ this.getProvenBlockNumber(),
653
+ this.getCheckpointedL2BlockNumber(),
654
+ this.getFinalizedL2BlockNumber(),
655
+ this.getBlockData(blockNumber)
656
+ ]);
657
+ let status;
658
+ if (blockNumber <= finalizedBlockNumber) {
659
+ status = TxStatus.FINALIZED;
660
+ } else if (blockNumber <= provenBlockNumber) {
661
+ status = TxStatus.PROVEN;
662
+ } else if (blockNumber <= checkpointedBlockNumber) {
663
+ status = TxStatus.CHECKPOINTED;
664
+ } else {
665
+ status = TxStatus.PROPOSED;
666
+ }
667
+ const epochNumber = blockData && l1Constants ? getEpochAtSlot(blockData.header.globalVariables.slotNumber, l1Constants) : undefined;
668
+ return new TxReceipt(txHash, status, TxReceipt.executionResultFromRevertCode(txEffect.data.revertCode), undefined, txEffect.data.transactionFee.toBigInt(), txEffect.l2BlockHash, blockNumber, epochNumber);
586
669
  }
587
670
  /**
588
671
  * Looks up which block included the requested tx effect.
@@ -615,7 +698,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
615
698
  if (!checkpoint) {
616
699
  return BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
617
700
  }
618
- return BlockNumber(checkpoint.startBlock + checkpoint.numBlocks - 1);
701
+ return BlockNumber(checkpoint.startBlock + checkpoint.blockCount - 1);
619
702
  }
620
703
  async getLatestL2BlockNumber() {
621
704
  const [lastBlockNumber] = await toArray(this.#blocks.keysAsync({
@@ -644,6 +727,16 @@ export { TxReceipt } from '@aztec/stdlib/tx';
644
727
  const result = await this.#lastProvenCheckpoint.set(checkpointNumber);
645
728
  return result;
646
729
  }
730
+ async getFinalizedCheckpointNumber() {
731
+ const [latestCheckpointNumber, finalizedCheckpointNumber] = await Promise.all([
732
+ this.getLatestCheckpointNumber(),
733
+ this.#lastFinalizedCheckpoint.getAsync()
734
+ ]);
735
+ return (finalizedCheckpointNumber ?? 0) > latestCheckpointNumber ? latestCheckpointNumber : CheckpointNumber(finalizedCheckpointNumber ?? 0);
736
+ }
737
+ setFinalizedCheckpointNumber(checkpointNumber) {
738
+ return this.#lastFinalizedCheckpoint.set(checkpointNumber);
739
+ }
647
740
  #computeBlockRange(start, limit) {
648
741
  if (limit < 1) {
649
742
  throw new Error(`Invalid limit: ${limit}`);
@@ -1,6 +1,6 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
- import type { ContractClassPublic, ExecutablePrivateFunctionWithMembershipProof, UtilityFunctionWithMembershipProof } from '@aztec/stdlib/contract';
3
+ import type { ContractClassPublic } from '@aztec/stdlib/contract';
4
4
  /**
5
5
  * LMDB-based contract class storage for the archiver.
6
6
  */
@@ -13,6 +13,5 @@ export declare class ContractClassStore {
13
13
  getContractClass(id: Fr): Promise<ContractClassPublic | undefined>;
14
14
  getBytecodeCommitment(id: Fr): Promise<Fr | undefined>;
15
15
  getContractClassIds(): Promise<Fr[]>;
16
- addFunctions(contractClassId: Fr, newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[], newUtilityFunctions: UtilityFunctionWithMembershipProof[]): Promise<boolean>;
17
16
  }
18
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfY2xhc3Nfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9jb250cmFjdF9jbGFzc19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQWlCLE1BQU0saUJBQWlCLENBQUM7QUFFeEUsT0FBTyxLQUFLLEVBQ1YsbUJBQW1CLEVBRW5CLDRDQUE0QyxFQUM1QyxrQ0FBa0MsRUFDbkMsTUFBTSx3QkFBd0IsQ0FBQztBQUdoQzs7R0FFRztBQUNILHFCQUFhLGtCQUFrQjs7SUFJakIsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUd4QztJQUVLLGdCQUFnQixDQUNwQixhQUFhLEVBQUUsbUJBQW1CLEVBQ2xDLGtCQUFrQixFQUFFLEVBQUUsRUFDdEIsV0FBVyxFQUFFLE1BQU0sR0FDbEIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU1mO0lBRUsscUJBQXFCLENBQUMsYUFBYSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU1sRztJQUVLLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxDQUd2RTtJQUVLLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FHM0Q7SUFFSyxtQkFBbUIsSUFBSSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FFekM7SUFFSyxZQUFZLENBQ2hCLGVBQWUsRUFBRSxFQUFFLEVBQ25CLG1CQUFtQixFQUFFLDRDQUE0QyxFQUFFLEVBQ25FLG1CQUFtQixFQUFFLGtDQUFrQyxFQUFFLEdBQ3hELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0F5QmxCO0NBQ0YifQ==
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfY2xhc3Nfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9jb250cmFjdF9jbGFzc19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQWlCLE1BQU0saUJBQWlCLENBQUM7QUFDeEUsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQXNDLE1BQU0sd0JBQXdCLENBQUM7QUFFdEc7O0dBRUc7QUFDSCxxQkFBYSxrQkFBa0I7O0lBSWpCLE9BQU8sQ0FBQyxFQUFFO0lBQXRCLFlBQW9CLEVBQUUsRUFBRSxpQkFBaUIsRUFHeEM7SUFFSyxnQkFBZ0IsQ0FDcEIsYUFBYSxFQUFFLG1CQUFtQixFQUNsQyxrQkFBa0IsRUFBRSxFQUFFLEVBQ3RCLFdBQVcsRUFBRSxNQUFNLEdBQ2xCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FZZjtJQUVLLHFCQUFxQixDQUFDLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FRbEc7SUFFSyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsR0FBRyxTQUFTLENBQUMsQ0FHdkU7SUFFSyxxQkFBcUIsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDLENBRzNEO0lBRUssbUJBQW1CLElBQUksT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBRXpDO0NBQ0YifQ==
@@ -1 +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,CAMf;IAEK,qBAAqB,CAAC,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMlG;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"}
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;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAsC,MAAM,wBAAwB,CAAC;AAEtG;;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,CAYf;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;CACF"}
@@ -1,8 +1,6 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { toArray } from '@aztec/foundation/iterable';
3
3
  import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/serialize';
4
- import { FunctionSelector } from '@aztec/stdlib/abi';
5
- import { Vector } from '@aztec/stdlib/types';
6
4
  /**
7
5
  * LMDB-based contract class storage for the archiver.
8
6
  */ export class ContractClassStore {
@@ -15,17 +13,25 @@ import { Vector } from '@aztec/stdlib/types';
15
13
  this.#bytecodeCommitments = db.openMap('archiver_bytecode_commitments');
16
14
  }
17
15
  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());
16
+ await this.db.transactionAsync(async ()=>{
17
+ const key = contractClass.id.toString();
18
+ if (await this.#contractClasses.hasAsync(key)) {
19
+ throw new Error(`Contract class ${key} already exists, cannot add again at block ${blockNumber}`);
20
+ }
21
+ await this.#contractClasses.set(key, serializeContractClassPublic({
22
+ ...contractClass,
23
+ l2BlockNumber: blockNumber
24
+ }));
25
+ await this.#bytecodeCommitments.set(key, bytecodeCommitment.toBuffer());
26
+ });
23
27
  }
24
28
  async deleteContractClasses(contractClass, blockNumber) {
25
29
  const restoredContractClass = await this.#contractClasses.getAsync(contractClass.id.toString());
26
30
  if (restoredContractClass && deserializeContractClassPublic(restoredContractClass).l2BlockNumber >= blockNumber) {
27
- await this.#contractClasses.delete(contractClass.id.toString());
28
- await this.#bytecodeCommitments.delete(contractClass.id.toString());
31
+ await this.db.transactionAsync(async ()=>{
32
+ await this.#contractClasses.delete(contractClass.id.toString());
33
+ await this.#bytecodeCommitments.delete(contractClass.id.toString());
34
+ });
29
35
  }
30
36
  }
31
37
  async getContractClass(id) {
@@ -42,38 +48,9 @@ import { Vector } from '@aztec/stdlib/types';
42
48
  async getContractClassIds() {
43
49
  return (await toArray(this.#contractClasses.keysAsync())).map((key)=>Fr.fromHexString(key));
44
50
  }
45
- async addFunctions(contractClassId, newPrivateFunctions, newUtilityFunctions) {
46
- await this.db.transactionAsync(async ()=>{
47
- const existingClassBuffer = await this.#contractClasses.getAsync(contractClassId.toString());
48
- if (!existingClassBuffer) {
49
- throw new Error(`Unknown contract class ${contractClassId} when adding private functions to store`);
50
- }
51
- const existingClass = deserializeContractClassPublic(existingClassBuffer);
52
- const { privateFunctions: existingPrivateFns, utilityFunctions: existingUtilityFns } = existingClass;
53
- const updatedClass = {
54
- ...existingClass,
55
- privateFunctions: [
56
- ...existingPrivateFns,
57
- ...newPrivateFunctions.filter((newFn)=>!existingPrivateFns.some((f)=>f.selector.equals(newFn.selector)))
58
- ],
59
- utilityFunctions: [
60
- ...existingUtilityFns,
61
- ...newUtilityFunctions.filter((newFn)=>!existingUtilityFns.some((f)=>f.selector.equals(newFn.selector)))
62
- ]
63
- };
64
- await this.#contractClasses.set(contractClassId.toString(), serializeContractClassPublic(updatedClass));
65
- });
66
- return true;
67
- }
68
51
  }
69
52
  function serializeContractClassPublic(contractClass) {
70
- return serializeToBuffer(contractClass.l2BlockNumber, numToUInt8(contractClass.version), contractClass.artifactHash, contractClass.privateFunctions.length, contractClass.privateFunctions.map(serializePrivateFunction), contractClass.utilityFunctions.length, contractClass.utilityFunctions.map(serializeUtilityFunction), contractClass.packedBytecode.length, contractClass.packedBytecode, contractClass.privateFunctionsRoot);
71
- }
72
- function serializePrivateFunction(fn) {
73
- return serializeToBuffer(fn.selector, fn.vkHash, fn.bytecode.length, fn.bytecode, fn.functionMetadataHash, fn.artifactMetadataHash, fn.utilityFunctionsTreeRoot, new Vector(fn.privateFunctionTreeSiblingPath), fn.privateFunctionTreeLeafIndex, new Vector(fn.artifactTreeSiblingPath), fn.artifactTreeLeafIndex);
74
- }
75
- function serializeUtilityFunction(fn) {
76
- return serializeToBuffer(fn.selector, fn.bytecode.length, fn.bytecode, fn.functionMetadataHash, fn.artifactMetadataHash, fn.privateFunctionsArtifactTreeRoot, new Vector(fn.artifactTreeSiblingPath), fn.artifactTreeLeafIndex);
53
+ return serializeToBuffer(contractClass.l2BlockNumber, numToUInt8(contractClass.version), contractClass.artifactHash, contractClass.packedBytecode.length, contractClass.packedBytecode, contractClass.privateFunctionsRoot);
77
54
  }
78
55
  function deserializeContractClassPublic(buffer) {
79
56
  const reader = BufferReader.asReader(buffer);
@@ -81,40 +58,7 @@ function deserializeContractClassPublic(buffer) {
81
58
  l2BlockNumber: reader.readNumber(),
82
59
  version: reader.readUInt8(),
83
60
  artifactHash: reader.readObject(Fr),
84
- privateFunctions: reader.readVector({
85
- fromBuffer: deserializePrivateFunction
86
- }),
87
- utilityFunctions: reader.readVector({
88
- fromBuffer: deserializeUtilityFunction
89
- }),
90
61
  packedBytecode: reader.readBuffer(),
91
62
  privateFunctionsRoot: reader.readObject(Fr)
92
63
  };
93
64
  }
94
- function deserializePrivateFunction(buffer) {
95
- const reader = BufferReader.asReader(buffer);
96
- return {
97
- selector: reader.readObject(FunctionSelector),
98
- vkHash: reader.readObject(Fr),
99
- bytecode: reader.readBuffer(),
100
- functionMetadataHash: reader.readObject(Fr),
101
- artifactMetadataHash: reader.readObject(Fr),
102
- utilityFunctionsTreeRoot: reader.readObject(Fr),
103
- privateFunctionTreeSiblingPath: reader.readVector(Fr),
104
- privateFunctionTreeLeafIndex: reader.readNumber(),
105
- artifactTreeSiblingPath: reader.readVector(Fr),
106
- artifactTreeLeafIndex: reader.readNumber()
107
- };
108
- }
109
- function deserializeUtilityFunction(buffer) {
110
- const reader = BufferReader.asReader(buffer);
111
- return {
112
- selector: reader.readObject(FunctionSelector),
113
- bytecode: reader.readBuffer(),
114
- functionMetadataHash: reader.readObject(Fr),
115
- artifactMetadataHash: reader.readObject(Fr),
116
- privateFunctionsArtifactTreeRoot: reader.readObject(Fr),
117
- artifactTreeSiblingPath: reader.readVector(Fr),
118
- artifactTreeLeafIndex: reader.readNumber()
119
- };
120
- }
@@ -21,4 +21,4 @@ export declare class ContractInstanceStore {
21
21
  getContractInstanceDeploymentBlockNumber(address: AztecAddress): Promise<number | undefined>;
22
22
  }
23
23
  export {};
24
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfaW5zdGFuY2Vfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9jb250cmFjdF9pbnN0YW5jZV9zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsS0FBSyxpQ0FBaUMsRUFDdEMsS0FBSywyQkFBMkIsRUFHakMsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVsRCxLQUFLLHlCQUF5QixHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUU3RTs7R0FFRztBQUNILHFCQUFhLHFCQUFxQjs7SUFLcEIsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUl4QztJQUVELG1CQUFtQixDQUFDLGdCQUFnQixFQUFFLDJCQUEyQixFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVFyRztJQUVELHNCQUFzQixDQUFDLGdCQUFnQixFQUFFLDJCQUEyQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FLbkY7SUFFRCxZQUFZLENBQUMsZUFBZSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFFLE1BQU0sR0FBRyx5QkFBeUIsQ0FNM0c7SUFFRCx5QkFBeUIsQ0FDdkIsc0JBQXNCLEVBQUUsaUNBQWlDLEVBQ3pELFNBQVMsRUFBRSxNQUFNLEVBQ2pCLFFBQVEsRUFBRSxNQUFNLEdBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUtmO0lBRUQsNEJBQTRCLENBQzFCLHNCQUFzQixFQUFFLGlDQUFpQyxFQUN6RCxTQUFTLEVBQUUsTUFBTSxFQUNqQixRQUFRLEVBQUUsTUFBTSxHQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFZjtJQUVLLGlDQUFpQyxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FvQmxIO0lBRUssbUJBQW1CLENBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQ3JCLFNBQVMsRUFBRSxNQUFNLEdBQ2hCLE9BQU8sQ0FBQywyQkFBMkIsR0FBRyxTQUFTLENBQUMsQ0FhbEQ7SUFFRCx3Q0FBd0MsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNGO0NBQ0YifQ==
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfaW5zdGFuY2Vfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9jb250cmFjdF9pbnN0YW5jZV9zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN6RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsS0FBSyxpQ0FBaUMsRUFDdEMsS0FBSywyQkFBMkIsRUFHakMsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVsRCxLQUFLLHlCQUF5QixHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUU3RTs7R0FFRztBQUNILHFCQUFhLHFCQUFxQjs7SUFLcEIsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUl4QztJQUVELG1CQUFtQixDQUFDLGdCQUFnQixFQUFFLDJCQUEyQixFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVdyRztJQUVELHNCQUFzQixDQUFDLGdCQUFnQixFQUFFLDJCQUEyQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FLbkY7SUFFRCxZQUFZLENBQUMsZUFBZSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFFLE1BQU0sR0FBRyx5QkFBeUIsQ0FNM0c7SUFFRCx5QkFBeUIsQ0FDdkIsc0JBQXNCLEVBQUUsaUNBQWlDLEVBQ3pELFNBQVMsRUFBRSxNQUFNLEVBQ2pCLFFBQVEsRUFBRSxNQUFNLEdBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUtmO0lBRUQsNEJBQTRCLENBQzFCLHNCQUFzQixFQUFFLGlDQUFpQyxFQUN6RCxTQUFTLEVBQUUsTUFBTSxFQUNqQixRQUFRLEVBQUUsTUFBTSxHQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFZjtJQUVLLGlDQUFpQyxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FvQmxIO0lBRUssbUJBQW1CLENBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQ3JCLFNBQVMsRUFBRSxNQUFNLEdBQ2hCLE9BQU8sQ0FBQywyQkFBMkIsR0FBRyxTQUFTLENBQUMsQ0FhbEQ7SUFFRCx3Q0FBd0MsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNGO0NBQ0YifQ==
@@ -1 +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
+ {"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,CAWrG;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"}