@aztec/prover-node 0.0.1-commit.9b94fc1 → 0.0.1-commit.b468ad8

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.
Files changed (47) hide show
  1. package/dest/actions/download-epoch-proving-job.d.ts +1 -1
  2. package/dest/actions/rerun-epoch-proving-job.d.ts +3 -2
  3. package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
  4. package/dest/actions/rerun-epoch-proving-job.js +5 -3
  5. package/dest/config.d.ts +5 -4
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +4 -3
  8. package/dest/factory.d.ts +2 -4
  9. package/dest/factory.d.ts.map +1 -1
  10. package/dest/factory.js +21 -16
  11. package/dest/index.d.ts +2 -1
  12. package/dest/index.d.ts.map +1 -1
  13. package/dest/index.js +1 -0
  14. package/dest/job/epoch-proving-job-data.d.ts +7 -6
  15. package/dest/job/epoch-proving-job-data.d.ts.map +1 -1
  16. package/dest/job/epoch-proving-job-data.js +24 -18
  17. package/dest/job/epoch-proving-job.d.ts +5 -4
  18. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  19. package/dest/job/epoch-proving-job.js +483 -101
  20. package/dest/metrics.d.ts +4 -3
  21. package/dest/metrics.d.ts.map +1 -1
  22. package/dest/metrics.js +29 -97
  23. package/dest/monitors/epoch-monitor.d.ts +1 -1
  24. package/dest/monitors/epoch-monitor.d.ts.map +1 -1
  25. package/dest/monitors/epoch-monitor.js +3 -11
  26. package/dest/prover-node-publisher.d.ts +10 -8
  27. package/dest/prover-node-publisher.d.ts.map +1 -1
  28. package/dest/prover-node-publisher.js +44 -38
  29. package/dest/prover-node.d.ts +4 -4
  30. package/dest/prover-node.d.ts.map +1 -1
  31. package/dest/prover-node.js +429 -47
  32. package/dest/prover-publisher-factory.d.ts +7 -3
  33. package/dest/prover-publisher-factory.d.ts.map +1 -1
  34. package/dest/prover-publisher-factory.js +4 -2
  35. package/package.json +25 -25
  36. package/src/actions/rerun-epoch-proving-job.ts +5 -3
  37. package/src/bin/run-failed-epoch.ts +1 -1
  38. package/src/config.ts +6 -4
  39. package/src/factory.ts +29 -18
  40. package/src/index.ts +1 -0
  41. package/src/job/epoch-proving-job-data.ts +28 -23
  42. package/src/job/epoch-proving-job.ts +109 -99
  43. package/src/metrics.ts +30 -81
  44. package/src/monitors/epoch-monitor.ts +3 -10
  45. package/src/prover-node-publisher.ts +64 -52
  46. package/src/prover-node.ts +38 -32
  47. package/src/prover-publisher-factory.ts +14 -6
@@ -1,9 +1,9 @@
1
1
  import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
2
  import { asyncPool } from '@aztec/foundation/async-pool';
3
- import { EpochNumber } from '@aztec/foundation/branded-types';
3
+ import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
4
4
  import { padArrayEnd } from '@aztec/foundation/collection';
5
- import { Fr } from '@aztec/foundation/fields';
6
- import { createLogger } from '@aztec/foundation/log';
5
+ import { Fr } from '@aztec/foundation/curves/bn254';
6
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
7
7
  import { RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
8
8
  import { Timer } from '@aztec/foundation/timer';
9
9
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
@@ -12,6 +12,7 @@ import { buildFinalBlobChallenges } from '@aztec/prover-client/helpers';
12
12
  import type { PublicProcessor, PublicProcessorFactory } from '@aztec/simulator/server';
13
13
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
14
14
  import type { L2Block, L2BlockSource } from '@aztec/stdlib/block';
15
+ import type { Checkpoint } from '@aztec/stdlib/checkpoint';
15
16
  import {
16
17
  type EpochProver,
17
18
  type EpochProvingJobState,
@@ -42,7 +43,7 @@ export type EpochProvingJobOptions = {
42
43
  */
43
44
  export class EpochProvingJob implements Traceable {
44
45
  private state: EpochProvingJobState = 'initialized';
45
- private log = createLogger('prover-node:epoch-proving-job');
46
+ private log: Logger;
46
47
  private uuid: string;
47
48
 
48
49
  private runPromise: Promise<void> | undefined;
@@ -61,9 +62,14 @@ export class EpochProvingJob implements Traceable {
61
62
  private metrics: ProverNodeJobMetrics,
62
63
  private deadline: Date | undefined,
63
64
  private config: EpochProvingJobOptions,
65
+ bindings?: LoggerBindings,
64
66
  ) {
65
67
  validateEpochProvingJobData(data);
66
68
  this.uuid = crypto.randomUUID();
69
+ this.log = createLogger('prover-node:epoch-proving-job', {
70
+ ...bindings,
71
+ instanceId: `epoch-${data.epochNumber}`,
72
+ });
67
73
  this.tracer = metrics.tracer;
68
74
  }
69
75
 
@@ -91,8 +97,8 @@ export class EpochProvingJob implements Traceable {
91
97
  return this.data.epochNumber;
92
98
  }
93
99
 
94
- private get blocks() {
95
- return this.data.blocks;
100
+ private get checkpoints() {
101
+ return this.data.checkpoints;
96
102
  }
97
103
 
98
104
  private get txs() {
@@ -117,13 +123,21 @@ export class EpochProvingJob implements Traceable {
117
123
 
118
124
  const attestations = this.attestations.map(attestation => attestation.toViem());
119
125
  const epochNumber = this.epochNumber;
120
- const epochSizeBlocks = this.blocks.length;
121
- const epochSizeTxs = this.blocks.reduce((total, current) => total + current.body.txEffects.length, 0);
122
- const [fromBlock, toBlock] = [this.blocks[0].number, this.blocks.at(-1)!.number];
123
- this.log.info(`Starting epoch ${epochNumber} proving job with blocks ${fromBlock} to ${toBlock}`, {
126
+ const epochSizeCheckpoints = this.checkpoints.length;
127
+ const epochSizeBlocks = this.checkpoints.reduce((accum, checkpoint) => accum + checkpoint.blocks.length, 0);
128
+ const epochSizeTxs = this.checkpoints.reduce(
129
+ (accum, checkpoint) =>
130
+ accum + checkpoint.blocks.reduce((accumC, block) => accumC + block.body.txEffects.length, 0),
131
+ 0,
132
+ );
133
+ const fromCheckpoint = this.checkpoints[0].number;
134
+ const toCheckpoint = this.checkpoints.at(-1)!.number;
135
+ const fromBlock = this.checkpoints[0].blocks[0].number;
136
+ const toBlock = this.checkpoints.at(-1)!.blocks.at(-1)!.number;
137
+ this.log.info(`Starting epoch ${epochNumber} proving job with checkpoints ${fromCheckpoint} to ${toCheckpoint}`, {
124
138
  fromBlock,
125
139
  toBlock,
126
- epochSizeBlocks,
140
+ epochSizeTxs,
127
141
  epochNumber,
128
142
  uuid: this.uuid,
129
143
  });
@@ -134,86 +148,93 @@ export class EpochProvingJob implements Traceable {
134
148
  this.runPromise = promise;
135
149
 
136
150
  try {
137
- const blobFieldsPerCheckpoint = this.blocks.map(block => block.getCheckpointBlobFields());
151
+ const blobFieldsPerCheckpoint = this.checkpoints.map(checkpoint => checkpoint.toBlobFields());
138
152
  const finalBlobBatchingChallenges = await buildFinalBlobChallenges(blobFieldsPerCheckpoint);
139
153
 
140
- // TODO(#17027): Enable multiple blocks per checkpoint.
141
- // Total number of checkpoints equals number of blocks because we currently build a checkpoint with only one block.
142
- const totalNumCheckpoints = epochSizeBlocks;
143
-
144
- this.prover.startNewEpoch(epochNumber, totalNumCheckpoints, finalBlobBatchingChallenges);
154
+ this.prover.startNewEpoch(epochNumber, epochSizeCheckpoints, finalBlobBatchingChallenges);
145
155
  await this.prover.startChonkVerifierCircuits(Array.from(this.txs.values()));
146
156
 
147
- await asyncPool(this.config.parallelBlockLimit ?? 32, this.blocks, async block => {
148
- this.checkState();
157
+ // Everything in the epoch should have the same chainId and version.
158
+ const { chainId, version } = this.checkpoints[0].blocks[0].header.globalVariables;
149
159
 
150
- const globalVariables = block.header.globalVariables;
151
- const txs = this.getTxs(block);
152
- const l1ToL2Messages = this.getL1ToL2Messages(block);
153
- const previousHeader = this.getBlockHeader(block.number - 1)!;
154
-
155
- this.log.verbose(`Starting processing block ${block.number}`, {
156
- number: block.number,
157
- blockHash: (await block.hash()).toString(),
158
- lastArchive: block.header.lastArchive.root,
159
- noteHashTreeRoot: block.header.state.partial.noteHashTree.root,
160
- nullifierTreeRoot: block.header.state.partial.nullifierTree.root,
161
- publicDataTreeRoot: block.header.state.partial.publicDataTree.root,
162
- previousHeader: previousHeader.hash(),
163
- uuid: this.uuid,
164
- ...globalVariables,
165
- });
160
+ const previousBlockHeaders = this.gatherPreviousBlockHeaders();
166
161
 
162
+ await asyncPool(this.config.parallelBlockLimit ?? 32, this.checkpoints, async checkpoint => {
163
+ this.checkState();
164
+
165
+ const checkpointIndex = checkpoint.number - fromCheckpoint;
167
166
  const checkpointConstants = CheckpointConstantData.from({
168
- chainId: globalVariables.chainId,
169
- version: globalVariables.version,
167
+ chainId,
168
+ version,
170
169
  vkTreeRoot: getVKTreeRoot(),
171
170
  protocolContractsHash: protocolContractsHash,
172
171
  proverId: this.prover.getProverId().toField(),
173
- slotNumber: globalVariables.slotNumber,
174
- coinbase: globalVariables.coinbase,
175
- feeRecipient: globalVariables.feeRecipient,
176
- gasFees: globalVariables.gasFees,
172
+ slotNumber: checkpoint.header.slotNumber,
173
+ coinbase: checkpoint.header.coinbase,
174
+ feeRecipient: checkpoint.header.feeRecipient,
175
+ gasFees: checkpoint.header.gasFees,
176
+ });
177
+ const previousHeader = previousBlockHeaders[checkpointIndex];
178
+ const l1ToL2Messages = this.getL1ToL2Messages(checkpoint);
179
+
180
+ this.log.verbose(`Starting processing checkpoint ${checkpoint.number}`, {
181
+ number: checkpoint.number,
182
+ checkpointHash: checkpoint.hash().toString(),
183
+ lastArchive: checkpoint.header.lastArchiveRoot,
184
+ previousHeader: previousHeader.hash(),
185
+ uuid: this.uuid,
177
186
  });
178
187
 
179
- // TODO(#17027): Enable multiple blocks per checkpoint.
180
- // Each checkpoint has only one block.
181
- const totalNumBlocks = 1;
182
- const checkpointIndex = block.number - fromBlock;
183
188
  await this.prover.startNewCheckpoint(
184
189
  checkpointIndex,
185
190
  checkpointConstants,
186
191
  l1ToL2Messages,
187
- totalNumBlocks,
192
+ checkpoint.blocks.length,
188
193
  previousHeader,
189
194
  );
190
195
 
191
- // Start block proving
192
- await this.prover.startNewBlock(block.number, globalVariables.timestamp, txs.length);
196
+ for (const block of checkpoint.blocks) {
197
+ const globalVariables = block.header.globalVariables;
198
+ const txs = this.getTxs(block);
199
+
200
+ this.log.verbose(`Starting processing block ${block.number}`, {
201
+ number: block.number,
202
+ blockHash: (await block.hash()).toString(),
203
+ lastArchive: block.header.lastArchive.root,
204
+ noteHashTreeRoot: block.header.state.partial.noteHashTree.root,
205
+ nullifierTreeRoot: block.header.state.partial.nullifierTree.root,
206
+ publicDataTreeRoot: block.header.state.partial.publicDataTree.root,
207
+ ...globalVariables,
208
+ numTxs: txs.length,
209
+ });
193
210
 
194
- // Process public fns
195
- const db = await this.createFork(block.number - 1, l1ToL2Messages);
196
- const config = PublicSimulatorConfig.from({
197
- proverId: this.prover.getProverId().toField(),
198
- skipFeeEnforcement: false,
199
- collectDebugLogs: false,
200
- collectHints: true,
201
- maxDebugLogMemoryReads: 0,
202
- collectStatistics: false,
203
- });
204
- const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config);
205
- const processed = await this.processTxs(publicProcessor, txs);
206
- await this.prover.addTxs(processed);
207
- await db.close();
208
- this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, {
209
- blockNumber: block.number,
210
- blockHash: (await block.hash()).toString(),
211
- uuid: this.uuid,
212
- });
211
+ // Start block proving
212
+ await this.prover.startNewBlock(block.number, globalVariables.timestamp, txs.length);
213
+
214
+ // Process public fns
215
+ const db = await this.createFork(BlockNumber(block.number - 1), l1ToL2Messages);
216
+ const config = PublicSimulatorConfig.from({
217
+ proverId: this.prover.getProverId().toField(),
218
+ skipFeeEnforcement: false,
219
+ collectDebugLogs: false,
220
+ collectHints: true,
221
+ collectPublicInputs: true,
222
+ collectStatistics: false,
223
+ });
224
+ const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config);
225
+ const processed = await this.processTxs(publicProcessor, txs);
226
+ await this.prover.addTxs(processed);
227
+ await db.close();
228
+ this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, {
229
+ blockNumber: block.number,
230
+ blockHash: (await block.hash()).toString(),
231
+ uuid: this.uuid,
232
+ });
213
233
 
214
- // Mark block as completed to pad it
215
- const expectedBlockHeader = block.getBlockHeader();
216
- await this.prover.setBlockCompleted(block.number, expectedBlockHeader);
234
+ // Mark block as completed to pad it
235
+ const expectedBlockHeader = block.header;
236
+ await this.prover.setBlockCompleted(block.number, expectedBlockHeader);
237
+ }
217
238
  });
218
239
 
219
240
  const executionTime = timer.ms();
@@ -226,16 +247,16 @@ export class EpochProvingJob implements Traceable {
226
247
 
227
248
  if (this.config.skipSubmitProof) {
228
249
  this.log.info(
229
- `Proof publishing is disabled. Dropping valid proof for epoch ${epochNumber} (blocks ${fromBlock} to ${toBlock})`,
250
+ `Proof publishing is disabled. Dropping valid proof for epoch ${epochNumber} (checkpoints ${fromCheckpoint} to ${toCheckpoint})`,
230
251
  );
231
252
  this.state = 'completed';
232
- this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeBlocks, epochSizeTxs);
253
+ this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeCheckpoints, epochSizeBlocks, epochSizeTxs);
233
254
  return;
234
255
  }
235
256
 
236
257
  const success = await this.publisher.submitEpochProof({
237
- fromBlock,
238
- toBlock,
258
+ fromCheckpoint,
259
+ toCheckpoint,
239
260
  epochNumber,
240
261
  publicInputs,
241
262
  proof,
@@ -246,12 +267,12 @@ export class EpochProvingJob implements Traceable {
246
267
  throw new Error('Failed to submit epoch proof to L1');
247
268
  }
248
269
 
249
- this.log.info(`Submitted proof for epoch ${epochNumber} (blocks ${fromBlock} to ${toBlock})`, {
270
+ this.log.info(`Submitted proof for epoch ${epochNumber} (checkpoints ${fromCheckpoint} to ${toCheckpoint})`, {
250
271
  epochNumber,
251
272
  uuid: this.uuid,
252
273
  });
253
274
  this.state = 'completed';
254
- this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeBlocks, epochSizeTxs);
275
+ this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeCheckpoints, epochSizeBlocks, epochSizeTxs);
255
276
  } catch (err: any) {
256
277
  if (err && err.name === 'HaltExecutionError') {
257
278
  this.log.warn(`Halted execution of epoch ${epochNumber} prover job`, {
@@ -277,7 +298,7 @@ export class EpochProvingJob implements Traceable {
277
298
  * Create a new db fork for tx processing, inserting all L1 to L2.
278
299
  * REFACTOR: The prover already spawns a db fork of its own for each block, so we may be able to do away with just one fork.
279
300
  */
280
- private async createFork(blockNumber: number, l1ToL2Messages: Fr[]) {
301
+ private async createFork(blockNumber: BlockNumber, l1ToL2Messages: Fr[]) {
281
302
  const db = await this.dbProvider.fork(blockNumber);
282
303
  const l1ToL2MessagesPadded = padArrayEnd<Fr, number>(
283
304
  l1ToL2Messages,
@@ -346,11 +367,12 @@ export class EpochProvingJob implements Traceable {
346
367
  const intervalMs = Math.ceil((await l2BlockSource.getL1Constants()).ethereumSlotDuration / 2) * 1000;
347
368
  this.epochCheckPromise = new RunningPromise(
348
369
  async () => {
349
- const blocks = await l2BlockSource.getBlockHeadersForEpoch(this.epochNumber);
350
- const blockHashes = await Promise.all(blocks.map(block => block.hash()));
351
- const thisBlockHashes = await Promise.all(this.blocks.map(block => block.hash()));
370
+ const blockHeaders = await l2BlockSource.getCheckpointedBlockHeadersForEpoch(this.epochNumber);
371
+ const blockHashes = await Promise.all(blockHeaders.map(header => header.hash()));
372
+ const thisBlocks = this.checkpoints.flatMap(checkpoint => checkpoint.blocks);
373
+ const thisBlockHashes = await Promise.all(thisBlocks.map(block => block.hash()));
352
374
  if (
353
- blocks.length !== this.blocks.length ||
375
+ blockHeaders.length !== thisBlocks.length ||
354
376
  !blockHashes.every((block, i) => block.equals(thisBlockHashes[i]))
355
377
  ) {
356
378
  this.log.warn('Epoch blocks changed underfoot', {
@@ -368,30 +390,18 @@ export class EpochProvingJob implements Traceable {
368
390
  this.log.verbose(`Scheduled epoch check for epoch ${this.epochNumber} every ${intervalMs}ms`);
369
391
  }
370
392
 
371
- /* Returns the header for the given block number based on the epoch proving job data. */
372
- private getBlockHeader(blockNumber: number) {
373
- const block = this.blocks.find(b => b.number === blockNumber);
374
- if (block) {
375
- return block.getBlockHeader();
376
- }
377
-
378
- if (blockNumber === Number(this.data.previousBlockHeader.getBlockNumber())) {
379
- return this.data.previousBlockHeader;
380
- }
381
-
382
- throw new Error(
383
- `Block header not found for block number ${blockNumber} (got ${this.blocks
384
- .map(b => b.number)
385
- .join(', ')} and previous header ${this.data.previousBlockHeader.getBlockNumber()})`,
386
- );
393
+ /* Returns the last block header in the previous checkpoint for all checkpoints in the epoch */
394
+ private gatherPreviousBlockHeaders() {
395
+ const lastBlocks = this.checkpoints.map(checkpoint => checkpoint.blocks.at(-1)!);
396
+ return [this.data.previousBlockHeader, ...lastBlocks.map(block => block.header).slice(0, -1)];
387
397
  }
388
398
 
389
399
  private getTxs(block: L2Block): Tx[] {
390
400
  return block.body.txEffects.map(txEffect => this.txs.get(txEffect.txHash.toString())!);
391
401
  }
392
402
 
393
- private getL1ToL2Messages(block: L2Block) {
394
- return this.data.l1ToL2Messages[block.number];
403
+ private getL1ToL2Messages(checkpoint: Checkpoint) {
404
+ return this.data.l1ToL2Messages[checkpoint.number];
395
405
  }
396
406
 
397
407
  private async processTxs(publicProcessor: PublicProcessor, txs: Tx[]): Promise<ProcessedTx[]> {
package/src/metrics.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { RollupContract } from '@aztec/ethereum';
1
+ import type { RollupContract } from '@aztec/ethereum/contracts';
2
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import type { L1PublishProofStats, L1PublishStats } from '@aztec/stdlib/stats';
@@ -13,7 +13,7 @@ import {
13
13
  type TelemetryClient,
14
14
  type Tracer,
15
15
  type UpDownCounter,
16
- ValueType,
16
+ createUpDownCounterWithDefault,
17
17
  } from '@aztec/telemetry-client';
18
18
 
19
19
  import { formatEther, formatUnits } from 'viem';
@@ -21,6 +21,7 @@ import { formatEther, formatUnits } from 'viem';
21
21
  export class ProverNodeJobMetrics {
22
22
  proverEpochExecutionDuration: Histogram;
23
23
  provingJobDuration: Histogram;
24
+ provingJobCheckpoints: Gauge;
24
25
  provingJobBlocks: Gauge;
25
26
  provingJobTransactions: Gauge;
26
27
 
@@ -29,29 +30,23 @@ export class ProverNodeJobMetrics {
29
30
  public readonly tracer: Tracer,
30
31
  private logger = createLogger('prover-node:publisher:metrics'),
31
32
  ) {
32
- this.proverEpochExecutionDuration = this.meter.createHistogram(Metrics.PROVER_NODE_EXECUTION_DURATION, {
33
- description: 'Duration of execution of an epoch by the prover',
34
- unit: 'ms',
35
- valueType: ValueType.INT,
36
- });
37
- this.provingJobDuration = this.meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
38
- description: 'Duration of proving job',
39
- unit: 's',
40
- valueType: ValueType.DOUBLE,
41
- });
42
- this.provingJobBlocks = this.meter.createGauge(Metrics.PROVER_NODE_JOB_BLOCKS, {
43
- description: 'Number of blocks in a proven epoch',
44
- valueType: ValueType.INT,
45
- });
46
- this.provingJobTransactions = this.meter.createGauge(Metrics.PROVER_NODE_JOB_TRANSACTIONS, {
47
- description: 'Number of transactions in a proven epoch',
48
- valueType: ValueType.INT,
49
- });
33
+ this.proverEpochExecutionDuration = this.meter.createHistogram(Metrics.PROVER_NODE_EXECUTION_DURATION);
34
+ this.provingJobDuration = this.meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION);
35
+ this.provingJobCheckpoints = this.meter.createGauge(Metrics.PROVER_NODE_JOB_CHECKPOINTS);
36
+ this.provingJobBlocks = this.meter.createGauge(Metrics.PROVER_NODE_JOB_BLOCKS);
37
+ this.provingJobTransactions = this.meter.createGauge(Metrics.PROVER_NODE_JOB_TRANSACTIONS);
50
38
  }
51
39
 
52
- public recordProvingJob(executionTimeMs: number, totalTimeMs: number, numBlocks: number, numTxs: number) {
40
+ public recordProvingJob(
41
+ executionTimeMs: number,
42
+ totalTimeMs: number,
43
+ numCheckpoints: number,
44
+ numBlocks: number,
45
+ numTxs: number,
46
+ ) {
53
47
  this.proverEpochExecutionDuration.record(Math.ceil(executionTimeMs));
54
48
  this.provingJobDuration.record(totalTimeMs / 1000);
49
+ this.provingJobCheckpoints.record(Math.floor(numCheckpoints));
55
50
  this.provingJobBlocks.record(Math.floor(numBlocks));
56
51
  this.provingJobTransactions.record(Math.floor(numTxs));
57
52
  }
@@ -69,15 +64,9 @@ export class ProverNodeRewardsMetrics {
69
64
  private rollup: RollupContract,
70
65
  private logger = createLogger('prover-node:publisher:metrics'),
71
66
  ) {
72
- this.rewards = this.meter.createObservableGauge(Metrics.PROVER_NODE_REWARDS_PER_EPOCH, {
73
- valueType: ValueType.DOUBLE,
74
- description: 'The rewards earned',
75
- });
67
+ this.rewards = this.meter.createObservableGauge(Metrics.PROVER_NODE_REWARDS_PER_EPOCH);
76
68
 
77
- this.accumulatedRewards = this.meter.createUpDownCounter(Metrics.PROVER_NODE_REWARDS_TOTAL, {
78
- valueType: ValueType.DOUBLE,
79
- description: 'The rewards earned (total)',
80
- });
69
+ this.accumulatedRewards = createUpDownCounterWithDefault(this.meter, Metrics.PROVER_NODE_REWARDS_TOTAL);
81
70
  }
82
71
 
83
72
  public async start() {
@@ -138,68 +127,28 @@ export class ProverNodePublisherMetrics {
138
127
  ) {
139
128
  this.meter = client.getMeter(name);
140
129
 
141
- this.gasPrice = this.meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE, {
142
- description: 'The gas price used for transactions',
143
- unit: 'gwei',
144
- valueType: ValueType.DOUBLE,
145
- });
130
+ this.gasPrice = this.meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE);
146
131
 
147
- this.txCount = this.meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT, {
148
- description: 'The number of transactions processed',
132
+ this.txCount = createUpDownCounterWithDefault(this.meter, Metrics.L1_PUBLISHER_TX_COUNT, {
133
+ [Attributes.L1_TX_TYPE]: ['submitProof'],
134
+ [Attributes.OK]: [true, false],
149
135
  });
150
136
 
151
- this.txDuration = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION, {
152
- description: 'The duration of transaction processing',
153
- unit: 'ms',
154
- valueType: ValueType.INT,
155
- });
137
+ this.txDuration = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION);
156
138
 
157
- this.txGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS, {
158
- description: 'The gas consumed by transactions',
159
- unit: 'gas',
160
- valueType: ValueType.INT,
161
- });
139
+ this.txGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS);
162
140
 
163
- this.txCalldataSize = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE, {
164
- description: 'The size of the calldata in transactions',
165
- unit: 'By',
166
- valueType: ValueType.INT,
167
- });
141
+ this.txCalldataSize = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE);
168
142
 
169
- this.txCalldataGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS, {
170
- description: 'The gas consumed by the calldata in transactions',
171
- unit: 'gas',
172
- valueType: ValueType.INT,
173
- });
143
+ this.txCalldataGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS);
174
144
 
175
- this.txBlobDataGasUsed = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED, {
176
- description: 'The amount of blob gas used in transactions',
177
- unit: 'gas',
178
- valueType: ValueType.INT,
179
- });
145
+ this.txBlobDataGasUsed = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED);
180
146
 
181
- this.txBlobDataGasCost = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST, {
182
- description: 'The gas cost of blobs in transactions',
183
- unit: 'gwei',
184
- valueType: ValueType.INT,
185
- });
147
+ this.txBlobDataGasCost = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST);
186
148
 
187
- this.txTotalFee = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_TOTAL_FEE, {
188
- description: 'How much L1 tx costs',
189
- unit: 'gwei',
190
- valueType: ValueType.DOUBLE,
191
- advice: {
192
- explicitBucketBoundaries: [
193
- 0.001, 0.002, 0.004, 0.008, 0.01, 0.02, 0.04, 0.08, 0.1, 0.2, 0.4, 0.8, 1, 1.2, 1.4, 1.8, 2,
194
- ],
195
- },
196
- });
149
+ this.txTotalFee = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_TOTAL_FEE);
197
150
 
198
- this.senderBalance = this.meter.createGauge(Metrics.L1_PUBLISHER_BALANCE, {
199
- unit: 'eth',
200
- description: 'The balance of the sender address',
201
- valueType: ValueType.DOUBLE,
202
- });
151
+ this.senderBalance = this.meter.createGauge(Metrics.L1_PUBLISHER_BALANCE);
203
152
  }
204
153
 
205
154
  recordFailedTx() {
@@ -1,16 +1,10 @@
1
- import { EpochNumber } from '@aztec/foundation/branded-types';
1
+ import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { RunningPromise } from '@aztec/foundation/running-promise';
4
4
  import { sleep } from '@aztec/foundation/sleep';
5
5
  import type { L2BlockSource } from '@aztec/stdlib/block';
6
6
  import { type L1RollupConstants, getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
7
- import {
8
- type TelemetryClient,
9
- type Traceable,
10
- type Tracer,
11
- getTelemetryClient,
12
- trackSpan,
13
- } from '@aztec/telemetry-client';
7
+ import { type TelemetryClient, type Traceable, type Tracer, getTelemetryClient } from '@aztec/telemetry-client';
14
8
 
15
9
  export interface EpochMonitorHandler {
16
10
  handleEpochReadyToProve(epochNumber: EpochNumber): Promise<boolean>;
@@ -73,7 +67,6 @@ export class EpochMonitor implements Traceable {
73
67
  this.log.info('Stopped EpochMonitor');
74
68
  }
75
69
 
76
- @trackSpan('EpochMonitor.work')
77
70
  public async work() {
78
71
  const { epochToProve, blockNumber, slotNumber } = await this.getEpochNumberToProve();
79
72
  this.log.debug(`Epoch to prove: ${epochToProve}`, { blockNumber, slotNumber });
@@ -105,7 +98,7 @@ export class EpochMonitor implements Traceable {
105
98
 
106
99
  private async getEpochNumberToProve() {
107
100
  const lastBlockProven = await this.l2BlockSource.getProvenBlockNumber();
108
- const firstBlockToProve = lastBlockProven + 1;
101
+ const firstBlockToProve = BlockNumber(lastBlockProven + 1);
109
102
  const firstBlockHeaderToProve = await this.l2BlockSource.getBlockHeader(firstBlockToProve);
110
103
  if (!firstBlockHeaderToProve) {
111
104
  return { epochToProve: undefined, blockNumber: firstBlockToProve };