@aztec/p2p 0.0.1-commit.10bd49492 → 0.0.1-commit.11bf3dd6e

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 (283) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +1 -1
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +23 -15
  5. package/dest/client/interface.d.ts +9 -2
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +3 -2
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +40 -14
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +17 -6
  11. package/dest/config.d.ts +107 -97
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +19 -4
  14. package/dest/errors/p2p-service.error.d.ts +9 -0
  15. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  16. package/dest/errors/p2p-service.error.js +10 -0
  17. package/dest/index.d.ts +1 -2
  18. package/dest/index.d.ts.map +1 -1
  19. package/dest/index.js +0 -1
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +7 -5
  21. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  22. package/dest/mem_pools/attestation_pool/attestation_pool.js +11 -8
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  24. package/dest/mem_pools/index.d.ts +1 -2
  25. package/dest/mem_pools/index.d.ts.map +1 -1
  26. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  27. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +2 -1
  29. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  30. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +7 -5
  31. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  32. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +9 -2
  33. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -3
  35. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
  36. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +3 -0
  38. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
  39. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +11 -4
  41. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +5 -2
  42. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  43. package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
  44. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -2
  45. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  47. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  48. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  49. package/dest/msg_validators/clock_tolerance.js +54 -3
  50. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +2 -1
  51. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  52. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +2 -1
  53. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  54. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -1
  55. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  56. package/dest/msg_validators/proposal_validator/proposal_validator.js +19 -11
  57. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  58. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  59. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  60. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  61. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  62. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  63. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  64. package/dest/msg_validators/tx_validator/factory.d.ts +9 -1
  65. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  66. package/dest/msg_validators/tx_validator/factory.js +23 -4
  67. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  68. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  69. package/dest/msg_validators/tx_validator/gas_validator.js +11 -9
  70. package/dest/msg_validators/tx_validator/phases_validator.d.ts +21 -1
  71. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  72. package/dest/msg_validators/tx_validator/phases_validator.js +28 -1
  73. package/dest/services/data_store.d.ts +1 -1
  74. package/dest/services/data_store.d.ts.map +1 -1
  75. package/dest/services/data_store.js +5 -5
  76. package/dest/services/dummy_service.d.ts +6 -3
  77. package/dest/services/dummy_service.d.ts.map +1 -1
  78. package/dest/services/dummy_service.js +6 -1
  79. package/dest/services/encoding.d.ts +5 -1
  80. package/dest/services/encoding.d.ts.map +1 -1
  81. package/dest/services/encoding.js +7 -1
  82. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  83. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  84. package/dest/services/gossipsub/topic_score_params.js +21 -4
  85. package/dest/services/libp2p/libp2p_service.d.ts +15 -25
  86. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  87. package/dest/services/libp2p/libp2p_service.js +121 -112
  88. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  89. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  90. package/dest/services/peer-manager/peer_manager.js +37 -10
  91. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  92. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  93. package/dest/services/peer-manager/peer_scoring.js +32 -10
  94. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
  95. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  96. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +69 -65
  97. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
  98. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  99. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  100. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  101. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  102. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
  103. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  104. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
  105. package/dest/services/reqresp/config.d.ts +3 -3
  106. package/dest/services/reqresp/config.d.ts.map +1 -1
  107. package/dest/services/reqresp/interface.d.ts +14 -9
  108. package/dest/services/reqresp/interface.d.ts.map +1 -1
  109. package/dest/services/reqresp/interface.js +10 -11
  110. package/dest/services/reqresp/metrics.d.ts +1 -1
  111. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  112. package/dest/services/reqresp/metrics.js +0 -1
  113. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  114. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  115. package/dest/services/reqresp/protocols/index.js +0 -1
  116. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  117. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  118. package/dest/services/reqresp/protocols/tx.js +1 -3
  119. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  120. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  121. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  122. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  123. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  124. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  125. package/dest/services/reqresp/reqresp.d.ts +4 -2
  126. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  127. package/dest/services/reqresp/reqresp.js +28 -11
  128. package/dest/services/service.d.ts +5 -2
  129. package/dest/services/service.d.ts.map +1 -1
  130. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
  131. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  132. package/dest/services/tx_collection/fast_tx_collection.js +57 -73
  133. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  134. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  135. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  136. package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
  137. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  138. package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
  139. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  140. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  141. package/dest/services/tx_collection/request_tracker.js +84 -0
  142. package/dest/services/tx_collection/slow_tx_collection.js +1 -1
  143. package/dest/services/tx_collection/tx_collection.d.ts +3 -6
  144. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  145. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  146. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  147. package/dest/services/tx_collection/tx_source.js +9 -7
  148. package/dest/test-helpers/mock-pubsub.d.ts +11 -3
  149. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  150. package/dest/test-helpers/mock-pubsub.js +35 -10
  151. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  152. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  153. package/dest/test-helpers/reqresp-nodes.js +1 -2
  154. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  155. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  156. package/dest/test-helpers/testbench-utils.js +21 -2
  157. package/dest/testbench/p2p_client_testbench_worker.js +66 -15
  158. package/dest/testbench/worker_client_manager.d.ts +8 -1
  159. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  160. package/dest/testbench/worker_client_manager.js +49 -1
  161. package/package.json +14 -14
  162. package/src/client/factory.ts +41 -19
  163. package/src/client/interface.ts +9 -1
  164. package/src/client/p2p_client.ts +47 -15
  165. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +18 -8
  166. package/src/config.ts +34 -5
  167. package/src/errors/p2p-service.error.ts +11 -0
  168. package/src/index.ts +0 -1
  169. package/src/mem_pools/attestation_pool/attestation_pool.ts +12 -8
  170. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  171. package/src/mem_pools/index.ts +0 -3
  172. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -1
  173. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  174. package/src/mem_pools/tx_pool_v2/interfaces.ts +6 -4
  175. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +19 -3
  176. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +13 -1
  177. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +12 -4
  178. package/src/msg_validators/attestation_validator/README.md +49 -0
  179. package/src/msg_validators/attestation_validator/attestation_validator.ts +21 -9
  180. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -1
  181. package/src/msg_validators/clock_tolerance.ts +72 -3
  182. package/src/msg_validators/proposal_validator/README.md +123 -0
  183. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +4 -1
  184. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +4 -1
  185. package/src/msg_validators/proposal_validator/proposal_validator.ts +17 -10
  186. package/src/msg_validators/tx_validator/README.md +5 -1
  187. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  188. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  189. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  190. package/src/msg_validators/tx_validator/factory.ts +28 -1
  191. package/src/msg_validators/tx_validator/gas_validator.ts +25 -9
  192. package/src/msg_validators/tx_validator/phases_validator.ts +31 -1
  193. package/src/services/data_store.ts +5 -13
  194. package/src/services/dummy_service.ts +8 -2
  195. package/src/services/encoding.ts +9 -1
  196. package/src/services/gossipsub/topic_score_params.ts +36 -4
  197. package/src/services/libp2p/libp2p_service.ts +122 -128
  198. package/src/services/peer-manager/peer_manager.ts +43 -10
  199. package/src/services/peer-manager/peer_scoring.ts +27 -5
  200. package/src/services/reqresp/README.md +229 -0
  201. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  202. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +64 -69
  203. package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
  204. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  205. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
  206. package/src/services/reqresp/config.ts +2 -2
  207. package/src/services/reqresp/interface.ts +21 -11
  208. package/src/services/reqresp/metrics.ts +0 -1
  209. package/src/services/reqresp/protocols/index.ts +0 -1
  210. package/src/services/reqresp/protocols/tx.ts +1 -3
  211. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  212. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  213. package/src/services/reqresp/reqresp.ts +37 -12
  214. package/src/services/service.ts +6 -1
  215. package/src/services/tx_collection/fast_tx_collection.ts +57 -83
  216. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  217. package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
  218. package/src/services/tx_collection/request_tracker.ts +127 -0
  219. package/src/services/tx_collection/slow_tx_collection.ts +1 -1
  220. package/src/services/tx_collection/tx_collection.ts +3 -5
  221. package/src/services/tx_collection/tx_source.ts +8 -7
  222. package/src/test-helpers/mock-pubsub.ts +31 -5
  223. package/src/test-helpers/reqresp-nodes.ts +2 -2
  224. package/src/test-helpers/testbench-utils.ts +29 -3
  225. package/src/testbench/p2p_client_testbench_worker.ts +70 -14
  226. package/src/testbench/worker_client_manager.ts +55 -1
  227. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  228. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  229. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  230. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  231. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  232. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  233. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  234. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  235. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  236. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  237. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  238. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  239. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  240. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  241. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  242. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  243. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  244. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  245. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  246. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  247. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  248. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  249. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  250. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  251. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  252. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  253. package/dest/mem_pools/tx_pool/index.js +0 -2
  254. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  255. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  256. package/dest/mem_pools/tx_pool/priority.js +0 -16
  257. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  258. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  259. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  260. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  261. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  262. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  263. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  264. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  265. package/dest/services/reqresp/protocols/block.js +0 -32
  266. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  267. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  268. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  269. package/src/mem_pools/tx_pool/README.md +0 -270
  270. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  271. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  272. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  273. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  274. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  275. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  276. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  277. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  278. package/src/mem_pools/tx_pool/index.ts +0 -2
  279. package/src/mem_pools/tx_pool/priority.ts +0 -23
  280. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  281. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  282. package/src/services/reqresp/protocols/block.ts +0 -37
  283. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
@@ -1,13 +1,12 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { maxBy } from '@aztec/foundation/collection';
4
- import { Fr } from '@aztec/foundation/curves/bn254';
5
4
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
6
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
7
6
  import { Timer } from '@aztec/foundation/timer';
8
7
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
9
8
  import { protocolContractsHash } from '@aztec/protocol-contracts';
10
- import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
9
+ import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
11
10
  import type { ContractDataSource } from '@aztec/stdlib/contract';
12
11
  import { GasFees } from '@aztec/stdlib/gas';
13
12
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
@@ -18,7 +17,6 @@ import {
18
17
  type CheckpointProposalCore,
19
18
  type Gossipable,
20
19
  P2PMessage,
21
- type ValidationResult as P2PValidationResult,
22
20
  PeerErrorSeverity,
23
21
  PeerErrorSeverityByHarshness,
24
22
  TopicType,
@@ -59,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
59
57
  import { createLibp2p } from 'libp2p';
60
58
 
61
59
  import type { P2PConfig } from '../../config.js';
60
+ import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
62
61
  import type { MemPools } from '../../mem_pools/interface.js';
63
62
  import {
64
63
  BlockProposalValidator,
@@ -105,7 +104,6 @@ import {
105
104
  ValidationError,
106
105
  pingHandler,
107
106
  reqGoodbyeHandler,
108
- reqRespBlockHandler,
109
107
  reqRespBlockTxsHandler,
110
108
  reqRespStatusHandler,
111
109
  reqRespTxHandler,
@@ -131,7 +129,7 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
131
129
  // REFACTOR: Unify with the type above
132
130
  type ReceivedMessageValidationResult<T, M = undefined> =
133
131
  | { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
134
- | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
132
+ | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
135
133
 
136
134
  /**
137
135
  * Lib P2P implementation of the P2PService interface.
@@ -172,7 +170,13 @@ export class LibP2PService extends WithTracer implements P2PService {
172
170
  * @param checkpoint - The checkpoint proposal received from the peer.
173
171
  * @returns The attestations for the checkpoint, if any.
174
172
  */
175
- private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
173
+ private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
174
+ /**
175
+ * Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
176
+ * @param checkpoint - The checkpoint proposal received from the peer.
177
+ * @returns The attestations for the checkpoint, if any.
178
+ */
179
+ private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
176
180
 
177
181
  private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
178
182
 
@@ -224,15 +228,19 @@ export class LibP2PService extends WithTracer implements P2PService {
224
228
  this.protocolVersion,
225
229
  );
226
230
 
231
+ const p2pPropagationTime = config.attestationPropagationTime;
227
232
  const proposalValidatorOpts = {
228
233
  txsPermitted: !config.disableTransactions,
229
- maxTxsPerBlock: config.validateMaxTxsPerBlock,
234
+ maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
235
+ p2pPropagationTime,
230
236
  };
231
237
  this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
232
238
  this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
233
239
  this.checkpointAttestationValidator = config.fishermanMode
234
- ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
235
- : new CheckpointAttestationValidator(epochCache);
240
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, {
241
+ l1PublishingTime: config.l1PublishingTime,
242
+ })
243
+ : new CheckpointAttestationValidator(epochCache, { l1PublishingTime: config.l1PublishingTime });
236
244
 
237
245
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
238
246
 
@@ -244,12 +252,15 @@ export class LibP2PService extends WithTracer implements P2PService {
244
252
  return true;
245
253
  };
246
254
 
247
- this.checkpointReceivedCallback = (
248
- checkpoint: CheckpointProposalCore,
255
+ this.allNodesCheckpointReceivedCallback = (
256
+ _checkpoint: CheckpointProposalCore,
257
+ ): Promise<CheckpointAttestation[] | undefined> => {
258
+ throw new CheckpointProposalReceivedCallbackNotRegisteredError();
259
+ };
260
+
261
+ this.validatorCheckpointReceivedCallback = (
262
+ _checkpoint: CheckpointProposalCore,
249
263
  ): Promise<CheckpointAttestation[] | undefined> => {
250
- this.logger.debug(
251
- `Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
252
- );
253
264
  return Promise.resolve(undefined);
254
265
  };
255
266
  }
@@ -339,9 +350,12 @@ export class LibP2PService extends WithTracer implements P2PService {
339
350
  const l1Constants = epochCache.getL1Constants();
340
351
  const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
341
352
  slotDurationMs: l1Constants.slotDuration * 1000,
353
+ ethereumSlotDuration: l1Constants.ethereumSlotDuration,
342
354
  heartbeatIntervalMs: config.gossipsubInterval,
343
355
  targetCommitteeSize: l1Constants.targetCommitteeSize,
344
356
  blockDurationMs: config.blockDurationMs,
357
+ l1PublishingTime: config.l1PublishingTime,
358
+ p2pPropagationTime: config.attestationPropagationTime,
345
359
  expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
346
360
  });
347
361
 
@@ -466,6 +480,9 @@ export class LibP2PService extends WithTracer implements P2PService {
466
480
  epochCache,
467
481
  );
468
482
 
483
+ // Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
484
+ reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
485
+
469
486
  // Configure application-specific scoring for gossipsub.
470
487
  // The weight scales app score to align with gossipsub thresholds:
471
488
  // - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
@@ -511,14 +528,12 @@ export class LibP2PService extends WithTracer implements P2PService {
511
528
  // Create request response protocol handlers
512
529
  const txHandler = reqRespTxHandler(this.mempools);
513
530
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
514
- const blockHandler = reqRespBlockHandler(this.archiver);
515
531
  const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
516
532
 
517
533
  const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
518
534
  [ReqRespSubProtocol.PING]: pingHandler,
519
535
  [ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
520
536
  [ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
521
- [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
522
537
  };
523
538
 
524
539
  if (!this.config.disableTransactions) {
@@ -539,7 +554,6 @@ export class LibP2PService extends WithTracer implements P2PService {
539
554
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
540
555
  [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
541
556
  [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
542
- [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
543
557
  };
544
558
 
545
559
  await this.peerManager.initializePeers();
@@ -667,8 +681,16 @@ export class LibP2PService extends WithTracer implements P2PService {
667
681
  this.blockReceivedCallback = callback;
668
682
  }
669
683
 
670
- public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
671
- this.checkpointReceivedCallback = callback;
684
+ public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
685
+ this.validatorCheckpointReceivedCallback = callback;
686
+ }
687
+
688
+ public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
689
+ this.allNodesCheckpointReceivedCallback = callback;
690
+ }
691
+
692
+ public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
693
+ await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
672
694
  }
673
695
 
674
696
  /**
@@ -883,30 +905,56 @@ export class LibP2PService extends WithTracer implements P2PService {
883
905
  source: PeerId,
884
906
  topicType: TopicType,
885
907
  ): Promise<ReceivedMessageValidationResult<T, M>> {
886
- let resultAndObj: ReceivedMessageValidationResult<T, M> = { result: TopicValidatorResult.Reject };
908
+ // Default to reject result with a penalty if validation function throws an error
909
+ let resultAndObj: ReceivedMessageValidationResult<T, M> = {
910
+ result: TopicValidatorResult.Reject,
911
+ severity: PeerErrorSeverity.MidToleranceError,
912
+ };
887
913
  const timer = new Timer();
888
914
  try {
889
915
  resultAndObj = await validationFunc();
890
916
  } catch (err) {
891
- this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
892
- this.logger.error(`Error deserializing and validating gossipsub message`, err, {
893
- msgId,
894
- source: source.toString(),
895
- topicType,
896
- });
917
+ this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
897
918
  }
898
919
 
899
920
  if (resultAndObj.result === TopicValidatorResult.Accept) {
921
+ this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
900
922
  this.instrumentation.recordMessageValidation(topicType, timer);
923
+ } else if (resultAndObj.result === TopicValidatorResult.Reject) {
924
+ this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
925
+ msgId,
926
+ source: source.toString(),
927
+ topicType,
928
+ severity: resultAndObj.severity,
929
+ });
930
+ this.peerManager.penalizePeer(source, resultAndObj.severity);
931
+ } else {
932
+ this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
901
933
  }
902
934
 
903
935
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
904
936
  return resultAndObj;
905
937
  }
906
938
 
939
+ private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
940
+ try {
941
+ return deserializeFunc();
942
+ } catch (err) {
943
+ this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
944
+ err,
945
+ msgId,
946
+ source: source.toString(),
947
+ });
948
+ return undefined;
949
+ }
950
+ }
951
+
907
952
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
908
953
  const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
909
- const tx = Tx.fromBuffer(payloadData);
954
+ const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
955
+ if (!tx) {
956
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
957
+ }
910
958
 
911
959
  const currentBlockNumber = await this.archiver.getBlockNumber();
912
960
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
@@ -931,8 +979,7 @@ export class LibP2PService extends WithTracer implements P2PService {
931
979
  severity,
932
980
  source: source.toString(),
933
981
  });
934
- this.peerManager.penalizePeer(source, severity);
935
- return { result: TopicValidatorResult.Reject };
982
+ return { result: TopicValidatorResult.Reject, severity };
936
983
  }
937
984
 
938
985
  // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
@@ -954,8 +1001,7 @@ export class LibP2PService extends WithTracer implements P2PService {
954
1001
  severity,
955
1002
  source: source.toString(),
956
1003
  });
957
- this.peerManager.penalizePeer(source, severity);
958
- return { result: TopicValidatorResult.Reject };
1004
+ return { result: TopicValidatorResult.Reject, severity };
959
1005
  }
960
1006
 
961
1007
  // Pool add: persist the tx
@@ -976,7 +1022,11 @@ export class LibP2PService extends WithTracer implements P2PService {
976
1022
  } else if (wasIgnored) {
977
1023
  return { result: TopicValidatorResult.Ignore, obj: tx };
978
1024
  } else {
979
- return { result: TopicValidatorResult.Reject };
1025
+ this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
1026
+ source: source.toString(),
1027
+ txHash: txHash.toString(),
1028
+ });
1029
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
980
1030
  }
981
1031
  };
982
1032
 
@@ -1006,7 +1056,16 @@ export class LibP2PService extends WithTracer implements P2PService {
1006
1056
  source: PeerId,
1007
1057
  ): Promise<void> {
1008
1058
  const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
1009
- () => this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)),
1059
+ () => {
1060
+ const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
1061
+ if (!attestation) {
1062
+ return Promise.resolve({
1063
+ result: TopicValidatorResult.Reject,
1064
+ severity: PeerErrorSeverity.LowToleranceError,
1065
+ });
1066
+ }
1067
+ return this.validateAndStoreCheckpointAttestation(source, attestation);
1068
+ },
1010
1069
  msgId,
1011
1070
  source,
1012
1071
  TopicType.checkpoint_attestation,
@@ -1039,8 +1098,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1039
1098
 
1040
1099
  if (validationResult.result === 'reject') {
1041
1100
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1042
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1043
- return { result: TopicValidatorResult.Reject };
1101
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1044
1102
  }
1045
1103
 
1046
1104
  if (validationResult.result === 'ignore') {
@@ -1066,16 +1124,16 @@ export class LibP2PService extends WithTracer implements P2PService {
1066
1124
  return { result: TopicValidatorResult.Ignore, obj: attestation };
1067
1125
  }
1068
1126
 
1069
- // Could not add (cap reached for signer), no need to re-broadcast
1127
+ // Could not add (cap reached for signer), penalize and do not re-broadcast
1070
1128
  if (!added) {
1071
- this.logger.warn(`Dropping checkpoint attestation due to cap`, {
1129
+ this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
1072
1130
  slot: slot.toString(),
1073
1131
  archive: attestation.archive.toString(),
1074
1132
  source: peerId.toString(),
1075
1133
  attester: attestation.getSender()?.toString(),
1076
1134
  count,
1077
1135
  });
1078
- return { result: TopicValidatorResult.Ignore, obj: attestation };
1136
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
1079
1137
  }
1080
1138
 
1081
1139
  // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
@@ -1130,8 +1188,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1130
1188
 
1131
1189
  if (validationResult.result === 'reject') {
1132
1190
  this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
1133
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1134
- return { result: TopicValidatorResult.Reject };
1191
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1135
1192
  }
1136
1193
 
1137
1194
  if (validationResult.result === 'ignore') {
@@ -1155,7 +1212,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1155
1212
 
1156
1213
  // Too many blocks received for this slot and index, penalize peer and do not re-broadcast
1157
1214
  if (!added) {
1158
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1159
1215
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1160
1216
  ...block.toBlockInfo(),
1161
1217
  indexWithinCheckpoint: block.indexWithinCheckpoint,
@@ -1163,7 +1219,11 @@ export class LibP2PService extends WithTracer implements P2PService {
1163
1219
  proposer: block.getSender()?.toString(),
1164
1220
  source: peerId.toString(),
1165
1221
  });
1166
- return { result: TopicValidatorResult.Reject, metadata: { isEquivocated } };
1222
+ return {
1223
+ result: TopicValidatorResult.Reject,
1224
+ metadata: { isEquivocated },
1225
+ severity: PeerErrorSeverity.HighToleranceError,
1226
+ };
1167
1227
  }
1168
1228
 
1169
1229
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1256,8 +1316,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1256
1316
 
1257
1317
  if (validationResult.result === 'reject') {
1258
1318
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1259
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1260
- return { result: TopicValidatorResult.Reject };
1319
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1261
1320
  }
1262
1321
 
1263
1322
  if (validationResult.result === 'ignore') {
@@ -1272,20 +1331,21 @@ export class LibP2PService extends WithTracer implements P2PService {
1272
1331
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1273
1332
  [Attributes.P2P_ID]: peerId.toString(),
1274
1333
  });
1275
- const {
1276
- result,
1277
- obj,
1278
- metadata: { isEquivocated } = {},
1279
- } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1280
- if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1334
+ const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1335
+ const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1336
+ if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1281
1337
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1282
1338
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1283
1339
  [Attributes.P2P_ID]: peerId.toString(),
1284
1340
  isEquivocated,
1285
- result,
1341
+ result: blockProposalResult.result,
1286
1342
  });
1287
- return { result: TopicValidatorResult.Reject };
1288
- } else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1343
+ return {
1344
+ result: TopicValidatorResult.Reject,
1345
+ severity:
1346
+ 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
1347
+ };
1348
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1289
1349
  processBlock = true;
1290
1350
  }
1291
1351
  }
@@ -1312,13 +1372,17 @@ export class LibP2PService extends WithTracer implements P2PService {
1312
1372
  // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1313
1373
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1314
1374
  if (!added) {
1315
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1316
1375
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1317
1376
  ...checkpoint.toCheckpointInfo(),
1318
1377
  count,
1319
1378
  source: peerId.toString(),
1320
1379
  });
1321
- return { result: TopicValidatorResult.Reject, obj: checkpoint, metadata: { isEquivocated, processBlock } };
1380
+ return {
1381
+ result: TopicValidatorResult.Reject,
1382
+ obj: checkpoint,
1383
+ metadata: { isEquivocated, processBlock },
1384
+ severity: PeerErrorSeverity.HighToleranceError,
1385
+ };
1322
1386
  }
1323
1387
 
1324
1388
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1363,9 +1427,11 @@ export class LibP2PService extends WithTracer implements P2PService {
1363
1427
  source: sender.toString(),
1364
1428
  });
1365
1429
 
1430
+ await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
1431
+
1366
1432
  // Call the checkpoint received callback with the core version (without lastBlock)
1367
1433
  // to validate and potentially generate attestations
1368
- const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
1434
+ const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
1369
1435
  if (attestations && attestations.length > 0) {
1370
1436
  // If the callback returned attestations, add them to the pool and propagate them
1371
1437
  await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
@@ -1513,53 +1579,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1513
1579
  }
1514
1580
  }
1515
1581
 
1516
- /**
1517
- * Validates a BLOCK response.
1518
- *
1519
- * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1520
- * Penalizes on block number mismatch or hash mismatch.
1521
- *
1522
- * @param requestedBlockNumber - The requested block number.
1523
- * @param responseBlock - The block returned by the peer.
1524
- * @param peerId - The peer that returned the block.
1525
- * @returns True if the response is valid, false otherwise.
1526
- */
1527
- @trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
1528
- [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
1529
- }))
1530
- protected async validateRequestedBlock(
1531
- requestedBlockNumber: Fr,
1532
- responseBlock: L2Block,
1533
- peerId: PeerId,
1534
- ): Promise<boolean> {
1535
- try {
1536
- const reqNum = Number(requestedBlockNumber.toString());
1537
- if (responseBlock.number !== reqNum) {
1538
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1539
- return false;
1540
- }
1541
-
1542
- const local = await this.archiver.getBlock(BlockNumber(reqNum));
1543
- if (!local) {
1544
- // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1545
- // TODO: Consider extending this validator to accept an expected hash or
1546
- // performing quorum-based checks when using P2P syncing prior to L1 sync.
1547
- this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1548
- return false;
1549
- }
1550
- const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
1551
- if (!localHash.equals(respHash)) {
1552
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1553
- return false;
1554
- }
1555
-
1556
- return true;
1557
- } catch (e) {
1558
- this.logger.warn(`Error validating requested block`, e);
1559
- return false;
1560
- }
1561
- }
1562
-
1563
1582
  protected async validateRequestedTx(
1564
1583
  tx: Tx,
1565
1584
  peerId: PeerId,
@@ -1742,31 +1761,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1742
1761
  return PeerErrorSeverity.HighToleranceError;
1743
1762
  }
1744
1763
 
1745
- /**
1746
- * Validate a checkpoint attestation.
1747
- *
1748
- * @param attestation - The checkpoint attestation to validate.
1749
- * @returns True if the checkpoint attestation is valid, false otherwise.
1750
- */
1751
- @trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
1752
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1753
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1754
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1755
- }))
1756
- public async validateCheckpointAttestation(
1757
- peerId: PeerId,
1758
- attestation: CheckpointAttestation,
1759
- ): Promise<P2PValidationResult> {
1760
- const result = await this.checkpointAttestationValidator.validate(attestation);
1761
-
1762
- if (result.result === 'reject') {
1763
- this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1764
- this.peerManager.penalizePeer(peerId, result.severity);
1765
- }
1766
-
1767
- return result;
1768
- }
1769
-
1770
1764
  public getPeerScore(peerId: PeerId): number {
1771
1765
  return this.node.services.pubsub.score.score(peerId.toString());
1772
1766
  }
@@ -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
 
@@ -226,20 +226,30 @@ export class PeerManager implements PeerManagerInterface {
226
226
  }
227
227
 
228
228
  /**
229
- * Cleans up expired timeouts.
229
+ * Cleans up expired timeouts and stale failed-auth-handshake entries.
230
230
  *
231
231
  * When peers fail to dial after a number of retries, they are temporarily timed out.
232
232
  * This function removes any peers that have been in the timed out state for too long.
233
233
  * To give them a chance to reconnect.
234
+ *
235
+ * Also evicts entries from the failed-auth-handshake map whose expiry window has passed.
236
+ * Without this, peers that probe once and never reconnect would leave their entries in the
237
+ * map forever, causing an unbounded memory leak.
234
238
  */
235
239
  private cleanupExpiredTimeouts() {
236
- // Clean up expired timeouts
237
240
  const now = this.dateProvider.now();
241
+
238
242
  for (const [peerId, timedOutPeer] of this.timedOutPeers.entries()) {
239
243
  if (now >= timedOutPeer.timeoutUntilMs) {
240
244
  this.timedOutPeers.delete(peerId);
241
245
  }
242
246
  }
247
+
248
+ for (const [id, entry] of this.failedAuthHandshakes.entries()) {
249
+ if (now - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
250
+ this.failedAuthHandshakes.delete(id);
251
+ }
252
+ }
243
253
  }
244
254
 
245
255
  /**
@@ -303,15 +313,20 @@ export class PeerManager implements PeerManagerInterface {
303
313
  */
304
314
  private handleDisconnectedPeerEvent(e: CustomEvent<PeerId>) {
305
315
  const peerId = e.detail;
316
+ const peerIdStr = peerId.toString();
306
317
  this.metrics.peerDisconnected(peerId);
307
- this.logger.verbose(`Disconnected from peer ${peerId.toString()}`);
308
- const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerId.toString());
318
+ this.logger.verbose(`Disconnected from peer ${peerIdStr}`);
319
+ const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerIdStr);
309
320
  if (validatorAddress !== undefined) {
310
321
  this.logger.info(
311
- `Removing authentication for validator ${validatorAddress} at peer id ${peerId.toString()} due to disconnection`,
322
+ `Removing authentication for validator ${validatorAddress} at peer id ${peerIdStr} due to disconnection`,
312
323
  );
313
324
  this.authenticatedValidatorAddressToPeerId.delete(validatorAddress.toString());
314
- this.authenticatedPeerIdToValidatorAddress.delete(peerId.toString());
325
+ this.authenticatedPeerIdToValidatorAddress.delete(peerIdStr);
326
+ }
327
+
328
+ if (this.peerScoring.getScoreState(peerIdStr) === PeerScoreState.Healthy) {
329
+ this.peerScoring.removePeer(peerIdStr);
315
330
  }
316
331
  }
317
332
 
@@ -713,6 +728,12 @@ export class PeerManager implements PeerManagerInterface {
713
728
  return;
714
729
  }
715
730
 
731
+ // Don't dial peers that have exceeded the auth failure threshold
732
+ if (!this.isNodeAllowedToConnect(peerId)) {
733
+ this.logger.trace(`Skipping peer ${peerId} due to failed auth handshake attempts`);
734
+ return;
735
+ }
736
+
716
737
  const [multiaddrTcp] = await Promise.all([enr.getFullMultiaddr('tcp')]);
717
738
 
718
739
  this.logger.trace(`Handling discovered peer ${peerId} at ${multiaddrTcp?.toString() ?? 'undefined address'}`);
@@ -776,7 +797,8 @@ export class PeerManager implements PeerManagerInterface {
776
797
  // Add to timed out peers
777
798
  this.timedOutPeers.set(id, {
778
799
  peerId: id,
779
- timeoutUntilMs: this.dateProvider.now() + FAILED_PEER_BAN_TIME_MS,
800
+ timeoutUntilMs:
801
+ this.dateProvider.now() + (this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS),
780
802
  });
781
803
  }
782
804
  }
@@ -938,6 +960,8 @@ export class PeerManager implements PeerManagerInterface {
938
960
  `Received auth for validator ${sender.toString()} from peer ${peerIdString}, but this validator is already authenticated to peer ${peerForAddress.toString()}`,
939
961
  { ...logData, address: sender.toString() },
940
962
  );
963
+ this.markAuthHandshakeFailed(peerId);
964
+ this.markPeerForDisconnect(peerId);
941
965
  return;
942
966
  }
943
967
 
@@ -967,14 +991,14 @@ export class PeerManager implements PeerManagerInterface {
967
991
  const peerIdStr = peerId.toString();
968
992
 
969
993
  const existingEntry = this.failedAuthHandshakes.get(peerIdStr);
994
+ const failureCount = (existingEntry?.count || 0) + 1;
970
995
  this.failedAuthHandshakes.set(peerIdStr, {
971
- count: (existingEntry?.count || 0) + 1,
996
+ count: failureCount,
972
997
  lastFailureTimestamp: now,
973
998
  });
974
999
 
975
1000
  const connections = this.libP2PNode.getConnections(peerId);
976
1001
  connections.forEach(conn => {
977
- // We mark the IP address
978
1002
  const address = conn.remoteAddr.nodeAddress().address;
979
1003
  const existingAddressEntry = this.failedAuthHandshakes.get(address);
980
1004
  this.failedAuthHandshakes.set(address, {
@@ -982,6 +1006,15 @@ export class PeerManager implements PeerManagerInterface {
982
1006
  lastFailureTimestamp: now,
983
1007
  });
984
1008
  });
1009
+
1010
+ // Ban the peer from being re-dialed for a cooldown period (exponential backoff)
1011
+ const banTimeMs = this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS;
1012
+ const backoffMs = banTimeMs * Math.pow(2, Math.min(failureCount - 1, 5));
1013
+ this.timedOutPeers.set(peerIdStr, {
1014
+ peerId: peerIdStr,
1015
+ timeoutUntilMs: now + backoffMs,
1016
+ });
1017
+ this.cachedPeers.delete(peerIdStr);
985
1018
  }
986
1019
 
987
1020
  /*