@lodestar/beacon-node 1.49.0-dev.ae6cc426f1 → 1.49.0-dev.b27f498c2c

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 (65) hide show
  1. package/lib/api/impl/beacon/blocks/index.js +2 -2
  2. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  3. package/lib/api/impl/validator/index.js +6 -6
  4. package/lib/api/impl/validator/index.js.map +1 -1
  5. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  6. package/lib/chain/archiveStore/utils/pruneHistory.js +9 -2
  7. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  8. package/lib/chain/blocks/index.js +2 -2
  9. package/lib/chain/blocks/index.js.map +1 -1
  10. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -1
  11. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  12. package/lib/chain/errors/attesterSlashingError.d.ts +4 -1
  13. package/lib/chain/errors/attesterSlashingError.d.ts.map +1 -1
  14. package/lib/chain/errors/attesterSlashingError.js +1 -0
  15. package/lib/chain/errors/attesterSlashingError.js.map +1 -1
  16. package/lib/chain/errors/proposerSlashingError.d.ts +4 -1
  17. package/lib/chain/errors/proposerSlashingError.d.ts.map +1 -1
  18. package/lib/chain/errors/proposerSlashingError.js +1 -0
  19. package/lib/chain/errors/proposerSlashingError.js.map +1 -1
  20. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  21. package/lib/chain/produceBlock/produceBlockBody.js +6 -6
  22. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  23. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +2 -1
  24. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  25. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +3 -2
  26. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  27. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  28. package/lib/chain/validation/attesterSlashing.js +1 -2
  29. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  30. package/lib/chain/validation/proposerSlashing.js +1 -2
  31. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  32. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  33. package/lib/chain/validatorMonitor.js +2 -2
  34. package/lib/chain/validatorMonitor.js.map +1 -1
  35. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  36. package/lib/network/gossip/gossipsub.js +15 -0
  37. package/lib/network/gossip/gossipsub.js.map +1 -1
  38. package/lib/network/gossip/topic.d.ts +1 -1
  39. package/lib/network/gossip/topic.d.ts.map +1 -1
  40. package/lib/network/gossip/topic.js +1 -1
  41. package/lib/network/gossip/topic.js.map +1 -1
  42. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  43. package/lib/network/processor/gossipHandlers.js +16 -5
  44. package/lib/network/processor/gossipHandlers.js.map +1 -1
  45. package/lib/network/processor/gossipValidatorFn.d.ts +2 -0
  46. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  47. package/lib/network/processor/gossipValidatorFn.js +88 -7
  48. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  49. package/package.json +14 -14
  50. package/src/api/impl/beacon/blocks/index.ts +2 -2
  51. package/src/api/impl/validator/index.ts +6 -6
  52. package/src/chain/archiveStore/utils/pruneHistory.ts +9 -2
  53. package/src/chain/blocks/index.ts +2 -2
  54. package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -1
  55. package/src/chain/errors/attesterSlashingError.ts +3 -1
  56. package/src/chain/errors/proposerSlashingError.ts +3 -1
  57. package/src/chain/produceBlock/produceBlockBody.ts +17 -6
  58. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +3 -2
  59. package/src/chain/validation/attesterSlashing.ts +1 -2
  60. package/src/chain/validation/proposerSlashing.ts +1 -2
  61. package/src/chain/validatorMonitor.ts +12 -2
  62. package/src/network/gossip/gossipsub.ts +18 -1
  63. package/src/network/gossip/topic.ts +2 -2
  64. package/src/network/processor/gossipHandlers.ts +18 -5
  65. package/src/network/processor/gossipValidatorFn.ts +111 -7
@@ -59,7 +59,18 @@ import {
59
59
  heze,
60
60
  ssz,
61
61
  } from "@lodestar/types";
62
- import {GWEI_TO_WEI, Logger, byteArrayEquals, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
62
+ import {
63
+ GWEI_TO_WEI,
64
+ Logger,
65
+ byteArrayEquals,
66
+ fromHex,
67
+ prettyGweiToEth,
68
+ prettyWeiToEth,
69
+ sleep,
70
+ toHex,
71
+ toPubkeyHex,
72
+ toRootHex,
73
+ } from "@lodestar/utils";
63
74
  import {ZERO_HASH_HEX} from "../../constants/index.js";
64
75
  import {numToQuantity} from "../../execution/engine/utils.js";
65
76
  import {IExecutionBuilder, IExecutionEngine, PayloadAttributes, PayloadId} from "../../execution/index.js";
@@ -259,7 +270,7 @@ export async function produceBlockBody<T extends BlockType>(
259
270
  this.logger.verbose("Produced block with builder bid", {
260
271
  slot: blockSlot,
261
272
  builderIndex: builderBid.message.builderIndex,
262
- bidValue: builderBid.message.value,
273
+ bidValue: prettyGweiToEth(builderBid.message.value),
263
274
  parentBlockHash: toRootHex(builderBid.message.parentBlockHash),
264
275
  parentBlockRoot: toRootHex(builderBid.message.parentBlockRoot),
265
276
  blockHash: toRootHex(builderBid.message.blockHash),
@@ -410,7 +421,7 @@ export async function produceBlockBody<T extends BlockType>(
410
421
  this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime);
411
422
  this.logger.verbose("Produced block with self-build bid", {
412
423
  slot: blockSlot,
413
- executionPayloadValue,
424
+ executionPayloadValue: prettyWeiToEth(executionPayloadValue),
414
425
  prepType,
415
426
  payloadId,
416
427
  fetchedTime,
@@ -490,7 +501,7 @@ export async function produceBlockBody<T extends BlockType>(
490
501
  this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime);
491
502
  this.logger.verbose("Fetched execution payload header from builder", {
492
503
  slot: blockSlot,
493
- executionPayloadValue,
504
+ executionPayloadValue: prettyWeiToEth(executionPayloadValue),
494
505
  prepType,
495
506
  fetchedTime,
496
507
  });
@@ -607,7 +618,7 @@ export async function produceBlockBody<T extends BlockType>(
607
618
  this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime);
608
619
  this.logger.verbose("Fetched execution payload from engine", {
609
620
  slot: blockSlot,
610
- executionPayloadValue,
621
+ executionPayloadValue: prettyWeiToEth(executionPayloadValue),
611
622
  prepType,
612
623
  payloadId,
613
624
  fetchedTime,
@@ -708,7 +719,7 @@ export async function produceBlockBody<T extends BlockType>(
708
719
  }
709
720
  }
710
721
 
711
- Object.assign(logMeta, {executionPayloadValue});
722
+ Object.assign(logMeta, {executionPayloadValue: prettyWeiToEth(executionPayloadValue)});
712
723
  this.logger.verbose("Produced beacon block body", logMeta);
713
724
 
714
725
  return {body: blockBody as AssembledBodyType<T>, produceResult, executionPayloadValue, shouldOverrideBuilder};
@@ -256,10 +256,11 @@ export class SeenPayloadEnvelopeInput {
256
256
  return this.payloadInputs.size;
257
257
  }
258
258
 
259
- prune(blockRootHex: RootHex): void {
259
+ /** Removes the single PayloadEnvelopeInput from the cache */
260
+ remove(blockRootHex: RootHex): void {
260
261
  const input = this.payloadInputs.get(blockRootHex);
261
262
  if (input) {
262
- this.evictPayloadInput(input, "prune");
263
+ this.evictPayloadInput(input, "remove");
263
264
  }
264
265
  }
265
266
 
@@ -63,8 +63,7 @@ export async function validateAttesterSlashing(
63
63
  const signatureSets = getAttesterSlashingSignatureSets(chain.config, state.slot, attesterSlashing);
64
64
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
65
65
  throw new AttesterSlashingError(GossipAction.REJECT, {
66
- code: AttesterSlashingErrorCode.INVALID,
67
- error: Error("Invalid signature"),
66
+ code: AttesterSlashingErrorCode.INVALID_SIGNATURE,
68
67
  });
69
68
  }
70
69
  }
@@ -48,8 +48,7 @@ async function validateProposerSlashing(
48
48
  const signatureSets = getProposerSlashingSignatureSets(chain.config, state.slot, proposerSlashing);
49
49
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
50
50
  throw new ProposerSlashingError(GossipAction.REJECT, {
51
- code: ProposerSlashingErrorCode.INVALID,
52
- error: Error("Invalid signature"),
51
+ code: ProposerSlashingErrorCode.INVALID_SIGNATURE,
53
52
  });
54
53
  }
55
54
  }
@@ -24,7 +24,17 @@ import {
24
24
  deneb,
25
25
  gloas,
26
26
  } from "@lodestar/types";
27
- import {LogData, LogHandler, LogLevel, Logger, MapDef, MapDefMax, prettyPrintIndices, toRootHex} from "@lodestar/utils";
27
+ import {
28
+ LogData,
29
+ LogHandler,
30
+ LogLevel,
31
+ Logger,
32
+ MapDef,
33
+ MapDefMax,
34
+ prettyGweiToEth,
35
+ prettyPrintIndices,
36
+ toRootHex,
37
+ } from "@lodestar/utils";
28
38
  import {GENESIS_SLOT} from "../constants/constants.js";
29
39
  import {RegistryMetricCreator} from "../metrics/index.js";
30
40
 
@@ -470,7 +480,7 @@ export function createValidatorMonitor(
470
480
  src,
471
481
  builderIndex: bid.builderIndex,
472
482
  gasLimit: Number(bid.gasLimit),
473
- value: bid.value.toString(),
483
+ value: prettyGweiToEth(bid.value),
474
484
  parentBlockRoot: toRootHex(bid.parentBlockRoot),
475
485
  parentBlockHash: toRootHex(bid.parentBlockHash),
476
486
  blockHash: toRootHex(bid.blockHash),
@@ -14,7 +14,7 @@ import {peerIdFromString} from "@libp2p/peer-id";
14
14
  import {type Multiaddr, multiaddr} from "@multiformats/multiaddr";
15
15
  import {ENR} from "@chainsafe/enr";
16
16
  import {routes} from "@lodestar/api";
17
- import {BeaconConfig, ForkBoundary} from "@lodestar/config";
17
+ import {BeaconConfig, ChainConfig, ForkBoundary} from "@lodestar/config";
18
18
  import {
19
19
  ATTESTATION_SUBNET_COUNT,
20
20
  MAX_SIGNED_AGGREGATE_AND_PROOF_SIZE,
@@ -47,6 +47,22 @@ const GOSSIPSUB_HEARTBEAT_INTERVAL = 0.7 * 1000;
47
47
 
48
48
  const MAX_OUTBOUND_BUFFER_SIZE = 2 ** 24; // 16MB
49
49
 
50
+ /**
51
+ * Snappy worst-case compressed length for a payload of `n` bytes
52
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-beta.0/specs/phase0/p2p-interface.md#max_compressed_len
53
+ */
54
+ function maxCompressedLen(n: number): number {
55
+ return 32 + n + Math.floor(n / 6);
56
+ }
57
+
58
+ /**
59
+ * Max size of an inbound gossipsub RPC frame, including all bundled messages and control
60
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-beta.0/specs/phase0/p2p-interface.md#max_message_size
61
+ */
62
+ function getMaxInboundDataLength(config: Pick<ChainConfig, "MAX_PAYLOAD_SIZE">): number {
63
+ return Math.max(maxCompressedLen(config.MAX_PAYLOAD_SIZE) + 1024, 1024 * 1024);
64
+ }
65
+
50
66
  export type Eth2Context = {
51
67
  activeValidatorCount: number;
52
68
  currentSlot: number;
@@ -176,6 +192,7 @@ export class Eth2Gossipsub {
176
192
  asyncValidation: true,
177
193
 
178
194
  maxOutboundBufferSize: MAX_OUTBOUND_BUFFER_SIZE,
195
+ maxInboundDataLength: getMaxInboundDataLength(config),
179
196
  // serialize message once and send to all peers when publishing
180
197
  batchPublish: true,
181
198
  // if this is false, only publish to mesh peers. If there is not enough GOSSIP_D mesh peers,
@@ -150,8 +150,8 @@ export function getGossipSSZType(topic: GossipTopic) {
150
150
  /**
151
151
  * Return the maximum uncompressed SSZ byte length allowed by the type and configured network bounds.
152
152
  */
153
- export function getGossipSSZMaxSize(topic: GossipTopic, config: ChainForkConfig, sszType?: CompositeTypeAny): number {
154
- const maxSize = Math.min((sszType ?? getGossipSSZType(topic)).maxSize, config.MAX_PAYLOAD_SIZE);
153
+ export function getGossipSSZMaxSize(topic: GossipTopic, config: ChainForkConfig, sszType: CompositeTypeAny): number {
154
+ const maxSize = Math.min(sszType.maxSize, config.MAX_PAYLOAD_SIZE);
155
155
  if (isForkPostGloas(topic.boundary.fork) && topic.type === GossipType.data_column_sidecar) {
156
156
  return Math.min(maxSize, computeMaxGloasDataColumnSidecarSize(config));
157
157
  }
@@ -244,8 +244,20 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
244
244
 
245
245
  // IGNORE means the block is acceptable (e.g. FUTURE_SLOT, ALREADY_KNOWN), just not propagated.
246
246
  // Keep the optimistically-added cache entries; they are pruned on finalization. Only REJECT
247
- // (provably invalid) and unexpected errors prune below.
247
+ // (provably invalid), unexpected errors and repeat proposals that are not imported prune.
248
248
  if (e.action === GossipAction.IGNORE) {
249
+ // Only a signature-verified sibling is imported by the beacon_block handler, any other repeat proposal
250
+ // is dropped from the caches and re-downloaded by sync if it ever becomes relevant. Its signature was not
251
+ // verified, so only its own entry is removed, never its claimed ancestors
252
+ if (
253
+ e.type.code === BlockErrorCode.REPEAT_PROPOSAL &&
254
+ !chain.seenBlockProposers.hasBlockRoot(slot, signedBlock.message.proposerIndex, blockRootHex)
255
+ ) {
256
+ chain.seenBlockInputCache.remove(blockRootHex);
257
+ if (isForkPostGloas(fork)) {
258
+ chain.seenPayloadEnvelopeInputCache.remove(blockRootHex);
259
+ }
260
+ }
249
261
  throw e;
250
262
  }
251
263
 
@@ -258,10 +270,10 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
258
270
  }
259
271
 
260
272
  // REJECT or unexpected (non-BlockGossipError) error: drop the optimistically-added entries from
261
- // both caches, keeping them consistent.
262
- chain.seenBlockInputCache.prune(blockRootHex);
273
+ // both caches, keeping them consistent. The block may carry any parent root, so only its own entry is removed
274
+ chain.seenBlockInputCache.remove(blockRootHex);
263
275
  if (isForkPostGloas(fork)) {
264
- chain.seenPayloadEnvelopeInputCache.prune(blockRootHex);
276
+ chain.seenPayloadEnvelopeInputCache.remove(blockRootHex);
265
277
  }
266
278
  throw e;
267
279
  } finally {
@@ -738,7 +750,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
738
750
  if (
739
751
  e instanceof BlockGossipError &&
740
752
  e.type.code === BlockErrorCode.REPEAT_PROPOSAL &&
741
- // this is make sure the block's proposer signature was verified, it should be true anyway
753
+ // Only a signature-verified sibling recorded in the seen cache is imported. The cache holds at most two
754
+ // roots per proposer and slot, which bounds full imports over gossip to one alternate
742
755
  chain.seenBlockProposers.hasBlockRoot(signedBlock.message.slot, e.type.proposerIndex, e.type.root)
743
756
  ) {
744
757
  // blockInput was optimistically seeded in validateBeaconBlock and retained on IGNORE
@@ -1,24 +1,122 @@
1
1
  import {TopicValidatorResult} from "@libp2p/gossipsub";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
3
  import {Logger} from "@lodestar/utils";
4
- import {AttestationError, GossipAction, GossipActionError} from "../../chain/errors/index.js";
4
+ import {
5
+ AttestationError,
6
+ AttestationErrorCode,
7
+ AttesterSlashingErrorCode,
8
+ BlobSidecarErrorCode,
9
+ BlockErrorCode,
10
+ BlsToExecutionChangeErrorCode,
11
+ DataColumnSidecarErrorCode,
12
+ ExecutionPayloadBidErrorCode,
13
+ ExecutionPayloadEnvelopeErrorCode,
14
+ GossipAction,
15
+ GossipActionError,
16
+ PayloadAttestationErrorCode,
17
+ ProposerPreferencesErrorCode,
18
+ ProposerSlashingErrorCode,
19
+ SyncCommitteeErrorCode,
20
+ VoluntaryExitErrorCode,
21
+ } from "../../chain/errors/index.js";
5
22
  import {Metrics} from "../../metrics/index.js";
23
+ import {INetworkCore} from "../core/index.js";
6
24
  import {
7
25
  BatchGossipHandlerFn,
8
26
  GossipHandlerFn,
9
27
  GossipHandlers,
10
28
  GossipMessageInfo,
29
+ GossipType,
11
30
  GossipValidatorBatchFn,
12
31
  GossipValidatorFn,
13
32
  } from "../gossip/interface.js";
33
+ import {PeerAction} from "../peers/index.js";
14
34
  import {prettyPrintPeerIdStr} from "../util.js";
15
35
 
16
36
  export type ValidatorFnModules = {
17
37
  config: ChainForkConfig;
18
38
  logger: Logger;
19
39
  metrics: Metrics | null;
40
+ core: INetworkCore;
41
+ };
42
+
43
+ type RejectPeerActionRule = {default: PeerAction; byCode?: Record<string, PeerAction>};
44
+
45
+ /**
46
+ * PeerAction mapping based on the topic and specific codes.
47
+ * Invalid signatures are Fatal on every topic.
48
+ */
49
+ const gossipRejectPeerAction: Record<GossipType, RejectPeerActionRule> = {
50
+ [GossipType.beacon_block]: {
51
+ default: PeerAction.LowToleranceError,
52
+ byCode: {[BlockErrorCode.PROPOSAL_SIGNATURE_INVALID]: PeerAction.Fatal},
53
+ },
54
+ [GossipType.blob_sidecar]: {
55
+ default: PeerAction.LowToleranceError,
56
+ byCode: {[BlobSidecarErrorCode.PROPOSAL_SIGNATURE_INVALID]: PeerAction.Fatal},
57
+ },
58
+ [GossipType.data_column_sidecar]: {
59
+ default: PeerAction.LowToleranceError,
60
+ byCode: {[DataColumnSidecarErrorCode.PROPOSAL_SIGNATURE_INVALID]: PeerAction.Fatal},
61
+ },
62
+ [GossipType.execution_payload]: {
63
+ default: PeerAction.LowToleranceError,
64
+ byCode: {[ExecutionPayloadEnvelopeErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
65
+ },
66
+ [GossipType.beacon_aggregate_and_proof]: {
67
+ default: PeerAction.MidToleranceError,
68
+ byCode: {[AttestationErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
69
+ },
70
+ [GossipType.beacon_attestation]: {
71
+ default: PeerAction.MidToleranceError,
72
+ byCode: {[AttestationErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
73
+ },
74
+ [GossipType.sync_committee_contribution_and_proof]: {
75
+ default: PeerAction.MidToleranceError,
76
+ byCode: {[SyncCommitteeErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
77
+ },
78
+ [GossipType.sync_committee]: {
79
+ default: PeerAction.MidToleranceError,
80
+ byCode: {[SyncCommitteeErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
81
+ },
82
+ [GossipType.payload_attestation_message]: {
83
+ default: PeerAction.MidToleranceError,
84
+ byCode: {[PayloadAttestationErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
85
+ },
86
+ [GossipType.execution_payload_bid]: {
87
+ default: PeerAction.HighToleranceError,
88
+ byCode: {[ExecutionPayloadBidErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
89
+ },
90
+ [GossipType.proposer_preferences]: {
91
+ default: PeerAction.HighToleranceError,
92
+ byCode: {[ProposerPreferencesErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
93
+ },
94
+ [GossipType.voluntary_exit]: {
95
+ default: PeerAction.HighToleranceError,
96
+ byCode: {[VoluntaryExitErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
97
+ },
98
+ [GossipType.bls_to_execution_change]: {
99
+ default: PeerAction.HighToleranceError,
100
+ byCode: {[BlsToExecutionChangeErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
101
+ },
102
+ [GossipType.proposer_slashing]: {
103
+ default: PeerAction.HighToleranceError,
104
+ byCode: {[ProposerSlashingErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
105
+ },
106
+ [GossipType.attester_slashing]: {
107
+ default: PeerAction.HighToleranceError,
108
+ byCode: {[AttesterSlashingErrorCode.INVALID_SIGNATURE]: PeerAction.Fatal},
109
+ },
110
+ // light client validators only throw IGNORE
111
+ [GossipType.light_client_finality_update]: {default: PeerAction.HighToleranceError},
112
+ [GossipType.light_client_optimistic_update]: {default: PeerAction.HighToleranceError},
20
113
  };
21
114
 
115
+ function rejectPeerAction(type: GossipType, code: string): PeerAction {
116
+ const rule = gossipRejectPeerAction[type];
117
+ return rule.byCode?.[code] ?? rule.default;
118
+ }
119
+
22
120
  /**
23
121
  * Similar to getGossipValidatorFn but return a function to accept a batch of beacon_attestation messages
24
122
  * with the same attestation data
@@ -27,7 +125,7 @@ export function getGossipValidatorBatchFn(
27
125
  gossipHandlers: GossipHandlers,
28
126
  modules: ValidatorFnModules
29
127
  ): GossipValidatorBatchFn {
30
- const {logger, metrics} = modules;
128
+ const {logger, metrics, core} = modules;
31
129
 
32
130
  return async function gossipValidatorBatchFn(messageInfos: GossipMessageInfo[]) {
33
131
  // all messageInfos have same topic type
@@ -69,16 +167,19 @@ export function getGossipValidatorBatchFn(
69
167
  // only beacon_attestation topic is validated in batch
70
168
  metrics?.networkProcessor.gossipAttestationIgnoreByReason.inc({reason: e.type.code});
71
169
  return TopicValidatorResult.Ignore;
72
- case GossipAction.REJECT:
170
+ case GossipAction.REJECT: {
73
171
  metrics?.networkProcessor.gossipValidationReject.inc({topic: type});
74
172
  // only beacon_attestation topic is validated in batch
75
173
  metrics?.networkProcessor.gossipAttestationRejectByReason.inc({reason: e.type.code});
174
+ const peerAction = rejectPeerAction(type, e.type.code);
175
+ core.reportPeer(propagationSource, peerAction, e.type.code);
76
176
  logger.debug(
77
177
  `Gossip validation ${type} rejected`,
78
- {peerId: prettyPrintPeerIdStr(propagationSource), clientAgent, clientVersion},
178
+ {peer: propagationSource, clientAgent, clientVersion, peerAction},
79
179
  e
80
180
  );
81
181
  return TopicValidatorResult.Reject;
182
+ }
82
183
  }
83
184
  });
84
185
  } catch (e) {
@@ -108,7 +209,7 @@ export function getGossipValidatorBatchFn(
108
209
  * @see getGossipHandlers for reasoning on why GossipHandlerFn are used for gossip validation.
109
210
  */
110
211
  export function getGossipValidatorFn(gossipHandlers: GossipHandlers, modules: ValidatorFnModules): GossipValidatorFn {
111
- const {logger, metrics} = modules;
212
+ const {logger, metrics, core} = modules;
112
213
 
113
214
  return async function gossipValidatorFn({
114
215
  topic,
@@ -155,14 +256,17 @@ export function getGossipValidatorFn(gossipHandlers: GossipHandlers, modules: Va
155
256
  metrics?.networkProcessor.gossipValidationIgnore.inc({topic: type});
156
257
  return TopicValidatorResult.Ignore;
157
258
 
158
- case GossipAction.REJECT:
259
+ case GossipAction.REJECT: {
159
260
  metrics?.networkProcessor.gossipValidationReject.inc({topic: type});
261
+ const peerAction = rejectPeerAction(type, e.type.code);
262
+ core.reportPeer(propagationSource, peerAction, e.type.code);
160
263
  logger.debug(
161
264
  `Gossip validation ${type} rejected`,
162
- {peerId: prettyPrintPeerIdStr(propagationSource), clientAgent, clientVersion},
265
+ {peer: propagationSource, clientAgent, clientVersion, peerAction},
163
266
  e
164
267
  );
165
268
  return TopicValidatorResult.Reject;
269
+ }
166
270
  }
167
271
  }
168
272
  };