Skip to content
1 change: 1 addition & 0 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ export class Archiver implements ArchiveSource, Traceable {
`to ${provenBlockNumber} due to predicted reorg at L1 block ${currentL1BlockNumber}. ` +
`Updated L2 latest block is ${await this.getBlockNumber()}.`,
);
this.instrumentation.processPrune();
// TODO(palla/reorg): Do we need to set the block synched L1 block number here?
// Seems like the next iteration should handle this.
// await this.store.setBlockSynchedL1BlockNumber(currentL1BlockNumber);
Expand Down
10 changes: 10 additions & 0 deletions yarn-project/archiver/src/archiver/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class ArchiverInstrumentation {
private proofsSubmittedDelay: Histogram;
private proofsSubmittedCount: UpDownCounter;
private dbMetrics: LmdbMetrics;
private pruneCount: UpDownCounter;

private log = createLogger('archiver:instrumentation');

Expand Down Expand Up @@ -68,6 +69,11 @@ export class ArchiverInstrumentation {
},
lmdbStats,
);

this.pruneCount = meter.createUpDownCounter(Metrics.ARCHIVER_PRUNE_COUNT, {
description: 'Number of prunes detected',
valueType: ValueType.INT,
});
}

public static async new(telemetry: TelemetryClient, lmdbStats?: LmdbStatsCallback) {
Expand All @@ -93,6 +99,10 @@ export class ArchiverInstrumentation {
}
}

public processPrune() {
this.pruneCount.add(1);
}

public updateLastProvenBlock(blockNumber: number) {
this.blockHeight.record(blockNumber, { [Attributes.STATUS]: 'proven' });
}
Expand Down
1 change: 1 addition & 0 deletions yarn-project/aztec.js/src/contract/get_gas_limits.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('getGasLimits', () => {
txSimulationResult.publicOutput!.gasUsed = {
totalGas: Gas.from({ daGas: 140, l2Gas: 280 }),
teardownGas: Gas.from({ daGas: 10, l2Gas: 20 }),
publicGas: Gas.from({ daGas: 50, l2Gas: 200 }),
};
});

Expand Down
17 changes: 15 additions & 2 deletions yarn-project/aztec.js/src/contract/get_gas_limits.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { type GasUsed, type TxSimulationResult } from '@aztec/circuit-types';
import { type TxSimulationResult } from '@aztec/circuit-types';
import { type Gas } from '@aztec/circuits.js';

/**
* Returns suggested total and teardown gas limits for a simulated tx.
* Note that public gas usage is only accounted for if the publicOutput is present.
* @param pad - Percentage to pad the suggested gas limits by, (as decimal, e.g., 0.10 for 10%).
*/
export function getGasLimits(simulationResult: TxSimulationResult, pad = 0.1): GasUsed {
export function getGasLimits(
simulationResult: TxSimulationResult,
pad = 0.1,
): {
/**
* Total gas used across private and public
*/
totalGas: Gas;
/**
* Teardown gas used
*/
teardownGas: Gas;
} {
return {
totalGas: simulationResult.gasUsed.totalGas.mul(1 + pad),
teardownGas: simulationResult.gasUsed.teardownGas.mul(1 + pad),
Expand Down
1 change: 1 addition & 0 deletions yarn-project/circuit-types/src/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export const mockSimulatedTx = (seed = 1) => {
{
totalGas: makeGas(),
teardownGas: makeGas(),
publicGas: makeGas(),
},
);
return new TxSimulationResult(privateExecutionResult, tx.data, output);
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/circuit-types/src/stats/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export type L1PublishStats = {
calldataGas: number;
/** Size in bytes of the calldata. */
calldataSize: number;
/** Gas cost of the blob data */
blobDataGas: bigint;
/** Amount of blob gas used. */
blobGasUsed: bigint;
};

/** Stats logged for each L1 rollup publish tx.*/
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/circuit-types/src/test/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { type MerkleTreeReadOperations } from '../interfaces/merkle_tree_operati
import { ProvingRequestType } from '../interfaces/proving-job.js';
import { makeHeader } from '../l2_block_code_to_purge.js';
import { mockTx } from '../mocks.js';
import { type GasUsed } from '../tx/gas_used.js';
import { makeProcessedTxFromPrivateOnlyTx, makeProcessedTxFromTxWithPublicCalls } from '../tx/processed_tx.js';

/** Makes a bloated processed tx for testing purposes. */
Expand Down Expand Up @@ -125,7 +126,8 @@ export function makeBloatedProcessedTx({
const gasUsed = {
totalGas: Gas.empty(),
teardownGas: Gas.empty(),
};
publicGas: Gas.empty(),
} satisfies GasUsed;

return makeProcessedTxFromTxWithPublicCalls(
tx,
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/circuit-types/src/tx/gas_used.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export interface GasUsed {
* `GasSettings`, rather than actual teardown gas.
*/
totalGas: Gas;

/** Total gas used during public execution, including teardown gas */
publicGas: Gas;

/**
* The actual gas used in the teardown phase.
*/
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/circuit-types/src/tx/processed_tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export function makeEmptyProcessedTx(
gasUsed: {
totalGas: Gas.empty(),
teardownGas: Gas.empty(),
publicGas: Gas.empty(),
},
revertReason: undefined,
isEmpty: true,
Expand Down Expand Up @@ -148,7 +149,8 @@ export function makeProcessedTxFromPrivateOnlyTx(
const gasUsed = {
totalGas: tx.data.gasUsed,
teardownGas: Gas.empty(),
};
publicGas: Gas.empty(),
} satisfies GasUsed;

return {
hash: tx.getTxHash(),
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/circuit-types/src/tx/public_simulation_output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class PublicSimulationOutput {
constants: CombinedConstantData.schema,
txEffect: TxEffect.schema,
publicReturnValues: z.array(NestedProcessReturnValues.schema),
gasUsed: z.object({ totalGas: Gas.schema, teardownGas: Gas.schema }),
gasUsed: z.object({ totalGas: Gas.schema, teardownGas: Gas.schema, publicGas: Gas.schema }),
})
.transform(
fields =>
Expand All @@ -81,7 +81,7 @@ export class PublicSimulationOutput {
CombinedConstantData.empty(),
TxEffect.empty(),
times(2, NestedProcessReturnValues.random),
{ teardownGas: Gas.random(), totalGas: Gas.random() },
{ teardownGas: Gas.random(), totalGas: Gas.random(), publicGas: Gas.random() },
);
}
}
1 change: 1 addition & 0 deletions yarn-project/circuit-types/src/tx/simulated_tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class TxSimulationResult extends PrivateSimulationResult {
this.publicOutput?.gasUsed ?? {
totalGas: this.publicInputs.gasUsed,
teardownGas: Gas.empty(),
publicGas: Gas.empty(),
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,7 @@ describe('L1Publisher integration', () => {
worldStateDbMapSizeKb: 10 * 1024 * 1024,
worldStateBlockHistory: 0,
};
worldStateSynchronizer = new ServerWorldStateSynchronizer(
builderDb,
blockSource,
worldStateConfig,
new NoopTelemetryClient(),
);
worldStateSynchronizer = new ServerWorldStateSynchronizer(builderDb, blockSource, worldStateConfig);
await worldStateSynchronizer.start();

publisher = new L1Publisher(
Expand Down
9 changes: 5 additions & 4 deletions yarn-project/prover-node/src/job/epoch-proving-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,13 @@ export class EpochProvingJob implements Traceable {
})
public async run() {
const epochNumber = Number(this.epochNumber);
const epochSize = this.blocks.length;
const epochSizeBlocks = this.blocks.length;
const epochSizeTxs = this.blocks.reduce((total, current) => total + current.body.numberOfTxsIncludingPadded, 0);
const [fromBlock, toBlock] = [this.blocks[0].number, this.blocks.at(-1)!.number];
this.log.info(`Starting epoch ${epochNumber} proving job with blocks ${fromBlock} to ${toBlock}`, {
fromBlock,
toBlock,
epochSize,
epochSizeBlocks,
epochNumber,
uuid: this.uuid,
});
Expand All @@ -87,7 +88,7 @@ export class EpochProvingJob implements Traceable {
this.runPromise = promise;

try {
this.prover.startNewEpoch(epochNumber, fromBlock, epochSize);
this.prover.startNewEpoch(epochNumber, fromBlock, epochSizeBlocks);

await asyncPool(this.config.parallelBlockLimit, this.blocks, async block => {
const globalVariables = block.header.globalVariables;
Expand Down Expand Up @@ -136,7 +137,7 @@ export class EpochProvingJob implements Traceable {
this.log.info(`Submitted proof for epoch`, { epochNumber, uuid: this.uuid });

this.state = 'completed';
this.metrics.recordProvingJob(timer);
this.metrics.recordProvingJob(timer, epochSizeBlocks, epochSizeTxs);
} catch (err) {
this.log.error(`Error running epoch ${epochNumber} prover job`, err, { uuid: this.uuid, epochNumber });
this.state = 'failed';
Expand Down
14 changes: 13 additions & 1 deletion yarn-project/prover-node/src/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { type Histogram, Metrics, type TelemetryClient, ValueType } from '@aztec

export class ProverNodeMetrics {
provingJobDuration: Histogram;
provingJobBlocks: Histogram;
provingJobTransactions: Histogram;

constructor(public readonly client: TelemetryClient, name = 'ProverNode') {
const meter = client.getMeter(name);
Expand All @@ -11,10 +13,20 @@ export class ProverNodeMetrics {
unit: 'ms',
valueType: ValueType.INT,
});
this.provingJobBlocks = meter.createHistogram(Metrics.PROVER_NODE_JOB_BLOCKS, {
description: 'Number of blocks in a proven epoch',
valueType: ValueType.INT,
});
this.provingJobTransactions = meter.createHistogram(Metrics.PROVER_NODE_JOB_TRANSACTIONS, {
description: 'Number of transactions in a proven epoch',
valueType: ValueType.INT,
});
}

public recordProvingJob(timerOrMs: Timer | number) {
public recordProvingJob(timerOrMs: Timer | number, numBlocks: number, numTxs: number) {
const ms = Math.ceil(typeof timerOrMs === 'number' ? timerOrMs : timerOrMs.ms());
this.provingJobDuration.record(ms);
this.provingJobBlocks.record(Math.floor(numBlocks));
this.provingJobTransactions.record(Math.floor(numTxs));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export class L1PublisherMetrics {
private txGas: Histogram;
private txCalldataSize: Histogram;
private txCalldataGas: Histogram;
private txBlobDataGasUsed: Histogram;
private txBlobDataGasCost: Histogram;

constructor(client: TelemetryClient, name = 'L1Publisher') {
const meter = client.getMeter(name);
Expand Down Expand Up @@ -57,6 +59,18 @@ export class L1PublisherMetrics {
unit: 'gas',
valueType: ValueType.INT,
});

this.txBlobDataGasUsed = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED, {
description: 'The amount of blob gas used in transactions',
unit: 'gas',
valueType: ValueType.INT,
});

this.txBlobDataGasCost = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST, {
description: 'The gas cost of blobs in transactions',
unit: 'gwei',
valueType: ValueType.INT,
});
}

recordFailedTx(txType: L1TxType) {
Expand Down Expand Up @@ -98,6 +112,9 @@ export class L1PublisherMetrics {
this.txCalldataGas.record(stats.calldataGas, attributes);
this.txCalldataSize.record(stats.calldataSize, attributes);

this.txBlobDataGasCost.record(Number(stats.blobDataGas), attributes);
this.txBlobDataGasUsed.record(Number(stats.blobGasUsed), attributes);

try {
this.gasPrice.record(parseInt(formatEther(stats.gasPrice, 'gwei'), 10));
} catch (e) {
Expand Down
6 changes: 6 additions & 0 deletions yarn-project/sequencer-client/src/publisher/l1-publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ export class L1Publisher {
const stats: L1PublishBlockStats = {
gasPrice: receipt.effectiveGasPrice,
gasUsed: receipt.gasUsed,
blobGasUsed: receipt.blobGasUsed ?? 0n,
blobDataGas: receipt.blobGasPrice ?? 0n,
transactionHash: receipt.transactionHash,
...pick(tx!, 'calldataGas', 'calldataSize', 'sender'),
...block.getStats(),
Expand Down Expand Up @@ -642,6 +644,8 @@ export class L1Publisher {
gasPrice: receipt.effectiveGasPrice,
gasUsed: receipt.gasUsed,
transactionHash: receipt.transactionHash,
blobDataGas: 0n,
blobGasUsed: 0n,
...pick(tx!, 'calldataGas', 'calldataSize', 'sender'),
};
this.log.verbose(`Submitted claim epoch proof right to L1 rollup contract`, {
Expand Down Expand Up @@ -758,6 +762,8 @@ export class L1Publisher {
const stats: L1PublishProofStats = {
...pick(receipt, 'gasPrice', 'gasUsed', 'transactionHash'),
...pick(tx!, 'calldataGas', 'calldataSize', 'sender'),
blobDataGas: 0n,
blobGasUsed: 0n,
eventName: 'proof-published-to-l1',
};
this.log.info(`Published epoch proof to L1 rollup contract`, { ...stats, ...ctx });
Expand Down
16 changes: 15 additions & 1 deletion yarn-project/sequencer-client/src/sequencer/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class SequencerMetrics {
private stateTransitionBufferDuration: Histogram;
private currentBlockNumber: Gauge;
private currentBlockSize: Gauge;
private blockBuilderInsertions: Histogram;

private timeToCollectAttestations: Gauge;

Expand Down Expand Up @@ -49,14 +50,23 @@ export class SequencerMetrics {

this.currentBlockNumber = meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
description: 'Current block number',
valueType: ValueType.INT,
});

this.currentBlockSize = meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
description: 'Current block number',
description: 'Current block size',
valueType: ValueType.INT,
});

this.timeToCollectAttestations = meter.createGauge(Metrics.SEQUENCER_TIME_TO_COLLECT_ATTESTATIONS, {
description: 'The time spent collecting attestations from committee members',
valueType: ValueType.INT,
});

this.blockBuilderInsertions = meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
description: 'Timer for tree insertions performed by the block builder',
unit: 'us',
valueType: ValueType.INT,
});

this.setCurrentBlock(0, 0);
Expand All @@ -75,6 +85,10 @@ export class SequencerMetrics {
this.timeToCollectAttestations.record(time);
}

recordBlockBuilderTreeInsertions(timeUs: number) {
this.blockBuilderInsertions.record(Math.ceil(timeUs));
}

recordCancelledBlock() {
this.blockCounter.add(1, {
[Attributes.STATUS]: 'cancelled',
Expand Down
5 changes: 5 additions & 0 deletions yarn-project/sequencer-client/src/sequencer/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,12 @@ export class Sequencer {
this.log.verbose(`Dropping failed txs ${Tx.getHashes(failedTxData).join(', ')}`);
await this.p2pClient.deleteTxs(Tx.getHashes(failedTxData));
}

const start = process.hrtime.bigint();
await blockBuilder.addTxs(processedTxs);
const end = process.hrtime.bigint();
const duration = Number(end - start) / 1_000;
this.metrics.recordBlockBuilderTreeInsertions(duration);

await interrupt?.(processedTxs);

Expand Down
13 changes: 13 additions & 0 deletions yarn-project/simulator/src/public/executor_metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class ExecutorMetrics {
private fnCount: UpDownCounter;
private fnDuration: Histogram;
private manaPerSecond: Histogram;
private privateEffectsInsertions: Histogram;

constructor(client: TelemetryClient, name = 'PublicExecutor') {
this.tracer = client.getTracer(name);
Expand All @@ -33,6 +34,12 @@ export class ExecutorMetrics {
unit: 'mana/s',
valueType: ValueType.INT,
});

this.privateEffectsInsertions = meter.createHistogram(Metrics.PUBLIC_EXECUTION_PRIVATE_EFFECTS_INSERTION, {
description: 'Private effects insertion time',
unit: 'us',
valueType: ValueType.INT,
});
}

recordFunctionSimulation(durationMs: number, manaUsed: number, fnName: string) {
Expand All @@ -55,4 +62,10 @@ export class ExecutorMetrics {
[Attributes.OK]: false,
});
}

recordPrivateEffectsInsertion(durationUs: number, type: 'revertible' | 'non-revertible') {
this.privateEffectsInsertions.record(Math.ceil(durationUs), {
[Attributes.REVERTIBILITY]: type,
});
}
}
Loading