Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions yarn-project/aztec-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"@aztec/p2p": "workspace:^",
"@aztec/protocol-contracts": "workspace:^",
"@aztec/prover-client": "workspace:^",
"@aztec/prover-node": "workspace:^",
"@aztec/sequencer-client": "workspace:^",
"@aztec/simulator": "workspace:^",
"@aztec/slasher": "workspace:^",
Expand Down
14 changes: 7 additions & 7 deletions yarn-project/aztec-node/src/aztec-node/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EthAddress } from '@aztec/foundation/eth-address';
import type { EthPrivateKey } from '@aztec/node-keystore';
import type { SharedNodeConfig } from '@aztec/node-lib/config';
import type { SequencerClientConfig, TxSenderConfig } from '@aztec/sequencer-client/config';
import type { SequencerClientConfig, SequencerTxSenderConfig } from '@aztec/sequencer-client/config';
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import type { ValidatorClientConfig } from '@aztec/validator-client/config';

Expand Down Expand Up @@ -33,7 +33,7 @@ describe('createKeyStoreForValidator', () => {
web3SignerUrl?: string,
validatorAddresses: EthAddress[] = [],
publisherAddresses: EthAddress[] = [],
): TxSenderConfig & ValidatorClientConfig & SequencerClientConfig & SharedNodeConfig => {
): SequencerTxSenderConfig & ValidatorClientConfig & SequencerClientConfig & SharedNodeConfig => {
const mockValidatorPrivateKeys =
validatorKeys.length > 0
? {
Expand All @@ -46,14 +46,14 @@ describe('createKeyStoreForValidator', () => {

return {
validatorPrivateKeys: mockValidatorPrivateKeys,
publisherPrivateKeys: mockPublisherPrivateKeys,
sequencerPublisherPrivateKeys: mockPublisherPrivateKeys,
coinbase: coinbase,
feeRecipient: feeRecipient,
web3SignerUrl,
validatorAddresses: validatorAddresses.map(addr => addr),
publisherAddresses: publisherAddresses.map(addr => addr),
sequencerPublisherAddresses: publisherAddresses.map(addr => addr),
l1Contracts: { rollupAddress: EthAddress.random() },
} as TxSenderConfig & ValidatorClientConfig & SequencerClientConfig & SharedNodeConfig;
} as SequencerTxSenderConfig & ValidatorClientConfig & SequencerClientConfig & SharedNodeConfig;
};

beforeAll(async () => {
Expand All @@ -69,11 +69,11 @@ describe('createKeyStoreForValidator', () => {
it('should return undefined when validatorPrivateKeys is undefined', () => {
const config = {
validatorPrivateKeys: undefined,
publisherPrivateKeys: undefined,
sequencerPublisherPrivateKeys: undefined,
coinbase: undefined,
feeRecipient: undefined,
l1Contracts: { rollupAddress: EthAddress.random() },
} as unknown as TxSenderConfig & ValidatorClientConfig & SequencerClientConfig & SharedNodeConfig;
} as unknown as SequencerTxSenderConfig & ValidatorClientConfig & SequencerClientConfig & SharedNodeConfig;
const result = createKeyStoreForValidator(config);
expect(result).toBeUndefined();
});
Expand Down
32 changes: 24 additions & 8 deletions yarn-project/aztec-node/src/aztec-node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ import {
import { type SharedNodeConfig, sharedNodeConfigMappings } from '@aztec/node-lib/config';
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
import { type ProverClientUserConfig, proverClientConfigMappings } from '@aztec/prover-client/config';
import {
type ProverNodeConfig,
proverNodeConfigMappings,
specificProverNodeConfigMappings,
} from '@aztec/prover-node/config';
import {
type SequencerClientConfig,
type TxSenderConfig,
type SequencerTxSenderConfig,
sequencerClientConfigMappings,
} from '@aztec/sequencer-client/config';
import { slasherConfigMappings } from '@aztec/slasher';
Expand Down Expand Up @@ -46,23 +51,26 @@ export type AztecNodeConfig = ArchiverConfig &
SharedNodeConfig &
GenesisStateConfig &
NodeRPCConfig &
SlasherConfig & {
SlasherConfig &
ProverNodeConfig & {
/** L1 contracts addresses */
l1Contracts: L1ContractAddresses;
/** Whether the validator is disabled for this node */
disableValidator: boolean;
/** Whether to skip waiting for the archiver to be fully synced before starting other services */
skipArchiverInitialSync: boolean;

/** A flag to force verification of tx Chonk proofs. Only used for testnet */
debugForceTxProofVerification: boolean;
/** Whether to enable the prover node as a subsystem. */
enableProverNode: boolean;
};

export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
...dataConfigMappings,
...keyStoreConfigMappings,
...archiverConfigMappings,
...sequencerClientConfigMappings,
...proverNodeConfigMappings,
...validatorClientConfigMappings,
...proverClientConfigMappings,
...worldStateConfigMappings,
Expand All @@ -72,6 +80,7 @@ export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
...genesisStateConfigMappings,
...nodeRpcConfigMappings,
...slasherConfigMappings,
...specificProverNodeConfigMappings,
l1Contracts: {
description: 'The deployed L1 contract addresses',
nested: l1ContractAddressesMapping,
Expand All @@ -91,6 +100,11 @@ export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
description: 'Whether to skip waiting for the archiver to be fully synced before starting other services.',
...booleanConfigHelper(false),
},
enableProverNode: {
env: 'ENABLE_PROVER_NODE',
description: 'Whether to enable the prover node as a subsystem.',
...booleanConfigHelper(false),
},
};

/**
Expand All @@ -101,7 +115,7 @@ export function getConfigEnvVars(): AztecNodeConfig {
return getConfigFromMappings<AztecNodeConfig>(aztecNodeConfigMappings);
}

type ConfigRequiredToBuildKeyStore = TxSenderConfig & SequencerClientConfig & SharedNodeConfig & ValidatorClientConfig;
type ConfigRequiredToBuildKeyStore = SequencerClientConfig & SharedNodeConfig & ValidatorClientConfig;

function createKeyStoreFromWeb3Signer(config: ConfigRequiredToBuildKeyStore): KeyStore | undefined {
const validatorKeyStores: ValidatorKeyStore[] = [];
Expand All @@ -120,7 +134,7 @@ function createKeyStoreFromWeb3Signer(config: ConfigRequiredToBuildKeyStore): Ke
feeRecipient: config.feeRecipient ?? AztecAddress.ZERO,
coinbase: config.coinbase ?? config.validatorAddresses[0],
remoteSigner: config.web3SignerUrl,
publisher: config.publisherAddresses ?? [],
publisher: config.sequencerPublisherAddresses ?? [],
});

const keyStore: KeyStore = {
Expand All @@ -145,8 +159,10 @@ function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore): K
const coinbase = config.coinbase ?? EthAddress.fromString(privateKeyToAddress(ethPrivateKeys[0]));
const feeRecipient = config.feeRecipient ?? AztecAddress.ZERO;

const publisherKeys = config.publisherPrivateKeys
? config.publisherPrivateKeys.map((k: { getValue: () => string }) => ethPrivateKeySchema.parse(k.getValue()))
const publisherKeys = config.sequencerPublisherPrivateKeys
? config.sequencerPublisherPrivateKeys.map((k: { getValue: () => string }) =>
ethPrivateKeySchema.parse(k.getValue()),
)
: [];

validatorKeyStores.push({
Expand All @@ -168,7 +184,7 @@ function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore): K
}

export function createKeyStoreForValidator(
config: TxSenderConfig & SequencerClientConfig & SharedNodeConfig,
config: SequencerTxSenderConfig & SequencerClientConfig & SharedNodeConfig,
): KeyStore | undefined {
if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
return createKeyStoreFromWeb3Signer(config);
Expand Down
1 change: 1 addition & 0 deletions yarn-project/aztec-node/src/aztec-node/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ describe('aztec node', () => {
undefined,
undefined,
undefined,
undefined,
12345,
rollupVersion.toNumber(),
globalVariablesBuilder,
Expand Down
70 changes: 58 additions & 12 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ import { type Logger, createLogger } from '@aztec/foundation/log';
import { count } from '@aztec/foundation/string';
import { DateProvider, Timer } from '@aztec/foundation/timer';
import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
import { type KeyStore, KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
import { createForwarderL1TxUtilsFromSigners, createL1TxUtilsFromSigners } from '@aztec/node-lib/factories';
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
import { type ProverNode, type ProverNodeDeps, createProverNode } from '@aztec/prover-node';
import { createKeyStoreForProver } from '@aztec/prover-node/config';
import { GlobalVariableBuilder, SequencerClient, type SequencerPublisher } from '@aztec/sequencer-client';
import { PublicProcessorFactory } from '@aztec/simulator/server';
import {
Expand Down Expand Up @@ -134,6 +136,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
protected readonly l1ToL2MessageSource: L1ToL2MessageSource,
protected readonly worldStateSynchronizer: WorldStateSynchronizer,
protected readonly sequencer: SequencerClient | undefined,
protected readonly proverNode: ProverNode | undefined,
protected readonly slasherClient: SlasherClientInterface | undefined,
protected readonly validatorsSentinel: Sentinel | undefined,
protected readonly epochPruneWatcher: EpochPruneWatcher | undefined,
Expand Down Expand Up @@ -176,10 +179,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
publisher?: SequencerPublisher;
dateProvider?: DateProvider;
p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
proverNodeDeps?: Partial<ProverNodeDeps>;
} = {},
options: {
prefilledPublicData?: PublicDataTreeLeaf[];
dontStartSequencer?: boolean;
dontStartProverNode?: boolean;
} = {},
): Promise<AztecNodeService> {
const config = { ...inputConfig }; // Copy the config so we dont mutate the input object
Expand All @@ -189,16 +194,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
const dateProvider = deps.dateProvider ?? new DateProvider();
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);

// Build a key store from file if given or from environment otherwise
// Build a key store from file if given or from environment otherwise.
// We keep the raw KeyStore available so we can merge with prover keys if enableProverNode is set.
let keyStoreManager: KeystoreManager | undefined;
const keyStoreProvided = config.keyStoreDirectory !== undefined && config.keyStoreDirectory.length > 0;
if (keyStoreProvided) {
const keyStores = loadKeystores(config.keyStoreDirectory!);
keyStoreManager = new KeystoreManager(mergeKeystores(keyStores));
} else {
const keyStore = createKeyStoreForValidator(config);
if (keyStore) {
keyStoreManager = new KeystoreManager(keyStore);
const rawKeyStores: KeyStore[] = [];
const validatorKeyStore = createKeyStoreForValidator(config);
if (validatorKeyStore) {
rawKeyStores.push(validatorKeyStore);
}
if (config.enableProverNode) {
const proverKeyStore = createKeyStoreForProver(config);
if (proverKeyStore) {
rawKeyStores.push(proverKeyStore);
}
}
if (rawKeyStores.length > 0) {
keyStoreManager = new KeystoreManager(
rawKeyStores.length === 1 ? rawKeyStores[0] : mergeKeystores(rawKeyStores),
);
}
}

Expand All @@ -209,10 +227,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
if (keyStoreManager === undefined) {
throw new Error('Failed to create key store, a requirement for running a validator');
}
if (!keyStoreProvided) {
log.warn(
'KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS',
);
if (!keyStoreProvided && process.env.NODE_ENV !== 'test') {
log.warn("Keystore created from env: it's recommended to use a file-based key store for production");
}
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager, log);
}
Expand Down Expand Up @@ -254,7 +270,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
);
}

const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
const blobClient = await createBlobClientWithFileStores(config, log.createChild('blob-client'));

// attempt snapshot sync if possible
await trySnapshotSync(config, log);
Expand Down Expand Up @@ -417,11 +433,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
);
await slasherClient.start();

const l1TxUtils = config.publisherForwarderAddress
const l1TxUtils = config.sequencerPublisherForwarderAddress
? await createForwarderL1TxUtilsFromSigners(
publicClient,
keyStoreManager!.createAllValidatorPublisherSigners(),
config.publisherForwarderAddress,
config.sequencerPublisherForwarderAddress,
{ ...config, scope: 'sequencer' },
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider, kzg: Blob.getViemKzgInstance() },
)
Expand Down Expand Up @@ -466,6 +482,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
log.warn(`Sequencer created but not started`);
}

// Create prover node subsystem if enabled
let proverNode: ProverNode | undefined;
if (config.enableProverNode) {
proverNode = await createProverNode(config, {
...deps.proverNodeDeps,
telemetry,
dateProvider,
archiver,
worldStateSynchronizer,
p2pClient,
epochCache,
blobClient,
keyStoreManager,
});

if (!options.dontStartProverNode) {
await proverNode.start();
log.info(`Prover node subsystem started`);
} else {
log.info(`Prover node subsystem created but not started`);
}
}

const globalVariableBuilder = new GlobalVariableBuilder({
...config,
rollupVersion: BigInt(config.rollupVersion),
Expand All @@ -482,6 +521,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
archiver,
worldStateSynchronizer,
sequencer,
proverNode,
slasherClient,
validatorsSentinel,
epochPruneWatcher,
Expand All @@ -507,6 +547,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
return this.sequencer;
}

/** Returns the prover node subsystem, if enabled. */
public getProverNode(): ProverNode | undefined {
return this.proverNode;
}

public getBlockSource(): L2BlockSource {
return this.blockSource;
}
Expand Down Expand Up @@ -810,6 +855,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
await tryStop(this.slasherClient);
await tryStop(this.proofVerifier);
await tryStop(this.sequencer);
await tryStop(this.proverNode);
await tryStop(this.p2pClient);
await tryStop(this.worldStateSynchronizer);
await tryStop(this.blockSource);
Expand Down
3 changes: 3 additions & 0 deletions yarn-project/aztec-node/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@
{
"path": "../prover-client"
},
{
"path": "../prover-node"
},
{
"path": "../sequencer-client"
},
Expand Down
8 changes: 5 additions & 3 deletions yarn-project/aztec/src/cli/aztec_start_action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
signalHandlers.push(stop);
services.node = [node, AztecNodeApiSchema];
} else {
// Route --prover-node through startNode
if (options.proverNode && !options.node) {
options.node = true;
}

if (options.node) {
const { startNode } = await import('./cmds/start_node.js');
({ config } = await startNode(options, signalHandlers, services, adminServices, userLog));
} else if (options.bot) {
const { startBot } = await import('./cmds/start_bot.js');
await startBot(options, signalHandlers, services, userLog);
} else if (options.proverNode) {
const { startProverNode } = await import('./cmds/start_prover_node.js');
({ config } = await startProverNode(options, signalHandlers, services, userLog));
} else if (options.archiver) {
const { startArchiver } = await import('./cmds/start_archiver.js');
({ config } = await startArchiver(options, signalHandlers, services));
Expand Down
4 changes: 0 additions & 4 deletions yarn-project/aztec/src/cli/aztec_start_options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,8 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
'proverNode',
omitConfigMappings(proverNodeConfigMappings, [
// filter out options passed separately
...getKeys(archiverConfigMappings),
...getKeys(proverBrokerConfigMappings),
...getKeys(proverAgentConfigMappings),
...getKeys(p2pConfigMappings),
...getKeys(worldStateConfigMappings),
...getKeys(sharedNodeConfigMappings),
]),
),
],
Expand Down
Loading
Loading