@aztec/prover-node 0.0.1-commit.fce3e4f → 0.0.1-commit.fffb133c

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 (46) 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 +3 -1
  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 +20 -15
  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 +3 -3
  18. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  19. package/dest/job/epoch-proving-job.js +478 -99
  20. package/dest/metrics.d.ts +4 -3
  21. package/dest/metrics.d.ts.map +1 -1
  22. package/dest/metrics.js +21 -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 +7 -6
  27. package/dest/prover-node-publisher.d.ts.map +1 -1
  28. package/dest/prover-node-publisher.js +41 -36
  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 +427 -45
  32. package/dest/prover-publisher-factory.d.ts +4 -2
  33. package/dest/prover-publisher-factory.d.ts.map +1 -1
  34. package/package.json +25 -25
  35. package/src/actions/rerun-epoch-proving-job.ts +3 -2
  36. package/src/bin/run-failed-epoch.ts +1 -1
  37. package/src/config.ts +6 -4
  38. package/src/factory.ts +28 -17
  39. package/src/index.ts +1 -0
  40. package/src/job/epoch-proving-job-data.ts +28 -23
  41. package/src/job/epoch-proving-job.ts +102 -97
  42. package/src/metrics.ts +27 -82
  43. package/src/monitors/epoch-monitor.ts +3 -10
  44. package/src/prover-node-publisher.ts +60 -50
  45. package/src/prover-node.ts +36 -32
  46. package/src/prover-publisher-factory.ts +3 -1
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,6 @@ import {
13
13
  type TelemetryClient,
14
14
  type Tracer,
15
15
  type UpDownCounter,
16
- ValueType,
17
16
  } from '@aztec/telemetry-client';
18
17
 
19
18
  import { formatEther, formatUnits } from 'viem';
@@ -21,6 +20,7 @@ import { formatEther, formatUnits } from 'viem';
21
20
  export class ProverNodeJobMetrics {
22
21
  proverEpochExecutionDuration: Histogram;
23
22
  provingJobDuration: Histogram;
23
+ provingJobCheckpoints: Gauge;
24
24
  provingJobBlocks: Gauge;
25
25
  provingJobTransactions: Gauge;
26
26
 
@@ -29,29 +29,23 @@ export class ProverNodeJobMetrics {
29
29
  public readonly tracer: Tracer,
30
30
  private logger = createLogger('prover-node:publisher:metrics'),
31
31
  ) {
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
- });
32
+ this.proverEpochExecutionDuration = this.meter.createHistogram(Metrics.PROVER_NODE_EXECUTION_DURATION);
33
+ this.provingJobDuration = this.meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION);
34
+ this.provingJobCheckpoints = this.meter.createGauge(Metrics.PROVER_NODE_JOB_CHECKPOINTS);
35
+ this.provingJobBlocks = this.meter.createGauge(Metrics.PROVER_NODE_JOB_BLOCKS);
36
+ this.provingJobTransactions = this.meter.createGauge(Metrics.PROVER_NODE_JOB_TRANSACTIONS);
50
37
  }
51
38
 
52
- public recordProvingJob(executionTimeMs: number, totalTimeMs: number, numBlocks: number, numTxs: number) {
39
+ public recordProvingJob(
40
+ executionTimeMs: number,
41
+ totalTimeMs: number,
42
+ numCheckpoints: number,
43
+ numBlocks: number,
44
+ numTxs: number,
45
+ ) {
53
46
  this.proverEpochExecutionDuration.record(Math.ceil(executionTimeMs));
54
47
  this.provingJobDuration.record(totalTimeMs / 1000);
48
+ this.provingJobCheckpoints.record(Math.floor(numCheckpoints));
55
49
  this.provingJobBlocks.record(Math.floor(numBlocks));
56
50
  this.provingJobTransactions.record(Math.floor(numTxs));
57
51
  }
@@ -69,15 +63,9 @@ export class ProverNodeRewardsMetrics {
69
63
  private rollup: RollupContract,
70
64
  private logger = createLogger('prover-node:publisher:metrics'),
71
65
  ) {
72
- this.rewards = this.meter.createObservableGauge(Metrics.PROVER_NODE_REWARDS_PER_EPOCH, {
73
- valueType: ValueType.DOUBLE,
74
- description: 'The rewards earned',
75
- });
66
+ this.rewards = this.meter.createObservableGauge(Metrics.PROVER_NODE_REWARDS_PER_EPOCH);
76
67
 
77
- this.accumulatedRewards = this.meter.createUpDownCounter(Metrics.PROVER_NODE_REWARDS_TOTAL, {
78
- valueType: ValueType.DOUBLE,
79
- description: 'The rewards earned (total)',
80
- });
68
+ this.accumulatedRewards = this.meter.createUpDownCounter(Metrics.PROVER_NODE_REWARDS_TOTAL);
81
69
  }
82
70
 
83
71
  public async start() {
@@ -138,68 +126,25 @@ export class ProverNodePublisherMetrics {
138
126
  ) {
139
127
  this.meter = client.getMeter(name);
140
128
 
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
- });
129
+ this.gasPrice = this.meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE);
146
130
 
147
- this.txCount = this.meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT, {
148
- description: 'The number of transactions processed',
149
- });
131
+ this.txCount = this.meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT);
150
132
 
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
- });
133
+ this.txDuration = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION);
156
134
 
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
- });
135
+ this.txGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS);
162
136
 
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
- });
137
+ this.txCalldataSize = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE);
168
138
 
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
- });
139
+ this.txCalldataGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS);
174
140
 
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
- });
141
+ this.txBlobDataGasUsed = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED);
180
142
 
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
- });
143
+ this.txBlobDataGasCost = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST);
186
144
 
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
- });
145
+ this.txTotalFee = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_TOTAL_FEE);
197
146
 
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
- });
147
+ this.senderBalance = this.meter.createGauge(Metrics.L1_PUBLISHER_BALANCE);
203
148
  }
204
149
 
205
150
  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 };
@@ -1,11 +1,12 @@
1
1
  import { BatchedBlob, getEthBlobEvaluationInputs } from '@aztec/blob-lib';
2
2
  import { AZTEC_MAX_EPOCH_DURATION } from '@aztec/constants';
3
- import type { L1TxUtils, RollupContract, ViemCommitteeAttestation } from '@aztec/ethereum';
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 { Fr } from '@aztec/foundation/fields';
9
10
  import { createLogger } from '@aztec/foundation/log';
10
11
  import type { Tuple } from '@aztec/foundation/serialize';
11
12
  import { Timer } from '@aztec/foundation/timer';
@@ -87,15 +88,15 @@ export class ProverNodePublisher {
87
88
 
88
89
  public async submitEpochProof(args: {
89
90
  epochNumber: EpochNumber;
90
- fromBlock: number;
91
- toBlock: number;
91
+ fromCheckpoint: CheckpointNumber;
92
+ toCheckpoint: CheckpointNumber;
92
93
  publicInputs: RootRollupPublicInputs;
93
94
  proof: Proof;
94
95
  batchedBlobInputs: BatchedBlob;
95
96
  attestations: ViemCommitteeAttestation[];
96
97
  }): Promise<boolean> {
97
- const { epochNumber, fromBlock, toBlock } = args;
98
- const ctx = { epochNumber, fromBlock, toBlock };
98
+ const { epochNumber, fromCheckpoint, toCheckpoint } = args;
99
+ const ctx = { epochNumber, fromCheckpoint, toCheckpoint };
99
100
 
100
101
  if (!this.interrupted) {
101
102
  const timer = new Timer();
@@ -104,6 +105,7 @@ export class ProverNodePublisher {
104
105
 
105
106
  const txReceipt = await this.sendSubmitEpochProofTx(args);
106
107
  if (!txReceipt) {
108
+ this.log.error(`Failed to mine submitEpochProof tx`, undefined, ctx);
107
109
  return false;
108
110
  }
109
111
 
@@ -136,47 +138,51 @@ export class ProverNodePublisher {
136
138
  }
137
139
 
138
140
  this.metrics.recordFailedTx();
139
- this.log.error(`Rollup.submitEpochProof tx status failed ${txReceipt.transactionHash}`, undefined, ctx);
141
+ this.log.error(`Rollup submitEpochProof tx reverted ${txReceipt.transactionHash}`, undefined, ctx);
140
142
  }
141
143
 
142
- this.log.verbose('L2 block data syncing interrupted', ctx);
144
+ this.log.verbose('Checkpoint data syncing interrupted', ctx);
143
145
  return false;
144
146
  }
145
147
 
146
148
  private async validateEpochProofSubmission(args: {
147
- fromBlock: number;
148
- toBlock: number;
149
+ fromCheckpoint: CheckpointNumber;
150
+ toCheckpoint: CheckpointNumber;
149
151
  publicInputs: RootRollupPublicInputs;
150
152
  proof: Proof;
151
153
  batchedBlobInputs: BatchedBlob;
152
154
  attestations: ViemCommitteeAttestation[];
153
155
  }) {
154
- const { fromBlock, toBlock, publicInputs, batchedBlobInputs } = args;
156
+ const { fromCheckpoint, toCheckpoint, publicInputs, batchedBlobInputs } = args;
155
157
 
156
- // Check that the block numbers match the expected epoch to be proven
158
+ // Check that the checkpoint numbers match the expected epoch to be proven
157
159
  const { pending, proven } = await this.rollupContract.getTips();
158
- // Don't publish if proven is beyond our toBlock, pointless to do so
159
- if (proven > BigInt(toBlock)) {
160
- throw new Error(`Cannot submit epoch proof for ${fromBlock}-${toBlock} as proven block is ${proven}`);
160
+ // Don't publish if proven is beyond our toCheckpoint, pointless to do so
161
+ if (proven > toCheckpoint) {
162
+ throw new Error(
163
+ `Cannot submit epoch proof for ${fromCheckpoint}-${toCheckpoint} as proven checkpoint is ${proven}`,
164
+ );
161
165
  }
162
- // toBlock can't be greater than pending
163
- if (toBlock > pending) {
164
- throw new Error(`Cannot submit epoch proof for ${fromBlock}-${toBlock} as pending block is ${pending}`);
166
+ // toCheckpoint can't be greater than pending
167
+ if (toCheckpoint > pending) {
168
+ throw new Error(
169
+ `Cannot submit epoch proof for ${fromCheckpoint}-${toCheckpoint} as pending checkpoint is ${pending}`,
170
+ );
165
171
  }
166
172
 
167
- // Check the archive for the immediate block before the epoch
168
- const blockLog = await this.rollupContract.getCheckpoint(BigInt(fromBlock - 1));
169
- if (publicInputs.previousArchiveRoot.toString() !== blockLog.archive) {
173
+ // Check the archive for the immediate checkpoint before the epoch
174
+ const checkpointLog = await this.rollupContract.getCheckpoint(CheckpointNumber(fromCheckpoint - 1));
175
+ if (!publicInputs.previousArchiveRoot.equals(checkpointLog.archive)) {
170
176
  throw new Error(
171
- `Previous archive root mismatch: ${publicInputs.previousArchiveRoot.toString()} !== ${blockLog.archive}`,
177
+ `Previous archive root mismatch: ${publicInputs.previousArchiveRoot.toString()} !== ${checkpointLog.archive.toString()}`,
172
178
  );
173
179
  }
174
180
 
175
- // Check the archive for the last block in the epoch
176
- const endBlockLog = await this.rollupContract.getCheckpoint(BigInt(toBlock));
177
- if (publicInputs.endArchiveRoot.toString() !== endBlockLog.archive) {
181
+ // Check the archive for the last checkpoint in the epoch
182
+ const endCheckpointLog = await this.rollupContract.getCheckpoint(toCheckpoint);
183
+ if (!publicInputs.endArchiveRoot.equals(endCheckpointLog.archive)) {
178
184
  throw new Error(
179
- `End archive root mismatch: ${publicInputs.endArchiveRoot.toString()} !== ${endBlockLog.archive}`,
185
+ `End archive root mismatch: ${publicInputs.endArchiveRoot.toString()} !== ${endCheckpointLog.archive.toString()}`,
180
186
  );
181
187
  }
182
188
 
@@ -194,7 +200,7 @@ export class ProverNodePublisher {
194
200
  );
195
201
  const argsPublicInputs = [...publicInputs.toFields()];
196
202
 
197
- if (!areArraysEqual(rollupPublicInputs.map(Fr.fromHexString), argsPublicInputs, (a, b) => a.equals(b))) {
203
+ if (!areArraysEqual(rollupPublicInputs, argsPublicInputs, (a, b) => a.equals(b))) {
198
204
  const fmt = (inputs: Fr[] | readonly string[]) => inputs.map(x => x.toString()).join(', ');
199
205
  throw new Error(
200
206
  `Root rollup public inputs mismatch:\nRollup: ${fmt(rollupPublicInputs)}\nComputed:${fmt(argsPublicInputs)}`,
@@ -203,8 +209,8 @@ export class ProverNodePublisher {
203
209
  }
204
210
 
205
211
  private async sendSubmitEpochProofTx(args: {
206
- fromBlock: number;
207
- toBlock: number;
212
+ fromCheckpoint: CheckpointNumber;
213
+ toCheckpoint: CheckpointNumber;
208
214
  publicInputs: RootRollupPublicInputs;
209
215
  proof: Proof;
210
216
  batchedBlobInputs: BatchedBlob;
@@ -214,8 +220,8 @@ export class ProverNodePublisher {
214
220
 
215
221
  this.log.info(`Submitting epoch proof to L1 rollup contract`, {
216
222
  proofSize: args.proof.withoutPublicInputs().length,
217
- fromBlock: args.fromBlock,
218
- toBlock: args.toBlock,
223
+ fromCheckpoint: args.fromCheckpoint,
224
+ toCheckpoint: args.toCheckpoint,
219
225
  });
220
226
  const data = encodeFunctionData({
221
227
  abi: RollupAbi,
@@ -224,39 +230,43 @@ export class ProverNodePublisher {
224
230
  });
225
231
  try {
226
232
  const { receipt } = await this.l1TxUtils.sendAndMonitorTransaction({ to: this.rollupContract.address, data });
233
+ if (receipt.status !== 'success') {
234
+ const errorMsg = await this.l1TxUtils.tryGetErrorFromRevertedTx(
235
+ data,
236
+ {
237
+ args: [...txArgs],
238
+ functionName: 'submitEpochRootProof',
239
+ abi: RollupAbi,
240
+ address: this.rollupContract.address,
241
+ },
242
+ /*blobInputs*/ undefined,
243
+ /*stateOverride*/ [],
244
+ );
245
+ this.log.error(`Rollup submit epoch proof tx reverted with ${errorMsg ?? 'unknown error'}`);
246
+ return undefined;
247
+ }
227
248
  return receipt;
228
249
  } catch (err) {
229
250
  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
251
  return undefined;
243
252
  }
244
253
  }
245
254
 
246
255
  private getEpochProofPublicInputsArgs(args: {
247
- fromBlock: number;
248
- toBlock: number;
256
+ fromCheckpoint: CheckpointNumber;
257
+ toCheckpoint: CheckpointNumber;
249
258
  publicInputs: RootRollupPublicInputs;
250
259
  batchedBlobInputs: BatchedBlob;
251
260
  attestations: ViemCommitteeAttestation[];
252
261
  }) {
253
262
  // Returns arguments for EpochProofLib.sol -> getEpochProofPublicInputs()
254
263
  return [
255
- BigInt(args.fromBlock) /*_start*/,
256
- BigInt(args.toBlock) /*_end*/,
264
+ BigInt(args.fromCheckpoint) /*_start*/,
265
+ BigInt(args.toCheckpoint) /*_end*/,
257
266
  {
258
267
  previousArchive: args.publicInputs.previousArchiveRoot.toString(),
259
268
  endArchive: args.publicInputs.endArchiveRoot.toString(),
269
+ outHash: args.publicInputs.outHash.toString(),
260
270
  proverId: EthAddress.fromField(args.publicInputs.constants.proverId).toString(),
261
271
  } /*_args*/,
262
272
  makeTuple(AZTEC_MAX_EPOCH_DURATION * 2, i =>
@@ -269,8 +279,8 @@ export class ProverNodePublisher {
269
279
  }
270
280
 
271
281
  private getSubmitEpochProofArgs(args: {
272
- fromBlock: number;
273
- toBlock: number;
282
+ fromCheckpoint: CheckpointNumber;
283
+ toCheckpoint: CheckpointNumber;
274
284
  publicInputs: RootRollupPublicInputs;
275
285
  proof: Proof;
276
286
  batchedBlobInputs: BatchedBlob;
@@ -1,15 +1,16 @@
1
1
  import type { Archiver } from '@aztec/archiver';
2
- import type { RollupContract } from '@aztec/ethereum';
3
- import { EpochNumber } from '@aztec/foundation/branded-types';
2
+ import type { RollupContract } from '@aztec/ethereum/contracts';
3
+ import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
4
4
  import { assertRequired, compact, pick, sum } from '@aztec/foundation/collection';
5
+ import type { Fr } from '@aztec/foundation/curves/bn254';
5
6
  import { memoize } from '@aztec/foundation/decorators';
6
- import type { Fr } from '@aztec/foundation/fields';
7
7
  import { createLogger } from '@aztec/foundation/log';
8
8
  import { DateProvider } from '@aztec/foundation/timer';
9
9
  import type { DataStoreConfig } from '@aztec/kv-store/config';
10
10
  import type { P2PClient } from '@aztec/p2p';
11
11
  import { PublicProcessorFactory } from '@aztec/simulator/server';
12
- import type { L2Block, L2BlockSource } from '@aztec/stdlib/block';
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';
@@ -271,10 +272,13 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
271
272
 
272
273
  // Gather all data for this epoch
273
274
  const epochData = await this.gatherEpochData(epochNumber);
274
-
275
- const fromBlock = epochData.blocks[0].number;
276
- const toBlock = epochData.blocks.at(-1)!.number;
277
- this.log.verbose(`Creating proving job for epoch ${epochNumber} for block range ${fromBlock} to ${toBlock}`);
275
+ const fromCheckpoint = epochData.checkpoints[0].number;
276
+ const toCheckpoint = epochData.checkpoints.at(-1)!.number;
277
+ const fromBlock = epochData.checkpoints[0].blocks[0].number;
278
+ const toBlock = epochData.checkpoints.at(-1)!.blocks.at(-1)!.number;
279
+ this.log.verbose(
280
+ `Creating proving job for epoch ${epochNumber} for checkpoint range ${fromCheckpoint} to ${toCheckpoint} and block range ${fromBlock} to ${toBlock}`,
281
+ );
278
282
 
279
283
  // Fast forward world state to right before the target block and get a fork
280
284
  await this.worldState.syncImmediate(toBlock);
@@ -289,7 +293,6 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
289
293
  // Set deadline for this job to run. It will abort if it takes too long.
290
294
  const deadlineTs = getProofSubmissionDeadlineTimestamp(epochNumber, await this.getL1Constants());
291
295
  const deadline = new Date(Number(deadlineTs) * 1000);
292
-
293
296
  const job = this.doCreateEpochProvingJob(epochData, deadline, publicProcessorFactory, this.publisher, opts);
294
297
  this.jobs.set(job.getId(), job);
295
298
  return job;
@@ -302,28 +305,30 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
302
305
 
303
306
  @trackSpan('ProverNode.gatherEpochData', epochNumber => ({ [Attributes.EPOCH_NUMBER]: epochNumber }))
304
307
  private async gatherEpochData(epochNumber: EpochNumber): Promise<EpochProvingJobData> {
305
- const blocks = await this.gatherBlocks(epochNumber);
306
- const txArray = await this.gatherTxs(epochNumber, blocks);
308
+ const checkpoints = await this.gatherCheckpoints(epochNumber);
309
+ const txArray = await this.gatherTxs(epochNumber, checkpoints);
307
310
  const txs = new Map<string, Tx>(txArray.map(tx => [tx.getTxHash().toString(), tx]));
308
- const l1ToL2Messages = await this.gatherMessages(epochNumber, blocks);
309
- const previousBlockHeader = await this.gatherPreviousBlockHeader(epochNumber, blocks[0]);
310
- const [lastBlock] = await this.l2BlockSource.getPublishedBlocks(blocks.at(-1)!.number, 1);
311
- const attestations = lastBlock?.attestations ?? [];
311
+ const l1ToL2Messages = await this.gatherMessages(epochNumber, checkpoints);
312
+ const [firstBlock] = checkpoints[0].blocks;
313
+ const previousBlockHeader = await this.gatherPreviousBlockHeader(epochNumber, firstBlock.number - 1);
314
+ const [lastPublishedCheckpoint] = await this.l2BlockSource.getCheckpoints(checkpoints.at(-1)!.number, 1);
315
+ const attestations = lastPublishedCheckpoint?.attestations ?? [];
312
316
 
313
- return { blocks, txs, l1ToL2Messages, epochNumber, previousBlockHeader, attestations };
317
+ return { checkpoints, txs, l1ToL2Messages, epochNumber, previousBlockHeader, attestations };
314
318
  }
315
319
 
316
- private async gatherBlocks(epochNumber: EpochNumber) {
317
- const blocks = await this.l2BlockSource.getBlocksForEpoch(epochNumber);
318
- if (blocks.length === 0) {
320
+ private async gatherCheckpoints(epochNumber: EpochNumber) {
321
+ const checkpoints = await this.l2BlockSource.getCheckpointsForEpoch(epochNumber);
322
+ if (checkpoints.length === 0) {
319
323
  throw new EmptyEpochError(epochNumber);
320
324
  }
321
- return blocks;
325
+ return checkpoints;
322
326
  }
323
327
 
324
- private async gatherTxs(epochNumber: EpochNumber, blocks: L2Block[]) {
328
+ private async gatherTxs(epochNumber: EpochNumber, checkpoints: Checkpoint[]) {
325
329
  const deadline = new Date(this.dateProvider.now() + this.config.txGatheringTimeoutMs);
326
330
  const txProvider = this.p2pClient.getTxProvider();
331
+ const blocks = checkpoints.flatMap(checkpoint => checkpoint.blocks);
327
332
  const txsByBlock = await Promise.all(blocks.map(block => txProvider.getTxsForBlock(block, { deadline })));
328
333
  const txs = txsByBlock.map(({ txs }) => txs).flat();
329
334
  const missingTxs = txsByBlock.map(({ missingTxs }) => missingTxs).flat();
@@ -336,25 +341,24 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
336
341
  throw new Error(`Txs not found for epoch ${epochNumber}: ${missingTxs.map(hash => hash.toString()).join(', ')}`);
337
342
  }
338
343
 
339
- private async gatherMessages(epochNumber: EpochNumber, blocks: L2Block[]) {
340
- const messages = await Promise.all(blocks.map(b => this.l1ToL2MessageSource.getL1ToL2Messages(b.number)));
344
+ private async gatherMessages(epochNumber: EpochNumber, checkpoints: Checkpoint[]) {
345
+ const messages = await Promise.all(checkpoints.map(c => this.l1ToL2MessageSource.getL1ToL2Messages(c.number)));
341
346
  const messageCount = sum(messages.map(m => m.length));
342
347
  this.log.verbose(`Gathered all ${messageCount} messages for epoch ${epochNumber}`, { epochNumber });
343
- const messagesByBlock: Record<number, Fr[]> = {};
344
- for (let i = 0; i < blocks.length; i++) {
345
- messagesByBlock[blocks[i].number] = messages[i];
348
+ const messagesByCheckpoint: Record<CheckpointNumber, Fr[]> = {};
349
+ for (let i = 0; i < checkpoints.length; i++) {
350
+ messagesByCheckpoint[checkpoints[i].number] = messages[i];
346
351
  }
347
- return messagesByBlock;
352
+ return messagesByCheckpoint;
348
353
  }
349
354
 
350
- private async gatherPreviousBlockHeader(epochNumber: EpochNumber, initialBlock: L2Block) {
351
- const previousBlockNumber = initialBlock.number - 1;
355
+ private async gatherPreviousBlockHeader(epochNumber: EpochNumber, previousBlockNumber: number) {
352
356
  const header = await (previousBlockNumber === 0
353
357
  ? this.worldState.getCommitted().getInitialHeader()
354
- : this.l2BlockSource.getBlockHeader(previousBlockNumber));
358
+ : this.l2BlockSource.getBlockHeader(BlockNumber(previousBlockNumber)));
355
359
 
356
360
  if (!header) {
357
- throw new Error(`Previous block header ${initialBlock.number} not found for proving epoch ${epochNumber}`);
361
+ throw new Error(`Previous block header ${previousBlockNumber} not found for proving epoch ${epochNumber}`);
358
362
  }
359
363
 
360
364
  this.log.verbose(`Gathered previous block header ${header.getBlockNumber()} for epoch ${epochNumber}`);
@@ -391,7 +395,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
391
395
  private validateConfig() {
392
396
  if (
393
397
  this.config.proverNodeFailedEpochStore &&
394
- (!this.config.dataDirectory || !this.config.l1ChainId || !this.config.rollupVersion)
398
+ (!this.config.dataDirectory || !this.config.l1ChainId || this.config.rollupVersion === undefined)
395
399
  ) {
396
400
  this.log.warn(
397
401
  `Invalid prover-node config (missing dataDirectory, l1ChainId, or rollupVersion)`,
@@ -1,4 +1,6 @@
1
- import type { L1TxUtils, PublisherManager, RollupContract } from '@aztec/ethereum';
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';
2
4
  import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
3
5
  import type { TelemetryClient } from '@aztec/telemetry-client';
4
6