@aztec/archiver 0.0.1-commit.ec5f612 → 0.0.1-commit.ec7ac5448
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 +12 -6
- package/dest/archiver.d.ts +8 -7
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +77 -26
- package/dest/config.d.ts +3 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -1
- package/dest/errors.d.ts +34 -10
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +45 -16
- package/dest/factory.d.ts +4 -5
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +24 -21
- package/dest/l1/calldata_retriever.d.ts +1 -1
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +2 -1
- package/dest/l1/data_retrieval.d.ts +3 -3
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +14 -15
- package/dest/modules/data_source_base.d.ts +8 -6
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +11 -5
- package/dest/modules/data_store_updater.d.ts +18 -12
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +87 -77
- package/dest/modules/instrumentation.d.ts +4 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +17 -6
- package/dest/modules/l1_synchronizer.d.ts +4 -2
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +166 -129
- package/dest/modules/validation.d.ts +1 -1
- package/dest/modules/validation.d.ts.map +1 -1
- package/dest/modules/validation.js +2 -2
- package/dest/store/block_store.d.ts +50 -16
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +288 -119
- package/dest/store/contract_class_store.d.ts +2 -3
- package/dest/store/contract_class_store.d.ts.map +1 -1
- package/dest/store/contract_class_store.js +7 -67
- package/dest/store/contract_instance_store.d.ts +1 -1
- package/dest/store/contract_instance_store.d.ts.map +1 -1
- package/dest/store/contract_instance_store.js +6 -2
- package/dest/store/kv_archiver_store.d.ts +45 -22
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +57 -27
- package/dest/store/l2_tips_cache.d.ts +2 -1
- package/dest/store/l2_tips_cache.d.ts.map +1 -1
- package/dest/store/l2_tips_cache.js +25 -5
- package/dest/store/log_store.d.ts +6 -3
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +93 -16
- package/dest/store/message_store.d.ts +5 -1
- package/dest/store/message_store.d.ts.map +1 -1
- package/dest/store/message_store.js +21 -9
- package/dest/test/fake_l1_state.d.ts +16 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +77 -8
- package/dest/test/mock_l1_to_l2_message_source.d.ts +1 -1
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +2 -1
- package/dest/test/mock_l2_block_source.d.ts +10 -4
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +35 -7
- package/dest/test/mock_structs.d.ts +4 -1
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +13 -1
- package/dest/test/noop_l1_archiver.d.ts +4 -1
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +5 -2
- package/package.json +13 -13
- package/src/archiver.ts +98 -31
- package/src/config.ts +8 -1
- package/src/errors.ts +70 -26
- package/src/factory.ts +23 -15
- package/src/l1/calldata_retriever.ts +2 -1
- package/src/l1/data_retrieval.ts +8 -12
- package/src/modules/data_source_base.ts +26 -7
- package/src/modules/data_store_updater.ts +96 -107
- package/src/modules/instrumentation.ts +19 -7
- package/src/modules/l1_synchronizer.ts +189 -161
- package/src/modules/validation.ts +2 -2
- package/src/store/block_store.ts +370 -140
- package/src/store/contract_class_store.ts +8 -106
- package/src/store/contract_instance_store.ts +8 -5
- package/src/store/kv_archiver_store.ts +81 -39
- package/src/store/l2_tips_cache.ts +50 -11
- package/src/store/log_store.ts +126 -27
- package/src/store/message_store.ts +27 -10
- package/src/structs/inbox_message.ts +1 -1
- package/src/test/fake_l1_state.ts +103 -13
- package/src/test/mock_l1_to_l2_message_source.ts +1 -0
- package/src/test/mock_l2_block_source.ts +52 -5
- package/src/test/mock_structs.ts +20 -6
- package/src/test/noop_l1_archiver.ts +7 -2
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
2
|
-
import {
|
|
2
|
+
import { filterAsync } from '@aztec/foundation/collection';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import {
|
|
5
|
-
ContractClassPublishedEvent,
|
|
6
|
-
PrivateFunctionBroadcastedEvent,
|
|
7
|
-
UtilityFunctionBroadcastedEvent,
|
|
8
|
-
} from '@aztec/protocol-contracts/class-registry';
|
|
4
|
+
import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
|
|
9
5
|
import {
|
|
10
6
|
ContractInstancePublishedEvent,
|
|
11
7
|
ContractInstanceUpdatedEvent,
|
|
12
8
|
} from '@aztec/protocol-contracts/instance-registry';
|
|
13
9
|
import type { L2Block, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
14
|
-
import type
|
|
10
|
+
import { type ProposedCheckpointInput, type PublishedCheckpoint, validateCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
15
11
|
import {
|
|
16
|
-
type
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
isValidPrivateFunctionMembershipProof,
|
|
20
|
-
isValidUtilityFunctionMembershipProof,
|
|
12
|
+
type ContractClassPublicWithCommitment,
|
|
13
|
+
computeContractAddressFromInstance,
|
|
14
|
+
computeContractClassId,
|
|
21
15
|
} from '@aztec/stdlib/contract';
|
|
22
16
|
import type { ContractClassLog, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
23
17
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
24
18
|
|
|
25
|
-
import groupBy from 'lodash.groupby';
|
|
26
|
-
|
|
27
19
|
import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
|
|
28
20
|
import type { L2TipsCache } from '../store/l2_tips_cache.js';
|
|
29
21
|
|
|
@@ -48,32 +40,32 @@ export class ArchiverDataStoreUpdater {
|
|
|
48
40
|
constructor(
|
|
49
41
|
private store: KVArchiverDataStore,
|
|
50
42
|
private l2TipsCache?: L2TipsCache,
|
|
43
|
+
private opts: { rollupManaLimit?: number } = {},
|
|
51
44
|
) {}
|
|
52
45
|
|
|
53
46
|
/**
|
|
54
|
-
* Adds proposed
|
|
55
|
-
*
|
|
56
|
-
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events
|
|
57
|
-
* and individually broadcasted functions from the block logs.
|
|
47
|
+
* Adds a proposed block to the store with contract class/instance extraction from logs.
|
|
48
|
+
* This is an uncheckpointed block that has been proposed by the sequencer but not yet included in a checkpoint on L1.
|
|
49
|
+
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events from the block logs.
|
|
58
50
|
*
|
|
59
|
-
* @param
|
|
51
|
+
* @param block - The proposed L2 block to add.
|
|
60
52
|
* @param pendingChainValidationStatus - Optional validation status to set.
|
|
61
53
|
* @returns True if the operation is successful.
|
|
62
54
|
*/
|
|
63
|
-
public async
|
|
64
|
-
|
|
55
|
+
public async addProposedBlock(
|
|
56
|
+
block: L2Block,
|
|
65
57
|
pendingChainValidationStatus?: ValidateCheckpointResult,
|
|
66
58
|
): Promise<boolean> {
|
|
67
59
|
const result = await this.store.transactionAsync(async () => {
|
|
68
|
-
await this.store.
|
|
60
|
+
await this.store.addProposedBlock(block);
|
|
69
61
|
|
|
70
62
|
const opResults = await Promise.all([
|
|
71
63
|
// Update the pending chain validation status if provided
|
|
72
64
|
pendingChainValidationStatus && this.store.setPendingChainValidationStatus(pendingChainValidationStatus),
|
|
73
|
-
// Add any logs emitted during the retrieved
|
|
74
|
-
this.store.addLogs(
|
|
75
|
-
// Unroll all logs emitted during the retrieved
|
|
76
|
-
|
|
65
|
+
// Add any logs emitted during the retrieved block
|
|
66
|
+
this.store.addLogs([block]),
|
|
67
|
+
// Unroll all logs emitted during the retrieved block and extract any contract classes and instances from it
|
|
68
|
+
this.addContractDataToDb(block),
|
|
77
69
|
]);
|
|
78
70
|
|
|
79
71
|
await this.l2TipsCache?.refresh();
|
|
@@ -86,8 +78,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
86
78
|
* Reconciles local blocks with incoming checkpoints from L1.
|
|
87
79
|
* Adds new checkpoints to the store with contract class/instance extraction from logs.
|
|
88
80
|
* Prunes any local blocks that conflict with checkpoint data (by comparing archive roots).
|
|
89
|
-
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events
|
|
90
|
-
* and individually broadcasted functions from the checkpoint block logs.
|
|
81
|
+
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events from the checkpoint block logs.
|
|
91
82
|
*
|
|
92
83
|
* @param checkpoints - The published checkpoints to add.
|
|
93
84
|
* @param pendingChainValidationStatus - Optional validation status to set.
|
|
@@ -97,13 +88,17 @@ export class ArchiverDataStoreUpdater {
|
|
|
97
88
|
checkpoints: PublishedCheckpoint[],
|
|
98
89
|
pendingChainValidationStatus?: ValidateCheckpointResult,
|
|
99
90
|
): Promise<ReconcileCheckpointsResult> {
|
|
91
|
+
for (const checkpoint of checkpoints) {
|
|
92
|
+
validateCheckpoint(checkpoint.checkpoint, { rollupManaLimit: this.opts?.rollupManaLimit });
|
|
93
|
+
}
|
|
94
|
+
|
|
100
95
|
const result = await this.store.transactionAsync(async () => {
|
|
101
96
|
// Before adding checkpoints, check for conflicts with local blocks if any
|
|
102
97
|
const { prunedBlocks, lastAlreadyInsertedBlockNumber } = await this.pruneMismatchingLocalBlocks(checkpoints);
|
|
103
98
|
|
|
104
99
|
await this.store.addCheckpoints(checkpoints);
|
|
105
100
|
|
|
106
|
-
// Filter out blocks that were already inserted via
|
|
101
|
+
// Filter out blocks that were already inserted via addProposedBlock() to avoid duplicating logs/contract data
|
|
107
102
|
const newBlocks = checkpoints
|
|
108
103
|
.flatMap((ch: PublishedCheckpoint) => ch.checkpoint.blocks)
|
|
109
104
|
.filter(b => lastAlreadyInsertedBlockNumber === undefined || b.number > lastAlreadyInsertedBlockNumber);
|
|
@@ -123,6 +118,15 @@ export class ArchiverDataStoreUpdater {
|
|
|
123
118
|
return result;
|
|
124
119
|
}
|
|
125
120
|
|
|
121
|
+
public async setProposedCheckpoint(proposedCheckpoint: ProposedCheckpointInput) {
|
|
122
|
+
const result = await this.store.transactionAsync(async () => {
|
|
123
|
+
await this.store.setProposedCheckpoint(proposedCheckpoint);
|
|
124
|
+
await this.l2TipsCache?.refresh();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
|
|
126
130
|
/**
|
|
127
131
|
* Checks for local proposed blocks that do not match the ones to be checkpointed and prunes them.
|
|
128
132
|
* This method handles multiple checkpoints but returns after pruning the first conflict found.
|
|
@@ -173,7 +177,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
173
177
|
this.log.verbose(`Block number ${blockNumber} already inserted and matches checkpoint`, blockInfos);
|
|
174
178
|
lastAlreadyInsertedBlockNumber = blockNumber;
|
|
175
179
|
} else {
|
|
176
|
-
this.log.
|
|
180
|
+
this.log.info(`Conflict detected at block ${blockNumber} between checkpointed and local block`, blockInfos);
|
|
177
181
|
const prunedBlocks = await this.removeBlocksAfter(BlockNumber(blockNumber - 1));
|
|
178
182
|
return { prunedBlocks, lastAlreadyInsertedBlockNumber };
|
|
179
183
|
}
|
|
@@ -216,6 +220,10 @@ export class ArchiverDataStoreUpdater {
|
|
|
216
220
|
}
|
|
217
221
|
|
|
218
222
|
const result = await this.removeBlocksAfter(blockNumber);
|
|
223
|
+
|
|
224
|
+
// Clear the proposed checkpoint if it exists, since its blocks have been pruned
|
|
225
|
+
await this.store.deleteProposedCheckpoint();
|
|
226
|
+
|
|
219
227
|
await this.l2TipsCache?.refresh();
|
|
220
228
|
return result;
|
|
221
229
|
});
|
|
@@ -276,6 +284,17 @@ export class ArchiverDataStoreUpdater {
|
|
|
276
284
|
});
|
|
277
285
|
}
|
|
278
286
|
|
|
287
|
+
/**
|
|
288
|
+
* Updates the finalized checkpoint number and refreshes the L2 tips cache.
|
|
289
|
+
* @param checkpointNumber - The checkpoint number to set as finalized.
|
|
290
|
+
*/
|
|
291
|
+
public async setFinalizedCheckpointNumber(checkpointNumber: CheckpointNumber): Promise<void> {
|
|
292
|
+
await this.store.transactionAsync(async () => {
|
|
293
|
+
await this.store.setFinalizedCheckpointNumber(checkpointNumber);
|
|
294
|
+
await this.l2TipsCache?.refresh();
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
279
298
|
/** Extracts and stores contract data from a single block. */
|
|
280
299
|
private addContractDataToDb(block: L2Block): Promise<boolean> {
|
|
281
300
|
return this.updateContractDataOnDb(block, Operation.Store);
|
|
@@ -297,9 +316,6 @@ export class ArchiverDataStoreUpdater {
|
|
|
297
316
|
this.updatePublishedContractClasses(contractClassLogs, block.number, operation),
|
|
298
317
|
this.updateDeployedContractInstances(privateLogs, block.number, operation),
|
|
299
318
|
this.updateUpdatedContractInstances(publicLogs, block.header.globalVariables.timestamp, operation),
|
|
300
|
-
operation === Operation.Store
|
|
301
|
-
? this.storeBroadcastedIndividualFunctions(contractClassLogs, block.number)
|
|
302
|
-
: Promise.resolve(true),
|
|
303
319
|
])
|
|
304
320
|
).every(Boolean);
|
|
305
321
|
}
|
|
@@ -316,18 +332,37 @@ export class ArchiverDataStoreUpdater {
|
|
|
316
332
|
.filter(log => ContractClassPublishedEvent.isContractClassPublishedEvent(log))
|
|
317
333
|
.map(log => ContractClassPublishedEvent.fromLog(log));
|
|
318
334
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
contractClasses.
|
|
322
|
-
|
|
323
|
-
// TODO: Will probably want to create some worker threads to compute these bytecode commitments as they are expensive
|
|
324
|
-
const commitments = await Promise.all(
|
|
325
|
-
contractClasses.map(c => computePublicBytecodeCommitment(c.packedBytecode)),
|
|
326
|
-
);
|
|
327
|
-
return await this.store.addContractClasses(contractClasses, commitments, blockNum);
|
|
328
|
-
} else if (operation == Operation.Delete) {
|
|
335
|
+
if (operation == Operation.Delete) {
|
|
336
|
+
const contractClasses = contractClassPublishedEvents.map(e => e.toContractClassPublic());
|
|
337
|
+
if (contractClasses.length > 0) {
|
|
338
|
+
contractClasses.forEach(c => this.log.verbose(`${Operation[operation]} contract class ${c.id.toString()}`));
|
|
329
339
|
return await this.store.deleteContractClasses(contractClasses, blockNum);
|
|
330
340
|
}
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Compute bytecode commitments and validate class IDs in a single pass.
|
|
345
|
+
const contractClasses: ContractClassPublicWithCommitment[] = [];
|
|
346
|
+
for (const event of contractClassPublishedEvents) {
|
|
347
|
+
const contractClass = await event.toContractClassPublicWithBytecodeCommitment();
|
|
348
|
+
const computedClassId = await computeContractClassId({
|
|
349
|
+
artifactHash: contractClass.artifactHash,
|
|
350
|
+
privateFunctionsRoot: contractClass.privateFunctionsRoot,
|
|
351
|
+
publicBytecodeCommitment: contractClass.publicBytecodeCommitment,
|
|
352
|
+
});
|
|
353
|
+
if (!computedClassId.equals(contractClass.id)) {
|
|
354
|
+
this.log.warn(
|
|
355
|
+
`Skipping contract class with mismatched id at block ${blockNum}. Claimed ${contractClass.id}, computed ${computedClassId}`,
|
|
356
|
+
{ blockNum, contractClassId: event.contractClassId.toString() },
|
|
357
|
+
);
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
contractClasses.push(contractClass);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (contractClasses.length > 0) {
|
|
364
|
+
contractClasses.forEach(c => this.log.verbose(`${Operation[operation]} contract class ${c.id.toString()}`));
|
|
365
|
+
return await this.store.addContractClasses(contractClasses, blockNum);
|
|
331
366
|
}
|
|
332
367
|
return true;
|
|
333
368
|
}
|
|
@@ -340,10 +375,27 @@ export class ArchiverDataStoreUpdater {
|
|
|
340
375
|
blockNum: BlockNumber,
|
|
341
376
|
operation: Operation,
|
|
342
377
|
): Promise<boolean> {
|
|
343
|
-
const
|
|
378
|
+
const allInstances = allLogs
|
|
344
379
|
.filter(log => ContractInstancePublishedEvent.isContractInstancePublishedEvent(log))
|
|
345
380
|
.map(log => ContractInstancePublishedEvent.fromLog(log))
|
|
346
381
|
.map(e => e.toContractInstance());
|
|
382
|
+
|
|
383
|
+
// Verify that each instance's address matches the one derived from its fields if we're adding
|
|
384
|
+
const contractInstances =
|
|
385
|
+
operation === Operation.Delete
|
|
386
|
+
? allInstances
|
|
387
|
+
: await filterAsync(allInstances, async instance => {
|
|
388
|
+
const computedAddress = await computeContractAddressFromInstance(instance);
|
|
389
|
+
if (!computedAddress.equals(instance.address)) {
|
|
390
|
+
this.log.warn(
|
|
391
|
+
`Found contract instance with mismatched address at block ${blockNum}. Claimed ${instance.address} but computed ${computedAddress}.`,
|
|
392
|
+
{ instanceAddress: instance.address.toString(), computedAddress: computedAddress.toString(), blockNum },
|
|
393
|
+
);
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
return true;
|
|
397
|
+
});
|
|
398
|
+
|
|
347
399
|
if (contractInstances.length > 0) {
|
|
348
400
|
contractInstances.forEach(c =>
|
|
349
401
|
this.log.verbose(`${Operation[operation]} contract instance at ${c.address.toString()}`),
|
|
@@ -382,67 +434,4 @@ export class ArchiverDataStoreUpdater {
|
|
|
382
434
|
}
|
|
383
435
|
return true;
|
|
384
436
|
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Stores the functions that were broadcasted individually.
|
|
388
|
-
*
|
|
389
|
-
* @dev Beware that there is not a delete variant of this, since they are added to contract classes
|
|
390
|
-
* and will be deleted as part of the class if needed.
|
|
391
|
-
*/
|
|
392
|
-
private async storeBroadcastedIndividualFunctions(
|
|
393
|
-
allLogs: ContractClassLog[],
|
|
394
|
-
_blockNum: BlockNumber,
|
|
395
|
-
): Promise<boolean> {
|
|
396
|
-
// Filter out private and utility function broadcast events
|
|
397
|
-
const privateFnEvents = allLogs
|
|
398
|
-
.filter(log => PrivateFunctionBroadcastedEvent.isPrivateFunctionBroadcastedEvent(log))
|
|
399
|
-
.map(log => PrivateFunctionBroadcastedEvent.fromLog(log));
|
|
400
|
-
const utilityFnEvents = allLogs
|
|
401
|
-
.filter(log => UtilityFunctionBroadcastedEvent.isUtilityFunctionBroadcastedEvent(log))
|
|
402
|
-
.map(log => UtilityFunctionBroadcastedEvent.fromLog(log));
|
|
403
|
-
|
|
404
|
-
// Group all events by contract class id
|
|
405
|
-
for (const [classIdString, classEvents] of Object.entries(
|
|
406
|
-
groupBy([...privateFnEvents, ...utilityFnEvents], e => e.contractClassId.toString()),
|
|
407
|
-
)) {
|
|
408
|
-
const contractClassId = Fr.fromHexString(classIdString);
|
|
409
|
-
const contractClass = await this.store.getContractClass(contractClassId);
|
|
410
|
-
if (!contractClass) {
|
|
411
|
-
this.log.warn(`Skipping broadcasted functions as contract class ${contractClassId.toString()} was not found`);
|
|
412
|
-
continue;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// Split private and utility functions, and filter out invalid ones
|
|
416
|
-
const allFns = classEvents.map(e => e.toFunctionWithMembershipProof());
|
|
417
|
-
const privateFns = allFns.filter(
|
|
418
|
-
(fn): fn is ExecutablePrivateFunctionWithMembershipProof => 'utilityFunctionsTreeRoot' in fn,
|
|
419
|
-
);
|
|
420
|
-
const utilityFns = allFns.filter(
|
|
421
|
-
(fn): fn is UtilityFunctionWithMembershipProof => 'privateFunctionsArtifactTreeRoot' in fn,
|
|
422
|
-
);
|
|
423
|
-
|
|
424
|
-
const privateFunctionsWithValidity = await Promise.all(
|
|
425
|
-
privateFns.map(async fn => ({ fn, valid: await isValidPrivateFunctionMembershipProof(fn, contractClass) })),
|
|
426
|
-
);
|
|
427
|
-
const validPrivateFns = privateFunctionsWithValidity.filter(({ valid }) => valid).map(({ fn }) => fn);
|
|
428
|
-
const utilityFunctionsWithValidity = await Promise.all(
|
|
429
|
-
utilityFns.map(async fn => ({
|
|
430
|
-
fn,
|
|
431
|
-
valid: await isValidUtilityFunctionMembershipProof(fn, contractClass),
|
|
432
|
-
})),
|
|
433
|
-
);
|
|
434
|
-
const validUtilityFns = utilityFunctionsWithValidity.filter(({ valid }) => valid).map(({ fn }) => fn);
|
|
435
|
-
const validFnCount = validPrivateFns.length + validUtilityFns.length;
|
|
436
|
-
if (validFnCount !== allFns.length) {
|
|
437
|
-
this.log.warn(`Skipping ${allFns.length - validFnCount} invalid functions`);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Store the functions in the contract class in a single operation
|
|
441
|
-
if (validFnCount > 0) {
|
|
442
|
-
this.log.verbose(`Storing ${validFnCount} functions for contract class ${contractClassId.toString()}`);
|
|
443
|
-
}
|
|
444
|
-
return await this.store.addFunctions(contractClassId, validPrivateFns, validUtilityFns);
|
|
445
|
-
}
|
|
446
|
-
return true;
|
|
447
|
-
}
|
|
448
437
|
}
|
|
@@ -32,6 +32,7 @@ export class ArchiverInstrumentation {
|
|
|
32
32
|
private pruneCount: UpDownCounter;
|
|
33
33
|
|
|
34
34
|
private syncDurationPerBlock: Histogram;
|
|
35
|
+
private syncDurationPerCheckpoint: Histogram;
|
|
35
36
|
private syncBlockCount: UpDownCounter;
|
|
36
37
|
private manaPerBlock: Histogram;
|
|
37
38
|
private txsPerBlock: Histogram;
|
|
@@ -68,6 +69,8 @@ export class ArchiverInstrumentation {
|
|
|
68
69
|
|
|
69
70
|
this.syncDurationPerBlock = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_BLOCK);
|
|
70
71
|
|
|
72
|
+
this.syncDurationPerCheckpoint = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_CHECKPOINT);
|
|
73
|
+
|
|
71
74
|
this.syncBlockCount = createUpDownCounterWithDefault(meter, Metrics.ARCHIVER_SYNC_BLOCK_COUNT);
|
|
72
75
|
|
|
73
76
|
this.manaPerBlock = meter.createHistogram(Metrics.ARCHIVER_MANA_PER_BLOCK);
|
|
@@ -113,17 +116,26 @@ export class ArchiverInstrumentation {
|
|
|
113
116
|
return this.telemetry.isEnabled();
|
|
114
117
|
}
|
|
115
118
|
|
|
116
|
-
public
|
|
119
|
+
public processNewProposedBlock(syncTimePerBlock: number, block: L2Block) {
|
|
120
|
+
const attrs = { [Attributes.STATUS]: 'proposed' };
|
|
121
|
+
this.blockHeight.record(block.number, attrs);
|
|
117
122
|
this.syncDurationPerBlock.record(Math.ceil(syncTimePerBlock));
|
|
123
|
+
|
|
124
|
+
// Per block metrics
|
|
125
|
+
this.txCount.add(block.body.txEffects.length);
|
|
126
|
+
this.txsPerBlock.record(block.body.txEffects.length);
|
|
127
|
+
this.manaPerBlock.record(block.header.totalManaUsed.toNumber() / 1e6);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public processNewCheckpointedBlocks(syncTimePerCheckpoint: number, blocks: L2Block[]) {
|
|
131
|
+
if (blocks.length === 0) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
this.syncDurationPerCheckpoint.record(Math.ceil(syncTimePerCheckpoint));
|
|
118
136
|
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
|
|
119
137
|
this.checkpointHeight.record(Math.max(...blocks.map(b => b.checkpointNumber)));
|
|
120
138
|
this.syncBlockCount.add(blocks.length);
|
|
121
|
-
|
|
122
|
-
for (const block of blocks) {
|
|
123
|
-
this.txCount.add(block.body.txEffects.length);
|
|
124
|
-
this.txsPerBlock.record(block.body.txEffects.length);
|
|
125
|
-
this.manaPerBlock.record(block.header.totalManaUsed.toNumber() / 1e6);
|
|
126
|
-
}
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
public processNewMessages(count: number, syncPerMessageMs: number) {
|