@aztec/archiver 0.0.1-commit.8c0b8ff → 0.0.1-commit.8cb2d04d8
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 +6 -5
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +11 -5
- package/dest/config.d.ts +3 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -2
- package/dest/errors.d.ts +28 -2
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +36 -2
- package/dest/factory.d.ts +2 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +1 -3
- 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 +8 -5
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +26 -21
- package/dest/modules/data_source_base.d.ts +6 -4
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +10 -4
- package/dest/modules/data_store_updater.d.ts +5 -7
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +14 -56
- package/dest/modules/instrumentation.d.ts +15 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +27 -6
- package/dest/modules/l1_synchronizer.d.ts +3 -2
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +143 -131
- 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 +38 -4
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +187 -63
- 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 +1 -65
- package/dest/store/kv_archiver_store.d.ts +28 -13
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +33 -14
- 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 +27 -7
- 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 +47 -10
- 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 +20 -8
- 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 +36 -6
- 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 +7 -2
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +28 -3
- package/dest/test/noop_l1_archiver.d.ts +1 -1
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +0 -1
- package/package.json +13 -13
- package/src/archiver.ts +19 -10
- package/src/config.ts +9 -2
- package/src/errors.ts +60 -2
- package/src/factory.ts +1 -3
- package/src/l1/calldata_retriever.ts +2 -1
- package/src/l1/data_retrieval.ts +25 -21
- package/src/modules/data_source_base.ts +23 -4
- package/src/modules/data_store_updater.ts +17 -83
- package/src/modules/instrumentation.ts +39 -7
- package/src/modules/l1_synchronizer.ts +166 -168
- package/src/modules/validation.ts +2 -2
- package/src/store/block_store.ts +243 -73
- package/src/store/contract_class_store.ts +1 -103
- package/src/store/kv_archiver_store.ts +52 -24
- package/src/store/l2_tips_cache.ts +58 -13
- package/src/store/log_store.ts +62 -20
- package/src/store/message_store.ts +26 -9
- package/src/structs/inbox_message.ts +1 -1
- package/src/test/fake_l1_state.ts +53 -9
- package/src/test/mock_l1_to_l2_message_source.ts +1 -0
- package/src/test/mock_l2_block_source.ts +37 -2
- package/src/test/noop_l1_archiver.ts +0 -1
package/src/l1/data_retrieval.ts
CHANGED
|
@@ -144,7 +144,7 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
144
144
|
* @param blobClient - The blob client client for fetching blob data.
|
|
145
145
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
146
146
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
147
|
-
* @param contractAddresses - The contract addresses (governanceProposerAddress,
|
|
147
|
+
* @param contractAddresses - The contract addresses (governanceProposerAddress, slashingProposerAddress).
|
|
148
148
|
* @param instrumentation - The archiver instrumentation instance.
|
|
149
149
|
* @param logger - The logger instance.
|
|
150
150
|
* @param isHistoricalSync - Whether this is a historical sync.
|
|
@@ -265,6 +265,9 @@ async function processCheckpointProposedLogs(
|
|
|
265
265
|
checkpointNumber,
|
|
266
266
|
expectedHashes,
|
|
267
267
|
);
|
|
268
|
+
const { timestamp, parentBeaconBlockRoot } = await getL1Block(publicClient, log.l1BlockNumber);
|
|
269
|
+
const l1 = new L1PublishedData(log.l1BlockNumber, timestamp, log.l1BlockHash.toString());
|
|
270
|
+
|
|
268
271
|
const checkpointBlobData = await getCheckpointBlobDataFromBlobs(
|
|
269
272
|
blobClient,
|
|
270
273
|
checkpoint.blockHash,
|
|
@@ -272,12 +275,8 @@ async function processCheckpointProposedLogs(
|
|
|
272
275
|
checkpointNumber,
|
|
273
276
|
logger,
|
|
274
277
|
isHistoricalSync,
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const l1 = new L1PublishedData(
|
|
278
|
-
log.l1BlockNumber,
|
|
279
|
-
await getL1BlockTime(publicClient, log.l1BlockNumber),
|
|
280
|
-
log.l1BlockHash.toString(),
|
|
278
|
+
parentBeaconBlockRoot,
|
|
279
|
+
timestamp,
|
|
281
280
|
);
|
|
282
281
|
|
|
283
282
|
retrievedCheckpoints.push({ ...checkpoint, checkpointBlobData, l1, chainId, version });
|
|
@@ -298,9 +297,12 @@ async function processCheckpointProposedLogs(
|
|
|
298
297
|
return retrievedCheckpoints;
|
|
299
298
|
}
|
|
300
299
|
|
|
301
|
-
export async function
|
|
300
|
+
export async function getL1Block(
|
|
301
|
+
publicClient: ViemPublicClient,
|
|
302
|
+
blockNumber: bigint,
|
|
303
|
+
): Promise<{ timestamp: bigint; parentBeaconBlockRoot: string | undefined }> {
|
|
302
304
|
const block = await publicClient.getBlock({ blockNumber, includeTransactions: false });
|
|
303
|
-
return block.timestamp;
|
|
305
|
+
return { timestamp: block.timestamp, parentBeaconBlockRoot: block.parentBeaconBlockRoot };
|
|
304
306
|
}
|
|
305
307
|
|
|
306
308
|
export async function getCheckpointBlobDataFromBlobs(
|
|
@@ -310,8 +312,14 @@ export async function getCheckpointBlobDataFromBlobs(
|
|
|
310
312
|
checkpointNumber: CheckpointNumber,
|
|
311
313
|
logger: Logger,
|
|
312
314
|
isHistoricalSync: boolean,
|
|
315
|
+
parentBeaconBlockRoot?: string,
|
|
316
|
+
l1BlockTimestamp?: bigint,
|
|
313
317
|
): Promise<CheckpointBlobData> {
|
|
314
|
-
const blobBodies = await blobClient.getBlobSidecar(blockHash, blobHashes, {
|
|
318
|
+
const blobBodies = await blobClient.getBlobSidecar(blockHash, blobHashes, {
|
|
319
|
+
isHistoricalSync,
|
|
320
|
+
parentBeaconBlockRoot,
|
|
321
|
+
l1BlockTimestamp,
|
|
322
|
+
});
|
|
315
323
|
if (blobBodies.length === 0) {
|
|
316
324
|
throw new NoBlobBodiesFoundError(checkpointNumber);
|
|
317
325
|
}
|
|
@@ -336,14 +344,10 @@ export async function getCheckpointBlobDataFromBlobs(
|
|
|
336
344
|
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
|
|
337
345
|
export async function retrieveL1ToL2Message(
|
|
338
346
|
inbox: InboxContract,
|
|
339
|
-
|
|
340
|
-
fromBlock: bigint,
|
|
341
|
-
toBlock: bigint,
|
|
347
|
+
message: InboxMessage,
|
|
342
348
|
): Promise<InboxMessage | undefined> {
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
const messages = mapLogsInboxMessage(logs);
|
|
346
|
-
return messages.length > 0 ? messages[0] : undefined;
|
|
349
|
+
const log = await inbox.getMessageSentEventByHash(message.leaf.toString(), message.l1BlockHash.toString());
|
|
350
|
+
return log && mapLogInboxMessage(log);
|
|
347
351
|
}
|
|
348
352
|
|
|
349
353
|
/**
|
|
@@ -366,22 +370,22 @@ export async function retrieveL1ToL2Messages(
|
|
|
366
370
|
break;
|
|
367
371
|
}
|
|
368
372
|
|
|
369
|
-
retrievedL1ToL2Messages.push(...
|
|
373
|
+
retrievedL1ToL2Messages.push(...messageSentLogs.map(mapLogInboxMessage));
|
|
370
374
|
searchStartBlock = messageSentLogs.at(-1)!.l1BlockNumber + 1n;
|
|
371
375
|
}
|
|
372
376
|
|
|
373
377
|
return retrievedL1ToL2Messages;
|
|
374
378
|
}
|
|
375
379
|
|
|
376
|
-
function
|
|
377
|
-
return
|
|
380
|
+
function mapLogInboxMessage(log: MessageSentLog): InboxMessage {
|
|
381
|
+
return {
|
|
378
382
|
index: log.args.index,
|
|
379
383
|
leaf: log.args.leaf,
|
|
380
384
|
l1BlockNumber: log.l1BlockNumber,
|
|
381
385
|
l1BlockHash: log.l1BlockHash,
|
|
382
386
|
checkpointNumber: log.args.checkpointNumber,
|
|
383
387
|
rollingHash: log.args.rollingHash,
|
|
384
|
-
}
|
|
388
|
+
};
|
|
385
389
|
}
|
|
386
390
|
|
|
387
391
|
/** Retrieves L2ProofVerified events from the rollup contract. */
|
|
@@ -6,7 +6,13 @@ import { isDefined } from '@aztec/foundation/types';
|
|
|
6
6
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
7
7
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
8
|
import { type BlockData, type BlockHash, CheckpointedL2Block, L2Block, type L2Tips } from '@aztec/stdlib/block';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
Checkpoint,
|
|
11
|
+
type CheckpointData,
|
|
12
|
+
type CommonCheckpointData,
|
|
13
|
+
type ProposedCheckpointData,
|
|
14
|
+
PublishedCheckpoint,
|
|
15
|
+
} from '@aztec/stdlib/checkpoint';
|
|
10
16
|
import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
11
17
|
import { type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
12
18
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
@@ -157,6 +163,14 @@ export abstract class ArchiverDataSourceBase
|
|
|
157
163
|
return this.store.getSettledTxReceipt(txHash, this.l1Constants);
|
|
158
164
|
}
|
|
159
165
|
|
|
166
|
+
public getProposedCheckpoint(): Promise<CommonCheckpointData | undefined> {
|
|
167
|
+
return this.store.getProposedCheckpoint();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
public getProposedCheckpointOnly(): Promise<ProposedCheckpointData | undefined> {
|
|
171
|
+
return this.store.getProposedCheckpointOnly();
|
|
172
|
+
}
|
|
173
|
+
|
|
160
174
|
public isPendingChainInvalid(): Promise<boolean> {
|
|
161
175
|
return this.getPendingChainValidationStatus().then(status => !status.valid);
|
|
162
176
|
}
|
|
@@ -165,16 +179,21 @@ export abstract class ArchiverDataSourceBase
|
|
|
165
179
|
return (await this.store.getPendingChainValidationStatus()) ?? { valid: true };
|
|
166
180
|
}
|
|
167
181
|
|
|
168
|
-
public getPrivateLogsByTags(
|
|
169
|
-
|
|
182
|
+
public getPrivateLogsByTags(
|
|
183
|
+
tags: SiloedTag[],
|
|
184
|
+
page?: number,
|
|
185
|
+
upToBlockNumber?: BlockNumber,
|
|
186
|
+
): Promise<TxScopedL2Log[][]> {
|
|
187
|
+
return this.store.getPrivateLogsByTags(tags, page, upToBlockNumber);
|
|
170
188
|
}
|
|
171
189
|
|
|
172
190
|
public getPublicLogsByTagsFromContract(
|
|
173
191
|
contractAddress: AztecAddress,
|
|
174
192
|
tags: Tag[],
|
|
175
193
|
page?: number,
|
|
194
|
+
upToBlockNumber?: BlockNumber,
|
|
176
195
|
): Promise<TxScopedL2Log[][]> {
|
|
177
|
-
return this.store.getPublicLogsByTagsFromContract(contractAddress, tags, page);
|
|
196
|
+
return this.store.getPublicLogsByTagsFromContract(contractAddress, tags, page, upToBlockNumber);
|
|
178
197
|
}
|
|
179
198
|
|
|
180
199
|
public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
|
|
@@ -1,32 +1,21 @@
|
|
|
1
1
|
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { filterAsync } from '@aztec/foundation/collection';
|
|
3
|
-
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import {
|
|
6
|
-
ContractClassPublishedEvent,
|
|
7
|
-
PrivateFunctionBroadcastedEvent,
|
|
8
|
-
UtilityFunctionBroadcastedEvent,
|
|
9
|
-
} from '@aztec/protocol-contracts/class-registry';
|
|
4
|
+
import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
|
|
10
5
|
import {
|
|
11
6
|
ContractInstancePublishedEvent,
|
|
12
7
|
ContractInstanceUpdatedEvent,
|
|
13
8
|
} from '@aztec/protocol-contracts/instance-registry';
|
|
14
9
|
import type { L2Block, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
15
|
-
import { type PublishedCheckpoint, validateCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
10
|
+
import { type ProposedCheckpointInput, type PublishedCheckpoint, validateCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
16
11
|
import {
|
|
17
12
|
type ContractClassPublicWithCommitment,
|
|
18
|
-
type ExecutablePrivateFunctionWithMembershipProof,
|
|
19
|
-
type UtilityFunctionWithMembershipProof,
|
|
20
13
|
computeContractAddressFromInstance,
|
|
21
14
|
computeContractClassId,
|
|
22
|
-
isValidPrivateFunctionMembershipProof,
|
|
23
|
-
isValidUtilityFunctionMembershipProof,
|
|
24
15
|
} from '@aztec/stdlib/contract';
|
|
25
16
|
import type { ContractClassLog, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
26
17
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
27
18
|
|
|
28
|
-
import groupBy from 'lodash.groupby';
|
|
29
|
-
|
|
30
19
|
import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
|
|
31
20
|
import type { L2TipsCache } from '../store/l2_tips_cache.js';
|
|
32
21
|
|
|
@@ -57,8 +46,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
57
46
|
/**
|
|
58
47
|
* Adds a proposed block to the store with contract class/instance extraction from logs.
|
|
59
48
|
* This is an uncheckpointed block that has been proposed by the sequencer but not yet included in a checkpoint on L1.
|
|
60
|
-
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events
|
|
61
|
-
* and individually broadcasted functions from the block logs.
|
|
49
|
+
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events from the block logs.
|
|
62
50
|
*
|
|
63
51
|
* @param block - The proposed L2 block to add.
|
|
64
52
|
* @param pendingChainValidationStatus - Optional validation status to set.
|
|
@@ -90,8 +78,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
90
78
|
* Reconciles local blocks with incoming checkpoints from L1.
|
|
91
79
|
* Adds new checkpoints to the store with contract class/instance extraction from logs.
|
|
92
80
|
* Prunes any local blocks that conflict with checkpoint data (by comparing archive roots).
|
|
93
|
-
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events
|
|
94
|
-
* and individually broadcasted functions from the checkpoint block logs.
|
|
81
|
+
* Extracts ContractClassPublished, ContractInstancePublished, ContractInstanceUpdated events from the checkpoint block logs.
|
|
95
82
|
*
|
|
96
83
|
* @param checkpoints - The published checkpoints to add.
|
|
97
84
|
* @param pendingChainValidationStatus - Optional validation status to set.
|
|
@@ -131,6 +118,15 @@ export class ArchiverDataStoreUpdater {
|
|
|
131
118
|
return result;
|
|
132
119
|
}
|
|
133
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
|
+
|
|
134
130
|
/**
|
|
135
131
|
* Checks for local proposed blocks that do not match the ones to be checkpointed and prunes them.
|
|
136
132
|
* This method handles multiple checkpoints but returns after pruning the first conflict found.
|
|
@@ -224,6 +220,10 @@ export class ArchiverDataStoreUpdater {
|
|
|
224
220
|
}
|
|
225
221
|
|
|
226
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
|
+
|
|
227
227
|
await this.l2TipsCache?.refresh();
|
|
228
228
|
return result;
|
|
229
229
|
});
|
|
@@ -316,9 +316,6 @@ export class ArchiverDataStoreUpdater {
|
|
|
316
316
|
this.updatePublishedContractClasses(contractClassLogs, block.number, operation),
|
|
317
317
|
this.updateDeployedContractInstances(privateLogs, block.number, operation),
|
|
318
318
|
this.updateUpdatedContractInstances(publicLogs, block.header.globalVariables.timestamp, operation),
|
|
319
|
-
operation === Operation.Store
|
|
320
|
-
? this.storeBroadcastedIndividualFunctions(contractClassLogs, block.number)
|
|
321
|
-
: Promise.resolve(true),
|
|
322
319
|
])
|
|
323
320
|
).every(Boolean);
|
|
324
321
|
}
|
|
@@ -437,67 +434,4 @@ export class ArchiverDataStoreUpdater {
|
|
|
437
434
|
}
|
|
438
435
|
return true;
|
|
439
436
|
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Stores the functions that were broadcasted individually.
|
|
443
|
-
*
|
|
444
|
-
* @dev Beware that there is not a delete variant of this, since they are added to contract classes
|
|
445
|
-
* and will be deleted as part of the class if needed.
|
|
446
|
-
*/
|
|
447
|
-
private async storeBroadcastedIndividualFunctions(
|
|
448
|
-
allLogs: ContractClassLog[],
|
|
449
|
-
_blockNum: BlockNumber,
|
|
450
|
-
): Promise<boolean> {
|
|
451
|
-
// Filter out private and utility function broadcast events
|
|
452
|
-
const privateFnEvents = allLogs
|
|
453
|
-
.filter(log => PrivateFunctionBroadcastedEvent.isPrivateFunctionBroadcastedEvent(log))
|
|
454
|
-
.map(log => PrivateFunctionBroadcastedEvent.fromLog(log));
|
|
455
|
-
const utilityFnEvents = allLogs
|
|
456
|
-
.filter(log => UtilityFunctionBroadcastedEvent.isUtilityFunctionBroadcastedEvent(log))
|
|
457
|
-
.map(log => UtilityFunctionBroadcastedEvent.fromLog(log));
|
|
458
|
-
|
|
459
|
-
// Group all events by contract class id
|
|
460
|
-
for (const [classIdString, classEvents] of Object.entries(
|
|
461
|
-
groupBy([...privateFnEvents, ...utilityFnEvents], e => e.contractClassId.toString()),
|
|
462
|
-
)) {
|
|
463
|
-
const contractClassId = Fr.fromHexString(classIdString);
|
|
464
|
-
const contractClass = await this.store.getContractClass(contractClassId);
|
|
465
|
-
if (!contractClass) {
|
|
466
|
-
this.log.warn(`Skipping broadcasted functions as contract class ${contractClassId.toString()} was not found`);
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// Split private and utility functions, and filter out invalid ones
|
|
471
|
-
const allFns = classEvents.map(e => e.toFunctionWithMembershipProof());
|
|
472
|
-
const privateFns = allFns.filter(
|
|
473
|
-
(fn): fn is ExecutablePrivateFunctionWithMembershipProof => 'utilityFunctionsTreeRoot' in fn,
|
|
474
|
-
);
|
|
475
|
-
const utilityFns = allFns.filter(
|
|
476
|
-
(fn): fn is UtilityFunctionWithMembershipProof => 'privateFunctionsArtifactTreeRoot' in fn,
|
|
477
|
-
);
|
|
478
|
-
|
|
479
|
-
const privateFunctionsWithValidity = await Promise.all(
|
|
480
|
-
privateFns.map(async fn => ({ fn, valid: await isValidPrivateFunctionMembershipProof(fn, contractClass) })),
|
|
481
|
-
);
|
|
482
|
-
const validPrivateFns = privateFunctionsWithValidity.filter(({ valid }) => valid).map(({ fn }) => fn);
|
|
483
|
-
const utilityFunctionsWithValidity = await Promise.all(
|
|
484
|
-
utilityFns.map(async fn => ({
|
|
485
|
-
fn,
|
|
486
|
-
valid: await isValidUtilityFunctionMembershipProof(fn, contractClass),
|
|
487
|
-
})),
|
|
488
|
-
);
|
|
489
|
-
const validUtilityFns = utilityFunctionsWithValidity.filter(({ valid }) => valid).map(({ fn }) => fn);
|
|
490
|
-
const validFnCount = validPrivateFns.length + validUtilityFns.length;
|
|
491
|
-
if (validFnCount !== allFns.length) {
|
|
492
|
-
this.log.warn(`Skipping ${allFns.length - validFnCount} invalid functions`);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
// Store the functions in the contract class in a single operation
|
|
496
|
-
if (validFnCount > 0) {
|
|
497
|
-
this.log.verbose(`Storing ${validFnCount} functions for contract class ${contractClassId.toString()}`);
|
|
498
|
-
}
|
|
499
|
-
await this.store.addFunctions(contractClassId, validPrivateFns, validUtilityFns);
|
|
500
|
-
}
|
|
501
|
-
return true;
|
|
502
|
-
}
|
|
503
437
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
3
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
3
4
|
import type { CheckpointData } from '@aztec/stdlib/checkpoint';
|
|
5
|
+
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
6
|
+
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
4
7
|
import {
|
|
5
8
|
Attributes,
|
|
6
9
|
type Gauge,
|
|
@@ -29,6 +32,7 @@ export class ArchiverInstrumentation {
|
|
|
29
32
|
private pruneCount: UpDownCounter;
|
|
30
33
|
|
|
31
34
|
private syncDurationPerBlock: Histogram;
|
|
35
|
+
private syncDurationPerCheckpoint: Histogram;
|
|
32
36
|
private syncBlockCount: UpDownCounter;
|
|
33
37
|
private manaPerBlock: Histogram;
|
|
34
38
|
private txsPerBlock: Histogram;
|
|
@@ -38,6 +42,8 @@ export class ArchiverInstrumentation {
|
|
|
38
42
|
|
|
39
43
|
private blockProposalTxTargetCount: UpDownCounter;
|
|
40
44
|
|
|
45
|
+
private checkpointL1InclusionDelay: Histogram;
|
|
46
|
+
|
|
41
47
|
private log = createLogger('archiver:instrumentation');
|
|
42
48
|
|
|
43
49
|
private constructor(
|
|
@@ -63,6 +69,8 @@ export class ArchiverInstrumentation {
|
|
|
63
69
|
|
|
64
70
|
this.syncDurationPerBlock = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_BLOCK);
|
|
65
71
|
|
|
72
|
+
this.syncDurationPerCheckpoint = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_CHECKPOINT);
|
|
73
|
+
|
|
66
74
|
this.syncBlockCount = createUpDownCounterWithDefault(meter, Metrics.ARCHIVER_SYNC_BLOCK_COUNT);
|
|
67
75
|
|
|
68
76
|
this.manaPerBlock = meter.createHistogram(Metrics.ARCHIVER_MANA_PER_BLOCK);
|
|
@@ -85,6 +93,8 @@ export class ArchiverInstrumentation {
|
|
|
85
93
|
},
|
|
86
94
|
);
|
|
87
95
|
|
|
96
|
+
this.checkpointL1InclusionDelay = meter.createHistogram(Metrics.ARCHIVER_CHECKPOINT_L1_INCLUSION_DELAY);
|
|
97
|
+
|
|
88
98
|
this.dbMetrics = new LmdbMetrics(
|
|
89
99
|
meter,
|
|
90
100
|
{
|
|
@@ -106,17 +116,26 @@ export class ArchiverInstrumentation {
|
|
|
106
116
|
return this.telemetry.isEnabled();
|
|
107
117
|
}
|
|
108
118
|
|
|
109
|
-
public
|
|
119
|
+
public processNewProposedBlock(syncTimePerBlock: number, block: L2Block) {
|
|
120
|
+
const attrs = { [Attributes.STATUS]: 'proposed' };
|
|
121
|
+
this.blockHeight.record(block.number, attrs);
|
|
110
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));
|
|
111
136
|
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
|
|
112
137
|
this.checkpointHeight.record(Math.max(...blocks.map(b => b.checkpointNumber)));
|
|
113
138
|
this.syncBlockCount.add(blocks.length);
|
|
114
|
-
|
|
115
|
-
for (const block of blocks) {
|
|
116
|
-
this.txCount.add(block.body.txEffects.length);
|
|
117
|
-
this.txsPerBlock.record(block.body.txEffects.length);
|
|
118
|
-
this.manaPerBlock.record(block.header.totalManaUsed.toNumber() / 1e6);
|
|
119
|
-
}
|
|
120
139
|
}
|
|
121
140
|
|
|
122
141
|
public processNewMessages(count: number, syncPerMessageMs: number) {
|
|
@@ -161,4 +180,17 @@ export class ArchiverInstrumentation {
|
|
|
161
180
|
[Attributes.L1_BLOCK_PROPOSAL_USED_TRACE]: usedTrace,
|
|
162
181
|
});
|
|
163
182
|
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Records L1 inclusion timing for a checkpoint observed on L1 (seconds into the L2 slot).
|
|
186
|
+
*/
|
|
187
|
+
public processCheckpointL1Timing(data: {
|
|
188
|
+
slotNumber: SlotNumber;
|
|
189
|
+
l1Timestamp: bigint;
|
|
190
|
+
l1Constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'>;
|
|
191
|
+
}): void {
|
|
192
|
+
const slotStartTs = getTimestampForSlot(data.slotNumber, data.l1Constants);
|
|
193
|
+
const inclusionDelaySeconds = Number(data.l1Timestamp - slotStartTs);
|
|
194
|
+
this.checkpointL1InclusionDelay.record(inclusionDelaySeconds);
|
|
195
|
+
}
|
|
164
196
|
}
|