@aztec/prover-node 2.0.0-nightly.20250826 → 2.0.0-nightly.20250828

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.
@@ -1,4 +1,4 @@
1
- /* eslint-disable no-console */ import { Fr } from '@aztec/foundation/fields';
1
+ /* eslint-disable no-console */ import { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import { downloadEpochProvingJob, getProverNodeConfigFromEnv, rerunEpochProvingJob } from '@aztec/prover-node';
@@ -19,7 +19,7 @@ async function rerunFailedEpoch(provingJobUrl, baseLocalDir) {
19
19
  ...getProverNodeConfigFromEnv(),
20
20
  dataDirectory: dataDir,
21
21
  dataStoreMapSizeKB: env.dataStoreMapSizeKB ?? 1024 * 1024,
22
- proverId: env.proverId ?? Fr.random()
22
+ proverId: env.proverId ?? EthAddress.random()
23
23
  };
24
24
  let metadata;
25
25
  const metadataPath = join(localDir, 'metadata.json');
package/dest/config.d.ts CHANGED
@@ -3,13 +3,14 @@ import type { ACVMConfig, BBConfig } from '@aztec/bb-prover/config';
3
3
  import { type GenesisStateConfig } from '@aztec/ethereum';
4
4
  import { type ConfigMappingsType } from '@aztec/foundation/config';
5
5
  import { type DataStoreConfig } from '@aztec/kv-store/config';
6
+ import { type KeyStore, type KeyStoreConfig } from '@aztec/node-keystore';
6
7
  import { type SharedNodeConfig } from '@aztec/node-lib/config';
7
8
  import { type P2PConfig } from '@aztec/p2p/config';
8
9
  import { type ProverAgentConfig, type ProverBrokerConfig } from '@aztec/prover-client/broker';
9
- import { type ProverClientConfig, type ProverClientUserConfig } from '@aztec/prover-client/config';
10
+ import { type ProverClientUserConfig } from '@aztec/prover-client/config';
10
11
  import { type PublisherConfig, type TxSenderConfig } from '@aztec/sequencer-client/config';
11
12
  import { type WorldStateConfig } from '@aztec/world-state/config';
12
- export type ProverNodeConfig = ArchiverConfig & ProverClientUserConfig & P2PConfig & WorldStateConfig & PublisherConfig & TxSenderConfig & DataStoreConfig & SharedNodeConfig & SpecificProverNodeConfig & GenesisStateConfig;
13
+ export type ProverNodeConfig = ArchiverConfig & ProverClientUserConfig & P2PConfig & WorldStateConfig & PublisherConfig & TxSenderConfig & DataStoreConfig & KeyStoreConfig & SharedNodeConfig & SpecificProverNodeConfig & GenesisStateConfig;
13
14
  export type SpecificProverNodeConfig = {
14
15
  proverNodeMaxPendingJobs: number;
15
16
  proverNodePollingIntervalMs: number;
@@ -24,5 +25,5 @@ export declare const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConf
24
25
  export declare function getProverNodeConfigFromEnv(): ProverNodeConfig;
25
26
  export declare function getProverNodeBrokerConfigFromEnv(): ProverBrokerConfig;
26
27
  export declare function getProverNodeAgentConfigFromEnv(): ProverAgentConfig & BBConfig & ACVMConfig;
27
- export declare function resolveConfig(userConfig: ProverNodeConfig): ProverNodeConfig & ProverClientConfig;
28
+ export declare function createKeyStoreForProver(config: ProverNodeConfig): KeyStore | undefined;
28
29
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,wBAAwB,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,KAAK,kBAAkB,EAAwD,MAAM,iBAAiB,CAAC;AAChH,OAAO,EAAE,KAAK,kBAAkB,EAA6C,MAAM,0BAA0B,CAAC;AAE9G,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EAGxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAG5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,2BAA2B,CAAC;AAE5F,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAC3C,sBAAsB,GACtB,SAAS,GACT,gBAAgB,GAChB,eAAe,GACf,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,wBAAwB,GACxB,kBAAkB,CAAC;AAErB,MAAM,MAAM,wBAAwB,GAAG;IACrC,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;IACpC,mCAAmC,EAAE,MAAM,CAAC;IAC5C,0BAA0B,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qCAAqC,EAAE,MAAM,CAAC;CAC/C,CAAC;AA6CF,eAAO,MAAM,wBAAwB,EAAE,kBAAkB,CAAC,gBAAgB,CAWzE,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAE7D;AAED,wBAAgB,gCAAgC,IAAI,kBAAkB,CAIrE;AAED,wBAAgB,+BAA+B,IAAI,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAK3F;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,kBAAkB,CAMjG"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,wBAAwB,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,KAAK,kBAAkB,EAA8B,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,KAAK,kBAAkB,EAA6C,MAAM,0BAA0B,CAAC;AAC9G,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,cAAc,EAEpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EAGxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,sBAAsB,EAAgD,MAAM,6BAA6B,CAAC;AACxH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,2BAA2B,CAAC;AAE5F,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAC3C,sBAAsB,GACtB,SAAS,GACT,gBAAgB,GAChB,eAAe,GACf,cAAc,GACd,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,wBAAwB,GACxB,kBAAkB,CAAC;AAErB,MAAM,MAAM,wBAAwB,GAAG;IACrC,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;IACpC,mCAAmC,EAAE,MAAM,CAAC;IAC5C,0BAA0B,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qCAAqC,EAAE,MAAM,CAAC;CAC/C,CAAC;AA6CF,eAAO,MAAM,wBAAwB,EAAE,kBAAkB,CAAC,gBAAgB,CAYzE,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAE7D;AAED,wBAAgB,gCAAgC,IAAI,kBAAkB,CAIrE;AAED,wBAAgB,+BAA+B,IAAI,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAK3F;AAkED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,wBAM/D"}
package/dest/config.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { archiverConfigMappings } from '@aztec/archiver/config';
2
- import { genesisStateConfigMappings, getAddressFromPrivateKey } from '@aztec/ethereum';
2
+ import { genesisStateConfigMappings } from '@aztec/ethereum';
3
3
  import { getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
4
- import { Fr } from '@aztec/foundation/fields';
5
4
  import { dataConfigMappings } from '@aztec/kv-store/config';
5
+ import { keyStoreConfigMappings } from '@aztec/node-keystore';
6
6
  import { sharedNodeConfigMappings } from '@aztec/node-lib/config';
7
7
  import { p2pConfigMappings } from '@aztec/p2p/config';
8
8
  import { proverAgentConfigMappings, proverBrokerConfigMappings } from '@aztec/prover-client/broker';
@@ -53,6 +53,7 @@ const specificProverNodeConfigMappings = {
53
53
  };
54
54
  export const proverNodeConfigMappings = {
55
55
  ...dataConfigMappings,
56
+ ...keyStoreConfigMappings,
56
57
  ...archiverConfigMappings,
57
58
  ...proverClientConfigMappings,
58
59
  ...p2pConfigMappings,
@@ -77,10 +78,56 @@ export function getProverNodeAgentConfigFromEnv() {
77
78
  ...getConfigFromMappings(bbConfigMappings)
78
79
  };
79
80
  }
80
- export function resolveConfig(userConfig) {
81
- const proverId = userConfig.proverId && !userConfig.proverId.isZero() ? userConfig.proverId : Fr.fromHexString(getAddressFromPrivateKey(userConfig.publisherPrivateKey.getValue()));
82
- return {
83
- ...userConfig,
84
- proverId
81
+ function createKeyStoreFromWeb3Signer(config) {
82
+ // See what we have been given for proverId.
83
+ const proverId = config.proverId ? config.proverId.toString() : undefined;
84
+ // If we don't have a valid prover Id then we can't build a valid key store with remote signers
85
+ if (proverId === undefined) {
86
+ return undefined;
87
+ }
88
+ // Also, we need at least one publisher address.
89
+ const publishers = config.publisherAddresses ? config.publisherAddresses.map((k)=>k.toChecksumString()) : [];
90
+ if (publishers.length === 0) {
91
+ return undefined;
92
+ }
93
+ const keyStore = {
94
+ schemaVersion: 1,
95
+ slasher: undefined,
96
+ prover: {
97
+ id: proverId,
98
+ publisher: publishers
99
+ },
100
+ remoteSigner: config.web3SignerUrl,
101
+ validators: undefined
102
+ };
103
+ return keyStore;
104
+ }
105
+ function createKeyStoreFromPublisherKeys(config) {
106
+ // Extract the publisher keys from the provided config.
107
+ const publisherKeys = config.publisherPrivateKeys ? config.publisherPrivateKeys.map((k)=>k.getValue()) : [];
108
+ // There must be at least 1.
109
+ if (publisherKeys.length === 0) {
110
+ return undefined;
111
+ }
112
+ // Now see what we have been given for proverId.
113
+ const proverId = config.proverId ? config.proverId.toString() : undefined;
114
+ // If we have a valid proverId then create a prover key store of the form { id, publisher: [publisherKeys] }
115
+ // Otherwise create one of the form ("0x12345678....." as EthAccount).
116
+ const keyStore = {
117
+ schemaVersion: 1,
118
+ slasher: undefined,
119
+ prover: proverId === undefined ? publisherKeys[0] : {
120
+ id: proverId,
121
+ publisher: publisherKeys.map((key)=>key)
122
+ },
123
+ remoteSigner: undefined,
124
+ validators: undefined
85
125
  };
126
+ return keyStore;
127
+ }
128
+ export function createKeyStoreForProver(config) {
129
+ if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
130
+ return createKeyStoreFromWeb3Signer(config);
131
+ }
132
+ return createKeyStoreFromPublisherKeys(config);
86
133
  }
package/dest/factory.d.ts CHANGED
@@ -4,25 +4,26 @@ import { L1TxUtils } from '@aztec/ethereum';
4
4
  import { type Logger } from '@aztec/foundation/log';
5
5
  import { DateProvider } from '@aztec/foundation/timer';
6
6
  import type { DataStoreConfig } from '@aztec/kv-store/config';
7
+ import { type KeyStoreConfig } from '@aztec/node-keystore';
7
8
  import type { AztecNode, ProvingJobBroker } from '@aztec/stdlib/interfaces/server';
8
9
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
9
10
  import { type TelemetryClient } from '@aztec/telemetry-client';
10
11
  import { type ProverNodeConfig } from './config.js';
11
- import { ProverNodePublisher } from './prover-node-publisher.js';
12
12
  import { ProverNode } from './prover-node.js';
13
+ import { ProverPublisherFactory } from './prover-publisher-factory.js';
13
14
  export type ProverNodeDeps = {
14
15
  telemetry?: TelemetryClient;
15
16
  log?: Logger;
16
17
  aztecNodeTxProvider?: Pick<AztecNode, 'getTxsByHash'>;
17
18
  archiver?: Archiver;
18
- publisher?: ProverNodePublisher;
19
+ publisherFactory?: ProverPublisherFactory;
19
20
  blobSinkClient?: BlobSinkClientInterface;
20
21
  broker?: ProvingJobBroker;
21
22
  l1TxUtils?: L1TxUtils;
22
23
  dateProvider?: DateProvider;
23
24
  };
24
25
  /** Creates a new prover node given a config. */
25
- export declare function createProverNode(userConfig: ProverNodeConfig & DataStoreConfig, deps?: ProverNodeDeps, options?: {
26
+ export declare function createProverNode(userConfig: ProverNodeConfig & DataStoreConfig & KeyStoreConfig, deps?: ProverNodeDeps, options?: {
26
27
  prefilledPublicData?: PublicDataTreeLeaf[];
27
28
  }): Promise<ProverNode>;
28
29
  //# sourceMappingURL=factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,iBAAiB,CAAC;AAEhE,OAAO,EAAE,KAAK,uBAAuB,EAAwB,MAAM,yBAAyB,CAAC;AAE7F,OAAO,EAAE,SAAS,EAA+D,MAAM,iBAAiB,CAAC;AAEzG,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAK9D,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAGnF,OAAO,EAAE,KAAK,gBAAgB,EAAiB,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,gDAAgD;AAChD,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,gBAAgB,GAAG,eAAe,EAC9C,IAAI,GAAE,cAAmB,EACzB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACvC,uBAiGP"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,iBAAiB,CAAC;AAEhE,OAAO,EAAE,KAAK,uBAAuB,EAAwB,MAAM,yBAAyB,CAAC;AAE7F,OAAO,EAEL,SAAS,EAKV,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,KAAK,cAAc,EAAkD,MAAM,sBAAsB,CAAC;AAK3G,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAa,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAK9F,OAAO,EAAE,KAAK,gBAAgB,EAA2B,MAAM,aAAa,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,gDAAgD;AAChD,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,gBAAgB,GAAG,eAAe,GAAG,cAAc,EAC/D,IAAI,GAAE,cAAmB,EACzB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACvC,uBAgKP"}
package/dest/factory.js CHANGED
@@ -2,30 +2,64 @@ import { createArchiver } from '@aztec/archiver';
2
2
  import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
3
3
  import { createBlobSinkClient } from '@aztec/blob-sink/client';
4
4
  import { EpochCache } from '@aztec/epoch-cache';
5
- import { L1TxUtils, RollupContract, createEthereumChain, createExtendedL1Client } from '@aztec/ethereum';
5
+ import { PublisherManager, RollupContract, createEthereumChain, createL1TxUtilsFromEthSigner } from '@aztec/ethereum';
6
6
  import { pick } from '@aztec/foundation/collection';
7
7
  import { createLogger } from '@aztec/foundation/log';
8
8
  import { DateProvider } from '@aztec/foundation/timer';
9
+ import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
9
10
  import { trySnapshotSync } from '@aztec/node-lib/actions';
10
11
  import { NodeRpcTxSource, createP2PClient } from '@aztec/p2p';
11
12
  import { createProverClient } from '@aztec/prover-client';
12
13
  import { createAndStartProvingBroker } from '@aztec/prover-client/broker';
13
14
  import { P2PClientType } from '@aztec/stdlib/p2p';
14
15
  import { getPackageVersion } from '@aztec/stdlib/update-checker';
15
- import { getTelemetryClient } from '@aztec/telemetry-client';
16
+ import { L1Metrics, getTelemetryClient } from '@aztec/telemetry-client';
16
17
  import { createWorldStateSynchronizer } from '@aztec/world-state';
17
- import { resolveConfig } from './config.js';
18
+ import { createPublicClient, fallback, http } from 'viem';
19
+ import { createKeyStoreForProver } from './config.js';
18
20
  import { EpochMonitor } from './monitors/epoch-monitor.js';
19
- import { ProverNodePublisher } from './prover-node-publisher.js';
20
21
  import { ProverNode } from './prover-node.js';
22
+ import { ProverPublisherFactory } from './prover-publisher-factory.js';
21
23
  /** Creates a new prover node given a config. */ export async function createProverNode(userConfig, deps = {}, options = {}) {
22
- const config = resolveConfig(userConfig);
24
+ const config = {
25
+ ...userConfig
26
+ };
23
27
  const telemetry = deps.telemetry ?? getTelemetryClient();
24
28
  const dateProvider = deps.dateProvider ?? new DateProvider();
25
29
  const blobSinkClient = deps.blobSinkClient ?? createBlobSinkClient(config, {
26
30
  logger: createLogger('prover-node:blob-sink:client')
27
31
  });
28
32
  const log = deps.log ?? createLogger('prover-node');
33
+ // Build a key store from file if given or from environment otherwise
34
+ let keyStoreManager;
35
+ const keyStoreProvided = config.keyStoreDirectory !== undefined && config.keyStoreDirectory.length > 0;
36
+ if (keyStoreProvided) {
37
+ const keyStores = loadKeystores(config.keyStoreDirectory);
38
+ keyStoreManager = new KeystoreManager(mergeKeystores(keyStores));
39
+ } else {
40
+ const keyStore = createKeyStoreForProver(config);
41
+ if (keyStore) {
42
+ keyStoreManager = new KeystoreManager(keyStore);
43
+ }
44
+ }
45
+ // Extract the prover signers from the key store and verify that we have one.
46
+ const proverSigners = keyStoreManager?.createProverSigners();
47
+ if (proverSigners === undefined) {
48
+ throw new Error('Failed to create prover key store configuration');
49
+ } else if (proverSigners.signers.length === 0) {
50
+ throw new Error('No prover signers found in the key store');
51
+ } else if (!keyStoreProvided) {
52
+ log.warn('KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS');
53
+ }
54
+ // Only consider user provided config if it is valid
55
+ const proverIdInUserConfig = config.proverId === undefined || config.proverId.isZero() ? undefined : config.proverId;
56
+ // ProverId: Take from key store if provided, otherwise from user config if valid, otherwise address of first signer
57
+ const proverId = proverSigners.id ?? proverIdInUserConfig ?? proverSigners.signers[0].address;
58
+ // Now create the prover client configuration from this.
59
+ const proverClientConfig = {
60
+ ...config,
61
+ proverId
62
+ };
29
63
  await trySnapshotSync(config, log);
30
64
  const epochCache = await EpochCache.create(config.l1Contracts.rollupAddress, config);
31
65
  const archiver = deps.archiver ?? await createArchiver(config, {
@@ -44,16 +78,24 @@ import { ProverNode } from './prover-node.js';
44
78
  const worldStateSynchronizer = await createWorldStateSynchronizer(worldStateConfig, archiver, options.prefilledPublicData, telemetry);
45
79
  await worldStateSynchronizer.start();
46
80
  const broker = deps.broker ?? await createAndStartProvingBroker(config, telemetry);
47
- const prover = await createProverClient(config, worldStateSynchronizer, broker, telemetry);
48
- const { l1RpcUrls: rpcUrls, l1ChainId: chainId, publisherPrivateKey } = config;
81
+ const prover = await createProverClient(proverClientConfig, worldStateSynchronizer, broker, telemetry);
82
+ const { l1RpcUrls: rpcUrls, l1ChainId: chainId } = config;
49
83
  const chain = createEthereumChain(rpcUrls, chainId);
50
- const l1Client = createExtendedL1Client(rpcUrls, publisherPrivateKey.getValue(), chain.chainInfo);
51
- const rollupContract = new RollupContract(l1Client, config.l1Contracts.rollupAddress.toString());
52
- const l1TxUtils = deps.l1TxUtils ?? new L1TxUtils(l1Client, log, deps.dateProvider, config);
53
- const publisher = deps.publisher ?? new ProverNodePublisher(config, {
54
- telemetry,
84
+ const publicClient = createPublicClient({
85
+ chain: chain.chainInfo,
86
+ transport: fallback(config.l1RpcUrls.map((url)=>http(url))),
87
+ pollingInterval: config.viemPollingIntervalMS
88
+ });
89
+ const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
90
+ const l1TxUtils = deps.l1TxUtils ? [
91
+ deps.l1TxUtils
92
+ ] : proverSigners.signers.map((signer)=>{
93
+ return createL1TxUtilsFromEthSigner(publicClient, signer, log, dateProvider, config);
94
+ });
95
+ const publisherFactory = deps.publisherFactory ?? new ProverPublisherFactory(config, {
55
96
  rollupContract,
56
- l1TxUtils
97
+ publisherManager: new PublisherManager(l1TxUtils),
98
+ telemetry
57
99
  });
58
100
  const proofVerifier = new QueuedIVCVerifier(config, config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier());
59
101
  const p2pClient = await createP2PClient(P2PClientType.Prover, config, archiver, proofVerifier, worldStateSynchronizer, epochCache, getPackageVersion() ?? '', dateProvider, telemetry, {
@@ -68,5 +110,6 @@ import { ProverNode } from './prover-node.js';
68
110
  const epochMonitor = await EpochMonitor.create(archiver, {
69
111
  pollingIntervalMs: config.proverNodePollingIntervalMs
70
112
  }, telemetry);
71
- return new ProverNode(prover, publisher, archiver, archiver, archiver, worldStateSynchronizer, p2pClient, epochMonitor, proverNodeConfig, telemetry);
113
+ const l1Metrics = new L1Metrics(telemetry.getMeter('ProverNodeL1Metrics'), publicClient, l1TxUtils.map((utils)=>utils.getSenderAddress()));
114
+ return new ProverNode(prover, publisherFactory, archiver, archiver, archiver, worldStateSynchronizer, p2pClient, epochMonitor, rollupContract, l1Metrics, proverNodeConfig, telemetry);
72
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prover-node-publisher.d.ts","sourceRoot":"","sources":["../src/prover-node-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAoC,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EACL,KAAK,SAAS,EACd,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC9B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAIzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAOnF,sEAAsE;AACtE,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,EAAE,CAAC;IACpB,UAAU,EAAE,EAAE,CAAC;IACf,YAAY,EAAE,EAAE,CAAC;IACjB,OAAO,EAAE,EAAE,CAAC;IACZ,QAAQ,EAAE,EAAE,CAAC;IACb,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,wBAAwB,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAA6B;IAE5C,SAAS,CAAC,GAAG,yCAA+C;IAE5D,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC;IAEzC,SAAgB,SAAS,EAAE,SAAS,CAAC;gBAGnC,MAAM,EAAE,cAAc,GAAG,eAAe,EACxC,IAAI,EAAE;QACJ,cAAc,EAAE,cAAc,CAAC;QAC/B,SAAS,EAAE,SAAS,CAAC;QACrB,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B;IAYI,iBAAiB;IAIxB;;;;;OAKG;IACI,SAAS;IAKhB,wDAAwD;IACjD,OAAO;IAIP,gBAAgB;IAIV,gBAAgB,CAAC,IAAI,EAAE;QAClC,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,sBAAsB,CAAC;QACrC,KAAK,EAAE,KAAK,CAAC;QACb,iBAAiB,EAAE,WAAW,CAAC;QAC/B,YAAY,EAAE,wBAAwB,EAAE,CAAC;KAC1C,GAAG,OAAO,CAAC,OAAO,CAAC;YA+CN,4BAA4B;YA0D5B,sBAAsB;IAyCpC,OAAO,CAAC,6BAA6B;IAyBrC,OAAO,CAAC,uBAAuB;cAsBf,kBAAkB;CAGnC"}
1
+ {"version":3,"file":"prover-node-publisher.d.ts","sourceRoot":"","sources":["../src/prover-node-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAoC,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EACL,KAAK,SAAS,EACd,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC9B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAIzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAOnF,sEAAsE;AACtE,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,EAAE,CAAC;IACpB,UAAU,EAAE,EAAE,CAAC;IACf,YAAY,EAAE,EAAE,CAAC;IACjB,OAAO,EAAE,EAAE,CAAC;IACZ,QAAQ,EAAE,EAAE,CAAC;IACb,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,wBAAwB,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAA6B;IAE5C,SAAS,CAAC,GAAG,yCAA+C;IAE5D,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC;IAEzC,SAAgB,SAAS,EAAE,SAAS,CAAC;gBAGnC,MAAM,EAAE,cAAc,GAAG,eAAe,EACxC,IAAI,EAAE;QACJ,cAAc,EAAE,cAAc,CAAC;QAC/B,SAAS,EAAE,SAAS,CAAC;QACrB,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B;IAYI,iBAAiB;IAIxB;;;;;OAKG;IACI,SAAS;IAKhB,wDAAwD;IACjD,OAAO;IAIP,gBAAgB;IAIV,gBAAgB,CAAC,IAAI,EAAE;QAClC,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,sBAAsB,CAAC;QACrC,KAAK,EAAE,KAAK,CAAC;QACb,iBAAiB,EAAE,WAAW,CAAC;QAC/B,YAAY,EAAE,wBAAwB,EAAE,CAAC;KAC1C,GAAG,OAAO,CAAC,OAAO,CAAC;YAkDN,4BAA4B;YA0D5B,sBAAsB;IAyCpC,OAAO,CAAC,6BAA6B;IAyBrC,OAAO,CAAC,uBAAuB;cAsBf,kBAAkB;CAGnC"}
@@ -44,7 +44,7 @@ export class ProverNodePublisher {
44
44
  this.interrupted = false;
45
45
  }
46
46
  getSenderAddress() {
47
- return EthAddress.fromString(this.l1TxUtils.getSenderAddress());
47
+ return this.l1TxUtils.getSenderAddress();
48
48
  }
49
49
  async submitEpochProof(args) {
50
50
  const { epochNumber, fromBlock, toBlock } = args;
@@ -62,7 +62,7 @@ export class ProverNodePublisher {
62
62
  return false;
63
63
  }
64
64
  try {
65
- this.metrics.recordSenderBalance(await this.l1TxUtils.getSenderBalance(), this.l1TxUtils.getSenderAddress());
65
+ this.metrics.recordSenderBalance(await this.l1TxUtils.getSenderBalance(), this.l1TxUtils.getSenderAddress().toString());
66
66
  } catch (err) {
67
67
  this.log.warn(`Failed to record the ETH balance of the prover node: ${err}`);
68
68
  }
@@ -134,7 +134,11 @@ export class ProverNodePublisher {
134
134
  const txArgs = [
135
135
  this.getSubmitEpochProofArgs(args)
136
136
  ];
137
- this.log.info(`SubmitEpochProof proofSize=${args.proof.withoutPublicInputs().length} bytes`);
137
+ this.log.info(`Submitting epoch proof to L1 rollup contract`, {
138
+ proofSize: args.proof.withoutPublicInputs().length,
139
+ fromBlock: args.fromBlock,
140
+ toBlock: args.toBlock
141
+ });
138
142
  const data = encodeFunctionData({
139
143
  abi: RollupAbi,
140
144
  functionName: 'submitEpochRootProof',
@@ -1,4 +1,4 @@
1
- import type { Fr } from '@aztec/foundation/fields';
1
+ import type { RollupContract } from '@aztec/ethereum';
2
2
  import type { DataStoreConfig } from '@aztec/kv-store/config';
3
3
  import type { P2PClient } from '@aztec/p2p';
4
4
  import { PublicProcessorFactory } from '@aztec/simulator/server';
@@ -8,12 +8,13 @@ import type { ContractDataSource } from '@aztec/stdlib/contract';
8
8
  import { type EpochProverManager, type ProverNodeApi, type Service, type WorldStateSyncStatus, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
9
9
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
10
10
  import type { P2PClientType } from '@aztec/stdlib/p2p';
11
- import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
11
+ import { L1Metrics, type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
12
12
  import type { SpecificProverNodeConfig } from './config.js';
13
13
  import type { EpochProvingJobData } from './job/epoch-proving-job-data.js';
14
14
  import { EpochProvingJob, type EpochProvingJobState } from './job/epoch-proving-job.js';
15
15
  import type { EpochMonitor, EpochMonitorHandler } from './monitors/epoch-monitor.js';
16
16
  import type { ProverNodePublisher } from './prover-node-publisher.js';
17
+ import type { ProverPublisherFactory } from './prover-publisher-factory.js';
17
18
  type ProverNodeOptions = SpecificProverNodeConfig & Partial<DataStoreOptions>;
18
19
  type DataStoreOptions = Pick<DataStoreConfig, 'dataDirectory'> & Pick<ChainConfig, 'l1ChainId' | 'rollupVersion'>;
19
20
  /**
@@ -23,13 +24,15 @@ type DataStoreOptions = Pick<DataStoreConfig, 'dataDirectory'> & Pick<ChainConfi
23
24
  */
24
25
  export declare class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable {
25
26
  protected readonly prover: EpochProverManager;
26
- protected readonly publisher: ProverNodePublisher;
27
+ protected readonly publisherFactory: ProverPublisherFactory;
27
28
  protected readonly l2BlockSource: L2BlockSource & Partial<Service>;
28
29
  protected readonly l1ToL2MessageSource: L1ToL2MessageSource;
29
30
  protected readonly contractDataSource: ContractDataSource;
30
31
  protected readonly worldState: WorldStateSynchronizer;
31
32
  protected readonly p2pClient: Pick<P2PClient<P2PClientType.Prover>, 'getTxProvider'> & Partial<Service>;
32
33
  protected readonly epochsMonitor: EpochMonitor;
34
+ protected readonly rollupContract: RollupContract;
35
+ protected readonly l1Metrics: L1Metrics;
33
36
  protected readonly telemetryClient: TelemetryClient;
34
37
  private log;
35
38
  private dateProvider;
@@ -37,10 +40,10 @@ export declare class ProverNode implements EpochMonitorHandler, ProverNodeApi, T
37
40
  private config;
38
41
  private jobMetrics;
39
42
  private rewardsMetrics;
40
- private l1Metrics;
41
43
  readonly tracer: Tracer;
42
- constructor(prover: EpochProverManager, publisher: ProverNodePublisher, l2BlockSource: L2BlockSource & Partial<Service>, l1ToL2MessageSource: L1ToL2MessageSource, contractDataSource: ContractDataSource, worldState: WorldStateSynchronizer, p2pClient: Pick<P2PClient<P2PClientType.Prover>, 'getTxProvider'> & Partial<Service>, epochsMonitor: EpochMonitor, config?: Partial<ProverNodeOptions>, telemetryClient?: TelemetryClient);
43
- getProverId(): Fr;
44
+ protected publisher: ProverNodePublisher | undefined;
45
+ constructor(prover: EpochProverManager, publisherFactory: ProverPublisherFactory, l2BlockSource: L2BlockSource & Partial<Service>, l1ToL2MessageSource: L1ToL2MessageSource, contractDataSource: ContractDataSource, worldState: WorldStateSynchronizer, p2pClient: Pick<P2PClient<P2PClientType.Prover>, 'getTxProvider'> & Partial<Service>, epochsMonitor: EpochMonitor, rollupContract: RollupContract, l1Metrics: L1Metrics, config?: Partial<ProverNodeOptions>, telemetryClient?: TelemetryClient);
46
+ getProverId(): import("@aztec/stdlib/block").EthAddress;
44
47
  getP2P(): Pick<P2PClient<P2PClientType.Prover>, "getTxProvider"> & Partial<Service>;
45
48
  /**
46
49
  * Handles an epoch being completed by starting a proof for it if there are no active jobs for it.
@@ -92,7 +95,7 @@ export declare class ProverNode implements EpochMonitorHandler, ProverNodeApi, T
92
95
  private gatherMessages;
93
96
  private gatherPreviousBlockHeader;
94
97
  /** Extracted for testing purposes. */
95
- protected doCreateEpochProvingJob(data: EpochProvingJobData, deadline: Date | undefined, publicProcessorFactory: PublicProcessorFactory, opts?: {
98
+ protected doCreateEpochProvingJob(data: EpochProvingJobData, deadline: Date | undefined, publicProcessorFactory: PublicProcessorFactory, publisher: ProverNodePublisher, opts?: {
96
99
  skipEpochCheck?: boolean;
97
100
  }): EpochProvingJob;
98
101
  /** Extracted for testing purposes. */
@@ -1 +1 @@
1
- {"version":3,"file":"prover-node.d.ts","sourceRoot":"","sources":["../src/prover-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prover-node.d.ts","sourceRoot":"","sources":["../src/prover-node.ts"],"names":[],"mappings":"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"}
@@ -6,13 +6,12 @@ function _ts_decorate(decorators, target, key, desc) {
6
6
  }
7
7
  import { assertRequired, compact, pick, sum } from '@aztec/foundation/collection';
8
8
  import { memoize } from '@aztec/foundation/decorators';
9
- import { EthAddress } from '@aztec/foundation/eth-address';
10
9
  import { createLogger } from '@aztec/foundation/log';
11
10
  import { DateProvider } from '@aztec/foundation/timer';
12
11
  import { PublicProcessorFactory } from '@aztec/simulator/server';
13
12
  import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
14
13
  import { EpochProvingJobTerminalState, tryStop } from '@aztec/stdlib/interfaces/server';
15
- import { Attributes, L1Metrics, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
14
+ import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
16
15
  import { uploadEpochProofFailure } from './actions/upload-epoch-proof-failure.js';
17
16
  import { EpochProvingJob } from './job/epoch-proving-job.js';
18
17
  import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
@@ -22,13 +21,15 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
22
21
  * proof for the epoch, and submits it to L1.
23
22
  */ export class ProverNode {
24
23
  prover;
25
- publisher;
24
+ publisherFactory;
26
25
  l2BlockSource;
27
26
  l1ToL2MessageSource;
28
27
  contractDataSource;
29
28
  worldState;
30
29
  p2pClient;
31
30
  epochsMonitor;
31
+ rollupContract;
32
+ l1Metrics;
32
33
  telemetryClient;
33
34
  log;
34
35
  dateProvider;
@@ -36,24 +37,23 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
36
37
  config;
37
38
  jobMetrics;
38
39
  rewardsMetrics;
39
- l1Metrics;
40
40
  tracer;
41
- constructor(prover, publisher, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, p2pClient, epochsMonitor, config = {}, telemetryClient = getTelemetryClient()){
41
+ publisher;
42
+ constructor(prover, publisherFactory, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, p2pClient, epochsMonitor, rollupContract, l1Metrics, config = {}, telemetryClient = getTelemetryClient()){
42
43
  this.prover = prover;
43
- this.publisher = publisher;
44
+ this.publisherFactory = publisherFactory;
44
45
  this.l2BlockSource = l2BlockSource;
45
46
  this.l1ToL2MessageSource = l1ToL2MessageSource;
46
47
  this.contractDataSource = contractDataSource;
47
48
  this.worldState = worldState;
48
49
  this.p2pClient = p2pClient;
49
50
  this.epochsMonitor = epochsMonitor;
51
+ this.rollupContract = rollupContract;
52
+ this.l1Metrics = l1Metrics;
50
53
  this.telemetryClient = telemetryClient;
51
54
  this.log = createLogger('prover-node');
52
55
  this.dateProvider = new DateProvider();
53
56
  this.jobs = new Map();
54
- this.l1Metrics = new L1Metrics(telemetryClient.getMeter('ProverNodeL1Metrics'), publisher.l1TxUtils.client, [
55
- publisher.getSenderAddress()
56
- ]);
57
57
  this.config = {
58
58
  proverNodePollingIntervalMs: 1_000,
59
59
  proverNodeMaxPendingJobs: 100,
@@ -69,7 +69,7 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
69
69
  const meter = telemetryClient.getMeter('ProverNode');
70
70
  this.tracer = telemetryClient.getTracer('ProverNode');
71
71
  this.jobMetrics = new ProverNodeJobMetrics(meter, telemetryClient.getTracer('EpochProvingJob'));
72
- this.rewardsMetrics = new ProverNodeRewardsMetrics(meter, EthAddress.fromField(this.prover.getProverId()), this.publisher.getRollupContract());
72
+ this.rewardsMetrics = new ProverNodeRewardsMetrics(meter, this.prover.getProverId(), rollupContract);
73
73
  }
74
74
  getProverId() {
75
75
  return this.prover.getProverId();
@@ -109,8 +109,9 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
109
109
  * starts proving jobs for them.
110
110
  */ async start() {
111
111
  this.epochsMonitor.start(this);
112
- this.l1Metrics.start();
112
+ this.publisher = await this.publisherFactory.create();
113
113
  await this.rewardsMetrics.start();
114
+ this.l1Metrics.start();
114
115
  this.log.info(`Started Prover Node with prover id ${this.prover.getProverId().toString()}`, this.config);
115
116
  }
116
117
  /**
@@ -121,11 +122,11 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
121
122
  await this.prover.stop();
122
123
  await tryStop(this.p2pClient);
123
124
  await tryStop(this.l2BlockSource);
124
- this.publisher.interrupt();
125
+ this.publisher?.interrupt();
125
126
  await Promise.all(Array.from(this.jobs.values()).map((job)=>job.stop()));
126
127
  await this.worldState.stop();
127
- this.l1Metrics.stop();
128
128
  this.rewardsMetrics.stop();
129
+ this.l1Metrics.stop();
129
130
  await this.telemetryClient.stop();
130
131
  this.log.info('Stopped ProverNode');
131
132
  }
@@ -202,6 +203,7 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
202
203
  }
203
204
  async createProvingJob(epochNumber, opts = {}) {
204
205
  this.checkMaximumPendingJobs();
206
+ this.publisher = await this.publisherFactory.create();
205
207
  // Gather all data for this epoch
206
208
  const epochData = await this.gatherEpochData(epochNumber);
207
209
  const fromBlock = epochData.blocks[0].number;
@@ -214,7 +216,7 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
214
216
  // Set deadline for this job to run. It will abort if it takes too long.
215
217
  const deadlineTs = getProofSubmissionDeadlineTimestamp(epochNumber, await this.getL1Constants());
216
218
  const deadline = new Date(Number(deadlineTs) * 1000);
217
- const job = this.doCreateEpochProvingJob(epochData, deadline, publicProcessorFactory, opts);
219
+ const job = this.doCreateEpochProvingJob(epochData, deadline, publicProcessorFactory, this.publisher, opts);
218
220
  this.jobs.set(job.getId(), job);
219
221
  return job;
220
222
  }
@@ -285,9 +287,9 @@ import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
285
287
  this.log.verbose(`Gathered previous block header ${header.getBlockNumber()} for epoch ${epochNumber}`);
286
288
  return header;
287
289
  }
288
- /** Extracted for testing purposes. */ doCreateEpochProvingJob(data, deadline, publicProcessorFactory, opts = {}) {
290
+ /** Extracted for testing purposes. */ doCreateEpochProvingJob(data, deadline, publicProcessorFactory, publisher, opts = {}) {
289
291
  const { proverNodeMaxParallelBlocksPerEpoch: parallelBlockLimit } = this.config;
290
- return new EpochProvingJob(data, this.worldState, this.prover.createEpochProver(), publicProcessorFactory, this.publisher, this.l2BlockSource, this.jobMetrics, deadline, {
292
+ return new EpochProvingJob(data, this.worldState, this.prover.createEpochProver(), publicProcessorFactory, publisher, this.l2BlockSource, this.jobMetrics, deadline, {
291
293
  parallelBlockLimit,
292
294
  ...opts
293
295
  });
@@ -0,0 +1,19 @@
1
+ import type { L1TxUtils, PublisherManager, RollupContract } from '@aztec/ethereum';
2
+ import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
3
+ import type { TelemetryClient } from '@aztec/telemetry-client';
4
+ import { ProverNodePublisher } from './prover-node-publisher.js';
5
+ export declare class ProverPublisherFactory {
6
+ private config;
7
+ private deps;
8
+ constructor(config: TxSenderConfig & PublisherConfig, deps: {
9
+ rollupContract: RollupContract;
10
+ publisherManager: PublisherManager<L1TxUtils>;
11
+ telemetry?: TelemetryClient;
12
+ });
13
+ /**
14
+ * Creates a new Prover Publisher instance.
15
+ * @returns A new ProverNodePublisher instance.
16
+ */
17
+ create(): Promise<ProverNodePublisher>;
18
+ }
19
+ //# sourceMappingURL=prover-publisher-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prover-publisher-factory.d.ts","sourceRoot":"","sources":["../src/prover-publisher-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;gBADJ,MAAM,EAAE,cAAc,GAAG,eAAe,EACxC,IAAI,EAAE;QACZ,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC9C,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B;IAEH;;;OAGG;IACU,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC;CAQpD"}
@@ -0,0 +1,20 @@
1
+ import { ProverNodePublisher } from './prover-node-publisher.js';
2
+ export class ProverPublisherFactory {
3
+ config;
4
+ deps;
5
+ constructor(config, deps){
6
+ this.config = config;
7
+ this.deps = deps;
8
+ }
9
+ /**
10
+ * Creates a new Prover Publisher instance.
11
+ * @returns A new ProverNodePublisher instance.
12
+ */ async create() {
13
+ const l1Publisher = await this.deps.publisherManager.getAvailablePublisher();
14
+ return new ProverNodePublisher(this.config, {
15
+ rollupContract: this.deps.rollupContract,
16
+ l1TxUtils: l1Publisher,
17
+ telemetry: this.deps.telemetry
18
+ });
19
+ }
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/prover-node",
3
- "version": "2.0.0-nightly.20250826",
3
+ "version": "2.0.0-nightly.20250828",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -56,26 +56,27 @@
56
56
  ]
57
57
  },
58
58
  "dependencies": {
59
- "@aztec/archiver": "2.0.0-nightly.20250826",
60
- "@aztec/bb-prover": "2.0.0-nightly.20250826",
61
- "@aztec/blob-lib": "2.0.0-nightly.20250826",
62
- "@aztec/blob-sink": "2.0.0-nightly.20250826",
63
- "@aztec/constants": "2.0.0-nightly.20250826",
64
- "@aztec/epoch-cache": "2.0.0-nightly.20250826",
65
- "@aztec/ethereum": "2.0.0-nightly.20250826",
66
- "@aztec/foundation": "2.0.0-nightly.20250826",
67
- "@aztec/kv-store": "2.0.0-nightly.20250826",
68
- "@aztec/l1-artifacts": "2.0.0-nightly.20250826",
69
- "@aztec/node-lib": "2.0.0-nightly.20250826",
70
- "@aztec/noir-protocol-circuits-types": "2.0.0-nightly.20250826",
71
- "@aztec/p2p": "2.0.0-nightly.20250826",
72
- "@aztec/protocol-contracts": "2.0.0-nightly.20250826",
73
- "@aztec/prover-client": "2.0.0-nightly.20250826",
74
- "@aztec/sequencer-client": "2.0.0-nightly.20250826",
75
- "@aztec/simulator": "2.0.0-nightly.20250826",
76
- "@aztec/stdlib": "2.0.0-nightly.20250826",
77
- "@aztec/telemetry-client": "2.0.0-nightly.20250826",
78
- "@aztec/world-state": "2.0.0-nightly.20250826",
59
+ "@aztec/archiver": "2.0.0-nightly.20250828",
60
+ "@aztec/bb-prover": "2.0.0-nightly.20250828",
61
+ "@aztec/blob-lib": "2.0.0-nightly.20250828",
62
+ "@aztec/blob-sink": "2.0.0-nightly.20250828",
63
+ "@aztec/constants": "2.0.0-nightly.20250828",
64
+ "@aztec/epoch-cache": "2.0.0-nightly.20250828",
65
+ "@aztec/ethereum": "2.0.0-nightly.20250828",
66
+ "@aztec/foundation": "2.0.0-nightly.20250828",
67
+ "@aztec/kv-store": "2.0.0-nightly.20250828",
68
+ "@aztec/l1-artifacts": "2.0.0-nightly.20250828",
69
+ "@aztec/node-keystore": "2.0.0-nightly.20250828",
70
+ "@aztec/node-lib": "2.0.0-nightly.20250828",
71
+ "@aztec/noir-protocol-circuits-types": "2.0.0-nightly.20250828",
72
+ "@aztec/p2p": "2.0.0-nightly.20250828",
73
+ "@aztec/protocol-contracts": "2.0.0-nightly.20250828",
74
+ "@aztec/prover-client": "2.0.0-nightly.20250828",
75
+ "@aztec/sequencer-client": "2.0.0-nightly.20250828",
76
+ "@aztec/simulator": "2.0.0-nightly.20250828",
77
+ "@aztec/stdlib": "2.0.0-nightly.20250828",
78
+ "@aztec/telemetry-client": "2.0.0-nightly.20250828",
79
+ "@aztec/world-state": "2.0.0-nightly.20250828",
79
80
  "source-map-support": "^0.5.21",
80
81
  "tslib": "^2.4.0",
81
82
  "viem": "2.23.7"
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
  import type { L1ContractAddresses } from '@aztec/ethereum';
3
- import { Fr } from '@aztec/foundation/fields';
3
+ import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import { downloadEpochProvingJob, getProverNodeConfigFromEnv, rerunEpochProvingJob } from '@aztec/prover-node';
@@ -26,7 +26,7 @@ async function rerunFailedEpoch(provingJobUrl: string, baseLocalDir: string) {
26
26
  ...getProverNodeConfigFromEnv(),
27
27
  dataDirectory: dataDir,
28
28
  dataStoreMapSizeKB: env.dataStoreMapSizeKB ?? 1024 * 1024,
29
- proverId: env.proverId ?? Fr.random(),
29
+ proverId: env.proverId ?? EthAddress.random(),
30
30
  };
31
31
 
32
32
  let metadata: UploadSnapshotMetadata;
package/src/config.ts CHANGED
@@ -1,9 +1,16 @@
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, getAddressFromPrivateKey } from '@aztec/ethereum';
3
+ import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum';
4
4
  import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
5
- import { Fr } from '@aztec/foundation/fields';
6
5
  import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
6
+ import {
7
+ type EthAccount,
8
+ type EthAddressHex,
9
+ type EthRemoteSignerAccount,
10
+ type KeyStore,
11
+ type KeyStoreConfig,
12
+ keyStoreConfigMappings,
13
+ } from '@aztec/node-keystore';
7
14
  import { type SharedNodeConfig, sharedNodeConfigMappings } from '@aztec/node-lib/config';
8
15
  import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
9
16
  import {
@@ -12,12 +19,7 @@ import {
12
19
  proverAgentConfigMappings,
13
20
  proverBrokerConfigMappings,
14
21
  } from '@aztec/prover-client/broker';
15
- import {
16
- type ProverClientConfig,
17
- type ProverClientUserConfig,
18
- bbConfigMappings,
19
- proverClientConfigMappings,
20
- } from '@aztec/prover-client/config';
22
+ import { type ProverClientUserConfig, bbConfigMappings, proverClientConfigMappings } from '@aztec/prover-client/config';
21
23
  import {
22
24
  type PublisherConfig,
23
25
  type TxSenderConfig,
@@ -33,6 +35,7 @@ export type ProverNodeConfig = ArchiverConfig &
33
35
  PublisherConfig &
34
36
  TxSenderConfig &
35
37
  DataStoreConfig &
38
+ KeyStoreConfig &
36
39
  SharedNodeConfig &
37
40
  SpecificProverNodeConfig &
38
41
  GenesisStateConfig;
@@ -93,6 +96,7 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
93
96
 
94
97
  export const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig> = {
95
98
  ...dataConfigMappings,
99
+ ...keyStoreConfigMappings,
96
100
  ...archiverConfigMappings,
97
101
  ...proverClientConfigMappings,
98
102
  ...p2pConfigMappings,
@@ -121,10 +125,74 @@ export function getProverNodeAgentConfigFromEnv(): ProverAgentConfig & BBConfig
121
125
  };
122
126
  }
123
127
 
124
- export function resolveConfig(userConfig: ProverNodeConfig): ProverNodeConfig & ProverClientConfig {
125
- const proverId =
126
- userConfig.proverId && !userConfig.proverId.isZero()
127
- ? userConfig.proverId
128
- : Fr.fromHexString(getAddressFromPrivateKey(userConfig.publisherPrivateKey.getValue()));
129
- return { ...userConfig, proverId };
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
+
132
+ // 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) {
134
+ return undefined;
135
+ }
136
+
137
+ // Also, we need at least one publisher address.
138
+ const publishers = config.publisherAddresses
139
+ ? config.publisherAddresses.map(k => k.toChecksumString() as EthRemoteSignerAccount)
140
+ : [];
141
+
142
+ if (publishers.length === 0) {
143
+ return undefined;
144
+ }
145
+
146
+ const keyStore: KeyStore = {
147
+ schemaVersion: 1,
148
+ slasher: undefined,
149
+ prover: {
150
+ id: proverId,
151
+ publisher: publishers,
152
+ },
153
+ remoteSigner: config.web3SignerUrl,
154
+ validators: undefined,
155
+ };
156
+ return keyStore;
157
+ }
158
+
159
+ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
160
+ // Extract the publisher keys from the provided config.
161
+ const publisherKeys = config.publisherPrivateKeys
162
+ ? config.publisherPrivateKeys.map(k => k.getValue() as EthAddressHex)
163
+ : [];
164
+
165
+ // There must be at least 1.
166
+ if (publisherKeys.length === 0) {
167
+ return undefined;
168
+ }
169
+
170
+ // Now see what we have been given for proverId.
171
+ const proverId = config.proverId ? (config.proverId.toString() as EthAddressHex) : undefined;
172
+
173
+ // If we have a valid proverId then create a prover key store of the form { id, publisher: [publisherKeys] }
174
+ // Otherwise create one of the form ("0x12345678....." as EthAccount).
175
+
176
+ const keyStore: KeyStore = {
177
+ schemaVersion: 1,
178
+ slasher: undefined,
179
+ prover:
180
+ proverId === undefined
181
+ ? (publisherKeys[0] as EthAccount)
182
+ : {
183
+ id: proverId,
184
+ publisher: publisherKeys.map(key => key as EthAccount),
185
+ },
186
+ remoteSigner: undefined,
187
+ validators: undefined,
188
+ };
189
+ return keyStore;
190
+ }
191
+
192
+ export function createKeyStoreForProver(config: ProverNodeConfig) {
193
+ if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
194
+ return createKeyStoreFromWeb3Signer(config);
195
+ }
196
+
197
+ return createKeyStoreFromPublisherKeys(config);
130
198
  }
package/src/factory.ts CHANGED
@@ -2,33 +2,43 @@ 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 { L1TxUtils, RollupContract, createEthereumChain, createExtendedL1Client } from '@aztec/ethereum';
5
+ import {
6
+ type EthSigner,
7
+ L1TxUtils,
8
+ PublisherManager,
9
+ RollupContract,
10
+ createEthereumChain,
11
+ createL1TxUtilsFromEthSigner,
12
+ } from '@aztec/ethereum';
6
13
  import { pick } from '@aztec/foundation/collection';
7
14
  import { type Logger, createLogger } from '@aztec/foundation/log';
8
15
  import { DateProvider } from '@aztec/foundation/timer';
9
16
  import type { DataStoreConfig } from '@aztec/kv-store/config';
17
+ import { type KeyStoreConfig, KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
10
18
  import { trySnapshotSync } from '@aztec/node-lib/actions';
11
19
  import { NodeRpcTxSource, createP2PClient } from '@aztec/p2p';
12
- import { createProverClient } from '@aztec/prover-client';
20
+ import { type ProverClientConfig, createProverClient } from '@aztec/prover-client';
13
21
  import { createAndStartProvingBroker } from '@aztec/prover-client/broker';
14
22
  import type { AztecNode, ProvingJobBroker } from '@aztec/stdlib/interfaces/server';
15
23
  import { P2PClientType } from '@aztec/stdlib/p2p';
16
24
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
17
25
  import { getPackageVersion } from '@aztec/stdlib/update-checker';
18
- import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
26
+ import { L1Metrics, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
19
27
  import { createWorldStateSynchronizer } from '@aztec/world-state';
20
28
 
21
- import { type ProverNodeConfig, resolveConfig } from './config.js';
29
+ import { createPublicClient, fallback, http } from 'viem';
30
+
31
+ import { type ProverNodeConfig, createKeyStoreForProver } from './config.js';
22
32
  import { EpochMonitor } from './monitors/epoch-monitor.js';
23
- import { ProverNodePublisher } from './prover-node-publisher.js';
24
33
  import { ProverNode } from './prover-node.js';
34
+ import { ProverPublisherFactory } from './prover-publisher-factory.js';
25
35
 
26
36
  export type ProverNodeDeps = {
27
37
  telemetry?: TelemetryClient;
28
38
  log?: Logger;
29
39
  aztecNodeTxProvider?: Pick<AztecNode, 'getTxsByHash'>;
30
40
  archiver?: Archiver;
31
- publisher?: ProverNodePublisher;
41
+ publisherFactory?: ProverPublisherFactory;
32
42
  blobSinkClient?: BlobSinkClientInterface;
33
43
  broker?: ProvingJobBroker;
34
44
  l1TxUtils?: L1TxUtils;
@@ -37,19 +47,57 @@ export type ProverNodeDeps = {
37
47
 
38
48
  /** Creates a new prover node given a config. */
39
49
  export async function createProverNode(
40
- userConfig: ProverNodeConfig & DataStoreConfig,
50
+ userConfig: ProverNodeConfig & DataStoreConfig & KeyStoreConfig,
41
51
  deps: ProverNodeDeps = {},
42
52
  options: {
43
53
  prefilledPublicData?: PublicDataTreeLeaf[];
44
54
  } = {},
45
55
  ) {
46
- const config = resolveConfig(userConfig);
56
+ const config = { ...userConfig };
47
57
  const telemetry = deps.telemetry ?? getTelemetryClient();
48
58
  const dateProvider = deps.dateProvider ?? new DateProvider();
49
59
  const blobSinkClient =
50
60
  deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('prover-node:blob-sink:client') });
51
61
  const log = deps.log ?? createLogger('prover-node');
52
62
 
63
+ // Build a key store from file if given or from environment otherwise
64
+ let keyStoreManager: KeystoreManager | undefined;
65
+ const keyStoreProvided = config.keyStoreDirectory !== undefined && config.keyStoreDirectory.length > 0;
66
+ if (keyStoreProvided) {
67
+ const keyStores = loadKeystores(config.keyStoreDirectory!);
68
+ keyStoreManager = new KeystoreManager(mergeKeystores(keyStores));
69
+ } else {
70
+ const keyStore = createKeyStoreForProver(config);
71
+ if (keyStore) {
72
+ keyStoreManager = new KeystoreManager(keyStore);
73
+ }
74
+ }
75
+
76
+ // Extract the prover signers from the key store and verify that we have one.
77
+ const proverSigners = keyStoreManager?.createProverSigners();
78
+
79
+ if (proverSigners === undefined) {
80
+ throw new Error('Failed to create prover key store configuration');
81
+ } else if (proverSigners.signers.length === 0) {
82
+ throw new Error('No prover signers found in the key store');
83
+ } else if (!keyStoreProvided) {
84
+ log.warn(
85
+ 'KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS',
86
+ );
87
+ }
88
+
89
+ // Only consider user provided config if it is valid
90
+ const proverIdInUserConfig = config.proverId === undefined || config.proverId.isZero() ? undefined : config.proverId;
91
+
92
+ // ProverId: Take from key store if provided, otherwise from user config if valid, otherwise address of first signer
93
+ const proverId = proverSigners.id ?? proverIdInUserConfig ?? proverSigners.signers[0].address;
94
+
95
+ // Now create the prover client configuration from this.
96
+ const proverClientConfig: ProverClientConfig = {
97
+ ...config,
98
+ proverId,
99
+ };
100
+
53
101
  await trySnapshotSync(config, log);
54
102
 
55
103
  const epochCache = await EpochCache.create(config.l1Contracts.rollupAddress, config);
@@ -69,16 +117,33 @@ export async function createProverNode(
69
117
  await worldStateSynchronizer.start();
70
118
 
71
119
  const broker = deps.broker ?? (await createAndStartProvingBroker(config, telemetry));
72
- const prover = await createProverClient(config, worldStateSynchronizer, broker, telemetry);
73
120
 
74
- const { l1RpcUrls: rpcUrls, l1ChainId: chainId, publisherPrivateKey } = config;
121
+ const prover = await createProverClient(proverClientConfig, worldStateSynchronizer, broker, telemetry);
122
+
123
+ const { l1RpcUrls: rpcUrls, l1ChainId: chainId } = config;
75
124
  const chain = createEthereumChain(rpcUrls, chainId);
76
- const l1Client = createExtendedL1Client(rpcUrls, publisherPrivateKey.getValue(), chain.chainInfo);
77
125
 
78
- const rollupContract = new RollupContract(l1Client, config.l1Contracts.rollupAddress.toString());
126
+ const publicClient = createPublicClient({
127
+ chain: chain.chainInfo,
128
+ transport: fallback(config.l1RpcUrls.map((url: string) => http(url))),
129
+ pollingInterval: config.viemPollingIntervalMS,
130
+ });
79
131
 
80
- const l1TxUtils = deps.l1TxUtils ?? new L1TxUtils(l1Client, log, deps.dateProvider, config);
81
- const publisher = deps.publisher ?? new ProverNodePublisher(config, { telemetry, rollupContract, l1TxUtils });
132
+ const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
133
+
134
+ const l1TxUtils = deps.l1TxUtils
135
+ ? [deps.l1TxUtils]
136
+ : proverSigners.signers.map((signer: EthSigner) => {
137
+ return createL1TxUtilsFromEthSigner(publicClient, signer, log, dateProvider, config);
138
+ });
139
+
140
+ const publisherFactory =
141
+ deps.publisherFactory ??
142
+ new ProverPublisherFactory(config, {
143
+ rollupContract,
144
+ publisherManager: new PublisherManager(l1TxUtils),
145
+ telemetry,
146
+ });
82
147
 
83
148
  const proofVerifier = new QueuedIVCVerifier(
84
149
  config,
@@ -126,15 +191,23 @@ export async function createProverNode(
126
191
  telemetry,
127
192
  );
128
193
 
194
+ const l1Metrics = new L1Metrics(
195
+ telemetry.getMeter('ProverNodeL1Metrics'),
196
+ publicClient,
197
+ l1TxUtils.map(utils => utils.getSenderAddress()),
198
+ );
199
+
129
200
  return new ProverNode(
130
201
  prover,
131
- publisher,
202
+ publisherFactory,
132
203
  archiver,
133
204
  archiver,
134
205
  archiver,
135
206
  worldStateSynchronizer,
136
207
  p2pClient,
137
208
  epochMonitor,
209
+ rollupContract,
210
+ l1Metrics,
138
211
  proverNodeConfig,
139
212
  telemetry,
140
213
  );
@@ -89,7 +89,7 @@ export class ProverNodePublisher {
89
89
  }
90
90
 
91
91
  public getSenderAddress() {
92
- return EthAddress.fromString(this.l1TxUtils.getSenderAddress());
92
+ return this.l1TxUtils.getSenderAddress();
93
93
  }
94
94
 
95
95
  public async submitEpochProof(args: {
@@ -114,7 +114,10 @@ export class ProverNodePublisher {
114
114
  }
115
115
 
116
116
  try {
117
- this.metrics.recordSenderBalance(await this.l1TxUtils.getSenderBalance(), this.l1TxUtils.getSenderAddress());
117
+ this.metrics.recordSenderBalance(
118
+ await this.l1TxUtils.getSenderBalance(),
119
+ this.l1TxUtils.getSenderAddress().toString(),
120
+ );
118
121
  } catch (err) {
119
122
  this.log.warn(`Failed to record the ETH balance of the prover node: ${err}`);
120
123
  }
@@ -215,18 +218,18 @@ export class ProverNodePublisher {
215
218
  }): Promise<TransactionReceipt | undefined> {
216
219
  const txArgs = [this.getSubmitEpochProofArgs(args)] as const;
217
220
 
218
- 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
+ fromBlock: args.fromBlock,
224
+ toBlock: args.toBlock,
225
+ });
219
226
  const data = encodeFunctionData({
220
227
  abi: RollupAbi,
221
228
  functionName: 'submitEpochRootProof',
222
229
  args: txArgs,
223
230
  });
224
231
  try {
225
- const { receipt } = await this.l1TxUtils.sendAndMonitorTransaction({
226
- to: this.rollupContract.address,
227
- data,
228
- });
229
-
232
+ const { receipt } = await this.l1TxUtils.sendAndMonitorTransaction({ to: this.rollupContract.address, data });
230
233
  return receipt;
231
234
  } catch (err) {
232
235
  this.log.error(`Rollup submit epoch proof failed`, err);
@@ -1,8 +1,7 @@
1
1
  import type { Archiver } from '@aztec/archiver';
2
- import type { ViemPublicClient } from '@aztec/ethereum';
2
+ import type { RollupContract } from '@aztec/ethereum';
3
3
  import { assertRequired, compact, pick, sum } from '@aztec/foundation/collection';
4
4
  import { memoize } from '@aztec/foundation/decorators';
5
- import { EthAddress } from '@aztec/foundation/eth-address';
6
5
  import type { Fr } from '@aztec/foundation/fields';
7
6
  import { createLogger } from '@aztec/foundation/log';
8
7
  import { DateProvider } from '@aztec/foundation/timer';
@@ -42,6 +41,7 @@ import { EpochProvingJob, type EpochProvingJobState } from './job/epoch-proving-
42
41
  import { ProverNodeJobMetrics, ProverNodeRewardsMetrics } from './metrics.js';
43
42
  import type { EpochMonitor, EpochMonitorHandler } from './monitors/epoch-monitor.js';
44
43
  import type { ProverNodePublisher } from './prover-node-publisher.js';
44
+ import type { ProverPublisherFactory } from './prover-publisher-factory.js';
45
45
 
46
46
  type ProverNodeOptions = SpecificProverNodeConfig & Partial<DataStoreOptions>;
47
47
  type DataStoreOptions = Pick<DataStoreConfig, 'dataDirectory'> & Pick<ChainConfig, 'l1ChainId' | 'rollupVersion'>;
@@ -59,28 +59,25 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
59
59
  private config: ProverNodeOptions;
60
60
  private jobMetrics: ProverNodeJobMetrics;
61
61
  private rewardsMetrics: ProverNodeRewardsMetrics;
62
- private l1Metrics: L1Metrics;
63
62
 
64
63
  public readonly tracer: Tracer;
65
64
 
65
+ protected publisher: ProverNodePublisher | undefined;
66
+
66
67
  constructor(
67
68
  protected readonly prover: EpochProverManager,
68
- protected readonly publisher: ProverNodePublisher,
69
+ protected readonly publisherFactory: ProverPublisherFactory,
69
70
  protected readonly l2BlockSource: L2BlockSource & Partial<Service>,
70
71
  protected readonly l1ToL2MessageSource: L1ToL2MessageSource,
71
72
  protected readonly contractDataSource: ContractDataSource,
72
73
  protected readonly worldState: WorldStateSynchronizer,
73
74
  protected readonly p2pClient: Pick<P2PClient<P2PClientType.Prover>, 'getTxProvider'> & Partial<Service>,
74
75
  protected readonly epochsMonitor: EpochMonitor,
76
+ protected readonly rollupContract: RollupContract,
77
+ protected readonly l1Metrics: L1Metrics,
75
78
  config: Partial<ProverNodeOptions> = {},
76
79
  protected readonly telemetryClient: TelemetryClient = getTelemetryClient(),
77
80
  ) {
78
- this.l1Metrics = new L1Metrics(
79
- telemetryClient.getMeter('ProverNodeL1Metrics'),
80
- publisher.l1TxUtils.client as unknown as ViemPublicClient,
81
- [publisher.getSenderAddress()],
82
- );
83
-
84
81
  this.config = {
85
82
  proverNodePollingIntervalMs: 1_000,
86
83
  proverNodeMaxPendingJobs: 100,
@@ -100,11 +97,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
100
97
 
101
98
  this.jobMetrics = new ProverNodeJobMetrics(meter, telemetryClient.getTracer('EpochProvingJob'));
102
99
 
103
- this.rewardsMetrics = new ProverNodeRewardsMetrics(
104
- meter,
105
- EthAddress.fromField(this.prover.getProverId()),
106
- this.publisher.getRollupContract(),
107
- );
100
+ this.rewardsMetrics = new ProverNodeRewardsMetrics(meter, this.prover.getProverId(), rollupContract);
108
101
  }
109
102
 
110
103
  public getProverId() {
@@ -150,8 +143,9 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
150
143
  */
151
144
  async start() {
152
145
  this.epochsMonitor.start(this);
153
- this.l1Metrics.start();
146
+ this.publisher = await this.publisherFactory.create();
154
147
  await this.rewardsMetrics.start();
148
+ this.l1Metrics.start();
155
149
  this.log.info(`Started Prover Node with prover id ${this.prover.getProverId().toString()}`, this.config);
156
150
  }
157
151
 
@@ -164,11 +158,11 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
164
158
  await this.prover.stop();
165
159
  await tryStop(this.p2pClient);
166
160
  await tryStop(this.l2BlockSource);
167
- this.publisher.interrupt();
161
+ this.publisher?.interrupt();
168
162
  await Promise.all(Array.from(this.jobs.values()).map(job => job.stop()));
169
163
  await this.worldState.stop();
170
- this.l1Metrics.stop();
171
164
  this.rewardsMetrics.stop();
165
+ this.l1Metrics.stop();
172
166
  await this.telemetryClient.stop();
173
167
  this.log.info('Stopped ProverNode');
174
168
  }
@@ -270,6 +264,8 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
270
264
  private async createProvingJob(epochNumber: bigint, opts: { skipEpochCheck?: boolean } = {}) {
271
265
  this.checkMaximumPendingJobs();
272
266
 
267
+ this.publisher = await this.publisherFactory.create();
268
+
273
269
  // Gather all data for this epoch
274
270
  const epochData = await this.gatherEpochData(epochNumber);
275
271
 
@@ -291,7 +287,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
291
287
  const deadlineTs = getProofSubmissionDeadlineTimestamp(epochNumber, await this.getL1Constants());
292
288
  const deadline = new Date(Number(deadlineTs) * 1000);
293
289
 
294
- const job = this.doCreateEpochProvingJob(epochData, deadline, publicProcessorFactory, opts);
290
+ const job = this.doCreateEpochProvingJob(epochData, deadline, publicProcessorFactory, this.publisher, opts);
295
291
  this.jobs.set(job.getId(), job);
296
292
  return job;
297
293
  }
@@ -367,6 +363,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
367
363
  data: EpochProvingJobData,
368
364
  deadline: Date | undefined,
369
365
  publicProcessorFactory: PublicProcessorFactory,
366
+ publisher: ProverNodePublisher,
370
367
  opts: { skipEpochCheck?: boolean } = {},
371
368
  ) {
372
369
  const { proverNodeMaxParallelBlocksPerEpoch: parallelBlockLimit } = this.config;
@@ -375,7 +372,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
375
372
  this.worldState,
376
373
  this.prover.createEpochProver(),
377
374
  publicProcessorFactory,
378
- this.publisher,
375
+ publisher,
379
376
  this.l2BlockSource,
380
377
  this.jobMetrics,
381
378
  deadline,
@@ -0,0 +1,28 @@
1
+ import type { L1TxUtils, PublisherManager, RollupContract } from '@aztec/ethereum';
2
+ import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
3
+ import type { TelemetryClient } from '@aztec/telemetry-client';
4
+
5
+ import { ProverNodePublisher } from './prover-node-publisher.js';
6
+
7
+ export class ProverPublisherFactory {
8
+ constructor(
9
+ private config: TxSenderConfig & PublisherConfig,
10
+ private deps: {
11
+ rollupContract: RollupContract;
12
+ publisherManager: PublisherManager<L1TxUtils>;
13
+ telemetry?: TelemetryClient;
14
+ },
15
+ ) {}
16
+ /**
17
+ * Creates a new Prover Publisher instance.
18
+ * @returns A new ProverNodePublisher instance.
19
+ */
20
+ public async create(): Promise<ProverNodePublisher> {
21
+ const l1Publisher = await this.deps.publisherManager.getAvailablePublisher();
22
+ return new ProverNodePublisher(this.config, {
23
+ rollupContract: this.deps.rollupContract,
24
+ l1TxUtils: l1Publisher,
25
+ telemetry: this.deps.telemetry,
26
+ });
27
+ }
28
+ }