@aztec/archiver 0.0.1-commit.96bb3f7 → 0.0.1-commit.96dac018d
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 +156 -22
- package/dest/archiver.d.ts +139 -0
- package/dest/archiver.d.ts.map +1 -0
- package/dest/archiver.js +699 -0
- package/dest/{archiver/config.d.ts → config.d.ts} +9 -1
- package/dest/config.d.ts.map +1 -0
- package/dest/{archiver/config.js → config.js} +9 -0
- package/dest/errors.d.ts +41 -0
- package/dest/errors.d.ts.map +1 -0
- package/dest/{archiver/errors.js → errors.js} +8 -0
- package/dest/factory.d.ts +9 -7
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +91 -11
- package/dest/index.d.ts +11 -4
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +9 -3
- package/dest/interfaces.d.ts +9 -0
- package/dest/interfaces.d.ts.map +1 -0
- package/dest/interfaces.js +3 -0
- package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.d.ts +1 -1
- package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
- package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.js +35 -32
- package/dest/l1/calldata_retriever.d.ts +135 -0
- package/dest/l1/calldata_retriever.d.ts.map +1 -0
- package/dest/l1/calldata_retriever.js +402 -0
- package/dest/l1/data_retrieval.d.ts +85 -0
- package/dest/l1/data_retrieval.d.ts.map +1 -0
- package/dest/{archiver/l1 → l1}/data_retrieval.js +43 -66
- package/dest/{archiver/l1 → l1}/debug_tx.d.ts +1 -1
- package/dest/l1/debug_tx.d.ts.map +1 -0
- package/dest/{archiver/l1 → l1}/spire_proposer.d.ts +5 -5
- package/dest/l1/spire_proposer.d.ts.map +1 -0
- package/dest/{archiver/l1 → l1}/spire_proposer.js +9 -17
- package/dest/{archiver/l1 → l1}/trace_tx.d.ts +1 -1
- package/dest/l1/trace_tx.d.ts.map +1 -0
- package/dest/l1/types.d.ts +12 -0
- package/dest/l1/types.d.ts.map +1 -0
- package/dest/{archiver/l1 → l1}/validate_trace.d.ts +6 -3
- package/dest/l1/validate_trace.d.ts.map +1 -0
- package/dest/{archiver/l1 → l1}/validate_trace.js +13 -9
- package/dest/modules/data_source_base.d.ts +89 -0
- package/dest/modules/data_source_base.d.ts.map +1 -0
- package/dest/modules/data_source_base.js +216 -0
- package/dest/modules/data_store_updater.d.ts +80 -0
- package/dest/modules/data_store_updater.d.ts.map +1 -0
- package/dest/modules/data_store_updater.js +323 -0
- package/dest/modules/instrumentation.d.ts +50 -0
- package/dest/modules/instrumentation.d.ts.map +1 -0
- package/dest/{archiver → modules}/instrumentation.js +36 -12
- package/dest/modules/l1_synchronizer.d.ts +71 -0
- package/dest/modules/l1_synchronizer.d.ts.map +1 -0
- package/dest/modules/l1_synchronizer.js +1117 -0
- package/dest/{archiver → modules}/validation.d.ts +1 -1
- package/dest/modules/validation.d.ts.map +1 -0
- package/dest/{archiver → modules}/validation.js +6 -0
- package/dest/store/block_store.d.ts +196 -0
- package/dest/store/block_store.d.ts.map +1 -0
- package/dest/{archiver/kv_archiver_store → store}/block_store.js +207 -60
- package/dest/store/contract_class_store.d.ts +18 -0
- package/dest/store/contract_class_store.d.ts.map +1 -0
- package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +12 -8
- package/dest/store/contract_instance_store.d.ts +24 -0
- package/dest/store/contract_instance_store.d.ts.map +1 -0
- package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
- package/dest/store/kv_archiver_store.d.ts +354 -0
- package/dest/store/kv_archiver_store.d.ts.map +1 -0
- package/dest/store/kv_archiver_store.js +464 -0
- 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 +54 -0
- package/dest/store/log_store.d.ts.map +1 -0
- package/dest/{archiver/kv_archiver_store → store}/log_store.js +146 -91
- package/dest/{archiver/kv_archiver_store → store}/message_store.d.ts +1 -1
- package/dest/store/message_store.d.ts.map +1 -0
- package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
- package/dest/structs/data_retrieval.d.ts.map +1 -0
- package/dest/structs/inbox_message.d.ts +15 -0
- package/dest/structs/inbox_message.d.ts.map +1 -0
- package/dest/{archiver/structs → structs}/published.d.ts +1 -1
- package/dest/structs/published.d.ts.map +1 -0
- package/dest/test/fake_l1_state.d.ts +195 -0
- package/dest/test/fake_l1_state.d.ts.map +1 -0
- package/dest/test/fake_l1_state.js +421 -0
- package/dest/test/index.d.ts +2 -1
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +4 -1
- package/dest/test/mock_archiver.d.ts +2 -2
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +3 -3
- package/dest/test/mock_l2_block_source.d.ts +35 -17
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +177 -74
- package/dest/test/mock_structs.d.ts +78 -3
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +140 -7
- package/dest/test/noop_l1_archiver.d.ts +23 -0
- package/dest/test/noop_l1_archiver.d.ts.map +1 -0
- package/dest/test/noop_l1_archiver.js +68 -0
- package/package.json +16 -17
- package/src/archiver.ts +443 -0
- package/src/{archiver/config.ts → config.ts} +11 -0
- package/src/{archiver/errors.ts → errors.ts} +12 -0
- package/src/factory.ts +139 -11
- package/src/index.ts +11 -3
- package/src/interfaces.ts +9 -0
- package/src/l1/README.md +55 -0
- package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +45 -33
- package/src/l1/calldata_retriever.ts +511 -0
- package/src/{archiver/l1 → l1}/data_retrieval.ts +61 -88
- package/src/{archiver/l1 → l1}/spire_proposer.ts +7 -15
- package/src/{archiver/l1 → l1}/validate_trace.ts +24 -6
- package/src/modules/data_source_base.ts +328 -0
- package/src/modules/data_store_updater.ts +448 -0
- package/src/{archiver → modules}/instrumentation.ts +46 -14
- package/src/modules/l1_synchronizer.ts +933 -0
- package/src/{archiver → modules}/validation.ts +5 -0
- package/src/{archiver/kv_archiver_store → store}/block_store.ts +258 -93
- package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +12 -8
- package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +1 -1
- package/src/{archiver/kv_archiver_store → store}/kv_archiver_store.ts +267 -38
- package/src/store/l2_tips_cache.ts +89 -0
- package/src/{archiver/kv_archiver_store → store}/log_store.ts +242 -121
- package/src/test/fake_l1_state.ts +657 -0
- package/src/test/index.ts +4 -0
- package/src/test/mock_archiver.ts +4 -3
- package/src/test/mock_l2_block_source.ts +218 -90
- package/src/test/mock_structs.ts +269 -8
- package/src/test/noop_l1_archiver.ts +109 -0
- package/dest/archiver/archiver.d.ts +0 -307
- package/dest/archiver/archiver.d.ts.map +0 -1
- package/dest/archiver/archiver.js +0 -2102
- package/dest/archiver/archiver_store.d.ts +0 -315
- package/dest/archiver/archiver_store.d.ts.map +0 -1
- package/dest/archiver/archiver_store.js +0 -4
- package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
- package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
- package/dest/archiver/archiver_store_test_suite.js +0 -2770
- package/dest/archiver/config.d.ts.map +0 -1
- package/dest/archiver/errors.d.ts +0 -36
- package/dest/archiver/errors.d.ts.map +0 -1
- package/dest/archiver/index.d.ts +0 -7
- package/dest/archiver/index.d.ts.map +0 -1
- package/dest/archiver/index.js +0 -4
- package/dest/archiver/instrumentation.d.ts +0 -37
- package/dest/archiver/instrumentation.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -164
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -159
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -316
- package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -45
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
- package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
- package/dest/archiver/l1/calldata_retriever.d.ts +0 -112
- package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
- package/dest/archiver/l1/calldata_retriever.js +0 -471
- package/dest/archiver/l1/data_retrieval.d.ts +0 -90
- package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
- package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
- package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
- package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
- package/dest/archiver/l1/types.d.ts +0 -12
- package/dest/archiver/l1/types.d.ts.map +0 -1
- package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
- package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
- package/dest/archiver/structs/inbox_message.d.ts +0 -15
- package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
- package/dest/archiver/structs/published.d.ts.map +0 -1
- package/dest/archiver/validation.d.ts.map +0 -1
- package/dest/rpc/index.d.ts +0 -9
- package/dest/rpc/index.d.ts.map +0 -1
- package/dest/rpc/index.js +0 -15
- package/src/archiver/archiver.ts +0 -2265
- package/src/archiver/archiver_store.ts +0 -380
- package/src/archiver/archiver_store_test_suite.ts +0 -2842
- package/src/archiver/index.ts +0 -6
- package/src/archiver/l1/README.md +0 -98
- package/src/archiver/l1/calldata_retriever.ts +0 -641
- package/src/rpc/index.ts +0 -16
- /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
- /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
- /package/dest/{archiver/l1 → l1}/types.js +0 -0
- /package/dest/{archiver/kv_archiver_store → store}/message_store.js +0 -0
- /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
- /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
- /package/dest/{archiver/structs → structs}/published.js +0 -0
- /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
- /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
- /package/src/{archiver/l1 → l1}/types.ts +0 -0
- /package/src/{archiver/kv_archiver_store → store}/message_store.ts +0 -0
- /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
- /package/src/{archiver/structs → structs}/inbox_message.ts +0 -0
- /package/src/{archiver/structs → structs}/published.ts +0 -0
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { L1BlockId } from '@aztec/ethereum/l1-types';
|
|
2
|
-
import type { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import type { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
4
|
import { toArray } from '@aztec/foundation/iterable';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import type { AztecAsyncKVStore, CustomRange, StoreSize } from '@aztec/kv-store';
|
|
7
7
|
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
8
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
-
import {
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
type BlockData,
|
|
11
|
+
BlockHash,
|
|
12
|
+
CheckpointedL2Block,
|
|
13
|
+
L2Block,
|
|
14
|
+
type ValidateCheckpointResult,
|
|
15
|
+
} from '@aztec/stdlib/block';
|
|
16
|
+
import type { CheckpointData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
11
17
|
import type {
|
|
12
18
|
ContractClassPublic,
|
|
13
19
|
ContractDataSource,
|
|
@@ -16,6 +22,7 @@ import type {
|
|
|
16
22
|
ExecutablePrivateFunctionWithMembershipProof,
|
|
17
23
|
UtilityFunctionWithMembershipProof,
|
|
18
24
|
} from '@aztec/stdlib/contract';
|
|
25
|
+
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
19
26
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
20
27
|
import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
21
28
|
import type { BlockHeader, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
@@ -23,9 +30,8 @@ import type { UInt64 } from '@aztec/stdlib/types';
|
|
|
23
30
|
|
|
24
31
|
import { join } from 'path';
|
|
25
32
|
|
|
26
|
-
import type { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
27
33
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
28
|
-
import { BlockStore, type
|
|
34
|
+
import { BlockStore, type RemoveCheckpointsResult } from './block_store.js';
|
|
29
35
|
import { ContractClassStore } from './contract_class_store.js';
|
|
30
36
|
import { ContractInstanceStore } from './contract_instance_store.js';
|
|
31
37
|
import { LogStore } from './log_store.js';
|
|
@@ -36,9 +42,20 @@ export const MAX_FUNCTION_SIGNATURES = 1000;
|
|
|
36
42
|
export const MAX_FUNCTION_NAME_LEN = 256;
|
|
37
43
|
|
|
38
44
|
/**
|
|
39
|
-
*
|
|
45
|
+
* Represents the latest L1 block processed by the archiver for various objects in L2.
|
|
40
46
|
*/
|
|
41
|
-
export
|
|
47
|
+
export type ArchiverL1SynchPoint = {
|
|
48
|
+
/** Number of the last L1 block that added a new L2 checkpoint metadata. */
|
|
49
|
+
blocksSynchedTo?: bigint;
|
|
50
|
+
/** Last L1 block checked for L1 to L2 messages. */
|
|
51
|
+
messagesSynchedTo?: L1BlockId;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* LMDB-based data store for the archiver.
|
|
56
|
+
* Stores all archiver data including blocks, logs, contract classes/instances, and L1 to L2 messages.
|
|
57
|
+
*/
|
|
58
|
+
export class KVArchiverDataStore implements ContractDataSource {
|
|
42
59
|
public static readonly SCHEMA_VERSION = ARCHIVER_DB_VERSION;
|
|
43
60
|
|
|
44
61
|
#blockStore: BlockStore;
|
|
@@ -54,14 +71,21 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
54
71
|
constructor(
|
|
55
72
|
private db: AztecAsyncKVStore,
|
|
56
73
|
logsMaxPageSize: number = 1000,
|
|
74
|
+
l1Constants: Pick<L1RollupConstants, 'epochDuration'>,
|
|
57
75
|
) {
|
|
58
|
-
this.#blockStore = new BlockStore(db);
|
|
76
|
+
this.#blockStore = new BlockStore(db, l1Constants);
|
|
59
77
|
this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
|
|
60
78
|
this.#messageStore = new MessageStore(db);
|
|
61
79
|
this.#contractClassStore = new ContractClassStore(db);
|
|
62
80
|
this.#contractInstanceStore = new ContractInstanceStore(db);
|
|
63
81
|
}
|
|
64
82
|
|
|
83
|
+
/** Returns the underlying block store. Used by L2TipsCache. */
|
|
84
|
+
get blockStore(): BlockStore {
|
|
85
|
+
return this.#blockStore;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Opens a new transaction to the underlying store and runs all operations within it. */
|
|
65
89
|
public transactionAsync<T>(callback: () => Promise<T>): Promise<T> {
|
|
66
90
|
return this.db.transactionAsync(callback);
|
|
67
91
|
}
|
|
@@ -79,19 +103,28 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
79
103
|
return this.getContractInstance(address, timestamp);
|
|
80
104
|
}
|
|
81
105
|
|
|
106
|
+
/** Backups the archiver db to the target folder. Returns the path to the db file. */
|
|
82
107
|
public async backupTo(path: string, compress = true): Promise<string> {
|
|
83
108
|
await this.db.backupTo(path, compress);
|
|
84
109
|
return join(path, 'data.mdb');
|
|
85
110
|
}
|
|
86
111
|
|
|
112
|
+
/** Closes the underlying data store. */
|
|
87
113
|
public close() {
|
|
88
114
|
return this.db.close();
|
|
89
115
|
}
|
|
90
116
|
|
|
117
|
+
/** Computes the finalized block number based on the proven block number. */
|
|
118
|
+
getFinalizedL2BlockNumber(): Promise<BlockNumber> {
|
|
119
|
+
return this.#blockStore.getFinalizedL2BlockNumber();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Looks up a public function name given a selector. */
|
|
91
123
|
getDebugFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
|
|
92
124
|
return Promise.resolve(this.functionNames.get(selector.toString()));
|
|
93
125
|
}
|
|
94
126
|
|
|
127
|
+
/** Register a public function signature, so it can be looked up by selector. */
|
|
95
128
|
async registerContractFunctionSignatures(signatures: string[]): Promise<void> {
|
|
96
129
|
for (const sig of signatures) {
|
|
97
130
|
if (this.functionNames.size > MAX_FUNCTION_SIGNATURES) {
|
|
@@ -106,14 +139,25 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
106
139
|
}
|
|
107
140
|
}
|
|
108
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Returns a contract class given its id, or undefined if not exists.
|
|
144
|
+
* @param id - Id of the contract class.
|
|
145
|
+
*/
|
|
109
146
|
getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
|
|
110
147
|
return this.#contractClassStore.getContractClass(id);
|
|
111
148
|
}
|
|
112
149
|
|
|
150
|
+
/** Returns the list of all class ids known by the archiver. */
|
|
113
151
|
getContractClassIds(): Promise<Fr[]> {
|
|
114
152
|
return this.#contractClassStore.getContractClassIds();
|
|
115
153
|
}
|
|
116
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Returns a contract instance given its address and the given timestamp, or undefined if not exists.
|
|
157
|
+
* @param address - Address of the contract.
|
|
158
|
+
* @param timestamp - Timestamp to get the contract instance at. Contract updates might change the instance.
|
|
159
|
+
* @returns The contract instance or undefined if not found.
|
|
160
|
+
*/
|
|
117
161
|
getContractInstance(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
118
162
|
return this.#contractInstanceStore.getContractInstance(address, timestamp);
|
|
119
163
|
}
|
|
@@ -122,6 +166,13 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
122
166
|
return this.#contractInstanceStore.getContractInstanceDeploymentBlockNumber(address);
|
|
123
167
|
}
|
|
124
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Add new contract classes from an L2 block to the store's list.
|
|
171
|
+
* @param data - List of contract classes to be added.
|
|
172
|
+
* @param bytecodeCommitments - Bytecode commitments for the contract classes.
|
|
173
|
+
* @param blockNumber - Number of the L2 block the contracts were registered in.
|
|
174
|
+
* @returns True if the operation is successful.
|
|
175
|
+
*/
|
|
125
176
|
async addContractClasses(
|
|
126
177
|
data: ContractClassPublic[],
|
|
127
178
|
bytecodeCommitments: Fr[],
|
|
@@ -144,6 +195,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
144
195
|
return this.#contractClassStore.getBytecodeCommitment(contractClassId);
|
|
145
196
|
}
|
|
146
197
|
|
|
198
|
+
/** Adds private functions to a contract class. */
|
|
147
199
|
addFunctions(
|
|
148
200
|
contractClassId: Fr,
|
|
149
201
|
privateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
|
|
@@ -152,6 +204,12 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
152
204
|
return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
|
|
153
205
|
}
|
|
154
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Add new contract instances from an L2 block to the store's list.
|
|
209
|
+
* @param data - List of contract instances to be added.
|
|
210
|
+
* @param blockNumber - Number of the L2 block the instances were deployed in.
|
|
211
|
+
* @returns True if the operation is successful.
|
|
212
|
+
*/
|
|
155
213
|
async addContractInstances(data: ContractInstanceWithAddress[], blockNumber: BlockNumber): Promise<boolean> {
|
|
156
214
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c, blockNumber)))).every(
|
|
157
215
|
Boolean,
|
|
@@ -162,6 +220,12 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
162
220
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
|
|
163
221
|
}
|
|
164
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Add new contract instance updates
|
|
225
|
+
* @param data - List of contract updates to be added.
|
|
226
|
+
* @param timestamp - Timestamp at which the updates were scheduled.
|
|
227
|
+
* @returns True if the operation is successful.
|
|
228
|
+
*/
|
|
165
229
|
async addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], timestamp: UInt64): Promise<boolean> {
|
|
166
230
|
return (
|
|
167
231
|
await Promise.all(
|
|
@@ -182,81 +246,156 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
182
246
|
}
|
|
183
247
|
|
|
184
248
|
/**
|
|
185
|
-
* Append new blocks to the store's list.
|
|
186
|
-
*
|
|
249
|
+
* Append new proposed blocks to the store's list.
|
|
250
|
+
* These are uncheckpointed blocks that have been proposed by the sequencer but not yet included in a checkpoint on L1.
|
|
251
|
+
* For checkpointed blocks (already published to L1), use addCheckpoints() instead.
|
|
252
|
+
* @param blocks - The proposed L2 blocks to be added to the store.
|
|
187
253
|
* @returns True if the operation is successful.
|
|
188
254
|
*/
|
|
189
|
-
|
|
190
|
-
return this.#blockStore.
|
|
255
|
+
addProposedBlocks(blocks: L2Block[], opts: { force?: boolean; checkpointNumber?: number } = {}): Promise<boolean> {
|
|
256
|
+
return this.#blockStore.addProposedBlocks(blocks, opts);
|
|
191
257
|
}
|
|
192
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Returns an array of checkpoint objects
|
|
261
|
+
* @param from The first checkpoint number to be retrieved
|
|
262
|
+
* @param limit The maximum number of checkpoints to retrieve
|
|
263
|
+
* @returns The array of requested checkpoint data objects
|
|
264
|
+
*/
|
|
193
265
|
getRangeOfCheckpoints(from: CheckpointNumber, limit: number): Promise<CheckpointData[]> {
|
|
194
266
|
return this.#blockStore.getRangeOfCheckpoints(from, limit);
|
|
195
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Returns the number of the latest block
|
|
270
|
+
* @returns The number of the latest block
|
|
271
|
+
*/
|
|
196
272
|
getLatestBlockNumber(): Promise<BlockNumber> {
|
|
197
273
|
return this.#blockStore.getLatestBlockNumber();
|
|
198
274
|
}
|
|
199
275
|
|
|
200
276
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
* @param checkpointsToUnwind - The number of checkpoints we are to unwind
|
|
205
|
-
* @returns True if the operation is successful
|
|
277
|
+
* Removes all checkpoints with checkpoint number > checkpointNumber.
|
|
278
|
+
* Also removes ALL blocks (both checkpointed and uncheckpointed) after the last block of the given checkpoint.
|
|
279
|
+
* @param checkpointNumber - Remove all checkpoints strictly after this one.
|
|
206
280
|
*/
|
|
207
|
-
|
|
208
|
-
return this.#blockStore.
|
|
281
|
+
removeCheckpointsAfter(checkpointNumber: CheckpointNumber): Promise<RemoveCheckpointsResult> {
|
|
282
|
+
return this.#blockStore.removeCheckpointsAfter(checkpointNumber);
|
|
209
283
|
}
|
|
210
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Appends new checkpoints, and their blocks to the store's collection
|
|
287
|
+
* @param checkpoints The collection of checkpoints to be added
|
|
288
|
+
* @returns True if the operation is successful
|
|
289
|
+
*/
|
|
211
290
|
addCheckpoints(checkpoints: PublishedCheckpoint[]): Promise<boolean> {
|
|
212
291
|
return this.#blockStore.addCheckpoints(checkpoints);
|
|
213
292
|
}
|
|
214
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Returns the block for the given number, or undefined if not exists.
|
|
296
|
+
* @param number - The block number to return.
|
|
297
|
+
*/
|
|
215
298
|
getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
|
|
216
299
|
return this.#blockStore.getCheckpointedBlock(number);
|
|
217
300
|
}
|
|
218
|
-
|
|
301
|
+
/**
|
|
302
|
+
* Returns the block for the given hash, or undefined if not exists.
|
|
303
|
+
* @param blockHash - The block hash to return.
|
|
304
|
+
*/
|
|
305
|
+
getCheckpointedBlockByHash(blockHash: BlockHash): Promise<CheckpointedL2Block | undefined> {
|
|
219
306
|
return this.#blockStore.getCheckpointedBlockByHash(blockHash);
|
|
220
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* Returns the block for the given archive root, or undefined if not exists.
|
|
310
|
+
* @param archive - The archive root to return.
|
|
311
|
+
*/
|
|
221
312
|
getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
|
|
222
313
|
return this.#blockStore.getCheckpointedBlockByArchive(archive);
|
|
223
314
|
}
|
|
224
|
-
|
|
315
|
+
/**
|
|
316
|
+
* Returns the block for the given number, or undefined if not exists.
|
|
317
|
+
* @param number - The block number to return.
|
|
318
|
+
*/
|
|
319
|
+
getBlock(number: BlockNumber): Promise<L2Block | undefined> {
|
|
225
320
|
return this.#blockStore.getBlock(number);
|
|
226
321
|
}
|
|
227
|
-
|
|
228
|
-
|
|
322
|
+
/**
|
|
323
|
+
* Returns the block for the given hash, or undefined if not exists.
|
|
324
|
+
* @param blockHash - The block hash to return.
|
|
325
|
+
*/
|
|
326
|
+
getBlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
|
|
327
|
+
return this.#blockStore.getBlockByHash(blockHash);
|
|
229
328
|
}
|
|
230
|
-
|
|
329
|
+
/**
|
|
330
|
+
* Returns the block for the given archive root, or undefined if not exists.
|
|
331
|
+
* @param archive - The archive root to return.
|
|
332
|
+
*/
|
|
333
|
+
getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
231
334
|
return this.#blockStore.getBlockByArchive(archive);
|
|
232
335
|
}
|
|
233
|
-
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Gets up to `limit` amount of published L2 blocks starting from `from`.
|
|
339
|
+
* @param from - Number of the first block to return (inclusive).
|
|
340
|
+
* @param limit - The number of blocks to return.
|
|
341
|
+
* @returns The requested L2 blocks.
|
|
342
|
+
*/
|
|
343
|
+
getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
234
344
|
return toArray(this.#blockStore.getBlocks(from, limit));
|
|
235
345
|
}
|
|
236
346
|
|
|
347
|
+
/**
|
|
348
|
+
* Gets up to `limit` amount of checkpointed L2 blocks starting from `from`.
|
|
349
|
+
* @param from - Number of the first block to return (inclusive).
|
|
350
|
+
* @param limit - The number of blocks to return.
|
|
351
|
+
* @returns The requested checkpointed L2 blocks.
|
|
352
|
+
*/
|
|
237
353
|
getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
|
|
238
354
|
return toArray(this.#blockStore.getCheckpointedBlocks(from, limit));
|
|
239
355
|
}
|
|
240
356
|
|
|
241
357
|
/**
|
|
242
|
-
* Gets up to `limit` amount of L2
|
|
243
|
-
*
|
|
358
|
+
* Gets up to `limit` amount of L2 block headers starting from `from`.
|
|
244
359
|
* @param start - Number of the first block to return (inclusive).
|
|
245
360
|
* @param limit - The number of blocks to return.
|
|
246
|
-
* @returns The requested L2
|
|
361
|
+
* @returns The requested L2 block headers.
|
|
247
362
|
*/
|
|
248
363
|
getBlockHeaders(start: BlockNumber, limit: number): Promise<BlockHeader[]> {
|
|
249
364
|
return toArray(this.#blockStore.getBlockHeaders(start, limit));
|
|
250
365
|
}
|
|
251
366
|
|
|
252
|
-
|
|
253
|
-
|
|
367
|
+
/**
|
|
368
|
+
* Returns the block header for the given hash, or undefined if not exists.
|
|
369
|
+
* @param blockHash - The block hash to return.
|
|
370
|
+
*/
|
|
371
|
+
getBlockHeaderByHash(blockHash: BlockHash): Promise<BlockHeader | undefined> {
|
|
372
|
+
return this.#blockStore.getBlockHeaderByHash(blockHash);
|
|
254
373
|
}
|
|
255
374
|
|
|
375
|
+
/**
|
|
376
|
+
* Returns the block header for the given archive root, or undefined if not exists.
|
|
377
|
+
* @param archive - The archive root to return.
|
|
378
|
+
*/
|
|
256
379
|
getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
|
|
257
380
|
return this.#blockStore.getBlockHeaderByArchive(archive);
|
|
258
381
|
}
|
|
259
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Gets block metadata (without tx data) by block number.
|
|
385
|
+
* @param blockNumber - The block number to return.
|
|
386
|
+
*/
|
|
387
|
+
getBlockData(blockNumber: BlockNumber): Promise<BlockData | undefined> {
|
|
388
|
+
return this.#blockStore.getBlockData(blockNumber);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Gets block metadata (without tx data) by archive root.
|
|
393
|
+
* @param archive - The archive root to return.
|
|
394
|
+
*/
|
|
395
|
+
getBlockDataByArchive(archive: Fr): Promise<BlockData | undefined> {
|
|
396
|
+
return this.#blockStore.getBlockDataByArchive(archive);
|
|
397
|
+
}
|
|
398
|
+
|
|
260
399
|
/**
|
|
261
400
|
* Gets a tx effect.
|
|
262
401
|
* @param txHash - The hash of the tx corresponding to the tx effect.
|
|
@@ -280,18 +419,23 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
280
419
|
* @param blocks - The blocks for which to add the logs.
|
|
281
420
|
* @returns True if the operation is successful.
|
|
282
421
|
*/
|
|
283
|
-
addLogs(blocks:
|
|
422
|
+
addLogs(blocks: L2Block[]): Promise<boolean> {
|
|
284
423
|
return this.#logStore.addLogs(blocks);
|
|
285
424
|
}
|
|
286
425
|
|
|
287
|
-
deleteLogs(blocks:
|
|
426
|
+
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
288
427
|
return this.#logStore.deleteLogs(blocks);
|
|
289
428
|
}
|
|
290
429
|
|
|
430
|
+
/**
|
|
431
|
+
* Get the total number of L1 to L2 messages
|
|
432
|
+
* @returns The number of L1 to L2 messages in the store
|
|
433
|
+
*/
|
|
291
434
|
getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
292
435
|
return this.#messageStore.getTotalL1ToL2MessageCount();
|
|
293
436
|
}
|
|
294
437
|
|
|
438
|
+
/** Returns the last L1 to L2 message stored. */
|
|
295
439
|
getLastL1ToL2Message(): Promise<InboxMessage | undefined> {
|
|
296
440
|
return this.#messageStore.getLastMessage();
|
|
297
441
|
}
|
|
@@ -299,6 +443,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
299
443
|
/**
|
|
300
444
|
* Append L1 to L2 messages to the store.
|
|
301
445
|
* @param messages - The L1 to L2 messages to be added to the store.
|
|
446
|
+
* @returns True if the operation is successful.
|
|
302
447
|
*/
|
|
303
448
|
addL1ToL2Messages(messages: InboxMessage[]): Promise<void> {
|
|
304
449
|
return this.#messageStore.addL1ToL2Messages(messages);
|
|
@@ -322,17 +467,34 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
322
467
|
return this.#messageStore.getL1ToL2Messages(checkpointNumber);
|
|
323
468
|
}
|
|
324
469
|
|
|
325
|
-
|
|
470
|
+
/**
|
|
471
|
+
* Gets private logs that match any of the `tags`. For each tag, an array of matching logs is returned. An empty
|
|
472
|
+
* array implies no logs match that tag.
|
|
473
|
+
* @param tags - The tags to search for.
|
|
474
|
+
* @param page - The page number (0-indexed) for pagination. Returns at most 10 logs per tag per page.
|
|
475
|
+
*/
|
|
476
|
+
getPrivateLogsByTags(tags: SiloedTag[], page?: number): Promise<TxScopedL2Log[][]> {
|
|
326
477
|
try {
|
|
327
|
-
return this.#logStore.getPrivateLogsByTags(tags);
|
|
478
|
+
return this.#logStore.getPrivateLogsByTags(tags, page);
|
|
328
479
|
} catch (err) {
|
|
329
480
|
return Promise.reject(err);
|
|
330
481
|
}
|
|
331
482
|
}
|
|
332
483
|
|
|
333
|
-
|
|
484
|
+
/**
|
|
485
|
+
* Gets public logs that match any of the `tags` from the specified contract. For each tag, an array of matching
|
|
486
|
+
* logs is returned. An empty array implies no logs match that tag.
|
|
487
|
+
* @param contractAddress - The contract address to search logs for.
|
|
488
|
+
* @param tags - The tags to search for.
|
|
489
|
+
* @param page - The page number (0-indexed) for pagination. Returns at most 10 logs per tag per page.
|
|
490
|
+
*/
|
|
491
|
+
getPublicLogsByTagsFromContract(
|
|
492
|
+
contractAddress: AztecAddress,
|
|
493
|
+
tags: Tag[],
|
|
494
|
+
page?: number,
|
|
495
|
+
): Promise<TxScopedL2Log[][]> {
|
|
334
496
|
try {
|
|
335
|
-
return this.#logStore.getPublicLogsByTagsFromContract(contractAddress, tags);
|
|
497
|
+
return this.#logStore.getPublicLogsByTagsFromContract(contractAddress, tags, page);
|
|
336
498
|
} catch (err) {
|
|
337
499
|
return Promise.reject(err);
|
|
338
500
|
}
|
|
@@ -364,10 +526,18 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
364
526
|
}
|
|
365
527
|
}
|
|
366
528
|
|
|
529
|
+
/**
|
|
530
|
+
* Gets the number of the latest proven checkpoint processed.
|
|
531
|
+
* @returns The number of the latest proven checkpoint processed.
|
|
532
|
+
*/
|
|
367
533
|
getProvenCheckpointNumber(): Promise<CheckpointNumber> {
|
|
368
534
|
return this.#blockStore.getProvenCheckpointNumber();
|
|
369
535
|
}
|
|
370
536
|
|
|
537
|
+
/**
|
|
538
|
+
* Stores the number of the latest proven checkpoint processed.
|
|
539
|
+
* @param checkpointNumber - The number of the latest proven checkpoint processed.
|
|
540
|
+
*/
|
|
371
541
|
async setProvenCheckpointNumber(checkpointNumber: CheckpointNumber) {
|
|
372
542
|
await this.#blockStore.setProvenCheckpointNumber(checkpointNumber);
|
|
373
543
|
}
|
|
@@ -376,16 +546,23 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
376
546
|
await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
|
|
377
547
|
}
|
|
378
548
|
|
|
549
|
+
/**
|
|
550
|
+
* Stores the l1 block that messages have been synched until
|
|
551
|
+
*/
|
|
379
552
|
async setMessageSynchedL1Block(l1Block: L1BlockId) {
|
|
380
553
|
await this.#messageStore.setSynchedL1Block(l1Block);
|
|
381
554
|
}
|
|
382
555
|
|
|
556
|
+
/**
|
|
557
|
+
* Returns the number of the most recent proven block
|
|
558
|
+
* @returns The number of the most recent proven block
|
|
559
|
+
*/
|
|
383
560
|
getProvenBlockNumber(): Promise<BlockNumber> {
|
|
384
561
|
return this.#blockStore.getProvenBlockNumber();
|
|
385
562
|
}
|
|
386
563
|
|
|
387
564
|
/**
|
|
388
|
-
* Gets the
|
|
565
|
+
* Gets the synch point of the archiver
|
|
389
566
|
*/
|
|
390
567
|
async getSynchPoint(): Promise<ArchiverL1SynchPoint> {
|
|
391
568
|
const [blocksSynchedTo, messagesSynchedTo] = await Promise.all([
|
|
@@ -398,45 +575,97 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
398
575
|
};
|
|
399
576
|
}
|
|
400
577
|
|
|
578
|
+
/** Estimates the size of the store in bytes. */
|
|
401
579
|
public estimateSize(): Promise<StoreSize> {
|
|
402
580
|
return this.db.estimateSize();
|
|
403
581
|
}
|
|
404
582
|
|
|
583
|
+
/** Deletes all L1 to L2 messages up until (excluding) the target checkpoint number. */
|
|
405
584
|
public rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber: CheckpointNumber): Promise<void> {
|
|
406
585
|
return this.#messageStore.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
|
|
407
586
|
}
|
|
408
587
|
|
|
588
|
+
/** Returns an async iterator to all L1 to L2 messages on the range. */
|
|
409
589
|
public iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
|
|
410
590
|
return this.#messageStore.iterateL1ToL2Messages(range);
|
|
411
591
|
}
|
|
412
592
|
|
|
593
|
+
/** Removes all L1 to L2 messages starting from the given index (inclusive). */
|
|
413
594
|
public removeL1ToL2Messages(startIndex: bigint): Promise<void> {
|
|
414
595
|
return this.#messageStore.removeL1ToL2Messages(startIndex);
|
|
415
596
|
}
|
|
416
597
|
|
|
598
|
+
/** Returns the last synced validation status of the pending chain. */
|
|
417
599
|
public getPendingChainValidationStatus(): Promise<ValidateCheckpointResult | undefined> {
|
|
418
600
|
return this.#blockStore.getPendingChainValidationStatus();
|
|
419
601
|
}
|
|
420
602
|
|
|
603
|
+
/** Sets the last synced validation status of the pending chain. */
|
|
421
604
|
public setPendingChainValidationStatus(status: ValidateCheckpointResult | undefined): Promise<void> {
|
|
422
605
|
return this.#blockStore.setPendingChainValidationStatus(status);
|
|
423
606
|
}
|
|
424
607
|
|
|
608
|
+
/**
|
|
609
|
+
* Gets the number of the latest L2 block processed.
|
|
610
|
+
* @returns The number of the latest L2 block processed.
|
|
611
|
+
*/
|
|
425
612
|
public getCheckpointedL2BlockNumber(): Promise<BlockNumber> {
|
|
426
613
|
return this.#blockStore.getCheckpointedL2BlockNumber();
|
|
427
614
|
}
|
|
615
|
+
/**
|
|
616
|
+
* Gets the number of the latest published checkpoint processed.
|
|
617
|
+
* @returns The number of the latest published checkpoint processed
|
|
618
|
+
*/
|
|
428
619
|
public getSynchedCheckpointNumber(): Promise<CheckpointNumber> {
|
|
429
620
|
return this.#blockStore.getLatestCheckpointNumber();
|
|
430
621
|
}
|
|
622
|
+
/**
|
|
623
|
+
* Stores the l1 block number that checkpoints have been synched until
|
|
624
|
+
* @param l1BlockNumber - The l1 block number
|
|
625
|
+
*/
|
|
431
626
|
async setCheckpointSynchedL1BlockNumber(l1BlockNumber: bigint): Promise<void> {
|
|
432
627
|
await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
|
|
433
628
|
}
|
|
434
629
|
|
|
435
|
-
|
|
630
|
+
/**
|
|
631
|
+
* Retrieves all blocks for the requested checkpoint
|
|
632
|
+
* @param checkpointNumber Retrieves all blocks for the given checkpoint
|
|
633
|
+
* @returns The collection of blocks for the requested checkpoint if available (undefined otherwise)
|
|
634
|
+
*/
|
|
635
|
+
getBlocksForCheckpoint(checkpointNumber: CheckpointNumber): Promise<L2Block[] | undefined> {
|
|
436
636
|
return this.#blockStore.getBlocksForCheckpoint(checkpointNumber);
|
|
437
637
|
}
|
|
438
638
|
|
|
639
|
+
/**
|
|
640
|
+
* Returns checkpoint data for the requested checkpoint number
|
|
641
|
+
* @param checkpointNumber - The checkpoint requested
|
|
642
|
+
* @returns The checkpoint data or undefined if not found
|
|
643
|
+
*/
|
|
439
644
|
getCheckpointData(checkpointNumber: CheckpointNumber): Promise<CheckpointData | undefined> {
|
|
440
645
|
return this.#blockStore.getCheckpointData(checkpointNumber);
|
|
441
646
|
}
|
|
647
|
+
|
|
648
|
+
/** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */
|
|
649
|
+
getCheckpointDataForSlotRange(startSlot: SlotNumber, endSlot: SlotNumber): Promise<CheckpointData[]> {
|
|
650
|
+
return this.#blockStore.getCheckpointDataForSlotRange(startSlot, endSlot);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Gets all blocks that have the given slot number.
|
|
655
|
+
* @param slotNumber - The slot number to search for.
|
|
656
|
+
* @returns All blocks with the given slot number.
|
|
657
|
+
*/
|
|
658
|
+
getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
|
|
659
|
+
return this.#blockStore.getBlocksForSlot(slotNumber);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Removes all blocks with block number > blockNumber.
|
|
664
|
+
* Does not remove any associated checkpoints.
|
|
665
|
+
* @param blockNumber - The block number to remove after.
|
|
666
|
+
* @returns The removed blocks (for event emission).
|
|
667
|
+
*/
|
|
668
|
+
removeBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
|
|
669
|
+
return this.#blockStore.removeBlocksAfter(blockNumber);
|
|
670
|
+
}
|
|
442
671
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { GENESIS_BLOCK_HEADER_HASH, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
|
+
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { type BlockData, type CheckpointId, GENESIS_CHECKPOINT_HEADER_HASH, type L2Tips } from '@aztec/stdlib/block';
|
|
4
|
+
|
|
5
|
+
import type { BlockStore } from './block_store.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* In-memory cache for L2 chain tips (proposed, checkpointed, proven, finalized).
|
|
9
|
+
* Populated from the BlockStore on first access, then kept up-to-date by the ArchiverDataStoreUpdater.
|
|
10
|
+
* Refresh calls should happen within the store transaction that mutates block data to ensure consistency.
|
|
11
|
+
*/
|
|
12
|
+
export class L2TipsCache {
|
|
13
|
+
#tipsPromise: Promise<L2Tips> | undefined;
|
|
14
|
+
|
|
15
|
+
constructor(private blockStore: BlockStore) {}
|
|
16
|
+
|
|
17
|
+
/** Returns the cached L2 tips. Loads from the block store on first call. */
|
|
18
|
+
public getL2Tips(): Promise<L2Tips> {
|
|
19
|
+
return (this.#tipsPromise ??= this.loadFromStore());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Reloads the L2 tips from the block store. Should be called within the store transaction that mutates data. */
|
|
23
|
+
public async refresh(): Promise<void> {
|
|
24
|
+
this.#tipsPromise = this.loadFromStore();
|
|
25
|
+
await this.#tipsPromise;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private async loadFromStore(): Promise<L2Tips> {
|
|
29
|
+
const [latestBlockNumber, provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber] = await Promise.all([
|
|
30
|
+
this.blockStore.getLatestBlockNumber(),
|
|
31
|
+
this.blockStore.getProvenBlockNumber(),
|
|
32
|
+
this.blockStore.getCheckpointedL2BlockNumber(),
|
|
33
|
+
this.blockStore.getFinalizedL2BlockNumber(),
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const genesisBlockHeader = {
|
|
37
|
+
blockHash: GENESIS_BLOCK_HEADER_HASH,
|
|
38
|
+
checkpointNumber: CheckpointNumber.ZERO,
|
|
39
|
+
} as const;
|
|
40
|
+
const beforeInitialBlockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
41
|
+
|
|
42
|
+
const getBlockData = (blockNumber: BlockNumber) =>
|
|
43
|
+
blockNumber > beforeInitialBlockNumber ? this.blockStore.getBlockData(blockNumber) : genesisBlockHeader;
|
|
44
|
+
|
|
45
|
+
const [latestBlockData, provenBlockData, checkpointedBlockData, finalizedBlockData] = await Promise.all(
|
|
46
|
+
[latestBlockNumber, provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber].map(getBlockData),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
if (!latestBlockData || !provenBlockData || !finalizedBlockData || !checkpointedBlockData) {
|
|
50
|
+
throw new Error('Failed to load block data for L2 tips');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const [provenCheckpointId, finalizedCheckpointId, checkpointedCheckpointId] = await Promise.all([
|
|
54
|
+
this.getCheckpointIdForBlock(provenBlockData),
|
|
55
|
+
this.getCheckpointIdForBlock(finalizedBlockData),
|
|
56
|
+
this.getCheckpointIdForBlock(checkpointedBlockData),
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
proposed: { number: latestBlockNumber, hash: latestBlockData.blockHash.toString() },
|
|
61
|
+
proven: {
|
|
62
|
+
block: { number: provenBlockNumber, hash: provenBlockData.blockHash.toString() },
|
|
63
|
+
checkpoint: provenCheckpointId,
|
|
64
|
+
},
|
|
65
|
+
finalized: {
|
|
66
|
+
block: { number: finalizedBlockNumber, hash: finalizedBlockData.blockHash.toString() },
|
|
67
|
+
checkpoint: finalizedCheckpointId,
|
|
68
|
+
},
|
|
69
|
+
checkpointed: {
|
|
70
|
+
block: { number: checkpointedBlockNumber, hash: checkpointedBlockData.blockHash.toString() },
|
|
71
|
+
checkpoint: checkpointedCheckpointId,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private async getCheckpointIdForBlock(blockData: Pick<BlockData, 'checkpointNumber'>): Promise<CheckpointId> {
|
|
77
|
+
const checkpointData = await this.blockStore.getCheckpointData(blockData.checkpointNumber);
|
|
78
|
+
if (!checkpointData) {
|
|
79
|
+
return {
|
|
80
|
+
number: CheckpointNumber.ZERO,
|
|
81
|
+
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
number: checkpointData.checkpointNumber,
|
|
86
|
+
hash: checkpointData.header.hash().toString(),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|