@aztec/prover-node 0.0.1-commit.934299a21 → 0.0.1-commit.949a33fd8
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.js +1 -1
- package/dest/actions/rerun-epoch-proving-job.d.ts +4 -3
- package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
- package/dest/actions/rerun-epoch-proving-job.js +5 -6
- package/dest/actions/upload-epoch-proof-failure.d.ts +2 -2
- package/dest/actions/upload-epoch-proof-failure.d.ts.map +1 -1
- package/dest/config.d.ts +2 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -2
- package/dest/factory.d.ts +2 -3
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +25 -7
- package/dest/job/epoch-proving-job.d.ts +2 -2
- package/dest/job/epoch-proving-job.d.ts.map +1 -1
- package/dest/job/epoch-proving-job.js +27 -4
- package/dest/metrics.d.ts +21 -1
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +47 -0
- 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 +5 -7
- package/dest/prover-node-publisher.d.ts +16 -1
- package/dest/prover-node-publisher.d.ts.map +1 -1
- package/dest/prover-node-publisher.js +52 -3
- package/dest/prover-node.d.ts +2 -2
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +5 -3
- package/dest/prover-publisher-factory.d.ts +2 -2
- package/dest/prover-publisher-factory.d.ts.map +1 -1
- package/dest/prover-publisher-factory.js +3 -3
- package/package.json +23 -22
- package/src/actions/download-epoch-proving-job.ts +1 -1
- package/src/actions/rerun-epoch-proving-job.ts +9 -4
- package/src/actions/upload-epoch-proof-failure.ts +1 -1
- package/src/config.ts +2 -2
- package/src/factory.ts +20 -8
- package/src/job/epoch-proving-job.ts +34 -5
- package/src/metrics.ts +71 -0
- package/src/monitors/epoch-monitor.ts +3 -4
- package/src/prover-node-publisher.ts +73 -5
- package/src/prover-node.ts +6 -4
- package/src/prover-publisher-factory.ts +3 -3
package/src/metrics.ts
CHANGED
|
@@ -25,6 +25,12 @@ export class ProverNodeJobMetrics {
|
|
|
25
25
|
provingJobBlocks: Gauge;
|
|
26
26
|
provingJobTransactions: Gauge;
|
|
27
27
|
|
|
28
|
+
private blobProcessingDuration: Gauge;
|
|
29
|
+
private chonkVerifierDuration: Gauge;
|
|
30
|
+
private blockProcessingDuration: Histogram;
|
|
31
|
+
private checkpointProcessingDuration: Histogram;
|
|
32
|
+
private allCheckpointsProcessingDuration: Gauge;
|
|
33
|
+
|
|
28
34
|
constructor(
|
|
29
35
|
private meter: Meter,
|
|
30
36
|
public readonly tracer: Tracer,
|
|
@@ -35,6 +41,14 @@ export class ProverNodeJobMetrics {
|
|
|
35
41
|
this.provingJobCheckpoints = this.meter.createGauge(Metrics.PROVER_NODE_JOB_CHECKPOINTS);
|
|
36
42
|
this.provingJobBlocks = this.meter.createGauge(Metrics.PROVER_NODE_JOB_BLOCKS);
|
|
37
43
|
this.provingJobTransactions = this.meter.createGauge(Metrics.PROVER_NODE_JOB_TRANSACTIONS);
|
|
44
|
+
|
|
45
|
+
this.blobProcessingDuration = this.meter.createGauge(Metrics.PROVER_NODE_BLOB_PROCESSING_LAST_DURATION);
|
|
46
|
+
this.chonkVerifierDuration = this.meter.createGauge(Metrics.PROVER_NODE_CHONK_VERIFIER_LAST_DURATION);
|
|
47
|
+
this.blockProcessingDuration = this.meter.createHistogram(Metrics.PROVER_NODE_BLOCK_PROCESSING_DURATION);
|
|
48
|
+
this.checkpointProcessingDuration = this.meter.createHistogram(Metrics.PROVER_NODE_CHECKPOINT_PROCESSING_DURATION);
|
|
49
|
+
this.allCheckpointsProcessingDuration = this.meter.createGauge(
|
|
50
|
+
Metrics.PROVER_NODE_ALL_CHECKPOINTS_PROCESSING_LAST_DURATION,
|
|
51
|
+
);
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
public recordProvingJob(
|
|
@@ -50,6 +64,26 @@ export class ProverNodeJobMetrics {
|
|
|
50
64
|
this.provingJobBlocks.record(Math.floor(numBlocks));
|
|
51
65
|
this.provingJobTransactions.record(Math.floor(numTxs));
|
|
52
66
|
}
|
|
67
|
+
|
|
68
|
+
public recordBlobProcessing(durationMs: number) {
|
|
69
|
+
this.blobProcessingDuration.record(Math.ceil(durationMs));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public recordChonkVerifier(durationMs: number) {
|
|
73
|
+
this.chonkVerifierDuration.record(Math.ceil(durationMs));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public recordBlockProcessing(durationMs: number) {
|
|
77
|
+
this.blockProcessingDuration.record(Math.ceil(durationMs));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public recordCheckpointProcessing(durationMs: number) {
|
|
81
|
+
this.checkpointProcessingDuration.record(Math.ceil(durationMs));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public recordAllCheckpointsProcessing(durationMs: number) {
|
|
85
|
+
this.allCheckpointsProcessingDuration.record(Math.ceil(durationMs));
|
|
86
|
+
}
|
|
53
87
|
}
|
|
54
88
|
|
|
55
89
|
export class ProverNodeRewardsMetrics {
|
|
@@ -106,6 +140,13 @@ export class ProverNodeRewardsMetrics {
|
|
|
106
140
|
};
|
|
107
141
|
}
|
|
108
142
|
|
|
143
|
+
export type EstimatedSubmitProofStats = {
|
|
144
|
+
gasLimit: bigint;
|
|
145
|
+
baseFeePerGas: bigint;
|
|
146
|
+
maxPriorityFeePerGas: bigint;
|
|
147
|
+
estimatedTotalFee: bigint;
|
|
148
|
+
};
|
|
149
|
+
|
|
109
150
|
export class ProverNodePublisherMetrics {
|
|
110
151
|
gasPrice: Histogram;
|
|
111
152
|
txCount: UpDownCounter;
|
|
@@ -117,6 +158,10 @@ export class ProverNodePublisherMetrics {
|
|
|
117
158
|
txBlobDataGasCost: Histogram;
|
|
118
159
|
txTotalFee: Histogram;
|
|
119
160
|
|
|
161
|
+
private txGasEstimated: Histogram;
|
|
162
|
+
private gasPriceEstimated: Histogram;
|
|
163
|
+
private txTotalFeeEstimated: Histogram;
|
|
164
|
+
|
|
120
165
|
private senderBalance: Gauge;
|
|
121
166
|
private meter: Meter;
|
|
122
167
|
|
|
@@ -148,6 +193,12 @@ export class ProverNodePublisherMetrics {
|
|
|
148
193
|
|
|
149
194
|
this.txTotalFee = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_TOTAL_FEE);
|
|
150
195
|
|
|
196
|
+
this.txGasEstimated = this.meter.createHistogram(Metrics.PROVER_NODE_ESTIMATED_SUBMISSION_GAS);
|
|
197
|
+
|
|
198
|
+
this.gasPriceEstimated = this.meter.createHistogram(Metrics.PROVER_NODE_ESTIMATED_SUBMISSION_GAS_PRICE);
|
|
199
|
+
|
|
200
|
+
this.txTotalFeeEstimated = this.meter.createHistogram(Metrics.PROVER_NODE_ESTIMATED_SUBMISSION_TOTAL_FEE);
|
|
201
|
+
|
|
151
202
|
this.senderBalance = this.meter.createGauge(Metrics.L1_PUBLISHER_BALANCE);
|
|
152
203
|
}
|
|
153
204
|
|
|
@@ -162,6 +213,26 @@ export class ProverNodePublisherMetrics {
|
|
|
162
213
|
this.recordTx(durationMs, stats);
|
|
163
214
|
}
|
|
164
215
|
|
|
216
|
+
public recordEstimatedSubmitProof(stats: EstimatedSubmitProofStats) {
|
|
217
|
+
const attributes = { [Attributes.L1_TX_TYPE]: 'submitProof' } as const;
|
|
218
|
+
|
|
219
|
+
this.txGasEstimated.record(Number(stats.gasLimit), attributes);
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
this.gasPriceEstimated.record(
|
|
223
|
+
parseInt(formatEther(stats.baseFeePerGas + stats.maxPriorityFeePerGas, 'gwei'), 10),
|
|
224
|
+
);
|
|
225
|
+
} catch {
|
|
226
|
+
// ignore
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
this.txTotalFeeEstimated.record(parseFloat(formatEther(stats.estimatedTotalFee)));
|
|
231
|
+
} catch {
|
|
232
|
+
// ignore
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
165
236
|
public recordSenderBalance(wei: bigint, senderAddress: string) {
|
|
166
237
|
const eth = parseFloat(formatEther(wei, 'wei'));
|
|
167
238
|
this.senderBalance.record(eth, {
|
|
@@ -69,9 +69,8 @@ export class EpochMonitor implements Traceable {
|
|
|
69
69
|
|
|
70
70
|
public async work() {
|
|
71
71
|
const { epochToProve, blockNumber, slotNumber } = await this.getEpochNumberToProve();
|
|
72
|
-
this.log.debug(`Epoch to prove: ${epochToProve}`, { blockNumber, slotNumber });
|
|
73
72
|
if (epochToProve === undefined) {
|
|
74
|
-
this.log.trace(`Next block to prove ${blockNumber} not yet mined`, { blockNumber });
|
|
73
|
+
this.log.trace(`Next block to prove ${blockNumber} not yet mined`, { epochToProve, blockNumber, slotNumber });
|
|
75
74
|
return;
|
|
76
75
|
}
|
|
77
76
|
if (this.latestEpochNumber !== undefined && epochToProve <= this.latestEpochNumber) {
|
|
@@ -86,11 +85,11 @@ export class EpochMonitor implements Traceable {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
if (this.options.provingDelayMs) {
|
|
89
|
-
this.log.
|
|
88
|
+
this.log.warn(`Waiting ${this.options.provingDelayMs}ms before proving epoch ${epochToProve}`);
|
|
90
89
|
await sleep(this.options.provingDelayMs);
|
|
91
90
|
}
|
|
92
91
|
|
|
93
|
-
this.log.
|
|
92
|
+
this.log.verbose(`Epoch ${epochToProve} is ready to be proven`);
|
|
94
93
|
if (await this.handler?.handleEpochReadyToProve(epochToProve)) {
|
|
95
94
|
this.latestEpochNumber = epochToProve;
|
|
96
95
|
}
|
|
@@ -19,9 +19,9 @@ import type { L1PublishProofStats } from '@aztec/stdlib/stats';
|
|
|
19
19
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
20
20
|
|
|
21
21
|
import { inspect } from 'util';
|
|
22
|
-
import { type Hex, type TransactionReceipt, encodeFunctionData } from 'viem';
|
|
22
|
+
import { type Hex, type TransactionReceipt, encodeFunctionData, formatEther, formatGwei } from 'viem';
|
|
23
23
|
|
|
24
|
-
import { ProverNodePublisherMetrics } from './metrics.js';
|
|
24
|
+
import { type EstimatedSubmitProofStats, ProverNodePublisherMetrics } from './metrics.js';
|
|
25
25
|
|
|
26
26
|
/** Arguments to the submitEpochProof method of the rollup contract */
|
|
27
27
|
export type L1SubmitEpochProofArgs = {
|
|
@@ -168,7 +168,7 @@ export class ProverNodePublisher {
|
|
|
168
168
|
// toCheckpoint can't be greater than pending
|
|
169
169
|
if (toCheckpoint > pending) {
|
|
170
170
|
throw new Error(
|
|
171
|
-
`Cannot submit epoch proof for ${fromCheckpoint}-${toCheckpoint} as
|
|
171
|
+
`Cannot submit epoch proof for ${fromCheckpoint}-${toCheckpoint} as proposed checkpoint is ${pending}`,
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -210,6 +210,74 @@ export class ProverNodePublisher {
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Estimates what submitting the epoch proof would have cost on L1 without actually sending it.
|
|
215
|
+
* Runs the same validation as `submitEpochProof`, encodes the calldata, estimates gas, and records metrics.
|
|
216
|
+
* Used when proof publishing is disabled (e.g. PROVER_NODE_DISABLE_PROOF_PUBLISH=true on mainnet).
|
|
217
|
+
*/
|
|
218
|
+
public async analyzeEpochProofSubmission(args: {
|
|
219
|
+
epochNumber: EpochNumber;
|
|
220
|
+
fromCheckpoint: CheckpointNumber;
|
|
221
|
+
toCheckpoint: CheckpointNumber;
|
|
222
|
+
publicInputs: RootRollupPublicInputs;
|
|
223
|
+
proof: Proof;
|
|
224
|
+
batchedBlobInputs: BatchedBlob;
|
|
225
|
+
attestations: ViemCommitteeAttestation[];
|
|
226
|
+
}): Promise<void> {
|
|
227
|
+
const { epochNumber, fromCheckpoint, toCheckpoint } = args;
|
|
228
|
+
|
|
229
|
+
await this.validateEpochProofSubmission(args);
|
|
230
|
+
|
|
231
|
+
const data = this.encodeSubmitEpochProofCalldata(args);
|
|
232
|
+
const senderAddress = this.l1TxUtils.getSenderAddress();
|
|
233
|
+
|
|
234
|
+
const [gasLimit, gasPrice, latestBlock] = await Promise.all([
|
|
235
|
+
this.l1TxUtils.estimateGas(senderAddress.toString() as `0x${string}`, { to: this.rollupContract.address, data }),
|
|
236
|
+
this.l1TxUtils.getGasPrice(),
|
|
237
|
+
this.l1TxUtils.client.getBlock({ blockTag: 'latest' }),
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
const baseFeePerGas = latestBlock.baseFeePerGas ?? 0n;
|
|
241
|
+
const { maxPriorityFeePerGas } = gasPrice;
|
|
242
|
+
|
|
243
|
+
const effectiveFeePerGas = baseFeePerGas + maxPriorityFeePerGas;
|
|
244
|
+
const estimatedTotalFee = gasLimit * effectiveFeePerGas;
|
|
245
|
+
|
|
246
|
+
const stats: EstimatedSubmitProofStats = {
|
|
247
|
+
gasLimit,
|
|
248
|
+
baseFeePerGas,
|
|
249
|
+
maxPriorityFeePerGas,
|
|
250
|
+
estimatedTotalFee,
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
this.log.info(`Estimated epoch proof submission cost (not submitted)`, {
|
|
254
|
+
epochNumber,
|
|
255
|
+
fromCheckpoint,
|
|
256
|
+
toCheckpoint,
|
|
257
|
+
gasLimit: gasLimit.toString(),
|
|
258
|
+
baseFeePerGas: formatGwei(baseFeePerGas),
|
|
259
|
+
maxPriorityFeePerGas: formatGwei(maxPriorityFeePerGas),
|
|
260
|
+
estimatedTotalFeeEth: formatEther(estimatedTotalFee),
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
this.metrics.recordEstimatedSubmitProof(stats);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private encodeSubmitEpochProofCalldata(args: {
|
|
267
|
+
fromCheckpoint: CheckpointNumber;
|
|
268
|
+
toCheckpoint: CheckpointNumber;
|
|
269
|
+
publicInputs: RootRollupPublicInputs;
|
|
270
|
+
proof: Proof;
|
|
271
|
+
batchedBlobInputs: BatchedBlob;
|
|
272
|
+
attestations: ViemCommitteeAttestation[];
|
|
273
|
+
}): Hex {
|
|
274
|
+
return encodeFunctionData({
|
|
275
|
+
abi: RollupAbi,
|
|
276
|
+
functionName: 'submitEpochRootProof',
|
|
277
|
+
args: [this.getSubmitEpochProofArgs(args)],
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
213
281
|
private async sendSubmitEpochProofTx(args: {
|
|
214
282
|
fromCheckpoint: CheckpointNumber;
|
|
215
283
|
toCheckpoint: CheckpointNumber;
|
|
@@ -296,9 +364,9 @@ export class ProverNodePublisher {
|
|
|
296
364
|
end: argsArray[1],
|
|
297
365
|
args: argsArray[2],
|
|
298
366
|
fees: argsArray[3],
|
|
299
|
-
attestations:
|
|
367
|
+
attestations: CommitteeAttestationsAndSigners.packAttestations(
|
|
300
368
|
args.attestations.map(a => CommitteeAttestation.fromViem(a)),
|
|
301
|
-
)
|
|
369
|
+
),
|
|
302
370
|
blobInputs: argsArray[4],
|
|
303
371
|
proof: proofHex,
|
|
304
372
|
};
|
package/src/prover-node.ts
CHANGED
|
@@ -7,7 +7,6 @@ import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
7
7
|
import { memoize } from '@aztec/foundation/decorators';
|
|
8
8
|
import { createLogger } from '@aztec/foundation/log';
|
|
9
9
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
10
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
11
10
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
12
11
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
13
12
|
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
@@ -24,6 +23,7 @@ import {
|
|
|
24
23
|
type WorldStateSynchronizer,
|
|
25
24
|
tryStop,
|
|
26
25
|
} from '@aztec/stdlib/interfaces/server';
|
|
26
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
27
27
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
28
28
|
import type { Tx } from '@aztec/stdlib/tx';
|
|
29
29
|
import {
|
|
@@ -84,7 +84,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
84
84
|
this.config = {
|
|
85
85
|
proverNodePollingIntervalMs: 1_000,
|
|
86
86
|
proverNodeMaxPendingJobs: 100,
|
|
87
|
-
proverNodeMaxParallelBlocksPerEpoch:
|
|
87
|
+
proverNodeMaxParallelBlocksPerEpoch: 0,
|
|
88
88
|
txGatheringIntervalMs: 1_000,
|
|
89
89
|
txGatheringBatchSize: 10,
|
|
90
90
|
txGatheringMaxParallelRequestsPerNode: 100,
|
|
@@ -279,13 +279,15 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
279
279
|
const fromCheckpoint = epochData.checkpoints[0].number;
|
|
280
280
|
const toCheckpoint = epochData.checkpoints.at(-1)!.number;
|
|
281
281
|
const fromBlock = epochData.checkpoints[0].blocks[0].number;
|
|
282
|
-
const
|
|
282
|
+
const lastBlock = epochData.checkpoints.at(-1)!.blocks.at(-1)!;
|
|
283
|
+
const toBlock = lastBlock.number;
|
|
283
284
|
this.log.verbose(
|
|
284
285
|
`Creating proving job for epoch ${epochNumber} for checkpoint range ${fromCheckpoint} to ${toCheckpoint} and block range ${fromBlock} to ${toBlock}`,
|
|
285
286
|
);
|
|
286
287
|
|
|
287
288
|
// Fast forward world state to right before the target block and get a fork
|
|
288
|
-
await
|
|
289
|
+
const lastBlockHash = await lastBlock.header.hash();
|
|
290
|
+
await this.worldState.syncImmediate(toBlock, lastBlockHash);
|
|
289
291
|
|
|
290
292
|
// Create a processor factory
|
|
291
293
|
const publicProcessorFactory = new PublicProcessorFactory(
|
|
@@ -19,11 +19,11 @@ export class ProverPublisherFactory {
|
|
|
19
19
|
) {}
|
|
20
20
|
|
|
21
21
|
public async start() {
|
|
22
|
-
await this.deps.publisherManager.
|
|
22
|
+
await this.deps.publisherManager.start();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
public stop() {
|
|
26
|
-
this.deps.publisherManager.
|
|
25
|
+
public async stop() {
|
|
26
|
+
await this.deps.publisherManager.stop();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|