@aztec/p2p 3.0.0-nightly.20251111 → 3.0.0-nightly.20251113

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
@@ -103,6 +103,8 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig, TxCollectionCo
103
103
  dropTransactionsProbability: number;
104
104
  /** Whether to delete transactions from the pool after a reorg instead of moving them back to pending. */
105
105
  txPoolDeleteTxsAfterReorg: boolean;
106
+ /** Whether to run in fisherman mode: validates all proposals and attestations but does not broadcast attestations or participate in consensus */
107
+ fishermanMode: boolean;
106
108
  }
107
109
  export declare const DEFAULT_P2P_PORT = 40400;
108
110
  export declare const p2pConfigMappings: ConfigMappingsType<P2PConfig>;
@@ -184,6 +186,7 @@ export declare const bootnodeConfigMappings: ConfigMappingsType<Pick<{
184
186
  dropTransactions: unknown;
185
187
  dropTransactionsProbability: unknown;
186
188
  txPoolDeleteTxsAfterReorg: unknown;
189
+ fishermanMode: unknown;
187
190
  }, "p2pPort" | "p2pBroadcastPort" | "p2pIp" | "listenAddress" | "peerIdPrivateKey" | "peerIdPrivateKeyPath" | "bootstrapNodes" | "queryForIp" | "l1ChainId" | "dataDirectory" | "dataStoreMapSizeKb">>;
188
191
  /**
189
192
  * Parses a string to a list of allowed elements.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dest/config.js CHANGED
@@ -255,6 +255,11 @@ export const p2pConfigMappings = {
255
255
  description: 'Whether to delete transactions from the pool after a reorg instead of moving them back to pending.',
256
256
  ...booleanConfigHelper(false)
257
257
  },
258
+ fishermanMode: {
259
+ env: 'FISHERMAN_MODE',
260
+ description: 'Whether to run in fisherman mode: validates all proposals and attestations but does not broadcast attestations or participate in consensus.',
261
+ ...booleanConfigHelper(false)
262
+ },
258
263
  ...p2pReqRespConfigMappings,
259
264
  ...chainConfigMappings,
260
265
  ...txCollectionConfigMappings
@@ -1,8 +1,9 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
+ import { type Logger } from '@aztec/foundation/log';
2
3
  import { type BlockAttestation, type P2PValidator, PeerErrorSeverity } from '@aztec/stdlib/p2p';
3
4
  export declare class AttestationValidator implements P2PValidator<BlockAttestation> {
4
- private epochCache;
5
- private logger;
5
+ protected epochCache: EpochCacheInterface;
6
+ protected logger: Logger;
6
7
  constructor(epochCache: EpochCacheInterface);
7
8
  validate(message: BlockAttestation): Promise<PeerErrorSeverity | undefined>;
8
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"attestation_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/attestation_validator/attestation_validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEhG,qBAAa,oBAAqB,YAAW,YAAY,CAAC,gBAAgB,CAAC;IACzE,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,MAAM,CAAS;gBAEX,UAAU,EAAE,mBAAmB;IAKrC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;CAwDlF"}
1
+ {"version":3,"file":"attestation_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/attestation_validator/attestation_validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEhG,qBAAa,oBAAqB,YAAW,YAAY,CAAC,gBAAgB,CAAC;IACzE,SAAS,CAAC,UAAU,EAAE,mBAAmB,CAAC;IAC1C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEb,UAAU,EAAE,mBAAmB;IAKrC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;CAwDlF"}
@@ -0,0 +1,20 @@
1
+ import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
+ import { type BlockAttestation, PeerErrorSeverity } from '@aztec/stdlib/p2p';
3
+ import { type TelemetryClient } from '@aztec/telemetry-client';
4
+ import type { AttestationPool } from '../../mem_pools/attestation_pool/attestation_pool.js';
5
+ import { AttestationValidator } from './attestation_validator.js';
6
+ /**
7
+ * FishermanAttestationValidator extends the base AttestationValidator to add
8
+ * additional validation for fisherman nodes: verifying that attestations sign
9
+ * the same payload as the original proposal.
10
+ * Invalid attestations are rejected (not propagated), but peer penalization is
11
+ * handled by LibP2PService based on the fishermanMode config to ensure a better
12
+ * view of the network.
13
+ */
14
+ export declare class FishermanAttestationValidator extends AttestationValidator {
15
+ private attestationPool;
16
+ private invalidAttestationCounter;
17
+ constructor(epochCache: EpochCacheInterface, attestationPool: AttestationPool, telemetryClient: TelemetryClient);
18
+ validate(message: BlockAttestation): Promise<PeerErrorSeverity | undefined>;
19
+ }
20
+ //# sourceMappingURL=fisherman_attestation_validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fisherman_attestation_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/attestation_validator/fisherman_attestation_validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,KAAK,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAuB,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAE/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sDAAsD,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;;;GAOG;AACH,qBAAa,6BAA8B,SAAQ,oBAAoB;IAKnE,OAAO,CAAC,eAAe;IAJzB,OAAO,CAAC,yBAAyB,CAAC;gBAGhC,UAAU,EAAE,mBAAmB,EACvB,eAAe,EAAE,eAAe,EACxC,eAAe,EAAE,eAAe;IAYnB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;CAyD3F"}
@@ -0,0 +1,67 @@
1
+ import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
2
+ import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
3
+ import { AttestationValidator } from './attestation_validator.js';
4
+ /**
5
+ * FishermanAttestationValidator extends the base AttestationValidator to add
6
+ * additional validation for fisherman nodes: verifying that attestations sign
7
+ * the same payload as the original proposal.
8
+ * Invalid attestations are rejected (not propagated), but peer penalization is
9
+ * handled by LibP2PService based on the fishermanMode config to ensure a better
10
+ * view of the network.
11
+ */ export class FishermanAttestationValidator extends AttestationValidator {
12
+ attestationPool;
13
+ invalidAttestationCounter;
14
+ constructor(epochCache, attestationPool, telemetryClient){
15
+ super(epochCache), this.attestationPool = attestationPool;
16
+ this.logger = this.logger.createChild('[FISHERMAN]');
17
+ const meter = telemetryClient.getMeter('FishermanAttestationValidator');
18
+ this.invalidAttestationCounter = meter.createUpDownCounter(Metrics.VALIDATOR_INVALID_ATTESTATION_RECEIVED_COUNT, {
19
+ description: 'The number of invalid attestations received',
20
+ valueType: ValueType.INT
21
+ });
22
+ }
23
+ async validate(message) {
24
+ // First run the standard validation
25
+ const baseValidationResult = await super.validate(message);
26
+ if (baseValidationResult !== undefined) {
27
+ // Track base validation failures (invalid signature, wrong committee, etc.)
28
+ this.invalidAttestationCounter.add(1, {
29
+ [Attributes.ERROR_TYPE]: 'base_validation_failed'
30
+ });
31
+ return baseValidationResult;
32
+ }
33
+ // fisherman validation: verify attestation payload matches proposal payload
34
+ const slotNumberBigInt = message.payload.header.slotNumber.toBigInt();
35
+ const attester = message.getSender();
36
+ const proposer = message.getProposer();
37
+ if (!attester || !proposer) {
38
+ return undefined;
39
+ }
40
+ const proposalId = message.archive.toString();
41
+ const proposal = await this.attestationPool.getBlockProposal(proposalId);
42
+ if (proposal) {
43
+ // Compare the attestation payload with the proposal payload
44
+ if (!message.payload.equals(proposal.payload)) {
45
+ this.logger.error(`Attestation payload mismatch for slot ${slotNumberBigInt}! ` + `Attester ${attester.toString()} signed different data than the proposal.`, {
46
+ slot: slotNumberBigInt.toString(),
47
+ attester: attester.toString(),
48
+ proposer: proposer.toString(),
49
+ proposalArchive: proposal.archive.toString(),
50
+ attestationArchive: message.archive.toString(),
51
+ proposalHeader: proposal.payload.header.hash().toString(),
52
+ attestationHeader: message.payload.header.hash().toString()
53
+ });
54
+ // Track invalid attestation metric
55
+ this.invalidAttestationCounter.add(1, {
56
+ [Attributes.ERROR_TYPE]: 'payload_mismatch'
57
+ });
58
+ // Return error to reject the message, but LibP2PService won't penalize in fisherman mode
59
+ return PeerErrorSeverity.LowToleranceError;
60
+ }
61
+ } else {
62
+ // We might receive attestations before proposals in some cases
63
+ this.logger.debug(`Received attestation for slot ${slotNumberBigInt} but proposal not found yet. ` + `Proposal ID: ${proposalId}`);
64
+ }
65
+ return undefined;
66
+ }
67
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './attestation_validator.js';
2
+ export * from './fisherman_attestation_validator.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/attestation_validator/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/attestation_validator/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sCAAsC,CAAC"}
@@ -1 +1,2 @@
1
1
  export * from './attestation_validator.js';
2
+ export * from './fisherman_attestation_validator.js';
@@ -39,7 +39,6 @@ export declare class LibP2PService<T extends P2PClientType = P2PClientType.Full>
39
39
  private epochCache;
40
40
  private proofVerifier;
41
41
  private worldStateSynchronizer;
42
- protected logger: Logger;
43
42
  private jobQueue;
44
43
  private discoveryRunningPromise?;
45
44
  private msgIdSeenValidators;
@@ -56,6 +55,7 @@ export declare class LibP2PService<T extends P2PClientType = P2PClientType.Full>
56
55
  private blockReceivedCallback;
57
56
  private gossipSubEventHandler;
58
57
  private instrumentation;
58
+ protected logger: Logger;
59
59
  constructor(clientType: T, config: P2PConfig, node: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, reqresp: ReqRespInterface, peerManager: PeerManagerInterface, mempools: MemPools<T>, archiver: L2BlockSource & ContractDataSource, epochCache: EpochCacheInterface, proofVerifier: ClientProtocolCircuitVerifier, worldStateSynchronizer: WorldStateSynchronizer, telemetry: TelemetryClient, logger?: Logger);
60
60
  updateConfig(config: Partial<P2PReqRespConfig>): void;
61
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,7 @@ import { mplex } from '@libp2p/mplex';
30
30
  import { tcp } from '@libp2p/tcp';
31
31
  import { ENR } from '@nethermindeth/enr';
32
32
  import { createLibp2p } from 'libp2p';
33
- import { AttestationValidator, BlockProposalValidator } from '../../msg_validators/index.js';
33
+ import { AttestationValidator, BlockProposalValidator, FishermanAttestationValidator } from '../../msg_validators/index.js';
34
34
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
35
35
  import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
36
36
  import { createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
@@ -64,7 +64,6 @@ import { P2PInstrumentation } from './instrumentation.js';
64
64
  epochCache;
65
65
  proofVerifier;
66
66
  worldStateSynchronizer;
67
- logger;
68
67
  jobQueue;
69
68
  discoveryRunningPromise;
70
69
  msgIdSeenValidators;
@@ -81,8 +80,11 @@ import { P2PInstrumentation } from './instrumentation.js';
81
80
  */ blockReceivedCallback;
82
81
  gossipSubEventHandler;
83
82
  instrumentation;
83
+ logger;
84
84
  constructor(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
85
- super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.logger = logger, this.jobQueue = new SerialQueue(), this.msgIdSeenValidators = {}, this.protocolVersion = '', this.topicStrings = {};
85
+ super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.jobQueue = new SerialQueue(), this.msgIdSeenValidators = {}, this.protocolVersion = '', this.topicStrings = {};
86
+ // Create child logger with fisherman prefix if in fisherman mode
87
+ this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
86
88
  this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
87
89
  this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
88
90
  this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
@@ -93,7 +95,8 @@ import { P2PInstrumentation } from './instrumentation.js';
93
95
  this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
94
96
  this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
95
97
  this.topicStrings[TopicType.block_attestation] = createTopicString(TopicType.block_attestation, this.protocolVersion);
96
- this.attestationValidator = new AttestationValidator(epochCache);
98
+ // Use FishermanAttestationValidator in fisherman mode to validate attestation payloads against proposals
99
+ this.attestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new AttestationValidator(epochCache);
97
100
  this.blockProposalValidator = new BlockProposalValidator(epochCache, {
98
101
  txsPermitted: !config.disableTransactions
99
102
  });
@@ -673,7 +676,7 @@ import { P2PInstrumentation } from './instrumentation.js';
673
676
  await this.mempools.attestationPool?.addBlockProposal(block);
674
677
  const attestations = await this.blockReceivedCallback(block, sender);
675
678
  // TODO: fix up this pattern - the abstraction is not nice
676
- // The attestation can be undefined if no handler is registered / the validator deems the block invalid
679
+ // The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
677
680
  if (attestations?.length) {
678
681
  for (const attestation of attestations){
679
682
  this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber.toNumber()}`, {
@@ -767,17 +770,18 @@ import { P2PInstrumentation } from './instrumentation.js';
767
770
  }), new TxProofValidator(this.proofVerifier));
768
771
  }
769
772
  async validateRequestedTx(tx, peerId, txValidator, requested) {
773
+ const penalize = (severity)=>this.peerManager.penalizePeer(peerId, severity);
770
774
  if (!await tx.validateTxHash()) {
771
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
775
+ penalize(PeerErrorSeverity.MidToleranceError);
772
776
  throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
773
777
  }
774
778
  if (requested && !requested.has(tx.getTxHash().toString())) {
775
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
779
+ penalize(PeerErrorSeverity.MidToleranceError);
776
780
  throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
777
781
  }
778
782
  const { result } = await txValidator.validateTx(tx);
779
783
  if (result === 'invalid') {
780
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
784
+ penalize(PeerErrorSeverity.LowToleranceError);
781
785
  throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
782
786
  }
783
787
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "3.0.0-nightly.20251111",
3
+ "version": "3.0.0-nightly.20251113",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -67,17 +67,17 @@
67
67
  ]
68
68
  },
69
69
  "dependencies": {
70
- "@aztec/constants": "3.0.0-nightly.20251111",
71
- "@aztec/epoch-cache": "3.0.0-nightly.20251111",
72
- "@aztec/ethereum": "3.0.0-nightly.20251111",
73
- "@aztec/foundation": "3.0.0-nightly.20251111",
74
- "@aztec/kv-store": "3.0.0-nightly.20251111",
75
- "@aztec/noir-contracts.js": "3.0.0-nightly.20251111",
76
- "@aztec/noir-protocol-circuits-types": "3.0.0-nightly.20251111",
77
- "@aztec/protocol-contracts": "3.0.0-nightly.20251111",
78
- "@aztec/simulator": "3.0.0-nightly.20251111",
79
- "@aztec/stdlib": "3.0.0-nightly.20251111",
80
- "@aztec/telemetry-client": "3.0.0-nightly.20251111",
70
+ "@aztec/constants": "3.0.0-nightly.20251113",
71
+ "@aztec/epoch-cache": "3.0.0-nightly.20251113",
72
+ "@aztec/ethereum": "3.0.0-nightly.20251113",
73
+ "@aztec/foundation": "3.0.0-nightly.20251113",
74
+ "@aztec/kv-store": "3.0.0-nightly.20251113",
75
+ "@aztec/noir-contracts.js": "3.0.0-nightly.20251113",
76
+ "@aztec/noir-protocol-circuits-types": "3.0.0-nightly.20251113",
77
+ "@aztec/protocol-contracts": "3.0.0-nightly.20251113",
78
+ "@aztec/simulator": "3.0.0-nightly.20251113",
79
+ "@aztec/stdlib": "3.0.0-nightly.20251113",
80
+ "@aztec/telemetry-client": "3.0.0-nightly.20251113",
81
81
  "@chainsafe/libp2p-gossipsub": "13.0.0",
82
82
  "@chainsafe/libp2p-noise": "^15.0.0",
83
83
  "@chainsafe/libp2p-yamux": "^6.0.2",
@@ -104,8 +104,8 @@
104
104
  "xxhash-wasm": "^1.1.0"
105
105
  },
106
106
  "devDependencies": {
107
- "@aztec/archiver": "3.0.0-nightly.20251111",
108
- "@aztec/world-state": "3.0.0-nightly.20251111",
107
+ "@aztec/archiver": "3.0.0-nightly.20251113",
108
+ "@aztec/world-state": "3.0.0-nightly.20251113",
109
109
  "@jest/globals": "^30.0.0",
110
110
  "@types/jest": "^30.0.0",
111
111
  "@types/node": "^22.15.17",
package/src/config.ts CHANGED
@@ -164,6 +164,9 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig, TxCollectionCo
164
164
 
165
165
  /** Whether to delete transactions from the pool after a reorg instead of moving them back to pending. */
166
166
  txPoolDeleteTxsAfterReorg: boolean;
167
+
168
+ /** Whether to run in fisherman mode: validates all proposals and attestations but does not broadcast attestations or participate in consensus */
169
+ fishermanMode: boolean;
167
170
  }
168
171
 
169
172
  export const DEFAULT_P2P_PORT = 40400;
@@ -420,6 +423,12 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
420
423
  description: 'Whether to delete transactions from the pool after a reorg instead of moving them back to pending.',
421
424
  ...booleanConfigHelper(false),
422
425
  },
426
+ fishermanMode: {
427
+ env: 'FISHERMAN_MODE',
428
+ description:
429
+ 'Whether to run in fisherman mode: validates all proposals and attestations but does not broadcast attestations or participate in consensus.',
430
+ ...booleanConfigHelper(false),
431
+ },
423
432
  ...p2pReqRespConfigMappings,
424
433
  ...chainConfigMappings,
425
434
  ...txCollectionConfigMappings,
@@ -4,8 +4,8 @@ import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { type BlockAttestation, type P2PValidator, PeerErrorSeverity } from '@aztec/stdlib/p2p';
5
5
 
6
6
  export class AttestationValidator implements P2PValidator<BlockAttestation> {
7
- private epochCache: EpochCacheInterface;
8
- private logger: Logger;
7
+ protected epochCache: EpochCacheInterface;
8
+ protected logger: Logger;
9
9
 
10
10
  constructor(epochCache: EpochCacheInterface) {
11
11
  this.epochCache = epochCache;
@@ -0,0 +1,91 @@
1
+ import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
+ import { type BlockAttestation, PeerErrorSeverity } from '@aztec/stdlib/p2p';
3
+ import { Attributes, Metrics, type TelemetryClient, ValueType } from '@aztec/telemetry-client';
4
+
5
+ import type { AttestationPool } from '../../mem_pools/attestation_pool/attestation_pool.js';
6
+ import { AttestationValidator } from './attestation_validator.js';
7
+
8
+ /**
9
+ * FishermanAttestationValidator extends the base AttestationValidator to add
10
+ * additional validation for fisherman nodes: verifying that attestations sign
11
+ * the same payload as the original proposal.
12
+ * Invalid attestations are rejected (not propagated), but peer penalization is
13
+ * handled by LibP2PService based on the fishermanMode config to ensure a better
14
+ * view of the network.
15
+ */
16
+ export class FishermanAttestationValidator extends AttestationValidator {
17
+ private invalidAttestationCounter;
18
+
19
+ constructor(
20
+ epochCache: EpochCacheInterface,
21
+ private attestationPool: AttestationPool,
22
+ telemetryClient: TelemetryClient,
23
+ ) {
24
+ super(epochCache);
25
+ this.logger = this.logger.createChild('[FISHERMAN]');
26
+
27
+ const meter = telemetryClient.getMeter('FishermanAttestationValidator');
28
+ this.invalidAttestationCounter = meter.createUpDownCounter(Metrics.VALIDATOR_INVALID_ATTESTATION_RECEIVED_COUNT, {
29
+ description: 'The number of invalid attestations received',
30
+ valueType: ValueType.INT,
31
+ });
32
+ }
33
+
34
+ override async validate(message: BlockAttestation): Promise<PeerErrorSeverity | undefined> {
35
+ // First run the standard validation
36
+ const baseValidationResult = await super.validate(message);
37
+ if (baseValidationResult !== undefined) {
38
+ // Track base validation failures (invalid signature, wrong committee, etc.)
39
+ this.invalidAttestationCounter.add(1, {
40
+ [Attributes.ERROR_TYPE]: 'base_validation_failed',
41
+ });
42
+ return baseValidationResult;
43
+ }
44
+
45
+ // fisherman validation: verify attestation payload matches proposal payload
46
+ const slotNumberBigInt = message.payload.header.slotNumber.toBigInt();
47
+ const attester = message.getSender();
48
+ const proposer = message.getProposer();
49
+
50
+ if (!attester || !proposer) {
51
+ return undefined;
52
+ }
53
+
54
+ const proposalId = message.archive.toString();
55
+ const proposal = await this.attestationPool.getBlockProposal(proposalId);
56
+
57
+ if (proposal) {
58
+ // Compare the attestation payload with the proposal payload
59
+ if (!message.payload.equals(proposal.payload)) {
60
+ this.logger.error(
61
+ `Attestation payload mismatch for slot ${slotNumberBigInt}! ` +
62
+ `Attester ${attester.toString()} signed different data than the proposal.`,
63
+ {
64
+ slot: slotNumberBigInt.toString(),
65
+ attester: attester.toString(),
66
+ proposer: proposer.toString(),
67
+ proposalArchive: proposal.archive.toString(),
68
+ attestationArchive: message.archive.toString(),
69
+ proposalHeader: proposal.payload.header.hash().toString(),
70
+ attestationHeader: message.payload.header.hash().toString(),
71
+ },
72
+ );
73
+
74
+ // Track invalid attestation metric
75
+ this.invalidAttestationCounter.add(1, {
76
+ [Attributes.ERROR_TYPE]: 'payload_mismatch',
77
+ });
78
+
79
+ // Return error to reject the message, but LibP2PService won't penalize in fisherman mode
80
+ return PeerErrorSeverity.LowToleranceError;
81
+ }
82
+ } else {
83
+ // We might receive attestations before proposals in some cases
84
+ this.logger.debug(
85
+ `Received attestation for slot ${slotNumberBigInt} but proposal not found yet. ` + `Proposal ID: ${proposalId}`,
86
+ );
87
+ }
88
+
89
+ return undefined;
90
+ }
91
+ }
@@ -1 +1,2 @@
1
1
  export * from './attestation_validator.js';
2
+ export * from './fisherman_attestation_validator.js';
@@ -51,7 +51,11 @@ import { createLibp2p } from 'libp2p';
51
51
 
52
52
  import type { P2PConfig } from '../../config.js';
53
53
  import type { MemPools } from '../../mem_pools/interface.js';
54
- import { AttestationValidator, BlockProposalValidator } from '../../msg_validators/index.js';
54
+ import {
55
+ AttestationValidator,
56
+ BlockProposalValidator,
57
+ FishermanAttestationValidator,
58
+ } from '../../msg_validators/index.js';
55
59
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
56
60
  import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
57
61
  import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
@@ -140,6 +144,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
140
144
 
141
145
  private instrumentation: P2PInstrumentation;
142
146
 
147
+ protected logger: Logger;
148
+
143
149
  constructor(
144
150
  private clientType: T,
145
151
  private config: P2PConfig,
@@ -153,10 +159,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
153
159
  private proofVerifier: ClientProtocolCircuitVerifier,
154
160
  private worldStateSynchronizer: WorldStateSynchronizer,
155
161
  telemetry: TelemetryClient,
156
- protected logger = createLogger('p2p:libp2p_service'),
162
+ logger: Logger = createLogger('p2p:libp2p_service'),
157
163
  ) {
158
164
  super(telemetry, 'LibP2PService');
159
165
 
166
+ // Create child logger with fisherman prefix if in fisherman mode
167
+ this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
168
+
160
169
  this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
161
170
 
162
171
  this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
@@ -174,7 +183,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
174
183
  this.protocolVersion,
175
184
  );
176
185
 
177
- this.attestationValidator = new AttestationValidator(epochCache);
186
+ // Use FishermanAttestationValidator in fisherman mode to validate attestation payloads against proposals
187
+ this.attestationValidator = config.fishermanMode
188
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool!, telemetry)
189
+ : new AttestationValidator(epochCache);
178
190
  this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
179
191
 
180
192
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
@@ -896,7 +908,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
896
908
  const attestations = await this.blockReceivedCallback(block, sender);
897
909
 
898
910
  // TODO: fix up this pattern - the abstraction is not nice
899
- // The attestation can be undefined if no handler is registered / the validator deems the block invalid
911
+ // The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
900
912
  if (attestations?.length) {
901
913
  for (const attestation of attestations) {
902
914
  this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber.toNumber()}`, {
@@ -1021,19 +1033,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1021
1033
  }
1022
1034
 
1023
1035
  private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
1036
+ const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity);
1037
+
1024
1038
  if (!(await tx.validateTxHash())) {
1025
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1039
+ penalize(PeerErrorSeverity.MidToleranceError);
1026
1040
  throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
1027
1041
  }
1028
1042
 
1029
1043
  if (requested && !requested.has(tx.getTxHash().toString())) {
1030
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1044
+ penalize(PeerErrorSeverity.MidToleranceError);
1031
1045
  throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
1032
1046
  }
1033
1047
 
1034
1048
  const { result } = await txValidator.validateTx(tx);
1035
1049
  if (result === 'invalid') {
1036
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1050
+ penalize(PeerErrorSeverity.LowToleranceError);
1037
1051
  throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
1038
1052
  }
1039
1053
  }