@aztec/p2p 0.0.1-commit.dbf9cec → 0.0.1-commit.df81a97b5

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 (217) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +2 -2
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +21 -8
  5. package/dest/client/p2p_client.d.ts +1 -1
  6. package/dest/client/p2p_client.d.ts.map +1 -1
  7. package/dest/client/p2p_client.js +22 -34
  8. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +3 -3
  9. package/dest/config.d.ts +32 -11
  10. package/dest/config.d.ts.map +1 -1
  11. package/dest/config.js +86 -32
  12. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
  13. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  14. package/dest/mem_pools/attestation_pool/attestation_pool.js +8 -4
  15. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  16. package/dest/mem_pools/instrumentation.d.ts +4 -2
  17. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  18. package/dest/mem_pools/instrumentation.js +16 -14
  19. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  20. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  21. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +2 -1
  22. package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
  23. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  24. package/dest/mem_pools/tx_pool/priority.js +4 -4
  25. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  26. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  27. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
  28. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  29. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  30. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +2 -1
  31. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
  32. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  33. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
  34. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  35. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
  36. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
  37. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  38. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
  39. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +9 -5
  40. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  42. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +25 -10
  43. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +33 -10
  45. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  46. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -43
  48. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
  49. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  50. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +6 -0
  51. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -1
  52. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +24 -6
  54. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
  55. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  56. package/dest/msg_validators/attestation_validator/attestation_validator.js +5 -4
  57. package/dest/msg_validators/clock_tolerance.d.ts +1 -1
  58. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  59. package/dest/msg_validators/clock_tolerance.js +4 -3
  60. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  61. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  62. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  63. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  64. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  65. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  66. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  67. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  68. package/dest/msg_validators/proposal_validator/proposal_validator.js +53 -41
  69. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  70. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  71. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  72. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  73. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  74. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  75. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  76. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  77. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  78. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  79. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  80. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  81. package/dest/msg_validators/tx_validator/factory.d.ts +23 -4
  82. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  83. package/dest/msg_validators/tx_validator/factory.js +36 -10
  84. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  85. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  86. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  87. package/dest/msg_validators/tx_validator/gas_validator.d.ts +13 -4
  88. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  89. package/dest/msg_validators/tx_validator/gas_validator.js +39 -9
  90. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  91. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  92. package/dest/msg_validators/tx_validator/index.js +1 -0
  93. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  94. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  96. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  97. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  99. package/dest/services/encoding.d.ts +5 -1
  100. package/dest/services/encoding.d.ts.map +1 -1
  101. package/dest/services/encoding.js +7 -1
  102. package/dest/services/libp2p/libp2p_service.d.ts +4 -9
  103. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  104. package/dest/services/libp2p/libp2p_service.js +130 -68
  105. package/dest/services/peer-manager/metrics.d.ts +3 -1
  106. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  107. package/dest/services/peer-manager/metrics.js +6 -0
  108. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  109. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  110. package/dest/services/peer-manager/peer_manager.js +6 -3
  111. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
  112. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  113. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +69 -65
  114. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
  115. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  116. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  117. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  118. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  119. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
  120. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  121. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
  122. package/dest/services/reqresp/reqresp.d.ts +1 -1
  123. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  124. package/dest/services/reqresp/reqresp.js +17 -9
  125. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
  126. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  127. package/dest/services/tx_collection/fast_tx_collection.js +57 -73
  128. package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
  129. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  130. package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
  131. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  132. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  133. package/dest/services/tx_collection/request_tracker.js +84 -0
  134. package/dest/services/tx_collection/slow_tx_collection.js +1 -1
  135. package/dest/services/tx_collection/tx_collection.d.ts +3 -6
  136. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  137. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  138. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  139. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  140. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  141. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  142. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  143. package/dest/test-helpers/testbench-utils.js +22 -3
  144. package/dest/testbench/p2p_client_testbench_worker.js +5 -4
  145. package/dest/testbench/worker_client_manager.d.ts +3 -1
  146. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  147. package/dest/testbench/worker_client_manager.js +6 -2
  148. package/dest/util.d.ts +1 -1
  149. package/package.json +14 -14
  150. package/src/client/factory.ts +36 -12
  151. package/src/client/p2p_client.ts +22 -34
  152. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +4 -6
  153. package/src/config.ts +124 -34
  154. package/src/mem_pools/attestation_pool/attestation_pool.ts +8 -7
  155. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  156. package/src/mem_pools/instrumentation.ts +17 -13
  157. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +2 -1
  158. package/src/mem_pools/tx_pool/priority.ts +4 -4
  159. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
  160. package/src/mem_pools/tx_pool_v2/README.md +9 -1
  161. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -1
  162. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
  163. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
  164. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
  165. package/src/mem_pools/tx_pool_v2/interfaces.ts +9 -4
  166. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +52 -12
  167. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
  168. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +16 -1
  169. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +28 -6
  170. package/src/msg_validators/attestation_validator/README.md +49 -0
  171. package/src/msg_validators/attestation_validator/attestation_validator.ts +5 -4
  172. package/src/msg_validators/clock_tolerance.ts +4 -3
  173. package/src/msg_validators/proposal_validator/README.md +123 -0
  174. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
  175. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
  176. package/src/msg_validators/proposal_validator/proposal_validator.ts +69 -45
  177. package/src/msg_validators/tx_validator/README.md +5 -1
  178. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  179. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  180. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  181. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  182. package/src/msg_validators/tx_validator/factory.ts +43 -3
  183. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  184. package/src/msg_validators/tx_validator/gas_validator.ts +41 -8
  185. package/src/msg_validators/tx_validator/index.ts +1 -0
  186. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  187. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  188. package/src/services/encoding.ts +9 -1
  189. package/src/services/libp2p/libp2p_service.ts +122 -75
  190. package/src/services/peer-manager/metrics.ts +7 -0
  191. package/src/services/peer-manager/peer_manager.ts +7 -3
  192. package/src/services/reqresp/README.md +229 -0
  193. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  194. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +64 -69
  195. package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
  196. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  197. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
  198. package/src/services/reqresp/reqresp.ts +19 -11
  199. package/src/services/tx_collection/fast_tx_collection.ts +57 -83
  200. package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
  201. package/src/services/tx_collection/request_tracker.ts +127 -0
  202. package/src/services/tx_collection/slow_tx_collection.ts +1 -1
  203. package/src/services/tx_collection/tx_collection.ts +3 -5
  204. package/src/test-helpers/make-test-p2p-clients.ts +1 -1
  205. package/src/test-helpers/reqresp-nodes.ts +1 -1
  206. package/src/test-helpers/testbench-utils.ts +29 -3
  207. package/src/testbench/p2p_client_testbench_worker.ts +5 -6
  208. package/src/testbench/worker_client_manager.ts +13 -5
  209. package/src/util.ts +1 -1
  210. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  211. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  212. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  213. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  214. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  215. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  216. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
  217. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
@@ -1,5 +1,6 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { maxBy } from '@aztec/foundation/collection';
3
4
  import { Fr } from '@aztec/foundation/curves/bn254';
4
5
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
5
6
  import { RunningPromise } from '@aztec/foundation/running-promise';
@@ -17,8 +18,8 @@ import {
17
18
  type CheckpointProposalCore,
18
19
  type Gossipable,
19
20
  P2PMessage,
20
- type ValidationResult as P2PValidationResult,
21
21
  PeerErrorSeverity,
22
+ PeerErrorSeverityByHarshness,
22
23
  TopicType,
23
24
  createTopicString,
24
25
  getTopicsForConfig,
@@ -129,7 +130,7 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
129
130
  // REFACTOR: Unify with the type above
130
131
  type ReceivedMessageValidationResult<T, M = undefined> =
131
132
  | { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
132
- | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
133
+ | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
133
134
 
134
135
  /**
135
136
  * Lib P2P implementation of the P2PService interface.
@@ -222,10 +223,12 @@ export class LibP2PService extends WithTracer implements P2PService {
222
223
  this.protocolVersion,
223
224
  );
224
225
 
225
- this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
226
- this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
226
+ const proposalValidatorOpts = {
227
227
  txsPermitted: !config.disableTransactions,
228
- });
228
+ maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
229
+ };
230
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
231
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
229
232
  this.checkpointAttestationValidator = config.fishermanMode
230
233
  ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
231
234
  : new CheckpointAttestationValidator(epochCache);
@@ -233,11 +236,11 @@ export class LibP2PService extends WithTracer implements P2PService {
233
236
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
234
237
 
235
238
  this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
236
- this.logger.debug(
237
- `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
239
+ this.logger.warn(
240
+ `Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`,
238
241
  { p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
239
242
  );
240
- return false;
243
+ return true;
241
244
  };
242
245
 
243
246
  this.checkpointReceivedCallback = (
@@ -750,6 +753,9 @@ export class LibP2PService extends WithTracer implements P2PService {
750
753
  if (!validator || !validator.addMessage(msgId)) {
751
754
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
752
755
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
756
+ if (topicType === TopicType.tx) {
757
+ this.logger.verbose(`Ignoring already-seen tx gossip message`, { msgId, source: source.toString() });
758
+ }
753
759
  return { result: false, topicType };
754
760
  }
755
761
 
@@ -876,30 +882,56 @@ export class LibP2PService extends WithTracer implements P2PService {
876
882
  source: PeerId,
877
883
  topicType: TopicType,
878
884
  ): Promise<ReceivedMessageValidationResult<T, M>> {
879
- let resultAndObj: ReceivedMessageValidationResult<T, M> = { result: TopicValidatorResult.Reject };
885
+ // Default to reject result with a penalty if validation function throws an error
886
+ let resultAndObj: ReceivedMessageValidationResult<T, M> = {
887
+ result: TopicValidatorResult.Reject,
888
+ severity: PeerErrorSeverity.MidToleranceError,
889
+ };
880
890
  const timer = new Timer();
881
891
  try {
882
892
  resultAndObj = await validationFunc();
883
893
  } catch (err) {
884
- this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
885
- this.logger.error(`Error deserializing and validating gossipsub message`, err, {
886
- msgId,
887
- source: source.toString(),
888
- topicType,
889
- });
894
+ this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
890
895
  }
891
896
 
892
897
  if (resultAndObj.result === TopicValidatorResult.Accept) {
898
+ this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
893
899
  this.instrumentation.recordMessageValidation(topicType, timer);
900
+ } else if (resultAndObj.result === TopicValidatorResult.Reject) {
901
+ this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
902
+ msgId,
903
+ source: source.toString(),
904
+ topicType,
905
+ severity: resultAndObj.severity,
906
+ });
907
+ this.peerManager.penalizePeer(source, resultAndObj.severity);
908
+ } else {
909
+ this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
894
910
  }
895
911
 
896
912
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
897
913
  return resultAndObj;
898
914
  }
899
915
 
916
+ private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
917
+ try {
918
+ return deserializeFunc();
919
+ } catch (err) {
920
+ this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
921
+ err,
922
+ msgId,
923
+ source: source.toString(),
924
+ });
925
+ return undefined;
926
+ }
927
+ }
928
+
900
929
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
901
930
  const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
902
- const tx = Tx.fromBuffer(payloadData);
931
+ const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
932
+ if (!tx) {
933
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
934
+ }
903
935
 
904
936
  const currentBlockNumber = await this.archiver.getBlockNumber();
905
937
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
@@ -919,13 +951,20 @@ export class LibP2PService extends WithTracer implements P2PService {
919
951
  severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
920
952
  }
921
953
 
922
- this.peerManager.penalizePeer(source, severity);
923
- return { result: TopicValidatorResult.Reject };
954
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
955
+ validator: name,
956
+ severity,
957
+ source: source.toString(),
958
+ });
959
+ return { result: TopicValidatorResult.Reject, severity };
924
960
  }
925
961
 
926
962
  // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
927
963
  const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
928
964
  if (canAdd === 'ignored') {
965
+ this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
966
+ source: source.toString(),
967
+ });
929
968
  return { result: TopicValidatorResult.Ignore, obj: tx };
930
969
  }
931
970
 
@@ -933,9 +972,13 @@ export class LibP2PService extends WithTracer implements P2PService {
933
972
  const secondStageValidators = this.createSecondStageMessageValidators();
934
973
  const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
935
974
  if (!secondStageOutcome.allPassed) {
936
- const { severity } = secondStageOutcome.failure;
937
- this.peerManager.penalizePeer(source, severity);
938
- return { result: TopicValidatorResult.Reject };
975
+ const { severity, name } = secondStageOutcome.failure;
976
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
977
+ validator: name,
978
+ severity,
979
+ source: source.toString(),
980
+ });
981
+ return { result: TopicValidatorResult.Reject, severity };
939
982
  }
940
983
 
941
984
  // Pool add: persist the tx
@@ -945,7 +988,7 @@ export class LibP2PService extends WithTracer implements P2PService {
945
988
  const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
946
989
  const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
947
990
 
948
- this.logger.trace(`Validate propagated tx`, {
991
+ this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
949
992
  wasAccepted,
950
993
  wasIgnored,
951
994
  [Attributes.P2P_ID]: source.toString(),
@@ -956,7 +999,11 @@ export class LibP2PService extends WithTracer implements P2PService {
956
999
  } else if (wasIgnored) {
957
1000
  return { result: TopicValidatorResult.Ignore, obj: tx };
958
1001
  } else {
959
- return { result: TopicValidatorResult.Reject };
1002
+ this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
1003
+ source: source.toString(),
1004
+ txHash: txHash.toString(),
1005
+ });
1006
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
960
1007
  }
961
1008
  };
962
1009
 
@@ -986,7 +1033,16 @@ export class LibP2PService extends WithTracer implements P2PService {
986
1033
  source: PeerId,
987
1034
  ): Promise<void> {
988
1035
  const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
989
- () => this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)),
1036
+ () => {
1037
+ const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
1038
+ if (!attestation) {
1039
+ return Promise.resolve({
1040
+ result: TopicValidatorResult.Reject,
1041
+ severity: PeerErrorSeverity.LowToleranceError,
1042
+ });
1043
+ }
1044
+ return this.validateAndStoreCheckpointAttestation(source, attestation);
1045
+ },
990
1046
  msgId,
991
1047
  source,
992
1048
  TopicType.checkpoint_attestation,
@@ -1019,8 +1075,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1019
1075
 
1020
1076
  if (validationResult.result === 'reject') {
1021
1077
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1022
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1023
- return { result: TopicValidatorResult.Reject };
1078
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1024
1079
  }
1025
1080
 
1026
1081
  if (validationResult.result === 'ignore') {
@@ -1046,16 +1101,16 @@ export class LibP2PService extends WithTracer implements P2PService {
1046
1101
  return { result: TopicValidatorResult.Ignore, obj: attestation };
1047
1102
  }
1048
1103
 
1049
- // Could not add (cap reached for signer), no need to re-broadcast
1104
+ // Could not add (cap reached for signer), penalize and do not re-broadcast
1050
1105
  if (!added) {
1051
- this.logger.warn(`Dropping checkpoint attestation due to cap`, {
1106
+ this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
1052
1107
  slot: slot.toString(),
1053
1108
  archive: attestation.archive.toString(),
1054
1109
  source: peerId.toString(),
1055
1110
  attester: attestation.getSender()?.toString(),
1056
1111
  count,
1057
1112
  });
1058
- return { result: TopicValidatorResult.Ignore, obj: attestation };
1113
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
1059
1114
  }
1060
1115
 
1061
1116
  // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
@@ -1110,8 +1165,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1110
1165
 
1111
1166
  if (validationResult.result === 'reject') {
1112
1167
  this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
1113
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1114
- return { result: TopicValidatorResult.Reject };
1168
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1115
1169
  }
1116
1170
 
1117
1171
  if (validationResult.result === 'ignore') {
@@ -1135,7 +1189,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1135
1189
 
1136
1190
  // Too many blocks received for this slot and index, penalize peer and do not re-broadcast
1137
1191
  if (!added) {
1138
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1139
1192
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1140
1193
  ...block.toBlockInfo(),
1141
1194
  indexWithinCheckpoint: block.indexWithinCheckpoint,
@@ -1143,7 +1196,11 @@ export class LibP2PService extends WithTracer implements P2PService {
1143
1196
  proposer: block.getSender()?.toString(),
1144
1197
  source: peerId.toString(),
1145
1198
  });
1146
- return { result: TopicValidatorResult.Reject, metadata: { isEquivocated } };
1199
+ return {
1200
+ result: TopicValidatorResult.Reject,
1201
+ metadata: { isEquivocated },
1202
+ severity: PeerErrorSeverity.HighToleranceError,
1203
+ };
1147
1204
  }
1148
1205
 
1149
1206
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1188,7 +1245,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1188
1245
  // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1189
1246
  const isValid = await this.blockReceivedCallback(block, sender);
1190
1247
  if (!isValid) {
1191
- this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1248
+ this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1192
1249
  }
1193
1250
  }
1194
1251
 
@@ -1236,8 +1293,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1236
1293
 
1237
1294
  if (validationResult.result === 'reject') {
1238
1295
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1239
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1240
- return { result: TopicValidatorResult.Reject };
1296
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1241
1297
  }
1242
1298
 
1243
1299
  if (validationResult.result === 'ignore') {
@@ -1252,20 +1308,21 @@ export class LibP2PService extends WithTracer implements P2PService {
1252
1308
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1253
1309
  [Attributes.P2P_ID]: peerId.toString(),
1254
1310
  });
1255
- const {
1256
- result,
1257
- obj,
1258
- metadata: { isEquivocated } = {},
1259
- } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1260
- if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1311
+ const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1312
+ const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1313
+ if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1261
1314
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1262
1315
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1263
1316
  [Attributes.P2P_ID]: peerId.toString(),
1264
1317
  isEquivocated,
1265
- result,
1318
+ result: blockProposalResult.result,
1266
1319
  });
1267
- return { result: TopicValidatorResult.Reject };
1268
- } else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1320
+ return {
1321
+ result: TopicValidatorResult.Reject,
1322
+ severity:
1323
+ 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
1324
+ };
1325
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1269
1326
  processBlock = true;
1270
1327
  }
1271
1328
  }
@@ -1292,13 +1349,17 @@ export class LibP2PService extends WithTracer implements P2PService {
1292
1349
  // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1293
1350
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1294
1351
  if (!added) {
1295
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1296
1352
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1297
1353
  ...checkpoint.toCheckpointInfo(),
1298
1354
  count,
1299
1355
  source: peerId.toString(),
1300
1356
  });
1301
- return { result: TopicValidatorResult.Reject, obj: checkpoint, metadata: { isEquivocated, processBlock } };
1357
+ return {
1358
+ result: TopicValidatorResult.Reject,
1359
+ obj: checkpoint,
1360
+ metadata: { isEquivocated, processBlock },
1361
+ severity: PeerErrorSeverity.HighToleranceError,
1362
+ };
1302
1363
  }
1303
1364
 
1304
1365
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1617,8 +1678,12 @@ export class LibP2PService extends WithTracer implements P2PService {
1617
1678
  nextSlotTimestamp: UInt64,
1618
1679
  ): Promise<Record<string, TransactionValidator>> {
1619
1680
  const gasFees = await this.getGasFees(currentBlockNumber);
1620
- const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
1681
+ const allowedInSetup = [
1682
+ ...(await getDefaultAllowedSetupFunctions()),
1683
+ ...(this.config.txPublicSetupAllowListExtend ?? []),
1684
+ ];
1621
1685
  const blockNumber = BlockNumber(currentBlockNumber + 1);
1686
+ const l1Constants = await this.archiver.getL1Constants();
1622
1687
 
1623
1688
  return createFirstStageTxValidationsForGossipedTransactions(
1624
1689
  nextSlotTimestamp,
@@ -1632,6 +1697,11 @@ export class LibP2PService extends WithTracer implements P2PService {
1632
1697
  !this.config.disableTransactions,
1633
1698
  allowedInSetup,
1634
1699
  this.logger.getBindings(),
1700
+ {
1701
+ rollupManaLimit: l1Constants.rollupManaLimit,
1702
+ maxBlockL2Gas: this.config.validateMaxL2BlockGas,
1703
+ maxBlockDAGas: this.config.validateMaxDABlockGas,
1704
+ },
1635
1705
  );
1636
1706
  }
1637
1707
 
@@ -1657,8 +1727,10 @@ export class LibP2PService extends WithTracer implements P2PService {
1657
1727
 
1658
1728
  // A promise that resolves when all validations have been run
1659
1729
  const allValidations = await Promise.all(validationPromises);
1660
- const failed = allValidations.find(x => !x.isValid);
1661
- if (failed) {
1730
+ const failures = allValidations.filter(x => !x.isValid);
1731
+ if (failures.length > 0) {
1732
+ // Pick the most severe failure (lowest tolerance = harshest penalty)
1733
+ const failed = maxBy(failures, f => PeerErrorSeverityByHarshness.indexOf(f.severity))!;
1662
1734
  return {
1663
1735
  allPassed: false,
1664
1736
  failure: {
@@ -1711,31 +1783,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1711
1783
  return PeerErrorSeverity.HighToleranceError;
1712
1784
  }
1713
1785
 
1714
- /**
1715
- * Validate a checkpoint attestation.
1716
- *
1717
- * @param attestation - The checkpoint attestation to validate.
1718
- * @returns True if the checkpoint attestation is valid, false otherwise.
1719
- */
1720
- @trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
1721
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1722
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1723
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1724
- }))
1725
- public async validateCheckpointAttestation(
1726
- peerId: PeerId,
1727
- attestation: CheckpointAttestation,
1728
- ): Promise<P2PValidationResult> {
1729
- const result = await this.checkpointAttestationValidator.validate(attestation);
1730
-
1731
- if (result.result === 'reject') {
1732
- this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1733
- this.peerManager.penalizePeer(peerId, result.severity);
1734
- }
1735
-
1736
- return result;
1737
- }
1738
-
1739
1786
  public getPeerScore(peerId: PeerId): number {
1740
1787
  return this.node.services.pubsub.score.score(peerId.toString());
1741
1788
  }
@@ -18,6 +18,7 @@ export class PeerManagerMetrics {
18
18
  private sentGoodbyes: UpDownCounter;
19
19
  private receivedGoodbyes: UpDownCounter;
20
20
  private peerCount: Gauge;
21
+ private healthyPeerCount: Gauge;
21
22
  private lowScoreDisconnects: UpDownCounter;
22
23
  private peerConnectionDuration: Histogram;
23
24
 
@@ -49,6 +50,7 @@ export class PeerManagerMetrics {
49
50
  goodbyeReasonAttrs,
50
51
  );
51
52
  this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT);
53
+ this.healthyPeerCount = meter.createGauge(Metrics.PEER_MANAGER_HEALTHY_PEER_COUNT);
52
54
  this.lowScoreDisconnects = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_LOW_SCORE_DISCONNECTS, {
53
55
  [Attributes.P2P_PEER_SCORE_STATE]: ['Banned', 'Disconnect'],
54
56
  });
@@ -67,6 +69,10 @@ export class PeerManagerMetrics {
67
69
  this.peerCount.record(count);
68
70
  }
69
71
 
72
+ public recordHealthyPeerCount(count: number) {
73
+ this.healthyPeerCount.record(count);
74
+ }
75
+
70
76
  public recordLowScoreDisconnect(scoreState: 'Banned' | 'Disconnect') {
71
77
  this.lowScoreDisconnects.add(1, { [Attributes.P2P_PEER_SCORE_STATE]: scoreState });
72
78
  }
@@ -79,6 +85,7 @@ export class PeerManagerMetrics {
79
85
  const connectedAt = this.peerConnectedAt.get(id.toString());
80
86
  if (connectedAt) {
81
87
  this.peerConnectionDuration.record(Date.now() - connectedAt);
88
+ this.peerConnectedAt.delete(id.toString());
82
89
  }
83
90
  }
84
91
  }
@@ -32,7 +32,7 @@ import { PeerScoreState, type PeerScoring } from './peer_scoring.js';
32
32
  const MAX_DIAL_ATTEMPTS = 3;
33
33
  const MAX_CACHED_PEERS = 100;
34
34
  const MAX_CACHED_PEER_AGE_MS = 5 * 60 * 1000; // 5 minutes
35
- const FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
35
+ const DEFAULT_FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
36
36
  const GOODBYE_DIAL_TIMEOUT_MS = 1000;
37
37
  const FAILED_AUTH_HANDSHAKE_EXPIRY_MS = 60 * 60 * 1000; // 1 hour
38
38
 
@@ -515,7 +515,8 @@ export class PeerManager implements PeerManagerInterface {
515
515
  ...this.peerScoring.getStats(),
516
516
  });
517
517
 
518
- this.metrics.recordPeerCount(healthyConnections.length);
518
+ this.metrics.recordPeerCount(connections.length);
519
+ this.metrics.recordHealthyPeerCount(healthyConnections.length);
519
520
 
520
521
  // Exit if no peers to connect
521
522
  if (peersToConnect <= 0) {
@@ -775,7 +776,8 @@ export class PeerManager implements PeerManagerInterface {
775
776
  // Add to timed out peers
776
777
  this.timedOutPeers.set(id, {
777
778
  peerId: id,
778
- timeoutUntilMs: this.dateProvider.now() + FAILED_PEER_BAN_TIME_MS,
779
+ timeoutUntilMs:
780
+ this.dateProvider.now() + (this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS),
779
781
  });
780
782
  }
781
783
  }
@@ -937,6 +939,8 @@ export class PeerManager implements PeerManagerInterface {
937
939
  `Received auth for validator ${sender.toString()} from peer ${peerIdString}, but this validator is already authenticated to peer ${peerForAddress.toString()}`,
938
940
  { ...logData, address: sender.toString() },
939
941
  );
942
+ this.markAuthHandshakeFailed(peerId);
943
+ this.markPeerForDisconnect(peerId);
940
944
  return;
941
945
  }
942
946