@aztec/archiver 0.0.1-commit.2f68f620 → 0.0.1-commit.321f6a9
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 +22 -4
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +79 -35
- package/dest/config.d.ts +5 -4
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +27 -5
- package/dest/factory.d.ts +8 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +37 -3
- package/dest/l1/calldata_retriever.d.ts +8 -1
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +7 -6
- package/dest/l1/data_retrieval.d.ts +7 -2
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/modules/contract_data_source_adapter.d.ts +2 -2
- package/dest/modules/contract_data_source_adapter.d.ts.map +1 -1
- package/dest/modules/contract_data_source_adapter.js +1 -9
- package/dest/modules/data_source_base.d.ts +2 -3
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +9 -35
- package/dest/modules/data_store_updater.d.ts +1 -1
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +4 -3
- package/dest/modules/instrumentation.d.ts +9 -1
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +23 -2
- package/dest/modules/l1_synchronizer.d.ts +3 -3
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +78 -41
- package/dest/modules/validation.d.ts +29 -7
- package/dest/modules/validation.d.ts.map +1 -1
- package/dest/modules/validation.js +31 -13
- package/dest/store/block_store.d.ts +20 -11
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +43 -25
- package/dest/store/contract_class_store.d.ts +1 -1
- package/dest/store/contract_class_store.d.ts.map +1 -1
- package/dest/store/contract_class_store.js +19 -1
- 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 +18 -1
- 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 +3 -3
- package/dest/store/log_store_codec.d.ts +9 -1
- package/dest/store/log_store_codec.d.ts.map +1 -1
- package/dest/store/log_store_codec.js +9 -0
- package/dest/test/fake_l1_state.js +3 -3
- 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 +1 -2
- package/dest/test/mock_l2_block_source.d.ts +1 -4
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +8 -22
- package/dest/test/mock_structs.d.ts +1 -1
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +2 -2
- package/dest/test/noop_l1_archiver.d.ts +7 -3
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +9 -6
- package/package.json +14 -13
- package/src/archiver.ts +107 -41
- package/src/config.ts +34 -9
- package/src/factory.ts +46 -4
- package/src/l1/calldata_retriever.ts +13 -6
- package/src/l1/data_retrieval.ts +8 -1
- package/src/modules/contract_data_source_adapter.ts +1 -10
- package/src/modules/data_source_base.ts +9 -38
- package/src/modules/data_store_updater.ts +4 -3
- package/src/modules/instrumentation.ts +15 -2
- package/src/modules/l1_synchronizer.ts +120 -57
- package/src/modules/validation.ts +71 -15
- package/src/store/block_store.ts +42 -31
- package/src/store/contract_class_store.ts +19 -1
- package/src/store/contract_instance_store.ts +18 -1
- package/src/store/log_store.ts +3 -2
- package/src/store/log_store_codec.ts +11 -0
- package/src/test/fake_l1_state.ts +3 -3
- package/src/test/mock_l1_to_l2_message_source.ts +0 -1
- package/src/test/mock_l2_block_source.ts +8 -22
- package/src/test/mock_structs.ts +5 -2
- package/src/test/noop_l1_archiver.ts +15 -5
package/src/factory.ts
CHANGED
|
@@ -12,11 +12,16 @@ import { DateProvider } from '@aztec/foundation/timer';
|
|
|
12
12
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
13
13
|
import { protocolContractNames } from '@aztec/protocol-contracts';
|
|
14
14
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
15
|
+
import { getPublishableStandardContracts } from '@aztec/standard-contracts';
|
|
15
16
|
import { FunctionType, decodeFunctionSignature } from '@aztec/stdlib/abi';
|
|
16
17
|
import type { ArchiverEmitter, BlockHash } from '@aztec/stdlib/block';
|
|
18
|
+
import { DEFAULT_BLOCK_DURATION_MS } from '@aztec/stdlib/config';
|
|
17
19
|
import { type ContractClassPublicWithCommitment, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
|
|
18
20
|
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
19
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
DEFAULT_ORPHAN_PRUNE_NO_PROPOSAL_TOLERANCE,
|
|
23
|
+
getDefaultCheckpointProposalSyncGrace,
|
|
24
|
+
} from '@aztec/stdlib/timetable';
|
|
20
25
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
21
26
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
22
27
|
|
|
@@ -58,12 +63,15 @@ export async function createArchiverStore(
|
|
|
58
63
|
export async function createArchiver(
|
|
59
64
|
config: ArchiverConfig & DataStoreConfig,
|
|
60
65
|
deps: ArchiverDeps,
|
|
61
|
-
opts: { blockUntilSync: boolean
|
|
66
|
+
opts: { blockUntilSync: boolean } = { blockUntilSync: true },
|
|
62
67
|
initialHeader: BlockHeader,
|
|
63
68
|
initialBlockHash: BlockHash,
|
|
64
69
|
): Promise<Archiver> {
|
|
65
70
|
const archiverStore = await createArchiverStore(config, initialBlockHash);
|
|
66
71
|
await registerProtocolContracts(archiverStore);
|
|
72
|
+
if (config.testPreloadStandardContracts) {
|
|
73
|
+
await registerStandardContracts(archiverStore);
|
|
74
|
+
}
|
|
67
75
|
|
|
68
76
|
// Create Ethereum clients
|
|
69
77
|
const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
@@ -132,8 +140,12 @@ export async function createArchiver(
|
|
|
132
140
|
maxAllowedEthClientDriftSeconds: 300,
|
|
133
141
|
ethereumAllowNoDebugHosts: false,
|
|
134
142
|
skipHistoricalLogsCheck: false,
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
checkpointProposalSyncGrace:
|
|
144
|
+
config.checkpointProposalSyncGraceSeconds ??
|
|
145
|
+
getDefaultCheckpointProposalSyncGrace((config.blockDurationMs ?? DEFAULT_BLOCK_DURATION_MS) / 1000),
|
|
146
|
+
orphanPruneNoProposalTolerance: DEFAULT_ORPHAN_PRUNE_NO_PROPOSAL_TOLERANCE,
|
|
147
|
+
skipOrphanProposedBlockPruning: false,
|
|
148
|
+
blockDuration: (config.blockDurationMs ?? DEFAULT_BLOCK_DURATION_MS) / 1000,
|
|
137
149
|
},
|
|
138
150
|
mapArchiverConfig(config),
|
|
139
151
|
);
|
|
@@ -219,3 +231,33 @@ export async function registerProtocolContracts(stores: ArchiverDataStores) {
|
|
|
219
231
|
await stores.contractInstances.addContractInstances([contract.instance], BlockNumber(blockNumber));
|
|
220
232
|
}
|
|
221
233
|
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Preloads the standard contracts (AuthRegistry, PublicChecks, HandshakeRegistry) into the archiver store at block 0,
|
|
237
|
+
* mirroring {@link registerProtocolContracts}. Only invoked for test environments (via `testPreloadStandardContracts`),
|
|
238
|
+
* which also seed the matching registration/deployment nullifiers into the genesis nullifier tree so the store and tree
|
|
239
|
+
* stay consistent. Idempotent — skips contracts that already exist (e.g. on node restart).
|
|
240
|
+
*/
|
|
241
|
+
export async function registerStandardContracts(stores: ArchiverDataStores) {
|
|
242
|
+
const blockNumber = 0;
|
|
243
|
+
for (const contract of await getPublishableStandardContracts()) {
|
|
244
|
+
// Skip if already registered (happens on node restart with a persisted store).
|
|
245
|
+
if (await stores.contractClasses.getContractClass(contract.contractClass.id)) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const publicBytecodeCommitment = await computePublicBytecodeCommitment(contract.contractClass.packedBytecode);
|
|
250
|
+
const contractClassPublic: ContractClassPublicWithCommitment = {
|
|
251
|
+
...contract.contractClass,
|
|
252
|
+
publicBytecodeCommitment,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const publicFunctionSignatures = contract.artifact.functions
|
|
256
|
+
.filter(fn => fn.functionType === FunctionType.PUBLIC)
|
|
257
|
+
.map(fn => decodeFunctionSignature(fn.name, fn.parameters));
|
|
258
|
+
|
|
259
|
+
await stores.functionNames.register(publicFunctionSignatures);
|
|
260
|
+
await stores.contractClasses.addContractClasses([contractClassPublic], BlockNumber(blockNumber));
|
|
261
|
+
await stores.contractInstances.addContractInstances([contract.instance], BlockNumber(blockNumber));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -34,6 +34,12 @@ type CheckpointData = {
|
|
|
34
34
|
archiveRoot: Fr;
|
|
35
35
|
header: CheckpointHeader;
|
|
36
36
|
attestations: CommitteeAttestation[];
|
|
37
|
+
/**
|
|
38
|
+
* The exact packed `CommitteeAttestations` tuple as it appears in the propose calldata, preserved
|
|
39
|
+
* verbatim (never re-derived from {@link attestations}) so invalidation evidence stays byte-faithful to
|
|
40
|
+
* the on-chain `attestationsHash`.
|
|
41
|
+
*/
|
|
42
|
+
verbatimAttestations: ViemCommitteeAttestations;
|
|
37
43
|
blockHash: string;
|
|
38
44
|
feeAssetPriceModifier: bigint;
|
|
39
45
|
};
|
|
@@ -406,14 +412,14 @@ export class CalldataRetriever {
|
|
|
406
412
|
return undefined;
|
|
407
413
|
}
|
|
408
414
|
|
|
409
|
-
const [decodedArgs,
|
|
415
|
+
const [decodedArgs, verbatimAttestations] = args! as readonly [
|
|
410
416
|
{ archive: Hex; oracleInput: { feeAssetPriceModifier: bigint }; header: ViemHeader },
|
|
411
417
|
ViemCommitteeAttestations,
|
|
412
418
|
...unknown[],
|
|
413
419
|
];
|
|
414
420
|
|
|
415
421
|
// Verify attestationsHash
|
|
416
|
-
const computedAttestationsHash = this.computeAttestationsHash(
|
|
422
|
+
const computedAttestationsHash = this.computeAttestationsHash(verbatimAttestations);
|
|
417
423
|
if (
|
|
418
424
|
!Buffer.from(hexToBytes(computedAttestationsHash)).equals(
|
|
419
425
|
Buffer.from(hexToBytes(expectedHashes.attestationsHash)),
|
|
@@ -441,7 +447,7 @@ export class CalldataRetriever {
|
|
|
441
447
|
return undefined;
|
|
442
448
|
}
|
|
443
449
|
|
|
444
|
-
const attestations = CommitteeAttestation.fromPacked(
|
|
450
|
+
const attestations = CommitteeAttestation.fromPacked(verbatimAttestations, this.targetCommitteeSize);
|
|
445
451
|
|
|
446
452
|
this.logger.trace(`Validated and decoded propose calldata for checkpoint ${checkpointNumber}`, {
|
|
447
453
|
checkpointNumber,
|
|
@@ -449,7 +455,7 @@ export class CalldataRetriever {
|
|
|
449
455
|
header: decodedArgs.header,
|
|
450
456
|
l1BlockHash: blockHash,
|
|
451
457
|
attestations,
|
|
452
|
-
|
|
458
|
+
verbatimAttestations,
|
|
453
459
|
targetCommitteeSize: this.targetCommitteeSize,
|
|
454
460
|
});
|
|
455
461
|
|
|
@@ -458,6 +464,7 @@ export class CalldataRetriever {
|
|
|
458
464
|
archiveRoot,
|
|
459
465
|
header,
|
|
460
466
|
attestations,
|
|
467
|
+
verbatimAttestations,
|
|
461
468
|
blockHash,
|
|
462
469
|
feeAssetPriceModifier,
|
|
463
470
|
};
|
|
@@ -467,8 +474,8 @@ export class CalldataRetriever {
|
|
|
467
474
|
}
|
|
468
475
|
|
|
469
476
|
/** Computes the keccak256 hash of ABI-encoded CommitteeAttestations. */
|
|
470
|
-
private computeAttestationsHash(
|
|
471
|
-
return keccak256(encodeAbiParameters([this.getCommitteeAttestationsStructDef()], [
|
|
477
|
+
private computeAttestationsHash(verbatimAttestations: ViemCommitteeAttestations): Hex {
|
|
478
|
+
return keccak256(encodeAbiParameters([this.getCommitteeAttestationsStructDef()], [verbatimAttestations]));
|
|
472
479
|
}
|
|
473
480
|
|
|
474
481
|
/** Computes the keccak256 payload digest from the checkpoint header, archive root, and fee asset price modifier. */
|
package/src/l1/data_retrieval.ts
CHANGED
|
@@ -12,6 +12,8 @@ import type {
|
|
|
12
12
|
InboxContract,
|
|
13
13
|
MessageSentLog,
|
|
14
14
|
RollupContract,
|
|
15
|
+
ViemCommitteeAttestations,
|
|
16
|
+
ViemHeader,
|
|
15
17
|
} from '@aztec/ethereum/contracts';
|
|
16
18
|
import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
17
19
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
@@ -55,6 +57,11 @@ export type RetrievedCheckpointFromCalldata = RetrievedCheckpointBase & {
|
|
|
55
57
|
blobHashes: Buffer[];
|
|
56
58
|
/** Parent beacon block root from the L1 block, used for blob fetching. */
|
|
57
59
|
parentBeaconBlockRoot: string | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* The exact packed `CommitteeAttestations` tuple from the propose calldata, carried verbatim so that
|
|
62
|
+
* attestation validation can attach byte-faithful invalidation evidence to a negative result.
|
|
63
|
+
*/
|
|
64
|
+
verbatimAttestations: ViemCommitteeAttestations;
|
|
58
65
|
};
|
|
59
66
|
|
|
60
67
|
export async function retrievedToPublishedCheckpoint({
|
|
@@ -460,7 +467,7 @@ export async function getProofFromSubmitProofTx(
|
|
|
460
467
|
start: bigint;
|
|
461
468
|
end: bigint;
|
|
462
469
|
args: EpochProofPublicInputArgs;
|
|
463
|
-
|
|
470
|
+
headers: readonly ViemHeader[];
|
|
464
471
|
proof: Hex;
|
|
465
472
|
},
|
|
466
473
|
];
|
|
@@ -28,16 +28,7 @@ export class ArchiverContractDataSourceAdapter implements ContractDataSource {
|
|
|
28
28
|
return this.stores.contractClasses.getBytecodeCommitment(id);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
public
|
|
32
|
-
address: AztecAddress,
|
|
33
|
-
maybeTimestamp?: UInt64,
|
|
34
|
-
): Promise<ContractInstanceWithAddress | undefined> {
|
|
35
|
-
let timestamp = maybeTimestamp;
|
|
36
|
-
if (timestamp === undefined) {
|
|
37
|
-
const latest = await this.stores.blocks.getLatestL2BlockNumber();
|
|
38
|
-
const blockData = latest > 0 ? await this.stores.blocks.getBlockData({ number: latest }) : undefined;
|
|
39
|
-
timestamp = blockData ? blockData.header.globalVariables.timestamp : 0n;
|
|
40
|
-
}
|
|
31
|
+
public getContract(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
41
32
|
return this.stores.contractInstances.getContractInstance(address, timestamp);
|
|
42
33
|
}
|
|
43
34
|
|
|
@@ -224,23 +224,6 @@ export abstract class ArchiverDataSourceBase
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
/**
|
|
228
|
-
* Resolves a {@link CheckpointsQuery} to a concrete `{from, limit}` pair used by BlockStore,
|
|
229
|
-
* or undefined when the epoch has no checkpoints.
|
|
230
|
-
*/
|
|
231
|
-
private async resolveCheckpointsQuery(
|
|
232
|
-
query: CheckpointsQuery,
|
|
233
|
-
): Promise<{ from: CheckpointNumber; limit: number } | undefined> {
|
|
234
|
-
if ('from' in query) {
|
|
235
|
-
return query;
|
|
236
|
-
}
|
|
237
|
-
const numbers = await this.getCheckpointNumbersForEpoch(query.epoch);
|
|
238
|
-
if (numbers.length === 0) {
|
|
239
|
-
return undefined;
|
|
240
|
-
}
|
|
241
|
-
return { from: numbers[0], limit: numbers.length };
|
|
242
|
-
}
|
|
243
|
-
|
|
244
227
|
public async getCheckpoint(query: CheckpointQuery): Promise<PublishedCheckpoint | undefined> {
|
|
245
228
|
const number = await this.resolveCheckpointQuery(query);
|
|
246
229
|
if (number === undefined || number === 0) {
|
|
@@ -254,11 +237,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
254
237
|
}
|
|
255
238
|
|
|
256
239
|
public async getCheckpoints(query: CheckpointsQuery): Promise<PublishedCheckpoint[]> {
|
|
257
|
-
const
|
|
258
|
-
if (!resolved) {
|
|
259
|
-
return [];
|
|
260
|
-
}
|
|
261
|
-
const checkpoints = await this.stores.blocks.getRangeOfCheckpoints(resolved.from, resolved.limit);
|
|
240
|
+
const checkpoints = await this.getCheckpointsData(query);
|
|
262
241
|
return Promise.all(checkpoints.map(ch => this.getPublishedCheckpointFromCheckpointData(ch)));
|
|
263
242
|
}
|
|
264
243
|
|
|
@@ -271,11 +250,14 @@ export abstract class ArchiverDataSourceBase
|
|
|
271
250
|
}
|
|
272
251
|
|
|
273
252
|
public async getCheckpointsData(query: CheckpointsQuery): Promise<CheckpointData[]> {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
253
|
+
if ('fromSlot' in query) {
|
|
254
|
+
return this.stores.blocks.getCheckpointsBySlot(query.fromSlot, query.limit, query.reverse ?? false);
|
|
255
|
+
}
|
|
256
|
+
if ('from' in query) {
|
|
257
|
+
return this.stores.blocks.getRangeOfCheckpoints(query.from, query.limit);
|
|
277
258
|
}
|
|
278
|
-
|
|
259
|
+
const numbers = await this.getCheckpointNumbersForEpoch(query.epoch);
|
|
260
|
+
return numbers.length > 0 ? this.stores.blocks.getRangeOfCheckpoints(numbers[0], numbers.length) : [];
|
|
279
261
|
}
|
|
280
262
|
|
|
281
263
|
public getProposedCheckpointData(query?: ProposedCheckpointQuery): Promise<ProposedCheckpointData | undefined> {
|
|
@@ -316,18 +298,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
316
298
|
return this.stores.contractClasses.getBytecodeCommitment(id);
|
|
317
299
|
}
|
|
318
300
|
|
|
319
|
-
public
|
|
320
|
-
address: AztecAddress,
|
|
321
|
-
maybeTimestamp?: UInt64,
|
|
322
|
-
): Promise<ContractInstanceWithAddress | undefined> {
|
|
323
|
-
let timestamp;
|
|
324
|
-
if (maybeTimestamp === undefined) {
|
|
325
|
-
const latestBlockData = await this.getBlockData({ tag: 'proposed' });
|
|
326
|
-
timestamp = latestBlockData ? latestBlockData.header.globalVariables.timestamp : 0n;
|
|
327
|
-
} else {
|
|
328
|
-
timestamp = maybeTimestamp;
|
|
329
|
-
}
|
|
330
|
-
|
|
301
|
+
public getContract(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
331
302
|
return this.stores.contractInstances.getContractInstance(address, timestamp);
|
|
332
303
|
}
|
|
333
304
|
|
|
@@ -114,10 +114,11 @@ export class ArchiverDataStoreUpdater {
|
|
|
114
114
|
// Before adding checkpoints, check for conflicts with local blocks if any
|
|
115
115
|
const { prunedBlocks, lastAlreadyInsertedBlockNumber } = await this.pruneMismatchingLocalBlocks(checkpoints);
|
|
116
116
|
|
|
117
|
-
await this.stores.blocks.addCheckpoints(checkpoints);
|
|
117
|
+
const insertedCheckpoints = await this.stores.blocks.addCheckpoints(checkpoints);
|
|
118
118
|
|
|
119
|
-
//
|
|
120
|
-
|
|
119
|
+
// Skip blocks already inserted via addProposedBlock() and blocks of already-stored checkpoints
|
|
120
|
+
// re-included by an L1 reorg: their logs/contract data were extracted when first inserted.
|
|
121
|
+
const newBlocks = insertedCheckpoints
|
|
121
122
|
.flatMap((ch: PublishedCheckpoint) => ch.checkpoint.blocks)
|
|
122
123
|
.filter(b => lastAlreadyInsertedBlockNumber === undefined || b.number > lastAlreadyInsertedBlockNumber);
|
|
123
124
|
|
|
@@ -84,7 +84,9 @@ export class ArchiverInstrumentation {
|
|
|
84
84
|
|
|
85
85
|
this.pruneDuration = meter.createHistogram(Metrics.ARCHIVER_PRUNE_DURATION);
|
|
86
86
|
|
|
87
|
-
this.pruneCount = createUpDownCounterWithDefault(meter, Metrics.ARCHIVER_PRUNE_COUNT
|
|
87
|
+
this.pruneCount = createUpDownCounterWithDefault(meter, Metrics.ARCHIVER_PRUNE_COUNT, {
|
|
88
|
+
[Attributes.PRUNE_TYPE]: ['unproven', 'uncheckpointed', 'l1_conflict', 'orphan', 'l1_mismatch'],
|
|
89
|
+
});
|
|
88
90
|
|
|
89
91
|
this.blockProposalTxTargetCount = createUpDownCounterWithDefault(
|
|
90
92
|
meter,
|
|
@@ -150,10 +152,21 @@ export class ArchiverInstrumentation {
|
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
public processPrune(duration: number) {
|
|
153
|
-
this.pruneCount.add(1);
|
|
155
|
+
this.pruneCount.add(1, { [Attributes.PRUNE_TYPE]: 'unproven' });
|
|
154
156
|
this.pruneDuration.record(Math.ceil(duration));
|
|
155
157
|
}
|
|
156
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Records a pending-chain reorg, where the archiver dropped proposed blocks (and world-state follows by pruning). The
|
|
161
|
+
* type distinguishes the cause: 'uncheckpointed' (slot ended without a checkpoint), 'l1_conflict' (proposed blocks
|
|
162
|
+
* conflicting with an L1 checkpoint), 'orphan' (no matching proposed checkpoint arrived before the deadline), or
|
|
163
|
+
* 'l1_mismatch' (the local checkpointed tip diverged from L1 — an L1 reorg or a pruned/missed-proof checkpoint — so
|
|
164
|
+
* already-checkpointed blocks were rewound).
|
|
165
|
+
*/
|
|
166
|
+
public recordPrune(pruneType: 'uncheckpointed' | 'l1_conflict' | 'orphan' | 'l1_mismatch') {
|
|
167
|
+
this.pruneCount.add(1, { [Attributes.PRUNE_TYPE]: pruneType });
|
|
168
|
+
}
|
|
169
|
+
|
|
157
170
|
public updateLastProvenCheckpoint(checkpoint: CheckpointData) {
|
|
158
171
|
const lastBlockNumberInCheckpoint = checkpoint.startBlock + checkpoint.blockCount - 1;
|
|
159
172
|
this.blockHeight.record(lastBlockNumberInCheckpoint, { [Attributes.STATUS]: 'proven' });
|