@aztec/prover-node 0.0.1-commit.2f68f620 → 0.0.1-commit.321f6a9
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/README.md +572 -0
- package/dest/actions/rerun-epoch-proving-job.d.ts +12 -3
- package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
- package/dest/actions/rerun-epoch-proving-job.js +170 -28
- package/dest/checkpoint-store.d.ts +95 -0
- package/dest/checkpoint-store.d.ts.map +1 -0
- package/dest/checkpoint-store.js +178 -0
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +1 -1
- package/dest/factory.d.ts +4 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +1 -6
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/job/checkpoint-prover.d.ts +154 -0
- package/dest/job/checkpoint-prover.d.ts.map +1 -0
- package/dest/job/checkpoint-prover.js +363 -0
- package/dest/job/epoch-session.d.ts +160 -0
- package/dest/job/epoch-session.d.ts.map +1 -0
- package/dest/job/epoch-session.js +744 -0
- package/dest/job/top-tree-job.d.ts +82 -0
- package/dest/job/top-tree-job.d.ts.map +1 -0
- package/dest/job/top-tree-job.js +152 -0
- package/dest/metrics.d.ts +25 -8
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +64 -14
- package/dest/proof-publishing-service.d.ts +161 -0
- package/dest/proof-publishing-service.d.ts.map +1 -0
- package/dest/proof-publishing-service.js +335 -0
- package/dest/prover-node-publisher.d.ts +7 -19
- package/dest/prover-node-publisher.d.ts.map +1 -1
- package/dest/prover-node-publisher.js +38 -96
- package/dest/prover-node.d.ts +133 -66
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +529 -255
- package/dest/session-manager.d.ts +158 -0
- package/dest/session-manager.d.ts.map +1 -0
- package/dest/session-manager.js +486 -0
- package/dest/test/index.d.ts +7 -6
- package/dest/test/index.d.ts.map +1 -1
- package/package.json +24 -23
- package/src/actions/rerun-epoch-proving-job.ts +178 -30
- package/src/checkpoint-store.ts +212 -0
- package/src/config.ts +2 -1
- package/src/factory.ts +4 -8
- package/src/index.ts +1 -0
- package/src/job/checkpoint-prover.ts +496 -0
- package/src/job/epoch-session.ts +462 -0
- package/src/job/top-tree-job.ts +227 -0
- package/src/metrics.ts +65 -23
- package/src/proof-publishing-service.ts +427 -0
- package/src/prover-node-publisher.ts +52 -121
- package/src/prover-node.ts +617 -277
- package/src/session-manager.ts +589 -0
- package/src/test/index.ts +6 -6
- package/dest/job/epoch-proving-job.d.ts +0 -67
- package/dest/job/epoch-proving-job.d.ts.map +0 -1
- package/dest/job/epoch-proving-job.js +0 -912
- package/src/job/epoch-proving-job.ts +0 -531
|
@@ -2,21 +2,17 @@ import { BatchedBlob, getEthBlobEvaluationInputs } from '@aztec/blob-lib';
|
|
|
2
2
|
import { MAX_CHECKPOINTS_PER_EPOCH } from '@aztec/constants';
|
|
3
3
|
import type { RollupContract, ViemCommitteeAttestation } from '@aztec/ethereum/contracts';
|
|
4
4
|
import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
5
|
-
import { makeTuple } from '@aztec/foundation/array';
|
|
6
5
|
import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
7
6
|
import { areArraysEqual } from '@aztec/foundation/collection';
|
|
8
7
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
9
8
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
10
9
|
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
11
|
-
import { retryUntil } from '@aztec/foundation/retry';
|
|
12
|
-
import type { Tuple } from '@aztec/foundation/serialize';
|
|
13
10
|
import { Timer } from '@aztec/foundation/timer';
|
|
14
11
|
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
15
12
|
import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
|
|
16
13
|
import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
17
|
-
import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
18
14
|
import type { Proof } from '@aztec/stdlib/proofs';
|
|
19
|
-
import type {
|
|
15
|
+
import type { CheckpointHeader, RootRollupPublicInputs } from '@aztec/stdlib/rollup';
|
|
20
16
|
import type { L1PublishProofStats } from '@aztec/stdlib/stats';
|
|
21
17
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
22
18
|
|
|
@@ -33,12 +29,11 @@ export type L1SubmitEpochProofArgs = {
|
|
|
33
29
|
endTimestamp: Fr;
|
|
34
30
|
outHash: Fr;
|
|
35
31
|
proverId: Fr;
|
|
36
|
-
|
|
32
|
+
headers: CheckpointHeader[];
|
|
37
33
|
proof: Proof;
|
|
38
34
|
};
|
|
39
35
|
|
|
40
36
|
export class ProverNodePublisher {
|
|
41
|
-
private interrupted = false;
|
|
42
37
|
private metrics: ProverNodePublisherMetrics;
|
|
43
38
|
|
|
44
39
|
protected log: Logger;
|
|
@@ -73,23 +68,6 @@ export class ProverNodePublisher {
|
|
|
73
68
|
return this.rollupContract;
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
/**
|
|
77
|
-
* Calling `interrupt` will cause any in progress call to `publishRollup` to return `false` asap.
|
|
78
|
-
* Be warned, the call may return false even if the tx subsequently gets successfully mined.
|
|
79
|
-
* In practice this shouldn't matter, as we'll only ever be calling `interrupt` when we know it's going to fail.
|
|
80
|
-
* A call to `restart` is required before you can continue publishing.
|
|
81
|
-
*/
|
|
82
|
-
public interrupt() {
|
|
83
|
-
this.interrupted = true;
|
|
84
|
-
this.l1TxUtils.interrupt();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/** Restarts the publisher after calling `interrupt`. */
|
|
88
|
-
public restart() {
|
|
89
|
-
this.interrupted = false;
|
|
90
|
-
this.l1TxUtils.restart();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
71
|
public getSenderAddress() {
|
|
94
72
|
return this.l1TxUtils.getSenderAddress();
|
|
95
73
|
}
|
|
@@ -102,107 +80,54 @@ export class ProverNodePublisher {
|
|
|
102
80
|
proof: Proof;
|
|
103
81
|
batchedBlobInputs: BatchedBlob;
|
|
104
82
|
attestations: ViemCommitteeAttestation[];
|
|
83
|
+
headers: CheckpointHeader[];
|
|
84
|
+
/** Wall-clock deadline (proof-submission window end) past which the L1 tx should stop retrying. */
|
|
85
|
+
deadline?: Date;
|
|
105
86
|
}): Promise<boolean> {
|
|
106
87
|
const { epochNumber, fromCheckpoint, toCheckpoint } = args;
|
|
107
88
|
const ctx = { epochNumber, fromCheckpoint, toCheckpoint };
|
|
108
89
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const timer = new Timer();
|
|
116
|
-
// Validate epoch proof range and hashes are correct before submitting
|
|
117
|
-
await this.validateEpochProofSubmission(args);
|
|
118
|
-
|
|
119
|
-
const txReceipt = await this.sendSubmitEpochProofTx(args);
|
|
120
|
-
if (!txReceipt) {
|
|
121
|
-
this.log.error(`Failed to mine submitEpochProof tx`, undefined, ctx);
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
try {
|
|
126
|
-
this.metrics.recordSenderBalance(
|
|
127
|
-
await this.l1TxUtils.getSenderBalance(),
|
|
128
|
-
this.l1TxUtils.getSenderAddress().toString(),
|
|
129
|
-
);
|
|
130
|
-
} catch (err) {
|
|
131
|
-
this.log.warn(`Failed to record the ETH balance of the prover node: ${err}`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Tx was mined successfully
|
|
135
|
-
if (txReceipt.status === 'success') {
|
|
136
|
-
const tx = await this.l1TxUtils.getTransactionStats(txReceipt.transactionHash);
|
|
137
|
-
const stats: L1PublishProofStats = {
|
|
138
|
-
gasPrice: txReceipt.effectiveGasPrice,
|
|
139
|
-
gasUsed: txReceipt.gasUsed,
|
|
140
|
-
transactionHash: txReceipt.transactionHash,
|
|
141
|
-
calldataGas: tx!.calldataGas,
|
|
142
|
-
calldataSize: tx!.calldataSize,
|
|
143
|
-
sender: tx!.sender,
|
|
144
|
-
blobDataGas: 0n,
|
|
145
|
-
blobGasUsed: 0n,
|
|
146
|
-
eventName: 'proof-published-to-l1',
|
|
147
|
-
};
|
|
148
|
-
this.log.info(`Published epoch proof to L1 rollup contract`, { ...stats, ...ctx });
|
|
149
|
-
this.metrics.recordSubmitProof(timer.ms(), stats);
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
90
|
+
const timer = new Timer();
|
|
91
|
+
// Validate epoch proof range and hashes are correct before submitting
|
|
92
|
+
await this.validateEpochProofSubmission(args);
|
|
152
93
|
|
|
153
|
-
|
|
154
|
-
|
|
94
|
+
const txReceipt = await this.sendSubmitEpochProofTx(args);
|
|
95
|
+
if (!txReceipt) {
|
|
96
|
+
this.log.error(`Failed to mine submitEpochProof tx`, undefined, ctx);
|
|
97
|
+
return false;
|
|
155
98
|
}
|
|
156
99
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
100
|
+
try {
|
|
101
|
+
this.metrics.recordSenderBalance(
|
|
102
|
+
await this.l1TxUtils.getSenderBalance(),
|
|
103
|
+
this.l1TxUtils.getSenderAddress().toString(),
|
|
104
|
+
);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
this.log.warn(`Failed to record the ETH balance of the prover node: ${err}`);
|
|
107
|
+
}
|
|
160
108
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
109
|
+
// Tx was mined successfully
|
|
110
|
+
if (txReceipt.status === 'success') {
|
|
111
|
+
const tx = await this.l1TxUtils.getTransactionStats(txReceipt.transactionHash);
|
|
112
|
+
const stats: L1PublishProofStats = {
|
|
113
|
+
gasPrice: txReceipt.effectiveGasPrice,
|
|
114
|
+
gasUsed: txReceipt.gasUsed,
|
|
115
|
+
transactionHash: txReceipt.transactionHash,
|
|
116
|
+
calldataGas: tx!.calldataGas,
|
|
117
|
+
calldataSize: tx!.calldataSize,
|
|
118
|
+
sender: tx!.sender,
|
|
119
|
+
blobDataGas: 0n,
|
|
120
|
+
blobGasUsed: 0n,
|
|
121
|
+
eventName: 'proof-published-to-l1',
|
|
122
|
+
};
|
|
123
|
+
this.log.info(`Published epoch proof to L1 rollup contract`, { ...stats, ...ctx });
|
|
124
|
+
this.metrics.recordSubmitProof(timer.ms(), stats);
|
|
165
125
|
return true;
|
|
166
126
|
}
|
|
167
127
|
|
|
168
|
-
|
|
169
|
-
this.log.
|
|
170
|
-
|
|
171
|
-
fromCheckpoint,
|
|
172
|
-
provenCheckpoint,
|
|
173
|
-
timeout,
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
await retryUntil(
|
|
177
|
-
async () => {
|
|
178
|
-
if (this.interrupted) {
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const proven = await this.getProvenCheckpoint();
|
|
183
|
-
this.log.verbose(`Proven checkpoint is at ${proven} (waiting for ${fromCheckpoint - 1})`, { epochNumber });
|
|
184
|
-
return this.isStartBuildingOnProven(fromCheckpoint, proven) ? true : undefined;
|
|
185
|
-
},
|
|
186
|
-
`proven checkpoint to reach ${fromCheckpoint - 1}`,
|
|
187
|
-
timeout,
|
|
188
|
-
4,
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
return !this.interrupted;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
private async getProvenCheckpoint() {
|
|
195
|
-
return (await this.rollupContract.getTips()).proven;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
private isStartBuildingOnProven(fromCheckpoint: CheckpointNumber, provenCheckpoint: CheckpointNumber) {
|
|
199
|
-
return fromCheckpoint - 1 <= provenCheckpoint;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private async getSecondsUntilProofSubmissionWindowEnd(epochNumber: EpochNumber) {
|
|
203
|
-
const deadline = getProofSubmissionDeadlineTimestamp(epochNumber, await this.rollupContract.getRollupConstants());
|
|
204
|
-
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
205
|
-
return Math.max(Number(deadline - now), 0.001);
|
|
128
|
+
this.metrics.recordFailedTx();
|
|
129
|
+
this.log.error(`Rollup submitEpochProof tx reverted ${txReceipt.transactionHash}`, undefined, ctx);
|
|
130
|
+
return false;
|
|
206
131
|
}
|
|
207
132
|
|
|
208
133
|
private async validateEpochProofSubmission(args: {
|
|
@@ -212,6 +137,7 @@ export class ProverNodePublisher {
|
|
|
212
137
|
proof: Proof;
|
|
213
138
|
batchedBlobInputs: BatchedBlob;
|
|
214
139
|
attestations: ViemCommitteeAttestation[];
|
|
140
|
+
headers: CheckpointHeader[];
|
|
215
141
|
}) {
|
|
216
142
|
const { fromCheckpoint, toCheckpoint, publicInputs, batchedBlobInputs } = args;
|
|
217
143
|
|
|
@@ -285,6 +211,7 @@ export class ProverNodePublisher {
|
|
|
285
211
|
proof: Proof;
|
|
286
212
|
batchedBlobInputs: BatchedBlob;
|
|
287
213
|
attestations: ViemCommitteeAttestation[];
|
|
214
|
+
headers: CheckpointHeader[];
|
|
288
215
|
}): Promise<void> {
|
|
289
216
|
const { epochNumber, fromCheckpoint, toCheckpoint } = args;
|
|
290
217
|
|
|
@@ -332,6 +259,7 @@ export class ProverNodePublisher {
|
|
|
332
259
|
proof: Proof;
|
|
333
260
|
batchedBlobInputs: BatchedBlob;
|
|
334
261
|
attestations: ViemCommitteeAttestation[];
|
|
262
|
+
headers: CheckpointHeader[];
|
|
335
263
|
}): Hex {
|
|
336
264
|
return encodeFunctionData({
|
|
337
265
|
abi: RollupAbi,
|
|
@@ -343,10 +271,12 @@ export class ProverNodePublisher {
|
|
|
343
271
|
private async sendSubmitEpochProofTx(args: {
|
|
344
272
|
fromCheckpoint: CheckpointNumber;
|
|
345
273
|
toCheckpoint: CheckpointNumber;
|
|
274
|
+
deadline?: Date;
|
|
346
275
|
publicInputs: RootRollupPublicInputs;
|
|
347
276
|
proof: Proof;
|
|
348
277
|
batchedBlobInputs: BatchedBlob;
|
|
349
278
|
attestations: ViemCommitteeAttestation[];
|
|
279
|
+
headers: CheckpointHeader[];
|
|
350
280
|
}): Promise<TransactionReceipt | undefined> {
|
|
351
281
|
const txArgs = [this.getSubmitEpochProofArgs(args)] as const;
|
|
352
282
|
|
|
@@ -361,7 +291,10 @@ export class ProverNodePublisher {
|
|
|
361
291
|
args: txArgs,
|
|
362
292
|
});
|
|
363
293
|
try {
|
|
364
|
-
const { receipt } = await this.l1TxUtils.sendAndMonitorTransaction(
|
|
294
|
+
const { receipt } = await this.l1TxUtils.sendAndMonitorTransaction(
|
|
295
|
+
{ to: this.proofSubmissionTarget, data },
|
|
296
|
+
{ txTimeoutAt: args.deadline },
|
|
297
|
+
);
|
|
365
298
|
if (receipt.status !== 'success') {
|
|
366
299
|
const errorMsg = await this.l1TxUtils.tryGetErrorFromRevertedTx(
|
|
367
300
|
data,
|
|
@@ -390,6 +323,7 @@ export class ProverNodePublisher {
|
|
|
390
323
|
publicInputs: RootRollupPublicInputs;
|
|
391
324
|
batchedBlobInputs: BatchedBlob;
|
|
392
325
|
attestations: ViemCommitteeAttestation[];
|
|
326
|
+
headers: CheckpointHeader[];
|
|
393
327
|
}) {
|
|
394
328
|
// Returns arguments for EpochProofLib.sol -> getEpochProofPublicInputs()
|
|
395
329
|
return [
|
|
@@ -401,11 +335,7 @@ export class ProverNodePublisher {
|
|
|
401
335
|
outHash: args.publicInputs.outHash.toString(),
|
|
402
336
|
proverId: EthAddress.fromField(args.publicInputs.constants.proverId).toString(),
|
|
403
337
|
} /*_args*/,
|
|
404
|
-
|
|
405
|
-
i % 2 === 0
|
|
406
|
-
? args.publicInputs.fees[i / 2].recipient.toField().toString()
|
|
407
|
-
: args.publicInputs.fees[(i - 1) / 2].value.toString(),
|
|
408
|
-
) /*_fees*/,
|
|
338
|
+
args.headers.map(header => header.toViem()) /*_headers*/,
|
|
409
339
|
getEthBlobEvaluationInputs(args.batchedBlobInputs) /*_blobPublicInputs*/,
|
|
410
340
|
] as const;
|
|
411
341
|
}
|
|
@@ -417,6 +347,7 @@ export class ProverNodePublisher {
|
|
|
417
347
|
proof: Proof;
|
|
418
348
|
batchedBlobInputs: BatchedBlob;
|
|
419
349
|
attestations: ViemCommitteeAttestation[];
|
|
350
|
+
headers: CheckpointHeader[];
|
|
420
351
|
}) {
|
|
421
352
|
// Returns arguments for EpochProofLib.sol -> submitEpochRootProof()
|
|
422
353
|
const proofHex: Hex = `0x${args.proof.withoutPublicInputs().toString('hex')}`;
|
|
@@ -425,7 +356,7 @@ export class ProverNodePublisher {
|
|
|
425
356
|
start: argsArray[0],
|
|
426
357
|
end: argsArray[1],
|
|
427
358
|
args: argsArray[2],
|
|
428
|
-
|
|
359
|
+
headers: argsArray[3],
|
|
429
360
|
attestations: CommitteeAttestationsAndSigners.packAttestations(
|
|
430
361
|
args.attestations.map(a => CommitteeAttestation.fromViem(a)),
|
|
431
362
|
),
|