@aztec/archiver 0.0.1-commit.3469e52 → 0.0.1-commit.381b1a9
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.
- package/README.md +9 -0
- package/dest/archiver.d.ts +12 -8
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +81 -120
- package/dest/errors.d.ts +6 -1
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +8 -0
- package/dest/factory.d.ts +3 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +14 -11
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/l1/bin/retrieve-calldata.js +35 -32
- package/dest/l1/calldata_retriever.d.ts +73 -50
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +190 -259
- package/dest/l1/data_retrieval.d.ts +4 -7
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +12 -16
- package/dest/l1/spire_proposer.d.ts +5 -5
- package/dest/l1/spire_proposer.d.ts.map +1 -1
- package/dest/l1/spire_proposer.js +9 -17
- package/dest/l1/validate_trace.d.ts +6 -3
- package/dest/l1/validate_trace.d.ts.map +1 -1
- package/dest/l1/validate_trace.js +13 -9
- package/dest/modules/data_source_base.d.ts +25 -21
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +45 -120
- package/dest/modules/data_store_updater.d.ts +40 -21
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +114 -64
- package/dest/modules/instrumentation.d.ts +6 -4
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +26 -12
- package/dest/modules/l1_synchronizer.d.ts +5 -8
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +46 -20
- package/dest/store/block_store.d.ts +49 -32
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +165 -54
- package/dest/store/contract_class_store.d.ts +1 -1
- package/dest/store/contract_class_store.d.ts.map +1 -1
- package/dest/store/contract_class_store.js +11 -7
- package/dest/store/kv_archiver_store.d.ts +53 -25
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +50 -17
- package/dest/store/l2_tips_cache.d.ts +19 -0
- package/dest/store/l2_tips_cache.d.ts.map +1 -0
- package/dest/store/l2_tips_cache.js +89 -0
- package/dest/store/log_store.d.ts +4 -4
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +105 -47
- package/dest/store/message_store.js +1 -1
- package/dest/test/fake_l1_state.d.ts +16 -4
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +84 -20
- package/dest/test/index.js +3 -1
- package/dest/test/mock_archiver.d.ts +1 -1
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +3 -2
- package/dest/test/mock_l2_block_source.d.ts +39 -23
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +157 -112
- package/dest/test/mock_structs.d.ts +6 -2
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +24 -10
- package/dest/test/noop_l1_archiver.d.ts +26 -0
- package/dest/test/noop_l1_archiver.d.ts.map +1 -0
- package/dest/test/noop_l1_archiver.js +72 -0
- package/package.json +14 -13
- package/src/archiver.ts +106 -149
- package/src/errors.ts +12 -0
- package/src/factory.ts +29 -12
- package/src/index.ts +1 -0
- package/src/l1/README.md +25 -68
- package/src/l1/bin/retrieve-calldata.ts +45 -33
- package/src/l1/calldata_retriever.ts +249 -379
- package/src/l1/data_retrieval.ts +10 -20
- package/src/l1/spire_proposer.ts +7 -15
- package/src/l1/validate_trace.ts +24 -6
- package/src/modules/data_source_base.ts +76 -166
- package/src/modules/data_store_updater.ts +130 -66
- package/src/modules/instrumentation.ts +26 -14
- package/src/modules/l1_synchronizer.ts +55 -26
- package/src/store/block_store.ts +216 -92
- package/src/store/contract_class_store.ts +11 -7
- package/src/store/kv_archiver_store.ts +88 -30
- package/src/store/l2_tips_cache.ts +89 -0
- package/src/store/log_store.ts +171 -55
- package/src/store/message_store.ts +1 -1
- package/src/test/fake_l1_state.ts +112 -23
- package/src/test/index.ts +3 -0
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l2_block_source.ts +211 -129
- package/src/test/mock_structs.ts +45 -15
- 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,
|
|
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 { BlockArchiveNotConsistentError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CannotOverwriteCheckpointedBlockError, CheckpointNotFoundError, CheckpointNumberNotConsistentError, CheckpointNumberNotSequentialError, InitialBlockNumberNotSequentialError, 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,14 +42,33 @@ 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
|
-
*
|
|
47
|
-
*
|
|
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);
|
|
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 new proposed blocks to the store's list. All blocks must be for the 'current' checkpoint.
|
|
67
|
+
* These are uncheckpointed blocks that have 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 blocks - The proposed L2 blocks to be added to the store.
|
|
48
70
|
* @returns True if the operation is successful.
|
|
49
|
-
*/ async
|
|
71
|
+
*/ async addProposedBlocks(blocks, opts = {}) {
|
|
50
72
|
if (blocks.length === 0) {
|
|
51
73
|
return true;
|
|
52
74
|
}
|
|
@@ -59,6 +81,11 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
59
81
|
// Extract the latest block and checkpoint numbers
|
|
60
82
|
const previousBlockNumber = await this.getLatestBlockNumber();
|
|
61
83
|
const previousCheckpointNumber = await this.getLatestCheckpointNumber();
|
|
84
|
+
// Verify we're not overwriting checkpointed blocks
|
|
85
|
+
const lastCheckpointedBlockNumber = await this.getCheckpointedL2BlockNumber();
|
|
86
|
+
if (!opts.force && firstBlockNumber <= lastCheckpointedBlockNumber) {
|
|
87
|
+
throw new CannotOverwriteCheckpointedBlockError(firstBlockNumber, lastCheckpointedBlockNumber);
|
|
88
|
+
}
|
|
62
89
|
// Check that the first block number is the expected one
|
|
63
90
|
if (!opts.force && previousBlockNumber !== firstBlockNumber - 1) {
|
|
64
91
|
throw new InitialBlockNumberNotSequentialError(firstBlockNumber, previousBlockNumber);
|
|
@@ -136,7 +163,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
136
163
|
let previousBlock = undefined;
|
|
137
164
|
// If we have a previous checkpoint then we need to get the previous block number
|
|
138
165
|
if (previousCheckpointData !== undefined) {
|
|
139
|
-
previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.
|
|
166
|
+
previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.blockCount - 1);
|
|
140
167
|
previousBlock = await this.getBlock(previousBlockNumber);
|
|
141
168
|
if (previousBlock === undefined) {
|
|
142
169
|
// We should be able to get the required previous block
|
|
@@ -181,19 +208,22 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
181
208
|
await this.#checkpoints.set(checkpoint.checkpoint.number, {
|
|
182
209
|
header: checkpoint.checkpoint.header.toBuffer(),
|
|
183
210
|
archive: checkpoint.checkpoint.archive.toBuffer(),
|
|
211
|
+
checkpointOutHash: checkpoint.checkpoint.getCheckpointOutHash().toBuffer(),
|
|
184
212
|
l1: checkpoint.l1.toBuffer(),
|
|
185
213
|
attestations: checkpoint.attestations.map((attestation)=>attestation.toBuffer()),
|
|
186
214
|
checkpointNumber: checkpoint.checkpoint.number,
|
|
187
215
|
startBlock: checkpoint.checkpoint.blocks[0].number,
|
|
188
|
-
|
|
216
|
+
blockCount: checkpoint.checkpoint.blocks.length
|
|
189
217
|
});
|
|
218
|
+
// Update slot-to-checkpoint index
|
|
219
|
+
await this.#slotToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, checkpoint.checkpoint.number);
|
|
190
220
|
}
|
|
191
221
|
await this.#lastSynchedL1Block.set(checkpoints[checkpoints.length - 1].l1.blockNumber);
|
|
192
222
|
return true;
|
|
193
223
|
});
|
|
194
224
|
}
|
|
195
225
|
async addBlockToDatabase(block, checkpointNumber, indexWithinCheckpoint) {
|
|
196
|
-
const blockHash =
|
|
226
|
+
const blockHash = await block.hash();
|
|
197
227
|
await this.#blocks.set(block.number, {
|
|
198
228
|
header: block.header.toBuffer(),
|
|
199
229
|
blockHash: blockHash.toBuffer(),
|
|
@@ -228,41 +258,50 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
228
258
|
await this.#blockArchiveIndex.delete(block.archive.root.toString());
|
|
229
259
|
}
|
|
230
260
|
/**
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
|
|
235
|
-
* @returns True if the operation is successful
|
|
236
|
-
*/ async unwindCheckpoints(from, checkpointsToUnwind) {
|
|
261
|
+
* Removes all checkpoints with checkpoint number > checkpointNumber.
|
|
262
|
+
* Also removes ALL blocks (both checkpointed and uncheckpointed) after the last block of the given checkpoint.
|
|
263
|
+
* @param checkpointNumber - Remove all checkpoints strictly after this one.
|
|
264
|
+
*/ async removeCheckpointsAfter(checkpointNumber) {
|
|
237
265
|
return await this.db.transactionAsync(async ()=>{
|
|
238
|
-
const
|
|
239
|
-
if (
|
|
240
|
-
|
|
266
|
+
const latestCheckpointNumber = await this.getLatestCheckpointNumber();
|
|
267
|
+
if (checkpointNumber >= latestCheckpointNumber) {
|
|
268
|
+
this.#log.warn(`No checkpoints to remove after ${checkpointNumber} (latest is ${latestCheckpointNumber})`);
|
|
269
|
+
return {
|
|
270
|
+
blocksRemoved: undefined
|
|
271
|
+
};
|
|
241
272
|
}
|
|
273
|
+
// If the proven checkpoint is beyond the target, update it
|
|
242
274
|
const proven = await this.getProvenCheckpointNumber();
|
|
243
|
-
if (
|
|
244
|
-
|
|
275
|
+
if (proven > checkpointNumber) {
|
|
276
|
+
this.#log.warn(`Updating proven checkpoint ${proven} to last valid checkpoint ${checkpointNumber}`);
|
|
277
|
+
await this.setProvenCheckpointNumber(checkpointNumber);
|
|
245
278
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
279
|
+
// Find the last block number to keep (last block of the given checkpoint, or 0 if no checkpoint)
|
|
280
|
+
let lastBlockToKeep;
|
|
281
|
+
if (checkpointNumber <= 0) {
|
|
282
|
+
lastBlockToKeep = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
283
|
+
} else {
|
|
284
|
+
const targetCheckpoint = await this.#checkpoints.getAsync(checkpointNumber);
|
|
285
|
+
if (!targetCheckpoint) {
|
|
286
|
+
throw new Error(`Target checkpoint ${checkpointNumber} not found in store`);
|
|
252
287
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
this.#
|
|
288
|
+
lastBlockToKeep = BlockNumber(targetCheckpoint.startBlock + targetCheckpoint.blockCount - 1);
|
|
289
|
+
}
|
|
290
|
+
// Remove all blocks after lastBlockToKeep (both checkpointed and uncheckpointed)
|
|
291
|
+
const blocksRemoved = await this.removeBlocksAfter(lastBlockToKeep);
|
|
292
|
+
// Remove all checkpoints after the target
|
|
293
|
+
for(let c = latestCheckpointNumber; c > checkpointNumber; c = CheckpointNumber(c - 1)){
|
|
294
|
+
const checkpointStorage = await this.#checkpoints.getAsync(c);
|
|
295
|
+
if (checkpointStorage) {
|
|
296
|
+
const slotNumber = CheckpointHeader.fromBuffer(checkpointStorage.header).slotNumber;
|
|
297
|
+
await this.#slotToCheckpoint.delete(slotNumber);
|
|
263
298
|
}
|
|
299
|
+
await this.#checkpoints.delete(c);
|
|
300
|
+
this.#log.debug(`Removed checkpoint ${c}`);
|
|
264
301
|
}
|
|
265
|
-
return
|
|
302
|
+
return {
|
|
303
|
+
blocksRemoved
|
|
304
|
+
};
|
|
266
305
|
});
|
|
267
306
|
}
|
|
268
307
|
async getCheckpointData(checkpointNumber) {
|
|
@@ -283,17 +322,30 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
283
322
|
}
|
|
284
323
|
return checkpoints;
|
|
285
324
|
}
|
|
325
|
+
/** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */ async getCheckpointDataForSlotRange(startSlot, endSlot) {
|
|
326
|
+
const result = [];
|
|
327
|
+
for await (const [, checkpointNumber] of this.#slotToCheckpoint.entriesAsync({
|
|
328
|
+
start: startSlot,
|
|
329
|
+
end: endSlot + 1
|
|
330
|
+
})){
|
|
331
|
+
const checkpointStorage = await this.#checkpoints.getAsync(checkpointNumber);
|
|
332
|
+
if (checkpointStorage) {
|
|
333
|
+
result.push(this.checkpointDataFromCheckpointStorage(checkpointStorage));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
286
338
|
checkpointDataFromCheckpointStorage(checkpointStorage) {
|
|
287
|
-
|
|
339
|
+
return {
|
|
288
340
|
header: CheckpointHeader.fromBuffer(checkpointStorage.header),
|
|
289
341
|
archive: AppendOnlyTreeSnapshot.fromBuffer(checkpointStorage.archive),
|
|
342
|
+
checkpointOutHash: Fr.fromBuffer(checkpointStorage.checkpointOutHash),
|
|
290
343
|
checkpointNumber: CheckpointNumber(checkpointStorage.checkpointNumber),
|
|
291
|
-
startBlock: checkpointStorage.startBlock,
|
|
292
|
-
|
|
344
|
+
startBlock: BlockNumber(checkpointStorage.startBlock),
|
|
345
|
+
blockCount: checkpointStorage.blockCount,
|
|
293
346
|
l1: L1PublishedData.fromBuffer(checkpointStorage.l1),
|
|
294
|
-
attestations: checkpointStorage.attestations
|
|
347
|
+
attestations: checkpointStorage.attestations.map((buf)=>CommitteeAttestation.fromBuffer(buf))
|
|
295
348
|
};
|
|
296
|
-
return data;
|
|
297
349
|
}
|
|
298
350
|
async getBlocksForCheckpoint(checkpointNumber) {
|
|
299
351
|
const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
|
|
@@ -302,7 +354,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
302
354
|
}
|
|
303
355
|
const blocksForCheckpoint = await toArray(this.#blocks.entriesAsync({
|
|
304
356
|
start: checkpoint.startBlock,
|
|
305
|
-
end: checkpoint.startBlock + checkpoint.
|
|
357
|
+
end: checkpoint.startBlock + checkpoint.blockCount
|
|
306
358
|
}));
|
|
307
359
|
const converted = await Promise.all(blocksForCheckpoint.map((x)=>this.getBlockFromBlockStorage(x[0], x[1])));
|
|
308
360
|
return converted.filter(isDefined);
|
|
@@ -332,9 +384,10 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
332
384
|
}
|
|
333
385
|
/**
|
|
334
386
|
* Removes all blocks with block number > blockNumber.
|
|
387
|
+
* Does not remove any associated checkpoints.
|
|
335
388
|
* @param blockNumber - The block number to remove after.
|
|
336
389
|
* @returns The removed blocks (for event emission).
|
|
337
|
-
*/ async
|
|
390
|
+
*/ async removeBlocksAfter(blockNumber) {
|
|
338
391
|
return await this.db.transactionAsync(async ()=>{
|
|
339
392
|
const removedBlocks = [];
|
|
340
393
|
// Get the latest block number to determine the range
|
|
@@ -362,7 +415,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
362
415
|
if (!checkpointStorage) {
|
|
363
416
|
throw new CheckpointNotFoundError(provenCheckpointNumber);
|
|
364
417
|
} else {
|
|
365
|
-
return BlockNumber(checkpointStorage.startBlock + checkpointStorage.
|
|
418
|
+
return BlockNumber(checkpointStorage.startBlock + checkpointStorage.blockCount - 1);
|
|
366
419
|
}
|
|
367
420
|
}
|
|
368
421
|
async getLatestBlockNumber() {
|
|
@@ -444,6 +497,28 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
444
497
|
}
|
|
445
498
|
}
|
|
446
499
|
/**
|
|
500
|
+
* Gets block metadata (without tx data) by block number.
|
|
501
|
+
* @param blockNumber - The number of the block to return.
|
|
502
|
+
* @returns The requested block data.
|
|
503
|
+
*/ async getBlockData(blockNumber) {
|
|
504
|
+
const blockStorage = await this.#blocks.getAsync(blockNumber);
|
|
505
|
+
if (!blockStorage || !blockStorage.header) {
|
|
506
|
+
return undefined;
|
|
507
|
+
}
|
|
508
|
+
return this.getBlockDataFromBlockStorage(blockStorage);
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Gets block metadata (without tx data) by archive root.
|
|
512
|
+
* @param archive - The archive root of the block to return.
|
|
513
|
+
* @returns The requested block data.
|
|
514
|
+
*/ async getBlockDataByArchive(archive) {
|
|
515
|
+
const blockNumber = await this.#blockArchiveIndex.getAsync(archive.toString());
|
|
516
|
+
if (blockNumber === undefined) {
|
|
517
|
+
return undefined;
|
|
518
|
+
}
|
|
519
|
+
return this.getBlockData(BlockNumber(blockNumber));
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
447
522
|
* Gets an L2 block.
|
|
448
523
|
* @param blockNumber - The number of the block to return.
|
|
449
524
|
* @returns The requested L2 block.
|
|
@@ -533,12 +608,19 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
533
608
|
];
|
|
534
609
|
}
|
|
535
610
|
}
|
|
611
|
+
getBlockDataFromBlockStorage(blockStorage) {
|
|
612
|
+
return {
|
|
613
|
+
header: BlockHeader.fromBuffer(blockStorage.header),
|
|
614
|
+
archive: AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive),
|
|
615
|
+
blockHash: Fr.fromBuffer(blockStorage.blockHash),
|
|
616
|
+
checkpointNumber: CheckpointNumber(blockStorage.checkpointNumber),
|
|
617
|
+
indexWithinCheckpoint: IndexWithinCheckpoint(blockStorage.indexWithinCheckpoint)
|
|
618
|
+
};
|
|
619
|
+
}
|
|
536
620
|
async getBlockFromBlockStorage(blockNumber, blockStorage) {
|
|
537
|
-
const header =
|
|
538
|
-
|
|
539
|
-
const
|
|
540
|
-
header.setHash(Fr.fromBuffer(blockHash));
|
|
541
|
-
const blockHashString = bufferToHex(blockHash);
|
|
621
|
+
const { header, archive, blockHash, checkpointNumber, indexWithinCheckpoint } = this.getBlockDataFromBlockStorage(blockStorage);
|
|
622
|
+
header.setHash(blockHash);
|
|
623
|
+
const blockHashString = bufferToHex(blockStorage.blockHash);
|
|
542
624
|
const blockTxsBuffer = await this.#blockTxs.getAsync(blockHashString);
|
|
543
625
|
if (blockTxsBuffer === undefined) {
|
|
544
626
|
this.#log.warn(`Could not find body for block ${header.globalVariables.blockNumber} ${blockHash}`);
|
|
@@ -556,7 +638,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
556
638
|
txEffects.push(deserializeIndexedTxEffect(txEffect).data);
|
|
557
639
|
}
|
|
558
640
|
const body = new Body(txEffects);
|
|
559
|
-
const block = new
|
|
641
|
+
const block = new L2Block(archive, header, body, checkpointNumber, indexWithinCheckpoint);
|
|
560
642
|
if (block.number !== blockNumber) {
|
|
561
643
|
throw new Error(`Block number mismatch when retrieving block from archive (expected ${blockNumber} but got ${block.number} with hash ${blockHashString})`);
|
|
562
644
|
}
|
|
@@ -577,12 +659,31 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
577
659
|
* Gets a receipt of a settled tx.
|
|
578
660
|
* @param txHash - The hash of a tx we try to get the receipt for.
|
|
579
661
|
* @returns The requested tx receipt (or undefined if not found).
|
|
580
|
-
*/ async getSettledTxReceipt(txHash) {
|
|
662
|
+
*/ async getSettledTxReceipt(txHash, l1Constants) {
|
|
581
663
|
const txEffect = await this.getTxEffect(txHash);
|
|
582
664
|
if (!txEffect) {
|
|
583
665
|
return undefined;
|
|
584
666
|
}
|
|
585
|
-
|
|
667
|
+
const blockNumber = BlockNumber(txEffect.l2BlockNumber);
|
|
668
|
+
// Use existing archiver methods to determine finalization level
|
|
669
|
+
const [provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber, blockData] = await Promise.all([
|
|
670
|
+
this.getProvenBlockNumber(),
|
|
671
|
+
this.getCheckpointedL2BlockNumber(),
|
|
672
|
+
this.getFinalizedL2BlockNumber(),
|
|
673
|
+
this.getBlockData(blockNumber)
|
|
674
|
+
]);
|
|
675
|
+
let status;
|
|
676
|
+
if (blockNumber <= finalizedBlockNumber) {
|
|
677
|
+
status = TxStatus.FINALIZED;
|
|
678
|
+
} else if (blockNumber <= provenBlockNumber) {
|
|
679
|
+
status = TxStatus.PROVEN;
|
|
680
|
+
} else if (blockNumber <= checkpointedBlockNumber) {
|
|
681
|
+
status = TxStatus.CHECKPOINTED;
|
|
682
|
+
} else {
|
|
683
|
+
status = TxStatus.PROPOSED;
|
|
684
|
+
}
|
|
685
|
+
const epochNumber = blockData && l1Constants ? getEpochAtSlot(blockData.header.globalVariables.slotNumber, l1Constants) : undefined;
|
|
686
|
+
return new TxReceipt(txHash, status, TxReceipt.executionResultFromRevertCode(txEffect.data.revertCode), undefined, txEffect.data.transactionFee.toBigInt(), txEffect.l2BlockHash, blockNumber, epochNumber);
|
|
586
687
|
}
|
|
587
688
|
/**
|
|
588
689
|
* Looks up which block included the requested tx effect.
|
|
@@ -615,7 +716,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
615
716
|
if (!checkpoint) {
|
|
616
717
|
return BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
617
718
|
}
|
|
618
|
-
return BlockNumber(checkpoint.startBlock + checkpoint.
|
|
719
|
+
return BlockNumber(checkpoint.startBlock + checkpoint.blockCount - 1);
|
|
619
720
|
}
|
|
620
721
|
async getLatestL2BlockNumber() {
|
|
621
722
|
const [lastBlockNumber] = await toArray(this.#blocks.keysAsync({
|
|
@@ -644,6 +745,16 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
644
745
|
const result = await this.#lastProvenCheckpoint.set(checkpointNumber);
|
|
645
746
|
return result;
|
|
646
747
|
}
|
|
748
|
+
async getFinalizedCheckpointNumber() {
|
|
749
|
+
const [latestCheckpointNumber, finalizedCheckpointNumber] = await Promise.all([
|
|
750
|
+
this.getLatestCheckpointNumber(),
|
|
751
|
+
this.#lastFinalizedCheckpoint.getAsync()
|
|
752
|
+
]);
|
|
753
|
+
return (finalizedCheckpointNumber ?? 0) > latestCheckpointNumber ? latestCheckpointNumber : CheckpointNumber(finalizedCheckpointNumber ?? 0);
|
|
754
|
+
}
|
|
755
|
+
setFinalizedCheckpointNumber(checkpointNumber) {
|
|
756
|
+
return this.#lastFinalizedCheckpoint.set(checkpointNumber);
|
|
757
|
+
}
|
|
647
758
|
#computeBlockRange(start, limit) {
|
|
648
759
|
if (limit < 1) {
|
|
649
760
|
throw new Error(`Invalid limit: ${limit}`);
|
|
@@ -15,4 +15,4 @@ export declare class ContractClassStore {
|
|
|
15
15
|
getContractClassIds(): Promise<Fr[]>;
|
|
16
16
|
addFunctions(contractClassId: Fr, newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[], newUtilityFunctions: UtilityFunctionWithMembershipProof[]): Promise<boolean>;
|
|
17
17
|
}
|
|
18
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RfY2xhc3Nfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9jb250cmFjdF9jbGFzc19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQWlCLE1BQU0saUJBQWlCLENBQUM7QUFFeEUsT0FBTyxLQUFLLEVBQ1YsbUJBQW1CLEVBRW5CLDRDQUE0QyxFQUM1QyxrQ0FBa0MsRUFDbkMsTUFBTSx3QkFBd0IsQ0FBQztBQUdoQzs7R0FFRztBQUNILHFCQUFhLGtCQUFrQjs7SUFJakIsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQUd4QztJQUVLLGdCQUFnQixDQUNwQixhQUFhLEVBQUUsbUJBQW1CLEVBQ2xDLGtCQUFrQixFQUFFLEVBQUUsRUFDdEIsV0FBVyxFQUFFLE1BQU0sR0FDbEIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVFmO0lBRUsscUJBQXFCLENBQUMsYUFBYSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVFsRztJQUVLLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxDQUd2RTtJQUVLLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FHM0Q7SUFFSyxtQkFBbUIsSUFBSSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FFekM7SUFFSyxZQUFZLENBQ2hCLGVBQWUsRUFBRSxFQUFFLEVBQ25CLG1CQUFtQixFQUFFLDRDQUE0QyxFQUFFLEVBQ25FLG1CQUFtQixFQUFFLGtDQUFrQyxFQUFFLEdBQ3hELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0F5QmxCO0NBQ0YifQ==
|
|
@@ -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,
|
|
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"}
|
|
@@ -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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
|
28
|
-
|
|
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) {
|