@aztec/p2p 0.0.1-commit.d1f2d6c → 0.0.1-commit.d20b825a7

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 (562) hide show
  1. package/README.md +129 -3
  2. package/dest/bootstrap/bootstrap.d.ts +4 -3
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  4. package/dest/bootstrap/bootstrap.js +4 -4
  5. package/dest/client/factory.d.ts +12 -11
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +61 -19
  8. package/dest/client/interface.d.ts +54 -34
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +43 -52
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +190 -226
  13. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +2 -0
  14. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +1 -0
  15. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +318 -0
  16. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +73 -0
  17. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +1 -0
  18. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +8 -0
  19. package/dest/config.d.ts +135 -82
  20. package/dest/config.d.ts.map +1 -1
  21. package/dest/config.js +114 -41
  22. package/dest/errors/p2p-service.error.d.ts +9 -0
  23. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  24. package/dest/errors/p2p-service.error.js +10 -0
  25. package/dest/errors/tx-pool.error.d.ts +8 -0
  26. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  27. package/dest/errors/tx-pool.error.js +9 -0
  28. package/dest/index.d.ts +2 -2
  29. package/dest/index.d.ts.map +1 -1
  30. package/dest/index.js +1 -1
  31. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +106 -88
  32. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  33. package/dest/mem_pools/attestation_pool/attestation_pool.js +448 -3
  34. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
  35. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  36. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
  37. package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
  38. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  39. package/dest/mem_pools/attestation_pool/index.js +1 -2
  40. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  41. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  42. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  43. package/dest/mem_pools/index.d.ts +3 -3
  44. package/dest/mem_pools/index.d.ts.map +1 -1
  45. package/dest/mem_pools/index.js +1 -1
  46. package/dest/mem_pools/instrumentation.d.ts +4 -2
  47. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  48. package/dest/mem_pools/instrumentation.js +18 -16
  49. package/dest/mem_pools/interface.d.ts +5 -5
  50. package/dest/mem_pools/interface.d.ts.map +1 -1
  51. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
  52. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
  53. package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
  54. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
  55. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
  56. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
  57. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  58. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  59. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  60. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
  61. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
  62. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +128 -0
  63. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
  64. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  65. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +94 -0
  66. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
  68. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +97 -0
  69. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +11 -0
  70. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
  71. package/dest/mem_pools/tx_pool_v2/eviction/index.js +12 -0
  72. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  73. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  74. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  75. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +180 -0
  76. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
  77. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +25 -0
  78. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
  79. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  80. package/dest/mem_pools/{tx_pool → tx_pool_v2}/eviction/invalid_txs_after_mining_rule.js +16 -35
  81. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
  82. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  83. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +93 -0
  84. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
  85. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  86. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +78 -0
  87. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
  88. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
  89. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +75 -0
  90. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
  91. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
  92. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
  93. package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
  94. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
  95. package/dest/mem_pools/tx_pool_v2/index.js +5 -0
  96. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  97. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  98. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  99. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +218 -0
  100. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
  101. package/dest/mem_pools/tx_pool_v2/interfaces.js +10 -0
  102. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +137 -0
  103. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
  104. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +223 -0
  105. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
  106. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
  107. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
  108. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +108 -0
  109. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
  110. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +337 -0
  111. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +62 -0
  112. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
  113. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +167 -0
  114. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +78 -0
  115. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
  116. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +924 -0
  117. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +5 -2
  118. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  119. package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
  120. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -3
  121. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  122. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +9 -4
  123. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  124. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  125. package/dest/msg_validators/clock_tolerance.js +54 -3
  126. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +7 -4
  127. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  128. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  129. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +7 -4
  130. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  131. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  132. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +15 -8
  133. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  134. package/dest/msg_validators/proposal_validator/proposal_validator.js +70 -50
  135. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  136. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  137. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  138. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  139. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  140. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  141. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  142. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  143. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  144. package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
  145. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  146. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +20 -6
  147. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  148. package/dest/msg_validators/tx_validator/block_header_validator.js +4 -3
  149. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  150. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  151. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  152. package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
  153. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  154. package/dest/msg_validators/tx_validator/data_validator.js +39 -3
  155. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +15 -4
  156. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  157. package/dest/msg_validators/tx_validator/double_spend_validator.js +7 -6
  158. package/dest/msg_validators/tx_validator/factory.d.ts +137 -5
  159. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  160. package/dest/msg_validators/tx_validator/factory.js +255 -58
  161. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  162. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  163. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  164. package/dest/msg_validators/tx_validator/gas_validator.d.ts +100 -3
  165. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  166. package/dest/msg_validators/tx_validator/gas_validator.js +138 -53
  167. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  168. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  169. package/dest/msg_validators/tx_validator/index.js +2 -0
  170. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
  171. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  172. package/dest/msg_validators/tx_validator/metadata_validator.js +6 -6
  173. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  174. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  175. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  176. package/dest/msg_validators/tx_validator/phases_validator.d.ts +24 -3
  177. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  178. package/dest/msg_validators/tx_validator/phases_validator.js +75 -27
  179. package/dest/msg_validators/tx_validator/size_validator.d.ts +3 -1
  180. package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -1
  181. package/dest/msg_validators/tx_validator/size_validator.js +4 -1
  182. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +22 -5
  183. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  184. package/dest/msg_validators/tx_validator/timestamp_validator.js +8 -8
  185. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
  186. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
  187. package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
  188. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
  189. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  190. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -2
  191. package/dest/services/data_store.d.ts +1 -1
  192. package/dest/services/data_store.d.ts.map +1 -1
  193. package/dest/services/data_store.js +14 -10
  194. package/dest/services/discv5/discV5_service.js +1 -1
  195. package/dest/services/dummy_service.d.ts +28 -5
  196. package/dest/services/dummy_service.d.ts.map +1 -1
  197. package/dest/services/dummy_service.js +52 -2
  198. package/dest/services/encoding.d.ts +7 -3
  199. package/dest/services/encoding.d.ts.map +1 -1
  200. package/dest/services/encoding.js +18 -11
  201. package/dest/services/gossipsub/index.d.ts +3 -0
  202. package/dest/services/gossipsub/index.d.ts.map +1 -0
  203. package/dest/services/gossipsub/index.js +2 -0
  204. package/dest/services/gossipsub/scoring.d.ts +21 -3
  205. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  206. package/dest/services/gossipsub/scoring.js +24 -7
  207. package/dest/services/gossipsub/topic_score_params.d.ts +184 -0
  208. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  209. package/dest/services/gossipsub/topic_score_params.js +363 -0
  210. package/dest/services/index.d.ts +2 -1
  211. package/dest/services/index.d.ts.map +1 -1
  212. package/dest/services/index.js +1 -0
  213. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  214. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  215. package/dest/services/libp2p/instrumentation.js +28 -3
  216. package/dest/services/libp2p/libp2p_service.d.ts +101 -51
  217. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  218. package/dest/services/libp2p/libp2p_service.js +596 -463
  219. package/dest/services/peer-manager/metrics.d.ts +4 -2
  220. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  221. package/dest/services/peer-manager/metrics.js +26 -5
  222. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  223. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  224. package/dest/services/peer-manager/peer_manager.js +39 -11
  225. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  226. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  227. package/dest/services/peer-manager/peer_scoring.js +65 -14
  228. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +51 -0
  229. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
  230. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +543 -0
  231. package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
  232. package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
  233. package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
  234. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +47 -0
  235. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
  236. package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
  237. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +35 -0
  238. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
  239. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +136 -0
  240. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +62 -0
  241. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
  242. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +176 -0
  243. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
  244. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
  245. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
  246. package/dest/services/reqresp/config.d.ts +3 -3
  247. package/dest/services/reqresp/config.d.ts.map +1 -1
  248. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
  249. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
  250. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
  251. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
  252. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  253. package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
  254. package/dest/services/reqresp/interface.d.ts +25 -9
  255. package/dest/services/reqresp/interface.d.ts.map +1 -1
  256. package/dest/services/reqresp/interface.js +23 -10
  257. package/dest/services/reqresp/metrics.d.ts +6 -5
  258. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  259. package/dest/services/reqresp/metrics.js +16 -5
  260. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
  261. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  262. package/dest/services/reqresp/protocols/block_txs/bitvector.js +5 -0
  263. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
  264. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  265. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +27 -9
  266. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +29 -6
  267. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  268. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +59 -13
  269. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  270. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  271. package/dest/services/reqresp/protocols/index.js +0 -1
  272. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  273. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  274. package/dest/services/reqresp/protocols/tx.js +21 -3
  275. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  276. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  277. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  278. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  279. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  280. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  281. package/dest/services/reqresp/reqresp.d.ts +9 -2
  282. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  283. package/dest/services/reqresp/reqresp.js +95 -34
  284. package/dest/services/service.d.ts +46 -4
  285. package/dest/services/service.d.ts.map +1 -1
  286. package/dest/services/tx_collection/config.d.ts +22 -1
  287. package/dest/services/tx_collection/config.d.ts.map +1 -1
  288. package/dest/services/tx_collection/config.js +55 -1
  289. package/dest/services/tx_collection/fast_tx_collection.d.ts +7 -7
  290. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  291. package/dest/services/tx_collection/fast_tx_collection.js +95 -84
  292. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  293. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  294. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  295. package/dest/services/tx_collection/file_store_tx_source.d.ts +38 -0
  296. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  297. package/dest/services/tx_collection/file_store_tx_source.js +100 -0
  298. package/dest/services/tx_collection/index.d.ts +3 -1
  299. package/dest/services/tx_collection/index.d.ts.map +1 -1
  300. package/dest/services/tx_collection/index.js +2 -0
  301. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  302. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  303. package/dest/services/tx_collection/instrumentation.js +10 -2
  304. package/dest/services/tx_collection/proposal_tx_collector.d.ts +48 -0
  305. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
  306. package/dest/services/tx_collection/proposal_tx_collector.js +50 -0
  307. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  308. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  309. package/dest/services/tx_collection/request_tracker.js +84 -0
  310. package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
  311. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  312. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  313. package/dest/services/tx_collection/tx_collection.d.ts +25 -15
  314. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  315. package/dest/services/tx_collection/tx_collection.js +79 -7
  316. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  317. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  318. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  319. package/dest/services/tx_collection/tx_source.d.ts +13 -7
  320. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  321. package/dest/services/tx_collection/tx_source.js +26 -7
  322. package/dest/services/tx_file_store/config.d.ts +16 -0
  323. package/dest/services/tx_file_store/config.d.ts.map +1 -0
  324. package/dest/services/tx_file_store/config.js +22 -0
  325. package/dest/services/tx_file_store/index.d.ts +4 -0
  326. package/dest/services/tx_file_store/index.d.ts.map +1 -0
  327. package/dest/services/tx_file_store/index.js +3 -0
  328. package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
  329. package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
  330. package/dest/services/tx_file_store/instrumentation.js +29 -0
  331. package/dest/services/tx_file_store/tx_file_store.d.ts +48 -0
  332. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
  333. package/dest/services/tx_file_store/tx_file_store.js +152 -0
  334. package/dest/services/tx_provider.d.ts +4 -4
  335. package/dest/services/tx_provider.d.ts.map +1 -1
  336. package/dest/services/tx_provider.js +9 -8
  337. package/dest/services/tx_provider_instrumentation.d.ts +1 -1
  338. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  339. package/dest/services/tx_provider_instrumentation.js +5 -5
  340. package/dest/test-helpers/index.d.ts +3 -1
  341. package/dest/test-helpers/index.d.ts.map +1 -1
  342. package/dest/test-helpers/index.js +2 -0
  343. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  344. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  345. package/dest/test-helpers/make-test-p2p-clients.js +4 -2
  346. package/dest/test-helpers/mock-pubsub.d.ts +40 -6
  347. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  348. package/dest/test-helpers/mock-pubsub.js +139 -13
  349. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  350. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  351. package/dest/test-helpers/reqresp-nodes.js +8 -5
  352. package/dest/test-helpers/test_tx_provider.d.ts +40 -0
  353. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
  354. package/dest/test-helpers/test_tx_provider.js +41 -0
  355. package/dest/test-helpers/testbench-utils.d.ts +163 -0
  356. package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
  357. package/dest/test-helpers/testbench-utils.js +386 -0
  358. package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
  359. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  360. package/dest/testbench/p2p_client_testbench_worker.js +281 -143
  361. package/dest/testbench/worker_client_manager.d.ts +60 -6
  362. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  363. package/dest/testbench/worker_client_manager.js +280 -46
  364. package/dest/util.d.ts +3 -3
  365. package/dest/util.d.ts.map +1 -1
  366. package/package.json +14 -14
  367. package/src/bootstrap/bootstrap.ts +7 -4
  368. package/src/client/factory.ts +119 -38
  369. package/src/client/interface.ts +65 -35
  370. package/src/client/p2p_client.ts +228 -272
  371. package/src/client/test/tx_proposal_collector/README.md +227 -0
  372. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +357 -0
  373. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
  374. package/src/config.ts +184 -46
  375. package/src/errors/p2p-service.error.ts +11 -0
  376. package/src/errors/tx-pool.error.ts +12 -0
  377. package/src/index.ts +1 -1
  378. package/src/mem_pools/attestation_pool/attestation_pool.ts +501 -91
  379. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
  380. package/src/mem_pools/attestation_pool/index.ts +9 -2
  381. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  382. package/src/mem_pools/index.ts +2 -2
  383. package/src/mem_pools/instrumentation.ts +19 -14
  384. package/src/mem_pools/interface.ts +4 -4
  385. package/src/mem_pools/tx_pool_v2/README.md +283 -0
  386. package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
  387. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
  388. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  389. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +160 -0
  390. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +122 -0
  391. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +125 -0
  392. package/src/mem_pools/tx_pool_v2/eviction/index.ts +28 -0
  393. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  394. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +219 -0
  395. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
  396. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
  397. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +91 -0
  398. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +99 -0
  399. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +32 -0
  400. package/src/mem_pools/tx_pool_v2/index.ts +12 -0
  401. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  402. package/src/mem_pools/tx_pool_v2/interfaces.ts +250 -0
  403. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +349 -0
  404. package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
  405. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +430 -0
  406. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +238 -0
  407. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1107 -0
  408. package/src/msg_validators/attestation_validator/README.md +49 -0
  409. package/src/msg_validators/attestation_validator/attestation_validator.ts +21 -9
  410. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +14 -5
  411. package/src/msg_validators/clock_tolerance.ts +72 -3
  412. package/src/msg_validators/proposal_validator/README.md +123 -0
  413. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +17 -4
  414. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +23 -7
  415. package/src/msg_validators/proposal_validator/proposal_validator.ts +81 -51
  416. package/src/msg_validators/tx_validator/README.md +127 -0
  417. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
  418. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  419. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  420. package/src/msg_validators/tx_validator/archive_cache.ts +2 -2
  421. package/src/msg_validators/tx_validator/block_header_validator.ts +21 -8
  422. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  423. package/src/msg_validators/tx_validator/data_validator.ts +48 -3
  424. package/src/msg_validators/tx_validator/double_spend_validator.ts +15 -9
  425. package/src/msg_validators/tx_validator/factory.ts +415 -56
  426. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  427. package/src/msg_validators/tx_validator/gas_validator.ts +203 -52
  428. package/src/msg_validators/tx_validator/index.ts +2 -0
  429. package/src/msg_validators/tx_validator/metadata_validator.ts +18 -7
  430. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  431. package/src/msg_validators/tx_validator/phases_validator.ts +87 -30
  432. package/src/msg_validators/tx_validator/size_validator.ts +6 -2
  433. package/src/msg_validators/tx_validator/timestamp_validator.ts +29 -21
  434. package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
  435. package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
  436. package/src/services/data_store.ts +14 -19
  437. package/src/services/discv5/discV5_service.ts +1 -1
  438. package/src/services/dummy_service.ts +66 -3
  439. package/src/services/encoding.ts +18 -10
  440. package/src/services/gossipsub/README.md +641 -0
  441. package/src/services/gossipsub/index.ts +2 -0
  442. package/src/services/gossipsub/scoring.ts +29 -5
  443. package/src/services/gossipsub/topic_score_params.ts +519 -0
  444. package/src/services/index.ts +1 -0
  445. package/src/services/libp2p/instrumentation.ts +29 -2
  446. package/src/services/libp2p/libp2p_service.ts +644 -514
  447. package/src/services/peer-manager/metrics.ts +28 -4
  448. package/src/services/peer-manager/peer_manager.ts +45 -11
  449. package/src/services/peer-manager/peer_scoring.ts +56 -6
  450. package/src/services/reqresp/README.md +229 -0
  451. package/src/services/reqresp/batch-tx-requester/README.md +344 -0
  452. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +673 -0
  453. package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
  454. package/src/services/reqresp/batch-tx-requester/interface.ts +54 -0
  455. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +168 -0
  456. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +249 -0
  457. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
  458. package/src/services/reqresp/config.ts +2 -2
  459. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
  460. package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
  461. package/src/services/reqresp/interface.ts +48 -10
  462. package/src/services/reqresp/metrics.ts +33 -9
  463. package/src/services/reqresp/protocols/block_txs/bitvector.ts +7 -0
  464. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +35 -12
  465. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +74 -9
  466. package/src/services/reqresp/protocols/index.ts +0 -1
  467. package/src/services/reqresp/protocols/tx.ts +23 -3
  468. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  469. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  470. package/src/services/reqresp/reqresp.ts +116 -32
  471. package/src/services/service.ts +61 -3
  472. package/src/services/tx_collection/config.ts +83 -1
  473. package/src/services/tx_collection/fast_tx_collection.ts +111 -91
  474. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  475. package/src/services/tx_collection/file_store_tx_source.ts +129 -0
  476. package/src/services/tx_collection/index.ts +6 -0
  477. package/src/services/tx_collection/instrumentation.ts +17 -2
  478. package/src/services/tx_collection/proposal_tx_collector.ts +108 -0
  479. package/src/services/tx_collection/request_tracker.ts +127 -0
  480. package/src/services/tx_collection/slow_tx_collection.ts +66 -33
  481. package/src/services/tx_collection/tx_collection.ts +118 -23
  482. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  483. package/src/services/tx_collection/tx_source.ts +28 -8
  484. package/src/services/tx_file_store/config.ts +37 -0
  485. package/src/services/tx_file_store/index.ts +3 -0
  486. package/src/services/tx_file_store/instrumentation.ts +36 -0
  487. package/src/services/tx_file_store/tx_file_store.ts +175 -0
  488. package/src/services/tx_provider.ts +10 -9
  489. package/src/services/tx_provider_instrumentation.ts +11 -5
  490. package/src/test-helpers/index.ts +2 -0
  491. package/src/test-helpers/make-test-p2p-clients.ts +6 -6
  492. package/src/test-helpers/mock-pubsub.ts +180 -14
  493. package/src/test-helpers/reqresp-nodes.ts +9 -9
  494. package/src/test-helpers/test_tx_provider.ts +64 -0
  495. package/src/test-helpers/testbench-utils.ts +457 -0
  496. package/src/testbench/p2p_client_testbench_worker.ts +396 -134
  497. package/src/testbench/worker_client_manager.ts +367 -48
  498. package/src/util.ts +8 -2
  499. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
  500. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  501. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
  502. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
  503. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  504. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
  505. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  506. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  507. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  508. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  509. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  510. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  511. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  512. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  513. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  514. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  515. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  516. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  517. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  518. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  519. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  520. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  521. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  522. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  523. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  524. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  525. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  526. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  527. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  528. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  529. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  530. package/dest/mem_pools/tx_pool/index.js +0 -2
  531. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  532. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  533. package/dest/mem_pools/tx_pool/priority.js +0 -15
  534. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  535. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  536. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  537. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  538. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  539. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  540. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  541. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  542. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  543. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  544. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  545. package/dest/services/reqresp/protocols/block.js +0 -32
  546. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
  547. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
  548. package/src/mem_pools/tx_pool/README.md +0 -270
  549. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  550. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  551. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  552. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  553. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  554. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  555. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  556. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  557. package/src/mem_pools/tx_pool/index.ts +0 -2
  558. package/src/mem_pools/tx_pool/priority.ts +0 -20
  559. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  560. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  561. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
  562. package/src/services/reqresp/protocols/block.ts +0 -37
@@ -0,0 +1,673 @@
1
+ import { chunkWrapAround } from '@aztec/foundation/collection';
2
+ import { type Logger, createLogger } from '@aztec/foundation/log';
3
+ import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/queue';
4
+ import { sleep } from '@aztec/foundation/sleep';
5
+ import { DateProvider } from '@aztec/foundation/timer';
6
+ import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
7
+ import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
8
+
9
+ import type { PeerId } from '@libp2p/interface';
10
+
11
+ import type { IRequestTracker } from '../../tx_collection/request_tracker.js';
12
+ import { ReqRespSubProtocol } from '.././interface.js';
13
+ import { BlockTxsRequest, BlockTxsResponse, type BlockTxsSource } from '.././protocols/index.js';
14
+ import { ReqRespStatus } from '.././status.js';
15
+ import {
16
+ DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD,
17
+ DEFAULT_BATCH_TX_REQUESTER_DUMB_PARALLEL_WORKER_COUNT,
18
+ DEFAULT_BATCH_TX_REQUESTER_SMART_PARALLEL_WORKER_COUNT,
19
+ DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
20
+ } from './config.js';
21
+ import type { BatchTxRequesterLibP2PService, BatchTxRequesterOptions, ITxMetadataCollection } from './interface.js';
22
+ import { MissingTxMetadataCollection } from './missing_txs.js';
23
+ import { type IPeerCollection, PeerCollection } from './peer_collection.js';
24
+ import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_validator.js';
25
+
26
+ /*
27
+ * Tries to fetch all missing transaction until deadline is hit.
28
+ * Transactions are yield by calling run*() method
29
+ *
30
+ * We have a couple of peer types:
31
+ * - Pinned peer is the one who sent us the block proposal
32
+ * - Dumb peer:
33
+ * - We query this peer blindly because we don't know which txs it has
34
+ * - We hope it might have some of the transactions we asked for
35
+ * - When this peer sends response it might become Smart peer
36
+ * - Smart peer:
37
+ * - Initially there are no smart peers, all are considered "dumb"
38
+ * - Peer becomes smart when in response it tels us exactly which transactions it has
39
+ * AND we are missing some of those transactions
40
+ * - Bad peer:
41
+ * - Is the peer which was unable to send us successful response N times in a row
42
+ * */
43
+ export class BatchTxRequester {
44
+ private readonly requestTracker: IRequestTracker;
45
+ private readonly blockTxsSource: BlockTxsSource;
46
+ private readonly pinnedPeer: PeerId | undefined;
47
+ private readonly p2pService: BatchTxRequesterLibP2PService;
48
+ private readonly logger: Logger;
49
+ private readonly opts: BatchTxRequesterOptions;
50
+ private readonly peers: IPeerCollection;
51
+ private readonly txsMetadata: ITxMetadataCollection;
52
+ private readonly smartRequesterSemaphore: ISemaphore;
53
+ private readonly txQueue: FifoMemoryQueue<Tx>;
54
+ private readonly txValidator: IBatchRequestTxValidator;
55
+ private readonly smartParallelWorkerCount: number;
56
+ private readonly dumbParallelWorkerCount: number;
57
+ private readonly txBatchSize: number;
58
+
59
+ constructor(
60
+ requestTracker: IRequestTracker,
61
+ blockTxsSource: BlockTxsSource,
62
+ pinnedPeer: PeerId | undefined,
63
+ p2pService: BatchTxRequesterLibP2PService,
64
+ logger?: Logger,
65
+ dateProvider?: DateProvider,
66
+ opts?: BatchTxRequesterOptions,
67
+ ) {
68
+ this.requestTracker = requestTracker;
69
+ this.blockTxsSource = blockTxsSource;
70
+ this.pinnedPeer = pinnedPeer;
71
+ this.p2pService = p2pService;
72
+ this.logger = logger ?? createLogger('p2p:reqresp_batch');
73
+ this.opts = opts ?? {};
74
+
75
+ this.smartParallelWorkerCount =
76
+ this.opts.smartParallelWorkerCount ?? DEFAULT_BATCH_TX_REQUESTER_SMART_PARALLEL_WORKER_COUNT;
77
+ this.dumbParallelWorkerCount =
78
+ this.opts.dumbParallelWorkerCount ?? DEFAULT_BATCH_TX_REQUESTER_DUMB_PARALLEL_WORKER_COUNT;
79
+ this.txBatchSize = this.opts.txBatchSize ?? DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE;
80
+ this.txQueue = new FifoMemoryQueue(this.logger);
81
+ this.txValidator = this.opts.txValidator ?? new BatchRequestTxValidator(this.p2pService.txValidatorConfig);
82
+
83
+ if (this.opts.peerCollection) {
84
+ this.peers = this.opts.peerCollection;
85
+ } else {
86
+ const badPeerThreshold = this.opts.badPeerThreshold ?? DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD;
87
+ this.peers = new PeerCollection(
88
+ this.p2pService.connectionSampler,
89
+ this.pinnedPeer,
90
+ dateProvider ?? new DateProvider(),
91
+ badPeerThreshold,
92
+ this.p2pService.peerScoring,
93
+ );
94
+ }
95
+ this.txsMetadata = new MissingTxMetadataCollection(requestTracker, this.txBatchSize);
96
+ this.smartRequesterSemaphore = this.opts.semaphore ?? new Semaphore(0);
97
+ }
98
+
99
+ /*
100
+ * Fetches all missing transactions and yields them one by one
101
+ * */
102
+ public async *run(): AsyncGenerator<Tx, Tx | undefined, unknown> {
103
+ try {
104
+ if (this.txsMetadata.getMissingTxHashes().size === 0) {
105
+ return undefined;
106
+ }
107
+
108
+ // Start workers in background. Workers stop themselves via requestTracker.checkCancelled().
109
+ const workersPromise = Promise.allSettled([
110
+ this.smartRequester(),
111
+ this.dumbRequester(),
112
+ this.pinnedPeerRequester(),
113
+ ]).finally(() => {
114
+ this.txQueue.end();
115
+ });
116
+
117
+ // Yield txs as workers put them on the queue. The queue's end() drains remaining items
118
+ // before returning null, so we don't lose any txs.
119
+ while (true) {
120
+ const tx = await this.txQueue.get();
121
+
122
+ if (tx === null) {
123
+ break;
124
+ }
125
+
126
+ yield tx;
127
+ }
128
+
129
+ this.unlockSmartRequesterSemaphores();
130
+ await workersPromise;
131
+ } catch (e: any) {
132
+ this.logger.error(`Batch tx requester failed with error: ${e.message}`, { error: e });
133
+ } finally {
134
+ this.txQueue.end();
135
+ this.unlockSmartRequesterSemaphores();
136
+ }
137
+ }
138
+
139
+ /*
140
+ * Fetches all missing transactions
141
+ * @returns Collection of fetched transactions */
142
+ public static async collectAllTxs(generator: AsyncGenerator<Tx, Tx | undefined, unknown>): Promise<Tx[]> {
143
+ const txs: Tx[] = [];
144
+ for await (const tx of generator) {
145
+ if (tx === undefined) {
146
+ break;
147
+ }
148
+ txs.push(tx);
149
+ }
150
+ return txs;
151
+ }
152
+
153
+ /*
154
+ * Handles so-called pinned peer
155
+ * The pinned peer is the one who sent us block proposal
156
+ * We expect pinned peer to have all transactions from the proposal at some point
157
+ * This holds because they them selves have to attest to proposal and thus fetch all missing transactions
158
+ *
159
+ * Given the reasoning above - we query pinned peer separately from dumb/smart peers
160
+ * */
161
+ private async pinnedPeerRequester() {
162
+ if (!this.pinnedPeer) {
163
+ this.logger.debug('No pinned peer to request from');
164
+ return;
165
+ }
166
+
167
+ while (!this.shouldStop()) {
168
+ // We've hit rate limits on the pinned peer - wait until rate limit expires (clamped to deadline)
169
+ const rateLimitDelay = this.peers.getPeerRateLimitDelayMs(this.pinnedPeer);
170
+ const pinnedPeerIsRateLimited = rateLimitDelay !== undefined;
171
+ if (pinnedPeerIsRateLimited) {
172
+ await this.sleepClampedToDeadline(rateLimitDelay);
173
+ continue;
174
+ }
175
+
176
+ const pinnedPeerWentBad = this.peers.getBadPeers().has(this.pinnedPeer.toString());
177
+ if (pinnedPeerWentBad) {
178
+ return;
179
+ }
180
+
181
+ // From pinned peer we always request transactions so that we first request the least requested and not in flight
182
+ // This makes sense since pinned peer should have ALL transactions,
183
+ // Thus if it has all it is best to ask pinned first for the transactions we have trouble getting from other peers
184
+ const txs = this.txsMetadata.getTxsToRequestFromThePeer(this.pinnedPeer);
185
+ if (txs.length === 0) {
186
+ this.logger.debug(`Pinned peer ${this.pinnedPeer.toString()} has no txs to request`);
187
+ return;
188
+ }
189
+
190
+ const request = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
191
+ if (!request) {
192
+ return;
193
+ }
194
+
195
+ txs.forEach(tx => {
196
+ this.txsMetadata.markRequested(tx);
197
+ this.txsMetadata.markInFlightBySmartPeer(tx);
198
+ });
199
+
200
+ await this.requestTxBatch(this.pinnedPeer, request);
201
+
202
+ txs.forEach(tx => {
203
+ this.txsMetadata.markNotInFlightBySmartPeer(tx);
204
+ });
205
+ }
206
+ }
207
+
208
+ /*
209
+ * Starts dumb worker loops
210
+ * */
211
+ private async dumbRequester() {
212
+ const nextBatchIndex = this.makeRoundRobinIndexer();
213
+
214
+ // Chunk missing tx hashes into batches of txBatchSize, wrapping around to ensure no peer gets less than txBatchSize
215
+ const txChunks = () => {
216
+ const missingHashes = Array.from(this.txsMetadata.getMissingTxHashes());
217
+ return chunkWrapAround(missingHashes, this.txBatchSize);
218
+ };
219
+
220
+ const makeRequest = (_pid: PeerId) => {
221
+ const chunks = txChunks();
222
+ const idx = nextBatchIndex(() => chunks.length);
223
+ const noMoreTxsToRequest = idx === undefined;
224
+ if (noMoreTxsToRequest) {
225
+ return undefined;
226
+ }
227
+
228
+ const txs = chunks[idx].map(t => TxHash.fromString(t));
229
+
230
+ // If peer is dumb peer, we don't know yet if they received full blockProposal
231
+ // there is solid chance that peer didn't receive proposal yet, thus we must send full hashes
232
+ const includeFullHashesInRequestNotJustIndices = true;
233
+ const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(
234
+ this.blockTxsSource,
235
+ txs,
236
+ includeFullHashesInRequestNotJustIndices,
237
+ );
238
+ const blockRequestHasNoMissingTxsFromTheProposal = !blockRequest;
239
+
240
+ if (blockRequestHasNoMissingTxsFromTheProposal) {
241
+ return undefined;
242
+ }
243
+
244
+ return { blockRequest, txs };
245
+ };
246
+
247
+ const workerCount = this.dumbParallelWorkerCount;
248
+ const workers = Array.from({ length: workerCount }, (_, index) =>
249
+ this.dumbWorkerLoop(this.peers.nextDumbPeerToQuery.bind(this.peers), makeRequest, index + 1),
250
+ );
251
+
252
+ await Promise.allSettled(workers);
253
+ }
254
+
255
+ /*
256
+ * Dumb worker loop.
257
+ * It fetches next available dumb peer and builds request for that peer
258
+ * Loops until shouldStop condition is not met or there are no more dubm peers to query
259
+ * This can happen if e.g. all "dumb" peers transition to "smart" or e.g. become "bad"
260
+ * */
261
+ private async dumbWorkerLoop(
262
+ pickNextPeer: () => PeerId | undefined,
263
+ request: (pid: PeerId) => { blockRequest: BlockTxsRequest; txs: TxHash[] } | undefined,
264
+ workerIndex: number,
265
+ ) {
266
+ try {
267
+ this.logger.debug(`Dumb worker ${workerIndex} started`);
268
+ while (!this.shouldStop()) {
269
+ const peerId = pickNextPeer();
270
+ const weRanOutOfPeersToQuery = peerId === undefined;
271
+ if (weRanOutOfPeersToQuery) {
272
+ const nextDumbPeerDelay = this.peers.getNextDumbPeerAvailabilityDelayMs();
273
+ const thereAreSomeRateLimitedDumbPeers = nextDumbPeerDelay !== undefined;
274
+ if (thereAreSomeRateLimitedDumbPeers) {
275
+ // There are still some dumb peers to query but they have been rate limited
276
+ // Sleep until the earliest one gets unblocked (clamped to deadline)
277
+ await this.sleepClampedToDeadline(nextDumbPeerDelay);
278
+ continue;
279
+ }
280
+
281
+ this.logger.debug(`Worker loop dumb: No more peers to query`);
282
+ break;
283
+ }
284
+
285
+ const nextBatchTxRequest = request(peerId);
286
+ if (!nextBatchTxRequest) {
287
+ this.logger.debug(`Worker loop dumb: no txs to request, exiting`);
288
+ break;
289
+ }
290
+
291
+ const { blockRequest, txs } = nextBatchTxRequest;
292
+
293
+ this.logger.debug(
294
+ `Worker type dumb: Requesting txs from peer ${peerId.toString()}: ${txs.map(tx => tx.toString()).join(', ')}`,
295
+ );
296
+
297
+ await this.requestTxBatch(peerId, blockRequest);
298
+ }
299
+ } catch (err: any) {
300
+ this.logger.error(`Dumb worker ${workerIndex} encountered an error: ${err}`);
301
+ } finally {
302
+ this.logger.debug(`Dumb worker ${workerIndex} finished`);
303
+ }
304
+ }
305
+
306
+ /*
307
+ * Starts smart worker loops
308
+ * */
309
+ private async smartRequester() {
310
+ const makeRequest = (pid: PeerId) => {
311
+ const txs = this.txsMetadata.getTxsToRequestFromThePeer(pid);
312
+ const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
313
+ if (!blockRequest) {
314
+ return undefined;
315
+ }
316
+
317
+ return { blockRequest, txs };
318
+ };
319
+
320
+ const workers = Array.from({ length: this.smartParallelWorkerCount }, (_, index) =>
321
+ this.smartWorkerLoop(this.peers.nextSmartPeerToQuery.bind(this.peers), makeRequest, index + 1),
322
+ );
323
+
324
+ await Promise.allSettled(workers);
325
+ }
326
+
327
+ /*
328
+ * Smart worker loop.
329
+ * It fetches next available smart peer and builds request for that peer
330
+ * Loops until shouldStop condition is not met
331
+ *
332
+ * Notes:
333
+ * - We don't start worker loop immediately, but block on semaphore
334
+ * until some dumb peer transactions to smart peer
335
+ * - We might run out of smart peers, because:
336
+ * - they "went bad"
337
+ * - there are less smart peers than worker loops
338
+ * In such scenario we either wait for next dumb peer to become smart or kill the worker loop
339
+ * */
340
+ private async smartWorkerLoop(
341
+ pickNextPeer: () => PeerId | undefined,
342
+ request: (pid: PeerId) => { blockRequest: BlockTxsRequest; txs: TxHash[] } | undefined,
343
+ workerIndex: number,
344
+ ) {
345
+ try {
346
+ this.logger.trace(`Smart worker ${workerIndex} started`);
347
+ await Promise.race([this.smartRequesterSemaphore.acquire(), this.requestTracker.cancellationToken]);
348
+ if (this.requestTracker.checkCancelled()) {
349
+ return;
350
+ }
351
+ this.logger.trace(`Smart worker ${workerIndex} acquired semaphore`);
352
+
353
+ while (!this.shouldStop()) {
354
+ const peerId = pickNextPeer();
355
+ const weRanOutOfPeersToQuery = peerId === undefined;
356
+ if (weRanOutOfPeersToQuery) {
357
+ this.logger.debug(`Worker loop smart: No more peers to query`);
358
+
359
+ // If we have rate limited peers wait for them.
360
+ const nextSmartPeerDelay = this.peers.getNextSmartPeerAvailabilityDelayMs();
361
+ const thereAreSomeRateLimitedSmartPeers = nextSmartPeerDelay !== undefined;
362
+ if (thereAreSomeRateLimitedSmartPeers) {
363
+ await this.sleepClampedToDeadline(nextSmartPeerDelay);
364
+ continue;
365
+ }
366
+
367
+ // We end up here when all known smart peers became temporarily unavailable via combination of
368
+ // (bad, in-flight, or rate-limited) or in some weird scenario all current smart peers turn bad which is permanent
369
+ // but there are dumb peers that could be promoted
370
+ // or new peer can join as dumb and be promoted later
371
+ //
372
+ // When a dumb peer responds with valid txIndices, it gets
373
+ // promoted to smart and releases the semaphore, waking this worker.
374
+ await Promise.race([this.smartRequesterSemaphore.acquire(), this.requestTracker.cancellationToken]);
375
+ if (this.requestTracker.checkCancelled()) {
376
+ break;
377
+ }
378
+ this.logger.debug(`Worker loop smart: acquired next smart peer`);
379
+ continue;
380
+ }
381
+
382
+ const nextBatchTxRequest = request(peerId);
383
+ if (!nextBatchTxRequest) {
384
+ this.logger.debug(`Worker loop smart: no txs to request, exiting`);
385
+ break;
386
+ }
387
+
388
+ const { blockRequest, txs } = nextBatchTxRequest;
389
+
390
+ // We only mark transactions as in flight if queried by Smart peer
391
+ // Because asking them from dumb peer is shot in the dark (there is a good chance they won't have it)
392
+ // So we don't gain anything if we mark txs in-flight for dumb peers
393
+ txs.forEach(tx => {
394
+ this.txsMetadata.markRequested(tx);
395
+ this.txsMetadata.markInFlightBySmartPeer(tx);
396
+ });
397
+
398
+ await this.requestTxBatch(peerId, blockRequest);
399
+ txs.forEach(tx => {
400
+ this.txsMetadata.markNotInFlightBySmartPeer(tx);
401
+ });
402
+ }
403
+ } catch (err: any) {
404
+ this.logger.error(`Smart worker ${workerIndex} encountered an error: ${err}`);
405
+ } finally {
406
+ this.logger.debug(`Smart worker ${workerIndex} finished`);
407
+ }
408
+ }
409
+
410
+ /*
411
+ * Sends actual request to the peer and handles response
412
+ *
413
+ * @param peerId - the peer to send request to
414
+ * @param request - the actual request
415
+ */
416
+ private async requestTxBatch(peerId: PeerId, request: BlockTxsRequest): Promise<void> {
417
+ try {
418
+ this.peers.markPeerInFlight(peerId);
419
+ const response = await this.p2pService.reqResp.sendRequestToPeer(
420
+ peerId,
421
+ ReqRespSubProtocol.BLOCK_TXS,
422
+ request.toBuffer(),
423
+ );
424
+ if (response.status !== ReqRespStatus.SUCCESS) {
425
+ this.logger.debug(`Peer ${peerId.toString()} failed to respond with status: ${response.status}`);
426
+ this.handleFailResponseFromPeer(peerId, response.status);
427
+ return;
428
+ }
429
+
430
+ const blockResponse = BlockTxsResponse.fromBuffer(response.data);
431
+ await this.handleSuccessResponseFromPeer(peerId, blockResponse);
432
+ } catch (err: any) {
433
+ this.logger.error(`Failed to get valid response from peer ${peerId.toString()}: ${err.message}`, {
434
+ peerId,
435
+ error: err,
436
+ });
437
+
438
+ this.handleFailResponseFromPeer(peerId, ReqRespStatus.UNKNOWN);
439
+ } finally {
440
+ this.peers.unMarkPeerInFlight(peerId);
441
+ }
442
+ }
443
+
444
+ /*
445
+ * Handles failed response form the peer
446
+ * There are 3 scenarios
447
+ * - RATE_LIMIT_EXCEEDED: We mark this and don't query this peer again for some_time
448
+ * - FAILURE and UNKNOWN: We penalise this, if peer has been penalised this way N times they are not queried again
449
+ * this implies we will query these peers couple of more times and give them a chance to "redeem" themselves before completely ignoring them
450
+ */
451
+ private handleFailResponseFromPeer(peerId: PeerId, responseStatus: ReqRespStatus) {
452
+ if (responseStatus === ReqRespStatus.FAILURE || responseStatus === ReqRespStatus.UNKNOWN) {
453
+ this.peers.penalisePeer(peerId, PeerErrorSeverity.HighToleranceError);
454
+ this.peers.markPeerDumb(peerId);
455
+ this.txsMetadata.clearPeerData(peerId);
456
+ return;
457
+ }
458
+
459
+ // NOT_FOUND means the peer pruned its block proposal — it can no longer serve
460
+ // index-based requests, but this is a legitimate state so we don't penalize.
461
+ if (responseStatus === ReqRespStatus.NOT_FOUND) {
462
+ this.peers.markPeerDumb(peerId);
463
+ this.txsMetadata.clearPeerData(peerId);
464
+ return;
465
+ }
466
+
467
+ if (responseStatus === ReqRespStatus.RATE_LIMIT_EXCEEDED) {
468
+ this.peers.markPeerRateLimitExceeded(peerId);
469
+ }
470
+ }
471
+
472
+ /*
473
+ * Handles successful response form the peer, this includes
474
+ * - Handling received transactions
475
+ * - Deciding if the peer is "smart" or not
476
+ * */
477
+ private async handleSuccessResponseFromPeer(peerId: PeerId, response: BlockTxsResponse) {
478
+ this.logger.debug(`Received txs: ${response.txs.length} from peer ${peerId.toString()} `);
479
+ await this.handleReceivedTxs(peerId, response.txs);
480
+
481
+ this.decideIfPeerIsSmart(peerId, response);
482
+ }
483
+
484
+ /*
485
+ * Handles received txs.
486
+ * Transactions are validated and then put on async queue
487
+ * to be yielded by main running loop
488
+ * */
489
+ private async handleReceivedTxs(peerId: PeerId, txs: TxArray) {
490
+ const newTxs = txs.filter(tx => !this.txsMetadata.alreadyFetched(tx.txHash));
491
+
492
+ if (newTxs.length === 0) {
493
+ return;
494
+ }
495
+
496
+ //TODO: this validation can be slow, maybe spawn worker just for validation
497
+ // We could use the async queue for communication.
498
+ const validationResults = await Promise.allSettled(
499
+ newTxs.map(async tx => ({
500
+ tx,
501
+ isValid: (await this.txValidator.validateRequestedTx(tx)).result === 'valid',
502
+ })),
503
+ );
504
+
505
+ let hasInvalidTx = false;
506
+ validationResults.forEach(result => {
507
+ if (result.status === 'fulfilled' && result.value.isValid) {
508
+ if (this.txsMetadata.markFetched(peerId, result.value.tx)) {
509
+ this.txQueue.put(result.value.tx);
510
+ }
511
+ } else {
512
+ hasInvalidTx = true;
513
+ }
514
+ });
515
+
516
+ if (hasInvalidTx) {
517
+ this.logger.warn(`Penalizing peer ${peerId.toString()} for sending invalid transactions in batch response`, {
518
+ peerId,
519
+ });
520
+ this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
521
+ } else {
522
+ // If we have received successful response from the peer, they have "redeemed" themselves and not considered bad anymore
523
+ this.peers.unMarkPeerAsBad(peerId);
524
+ }
525
+
526
+ const missingTxHashes = this.txsMetadata.getMissingTxHashes();
527
+ if (missingTxHashes.size === 0) {
528
+ // wake sleepers so they can see shouldStop() and exit before waiting on timeout
529
+ this.unlockSmartRequesterSemaphores();
530
+ } else {
531
+ this.logger.trace(
532
+ `Missing txs: ${Array.from(this.txsMetadata.getMissingTxHashes())
533
+ .map(tx => tx.toString())
534
+ .join(', ')}`,
535
+ );
536
+ }
537
+ }
538
+
539
+ /*
540
+ * Peer is smart if:
541
+ * - They are not pinned peer
542
+ * - They have sent successful response indicating which txs from Block proposal they have
543
+ * - They have transactions we are missing
544
+ */
545
+ private decideIfPeerIsSmart(peerId: PeerId, response: BlockTxsResponse) {
546
+ const pinnedPeerShouldNeverBeMarkedAsSmart = this.pinnedPeer && peerId.toString() === this.pinnedPeer.toString();
547
+ if (pinnedPeerShouldNeverBeMarkedAsSmart) {
548
+ return;
549
+ }
550
+
551
+ const smartPeersAreDisabled = this.smartParallelWorkerCount === 0;
552
+ if (smartPeersAreDisabled) {
553
+ return;
554
+ }
555
+
556
+ const hasArchiveRootMismatch = this.blockTxsSource.archive.toString() !== response.archiveRoot.toString();
557
+ if (hasArchiveRootMismatch) {
558
+ this.handleArchiveRootMismatch(peerId, response);
559
+ return;
560
+ }
561
+
562
+ // We mark peer as "smart" only if they have some txs we are missing
563
+ // Otherwise we keep them as "dumb" in hope they'll receive some new txs we are missing in the future
564
+ if (!this.peerHasSomeTxsWeAreMissing(peerId, response)) {
565
+ this.logger.debug(`${peerId.toString()} has no txs we are missing, skipping`);
566
+ return;
567
+ }
568
+
569
+ this.peers.markPeerSmart(peerId);
570
+ this.markTxsPeerHas(peerId, response);
571
+
572
+ // Unblock smart workers
573
+ this.smartRequesterSemaphore.release();
574
+ }
575
+
576
+ /**
577
+ * Handles an archive root mismatch between local state and peer response.
578
+ *
579
+ * - Response archive is Fr.ZERO (peer pruned proposal, legitimate): marks peer dumb.
580
+ * - Non-zero archive mismatch (malicious response): penalises + marks dumb.
581
+ */
582
+ private handleArchiveRootMismatch(peerId: PeerId, response: BlockTxsResponse): void {
583
+ if (!response.archiveRoot.isZero()) {
584
+ this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
585
+ }
586
+
587
+ this.peers.markPeerDumb(peerId);
588
+ this.txsMetadata.clearPeerData(peerId);
589
+ }
590
+
591
+ private peerHasSomeTxsWeAreMissing(_peerId: PeerId, response: BlockTxsResponse): boolean {
592
+ if (response.txIndices.isEmpty()) {
593
+ return false;
594
+ }
595
+ const txsPeerHas = new Set(this.extractHashesPeerHasFromResponse(response).map(h => h.toString()));
596
+ return this.txsMetadata.getMissingTxHashes().intersection(txsPeerHas).size > 0;
597
+ }
598
+
599
+ private markTxsPeerHas(peerId: PeerId, response: BlockTxsResponse) {
600
+ const txsPeerHas = this.extractHashesPeerHasFromResponse(response);
601
+ this.logger.debug(`${peerId.toString()} has txs: ${txsPeerHas.map(tx => tx.toString()).join(', ')}`);
602
+ this.txsMetadata.markPeerHas(peerId, txsPeerHas);
603
+ }
604
+
605
+ private extractHashesPeerHasFromResponse(response: BlockTxsResponse): Array<TxHash> {
606
+ const hashes: TxHash[] = [];
607
+ const indicesOfHashesPeerHas = new Set(response.txIndices.getTrueIndices());
608
+ this.blockTxsSource.txHashes.forEach((hash, idx) => {
609
+ if (indicesOfHashesPeerHas.has(idx)) {
610
+ hashes.push(hash);
611
+ }
612
+ });
613
+
614
+ return hashes;
615
+ }
616
+
617
+ /*
618
+ * Helper function to crate round robin indexer -
619
+ * i.e. the "thing" which returns next index/number in round robin fashion
620
+ **/
621
+ private makeRoundRobinIndexer(start = 0) {
622
+ let i = start;
623
+ /*
624
+ * Function to calculate next round-robin number
625
+ * Idea is that we pass in an array size and based on it and previous state we call next
626
+ * Array size can change between calls thus it is passed as function
627
+ *
628
+ * @returns next index or undefined if size is 0
629
+ */
630
+ return (size: () => number) => {
631
+ const length = size();
632
+ if (length === 0) {
633
+ return undefined;
634
+ }
635
+
636
+ const current = i % length;
637
+ i = (current + 1) % length;
638
+ return current;
639
+ };
640
+ }
641
+
642
+ /*
643
+ * Checks if the BatchTxRequester should stop fetching missing txs.
644
+ * Delegates to requestTracker which covers: deadline hit, all txs fetched, or external cancellation. */
645
+ private shouldStop() {
646
+ if (this.requestTracker.checkCancelled()) {
647
+ this.unlockSmartRequesterSemaphores();
648
+ }
649
+
650
+ return this.requestTracker.checkCancelled();
651
+ }
652
+
653
+ /*
654
+ * Helper function which unlocks all smart requester semaphores
655
+ * @note This is needed otherwise they will block forever
656
+ * */
657
+ private unlockSmartRequesterSemaphores() {
658
+ for (let i = 0; i < this.smartParallelWorkerCount; i++) {
659
+ this.smartRequesterSemaphore.release();
660
+ }
661
+ }
662
+
663
+ /*
664
+ * Sleeps for the given duration, but clamped to the deadline.
665
+ * This ensures we don't sleep past the deadline.
666
+ * */
667
+ private async sleepClampedToDeadline(durationMs: number) {
668
+ if (this.requestTracker.checkCancelled()) {
669
+ return;
670
+ }
671
+ await Promise.race([sleep(durationMs), this.requestTracker.cancellationToken]);
672
+ }
673
+ }