@aztec/p2p 0.0.1-commit.b655e406 → 0.0.1-commit.c7c42ec

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 (300) hide show
  1. package/dest/bootstrap/bootstrap.d.ts +1 -1
  2. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  3. package/dest/client/factory.d.ts +2 -2
  4. package/dest/client/factory.d.ts.map +1 -1
  5. package/dest/client/factory.js +2 -3
  6. package/dest/client/index.d.ts +1 -1
  7. package/dest/client/interface.d.ts +4 -2
  8. package/dest/client/interface.d.ts.map +1 -1
  9. package/dest/client/p2p_client.d.ts +9 -27
  10. package/dest/client/p2p_client.d.ts.map +1 -1
  11. package/dest/client/p2p_client.js +39 -32
  12. package/dest/config.d.ts +62 -59
  13. package/dest/config.d.ts.map +1 -1
  14. package/dest/config.js +19 -12
  15. package/dest/enr/generate-enr.d.ts +1 -1
  16. package/dest/enr/index.d.ts +1 -1
  17. package/dest/errors/attestation-pool.error.d.ts +7 -0
  18. package/dest/errors/attestation-pool.error.d.ts.map +1 -0
  19. package/dest/errors/attestation-pool.error.js +12 -0
  20. package/dest/errors/reqresp.error.d.ts +1 -1
  21. package/dest/errors/reqresp.error.d.ts.map +1 -1
  22. package/dest/index.d.ts +1 -1
  23. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +28 -6
  24. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  26. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +35 -34
  28. package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
  29. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +13 -6
  30. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
  31. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +41 -18
  32. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +11 -6
  33. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  34. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +30 -8
  35. package/dest/mem_pools/attestation_pool/mocks.d.ts +226 -5
  36. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  37. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  38. package/dest/mem_pools/index.d.ts +1 -1
  39. package/dest/mem_pools/instrumentation.d.ts +9 -1
  40. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  41. package/dest/mem_pools/instrumentation.js +38 -2
  42. package/dest/mem_pools/interface.d.ts +3 -4
  43. package/dest/mem_pools/interface.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +30 -60
  45. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  46. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +262 -324
  47. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +18 -0
  48. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
  49. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +56 -0
  50. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +83 -0
  51. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
  52. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +5 -0
  53. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +15 -0
  54. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +1 -0
  55. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +88 -0
  56. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
  57. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  58. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
  59. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
  60. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  61. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +76 -0
  62. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
  63. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  64. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
  65. package/dest/mem_pools/tx_pool/index.d.ts +1 -2
  66. package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool/index.js +0 -1
  68. package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
  69. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool/priority.js +6 -1
  71. package/dest/mem_pools/tx_pool/tx_pool.d.ts +11 -6
  72. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  73. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  74. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  75. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +30 -24
  76. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -3
  77. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  78. package/dest/msg_validators/attestation_validator/attestation_validator.js +12 -12
  79. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
  80. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
  81. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +67 -0
  82. package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
  83. package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
  84. package/dest/msg_validators/attestation_validator/index.js +1 -0
  85. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +1 -1
  86. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
  87. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +22 -10
  88. package/dest/msg_validators/block_proposal_validator/index.d.ts +1 -1
  89. package/dest/msg_validators/index.d.ts +1 -1
  90. package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +1 -1
  91. package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -1
  92. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  93. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  94. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
  95. package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
  96. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  97. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
  98. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  99. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  100. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +1 -1
  102. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  103. package/dest/msg_validators/tx_validator/factory.d.ts +4 -3
  104. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  105. package/dest/msg_validators/tx_validator/factory.js +1 -1
  106. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  107. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  108. package/dest/msg_validators/tx_validator/index.d.ts +1 -1
  109. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +2 -2
  110. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  111. package/dest/msg_validators/tx_validator/phases_validator.d.ts +1 -1
  112. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  113. package/dest/msg_validators/tx_validator/phases_validator.js +3 -1
  114. package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
  115. package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
  116. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
  117. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  118. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +1 -1
  119. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
  120. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +1 -1
  121. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  122. package/dest/services/data_store.d.ts +1 -1
  123. package/dest/services/data_store.d.ts.map +1 -1
  124. package/dest/services/discv5/discV5_service.d.ts +1 -1
  125. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  126. package/dest/services/dummy_service.d.ts +1 -1
  127. package/dest/services/dummy_service.d.ts.map +1 -1
  128. package/dest/services/encoding.d.ts +1 -1
  129. package/dest/services/encoding.d.ts.map +1 -1
  130. package/dest/services/encoding.js +1 -1
  131. package/dest/services/gossipsub/scoring.d.ts +1 -1
  132. package/dest/services/index.d.ts +1 -1
  133. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  134. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  135. package/dest/services/libp2p/instrumentation.js +9 -2
  136. package/dest/services/libp2p/libp2p_service.d.ts +14 -70
  137. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  138. package/dest/services/libp2p/libp2p_service.js +231 -66
  139. package/dest/services/peer-manager/interface.d.ts +1 -1
  140. package/dest/services/peer-manager/metrics.d.ts +8 -1
  141. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  142. package/dest/services/peer-manager/metrics.js +28 -0
  143. package/dest/services/peer-manager/peer_manager.d.ts +1 -32
  144. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  145. package/dest/services/peer-manager/peer_manager.js +6 -2
  146. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  147. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  148. package/dest/services/peer-manager/peer_scoring.js +40 -2
  149. package/dest/services/reqresp/config.d.ts +1 -1
  150. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +1 -1
  151. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
  152. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -4
  153. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  154. package/dest/services/reqresp/index.d.ts +1 -1
  155. package/dest/services/reqresp/interface.d.ts +2 -2
  156. package/dest/services/reqresp/interface.d.ts.map +1 -1
  157. package/dest/services/reqresp/interface.js +1 -1
  158. package/dest/services/reqresp/metrics.d.ts +1 -1
  159. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  160. package/dest/services/reqresp/protocols/auth.d.ts +2 -2
  161. package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
  162. package/dest/services/reqresp/protocols/auth.js +2 -2
  163. package/dest/services/reqresp/protocols/block.d.ts +1 -1
  164. package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
  165. package/dest/services/reqresp/protocols/block.js +3 -2
  166. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
  167. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  168. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  169. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +4 -6
  170. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  171. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +1 -1
  172. package/dest/services/reqresp/protocols/block_txs/index.d.ts +1 -1
  173. package/dest/services/reqresp/protocols/goodbye.d.ts +1 -1
  174. package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
  175. package/dest/services/reqresp/protocols/index.d.ts +1 -1
  176. package/dest/services/reqresp/protocols/ping.d.ts +1 -1
  177. package/dest/services/reqresp/protocols/status.d.ts +6 -5
  178. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  179. package/dest/services/reqresp/protocols/status.js +4 -3
  180. package/dest/services/reqresp/protocols/tx.d.ts +2 -3
  181. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  182. package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
  183. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +2 -2
  184. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  185. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  186. package/dest/services/reqresp/reqresp.d.ts +1 -41
  187. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  188. package/dest/services/reqresp/status.d.ts +2 -2
  189. package/dest/services/reqresp/status.d.ts.map +1 -1
  190. package/dest/services/service.d.ts +1 -1
  191. package/dest/services/tx_collection/config.d.ts +1 -1
  192. package/dest/services/tx_collection/config.js +1 -1
  193. package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -9
  194. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  195. package/dest/services/tx_collection/index.d.ts +1 -1
  196. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  197. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  198. package/dest/services/tx_collection/slow_tx_collection.d.ts +6 -7
  199. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  200. package/dest/services/tx_collection/slow_tx_collection.js +2 -1
  201. package/dest/services/tx_collection/tx_collection.d.ts +11 -11
  202. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  203. package/dest/services/tx_collection/tx_collection_sink.d.ts +3 -3
  204. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  205. package/dest/services/tx_collection/tx_source.d.ts +1 -1
  206. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  207. package/dest/services/tx_provider.d.ts +6 -4
  208. package/dest/services/tx_provider.d.ts.map +1 -1
  209. package/dest/services/tx_provider.js +11 -2
  210. package/dest/services/tx_provider_instrumentation.d.ts +5 -2
  211. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  212. package/dest/services/tx_provider_instrumentation.js +14 -1
  213. package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
  214. package/dest/test-helpers/get-ports.d.ts +1 -1
  215. package/dest/test-helpers/get-ports.d.ts.map +1 -1
  216. package/dest/test-helpers/index.d.ts +1 -1
  217. package/dest/test-helpers/make-enrs.d.ts +1 -1
  218. package/dest/test-helpers/make-test-p2p-clients.d.ts +2 -2
  219. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  220. package/dest/test-helpers/mock-pubsub.d.ts +4 -4
  221. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  222. package/dest/test-helpers/mock-tx-helpers.d.ts +2 -2
  223. package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -1
  224. package/dest/test-helpers/mock-tx-helpers.js +1 -1
  225. package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
  226. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  227. package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
  228. package/dest/testbench/p2p_client_testbench_worker.js +12 -8
  229. package/dest/testbench/parse_log_file.d.ts +1 -1
  230. package/dest/testbench/testbench.d.ts +1 -1
  231. package/dest/testbench/worker_client_manager.d.ts +1 -1
  232. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  233. package/dest/types/index.d.ts +1 -1
  234. package/dest/util.d.ts +2 -1
  235. package/dest/util.d.ts.map +1 -1
  236. package/dest/util.js +11 -2
  237. package/dest/versioning.d.ts +1 -1
  238. package/package.json +19 -18
  239. package/src/client/factory.ts +5 -10
  240. package/src/client/interface.ts +4 -1
  241. package/src/client/p2p_client.ts +63 -60
  242. package/src/config.ts +28 -17
  243. package/src/errors/attestation-pool.error.ts +13 -0
  244. package/src/mem_pools/attestation_pool/attestation_pool.ts +29 -5
  245. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +47 -34
  246. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +66 -24
  247. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +50 -16
  248. package/src/mem_pools/attestation_pool/mocks.ts +3 -3
  249. package/src/mem_pools/instrumentation.ts +46 -0
  250. package/src/mem_pools/interface.ts +2 -4
  251. package/src/mem_pools/tx_pool/README.md +255 -0
  252. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +314 -373
  253. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +71 -0
  254. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +93 -0
  255. package/src/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.ts +108 -0
  256. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
  257. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +91 -0
  258. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
  259. package/src/mem_pools/tx_pool/index.ts +0 -1
  260. package/src/mem_pools/tx_pool/priority.ts +8 -1
  261. package/src/mem_pools/tx_pool/tx_pool.ts +11 -5
  262. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +23 -17
  263. package/src/msg_validators/attestation_validator/attestation_validator.ts +14 -16
  264. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +91 -0
  265. package/src/msg_validators/attestation_validator/index.ts +1 -0
  266. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +26 -10
  267. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  268. package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
  269. package/src/msg_validators/tx_validator/factory.ts +3 -2
  270. package/src/msg_validators/tx_validator/metadata_validator.ts +1 -1
  271. package/src/msg_validators/tx_validator/phases_validator.ts +3 -1
  272. package/src/msg_validators/tx_validator/test_utils.ts +1 -1
  273. package/src/msg_validators/tx_validator/timestamp_validator.ts +2 -1
  274. package/src/services/encoding.ts +1 -1
  275. package/src/services/libp2p/instrumentation.ts +10 -1
  276. package/src/services/libp2p/libp2p_service.ts +263 -79
  277. package/src/services/peer-manager/metrics.ts +32 -0
  278. package/src/services/peer-manager/peer_manager.ts +6 -2
  279. package/src/services/peer-manager/peer_scoring.ts +46 -3
  280. package/src/services/reqresp/interface.ts +1 -1
  281. package/src/services/reqresp/protocols/auth.ts +2 -2
  282. package/src/services/reqresp/protocols/block.ts +3 -2
  283. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
  284. package/src/services/reqresp/protocols/status.ts +9 -8
  285. package/src/services/reqresp/protocols/tx.ts +1 -2
  286. package/src/services/tx_collection/config.ts +1 -1
  287. package/src/services/tx_collection/fast_tx_collection.ts +3 -2
  288. package/src/services/tx_collection/slow_tx_collection.ts +7 -6
  289. package/src/services/tx_collection/tx_collection.ts +10 -9
  290. package/src/services/tx_provider.ts +21 -5
  291. package/src/services/tx_provider_instrumentation.ts +19 -2
  292. package/src/test-helpers/mock-pubsub.ts +1 -1
  293. package/src/test-helpers/mock-tx-helpers.ts +1 -1
  294. package/src/test-helpers/reqresp-nodes.ts +1 -1
  295. package/src/testbench/p2p_client_testbench_worker.ts +10 -6
  296. package/src/util.ts +12 -2
  297. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -80
  298. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
  299. package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -238
  300. package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -283
@@ -1,14 +1,14 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
- import { randomInt } from '@aztec/foundation/crypto';
3
- import { Fr } from '@aztec/foundation/fields';
2
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { randomInt } from '@aztec/foundation/crypto/random';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
5
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
5
- import { SerialQueue } from '@aztec/foundation/queue';
6
6
  import { RunningPromise } from '@aztec/foundation/running-promise';
7
7
  import { Timer } from '@aztec/foundation/timer';
8
8
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
9
9
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
10
10
  import { protocolContractsHash } from '@aztec/protocol-contracts';
11
- import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
11
+ import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
12
12
  import type { ContractDataSource } from '@aztec/stdlib/contract';
13
13
  import { GasFees } from '@aztec/stdlib/gas';
14
14
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
@@ -50,8 +50,13 @@ import { ENR } from '@nethermindeth/enr';
50
50
  import { createLibp2p } from 'libp2p';
51
51
 
52
52
  import type { P2PConfig } from '../../config.js';
53
+ import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
53
54
  import type { MemPools } from '../../mem_pools/interface.js';
54
- import { AttestationValidator, BlockProposalValidator } from '../../msg_validators/index.js';
55
+ import {
56
+ AttestationValidator,
57
+ BlockProposalValidator,
58
+ FishermanAttestationValidator,
59
+ } from '../../msg_validators/index.js';
55
60
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
56
61
  import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
57
62
  import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
@@ -116,7 +121,6 @@ type ReceivedMessageValidationResult<T> =
116
121
  * Lib P2P implementation of the P2PService interface.
117
122
  */
118
123
  export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
119
- private jobQueue: SerialQueue = new SerialQueue();
120
124
  private discoveryRunningPromise?: RunningPromise;
121
125
  private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
122
126
 
@@ -127,7 +131,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
127
131
  private protocolVersion = '';
128
132
  private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
129
133
 
130
- private feesCache: { blockNumber: number; gasFees: GasFees } | undefined;
134
+ private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
131
135
 
132
136
  /**
133
137
  * Callback for when a block is received from a peer.
@@ -140,6 +144,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
140
144
 
141
145
  private instrumentation: P2PInstrumentation;
142
146
 
147
+ protected logger: Logger;
148
+
143
149
  constructor(
144
150
  private clientType: T,
145
151
  private config: P2PConfig,
@@ -147,16 +153,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
147
153
  private peerDiscoveryService: PeerDiscoveryService,
148
154
  private reqresp: ReqRespInterface,
149
155
  private peerManager: PeerManagerInterface,
150
- protected mempools: MemPools<T>,
156
+ protected mempools: MemPools,
151
157
  private archiver: L2BlockSource & ContractDataSource,
152
158
  private epochCache: EpochCacheInterface,
153
159
  private proofVerifier: ClientProtocolCircuitVerifier,
154
160
  private worldStateSynchronizer: WorldStateSynchronizer,
155
161
  telemetry: TelemetryClient,
156
- protected logger = createLogger('p2p:libp2p_service'),
162
+ logger: Logger = createLogger('p2p:libp2p_service'),
157
163
  ) {
158
164
  super(telemetry, 'LibP2PService');
159
165
 
166
+ // Create child logger with fisherman prefix if in fisherman mode
167
+ this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
168
+
160
169
  this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
161
170
 
162
171
  this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
@@ -174,15 +183,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
174
183
  this.protocolVersion,
175
184
  );
176
185
 
177
- this.attestationValidator = new AttestationValidator(epochCache);
186
+ // Use FishermanAttestationValidator in fisherman mode to validate attestation payloads against proposals
187
+ this.attestationValidator = config.fishermanMode
188
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
189
+ : new AttestationValidator(epochCache);
178
190
  this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
179
191
 
180
192
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
181
193
 
182
194
  this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation[] | undefined> => {
183
195
  this.logger.debug(
184
- `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber.toNumber()} from peer.`,
185
- { p2pMessageIdentifier: await block.p2pMessageIdentifier() },
196
+ `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
197
+ { p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
186
198
  );
187
199
  return undefined;
188
200
  };
@@ -203,7 +215,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
203
215
  config: P2PConfig,
204
216
  peerId: PeerId,
205
217
  deps: {
206
- mempools: MemPools<T>;
218
+ mempools: MemPools;
207
219
  l2BlockSource: L2BlockSource & ContractDataSource;
208
220
  epochCache: EpochCacheInterface;
209
221
  proofVerifier: ClientProtocolCircuitVerifier;
@@ -395,7 +407,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
395
407
  logger: createLibp2pComponentLogger(logger.module),
396
408
  });
397
409
 
398
- const peerScoring = new PeerScoring(config);
410
+ const peerScoring = new PeerScoring(config, telemetry);
399
411
  const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
400
412
 
401
413
  const peerManager = new PeerManager(
@@ -450,9 +462,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
450
462
  }
451
463
  const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
452
464
 
453
- // Start job queue, peer discovery service and libp2p node
454
- this.jobQueue.start();
455
-
456
465
  await this.peerManager.initializePeers();
457
466
  if (!this.config.p2pDiscoveryDisabled) {
458
467
  await this.peerDiscoveryService.start();
@@ -477,8 +486,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
477
486
  [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
478
487
  };
479
488
 
480
- // Only handle block transactions request if attestation pool is available to the client
481
- if (this.mempools.attestationPool && !this.config.disableTransactions) {
489
+ if (!this.config.disableTransactions) {
482
490
  const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
483
491
  requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
484
492
  }
@@ -490,9 +498,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
490
498
  // add GossipSub listener
491
499
  this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
492
500
 
493
- // Start running promise for peer discovery
501
+ // Start running promise for peer discovery and metrics collection
494
502
  this.discoveryRunningPromise = new RunningPromise(
495
- () => this.peerManager.heartbeat(),
503
+ async () => {
504
+ await this.peerManager.heartbeat();
505
+ },
496
506
  this.logger,
497
507
  this.config.peerCheckIntervalMS,
498
508
  );
@@ -501,9 +511,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
501
511
  // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
502
512
  const reqrespSubProtocolValidators = {
503
513
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
504
- // TODO(#11336): A request validator for blocks
505
514
  [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
506
515
  [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
516
+ [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
507
517
  };
508
518
  await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
509
519
  this.logger.info(`Started P2P service`, {
@@ -525,9 +535,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
525
535
  // Stop peer manager
526
536
  this.logger.debug('Stopping peer manager...');
527
537
  await this.peerManager.stop();
528
-
529
- this.logger.debug('Stopping job queue...');
530
- await this.jobQueue.end();
531
538
  this.logger.debug('Stopping running promise...');
532
539
  await this.discoveryRunningPromise?.stop();
533
540
  this.logger.debug('Stopping peer discovery service...');
@@ -615,7 +622,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
615
622
  if (!this.node.services.pubsub) {
616
623
  throw new Error('Pubsub service not available.');
617
624
  }
618
- const p2pMessage = P2PMessage.fromGossipable(message);
625
+ const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages);
619
626
  const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
620
627
  return result.recipients.length;
621
628
  }
@@ -660,13 +667,39 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
660
667
  return { result: true, topicType };
661
668
  }
662
669
 
670
+ /**
671
+ * Safely deserializes a P2PMessage from raw message data.
672
+ * @param msgId - The message ID.
673
+ * @param source - The peer ID of the message source.
674
+ * @param data - The raw message data.
675
+ * @returns The deserialized P2PMessage or undefined if deserialization fails.
676
+ */
677
+ private safelyDeserializeP2PMessage(msgId: string, source: PeerId, data: Uint8Array): P2PMessage | undefined {
678
+ try {
679
+ return P2PMessage.fromMessageData(Buffer.from(data), this.config.debugP2PInstrumentMessages);
680
+ } catch (err) {
681
+ this.logger.error(`Error deserializing P2PMessage`, err, {
682
+ msgId,
683
+ source: source.toString(),
684
+ });
685
+ this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Reject);
686
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
687
+ return undefined;
688
+ }
689
+ }
690
+
663
691
  /**
664
692
  * Handles a new gossip message that was received by the client.
665
693
  * @param topic - The message's topic.
666
694
  * @param data - The message data
667
695
  */
668
696
  protected async handleNewGossipMessage(msg: Message, msgId: string, source: PeerId) {
669
- const p2pMessage = P2PMessage.fromMessageData(Buffer.from(msg.data));
697
+ const msgReceivedTime = Date.now();
698
+ let topicType: TopicType | undefined;
699
+ const p2pMessage = this.safelyDeserializeP2PMessage(msgId, source, msg.data);
700
+ if (!p2pMessage) {
701
+ return;
702
+ }
670
703
 
671
704
  const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
672
705
 
@@ -675,15 +708,25 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
675
708
  }
676
709
 
677
710
  if (msg.topic === this.topicStrings[TopicType.tx]) {
711
+ topicType = TopicType.tx;
678
712
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
679
713
  }
680
- if (msg.topic === this.topicStrings[TopicType.block_attestation] && this.clientType === P2PClientType.Full) {
681
- await this.processAttestationFromPeer(p2pMessage.payload, msgId, source);
714
+ if (msg.topic === this.topicStrings[TopicType.block_attestation]) {
715
+ topicType = TopicType.block_attestation;
716
+ if (this.clientType === P2PClientType.Full) {
717
+ await this.processAttestationFromPeer(p2pMessage.payload, msgId, source);
718
+ }
682
719
  }
683
720
  if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
721
+ topicType = TopicType.block_proposal;
684
722
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
685
723
  }
686
724
 
725
+ if (p2pMessage.timestamp !== undefined && topicType !== undefined) {
726
+ const latency = msgReceivedTime - p2pMessage.timestamp.getTime();
727
+ this.instrumentation.recordMessageLatency(topicType, latency);
728
+ }
729
+
687
730
  return;
688
731
  }
689
732
 
@@ -698,6 +741,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
698
741
  try {
699
742
  resultAndObj = await validationFunc();
700
743
  } catch (err) {
744
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
701
745
  this.logger.error(`Error deserializing and validating gossipsub message`, err, {
702
746
  msgId,
703
747
  source: source.toString(),
@@ -751,6 +795,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
751
795
  return;
752
796
  }
753
797
 
798
+ this.instrumentation.incrementTxReceived(1);
754
799
  await this.mempools.txPool.addTxs([tx]);
755
800
  }
756
801
 
@@ -763,12 +808,22 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
763
808
  private async processAttestationFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
764
809
  const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockAttestation>> = async () => {
765
810
  const attestation = BlockAttestation.fromBuffer(payloadData);
811
+ const pool = this.mempools.attestationPool;
766
812
  const isValid = await this.validateAttestation(source, attestation);
767
- const exists = isValid && (await this.mempools.attestationPool!.hasAttestation(attestation));
813
+ const exists = isValid && (await pool.hasAttestation(attestation));
814
+
815
+ let canAdd = true;
816
+ if (isValid && !exists) {
817
+ const slot = attestation.payload.header.slotNumber;
818
+ const { committee } = await this.epochCache.getCommittee(slot);
819
+ const committeeSize = committee?.length ?? 0;
820
+ canAdd = await pool.canAddAttestation(attestation, committeeSize);
821
+ }
768
822
 
769
823
  this.logger.trace(`Validate propagated block attestation`, {
770
824
  isValid,
771
825
  exists,
826
+ canAdd,
772
827
  [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
773
828
  [Attributes.P2P_ID]: source.toString(),
774
829
  });
@@ -777,6 +832,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
777
832
  return { result: TopicValidatorResult.Reject };
778
833
  } else if (exists) {
779
834
  return { result: TopicValidatorResult.Ignore, obj: attestation };
835
+ } else if (!canAdd) {
836
+ this.logger.warn(`Dropping block attestation due to per-(slot, proposalId) attestation cap`, {
837
+ slot: attestation.payload.header.slotNumber.toString(),
838
+ archive: attestation.archive.toString(),
839
+ source: source.toString(),
840
+ });
841
+ return { result: TopicValidatorResult.Ignore, obj: attestation };
780
842
  } else {
781
843
  return { result: TopicValidatorResult.Accept, obj: attestation };
782
844
  }
@@ -794,30 +856,31 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
794
856
  }
795
857
 
796
858
  this.logger.debug(
797
- `Received attestation for slot ${attestation.slotNumber.toNumber()} from external peer ${source.toString()}`,
859
+ `Received attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
798
860
  {
799
- p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
800
- slot: attestation.slotNumber.toNumber(),
861
+ p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
862
+ slot: attestation.slotNumber,
801
863
  archive: attestation.archive.toString(),
802
864
  source: source.toString(),
803
865
  },
804
866
  );
805
867
 
806
- await this.mempools.attestationPool!.addAttestations([attestation]);
868
+ await this.mempools.attestationPool.addAttestations([attestation]);
807
869
  }
808
870
 
809
871
  private async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
810
872
  const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockProposal>> = async () => {
811
873
  const block = BlockProposal.fromBuffer(payloadData);
812
874
  const isValid = await this.validateBlockProposal(source, block);
875
+ const pool = this.mempools.attestationPool;
813
876
 
814
- // Note that we dont have an attestation pool if we're a prover node, but we still
815
- // subscribe to block proposal topics in order to prevent their txs from being cleared.
816
- const exists = isValid && (await this.mempools.attestationPool?.hasBlockProposal(block));
877
+ const exists = isValid && (await pool.hasBlockProposal(block));
878
+ const canAdd = isValid && (await pool.canAddProposal(block));
817
879
 
818
880
  this.logger.trace(`Validate propagated block proposal`, {
819
881
  isValid,
820
882
  exists,
883
+ canAdd,
821
884
  [Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
822
885
  [Attributes.P2P_ID]: source.toString(),
823
886
  });
@@ -826,6 +889,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
826
889
  return { result: TopicValidatorResult.Reject };
827
890
  } else if (exists) {
828
891
  return { result: TopicValidatorResult.Ignore, obj: block };
892
+ } else if (!canAdd) {
893
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
894
+ this.logger.warn(`Penalizing peer for block proposal exceeding per-slot cap`, {
895
+ slot: block.slotNumber.toString(),
896
+ archive: block.archive.toString(),
897
+ source: source.toString(),
898
+ });
899
+ return { result: TopicValidatorResult.Reject };
829
900
  } else {
830
901
  return { result: TopicValidatorResult.Accept, obj: block };
831
902
  }
@@ -847,36 +918,47 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
847
918
 
848
919
  // REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
849
920
  @trackSpan('Libp2pService.processValidBlockProposal', async block => ({
850
- [Attributes.SLOT_NUMBER]: block.slotNumber.toNumber(),
921
+ [Attributes.SLOT_NUMBER]: block.slotNumber,
851
922
  [Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
852
- [Attributes.P2P_ID]: await block.p2pMessageIdentifier().then(i => i.toString()),
923
+ [Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then(i => i.toString()),
853
924
  }))
854
925
  private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
855
- const slot = block.slotNumber.toBigInt();
856
- const previousSlot = slot - 1n;
926
+ const slot = block.slotNumber;
927
+ const previousSlot = SlotNumber(slot - 1);
857
928
  this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
858
- p2pMessageIdentifier: await block.p2pMessageIdentifier(),
859
- slot: block.slotNumber.toNumber(),
929
+ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
930
+ slot: block.slotNumber,
860
931
  archive: block.archive.toString(),
861
932
  source: sender.toString(),
862
933
  });
863
- const attestationsForPreviousSlot = await this.mempools.attestationPool?.getAttestationsForSlot(previousSlot);
864
- if (attestationsForPreviousSlot !== undefined) {
865
- this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
866
- }
934
+ const attestationsForPreviousSlot = await this.mempools.attestationPool.getAttestationsForSlot(previousSlot);
935
+ this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
867
936
 
868
- // Mark the txs in this proposal as non-evictable
937
+ // Attempt to add proposal, then mark the txs in this proposal as non-evictable
938
+ try {
939
+ await this.mempools.attestationPool.addBlockProposal(block);
940
+ } catch (err: unknown) {
941
+ // Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
942
+ if (err instanceof ProposalSlotCapExceededError) {
943
+ this.logger.warn(`Dropping block proposal due to per-slot proposal cap`, {
944
+ slot: String(slot),
945
+ archive: block.archive.toString(),
946
+ error: (err as Error).message,
947
+ });
948
+ return;
949
+ }
950
+ throw err;
951
+ }
869
952
  await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
870
- await this.mempools.attestationPool?.addBlockProposal(block);
871
953
  const attestations = await this.blockReceivedCallback(block, sender);
872
954
 
873
955
  // TODO: fix up this pattern - the abstraction is not nice
874
- // The attestation can be undefined if no handler is registered / the validator deems the block invalid
956
+ // The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
875
957
  if (attestations?.length) {
876
958
  for (const attestation of attestations) {
877
- this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber.toNumber()}`, {
878
- p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
879
- slot: attestation.slotNumber.toNumber(),
959
+ this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber}`, {
960
+ p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
961
+ slot: attestation.slotNumber,
880
962
  archive: attestation.archive.toString(),
881
963
  });
882
964
  await this.broadcastAttestation(attestation);
@@ -889,9 +971,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
889
971
  * @param attestation - The attestation to broadcast.
890
972
  */
891
973
  @trackSpan('Libp2pService.broadcastAttestation', async attestation => ({
892
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
974
+ [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
893
975
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
894
- [Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
976
+ [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
895
977
  }))
896
978
  private async broadcastAttestation(attestation: BlockAttestation) {
897
979
  await this.propagate(attestation);
@@ -902,19 +984,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
902
984
  * @param message - The message to propagate.
903
985
  */
904
986
  public async propagate<T extends Gossipable>(message: T) {
905
- const p2pMessageIdentifier = await message.p2pMessageIdentifier();
987
+ const p2pMessageIdentifier = await message.p2pMessageLoggingIdentifier();
906
988
  this.logger.trace(`Message ${p2pMessageIdentifier} queued`, { p2pMessageIdentifier });
907
- void this.jobQueue
908
- .put(async () => {
909
- await this.sendToPeers(message);
910
- })
911
- .catch(error => {
912
- this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
913
- });
989
+ void this.sendToPeers(message).catch(error => {
990
+ this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
991
+ });
914
992
  }
915
993
 
916
994
  /**
917
- * Validate the requested block transactions.
995
+ * Validate the requested block transactions. Allow partial returns.
918
996
  * @param request - The block transactions request.
919
997
  * @param response - The block transactions response.
920
998
  * @param peerId - The ID of the peer that made the request.
@@ -924,14 +1002,71 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
924
1002
  [Attributes.BLOCK_HASH]: request.blockHash.toString(),
925
1003
  }))
926
1004
  private async validateRequestedBlockTxs(
927
- _request: BlockTxsRequest,
1005
+ request: BlockTxsRequest,
928
1006
  response: BlockTxsResponse,
929
1007
  peerId: PeerId,
930
1008
  ): Promise<boolean> {
931
1009
  const requestedTxValidator = this.createRequestedTxValidator();
932
1010
 
933
1011
  try {
934
- // TODO(palla/txs): Validate that this tx belongs to the block hash being requested
1012
+ if (!response.blockHash.equals(request.blockHash)) {
1013
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1014
+ throw new ValidationError(
1015
+ `Received block txs for unexpected block: expected ${request.blockHash.toString()}, got ${response.blockHash.toString()}`,
1016
+ );
1017
+ }
1018
+
1019
+ if (response.txIndices.getLength() !== request.txIndices.getLength()) {
1020
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1021
+ throw new ValidationError(
1022
+ `Received block txs with mismatched bitvector length: expected ${request.txIndices.getLength()}, got ${response.txIndices.getLength()}`,
1023
+ );
1024
+ }
1025
+
1026
+ // Check no duplicates and not exceeding returnable count
1027
+ const requestedIndices = new Set(request.txIndices.getTrueIndices());
1028
+ const availableIndices = new Set(response.txIndices.getTrueIndices());
1029
+ const maxReturnable = [...requestedIndices].filter(i => availableIndices.has(i)).length;
1030
+
1031
+ const returnedHashes = await Promise.all(response.txs.map(tx => tx.getTxHash().toString()));
1032
+ const uniqueReturned = new Set(returnedHashes.map(h => h.toString()));
1033
+ if (uniqueReturned.size !== returnedHashes.length) {
1034
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1035
+ throw new ValidationError(`Received duplicate txs in block txs response`);
1036
+ }
1037
+ if (response.txs.length > maxReturnable) {
1038
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1039
+ throw new ValidationError(
1040
+ `Received more txs (${response.txs.length}) than requested-and-available (${maxReturnable})`,
1041
+ );
1042
+ }
1043
+
1044
+ // Given proposal (should have locally), ensure returned txs are valid subset and match request indices
1045
+ const proposal = await this.mempools.attestationPool.getBlockProposal(request.blockHash.toString());
1046
+ if (proposal) {
1047
+ // Build intersected indices
1048
+ const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
1049
+
1050
+ // Enforce subset membership and preserve increasing order by index.
1051
+ const hashToIndexInProposal = new Map<string, number>(
1052
+ proposal.txHashes.map((h, i) => [h.toString(), i] as [string, number]),
1053
+ );
1054
+ const allowedIndexSet = new Set(intersectIdx);
1055
+ const indices = returnedHashes.map(h => hashToIndexInProposal.get(h));
1056
+ const allAllowed = indices.every(idx => idx !== undefined && allowedIndexSet.has(idx));
1057
+ const strictlyIncreasing = indices.every((idx, i) => (i === 0 ? idx !== undefined : idx! > indices[i - 1]!));
1058
+ if (!allAllowed || !strictlyIncreasing) {
1059
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1060
+ throw new ValidationError('Returned txs do not match expected subset/order for requested indices');
1061
+ }
1062
+ } else {
1063
+ // No local proposal, cannot check the membership/order of the returned txs
1064
+ this.logger.warn(
1065
+ `Block proposal not found for block hash ${request.blockHash.toString()}; cannot validate membership/order of returned txs`,
1066
+ );
1067
+ return false;
1068
+ }
1069
+
935
1070
  await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator)));
936
1071
  return true;
937
1072
  } catch (e: any) {
@@ -955,7 +1090,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
955
1090
  * ReqRespSubProtocol.TX subprotocol validation.
956
1091
  *
957
1092
  * @param requestedTxHash - The collection of the txs that was requested.
958
- * @param responseTx - The collectin of txs that was received as a response to the request.
1093
+ * @param responseTx - The collection of txs that was received as a response to the request.
959
1094
  * @param peerId - The peer ID of the peer that sent the tx.
960
1095
  * @returns True if the whole collection of txs is valid, false otherwise.
961
1096
  */
@@ -982,6 +1117,53 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
982
1117
  }
983
1118
  }
984
1119
 
1120
+ /**
1121
+ * Validates a BLOCK response.
1122
+ *
1123
+ * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1124
+ * Penalizes on block number mismatch or hash mismatch.
1125
+ *
1126
+ * @param requestedBlockNumber - The requested block number.
1127
+ * @param responseBlock - The block returned by the peer.
1128
+ * @param peerId - The peer that returned the block.
1129
+ * @returns True if the response is valid, false otherwise.
1130
+ */
1131
+ @trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
1132
+ [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
1133
+ }))
1134
+ private async validateRequestedBlock(
1135
+ requestedBlockNumber: Fr,
1136
+ responseBlock: L2Block,
1137
+ peerId: PeerId,
1138
+ ): Promise<boolean> {
1139
+ try {
1140
+ const reqNum = Number(requestedBlockNumber.toString());
1141
+ if (responseBlock.number !== reqNum) {
1142
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1143
+ return false;
1144
+ }
1145
+
1146
+ const local = await this.archiver.getBlock(BlockNumber(reqNum));
1147
+ if (!local) {
1148
+ // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1149
+ // TODO: Consider extending this validator to accept an expected hash or
1150
+ // performing quorum-based checks when using P2P syncing prior to L1 sync.
1151
+ this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1152
+ return false;
1153
+ }
1154
+ const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
1155
+ if (!localHash.equals(respHash)) {
1156
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1157
+ return false;
1158
+ }
1159
+
1160
+ return true;
1161
+ } catch (e) {
1162
+ this.logger.warn(`Error validating requested block`, e);
1163
+ return false;
1164
+ }
1165
+ }
1166
+
985
1167
  private createRequestedTxValidator(): TxValidator {
986
1168
  return new AggregateTxValidator(
987
1169
  new DataTxValidator(),
@@ -996,19 +1178,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
996
1178
  }
997
1179
 
998
1180
  private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
1181
+ const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity);
1182
+
999
1183
  if (!(await tx.validateTxHash())) {
1000
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1184
+ penalize(PeerErrorSeverity.MidToleranceError);
1001
1185
  throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
1002
1186
  }
1003
1187
 
1004
1188
  if (requested && !requested.has(tx.getTxHash().toString())) {
1005
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1189
+ penalize(PeerErrorSeverity.MidToleranceError);
1006
1190
  throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
1007
1191
  }
1008
1192
 
1009
1193
  const { result } = await txValidator.validateTx(tx);
1010
1194
  if (result === 'invalid') {
1011
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1195
+ penalize(PeerErrorSeverity.LowToleranceError);
1012
1196
  throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
1013
1197
  }
1014
1198
  }
@@ -1034,7 +1218,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1034
1218
 
1035
1219
  // Double spend validator has a special case handler
1036
1220
  if (name === 'doubleSpendValidator') {
1037
- const txBlockNumber = currentBlockNumber + 1; // tx is expected to be in the next block
1221
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1038
1222
  severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1039
1223
  }
1040
1224
 
@@ -1044,7 +1228,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1044
1228
  return true;
1045
1229
  }
1046
1230
 
1047
- private async getGasFees(blockNumber: number): Promise<GasFees> {
1231
+ private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
1048
1232
  if (blockNumber === this.feesCache?.blockNumber) {
1049
1233
  return this.feesCache.gasFees;
1050
1234
  }
@@ -1085,13 +1269,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1085
1269
  * @returns The message validators.
1086
1270
  */
1087
1271
  private async createMessageValidators(
1088
- currentBlockNumber: number,
1272
+ currentBlockNumber: BlockNumber,
1089
1273
  nextSlotTimestamp: UInt64,
1090
1274
  ): Promise<Record<string, MessageValidator>[]> {
1091
1275
  const gasFees = await this.getGasFees(currentBlockNumber);
1092
1276
  const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
1093
1277
 
1094
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
1278
+ const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1095
1279
 
1096
1280
  return createTxMessageValidators(
1097
1281
  nextSlotTimestamp,
@@ -1153,7 +1337,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1153
1337
  * @param peerId - The peer ID of the peer that sent the tx.
1154
1338
  * @returns Severity
1155
1339
  */
1156
- private async handleDoubleSpendFailure(tx: Tx, blockNumber: number): Promise<PeerErrorSeverity> {
1340
+ private async handleDoubleSpendFailure(tx: Tx, blockNumber: BlockNumber): Promise<PeerErrorSeverity> {
1157
1341
  if (blockNumber <= this.config.doubleSpendSeverePeerPenaltyWindow) {
1158
1342
  return PeerErrorSeverity.HighToleranceError;
1159
1343
  }
@@ -1161,7 +1345,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1161
1345
  const snapshotValidator = new DoubleSpendTxValidator({
1162
1346
  nullifiersExist: async (nullifiers: Buffer[]) => {
1163
1347
  const merkleTree = this.worldStateSynchronizer.getSnapshot(
1164
- blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow,
1348
+ BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow),
1165
1349
  );
1166
1350
  const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
1167
1351
  return indices.map(index => index !== undefined);
@@ -1183,9 +1367,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1183
1367
  * @returns True if the attestation is valid, false otherwise.
1184
1368
  */
1185
1369
  @trackSpan('Libp2pService.validateAttestation', async (_, attestation) => ({
1186
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
1370
+ [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1187
1371
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1188
- [Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
1372
+ [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1189
1373
  }))
1190
1374
  public async validateAttestation(peerId: PeerId, attestation: BlockAttestation): Promise<boolean> {
1191
1375
  const severity = await this.attestationValidator.validate(attestation);
@@ -1228,7 +1412,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1228
1412
  private async sendToPeers<T extends Gossipable>(message: T) {
1229
1413
  const parent = message.constructor as typeof Gossipable;
1230
1414
 
1231
- const identifier = await message.p2pMessageIdentifier().then(i => i.toString());
1415
+ const identifier = await message.p2pMessageLoggingIdentifier().then(i => i.toString());
1232
1416
  this.logger.trace(`Sending message ${identifier}`, { p2pMessageIdentifier: identifier });
1233
1417
 
1234
1418
  const recipientsNum = await this.publishToTopic(this.topicStrings[parent.p2pTopic], message);