@aztec/prover-node 0.0.1-commit.fce3e4f → 0.0.1-commit.ff7989d6c
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/bin/run-failed-epoch.js +5 -2
- package/dest/config.d.ts +7 -9
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +17 -19
- package/dest/factory.d.ts +20 -15
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +28 -61
- 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 +501 -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 +21 -11
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +438 -53
- package/dest/prover-publisher-factory.d.ts +9 -5
- 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 +5 -2
- package/src/config.ts +25 -31
- package/src/factory.ts +65 -101
- package/src/index.ts +1 -0
- package/src/job/epoch-proving-job-data.ts +28 -23
- package/src/job/epoch-proving-job.ts +135 -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 +49 -39
- package/src/prover-publisher-factory.ts +16 -8
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { BatchedBlob, getEthBlobEvaluationInputs } from '@aztec/blob-lib';
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
2
|
+
import { MAX_CHECKPOINTS_PER_EPOCH } from '@aztec/constants';
|
|
3
|
+
import type { RollupContract, ViemCommitteeAttestation } from '@aztec/ethereum/contracts';
|
|
4
|
+
import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
4
5
|
import { makeTuple } from '@aztec/foundation/array';
|
|
5
|
-
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
6
|
+
import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
6
7
|
import { areArraysEqual } from '@aztec/foundation/collection';
|
|
8
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
7
9
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
8
|
-
import {
|
|
9
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
10
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
10
11
|
import type { Tuple } from '@aztec/foundation/serialize';
|
|
11
12
|
import { Timer } from '@aztec/foundation/timer';
|
|
12
13
|
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
@@ -30,7 +31,7 @@ export type L1SubmitEpochProofArgs = {
|
|
|
30
31
|
endTimestamp: Fr;
|
|
31
32
|
outHash: Fr;
|
|
32
33
|
proverId: Fr;
|
|
33
|
-
fees: Tuple<FeeRecipient, typeof
|
|
34
|
+
fees: Tuple<FeeRecipient, typeof MAX_CHECKPOINTS_PER_EPOCH>;
|
|
34
35
|
proof: Proof;
|
|
35
36
|
};
|
|
36
37
|
|
|
@@ -38,7 +39,7 @@ export class ProverNodePublisher {
|
|
|
38
39
|
private interrupted = false;
|
|
39
40
|
private metrics: ProverNodePublisherMetrics;
|
|
40
41
|
|
|
41
|
-
protected log
|
|
42
|
+
protected log: Logger;
|
|
42
43
|
|
|
43
44
|
protected rollupContract: RollupContract;
|
|
44
45
|
|
|
@@ -51,10 +52,12 @@ export class ProverNodePublisher {
|
|
|
51
52
|
l1TxUtils: L1TxUtils;
|
|
52
53
|
telemetry?: TelemetryClient;
|
|
53
54
|
},
|
|
55
|
+
bindings?: LoggerBindings,
|
|
54
56
|
) {
|
|
55
57
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
56
58
|
|
|
57
59
|
this.metrics = new ProverNodePublisherMetrics(telemetry, 'ProverNode');
|
|
60
|
+
this.log = createLogger('prover-node:l1-tx-publisher', bindings);
|
|
58
61
|
|
|
59
62
|
this.rollupContract = deps.rollupContract;
|
|
60
63
|
this.l1TxUtils = deps.l1TxUtils;
|
|
@@ -87,15 +90,15 @@ export class ProverNodePublisher {
|
|
|
87
90
|
|
|
88
91
|
public async submitEpochProof(args: {
|
|
89
92
|
epochNumber: EpochNumber;
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
fromCheckpoint: CheckpointNumber;
|
|
94
|
+
toCheckpoint: CheckpointNumber;
|
|
92
95
|
publicInputs: RootRollupPublicInputs;
|
|
93
96
|
proof: Proof;
|
|
94
97
|
batchedBlobInputs: BatchedBlob;
|
|
95
98
|
attestations: ViemCommitteeAttestation[];
|
|
96
99
|
}): Promise<boolean> {
|
|
97
|
-
const { epochNumber,
|
|
98
|
-
const ctx = { epochNumber,
|
|
100
|
+
const { epochNumber, fromCheckpoint, toCheckpoint } = args;
|
|
101
|
+
const ctx = { epochNumber, fromCheckpoint, toCheckpoint };
|
|
99
102
|
|
|
100
103
|
if (!this.interrupted) {
|
|
101
104
|
const timer = new Timer();
|
|
@@ -104,6 +107,7 @@ export class ProverNodePublisher {
|
|
|
104
107
|
|
|
105
108
|
const txReceipt = await this.sendSubmitEpochProofTx(args);
|
|
106
109
|
if (!txReceipt) {
|
|
110
|
+
this.log.error(`Failed to mine submitEpochProof tx`, undefined, ctx);
|
|
107
111
|
return false;
|
|
108
112
|
}
|
|
109
113
|
|
|
@@ -136,47 +140,51 @@ export class ProverNodePublisher {
|
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
this.metrics.recordFailedTx();
|
|
139
|
-
this.log.error(`Rollup
|
|
143
|
+
this.log.error(`Rollup submitEpochProof tx reverted ${txReceipt.transactionHash}`, undefined, ctx);
|
|
140
144
|
}
|
|
141
145
|
|
|
142
|
-
this.log.verbose('
|
|
146
|
+
this.log.verbose('Checkpoint data syncing interrupted', ctx);
|
|
143
147
|
return false;
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
private async validateEpochProofSubmission(args: {
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
fromCheckpoint: CheckpointNumber;
|
|
152
|
+
toCheckpoint: CheckpointNumber;
|
|
149
153
|
publicInputs: RootRollupPublicInputs;
|
|
150
154
|
proof: Proof;
|
|
151
155
|
batchedBlobInputs: BatchedBlob;
|
|
152
156
|
attestations: ViemCommitteeAttestation[];
|
|
153
157
|
}) {
|
|
154
|
-
const {
|
|
158
|
+
const { fromCheckpoint, toCheckpoint, publicInputs, batchedBlobInputs } = args;
|
|
155
159
|
|
|
156
|
-
// Check that the
|
|
160
|
+
// Check that the checkpoint numbers match the expected epoch to be proven
|
|
157
161
|
const { pending, proven } = await this.rollupContract.getTips();
|
|
158
|
-
// Don't publish if proven is beyond our
|
|
159
|
-
if (proven >
|
|
160
|
-
throw new Error(
|
|
162
|
+
// Don't publish if proven is beyond our toCheckpoint, pointless to do so
|
|
163
|
+
if (proven > toCheckpoint) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
`Cannot submit epoch proof for ${fromCheckpoint}-${toCheckpoint} as proven checkpoint is ${proven}`,
|
|
166
|
+
);
|
|
161
167
|
}
|
|
162
|
-
//
|
|
163
|
-
if (
|
|
164
|
-
throw new Error(
|
|
168
|
+
// toCheckpoint can't be greater than pending
|
|
169
|
+
if (toCheckpoint > pending) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`Cannot submit epoch proof for ${fromCheckpoint}-${toCheckpoint} as pending checkpoint is ${pending}`,
|
|
172
|
+
);
|
|
165
173
|
}
|
|
166
174
|
|
|
167
|
-
// Check the archive for the immediate
|
|
168
|
-
const
|
|
169
|
-
if (publicInputs.previousArchiveRoot.
|
|
175
|
+
// Check the archive for the immediate checkpoint before the epoch
|
|
176
|
+
const checkpointLog = await this.rollupContract.getCheckpoint(CheckpointNumber(fromCheckpoint - 1));
|
|
177
|
+
if (!publicInputs.previousArchiveRoot.equals(checkpointLog.archive)) {
|
|
170
178
|
throw new Error(
|
|
171
|
-
`Previous archive root mismatch: ${publicInputs.previousArchiveRoot.toString()} !== ${
|
|
179
|
+
`Previous archive root mismatch: ${publicInputs.previousArchiveRoot.toString()} !== ${checkpointLog.archive.toString()}`,
|
|
172
180
|
);
|
|
173
181
|
}
|
|
174
182
|
|
|
175
|
-
// Check the archive for the last
|
|
176
|
-
const
|
|
177
|
-
if (publicInputs.endArchiveRoot.
|
|
183
|
+
// Check the archive for the last checkpoint in the epoch
|
|
184
|
+
const endCheckpointLog = await this.rollupContract.getCheckpoint(toCheckpoint);
|
|
185
|
+
if (!publicInputs.endArchiveRoot.equals(endCheckpointLog.archive)) {
|
|
178
186
|
throw new Error(
|
|
179
|
-
`End archive root mismatch: ${publicInputs.endArchiveRoot.toString()} !== ${
|
|
187
|
+
`End archive root mismatch: ${publicInputs.endArchiveRoot.toString()} !== ${endCheckpointLog.archive.toString()}`,
|
|
180
188
|
);
|
|
181
189
|
}
|
|
182
190
|
|
|
@@ -194,7 +202,7 @@ export class ProverNodePublisher {
|
|
|
194
202
|
);
|
|
195
203
|
const argsPublicInputs = [...publicInputs.toFields()];
|
|
196
204
|
|
|
197
|
-
if (!areArraysEqual(rollupPublicInputs
|
|
205
|
+
if (!areArraysEqual(rollupPublicInputs, argsPublicInputs, (a, b) => a.equals(b))) {
|
|
198
206
|
const fmt = (inputs: Fr[] | readonly string[]) => inputs.map(x => x.toString()).join(', ');
|
|
199
207
|
throw new Error(
|
|
200
208
|
`Root rollup public inputs mismatch:\nRollup: ${fmt(rollupPublicInputs)}\nComputed:${fmt(argsPublicInputs)}`,
|
|
@@ -203,8 +211,8 @@ export class ProverNodePublisher {
|
|
|
203
211
|
}
|
|
204
212
|
|
|
205
213
|
private async sendSubmitEpochProofTx(args: {
|
|
206
|
-
|
|
207
|
-
|
|
214
|
+
fromCheckpoint: CheckpointNumber;
|
|
215
|
+
toCheckpoint: CheckpointNumber;
|
|
208
216
|
publicInputs: RootRollupPublicInputs;
|
|
209
217
|
proof: Proof;
|
|
210
218
|
batchedBlobInputs: BatchedBlob;
|
|
@@ -214,8 +222,8 @@ export class ProverNodePublisher {
|
|
|
214
222
|
|
|
215
223
|
this.log.info(`Submitting epoch proof to L1 rollup contract`, {
|
|
216
224
|
proofSize: args.proof.withoutPublicInputs().length,
|
|
217
|
-
|
|
218
|
-
|
|
225
|
+
fromCheckpoint: args.fromCheckpoint,
|
|
226
|
+
toCheckpoint: args.toCheckpoint,
|
|
219
227
|
});
|
|
220
228
|
const data = encodeFunctionData({
|
|
221
229
|
abi: RollupAbi,
|
|
@@ -224,42 +232,46 @@ export class ProverNodePublisher {
|
|
|
224
232
|
});
|
|
225
233
|
try {
|
|
226
234
|
const { receipt } = await this.l1TxUtils.sendAndMonitorTransaction({ to: this.rollupContract.address, data });
|
|
235
|
+
if (receipt.status !== 'success') {
|
|
236
|
+
const errorMsg = await this.l1TxUtils.tryGetErrorFromRevertedTx(
|
|
237
|
+
data,
|
|
238
|
+
{
|
|
239
|
+
args: [...txArgs],
|
|
240
|
+
functionName: 'submitEpochRootProof',
|
|
241
|
+
abi: RollupAbi,
|
|
242
|
+
address: this.rollupContract.address,
|
|
243
|
+
},
|
|
244
|
+
/*blobInputs*/ undefined,
|
|
245
|
+
/*stateOverride*/ [],
|
|
246
|
+
);
|
|
247
|
+
this.log.error(`Rollup submit epoch proof tx reverted with ${errorMsg ?? 'unknown error'}`);
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
227
250
|
return receipt;
|
|
228
251
|
} catch (err) {
|
|
229
252
|
this.log.error(`Rollup submit epoch proof failed`, err);
|
|
230
|
-
const errorMsg = await this.l1TxUtils.tryGetErrorFromRevertedTx(
|
|
231
|
-
data,
|
|
232
|
-
{
|
|
233
|
-
args: [...txArgs],
|
|
234
|
-
functionName: 'submitEpochRootProof',
|
|
235
|
-
abi: RollupAbi,
|
|
236
|
-
address: this.rollupContract.address,
|
|
237
|
-
},
|
|
238
|
-
/*blobInputs*/ undefined,
|
|
239
|
-
/*stateOverride*/ [],
|
|
240
|
-
);
|
|
241
|
-
this.log.error(`Rollup submit epoch proof tx reverted. ${errorMsg}`);
|
|
242
253
|
return undefined;
|
|
243
254
|
}
|
|
244
255
|
}
|
|
245
256
|
|
|
246
257
|
private getEpochProofPublicInputsArgs(args: {
|
|
247
|
-
|
|
248
|
-
|
|
258
|
+
fromCheckpoint: CheckpointNumber;
|
|
259
|
+
toCheckpoint: CheckpointNumber;
|
|
249
260
|
publicInputs: RootRollupPublicInputs;
|
|
250
261
|
batchedBlobInputs: BatchedBlob;
|
|
251
262
|
attestations: ViemCommitteeAttestation[];
|
|
252
263
|
}) {
|
|
253
264
|
// Returns arguments for EpochProofLib.sol -> getEpochProofPublicInputs()
|
|
254
265
|
return [
|
|
255
|
-
BigInt(args.
|
|
256
|
-
BigInt(args.
|
|
266
|
+
BigInt(args.fromCheckpoint) /*_start*/,
|
|
267
|
+
BigInt(args.toCheckpoint) /*_end*/,
|
|
257
268
|
{
|
|
258
269
|
previousArchive: args.publicInputs.previousArchiveRoot.toString(),
|
|
259
270
|
endArchive: args.publicInputs.endArchiveRoot.toString(),
|
|
271
|
+
outHash: args.publicInputs.outHash.toString(),
|
|
260
272
|
proverId: EthAddress.fromField(args.publicInputs.constants.proverId).toString(),
|
|
261
273
|
} /*_args*/,
|
|
262
|
-
makeTuple(
|
|
274
|
+
makeTuple(MAX_CHECKPOINTS_PER_EPOCH * 2, i =>
|
|
263
275
|
i % 2 === 0
|
|
264
276
|
? args.publicInputs.fees[i / 2].recipient.toField().toString()
|
|
265
277
|
: args.publicInputs.fees[(i - 1) / 2].value.toString(),
|
|
@@ -269,8 +281,8 @@ export class ProverNodePublisher {
|
|
|
269
281
|
}
|
|
270
282
|
|
|
271
283
|
private getSubmitEpochProofArgs(args: {
|
|
272
|
-
|
|
273
|
-
|
|
284
|
+
fromCheckpoint: CheckpointNumber;
|
|
285
|
+
toCheckpoint: CheckpointNumber;
|
|
274
286
|
publicInputs: RootRollupPublicInputs;
|
|
275
287
|
proof: Proof;
|
|
276
288
|
batchedBlobInputs: BatchedBlob;
|
package/src/prover-node.ts
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import type { Archiver } from '@aztec/archiver';
|
|
2
|
-
import type { RollupContract } from '@aztec/ethereum';
|
|
3
|
-
import {
|
|
2
|
+
import type { RollupContract } from '@aztec/ethereum/contracts';
|
|
3
|
+
import type { Delayer } from '@aztec/ethereum/l1-tx-utils';
|
|
4
|
+
import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
4
5
|
import { assertRequired, compact, pick, sum } from '@aztec/foundation/collection';
|
|
6
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
7
|
import { memoize } from '@aztec/foundation/decorators';
|
|
6
|
-
import type { Fr } from '@aztec/foundation/fields';
|
|
7
8
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
9
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
9
10
|
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
10
|
-
import type { P2PClient } from '@aztec/p2p';
|
|
11
11
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
12
|
-
import type {
|
|
12
|
+
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
13
|
+
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
13
14
|
import type { ChainConfig } from '@aztec/stdlib/config';
|
|
14
15
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
15
16
|
import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
16
17
|
import {
|
|
17
18
|
type EpochProverManager,
|
|
18
19
|
EpochProvingJobTerminalState,
|
|
20
|
+
type ITxProvider,
|
|
19
21
|
type ProverNodeApi,
|
|
20
22
|
type Service,
|
|
21
23
|
type WorldStateSyncStatus,
|
|
@@ -23,7 +25,6 @@ import {
|
|
|
23
25
|
tryStop,
|
|
24
26
|
} from '@aztec/stdlib/interfaces/server';
|
|
25
27
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
26
|
-
import type { P2PClientType } from '@aztec/stdlib/p2p';
|
|
27
28
|
import type { Tx } from '@aztec/stdlib/tx';
|
|
28
29
|
import {
|
|
29
30
|
Attributes,
|
|
@@ -54,7 +55,6 @@ type DataStoreOptions = Pick<DataStoreConfig, 'dataDirectory'> & Pick<ChainConfi
|
|
|
54
55
|
*/
|
|
55
56
|
export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable {
|
|
56
57
|
private log = createLogger('prover-node');
|
|
57
|
-
private dateProvider = new DateProvider();
|
|
58
58
|
|
|
59
59
|
private jobs: Map<string, EpochProvingJob> = new Map();
|
|
60
60
|
private config: ProverNodeOptions;
|
|
@@ -72,12 +72,14 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
72
72
|
protected readonly l1ToL2MessageSource: L1ToL2MessageSource,
|
|
73
73
|
protected readonly contractDataSource: ContractDataSource,
|
|
74
74
|
protected readonly worldState: WorldStateSynchronizer,
|
|
75
|
-
protected readonly p2pClient:
|
|
75
|
+
protected readonly p2pClient: { getTxProvider(): ITxProvider } & Partial<Service>,
|
|
76
76
|
protected readonly epochsMonitor: EpochMonitor,
|
|
77
77
|
protected readonly rollupContract: RollupContract,
|
|
78
78
|
protected readonly l1Metrics: L1Metrics,
|
|
79
79
|
config: Partial<ProverNodeOptions> = {},
|
|
80
80
|
protected readonly telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
81
|
+
private delayer?: Delayer,
|
|
82
|
+
private readonly dateProvider: DateProvider = new DateProvider(),
|
|
81
83
|
) {
|
|
82
84
|
this.config = {
|
|
83
85
|
proverNodePollingIntervalMs: 1_000,
|
|
@@ -110,6 +112,11 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
110
112
|
return this.p2pClient;
|
|
111
113
|
}
|
|
112
114
|
|
|
115
|
+
/** Returns the shared tx delayer for prover L1 txs, if enabled. Test-only. */
|
|
116
|
+
public getDelayer(): Delayer | undefined {
|
|
117
|
+
return this.delayer;
|
|
118
|
+
}
|
|
119
|
+
|
|
113
120
|
/**
|
|
114
121
|
* Handles an epoch being completed by starting a proof for it if there are no active jobs for it.
|
|
115
122
|
* @param epochNumber - The epoch number that was just completed.
|
|
@@ -154,17 +161,15 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
154
161
|
|
|
155
162
|
/**
|
|
156
163
|
* Stops the prover node and all its dependencies.
|
|
164
|
+
* Resources not owned by this node (shared with the parent aztec-node) are skipped.
|
|
157
165
|
*/
|
|
158
166
|
async stop() {
|
|
159
167
|
this.log.info('Stopping ProverNode');
|
|
160
168
|
await this.epochsMonitor.stop();
|
|
161
169
|
await this.prover.stop();
|
|
162
|
-
await tryStop(this.p2pClient);
|
|
163
|
-
await tryStop(this.l2BlockSource);
|
|
164
170
|
await tryStop(this.publisherFactory);
|
|
165
171
|
this.publisher?.interrupt();
|
|
166
172
|
await Promise.all(Array.from(this.jobs.values()).map(job => job.stop()));
|
|
167
|
-
await this.worldState.stop();
|
|
168
173
|
this.rewardsMetrics.stop();
|
|
169
174
|
this.l1Metrics.stop();
|
|
170
175
|
await this.telemetryClient.stop();
|
|
@@ -271,10 +276,13 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
271
276
|
|
|
272
277
|
// Gather all data for this epoch
|
|
273
278
|
const epochData = await this.gatherEpochData(epochNumber);
|
|
274
|
-
|
|
275
|
-
const
|
|
276
|
-
const
|
|
277
|
-
|
|
279
|
+
const fromCheckpoint = epochData.checkpoints[0].number;
|
|
280
|
+
const toCheckpoint = epochData.checkpoints.at(-1)!.number;
|
|
281
|
+
const fromBlock = epochData.checkpoints[0].blocks[0].number;
|
|
282
|
+
const toBlock = epochData.checkpoints.at(-1)!.blocks.at(-1)!.number;
|
|
283
|
+
this.log.verbose(
|
|
284
|
+
`Creating proving job for epoch ${epochNumber} for checkpoint range ${fromCheckpoint} to ${toCheckpoint} and block range ${fromBlock} to ${toBlock}`,
|
|
285
|
+
);
|
|
278
286
|
|
|
279
287
|
// Fast forward world state to right before the target block and get a fork
|
|
280
288
|
await this.worldState.syncImmediate(toBlock);
|
|
@@ -284,12 +292,12 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
284
292
|
this.contractDataSource,
|
|
285
293
|
this.dateProvider,
|
|
286
294
|
this.telemetryClient,
|
|
295
|
+
this.log.getBindings(),
|
|
287
296
|
);
|
|
288
297
|
|
|
289
298
|
// Set deadline for this job to run. It will abort if it takes too long.
|
|
290
299
|
const deadlineTs = getProofSubmissionDeadlineTimestamp(epochNumber, await this.getL1Constants());
|
|
291
300
|
const deadline = new Date(Number(deadlineTs) * 1000);
|
|
292
|
-
|
|
293
301
|
const job = this.doCreateEpochProvingJob(epochData, deadline, publicProcessorFactory, this.publisher, opts);
|
|
294
302
|
this.jobs.set(job.getId(), job);
|
|
295
303
|
return job;
|
|
@@ -302,28 +310,30 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
302
310
|
|
|
303
311
|
@trackSpan('ProverNode.gatherEpochData', epochNumber => ({ [Attributes.EPOCH_NUMBER]: epochNumber }))
|
|
304
312
|
private async gatherEpochData(epochNumber: EpochNumber): Promise<EpochProvingJobData> {
|
|
305
|
-
const
|
|
306
|
-
const txArray = await this.gatherTxs(epochNumber,
|
|
313
|
+
const checkpoints = await this.gatherCheckpoints(epochNumber);
|
|
314
|
+
const txArray = await this.gatherTxs(epochNumber, checkpoints);
|
|
307
315
|
const txs = new Map<string, Tx>(txArray.map(tx => [tx.getTxHash().toString(), tx]));
|
|
308
|
-
const l1ToL2Messages = await this.gatherMessages(epochNumber,
|
|
309
|
-
const
|
|
310
|
-
const
|
|
311
|
-
const
|
|
316
|
+
const l1ToL2Messages = await this.gatherMessages(epochNumber, checkpoints);
|
|
317
|
+
const [firstBlock] = checkpoints[0].blocks;
|
|
318
|
+
const previousBlockHeader = await this.gatherPreviousBlockHeader(epochNumber, firstBlock.number - 1);
|
|
319
|
+
const [lastPublishedCheckpoint] = await this.l2BlockSource.getCheckpoints(checkpoints.at(-1)!.number, 1);
|
|
320
|
+
const attestations = lastPublishedCheckpoint?.attestations ?? [];
|
|
312
321
|
|
|
313
|
-
return {
|
|
322
|
+
return { checkpoints, txs, l1ToL2Messages, epochNumber, previousBlockHeader, attestations };
|
|
314
323
|
}
|
|
315
324
|
|
|
316
|
-
private async
|
|
317
|
-
const
|
|
318
|
-
if (
|
|
325
|
+
private async gatherCheckpoints(epochNumber: EpochNumber) {
|
|
326
|
+
const checkpoints = await this.l2BlockSource.getCheckpointsForEpoch(epochNumber);
|
|
327
|
+
if (checkpoints.length === 0) {
|
|
319
328
|
throw new EmptyEpochError(epochNumber);
|
|
320
329
|
}
|
|
321
|
-
return
|
|
330
|
+
return checkpoints;
|
|
322
331
|
}
|
|
323
332
|
|
|
324
|
-
private async gatherTxs(epochNumber: EpochNumber,
|
|
333
|
+
private async gatherTxs(epochNumber: EpochNumber, checkpoints: Checkpoint[]) {
|
|
325
334
|
const deadline = new Date(this.dateProvider.now() + this.config.txGatheringTimeoutMs);
|
|
326
335
|
const txProvider = this.p2pClient.getTxProvider();
|
|
336
|
+
const blocks = checkpoints.flatMap(checkpoint => checkpoint.blocks);
|
|
327
337
|
const txsByBlock = await Promise.all(blocks.map(block => txProvider.getTxsForBlock(block, { deadline })));
|
|
328
338
|
const txs = txsByBlock.map(({ txs }) => txs).flat();
|
|
329
339
|
const missingTxs = txsByBlock.map(({ missingTxs }) => missingTxs).flat();
|
|
@@ -336,25 +346,24 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
336
346
|
throw new Error(`Txs not found for epoch ${epochNumber}: ${missingTxs.map(hash => hash.toString()).join(', ')}`);
|
|
337
347
|
}
|
|
338
348
|
|
|
339
|
-
private async gatherMessages(epochNumber: EpochNumber,
|
|
340
|
-
const messages = await Promise.all(
|
|
349
|
+
private async gatherMessages(epochNumber: EpochNumber, checkpoints: Checkpoint[]) {
|
|
350
|
+
const messages = await Promise.all(checkpoints.map(c => this.l1ToL2MessageSource.getL1ToL2Messages(c.number)));
|
|
341
351
|
const messageCount = sum(messages.map(m => m.length));
|
|
342
352
|
this.log.verbose(`Gathered all ${messageCount} messages for epoch ${epochNumber}`, { epochNumber });
|
|
343
|
-
const
|
|
344
|
-
for (let i = 0; i <
|
|
345
|
-
|
|
353
|
+
const messagesByCheckpoint: Record<CheckpointNumber, Fr[]> = {};
|
|
354
|
+
for (let i = 0; i < checkpoints.length; i++) {
|
|
355
|
+
messagesByCheckpoint[checkpoints[i].number] = messages[i];
|
|
346
356
|
}
|
|
347
|
-
return
|
|
357
|
+
return messagesByCheckpoint;
|
|
348
358
|
}
|
|
349
359
|
|
|
350
|
-
private async gatherPreviousBlockHeader(epochNumber: EpochNumber,
|
|
351
|
-
const previousBlockNumber = initialBlock.number - 1;
|
|
360
|
+
private async gatherPreviousBlockHeader(epochNumber: EpochNumber, previousBlockNumber: number) {
|
|
352
361
|
const header = await (previousBlockNumber === 0
|
|
353
362
|
? this.worldState.getCommitted().getInitialHeader()
|
|
354
|
-
: this.l2BlockSource.getBlockHeader(previousBlockNumber));
|
|
363
|
+
: this.l2BlockSource.getBlockHeader(BlockNumber(previousBlockNumber)));
|
|
355
364
|
|
|
356
365
|
if (!header) {
|
|
357
|
-
throw new Error(`Previous block header ${
|
|
366
|
+
throw new Error(`Previous block header ${previousBlockNumber} not found for proving epoch ${epochNumber}`);
|
|
358
367
|
}
|
|
359
368
|
|
|
360
369
|
this.log.verbose(`Gathered previous block header ${header.getBlockNumber()} for epoch ${epochNumber}`);
|
|
@@ -380,6 +389,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
380
389
|
this.jobMetrics,
|
|
381
390
|
deadline,
|
|
382
391
|
{ parallelBlockLimit, skipSubmitProof: proverNodeDisableProofPublish, ...opts },
|
|
392
|
+
this.log.getBindings(),
|
|
383
393
|
);
|
|
384
394
|
}
|
|
385
395
|
|
|
@@ -391,7 +401,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
|
|
|
391
401
|
private validateConfig() {
|
|
392
402
|
if (
|
|
393
403
|
this.config.proverNodeFailedEpochStore &&
|
|
394
|
-
(!this.config.dataDirectory || !this.config.l1ChainId ||
|
|
404
|
+
(!this.config.dataDirectory || !this.config.l1ChainId || this.config.rollupVersion === undefined)
|
|
395
405
|
) {
|
|
396
406
|
this.log.warn(
|
|
397
407
|
`Invalid prover-node config (missing dataDirectory, l1ChainId, or rollupVersion)`,
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { RollupContract } from '@aztec/ethereum/contracts';
|
|
2
|
+
import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
3
|
+
import type { PublisherManager } from '@aztec/ethereum/publisher-manager';
|
|
4
|
+
import type { LoggerBindings } from '@aztec/foundation/log';
|
|
5
|
+
import type { ProverPublisherConfig, ProverTxSenderConfig } from '@aztec/sequencer-client';
|
|
3
6
|
import type { TelemetryClient } from '@aztec/telemetry-client';
|
|
4
7
|
|
|
5
8
|
import { ProverNodePublisher } from './prover-node-publisher.js';
|
|
6
9
|
|
|
7
10
|
export class ProverPublisherFactory {
|
|
8
11
|
constructor(
|
|
9
|
-
private config:
|
|
12
|
+
private config: ProverTxSenderConfig & ProverPublisherConfig,
|
|
10
13
|
private deps: {
|
|
11
14
|
rollupContract: RollupContract;
|
|
12
15
|
publisherManager: PublisherManager<L1TxUtils>;
|
|
13
16
|
telemetry?: TelemetryClient;
|
|
14
17
|
},
|
|
18
|
+
private bindings?: LoggerBindings,
|
|
15
19
|
) {}
|
|
16
20
|
|
|
17
21
|
public async start() {
|
|
@@ -28,10 +32,14 @@ export class ProverPublisherFactory {
|
|
|
28
32
|
*/
|
|
29
33
|
public async create(): Promise<ProverNodePublisher> {
|
|
30
34
|
const l1Publisher = await this.deps.publisherManager.getAvailablePublisher();
|
|
31
|
-
return new ProverNodePublisher(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
return new ProverNodePublisher(
|
|
36
|
+
this.config,
|
|
37
|
+
{
|
|
38
|
+
rollupContract: this.deps.rollupContract,
|
|
39
|
+
l1TxUtils: l1Publisher,
|
|
40
|
+
telemetry: this.deps.telemetry,
|
|
41
|
+
},
|
|
42
|
+
this.bindings,
|
|
43
|
+
);
|
|
36
44
|
}
|
|
37
45
|
}
|