@aztec/archiver 0.0.1-commit.f1df4d2 → 0.0.1-commit.f224bb98b
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/dest/archiver.d.ts +7 -4
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +62 -110
- package/dest/errors.d.ts +7 -9
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +9 -14
- package/dest/factory.d.ts +3 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +15 -13
- 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 +36 -33
- 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 +9 -9
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +21 -19
- 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/modules/data_source_base.d.ts +10 -5
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +28 -72
- package/dest/modules/data_store_updater.d.ts +22 -7
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +69 -29
- package/dest/modules/instrumentation.d.ts +15 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +19 -2
- 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 +41 -10
- package/dest/store/block_store.d.ts +27 -25
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +123 -74
- package/dest/store/kv_archiver_store.d.ts +33 -11
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +37 -7
- 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 +1 -1
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +55 -35
- package/dest/store/message_store.js +1 -1
- package/dest/test/fake_l1_state.d.ts +13 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +84 -20
- 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 +21 -5
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +130 -84
- package/dest/test/mock_structs.d.ts +4 -1
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +13 -1
- package/dest/test/noop_l1_archiver.d.ts +4 -1
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +5 -1
- package/package.json +13 -13
- package/src/archiver.ts +74 -130
- package/src/errors.ts +10 -24
- package/src/factory.ts +29 -14
- package/src/index.ts +1 -0
- package/src/l1/README.md +25 -68
- package/src/l1/bin/retrieve-calldata.ts +46 -39
- package/src/l1/calldata_retriever.ts +249 -379
- package/src/l1/data_retrieval.ts +23 -25
- package/src/l1/spire_proposer.ts +7 -15
- package/src/modules/data_source_base.ts +55 -94
- package/src/modules/data_store_updater.ts +71 -30
- package/src/modules/instrumentation.ts +29 -2
- package/src/modules/l1_synchronizer.ts +46 -14
- package/src/store/block_store.ts +146 -103
- package/src/store/kv_archiver_store.ts +57 -11
- package/src/store/l2_tips_cache.ts +89 -0
- package/src/store/log_store.ts +93 -31
- package/src/store/message_store.ts +1 -1
- package/src/test/fake_l1_state.ts +110 -21
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l2_block_source.ts +166 -80
- package/src/test/mock_structs.ts +20 -6
- package/src/test/noop_l1_archiver.ts +7 -1
|
@@ -2,22 +2,10 @@ import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/bra
|
|
|
2
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
3
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
-
import { BlockHash, CheckpointedL2Block, L2Block, type ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
6
|
-
import {
|
|
7
|
-
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
8
|
-
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
9
|
-
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
5
|
+
import { type BlockData, BlockHash, CheckpointedL2Block, L2Block, type ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
6
|
+
import { type CheckpointData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
10
7
|
import { BlockHeader, type IndexedTxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
11
8
|
export { TxReceipt, type TxEffect, type TxHash } from '@aztec/stdlib/tx';
|
|
12
|
-
export type CheckpointData = {
|
|
13
|
-
checkpointNumber: CheckpointNumber;
|
|
14
|
-
header: CheckpointHeader;
|
|
15
|
-
archive: AppendOnlyTreeSnapshot;
|
|
16
|
-
startBlock: number;
|
|
17
|
-
numBlocks: number;
|
|
18
|
-
l1: L1PublishedData;
|
|
19
|
-
attestations: Buffer[];
|
|
20
|
-
};
|
|
21
9
|
export type RemoveCheckpointsResult = {
|
|
22
10
|
blocksRemoved: L2Block[] | undefined;
|
|
23
11
|
};
|
|
@@ -27,24 +15,21 @@ export type RemoveCheckpointsResult = {
|
|
|
27
15
|
export declare class BlockStore {
|
|
28
16
|
#private;
|
|
29
17
|
private db;
|
|
30
|
-
|
|
31
|
-
constructor(db: AztecAsyncKVStore, l1Constants: Pick<L1RollupConstants, 'epochDuration'>);
|
|
18
|
+
constructor(db: AztecAsyncKVStore);
|
|
32
19
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* TODO(#13569): Compute proper finalized block number based on L1 finalized block.
|
|
36
|
-
* TODO(palla/mbps): Even the provisional computation is wrong, since it should subtract checkpoints, not blocks
|
|
20
|
+
* Returns the finalized L2 block number. An L2 block is finalized when it was proven
|
|
21
|
+
* in an L1 block that has itself been finalized on Ethereum.
|
|
37
22
|
* @returns The finalized block number.
|
|
38
23
|
*/
|
|
39
24
|
getFinalizedL2BlockNumber(): Promise<BlockNumber>;
|
|
40
25
|
/**
|
|
41
|
-
* Append new proposed
|
|
42
|
-
*
|
|
26
|
+
* Append a new proposed block to the store.
|
|
27
|
+
* This is an uncheckpointed block that has been proposed by the sequencer but not yet included in a checkpoint on L1.
|
|
43
28
|
* For checkpointed blocks (already published to L1), use addCheckpoints() instead.
|
|
44
|
-
* @param
|
|
29
|
+
* @param block - The proposed L2 block to be added to the store.
|
|
45
30
|
* @returns True if the operation is successful.
|
|
46
31
|
*/
|
|
47
|
-
|
|
32
|
+
addProposedBlock(block: L2Block, opts?: {
|
|
48
33
|
force?: boolean;
|
|
49
34
|
}): Promise<boolean>;
|
|
50
35
|
/**
|
|
@@ -65,6 +50,8 @@ export declare class BlockStore {
|
|
|
65
50
|
removeCheckpointsAfter(checkpointNumber: CheckpointNumber): Promise<RemoveCheckpointsResult>;
|
|
66
51
|
getCheckpointData(checkpointNumber: CheckpointNumber): Promise<CheckpointData | undefined>;
|
|
67
52
|
getRangeOfCheckpoints(from: CheckpointNumber, limit: number): Promise<CheckpointData[]>;
|
|
53
|
+
/** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */
|
|
54
|
+
getCheckpointDataForSlotRange(startSlot: SlotNumber, endSlot: SlotNumber): Promise<CheckpointData[]>;
|
|
68
55
|
private checkpointDataFromCheckpointStorage;
|
|
69
56
|
getBlocksForCheckpoint(checkpointNumber: CheckpointNumber): Promise<L2Block[] | undefined>;
|
|
70
57
|
/**
|
|
@@ -101,6 +88,18 @@ export declare class BlockStore {
|
|
|
101
88
|
* @returns The requested L2 blocks
|
|
102
89
|
*/
|
|
103
90
|
getBlocks(start: BlockNumber, limit: number): AsyncIterableIterator<L2Block>;
|
|
91
|
+
/**
|
|
92
|
+
* Gets block metadata (without tx data) by block number.
|
|
93
|
+
* @param blockNumber - The number of the block to return.
|
|
94
|
+
* @returns The requested block data.
|
|
95
|
+
*/
|
|
96
|
+
getBlockData(blockNumber: BlockNumber): Promise<BlockData | undefined>;
|
|
97
|
+
/**
|
|
98
|
+
* Gets block metadata (without tx data) by archive root.
|
|
99
|
+
* @param archive - The archive root of the block to return.
|
|
100
|
+
* @returns The requested block data.
|
|
101
|
+
*/
|
|
102
|
+
getBlockDataByArchive(archive: Fr): Promise<BlockData | undefined>;
|
|
104
103
|
/**
|
|
105
104
|
* Gets an L2 block.
|
|
106
105
|
* @param blockNumber - The number of the block to return.
|
|
@@ -139,6 +138,7 @@ export declare class BlockStore {
|
|
|
139
138
|
*/
|
|
140
139
|
getBlockHeaders(start: BlockNumber, limit: number): AsyncIterableIterator<BlockHeader>;
|
|
141
140
|
private getBlockStorages;
|
|
141
|
+
private getBlockDataFromBlockStorage;
|
|
142
142
|
private getBlockFromBlockStorage;
|
|
143
143
|
/**
|
|
144
144
|
* Gets a tx effect.
|
|
@@ -178,6 +178,8 @@ export declare class BlockStore {
|
|
|
178
178
|
setSynchedL1BlockNumber(l1BlockNumber: bigint): Promise<boolean>;
|
|
179
179
|
getProvenCheckpointNumber(): Promise<CheckpointNumber>;
|
|
180
180
|
setProvenCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<boolean>;
|
|
181
|
+
getFinalizedCheckpointNumber(): Promise<CheckpointNumber>;
|
|
182
|
+
setFinalizedCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<boolean>;
|
|
181
183
|
/**
|
|
182
184
|
* Gets the pending chain validation status.
|
|
183
185
|
* @returns The validation status or undefined if not set.
|
|
@@ -189,4 +191,4 @@ export declare class BlockStore {
|
|
|
189
191
|
*/
|
|
190
192
|
setPendingChainValidationStatus(status: ValidateCheckpointResult | undefined): Promise<void>;
|
|
191
193
|
}
|
|
192
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
194
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9ibG9ja19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUF5QixVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuSCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFNcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQTZDLE1BQU0saUJBQWlCLENBQUM7QUFDcEcsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDaEUsT0FBTyxFQUNMLEtBQUssU0FBUyxFQUNkLFNBQVMsRUFFVCxtQkFBbUIsRUFFbkIsT0FBTyxFQUNQLEtBQUssd0JBQXdCLEVBRzlCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLEtBQUssY0FBYyxFQUFtQixtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBR3JHLE9BQU8sRUFDTCxXQUFXLEVBQ1gsS0FBSyxlQUFlLEVBRXBCLE1BQU0sRUFDTixTQUFTLEVBSVYsTUFBTSxrQkFBa0IsQ0FBQztBQWMxQixPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssUUFBUSxFQUFFLEtBQUssTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUF1QnpFLE1BQU0sTUFBTSx1QkFBdUIsR0FBRztJQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsR0FBRyxTQUFTLENBQUE7Q0FBRSxDQUFDO0FBRS9FOztHQUVHO0FBQ0gscUJBQWEsVUFBVTs7SUF1Q1QsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQWF4QztJQUVEOzs7O09BSUc7SUFDRyx5QkFBeUIsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLENBVXREO0lBRUQ7Ozs7OztPQU1HO0lBQ0csZ0JBQWdCLENBQUMsS0FBSyxF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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_store.d.ts","sourceRoot":"","sources":["../../src/store/block_store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAyB,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACnH,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAMpD,OAAO,KAAK,EAAE,iBAAiB,EAA6C,MAAM,iBAAiB,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,SAAS,EAET,mBAAmB,EAEnB,OAAO,EACP,KAAK,wBAAwB,EAG9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"block_store.d.ts","sourceRoot":"","sources":["../../src/store/block_store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAyB,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACnH,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAMpD,OAAO,KAAK,EAAE,iBAAiB,EAA6C,MAAM,iBAAiB,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,KAAK,SAAS,EACd,SAAS,EAET,mBAAmB,EAEnB,OAAO,EACP,KAAK,wBAAwB,EAG9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,cAAc,EAAmB,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGrG,OAAO,EACL,WAAW,EACX,KAAK,eAAe,EAEpB,MAAM,EACN,SAAS,EAIV,MAAM,kBAAkB,CAAC;AAc1B,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAuBzE,MAAM,MAAM,uBAAuB,GAAG;IAAE,aAAa,EAAE,OAAO,EAAE,GAAG,SAAS,CAAA;CAAE,CAAC;AAE/E;;GAEG;AACH,qBAAa,UAAU;;IAuCT,OAAO,CAAC,EAAE;IAAtB,YAAoB,EAAE,EAAE,iBAAiB,EAaxC;IAED;;;;OAIG;IACG,yBAAyB,IAAI,OAAO,CAAC,WAAW,CAAC,CAUtD;IAED;;;;;;OAMG;IACG,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CA8DvF;IAED;;;;OAIG;IACG,cAAc,CAAC,WAAW,EAAE,mBAAmB,EAAE,EAAE,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CA4GzG;YAEa,kBAAkB;YA6BlB,WAAW;IAgBzB;;;;OAIG;IACG,sBAAsB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA4CjG;IAEK,iBAAiB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAM/F;IAEK,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAU5F;IAED,uGAAuG;IACjG,6BAA6B,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAYzG;IAED,OAAO,CAAC,mCAAmC;IAarC,sBAAsB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,CAe/F;IAED;;;;;OAKG;IACG,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAiBjE;IAED;;;;;OAKG;IACG,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAuBpE;IAEK,oBAAoB,IAAI,OAAO,CAAC,WAAW,CAAC,CAWjD;IAEK,oBAAoB,IAAI,OAAO,CAAC,WAAW,CAAC,CAKjD;IAEK,yBAAyB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAM3D;IAEK,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAmBxF;IAED;;;;;OAKG;IACI,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAAC,mBAAmB,CAAC,CAoB1G;IAEK,0BAA0B,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAM/F;IAEK,6BAA6B,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAMzF;IAED;;;;;OAKG;IACI,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAOlF;IAED;;;;OAIG;IACG,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAM3E;IAED;;;;OAIG;IACG,qBAAqB,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAMvE;IAED;;;;OAIG;IACG,QAAQ,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAMrE;IAED;;;;OAIG;IACG,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAMvE;IAED;;;;OAIG;IACG,iBAAiB,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAMjE;IAED;;;;OAIG;IACG,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAUjF;IAED;;;;OAIG;IACG,uBAAuB,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAU3E;IAED;;;;;OAKG;IACI,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAU5F;YAEc,gBAAgB;IAa/B,OAAO,CAAC,4BAA4B;YAUtB,wBAAwB;IAsCtC;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAMtE;IAED;;;;OAIG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAmCxE;IAED;;;;OAIG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAOtG;IAED;;;;OAIG;IACH,mBAAmB,CAAC,eAAe,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAE5G;IAED;;;OAGG;IACG,4BAA4B,IAAI,OAAO,CAAC,WAAW,CAAC,CAOzD;IAEK,sBAAsB,IAAI,OAAO,CAAC,WAAW,CAAC,CAGnD;IAED;;;OAGG;IACH,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAErD;IAED,uBAAuB,CAAC,aAAa,EAAE,MAAM,oBAE5C;IAEK,yBAAyB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAQ3D;IAEK,yBAAyB,CAAC,gBAAgB,EAAE,gBAAgB,oBAGjE;IAEK,4BAA4B,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAQ9D;IAED,4BAA4B,CAAC,gBAAgB,EAAE,gBAAgB,oBAE9D;IAcD;;;OAGG;IACG,+BAA+B,IAAI,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAMrF;IAED;;;OAGG;IACG,+BAA+B,CAAC,MAAM,EAAE,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjG;CACF"}
|
|
@@ -11,27 +11,27 @@ import { L1PublishedData } from '@aztec/stdlib/checkpoint';
|
|
|
11
11
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
12
12
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
13
13
|
import { BlockHeader, TxHash, TxReceipt, TxStatus, deserializeIndexedTxEffect, serializeIndexedTxEffect } from '@aztec/stdlib/tx';
|
|
14
|
-
import { BlockArchiveNotConsistentError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CannotOverwriteCheckpointedBlockError, CheckpointNotFoundError,
|
|
14
|
+
import { BlockAlreadyCheckpointedError, BlockArchiveNotConsistentError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CannotOverwriteCheckpointedBlockError, CheckpointNotFoundError, CheckpointNumberNotSequentialError, InitialCheckpointNumberNotSequentialError } from '../errors.js';
|
|
15
15
|
export { TxReceipt } from '@aztec/stdlib/tx';
|
|
16
16
|
/**
|
|
17
17
|
* LMDB-based block storage for the archiver.
|
|
18
18
|
*/ export class BlockStore {
|
|
19
19
|
db;
|
|
20
|
-
l1Constants;
|
|
21
20
|
/** Map block number to block data */ #blocks;
|
|
22
21
|
/** Map checkpoint number to checkpoint data */ #checkpoints;
|
|
22
|
+
/** Map slot number to checkpoint number, for looking up checkpoints by slot range. */ #slotToCheckpoint;
|
|
23
23
|
/** Map block hash to list of tx hashes */ #blockTxs;
|
|
24
24
|
/** Tx hash to serialized IndexedTxEffect */ #txEffects;
|
|
25
25
|
/** Stores L1 block number in which the last processed L2 block was included */ #lastSynchedL1Block;
|
|
26
26
|
/** Stores last proven checkpoint */ #lastProvenCheckpoint;
|
|
27
|
+
/** Stores last finalized checkpoint (proven at or before the finalized L1 block) */ #lastFinalizedCheckpoint;
|
|
27
28
|
/** Stores the pending chain validation status */ #pendingChainValidationStatus;
|
|
28
29
|
/** Index mapping a contract's address (as a string) to its location in a block */ #contractIndex;
|
|
29
30
|
/** Index mapping block hash to block number */ #blockHashIndex;
|
|
30
31
|
/** Index mapping block archive to block number */ #blockArchiveIndex;
|
|
31
32
|
#log;
|
|
32
|
-
constructor(db
|
|
33
|
+
constructor(db){
|
|
33
34
|
this.db = db;
|
|
34
|
-
this.l1Constants = l1Constants;
|
|
35
35
|
this.#log = createLogger('archiver:block_store');
|
|
36
36
|
this.#blocks = db.openMap('archiver_blocks');
|
|
37
37
|
this.#blockTxs = db.openMap('archiver_block_txs');
|
|
@@ -41,89 +41,78 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
41
41
|
this.#blockArchiveIndex = db.openMap('archiver_block_archive_index');
|
|
42
42
|
this.#lastSynchedL1Block = db.openSingleton('archiver_last_synched_l1_block');
|
|
43
43
|
this.#lastProvenCheckpoint = db.openSingleton('archiver_last_proven_l2_checkpoint');
|
|
44
|
+
this.#lastFinalizedCheckpoint = db.openSingleton('archiver_last_finalized_l2_checkpoint');
|
|
44
45
|
this.#pendingChainValidationStatus = db.openSingleton('archiver_pending_chain_validation_status');
|
|
45
46
|
this.#checkpoints = db.openMap('archiver_checkpoints');
|
|
47
|
+
this.#slotToCheckpoint = db.openMap('archiver_slot_to_checkpoint');
|
|
46
48
|
}
|
|
47
49
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* TODO(#13569): Compute proper finalized block number based on L1 finalized block.
|
|
51
|
-
* TODO(palla/mbps): Even the provisional computation is wrong, since it should subtract checkpoints, not blocks
|
|
50
|
+
* Returns the finalized L2 block number. An L2 block is finalized when it was proven
|
|
51
|
+
* in an L1 block that has itself been finalized on Ethereum.
|
|
52
52
|
* @returns The finalized block number.
|
|
53
53
|
*/ async getFinalizedL2BlockNumber() {
|
|
54
|
-
const
|
|
55
|
-
|
|
54
|
+
const finalizedCheckpointNumber = await this.getFinalizedCheckpointNumber();
|
|
55
|
+
if (finalizedCheckpointNumber === INITIAL_CHECKPOINT_NUMBER - 1) {
|
|
56
|
+
return BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
57
|
+
}
|
|
58
|
+
const checkpointStorage = await this.#checkpoints.getAsync(finalizedCheckpointNumber);
|
|
59
|
+
if (!checkpointStorage) {
|
|
60
|
+
throw new CheckpointNotFoundError(finalizedCheckpointNumber);
|
|
61
|
+
}
|
|
62
|
+
return BlockNumber(checkpointStorage.startBlock + checkpointStorage.blockCount - 1);
|
|
56
63
|
}
|
|
57
64
|
/**
|
|
58
|
-
* Append new proposed
|
|
59
|
-
*
|
|
65
|
+
* Append a new proposed block to the store.
|
|
66
|
+
* This is an uncheckpointed block that has been proposed by the sequencer but not yet included in a checkpoint on L1.
|
|
60
67
|
* For checkpointed blocks (already published to L1), use addCheckpoints() instead.
|
|
61
|
-
* @param
|
|
68
|
+
* @param block - The proposed L2 block to be added to the store.
|
|
62
69
|
* @returns True if the operation is successful.
|
|
63
|
-
*/ async
|
|
64
|
-
if (blocks.length === 0) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
70
|
+
*/ async addProposedBlock(block, opts = {}) {
|
|
67
71
|
return await this.db.transactionAsync(async ()=>{
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
const firstBlockLastArchive = blocks[0].header.lastArchive.root;
|
|
72
|
+
const blockNumber = block.number;
|
|
73
|
+
const blockCheckpointNumber = block.checkpointNumber;
|
|
74
|
+
const blockIndex = block.indexWithinCheckpoint;
|
|
75
|
+
const blockLastArchive = block.header.lastArchive.root;
|
|
73
76
|
// Extract the latest block and checkpoint numbers
|
|
74
77
|
const previousBlockNumber = await this.getLatestBlockNumber();
|
|
75
78
|
const previousCheckpointNumber = await this.getLatestCheckpointNumber();
|
|
76
79
|
// Verify we're not overwriting checkpointed blocks
|
|
77
80
|
const lastCheckpointedBlockNumber = await this.getCheckpointedL2BlockNumber();
|
|
78
|
-
if (!opts.force &&
|
|
79
|
-
|
|
81
|
+
if (!opts.force && blockNumber <= lastCheckpointedBlockNumber) {
|
|
82
|
+
// Check if the proposed block matches the already-checkpointed one
|
|
83
|
+
const existingBlock = await this.getBlock(BlockNumber(blockNumber));
|
|
84
|
+
if (existingBlock && existingBlock.archive.root.equals(block.archive.root)) {
|
|
85
|
+
throw new BlockAlreadyCheckpointedError(blockNumber);
|
|
86
|
+
}
|
|
87
|
+
throw new CannotOverwriteCheckpointedBlockError(blockNumber, lastCheckpointedBlockNumber);
|
|
80
88
|
}
|
|
81
|
-
// Check that the
|
|
82
|
-
if (!opts.force && previousBlockNumber !==
|
|
83
|
-
throw new
|
|
89
|
+
// Check that the block number is the expected one
|
|
90
|
+
if (!opts.force && previousBlockNumber !== blockNumber - 1) {
|
|
91
|
+
throw new BlockNumberNotSequentialError(blockNumber, previousBlockNumber);
|
|
84
92
|
}
|
|
85
93
|
// The same check as above but for checkpoints
|
|
86
|
-
if (!opts.force && previousCheckpointNumber !==
|
|
87
|
-
throw new
|
|
94
|
+
if (!opts.force && previousCheckpointNumber !== blockCheckpointNumber - 1) {
|
|
95
|
+
throw new CheckpointNumberNotSequentialError(blockCheckpointNumber, previousCheckpointNumber);
|
|
88
96
|
}
|
|
89
97
|
// Extract the previous block if there is one and see if it is for the same checkpoint or not
|
|
90
98
|
const previousBlockResult = await this.getBlock(previousBlockNumber);
|
|
91
|
-
let
|
|
99
|
+
let expectedBlockIndex = 0;
|
|
92
100
|
let previousBlockIndex = undefined;
|
|
93
101
|
if (previousBlockResult !== undefined) {
|
|
94
|
-
if (previousBlockResult.checkpointNumber ===
|
|
102
|
+
if (previousBlockResult.checkpointNumber === blockCheckpointNumber) {
|
|
95
103
|
// The previous block is for the same checkpoint, therefore our index should follow it
|
|
96
104
|
previousBlockIndex = previousBlockResult.indexWithinCheckpoint;
|
|
97
|
-
|
|
105
|
+
expectedBlockIndex = previousBlockIndex + 1;
|
|
98
106
|
}
|
|
99
|
-
if (!previousBlockResult.archive.root.equals(
|
|
100
|
-
throw new BlockArchiveNotConsistentError(
|
|
107
|
+
if (!previousBlockResult.archive.root.equals(blockLastArchive)) {
|
|
108
|
+
throw new BlockArchiveNotConsistentError(blockNumber, previousBlockResult.number, blockLastArchive, previousBlockResult.archive.root);
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
|
-
// Now check that the
|
|
104
|
-
if (!opts.force &&
|
|
105
|
-
throw new BlockIndexNotSequentialError(
|
|
106
|
-
}
|
|
107
|
-
// Iterate over blocks array and insert them, checking that the block numbers and indexes are sequential. Also check they are for the correct checkpoint.
|
|
108
|
-
let previousBlock = undefined;
|
|
109
|
-
for (const block of blocks){
|
|
110
|
-
if (!opts.force && previousBlock) {
|
|
111
|
-
if (previousBlock.number + 1 !== block.number) {
|
|
112
|
-
throw new BlockNumberNotSequentialError(block.number, previousBlock.number);
|
|
113
|
-
}
|
|
114
|
-
if (previousBlock.indexWithinCheckpoint + 1 !== block.indexWithinCheckpoint) {
|
|
115
|
-
throw new BlockIndexNotSequentialError(block.indexWithinCheckpoint, previousBlock.indexWithinCheckpoint);
|
|
116
|
-
}
|
|
117
|
-
if (!previousBlock.archive.root.equals(block.header.lastArchive.root)) {
|
|
118
|
-
throw new BlockArchiveNotConsistentError(block.number, previousBlock.number, block.header.lastArchive.root, previousBlock.archive.root);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
if (!opts.force && firstBlockCheckpointNumber !== block.checkpointNumber) {
|
|
122
|
-
throw new CheckpointNumberNotConsistentError(block.checkpointNumber, firstBlockCheckpointNumber);
|
|
123
|
-
}
|
|
124
|
-
previousBlock = block;
|
|
125
|
-
await this.addBlockToDatabase(block, block.checkpointNumber, block.indexWithinCheckpoint);
|
|
111
|
+
// Now check that the block has the expected index value
|
|
112
|
+
if (!opts.force && expectedBlockIndex !== blockIndex) {
|
|
113
|
+
throw new BlockIndexNotSequentialError(blockIndex, previousBlockIndex);
|
|
126
114
|
}
|
|
115
|
+
await this.addBlockToDatabase(block, block.checkpointNumber, block.indexWithinCheckpoint);
|
|
127
116
|
return true;
|
|
128
117
|
});
|
|
129
118
|
}
|
|
@@ -155,7 +144,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
155
144
|
let previousBlock = undefined;
|
|
156
145
|
// If we have a previous checkpoint then we need to get the previous block number
|
|
157
146
|
if (previousCheckpointData !== undefined) {
|
|
158
|
-
previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.
|
|
147
|
+
previousBlockNumber = BlockNumber(previousCheckpointData.startBlock + previousCheckpointData.blockCount - 1);
|
|
159
148
|
previousBlock = await this.getBlock(previousBlockNumber);
|
|
160
149
|
if (previousBlock === undefined) {
|
|
161
150
|
// We should be able to get the required previous block
|
|
@@ -200,12 +189,15 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
200
189
|
await this.#checkpoints.set(checkpoint.checkpoint.number, {
|
|
201
190
|
header: checkpoint.checkpoint.header.toBuffer(),
|
|
202
191
|
archive: checkpoint.checkpoint.archive.toBuffer(),
|
|
192
|
+
checkpointOutHash: checkpoint.checkpoint.getCheckpointOutHash().toBuffer(),
|
|
203
193
|
l1: checkpoint.l1.toBuffer(),
|
|
204
194
|
attestations: checkpoint.attestations.map((attestation)=>attestation.toBuffer()),
|
|
205
195
|
checkpointNumber: checkpoint.checkpoint.number,
|
|
206
196
|
startBlock: checkpoint.checkpoint.blocks[0].number,
|
|
207
|
-
|
|
197
|
+
blockCount: checkpoint.checkpoint.blocks.length
|
|
208
198
|
});
|
|
199
|
+
// Update slot-to-checkpoint index
|
|
200
|
+
await this.#slotToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, checkpoint.checkpoint.number);
|
|
209
201
|
}
|
|
210
202
|
await this.#lastSynchedL1Block.set(checkpoints[checkpoints.length - 1].l1.blockNumber);
|
|
211
203
|
return true;
|
|
@@ -274,12 +266,17 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
274
266
|
if (!targetCheckpoint) {
|
|
275
267
|
throw new Error(`Target checkpoint ${checkpointNumber} not found in store`);
|
|
276
268
|
}
|
|
277
|
-
lastBlockToKeep = BlockNumber(targetCheckpoint.startBlock + targetCheckpoint.
|
|
269
|
+
lastBlockToKeep = BlockNumber(targetCheckpoint.startBlock + targetCheckpoint.blockCount - 1);
|
|
278
270
|
}
|
|
279
271
|
// Remove all blocks after lastBlockToKeep (both checkpointed and uncheckpointed)
|
|
280
272
|
const blocksRemoved = await this.removeBlocksAfter(lastBlockToKeep);
|
|
281
273
|
// Remove all checkpoints after the target
|
|
282
274
|
for(let c = latestCheckpointNumber; c > checkpointNumber; c = CheckpointNumber(c - 1)){
|
|
275
|
+
const checkpointStorage = await this.#checkpoints.getAsync(c);
|
|
276
|
+
if (checkpointStorage) {
|
|
277
|
+
const slotNumber = CheckpointHeader.fromBuffer(checkpointStorage.header).slotNumber;
|
|
278
|
+
await this.#slotToCheckpoint.delete(slotNumber);
|
|
279
|
+
}
|
|
283
280
|
await this.#checkpoints.delete(c);
|
|
284
281
|
this.#log.debug(`Removed checkpoint ${c}`);
|
|
285
282
|
}
|
|
@@ -306,17 +303,30 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
306
303
|
}
|
|
307
304
|
return checkpoints;
|
|
308
305
|
}
|
|
306
|
+
/** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */ async getCheckpointDataForSlotRange(startSlot, endSlot) {
|
|
307
|
+
const result = [];
|
|
308
|
+
for await (const [, checkpointNumber] of this.#slotToCheckpoint.entriesAsync({
|
|
309
|
+
start: startSlot,
|
|
310
|
+
end: endSlot + 1
|
|
311
|
+
})){
|
|
312
|
+
const checkpointStorage = await this.#checkpoints.getAsync(checkpointNumber);
|
|
313
|
+
if (checkpointStorage) {
|
|
314
|
+
result.push(this.checkpointDataFromCheckpointStorage(checkpointStorage));
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
309
319
|
checkpointDataFromCheckpointStorage(checkpointStorage) {
|
|
310
|
-
|
|
320
|
+
return {
|
|
311
321
|
header: CheckpointHeader.fromBuffer(checkpointStorage.header),
|
|
312
322
|
archive: AppendOnlyTreeSnapshot.fromBuffer(checkpointStorage.archive),
|
|
323
|
+
checkpointOutHash: Fr.fromBuffer(checkpointStorage.checkpointOutHash),
|
|
313
324
|
checkpointNumber: CheckpointNumber(checkpointStorage.checkpointNumber),
|
|
314
|
-
startBlock: checkpointStorage.startBlock,
|
|
315
|
-
|
|
325
|
+
startBlock: BlockNumber(checkpointStorage.startBlock),
|
|
326
|
+
blockCount: checkpointStorage.blockCount,
|
|
316
327
|
l1: L1PublishedData.fromBuffer(checkpointStorage.l1),
|
|
317
|
-
attestations: checkpointStorage.attestations
|
|
328
|
+
attestations: checkpointStorage.attestations.map((buf)=>CommitteeAttestation.fromBuffer(buf))
|
|
318
329
|
};
|
|
319
|
-
return data;
|
|
320
330
|
}
|
|
321
331
|
async getBlocksForCheckpoint(checkpointNumber) {
|
|
322
332
|
const checkpoint = await this.#checkpoints.getAsync(checkpointNumber);
|
|
@@ -325,7 +335,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
325
335
|
}
|
|
326
336
|
const blocksForCheckpoint = await toArray(this.#blocks.entriesAsync({
|
|
327
337
|
start: checkpoint.startBlock,
|
|
328
|
-
end: checkpoint.startBlock + checkpoint.
|
|
338
|
+
end: checkpoint.startBlock + checkpoint.blockCount
|
|
329
339
|
}));
|
|
330
340
|
const converted = await Promise.all(blocksForCheckpoint.map((x)=>this.getBlockFromBlockStorage(x[0], x[1])));
|
|
331
341
|
return converted.filter(isDefined);
|
|
@@ -386,7 +396,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
386
396
|
if (!checkpointStorage) {
|
|
387
397
|
throw new CheckpointNotFoundError(provenCheckpointNumber);
|
|
388
398
|
} else {
|
|
389
|
-
return BlockNumber(checkpointStorage.startBlock + checkpointStorage.
|
|
399
|
+
return BlockNumber(checkpointStorage.startBlock + checkpointStorage.blockCount - 1);
|
|
390
400
|
}
|
|
391
401
|
}
|
|
392
402
|
async getLatestBlockNumber() {
|
|
@@ -468,6 +478,28 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
468
478
|
}
|
|
469
479
|
}
|
|
470
480
|
/**
|
|
481
|
+
* Gets block metadata (without tx data) by block number.
|
|
482
|
+
* @param blockNumber - The number of the block to return.
|
|
483
|
+
* @returns The requested block data.
|
|
484
|
+
*/ async getBlockData(blockNumber) {
|
|
485
|
+
const blockStorage = await this.#blocks.getAsync(blockNumber);
|
|
486
|
+
if (!blockStorage || !blockStorage.header) {
|
|
487
|
+
return undefined;
|
|
488
|
+
}
|
|
489
|
+
return this.getBlockDataFromBlockStorage(blockStorage);
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Gets block metadata (without tx data) by archive root.
|
|
493
|
+
* @param archive - The archive root of the block to return.
|
|
494
|
+
* @returns The requested block data.
|
|
495
|
+
*/ async getBlockDataByArchive(archive) {
|
|
496
|
+
const blockNumber = await this.#blockArchiveIndex.getAsync(archive.toString());
|
|
497
|
+
if (blockNumber === undefined) {
|
|
498
|
+
return undefined;
|
|
499
|
+
}
|
|
500
|
+
return this.getBlockData(BlockNumber(blockNumber));
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
471
503
|
* Gets an L2 block.
|
|
472
504
|
* @param blockNumber - The number of the block to return.
|
|
473
505
|
* @returns The requested L2 block.
|
|
@@ -557,12 +589,19 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
557
589
|
];
|
|
558
590
|
}
|
|
559
591
|
}
|
|
592
|
+
getBlockDataFromBlockStorage(blockStorage) {
|
|
593
|
+
return {
|
|
594
|
+
header: BlockHeader.fromBuffer(blockStorage.header),
|
|
595
|
+
archive: AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive),
|
|
596
|
+
blockHash: Fr.fromBuffer(blockStorage.blockHash),
|
|
597
|
+
checkpointNumber: CheckpointNumber(blockStorage.checkpointNumber),
|
|
598
|
+
indexWithinCheckpoint: IndexWithinCheckpoint(blockStorage.indexWithinCheckpoint)
|
|
599
|
+
};
|
|
600
|
+
}
|
|
560
601
|
async getBlockFromBlockStorage(blockNumber, blockStorage) {
|
|
561
|
-
const header =
|
|
562
|
-
|
|
563
|
-
const
|
|
564
|
-
header.setHash(Fr.fromBuffer(blockHash));
|
|
565
|
-
const blockHashString = bufferToHex(blockHash);
|
|
602
|
+
const { header, archive, blockHash, checkpointNumber, indexWithinCheckpoint } = this.getBlockDataFromBlockStorage(blockStorage);
|
|
603
|
+
header.setHash(blockHash);
|
|
604
|
+
const blockHashString = bufferToHex(blockStorage.blockHash);
|
|
566
605
|
const blockTxsBuffer = await this.#blockTxs.getAsync(blockHashString);
|
|
567
606
|
if (blockTxsBuffer === undefined) {
|
|
568
607
|
this.#log.warn(`Could not find body for block ${header.globalVariables.blockNumber} ${blockHash}`);
|
|
@@ -580,7 +619,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
580
619
|
txEffects.push(deserializeIndexedTxEffect(txEffect).data);
|
|
581
620
|
}
|
|
582
621
|
const body = new Body(txEffects);
|
|
583
|
-
const block = new L2Block(archive, header, body,
|
|
622
|
+
const block = new L2Block(archive, header, body, checkpointNumber, indexWithinCheckpoint);
|
|
584
623
|
if (block.number !== blockNumber) {
|
|
585
624
|
throw new Error(`Block number mismatch when retrieving block from archive (expected ${blockNumber} but got ${block.number} with hash ${blockHashString})`);
|
|
586
625
|
}
|
|
@@ -656,7 +695,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
656
695
|
if (!checkpoint) {
|
|
657
696
|
return BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
658
697
|
}
|
|
659
|
-
return BlockNumber(checkpoint.startBlock + checkpoint.
|
|
698
|
+
return BlockNumber(checkpoint.startBlock + checkpoint.blockCount - 1);
|
|
660
699
|
}
|
|
661
700
|
async getLatestL2BlockNumber() {
|
|
662
701
|
const [lastBlockNumber] = await toArray(this.#blocks.keysAsync({
|
|
@@ -685,6 +724,16 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
685
724
|
const result = await this.#lastProvenCheckpoint.set(checkpointNumber);
|
|
686
725
|
return result;
|
|
687
726
|
}
|
|
727
|
+
async getFinalizedCheckpointNumber() {
|
|
728
|
+
const [latestCheckpointNumber, finalizedCheckpointNumber] = await Promise.all([
|
|
729
|
+
this.getLatestCheckpointNumber(),
|
|
730
|
+
this.#lastFinalizedCheckpoint.getAsync()
|
|
731
|
+
]);
|
|
732
|
+
return (finalizedCheckpointNumber ?? 0) > latestCheckpointNumber ? latestCheckpointNumber : CheckpointNumber(finalizedCheckpointNumber ?? 0);
|
|
733
|
+
}
|
|
734
|
+
setFinalizedCheckpointNumber(checkpointNumber) {
|
|
735
|
+
return this.#lastFinalizedCheckpoint.set(checkpointNumber);
|
|
736
|
+
}
|
|
688
737
|
#computeBlockRange(start, limit) {
|
|
689
738
|
if (limit < 1) {
|
|
690
739
|
throw new Error(`Invalid limit: ${limit}`);
|