@aztec/p2p 0.0.1-commit.c2eed6949 → 0.0.1-commit.c52d6e7

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 (427) hide show
  1. package/README.md +7 -6
  2. package/dest/bootstrap/bootstrap.d.ts +1 -1
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  4. package/dest/bootstrap/bootstrap.js +22 -6
  5. package/dest/client/factory.d.ts +4 -3
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +36 -26
  8. package/dest/client/interface.d.ts +52 -12
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +34 -19
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +105 -46
  13. package/dest/config.d.ts +143 -107
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +72 -26
  16. package/dest/errors/p2p-service.error.d.ts +9 -0
  17. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  18. package/dest/errors/p2p-service.error.js +10 -0
  19. package/dest/errors/reqresp.error.d.ts +9 -16
  20. package/dest/errors/reqresp.error.d.ts.map +1 -1
  21. package/dest/errors/reqresp.error.js +10 -17
  22. package/dest/index.d.ts +1 -2
  23. package/dest/index.d.ts.map +1 -1
  24. package/dest/index.js +0 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +98 -56
  26. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool.js +269 -196
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +218 -59
  31. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  32. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  33. package/dest/mem_pools/attestation_pool/mocks.js +6 -4
  34. package/dest/mem_pools/index.d.ts +1 -2
  35. package/dest/mem_pools/index.d.ts.map +1 -1
  36. package/dest/mem_pools/instrumentation.d.ts +9 -4
  37. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  38. package/dest/mem_pools/instrumentation.js +28 -9
  39. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -5
  40. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
  42. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -3
  43. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +6 -6
  45. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +3 -3
  48. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
  49. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  50. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +3 -1
  51. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  52. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  54. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  55. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  56. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +64 -0
  57. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +1 -1
  58. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -1
  59. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +3 -4
  60. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +1 -1
  61. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
  62. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +6 -7
  63. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +1 -1
  64. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  65. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +6 -5
  66. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +33 -5
  67. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  68. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  69. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -2
  70. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  71. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
  72. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +15 -1
  73. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  74. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +31 -0
  75. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -3
  76. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  77. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +19 -8
  78. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +17 -4
  79. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  80. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +208 -118
  81. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +10 -3
  82. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  83. package/dest/msg_validators/attestation_validator/attestation_validator.js +38 -16
  84. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  85. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  86. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  87. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +8 -3
  88. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  89. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +2 -2
  90. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +8 -3
  91. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  92. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +8 -2
  93. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +25 -3
  94. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/proposal_validator/proposal_validator.js +85 -15
  96. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  97. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +8 -15
  99. package/dest/msg_validators/tx_validator/allowed_public_setup.js +3 -3
  100. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  101. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  102. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  103. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  104. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  105. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  106. package/dest/msg_validators/tx_validator/data_validator.js +1 -0
  107. package/dest/msg_validators/tx_validator/factory.d.ts +14 -15
  108. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/factory.js +29 -16
  110. package/dest/msg_validators/tx_validator/gas_validator.d.ts +47 -10
  111. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  112. package/dest/msg_validators/tx_validator/gas_validator.js +65 -48
  113. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  114. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/index.js +2 -0
  116. package/dest/msg_validators/tx_validator/phases_validator.js +2 -2
  117. package/dest/msg_validators/tx_validator/timestamp_validator.js +1 -1
  118. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  119. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  120. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  121. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  122. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  123. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  124. package/dest/services/data_store.d.ts +1 -1
  125. package/dest/services/data_store.d.ts.map +1 -1
  126. package/dest/services/data_store.js +5 -5
  127. package/dest/services/discv5/discV5_service.d.ts +13 -2
  128. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  129. package/dest/services/discv5/discV5_service.js +119 -25
  130. package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
  131. package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
  132. package/dest/services/discv5/persisted_enr_store.js +145 -0
  133. package/dest/services/dummy_service.d.ts +15 -15
  134. package/dest/services/dummy_service.d.ts.map +1 -1
  135. package/dest/services/dummy_service.js +15 -16
  136. package/dest/services/encoding.d.ts +19 -6
  137. package/dest/services/encoding.d.ts.map +1 -1
  138. package/dest/services/encoding.js +25 -15
  139. package/dest/services/gossipsub/topic_score_params.d.ts +6 -12
  140. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  141. package/dest/services/gossipsub/topic_score_params.js +4 -14
  142. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  143. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  144. package/dest/services/libp2p/instrumentation.js +14 -0
  145. package/dest/services/libp2p/libp2p_service.d.ts +41 -40
  146. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  147. package/dest/services/libp2p/libp2p_service.js +323 -275
  148. package/dest/services/peer-manager/peer_manager.d.ts +20 -3
  149. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  150. package/dest/services/peer-manager/peer_manager.js +77 -23
  151. package/dest/services/peer-manager/peer_scoring.d.ts +34 -2
  152. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  153. package/dest/services/peer-manager/peer_scoring.js +102 -13
  154. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -8
  155. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  156. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +35 -44
  157. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +8 -5
  158. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  159. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  160. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  161. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  162. package/dest/services/reqresp/config.d.ts +15 -3
  163. package/dest/services/reqresp/config.d.ts.map +1 -1
  164. package/dest/services/reqresp/config.js +11 -0
  165. package/dest/services/reqresp/interface.d.ts +16 -18
  166. package/dest/services/reqresp/interface.d.ts.map +1 -1
  167. package/dest/services/reqresp/interface.js +10 -20
  168. package/dest/services/reqresp/metrics.d.ts +1 -1
  169. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  170. package/dest/services/reqresp/metrics.js +0 -1
  171. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  172. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  173. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  174. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  175. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  176. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
  177. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
  178. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  179. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
  180. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  181. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  182. package/dest/services/reqresp/protocols/index.js +0 -1
  183. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  184. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  185. package/dest/services/reqresp/protocols/tx.js +1 -3
  186. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  187. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  188. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  189. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  190. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  191. package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -13
  192. package/dest/services/reqresp/reqresp.d.ts +7 -29
  193. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  194. package/dest/services/reqresp/reqresp.js +59 -209
  195. package/dest/services/service.d.ts +27 -16
  196. package/dest/services/service.d.ts.map +1 -1
  197. package/dest/services/tx_collection/config.d.ts +2 -23
  198. package/dest/services/tx_collection/config.d.ts.map +1 -1
  199. package/dest/services/tx_collection/config.js +2 -55
  200. package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
  201. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  202. package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
  203. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  204. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  205. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  206. package/dest/services/tx_collection/index.d.ts +2 -3
  207. package/dest/services/tx_collection/index.d.ts.map +1 -1
  208. package/dest/services/tx_collection/index.js +0 -1
  209. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  210. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  211. package/dest/services/tx_collection/instrumentation.js +0 -2
  212. package/dest/services/tx_collection/tx_collection.d.ts +35 -51
  213. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  214. package/dest/services/tx_collection/tx_collection.js +275 -119
  215. package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
  216. package/dest/services/tx_collection/tx_collection_sink.js +2 -2
  217. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  218. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  219. package/dest/services/tx_collection/tx_source.js +13 -8
  220. package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
  221. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  222. package/dest/services/tx_file_store/tx_file_store.js +4 -14
  223. package/dest/services/tx_provider.d.ts +3 -1
  224. package/dest/services/tx_provider.d.ts.map +1 -1
  225. package/dest/services/tx_provider.js +3 -0
  226. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  227. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  228. package/dest/test-helpers/make-test-p2p-clients.js +5 -2
  229. package/dest/test-helpers/mock-pubsub.d.ts +21 -12
  230. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  231. package/dest/test-helpers/mock-pubsub.js +39 -47
  232. package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
  233. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  234. package/dest/test-helpers/reqresp-nodes.js +16 -18
  235. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  236. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  237. package/dest/test-helpers/test_tx_provider.js +3 -0
  238. package/dest/test-helpers/testbench-utils.d.ts +15 -14
  239. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  240. package/dest/test-helpers/testbench-utils.js +30 -14
  241. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  242. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  243. package/dest/testbench/p2p_client_testbench_worker.js +101 -39
  244. package/dest/testbench/worker_client_manager.d.ts +10 -6
  245. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  246. package/dest/testbench/worker_client_manager.js +51 -9
  247. package/dest/util.d.ts +8 -8
  248. package/dest/util.d.ts.map +1 -1
  249. package/dest/util.js +38 -10
  250. package/dest/versioning.d.ts +3 -6
  251. package/dest/versioning.d.ts.map +1 -1
  252. package/dest/versioning.js +3 -24
  253. package/package.json +15 -16
  254. package/src/bootstrap/bootstrap.ts +17 -3
  255. package/src/client/factory.ts +54 -25
  256. package/src/client/interface.ts +48 -18
  257. package/src/client/p2p_client.ts +125 -79
  258. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  259. package/src/config.ts +146 -34
  260. package/src/errors/p2p-service.error.ts +11 -0
  261. package/src/errors/reqresp.error.ts +13 -19
  262. package/src/index.ts +0 -1
  263. package/src/mem_pools/attestation_pool/attestation_pool.ts +324 -239
  264. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +238 -63
  265. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  266. package/src/mem_pools/index.ts +0 -3
  267. package/src/mem_pools/instrumentation.ts +18 -12
  268. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
  269. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
  270. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -4
  271. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -2
  272. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  273. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +67 -0
  274. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +1 -3
  275. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -7
  276. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +5 -6
  277. package/src/mem_pools/tx_pool_v2/interfaces.ts +31 -4
  278. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +20 -8
  279. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +35 -0
  280. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +22 -8
  281. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +233 -123
  282. package/src/msg_validators/attestation_validator/attestation_validator.ts +46 -15
  283. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +15 -7
  284. package/src/msg_validators/proposal_validator/README.md +1 -1
  285. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +15 -3
  286. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +26 -3
  287. package/src/msg_validators/proposal_validator/proposal_validator.ts +94 -12
  288. package/src/msg_validators/tx_validator/README.md +13 -3
  289. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
  290. package/src/msg_validators/tx_validator/allowed_public_setup.ts +3 -3
  291. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  292. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  293. package/src/msg_validators/tx_validator/data_validator.ts +2 -0
  294. package/src/msg_validators/tx_validator/factory.ts +37 -20
  295. package/src/msg_validators/tx_validator/gas_validator.ts +99 -54
  296. package/src/msg_validators/tx_validator/index.ts +2 -0
  297. package/src/msg_validators/tx_validator/phases_validator.ts +2 -2
  298. package/src/msg_validators/tx_validator/timestamp_validator.ts +1 -1
  299. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  300. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  301. package/src/services/data_store.ts +5 -13
  302. package/src/services/discv5/discV5_service.ts +126 -16
  303. package/src/services/discv5/persisted_enr_store.ts +158 -0
  304. package/src/services/dummy_service.ts +20 -39
  305. package/src/services/encoding.ts +28 -20
  306. package/src/services/gossipsub/README.md +33 -11
  307. package/src/services/gossipsub/topic_score_params.ts +9 -18
  308. package/src/services/libp2p/instrumentation.ts +14 -0
  309. package/src/services/libp2p/libp2p_service.ts +371 -301
  310. package/src/services/peer-manager/peer_manager.ts +84 -22
  311. package/src/services/peer-manager/peer_scoring.ts +102 -8
  312. package/src/services/reqresp/README.md +2 -37
  313. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +39 -52
  314. package/src/services/reqresp/batch-tx-requester/interface.ts +11 -4
  315. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  316. package/src/services/reqresp/config.ts +19 -2
  317. package/src/services/reqresp/interface.ts +21 -47
  318. package/src/services/reqresp/metrics.ts +0 -1
  319. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  320. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -30
  321. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
  322. package/src/services/reqresp/protocols/index.ts +0 -1
  323. package/src/services/reqresp/protocols/tx.ts +1 -3
  324. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  325. package/src/services/reqresp/rate-limiter/rate_limits.ts +3 -13
  326. package/src/services/reqresp/reqresp.ts +69 -252
  327. package/src/services/service.ts +32 -32
  328. package/src/services/tx_collection/config.ts +3 -80
  329. package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
  330. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  331. package/src/services/tx_collection/index.ts +1 -6
  332. package/src/services/tx_collection/instrumentation.ts +1 -7
  333. package/src/services/tx_collection/tx_collection.ts +330 -173
  334. package/src/services/tx_collection/tx_collection_sink.ts +2 -2
  335. package/src/services/tx_collection/tx_source.ts +10 -8
  336. package/src/services/tx_file_store/tx_file_store.ts +5 -17
  337. package/src/services/tx_provider.ts +5 -0
  338. package/src/test-helpers/make-test-p2p-clients.ts +3 -0
  339. package/src/test-helpers/mock-pubsub.ts +41 -64
  340. package/src/test-helpers/reqresp-nodes.ts +12 -22
  341. package/src/test-helpers/test_tx_provider.ts +5 -0
  342. package/src/test-helpers/testbench-utils.ts +36 -26
  343. package/src/testbench/p2p_client_testbench_worker.ts +108 -53
  344. package/src/testbench/worker_client_manager.ts +59 -20
  345. package/src/util.ts +33 -14
  346. package/src/versioning.ts +3 -33
  347. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  348. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  349. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -304
  350. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  351. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  352. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  353. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  354. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  355. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  356. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  357. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  358. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  359. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  360. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  361. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  362. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  363. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  364. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  365. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  366. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  367. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  368. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  369. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  370. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  371. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  372. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  373. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  374. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  375. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  376. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  377. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  378. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  379. package/dest/mem_pools/tx_pool/index.js +0 -2
  380. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  381. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  382. package/dest/mem_pools/tx_pool/priority.js +0 -15
  383. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  384. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  385. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  386. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  387. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  388. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  389. package/dest/msg_validators/clock_tolerance.d.ts +0 -21
  390. package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
  391. package/dest/msg_validators/clock_tolerance.js +0 -38
  392. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  393. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  394. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  395. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  396. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  397. package/dest/services/reqresp/protocols/block.js +0 -32
  398. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -51
  399. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  400. package/dest/services/tx_collection/fast_tx_collection.js +0 -311
  401. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
  402. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  403. package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
  404. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
  405. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  406. package/dest/services/tx_collection/slow_tx_collection.js +0 -211
  407. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -343
  408. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  409. package/src/mem_pools/tx_pool/README.md +0 -270
  410. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  411. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  412. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  413. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  414. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  415. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  416. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  417. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  418. package/src/mem_pools/tx_pool/index.ts +0 -2
  419. package/src/mem_pools/tx_pool/priority.ts +0 -20
  420. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  421. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  422. package/src/msg_validators/clock_tolerance.ts +0 -52
  423. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  424. package/src/services/reqresp/protocols/block.ts +0 -37
  425. package/src/services/tx_collection/fast_tx_collection.ts +0 -361
  426. package/src/services/tx_collection/proposal_tx_collector.ts +0 -108
  427. package/src/services/tx_collection/slow_tx_collection.ts +0 -266
@@ -1,5 +1,7 @@
1
1
  import { createLogger } from '@aztec/foundation/log';
2
2
  import { sleep } from '@aztec/foundation/sleep';
3
+ import { DateProvider } from '@aztec/foundation/timer';
4
+ import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
5
  import { type ComponentsVersions, checkCompressedComponentVersion } from '@aztec/stdlib/versioning';
4
6
  import { OtelMetricsAdapter, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
5
7
 
@@ -14,9 +16,13 @@ import { createNodeENR } from '../../enr/generate-enr.js';
14
16
  import { AZTEC_ENR_KEY, Discv5Event, PeerEvent } from '../../types/index.js';
15
17
  import { convertToMultiaddr } from '../../util.js';
16
18
  import { type PeerDiscoveryService, PeerDiscoveryState } from '../service.js';
19
+ import { PersistedEnrStore } from './persisted_enr_store.js';
17
20
 
18
21
  const delayBeforeStart = 2000; // 2sec
19
22
 
23
+ /** Upper bound on persisted peer ENRs, to keep the store bounded as peers churn. */
24
+ const MAX_PERSISTED_PEER_ENRS = 100;
25
+
20
26
  /**
21
27
  * Peer discovery service using Discv5.
22
28
  */
@@ -35,12 +41,19 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
35
41
  private bootstrapNodePeerIds: PeerId[] = [];
36
42
  public bootstrapNodeEnrs: ENR[] = [];
37
43
  private trustedPeerEnrs: ENR[] = [];
44
+ /** Node IDs of all config-provided peers (bootstrap, trusted, private); these are never persisted. */
45
+ private readonly configProvidedNodeIds: Set<string>;
38
46
 
39
47
  private startTime = 0;
40
48
 
49
+ private currentIp: string | undefined;
50
+
51
+ /** Persistent store of discovered peer ENRs, used to re-seed discovery after a restart. */
52
+ private readonly persistedEnrs?: PersistedEnrStore;
53
+
41
54
  private handlers = {
42
55
  onMultiaddrUpdated: this.onMultiaddrUpdated.bind(this),
43
- onDiscovered: this.onDiscovered.bind(this),
56
+ onPeerDiscovered: this.onPeerDiscovered.bind(this),
44
57
  onEnrAdded: this.onEnrAdded.bind(this),
45
58
  };
46
59
 
@@ -50,14 +63,27 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
50
63
  private readonly packageVersion: string,
51
64
  telemetry: TelemetryClient = getTelemetryClient(),
52
65
  private logger = createLogger('p2p:discv5_service'),
66
+ store?: AztecAsyncKVStore,
53
67
  configOverrides: Partial<IDiscv5CreateOptions> = {},
68
+ private readonly dateProvider: DateProvider = new DateProvider(),
54
69
  ) {
55
70
  super();
71
+
72
+ this.persistedEnrs = store
73
+ ? new PersistedEnrStore(store, MAX_PERSISTED_PEER_ENRS, createLogger(`${this.logger.module}:enr-store`))
74
+ : undefined;
75
+
56
76
  const { p2pIp, p2pPort, p2pBroadcastPort, bootstrapNodes, trustedPeers, privatePeers } = config;
57
77
 
78
+ this.currentIp = p2pIp;
58
79
  this.bootstrapNodeEnrs = bootstrapNodes.map(x => ENR.decodeTxt(x));
59
80
  const privatePeerEnrs = new Set(privatePeers);
60
81
  this.trustedPeerEnrs = trustedPeers.filter(x => !privatePeerEnrs.has(x)).map(x => ENR.decodeTxt(x));
82
+ // Peers supplied via config are re-injected from config on every start, so they must never end up
83
+ // in the persisted (discovered-peer) store — private peers especially must not be written there.
84
+ this.configProvidedNodeIds = new Set(
85
+ [...bootstrapNodes, ...trustedPeers, ...privatePeers].map(x => ENR.decodeTxt(x).nodeId),
86
+ );
61
87
 
62
88
  // If no overridden broadcast port is provided, use the p2p port as the broadcast port
63
89
  if (!p2pBroadcastPort) {
@@ -96,7 +122,8 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
96
122
  lookupTimeout: 2000,
97
123
  requestTimeout: 2000,
98
124
  allowUnverifiedSessions: true,
99
- enrUpdate: config.queryForIp && !p2pIp, // Enable native ENR IP discovery when no static IP is configured
125
+ enrUpdate: config.queryForIp || !p2pIp,
126
+ pingInterval: config.queryForIp ? 10_000 : 300_000,
100
127
  ...configOverrides.config,
101
128
  },
102
129
  metricsRegistry,
@@ -121,19 +148,40 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
121
148
  }
122
149
  };
123
150
 
124
- this.discv5.on(Discv5Event.DISCOVERED, this.handlers.onDiscovered);
151
+ this.discv5.on(Discv5Event.DISCOVERED, this.handlers.onPeerDiscovered);
125
152
  this.discv5.on(Discv5Event.ENR_ADDED, this.handlers.onEnrAdded);
126
153
  this.discv5.on(Discv5Event.MULTIADDR_UPDATED, this.handlers.onMultiaddrUpdated);
127
154
  }
128
155
 
129
156
  private onMultiaddrUpdated(m: Multiaddr) {
130
- // We want to update our tcp port to match the udp port
131
- // p2pBroadcastPort is optional on config, however it is set to default within the p2p client factory
132
- const address = m.nodeAddress().address;
133
- const multiAddrTcp = multiaddr(convertToMultiaddr(address, this.config.p2pBroadcastPort!, 'tcp'));
157
+ const newIp = m.nodeAddress().address;
158
+ const previousIp = this.currentIp;
159
+
160
+ if (newIp === previousIp) {
161
+ this.logger.debug('Discv5 confirmed current IP (no change)', { ip: newIp });
162
+ return;
163
+ }
164
+
165
+ const multiAddrTcp = multiaddr(convertToMultiaddr(newIp, this.config.p2pBroadcastPort!, 'tcp'));
134
166
  this.enr.setLocationMultiaddr(multiAddrTcp);
135
- this.logger.info('Multiaddr updated', { multiaddr: multiAddrTcp.toString() });
136
- this.emit('ip:changed', address);
167
+ this.currentIp = newIp;
168
+
169
+ if (previousIp) {
170
+ this.logger.info('IP address changed, ENR updated', {
171
+ previousIp,
172
+ newIp,
173
+ multiaddr: multiAddrTcp.toString(),
174
+ enr: this.enr.encodeTxt(),
175
+ });
176
+ } else {
177
+ this.logger.info('Initial IP discovered via discv5, ENR updated', {
178
+ ip: newIp,
179
+ multiaddr: multiAddrTcp.toString(),
180
+ enr: this.enr.encodeTxt(),
181
+ });
182
+ }
183
+
184
+ this.emit('ip:changed', newIp);
137
185
  }
138
186
 
139
187
  public async start(): Promise<void> {
@@ -142,14 +190,19 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
142
190
  }
143
191
  this.logger.debug('Starting DiscV5');
144
192
  await this.discv5.start();
145
- this.startTime = Date.now();
193
+ this.startTime = this.dateProvider.now();
146
194
 
195
+ const enrUpdateEnabled = this.config.queryForIp || !this.config.p2pIp;
147
196
  this.logger.info(`DiscV5 service started`, {
148
197
  nodeId: this.enr.nodeId,
149
198
  peerId: this.peerId,
150
199
  enrUdp: await this.enr.getFullMultiaddr('udp'),
151
200
  enrTcp: await this.enr.getFullMultiaddr('tcp'),
152
201
  versions: this.versions,
202
+ enrUpdateEnabled,
203
+ queryForIp: this.config.queryForIp,
204
+ configuredIp: this.config.p2pIp ?? 'none',
205
+ pingIntervalMs: this.config.queryForIp ? 10_000 : 300_000,
153
206
  });
154
207
  this.currentState = PeerDiscoveryState.RUNNING;
155
208
 
@@ -189,6 +242,26 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
189
242
  this.discv5.addEnr(enr);
190
243
  }
191
244
  }
245
+
246
+ // Re-seed discovery from peers persisted on previous runs. This lets a node rejoin the network
247
+ // after a restart even when no bootstrap node is reachable: discv5 has no on-disk routing table,
248
+ // so without this its DHT would start empty and rediscovery would depend on inbound dials alone.
249
+ if (this.persistedEnrs) {
250
+ // Drop peers that are now config-provided (re-injected above) or fail version checks.
251
+ const enrs = await this.persistedEnrs.load(
252
+ enr => this.validateEnr(enr) && !this.configProvidedNodeIds.has(enr.nodeId),
253
+ );
254
+ for (const enr of enrs) {
255
+ try {
256
+ this.discv5.addEnr(enr);
257
+ } catch (err) {
258
+ this.logger.debug(`Error re-seeding persisted ENR ${enr.nodeId}`, err);
259
+ }
260
+ }
261
+ if (enrs.length > 0) {
262
+ this.logger.info(`Re-seeded discovery with ${enrs.length} persisted peer ENRs`);
263
+ }
264
+ }
192
265
  }
193
266
 
194
267
  public async runRandomNodesQuery(): Promise<void> {
@@ -198,8 +271,8 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
198
271
 
199
272
  // First, wait some time before starting the peer discovery
200
273
  // reference: https://github.com/ChainSafe/lodestar/issues/3423
201
- const msSinceStart = Date.now() - this.startTime;
202
- if (Date.now() - this.startTime <= delayBeforeStart) {
274
+ const msSinceStart = this.dateProvider.now() - this.startTime;
275
+ if (this.dateProvider.now() - this.startTime <= delayBeforeStart) {
203
276
  await sleep(delayBeforeStart - msSinceStart);
204
277
  }
205
278
 
@@ -234,7 +307,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
234
307
  if (this.currentState !== PeerDiscoveryState.RUNNING) {
235
308
  return;
236
309
  }
237
- await this.discv5.off(Discv5Event.DISCOVERED, this.handlers.onDiscovered);
310
+ await this.discv5.off(Discv5Event.DISCOVERED, this.handlers.onPeerDiscovered);
238
311
  await this.discv5.off(Discv5Event.ENR_ADDED, this.handlers.onEnrAdded);
239
312
  await this.discv5.off(Discv5Event.MULTIADDR_UPDATED, this.handlers.onMultiaddrUpdated);
240
313
 
@@ -244,12 +317,38 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
244
317
  }
245
318
 
246
319
  private async onEnrAdded(enr: ENR) {
247
- const multiAddrTcp = await enr.getFullMultiaddr('tcp');
248
- const multiAddrUdp = await enr.getFullMultiaddr('udp');
249
- this.logger.debug(`Added ENR ${enr.encodeTxt()}`, { multiAddrTcp, multiAddrUdp, nodeId: enr.nodeId });
320
+ try {
321
+ const multiAddrTcp = await enr.getFullMultiaddr('tcp');
322
+ const multiAddrUdp = await enr.getFullMultiaddr('udp');
323
+ this.logger.debug(`Added ENR ${enr.encodeTxt()}`, { multiAddrTcp, multiAddrUdp, nodeId: enr.nodeId });
324
+ // A peer just entered the routing table — persist it so we can re-seed discovery after a restart.
325
+ if (this.persistedEnrs && this.shouldPersist(enr)) {
326
+ await this.persistedEnrs.persist(enr);
327
+ }
328
+ this.onDiscovered(enr);
329
+ } catch (err) {
330
+ // A malformed ENR address field (e.g. a 3-byte TCP port) makes @nethermindeth/enr throw while
331
+ // parsing the multiaddr. This is an async event listener, so an unhandled rejection would crash
332
+ // the process — catch, log, and drop the ENR instead.
333
+ this.logger.warn(`Dropping ENR with unparseable address`, { nodeId: enr.nodeId, err });
334
+ }
335
+ }
336
+
337
+ private async onPeerDiscovered(enr: ENR) {
338
+ // discv5 updates an existing routing-table entry on an ENR sequence bump without emitting enrAdded,
339
+ // so DISCOVERED is our only signal that a peer we already track may have changed address. Refresh
340
+ // the persisted copy (a no-op for peers we don't already store) so we don't keep dialing a stale ENR.
341
+ if (this.persistedEnrs && this.shouldPersist(enr)) {
342
+ await this.persistedEnrs.refresh(enr);
343
+ }
250
344
  this.onDiscovered(enr);
251
345
  }
252
346
 
347
+ /** Whether an ENR belongs in the persisted store: a validated, non-config peer that isn't ourselves. */
348
+ private shouldPersist(enr: ENR): boolean {
349
+ return !this.configProvidedNodeIds.has(enr.nodeId) && enr.nodeId !== this.enr.nodeId && this.validateEnr(enr);
350
+ }
351
+
253
352
  private isOurBootnode(enr: ENR) {
254
353
  return this.bootstrapNodeEnrs.some(x => x.nodeId === enr.nodeId);
255
354
  }
@@ -283,6 +382,17 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
283
382
  return false;
284
383
  }
285
384
 
385
+ // A malformed TCP field (e.g. a non-2-byte port) makes @nethermindeth/enr throw while building the
386
+ // multiaddr. Reject such an ENR here so it's never emitted as a full peer or re-parsed by an
387
+ // unguarded listener (which would crash the process). A missing TCP addr is allowed — those peers
388
+ // are simply skipped at dial time.
389
+ try {
390
+ enr.getLocationMultiaddr('tcp');
391
+ } catch (err) {
392
+ this.logger.debug(`Peer node ${enr.nodeId} has an unparseable TCP address`, { err });
393
+ return false;
394
+ }
395
+
286
396
  // And check it has the correct version
287
397
  let compressedVersion;
288
398
  try {
@@ -0,0 +1,158 @@
1
+ import { type Logger, createLogger } from '@aztec/foundation/log';
2
+ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
3
+
4
+ import { ENR } from '@nethermindeth/enr';
5
+
6
+ /** Map name under which discovered peer ENRs are persisted so discovery can be re-seeded after a restart. */
7
+ const PERSISTED_ENRS_MAP_NAME = 'discovered_peer_enrs';
8
+
9
+ /**
10
+ * A persisted peer entry: the ENR text plus a monotonic sequence number recording when the peer was
11
+ * last seen. The sequence orders the store as a FIFO so eviction drops the oldest-seen peers first.
12
+ */
13
+ interface PersistedEnr {
14
+ enr: string;
15
+ seq: number;
16
+ }
17
+
18
+ function parsePersistedEnr(value: string): PersistedEnr | undefined {
19
+ try {
20
+ const parsed = JSON.parse(value);
21
+ if (typeof parsed?.enr === 'string' && typeof parsed?.seq === 'number') {
22
+ return parsed;
23
+ }
24
+ } catch {
25
+ // Unparseable entry; caller treats it as stale.
26
+ }
27
+ return undefined;
28
+ }
29
+
30
+ /**
31
+ * A bounded, transactional store of discovered peer ENRs used to re-seed discovery after a restart.
32
+ *
33
+ * Entries are keyed by nodeId (so re-seeing a peer dedups in place) and carry a monotonic sequence so
34
+ * the store behaves as a FIFO: when it exceeds its cap, the oldest-seen peers are evicted first. All
35
+ * writes run in a transaction so concurrent discovery events can't race the size check.
36
+ */
37
+ export class PersistedEnrStore {
38
+ private readonly enrs: AztecAsyncMap<string, string>;
39
+ /** Monotonic sequence stamped on each entry; seeded from the store's max in {@link load}. */
40
+ private seq = 0;
41
+
42
+ constructor(
43
+ private readonly store: AztecAsyncKVStore,
44
+ private readonly maxEntries: number,
45
+ private readonly logger: Logger = createLogger('p2p:discv5:enr-store'),
46
+ ) {
47
+ this.enrs = store.openMap(PERSISTED_ENRS_MAP_NAME);
48
+ }
49
+
50
+ /** Adds or replaces a peer's ENR, stamping it as most-recently-seen and evicting the oldest if over cap. */
51
+ public async persist(enr: ENR): Promise<void> {
52
+ const nodeId = enr.nodeId;
53
+ const enrTxt = enr.encodeTxt();
54
+ try {
55
+ await this.store.transactionAsync(async () => {
56
+ const seq = ++this.seq;
57
+ const others: { nodeId: string; seq: number }[] = [];
58
+ for await (const [id, value] of this.enrs.entriesAsync()) {
59
+ if (id !== nodeId) {
60
+ others.push({ nodeId: id, seq: parsePersistedEnr(value)?.seq ?? 0 });
61
+ }
62
+ }
63
+ const overflow = others.length + 1 - this.maxEntries;
64
+ if (overflow > 0) {
65
+ others.sort((a, b) => a.seq - b.seq); // oldest-seen (lowest sequence) first
66
+ for (let i = 0; i < overflow; i++) {
67
+ await this.enrs.delete(others[i].nodeId);
68
+ }
69
+ }
70
+ await this.enrs.set(nodeId, JSON.stringify({ enr: enrTxt, seq }));
71
+ });
72
+ } catch (err) {
73
+ this.logger.warn(`Failed to persist discovered ENR ${nodeId}`, err);
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Refreshes an already-persisted peer's stored ENR when a newer one (higher ENR sequence) is seen.
79
+ * A no-op for peers we don't already track — we never add new peers via this path, only update.
80
+ *
81
+ * This exists because discv5 updates an existing routing-table entry on an ENR sequence bump without
82
+ * emitting an `enrAdded` event, so a peer that changes address would otherwise keep its stale ENR
83
+ * persisted until evicted.
84
+ */
85
+ public async refresh(enr: ENR): Promise<void> {
86
+ const nodeId = enr.nodeId;
87
+ try {
88
+ await this.store.transactionAsync(async () => {
89
+ const existing = await this.enrs.getAsync(nodeId);
90
+ if (!existing) {
91
+ return;
92
+ }
93
+ // Two unrelated sequence numbers are in play:
94
+ // - the ENR sequence (`enr.seq` / `storedEnrSeq`) is set by the *peer* and bumped whenever it
95
+ // revises its record (e.g. changes address); we compare these to decide whether the incoming
96
+ // ENR is genuinely newer and worth keeping.
97
+ // - our storage sequence (`this.seq`) is an internal counter used only for FIFO eviction; we
98
+ // stamp a fresh one so this entry counts as most-recently-seen.
99
+ const storedEnrSeq = this.decodeStoredEnr(existing)?.seq;
100
+ if (storedEnrSeq !== undefined && enr.seq <= storedEnrSeq) {
101
+ return;
102
+ }
103
+ await this.enrs.set(nodeId, JSON.stringify({ enr: enr.encodeTxt(), seq: ++this.seq }));
104
+ });
105
+ } catch (err) {
106
+ this.logger.warn(`Failed to refresh persisted ENR ${nodeId}`, err);
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Loads all persisted ENRs, decoding each and keeping those the `accept` predicate allows. Entries
112
+ * that fail to decode or are rejected are removed from the store. The FIFO sequence resumes from the
113
+ * highest persisted value so eviction order survives restarts.
114
+ */
115
+ public async load(accept: (enr: ENR) => boolean): Promise<ENR[]> {
116
+ const valid: ENR[] = [];
117
+ const stale: string[] = [];
118
+ let maxSeq = 0;
119
+ for await (const [nodeId, value] of this.enrs.entriesAsync()) {
120
+ const parsed = parsePersistedEnr(value);
121
+ let enr: ENR | undefined;
122
+ if (parsed) {
123
+ try {
124
+ enr = ENR.decodeTxt(parsed.enr);
125
+ } catch (err) {
126
+ this.logger.debug(`Dropping undecodable persisted ENR ${nodeId}`, err);
127
+ }
128
+ }
129
+ if (!parsed || !enr || !accept(enr)) {
130
+ stale.push(nodeId);
131
+ continue;
132
+ }
133
+ maxSeq = Math.max(maxSeq, parsed.seq);
134
+ valid.push(enr);
135
+ }
136
+ this.seq = maxSeq;
137
+ if (stale.length > 0) {
138
+ await this.store.transactionAsync(async () => {
139
+ for (const nodeId of stale) {
140
+ await this.enrs.delete(nodeId);
141
+ }
142
+ });
143
+ }
144
+ return valid;
145
+ }
146
+
147
+ private decodeStoredEnr(value: string): ENR | undefined {
148
+ const parsed = parsePersistedEnr(value);
149
+ if (!parsed) {
150
+ return undefined;
151
+ }
152
+ try {
153
+ return ENR.decodeTxt(parsed.enr);
154
+ } catch {
155
+ return undefined;
156
+ }
157
+ }
158
+ }
@@ -18,16 +18,17 @@ import type {
18
18
  ReqRespSubProtocol,
19
19
  ReqRespSubProtocolHandler,
20
20
  ReqRespSubProtocolHandlers,
21
- ReqRespSubProtocolValidators,
22
21
  SubProtocolMap,
23
22
  } from './reqresp/interface.js';
24
23
  import type { GoodByeReason } from './reqresp/protocols/goodbye.js';
25
24
  import { ReqRespStatus } from './reqresp/status.js';
26
25
  import {
27
26
  type P2PBlockReceivedCallback,
27
+ type P2PCheckpointAttestationCallback,
28
28
  type P2PCheckpointReceivedCallback,
29
29
  type P2PDuplicateAttestationCallback,
30
30
  type P2PDuplicateProposalCallback,
31
+ type P2POversizedProposalCallback,
31
32
  type P2PService,
32
33
  type PeerDiscoveryService,
33
34
  PeerDiscoveryState,
@@ -37,6 +38,8 @@ import {
37
38
  * A dummy implementation of the P2P Service.
38
39
  */
39
40
  export class DummyP2PService implements P2PService {
41
+ private allNodesCheckpointReceivedCallback?: P2PCheckpointReceivedCallback;
42
+
40
43
  updateConfig(_config: Partial<P2PReqRespConfig>): void {}
41
44
 
42
45
  /** Returns an empty array for peers. */
@@ -86,18 +89,28 @@ export class DummyP2PService implements P2PService {
86
89
  /**
87
90
  * Register a callback into the validator client for when a checkpoint proposal is received
88
91
  */
89
- public registerCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {}
92
+ public registerValidatorCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {}
93
+ public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
94
+ this.allNodesCheckpointReceivedCallback = callback;
95
+ }
90
96
 
91
97
  /**
92
98
  * Register a callback for when a duplicate proposal is detected
93
99
  */
94
100
  public registerDuplicateProposalCallback(_callback: P2PDuplicateProposalCallback): void {}
95
101
 
102
+ /**
103
+ * Register a callback for when an oversized proposal is stored
104
+ */
105
+ public registerOversizedProposalCallback(_callback: P2POversizedProposalCallback): void {}
106
+
96
107
  /**
97
108
  * Register a callback for when a duplicate attestation is detected
98
109
  */
99
110
  public registerDuplicateAttestationCallback(_callback: P2PDuplicateAttestationCallback): void {}
100
111
 
112
+ public registerCheckpointAttestationCallback(_callback: P2PCheckpointAttestationCallback): void {}
113
+
101
114
  /**
102
115
  * Sends a request to a peer.
103
116
  * @param _protocol - The protocol to send the request on.
@@ -111,19 +124,6 @@ export class DummyP2PService implements P2PService {
111
124
  return Promise.resolve(undefined);
112
125
  }
113
126
 
114
- /**
115
- * Sends a batch request to a peer.
116
- * @param _protocol - The protocol to send the request on.
117
- * @param _requests - The requests to send.
118
- * @returns The responses from the peer, otherwise undefined.
119
- */
120
- public sendBatchRequest<Protocol extends ReqRespSubProtocol>(
121
- _protocol: Protocol,
122
- _requests: InstanceType<SubProtocolMap[Protocol]['request']>[],
123
- ): Promise<InstanceType<SubProtocolMap[Protocol]['response']>[]> {
124
- return Promise.resolve([]);
125
- }
126
-
127
127
  public sendRequestToPeer(
128
128
  _peerId: PeerId,
129
129
  _subProtocol: ReqRespSubProtocol,
@@ -145,11 +145,7 @@ export class DummyP2PService implements P2PService {
145
145
  return Promise.resolve();
146
146
  }
147
147
 
148
- addReqRespSubProtocol(
149
- _subProtocol: ReqRespSubProtocol,
150
- _handler: ReqRespSubProtocolHandler,
151
- _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol],
152
- ): Promise<void> {
148
+ addReqRespSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise<void> {
153
149
  return Promise.resolve();
154
150
  }
155
151
 
@@ -178,6 +174,7 @@ export class DummyP2PService implements P2PService {
178
174
  peerScoring: {
179
175
  penalizePeer: (_peerId, _penalty) => {},
180
176
  },
177
+ validateRequestedBlockTxsConsistency: () => Promise.resolve(true),
181
178
  };
182
179
  }
183
180
  }
@@ -282,10 +279,8 @@ export class DummyPeerManager implements PeerManagerInterface {
282
279
 
283
280
  export class DummyReqResp implements ReqRespInterface {
284
281
  updateConfig(_config: Partial<P2PReqRespConfig>): void {}
285
- start(
286
- _subProtocolHandlers: ReqRespSubProtocolHandlers,
287
- _subProtocolValidators: ReqRespSubProtocolValidators,
288
- ): Promise<void> {
282
+ setShouldRejectPeer(): void {}
283
+ start(_subProtocolHandlers: ReqRespSubProtocolHandlers): Promise<void> {
289
284
  return Promise.resolve();
290
285
  }
291
286
  stop(): Promise<void> {
@@ -297,16 +292,6 @@ export class DummyReqResp implements ReqRespInterface {
297
292
  ): Promise<InstanceType<SubProtocolMap[SubProtocol]['response']> | undefined> {
298
293
  return Promise.resolve(undefined);
299
294
  }
300
- sendBatchRequest<SubProtocol extends ReqRespSubProtocol>(
301
- _subProtocol: SubProtocol,
302
- _requests: InstanceType<SubProtocolMap[SubProtocol]['request']>[],
303
- _pinnedPeer: PeerId | undefined,
304
- _timeoutMs?: number,
305
- _maxPeers?: number,
306
- _maxRetryAttempts?: number,
307
- ): Promise<InstanceType<SubProtocolMap[SubProtocol]['response']>[]> {
308
- return Promise.resolve([]);
309
- }
310
295
  public sendRequestToPeer(
311
296
  _peerId: PeerId,
312
297
  _subProtocol: ReqRespSubProtocol,
@@ -325,11 +310,7 @@ export class DummyReqResp implements ReqRespInterface {
325
310
  };
326
311
  }
327
312
 
328
- addSubProtocol(
329
- _subProtocol: ReqRespSubProtocol,
330
- _handler: ReqRespSubProtocolHandler,
331
- _validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol],
332
- ): Promise<void> {
313
+ addSubProtocol(_subProtocol: ReqRespSubProtocol, _handler: ReqRespSubProtocolHandler): Promise<void> {
333
314
  return Promise.resolve();
334
315
  }
335
316
  }
@@ -2,12 +2,16 @@
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { MAX_TX_SIZE_KB, TopicType, getTopicFromString } from '@aztec/stdlib/p2p';
4
4
 
5
- import type { RPC } from '@chainsafe/libp2p-gossipsub/message';
6
5
  import type { DataTransform } from '@chainsafe/libp2p-gossipsub/types';
7
6
  import type { Message } from '@libp2p/interface';
8
7
  import { webcrypto } from 'node:crypto';
9
8
  import { compressSync, uncompressSync } from 'snappy';
10
- import xxhashFactory from 'xxhash-wasm';
9
+
10
+ /**
11
+ * Fallback maximum response size (in KB) applied when no explicit per-request bound is supplied.
12
+ * Used both as the `SnappyTransform` default and as the reception-side fallback in `readMessage`.
13
+ */
14
+ export const DEFAULT_MAX_RESPONSE_SIZE_KB = 10 * 1024;
11
15
 
12
16
  /** Thrown when a Snappy-compressed response exceeds the allowed decompressed size. */
13
17
  export class OversizedSnappyResponseError extends Error {
@@ -17,26 +21,21 @@ export class OversizedSnappyResponseError extends Error {
17
21
  }
18
22
  }
19
23
 
20
- // Load WASM
21
- const xxhash = await xxhashFactory();
22
-
23
- // Use salt to prevent msgId from being mined for collisions
24
- const h64Seed = BigInt(Math.floor(Math.random() * 1e9));
25
-
26
- // Shared buffer to convert msgId to string
27
- const sharedMsgIdBuf = Buffer.alloc(20);
28
-
29
24
  /**
30
- * The function used to generate a gossipsub message id
31
- * We use the first 8 bytes of SHA256(data) for content addressing
25
+ * Thrown when the compressed bytes accumulated while reading a response stream exceed the reception
26
+ * bound, before the full payload is buffered. Distinct from {@link OversizedSnappyResponseError},
27
+ * which guards the decompressed size after the stream has already been fully received.
32
28
  */
33
- export function fastMsgIdFn(rpcMsg: RPC.Message): string {
34
- if (rpcMsg.data) {
35
- return xxhash.h64Raw(rpcMsg.data, h64Seed).toString(16);
29
+ export class ResponseSizeLimitExceededError extends Error {
30
+ constructor(accumulatedBytes: number, limitBytes: number) {
31
+ super(`Accumulated response size ${accumulatedBytes} bytes exceeds reception limit of ${limitBytes} bytes`);
32
+ this.name = 'ResponseSizeLimitExceededError';
36
33
  }
37
- return '0000000000000000';
38
34
  }
39
35
 
36
+ // Shared buffer to convert msgId to string
37
+ const sharedMsgIdBuf = Buffer.alloc(20);
38
+
40
39
  export function msgIdToStrFn(msgId: Uint8Array): string {
41
40
  // This happens serially, no need to reallocate the buffer
42
41
  sharedMsgIdBuf.set(msgId);
@@ -49,11 +48,20 @@ export function msgIdToStrFn(msgId: Uint8Array): string {
49
48
  * Follows similarly to:
50
49
  * https://github.com/ethereum/consensus-specs/blob/v1.1.0-alpha.7/specs/altair/p2p-interface.md#topics-and-messages
51
50
  *
51
+ * The topic length is framed into the hash input (`uint32be(topicLen) || topic || data`) so the
52
+ * `(topic, data)` boundary is unambiguous. A raw `topic || data` concatenation is not injective —
53
+ * shifting bytes across the boundary (e.g. `(topic + data[0], data[1:])`) yields the same bytes and
54
+ * thus the same id, letting an unsubscribed-topic message pre-occupy a real message's seenCache slot
55
+ * and suppress it as a duplicate.
56
+ *
52
57
  * @param message - The libp2p message
53
58
  * @returns The message identifier
54
59
  */
55
- export async function getMsgIdFn({ topic, data }: Message): Promise<Uint8Array> {
56
- const buffer = Buffer.concat([Buffer.from(topic), data]);
60
+ export async function getMsgIdFn({ topic, data }: Pick<Message, 'topic' | 'data'>): Promise<Uint8Array> {
61
+ const topicBytes = Buffer.from(topic);
62
+ const framedTopicLength = Buffer.allocUnsafe(4);
63
+ framedTopicLength.writeUInt32BE(topicBytes.length);
64
+ const buffer = Buffer.concat([framedTopicLength, topicBytes, data]);
57
65
  const hash = await webcrypto.subtle.digest('SHA-256', buffer);
58
66
  return Buffer.from(hash.slice(0, 20));
59
67
  }
@@ -76,7 +84,7 @@ const DefaultMaxSizesKb: Record<TopicType, number> = {
76
84
  export class SnappyTransform implements DataTransform {
77
85
  constructor(
78
86
  private maxSizesKb: Record<TopicType, number> = DefaultMaxSizesKb,
79
- private defaultMaxSizeKb: number = 10 * 1024,
87
+ private defaultMaxSizeKb: number = DEFAULT_MAX_RESPONSE_SIZE_KB,
80
88
  private logger = createLogger('p2p:snappy-transform'),
81
89
  ) {}
82
90