@aztec/prover-node 0.0.1-commit.21caa21 → 0.0.1-commit.21ecf947b
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/actions/download-epoch-proving-job.d.ts +1 -1
- package/dest/actions/rerun-epoch-proving-job.d.ts +3 -2
- package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
- package/dest/actions/rerun-epoch-proving-job.js +5 -3
- package/dest/config.d.ts +5 -4
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +4 -3
- package/dest/factory.d.ts +5 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +28 -19
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/job/epoch-proving-job-data.d.ts +7 -6
- package/dest/job/epoch-proving-job-data.d.ts.map +1 -1
- package/dest/job/epoch-proving-job-data.js +24 -18
- package/dest/job/epoch-proving-job.d.ts +5 -4
- package/dest/job/epoch-proving-job.d.ts.map +1 -1
- package/dest/job/epoch-proving-job.js +499 -108
- package/dest/metrics.d.ts +4 -3
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +29 -97
- package/dest/monitors/epoch-monitor.d.ts +1 -1
- package/dest/monitors/epoch-monitor.d.ts.map +1 -1
- package/dest/monitors/epoch-monitor.js +3 -11
- package/dest/prover-node-publisher.d.ts +12 -10
- package/dest/prover-node-publisher.d.ts.map +1 -1
- package/dest/prover-node-publisher.js +46 -40
- package/dest/prover-node.d.ts +4 -4
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +429 -47
- package/dest/prover-publisher-factory.d.ts +7 -3
- package/dest/prover-publisher-factory.d.ts.map +1 -1
- package/dest/prover-publisher-factory.js +4 -2
- package/package.json +25 -25
- package/src/actions/rerun-epoch-proving-job.ts +5 -3
- package/src/bin/run-failed-epoch.ts +1 -1
- package/src/config.ts +6 -4
- package/src/factory.ts +36 -22
- package/src/index.ts +1 -0
- package/src/job/epoch-proving-job-data.ts +28 -23
- package/src/job/epoch-proving-job.ts +133 -111
- package/src/metrics.ts +30 -81
- package/src/monitors/epoch-monitor.ts +3 -10
- package/src/prover-node-publisher.ts +67 -55
- package/src/prover-node.ts +38 -32
- 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/
|
|
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
|
|
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
|
|
95
|
-
return this.data.
|
|
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
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
|
|
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
|
-
|
|
140
|
+
epochSizeTxs,
|
|
127
141
|
epochNumber,
|
|
128
142
|
uuid: this.uuid,
|
|
129
143
|
});
|
|
@@ -134,86 +148,98 @@ export class EpochProvingJob implements Traceable {
|
|
|
134
148
|
this.runPromise = promise;
|
|
135
149
|
|
|
136
150
|
try {
|
|
137
|
-
const blobFieldsPerCheckpoint = this.
|
|
151
|
+
const blobFieldsPerCheckpoint = this.checkpoints.map(checkpoint => checkpoint.toBlobFields());
|
|
138
152
|
const finalBlobBatchingChallenges = await buildFinalBlobChallenges(blobFieldsPerCheckpoint);
|
|
139
153
|
|
|
140
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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();
|
|
161
|
+
|
|
162
|
+
await asyncPool(this.config.parallelBlockLimit ?? 32, this.checkpoints, async checkpoint => {
|
|
163
|
+
this.checkState();
|
|
166
164
|
|
|
165
|
+
const checkpointIndex = checkpoint.number - fromCheckpoint;
|
|
167
166
|
const checkpointConstants = CheckpointConstantData.from({
|
|
168
|
-
chainId
|
|
169
|
-
version
|
|
167
|
+
chainId,
|
|
168
|
+
version,
|
|
170
169
|
vkTreeRoot: getVKTreeRoot(),
|
|
171
170
|
protocolContractsHash: protocolContractsHash,
|
|
172
171
|
proverId: this.prover.getProverId().toField(),
|
|
173
|
-
slotNumber:
|
|
174
|
-
coinbase:
|
|
175
|
-
feeRecipient:
|
|
176
|
-
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
|
-
|
|
192
|
+
checkpoint.blocks.length,
|
|
188
193
|
previousHeader,
|
|
189
194
|
);
|
|
190
195
|
|
|
191
|
-
|
|
192
|
-
|
|
196
|
+
for (let blockIndex = 0; blockIndex < checkpoint.blocks.length; blockIndex++) {
|
|
197
|
+
const block = checkpoint.blocks[blockIndex];
|
|
198
|
+
const globalVariables = block.header.globalVariables;
|
|
199
|
+
const txs = this.getTxs(block);
|
|
200
|
+
|
|
201
|
+
this.log.verbose(`Starting processing block ${block.number}`, {
|
|
202
|
+
number: block.number,
|
|
203
|
+
blockHash: (await block.hash()).toString(),
|
|
204
|
+
lastArchive: block.header.lastArchive.root,
|
|
205
|
+
noteHashTreeRoot: block.header.state.partial.noteHashTree.root,
|
|
206
|
+
nullifierTreeRoot: block.header.state.partial.nullifierTree.root,
|
|
207
|
+
publicDataTreeRoot: block.header.state.partial.publicDataTree.root,
|
|
208
|
+
...globalVariables,
|
|
209
|
+
numTxs: txs.length,
|
|
210
|
+
});
|
|
193
211
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
// Start block proving
|
|
213
|
+
await this.prover.startNewBlock(block.number, globalVariables.timestamp, txs.length);
|
|
214
|
+
|
|
215
|
+
// Process public fns. L1 to L2 messages are only inserted for the first block of a checkpoint,
|
|
216
|
+
// as the fork for subsequent blocks already includes them from the previous block's synced state.
|
|
217
|
+
const db = await this.createFork(
|
|
218
|
+
BlockNumber(block.number - 1),
|
|
219
|
+
blockIndex === 0 ? l1ToL2Messages : undefined,
|
|
220
|
+
);
|
|
221
|
+
const config = PublicSimulatorConfig.from({
|
|
222
|
+
proverId: this.prover.getProverId().toField(),
|
|
223
|
+
skipFeeEnforcement: false,
|
|
224
|
+
collectDebugLogs: false,
|
|
225
|
+
collectHints: true,
|
|
226
|
+
collectPublicInputs: true,
|
|
227
|
+
collectStatistics: false,
|
|
228
|
+
});
|
|
229
|
+
const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config);
|
|
230
|
+
const processed = await this.processTxs(publicProcessor, txs);
|
|
231
|
+
await this.prover.addTxs(processed);
|
|
232
|
+
await db.close();
|
|
233
|
+
this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, {
|
|
234
|
+
blockNumber: block.number,
|
|
235
|
+
blockHash: (await block.hash()).toString(),
|
|
236
|
+
uuid: this.uuid,
|
|
237
|
+
});
|
|
213
238
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
239
|
+
// Mark block as completed to pad it
|
|
240
|
+
const expectedBlockHeader = block.header;
|
|
241
|
+
await this.prover.setBlockCompleted(block.number, expectedBlockHeader);
|
|
242
|
+
}
|
|
217
243
|
});
|
|
218
244
|
|
|
219
245
|
const executionTime = timer.ms();
|
|
@@ -226,16 +252,16 @@ export class EpochProvingJob implements Traceable {
|
|
|
226
252
|
|
|
227
253
|
if (this.config.skipSubmitProof) {
|
|
228
254
|
this.log.info(
|
|
229
|
-
`Proof publishing is disabled. Dropping valid proof for epoch ${epochNumber} (
|
|
255
|
+
`Proof publishing is disabled. Dropping valid proof for epoch ${epochNumber} (checkpoints ${fromCheckpoint} to ${toCheckpoint})`,
|
|
230
256
|
);
|
|
231
257
|
this.state = 'completed';
|
|
232
|
-
this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeBlocks, epochSizeTxs);
|
|
258
|
+
this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeCheckpoints, epochSizeBlocks, epochSizeTxs);
|
|
233
259
|
return;
|
|
234
260
|
}
|
|
235
261
|
|
|
236
262
|
const success = await this.publisher.submitEpochProof({
|
|
237
|
-
|
|
238
|
-
|
|
263
|
+
fromCheckpoint,
|
|
264
|
+
toCheckpoint,
|
|
239
265
|
epochNumber,
|
|
240
266
|
publicInputs,
|
|
241
267
|
proof,
|
|
@@ -246,12 +272,12 @@ export class EpochProvingJob implements Traceable {
|
|
|
246
272
|
throw new Error('Failed to submit epoch proof to L1');
|
|
247
273
|
}
|
|
248
274
|
|
|
249
|
-
this.log.info(`Submitted proof for epoch ${epochNumber} (
|
|
275
|
+
this.log.info(`Submitted proof for epoch ${epochNumber} (checkpoints ${fromCheckpoint} to ${toCheckpoint})`, {
|
|
250
276
|
epochNumber,
|
|
251
277
|
uuid: this.uuid,
|
|
252
278
|
});
|
|
253
279
|
this.state = 'completed';
|
|
254
|
-
this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeBlocks, epochSizeTxs);
|
|
280
|
+
this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeCheckpoints, epochSizeBlocks, epochSizeTxs);
|
|
255
281
|
} catch (err: any) {
|
|
256
282
|
if (err && err.name === 'HaltExecutionError') {
|
|
257
283
|
this.log.warn(`Halted execution of epoch ${epochNumber} prover job`, {
|
|
@@ -274,22 +300,29 @@ export class EpochProvingJob implements Traceable {
|
|
|
274
300
|
}
|
|
275
301
|
|
|
276
302
|
/**
|
|
277
|
-
* Create a new db fork for tx processing, inserting
|
|
303
|
+
* Create a new db fork for tx processing, optionally inserting L1 to L2 messages.
|
|
304
|
+
* L1 to L2 messages should only be inserted for the first block in a checkpoint,
|
|
305
|
+
* as subsequent blocks' synced state already includes them.
|
|
278
306
|
* 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
307
|
*/
|
|
280
|
-
private async createFork(blockNumber:
|
|
308
|
+
private async createFork(blockNumber: BlockNumber, l1ToL2Messages: Fr[] | undefined) {
|
|
309
|
+
this.log.verbose(`Creating fork at ${blockNumber}`, { blockNumber });
|
|
281
310
|
const db = await this.dbProvider.fork(blockNumber);
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
311
|
+
|
|
312
|
+
if (l1ToL2Messages !== undefined) {
|
|
313
|
+
this.log.verbose(`Inserting ${l1ToL2Messages.length} L1 to L2 messages in fork`, {
|
|
314
|
+
blockNumber,
|
|
315
|
+
l1ToL2Messages: l1ToL2Messages.map(m => m.toString()),
|
|
316
|
+
});
|
|
317
|
+
const l1ToL2MessagesPadded = padArrayEnd<Fr, number>(
|
|
318
|
+
l1ToL2Messages,
|
|
319
|
+
Fr.ZERO,
|
|
320
|
+
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
321
|
+
'Too many L1 to L2 messages',
|
|
322
|
+
);
|
|
323
|
+
await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
|
|
324
|
+
}
|
|
325
|
+
|
|
293
326
|
return db;
|
|
294
327
|
}
|
|
295
328
|
|
|
@@ -346,11 +379,12 @@ export class EpochProvingJob implements Traceable {
|
|
|
346
379
|
const intervalMs = Math.ceil((await l2BlockSource.getL1Constants()).ethereumSlotDuration / 2) * 1000;
|
|
347
380
|
this.epochCheckPromise = new RunningPromise(
|
|
348
381
|
async () => {
|
|
349
|
-
const
|
|
350
|
-
const blockHashes = await Promise.all(
|
|
351
|
-
const
|
|
382
|
+
const blockHeaders = await l2BlockSource.getCheckpointedBlockHeadersForEpoch(this.epochNumber);
|
|
383
|
+
const blockHashes = await Promise.all(blockHeaders.map(header => header.hash()));
|
|
384
|
+
const thisBlocks = this.checkpoints.flatMap(checkpoint => checkpoint.blocks);
|
|
385
|
+
const thisBlockHashes = await Promise.all(thisBlocks.map(block => block.hash()));
|
|
352
386
|
if (
|
|
353
|
-
|
|
387
|
+
blockHeaders.length !== thisBlocks.length ||
|
|
354
388
|
!blockHashes.every((block, i) => block.equals(thisBlockHashes[i]))
|
|
355
389
|
) {
|
|
356
390
|
this.log.warn('Epoch blocks changed underfoot', {
|
|
@@ -368,30 +402,18 @@ export class EpochProvingJob implements Traceable {
|
|
|
368
402
|
this.log.verbose(`Scheduled epoch check for epoch ${this.epochNumber} every ${intervalMs}ms`);
|
|
369
403
|
}
|
|
370
404
|
|
|
371
|
-
/* Returns the header
|
|
372
|
-
private
|
|
373
|
-
const
|
|
374
|
-
|
|
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
|
-
);
|
|
405
|
+
/* Returns the last block header in the previous checkpoint for all checkpoints in the epoch */
|
|
406
|
+
private gatherPreviousBlockHeaders() {
|
|
407
|
+
const lastBlocks = this.checkpoints.map(checkpoint => checkpoint.blocks.at(-1)!);
|
|
408
|
+
return [this.data.previousBlockHeader, ...lastBlocks.map(block => block.header).slice(0, -1)];
|
|
387
409
|
}
|
|
388
410
|
|
|
389
411
|
private getTxs(block: L2Block): Tx[] {
|
|
390
412
|
return block.body.txEffects.map(txEffect => this.txs.get(txEffect.txHash.toString())!);
|
|
391
413
|
}
|
|
392
414
|
|
|
393
|
-
private getL1ToL2Messages(
|
|
394
|
-
return this.data.l1ToL2Messages[
|
|
415
|
+
private getL1ToL2Messages(checkpoint: Checkpoint) {
|
|
416
|
+
return this.data.l1ToL2Messages[checkpoint.number];
|
|
395
417
|
}
|
|
396
418
|
|
|
397
419
|
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
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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(
|
|
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
|
|
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
|
|
148
|
-
|
|
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 };
|