@aztec/p2p 0.0.1-commit.86469d5 → 0.0.1-commit.88c5703d4

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 (414) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +11 -11
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +53 -14
  5. package/dest/client/interface.d.ts +46 -33
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +41 -51
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +159 -224
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +7 -8
  11. package/dest/config.d.ts +54 -17
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +95 -39
  14. package/dest/errors/tx-pool.error.d.ts +8 -0
  15. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  16. package/dest/errors/tx-pool.error.js +9 -0
  17. package/dest/index.d.ts +2 -1
  18. package/dest/index.d.ts.map +1 -1
  19. package/dest/index.js +1 -0
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -88
  21. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  22. package/dest/mem_pools/attestation_pool/attestation_pool.js +445 -3
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
  24. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
  26. package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
  27. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  28. package/dest/mem_pools/attestation_pool/index.js +1 -2
  29. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  30. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  31. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  32. package/dest/mem_pools/index.d.ts +3 -2
  33. package/dest/mem_pools/index.d.ts.map +1 -1
  34. package/dest/mem_pools/index.js +1 -1
  35. package/dest/mem_pools/instrumentation.d.ts +4 -2
  36. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  37. package/dest/mem_pools/instrumentation.js +16 -14
  38. package/dest/mem_pools/interface.d.ts +5 -5
  39. package/dest/mem_pools/interface.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  41. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  42. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +2 -1
  43. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  44. package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
  45. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  46. package/dest/mem_pools/tx_pool/priority.js +4 -4
  47. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  48. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
  50. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
  51. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
  52. package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
  53. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
  54. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
  55. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
  56. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  57. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  58. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  59. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
  60. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
  61. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +128 -0
  62. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
  63. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  64. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +94 -0
  65. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
  66. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +97 -0
  68. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
  69. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
  70. package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
  71. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +180 -0
  72. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
  73. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +25 -0
  74. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
  75. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  76. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +65 -0
  77. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
  78. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  79. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +93 -0
  80. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
  81. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  82. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +78 -0
  83. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
  84. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
  85. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +75 -0
  86. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
  87. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
  88. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
  89. package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
  90. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
  91. package/dest/mem_pools/tx_pool_v2/index.js +5 -0
  92. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  93. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  94. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  95. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +215 -0
  96. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
  97. package/dest/mem_pools/tx_pool_v2/interfaces.js +10 -0
  98. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +134 -0
  99. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
  100. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +216 -0
  101. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
  102. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
  103. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
  104. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +108 -0
  105. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
  106. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +337 -0
  107. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +62 -0
  108. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
  109. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +167 -0
  110. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +78 -0
  111. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
  112. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +923 -0
  113. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -3
  114. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  116. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  117. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  118. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  119. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  120. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  121. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  122. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  123. package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
  124. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  125. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  126. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  127. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  128. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  129. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  130. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  131. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  132. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  133. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  134. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  135. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  136. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  137. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  138. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  139. package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
  140. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  141. package/dest/msg_validators/tx_validator/factory.js +240 -59
  142. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  143. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  144. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  145. package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
  146. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  147. package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
  148. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  149. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  150. package/dest/msg_validators/tx_validator/index.js +2 -0
  151. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  152. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  153. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  154. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  155. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  156. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  157. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  158. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  159. package/dest/msg_validators/tx_validator/phases_validator.js +71 -23
  160. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  161. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  162. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  163. package/dest/services/dummy_service.d.ts +13 -5
  164. package/dest/services/dummy_service.d.ts.map +1 -1
  165. package/dest/services/dummy_service.js +10 -4
  166. package/dest/services/encoding.d.ts +3 -3
  167. package/dest/services/encoding.d.ts.map +1 -1
  168. package/dest/services/encoding.js +11 -10
  169. package/dest/services/gossipsub/index.d.ts +3 -0
  170. package/dest/services/gossipsub/index.d.ts.map +1 -0
  171. package/dest/services/gossipsub/index.js +2 -0
  172. package/dest/services/gossipsub/scoring.d.ts +21 -3
  173. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  174. package/dest/services/gossipsub/scoring.js +24 -7
  175. package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
  176. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  177. package/dest/services/gossipsub/topic_score_params.js +346 -0
  178. package/dest/services/index.d.ts +2 -1
  179. package/dest/services/index.d.ts.map +1 -1
  180. package/dest/services/index.js +1 -0
  181. package/dest/services/libp2p/libp2p_service.d.ts +94 -42
  182. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  183. package/dest/services/libp2p/libp2p_service.js +463 -350
  184. package/dest/services/peer-manager/metrics.d.ts +3 -1
  185. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  186. package/dest/services/peer-manager/metrics.js +6 -0
  187. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  188. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  189. package/dest/services/peer-manager/peer_manager.js +2 -1
  190. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  191. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  192. package/dest/services/peer-manager/peer_scoring.js +25 -2
  193. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +13 -6
  194. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  195. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +51 -61
  196. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -6
  197. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  198. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  199. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  200. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  201. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  202. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  203. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  204. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  205. package/dest/services/reqresp/interface.d.ts +10 -1
  206. package/dest/services/reqresp/interface.d.ts.map +1 -1
  207. package/dest/services/reqresp/interface.js +15 -1
  208. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
  209. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  210. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +16 -11
  211. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +21 -10
  212. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  213. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +27 -11
  214. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  215. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  216. package/dest/services/reqresp/protocols/tx.js +20 -0
  217. package/dest/services/reqresp/reqresp.d.ts +1 -1
  218. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  219. package/dest/services/reqresp/reqresp.js +14 -6
  220. package/dest/services/service.d.ts +39 -3
  221. package/dest/services/service.d.ts.map +1 -1
  222. package/dest/services/tx_collection/config.d.ts +22 -4
  223. package/dest/services/tx_collection/config.d.ts.map +1 -1
  224. package/dest/services/tx_collection/config.js +49 -3
  225. package/dest/services/tx_collection/fast_tx_collection.d.ts +6 -5
  226. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  227. package/dest/services/tx_collection/fast_tx_collection.js +64 -48
  228. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  229. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  230. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  231. package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
  232. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  233. package/dest/services/tx_collection/file_store_tx_source.js +90 -0
  234. package/dest/services/tx_collection/index.d.ts +3 -2
  235. package/dest/services/tx_collection/index.d.ts.map +1 -1
  236. package/dest/services/tx_collection/index.js +1 -0
  237. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  238. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  239. package/dest/services/tx_collection/instrumentation.js +2 -1
  240. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  241. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  242. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  243. package/dest/services/tx_collection/proposal_tx_collector.d.ts +15 -14
  244. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  245. package/dest/services/tx_collection/proposal_tx_collector.js +6 -6
  246. package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
  247. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  248. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  249. package/dest/services/tx_collection/tx_collection.d.ts +23 -10
  250. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  251. package/dest/services/tx_collection/tx_collection.js +75 -3
  252. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  253. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  254. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  255. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  256. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  257. package/dest/services/tx_collection/tx_source.js +19 -2
  258. package/dest/services/tx_file_store/config.d.ts +16 -0
  259. package/dest/services/tx_file_store/config.d.ts.map +1 -0
  260. package/dest/services/tx_file_store/config.js +22 -0
  261. package/dest/services/tx_file_store/index.d.ts +4 -0
  262. package/dest/services/tx_file_store/index.d.ts.map +1 -0
  263. package/dest/services/tx_file_store/index.js +3 -0
  264. package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
  265. package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
  266. package/dest/services/tx_file_store/instrumentation.js +29 -0
  267. package/dest/services/tx_file_store/tx_file_store.d.ts +48 -0
  268. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
  269. package/dest/services/tx_file_store/tx_file_store.js +152 -0
  270. package/dest/services/tx_provider.d.ts +4 -4
  271. package/dest/services/tx_provider.d.ts.map +1 -1
  272. package/dest/services/tx_provider.js +9 -8
  273. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  274. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  275. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  276. package/dest/test-helpers/mock-pubsub.d.ts +30 -4
  277. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  278. package/dest/test-helpers/mock-pubsub.js +105 -4
  279. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  280. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  281. package/dest/test-helpers/reqresp-nodes.js +4 -3
  282. package/dest/test-helpers/testbench-utils.d.ts +43 -38
  283. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  284. package/dest/test-helpers/testbench-utils.js +129 -59
  285. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  286. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  287. package/dest/testbench/p2p_client_testbench_worker.js +17 -16
  288. package/dest/testbench/worker_client_manager.d.ts +3 -1
  289. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  290. package/dest/testbench/worker_client_manager.js +6 -2
  291. package/dest/util.d.ts +3 -3
  292. package/dest/util.d.ts.map +1 -1
  293. package/package.json +14 -14
  294. package/src/client/factory.ts +102 -27
  295. package/src/client/interface.ts +56 -34
  296. package/src/client/p2p_client.ts +193 -269
  297. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +21 -12
  298. package/src/config.ts +148 -44
  299. package/src/errors/tx-pool.error.ts +12 -0
  300. package/src/index.ts +1 -0
  301. package/src/mem_pools/attestation_pool/attestation_pool.ts +497 -91
  302. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
  303. package/src/mem_pools/attestation_pool/index.ts +9 -2
  304. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  305. package/src/mem_pools/index.ts +4 -1
  306. package/src/mem_pools/instrumentation.ts +17 -13
  307. package/src/mem_pools/interface.ts +4 -4
  308. package/src/mem_pools/tx_pool/README.md +1 -1
  309. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +2 -1
  310. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  311. package/src/mem_pools/tx_pool/priority.ts +4 -4
  312. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
  313. package/src/mem_pools/tx_pool_v2/README.md +283 -0
  314. package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
  315. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
  316. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  317. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +160 -0
  318. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +122 -0
  319. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +125 -0
  320. package/src/mem_pools/tx_pool_v2/eviction/index.ts +27 -0
  321. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +219 -0
  322. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
  323. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
  324. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +91 -0
  325. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +99 -0
  326. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +32 -0
  327. package/src/mem_pools/tx_pool_v2/index.ts +12 -0
  328. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  329. package/src/mem_pools/tx_pool_v2/interfaces.ts +247 -0
  330. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +337 -0
  331. package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
  332. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +430 -0
  333. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +238 -0
  334. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1105 -0
  335. package/src/msg_validators/attestation_validator/README.md +49 -0
  336. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +2 -2
  337. package/src/msg_validators/proposal_validator/README.md +123 -0
  338. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
  339. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
  340. package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
  341. package/src/msg_validators/tx_validator/README.md +119 -0
  342. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
  343. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  344. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  345. package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
  346. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  347. package/src/msg_validators/tx_validator/factory.ts +387 -78
  348. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  349. package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
  350. package/src/msg_validators/tx_validator/index.ts +2 -0
  351. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  352. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  353. package/src/msg_validators/tx_validator/phases_validator.ts +81 -26
  354. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  355. package/src/services/dummy_service.ts +18 -6
  356. package/src/services/encoding.ts +9 -9
  357. package/src/services/gossipsub/README.md +641 -0
  358. package/src/services/gossipsub/index.ts +2 -0
  359. package/src/services/gossipsub/scoring.ts +29 -5
  360. package/src/services/gossipsub/topic_score_params.ts +487 -0
  361. package/src/services/index.ts +1 -0
  362. package/src/services/libp2p/libp2p_service.ts +488 -372
  363. package/src/services/peer-manager/metrics.ts +7 -0
  364. package/src/services/peer-manager/peer_manager.ts +2 -1
  365. package/src/services/peer-manager/peer_scoring.ts +25 -0
  366. package/src/services/reqresp/README.md +229 -0
  367. package/src/services/reqresp/batch-tx-requester/README.md +7 -7
  368. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +59 -67
  369. package/src/services/reqresp/batch-tx-requester/interface.ts +3 -5
  370. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  371. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  372. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  373. package/src/services/reqresp/interface.ts +26 -1
  374. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +23 -14
  375. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +38 -15
  376. package/src/services/reqresp/protocols/tx.ts +22 -0
  377. package/src/services/reqresp/reqresp.ts +17 -5
  378. package/src/services/service.ts +51 -2
  379. package/src/services/tx_collection/config.ts +74 -6
  380. package/src/services/tx_collection/fast_tx_collection.ts +74 -51
  381. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  382. package/src/services/tx_collection/file_store_tx_source.ts +117 -0
  383. package/src/services/tx_collection/index.ts +2 -1
  384. package/src/services/tx_collection/instrumentation.ts +7 -1
  385. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  386. package/src/services/tx_collection/proposal_tx_collector.ts +20 -21
  387. package/src/services/tx_collection/slow_tx_collection.ts +66 -33
  388. package/src/services/tx_collection/tx_collection.ts +113 -16
  389. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  390. package/src/services/tx_collection/tx_source.ts +22 -3
  391. package/src/services/tx_file_store/config.ts +37 -0
  392. package/src/services/tx_file_store/index.ts +3 -0
  393. package/src/services/tx_file_store/instrumentation.ts +36 -0
  394. package/src/services/tx_file_store/tx_file_store.ts +175 -0
  395. package/src/services/tx_provider.ts +10 -9
  396. package/src/test-helpers/make-test-p2p-clients.ts +4 -6
  397. package/src/test-helpers/mock-pubsub.ts +146 -9
  398. package/src/test-helpers/reqresp-nodes.ts +5 -7
  399. package/src/test-helpers/testbench-utils.ts +128 -71
  400. package/src/testbench/p2p_client_testbench_worker.ts +26 -22
  401. package/src/testbench/worker_client_manager.ts +13 -5
  402. package/src/util.ts +8 -2
  403. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
  404. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  405. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
  406. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
  407. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  408. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
  409. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  410. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  411. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  412. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
  413. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
  414. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
@@ -18,6 +18,7 @@ export class PeerManagerMetrics {
18
18
  private sentGoodbyes: UpDownCounter;
19
19
  private receivedGoodbyes: UpDownCounter;
20
20
  private peerCount: Gauge;
21
+ private healthyPeerCount: Gauge;
21
22
  private lowScoreDisconnects: UpDownCounter;
22
23
  private peerConnectionDuration: Histogram;
23
24
 
@@ -49,6 +50,7 @@ export class PeerManagerMetrics {
49
50
  goodbyeReasonAttrs,
50
51
  );
51
52
  this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT);
53
+ this.healthyPeerCount = meter.createGauge(Metrics.PEER_MANAGER_HEALTHY_PEER_COUNT);
52
54
  this.lowScoreDisconnects = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_LOW_SCORE_DISCONNECTS, {
53
55
  [Attributes.P2P_PEER_SCORE_STATE]: ['Banned', 'Disconnect'],
54
56
  });
@@ -67,6 +69,10 @@ export class PeerManagerMetrics {
67
69
  this.peerCount.record(count);
68
70
  }
69
71
 
72
+ public recordHealthyPeerCount(count: number) {
73
+ this.healthyPeerCount.record(count);
74
+ }
75
+
70
76
  public recordLowScoreDisconnect(scoreState: 'Banned' | 'Disconnect') {
71
77
  this.lowScoreDisconnects.add(1, { [Attributes.P2P_PEER_SCORE_STATE]: scoreState });
72
78
  }
@@ -79,6 +85,7 @@ export class PeerManagerMetrics {
79
85
  const connectedAt = this.peerConnectedAt.get(id.toString());
80
86
  if (connectedAt) {
81
87
  this.peerConnectionDuration.record(Date.now() - connectedAt);
88
+ this.peerConnectedAt.delete(id.toString());
82
89
  }
83
90
  }
84
91
  }
@@ -515,7 +515,8 @@ export class PeerManager implements PeerManagerInterface {
515
515
  ...this.peerScoring.getStats(),
516
516
  });
517
517
 
518
- this.metrics.recordPeerCount(healthyConnections.length);
518
+ this.metrics.recordPeerCount(connections.length);
519
+ this.metrics.recordHealthyPeerCount(healthyConnections.length);
519
520
 
520
521
  // Exit if no peers to connect
521
522
  if (peersToConnect <= 0) {
@@ -14,6 +14,21 @@ import type { PeerId } from '@libp2p/interface';
14
14
 
15
15
  import type { P2PConfig } from '../../config.js';
16
16
 
17
+ /**
18
+ * Application-level peer penalties.
19
+ *
20
+ * These scores are multiplied by appSpecificWeight (10) when contributing to gossipsub score.
21
+ * The values are designed to align with gossipsub thresholds:
22
+ *
23
+ * - LowToleranceError (50): 1 error → app score -50 → gossipsub -500 → gossipThreshold
24
+ * - MidToleranceError (10): 5 errors → app score -50 → gossipsub -500 → gossipThreshold
25
+ * - HighToleranceError (2): 25 errors → app score -50 → gossipsub -500 → gossipThreshold
26
+ *
27
+ * Examples of each severity:
28
+ * - LowToleranceError: Invalid messages, deserialization errors, manipulation attempts
29
+ * - MidToleranceError: Hash mismatches, protocol violations
30
+ * - HighToleranceError: Rate limit exceeded, failed responses, transient errors
31
+ */
17
32
  const DefaultPeerPenalties = {
18
33
  [PeerErrorSeverity.LowToleranceError]: 50,
19
34
  [PeerErrorSeverity.MidToleranceError]: 10,
@@ -26,6 +41,16 @@ export enum PeerScoreState {
26
41
  Healthy,
27
42
  }
28
43
 
44
+ /**
45
+ * Score thresholds for peer states.
46
+ *
47
+ * These values align with gossipsub thresholds when multiplied by appSpecificWeight (10):
48
+ * - MIN_SCORE_BEFORE_DISCONNECT (-50) × 10 = -500 = gossipThreshold
49
+ * - MIN_SCORE_BEFORE_BAN (-100) × 10 = -1000 = publishThreshold
50
+ *
51
+ * This ensures that when a peer is disconnected at the application level,
52
+ * they also stop receiving gossip, and when banned, they cannot publish.
53
+ */
29
54
  // TODO: move into config / constants
30
55
  const MIN_SCORE_BEFORE_BAN = -100;
31
56
  const MIN_SCORE_BEFORE_DISCONNECT = -50;
@@ -0,0 +1,229 @@
1
+ # ReqResp Protocols
2
+
3
+ This module implements libp2p request-response protocols for the Aztec P2P network. All protocols share common transport-level validation (rate limiting, timeouts, Snappy decompression, error penalties) with protocol-specific logic layered on top.
4
+
5
+ ## Common Transport Validation
6
+
7
+ ### Rate Limiting (Responder Side)
8
+
9
+ Applied before the protocol handler runs.
10
+
11
+ | Protocol | Peer Limit | Global Limit | File |
12
+ |----------|-----------|-------------|------|
13
+ | PING | 5/s | 10/s | `rate-limiter/rate_limits.ts` |
14
+ | STATUS | 5/s | 10/s | same |
15
+ | AUTH | 5/s | 10/s | same |
16
+ | GOODBYE | 5/s | 10/s | same |
17
+ | BLOCK | 2/s | 5/s | same |
18
+ | BLOCK_TXS | 10/s | 200/s | same |
19
+ | TX | (see rate limits file) | (see rate limits file) | same |
20
+
21
+ - Per-peer limit exceeded: `HighToleranceError` penalty + `RATE_LIMIT_EXCEEDED` status. Penalty fires inside `RequestResponseRateLimiter.allow()`, not the stream handler.
22
+ - Global limit exceeded: `RATE_LIMIT_EXCEEDED` status only (no peer penalty).
23
+
24
+ ### Response Status Byte (Requester Side)
25
+
26
+ | Rule | Consequence | File |
27
+ |------|-------------|------|
28
+ | First chunk must be exactly 1 byte | `ReqRespStatusError(UNKNOWN)` | `status.ts` |
29
+ | Byte must be valid `ReqRespStatus` enum (0-4, 126, 127) | `ReqRespStatusError(UNKNOWN)` | same |
30
+
31
+ Note: `prettyPrintReqRespStatus` is missing a `NOT_FOUND` case (minor logging bug).
32
+
33
+ ### Snappy Decompression (Requester Side)
34
+
35
+ Per-protocol size limits checked via preamble before decompression.
36
+
37
+ ### Timeouts (Requester Side)
38
+
39
+ | Timeout | Default | Penalty |
40
+ |---------|---------|---------|
41
+ | Individual request | 10s | HighToleranceError |
42
+ | Dial | 5s | HighToleranceError |
43
+
44
+ ### Error Penalty Categorization (Requester Side)
45
+
46
+ | Error Type | Severity |
47
+ |------------|----------|
48
+ | GOODBYE subprotocol errors | None |
49
+ | `CollectiveReqRespTimeoutError` / `InvalidResponseError` | None |
50
+ | `AbortError` / connection close / muxer closed | None |
51
+ | `ECONNRESET` / `EPIPE` / `ECONNREFUSED` / `ERR_UNEXPECTED_EOF` | HighToleranceError |
52
+ | `ERR_UNSUPPORTED_PROTOCOL` | HighToleranceError |
53
+ | `IndividualReqRespTimeoutError` / `TimeoutError` | HighToleranceError |
54
+ | Catch-all | HighToleranceError |
55
+
56
+ ### Request Error Penalty (Responder Side)
57
+
58
+ | Error Type | Severity |
59
+ |------------|----------|
60
+ | `BADLY_FORMED_REQUEST` | LowToleranceError |
61
+ | All others | None |
62
+
63
+ ### Notes
64
+
65
+ - Request payloads are NOT snappy-compressed (asymmetric: only responses use snappy).
66
+
67
+ ---
68
+
69
+ ## Handshake Protocols
70
+
71
+ ### Connection-Level Gating (Before Any Handshake)
72
+
73
+ | Rule | Consequence | File |
74
+ |------|-------------|------|
75
+ | Deny inbound connection from IP/peerId with too many failed auth handshakes | Connection denied | `libp2p_service.ts` |
76
+ | Threshold: `p2pMaxFailedAuthAttemptsAllowed` (default 3) | Tracked per peerId AND per IP | `peer_manager.ts` |
77
+ | Failed auth entries expire after 1 hour | Peer can reconnect; no escalating penalty for repeat offenders | same |
78
+
79
+ ### Handshake Trigger Logic (`peer:connect`)
80
+
81
+ 1. `p2pDisableStatusHandshake` = true: no handshake
82
+ 2. `p2pAllowOnlyValidators` = false: STATUS handshake
83
+ 3. Peer is protected (trusted/private/preferred): STATUS handshake
84
+ 4. Otherwise: AUTH handshake (superset of STATUS)
85
+
86
+ Config constraint: `p2pDisableStatusHandshake && p2pAllowOnlyValidators` is disallowed.
87
+
88
+ ### STATUS Protocol (`/aztec/req/status/1.0.0`)
89
+
90
+ **Requester side** (`peer_manager.ts`):
91
+
92
+ | Rule | Consequence |
93
+ |------|-------------|
94
+ | Response status must be SUCCESS | Peer scheduled for disconnect |
95
+ | `compressedComponentsVersion` must match | Peer scheduled for disconnect |
96
+ | Any exception | Peer scheduled for disconnect |
97
+
98
+ `StatusMessage.validate()` currently only checks `compressedComponentsVersion`. Fields `latestBlockNumber`, `latestBlockHash`, `finalizedBlockNumber` are NOT validated (TODO in code).
99
+
100
+ **Responder side**: no validation of incoming request content (always responds with own status). This means the requester leaks its blockchain state to any peer before validation.
101
+
102
+ **Deserialization bounds**: `MAX_VERSION_STRING_LENGTH` = 64 bytes, `MAX_BLOCK_HASH_STRING_LENGTH` = 128 bytes. Expected response size: 1 KB.
103
+
104
+ ### AUTH Protocol (`/aztec/req/auth/1.0.0`)
105
+
106
+ **Requester side** (`peer_manager.ts`):
107
+
108
+ | # | Rule | Consequence |
109
+ |---|------|-------------|
110
+ | 1 | Response status is SUCCESS | `markAuthHandshakeFailed` + disconnect |
111
+ | 2 | `compressedComponentsVersion` match | `markAuthHandshakeFailed` + disconnect |
112
+ | 3 | Valid ECDSA signature recovery from challenge response | `markAuthHandshakeFailed` + disconnect |
113
+ | 4 | Recovered address is a registered validator | `markAuthHandshakeFailed` + disconnect |
114
+ | 5 | Validator address not already authenticated to different peerId | Silent return (no disconnect, no failure marking -- peer stays connected but unauthenticated) |
115
+ | 6 | Any exception | `markAuthHandshakeFailed` + disconnect |
116
+
117
+ Challenge: random `Fr`, payload = `keccak256("Aztec Validator Challenge:" + challenge)`, signed with `eth_sign` style. Challenge is NOT bound to peer identity (transport encryption via Noise is the binding layer).
118
+
119
+ On success: peer added to authenticated maps, prior failures cleared (including IP-based ones -- shared-IP peers benefit from a legitimate validator's success).
120
+
121
+ **Responder side** (`validator-client/src/validator.ts` + `peer_manager.ts`):
122
+
123
+ | # | Rule | Consequence |
124
+ |---|------|-------------|
125
+ | 1 | Peer must be protected (`shouldTrustWithIdentity` in `peer_manager.ts`) | Returns empty buffer (SUCCESS status + empty payload -> requester gets parse error -> `markAuthHandshakeFailed`) |
126
+ | 2 | Node must have registered validator address | Returns empty buffer (same consequence) |
127
+
128
+ **Unauthenticated peer gossip**: when `p2pAllowOnlyValidators` is true, unauthenticated peers get `appSpecificScore = -Infinity`, completely excluding them from all gossip.
129
+
130
+ ### PING Protocol (`/aztec/req/ping/1.0.0`)
131
+
132
+ No validation on either side. Responder returns `Buffer.from('pong')`. Expected response: 1 KB.
133
+
134
+ ### GOODBYE Protocol (`/aztec/req/goodbye/1.0.0`)
135
+
136
+ **Responder**: buffer must be 1 byte (defaults to `UNKNOWN` on invalid length). Goodbye reason byte is NOT validated against the enum -- any byte 0-255 accepted. Peer scheduled for disconnect regardless of reason.
137
+
138
+ **Requester**: response errors are never penalized (GOODBYE subprotocol exempt from error categorization).
139
+
140
+ ### Periodic Re-validation
141
+
142
+ | Rule | Interval | File |
143
+ |------|----------|------|
144
+ | Authenticated validators re-checked against current validator set | Every heartbeat (`peerCheckIntervalMS`) | `peer_manager.ts` |
145
+ | If validator address no longer registered, auth entry removed | Same | same |
146
+
147
+ Protected peers (private/trusted/preferred) are always considered "authenticated" without AUTH handshake.
148
+
149
+ ---
150
+
151
+ ## Block Data Protocols
152
+
153
+ ### BLOCK Protocol (`/aztec/req/block/1.0.0`)
154
+
155
+ **Server side**:
156
+
157
+ | Rule | Consequence | File |
158
+ |------|-------------|------|
159
+ | Request must parse as `Fr` | `BADLY_FORMED_REQUEST` + LowToleranceError | `protocols/block.ts` |
160
+ | Block lookup throws | `INTERNAL_ERROR` status | same |
161
+ | Block not found | SUCCESS + empty buffer (design choice; no `NOT_FOUND` status used) | same |
162
+
163
+ **Requester side** (Snappy limit: 3 MB):
164
+
165
+ | Rule | Consequence | File |
166
+ |------|-------------|------|
167
+ | Response block number must match requested | LowToleranceError; rejected | `libp2p_service.ts` (`validateRequestedBlock`) |
168
+ | Local block must exist for hash verification | Rejected (no penalty) | same |
169
+ | Response block hash must equal local block hash | MidToleranceError; rejected | same |
170
+
171
+ **Limitation**: the local-block requirement means BLOCK req/resp is unusable for initial P2P-only sync (before L1 sync provides local copies for verification). A TODO in the code acknowledges this.
172
+
173
+ ### BLOCK_TXS Protocol (`/aztec/req/block_txs/1.0.0`)
174
+
175
+ **Server side**:
176
+
177
+ | Rule | Consequence | File |
178
+ |------|-------------|------|
179
+ | Request must parse as `BlockTxsRequest` (Fr + TxHashArray + BitVector) | `BADLY_FORMED_REQUEST` + LowToleranceError | `protocols/block_txs/block_txs_handler.ts` |
180
+ | BitVector length: non-negative and <= `MAX_TXS_PER_BLOCK` (65536) | Deserialization throws -> `BADLY_FORMED_REQUEST` | `protocols/block_txs/bitvector.ts` |
181
+ | Archive root not found and no explicit txHashes | `NOT_FOUND` status | handler |
182
+ | Internal error during lookup | Unhandled exception -> stream abort (no `INTERNAL_ERROR` status, unlike BLOCK) | handler |
183
+
184
+ Conditional registration: BLOCK_TXS handler only registered when `config.disableTransactions` is false. Otherwise peers get `ERR_UNSUPPORTED_PROTOCOL`.
185
+
186
+ **Requester side via `sendBatchRequest`** (Snappy limit: `max(N, 1) * 512 + 1` KB):
187
+
188
+ | Rule | Consequence | File |
189
+ |------|-------------|------|
190
+ | Archive root must match request | MidToleranceError | `libp2p_service.ts` (`validateRequestedBlockTxs`) |
191
+ | BitVector length must match request | MidToleranceError | same |
192
+ | No duplicate tx hashes | MidToleranceError | same |
193
+ | Tx count within bounds | MidToleranceError | same |
194
+ | Local block proposal must exist for archive root | Rejected (no penalty) | same |
195
+ | All tx hashes must be in proposal's tx list at allowed indices | LowToleranceError | same |
196
+ | Txs in strictly increasing index order | LowToleranceError | same |
197
+ | Each tx passes well-formedness (Metadata [4 fields], Size, Data, Proof) | LowToleranceError | same |
198
+
199
+ **Requester side via `BatchTxRequester`** (separate validation path):
200
+
201
+ | Rule | Consequence | File |
202
+ |------|-------------|------|
203
+ | Non-SUCCESS status: `FAILURE`/`UNKNOWN` | HighToleranceError + "bad peer" tracking | `batch-tx-requester/batch_tx_requester.ts` |
204
+ | `RATE_LIMIT_EXCEEDED` | Peer marked rate-limited (cooldown) | same |
205
+ | `NOT_FOUND` / `BADLY_FORMED_REQUEST` / `INTERNAL_ERROR` | Falls through silently (no penalty) | same |
206
+ | Each tx validated (Metadata + Size + Data + Proof) | LowToleranceError per invalid tx; valid txs from same response still accepted | same |
207
+ | Archive root match + non-empty txIndices | No penalty on mismatch; peer not promoted to "smart" | same |
208
+
209
+ **Double penalty on transport errors**: when `BatchTxRequester` encounters a transport error (e.g., ECONNRESET), both `sendRequestToPeer`'s internal handler and the `BatchTxRequester`'s catch block penalize the peer, resulting in double HighToleranceError.
210
+
211
+ See [BatchTxRequester README](batch-tx-requester/README.md) for the full architecture (peer classification, worker model, wire protocol).
212
+
213
+ ### TX Protocol (`/aztec/req/tx/1.0.0`)
214
+
215
+ **Server side**:
216
+
217
+ | Rule | Consequence | File |
218
+ |------|-------------|------|
219
+ | Request must parse as `TxHashArray` | `BADLY_FORMED_REQUEST` + LowToleranceError | `protocols/tx.ts` |
220
+
221
+ **Requester side** (validator registered at startup, not the default noop):
222
+
223
+ | Rule | Consequence | File |
224
+ |------|-------------|------|
225
+ | Each returned tx hash must be in the requested set | MidToleranceError | `libp2p_service.ts` (`validateRequestedTxs`) |
226
+ | Each tx passes well-formedness (Metadata + Size + Data + Proof) | LowToleranceError | same |
227
+
228
+ Snappy limit: `max(N, 1) * 512 + 1` KB.
229
+
@@ -1,14 +1,14 @@
1
1
  # BatchTxRequester
2
2
 
3
- The `BatchTxRequester` is a specialized P2P service that aggressively fetches missing transactions from peers when a node receives a block proposal but lacks some of the referenced transactions. This is critical for validators who need all transactions to attest to a proposal.
3
+ The `BatchTxRequester` is a specialized P2P service that aggressively fetches missing transactions from peers when a node lacks some of the referenced transactions. It serves two pathways: (1) block proposals, where validators need all transactions to attest, and (2) block proving, where provers need all transactions to generate proofs.
4
4
 
5
5
  ## Overview
6
6
 
7
- When a validator receives a block proposal, they must verify all transactions in the block. If some transactions are missing from the local mempool (e.g., due to gossip delays), the `BatchTxRequester` kicks in to fetch them via direct peer-to-peer requests before the attestation deadline.
7
+ When a validator receives a block proposal or a prover needs to prove a block, they must have all transactions. If some transactions are missing from the local mempool (e.g., due to gossip delays), the `BatchTxRequester` kicks in to fetch them via direct peer-to-peer requests before the deadline.
8
8
 
9
9
  ```
10
10
  ┌─────────────────────────────────────────────────────────────────────────────┐
11
- Block Proposal Received
11
+ Block Proposal or Block Received
12
12
  │ (contains hashes of N transactions) │
13
13
  └─────────────────────────────────────────────────────────────────────────────┘
14
14
 
@@ -230,8 +230,8 @@ Request to peer fails
230
230
  ```typescript
231
231
  const requester = new BatchTxRequester(
232
232
  missingTxHashes, // TxHash[] - what we need
233
- blockProposal, // BlockProposal - the proposal we're attesting to
234
- pinnedPeer, // PeerId | undefined - who sent us the proposal
233
+ blockTxsSource, // BlockTxsSource - the proposal or block we need txs for
234
+ pinnedPeer, // PeerId | undefined - peer expected to have the txs
235
235
  timeoutMs, // number - how long to try
236
236
  p2pService, // BatchTxRequesterLibP2PService
237
237
  );
@@ -268,14 +268,14 @@ const txs = await BatchTxRequester.collectAllTxs(requester.run());
268
268
  ┌───────────────────────────────────┐ ┌─────────────────────────────────────┐
269
269
  │ FastTxCollection │ │ SlowTxCollection │
270
270
  │ │ │ │
271
- │ Time-critical: attestations │ │ Background: unproven blocks │
271
+ │ Time-critical: proposals/proving │ │ Background: unproven blocks │
272
272
  │ │ │ │
273
273
  │ 1. Try RPC nodes first (fast) │ │ Periodic polling of RPC nodes │
274
274
  │ 2. Fall back to BatchTxRequester │ │ and peers for missing txs │
275
275
  │ │ │ │
276
276
  └───────────────────┬───────────────┘ └─────────────────────────────────────┘
277
277
 
278
- │ For 'proposal' requests
278
+ │ For 'proposal' and 'block' requests
279
279
 
280
280
  ┌─────────────────────────────────────────────────────────────────────────────┐
281
281
  │ BatchTxRequester │
@@ -4,14 +4,14 @@ import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/queue';
5
5
  import { sleep } from '@aztec/foundation/sleep';
6
6
  import { DateProvider, executeTimeout } from '@aztec/foundation/timer';
7
- import { type BlockProposal, PeerErrorSeverity } from '@aztec/stdlib/p2p';
7
+ import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
8
8
  import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
9
9
 
10
10
  import type { PeerId } from '@libp2p/interface';
11
- import { peerIdFromString } from '@libp2p/peer-id';
12
11
 
12
+ import type { IMissingTxsTracker } from '../../tx_collection/missing_txs_tracker.js';
13
13
  import { ReqRespSubProtocol } from '.././interface.js';
14
- import { BlockTxsRequest, BlockTxsResponse } from '.././protocols/index.js';
14
+ import { BlockTxsRequest, BlockTxsResponse, type BlockTxsSource } from '.././protocols/index.js';
15
15
  import { ReqRespStatus } from '.././status.js';
16
16
  import {
17
17
  DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD,
@@ -20,7 +20,7 @@ import {
20
20
  DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
21
21
  } from './config.js';
22
22
  import type { BatchTxRequesterLibP2PService, BatchTxRequesterOptions, ITxMetadataCollection } from './interface.js';
23
- import { MissingTxMetadata, MissingTxMetadataCollection } from './missing_txs.js';
23
+ import { MissingTxMetadataCollection } from './missing_txs.js';
24
24
  import { type IPeerCollection, PeerCollection } from './peer_collection.js';
25
25
  import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_validator.js';
26
26
 
@@ -42,7 +42,7 @@ import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_val
42
42
  * - Is the peer which was unable to send us successful response N times in a row
43
43
  * */
44
44
  export class BatchTxRequester {
45
- private readonly blockProposal: BlockProposal;
45
+ private readonly blockTxsSource: BlockTxsSource;
46
46
  private readonly pinnedPeer: PeerId | undefined;
47
47
  private readonly timeoutMs: number;
48
48
  private readonly p2pService: BatchTxRequesterLibP2PService;
@@ -60,8 +60,8 @@ export class BatchTxRequester {
60
60
  private readonly txBatchSize: number;
61
61
 
62
62
  constructor(
63
- missingTxs: TxHash[],
64
- blockProposal: BlockProposal,
63
+ missingTxsTracker: IMissingTxsTracker,
64
+ blockTxsSource: BlockTxsSource,
65
65
  pinnedPeer: PeerId | undefined,
66
66
  timeoutMs: number,
67
67
  p2pService: BatchTxRequesterLibP2PService,
@@ -69,7 +69,7 @@ export class BatchTxRequester {
69
69
  dateProvider?: DateProvider,
70
70
  opts?: BatchTxRequesterOptions,
71
71
  ) {
72
- this.blockProposal = blockProposal;
72
+ this.blockTxsSource = blockTxsSource;
73
73
  this.pinnedPeer = pinnedPeer;
74
74
  this.timeoutMs = timeoutMs;
75
75
  this.p2pService = p2pService;
@@ -89,18 +89,16 @@ export class BatchTxRequester {
89
89
  if (this.opts.peerCollection) {
90
90
  this.peers = this.opts.peerCollection;
91
91
  } else {
92
- const initialPeers = this.p2pService.connectionSampler.getPeerListSortedByConnectionCountAsc();
93
92
  const badPeerThreshold = this.opts.badPeerThreshold ?? DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD;
94
93
  this.peers = new PeerCollection(
95
- initialPeers,
94
+ this.p2pService.connectionSampler,
96
95
  this.pinnedPeer,
97
96
  this.dateProvider,
98
97
  badPeerThreshold,
99
98
  this.p2pService.peerScoring,
100
99
  );
101
100
  }
102
- const entries: Array<[string, MissingTxMetadata]> = missingTxs.map(h => [h.toString(), new MissingTxMetadata(h)]);
103
- this.txsMetadata = new MissingTxMetadataCollection(entries, this.txBatchSize);
101
+ this.txsMetadata = new MissingTxMetadataCollection(missingTxsTracker, this.txBatchSize);
104
102
  this.smartRequesterSemaphore = this.opts.semaphore ?? new Semaphore(0);
105
103
  }
106
104
 
@@ -205,7 +203,7 @@ export class BatchTxRequester {
205
203
  return;
206
204
  }
207
205
 
208
- const request = BlockTxsRequest.fromBlockProposalAndMissingTxs(this.blockProposal, txs);
206
+ const request = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
209
207
  if (!request) {
210
208
  return;
211
209
  }
@@ -227,7 +225,6 @@ export class BatchTxRequester {
227
225
  * Starts dumb worker loops
228
226
  * */
229
227
  private async dumbRequester() {
230
- const nextPeerIndex = this.makeRoundRobinIndexer();
231
228
  const nextBatchIndex = this.makeRoundRobinIndexer();
232
229
 
233
230
  // Chunk missing tx hashes into batches of txBatchSize, wrapping around to ensure no peer gets less than txBatchSize
@@ -249,8 +246,8 @@ export class BatchTxRequester {
249
246
  // If peer is dumb peer, we don't know yet if they received full blockProposal
250
247
  // there is solid chance that peer didn't receive proposal yet, thus we must send full hashes
251
248
  const includeFullHashesInRequestNotJustIndices = true;
252
- const blockRequest = BlockTxsRequest.fromBlockProposalAndMissingTxs(
253
- this.blockProposal,
249
+ const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(
250
+ this.blockTxsSource,
254
251
  txs,
255
252
  includeFullHashesInRequestNotJustIndices,
256
253
  );
@@ -263,15 +260,9 @@ export class BatchTxRequester {
263
260
  return { blockRequest, txs };
264
261
  };
265
262
 
266
- const nextPeer = () => {
267
- const peers = this.peers.getDumbPeersToQuery();
268
- const idx = nextPeerIndex(() => peers.length);
269
- return idx === undefined ? undefined : peerIdFromString(peers[idx]);
270
- };
271
-
272
- const workerCount = Math.min(this.dumbParallelWorkerCount, this.peers.getAllPeers().size);
263
+ const workerCount = this.dumbParallelWorkerCount;
273
264
  const workers = Array.from({ length: workerCount }, (_, index) =>
274
- this.dumbWorkerLoop(nextPeer, makeRequest, index + 1),
265
+ this.dumbWorkerLoop(this.peers.nextDumbPeerToQuery.bind(this.peers), makeRequest, index + 1),
275
266
  );
276
267
 
277
268
  await Promise.allSettled(workers);
@@ -332,17 +323,9 @@ export class BatchTxRequester {
332
323
  * Starts smart worker loops
333
324
  * */
334
325
  private async smartRequester() {
335
- const nextPeerIndex = this.makeRoundRobinIndexer();
336
-
337
- const nextPeer = () => {
338
- const peers = this.peers.getSmartPeersToQuery();
339
- const idx = nextPeerIndex(() => peers.length);
340
- return idx === undefined ? undefined : peerIdFromString(peers[idx]);
341
- };
342
-
343
326
  const makeRequest = (pid: PeerId) => {
344
327
  const txs = this.txsMetadata.getTxsToRequestFromThePeer(pid);
345
- const blockRequest = BlockTxsRequest.fromBlockProposalAndMissingTxs(this.blockProposal, txs);
328
+ const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
346
329
  if (!blockRequest) {
347
330
  return undefined;
348
331
  }
@@ -350,9 +333,8 @@ export class BatchTxRequester {
350
333
  return { blockRequest, txs };
351
334
  };
352
335
 
353
- const workers = Array.from(
354
- { length: Math.min(this.smartParallelWorkerCount, this.peers.getAllPeers().size) },
355
- (_, index) => this.smartWorkerLoop(nextPeer, makeRequest, index + 1),
336
+ const workers = Array.from({ length: this.smartParallelWorkerCount }, (_, index) =>
337
+ this.smartWorkerLoop(this.peers.nextSmartPeerToQuery.bind(this.peers), makeRequest, index + 1),
356
338
  );
357
339
 
358
340
  await Promise.allSettled(workers);
@@ -387,26 +369,18 @@ export class BatchTxRequester {
387
369
  if (weRanOutOfPeersToQuery) {
388
370
  this.logger.debug(`Worker loop smart: No more peers to query`);
389
371
 
390
- // If there are no more dumb peers to query then none of our peers can become smart,
391
- // thus we can simply exit this worker
392
- const noMoreDumbPeersToQuery = this.peers.getDumbPeersToQuery().length === 0;
393
- if (noMoreDumbPeersToQuery) {
394
- // These might be either smart peers that will get unblocked after _some time_
395
- const nextSmartPeerDelay = this.peers.getNextSmartPeerAvailabilityDelayMs();
396
- const thereAreSomeRateLimitedSmartPeers = nextSmartPeerDelay !== undefined;
397
- if (thereAreSomeRateLimitedSmartPeers) {
398
- await this.sleepClampedToDeadline(nextSmartPeerDelay);
399
- continue;
400
- }
401
-
402
- this.logger.debug(`Worker loop smart: No more smart peers to query killing ${workerIndex}`);
403
- break;
372
+ // If we have rate limited peers wait for them.
373
+ const nextSmartPeerDelay = this.peers.getNextSmartPeerAvailabilityDelayMs();
374
+ const thereAreSomeRateLimitedSmartPeers = nextSmartPeerDelay !== undefined;
375
+ if (thereAreSomeRateLimitedSmartPeers) {
376
+ await this.sleepClampedToDeadline(nextSmartPeerDelay);
377
+ continue;
404
378
  }
405
379
 
406
- // Otherwise there are still some dumb peers that could become smart.
407
380
  // We end up here when all known smart peers became temporarily unavailable via combination of
408
381
  // (bad, in-flight, or rate-limited) or in some weird scenario all current smart peers turn bad which is permanent
409
- // but dumb peers still exist that could become smart.
382
+ // but there are dumb peers that could be promoted
383
+ // or new peer can join as dumb and be promoted later
410
384
  //
411
385
  // When a dumb peer responds with valid txIndices, it gets
412
386
  // promoted to smart and releases the semaphore, waking this worker.
@@ -489,9 +463,18 @@ export class BatchTxRequester {
489
463
  * this implies we will query these peers couple of more times and give them a chance to "redeem" themselves before completely ignoring them
490
464
  */
491
465
  private handleFailResponseFromPeer(peerId: PeerId, responseStatus: ReqRespStatus) {
492
- //TODO: Should we ban these peers?
493
466
  if (responseStatus === ReqRespStatus.FAILURE || responseStatus === ReqRespStatus.UNKNOWN) {
494
467
  this.peers.penalisePeer(peerId, PeerErrorSeverity.HighToleranceError);
468
+ this.peers.markPeerDumb(peerId);
469
+ this.txsMetadata.clearPeerData(peerId);
470
+ return;
471
+ }
472
+
473
+ // NOT_FOUND means the peer pruned its block proposal — it can no longer serve
474
+ // index-based requests, but this is a legitimate state so we don't penalize.
475
+ if (responseStatus === ReqRespStatus.NOT_FOUND) {
476
+ this.peers.markPeerDumb(peerId);
477
+ this.txsMetadata.clearPeerData(peerId);
495
478
  return;
496
479
  }
497
480
 
@@ -581,10 +564,9 @@ export class BatchTxRequester {
581
564
  return;
582
565
  }
583
566
 
584
- // If block response is invalid we still want to query this peer in the future
585
- // Because they sent successful response, so they might become smart peer in the future
586
- // Or send us needed txs
587
- if (!this.isBlockResponseValid(response)) {
567
+ const hasArchiveRootMismatch = this.blockTxsSource.archive.toString() !== response.archiveRoot.toString();
568
+ if (hasArchiveRootMismatch) {
569
+ this.handleArchiveRootMismatch(peerId, response);
588
570
  return;
589
571
  }
590
572
 
@@ -599,18 +581,28 @@ export class BatchTxRequester {
599
581
  this.markTxsPeerHas(peerId, response);
600
582
 
601
583
  // Unblock smart workers
602
- if (this.peers.getSmartPeersToQuery().length <= this.smartParallelWorkerCount) {
603
- this.smartRequesterSemaphore.release();
604
- }
584
+ this.smartRequesterSemaphore.release();
605
585
  }
606
586
 
607
- private isBlockResponseValid(response: BlockTxsResponse): boolean {
608
- const archiveRootsMatch = this.blockProposal.archive.toString() === response.archiveRoot.toString();
609
- const peerHasSomeTxsFromProposal = !response.txIndices.isEmpty();
610
- return archiveRootsMatch && peerHasSomeTxsFromProposal;
587
+ /**
588
+ * Handles an archive root mismatch between local state and peer response.
589
+ *
590
+ * - Response archive is Fr.ZERO (peer pruned proposal, legitimate): marks peer dumb.
591
+ * - Non-zero archive mismatch (malicious response): penalises + marks dumb.
592
+ */
593
+ private handleArchiveRootMismatch(peerId: PeerId, response: BlockTxsResponse): void {
594
+ if (!response.archiveRoot.isZero()) {
595
+ this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
596
+ }
597
+
598
+ this.peers.markPeerDumb(peerId);
599
+ this.txsMetadata.clearPeerData(peerId);
611
600
  }
612
601
 
613
602
  private peerHasSomeTxsWeAreMissing(_peerId: PeerId, response: BlockTxsResponse): boolean {
603
+ if (response.txIndices.isEmpty()) {
604
+ return false;
605
+ }
614
606
  const txsPeerHas = new Set(this.extractHashesPeerHasFromResponse(response).map(h => h.toString()));
615
607
  return this.txsMetadata.getMissingTxHashes().intersection(txsPeerHas).size > 0;
616
608
  }
@@ -624,7 +616,7 @@ export class BatchTxRequester {
624
616
  private extractHashesPeerHasFromResponse(response: BlockTxsResponse): Array<TxHash> {
625
617
  const hashes: TxHash[] = [];
626
618
  const indicesOfHashesPeerHas = new Set(response.txIndices.getTrueIndices());
627
- this.blockProposal.txHashes.forEach((hash, idx) => {
619
+ this.blockTxsSource.txHashes.forEach((hash, idx) => {
628
620
  if (indicesOfHashesPeerHas.has(idx)) {
629
621
  hashes.push(hash);
630
622
  }
@@ -661,7 +653,7 @@ export class BatchTxRequester {
661
653
  /*
662
654
  * @returns true if all missing txs have been fetched */
663
655
  private fetchedAllTxs() {
664
- return Array.from(this.txsMetadata.values()).every(tx => tx.fetched);
656
+ return this.txsMetadata.getMissingTxHashes().size == 0;
665
657
  }
666
658
 
667
659
  /*
@@ -679,7 +671,7 @@ export class BatchTxRequester {
679
671
  this.unlockSmartRequesterSemaphores();
680
672
  }
681
673
 
682
- return aborted || this.txsMetadata.size === 0 || this.fetchedAllTxs() || this.dateProvider.now() > this.deadline;
674
+ return aborted || this.fetchedAllTxs() || this.dateProvider.now() > this.deadline;
683
675
  }
684
676
 
685
677
  /*