@aztec/archiver 0.0.1-commit.b2a5d0dd1 → 0.0.1-commit.b3d3157a
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 +7 -5
- package/dest/archiver.d.ts +49 -14
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +216 -68
- package/dest/config.d.ts +4 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +11 -16
- package/dest/errors.d.ts +19 -13
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +32 -16
- package/dest/factory.d.ts +12 -6
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +31 -21
- package/dest/index.d.ts +9 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +8 -1
- 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 +13 -4
- package/dest/l1/trace_tx.d.ts +12 -66
- package/dest/l1/trace_tx.d.ts.map +1 -1
- 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 +40 -0
- package/dest/modules/data_source_base.d.ts +71 -49
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +269 -143
- package/dest/modules/data_store_updater.d.ts +18 -6
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +108 -59
- package/dest/modules/instrumentation.js +3 -1
- package/dest/modules/l1_synchronizer.d.ts +6 -5
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +203 -100
- package/dest/modules/outbox_trees_resolver.d.ts +62 -0
- package/dest/modules/outbox_trees_resolver.d.ts.map +1 -0
- package/dest/modules/outbox_trees_resolver.js +162 -0
- 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 +155 -98
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +473 -265
- 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 +54 -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 +13 -8
- package/dest/store/l2_tips_cache.d.ts.map +1 -1
- package/dest/store/l2_tips_cache.js +13 -96
- package/dest/store/log_store.d.ts +42 -40
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +257 -478
- package/dest/store/log_store_codec.d.ts +70 -0
- package/dest/store/log_store_codec.d.ts.map +1 -0
- package/dest/store/log_store_codec.js +101 -0
- 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 +2 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +25 -8
- package/dest/test/mock_l2_block_source.d.ts +47 -51
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +223 -185
- package/dest/test/noop_l1_archiver.d.ts +10 -6
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +19 -8
- package/package.json +14 -14
- package/src/archiver.ts +265 -72
- package/src/config.ts +12 -19
- package/src/errors.ts +46 -23
- package/src/factory.ts +38 -20
- package/src/index.ts +16 -1
- package/src/l1/calldata_retriever.ts +14 -4
- package/src/modules/contract_data_source_adapter.ts +55 -0
- package/src/modules/data_source_base.ts +335 -187
- package/src/modules/data_store_updater.ts +118 -61
- package/src/modules/instrumentation.ts +1 -1
- package/src/modules/l1_synchronizer.ts +278 -120
- package/src/modules/outbox_trees_resolver.ts +199 -0
- package/src/modules/validation.ts +8 -7
- package/src/store/block_store.ts +566 -323
- package/src/store/contract_class_store.ts +28 -2
- package/src/store/contract_instance_store.ts +43 -0
- package/src/store/data_stores.ts +104 -0
- package/src/store/function_names_cache.ts +37 -0
- package/src/store/l2_tips_cache.ts +16 -115
- package/src/store/log_store.ts +296 -650
- package/src/store/log_store_codec.ts +132 -0
- package/src/store/message_store.ts +35 -2
- package/src/test/fake_l1_state.ts +24 -14
- package/src/test/mock_l2_block_source.ts +271 -239
- package/src/test/noop_l1_archiver.ts +39 -8
- package/dest/store/kv_archiver_store.d.ts +0 -383
- package/dest/store/kv_archiver_store.d.ts.map +0 -1
- package/dest/store/kv_archiver_store.js +0 -501
- package/src/store/kv_archiver_store.ts +0 -728
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
import type { ContractClassLog, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
22
22
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
23
23
|
|
|
24
|
-
import type {
|
|
24
|
+
import type { ArchiverDataStores } from '../store/data_stores.js';
|
|
25
25
|
import type { L2TipsCache } from '../store/l2_tips_cache.js';
|
|
26
26
|
|
|
27
27
|
/** Operation type for contract data updates. */
|
|
@@ -43,7 +43,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
43
43
|
private readonly log = createLogger('archiver:store_updater');
|
|
44
44
|
|
|
45
45
|
constructor(
|
|
46
|
-
private
|
|
46
|
+
private stores: ArchiverDataStores,
|
|
47
47
|
private l2TipsCache?: L2TipsCache,
|
|
48
48
|
private opts: { rollupManaLimit?: number } = {},
|
|
49
49
|
) {}
|
|
@@ -61,21 +61,22 @@ export class ArchiverDataStoreUpdater {
|
|
|
61
61
|
block: L2Block,
|
|
62
62
|
pendingChainValidationStatus?: ValidateCheckpointResult,
|
|
63
63
|
): Promise<boolean> {
|
|
64
|
-
const result = await this.
|
|
65
|
-
await this.
|
|
64
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
65
|
+
await this.stores.blocks.addProposedBlock(block);
|
|
66
66
|
|
|
67
67
|
const opResults = await Promise.all([
|
|
68
68
|
// Update the pending chain validation status if provided
|
|
69
|
-
pendingChainValidationStatus &&
|
|
69
|
+
pendingChainValidationStatus &&
|
|
70
|
+
this.stores.blocks.setPendingChainValidationStatus(pendingChainValidationStatus),
|
|
70
71
|
// Add any logs emitted during the retrieved block
|
|
71
|
-
this.
|
|
72
|
+
this.stores.logs.addLogs([block]),
|
|
72
73
|
// Unroll all logs emitted during the retrieved block and extract any contract classes and instances from it
|
|
73
74
|
this.addContractDataToDb(block),
|
|
74
75
|
]);
|
|
75
76
|
|
|
76
|
-
await this.l2TipsCache?.refresh();
|
|
77
77
|
return opResults.every(Boolean);
|
|
78
78
|
});
|
|
79
|
+
await this.l2TipsCache?.refresh();
|
|
79
80
|
return result;
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -100,6 +101,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
100
101
|
attestations: CommitteeAttestation[];
|
|
101
102
|
checkpoint: PublishedCheckpoint;
|
|
102
103
|
},
|
|
104
|
+
evictProposedFrom?: CheckpointNumber,
|
|
103
105
|
): Promise<ReconcileCheckpointsResult> {
|
|
104
106
|
for (const checkpoint of checkpoints) {
|
|
105
107
|
validateCheckpoint(checkpoint.checkpoint, { rollupManaLimit: this.opts?.rollupManaLimit });
|
|
@@ -108,11 +110,11 @@ export class ArchiverDataStoreUpdater {
|
|
|
108
110
|
validateCheckpoint(promoteProposed.checkpoint.checkpoint, { rollupManaLimit: this.opts?.rollupManaLimit });
|
|
109
111
|
}
|
|
110
112
|
|
|
111
|
-
const result = await this.
|
|
113
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
112
114
|
// Before adding checkpoints, check for conflicts with local blocks if any
|
|
113
115
|
const { prunedBlocks, lastAlreadyInsertedBlockNumber } = await this.pruneMismatchingLocalBlocks(checkpoints);
|
|
114
116
|
|
|
115
|
-
await this.
|
|
117
|
+
await this.stores.blocks.addCheckpoints(checkpoints);
|
|
116
118
|
|
|
117
119
|
// Filter out blocks that were already inserted via addProposedBlock() to avoid duplicating logs/contract data
|
|
118
120
|
const newBlocks = checkpoints
|
|
@@ -121,46 +123,59 @@ export class ArchiverDataStoreUpdater {
|
|
|
121
123
|
|
|
122
124
|
await Promise.all([
|
|
123
125
|
// Update the pending chain validation status if provided
|
|
124
|
-
pendingChainValidationStatus &&
|
|
126
|
+
pendingChainValidationStatus &&
|
|
127
|
+
this.stores.blocks.setPendingChainValidationStatus(pendingChainValidationStatus),
|
|
125
128
|
// Add any logs emitted during the retrieved blocks
|
|
126
|
-
this.
|
|
129
|
+
this.stores.logs.addLogs(newBlocks),
|
|
127
130
|
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
128
131
|
...newBlocks.map(block => this.addContractDataToDb(block)),
|
|
129
|
-
// Promote the proposed checkpoint if requested
|
|
132
|
+
// Promote the proposed checkpoint if requested (uses explicit checkpoint number)
|
|
130
133
|
promoteProposed
|
|
131
|
-
? this.
|
|
134
|
+
? this.stores.blocks.promoteProposedToCheckpointed(
|
|
135
|
+
promoteProposed.checkpoint.checkpoint.number,
|
|
132
136
|
promoteProposed.l1,
|
|
133
137
|
promoteProposed.attestations,
|
|
134
138
|
promoteProposed.checkpoint.checkpoint.archive.root,
|
|
135
139
|
)
|
|
136
140
|
: undefined,
|
|
141
|
+
// Evict pending checkpoints that diverged from what L1 mined
|
|
142
|
+
evictProposedFrom !== undefined
|
|
143
|
+
? this.stores.blocks.evictProposedCheckpointsFrom(evictProposedFrom)
|
|
144
|
+
: undefined,
|
|
137
145
|
]);
|
|
138
146
|
|
|
139
|
-
await this.l2TipsCache?.refresh();
|
|
140
147
|
return { prunedBlocks, lastAlreadyInsertedBlockNumber };
|
|
141
148
|
});
|
|
149
|
+
await this.l2TipsCache?.refresh();
|
|
142
150
|
return result;
|
|
143
151
|
}
|
|
144
152
|
|
|
145
|
-
public async
|
|
146
|
-
const result = await this.
|
|
147
|
-
await this.
|
|
148
|
-
await this.l2TipsCache?.refresh();
|
|
153
|
+
public async addProposedCheckpoint(proposedCheckpoint: ProposedCheckpointInput) {
|
|
154
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
155
|
+
await this.stores.blocks.addProposedCheckpoint(proposedCheckpoint);
|
|
149
156
|
});
|
|
150
|
-
|
|
157
|
+
await this.l2TipsCache?.refresh();
|
|
151
158
|
return result;
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
/**
|
|
155
162
|
* Checks for local proposed blocks that do not match the ones to be checkpointed and prunes them.
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
163
|
+
* Conflict detection is keyed on `blockNumber`: when a local proposed block and an L1
|
|
164
|
+
* checkpointed block share a block number but live at different slots (e.g. a different proposer
|
|
165
|
+
* mined the same block number one slot earlier), we still treat them as a conflict and prune.
|
|
166
|
+
* The trailing per-checkpoint prune that handles "local has extra trailing blocks within the
|
|
167
|
+
* same slot as the published checkpoint" remains scoped by slot to preserve pipelining: local
|
|
168
|
+
* blocks that live at a later slot than the checkpoint being processed represent speculation
|
|
169
|
+
* atop the just-confirmed tip (and may be referenced by a pending proposed checkpoint), so we
|
|
170
|
+
* leave them in place. This method handles multiple checkpoints but returns after pruning the
|
|
171
|
+
* first conflict found. This is correct because pruning from the first conflict point removes
|
|
172
|
+
* all subsequent blocks, and when checkpoints are added afterward, they include all the correct
|
|
173
|
+
* blocks.
|
|
159
174
|
*/
|
|
160
175
|
private async pruneMismatchingLocalBlocks(checkpoints: PublishedCheckpoint[]): Promise<ReconcileCheckpointsResult> {
|
|
161
176
|
const [lastCheckpointedBlockNumber, lastBlockNumber] = await Promise.all([
|
|
162
|
-
this.
|
|
163
|
-
this.
|
|
177
|
+
this.stores.blocks.getCheckpointedL2BlockNumber(),
|
|
178
|
+
this.stores.blocks.getLatestL2BlockNumber(),
|
|
164
179
|
]);
|
|
165
180
|
|
|
166
181
|
// Exit early if there are no local uncheckpointed blocks
|
|
@@ -169,29 +184,29 @@ export class ArchiverDataStoreUpdater {
|
|
|
169
184
|
}
|
|
170
185
|
|
|
171
186
|
// Get all uncheckpointed local blocks
|
|
172
|
-
const uncheckpointedLocalBlocks = await this.
|
|
173
|
-
BlockNumber.add(lastCheckpointedBlockNumber, 1),
|
|
174
|
-
lastBlockNumber - lastCheckpointedBlockNumber,
|
|
175
|
-
);
|
|
187
|
+
const uncheckpointedLocalBlocks = await this.stores.blocks.getBlocksData({
|
|
188
|
+
from: BlockNumber.add(lastCheckpointedBlockNumber, 1),
|
|
189
|
+
limit: lastBlockNumber - lastCheckpointedBlockNumber,
|
|
190
|
+
});
|
|
176
191
|
|
|
177
192
|
let lastAlreadyInsertedBlockNumber: BlockNumber | undefined;
|
|
178
193
|
|
|
179
194
|
for (const publishedCheckpoint of checkpoints) {
|
|
180
195
|
const checkpointBlocks = publishedCheckpoint.checkpoint.blocks;
|
|
181
196
|
const slot = publishedCheckpoint.checkpoint.slot;
|
|
182
|
-
const localBlocksInSlot = uncheckpointedLocalBlocks.filter(b => b.slot === slot);
|
|
183
197
|
|
|
184
198
|
if (checkpointBlocks.length === 0) {
|
|
185
199
|
this.log.warn(`Checkpoint ${publishedCheckpoint.checkpoint.number} for slot ${slot} has no blocks`);
|
|
186
200
|
continue;
|
|
187
201
|
}
|
|
188
202
|
|
|
189
|
-
// Find the first checkpoint block that conflicts with an existing local block and prune local afterwards
|
|
203
|
+
// Find the first checkpoint block that conflicts with an existing local block and prune local afterwards.
|
|
204
|
+
// Conflict detection joins on block number only — same block number at a different slot is still a conflict.
|
|
190
205
|
for (const checkpointBlock of checkpointBlocks) {
|
|
191
206
|
const blockNumber = checkpointBlock.number;
|
|
192
|
-
const existingBlock =
|
|
207
|
+
const existingBlock = uncheckpointedLocalBlocks.find(b => b.header.getBlockNumber() === blockNumber);
|
|
193
208
|
const blockInfos = {
|
|
194
|
-
existingBlock: existingBlock?.
|
|
209
|
+
existingBlock: existingBlock?.header.toInspect(),
|
|
195
210
|
checkpointBlock: checkpointBlock.toBlockInfo(),
|
|
196
211
|
};
|
|
197
212
|
|
|
@@ -203,20 +218,24 @@ export class ArchiverDataStoreUpdater {
|
|
|
203
218
|
} else {
|
|
204
219
|
this.log.info(`Conflict detected at block ${blockNumber} between checkpointed and local block`, blockInfos);
|
|
205
220
|
const prunedBlocks = await this.removeBlocksAfter(BlockNumber(blockNumber - 1));
|
|
221
|
+
await this.evictProposedCheckpointsForPrunedBlocks(prunedBlocks);
|
|
206
222
|
return { prunedBlocks, lastAlreadyInsertedBlockNumber };
|
|
207
223
|
}
|
|
208
224
|
}
|
|
209
225
|
|
|
210
|
-
// If
|
|
211
|
-
//
|
|
226
|
+
// If the sequencer locally proposed extra blocks within this checkpoint's slot (e.g. local has
|
|
227
|
+
// [N, N+1] but L1 confirmed just [N]), prune the extras. Scoped to the checkpoint's slot so we
|
|
228
|
+
// do not throw away speculative blocks at later slots that belong to a pending proposed checkpoint.
|
|
212
229
|
const lastCheckpointBlockNumber = checkpointBlocks.at(-1)!.number;
|
|
213
|
-
const
|
|
230
|
+
const localBlocksInSlot = uncheckpointedLocalBlocks.filter(b => b.header.getSlot() === slot);
|
|
231
|
+
const lastLocalBlockNumber = localBlocksInSlot.at(-1)?.header.getBlockNumber();
|
|
214
232
|
|
|
215
233
|
if (lastLocalBlockNumber !== undefined && lastLocalBlockNumber > lastCheckpointBlockNumber) {
|
|
216
234
|
this.log.warn(
|
|
217
235
|
`Local chain for slot ${slot} ends at block ${lastLocalBlockNumber} but checkpoint ends at ${lastCheckpointBlockNumber}. Pruning blocks after block ${lastCheckpointBlockNumber}.`,
|
|
218
236
|
);
|
|
219
237
|
const prunedBlocks = await this.removeBlocksAfter(lastCheckpointBlockNumber);
|
|
238
|
+
await this.evictProposedCheckpointsForPrunedBlocks(prunedBlocks);
|
|
220
239
|
return { prunedBlocks, lastAlreadyInsertedBlockNumber };
|
|
221
240
|
}
|
|
222
241
|
}
|
|
@@ -234,37 +253,74 @@ export class ArchiverDataStoreUpdater {
|
|
|
234
253
|
* @throws Error if any block to be removed is checkpointed.
|
|
235
254
|
*/
|
|
236
255
|
public async removeUncheckpointedBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
|
|
237
|
-
const result = await this.
|
|
256
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
238
257
|
// Verify we're only removing uncheckpointed blocks
|
|
239
|
-
const lastCheckpointedBlockNumber = await this.
|
|
258
|
+
const lastCheckpointedBlockNumber = await this.stores.blocks.getCheckpointedL2BlockNumber();
|
|
240
259
|
if (blockNumber < lastCheckpointedBlockNumber) {
|
|
241
260
|
throw new Error(
|
|
242
261
|
`Cannot remove blocks after ${blockNumber} because checkpointed blocks exist up to ${lastCheckpointedBlockNumber}`,
|
|
243
262
|
);
|
|
244
263
|
}
|
|
245
264
|
|
|
246
|
-
const
|
|
265
|
+
const prunedBlocks = await this.removeBlocksAfter(blockNumber);
|
|
266
|
+
await this.evictProposedCheckpointsForPrunedBlocks(prunedBlocks);
|
|
247
267
|
|
|
248
|
-
|
|
249
|
-
|
|
268
|
+
return prunedBlocks;
|
|
269
|
+
});
|
|
270
|
+
await this.l2TipsCache?.refresh();
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
250
273
|
|
|
251
|
-
|
|
252
|
-
|
|
274
|
+
/**
|
|
275
|
+
* Removes all blocks without a proposed checkpoint strictly after the specified block number and cleans up associated contract data.
|
|
276
|
+
* This handles removal of provisionally added blocks along with their contract classes/instances.
|
|
277
|
+
* Verifies that each block being removed is not part of a stored checkpoint (proposed or not).
|
|
278
|
+
* This differs from `removeUncheckpointedBlocksAfter` in that it also checks proposed checkpoints.
|
|
279
|
+
*
|
|
280
|
+
* @param blockNumber - Remove all blocks with number greater than this.
|
|
281
|
+
* @returns The removed blocks.
|
|
282
|
+
* @throws Error if any block to be removed is checkpointed.
|
|
283
|
+
*/
|
|
284
|
+
public async removeBlocksWithoutProposedCheckpointAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
|
|
285
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
286
|
+
// Verify we're only removing uncheckpointed blocks
|
|
287
|
+
const lastCheckpointedBlockNumber = await this.stores.blocks.getProposedCheckpointL2BlockNumber();
|
|
288
|
+
if (blockNumber < lastCheckpointedBlockNumber) {
|
|
289
|
+
throw new Error(
|
|
290
|
+
`Cannot remove blocks after ${blockNumber} because proposed checkpointed blocks exist up to ${lastCheckpointedBlockNumber}`,
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return await this.removeBlocksAfter(blockNumber);
|
|
253
295
|
});
|
|
296
|
+
await this.l2TipsCache?.refresh();
|
|
254
297
|
return result;
|
|
255
298
|
}
|
|
256
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Evicts pending proposed checkpoints that referenced any of the just-pruned blocks. Pruned
|
|
302
|
+
* blocks invalidate all proposed checkpoints from the lowest pruned block's checkpoint number
|
|
303
|
+
* onwards: those checkpoints either reference the pruned blocks directly or chain off them.
|
|
304
|
+
*/
|
|
305
|
+
private async evictProposedCheckpointsForPrunedBlocks(prunedBlocks: L2Block[]): Promise<void> {
|
|
306
|
+
if (prunedBlocks.length === 0) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const fromCheckpointNumber = prunedBlocks[0].checkpointNumber;
|
|
310
|
+
await this.stores.blocks.evictProposedCheckpointsFrom(fromCheckpointNumber);
|
|
311
|
+
}
|
|
312
|
+
|
|
257
313
|
/**
|
|
258
314
|
* Removes all blocks strictly after the given block number along with any logs and contract data.
|
|
259
315
|
* Does not remove their checkpoints.
|
|
260
316
|
*/
|
|
261
317
|
private async removeBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
|
|
262
318
|
// First get the blocks to be removed so we can clean up contract data
|
|
263
|
-
const removedBlocks = await this.
|
|
319
|
+
const removedBlocks = await this.stores.blocks.removeBlocksAfter(blockNumber);
|
|
264
320
|
|
|
265
321
|
// Clean up contract data and logs for the removed blocks
|
|
266
322
|
await Promise.all([
|
|
267
|
-
this.
|
|
323
|
+
this.stores.logs.deleteLogs(removedBlocks),
|
|
268
324
|
...removedBlocks.map(block => this.removeContractDataFromDb(block)),
|
|
269
325
|
]);
|
|
270
326
|
|
|
@@ -281,20 +337,21 @@ export class ArchiverDataStoreUpdater {
|
|
|
281
337
|
* @returns True if the operation is successful.
|
|
282
338
|
*/
|
|
283
339
|
public async removeCheckpointsAfter(checkpointNumber: CheckpointNumber): Promise<boolean> {
|
|
284
|
-
|
|
285
|
-
const { blocksRemoved = [] } = await this.
|
|
340
|
+
const result = await this.stores.db.transactionAsync(async () => {
|
|
341
|
+
const { blocksRemoved = [] } = await this.stores.blocks.removeCheckpointsAfter(checkpointNumber);
|
|
286
342
|
|
|
287
343
|
const opResults = await Promise.all([
|
|
288
344
|
// Prune rolls back to the last proven block, which is by definition valid
|
|
289
|
-
this.
|
|
345
|
+
this.stores.blocks.setPendingChainValidationStatus({ valid: true }),
|
|
290
346
|
// Remove contract data for all blocks being removed
|
|
291
347
|
...blocksRemoved.map(block => this.removeContractDataFromDb(block)),
|
|
292
|
-
this.
|
|
348
|
+
this.stores.logs.deleteLogs(blocksRemoved),
|
|
293
349
|
]);
|
|
294
350
|
|
|
295
|
-
await this.l2TipsCache?.refresh();
|
|
296
351
|
return opResults.every(Boolean);
|
|
297
352
|
});
|
|
353
|
+
await this.l2TipsCache?.refresh();
|
|
354
|
+
return result;
|
|
298
355
|
}
|
|
299
356
|
|
|
300
357
|
/**
|
|
@@ -302,10 +359,10 @@ export class ArchiverDataStoreUpdater {
|
|
|
302
359
|
* @param checkpointNumber - The checkpoint number to set as proven.
|
|
303
360
|
*/
|
|
304
361
|
public async setProvenCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<void> {
|
|
305
|
-
await this.
|
|
306
|
-
await this.
|
|
307
|
-
await this.l2TipsCache?.refresh();
|
|
362
|
+
await this.stores.db.transactionAsync(async () => {
|
|
363
|
+
await this.stores.blocks.setProvenCheckpointNumber(checkpointNumber);
|
|
308
364
|
});
|
|
365
|
+
await this.l2TipsCache?.refresh();
|
|
309
366
|
}
|
|
310
367
|
|
|
311
368
|
/**
|
|
@@ -313,10 +370,10 @@ export class ArchiverDataStoreUpdater {
|
|
|
313
370
|
* @param checkpointNumber - The checkpoint number to set as finalized.
|
|
314
371
|
*/
|
|
315
372
|
public async setFinalizedCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<void> {
|
|
316
|
-
await this.
|
|
317
|
-
await this.
|
|
318
|
-
await this.l2TipsCache?.refresh();
|
|
373
|
+
await this.stores.db.transactionAsync(async () => {
|
|
374
|
+
await this.stores.blocks.setFinalizedCheckpointNumber(checkpointNumber);
|
|
319
375
|
});
|
|
376
|
+
await this.l2TipsCache?.refresh();
|
|
320
377
|
}
|
|
321
378
|
|
|
322
379
|
/** Extracts and stores contract data from a single block. */
|
|
@@ -360,7 +417,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
360
417
|
const contractClasses = contractClassPublishedEvents.map(e => e.toContractClassPublic());
|
|
361
418
|
if (contractClasses.length > 0) {
|
|
362
419
|
contractClasses.forEach(c => this.log.verbose(`${Operation[operation]} contract class ${c.id.toString()}`));
|
|
363
|
-
return await this.
|
|
420
|
+
return await this.stores.contractClasses.deleteContractClasses(contractClasses, blockNum);
|
|
364
421
|
}
|
|
365
422
|
return true;
|
|
366
423
|
}
|
|
@@ -386,7 +443,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
386
443
|
|
|
387
444
|
if (contractClasses.length > 0) {
|
|
388
445
|
contractClasses.forEach(c => this.log.verbose(`${Operation[operation]} contract class ${c.id.toString()}`));
|
|
389
|
-
return await this.
|
|
446
|
+
return await this.stores.contractClasses.addContractClasses(contractClasses, blockNum);
|
|
390
447
|
}
|
|
391
448
|
return true;
|
|
392
449
|
}
|
|
@@ -425,9 +482,9 @@ export class ArchiverDataStoreUpdater {
|
|
|
425
482
|
this.log.verbose(`${Operation[operation]} contract instance at ${c.address.toString()}`),
|
|
426
483
|
);
|
|
427
484
|
if (operation == Operation.Store) {
|
|
428
|
-
return await this.
|
|
485
|
+
return await this.stores.contractInstances.addContractInstances(contractInstances, blockNum);
|
|
429
486
|
} else if (operation == Operation.Delete) {
|
|
430
|
-
return await this.
|
|
487
|
+
return await this.stores.contractInstances.deleteContractInstances(contractInstances);
|
|
431
488
|
}
|
|
432
489
|
}
|
|
433
490
|
return true;
|
|
@@ -451,9 +508,9 @@ export class ArchiverDataStoreUpdater {
|
|
|
451
508
|
this.log.verbose(`${Operation[operation]} contract instance update at ${c.address.toString()}`),
|
|
452
509
|
);
|
|
453
510
|
if (operation == Operation.Store) {
|
|
454
|
-
return await this.
|
|
511
|
+
return await this.stores.contractInstances.addContractInstanceUpdates(contractUpdates, timestamp);
|
|
455
512
|
} else if (operation == Operation.Delete) {
|
|
456
|
-
return await this.
|
|
513
|
+
return await this.stores.contractInstances.deleteContractInstanceUpdates(contractUpdates, timestamp);
|
|
457
514
|
}
|
|
458
515
|
}
|
|
459
516
|
return true;
|
|
@@ -136,7 +136,7 @@ export class ArchiverInstrumentation {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
this.syncDurationPerCheckpoint.record(Math.ceil(syncTimePerCheckpoint));
|
|
139
|
-
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
|
|
139
|
+
this.blockHeight.record(Math.max(...blocks.map(b => b.number)), { [Attributes.STATUS]: 'checkpointed' });
|
|
140
140
|
this.checkpointHeight.record(Math.max(...blocks.map(b => b.checkpointNumber)));
|
|
141
141
|
this.syncBlockCount.add(blocks.length);
|
|
142
142
|
}
|