@aztec/archiver 0.0.1-commit.e588bc7e5 → 0.0.1-commit.e5a3663dd
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 +19 -11
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +96 -53
- package/dest/config.d.ts +3 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +14 -3
- package/dest/errors.d.ts +32 -5
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +51 -6
- package/dest/factory.d.ts +4 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +13 -10
- package/dest/index.d.ts +10 -3
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +9 -2
- package/dest/l1/calldata_retriever.d.ts +2 -1
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +9 -4
- package/dest/l1/data_retrieval.d.ts +18 -9
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +13 -19
- package/dest/l1/validate_historical_logs.d.ts +23 -0
- package/dest/l1/validate_historical_logs.d.ts.map +1 -0
- package/dest/l1/validate_historical_logs.js +108 -0
- package/dest/modules/contract_data_source_adapter.d.ts +25 -0
- package/dest/modules/contract_data_source_adapter.d.ts.map +1 -0
- package/dest/modules/contract_data_source_adapter.js +42 -0
- package/dest/modules/data_source_base.d.ts +16 -10
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +71 -60
- package/dest/modules/data_store_updater.d.ts +16 -9
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +52 -40
- package/dest/modules/instrumentation.d.ts +7 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +22 -6
- package/dest/modules/l1_synchronizer.d.ts +8 -4
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +212 -79
- package/dest/modules/validation.d.ts +4 -3
- package/dest/modules/validation.d.ts.map +1 -1
- package/dest/modules/validation.js +4 -4
- package/dest/store/block_store.d.ts +60 -21
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +229 -70
- package/dest/store/contract_class_store.d.ts +17 -3
- package/dest/store/contract_class_store.d.ts.map +1 -1
- package/dest/store/contract_class_store.js +17 -1
- package/dest/store/contract_instance_store.d.ts +28 -1
- package/dest/store/contract_instance_store.d.ts.map +1 -1
- package/dest/store/contract_instance_store.js +31 -0
- package/dest/store/data_stores.d.ts +68 -0
- package/dest/store/data_stores.d.ts.map +1 -0
- package/dest/store/data_stores.js +50 -0
- package/dest/store/function_names_cache.d.ts +17 -0
- package/dest/store/function_names_cache.d.ts.map +1 -0
- package/dest/store/function_names_cache.js +30 -0
- package/dest/store/l2_tips_cache.d.ts +1 -1
- package/dest/store/l2_tips_cache.d.ts.map +1 -1
- package/dest/store/l2_tips_cache.js +3 -3
- 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 +2 -4
- package/dest/store/message_store.d.ts +9 -3
- package/dest/store/message_store.d.ts.map +1 -1
- package/dest/store/message_store.js +31 -1
- package/dest/test/fake_l1_state.d.ts +14 -3
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +55 -15
- package/dest/test/mock_l2_block_source.d.ts +12 -3
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +24 -2
- package/dest/test/noop_l1_archiver.d.ts +4 -4
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +9 -7
- package/package.json +13 -13
- package/src/archiver.ts +113 -52
- package/src/config.ts +15 -1
- package/src/errors.ts +75 -8
- package/src/factory.ts +11 -10
- package/src/index.ts +17 -2
- package/src/l1/calldata_retriever.ts +15 -4
- package/src/l1/data_retrieval.ts +30 -35
- package/src/l1/validate_historical_logs.ts +140 -0
- package/src/modules/contract_data_source_adapter.ts +59 -0
- package/src/modules/data_source_base.ts +75 -57
- package/src/modules/data_store_updater.ts +71 -39
- package/src/modules/instrumentation.ts +27 -7
- package/src/modules/l1_synchronizer.ts +301 -83
- package/src/modules/validation.ts +8 -7
- package/src/store/block_store.ts +264 -77
- package/src/store/contract_class_store.ts +28 -2
- package/src/store/contract_instance_store.ts +43 -0
- package/src/store/data_stores.ts +108 -0
- package/src/store/function_names_cache.ts +37 -0
- package/src/store/l2_tips_cache.ts +9 -3
- package/src/store/log_store.ts +2 -5
- package/src/store/message_store.ts +35 -2
- package/src/test/fake_l1_state.ts +62 -24
- package/src/test/mock_l2_block_source.ts +23 -2
- package/src/test/noop_l1_archiver.ts +9 -7
- package/dest/store/kv_archiver_store.d.ts +0 -377
- package/dest/store/kv_archiver_store.d.ts.map +0 -1
- package/dest/store/kv_archiver_store.js +0 -494
- package/src/store/kv_archiver_store.ts +0 -713
|
@@ -24,19 +24,19 @@ import type { BlockHeader, IndexedTxEffect, TxHash, TxReceipt } from '@aztec/std
|
|
|
24
24
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
25
25
|
|
|
26
26
|
import type { ArchiverDataSource } from '../interfaces.js';
|
|
27
|
-
import type {
|
|
27
|
+
import type { ArchiverDataStores } from '../store/data_stores.js';
|
|
28
28
|
import type { ValidateCheckpointResult } from './validation.js';
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* Abstract base class implementing ArchiverDataSource using a
|
|
32
|
-
* Provides implementations for all
|
|
33
|
-
*
|
|
31
|
+
* Abstract base class implementing ArchiverDataSource using a bundle of archiver substores.
|
|
32
|
+
* Provides implementations for all read-side methods and declares abstract methods for
|
|
33
|
+
* L1-dependent functionality that subclasses must implement.
|
|
34
34
|
*/
|
|
35
35
|
export abstract class ArchiverDataSourceBase
|
|
36
36
|
implements ArchiverDataSource, L2LogsSource, ContractDataSource, L1ToL2MessageSource
|
|
37
37
|
{
|
|
38
38
|
constructor(
|
|
39
|
-
protected readonly
|
|
39
|
+
protected readonly stores: ArchiverDataStores,
|
|
40
40
|
protected readonly l1Constants?: L1RollupConstants,
|
|
41
41
|
) {}
|
|
42
42
|
|
|
@@ -61,54 +61,54 @@ export abstract class ArchiverDataSourceBase
|
|
|
61
61
|
abstract syncImmediate(): Promise<void>;
|
|
62
62
|
|
|
63
63
|
public getCheckpointNumber(): Promise<CheckpointNumber> {
|
|
64
|
-
return this.
|
|
64
|
+
return this.stores.blocks.getLatestCheckpointNumber();
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
public getSynchedCheckpointNumber(): Promise<CheckpointNumber> {
|
|
68
|
-
return this.
|
|
68
|
+
return this.stores.blocks.getLatestCheckpointNumber();
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
public getProvenCheckpointNumber(): Promise<CheckpointNumber> {
|
|
72
|
-
return this.
|
|
72
|
+
return this.stores.blocks.getProvenCheckpointNumber();
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
public getBlockNumber(): Promise<BlockNumber> {
|
|
76
|
-
return this.
|
|
76
|
+
return this.stores.blocks.getLatestL2BlockNumber();
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
public getProvenBlockNumber(): Promise<BlockNumber> {
|
|
80
|
-
return this.
|
|
80
|
+
return this.stores.blocks.getProvenBlockNumber();
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
public async getBlockHeader(number: BlockNumber | 'latest'): Promise<BlockHeader | undefined> {
|
|
84
|
-
const blockNumber = number === 'latest' ? await this.
|
|
84
|
+
const blockNumber = number === 'latest' ? await this.stores.blocks.getLatestL2BlockNumber() : number;
|
|
85
85
|
if (blockNumber === 0) {
|
|
86
86
|
return undefined;
|
|
87
87
|
}
|
|
88
|
-
const headers = await this.
|
|
88
|
+
const headers = await this.stores.blocks.getBlockHeaders(blockNumber, 1);
|
|
89
89
|
return headers.length === 0 ? undefined : headers[0];
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
public getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
|
|
93
|
-
return this.
|
|
93
|
+
return this.stores.blocks.getCheckpointedBlock(number);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
public getCheckpointedL2BlockNumber(): Promise<BlockNumber> {
|
|
97
|
-
return this.
|
|
97
|
+
return this.stores.blocks.getCheckpointedL2BlockNumber();
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
public getFinalizedL2BlockNumber(): Promise<BlockNumber> {
|
|
101
|
-
return this.
|
|
101
|
+
return this.stores.blocks.getFinalizedL2BlockNumber();
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
public async getCheckpointHeader(number: CheckpointNumber | 'latest'): Promise<CheckpointHeader | undefined> {
|
|
105
105
|
if (number === 'latest') {
|
|
106
|
-
number = await this.
|
|
106
|
+
number = await this.stores.blocks.getLatestCheckpointNumber();
|
|
107
107
|
}
|
|
108
108
|
if (number === 0) {
|
|
109
109
|
return undefined;
|
|
110
110
|
}
|
|
111
|
-
const checkpoint = await this.
|
|
111
|
+
const checkpoint = await this.stores.blocks.getCheckpointData(number);
|
|
112
112
|
if (!checkpoint) {
|
|
113
113
|
return undefined;
|
|
114
114
|
}
|
|
@@ -116,7 +116,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
public async getLastBlockNumberInCheckpoint(checkpointNumber: CheckpointNumber): Promise<BlockNumber | undefined> {
|
|
119
|
-
const checkpointData = await this.
|
|
119
|
+
const checkpointData = await this.stores.blocks.getCheckpointData(checkpointNumber);
|
|
120
120
|
if (!checkpointData) {
|
|
121
121
|
return undefined;
|
|
122
122
|
}
|
|
@@ -124,51 +124,66 @@ export abstract class ArchiverDataSourceBase
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
public getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
|
|
127
|
-
return this.
|
|
127
|
+
return this.stores.blocks.getCheckpointedBlocks(from, limit);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public getCheckpointData(checkpointNumber: CheckpointNumber): Promise<CheckpointData | undefined> {
|
|
131
|
+
return this.stores.blocks.getCheckpointData(checkpointNumber);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public getCheckpointDataRange(from: CheckpointNumber, limit: number): Promise<CheckpointData[]> {
|
|
135
|
+
return this.stores.blocks.getRangeOfCheckpoints(from, limit);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public getCheckpointNumberBySlot(slot: SlotNumber): Promise<CheckpointNumber | undefined> {
|
|
139
|
+
return this.stores.blocks.getCheckpointNumberBySlot(slot);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public getBlockDataWithCheckpointContext(blockNumber: BlockNumber) {
|
|
143
|
+
return this.stores.blocks.getBlockDataWithCheckpointContext(blockNumber);
|
|
128
144
|
}
|
|
129
145
|
|
|
130
146
|
public getBlockHeaderByHash(blockHash: BlockHash): Promise<BlockHeader | undefined> {
|
|
131
|
-
return this.
|
|
147
|
+
return this.stores.blocks.getBlockHeaderByHash(blockHash);
|
|
132
148
|
}
|
|
133
149
|
|
|
134
150
|
public getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
|
|
135
|
-
return this.
|
|
151
|
+
return this.stores.blocks.getBlockHeaderByArchive(archive);
|
|
136
152
|
}
|
|
137
153
|
|
|
138
154
|
public getBlockData(number: BlockNumber): Promise<BlockData | undefined> {
|
|
139
|
-
return this.
|
|
155
|
+
return this.stores.blocks.getBlockData(number);
|
|
140
156
|
}
|
|
141
157
|
|
|
142
158
|
public getBlockDataByArchive(archive: Fr): Promise<BlockData | undefined> {
|
|
143
|
-
return this.
|
|
159
|
+
return this.stores.blocks.getBlockDataByArchive(archive);
|
|
144
160
|
}
|
|
145
161
|
|
|
146
162
|
public async getL2Block(number: BlockNumber): Promise<L2Block | undefined> {
|
|
147
163
|
// If the number provided is -ve, then return the latest block.
|
|
148
164
|
if (number < 0) {
|
|
149
|
-
number = await this.
|
|
165
|
+
number = await this.stores.blocks.getLatestL2BlockNumber();
|
|
150
166
|
}
|
|
151
167
|
if (number === 0) {
|
|
152
168
|
return undefined;
|
|
153
169
|
}
|
|
154
|
-
|
|
155
|
-
return publishedBlock;
|
|
170
|
+
return this.stores.blocks.getBlock(number);
|
|
156
171
|
}
|
|
157
172
|
|
|
158
173
|
public getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined> {
|
|
159
|
-
return this.
|
|
174
|
+
return this.stores.blocks.getTxEffect(txHash);
|
|
160
175
|
}
|
|
161
176
|
|
|
162
177
|
public getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined> {
|
|
163
|
-
return this.
|
|
178
|
+
return this.stores.blocks.getSettledTxReceipt(txHash, this.l1Constants);
|
|
164
179
|
}
|
|
165
180
|
|
|
166
|
-
public
|
|
167
|
-
return this.
|
|
181
|
+
public getLastCheckpoint(): Promise<CommonCheckpointData | undefined> {
|
|
182
|
+
return this.stores.blocks.getLastCheckpoint();
|
|
168
183
|
}
|
|
169
184
|
|
|
170
|
-
public
|
|
171
|
-
return this.
|
|
185
|
+
public getLastProposedCheckpoint(): Promise<ProposedCheckpointData | undefined> {
|
|
186
|
+
return this.stores.blocks.getLastProposedCheckpoint();
|
|
172
187
|
}
|
|
173
188
|
|
|
174
189
|
public isPendingChainInvalid(): Promise<boolean> {
|
|
@@ -176,7 +191,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
176
191
|
}
|
|
177
192
|
|
|
178
193
|
public async getPendingChainValidationStatus(): Promise<ValidateCheckpointResult> {
|
|
179
|
-
return (await this.
|
|
194
|
+
return (await this.stores.blocks.getPendingChainValidationStatus()) ?? { valid: true };
|
|
180
195
|
}
|
|
181
196
|
|
|
182
197
|
public getPrivateLogsByTags(
|
|
@@ -184,7 +199,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
184
199
|
page?: number,
|
|
185
200
|
upToBlockNumber?: BlockNumber,
|
|
186
201
|
): Promise<TxScopedL2Log[][]> {
|
|
187
|
-
return this.
|
|
202
|
+
return this.stores.logs.getPrivateLogsByTags(tags, page, upToBlockNumber);
|
|
188
203
|
}
|
|
189
204
|
|
|
190
205
|
public getPublicLogsByTagsFromContract(
|
|
@@ -193,23 +208,23 @@ export abstract class ArchiverDataSourceBase
|
|
|
193
208
|
page?: number,
|
|
194
209
|
upToBlockNumber?: BlockNumber,
|
|
195
210
|
): Promise<TxScopedL2Log[][]> {
|
|
196
|
-
return this.
|
|
211
|
+
return this.stores.logs.getPublicLogsByTagsFromContract(contractAddress, tags, page, upToBlockNumber);
|
|
197
212
|
}
|
|
198
213
|
|
|
199
214
|
public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
|
|
200
|
-
return this.
|
|
215
|
+
return this.stores.logs.getPublicLogs(filter);
|
|
201
216
|
}
|
|
202
217
|
|
|
203
218
|
public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
|
|
204
|
-
return this.
|
|
219
|
+
return this.stores.logs.getContractClassLogs(filter);
|
|
205
220
|
}
|
|
206
221
|
|
|
207
222
|
public getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
|
|
208
|
-
return this.
|
|
223
|
+
return this.stores.contractClasses.getContractClass(id);
|
|
209
224
|
}
|
|
210
225
|
|
|
211
226
|
public getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
|
|
212
|
-
return this.
|
|
227
|
+
return this.stores.contractClasses.getBytecodeCommitment(id);
|
|
213
228
|
}
|
|
214
229
|
|
|
215
230
|
public async getContract(
|
|
@@ -225,36 +240,38 @@ export abstract class ArchiverDataSourceBase
|
|
|
225
240
|
timestamp = maybeTimestamp;
|
|
226
241
|
}
|
|
227
242
|
|
|
228
|
-
return this.
|
|
243
|
+
return this.stores.contractInstances.getContractInstance(address, timestamp);
|
|
229
244
|
}
|
|
230
245
|
|
|
231
246
|
public getContractClassIds(): Promise<Fr[]> {
|
|
232
|
-
return this.
|
|
247
|
+
return this.stores.contractClasses.getContractClassIds();
|
|
233
248
|
}
|
|
234
249
|
|
|
235
|
-
|
|
236
|
-
|
|
250
|
+
/** Looks up a public function name given a selector. */
|
|
251
|
+
public getDebugFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
|
|
252
|
+
return Promise.resolve(this.stores.functionNames.get(selector));
|
|
237
253
|
}
|
|
238
254
|
|
|
255
|
+
/** Register public function signatures so they can be looked up by selector. */
|
|
239
256
|
public registerContractFunctionSignatures(signatures: string[]): Promise<void> {
|
|
240
|
-
return this.
|
|
257
|
+
return this.stores.functionNames.register(signatures);
|
|
241
258
|
}
|
|
242
259
|
|
|
243
260
|
public getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
|
|
244
|
-
return this.
|
|
261
|
+
return this.stores.messages.getL1ToL2Messages(checkpointNumber);
|
|
245
262
|
}
|
|
246
263
|
|
|
247
264
|
public getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined> {
|
|
248
|
-
return this.
|
|
265
|
+
return this.stores.messages.getL1ToL2MessageIndex(l1ToL2Message);
|
|
249
266
|
}
|
|
250
267
|
|
|
251
268
|
public async getCheckpoints(checkpointNumber: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
|
|
252
|
-
const checkpoints = await this.
|
|
269
|
+
const checkpoints = await this.stores.blocks.getRangeOfCheckpoints(checkpointNumber, limit);
|
|
253
270
|
return Promise.all(checkpoints.map(ch => this.getPublishedCheckpointFromCheckpointData(ch)));
|
|
254
271
|
}
|
|
255
272
|
|
|
256
273
|
private async getPublishedCheckpointFromCheckpointData(checkpoint: CheckpointData): Promise<PublishedCheckpoint> {
|
|
257
|
-
const blocksForCheckpoint = await this.
|
|
274
|
+
const blocksForCheckpoint = await this.stores.blocks.getBlocksForCheckpoint(checkpoint.checkpointNumber);
|
|
258
275
|
if (!blocksForCheckpoint) {
|
|
259
276
|
throw new Error(`Blocks for checkpoint ${checkpoint.checkpointNumber} not found`);
|
|
260
277
|
}
|
|
@@ -263,12 +280,13 @@ export abstract class ArchiverDataSourceBase
|
|
|
263
280
|
checkpoint.header,
|
|
264
281
|
blocksForCheckpoint,
|
|
265
282
|
checkpoint.checkpointNumber,
|
|
283
|
+
checkpoint.feeAssetPriceModifier,
|
|
266
284
|
);
|
|
267
285
|
return new PublishedCheckpoint(fullCheckpoint, checkpoint.l1, checkpoint.attestations);
|
|
268
286
|
}
|
|
269
287
|
|
|
270
288
|
public getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
|
|
271
|
-
return this.
|
|
289
|
+
return this.stores.blocks.getBlocksForSlot(slotNumber);
|
|
272
290
|
}
|
|
273
291
|
|
|
274
292
|
public async getCheckpointedBlocksForEpoch(epochNumber: EpochNumber): Promise<CheckpointedL2Block[]> {
|
|
@@ -309,39 +327,39 @@ export abstract class ArchiverDataSourceBase
|
|
|
309
327
|
}
|
|
310
328
|
|
|
311
329
|
const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
|
|
312
|
-
return this.
|
|
330
|
+
return this.stores.blocks.getCheckpointDataForSlotRange(start, end);
|
|
313
331
|
}
|
|
314
332
|
|
|
315
333
|
public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
|
|
316
334
|
// If the number provided is -ve, then return the latest block.
|
|
317
335
|
if (number < 0) {
|
|
318
|
-
number = await this.
|
|
336
|
+
number = await this.stores.blocks.getLatestL2BlockNumber();
|
|
319
337
|
}
|
|
320
338
|
if (number === 0) {
|
|
321
339
|
return undefined;
|
|
322
340
|
}
|
|
323
|
-
return this.
|
|
341
|
+
return this.stores.blocks.getBlock(number);
|
|
324
342
|
}
|
|
325
343
|
|
|
326
344
|
public getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
327
|
-
return this.
|
|
345
|
+
return this.stores.blocks.getBlocks(from, limit);
|
|
328
346
|
}
|
|
329
347
|
|
|
330
348
|
public getCheckpointedBlockByHash(blockHash: BlockHash): Promise<CheckpointedL2Block | undefined> {
|
|
331
|
-
return this.
|
|
349
|
+
return this.stores.blocks.getCheckpointedBlockByHash(blockHash);
|
|
332
350
|
}
|
|
333
351
|
|
|
334
352
|
public getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
|
|
335
|
-
return this.
|
|
353
|
+
return this.stores.blocks.getCheckpointedBlockByArchive(archive);
|
|
336
354
|
}
|
|
337
355
|
|
|
338
356
|
public async getL2BlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
|
|
339
|
-
const checkpointedBlock = await this.
|
|
357
|
+
const checkpointedBlock = await this.stores.blocks.getCheckpointedBlockByHash(blockHash);
|
|
340
358
|
return checkpointedBlock?.block;
|
|
341
359
|
}
|
|
342
360
|
|
|
343
361
|
public async getL2BlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
344
|
-
const checkpointedBlock = await this.
|
|
362
|
+
const checkpointedBlock = await this.stores.blocks.getCheckpointedBlockByArchive(archive);
|
|
345
363
|
return checkpointedBlock?.block;
|
|
346
364
|
}
|
|
347
365
|
}
|
|
@@ -6,8 +6,13 @@ import {
|
|
|
6
6
|
ContractInstancePublishedEvent,
|
|
7
7
|
ContractInstanceUpdatedEvent,
|
|
8
8
|
} from '@aztec/protocol-contracts/instance-registry';
|
|
9
|
-
import type { L2Block, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
10
|
-
import {
|
|
9
|
+
import type { CommitteeAttestation, L2Block, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
10
|
+
import {
|
|
11
|
+
type L1PublishedData,
|
|
12
|
+
type ProposedCheckpointInput,
|
|
13
|
+
type PublishedCheckpoint,
|
|
14
|
+
validateCheckpoint,
|
|
15
|
+
} from '@aztec/stdlib/checkpoint';
|
|
11
16
|
import {
|
|
12
17
|
type ContractClassPublicWithCommitment,
|
|
13
18
|
computeContractAddressFromInstance,
|
|
@@ -16,7 +21,7 @@ import {
|
|
|
16
21
|
import type { ContractClassLog, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
17
22
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
18
23
|
|
|
19
|
-
import type {
|
|
24
|
+
import type { ArchiverDataStores } from '../store/data_stores.js';
|
|
20
25
|
import type { L2TipsCache } from '../store/l2_tips_cache.js';
|
|
21
26
|
|
|
22
27
|
/** Operation type for contract data updates. */
|
|
@@ -38,7 +43,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
38
43
|
private readonly log = createLogger('archiver:store_updater');
|
|
39
44
|
|
|
40
45
|
constructor(
|
|
41
|
-
private
|
|
46
|
+
private stores: ArchiverDataStores,
|
|
42
47
|
private l2TipsCache?: L2TipsCache,
|
|
43
48
|
private opts: { rollupManaLimit?: number } = {},
|
|
44
49
|
) {}
|
|
@@ -56,14 +61,15 @@ export class ArchiverDataStoreUpdater {
|
|
|
56
61
|
block: L2Block,
|
|
57
62
|
pendingChainValidationStatus?: ValidateCheckpointResult,
|
|
58
63
|
): Promise<boolean> {
|
|
59
|
-
const result = await this.
|
|
60
|
-
await this.
|
|
64
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
65
|
+
await this.stores.blocks.addProposedBlock(block);
|
|
61
66
|
|
|
62
67
|
const opResults = await Promise.all([
|
|
63
68
|
// Update the pending chain validation status if provided
|
|
64
|
-
pendingChainValidationStatus &&
|
|
69
|
+
pendingChainValidationStatus &&
|
|
70
|
+
this.stores.blocks.setPendingChainValidationStatus(pendingChainValidationStatus),
|
|
65
71
|
// Add any logs emitted during the retrieved block
|
|
66
|
-
this.
|
|
72
|
+
this.stores.logs.addLogs([block]),
|
|
67
73
|
// Unroll all logs emitted during the retrieved block and extract any contract classes and instances from it
|
|
68
74
|
this.addContractDataToDb(block),
|
|
69
75
|
]);
|
|
@@ -79,24 +85,36 @@ export class ArchiverDataStoreUpdater {
|
|
|
79
85
|
* Adds new checkpoints to the store with contract class/instance extraction from logs.
|
|
80
86
|
* Prunes any local blocks that conflict with checkpoint data (by comparing archive roots).
|
|
81
87
|
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events from the checkpoint block logs.
|
|
88
|
+
* If `promoteProposed` is supplied, the proposed-checkpoint promotion runs inside the same transaction
|
|
89
|
+
* as the added checkpoints so both updates are applied atomically.
|
|
82
90
|
*
|
|
83
|
-
* @param checkpoints - The published checkpoints to add.
|
|
91
|
+
* @param checkpoints - The published checkpoints to add (excluding any being promoted from proposed).
|
|
84
92
|
* @param pendingChainValidationStatus - Optional validation status to set.
|
|
93
|
+
* @param promoteProposed - Optional promotion of the current proposed checkpoint (fast path when blocks are already local).
|
|
85
94
|
* @returns Result with information about any pruned blocks.
|
|
86
95
|
*/
|
|
87
96
|
public async addCheckpoints(
|
|
88
97
|
checkpoints: PublishedCheckpoint[],
|
|
89
98
|
pendingChainValidationStatus?: ValidateCheckpointResult,
|
|
99
|
+
promoteProposed?: {
|
|
100
|
+
l1: L1PublishedData;
|
|
101
|
+
attestations: CommitteeAttestation[];
|
|
102
|
+
checkpoint: PublishedCheckpoint;
|
|
103
|
+
},
|
|
104
|
+
evictProposedFrom?: CheckpointNumber,
|
|
90
105
|
): Promise<ReconcileCheckpointsResult> {
|
|
91
106
|
for (const checkpoint of checkpoints) {
|
|
92
107
|
validateCheckpoint(checkpoint.checkpoint, { rollupManaLimit: this.opts?.rollupManaLimit });
|
|
93
108
|
}
|
|
109
|
+
if (promoteProposed) {
|
|
110
|
+
validateCheckpoint(promoteProposed.checkpoint.checkpoint, { rollupManaLimit: this.opts?.rollupManaLimit });
|
|
111
|
+
}
|
|
94
112
|
|
|
95
|
-
const result = await this.
|
|
113
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
96
114
|
// Before adding checkpoints, check for conflicts with local blocks if any
|
|
97
115
|
const { prunedBlocks, lastAlreadyInsertedBlockNumber } = await this.pruneMismatchingLocalBlocks(checkpoints);
|
|
98
116
|
|
|
99
|
-
await this.
|
|
117
|
+
await this.stores.blocks.addCheckpoints(checkpoints);
|
|
100
118
|
|
|
101
119
|
// Filter out blocks that were already inserted via addProposedBlock() to avoid duplicating logs/contract data
|
|
102
120
|
const newBlocks = checkpoints
|
|
@@ -105,11 +123,25 @@ export class ArchiverDataStoreUpdater {
|
|
|
105
123
|
|
|
106
124
|
await Promise.all([
|
|
107
125
|
// Update the pending chain validation status if provided
|
|
108
|
-
pendingChainValidationStatus &&
|
|
126
|
+
pendingChainValidationStatus &&
|
|
127
|
+
this.stores.blocks.setPendingChainValidationStatus(pendingChainValidationStatus),
|
|
109
128
|
// Add any logs emitted during the retrieved blocks
|
|
110
|
-
this.
|
|
129
|
+
this.stores.logs.addLogs(newBlocks),
|
|
111
130
|
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
112
131
|
...newBlocks.map(block => this.addContractDataToDb(block)),
|
|
132
|
+
// Promote the proposed checkpoint if requested (uses explicit checkpoint number)
|
|
133
|
+
promoteProposed
|
|
134
|
+
? this.stores.blocks.promoteProposedToCheckpointed(
|
|
135
|
+
promoteProposed.checkpoint.checkpoint.number,
|
|
136
|
+
promoteProposed.l1,
|
|
137
|
+
promoteProposed.attestations,
|
|
138
|
+
promoteProposed.checkpoint.checkpoint.archive.root,
|
|
139
|
+
)
|
|
140
|
+
: undefined,
|
|
141
|
+
// Evict pending checkpoints that diverged from what L1 mined
|
|
142
|
+
evictProposedFrom !== undefined
|
|
143
|
+
? this.stores.blocks.evictProposedCheckpointsFrom(evictProposedFrom)
|
|
144
|
+
: undefined,
|
|
113
145
|
]);
|
|
114
146
|
|
|
115
147
|
await this.l2TipsCache?.refresh();
|
|
@@ -118,9 +150,9 @@ export class ArchiverDataStoreUpdater {
|
|
|
118
150
|
return result;
|
|
119
151
|
}
|
|
120
152
|
|
|
121
|
-
public async
|
|
122
|
-
const result = await this.
|
|
123
|
-
await this.
|
|
153
|
+
public async addProposedCheckpoint(proposedCheckpoint: ProposedCheckpointInput) {
|
|
154
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
155
|
+
await this.stores.blocks.addProposedCheckpoint(proposedCheckpoint);
|
|
124
156
|
await this.l2TipsCache?.refresh();
|
|
125
157
|
});
|
|
126
158
|
|
|
@@ -135,8 +167,8 @@ export class ArchiverDataStoreUpdater {
|
|
|
135
167
|
*/
|
|
136
168
|
private async pruneMismatchingLocalBlocks(checkpoints: PublishedCheckpoint[]): Promise<ReconcileCheckpointsResult> {
|
|
137
169
|
const [lastCheckpointedBlockNumber, lastBlockNumber] = await Promise.all([
|
|
138
|
-
this.
|
|
139
|
-
this.
|
|
170
|
+
this.stores.blocks.getCheckpointedL2BlockNumber(),
|
|
171
|
+
this.stores.blocks.getLatestL2BlockNumber(),
|
|
140
172
|
]);
|
|
141
173
|
|
|
142
174
|
// Exit early if there are no local uncheckpointed blocks
|
|
@@ -145,7 +177,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
145
177
|
}
|
|
146
178
|
|
|
147
179
|
// Get all uncheckpointed local blocks
|
|
148
|
-
const uncheckpointedLocalBlocks = await this.
|
|
180
|
+
const uncheckpointedLocalBlocks = await this.stores.blocks.getBlocks(
|
|
149
181
|
BlockNumber.add(lastCheckpointedBlockNumber, 1),
|
|
150
182
|
lastBlockNumber - lastCheckpointedBlockNumber,
|
|
151
183
|
);
|
|
@@ -210,9 +242,9 @@ export class ArchiverDataStoreUpdater {
|
|
|
210
242
|
* @throws Error if any block to be removed is checkpointed.
|
|
211
243
|
*/
|
|
212
244
|
public async removeUncheckpointedBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
|
|
213
|
-
const result = await this.
|
|
245
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
214
246
|
// Verify we're only removing uncheckpointed blocks
|
|
215
|
-
const lastCheckpointedBlockNumber = await this.
|
|
247
|
+
const lastCheckpointedBlockNumber = await this.stores.blocks.getCheckpointedL2BlockNumber();
|
|
216
248
|
if (blockNumber < lastCheckpointedBlockNumber) {
|
|
217
249
|
throw new Error(
|
|
218
250
|
`Cannot remove blocks after ${blockNumber} because checkpointed blocks exist up to ${lastCheckpointedBlockNumber}`,
|
|
@@ -221,8 +253,8 @@ export class ArchiverDataStoreUpdater {
|
|
|
221
253
|
|
|
222
254
|
const result = await this.removeBlocksAfter(blockNumber);
|
|
223
255
|
|
|
224
|
-
// Clear
|
|
225
|
-
await this.
|
|
256
|
+
// Clear all pending proposed checkpoints since their blocks have been pruned
|
|
257
|
+
await this.stores.blocks.deleteProposedCheckpoints();
|
|
226
258
|
|
|
227
259
|
await this.l2TipsCache?.refresh();
|
|
228
260
|
return result;
|
|
@@ -236,11 +268,11 @@ export class ArchiverDataStoreUpdater {
|
|
|
236
268
|
*/
|
|
237
269
|
private async removeBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
|
|
238
270
|
// First get the blocks to be removed so we can clean up contract data
|
|
239
|
-
const removedBlocks = await this.
|
|
271
|
+
const removedBlocks = await this.stores.blocks.removeBlocksAfter(blockNumber);
|
|
240
272
|
|
|
241
273
|
// Clean up contract data and logs for the removed blocks
|
|
242
274
|
await Promise.all([
|
|
243
|
-
this.
|
|
275
|
+
this.stores.logs.deleteLogs(removedBlocks),
|
|
244
276
|
...removedBlocks.map(block => this.removeContractDataFromDb(block)),
|
|
245
277
|
]);
|
|
246
278
|
|
|
@@ -257,15 +289,15 @@ export class ArchiverDataStoreUpdater {
|
|
|
257
289
|
* @returns True if the operation is successful.
|
|
258
290
|
*/
|
|
259
291
|
public async removeCheckpointsAfter(checkpointNumber: CheckpointNumber): Promise<boolean> {
|
|
260
|
-
return await this.
|
|
261
|
-
const { blocksRemoved = [] } = await this.
|
|
292
|
+
return await this.stores.db.transactionAsync(async () => {
|
|
293
|
+
const { blocksRemoved = [] } = await this.stores.blocks.removeCheckpointsAfter(checkpointNumber);
|
|
262
294
|
|
|
263
295
|
const opResults = await Promise.all([
|
|
264
296
|
// Prune rolls back to the last proven block, which is by definition valid
|
|
265
|
-
this.
|
|
297
|
+
this.stores.blocks.setPendingChainValidationStatus({ valid: true }),
|
|
266
298
|
// Remove contract data for all blocks being removed
|
|
267
299
|
...blocksRemoved.map(block => this.removeContractDataFromDb(block)),
|
|
268
|
-
this.
|
|
300
|
+
this.stores.logs.deleteLogs(blocksRemoved),
|
|
269
301
|
]);
|
|
270
302
|
|
|
271
303
|
await this.l2TipsCache?.refresh();
|
|
@@ -278,8 +310,8 @@ export class ArchiverDataStoreUpdater {
|
|
|
278
310
|
* @param checkpointNumber - The checkpoint number to set as proven.
|
|
279
311
|
*/
|
|
280
312
|
public async setProvenCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<void> {
|
|
281
|
-
await this.
|
|
282
|
-
await this.
|
|
313
|
+
await this.stores.db.transactionAsync(async () => {
|
|
314
|
+
await this.stores.blocks.setProvenCheckpointNumber(checkpointNumber);
|
|
283
315
|
await this.l2TipsCache?.refresh();
|
|
284
316
|
});
|
|
285
317
|
}
|
|
@@ -289,8 +321,8 @@ export class ArchiverDataStoreUpdater {
|
|
|
289
321
|
* @param checkpointNumber - The checkpoint number to set as finalized.
|
|
290
322
|
*/
|
|
291
323
|
public async setFinalizedCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<void> {
|
|
292
|
-
await this.
|
|
293
|
-
await this.
|
|
324
|
+
await this.stores.db.transactionAsync(async () => {
|
|
325
|
+
await this.stores.blocks.setFinalizedCheckpointNumber(checkpointNumber);
|
|
294
326
|
await this.l2TipsCache?.refresh();
|
|
295
327
|
});
|
|
296
328
|
}
|
|
@@ -336,7 +368,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
336
368
|
const contractClasses = contractClassPublishedEvents.map(e => e.toContractClassPublic());
|
|
337
369
|
if (contractClasses.length > 0) {
|
|
338
370
|
contractClasses.forEach(c => this.log.verbose(`${Operation[operation]} contract class ${c.id.toString()}`));
|
|
339
|
-
return await this.
|
|
371
|
+
return await this.stores.contractClasses.deleteContractClasses(contractClasses, blockNum);
|
|
340
372
|
}
|
|
341
373
|
return true;
|
|
342
374
|
}
|
|
@@ -362,7 +394,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
362
394
|
|
|
363
395
|
if (contractClasses.length > 0) {
|
|
364
396
|
contractClasses.forEach(c => this.log.verbose(`${Operation[operation]} contract class ${c.id.toString()}`));
|
|
365
|
-
return await this.
|
|
397
|
+
return await this.stores.contractClasses.addContractClasses(contractClasses, blockNum);
|
|
366
398
|
}
|
|
367
399
|
return true;
|
|
368
400
|
}
|
|
@@ -401,9 +433,9 @@ export class ArchiverDataStoreUpdater {
|
|
|
401
433
|
this.log.verbose(`${Operation[operation]} contract instance at ${c.address.toString()}`),
|
|
402
434
|
);
|
|
403
435
|
if (operation == Operation.Store) {
|
|
404
|
-
return await this.
|
|
436
|
+
return await this.stores.contractInstances.addContractInstances(contractInstances, blockNum);
|
|
405
437
|
} else if (operation == Operation.Delete) {
|
|
406
|
-
return await this.
|
|
438
|
+
return await this.stores.contractInstances.deleteContractInstances(contractInstances);
|
|
407
439
|
}
|
|
408
440
|
}
|
|
409
441
|
return true;
|
|
@@ -427,9 +459,9 @@ export class ArchiverDataStoreUpdater {
|
|
|
427
459
|
this.log.verbose(`${Operation[operation]} contract instance update at ${c.address.toString()}`),
|
|
428
460
|
);
|
|
429
461
|
if (operation == Operation.Store) {
|
|
430
|
-
return await this.
|
|
462
|
+
return await this.stores.contractInstances.addContractInstanceUpdates(contractUpdates, timestamp);
|
|
431
463
|
} else if (operation == Operation.Delete) {
|
|
432
|
-
return await this.
|
|
464
|
+
return await this.stores.contractInstances.deleteContractInstanceUpdates(contractUpdates, timestamp);
|
|
433
465
|
}
|
|
434
466
|
}
|
|
435
467
|
return true;
|