@aztec/p2p 0.0.1-commit.2f68f620 → 0.0.1-commit.321f6a9

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 (153) hide show
  1. package/README.md +7 -6
  2. package/dest/bootstrap/bootstrap.d.ts +1 -1
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  4. package/dest/bootstrap/bootstrap.js +20 -12
  5. package/dest/client/factory.d.ts +2 -2
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +10 -5
  8. package/dest/client/interface.d.ts +36 -8
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +23 -12
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +38 -35
  13. package/dest/config.d.ts +19 -13
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +27 -26
  16. package/dest/errors/reqresp.error.d.ts +13 -1
  17. package/dest/errors/reqresp.error.d.ts.map +1 -1
  18. package/dest/errors/reqresp.error.js +14 -0
  19. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -2
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/attestation_pool.js +9 -2
  22. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  24. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +43 -0
  25. package/dest/mem_pools/instrumentation.d.ts +9 -4
  26. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  27. package/dest/mem_pools/instrumentation.js +11 -8
  28. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -3
  29. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  30. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +6 -6
  31. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
  32. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +30 -5
  33. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  35. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +15 -1
  36. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +31 -0
  38. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -3
  39. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +19 -8
  41. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +17 -4
  42. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +133 -34
  44. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +6 -5
  45. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/attestation_validator/attestation_validator.js +24 -26
  47. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -4
  48. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  49. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  50. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +4 -3
  51. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  52. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +2 -2
  53. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +4 -3
  54. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  55. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +8 -2
  56. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +19 -5
  57. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  58. package/dest/msg_validators/proposal_validator/proposal_validator.js +66 -30
  59. package/dest/msg_validators/tx_validator/factory.d.ts +9 -11
  60. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  61. package/dest/msg_validators/tx_validator/factory.js +15 -6
  62. package/dest/msg_validators/tx_validator/gas_validator.d.ts +12 -7
  63. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  64. package/dest/msg_validators/tx_validator/gas_validator.js +15 -15
  65. package/dest/msg_validators/tx_validator/phases_validator.js +2 -2
  66. package/dest/services/discv5/discV5_service.d.ts +12 -2
  67. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  68. package/dest/services/discv5/discV5_service.js +84 -15
  69. package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
  70. package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
  71. package/dest/services/discv5/persisted_enr_store.js +145 -0
  72. package/dest/services/dummy_service.d.ts +6 -2
  73. package/dest/services/dummy_service.d.ts.map +1 -1
  74. package/dest/services/dummy_service.js +3 -0
  75. package/dest/services/encoding.d.ts +19 -6
  76. package/dest/services/encoding.d.ts.map +1 -1
  77. package/dest/services/encoding.js +25 -15
  78. package/dest/services/gossipsub/topic_score_params.d.ts +6 -23
  79. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  80. package/dest/services/gossipsub/topic_score_params.js +4 -31
  81. package/dest/services/libp2p/libp2p_service.d.ts +11 -3
  82. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  83. package/dest/services/libp2p/libp2p_service.js +135 -53
  84. package/dest/services/peer-manager/peer_manager.d.ts +15 -2
  85. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  86. package/dest/services/peer-manager/peer_manager.js +46 -18
  87. package/dest/services/peer-manager/peer_scoring.d.ts +28 -1
  88. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  89. package/dest/services/peer-manager/peer_scoring.js +70 -3
  90. package/dest/services/reqresp/config.d.ts +13 -1
  91. package/dest/services/reqresp/config.d.ts.map +1 -1
  92. package/dest/services/reqresp/config.js +11 -0
  93. package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -3
  94. package/dest/services/reqresp/reqresp.d.ts +1 -1
  95. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  96. package/dest/services/reqresp/reqresp.js +34 -3
  97. package/dest/services/service.d.ts +17 -1
  98. package/dest/services/service.d.ts.map +1 -1
  99. package/dest/services/tx_collection/tx_source.d.ts +1 -1
  100. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  101. package/dest/services/tx_collection/tx_source.js +4 -1
  102. package/dest/test-helpers/testbench-utils.d.ts +4 -1
  103. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  104. package/dest/test-helpers/testbench-utils.js +9 -0
  105. package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
  106. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  107. package/dest/testbench/p2p_client_testbench_worker.js +19 -2
  108. package/package.json +16 -17
  109. package/src/bootstrap/bootstrap.ts +15 -9
  110. package/src/client/factory.ts +9 -5
  111. package/src/client/interface.ts +29 -6
  112. package/src/client/p2p_client.ts +46 -48
  113. package/src/config.ts +50 -38
  114. package/src/errors/reqresp.error.ts +19 -0
  115. package/src/mem_pools/attestation_pool/attestation_pool.ts +12 -2
  116. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +40 -1
  117. package/src/mem_pools/instrumentation.ts +13 -11
  118. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
  119. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
  120. package/src/mem_pools/tx_pool_v2/interfaces.ts +28 -4
  121. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +35 -0
  122. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +22 -8
  123. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +158 -33
  124. package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -26
  125. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -3
  126. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +4 -2
  127. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +10 -2
  128. package/src/msg_validators/proposal_validator/proposal_validator.ts +69 -30
  129. package/src/msg_validators/tx_validator/README.md +2 -0
  130. package/src/msg_validators/tx_validator/factory.ts +19 -13
  131. package/src/msg_validators/tx_validator/gas_validator.ts +16 -20
  132. package/src/msg_validators/tx_validator/phases_validator.ts +2 -2
  133. package/src/services/discv5/discV5_service.ts +88 -9
  134. package/src/services/discv5/persisted_enr_store.ts +158 -0
  135. package/src/services/dummy_service.ts +6 -0
  136. package/src/services/encoding.ts +28 -20
  137. package/src/services/gossipsub/README.md +33 -11
  138. package/src/services/gossipsub/topic_score_params.ts +9 -50
  139. package/src/services/libp2p/libp2p_service.ts +159 -56
  140. package/src/services/peer-manager/peer_manager.ts +48 -17
  141. package/src/services/peer-manager/peer_scoring.ts +75 -3
  142. package/src/services/reqresp/README.md +2 -23
  143. package/src/services/reqresp/config.ts +17 -0
  144. package/src/services/reqresp/rate-limiter/rate_limits.ts +3 -3
  145. package/src/services/reqresp/reqresp.ts +42 -2
  146. package/src/services/service.ts +19 -0
  147. package/src/services/tx_collection/tx_source.ts +2 -1
  148. package/src/test-helpers/testbench-utils.ts +12 -0
  149. package/src/testbench/p2p_client_testbench_worker.ts +22 -2
  150. package/dest/msg_validators/clock_tolerance.d.ts +0 -32
  151. package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
  152. package/dest/msg_validators/clock_tolerance.js +0 -90
  153. package/src/msg_validators/clock_tolerance.ts +0 -121
@@ -372,12 +372,15 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
372
372
  }
373
373
  var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _initProto;
374
374
  import { BlockNumber } from '@aztec/foundation/branded-types';
375
- import { maxBy, merge } from '@aztec/foundation/collection';
375
+ import { compactArray, maxBy, merge } from '@aztec/foundation/collection';
376
376
  import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
377
377
  import { RunningPromise } from '@aztec/foundation/running-promise';
378
378
  import { Timer } from '@aztec/foundation/timer';
379
379
  import { protocolContractsHash } from '@aztec/protocol-contracts';
380
+ import { DEFAULT_MAX_BLOCKS_PER_CHECKPOINT } from '@aztec/stdlib/config';
381
+ import { getNetworkTxGasLimits } from '@aztec/stdlib/gas';
380
382
  import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PMessage, PeerErrorSeverity, PeerErrorSeverityByHarshness, TopicType, createTopicString, getTopicsForConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
383
+ import { ConsensusTimetable, getDefaultCheckpointProposalSyncGrace } from '@aztec/stdlib/timetable';
381
384
  import { MerkleTreeId } from '@aztec/stdlib/trees';
382
385
  import { Tx } from '@aztec/stdlib/tx';
383
386
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
@@ -404,14 +407,27 @@ import { convertToMultiaddr } from '../../util.js';
404
407
  import { getVersions } from '../../versioning.js';
405
408
  import { AztecDatastore } from '../data_store.js';
406
409
  import { DiscV5Service } from '../discv5/discV5_service.js';
407
- import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
410
+ import { SnappyTransform, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
408
411
  import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring.js';
409
412
  import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
410
413
  import { PeerManager } from '../peer-manager/peer_manager.js';
411
414
  import { PeerScoring } from '../peer-manager/peer_scoring.js';
415
+ import { YAMUX_MAX_MESSAGE_SIZE_BYTES } from '../reqresp/config.js';
412
416
  import { ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
413
417
  import { ReqResp } from '../reqresp/reqresp.js';
414
418
  import { P2PInstrumentation } from './instrumentation.js';
419
+ /**
420
+ * Builds the {@link ConsensusTimetable} shared by the gossip validators for proposal/attestation receive-window
421
+ * bounds. Derived purely from protocol slot-timing constants plus the block sub-slot duration and the consensus
422
+ * materialization grace, so every node agrees on these bounds without depending on proposer operational budgets.
423
+ */ function buildConsensusTimetable(config, l1Constants) {
424
+ const blockDuration = config.blockDurationMs / 1000;
425
+ return new ConsensusTimetable({
426
+ l1Constants,
427
+ blockDuration,
428
+ checkpointProposalSyncGrace: config.checkpointProposalSyncGraceSeconds ?? getDefaultCheckpointProposalSyncGrace(blockDuration)
429
+ });
430
+ }
415
431
  _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
416
432
  [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString()
417
433
  })), _dec1 = trackSpan('Libp2pService.validateAndStoreBlockProposal', (_peerId, block)=>({
@@ -488,6 +504,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
488
504
  protocolVersion;
489
505
  topicStrings;
490
506
  /** Callback invoked when a duplicate proposal is detected (triggers slashing). */ duplicateProposalCallback;
507
+ /** Callback invoked when an oversized block proposal is stored as slashing evidence (triggers slashing). */ oversizedProposalCallback;
491
508
  /** Callback invoked when a duplicate attestation is detected (triggers slashing). */ duplicateAttestationCallback;
492
509
  /** Callback invoked when a valid checkpoint attestation is accepted into the pool. */ checkpointAttestationCallback;
493
510
  /**
@@ -528,26 +545,27 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
528
545
  this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
529
546
  this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
530
547
  this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
531
- const p2pPropagationTime = config.attestationPropagationTime;
548
+ // Build the consensus timetable once from protocol slot-timing constants and inject it into every
549
+ // validator so they share one set of receive-window bounds, independent of proposer operational budgets.
550
+ const consensusTimetable = buildConsensusTimetable(config, epochCache.getL1Constants());
532
551
  const proposalValidatorOpts = {
533
552
  txsPermitted: !config.disableTransactions,
534
553
  maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
535
554
  maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
536
- p2pPropagationTime,
537
555
  skipSlotValidation: config.skipProposalSlotValidation,
538
556
  signatureContext: {
539
557
  chainId: config.l1ChainId,
540
558
  rollupAddress: config.rollupAddress
541
- }
559
+ },
560
+ clockDisparityMs: config.maxGossipClockDisparityMs
542
561
  };
543
- this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
544
- this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
562
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, consensusTimetable, proposalValidatorOpts);
563
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, consensusTimetable, proposalValidatorOpts);
545
564
  const attestationValidatorOpts = {
546
- l1PublishingTime: config.l1PublishingTime,
547
- p2pPropagationTime,
548
- signatureContext: proposalValidatorOpts.signatureContext
565
+ signatureContext: proposalValidatorOpts.signatureContext,
566
+ clockDisparityMs: config.maxGossipClockDisparityMs
549
567
  };
550
- this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, attestationValidatorOpts) : new CheckpointAttestationValidator(epochCache, attestationValidatorOpts);
568
+ this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, consensusTimetable, mempools.attestationPool, telemetry, attestationValidatorOpts) : new CheckpointAttestationValidator(epochCache, consensusTimetable, attestationValidatorOpts);
551
569
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
552
570
  this.blockReceivedCallback = async (block)=>{
553
571
  this.logger.warn(`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`, {
@@ -577,7 +595,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
577
595
  const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
578
596
  const datastore = new AztecDatastore(peerStore);
579
597
  const otelMetricsAdapter = new OtelMetricsAdapter(telemetry, logger.getBindings());
580
- const peerDiscoveryService = new DiscV5Service(peerId, config, packageVersion, telemetry, createLogger(`${logger.module}:discv5_service`, logger.getBindings()));
598
+ const peerDiscoveryService = new DiscV5Service(peerId, config, packageVersion, telemetry, createLogger(`${logger.module}:discv5_service`, logger.getBindings()), peerStore);
581
599
  // Seed libp2p's bootstrap discovery with private and trusted peers
582
600
  const bootstrapNodes = [
583
601
  ...config.privatePeers,
@@ -592,34 +610,45 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
592
610
  const versions = getVersions(config);
593
611
  const protocolVersion = compressComponentVersions(versions);
594
612
  const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
595
- const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
596
- const peerId = await enr.peerId();
597
- const address = enr.getLocationMultiaddr('tcp');
598
- if (address === undefined) {
599
- throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
613
+ const directPeers = compactArray(await Promise.all(preferredPeersEnrs.map(async (enr)=>{
614
+ try {
615
+ const peerId = await enr.peerId();
616
+ const address = enr.getLocationMultiaddr('tcp');
617
+ if (address === undefined) {
618
+ throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
619
+ }
620
+ return {
621
+ id: peerId,
622
+ addrs: [
623
+ address
624
+ ]
625
+ };
626
+ } catch (err) {
627
+ // A malformed configured ENR shouldn't abort node setup — skip it and log.
628
+ logger.warn(`Skipping preferred peer with invalid ENR`, {
629
+ err
630
+ });
631
+ return undefined;
600
632
  }
601
- return {
602
- id: peerId,
603
- addrs: [
604
- address
605
- ]
606
- };
607
- }))).filter((peer)=>peer !== undefined);
633
+ })));
608
634
  const announceTcpMultiaddr = config.p2pIp ? [
609
635
  convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')
610
636
  ] : [];
611
- // Create dynamic topic score params based on network configuration
637
+ // Create dynamic topic score params based on network configuration. Scoring uses the network-wide
638
+ // max-blocks-per-checkpoint config value directly to size expected per-slot message rates; these are
639
+ // peer-rate thresholds, not consensus deadlines, so they need no proposer operational budgets.
612
640
  const l1Constants = epochCache.getL1Constants();
613
641
  const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
614
642
  slotDurationMs: l1Constants.slotDuration * 1000,
615
- ethereumSlotDuration: l1Constants.ethereumSlotDuration,
616
643
  heartbeatIntervalMs: config.gossipsubInterval,
617
644
  targetCommitteeSize: l1Constants.targetCommitteeSize,
618
- blockDurationMs: config.blockDurationMs,
619
- l1PublishingTime: config.l1PublishingTime,
620
- p2pPropagationTime: config.attestationPropagationTime,
645
+ maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint ?? DEFAULT_MAX_BLOCKS_PER_CHECKPOINT,
621
646
  expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot
622
647
  });
648
+ // Restrict gossipsub to exactly the topics we subscribe to. Without this, an arbitrary-topic
649
+ // message is transformed, msg-id'd and inserted into the seenCache before the subscription check,
650
+ // so a crafted topic colliding on msg id can suppress a real message as a duplicate.
651
+ const allowedTopics = getTopicsForConfig(config.disableTransactions).map((topic)=>createTopicString(topic, protocolVersion));
623
652
  const node = await createLibp2p({
624
653
  start: false,
625
654
  peerId,
@@ -653,8 +682,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
653
682
  ],
654
683
  datastore,
655
684
  peerDiscovery,
685
+ // Pin the yamux frame size: MAX_REQRESP_REQUEST_SIZE_BYTES relies on a reqresp request fitting in one frame.
656
686
  streamMuxers: [
657
- yamux(),
687
+ yamux({
688
+ maxMessageSize: YAMUX_MAX_MESSAGE_SIZE_BYTES
689
+ }),
658
690
  mplex()
659
691
  ],
660
692
  connectionEncryption: [
@@ -672,7 +704,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
672
704
  },
673
705
  connectionGater: {
674
706
  denyInboundConnection: (maConn)=>{
675
- const allowed = peerManager.isNodeAllowedToConnect(maConn.remoteAddr.nodeAddress().address);
707
+ const allowed = peerManager.isAddressAllowedToConnect(maConn.remoteAddr.nodeAddress().address);
676
708
  if (allowed) {
677
709
  return false;
678
710
  }
@@ -682,7 +714,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
682
714
  denyInboundEncryptedConnection: (peerId, _maConn)=>{
683
715
  //NOTE: it is not necessary to check address here because this was already done by
684
716
  // denyInboundConnection
685
- const allowed = peerManager.isNodeAllowedToConnect(peerId);
717
+ const allowed = peerManager.isPeerAllowedToConnect(peerId);
686
718
  if (allowed) {
687
719
  return false;
688
720
  }
@@ -709,9 +741,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
709
741
  mcacheLength: config.gossipsubMcacheLength,
710
742
  mcacheGossip: config.gossipsubMcacheGossip,
711
743
  seenTTL: config.gossipsubSeenTTL,
744
+ allowedTopics,
745
+ // No fastMsgIdFn: the fast-path dedup cache keys on a non-cryptographic 64-bit hash of the
746
+ // raw data only (no topic), so a collision — accidental or engineered via a weak seed — drops
747
+ // a different message with no fallback to the full id. Dedup instead rests solely on the
748
+ // cryptographic, topic-framed msgIdFn below.
712
749
  msgIdFn: getMsgIdFn,
713
750
  msgIdToStrFn: msgIdToStrFn,
714
- fastMsgIdFn: fastMsgIdFn,
715
751
  dataTransform: new SnappyTransform(),
716
752
  metricsRegister: otelMetricsAdapter,
717
753
  metricsTopicStrToLabel: metricsTopicStrToLabels(protocolVersion),
@@ -896,6 +932,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
896
932
  this.duplicateProposalCallback = callback;
897
933
  }
898
934
  /**
935
+ * Registers a callback to be invoked when an oversized block proposal is stored as slashing evidence.
936
+ */ registerOversizedProposalCallback(callback) {
937
+ this.oversizedProposalCallback = callback;
938
+ }
939
+ /**
899
940
  * Registers a callback to be invoked when a duplicate attestation is detected.
900
941
  * A validator signing attestations for different proposals at the same slot.
901
942
  * This callback is triggered on the first duplicate (when count goes from 1 to 2).
@@ -1342,9 +1383,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1342
1383
  };
1343
1384
  }
1344
1385
  async processBlockFromPeer(payloadData, msgId, source) {
1345
- const { result, obj: block, metadata: { isEquivocated } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreBlockProposal(source, BlockProposal.fromBuffer(payloadData)), msgId, source, TopicType.block_proposal);
1346
- // If not accepted or equivocated, return
1347
- if (result !== TopicValidatorResult.Accept || !block || isEquivocated) {
1386
+ const { result, obj: block, metadata: { isEquivocated, isOversized } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreBlockProposal(source, BlockProposal.fromBuffer(payloadData)), msgId, source, TopicType.block_proposal);
1387
+ // If not accepted, equivocated, or oversized, return. Oversized proposals are re-broadcast as
1388
+ // slashing evidence but never attested or processed.
1389
+ if (result !== TopicValidatorResult.Accept || !block || isEquivocated || isOversized) {
1348
1390
  return;
1349
1391
  }
1350
1392
  await this.processValidBlockProposal(block, source);
@@ -1367,6 +1409,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1367
1409
  // Try to add the proposal: this handles existence check, cap check, and adding in one call
1368
1410
  const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1369
1411
  const isEquivocated = count !== undefined && count > 1;
1412
+ // An oversized proposal (index at or beyond the consensus per-checkpoint limit) is structurally valid
1413
+ // proposer misbehavior: it is stored and re-broadcast as slashing evidence but never processed or
1414
+ // attested to. No-ops when maxBlocksPerCheckpoint is unset (local/test).
1415
+ const isOversized = this.config.maxBlocksPerCheckpoint !== undefined && block.indexWithinCheckpoint >= this.config.maxBlocksPerCheckpoint;
1370
1416
  // Duplicate proposal received, no need to re-broadcast
1371
1417
  if (alreadyExists) {
1372
1418
  this.logger.debug(`Ignoring duplicate block proposal received`, {
@@ -1379,7 +1425,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1379
1425
  result: TopicValidatorResult.Ignore,
1380
1426
  obj: block,
1381
1427
  metadata: {
1382
- isEquivocated
1428
+ isEquivocated,
1429
+ isOversized
1383
1430
  }
1384
1431
  };
1385
1432
  }
@@ -1395,11 +1442,30 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1395
1442
  return {
1396
1443
  result: TopicValidatorResult.Reject,
1397
1444
  metadata: {
1398
- isEquivocated
1445
+ isEquivocated,
1446
+ isOversized
1399
1447
  },
1400
1448
  severity: PeerErrorSeverity.HighToleranceError
1401
1449
  };
1402
1450
  }
1451
+ // The proposal was stored: if oversized, invoke the oversized callback so the proposer can be
1452
+ // slashed. Fired alongside (not instead of) equivocation detection below.
1453
+ if (isOversized) {
1454
+ const proposer = block.getSender();
1455
+ if (proposer) {
1456
+ this.logger.warn(`Detected oversized block proposal at slot ${block.slotNumber}`, {
1457
+ ...block.toBlockInfo(),
1458
+ indexWithinCheckpoint: block.indexWithinCheckpoint,
1459
+ maxBlocksPerCheckpoint: this.config.maxBlocksPerCheckpoint,
1460
+ source: peerId.toString(),
1461
+ proposer: proposer.toString()
1462
+ });
1463
+ this.oversizedProposalCallback?.({
1464
+ slot: block.slotNumber,
1465
+ proposer
1466
+ });
1467
+ }
1468
+ }
1403
1469
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
1404
1470
  // and do re-broadcast it so other nodes in the network know to slash the proposer
1405
1471
  if (isEquivocated) {
@@ -1421,14 +1487,19 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1421
1487
  result: TopicValidatorResult.Accept,
1422
1488
  obj: block,
1423
1489
  metadata: {
1424
- isEquivocated
1490
+ isEquivocated,
1491
+ isOversized
1425
1492
  }
1426
1493
  };
1427
1494
  }
1428
1495
  // Otherwise, we're good to go!
1429
1496
  return {
1430
1497
  result: TopicValidatorResult.Accept,
1431
- obj: block
1498
+ obj: block,
1499
+ metadata: {
1500
+ isEquivocated: false,
1501
+ isOversized
1502
+ }
1432
1503
  };
1433
1504
  }
1434
1505
  // REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
@@ -1447,15 +1518,19 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1447
1518
  const isValid = await this.blockReceivedCallback(block, sender);
1448
1519
  if (!isValid) {
1449
1520
  this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1521
+ // Release the protections this proposal created so its txs return to pending. Only entries still
1522
+ // keyed to this slot are cleared, so a tx referenced by a live proposal at another slot stays protected.
1523
+ await this.mempools.txPool.unprotectTxs(block.txHashes, slot);
1450
1524
  }
1451
1525
  }
1452
1526
  /**
1453
1527
  * Handle a gossiped checkpoint proposal.
1454
1528
  * Validates and processes the checkpoint proposal, then triggers the callback for attestation.
1455
1529
  */ async handleGossipedCheckpointProposal(payloadData, msgId, source) {
1456
- const { result, obj: checkpoint, metadata: { isEquivocated, processBlock } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointProposal(source, CheckpointProposal.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_proposal);
1457
- // Process checkpoint proposal if valid and not equivocated.
1458
- const processCheckpointFn = ()=>result === TopicValidatorResult.Accept && checkpoint && !isEquivocated ? this.processValidCheckpointProposal(checkpoint.toCore(), source) : Promise.resolve();
1530
+ const { result, obj: checkpoint, metadata: { isEquivocated, processBlock, isOversized } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointProposal(source, CheckpointProposal.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_proposal);
1531
+ // An oversized checkpoint is re-broadcast as slashing evidence but never attested or processed.
1532
+ // Process checkpoint proposal if valid and neither equivocated nor oversized.
1533
+ const processCheckpointFn = ()=>result === TopicValidatorResult.Accept && checkpoint && !isEquivocated && !isOversized ? this.processValidCheckpointProposal(checkpoint.toCore(), source) : Promise.resolve();
1459
1534
  // If the checkpoint contained a valid last block, we process it even if the checkpoint itself is to be rejected
1460
1535
  // TODO(palla/mbps): Is this ok? Should we be considering a block from a checkpoint that was equivocated?
1461
1536
  const processBlockFn = ()=>processBlock && checkpoint && checkpoint.getBlockProposal() ? this.processValidBlockProposal(checkpoint.getBlockProposal(), source) : Promise.resolve();
@@ -1494,13 +1569,15 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1494
1569
  // Extract and try to add the block proposal first if present
1495
1570
  const blockProposal = checkpoint.getBlockProposal();
1496
1571
  let processBlock = false;
1572
+ let isOversized = false;
1497
1573
  if (blockProposal) {
1498
1574
  this.logger.debug(`Validating block proposal from propagated checkpoint`, {
1499
1575
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1500
1576
  [Attributes.P2P_ID]: peerId.toString()
1501
1577
  });
1502
1578
  const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1503
- const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1579
+ const { obj, metadata: { isEquivocated, isOversized: blockIsOversized } = {} } = blockProposalResult;
1580
+ isOversized = blockIsOversized ?? false;
1504
1581
  if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1505
1582
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1506
1583
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
@@ -1512,7 +1589,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1512
1589
  result: TopicValidatorResult.Reject,
1513
1590
  severity: 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError
1514
1591
  };
1515
- } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1592
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated && !isOversized) {
1593
+ // An oversized terminal block is re-broadcast as slashing evidence but never processed.
1516
1594
  processBlock = true;
1517
1595
  }
1518
1596
  }
@@ -1532,11 +1610,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1532
1610
  obj: checkpoint,
1533
1611
  metadata: {
1534
1612
  isEquivocated,
1535
- processBlock
1613
+ processBlock,
1614
+ isOversized
1536
1615
  }
1537
1616
  };
1538
1617
  }
1539
- // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1618
+ // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast.
1540
1619
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1541
1620
  if (!added) {
1542
1621
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
@@ -1549,7 +1628,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1549
1628
  obj: checkpoint,
1550
1629
  metadata: {
1551
1630
  isEquivocated,
1552
- processBlock
1631
+ processBlock,
1632
+ isOversized
1553
1633
  },
1554
1634
  severity: PeerErrorSeverity.HighToleranceError
1555
1635
  };
@@ -1576,7 +1656,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1576
1656
  obj: checkpoint,
1577
1657
  metadata: {
1578
1658
  isEquivocated,
1579
- processBlock
1659
+ processBlock,
1660
+ isOversized
1580
1661
  }
1581
1662
  };
1582
1663
  }
@@ -1586,7 +1667,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1586
1667
  obj: checkpoint,
1587
1668
  metadata: {
1588
1669
  processBlock,
1589
- isEquivocated
1670
+ isEquivocated,
1671
+ isOversized
1590
1672
  }
1591
1673
  };
1592
1674
  }
@@ -1738,10 +1820,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1738
1820
  ];
1739
1821
  const blockNumber = BlockNumber(currentBlockNumber + 1);
1740
1822
  const l1Constants = await this.archiver.getL1Constants();
1823
+ const networkTxGasLimits = getNetworkTxGasLimits(this.config, l1Constants);
1741
1824
  return createFirstStageTxValidationsForGossipedTransactions(nextSlotTimestamp, blockNumber, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings(), {
1742
- rollupManaLimit: l1Constants.rollupManaLimit,
1743
- maxBlockL2Gas: this.config.validateMaxL2BlockGas,
1744
- maxBlockDAGas: this.config.validateMaxDABlockGas
1825
+ maxTxL2Gas: networkTxGasLimits.l2Gas,
1826
+ maxTxDAGas: networkTxGasLimits.daGas
1745
1827
  });
1746
1828
  }
1747
1829
  /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */ createSecondStageMessageValidators() {
@@ -129,7 +129,20 @@ export declare class PeerManager implements PeerManagerInterface {
129
129
  shouldDisableP2PGossip(peerId: string): boolean;
130
130
  getPeers(includePending?: boolean): PeerInfo[];
131
131
  isAuthenticatedPeer(peerId: PeerId): boolean;
132
- isNodeAllowedToConnect(id: string | PeerId): boolean;
132
+ /**
133
+ * Whether a peer is allowed to connect, given its peer id. Rejects peers serving an active ban and
134
+ * peers that have exceeded the failed auth-handshake limit. Use this once the peer id is known —
135
+ * i.e. for the encrypted-inbound gater and when dialing.
136
+ */
137
+ isPeerAllowedToConnect(peerId: string | PeerId): boolean;
138
+ /**
139
+ * Whether a connection from an address is allowed. Bans are keyed by peer id, which isn't known at
140
+ * the raw-inbound layer, so only the failed auth-handshake limit (also tracked per address) is
141
+ * enforced here; the ban is applied once the peer id is known via {@link isPeerAllowedToConnect}.
142
+ */
143
+ isAddressAllowedToConnect(address: string): boolean;
144
+ /** Whether the failed auth-handshake count for a peer id or address is below the configured limit. */
145
+ private isWithinFailedAuthLimit;
133
146
  /**
134
147
  * Discovers peers.
135
148
  */
@@ -175,4 +188,4 @@ export declare class PeerManager implements PeerManagerInterface {
175
188
  handleAuthRequestFromPeer(_authRequest: AuthRequest, peerId: PeerId): Promise<StatusMessage>;
176
189
  private updateAuthenticatedPeers;
177
190
  }
178
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvcGVlci1tYW5hZ2VyL3BlZXJfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRzlELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBR2hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RixPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRS9ELE9BQU8sS0FBSyxFQUFjLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBTTVELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRCxPQUFPLEVBQUUsV0FBVyxFQUFnQixNQUFNLDhCQUE4QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxhQUFhLEVBQXVCLE1BQU0saUNBQWlDLENBQUM7QUFDckYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0QsT0FBTyxFQUFrQixLQUFLLFdBQVcsRUFBRSxNQUFNLG1C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
191
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvcGVlci1tYW5hZ2VyL3BlZXJfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBSTlELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBR2hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RixPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRS9ELE9BQU8sS0FBSyxFQUFjLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBTTVELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRCxPQUFPLEVBQUUsV0FBVyxFQUFnQixNQUFNLDhCQUE4QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxhQUFhLEVBQXVCLE1BQU0saUNBQWlDLENBQUM7QUFDckYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0QsT0FBTyxFQUFrQixLQUFLLFdBQVcsRUFBRSxNQUFNLG1C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
@@ -1 +1 @@
1
- {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAM5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAgB,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA2BrE,qBAAa,WAAY,YAAW,oBAAoB;IAyBpD,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAlC/B,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,8BAA8B,CAAa;IACnD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IACjD,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IACjD,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,qCAAqC,CAAsC;IACnF,OAAO,CAAC,qCAAqC,CAAkC;IAC/E,OAAO,CAAC,qBAAqB,CAA0B;IACvD,OAAO,CAAC,oBAAoB,CAAoD;IAChF,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,yBAAyB,CAAkB;IAEnD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAId;IAEF,YACU,UAAU,EAAE,UAAU,EACtB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACzB,eAAe,EAAE,eAAe,EACxB,MAAM,oDAAmC,EACzC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO,EACP,sBAAsB,EAAE,sBAAsB,EAC9C,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,mBAAmB,EAC/B,YAAY,GAAE,YAAiC,EAyBjE;IACD;;;;OAIG;IACG,eAAe,kBAmCpB;IAED,IAAI,MAAM,6CAET;IAEY,SAAS,kBAUrB;IAIK,2BAA2B,kBAgDhC;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,sBAAsB;YAsBhB,2BAA2B;IAsBzC;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAuBhC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAmB5B,8BAA8B,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAEjE;IAED;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAM1C;IAED;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQ1C;IAED;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAK5C;IAED;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;;OAMG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,QAM3D;IAEM,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,QAE7D;IAEM,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1C;IAEM,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD;IAEM,QAAQ,CAAC,cAAc,UAAQ,GAAG,QAAQ,EAAE,CA+BlD;IAEM,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQlD;IASM,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAa1D;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ;IAoEhB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,mBAAmB;IAsB3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;YAyBT,wBAAwB;IAgCtC,OAAO,CAAC,qBAAqB;YAYf,cAAc;YAkBd,oBAAoB;YA0EpB,QAAQ;IA4BtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,gBAAgB;YAsBV,mBAAmB;YAenB,uBAAuB;YA2CvB,qBAAqB;IA2FnC,OAAO,CAAC,uBAAuB;IAmC/B,OAAO,CAAC,wBAAwB;IAUhC;;;OAGG;IACU,IAAI,kBAWhB;IAED,OAAO,CAAC,uBAAuB;IAI/B;;;;;;;;;SASK;IACQ,yBAAyB,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAOxG;YAEa,wBAAwB;CAwBvC"}
1
+ {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { compactArray } from '@aztec/foundation/collection';
1
2
  import { makeEthSignDigest, tryRecoverAddress } from '@aztec/foundation/crypto/secp256k1-signer';
2
3
  import { Fr } from '@aztec/foundation/curves/bn254';
3
4
  import { createLogger } from '@aztec/foundation/log';
@@ -127,6 +128,7 @@ export class PeerManager {
127
128
  async heartbeat() {
128
129
  this.heartbeatCounter++;
129
130
  this.peerScoring.decayAllScores();
131
+ this.peerScoring.pruneExpiredBans();
130
132
  this.cleanupExpiredTimeouts();
131
133
  await this.setupDirectPeersIfValidator();
132
134
  await this.updateAuthenticatedPeers();
@@ -150,19 +152,27 @@ export class PeerManager {
150
152
  }
151
153
  const preferredPeersEnrs = this.config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
152
154
  await Promise.all(preferredPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.preferredPeers.add(peerId.toString()))).catch((e)=>this.logger.error('Error initializing preferred peers', e));
153
- const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
154
- const peerId = await enr.peerId();
155
- const address = enr.getLocationMultiaddr('tcp');
156
- if (address === undefined) {
157
- throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
155
+ const directPeers = compactArray(await Promise.all(preferredPeersEnrs.map(async (enr)=>{
156
+ try {
157
+ const peerId = await enr.peerId();
158
+ const address = enr.getLocationMultiaddr('tcp');
159
+ if (address === undefined) {
160
+ throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
161
+ }
162
+ return {
163
+ id: peerId,
164
+ addrs: [
165
+ address
166
+ ]
167
+ };
168
+ } catch (err) {
169
+ // A malformed configured ENR shouldn't abort preferred-peer setup — skip it and log.
170
+ this.logger.warn(`Skipping preferred peer with invalid ENR`, {
171
+ err
172
+ });
173
+ return undefined;
158
174
  }
159
- return {
160
- id: peerId,
161
- addrs: [
162
- address
163
- ]
164
- };
165
- }))).filter((peer)=>peer !== undefined);
175
+ })));
166
176
  await Promise.all(directPeers.map((peer)=>{
167
177
  this.libP2PNode.services.pubsub.direct.add(peer.id.toString());
168
178
  return this.libP2PNode.peerStore.merge(peer.id, {
@@ -390,14 +400,32 @@ export class PeerManager {
390
400
  * @param id: Address of the node or it's peerId
391
401
  *
392
402
  * @returns: True if node is allowed to connect, otherwise false
393
- * */ isNodeAllowedToConnect(id) {
394
- const entry = this.failedAuthHandshakes.get(id.toString());
403
+ * */ /**
404
+ * Whether a peer is allowed to connect, given its peer id. Rejects peers serving an active ban and
405
+ * peers that have exceeded the failed auth-handshake limit. Use this once the peer id is known —
406
+ * i.e. for the encrypted-inbound gater and when dialing.
407
+ */ isPeerAllowedToConnect(peerId) {
408
+ const id = peerId.toString();
409
+ if (this.peerScoring.getScoreState(id) === PeerScoreState.Banned) {
410
+ return false;
411
+ }
412
+ return this.isWithinFailedAuthLimit(id);
413
+ }
414
+ /**
415
+ * Whether a connection from an address is allowed. Bans are keyed by peer id, which isn't known at
416
+ * the raw-inbound layer, so only the failed auth-handshake limit (also tracked per address) is
417
+ * enforced here; the ban is applied once the peer id is known via {@link isPeerAllowedToConnect}.
418
+ */ isAddressAllowedToConnect(address) {
419
+ return this.isWithinFailedAuthLimit(address);
420
+ }
421
+ /** Whether the failed auth-handshake count for a peer id or address is below the configured limit. */ isWithinFailedAuthLimit(key) {
422
+ const entry = this.failedAuthHandshakes.get(key);
395
423
  if (!entry) {
396
424
  return true;
397
425
  }
398
426
  // In case entry is too old, remove it and allow connection
399
427
  if (this.dateProvider.now() - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
400
- this.failedAuthHandshakes.delete(id.toString());
428
+ this.failedAuthHandshakes.delete(key);
401
429
  return true;
402
430
  }
403
431
  return entry.count <= this.config.p2pMaxFailedAuthAttemptsAllowed;
@@ -572,9 +600,9 @@ export class PeerManager {
572
600
  if (this.peerScoring.getScoreState(peerIdString) != PeerScoreState.Healthy) {
573
601
  return;
574
602
  }
575
- // Don't dial peers that have exceeded the auth failure threshold
576
- if (!this.isNodeAllowedToConnect(peerId)) {
577
- this.logger.trace(`Skipping peer ${peerId} due to failed auth handshake attempts`);
603
+ // Don't dial banned peers or those that have exceeded the auth failure threshold
604
+ if (!this.isPeerAllowedToConnect(peerId)) {
605
+ this.logger.trace(`Skipping peer ${peerId} due to ban or failed auth handshake attempts`);
578
606
  return;
579
607
  }
580
608
  const [multiaddrTcp] = await Promise.all([
@@ -19,13 +19,40 @@ export declare class PeerScoring {
19
19
  [key in PeerErrorSeverity]: number;
20
20
  };
21
21
  private peerStateCounter;
22
+ /** Active bans, keyed by peer id. Held in memory only, so they are cleared on restart. */
23
+ private bannedPeers;
24
+ /**
25
+ * How long a peer remains banned once its score crosses MIN_SCORE_BEFORE_BAN. While banned, the
26
+ * peer's ban score is returned by getScore regardless of decay, so it cannot recover its way out
27
+ * of the ban early. After the ban expires the live (decayed) score takes over again.
28
+ */
29
+ private readonly banDurationMs;
22
30
  constructor(config: P2PConfig, telemetry?: TelemetryClient, dateProvider?: DateProvider);
23
31
  penalizePeer(peerId: PeerId, penalty: PeerErrorSeverity): number;
24
32
  updateScore(peerId: string, scoreDelta: number): number;
33
+ /**
34
+ * Records a ban for a peer whose score has crossed the ban threshold, with an expiry banDurationMs
35
+ * in the future. No-op if the score is above the threshold or the peer is already serving an active
36
+ * ban (an existing ban is not extended; the original window stands). A previously expired ban does
37
+ * not block a fresh one — getActiveBanScore prunes it first.
38
+ */
39
+ private maybeBanPeer;
25
40
  decayAllScores(): void;
41
+ /**
42
+ * Removes bans whose window has elapsed. Expired bans are otherwise only pruned lazily when their
43
+ * peer's score is next queried, so a banned peer that disconnects and is never queried again would
44
+ * linger in the map. Called periodically (per heartbeat) to bound the ban map's size.
45
+ */
46
+ pruneExpiredBans(): void;
26
47
  /** Resets all peer scores. Useful for benchmarks to prevent cross-case contamination. */
27
48
  resetAllScores(): void;
28
49
  removePeer(peerId: string): void;
50
+ /**
51
+ * The single source of truth for whether a peer is banned. Returns the ban score while the ban is
52
+ * active, or undefined if the peer is not banned. A ban that has expired is lazily lifted before
53
+ * returning undefined, so callers never see a stale ban.
54
+ */
55
+ private getActiveBanScore;
29
56
  getScore(peerId: string): number;
30
57
  getScoreState(peerId: string): PeerScoreState;
31
58
  getStats(): {
@@ -35,4 +62,4 @@ export declare class PeerScoring {
35
62
  bannedCount: number;
36
63
  };
37
64
  }
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9zY29yaW5nLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvcGVlci1tYW5hZ2VyL3BlZXJfc2NvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUdMLEtBQUssZUFBZSxFQUlyQixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWhELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBdUJqRCxvQkFBWSxjQUFjO0lBQ3hCLE1BQU0sSUFBQTtJQUNOLFVBQVUsSUFBQTtJQUNWLE9BQU8sSUFBQTtDQUNSO0FBaUJELHFCQUFhLFdBQVc7SUFhcEIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxZQUFZO0lBWi9CLE9BQU8sQ0FBQyxNQUFNLENBQW9DO0lBQ2xELE9BQU8sQ0FBQyxNQUFNLENBQWtDO0lBQ2hELE9BQU8sQ0FBQyxjQUFjLENBQWtDO0lBQ3hELE9BQU8sQ0FBQyxhQUFhLENBQWE7SUFDbEMsT0FBTyxDQUFDLFdBQVcsQ0FBTztJQUMxQixhQUFhLEVBQUU7U0FBRyxHQUFHLElBQUksaUJBQWlCLEdBQUcsTUFBTTtLQUFFLENBQUM7SUFFdEQsT0FBTyxDQUFDLGdCQUFnQixDQUFnQjtJQUV4QyxZQUNFLE1BQU0sRUFBRSxTQUFTLEVBQ2pCLFNBQVMsR0FBRSxlQUFzQyxFQUNoQyxZQUFZLEdBQUUsWUFBaUMsRUFpQmpFO0lBRU0sWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixVQU03RDtJQUVELFdBQVcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEdBQUcsTUFBTSxDQWlCdEQ7SUFFRCxjQUFjLElBQUksSUFBSSxDQWlCckI7SUFFRCx5RkFBeUY7SUFDekYsY0FBYyxJQUFJLElBQUksQ0FHckI7SUFFRCxVQUFVLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBRy9CO0lBRUQsUUFBUSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsTUFBTSxDQUUvQjtJQUVNLGFBQWEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLGNBQWMsQ0FVbkQ7SUFFRCxRQUFRLElBQUk7UUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDO1FBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQztRQUFDLGVBQWUsRUFBRSxNQUFNLENBQUM7UUFBQyxXQUFXLEVBQUUsTUFBTSxDQUFBO0tBQUUsQ0E0QnRHO0NBQ0YifQ==
65
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9zY29yaW5nLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvcGVlci1tYW5hZ2VyL3BlZXJfc2NvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUdMLEtBQUssZUFBZSxFQUlyQixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWhELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBdUJqRCxvQkFBWSxjQUFjO0lBQ3hCLE1BQU0sSUFBQTtJQUNOLFVBQVUsSUFBQTtJQUNWLE9BQU8sSUFBQTtDQUNSO0FBb0JELHFCQUFhLFdBQVc7SUFzQnBCLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWTtJQXJCL0IsT0FBTyxDQUFDLE1BQU0sQ0FBb0M7SUFDbEQsT0FBTyxDQUFDLE1BQU0sQ0FBa0M7SUFDaEQsT0FBTyxDQUFDLGNBQWMsQ0FBa0M7SUFDeEQsT0FBTyxDQUFDLGFBQWEsQ0FBYTtJQUNsQyxPQUFPLENBQUMsV0FBVyxDQUFPO0lBQzFCLGFBQWEsRUFBRTtTQUFHLEdBQUcsSUFBSSxpQkFBaUIsR0FBRyxNQUFNO0tBQUUsQ0FBQztJQUV0RCxPQUFPLENBQUMsZ0JBQWdCLENBQWdCO0lBRXhDLDBGQUEwRjtJQUMxRixPQUFPLENBQUMsV0FBVyxDQUFxQztJQUN4RDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQVM7SUFFdkMsWUFDRSxNQUFNLEVBQUUsU0FBUyxFQUNqQixTQUFTLEdBQUUsZUFBc0MsRUFDaEMsWUFBWSxHQUFFLFlBQWlDLEVBa0JqRTtJQUVNLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsVUFNN0Q7SUFFRCxXQUFXLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FvQnREO0lBRUQ7Ozs7O09BS0c7SUFDSCxPQUFPLENBQUMsWUFBWTtJQWFwQixjQUFjLElBQUksSUFBSSxDQWlCckI7SUFFRDs7OztPQUlHO0lBQ0gsZ0JBQWdCLElBQUksSUFBSSxDQU12QjtJQUVELHlGQUF5RjtJQUN6RixjQUFjLElBQUksSUFBSSxDQUlyQjtJQUVELFVBQVUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FHL0I7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLGlCQUFpQjtJQWF6QixRQUFRLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxNQUFNLENBSS9CO0lBRU0sYUFBYSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsY0FBYyxDQVduRDtJQUVELFFBQVEsSUFBSTtRQUFFLFdBQVcsRUFBRSxNQUFNLENBQUM7UUFBQyxZQUFZLEVBQUUsTUFBTSxDQUFDO1FBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQztRQUFDLFdBQVcsRUFBRSxNQUFNLENBQUE7S0FBRSxDQThCdEc7Q0FDRiJ9