@aztec/prover-node 0.0.0-test.1 → 0.0.1-commit.03f7ef2

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 (82) hide show
  1. package/dest/actions/download-epoch-proving-job.d.ts +18 -0
  2. package/dest/actions/download-epoch-proving-job.d.ts.map +1 -0
  3. package/dest/actions/download-epoch-proving-job.js +37 -0
  4. package/dest/actions/index.d.ts +3 -0
  5. package/dest/actions/index.d.ts.map +1 -0
  6. package/dest/actions/index.js +2 -0
  7. package/dest/actions/rerun-epoch-proving-job.d.ts +11 -0
  8. package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -0
  9. package/dest/actions/rerun-epoch-proving-job.js +40 -0
  10. package/dest/actions/upload-epoch-proof-failure.d.ts +15 -0
  11. package/dest/actions/upload-epoch-proof-failure.d.ts.map +1 -0
  12. package/dest/actions/upload-epoch-proof-failure.js +78 -0
  13. package/dest/bin/run-failed-epoch.d.ts +2 -0
  14. package/dest/bin/run-failed-epoch.d.ts.map +1 -0
  15. package/dest/bin/run-failed-epoch.js +67 -0
  16. package/dest/config.d.ts +15 -11
  17. package/dest/config.d.ts.map +1 -1
  18. package/dest/config.js +83 -15
  19. package/dest/factory.d.ts +16 -12
  20. package/dest/factory.d.ts.map +1 -1
  21. package/dest/factory.js +100 -32
  22. package/dest/index.d.ts +2 -2
  23. package/dest/index.d.ts.map +1 -1
  24. package/dest/index.js +1 -1
  25. package/dest/job/epoch-proving-job-data.d.ts +18 -0
  26. package/dest/job/epoch-proving-job-data.d.ts.map +1 -0
  27. package/dest/job/epoch-proving-job-data.js +59 -0
  28. package/dest/job/epoch-proving-job.d.ts +26 -18
  29. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  30. package/dest/job/epoch-proving-job.js +193 -84
  31. package/dest/metrics.d.ts +30 -5
  32. package/dest/metrics.d.ts.map +1 -1
  33. package/dest/metrics.js +147 -35
  34. package/dest/monitors/epoch-monitor.d.ts +5 -2
  35. package/dest/monitors/epoch-monitor.d.ts.map +1 -1
  36. package/dest/monitors/epoch-monitor.js +17 -3
  37. package/dest/monitors/index.d.ts +1 -1
  38. package/dest/prover-node-publisher.d.ts +14 -15
  39. package/dest/prover-node-publisher.d.ts.map +1 -1
  40. package/dest/prover-node-publisher.js +86 -81
  41. package/dest/prover-node.d.ts +49 -44
  42. package/dest/prover-node.d.ts.map +1 -1
  43. package/dest/prover-node.js +186 -112
  44. package/dest/prover-publisher-factory.d.ts +23 -0
  45. package/dest/prover-publisher-factory.d.ts.map +1 -0
  46. package/dest/prover-publisher-factory.js +26 -0
  47. package/dest/test/index.d.ts +5 -3
  48. package/dest/test/index.d.ts.map +1 -1
  49. package/dest/test/index.js +1 -3
  50. package/package.json +39 -33
  51. package/src/actions/download-epoch-proving-job.ts +44 -0
  52. package/src/actions/index.ts +2 -0
  53. package/src/actions/rerun-epoch-proving-job.ts +61 -0
  54. package/src/actions/upload-epoch-proof-failure.ts +88 -0
  55. package/src/bin/run-failed-epoch.ts +77 -0
  56. package/src/config.ts +111 -25
  57. package/src/factory.ts +167 -44
  58. package/src/index.ts +1 -1
  59. package/src/job/epoch-proving-job-data.ts +82 -0
  60. package/src/job/epoch-proving-job.ts +255 -83
  61. package/src/metrics.ts +147 -37
  62. package/src/monitors/epoch-monitor.ts +19 -7
  63. package/src/prover-node-publisher.ts +132 -115
  64. package/src/prover-node.ts +223 -142
  65. package/src/prover-publisher-factory.ts +39 -0
  66. package/src/test/index.ts +7 -4
  67. package/dest/http.d.ts +0 -8
  68. package/dest/http.d.ts.map +0 -1
  69. package/dest/http.js +0 -9
  70. package/dest/prover-coordination/config.d.ts +0 -7
  71. package/dest/prover-coordination/config.d.ts.map +0 -1
  72. package/dest/prover-coordination/config.js +0 -11
  73. package/dest/prover-coordination/factory.d.ts +0 -22
  74. package/dest/prover-coordination/factory.d.ts.map +0 -1
  75. package/dest/prover-coordination/factory.js +0 -42
  76. package/dest/prover-coordination/index.d.ts +0 -3
  77. package/dest/prover-coordination/index.d.ts.map +0 -1
  78. package/dest/prover-coordination/index.js +0 -2
  79. package/src/http.ts +0 -13
  80. package/src/prover-coordination/config.ts +0 -17
  81. package/src/prover-coordination/factory.ts +0 -72
  82. package/src/prover-coordination/index.ts +0 -2
@@ -1,34 +1,33 @@
1
- import { AGGREGATION_OBJECT_LENGTH, AZTEC_MAX_EPOCH_DURATION } from '@aztec/constants';
2
- import type { L1TxUtils, RollupContract } from '@aztec/ethereum';
1
+ import { BatchedBlob, getEthBlobEvaluationInputs } from '@aztec/blob-lib';
2
+ import { AZTEC_MAX_EPOCH_DURATION } from '@aztec/constants';
3
+ import type { RollupContract, ViemCommitteeAttestation } from '@aztec/ethereum/contracts';
4
+ import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
3
5
  import { makeTuple } from '@aztec/foundation/array';
4
- import { areArraysEqual, times } from '@aztec/foundation/collection';
6
+ import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
7
+ import { areArraysEqual } from '@aztec/foundation/collection';
8
+ import { Fr } from '@aztec/foundation/curves/bn254';
5
9
  import { EthAddress } from '@aztec/foundation/eth-address';
6
- import { Fr } from '@aztec/foundation/fields';
7
10
  import { createLogger } from '@aztec/foundation/log';
8
- import { type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
9
- import { InterruptibleSleep } from '@aztec/foundation/sleep';
11
+ import type { Tuple } from '@aztec/foundation/serialize';
10
12
  import { Timer } from '@aztec/foundation/timer';
11
13
  import { RollupAbi } from '@aztec/l1-artifacts';
12
14
  import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
15
+ import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
13
16
  import type { Proof } from '@aztec/stdlib/proofs';
14
17
  import type { FeeRecipient, RootRollupPublicInputs } from '@aztec/stdlib/rollup';
15
18
  import type { L1PublishProofStats } from '@aztec/stdlib/stats';
16
19
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
17
20
 
21
+ import { inspect } from 'util';
18
22
  import { type Hex, type TransactionReceipt, encodeFunctionData } from 'viem';
19
23
 
20
- import { ProverNodeMetrics } from './metrics.js';
24
+ import { ProverNodePublisherMetrics } from './metrics.js';
21
25
 
22
- /**
23
- * Stats for a sent transaction.
24
- */
25
26
  /** Arguments to the submitEpochProof method of the rollup contract */
26
27
  export type L1SubmitEpochProofArgs = {
27
28
  epochSize: number;
28
29
  previousArchive: Fr;
29
30
  endArchive: Fr;
30
- previousBlockHash: Fr;
31
- endBlockHash: Fr;
32
31
  endTimestamp: Fr;
33
32
  outHash: Fr;
34
33
  proverId: Fr;
@@ -37,10 +36,8 @@ export type L1SubmitEpochProofArgs = {
37
36
  };
38
37
 
39
38
  export class ProverNodePublisher {
40
- private interruptibleSleep = new InterruptibleSleep();
41
- private sleepTimeMs: number;
42
39
  private interrupted = false;
43
- private metrics: ProverNodeMetrics;
40
+ private metrics: ProverNodePublisherMetrics;
44
41
 
45
42
  protected log = createLogger('prover-node:l1-tx-publisher');
46
43
 
@@ -56,16 +53,18 @@ export class ProverNodePublisher {
56
53
  telemetry?: TelemetryClient;
57
54
  },
58
55
  ) {
59
- this.sleepTimeMs = config?.l1PublishRetryIntervalMS ?? 60_000;
60
-
61
56
  const telemetry = deps.telemetry ?? getTelemetryClient();
62
57
 
63
- this.metrics = new ProverNodeMetrics(telemetry, 'ProverNode');
58
+ this.metrics = new ProverNodePublisherMetrics(telemetry, 'ProverNode');
64
59
 
65
60
  this.rollupContract = deps.rollupContract;
66
61
  this.l1TxUtils = deps.l1TxUtils;
67
62
  }
68
63
 
64
+ public getRollupContract() {
65
+ return this.rollupContract;
66
+ }
67
+
69
68
  /**
70
69
  * Calling `interrupt` will cause any in progress call to `publishRollup` to return `false` asap.
71
70
  * Be warned, the call may return false even if the tx subsequently gets successfully mined.
@@ -74,46 +73,53 @@ export class ProverNodePublisher {
74
73
  */
75
74
  public interrupt() {
76
75
  this.interrupted = true;
77
- this.interruptibleSleep.interrupt();
76
+ this.l1TxUtils.interrupt();
78
77
  }
79
78
 
80
79
  /** Restarts the publisher after calling `interrupt`. */
81
80
  public restart() {
82
81
  this.interrupted = false;
82
+ this.l1TxUtils.restart();
83
83
  }
84
84
 
85
85
  public getSenderAddress() {
86
- return EthAddress.fromString(this.l1TxUtils.getSenderAddress());
86
+ return this.l1TxUtils.getSenderAddress();
87
87
  }
88
88
 
89
89
  public async submitEpochProof(args: {
90
- epochNumber: number;
91
- fromBlock: number;
92
- toBlock: number;
90
+ epochNumber: EpochNumber;
91
+ fromCheckpoint: CheckpointNumber;
92
+ toCheckpoint: CheckpointNumber;
93
93
  publicInputs: RootRollupPublicInputs;
94
94
  proof: Proof;
95
+ batchedBlobInputs: BatchedBlob;
96
+ attestations: ViemCommitteeAttestation[];
95
97
  }): Promise<boolean> {
96
- const { epochNumber, fromBlock, toBlock } = args;
97
- const ctx = { epochNumber, fromBlock, toBlock };
98
+ const { epochNumber, fromCheckpoint, toCheckpoint } = args;
99
+ const ctx = { epochNumber, fromCheckpoint, toCheckpoint };
100
+
98
101
  if (!this.interrupted) {
99
102
  const timer = new Timer();
100
-
101
103
  // Validate epoch proof range and hashes are correct before submitting
102
104
  await this.validateEpochProofSubmission(args);
103
105
 
104
106
  const txReceipt = await this.sendSubmitEpochProofTx(args);
105
107
  if (!txReceipt) {
108
+ this.log.error(`Failed to mine submitEpochProof tx`, undefined, ctx);
106
109
  return false;
107
110
  }
108
111
 
109
112
  try {
110
- this.metrics.recordSenderBalance(await this.l1TxUtils.getSenderBalance(), this.l1TxUtils.getSenderAddress());
113
+ this.metrics.recordSenderBalance(
114
+ await this.l1TxUtils.getSenderBalance(),
115
+ this.l1TxUtils.getSenderAddress().toString(),
116
+ );
111
117
  } catch (err) {
112
118
  this.log.warn(`Failed to record the ETH balance of the prover node: ${err}`);
113
119
  }
114
120
 
115
121
  // Tx was mined successfully
116
- if (txReceipt.status) {
122
+ if (txReceipt.status === 'success') {
117
123
  const tx = await this.l1TxUtils.getTransactionStats(txReceipt.transactionHash);
118
124
  const stats: L1PublishProofStats = {
119
125
  gasPrice: txReceipt.effectiveGasPrice,
@@ -132,62 +138,67 @@ export class ProverNodePublisher {
132
138
  }
133
139
 
134
140
  this.metrics.recordFailedTx();
135
- this.log.error(`Rollup.submitEpochProof tx status failed: ${txReceipt.transactionHash}`, ctx);
136
- await this.sleepOrInterrupted();
141
+ this.log.error(`Rollup submitEpochProof tx reverted ${txReceipt.transactionHash}`, undefined, ctx);
137
142
  }
138
143
 
139
- this.log.verbose('L2 block data syncing interrupted while processing blocks.', ctx);
144
+ this.log.verbose('Checkpoint data syncing interrupted', ctx);
140
145
  return false;
141
146
  }
142
147
 
143
148
  private async validateEpochProofSubmission(args: {
144
- fromBlock: number;
145
- toBlock: number;
149
+ fromCheckpoint: CheckpointNumber;
150
+ toCheckpoint: CheckpointNumber;
146
151
  publicInputs: RootRollupPublicInputs;
147
152
  proof: Proof;
153
+ batchedBlobInputs: BatchedBlob;
154
+ attestations: ViemCommitteeAttestation[];
148
155
  }) {
149
- const { fromBlock, toBlock, publicInputs, proof } = args;
156
+ const { fromCheckpoint, toCheckpoint, publicInputs, batchedBlobInputs } = args;
150
157
 
151
- // Check that the block numbers match the expected epoch to be proven
152
- const { pendingBlockNumber: pending, provenBlockNumber: proven } = await this.rollupContract.getTips();
153
- if (proven !== BigInt(fromBlock) - 1n) {
154
- throw new Error(`Cannot submit epoch proof for ${fromBlock}-${toBlock} as proven block is ${proven}`);
158
+ // Check that the checkpoint numbers match the expected epoch to be proven
159
+ const { pending, proven } = await this.rollupContract.getTips();
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
+ );
155
165
  }
156
- if (toBlock > pending) {
157
- 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
+ );
158
171
  }
159
172
 
160
- // Check the block hash and archive for the immediate block before the epoch
161
- const blockLog = await this.rollupContract.getBlock(proven);
162
- if (publicInputs.previousArchive.root.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.toString() !== checkpointLog.archive) {
163
176
  throw new Error(
164
- `Previous archive root mismatch: ${publicInputs.previousArchive.root.toString()} !== ${blockLog.archive}`,
177
+ `Previous archive root mismatch: ${publicInputs.previousArchiveRoot.toString()} !== ${checkpointLog.archive}`,
165
178
  );
166
179
  }
167
- // TODO: Remove zero check once we inject the proper zero blockhash
168
- if (blockLog.blockHash !== Fr.ZERO.toString() && publicInputs.previousBlockHash.toString() !== blockLog.blockHash) {
180
+
181
+ // Check the archive for the last checkpoint in the epoch
182
+ const endCheckpointLog = await this.rollupContract.getCheckpoint(toCheckpoint);
183
+ if (publicInputs.endArchiveRoot.toString() !== endCheckpointLog.archive) {
169
184
  throw new Error(
170
- `Previous block hash mismatch: ${publicInputs.previousBlockHash.toString()} !== ${blockLog.blockHash}`,
185
+ `End archive root mismatch: ${publicInputs.endArchiveRoot.toString()} !== ${endCheckpointLog.archive}`,
171
186
  );
172
187
  }
173
188
 
174
- // Check the block hash and archive for the last block in the epoch
175
- const endBlockLog = await this.rollupContract.getBlock(BigInt(toBlock));
176
- if (publicInputs.endArchive.root.toString() !== endBlockLog.archive) {
189
+ // Check the batched blob inputs from the root rollup against the batched blob computed in ts
190
+ const finalBlobAccumulator = batchedBlobInputs.toFinalBlobAccumulator();
191
+ if (!publicInputs.blobPublicInputs.equals(finalBlobAccumulator)) {
177
192
  throw new Error(
178
- `End archive root mismatch: ${publicInputs.endArchive.root.toString()} !== ${endBlockLog.archive}`,
193
+ `Batched blob mismatch: ${inspect(publicInputs.blobPublicInputs)} !== ${inspect(finalBlobAccumulator)}`,
179
194
  );
180
195
  }
181
- if (publicInputs.endBlockHash.toString() !== endBlockLog.blockHash) {
182
- throw new Error(`End block hash mismatch: ${publicInputs.endBlockHash.toString()} !== ${endBlockLog.blockHash}`);
183
- }
184
196
 
185
197
  // Compare the public inputs computed by the contract with the ones injected
186
- const rollupPublicInputs = await this.rollupContract.getEpochProofPublicInputs(this.getSubmitEpochProofArgs(args));
187
- const aggregationObject = proof.isEmpty()
188
- ? times(AGGREGATION_OBJECT_LENGTH, Fr.zero)
189
- : proof.extractAggregationObject();
190
- const argsPublicInputs = [...publicInputs.toFields(), ...aggregationObject];
198
+ const rollupPublicInputs = await this.rollupContract.getEpochProofPublicInputs(
199
+ this.getEpochProofPublicInputsArgs(args),
200
+ );
201
+ const argsPublicInputs = [...publicInputs.toFields()];
191
202
 
192
203
  if (!areArraysEqual(rollupPublicInputs.map(Fr.fromHexString), argsPublicInputs, (a, b) => a.equals(b))) {
193
204
  const fmt = (inputs: Fr[] | readonly string[]) => inputs.map(x => x.toString()).join(', ');
@@ -198,89 +209,95 @@ export class ProverNodePublisher {
198
209
  }
199
210
 
200
211
  private async sendSubmitEpochProofTx(args: {
201
- fromBlock: number;
202
- toBlock: number;
212
+ fromCheckpoint: CheckpointNumber;
213
+ toCheckpoint: CheckpointNumber;
203
214
  publicInputs: RootRollupPublicInputs;
204
215
  proof: Proof;
216
+ batchedBlobInputs: BatchedBlob;
217
+ attestations: ViemCommitteeAttestation[];
205
218
  }): Promise<TransactionReceipt | undefined> {
206
- const proofHex: Hex = `0x${args.proof.withoutPublicInputs().toString('hex')}`;
207
- const argsArray = this.getSubmitEpochProofArgs(args);
208
-
209
- const txArgs = [
210
- {
211
- start: argsArray[0],
212
- end: argsArray[1],
213
- args: argsArray[2],
214
- fees: argsArray[3],
215
- blobPublicInputs: argsArray[4],
216
- aggregationObject: argsArray[5],
217
- proof: proofHex,
218
- },
219
- ] as const;
219
+ const txArgs = [this.getSubmitEpochProofArgs(args)] as const;
220
220
 
221
- this.log.info(`SubmitEpochProof proofSize=${args.proof.withoutPublicInputs().length} bytes`);
221
+ this.log.info(`Submitting epoch proof to L1 rollup contract`, {
222
+ proofSize: args.proof.withoutPublicInputs().length,
223
+ fromCheckpoint: args.fromCheckpoint,
224
+ toCheckpoint: args.toCheckpoint,
225
+ });
222
226
  const data = encodeFunctionData({
223
227
  abi: RollupAbi,
224
228
  functionName: 'submitEpochRootProof',
225
229
  args: txArgs,
226
230
  });
227
231
  try {
228
- const { receipt } = await this.l1TxUtils.sendAndMonitorTransaction({
229
- to: this.rollupContract.address,
230
- data,
231
- });
232
-
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
+ }
233
248
  return receipt;
234
249
  } catch (err) {
235
250
  this.log.error(`Rollup submit epoch proof failed`, err);
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. ${errorMsg}`);
248
251
  return undefined;
249
252
  }
250
253
  }
251
254
 
252
- private getSubmitEpochProofArgs(args: {
253
- fromBlock: number;
254
- toBlock: number;
255
+ private getEpochProofPublicInputsArgs(args: {
256
+ fromCheckpoint: CheckpointNumber;
257
+ toCheckpoint: CheckpointNumber;
255
258
  publicInputs: RootRollupPublicInputs;
256
- proof: Proof;
259
+ batchedBlobInputs: BatchedBlob;
260
+ attestations: ViemCommitteeAttestation[];
257
261
  }) {
262
+ // Returns arguments for EpochProofLib.sol -> getEpochProofPublicInputs()
258
263
  return [
259
- BigInt(args.fromBlock),
260
- BigInt(args.toBlock),
264
+ BigInt(args.fromCheckpoint) /*_start*/,
265
+ BigInt(args.toCheckpoint) /*_end*/,
261
266
  {
262
- previousArchive: args.publicInputs.previousArchive.root.toString(),
263
- endArchive: args.publicInputs.endArchive.root.toString(),
264
- previousBlockHash: args.publicInputs.previousBlockHash.toString(),
265
- endBlockHash: args.publicInputs.endBlockHash.toString(),
266
- endTimestamp: args.publicInputs.endTimestamp.toBigInt(),
267
- outHash: args.publicInputs.outHash.toString(),
268
- proverId: EthAddress.fromField(args.publicInputs.proverId).toString(),
269
- },
267
+ previousArchive: args.publicInputs.previousArchiveRoot.toString(),
268
+ endArchive: args.publicInputs.endArchiveRoot.toString(),
269
+ proverId: EthAddress.fromField(args.publicInputs.constants.proverId).toString(),
270
+ } /*_args*/,
270
271
  makeTuple(AZTEC_MAX_EPOCH_DURATION * 2, i =>
271
272
  i % 2 === 0
272
273
  ? args.publicInputs.fees[i / 2].recipient.toField().toString()
273
274
  : args.publicInputs.fees[(i - 1) / 2].value.toString(),
274
- ),
275
- `0x${args.publicInputs.blobPublicInputs
276
- .filter((_, i) => i < args.toBlock - args.fromBlock + 1)
277
- .map(b => b.toString())
278
- .join(``)}`,
279
- `0x${serializeToBuffer(args.proof.extractAggregationObject()).toString('hex')}`,
275
+ ) /*_fees*/,
276
+ getEthBlobEvaluationInputs(args.batchedBlobInputs) /*_blobPublicInputs*/,
280
277
  ] as const;
281
278
  }
282
279
 
283
- protected async sleepOrInterrupted() {
284
- await this.interruptibleSleep.sleep(this.sleepTimeMs);
280
+ private getSubmitEpochProofArgs(args: {
281
+ fromCheckpoint: CheckpointNumber;
282
+ toCheckpoint: CheckpointNumber;
283
+ publicInputs: RootRollupPublicInputs;
284
+ proof: Proof;
285
+ batchedBlobInputs: BatchedBlob;
286
+ attestations: ViemCommitteeAttestation[];
287
+ }) {
288
+ // Returns arguments for EpochProofLib.sol -> submitEpochRootProof()
289
+ const proofHex: Hex = `0x${args.proof.withoutPublicInputs().toString('hex')}`;
290
+ const argsArray = this.getEpochProofPublicInputsArgs(args);
291
+ return {
292
+ start: argsArray[0],
293
+ end: argsArray[1],
294
+ args: argsArray[2],
295
+ fees: argsArray[3],
296
+ attestations: new CommitteeAttestationsAndSigners(
297
+ args.attestations.map(a => CommitteeAttestation.fromViem(a)),
298
+ ).getPackedAttestations(),
299
+ blobInputs: argsArray[4],
300
+ proof: proofHex,
301
+ };
285
302
  }
286
303
  }