Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion spartan/metrics/grafana/alerts/rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ groups:
datasourceUid: spartan-metrics-prometheus
model:
editorMode: code
expr: sum by (k8s_namespace_name, aztec_error_type) (increase(aztec_sequencer_block_proposal_precheck_failed_count{k8s_namespace_name=~".*(fisherman|mainnet).*"}[$__rate_interval]))
expr: sum by (k8s_namespace_name, aztec_error_type) (increase(aztec_sequencer_checkpoint_precheck_failed_count{k8s_namespace_name=~".*(fisherman|mainnet).*"}[$__rate_interval]))
instant: true
intervalMs: 60000
legendFormat: __auto
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class CheckpointProposalJob implements Traceable {
await Promise.all(votesPromises);

if (checkpoint) {
this.metrics.recordBlockProposalSuccess();
this.metrics.recordCheckpointProposalSuccess();
}

// Do not post anything to L1 if we are fishermen, but do perform L1 fee analysis
Expand Down Expand Up @@ -221,6 +221,7 @@ export class CheckpointProposalJob implements Traceable {

let blocksInCheckpoint: L2Block[] = [];
let blockPendingBroadcast: { block: L2Block; txs: Tx[] } | undefined = undefined;
const checkpointBuildTimer = new Timer();

try {
// Main loop: build blocks for the checkpoint
Expand Down Expand Up @@ -253,6 +254,14 @@ export class CheckpointProposalJob implements Traceable {
this.setStateFn(SequencerState.ASSEMBLING_CHECKPOINT, this.slot);
const checkpoint = await checkpointBuilder.completeCheckpoint();

// Record checkpoint-level build metrics
this.metrics.recordCheckpointBuild(
checkpointBuildTimer.ms(),
blocksInCheckpoint.length,
checkpoint.getStats().txCount,
Number(checkpoint.header.totalManaUsed.toBigInt()),
);

// Do not collect attestations nor publish to L1 in fisherman mode
if (this.config.fishermanMode) {
this.log.info(
Expand Down Expand Up @@ -826,7 +835,7 @@ export class CheckpointProposalJob implements Traceable {
slot: this.slot,
feeAnalysisId: feeAnalysis?.id,
});
this.metrics.recordBlockProposalFailed('block_build_failed');
this.metrics.recordCheckpointProposalFailed('block_build_failed');
}

this.publisher.clearPendingRequests();
Expand Down
52 changes: 39 additions & 13 deletions yarn-project/sequencer-client/src/sequencer/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { type Hex, formatUnits } from 'viem';

import type { SequencerState } from './utils.js';

// TODO(palla/mbps): Review all metrics and add any missing ones per checkpoint
export class SequencerMetrics {
public readonly tracer: Tracer;
private meter: Meter;
Expand All @@ -40,11 +39,16 @@ export class SequencerMetrics {
private filledSlots: UpDownCounter;

private blockProposalFailed: UpDownCounter;
private blockProposalSuccess: UpDownCounter;
private blockProposalPrecheckFailed: UpDownCounter;
private checkpointProposalSuccess: UpDownCounter;
private checkpointPrecheckFailed: UpDownCounter;
private checkpointProposalFailed: UpDownCounter;
private checkpointSuccess: UpDownCounter;
private slashingAttempts: UpDownCounter;
private checkpointAttestationDelay: Histogram;
private checkpointBuildDuration: Histogram;
private checkpointBlockCount: Gauge;
private checkpointTxCount: Gauge;
private checkpointTotalMana: Gauge;

// Fisherman fee analysis metrics
private fishermanWouldBeIncluded: UpDownCounter;
Expand Down Expand Up @@ -83,7 +87,7 @@ export class SequencerMetrics {

this.checkpointAttestationDelay = this.meter.createHistogram(Metrics.SEQUENCER_CHECKPOINT_ATTESTATION_DELAY);

this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS);
this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_SLOT_REWARDS);

this.slots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLOT_COUNT);

Expand All @@ -106,16 +110,16 @@ export class SequencerMetrics {
Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT,
);

this.blockProposalSuccess = createUpDownCounterWithDefault(
this.checkpointProposalSuccess = createUpDownCounterWithDefault(
this.meter,
Metrics.SEQUENCER_BLOCK_PROPOSAL_SUCCESS_COUNT,
Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_SUCCESS_COUNT,
);

this.checkpointSuccess = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_SUCCESS_COUNT);

this.blockProposalPrecheckFailed = createUpDownCounterWithDefault(
this.checkpointPrecheckFailed = createUpDownCounterWithDefault(
this.meter,
Metrics.SEQUENCER_BLOCK_PROPOSAL_PRECHECK_FAILED_COUNT,
Metrics.SEQUENCER_CHECKPOINT_PRECHECK_FAILED_COUNT,
{
[Attributes.ERROR_TYPE]: [
'slot_already_taken',
Expand All @@ -126,6 +130,16 @@ export class SequencerMetrics {
},
);

this.checkpointProposalFailed = createUpDownCounterWithDefault(
this.meter,
Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_FAILED_COUNT,
);

this.checkpointBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_CHECKPOINT_BUILD_DURATION);
this.checkpointBlockCount = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_BLOCK_COUNT);
this.checkpointTxCount = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_TX_COUNT);
this.checkpointTotalMana = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_TOTAL_MANA);

this.slashingAttempts = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT);

// Fisherman fee analysis metrics
Expand Down Expand Up @@ -258,18 +272,30 @@ export class SequencerMetrics {
});
}

recordBlockProposalSuccess() {
this.blockProposalSuccess.add(1);
recordCheckpointProposalSuccess() {
this.checkpointProposalSuccess.add(1);
}

recordBlockProposalPrecheckFailed(
recordCheckpointPrecheckFailed(
checkType: 'slot_already_taken' | 'rollup_contract_check_failed' | 'slot_mismatch' | 'block_number_mismatch',
) {
this.blockProposalPrecheckFailed.add(1, {
[Attributes.ERROR_TYPE]: checkType,
this.checkpointPrecheckFailed.add(1, { [Attributes.ERROR_TYPE]: checkType });
}

recordCheckpointProposalFailed(reason?: string) {
this.checkpointProposalFailed.add(1, {
...(reason && { [Attributes.ERROR_TYPE]: reason }),
});
}

/** Records aggregate metrics for a completed checkpoint build. */
recordCheckpointBuild(durationMs: number, blockCount: number, txCount: number, totalMana: number) {
this.checkpointBuildDuration.record(Math.ceil(durationMs));
this.checkpointBlockCount.record(blockCount);
this.checkpointTxCount.record(txCount);
this.checkpointTotalMana.record(totalMana);
}

recordSlashingAttempt(actionCount: number) {
this.slashingAttempts.add(actionCount);
}
Expand Down
8 changes: 4 additions & 4 deletions yarn-project/sequencer-client/src/sequencer/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
`Cannot propose block at next L2 slot ${slot} since that slot was taken by block ${syncedTo.blockNumber}`,
{ ...logCtx, block: syncedTo.block.header.toInspect() },
);
this.metrics.recordBlockProposalPrecheckFailed('slot_already_taken');
this.metrics.recordCheckpointPrecheckFailed('slot_already_taken');
return undefined;
}

Expand Down Expand Up @@ -341,7 +341,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
logCtx,
);
this.emit('proposer-rollup-check-failed', { reason: 'Rollup contract check failed', slot });
this.metrics.recordBlockProposalPrecheckFailed('rollup_contract_check_failed');
this.metrics.recordCheckpointPrecheckFailed('rollup_contract_check_failed');
return undefined;
}

Expand All @@ -351,7 +351,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
{ ...logCtx, rollup: canProposeCheck, expectedSlot: slot },
);
this.emit('proposer-rollup-check-failed', { reason: 'Slot mismatch', slot });
this.metrics.recordBlockProposalPrecheckFailed('slot_mismatch');
this.metrics.recordCheckpointPrecheckFailed('slot_mismatch');
return undefined;
}

Expand All @@ -361,7 +361,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
{ ...logCtx, rollup: canProposeCheck, expectedSlot: slot },
);
this.emit('proposer-rollup-check-failed', { reason: 'Block mismatch', slot });
this.metrics.recordBlockProposalPrecheckFailed('block_number_mismatch');
this.metrics.recordCheckpointPrecheckFailed('block_number_mismatch');
return undefined;
}

Expand Down
50 changes: 39 additions & 11 deletions yarn-project/telemetry-client/src/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,9 @@ export const SEQUENCER_BLOCK_COUNT: MetricDefinition = {
description: 'Number of blocks built by this sequencer',
valueType: ValueType.INT,
};
export const SEQUENCER_CURRENT_BLOCK_REWARDS: MetricDefinition = {
name: 'aztec.sequencer.current_block_rewards',
description: 'The rewards earned',
export const SEQUENCER_CURRENT_SLOT_REWARDS: MetricDefinition = {
name: 'aztec.sequencer.current_slot_rewards',
description: 'The rewards earned per filled slot',
valueType: ValueType.DOUBLE,
};
export const SEQUENCER_SLOT_COUNT: MetricDefinition = {
Expand All @@ -369,12 +369,12 @@ export const SEQUENCER_CHECKPOINT_ATTESTATION_DELAY: MetricDefinition = {

export const SEQUENCER_COLLECTED_ATTESTATIONS_COUNT: MetricDefinition = {
name: 'aztec.sequencer.attestations.collected_count',
description: 'The number of attestations collected for a block proposal',
description: 'The number of attestations collected for a checkpoint proposal',
valueType: ValueType.INT,
};
export const SEQUENCER_REQUIRED_ATTESTATIONS_COUNT: MetricDefinition = {
name: 'aztec.sequencer.attestations.required_count',
description: 'The minimum number of attestations required to publish a block',
description: 'The minimum number of attestations required to publish a checkpoint',
valueType: ValueType.INT,
};
export const SEQUENCER_COLLECT_ATTESTATIONS_DURATION: MetricDefinition = {
Expand All @@ -395,14 +395,42 @@ export const SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT: MetricDefinition = {
description: 'The number of times block proposal failed (including validation builds)',
valueType: ValueType.INT,
};
export const SEQUENCER_BLOCK_PROPOSAL_SUCCESS_COUNT: MetricDefinition = {
name: 'aztec.sequencer.block.proposal_success_count',
description: 'The number of times block proposal succeeded (including validation builds)',
export const SEQUENCER_CHECKPOINT_PROPOSAL_SUCCESS_COUNT: MetricDefinition = {
name: 'aztec.sequencer.checkpoint.proposal_success_count',
description: 'The number of times checkpoint proposal succeeded',
valueType: ValueType.INT,
};
export const SEQUENCER_CHECKPOINT_PRECHECK_FAILED_COUNT: MetricDefinition = {
name: 'aztec.sequencer.checkpoint.precheck_failed_count',
description: 'The number of times checkpoint pre-build checks failed',
valueType: ValueType.INT,
};
export const SEQUENCER_CHECKPOINT_PROPOSAL_FAILED_COUNT: MetricDefinition = {
name: 'aztec.sequencer.checkpoint.proposal_failed_count',
description: 'The number of times checkpoint proposal failed',
valueType: ValueType.INT,
};
export const SEQUENCER_CHECKPOINT_BUILD_DURATION: MetricDefinition = {
name: 'aztec.sequencer.checkpoint.build_duration',
description: 'Total duration to build all blocks in a checkpoint',
unit: 'ms',
valueType: ValueType.INT,
};
export const SEQUENCER_CHECKPOINT_BLOCK_COUNT: MetricDefinition = {
name: 'aztec.sequencer.checkpoint.block_count',
description: 'Number of blocks built in a checkpoint',
valueType: ValueType.INT,
};
export const SEQUENCER_BLOCK_PROPOSAL_PRECHECK_FAILED_COUNT: MetricDefinition = {
name: 'aztec.sequencer.block.proposal_precheck_failed_count',
description: 'The number of times block proposal pre-build checks failed',
export const SEQUENCER_CHECKPOINT_TX_COUNT: MetricDefinition = {
name: 'aztec.sequencer.checkpoint.tx_count',
description: 'Total number of transactions across all blocks in a checkpoint',
unit: 'tx',
valueType: ValueType.INT,
};
export const SEQUENCER_CHECKPOINT_TOTAL_MANA: MetricDefinition = {
name: 'aztec.sequencer.checkpoint.total_mana',
description: 'Total L2 mana used across all blocks in a checkpoint',
unit: 'mana',
valueType: ValueType.INT,
};
export const SEQUENCER_SLASHING_ATTEMPTS_COUNT: MetricDefinition = {
Expand Down
Loading