@aztec/prover-node 3.0.0-canary.a9708bd → 3.0.0-devnet.2-patch.1

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 (48) hide show
  1. package/dest/actions/download-epoch-proving-job.d.ts +4 -4
  2. package/dest/actions/index.d.ts +1 -1
  3. package/dest/actions/rerun-epoch-proving-job.d.ts +2 -2
  4. package/dest/actions/upload-epoch-proof-failure.d.ts +1 -1
  5. package/dest/bin/run-failed-epoch.d.ts +1 -1
  6. package/dest/bin/run-failed-epoch.js +1 -1
  7. package/dest/config.d.ts +4 -2
  8. package/dest/config.d.ts.map +1 -1
  9. package/dest/config.js +19 -14
  10. package/dest/factory.d.ts +2 -2
  11. package/dest/factory.d.ts.map +1 -1
  12. package/dest/factory.js +18 -7
  13. package/dest/index.d.ts +1 -1
  14. package/dest/job/epoch-proving-job-data.d.ts +8 -6
  15. package/dest/job/epoch-proving-job-data.d.ts.map +1 -1
  16. package/dest/job/epoch-proving-job-data.js +25 -18
  17. package/dest/job/epoch-proving-job.d.ts +11 -16
  18. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  19. package/dest/job/epoch-proving-job.js +107 -65
  20. package/dest/metrics.d.ts +4 -3
  21. package/dest/metrics.d.ts.map +1 -1
  22. package/dest/metrics.js +9 -3
  23. package/dest/monitors/epoch-monitor.d.ts +5 -2
  24. package/dest/monitors/epoch-monitor.d.ts.map +1 -1
  25. package/dest/monitors/epoch-monitor.js +10 -1
  26. package/dest/monitors/index.d.ts +1 -1
  27. package/dest/prover-node-publisher.d.ts +9 -10
  28. package/dest/prover-node-publisher.d.ts.map +1 -1
  29. package/dest/prover-node-publisher.js +51 -52
  30. package/dest/prover-node.d.ts +8 -7
  31. package/dest/prover-node.d.ts.map +1 -1
  32. package/dest/prover-node.js +39 -32
  33. package/dest/prover-publisher-factory.d.ts +6 -2
  34. package/dest/prover-publisher-factory.d.ts.map +1 -1
  35. package/dest/prover-publisher-factory.js +6 -0
  36. package/dest/test/index.d.ts +1 -1
  37. package/dest/test/index.d.ts.map +1 -1
  38. package/package.json +26 -25
  39. package/src/bin/run-failed-epoch.ts +2 -2
  40. package/src/config.ts +30 -29
  41. package/src/factory.ts +22 -14
  42. package/src/job/epoch-proving-job-data.ts +31 -25
  43. package/src/job/epoch-proving-job.ts +138 -82
  44. package/src/metrics.ts +16 -4
  45. package/src/monitors/epoch-monitor.ts +15 -5
  46. package/src/prover-node-publisher.ts +73 -72
  47. package/src/prover-node.ts +51 -44
  48. package/src/prover-publisher-factory.ts +12 -1
package/src/config.ts CHANGED
@@ -1,16 +1,14 @@
1
1
  import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
2
2
  import type { ACVMConfig, BBConfig } from '@aztec/bb-prover/config';
3
- import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum';
4
- import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
5
- import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
3
+ import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum/config';
6
4
  import {
7
- type EthAccount,
8
- type EthAddressHex,
9
- type EthRemoteSignerAccount,
10
- type KeyStore,
11
- type KeyStoreConfig,
12
- keyStoreConfigMappings,
13
- } from '@aztec/node-keystore';
5
+ type ConfigMappingsType,
6
+ booleanConfigHelper,
7
+ getConfigFromMappings,
8
+ numberConfigHelper,
9
+ } from '@aztec/foundation/config';
10
+ import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
11
+ import { type KeyStore, type KeyStoreConfig, ethPrivateKeySchema, keyStoreConfigMappings } from '@aztec/node-keystore';
14
12
  import { type SharedNodeConfig, sharedNodeConfigMappings } from '@aztec/node-lib/config';
15
13
  import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
16
14
  import {
@@ -45,6 +43,8 @@ export type SpecificProverNodeConfig = {
45
43
  proverNodePollingIntervalMs: number;
46
44
  proverNodeMaxParallelBlocksPerEpoch: number;
47
45
  proverNodeFailedEpochStore: string | undefined;
46
+ proverNodeEpochProvingDelayMs: number | undefined;
47
+ proverNodeDisableProofPublish?: boolean;
48
48
  txGatheringTimeoutMs: number;
49
49
  txGatheringIntervalMs: number;
50
50
  txGatheringBatchSize: number;
@@ -72,6 +72,10 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
72
72
  description: 'File store where to upload node state when an epoch fails to be proven',
73
73
  defaultValue: undefined,
74
74
  },
75
+ proverNodeEpochProvingDelayMs: {
76
+ description: 'Optional delay in milliseconds to wait before proving a new epoch',
77
+ defaultValue: undefined,
78
+ },
75
79
  txGatheringIntervalMs: {
76
80
  env: 'PROVER_NODE_TX_GATHERING_INTERVAL_MS',
77
81
  description: 'How often to check that tx data is available',
@@ -92,6 +96,11 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
92
96
  description: 'How long to wait for tx data to be available before giving up',
93
97
  ...numberConfigHelper(120_000),
94
98
  },
99
+ proverNodeDisableProofPublish: {
100
+ env: 'PROVER_NODE_DISABLE_PROOF_PUBLISH',
101
+ description: 'Whether the prover node skips publishing proofs to L1',
102
+ ...booleanConfigHelper(false),
103
+ },
95
104
  };
96
105
 
97
106
  export const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig> = {
@@ -125,19 +134,14 @@ export function getProverNodeAgentConfigFromEnv(): ProverAgentConfig & BBConfig
125
134
  };
126
135
  }
127
136
 
128
- function createKeyStoreFromWeb3Signer(config: ProverNodeConfig) {
129
- // See what we have been given for proverId.
130
- const proverId = config.proverId ? (config.proverId.toString() as EthAddressHex) : undefined;
131
-
137
+ function createKeyStoreFromWeb3Signer(config: ProverNodeConfig): KeyStore | undefined {
132
138
  // If we don't have a valid prover Id then we can't build a valid key store with remote signers
133
- if (proverId === undefined) {
139
+ if (config.proverId === undefined) {
134
140
  return undefined;
135
141
  }
136
142
 
137
143
  // Also, we need at least one publisher address.
138
- const publishers = config.publisherAddresses
139
- ? config.publisherAddresses.map(k => k.toChecksumString() as EthRemoteSignerAccount)
140
- : [];
144
+ const publishers = config.publisherAddresses ?? [];
141
145
 
142
146
  if (publishers.length === 0) {
143
147
  return undefined;
@@ -147,7 +151,7 @@ function createKeyStoreFromWeb3Signer(config: ProverNodeConfig) {
147
151
  schemaVersion: 1,
148
152
  slasher: undefined,
149
153
  prover: {
150
- id: proverId,
154
+ id: config.proverId,
151
155
  publisher: publishers,
152
156
  },
153
157
  remoteSigner: config.web3SignerUrl,
@@ -156,10 +160,10 @@ function createKeyStoreFromWeb3Signer(config: ProverNodeConfig) {
156
160
  return keyStore;
157
161
  }
158
162
 
159
- function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
163
+ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig): KeyStore | undefined {
160
164
  // Extract the publisher keys from the provided config.
161
165
  const publisherKeys = config.publisherPrivateKeys
162
- ? config.publisherPrivateKeys.map(k => k.getValue() as EthAddressHex)
166
+ ? config.publisherPrivateKeys.map(k => ethPrivateKeySchema.parse(k.getValue()))
163
167
  : [];
164
168
 
165
169
  // There must be at least 1.
@@ -167,9 +171,6 @@ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
167
171
  return undefined;
168
172
  }
169
173
 
170
- // Now see what we have been given for proverId.
171
- const proverId = config.proverId ? (config.proverId.toString() as EthAddressHex) : undefined;
172
-
173
174
  // If we have a valid proverId then create a prover key store of the form { id, publisher: [publisherKeys] }
174
175
  // Otherwise create one of the form ("0x12345678....." as EthAccount).
175
176
 
@@ -177,11 +178,11 @@ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
177
178
  schemaVersion: 1,
178
179
  slasher: undefined,
179
180
  prover:
180
- proverId === undefined
181
- ? (publisherKeys[0] as EthAccount)
181
+ config.proverId === undefined
182
+ ? publisherKeys[0]
182
183
  : {
183
- id: proverId,
184
- publisher: publisherKeys.map(key => key as EthAccount),
184
+ id: config.proverId,
185
+ publisher: publisherKeys,
185
186
  },
186
187
  remoteSigner: undefined,
187
188
  validators: undefined,
@@ -189,7 +190,7 @@ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
189
190
  return keyStore;
190
191
  }
191
192
 
192
- export function createKeyStoreForProver(config: ProverNodeConfig) {
193
+ export function createKeyStoreForProver(config: ProverNodeConfig): KeyStore | undefined {
193
194
  if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
194
195
  return createKeyStoreFromWeb3Signer(config);
195
196
  }
package/src/factory.ts CHANGED
@@ -2,20 +2,17 @@ import { type Archiver, createArchiver } from '@aztec/archiver';
2
2
  import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
3
3
  import { type BlobSinkClientInterface, createBlobSinkClient } from '@aztec/blob-sink/client';
4
4
  import { EpochCache } from '@aztec/epoch-cache';
5
- import {
6
- type EthSigner,
7
- L1TxUtils,
8
- PublisherManager,
9
- RollupContract,
10
- createEthereumChain,
11
- createL1TxUtilsFromEthSigner,
12
- } from '@aztec/ethereum';
5
+ import { createEthereumChain } from '@aztec/ethereum/chain';
6
+ import { RollupContract } from '@aztec/ethereum/contracts';
7
+ import { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
8
+ import { PublisherManager } from '@aztec/ethereum/publisher-manager';
13
9
  import { pick } from '@aztec/foundation/collection';
14
10
  import { type Logger, createLogger } from '@aztec/foundation/log';
15
11
  import { DateProvider } from '@aztec/foundation/timer';
16
12
  import type { DataStoreConfig } from '@aztec/kv-store/config';
17
13
  import { type KeyStoreConfig, KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
18
14
  import { trySnapshotSync } from '@aztec/node-lib/actions';
15
+ import { createL1TxUtilsFromEthSignerWithStore } from '@aztec/node-lib/factories';
19
16
  import { NodeRpcTxSource, createP2PClient } from '@aztec/p2p';
20
17
  import { type ProverClientConfig, createProverClient } from '@aztec/prover-client';
21
18
  import { createAndStartProvingBroker } from '@aztec/prover-client/broker';
@@ -73,6 +70,8 @@ export async function createProverNode(
73
70
  }
74
71
  }
75
72
 
73
+ await keyStoreManager?.validateSigners();
74
+
76
75
  // Extract the prover signers from the key store and verify that we have one.
77
76
  const proverSigners = keyStoreManager?.createProverSigners();
78
77
 
@@ -86,6 +85,8 @@ export async function createProverNode(
86
85
  );
87
86
  }
88
87
 
88
+ log.info(`Creating prover with publishers ${proverSigners.signers.map(signer => signer.address.toString()).join()}`);
89
+
89
90
  // Only consider user provided config if it is valid
90
91
  const proverIdInUserConfig = config.proverId === undefined || config.proverId.isZero() ? undefined : config.proverId;
91
92
 
@@ -133,21 +134,26 @@ export async function createProverNode(
133
134
 
134
135
  const l1TxUtils = deps.l1TxUtils
135
136
  ? [deps.l1TxUtils]
136
- : proverSigners.signers.map((signer: EthSigner) => {
137
- return createL1TxUtilsFromEthSigner(publicClient, signer, log, dateProvider, config);
138
- });
137
+ : await createL1TxUtilsFromEthSignerWithStore(
138
+ publicClient,
139
+ proverSigners.signers,
140
+ { ...config, scope: 'prover' },
141
+ { telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
142
+ );
139
143
 
140
144
  const publisherFactory =
141
145
  deps.publisherFactory ??
142
146
  new ProverPublisherFactory(config, {
143
147
  rollupContract,
144
- publisherManager: new PublisherManager(l1TxUtils),
148
+ publisherManager: new PublisherManager(l1TxUtils, config),
145
149
  telemetry,
146
150
  });
147
151
 
148
152
  const proofVerifier = new QueuedIVCVerifier(
149
153
  config,
150
- config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier(),
154
+ config.realProofs || config.debugForceTxProofVerification
155
+ ? await BBCircuitVerifier.new(config)
156
+ : new TestCircuitVerifier(config.proverTestVerificationDelayMs),
151
157
  );
152
158
 
153
159
  const p2pClient = await createP2PClient(
@@ -175,10 +181,12 @@ export async function createProverNode(
175
181
  'proverNodeMaxPendingJobs',
176
182
  'proverNodeMaxParallelBlocksPerEpoch',
177
183
  'proverNodePollingIntervalMs',
184
+ 'proverNodeEpochProvingDelayMs',
178
185
  'txGatheringMaxParallelRequests',
179
186
  'txGatheringIntervalMs',
180
187
  'txGatheringTimeoutMs',
181
188
  'proverNodeFailedEpochStore',
189
+ 'proverNodeDisableProofPublish',
182
190
  'dataDirectory',
183
191
  'l1ChainId',
184
192
  'rollupVersion',
@@ -187,7 +195,7 @@ export async function createProverNode(
187
195
 
188
196
  const epochMonitor = await EpochMonitor.create(
189
197
  archiver,
190
- { pollingIntervalMs: config.proverNodePollingIntervalMs },
198
+ { pollingIntervalMs: config.proverNodePollingIntervalMs, provingDelayMs: config.proverNodeEpochProvingDelayMs },
191
199
  telemetry,
192
200
  );
193
201
 
@@ -1,49 +1,55 @@
1
- import { Fr } from '@aztec/foundation/fields';
1
+ import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
3
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
3
- import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
4
+ import { CommitteeAttestation } from '@aztec/stdlib/block';
5
+ import { Checkpoint } from '@aztec/stdlib/checkpoint';
4
6
  import { BlockHeader, Tx } from '@aztec/stdlib/tx';
5
7
 
6
8
  /** All data from an epoch used in proving. */
7
9
  export type EpochProvingJobData = {
8
- epochNumber: bigint;
9
- blocks: L2Block[];
10
+ epochNumber: EpochNumber;
11
+ checkpoints: Checkpoint[];
10
12
  txs: Map<string, Tx>;
11
- l1ToL2Messages: Record<number, Fr[]>;
13
+ l1ToL2Messages: Record<CheckpointNumber, Fr[]>;
12
14
  previousBlockHeader: BlockHeader;
13
15
  attestations: CommitteeAttestation[];
14
16
  };
15
17
 
16
18
  export function validateEpochProvingJobData(data: EpochProvingJobData) {
17
- if (data.blocks.length > 0 && data.previousBlockHeader.getBlockNumber() + 1 !== data.blocks[0].number) {
19
+ if (data.checkpoints.length === 0) {
20
+ throw new Error('No checkpoints to prove');
21
+ }
22
+
23
+ const firstBlockNumber = data.checkpoints[0].blocks[0].number;
24
+ const previousBlockNumber = data.previousBlockHeader.getBlockNumber();
25
+ if (previousBlockNumber + 1 !== firstBlockNumber) {
18
26
  throw new Error(
19
- `Initial block number ${
20
- data.blocks[0].number
21
- } does not match previous block header ${data.previousBlockHeader.getBlockNumber()}`,
27
+ `Initial block number ${firstBlockNumber} does not match previous block header ${previousBlockNumber}`,
22
28
  );
23
29
  }
24
30
 
25
- for (const blockNumber of data.blocks.map(block => block.number)) {
26
- if (!(blockNumber in data.l1ToL2Messages)) {
27
- throw new Error(`Missing L1 to L2 messages for block number ${blockNumber}`);
31
+ for (const checkpoint of data.checkpoints) {
32
+ if (!(checkpoint.number in data.l1ToL2Messages)) {
33
+ throw new Error(`Missing L1 to L2 messages for checkpoint number ${checkpoint.number}`);
28
34
  }
29
35
  }
30
36
  }
31
37
 
32
38
  export function serializeEpochProvingJobData(data: EpochProvingJobData): Buffer {
33
- const blocks = data.blocks.map(block => block.toBuffer());
39
+ const checkpoints = data.checkpoints.map(checkpoint => checkpoint.toBuffer());
34
40
  const txs = Array.from(data.txs.values()).map(tx => tx.toBuffer());
35
- const l1ToL2Messages = Object.entries(data.l1ToL2Messages).map(([blockNumber, messages]) => [
36
- Number(blockNumber),
41
+ const l1ToL2Messages = Object.entries(data.l1ToL2Messages).map(([checkpointNumber, messages]) => [
42
+ Number(checkpointNumber),
37
43
  messages.length,
38
44
  ...messages,
39
45
  ]);
40
46
  const attestations = data.attestations.map(attestation => attestation.toBuffer());
41
47
 
42
48
  return serializeToBuffer(
43
- Number(data.epochNumber),
49
+ data.epochNumber,
44
50
  data.previousBlockHeader,
45
- blocks.length,
46
- ...blocks,
51
+ checkpoints.length,
52
+ ...checkpoints,
47
53
  txs.length,
48
54
  ...txs,
49
55
  l1ToL2Messages.length,
@@ -55,22 +61,22 @@ export function serializeEpochProvingJobData(data: EpochProvingJobData): Buffer
55
61
 
56
62
  export function deserializeEpochProvingJobData(buf: Buffer): EpochProvingJobData {
57
63
  const reader = BufferReader.asReader(buf);
58
- const epochNumber = BigInt(reader.readNumber());
64
+ const epochNumber = EpochNumber(reader.readNumber());
59
65
  const previousBlockHeader = reader.readObject(BlockHeader);
60
- const blocks = reader.readVector(L2Block);
66
+ const checkpoints = reader.readVector(Checkpoint);
61
67
  const txArray = reader.readVector(Tx);
62
68
 
63
- const l1ToL2MessageBlockCount = reader.readNumber();
69
+ const l1ToL2MessageCheckpointCount = reader.readNumber();
64
70
  const l1ToL2Messages: Record<number, Fr[]> = {};
65
- for (let i = 0; i < l1ToL2MessageBlockCount; i++) {
66
- const blockNumber = reader.readNumber();
71
+ for (let i = 0; i < l1ToL2MessageCheckpointCount; i++) {
72
+ const checkpointNumber = CheckpointNumber(reader.readNumber());
67
73
  const messages = reader.readVector(Fr);
68
- l1ToL2Messages[blockNumber] = messages;
74
+ l1ToL2Messages[checkpointNumber] = messages;
69
75
  }
70
76
 
71
77
  const attestations = reader.readVector(CommitteeAttestation);
72
78
 
73
79
  const txs = new Map<string, Tx>(txArray.map(tx => [tx.getTxHash().toString(), tx]));
74
80
 
75
- return { epochNumber, previousBlockHeader, blocks, txs, l1ToL2Messages, attestations };
81
+ return { epochNumber, previousBlockHeader, checkpoints, txs, l1ToL2Messages, attestations };
76
82
  }