@aztec/validator-client 3.0.0-nightly.20250905 → 4.0.0-nightly.20250907

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.
package/dest/config.d.ts CHANGED
@@ -1,22 +1,6 @@
1
- import { type ConfigMappingsType, type SecretValue } from '@aztec/foundation/config';
2
- import { EthAddress } from '@aztec/foundation/eth-address';
3
- /**
4
- * The Validator Configuration
5
- */
6
- export interface ValidatorClientConfig {
7
- /** The private keys of the validators participating in attestation duties */
8
- validatorPrivateKeys?: SecretValue<`0x${string}`[]>;
9
- /** The addresses of the validators to use with remote signers */
10
- validatorAddresses?: EthAddress[];
11
- /** Do not run the validator */
12
- disableValidator: boolean;
13
- /** Interval between polling for new attestations from peers */
14
- attestationPollingIntervalMs: number;
15
- /** Re-execute transactions before attesting */
16
- validatorReexecute: boolean;
17
- /** Will re-execute until this many milliseconds are left in the slot */
18
- validatorReexecuteDeadlineMs: number;
19
- }
1
+ import { type ConfigMappingsType } from '@aztec/foundation/config';
2
+ import type { ValidatorClientConfig } from '@aztec/stdlib/interfaces/server';
3
+ export type { ValidatorClientConfig };
20
4
  export declare const validatorClientConfigMappings: ConfigMappingsType<ValidatorClientConfig>;
21
5
  /**
22
6
  * Returns the prover configuration from the environment variables.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAKjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,WAAW,CAAC,KAAK,MAAM,EAAE,EAAE,CAAC,CAAC;IAEpD,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,UAAU,EAAE,CAAC;IAElC,+BAA+B;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAE1B,+DAA+D;IAC/D,4BAA4B,EAAE,MAAM,CAAC;IAErC,+CAA+C;IAC/C,kBAAkB,EAAE,OAAO,CAAC;IAE5B,wEAAwE;IACxE,4BAA4B,EAAE,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CAkCnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CAgDnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
package/dest/config.js CHANGED
@@ -12,12 +12,18 @@ export const validatorClientConfigMappings = {
12
12
  validatorAddresses: {
13
13
  env: 'VALIDATOR_ADDRESSES',
14
14
  description: 'List of addresses of the validators to use with remote signers',
15
- parseEnv: (val)=>val.split(',').map((address)=>EthAddress.fromString(address))
15
+ parseEnv: (val)=>val.split(',').filter((address)=>address && address.trim().length > 0).map((address)=>EthAddress.fromString(address.trim())),
16
+ defaultValue: []
16
17
  },
17
18
  disableValidator: {
18
19
  env: 'VALIDATOR_DISABLED',
19
20
  description: 'Do not run the validator',
20
- ...booleanConfigHelper()
21
+ ...booleanConfigHelper(false)
22
+ },
23
+ disabledValidators: {
24
+ description: 'Temporarily disable these specific validator addresses',
25
+ parseEnv: (val)=>val.split(',').filter((address)=>address && address.trim().length > 0).map((address)=>EthAddress.fromString(address.trim())),
26
+ defaultValue: []
21
27
  },
22
28
  attestationPollingIntervalMs: {
23
29
  env: 'VALIDATOR_ATTESTATIONS_POLLING_INTERVAL_MS',
@@ -8,7 +8,7 @@ import { TxProvider } from '@aztec/p2p';
8
8
  import { type SlasherConfig, type Watcher, type WatcherEmitter } from '@aztec/slasher';
9
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
10
10
  import type { L2BlockSource } from '@aztec/stdlib/block';
11
- import type { IFullNodeBlockBuilder, SequencerConfig } from '@aztec/stdlib/interfaces/server';
11
+ import type { IFullNodeBlockBuilder, Validator, ValidatorClientFullConfig } from '@aztec/stdlib/interfaces/server';
12
12
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
13
13
  import type { BlockAttestation, BlockProposal, BlockProposalOptions } from '@aztec/stdlib/p2p';
14
14
  import { type ProposedBlockHeader, type StateReference, type Tx } from '@aztec/stdlib/tx';
@@ -16,14 +16,6 @@ import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
16
16
  import type { TypedDataDefinition } from 'viem';
17
17
  import type { ValidatorClientConfig } from './config.js';
18
18
  import { NodeKeystoreAdapter } from './key_store/node_keystore_adapter.js';
19
- export interface Validator {
20
- start(): Promise<void>;
21
- registerBlockProposalHandler(): void;
22
- createBlockProposal(blockNumber: number, header: ProposedBlockHeader, archive: Fr, stateReference: StateReference, txs: Tx[], proposerAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal | undefined>;
23
- attestToProposal(proposal: BlockProposal, sender: PeerId): Promise<BlockAttestation[] | undefined>;
24
- broadcastBlockProposal(proposal: BlockProposal): Promise<void>;
25
- collectAttestations(proposal: BlockProposal, required: number, deadline: Date): Promise<BlockAttestation[]>;
26
- }
27
19
  declare const ValidatorClient_base: new () => WatcherEmitter;
28
20
  /**
29
21
  * Validator Client
@@ -43,12 +35,11 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
43
35
  private validationService;
44
36
  private metrics;
45
37
  private previousProposal?;
46
- private myAddresses;
47
38
  private lastEpochForCommitteeUpdateLoop;
48
39
  private epochCacheUpdateLoop;
49
40
  private blockProposalValidator;
50
41
  private proposersOfInvalidBlocks;
51
- protected constructor(blockBuilder: IFullNodeBlockBuilder, keyStore: NodeKeystoreAdapter, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, config: ValidatorClientConfig & Pick<SequencerConfig, 'txPublicSetupAllowList'> & Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
42
+ protected constructor(blockBuilder: IFullNodeBlockBuilder, keyStore: NodeKeystoreAdapter, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, config: ValidatorClientFullConfig, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
52
43
  static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager): void;
53
44
  private handleEpochCommitteeUpdate;
54
45
  static new(config: ValidatorClientConfig & Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>, blockBuilder: IFullNodeBlockBuilder, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, keyStoreManager: KeystoreManager, dateProvider?: DateProvider, telemetry?: TelemetryClient): ValidatorClient;
@@ -56,7 +47,8 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
56
47
  signWithAddress(addr: EthAddress, msg: TypedDataDefinition): Promise<import("@aztec/stdlib/block").Signature>;
57
48
  getCoinbaseForAttestor(attestor: EthAddress): EthAddress;
58
49
  getFeeRecipientForAttestor(attestor: EthAddress): AztecAddress;
59
- configureSlashing(config: Partial<Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>>): void;
50
+ getConfig(): ValidatorClientFullConfig;
51
+ updateConfig(config: Partial<ValidatorClientFullConfig>): void;
60
52
  start(): Promise<void>;
61
53
  stop(): Promise<void>;
62
54
  registerBlockProposalHandler(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAK9C,OAAO,EAAE,YAAY,EAAS,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAiD,UAAU,EAAE,MAAM,YAAY,CAAC;AAGvF,OAAO,EAEL,KAAK,aAAa,EAElB,KAAK,OAAO,EACZ,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC9F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAmB,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAE,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAQ3G,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAsB,MAAM,yBAAyB,CAAC;AAGhG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAEhD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAO3E,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,4BAA4B,IAAI,IAAI,CAAC;IAGrC,mBAAmB,CACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,EAAE,EACX,cAAc,EAAE,cAAc,EAC9B,GAAG,EAAE,EAAE,EAAE,EACT,eAAe,EAAE,UAAU,GAAG,SAAS,EACvC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IACtC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,SAAS,CAAC,CAAC;IAEnG,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,mBAAmB,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CAC7G;oCAKqD,UAAU,cAAc;AAH9E;;GAEG;AACH,qBAAa,eAAgB,SAAQ,oBAA2C,YAAW,SAAS,EAAE,OAAO;IAiBzG,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IAGd,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,GAAG;IA5Bb,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,OAAO,CAAmB;IAGlC,OAAO,CAAC,gBAAgB,CAAC,CAAgB;IAEzC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,+BAA+B,CAAqB;IAC5D,OAAO,CAAC,oBAAoB,CAAiB;IAE7C,OAAO,CAAC,sBAAsB,CAAyB;IAEvD,OAAO,CAAC,wBAAwB,CAA0B;IAE1D,SAAS,aACC,YAAY,EAAE,qBAAqB,EACnC,QAAQ,EAAE,mBAAmB,EAC7B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,GAAG,EACd,WAAW,EAAE,aAAa,EAC1B,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,qBAAqB,GACnC,IAAI,CAAC,eAAe,EAAE,wBAAwB,CAAC,GAC/C,IAAI,CAAC,aAAa,EAAE,qCAAqC,CAAC,EACpD,YAAY,GAAE,YAAiC,EACvD,SAAS,GAAE,eAAsC,EACzC,GAAG,yCAA4B;WAiB3B,6BAA6B,CAAC,eAAe,EAAE,eAAe;YAoB9D,0BAA0B;IA2BxC,MAAM,CAAC,GAAG,CACR,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC,aAAa,EAAE,qCAAqC,CAAC,EAC1F,YAAY,EAAE,qBAAqB,EACnC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,GAAG,EACd,WAAW,EAAE,aAAa,EAC1B,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe,EAChC,YAAY,GAAE,YAAiC,EAC/C,SAAS,GAAE,eAAsC;IAoB5C,qBAAqB;IAIrB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,mBAAmB;IAI1D,sBAAsB,CAAC,QAAQ,EAAE,UAAU,GAAG,UAAU;IAIxD,0BAA0B,CAAC,QAAQ,EAAE,UAAU,GAAG,YAAY;IAI9D,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,qCAAqC,CAAC,CAAC;IAKvF,KAAK;IAwBL,IAAI;IAIV,4BAA4B;IAM7B,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,SAAS,CAAC;IA8IhH,OAAO,CAAC,sBAAsB;IAS9B;;;OAGG;IACG,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDpG,OAAO,CAAC,iBAAiB;IAqBnB,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,EAAE,EACX,cAAc,EAAE,cAAc,EAC9B,GAAG,EAAE,EAAE,EAAE,EACT,eAAe,EAAE,UAAU,GAAG,SAAS,EACvC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAmB/B,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAO5E,mBAAmB,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;YA+CnG,kBAAkB;YAMlB,iBAAiB;CAsBhC"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/dest/validator.js CHANGED
@@ -38,7 +38,6 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
38
38
  metrics;
39
39
  // Used to check if we are sending the same proposal twice
40
40
  previousProposal;
41
- myAddresses;
42
41
  lastEpochForCommitteeUpdateLoop;
43
42
  epochCacheUpdateLoop;
44
43
  blockProposalValidator;
@@ -50,9 +49,9 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
50
49
  this.validationService = new ValidationService(keyStore);
51
50
  this.blockProposalValidator = new BlockProposalValidator(epochCache);
52
51
  // Refresh epoch cache every second to trigger alert if participation in committee changes
53
- this.myAddresses = this.keyStore.getAddresses();
54
52
  this.epochCacheUpdateLoop = new RunningPromise(this.handleEpochCommitteeUpdate.bind(this), log, 1000);
55
- this.log.verbose(`Initialized validator with addresses: ${this.myAddresses.map((a)=>a.toString()).join(', ')}`);
53
+ const myAddresses = this.getValidatorAddresses();
54
+ this.log.verbose(`Initialized validator with addresses: ${myAddresses.map((a)=>a.toString()).join(', ')}`);
56
55
  }
57
56
  static validateKeyStoreConfiguration(keyStoreManager) {
58
57
  const validatorKeyStore = NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager);
@@ -80,7 +79,7 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
80
79
  return;
81
80
  }
82
81
  if (epoch !== this.lastEpochForCommitteeUpdateLoop) {
83
- const me = this.myAddresses;
82
+ const me = this.getValidatorAddresses();
84
83
  const committeeSet = new Set(committee.map((v)=>v.toString()));
85
84
  const inCommittee = me.filter((a)=>committeeSet.has(a.toString()));
86
85
  if (inCommittee.length > 0) {
@@ -101,7 +100,7 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
101
100
  return validator;
102
101
  }
103
102
  getValidatorAddresses() {
104
- return this.keyStore.getAddresses();
103
+ return this.keyStore.getAddresses().filter((addr)=>!this.config.disabledValidators.some((disabled)=>disabled.equals(addr)));
105
104
  }
106
105
  signWithAddress(addr, msg) {
107
106
  return this.keyStore.signTypedDataWithAddress(addr, msg);
@@ -112,13 +111,19 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
112
111
  getFeeRecipientForAttestor(attestor) {
113
112
  return this.keyStore.getFeeRecipient(attestor);
114
113
  }
115
- configureSlashing(config) {
116
- this.config.slashBroadcastedInvalidBlockPenalty = config.slashBroadcastedInvalidBlockPenalty ?? this.config.slashBroadcastedInvalidBlockPenalty;
114
+ getConfig() {
115
+ return this.config;
116
+ }
117
+ updateConfig(config) {
118
+ this.config = {
119
+ ...this.config,
120
+ ...config
121
+ };
117
122
  }
118
123
  async start() {
119
124
  // Sync the committee from the smart contract
120
125
  // https://github.com/AztecProtocol/aztec-packages/issues/7962
121
- const myAddresses = this.keyStore.getAddresses();
126
+ const myAddresses = this.getValidatorAddresses();
122
127
  const inCommittee = await this.epochCache.filterInCommittee('now', myAddresses);
123
128
  if (inCommittee.length > 0) {
124
129
  this.log.info(`Started validator with addresses in current validator committee: ${inCommittee.map((a)=>a.toString()).join(', ')}`);
@@ -142,7 +147,7 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
142
147
  const blockNumber = proposal.blockNumber;
143
148
  const proposer = proposal.getSender();
144
149
  // Check that I have any address in current committee before attesting
145
- const inCommittee = await this.epochCache.filterInCommittee(slotNumber, this.keyStore.getAddresses());
150
+ const inCommittee = await this.epochCache.filterInCommittee(slotNumber, this.getValidatorAddresses());
146
151
  const partOfCommittee = inCommittee.length > 0;
147
152
  const proposalInfo = {
148
153
  ...proposal.toBlockInfo(),
@@ -337,7 +342,7 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
337
342
  }
338
343
  async collectOwnAttestations(proposal) {
339
344
  const slot = proposal.payload.header.slotNumber.toBigInt();
340
- const inCommittee = await this.epochCache.filterInCommittee(slot, this.keyStore.getAddresses());
345
+ const inCommittee = await this.epochCache.filterInCommittee(slot, this.getValidatorAddresses());
341
346
  this.log.debug(`Collecting ${inCommittee.length} self-attestations for slot ${slot}`, {
342
347
  inCommittee
343
348
  });
@@ -353,7 +358,7 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
353
358
  }
354
359
  await this.collectOwnAttestations(proposal);
355
360
  const proposalId = proposal.archive.toString();
356
- const myAddresses = this.keyStore.getAddresses();
361
+ const myAddresses = this.getValidatorAddresses();
357
362
  let attestations = [];
358
363
  while(true){
359
364
  const collectedAttestations = await this.p2pClient.getAttestationsForSlot(slot, proposalId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/validator-client",
3
- "version": "3.0.0-nightly.20250905",
3
+ "version": "4.0.0-nightly.20250907",
4
4
  "main": "dest/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -64,16 +64,16 @@
64
64
  ]
65
65
  },
66
66
  "dependencies": {
67
- "@aztec/constants": "3.0.0-nightly.20250905",
68
- "@aztec/epoch-cache": "3.0.0-nightly.20250905",
69
- "@aztec/ethereum": "3.0.0-nightly.20250905",
70
- "@aztec/foundation": "3.0.0-nightly.20250905",
71
- "@aztec/node-keystore": "3.0.0-nightly.20250905",
72
- "@aztec/p2p": "3.0.0-nightly.20250905",
73
- "@aztec/prover-client": "3.0.0-nightly.20250905",
74
- "@aztec/slasher": "3.0.0-nightly.20250905",
75
- "@aztec/stdlib": "3.0.0-nightly.20250905",
76
- "@aztec/telemetry-client": "3.0.0-nightly.20250905",
67
+ "@aztec/constants": "4.0.0-nightly.20250907",
68
+ "@aztec/epoch-cache": "4.0.0-nightly.20250907",
69
+ "@aztec/ethereum": "4.0.0-nightly.20250907",
70
+ "@aztec/foundation": "4.0.0-nightly.20250907",
71
+ "@aztec/node-keystore": "4.0.0-nightly.20250907",
72
+ "@aztec/p2p": "4.0.0-nightly.20250907",
73
+ "@aztec/prover-client": "4.0.0-nightly.20250907",
74
+ "@aztec/slasher": "4.0.0-nightly.20250907",
75
+ "@aztec/stdlib": "4.0.0-nightly.20250907",
76
+ "@aztec/telemetry-client": "4.0.0-nightly.20250907",
77
77
  "koa": "^2.16.1",
78
78
  "koa-router": "^12.0.0",
79
79
  "tslib": "^2.4.0",
package/src/config.ts CHANGED
@@ -1,35 +1,14 @@
1
1
  import {
2
2
  type ConfigMappingsType,
3
- type SecretValue,
4
3
  booleanConfigHelper,
5
4
  getConfigFromMappings,
6
5
  numberConfigHelper,
7
6
  secretValueConfigHelper,
8
7
  } from '@aztec/foundation/config';
9
8
  import { EthAddress } from '@aztec/foundation/eth-address';
9
+ import type { ValidatorClientConfig } from '@aztec/stdlib/interfaces/server';
10
10
 
11
- /**
12
- * The Validator Configuration
13
- */
14
- export interface ValidatorClientConfig {
15
- /** The private keys of the validators participating in attestation duties */
16
- validatorPrivateKeys?: SecretValue<`0x${string}`[]>;
17
-
18
- /** The addresses of the validators to use with remote signers */
19
- validatorAddresses?: EthAddress[];
20
-
21
- /** Do not run the validator */
22
- disableValidator: boolean;
23
-
24
- /** Interval between polling for new attestations from peers */
25
- attestationPollingIntervalMs: number;
26
-
27
- /** Re-execute transactions before attesting */
28
- validatorReexecute: boolean;
29
-
30
- /** Will re-execute until this many milliseconds are left in the slot */
31
- validatorReexecuteDeadlineMs: number;
32
- }
11
+ export type { ValidatorClientConfig };
33
12
 
34
13
  export const validatorClientConfigMappings: ConfigMappingsType<ValidatorClientConfig> = {
35
14
  validatorPrivateKeys: {
@@ -43,12 +22,26 @@ export const validatorClientConfigMappings: ConfigMappingsType<ValidatorClientCo
43
22
  validatorAddresses: {
44
23
  env: 'VALIDATOR_ADDRESSES',
45
24
  description: 'List of addresses of the validators to use with remote signers',
46
- parseEnv: (val: string) => val.split(',').map(address => EthAddress.fromString(address)),
25
+ parseEnv: (val: string) =>
26
+ val
27
+ .split(',')
28
+ .filter(address => address && address.trim().length > 0)
29
+ .map(address => EthAddress.fromString(address.trim())),
30
+ defaultValue: [],
47
31
  },
48
32
  disableValidator: {
49
33
  env: 'VALIDATOR_DISABLED',
50
34
  description: 'Do not run the validator',
51
- ...booleanConfigHelper(),
35
+ ...booleanConfigHelper(false),
36
+ },
37
+ disabledValidators: {
38
+ description: 'Temporarily disable these specific validator addresses',
39
+ parseEnv: (val: string) =>
40
+ val
41
+ .split(',')
42
+ .filter(address => address && address.trim().length > 0)
43
+ .map(address => EthAddress.fromString(address.trim())),
44
+ defaultValue: [],
52
45
  },
53
46
  attestationPollingIntervalMs: {
54
47
  env: 'VALIDATOR_ATTESTATIONS_POLLING_INTERVAL_MS',
package/src/validator.ts CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
23
23
  import type { L2BlockSource } from '@aztec/stdlib/block';
24
24
  import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
25
- import type { IFullNodeBlockBuilder, SequencerConfig } from '@aztec/stdlib/interfaces/server';
25
+ import type { IFullNodeBlockBuilder, Validator, ValidatorClientFullConfig } from '@aztec/stdlib/interfaces/server';
26
26
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
27
27
  import type { BlockAttestation, BlockProposal, BlockProposalOptions } from '@aztec/stdlib/p2p';
28
28
  import { GlobalVariables, type ProposedBlockHeader, type StateReference, type Tx } from '@aztec/stdlib/tx';
@@ -47,26 +47,6 @@ import { ValidatorMetrics } from './metrics.js';
47
47
  // Just cap the set to avoid unbounded growth.
48
48
  const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
49
49
 
50
- export interface Validator {
51
- start(): Promise<void>;
52
- registerBlockProposalHandler(): void;
53
-
54
- // Block validation responsibilities
55
- createBlockProposal(
56
- blockNumber: number,
57
- header: ProposedBlockHeader,
58
- archive: Fr,
59
- stateReference: StateReference,
60
- txs: Tx[],
61
- proposerAddress: EthAddress | undefined,
62
- options: BlockProposalOptions,
63
- ): Promise<BlockProposal | undefined>;
64
- attestToProposal(proposal: BlockProposal, sender: PeerId): Promise<BlockAttestation[] | undefined>;
65
-
66
- broadcastBlockProposal(proposal: BlockProposal): Promise<void>;
67
- collectAttestations(proposal: BlockProposal, required: number, deadline: Date): Promise<BlockAttestation[]>;
68
- }
69
-
70
50
  /**
71
51
  * Validator Client
72
52
  */
@@ -78,7 +58,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
78
58
  // Used to check if we are sending the same proposal twice
79
59
  private previousProposal?: BlockProposal;
80
60
 
81
- private myAddresses: EthAddress[];
82
61
  private lastEpochForCommitteeUpdateLoop: bigint | undefined;
83
62
  private epochCacheUpdateLoop: RunningPromise;
84
63
 
@@ -94,9 +73,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
94
73
  private blockSource: L2BlockSource,
95
74
  private l1ToL2MessageSource: L1ToL2MessageSource,
96
75
  private txProvider: TxProvider,
97
- private config: ValidatorClientConfig &
98
- Pick<SequencerConfig, 'txPublicSetupAllowList'> &
99
- Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>,
76
+ private config: ValidatorClientFullConfig,
100
77
  private dateProvider: DateProvider = new DateProvider(),
101
78
  telemetry: TelemetryClient = getTelemetryClient(),
102
79
  private log = createLogger('validator'),
@@ -110,10 +87,10 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
110
87
  this.blockProposalValidator = new BlockProposalValidator(epochCache);
111
88
 
112
89
  // Refresh epoch cache every second to trigger alert if participation in committee changes
113
- this.myAddresses = this.keyStore.getAddresses();
114
90
  this.epochCacheUpdateLoop = new RunningPromise(this.handleEpochCommitteeUpdate.bind(this), log, 1000);
115
91
 
116
- this.log.verbose(`Initialized validator with addresses: ${this.myAddresses.map(a => a.toString()).join(', ')}`);
92
+ const myAddresses = this.getValidatorAddresses();
93
+ this.log.verbose(`Initialized validator with addresses: ${myAddresses.map(a => a.toString()).join(', ')}`);
117
94
  }
118
95
 
119
96
  public static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager) {
@@ -144,7 +121,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
144
121
  return;
145
122
  }
146
123
  if (epoch !== this.lastEpochForCommitteeUpdateLoop) {
147
- const me = this.myAddresses;
124
+ const me = this.getValidatorAddresses();
148
125
  const committeeSet = new Set(committee.map(v => v.toString()));
149
126
  const inCommittee = me.filter(a => committeeSet.has(a.toString()));
150
127
  if (inCommittee.length > 0) {
@@ -194,7 +171,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
194
171
  }
195
172
 
196
173
  public getValidatorAddresses() {
197
- return this.keyStore.getAddresses();
174
+ return this.keyStore
175
+ .getAddresses()
176
+ .filter(addr => !this.config.disabledValidators.some(disabled => disabled.equals(addr)));
198
177
  }
199
178
 
200
179
  public signWithAddress(addr: EthAddress, msg: TypedDataDefinition) {
@@ -209,16 +188,19 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
209
188
  return this.keyStore.getFeeRecipient(attestor);
210
189
  }
211
190
 
212
- public configureSlashing(config: Partial<Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>>) {
213
- this.config.slashBroadcastedInvalidBlockPenalty =
214
- config.slashBroadcastedInvalidBlockPenalty ?? this.config.slashBroadcastedInvalidBlockPenalty;
191
+ public getConfig(): ValidatorClientFullConfig {
192
+ return this.config;
193
+ }
194
+
195
+ public updateConfig(config: Partial<ValidatorClientFullConfig>) {
196
+ this.config = { ...this.config, ...config };
215
197
  }
216
198
 
217
199
  public async start() {
218
200
  // Sync the committee from the smart contract
219
201
  // https://github.com/AztecProtocol/aztec-packages/issues/7962
220
202
 
221
- const myAddresses = this.keyStore.getAddresses();
203
+ const myAddresses = this.getValidatorAddresses();
222
204
 
223
205
  const inCommittee = await this.epochCache.filterInCommittee('now', myAddresses);
224
206
  if (inCommittee.length > 0) {
@@ -254,7 +236,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
254
236
  const proposer = proposal.getSender();
255
237
 
256
238
  // Check that I have any address in current committee before attesting
257
- const inCommittee = await this.epochCache.filterInCommittee(slotNumber, this.keyStore.getAddresses());
239
+ const inCommittee = await this.epochCache.filterInCommittee(slotNumber, this.getValidatorAddresses());
258
240
  const partOfCommittee = inCommittee.length > 0;
259
241
 
260
242
  const proposalInfo = {
@@ -510,7 +492,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
510
492
 
511
493
  async collectOwnAttestations(proposal: BlockProposal): Promise<BlockAttestation[]> {
512
494
  const slot = proposal.payload.header.slotNumber.toBigInt();
513
- const inCommittee = await this.epochCache.filterInCommittee(slot, this.keyStore.getAddresses());
495
+ const inCommittee = await this.epochCache.filterInCommittee(slot, this.getValidatorAddresses());
514
496
  this.log.debug(`Collecting ${inCommittee.length} self-attestations for slot ${slot}`, { inCommittee });
515
497
  return this.doAttestToProposal(proposal, inCommittee);
516
498
  }
@@ -530,7 +512,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
530
512
  await this.collectOwnAttestations(proposal);
531
513
 
532
514
  const proposalId = proposal.archive.toString();
533
- const myAddresses = this.keyStore.getAddresses();
515
+ const myAddresses = this.getValidatorAddresses();
534
516
 
535
517
  let attestations: BlockAttestation[] = [];
536
518
  while (true) {