Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: prover node metrics #8086

Merged
merged 5 commits into from
Aug 22, 2024
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 yarn-project/archiver/src/archiver/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class ArchiverInstrumentation {
}

public processNewBlocks(syncTimePerBlock: number, blocks: L2Block[]) {
this.syncDuration.record(syncTimePerBlock);
this.syncDuration.record(Math.ceil(syncTimePerBlock));
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
for (const block of blocks) {
this.blockSize.record(block.body.txEffects.length);
Expand Down
6 changes: 6 additions & 0 deletions yarn-project/prover-node/src/job/block-proving-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import {
type TxProvider,
} from '@aztec/circuit-types';
import { createDebugLogger } from '@aztec/foundation/log';
import { Timer } from '@aztec/foundation/timer';
import { type L1Publisher } from '@aztec/sequencer-client';
import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator';

import * as crypto from 'node:crypto';

import { type ProverNodeMetrics } from '../metrics.js';

/**
* Job that grabs a range of blocks from the unfinalised chain from L1, gets their txs given their hashes,
* re-executes their public calls, generates a rollup proof, and submits it to L1. This job will update the
Expand All @@ -33,6 +36,7 @@ export class BlockProvingJob {
private l2BlockSource: L2BlockSource,
private l1ToL2MessageSource: L1ToL2MessageSource,
private txProvider: TxProvider,
private metrics: ProverNodeMetrics,
private cleanUp: (job: BlockProvingJob) => Promise<void> = () => Promise.resolve(),
) {
this.uuid = crypto.randomUUID();
Expand All @@ -53,6 +57,7 @@ export class BlockProvingJob {

this.log.info(`Starting block proving job`, { fromBlock, toBlock, uuid: this.uuid });
this.state = 'processing';
const timer = new Timer();
try {
let historicalHeader = (await this.l2BlockSource.getBlock(fromBlock - 1))?.header;
for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {
Expand Down Expand Up @@ -114,6 +119,7 @@ export class BlockProvingJob {
this.log.info(`Submitted proof for block range`, { fromBlock, toBlock, uuid: this.uuid });

this.state = 'completed';
this.metrics.recordProvingJob(timer);
} catch (err) {
this.log.error(`Error running block prover job`, err, { uuid: this.uuid });
this.state = 'failed';
Expand Down
23 changes: 23 additions & 0 deletions yarn-project/prover-node/src/metrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { type Timer } from '@aztec/foundation/timer';
import { type Histogram, Metrics, type TelemetryClient, ValueType, millisecondBuckets } from '@aztec/telemetry-client';

export class ProverNodeMetrics {
provingJobDuration: Histogram;

constructor(client: TelemetryClient, name = 'ProverNode') {
const meter = client.getMeter(name);
this.provingJobDuration = meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
description: 'Duration of proving job',
unit: 'ms',
valueType: ValueType.INT,
advice: {
explicitBucketBoundaries: millisecondBuckets(2), // 60 buckets spanning an interval of ~100ms to ~1hour
},
});
}

public recordProvingJob(timerOrMs: Timer | number) {
const ms = Math.ceil(typeof timerOrMs === 'number' ? timerOrMs : timerOrMs.ms());
this.provingJobDuration.record(ms);
}
}
5 changes: 2 additions & 3 deletions yarn-project/prover-node/src/prover-node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from '@aztec/circuit-types';
import { type L1Publisher } from '@aztec/sequencer-client';
import { type PublicProcessorFactory, type SimulationProvider } from '@aztec/simulator';
import { type TelemetryClient } from '@aztec/telemetry-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
import { type ContractDataSource } from '@aztec/types/contracts';
import { WorldStateRunningState, type WorldStateSynchronizer } from '@aztec/world-state';

Expand All @@ -25,7 +25,6 @@ describe('prover-node', () => {
let worldState: MockProxy<WorldStateSynchronizer>;
let txProvider: MockProxy<TxProvider>;
let simulator: MockProxy<SimulationProvider>;
let telemetryClient: MockProxy<TelemetryClient>;

let proverNode: TestProverNode;

Expand All @@ -45,7 +44,7 @@ describe('prover-node', () => {
worldState = mock<WorldStateSynchronizer>();
txProvider = mock<TxProvider>();
simulator = mock<SimulationProvider>();
telemetryClient = mock<TelemetryClient>();
const telemetryClient = new NoopTelemetryClient();

// World state returns a new mock db every time it is asked to fork
worldState.syncImmediateAndFork.mockImplementation(() => Promise.resolve(mock<MerkleTreeOperations>()));
Expand Down
5 changes: 5 additions & 0 deletions yarn-project/prover-node/src/prover-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { type ContractDataSource } from '@aztec/types/contracts';
import { type WorldStateSynchronizer } from '@aztec/world-state';

import { BlockProvingJob, type BlockProvingJobState } from './job/block-proving-job.js';
import { ProverNodeMetrics } from './metrics.js';

/**
* An Aztec Prover Node is a standalone process that monitors the unfinalised chain on L1 for unproven blocks,
Expand All @@ -26,6 +27,7 @@ export class ProverNode {
private latestBlockWeAreProving: number | undefined;
private jobs: Map<string, BlockProvingJob> = new Map();
private options: { pollingIntervalMs: number; disableAutomaticProving: boolean; maxPendingJobs: number };
private metrics: ProverNodeMetrics;

constructor(
private prover: ProverClient,
Expand All @@ -45,6 +47,8 @@ export class ProverNode {
maxPendingJobs: 100,
...options,
};

this.metrics = new ProverNodeMetrics(telemetryClient, 'ProverNode');
}

/**
Expand Down Expand Up @@ -200,6 +204,7 @@ export class ProverNode {
this.l2BlockSource,
this.l1ToL2MessageSource,
this.txProvider,
this.metrics,
cleanUp,
);
}
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/telemetry-client/src/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ export const PROVING_ORCHESTRATOR_BASE_ROLLUP_INPUTS_DURATION =
export const PROVING_QUEUE_JOB_SIZE = 'aztec.proving_queue.job_size';
export const PROVING_QUEUE_SIZE = 'aztec.proving_queue.size';

export const PROVER_NODE_JOB_DURATION = 'aztec.prover_node.job_duration';

export const WORLD_STATE_FORK_DURATION = 'aztec.world_state.fork.duration';
export const WORLD_STATE_SYNC_DURATION = 'aztec.world_state.sync.duration';
export const WORLD_STATE_MERKLE_TREE_SIZE = 'aztec.world_state.merkle_tree_size';
Expand Down
Loading