@aztec/prover-node 0.76.4 → 0.77.0-testnet-ignition.21

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 (45) hide show
  1. package/dest/config.d.ts +5 -2
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +24 -30
  4. package/dest/factory.d.ts +6 -3
  5. package/dest/factory.d.ts.map +1 -1
  6. package/dest/factory.js +21 -14
  7. package/dest/http.d.ts +1 -1
  8. package/dest/http.d.ts.map +1 -1
  9. package/dest/http.js +2 -4
  10. package/dest/index.js +0 -1
  11. package/dest/job/epoch-proving-job.d.ts +7 -4
  12. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  13. package/dest/job/epoch-proving-job.js +233 -193
  14. package/dest/metrics.d.ts +5 -2
  15. package/dest/metrics.d.ts.map +1 -1
  16. package/dest/metrics.js +50 -25
  17. package/dest/monitors/epoch-monitor.d.ts +22 -3
  18. package/dest/monitors/epoch-monitor.d.ts.map +1 -1
  19. package/dest/monitors/epoch-monitor.js +102 -48
  20. package/dest/monitors/index.js +0 -1
  21. package/dest/prover-coordination/config.js +2 -3
  22. package/dest/prover-coordination/factory.d.ts +5 -5
  23. package/dest/prover-coordination/factory.d.ts.map +1 -1
  24. package/dest/prover-coordination/factory.js +11 -8
  25. package/dest/prover-coordination/index.js +0 -1
  26. package/dest/prover-node-publisher.d.ts +5 -4
  27. package/dest/prover-node-publisher.d.ts.map +1 -1
  28. package/dest/prover-node-publisher.js +60 -52
  29. package/dest/prover-node.d.ts +12 -7
  30. package/dest/prover-node.d.ts.map +1 -1
  31. package/dest/prover-node.js +237 -224
  32. package/dest/test/index.d.ts +2 -2
  33. package/dest/test/index.d.ts.map +1 -1
  34. package/dest/test/index.js +2 -1
  35. package/package.json +21 -22
  36. package/src/config.ts +23 -31
  37. package/src/factory.ts +17 -8
  38. package/src/http.ts +2 -2
  39. package/src/job/epoch-proving-job.ts +11 -13
  40. package/src/metrics.ts +26 -5
  41. package/src/monitors/epoch-monitor.ts +57 -12
  42. package/src/prover-coordination/factory.ts +9 -12
  43. package/src/prover-node-publisher.ts +21 -14
  44. package/src/prover-node.ts +24 -22
  45. package/src/test/index.ts +2 -2
package/src/config.ts CHANGED
@@ -1,35 +1,29 @@
1
- import { type ArchiverConfig, archiverConfigMappings, getArchiverConfigFromEnv } from '@aztec/archiver/config';
2
- import { type ACVMConfig, type BBConfig } from '@aztec/bb-prover/config';
3
- import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
4
- import { type DataStoreConfig, dataConfigMappings, getDataConfigFromEnv } from '@aztec/kv-store/config';
5
- import { type P2PConfig, getP2PConfigFromEnv, p2pConfigMappings } from '@aztec/p2p/config';
1
+ import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
2
+ import type { ACVMConfig, BBConfig } from '@aztec/bb-prover/config';
3
+ import {
4
+ type ConfigMappingsType,
5
+ booleanConfigHelper,
6
+ getConfigFromMappings,
7
+ numberConfigHelper,
8
+ } from '@aztec/foundation/config';
9
+ import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
10
+ import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
6
11
  import {
7
12
  type ProverAgentConfig,
8
13
  type ProverBrokerConfig,
9
14
  proverAgentConfigMappings,
10
15
  proverBrokerConfigMappings,
11
16
  } from '@aztec/prover-client/broker';
12
- import {
13
- type ProverClientConfig,
14
- bbConfigMappings,
15
- getProverEnvVars,
16
- proverClientConfigMappings,
17
- } from '@aztec/prover-client/config';
17
+ import { type ProverClientConfig, bbConfigMappings, proverClientConfigMappings } from '@aztec/prover-client/config';
18
18
  import {
19
19
  type PublisherConfig,
20
20
  type TxSenderConfig,
21
- getPublisherConfigFromEnv,
22
21
  getPublisherConfigMappings,
23
- getTxSenderConfigFromEnv,
24
22
  getTxSenderConfigMappings,
25
23
  } from '@aztec/sequencer-client/config';
26
- import { type WorldStateConfig, getWorldStateConfigFromEnv, worldStateConfigMappings } from '@aztec/world-state/config';
24
+ import { type WorldStateConfig, worldStateConfigMappings } from '@aztec/world-state/config';
27
25
 
28
- import {
29
- type ProverCoordinationConfig,
30
- getTxProviderConfigFromEnv,
31
- proverCoordinationConfigMappings,
32
- } from './prover-coordination/config.js';
26
+ import { type ProverCoordinationConfig, proverCoordinationConfigMappings } from './prover-coordination/config.js';
33
27
 
34
28
  export type ProverNodeConfig = ArchiverConfig &
35
29
  ProverClientConfig &
@@ -39,7 +33,10 @@ export type ProverNodeConfig = ArchiverConfig &
39
33
  TxSenderConfig &
40
34
  DataStoreConfig &
41
35
  ProverCoordinationConfig &
42
- SpecificProverNodeConfig;
36
+ SpecificProverNodeConfig & {
37
+ /** Whether to populate the genesis state with initial fee juice for the test accounts */
38
+ testAccounts: boolean;
39
+ };
43
40
 
44
41
  type SpecificProverNodeConfig = {
45
42
  proverNodeMaxPendingJobs: number;
@@ -93,20 +90,15 @@ export const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig> = {
93
90
  ...getTxSenderConfigMappings('PROVER'),
94
91
  ...proverCoordinationConfigMappings,
95
92
  ...specificProverNodeConfigMappings,
93
+ testAccounts: {
94
+ env: 'TEST_ACCOUNTS',
95
+ description: 'Whether to populate the genesis state with initial fee juice for the test accounts.',
96
+ ...booleanConfigHelper(false),
97
+ },
96
98
  };
97
99
 
98
100
  export function getProverNodeConfigFromEnv(): ProverNodeConfig {
99
- return {
100
- ...getP2PConfigFromEnv(),
101
- ...getDataConfigFromEnv(),
102
- ...getArchiverConfigFromEnv(),
103
- ...getProverEnvVars(),
104
- ...getWorldStateConfigFromEnv(),
105
- ...getPublisherConfigFromEnv('PROVER'),
106
- ...getTxSenderConfigFromEnv('PROVER'),
107
- ...getTxProviderConfigFromEnv(),
108
- ...getConfigFromMappings(specificProverNodeConfigMappings),
109
- };
101
+ return getConfigFromMappings(proverNodeConfigMappings);
110
102
  }
111
103
 
112
104
  export function getProverNodeBrokerConfigFromEnv(): ProverBrokerConfig {
package/src/factory.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import { type Archiver, createArchiver } from '@aztec/archiver';
2
2
  import { type BlobSinkClientInterface, createBlobSinkClient } from '@aztec/blob-sink/client';
3
- import { type ProverCoordination, type ProvingJobBroker } from '@aztec/circuit-types';
4
3
  import { EpochCache } from '@aztec/epoch-cache';
5
4
  import { L1TxUtils, RollupContract, createEthereumChain, createL1Clients } from '@aztec/ethereum';
6
5
  import { type Logger, createLogger } from '@aztec/foundation/log';
7
- import { type DataStoreConfig } from '@aztec/kv-store/config';
6
+ import type { DataStoreConfig } from '@aztec/kv-store/config';
8
7
  import { createProverClient } from '@aztec/prover-client';
9
8
  import { createAndStartProvingBroker } from '@aztec/prover-client/broker';
9
+ import type { ProverCoordination, ProvingJobBroker } from '@aztec/stdlib/interfaces/server';
10
+ import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
10
11
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
11
12
  import { createWorldStateSynchronizer } from '@aztec/world-state';
12
13
 
13
- import { type ProverNodeConfig } from './config.js';
14
+ import type { ProverNodeConfig } from './config.js';
14
15
  import { EpochMonitor } from './monitors/epoch-monitor.js';
15
16
  import { createProverCoordination } from './prover-coordination/factory.js';
16
17
  import { ProverNodePublisher } from './prover-node-publisher.js';
@@ -29,6 +30,9 @@ export async function createProverNode(
29
30
  broker?: ProvingJobBroker;
30
31
  l1TxUtils?: L1TxUtils;
31
32
  } = {},
33
+ options: {
34
+ prefilledPublicData?: PublicDataTreeLeaf[];
35
+ } = {},
32
36
  ) {
33
37
  const telemetry = deps.telemetry ?? getTelemetryClient();
34
38
  const blobSinkClient = deps.blobSinkClient ?? createBlobSinkClient(config);
@@ -37,15 +41,20 @@ export async function createProverNode(
37
41
  log.verbose(`Created archiver and synced to block ${await archiver.getBlockNumber()}`);
38
42
 
39
43
  const worldStateConfig = { ...config, worldStateProvenBlocksOnly: false };
40
- const worldStateSynchronizer = await createWorldStateSynchronizer(worldStateConfig, archiver, telemetry);
44
+ const worldStateSynchronizer = await createWorldStateSynchronizer(
45
+ worldStateConfig,
46
+ archiver,
47
+ options.prefilledPublicData,
48
+ telemetry,
49
+ );
41
50
  await worldStateSynchronizer.start();
42
51
 
43
52
  const broker = deps.broker ?? (await createAndStartProvingBroker(config, telemetry));
44
53
  const prover = await createProverClient(config, worldStateSynchronizer, broker, telemetry);
45
54
 
46
- const { l1RpcUrl: rpcUrl, l1ChainId: chainId, publisherPrivateKey } = config;
47
- const chain = createEthereumChain(rpcUrl, chainId);
48
- const { publicClient, walletClient } = createL1Clients(rpcUrl, publisherPrivateKey, chain.chainInfo);
55
+ const { l1RpcUrls: rpcUrls, l1ChainId: chainId, publisherPrivateKey } = config;
56
+ const chain = createEthereumChain(rpcUrls, chainId);
57
+ const { publicClient, walletClient } = createL1Clients(rpcUrls, publisherPrivateKey, chain.chainInfo);
49
58
 
50
59
  const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
51
60
 
@@ -73,7 +82,7 @@ export async function createProverNode(
73
82
  txGatheringTimeoutMs: config.txGatheringTimeoutMs,
74
83
  };
75
84
 
76
- const epochMonitor = new EpochMonitor(archiver, proverNodeConfig, telemetry);
85
+ const epochMonitor = await EpochMonitor.create(archiver, proverNodeConfig, telemetry);
77
86
 
78
87
  return new ProverNode(
79
88
  prover,
package/src/http.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { ProverNodeApiSchema } from '@aztec/circuit-types';
1
+ import { ProverNodeApiSchema } from '@aztec/stdlib/interfaces/server';
2
2
  import { createTracedJsonRpcServer } from '@aztec/telemetry-client';
3
3
 
4
- import { type ProverNode } from './prover-node.js';
4
+ import type { ProverNode } from './prover-node.js';
5
5
 
6
6
  /**
7
7
  * Wrap a ProverNode instance with a JSON RPC HTTP server.
@@ -1,25 +1,23 @@
1
+ import { asyncPool } from '@aztec/foundation/async-pool';
2
+ import { createLogger } from '@aztec/foundation/log';
3
+ import { promiseWithResolvers } from '@aztec/foundation/promise';
4
+ import { Timer } from '@aztec/foundation/timer';
5
+ import type { PublicProcessor, PublicProcessorFactory } from '@aztec/simulator/server';
6
+ import type { L2Block, L2BlockSource } from '@aztec/stdlib/block';
1
7
  import {
2
8
  type EpochProver,
3
9
  type EpochProvingJobState,
4
10
  EpochProvingJobTerminalState,
5
11
  type ForkMerkleTreeOperations,
6
- type L1ToL2MessageSource,
7
- type L2Block,
8
- type L2BlockSource,
9
- type ProcessedTx,
10
- type Tx,
11
- } from '@aztec/circuit-types';
12
- import { asyncPool } from '@aztec/foundation/async-pool';
13
- import { createLogger } from '@aztec/foundation/log';
14
- import { promiseWithResolvers } from '@aztec/foundation/promise';
15
- import { Timer } from '@aztec/foundation/timer';
16
- import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator/server';
12
+ } from '@aztec/stdlib/interfaces/server';
13
+ import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
14
+ import type { ProcessedTx, Tx } from '@aztec/stdlib/tx';
17
15
  import { Attributes, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
18
16
 
19
17
  import * as crypto from 'node:crypto';
20
18
 
21
- import { type ProverNodeMetrics } from '../metrics.js';
22
- import { type ProverNodePublisher } from '../prover-node-publisher.js';
19
+ import type { ProverNodeMetrics } from '../metrics.js';
20
+ import type { ProverNodePublisher } from '../prover-node-publisher.js';
23
21
 
24
22
  /**
25
23
  * Job that grabs a range of blocks from the unfinalised chain from L1, gets their txs given their hashes,
package/src/metrics.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { type L1PublishProofStats, type L1PublishStats } from '@aztec/circuit-types/stats';
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import type { L1PublishProofStats, L1PublishStats } from '@aztec/stdlib/stats';
2
3
  import {
3
4
  Attributes,
5
+ type Gauge,
4
6
  type Histogram,
5
7
  Metrics,
6
8
  type TelemetryClient,
@@ -25,7 +27,13 @@ export class ProverNodeMetrics {
25
27
  txBlobDataGasUsed: Histogram;
26
28
  txBlobDataGasCost: Histogram;
27
29
 
28
- constructor(public readonly client: TelemetryClient, name = 'ProverNode') {
30
+ private senderBalance: Gauge;
31
+
32
+ constructor(
33
+ public readonly client: TelemetryClient,
34
+ name = 'ProverNode',
35
+ private logger = createLogger('prover-node:publisher:metrics'),
36
+ ) {
29
37
  const meter = client.getMeter(name);
30
38
  this.proverEpochExecutionDuration = meter.createHistogram(Metrics.PROVER_NODE_EXECUTION_DURATION, {
31
39
  description: 'Duration of execution of an epoch by the prover',
@@ -34,8 +42,8 @@ export class ProverNodeMetrics {
34
42
  });
35
43
  this.provingJobDuration = meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
36
44
  description: 'Duration of proving job',
37
- unit: 'ms',
38
- valueType: ValueType.INT,
45
+ unit: 's',
46
+ valueType: ValueType.DOUBLE,
39
47
  });
40
48
  this.provingJobBlocks = meter.createHistogram(Metrics.PROVER_NODE_JOB_BLOCKS, {
41
49
  description: 'Number of blocks in a proven epoch',
@@ -91,6 +99,12 @@ export class ProverNodeMetrics {
91
99
  unit: 'gwei',
92
100
  valueType: ValueType.INT,
93
101
  });
102
+
103
+ this.senderBalance = meter.createGauge(Metrics.L1_PUBLISHER_BALANCE, {
104
+ unit: 'eth',
105
+ description: 'The balance of the sender address',
106
+ valueType: ValueType.DOUBLE,
107
+ });
94
108
  }
95
109
 
96
110
  recordFailedTx() {
@@ -106,11 +120,18 @@ export class ProverNodeMetrics {
106
120
 
107
121
  public recordProvingJob(executionTimeMs: number, totalTimeMs: number, numBlocks: number, numTxs: number) {
108
122
  this.proverEpochExecutionDuration.record(Math.ceil(executionTimeMs));
109
- this.provingJobDuration.record(Math.ceil(totalTimeMs));
123
+ this.provingJobDuration.record(totalTimeMs / 1000);
110
124
  this.provingJobBlocks.record(Math.floor(numBlocks));
111
125
  this.provingJobTransactions.record(Math.floor(numTxs));
112
126
  }
113
127
 
128
+ public recordSenderBalance(wei: bigint, senderAddress: string) {
129
+ const eth = parseFloat(formatEther(wei, 'wei'));
130
+ this.senderBalance.record(eth, {
131
+ [Attributes.SENDER_ADDRESS]: senderAddress,
132
+ });
133
+ }
134
+
114
135
  private recordTx(durationMs: number, stats: L1PublishStats) {
115
136
  const attributes = {
116
137
  [Attributes.L1_TX_TYPE]: 'submitProof',
@@ -1,6 +1,7 @@
1
- import { type L2BlockSource } from '@aztec/circuit-types';
2
1
  import { createLogger } from '@aztec/foundation/log';
3
2
  import { RunningPromise } from '@aztec/foundation/running-promise';
3
+ import type { L2BlockSource } from '@aztec/stdlib/block';
4
+ import { type L1RollupConstants, getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
4
5
  import {
5
6
  type TelemetryClient,
6
7
  type Traceable,
@@ -10,20 +11,31 @@ import {
10
11
  } from '@aztec/telemetry-client';
11
12
 
12
13
  export interface EpochMonitorHandler {
13
- handleEpochCompleted(epochNumber: bigint): Promise<void>;
14
+ handleEpochReadyToProve(epochNumber: bigint): Promise<void>;
14
15
  }
15
16
 
17
+ /**
18
+ * Fires an event when a new epoch ready to prove is detected.
19
+ *
20
+ * We define an epoch as ready to prove when:
21
+ * - The epoch is complete
22
+ * - Its blocks have not been reorg'd out due to a missing L2 proof
23
+ * - Its first block is the immediate successor of the last proven block
24
+ *
25
+ * This class periodically hits the L2BlockSource.
26
+ * On start it will trigger the event for the last epoch ready to prove.
27
+ */
16
28
  export class EpochMonitor implements Traceable {
17
29
  private runningPromise: RunningPromise;
18
30
  private log = createLogger('prover-node:epoch-monitor');
19
31
  public readonly tracer: Tracer;
20
32
 
21
33
  private handler: EpochMonitorHandler | undefined;
22
-
23
34
  private latestEpochNumber: bigint | undefined;
24
35
 
25
36
  constructor(
26
37
  private readonly l2BlockSource: L2BlockSource,
38
+ private readonly l1Constants: Pick<L1RollupConstants, 'epochDuration'>,
27
39
  private options: { pollingIntervalMs: number },
28
40
  telemetry: TelemetryClient = getTelemetryClient(),
29
41
  ) {
@@ -31,12 +43,26 @@ export class EpochMonitor implements Traceable {
31
43
  this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.options.pollingIntervalMs);
32
44
  }
33
45
 
46
+ public static async create(
47
+ l2BlockSource: L2BlockSource,
48
+ options: { pollingIntervalMs: number },
49
+ telemetry: TelemetryClient = getTelemetryClient(),
50
+ ): Promise<EpochMonitor> {
51
+ const l1Constants = await l2BlockSource.getL1Constants();
52
+ return new EpochMonitor(l2BlockSource, l1Constants, options, telemetry);
53
+ }
54
+
34
55
  public start(handler: EpochMonitorHandler) {
35
56
  this.handler = handler;
36
57
  this.runningPromise.start();
37
58
  this.log.info('Started EpochMonitor', this.options);
38
59
  }
39
60
 
61
+ /** Exposed for testing */
62
+ public setHandler(handler: EpochMonitorHandler) {
63
+ this.handler = handler;
64
+ }
65
+
40
66
  public async stop() {
41
67
  await this.runningPromise.stop();
42
68
  this.log.info('Stopped EpochMonitor');
@@ -44,18 +70,37 @@ export class EpochMonitor implements Traceable {
44
70
 
45
71
  @trackSpan('EpochMonitor.work')
46
72
  public async work() {
47
- if (!this.latestEpochNumber) {
48
- const epochNumber = await this.l2BlockSource.getL2EpochNumber();
49
- if (epochNumber > 0n) {
50
- await this.handler?.handleEpochCompleted(epochNumber - 1n);
51
- }
52
- this.latestEpochNumber = epochNumber;
73
+ const { epochToProve, blockNumber, slotNumber } = await this.getEpochNumberToProve();
74
+ if (epochToProve === undefined) {
75
+ this.log.trace(`Next block to prove ${blockNumber} not yet mined`, { blockNumber });
76
+ return;
77
+ }
78
+ if (this.latestEpochNumber !== undefined && epochToProve <= this.latestEpochNumber) {
79
+ this.log.trace(`Epoch ${epochToProve} already processed`, { epochToProve, blockNumber, slotNumber });
53
80
  return;
54
81
  }
55
82
 
56
- if (await this.l2BlockSource.isEpochComplete(this.latestEpochNumber)) {
57
- await this.handler?.handleEpochCompleted(this.latestEpochNumber);
58
- this.latestEpochNumber += 1n;
83
+ const isCompleted = await this.l2BlockSource.isEpochComplete(epochToProve);
84
+ if (!isCompleted) {
85
+ this.log.trace(`Epoch ${epochToProve} is not complete`, { epochToProve, blockNumber, slotNumber });
86
+ return;
59
87
  }
88
+
89
+ this.log.debug(`Epoch ${epochToProve} is ready to be proven`);
90
+ await this.handler?.handleEpochReadyToProve(epochToProve);
91
+ this.latestEpochNumber = epochToProve;
92
+ }
93
+
94
+ private async getEpochNumberToProve() {
95
+ const lastBlockProven = await this.l2BlockSource.getProvenBlockNumber();
96
+ const firstBlockToProve = lastBlockProven + 1;
97
+ const firstBlockHeaderToProve = await this.l2BlockSource.getBlockHeader(firstBlockToProve);
98
+ if (!firstBlockHeaderToProve) {
99
+ return { epochToProve: undefined, blockNumber: firstBlockToProve };
100
+ }
101
+
102
+ const firstSlotOfEpochToProve = firstBlockHeaderToProve.getSlot();
103
+ const epochToProve = getEpochAtSlot(firstSlotOfEpochToProve, this.l1Constants);
104
+ return { epochToProve, blockNumber: firstBlockToProve, slotNumber: firstSlotOfEpochToProve };
60
105
  }
61
106
  }
@@ -1,21 +1,18 @@
1
- import { type ArchiveSource, type Archiver } from '@aztec/archiver';
1
+ import type { ArchiveSource, Archiver } from '@aztec/archiver';
2
2
  import { BBCircuitVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
3
- import {
4
- P2PClientType,
5
- type ProverCoordination,
6
- type WorldStateSynchronizer,
7
- createAztecNodeClient,
8
- getComponentsVersionsFromConfig,
9
- } from '@aztec/circuit-types';
10
- import { type EpochCache } from '@aztec/epoch-cache';
3
+ import type { EpochCache } from '@aztec/epoch-cache';
11
4
  import { createLogger } from '@aztec/foundation/log';
12
- import { type DataStoreConfig } from '@aztec/kv-store/config';
13
- import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks';
5
+ import type { DataStoreConfig } from '@aztec/kv-store/config';
6
+ import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
14
7
  import { createP2PClient } from '@aztec/p2p';
15
8
  import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
9
+ import { createAztecNodeClient } from '@aztec/stdlib/interfaces/client';
10
+ import type { ProverCoordination, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
11
+ import { P2PClientType } from '@aztec/stdlib/p2p';
12
+ import { getComponentsVersionsFromConfig } from '@aztec/stdlib/versioning';
16
13
  import { type TelemetryClient, makeTracedFetch } from '@aztec/telemetry-client';
17
14
 
18
- import { type ProverNodeConfig } from '../config.js';
15
+ import type { ProverNodeConfig } from '../config.js';
19
16
 
20
17
  // We return a reference to the P2P client so that the prover node can stop the service when it shuts down.
21
18
  type ProverCoordinationDeps = {
@@ -1,7 +1,5 @@
1
- import { type L1PublishProofStats } from '@aztec/circuit-types/stats';
2
- import { AGGREGATION_OBJECT_LENGTH, AZTEC_MAX_EPOCH_DURATION, type Proof } from '@aztec/circuits.js';
3
- import { type FeeRecipient, type RootRollupPublicInputs } from '@aztec/circuits.js/rollup';
4
- import { type L1TxUtils, type RollupContract } from '@aztec/ethereum';
1
+ import { AGGREGATION_OBJECT_LENGTH, AZTEC_MAX_EPOCH_DURATION } from '@aztec/constants';
2
+ import type { L1TxUtils, RollupContract } from '@aztec/ethereum';
5
3
  import { makeTuple } from '@aztec/foundation/array';
6
4
  import { areArraysEqual, times } from '@aztec/foundation/collection';
7
5
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -11,7 +9,10 @@ import { type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
11
9
  import { InterruptibleSleep } from '@aztec/foundation/sleep';
12
10
  import { Timer } from '@aztec/foundation/timer';
13
11
  import { RollupAbi } from '@aztec/l1-artifacts';
14
- import { type PublisherConfig, type TxSenderConfig } from '@aztec/sequencer-client';
12
+ import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
13
+ import type { Proof } from '@aztec/stdlib/proofs';
14
+ import type { FeeRecipient, RootRollupPublicInputs } from '@aztec/stdlib/rollup';
15
+ import type { L1PublishProofStats } from '@aztec/stdlib/stats';
15
16
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
16
17
 
17
18
  import { type Hex, type TransactionReceipt, encodeFunctionData } from 'viem';
@@ -105,6 +106,12 @@ export class ProverNodePublisher {
105
106
  return false;
106
107
  }
107
108
 
109
+ try {
110
+ this.metrics.recordSenderBalance(await this.l1TxUtils.getSenderBalance(), this.l1TxUtils.getSenderAddress());
111
+ } catch (err) {
112
+ this.log.warn(`Failed to record the ETH balance of the prover node: ${err}`);
113
+ }
114
+
108
115
  // Tx was mined successfully
109
116
  if (txReceipt.status) {
110
117
  const tx = await this.l1TxUtils.getTransactionStats(txReceipt.transactionHash);
@@ -251,15 +258,15 @@ export class ProverNodePublisher {
251
258
  return [
252
259
  BigInt(args.fromBlock),
253
260
  BigInt(args.toBlock),
254
- [
255
- args.publicInputs.previousArchive.root.toString(),
256
- args.publicInputs.endArchive.root.toString(),
257
- args.publicInputs.previousBlockHash.toString(),
258
- args.publicInputs.endBlockHash.toString(),
259
- args.publicInputs.endTimestamp.toString(),
260
- args.publicInputs.outHash.toString(),
261
- args.publicInputs.proverId.toString(),
262
- ],
261
+ {
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
+ },
263
270
  makeTuple(AZTEC_MAX_EPOCH_DURATION * 2, i =>
264
271
  i % 2 === 0
265
272
  ? args.publicInputs.fees[i / 2].recipient.toField().toString()
@@ -1,28 +1,26 @@
1
+ import { compact } from '@aztec/foundation/collection';
2
+ import { memoize } from '@aztec/foundation/decorators';
3
+ import { createLogger } from '@aztec/foundation/log';
4
+ import { RunningPromise } from '@aztec/foundation/running-promise';
5
+ import { DateProvider } from '@aztec/foundation/timer';
6
+ import type { Maybe } from '@aztec/foundation/types';
7
+ import type { P2P } from '@aztec/p2p';
8
+ import { PublicProcessorFactory } from '@aztec/simulator/server';
9
+ import type { L2Block, L2BlockSource } from '@aztec/stdlib/block';
10
+ import type { ContractDataSource } from '@aztec/stdlib/contract';
11
+ import { getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
1
12
  import {
2
13
  type EpochProverManager,
3
14
  EpochProvingJobTerminalState,
4
- type L1ToL2MessageSource,
5
- type L2Block,
6
- type L2BlockSource,
7
- type P2PClientType,
8
15
  type ProverCoordination,
9
16
  type ProverNodeApi,
10
17
  type Service,
11
- type Tx,
12
- type TxHash,
13
18
  type WorldStateSynchronizer,
14
- getTimestampRangeForEpoch,
15
19
  tryStop,
16
- } from '@aztec/circuit-types';
17
- import { type ContractDataSource } from '@aztec/circuits.js';
18
- import { compact } from '@aztec/foundation/collection';
19
- import { memoize } from '@aztec/foundation/decorators';
20
- import { createLogger } from '@aztec/foundation/log';
21
- import { RunningPromise } from '@aztec/foundation/running-promise';
22
- import { DateProvider } from '@aztec/foundation/timer';
23
- import { type Maybe } from '@aztec/foundation/types';
24
- import { type P2P } from '@aztec/p2p';
25
- import { PublicProcessorFactory } from '@aztec/simulator/server';
20
+ } from '@aztec/stdlib/interfaces/server';
21
+ import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
22
+ import type { P2PClientType } from '@aztec/stdlib/p2p';
23
+ import type { Tx, TxHash } from '@aztec/stdlib/tx';
26
24
  import {
27
25
  Attributes,
28
26
  type TelemetryClient,
@@ -34,8 +32,8 @@ import {
34
32
 
35
33
  import { EpochProvingJob, type EpochProvingJobState } from './job/epoch-proving-job.js';
36
34
  import { ProverNodeMetrics } from './metrics.js';
37
- import { type EpochMonitor, type EpochMonitorHandler } from './monitors/epoch-monitor.js';
38
- import { type ProverNodePublisher } from './prover-node-publisher.js';
35
+ import type { EpochMonitor, EpochMonitorHandler } from './monitors/epoch-monitor.js';
36
+ import type { ProverNodePublisher } from './prover-node-publisher.js';
39
37
 
40
38
  export type ProverNodeOptions = {
41
39
  pollingIntervalMs: number;
@@ -94,6 +92,10 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
94
92
  this.txFetcher = new RunningPromise(() => this.checkForTxs(), this.log, this.options.txGatheringIntervalMs);
95
93
  }
96
94
 
95
+ public getProverId() {
96
+ return this.prover.getProverId();
97
+ }
98
+
97
99
  public getP2P() {
98
100
  const asP2PClient = this.coordination as P2P<P2PClientType.Prover>;
99
101
  if (typeof asP2PClient.isP2PClient === 'function' && asP2PClient.isP2PClient()) {
@@ -106,7 +108,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
106
108
  * Handles an epoch being completed by starting a proof for it if there are no active jobs for it.
107
109
  * @param epochNumber - The epoch number that was just completed.
108
110
  */
109
- async handleEpochCompleted(epochNumber: bigint): Promise<void> {
111
+ async handleEpochReadyToProve(epochNumber: bigint): Promise<void> {
110
112
  try {
111
113
  this.log.debug('jobs', JSON.stringify(this.jobs, null, 2));
112
114
  const activeJobs = await this.getActiveJobsForEpoch(epochNumber);
@@ -216,7 +218,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
216
218
 
217
219
  // Fast forward world state to right before the target block and get a fork
218
220
  this.log.verbose(`Creating proving job for epoch ${epochNumber} for block range ${fromBlock} to ${toBlock}`);
219
- await this.worldState.syncImmediate(fromBlock - 1);
221
+ await this.worldState.syncImmediate(toBlock);
220
222
 
221
223
  // Create a processor using the forked world state
222
224
  const publicProcessorFactory = new PublicProcessorFactory(
@@ -253,7 +255,7 @@ export class ProverNode implements EpochMonitorHandler, ProverNodeApi, Traceable
253
255
  return;
254
256
  }
255
257
  const txHashes = block.body.txEffects.map(tx => tx.txHash);
256
- this.log.verbose(`Fetching ${txHashes.length} for block number ${blockNumber} from coordination`);
258
+ this.log.verbose(`Fetching ${txHashes.length} tx hashes for block number ${blockNumber} from coordination`);
257
259
  await this.coordination.getTxsByHash(txHashes); // This stores the txs in the tx pool, no need to persist them here
258
260
  this.lastBlockNumber = blockNumber;
259
261
  }
package/src/test/index.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { type EpochProverManager } from '@aztec/circuit-types';
1
+ import type { EpochProverManager } from '@aztec/stdlib/interfaces/server';
2
2
 
3
- import { type ProverNodePublisher } from '../prover-node-publisher.js';
3
+ import type { ProverNodePublisher } from '../prover-node-publisher.js';
4
4
  import { ProverNode } from '../prover-node.js';
5
5
 
6
6
  class TestProverNode_ extends ProverNode {