Skip to content

Commit c995f52

Browse files
committed
feat(prover-client): existing prover agents handle BLOCK_EXECUTION via a composite prover
Drops the separate `InternalExecutionAgents` agent pool added in Issue 7 and replaces it with a single composite `ServerCircuitProver` shared by the existing prover-client agents. One agent count, one polling loop, one allowlist — the broker hands jobs to whichever agent is free and the composite dispatches internally: - Proving methods (`getAvmProof`, `getPrivateTxBaseRollupProof`, parity, merge, block-root, etc.) delegate to the regular prover (`BBNativeRollupProver` or `TestCircuitProver`). - `executeBlock` delegates to a `BlockExecutionHandler` instance constructed against the supplied world state, public processor factory and tx fetcher. Wiring: - `ProverClient.new(...)` and `createProverClient(...)` take an optional `ProverClientBlockExecutionDeps` (`publicProcessorFactory + txFetcher`). When supplied, every agent gets the composite. When absent, agents stay proving-only and `executeBlock` rejects. - The prover node factory now always supplies these deps (it has every ingredient already — archiver, world state synchronizer, p2p client). No new config switch — execution capability is automatic when the prover node has the prerequisites. - `proverAgentCount` continues to control the agent count. There is no second pool. Removes: - `InternalExecutionAgents` class + its test. - `proverNodeExecutionAgentCount` / `proverNodeExecutionAgentPollIntervalMs` config and the matching env vars. - The optional `internalExecutionAgents` constructor arg on `ProverNode` and the corresponding start/stop calls. Adds a small unit test exercising the composite's dispatch behaviour.
1 parent 5930089 commit c995f52

12 files changed

Lines changed: 222 additions & 276 deletions

File tree

yarn-project/foundation/src/config/env_var.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,6 @@ export type EnvVar =
187187
| 'PROVER_NODE_TX_GATHERING_BATCH_SIZE'
188188
| 'PROVER_NODE_TX_GATHERING_MAX_PARALLEL_REQUESTS_PER_NODE'
189189
| 'PROVER_NODE_TX_GATHERING_TIMEOUT_MS'
190-
| 'PROVER_NODE_EXECUTION_AGENT_COUNT'
191-
| 'PROVER_NODE_EXECUTION_AGENT_POLL_INTERVAL_MS'
192190
| 'PROVER_PUBLISHER_PRIVATE_KEY'
193191
| 'PROVER_PUBLISHER_PRIVATE_KEYS'
194192
| 'PROVER_PUBLISHER_ADDRESSES'
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import type { ServerCircuitProver } from '@aztec/stdlib/interfaces/server';
2+
3+
import { jest } from '@jest/globals';
4+
import { type MockProxy, mock } from 'jest-mock-extended';
5+
6+
import { CompositeServerCircuitProver } from './composite_circuit_prover.js';
7+
8+
describe('CompositeServerCircuitProver', () => {
9+
let base: MockProxy<ServerCircuitProver>;
10+
let execution: MockProxy<ServerCircuitProver>;
11+
let composite: CompositeServerCircuitProver;
12+
13+
beforeEach(() => {
14+
base = mock<ServerCircuitProver>();
15+
execution = mock<ServerCircuitProver>();
16+
composite = new CompositeServerCircuitProver(base, execution);
17+
});
18+
19+
it('routes proving methods to the base prover', async () => {
20+
base.getAvmProof.mockResolvedValue('avm' as unknown as Awaited<ReturnType<ServerCircuitProver['getAvmProof']>>);
21+
base.getBaseParityProof.mockResolvedValue(
22+
'parity' as unknown as Awaited<ReturnType<ServerCircuitProver['getBaseParityProof']>>,
23+
);
24+
25+
await composite.getAvmProof({} as any);
26+
await composite.getBaseParityProof({} as any);
27+
28+
expect(base.getAvmProof).toHaveBeenCalledTimes(1);
29+
expect(base.getBaseParityProof).toHaveBeenCalledTimes(1);
30+
expect(execution.getAvmProof).not.toHaveBeenCalled();
31+
expect(execution.getBaseParityProof).not.toHaveBeenCalled();
32+
});
33+
34+
it('routes executeBlock to the execution prover', async () => {
35+
execution.executeBlock.mockResolvedValue(
36+
'block-execution-result' as unknown as Awaited<ReturnType<ServerCircuitProver['executeBlock']>>,
37+
);
38+
39+
await composite.executeBlock({} as any);
40+
41+
expect(execution.executeBlock).toHaveBeenCalledTimes(1);
42+
expect(base.executeBlock).not.toHaveBeenCalled();
43+
});
44+
45+
it('falls back to the base prover for executeBlock when no execution prover is supplied', async () => {
46+
const fallback = new CompositeServerCircuitProver(base);
47+
base.executeBlock.mockRejectedValue(new Error('not supported'));
48+
49+
await expect(fallback.executeBlock({} as any)).rejects.toThrow(/not supported/);
50+
expect(base.executeBlock).toHaveBeenCalledTimes(1);
51+
});
52+
53+
it('preserves rejection from the underlying prover', async () => {
54+
base.getRootRollupProof.mockRejectedValue(new Error('boom'));
55+
56+
await expect(composite.getRootRollupProof({} as any)).rejects.toThrow('boom');
57+
});
58+
59+
it('forwards multiple arguments through to the underlying prover', async () => {
60+
base.getAvmProof.mockResolvedValue('avm' as any);
61+
62+
const inputs = {} as any;
63+
const signal = new AbortController().signal;
64+
const epochNumber = 5;
65+
await composite.getAvmProof(inputs, signal, epochNumber);
66+
67+
expect(base.getAvmProof).toHaveBeenCalledWith(inputs, signal, epochNumber);
68+
});
69+
});
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import type { ServerCircuitProver } from '@aztec/stdlib/interfaces/server';
2+
3+
/**
4+
* `ServerCircuitProver` that composes a "base" prover for circuit-proving methods
5+
* with an execution prover for `executeBlock`. Used so a single `ProvingAgent`
6+
* can take any kind of job from the broker — proving jobs route to the base
7+
* prover, `BLOCK_EXECUTION` jobs route to the execution handler.
8+
*
9+
* Every method other than `executeBlock` delegates to the base prover. If the
10+
* caller does not provide an execution prover, `executeBlock` falls back to the
11+
* base prover (which rejects).
12+
*/
13+
export class CompositeServerCircuitProver implements ServerCircuitProver {
14+
constructor(
15+
private readonly base: ServerCircuitProver,
16+
private readonly execution: ServerCircuitProver = base,
17+
) {}
18+
19+
// --- Proving methods: delegate to base ---
20+
public getBaseParityProof: ServerCircuitProver['getBaseParityProof'] = (...args) =>
21+
this.base.getBaseParityProof(...args);
22+
public getRootParityProof: ServerCircuitProver['getRootParityProof'] = (...args) =>
23+
this.base.getRootParityProof(...args);
24+
public getPublicChonkVerifierProof: ServerCircuitProver['getPublicChonkVerifierProof'] = (...args) =>
25+
this.base.getPublicChonkVerifierProof(...args);
26+
public getPrivateTxBaseRollupProof: ServerCircuitProver['getPrivateTxBaseRollupProof'] = (...args) =>
27+
this.base.getPrivateTxBaseRollupProof(...args);
28+
public getPublicTxBaseRollupProof: ServerCircuitProver['getPublicTxBaseRollupProof'] = (...args) =>
29+
this.base.getPublicTxBaseRollupProof(...args);
30+
public getTxMergeRollupProof: ServerCircuitProver['getTxMergeRollupProof'] = (...args) =>
31+
this.base.getTxMergeRollupProof(...args);
32+
public getBlockRootFirstRollupProof: ServerCircuitProver['getBlockRootFirstRollupProof'] = (...args) =>
33+
this.base.getBlockRootFirstRollupProof(...args);
34+
public getBlockRootSingleTxFirstRollupProof: ServerCircuitProver['getBlockRootSingleTxFirstRollupProof'] = (
35+
...args
36+
) => this.base.getBlockRootSingleTxFirstRollupProof(...args);
37+
public getBlockRootEmptyTxFirstRollupProof: ServerCircuitProver['getBlockRootEmptyTxFirstRollupProof'] = (...args) =>
38+
this.base.getBlockRootEmptyTxFirstRollupProof(...args);
39+
public getBlockRootRollupProof: ServerCircuitProver['getBlockRootRollupProof'] = (...args) =>
40+
this.base.getBlockRootRollupProof(...args);
41+
public getBlockRootSingleTxRollupProof: ServerCircuitProver['getBlockRootSingleTxRollupProof'] = (...args) =>
42+
this.base.getBlockRootSingleTxRollupProof(...args);
43+
public getBlockMergeRollupProof: ServerCircuitProver['getBlockMergeRollupProof'] = (...args) =>
44+
this.base.getBlockMergeRollupProof(...args);
45+
public getCheckpointRootRollupProof: ServerCircuitProver['getCheckpointRootRollupProof'] = (...args) =>
46+
this.base.getCheckpointRootRollupProof(...args);
47+
public getCheckpointRootSingleBlockRollupProof: ServerCircuitProver['getCheckpointRootSingleBlockRollupProof'] = (
48+
...args
49+
) => this.base.getCheckpointRootSingleBlockRollupProof(...args);
50+
public getCheckpointPaddingRollupProof: ServerCircuitProver['getCheckpointPaddingRollupProof'] = (...args) =>
51+
this.base.getCheckpointPaddingRollupProof(...args);
52+
public getCheckpointMergeRollupProof: ServerCircuitProver['getCheckpointMergeRollupProof'] = (...args) =>
53+
this.base.getCheckpointMergeRollupProof(...args);
54+
public getRootRollupProof: ServerCircuitProver['getRootRollupProof'] = (...args) =>
55+
this.base.getRootRollupProof(...args);
56+
public getAvmProof: ServerCircuitProver['getAvmProof'] = (...args) => this.base.getAvmProof(...args);
57+
58+
// --- Block execution: delegate to execution prover ---
59+
public executeBlock: ServerCircuitProver['executeBlock'] = (...args) => this.execution.executeBlock(...args);
60+
}
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
1+
import type { PublicProcessorFactory } from '@aztec/simulator/server';
2+
3+
import type { TxFetcher } from './block_execution_handler.js';
4+
15
export { BlockExecutionHandler, type TxFetcher } from './block_execution_handler.js';
2-
export { InternalExecutionAgents, type InternalExecutionAgentsConfig } from './internal_execution_agents.js';
6+
export { CompositeServerCircuitProver } from './composite_circuit_prover.js';
7+
8+
/**
9+
* Optional dependencies the prover-client needs to run BLOCK_EXECUTION jobs in its
10+
* agents. When provided, every agent the prover-client spins up gets a composite
11+
* `ServerCircuitProver` that handles BLOCK_EXECUTION via a `BlockExecutionHandler`
12+
* and routes everything else to the regular proving prover.
13+
*/
14+
export type ProverClientBlockExecutionDeps = {
15+
publicProcessorFactory: PublicProcessorFactory;
16+
txFetcher: TxFetcher;
17+
};

yarn-project/prover-client/src/block_execution/internal_execution_agents.test.ts

Lines changed: 0 additions & 103 deletions
This file was deleted.

yarn-project/prover-client/src/block_execution/internal_execution_agents.ts

Lines changed: 0 additions & 94 deletions
This file was deleted.

yarn-project/prover-client/src/prover-client/factory.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
} from '@aztec/stdlib/interfaces/server';
66
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
77

8+
import type { ProverClientBlockExecutionDeps } from '../block_execution/index.js';
89
import type { ProverClientConfig } from '../config.js';
910
import { ProverClient } from './prover-client.js';
1011

@@ -13,6 +14,7 @@ export function createProverClient(
1314
worldState: ForkMerkleTreeOperations & ReadonlyWorldStateAccess,
1415
broker: ProvingJobBroker,
1516
telemetry: TelemetryClient = getTelemetryClient(),
17+
blockExecutionDeps?: ProverClientBlockExecutionDeps,
1618
) {
17-
return ProverClient.new(config, worldState, broker, telemetry);
19+
return ProverClient.new(config, worldState, broker, telemetry, blockExecutionDeps);
1820
}

0 commit comments

Comments
 (0)