@aztec/p2p 0.0.1-commit.6230a0c → 0.0.1-commit.643667a5cb

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 (313) hide show
  1. package/dest/client/factory.d.ts +7 -6
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +47 -11
  4. package/dest/client/interface.d.ts +43 -23
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +38 -42
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +145 -145
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -6
  10. package/dest/config.d.ts +25 -9
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +16 -6
  13. package/dest/errors/tx-pool.error.d.ts +8 -0
  14. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  15. package/dest/errors/tx-pool.error.js +9 -0
  16. package/dest/index.d.ts +2 -1
  17. package/dest/index.d.ts.map +1 -1
  18. package/dest/index.js +1 -0
  19. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -88
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/attestation_pool.js +441 -3
  22. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  24. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
  25. package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
  26. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/index.js +1 -2
  28. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  29. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  31. package/dest/mem_pools/index.d.ts +3 -2
  32. package/dest/mem_pools/index.d.ts.map +1 -1
  33. package/dest/mem_pools/index.js +1 -1
  34. package/dest/mem_pools/interface.d.ts +5 -5
  35. package/dest/mem_pools/interface.d.ts.map +1 -1
  36. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  37. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
  38. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
  39. package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
  40. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
  41. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
  42. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
  43. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  44. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  45. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  46. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
  47. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
  48. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +128 -0
  49. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
  50. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  51. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +93 -0
  52. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
  53. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
  54. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +95 -0
  55. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
  56. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
  57. package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
  58. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +174 -0
  59. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
  60. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +25 -0
  61. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
  62. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  63. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +65 -0
  64. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
  65. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  66. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +93 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
  68. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  69. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +78 -0
  70. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
  71. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
  72. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +73 -0
  73. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
  74. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
  75. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
  76. package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
  77. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
  78. package/dest/mem_pools/tx_pool_v2/index.js +5 -0
  79. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  80. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  81. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  82. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +211 -0
  83. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
  84. package/dest/mem_pools/tx_pool_v2/interfaces.js +9 -0
  85. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +97 -0
  86. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
  87. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +152 -0
  88. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
  89. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
  90. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
  91. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +108 -0
  92. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
  93. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +355 -0
  94. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +60 -0
  95. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
  96. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +161 -0
  97. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +77 -0
  98. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
  99. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +896 -0
  100. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -3
  101. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  102. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +3 -3
  103. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  105. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  106. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  107. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  108. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  110. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  111. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  112. package/dest/msg_validators/tx_validator/gas_validator.js +3 -3
  113. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  114. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  116. package/dest/services/dummy_service.d.ts +12 -3
  117. package/dest/services/dummy_service.d.ts.map +1 -1
  118. package/dest/services/dummy_service.js +9 -0
  119. package/dest/services/encoding.d.ts +2 -2
  120. package/dest/services/encoding.d.ts.map +1 -1
  121. package/dest/services/encoding.js +4 -3
  122. package/dest/services/gossipsub/index.d.ts +3 -0
  123. package/dest/services/gossipsub/index.d.ts.map +1 -0
  124. package/dest/services/gossipsub/index.js +2 -0
  125. package/dest/services/gossipsub/scoring.d.ts +21 -3
  126. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  127. package/dest/services/gossipsub/scoring.js +24 -7
  128. package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
  129. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  130. package/dest/services/gossipsub/topic_score_params.js +346 -0
  131. package/dest/services/libp2p/libp2p_service.d.ts +85 -35
  132. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  133. package/dest/services/libp2p/libp2p_service.js +374 -275
  134. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  135. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  136. package/dest/services/peer-manager/peer_scoring.js +25 -2
  137. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +6 -5
  138. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  139. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +12 -16
  140. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
  141. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  142. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
  143. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  144. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
  145. package/dest/services/reqresp/interface.d.ts +10 -1
  146. package/dest/services/reqresp/interface.d.ts.map +1 -1
  147. package/dest/services/reqresp/interface.js +15 -1
  148. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
  149. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  150. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +16 -11
  151. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +21 -10
  152. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  153. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +27 -11
  154. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  155. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  156. package/dest/services/reqresp/protocols/tx.js +20 -0
  157. package/dest/services/reqresp/reqresp.d.ts +1 -1
  158. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  159. package/dest/services/reqresp/reqresp.js +11 -4
  160. package/dest/services/service.d.ts +38 -2
  161. package/dest/services/service.d.ts.map +1 -1
  162. package/dest/services/tx_collection/config.d.ts +22 -4
  163. package/dest/services/tx_collection/config.d.ts.map +1 -1
  164. package/dest/services/tx_collection/config.js +49 -3
  165. package/dest/services/tx_collection/fast_tx_collection.d.ts +6 -5
  166. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  167. package/dest/services/tx_collection/fast_tx_collection.js +64 -48
  168. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  169. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  170. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  171. package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
  172. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  173. package/dest/services/tx_collection/file_store_tx_source.js +90 -0
  174. package/dest/services/tx_collection/index.d.ts +3 -2
  175. package/dest/services/tx_collection/index.d.ts.map +1 -1
  176. package/dest/services/tx_collection/index.js +1 -0
  177. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  178. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  179. package/dest/services/tx_collection/instrumentation.js +2 -1
  180. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  181. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  182. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  183. package/dest/services/tx_collection/proposal_tx_collector.d.ts +15 -14
  184. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  185. package/dest/services/tx_collection/proposal_tx_collector.js +6 -6
  186. package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
  187. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  188. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  189. package/dest/services/tx_collection/tx_collection.d.ts +23 -10
  190. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  191. package/dest/services/tx_collection/tx_collection.js +75 -3
  192. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  193. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  194. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  195. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  196. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  197. package/dest/services/tx_collection/tx_source.js +19 -2
  198. package/dest/services/tx_file_store/config.d.ts +1 -3
  199. package/dest/services/tx_file_store/config.d.ts.map +1 -1
  200. package/dest/services/tx_file_store/config.js +0 -4
  201. package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
  202. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  203. package/dest/services/tx_file_store/tx_file_store.js +9 -6
  204. package/dest/services/tx_provider.d.ts +3 -3
  205. package/dest/services/tx_provider.d.ts.map +1 -1
  206. package/dest/services/tx_provider.js +5 -4
  207. package/dest/test-helpers/make-test-p2p-clients.d.ts +3 -3
  208. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  209. package/dest/test-helpers/mock-pubsub.d.ts +29 -2
  210. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  211. package/dest/test-helpers/mock-pubsub.js +103 -2
  212. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  213. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  214. package/dest/test-helpers/reqresp-nodes.js +2 -1
  215. package/dest/test-helpers/testbench-utils.d.ts +43 -38
  216. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  217. package/dest/test-helpers/testbench-utils.js +128 -59
  218. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  219. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  220. package/dest/testbench/p2p_client_testbench_worker.js +10 -10
  221. package/dest/util.d.ts +2 -2
  222. package/dest/util.d.ts.map +1 -1
  223. package/package.json +14 -14
  224. package/src/client/factory.ts +87 -15
  225. package/src/client/interface.ts +59 -23
  226. package/src/client/p2p_client.ts +184 -167
  227. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -9
  228. package/src/config.ts +35 -11
  229. package/src/errors/tx-pool.error.ts +12 -0
  230. package/src/index.ts +1 -0
  231. package/src/mem_pools/attestation_pool/attestation_pool.ts +496 -91
  232. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
  233. package/src/mem_pools/attestation_pool/index.ts +9 -2
  234. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  235. package/src/mem_pools/index.ts +4 -1
  236. package/src/mem_pools/interface.ts +4 -4
  237. package/src/mem_pools/tx_pool/README.md +1 -1
  238. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  239. package/src/mem_pools/tx_pool_v2/README.md +275 -0
  240. package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
  241. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
  242. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  243. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +160 -0
  244. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +121 -0
  245. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +122 -0
  246. package/src/mem_pools/tx_pool_v2/eviction/index.ts +27 -0
  247. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +209 -0
  248. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
  249. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
  250. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +91 -0
  251. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +90 -0
  252. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +31 -0
  253. package/src/mem_pools/tx_pool_v2/index.ts +12 -0
  254. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  255. package/src/mem_pools/tx_pool_v2/interfaces.ts +242 -0
  256. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +242 -0
  257. package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
  258. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +444 -0
  259. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +223 -0
  260. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1069 -0
  261. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +2 -2
  262. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +2 -2
  263. package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
  264. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  265. package/src/msg_validators/tx_validator/gas_validator.ts +11 -3
  266. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  267. package/src/services/dummy_service.ts +17 -1
  268. package/src/services/encoding.ts +4 -3
  269. package/src/services/gossipsub/README.md +641 -0
  270. package/src/services/gossipsub/index.ts +2 -0
  271. package/src/services/gossipsub/scoring.ts +29 -5
  272. package/src/services/gossipsub/topic_score_params.ts +487 -0
  273. package/src/services/libp2p/libp2p_service.ts +377 -277
  274. package/src/services/peer-manager/peer_scoring.ts +25 -0
  275. package/src/services/reqresp/batch-tx-requester/README.md +7 -7
  276. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +17 -17
  277. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
  278. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
  279. package/src/services/reqresp/interface.ts +26 -1
  280. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +23 -14
  281. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +38 -15
  282. package/src/services/reqresp/protocols/tx.ts +22 -0
  283. package/src/services/reqresp/reqresp.ts +13 -3
  284. package/src/services/service.ts +50 -1
  285. package/src/services/tx_collection/config.ts +74 -6
  286. package/src/services/tx_collection/fast_tx_collection.ts +74 -51
  287. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  288. package/src/services/tx_collection/file_store_tx_source.ts +117 -0
  289. package/src/services/tx_collection/index.ts +2 -1
  290. package/src/services/tx_collection/instrumentation.ts +7 -1
  291. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  292. package/src/services/tx_collection/proposal_tx_collector.ts +20 -21
  293. package/src/services/tx_collection/slow_tx_collection.ts +66 -33
  294. package/src/services/tx_collection/tx_collection.ts +113 -16
  295. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  296. package/src/services/tx_collection/tx_source.ts +22 -3
  297. package/src/services/tx_file_store/config.ts +0 -6
  298. package/src/services/tx_file_store/tx_file_store.ts +10 -8
  299. package/src/services/tx_provider.ts +8 -7
  300. package/src/test-helpers/make-test-p2p-clients.ts +3 -3
  301. package/src/test-helpers/mock-pubsub.ts +143 -3
  302. package/src/test-helpers/reqresp-nodes.ts +2 -1
  303. package/src/test-helpers/testbench-utils.ts +127 -71
  304. package/src/testbench/p2p_client_testbench_worker.ts +22 -15
  305. package/src/util.ts +7 -1
  306. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
  307. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  308. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
  309. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
  310. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  311. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
  312. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
  313. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
@@ -1,4 +1,5 @@
1
1
  import { chunk } from '@aztec/foundation/collection';
2
+ import { MAX_TX_SIZE_KB } from '@aztec/stdlib/p2p';
2
3
  import { TxArray, TxHash, TxHashArray } from '@aztec/stdlib/tx';
3
4
 
4
5
  import type { PeerId } from '@libp2p/interface';
@@ -55,3 +56,24 @@ export function reqRespTxHandler(mempools: MemPools): ReqRespSubProtocolHandler
55
56
  export function chunkTxHashesRequest(hashes: TxHash[], chunkSize = 1): Array<TxHashArray> {
56
57
  return chunk(hashes, chunkSize).map(chunk => new TxHashArray(...chunk));
57
58
  }
59
+
60
+ /**
61
+ * Calculate the expected response size for a TX request.
62
+ * @param requestBuffer - The serialized request buffer containing TxHashArray
63
+ * @returns Expected response size in KB
64
+ */
65
+ export function calculateTxResponseSize(requestBuffer: Buffer): number {
66
+ try {
67
+ const txHashes = TxHashArray.fromBuffer(requestBuffer);
68
+ // TxHashArray.fromBuffer returns empty array on parse failure, so check for that
69
+ if (txHashes.length === 0 && requestBuffer.length > 0) {
70
+ // If we got an empty array but had a non-empty buffer, parsing likely failed
71
+ // Fall back to allowing a single transaction response
72
+ return MAX_TX_SIZE_KB + 1;
73
+ }
74
+ return Math.max(txHashes.length, 1) * MAX_TX_SIZE_KB + 1; // +1 KB overhead, at least 1 tx
75
+ } catch {
76
+ // If we can't parse the request, fall back to allowing a single transaction response
77
+ return MAX_TX_SIZE_KB + 1;
78
+ }
79
+ }
@@ -36,6 +36,7 @@ import {
36
36
  type ReqRespSubProtocolValidators,
37
37
  type SubProtocolMap,
38
38
  responseFromBuffer,
39
+ subProtocolSizeCalculators,
39
40
  } from './interface.js';
40
41
  import { ReqRespMetrics } from './metrics.js';
41
42
  import {
@@ -437,6 +438,9 @@ export class ReqResp implements ReqRespInterface {
437
438
  try {
438
439
  this.metrics.recordRequestSent(subProtocol);
439
440
 
441
+ // Calculate expected response size based on the request payload
442
+ const expectedSizeKb = subProtocolSizeCalculators[subProtocol](payload);
443
+
440
444
  this.logger.trace(`Sending request to peer ${peerId.toString()} on sub protocol ${subProtocol}`);
441
445
  stream = await this.connectionSampler.dialProtocol(peerId, subProtocol, dialTimeout);
442
446
  this.logger.trace(
@@ -444,11 +448,14 @@ export class ReqResp implements ReqRespInterface {
444
448
  );
445
449
 
446
450
  const timeoutErr = new IndividualReqRespTimeoutError();
451
+ // Create a wrapper to pass the expected size to readMessage
452
+ const readMessageWithSizeLimit = (source: AsyncIterable<Uint8ArrayList>) =>
453
+ this.readMessage(source, expectedSizeKb);
447
454
  const [_, resp] = await executeTimeout(
448
455
  signal =>
449
456
  Promise.all([
450
457
  pipeline([payload], stream!.sink, { signal }),
451
- pipeline(stream!.source, this.readMessage.bind(this), { signal }),
458
+ pipeline(stream!.source, readMessageWithSizeLimit, { signal }),
452
459
  ]),
453
460
  this.individualRequestTimeoutMs,
454
461
  () => timeoutErr,
@@ -510,8 +517,11 @@ export class ReqResp implements ReqRespInterface {
510
517
  * The message is split into two components
511
518
  * - The first chunk should contain a control byte, indicating the status of the response see `ReqRespStatus`
512
519
  * - The second chunk should contain the response data
520
+ *
521
+ * @param source - The async iterable source of data chunks
522
+ * @param maxSizeKb - Optional maximum expected size in KB for the decompressed response
513
523
  */
514
- private async readMessage(source: AsyncIterable<Uint8ArrayList>): Promise<ReqRespResponse> {
524
+ private async readMessage(source: AsyncIterable<Uint8ArrayList>, maxSizeKb?: number): Promise<ReqRespResponse> {
515
525
  let status: ReqRespStatus | undefined;
516
526
  const chunks: Uint8Array[] = [];
517
527
 
@@ -536,7 +546,7 @@ export class ReqResp implements ReqRespInterface {
536
546
  }
537
547
 
538
548
  const messageData = Buffer.concat(chunks);
539
- const message: Buffer = this.snappyTransform.inboundTransformData(messageData);
549
+ const message: Buffer = this.snappyTransform.inboundTransformData(messageData, undefined, maxSizeKb);
540
550
 
541
551
  return {
542
552
  status: status ?? ReqRespStatus.UNKNOWN,
@@ -1,6 +1,13 @@
1
+ import type { SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
2
3
  import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
3
- import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore, Gossipable } from '@aztec/stdlib/p2p';
4
+ import type {
5
+ BlockProposal,
6
+ CheckpointAttestation,
7
+ CheckpointProposalCore,
8
+ Gossipable,
9
+ TopicType,
10
+ } from '@aztec/stdlib/p2p';
4
11
  import type { Tx } from '@aztec/stdlib/tx';
5
12
 
6
13
  import type { PeerId } from '@libp2p/interface';
@@ -43,6 +50,32 @@ export type P2PCheckpointReceivedCallback = (
43
50
 
44
51
  export type AuthReceivedCallback = (peerId: PeerId, authRequest: AuthRequest) => Promise<AuthResponse | undefined>;
45
52
 
53
+ /** Minimal info passed to the duplicate proposal callback. */
54
+ export type DuplicateProposalInfo = {
55
+ slot: SlotNumber;
56
+ proposer: EthAddress;
57
+ type: 'checkpoint' | 'block';
58
+ };
59
+
60
+ /**
61
+ * Callback for when a duplicate proposal is detected (equivocation).
62
+ * Invoked on the first duplicate (when count goes from 1 to 2).
63
+ */
64
+ export type P2PDuplicateProposalCallback = (info: DuplicateProposalInfo) => void;
65
+
66
+ /** Minimal info passed to the duplicate attestation callback. */
67
+ export type DuplicateAttestationInfo = {
68
+ slot: SlotNumber;
69
+ attester: EthAddress;
70
+ };
71
+
72
+ /**
73
+ * Callback for when a duplicate attestation is detected (equivocation).
74
+ * A validator signing attestations for different proposals at the same slot.
75
+ * Invoked on the first duplicate (when count goes from 1 to 2).
76
+ */
77
+ export type P2PDuplicateAttestationCallback = (info: DuplicateAttestationInfo) => void;
78
+
46
79
  /**
47
80
  * The interface for a P2P service implementation.
48
81
  */
@@ -86,10 +119,26 @@ export interface P2PService {
86
119
 
87
120
  registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback): void;
88
121
 
122
+ /**
123
+ * Registers a callback invoked when a duplicate proposal is detected (equivocation).
124
+ * The callback is triggered on the first duplicate (when count goes from 1 to 2).
125
+ */
126
+ registerDuplicateProposalCallback(callback: P2PDuplicateProposalCallback): void;
127
+
128
+ /**
129
+ * Registers a callback invoked when a duplicate attestation is detected (equivocation).
130
+ * A validator signing attestations for different proposals at the same slot.
131
+ * The callback is triggered on the first duplicate (when count goes from 1 to 2).
132
+ */
133
+ registerDuplicateAttestationCallback(callback: P2PDuplicateAttestationCallback): void;
134
+
89
135
  getEnr(): ENR | undefined;
90
136
 
91
137
  getPeers(includePending?: boolean): PeerInfo[];
92
138
 
139
+ /** Returns the number of peers in the GossipSub mesh for a given topic type. */
140
+ getGossipMeshPeerCount(topicType: TopicType): number;
141
+
93
142
  validate(txs: Tx[]): Promise<void>;
94
143
 
95
144
  addReqRespSubProtocol(
@@ -6,7 +6,7 @@ import {
6
6
  } from '@aztec/foundation/config';
7
7
  import { MAX_RPC_TXS_LEN } from '@aztec/stdlib/interfaces/api-limit';
8
8
 
9
- export type ProposalTxCollectorType = 'new' | 'old';
9
+ export type MissingTxsCollectorType = 'new' | 'old';
10
10
 
11
11
  export type TxCollectionConfig = {
12
12
  /** How long to wait before starting reqresp for fast collection */
@@ -29,8 +29,26 @@ export type TxCollectionConfig = {
29
29
  txCollectionFastMaxParallelRequestsPerNode: number;
30
30
  /** Maximum number of transactions to request from a node in a single batch */
31
31
  txCollectionNodeRpcMaxBatchSize: number;
32
- /** Which collector implementation to use for proposal tx collection */
33
- txCollectionProposalTxCollectorType: ProposalTxCollectorType;
32
+ /** Which collector implementation to use for missing txs collection */
33
+ txCollectionMissingTxsCollectorType: MissingTxsCollectorType;
34
+ /** A comma-separated list of file store URLs (s3://, gs://, file://, http://) for tx collection */
35
+ txCollectionFileStoreUrls: string[];
36
+ /** Delay in ms before file store collection starts after slow collection is triggered */
37
+ txCollectionFileStoreSlowDelayMs: number;
38
+ /** Delay in ms before file store collection starts after fast collection is triggered */
39
+ txCollectionFileStoreFastDelayMs: number;
40
+ /** Number of concurrent workers for fast file store collection */
41
+ txCollectionFileStoreFastWorkerCount: number;
42
+ /** Number of concurrent workers for slow file store collection */
43
+ txCollectionFileStoreSlowWorkerCount: number;
44
+ /** Base backoff time in ms for fast file store collection retries */
45
+ txCollectionFileStoreFastBackoffBaseMs: number;
46
+ /** Base backoff time in ms for slow file store collection retries */
47
+ txCollectionFileStoreSlowBackoffBaseMs: number;
48
+ /** Max backoff time in ms for fast file store collection retries */
49
+ txCollectionFileStoreFastBackoffMaxMs: number;
50
+ /** Max backoff time in ms for slow file store collection retries */
51
+ txCollectionFileStoreSlowBackoffMaxMs: number;
34
52
  };
35
53
 
36
54
  export const txCollectionConfigMappings: ConfigMappingsType<TxCollectionConfig> = {
@@ -90,9 +108,59 @@ export const txCollectionConfigMappings: ConfigMappingsType<TxCollectionConfig>
90
108
  description: 'Maximum number of transactions to request from a node in a single batch',
91
109
  ...numberConfigHelper(MAX_RPC_TXS_LEN),
92
110
  },
93
- txCollectionProposalTxCollectorType: {
94
- env: 'TX_COLLECTION_PROPOSAL_TX_COLLECTOR_TYPE',
95
- description: 'Which collector implementation to use for proposal tx collection (new or old)',
111
+ txCollectionMissingTxsCollectorType: {
112
+ env: 'TX_COLLECTION_MISSING_TXS_COLLECTOR_TYPE',
113
+ description: 'Which collector implementation to use for missing txs collection (new or old)',
96
114
  ...enumConfigHelper(['new', 'old'] as const, 'new'),
97
115
  },
116
+ txCollectionFileStoreUrls: {
117
+ env: 'TX_COLLECTION_FILE_STORE_URLS',
118
+ description: 'A comma-separated list of file store URLs (s3://, gs://, file://, http://) for tx collection',
119
+ parseEnv: (val: string) =>
120
+ val
121
+ .split(',')
122
+ .map(url => url.trim())
123
+ .filter(url => url.length > 0),
124
+ defaultValue: [],
125
+ },
126
+ txCollectionFileStoreSlowDelayMs: {
127
+ env: 'TX_COLLECTION_FILE_STORE_SLOW_DELAY_MS',
128
+ description: 'Delay before file store collection starts after slow collection',
129
+ ...numberConfigHelper(24_000),
130
+ },
131
+ txCollectionFileStoreFastDelayMs: {
132
+ env: 'TX_COLLECTION_FILE_STORE_FAST_DELAY_MS',
133
+ description: 'Delay before file store collection starts after fast collection',
134
+ ...numberConfigHelper(2_000),
135
+ },
136
+ txCollectionFileStoreFastWorkerCount: {
137
+ env: 'TX_COLLECTION_FILE_STORE_FAST_WORKER_COUNT',
138
+ description: 'Number of concurrent workers for fast file store collection',
139
+ ...numberConfigHelper(5),
140
+ },
141
+ txCollectionFileStoreSlowWorkerCount: {
142
+ env: 'TX_COLLECTION_FILE_STORE_SLOW_WORKER_COUNT',
143
+ description: 'Number of concurrent workers for slow file store collection',
144
+ ...numberConfigHelper(2),
145
+ },
146
+ txCollectionFileStoreFastBackoffBaseMs: {
147
+ env: 'TX_COLLECTION_FILE_STORE_FAST_BACKOFF_BASE_MS',
148
+ description: 'Base backoff time in ms for fast file store collection retries',
149
+ ...numberConfigHelper(1_000),
150
+ },
151
+ txCollectionFileStoreSlowBackoffBaseMs: {
152
+ env: 'TX_COLLECTION_FILE_STORE_SLOW_BACKOFF_BASE_MS',
153
+ description: 'Base backoff time in ms for slow file store collection retries',
154
+ ...numberConfigHelper(5_000),
155
+ },
156
+ txCollectionFileStoreFastBackoffMaxMs: {
157
+ env: 'TX_COLLECTION_FILE_STORE_FAST_BACKOFF_MAX_MS',
158
+ description: 'Max backoff time in ms for fast file store collection retries',
159
+ ...numberConfigHelper(5_000),
160
+ },
161
+ txCollectionFileStoreSlowBackoffMaxMs: {
162
+ env: 'TX_COLLECTION_FILE_STORE_SLOW_BACKOFF_MAX_MS',
163
+ description: 'Max backoff time in ms for slow file store collection retries',
164
+ ...numberConfigHelper(30_000),
165
+ },
98
166
  };
@@ -2,7 +2,6 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { times } from '@aztec/foundation/collection';
3
3
  import { AbortError, TimeoutError } from '@aztec/foundation/error';
4
4
  import { type Logger, createLogger } from '@aztec/foundation/log';
5
- import { boundInclusive } from '@aztec/foundation/number';
6
5
  import { promiseWithResolvers } from '@aztec/foundation/promise';
7
6
  import { sleep } from '@aztec/foundation/sleep';
8
7
  import { DateProvider, elapsed } from '@aztec/foundation/timer';
@@ -14,37 +13,36 @@ import type { PeerId } from '@libp2p/interface';
14
13
 
15
14
  import type { BatchTxRequesterConfig } from '../reqresp/batch-tx-requester/config.js';
16
15
  import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
17
- import { ReqRespSubProtocol } from '../reqresp/interface.js';
18
- import { chunkTxHashesRequest } from '../reqresp/protocols/tx.js';
19
16
  import type { TxCollectionConfig } from './config.js';
17
+ import { MissingTxsTracker } from './missing_txs_tracker.js';
20
18
  import {
21
19
  BatchTxRequesterCollector,
22
- type ProposalTxCollector,
20
+ type MissingTxsCollector,
23
21
  SendBatchRequestCollector,
24
22
  } from './proposal_tx_collector.js';
25
23
  import type { FastCollectionRequest, FastCollectionRequestInput } from './tx_collection.js';
26
- import type { TxCollectionSink } from './tx_collection_sink.js';
24
+ import type { TxAddContext, TxCollectionSink } from './tx_collection_sink.js';
27
25
  import type { TxSource } from './tx_source.js';
28
26
 
29
27
  export class FastTxCollection {
30
28
  // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
31
29
  protected requests: Set<FastCollectionRequest> = new Set();
32
- private proposalTxCollector: ProposalTxCollector;
30
+ private missingTxsCollector: MissingTxsCollector;
33
31
 
34
32
  constructor(
35
- private p2pService: BatchTxRequesterLibP2PService,
33
+ p2pService: BatchTxRequesterLibP2PService,
36
34
  private nodes: TxSource[],
37
35
  private txCollectionSink: TxCollectionSink,
38
36
  private config: TxCollectionConfig,
39
37
  private dateProvider: DateProvider = new DateProvider(),
40
38
  private log: Logger = createLogger('p2p:tx_collection_service'),
41
- proposalTxCollector?: ProposalTxCollector,
39
+ missingTxsCollector?: MissingTxsCollector,
42
40
  ) {
43
41
  const batchTxRequesterConfig = this.config as Partial<BatchTxRequesterConfig>;
44
- const proposalCollectorType = this.config.txCollectionProposalTxCollectorType;
45
- this.proposalTxCollector =
46
- proposalTxCollector ??
47
- (proposalCollectorType === 'old'
42
+ const missingTxsCollectorType = this.config.txCollectionMissingTxsCollectorType;
43
+ this.missingTxsCollector =
44
+ missingTxsCollector ??
45
+ (missingTxsCollectorType === 'old'
48
46
  ? new SendBatchRequestCollector(p2pService)
49
47
  : new BatchTxRequesterCollector(p2pService, log, dateProvider, undefined, batchTxRequesterConfig));
50
48
  }
@@ -80,29 +78,29 @@ export class FastTxCollection {
80
78
  // This promise is used to await for the collection to finish during the main collectFast method.
81
79
  // It gets resolved in `foundTxs` when all txs have been collected, or rejected if the request is aborted or hits the deadline.
82
80
  const promise = promiseWithResolvers<void>();
83
- setTimeout(() => promise.reject(new TimeoutError(`Timed out while collecting txs`)), timeout);
81
+ const timeoutTimer = setTimeout(() => promise.reject(new TimeoutError(`Timed out while collecting txs`)), timeout);
84
82
 
85
83
  const request: FastCollectionRequest = {
86
84
  ...input,
87
85
  blockInfo,
88
86
  promise,
89
- foundTxs: new Map<string, Tx>(),
90
- missingTxHashes: new Set(txHashes.map(t => t.toString())),
87
+ missingTxTracker: MissingTxsTracker.fromArray(txHashes),
91
88
  deadline: opts.deadline,
92
89
  };
93
90
 
94
91
  const [duration] = await elapsed(() => this.collectFast(request, { ...opts }));
92
+ clearTimeout(timeoutTimer);
95
93
 
96
94
  this.log.verbose(
97
- `Collected ${request.foundTxs.size} txs out of ${txHashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`,
95
+ `Collected ${request.missingTxTracker.collectedTxs.length} txs out of ${txHashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`,
98
96
  {
99
97
  ...blockInfo,
100
98
  duration,
101
99
  requestType: input.type,
102
- missingTxs: [...request.missingTxHashes],
100
+ missingTxs: [...request.missingTxTracker.missingTxHashes],
103
101
  },
104
102
  );
105
- return [...request.foundTxs.values()];
103
+ return request.missingTxTracker.collectedTxs;
106
104
  }
107
105
 
108
106
  protected async collectFast(
@@ -113,7 +111,7 @@ export class FastTxCollection {
113
111
  const { blockInfo } = request;
114
112
 
115
113
  this.log.debug(
116
- `Starting fast collection of ${request.missingTxHashes.size} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
114
+ `Starting fast collection of ${request.missingTxTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
117
115
  { ...blockInfo, requestType: request.type, deadline: opts.deadline },
118
116
  );
119
117
 
@@ -126,7 +124,7 @@ export class FastTxCollection {
126
124
  await Promise.race([request.promise.promise, waitBeforeReqResp]);
127
125
 
128
126
  // If we have collected all txs, we can stop here
129
- if (request.missingTxHashes.size === 0) {
127
+ if (request.missingTxTracker.allFetched()) {
130
128
  this.log.debug(`All txs collected for slot ${blockInfo.slotNumber} without reqresp`, blockInfo);
131
129
  return;
132
130
  }
@@ -140,7 +138,7 @@ export class FastTxCollection {
140
138
  const logCtx = {
141
139
  ...blockInfo,
142
140
  errorMessage: err instanceof Error ? err.message : undefined,
143
- missingTxs: [...request.missingTxHashes].map(txHash => txHash.toString()),
141
+ missingTxs: request.missingTxTracker.missingTxHashes.values().map(txHash => txHash.toString()),
144
142
  };
145
143
  if (err instanceof Error && err.name === 'TimeoutError') {
146
144
  this.log.warn(`Timed out collecting txs for ${request.type} at slot ${blockInfo.slotNumber}`, logCtx);
@@ -168,7 +166,11 @@ export class FastTxCollection {
168
166
  }
169
167
 
170
168
  // Keep a shared priority queue of all txs pending to be requested, sorted by the number of attempts made to collect them.
171
- const attemptsPerTx = [...request.missingTxHashes].map(txHash => ({ txHash, attempts: 0, found: false }));
169
+ const attemptsPerTx = [...request.missingTxTracker.missingTxHashes].map(txHash => ({
170
+ txHash,
171
+ attempts: 0,
172
+ found: false,
173
+ }));
172
174
 
173
175
  // Returns once we have finished all node loops. Each loop finishes when the deadline is hit, or all txs have been collected.
174
176
  await Promise.allSettled(this.nodes.map(node => this.collectFastFromNode(request, node, attemptsPerTx, opts)));
@@ -181,7 +183,7 @@ export class FastTxCollection {
181
183
  opts: { deadline: Date },
182
184
  ) {
183
185
  const notFinished = () =>
184
- this.dateProvider.now() <= +opts.deadline && request.missingTxHashes.size > 0 && this.requests.has(request);
186
+ this.dateProvider.now() <= +opts.deadline && !request.missingTxTracker.allFetched() && this.requests.has(request);
185
187
 
186
188
  const maxParallelRequests = this.config.txCollectionFastMaxParallelRequestsPerNode;
187
189
  const maxBatchSize = this.config.txCollectionNodeRpcMaxBatchSize;
@@ -198,7 +200,7 @@ export class FastTxCollection {
198
200
  if (!txToRequest) {
199
201
  // No more txs to process
200
202
  break;
201
- } else if (!request.missingTxHashes.has(txToRequest.txHash)) {
203
+ } else if (!request.missingTxTracker.isMissing(txToRequest.txHash)) {
202
204
  // Mark as found if it was found somewhere else, we'll then remove it from the array.
203
205
  // We don't delete it now since 'array.splice' is pretty expensive, so we do it after sorting.
204
206
  txToRequest.found = true;
@@ -227,16 +229,24 @@ export class FastTxCollection {
227
229
  return;
228
230
  }
229
231
 
232
+ const txHashes = batch.map(({ txHash }) => txHash);
230
233
  // Collect this batch from the node
231
234
  await this.txCollectionSink.collect(
232
- txHashes => node.getTxsByHash(txHashes),
233
- batch.map(({ txHash }) => TxHash.fromString(txHash)),
235
+ async () => {
236
+ const result = await node.getTxsByHash(txHashes.map(TxHash.fromString));
237
+ for (const tx of result.validTxs) {
238
+ request.missingTxTracker.markFetched(tx);
239
+ }
240
+ return result;
241
+ },
242
+ txHashes,
234
243
  {
235
244
  description: `fast ${node.getInfo()}`,
236
245
  node: node.getInfo(),
237
246
  method: 'fast-node-rpc',
238
247
  ...request.blockInfo,
239
248
  },
249
+ this.getAddContext(request),
240
250
  );
241
251
 
242
252
  // Clear from the active requests the txs we just requested
@@ -258,8 +268,6 @@ export class FastTxCollection {
258
268
  private async collectFastViaReqResp(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) {
259
269
  const timeoutMs = +request.deadline - this.dateProvider.now();
260
270
  const pinnedPeer = opts.pinnedPeer;
261
- const maxPeers = boundInclusive(Math.ceil(request.missingTxHashes.size / 2), 8, 32);
262
- const maxRetryAttempts = 5;
263
271
  const blockInfo = request.blockInfo;
264
272
  const slotNumber = blockInfo.slotNumber;
265
273
  if (timeoutMs < 100) {
@@ -271,41 +279,58 @@ export class FastTxCollection {
271
279
  }
272
280
 
273
281
  this.log.debug(
274
- `Starting fast reqresp for ${request.missingTxHashes.size} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
282
+ `Starting fast reqresp for ${request.missingTxTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
275
283
  { ...blockInfo, timeoutMs, pinnedPeer },
276
284
  );
277
285
 
278
286
  try {
279
287
  await this.txCollectionSink.collect(
280
- async txHashes => {
288
+ async () => {
289
+ let result: Tx[];
281
290
  if (request.type === 'proposal') {
282
- return await this.proposalTxCollector.collectTxs(txHashes, request.blockProposal, pinnedPeer, timeoutMs);
291
+ result = await this.missingTxsCollector.collectTxs(
292
+ request.missingTxTracker,
293
+ request.blockProposal,
294
+ pinnedPeer,
295
+ timeoutMs,
296
+ );
283
297
  } else if (request.type === 'block') {
284
- const txs = await this.p2pService.reqResp.sendBatchRequest<ReqRespSubProtocol.TX>(
285
- ReqRespSubProtocol.TX,
286
- chunkTxHashesRequest(txHashes),
298
+ const blockTxsSource = {
299
+ txHashes: request.block.body.txEffects.map(e => e.txHash),
300
+ archive: request.block.archive.root,
301
+ };
302
+ result = await this.missingTxsCollector.collectTxs(
303
+ request.missingTxTracker,
304
+ blockTxsSource,
287
305
  pinnedPeer,
288
306
  timeoutMs,
289
- maxPeers,
290
- maxRetryAttempts,
291
307
  );
292
-
293
- return txs.flat();
294
308
  } else {
295
309
  throw new Error(`Unknown request type: ${(request as any).type}`);
296
310
  }
311
+ return { validTxs: result, invalidTxHashes: [] };
297
312
  },
298
- Array.from(request.missingTxHashes).map(txHash => TxHash.fromString(txHash)),
313
+ Array.from(request.missingTxTracker.missingTxHashes),
299
314
  { description: `reqresp for slot ${slotNumber}`, method: 'fast-req-resp', ...opts, ...request.blockInfo },
315
+ this.getAddContext(request),
300
316
  );
301
317
  } catch (err) {
302
318
  this.log.error(`Error sending fast reqresp request for txs`, err, {
303
- txs: [...request.missingTxHashes],
319
+ txs: [...request.missingTxTracker.missingTxHashes],
304
320
  ...blockInfo,
305
321
  });
306
322
  }
307
323
  }
308
324
 
325
+ /** Returns the TxAddContext for the given request, used by the sink to add txs to the pool correctly. */
326
+ private getAddContext(request: FastCollectionRequest): TxAddContext {
327
+ if (request.type === 'proposal') {
328
+ return { type: 'proposal', blockHeader: request.blockProposal.blockHeader };
329
+ } else {
330
+ return { type: 'mined', block: request.block };
331
+ }
332
+ }
333
+
309
334
  /**
310
335
  * Handle txs by marking them as found for the requests that are waiting for them, and resolves the request if all its txs have been found.
311
336
  * Called internally and from the main tx collection manager whenever the tx pool emits a tx-added event.
@@ -315,22 +340,20 @@ export class FastTxCollection {
315
340
  for (const tx of txs) {
316
341
  const txHash = tx.txHash.toString();
317
342
  // Remove the tx hash from the missing set, and add it to the found set.
318
- if (request.missingTxHashes.has(txHash)) {
319
- request.missingTxHashes.delete(txHash);
320
- request.foundTxs.set(txHash, tx);
343
+ if (request.missingTxTracker.markFetched(tx)) {
321
344
  this.log.trace(`Found tx ${txHash} for fast collection request`, {
322
345
  ...request.blockInfo,
323
346
  txHash: tx.txHash.toString(),
324
347
  type: request.type,
325
348
  });
326
- // If we found all txs for this request, we resolve the promise
327
- if (request.missingTxHashes.size === 0) {
328
- this.log.trace(`All txs found for fast collection request`, {
329
- ...request.blockInfo,
330
- type: request.type,
331
- });
332
- request.promise.resolve();
333
- }
349
+ }
350
+ // If we found all txs for this request, we resolve the promise
351
+ if (request.missingTxTracker.allFetched()) {
352
+ this.log.trace(`All txs found for fast collection request`, {
353
+ ...request.blockInfo,
354
+ type: request.type,
355
+ });
356
+ request.promise.resolve();
334
357
  }
335
358
  }
336
359
  }