@aztec/p2p 0.0.1-commit.4ad48494d → 0.0.1-commit.4d3c002

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 (381) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +7 -7
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +33 -29
  5. package/dest/client/interface.d.ts +18 -20
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +9 -19
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +72 -102
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +20 -10
  11. package/dest/config.d.ts +34 -15
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +86 -37
  14. package/dest/errors/p2p-service.error.d.ts +9 -0
  15. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  16. package/dest/errors/p2p-service.error.js +10 -0
  17. package/dest/errors/tx-pool.error.d.ts +8 -0
  18. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  19. package/dest/errors/tx-pool.error.js +9 -0
  20. package/dest/index.d.ts +1 -2
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +0 -1
  23. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
  24. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.js +11 -6
  26. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  27. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  28. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  29. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  30. package/dest/mem_pools/index.d.ts +1 -2
  31. package/dest/mem_pools/index.d.ts.map +1 -1
  32. package/dest/mem_pools/instrumentation.d.ts +4 -2
  33. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  34. package/dest/mem_pools/instrumentation.js +16 -14
  35. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -1
  36. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +9 -0
  38. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  39. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  41. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  42. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +5 -4
  44. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  45. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  47. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  48. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  50. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  51. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  53. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +4 -4
  54. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +5 -5
  55. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  56. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  57. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +12 -6
  58. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  59. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  60. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  61. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  62. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  63. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  64. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  65. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  66. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  67. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  68. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  69. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  70. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +24 -10
  71. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  72. package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
  73. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +54 -15
  74. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  75. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +111 -19
  76. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +5 -2
  77. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  78. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +38 -46
  79. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -4
  80. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  81. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +12 -5
  82. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -5
  83. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  84. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +296 -153
  85. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
  86. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  87. package/dest/msg_validators/attestation_validator/attestation_validator.js +5 -4
  88. package/dest/msg_validators/clock_tolerance.d.ts +1 -1
  89. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  90. package/dest/msg_validators/clock_tolerance.js +4 -3
  91. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  92. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  93. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  94. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  95. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  96. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  97. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  98. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  99. package/dest/msg_validators/proposal_validator/proposal_validator.js +53 -41
  100. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  101. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  102. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  103. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  104. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  105. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  106. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  107. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  108. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  109. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  110. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  111. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  112. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  113. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  114. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  115. package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
  116. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  117. package/dest/msg_validators/tx_validator/factory.js +247 -60
  118. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  119. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  120. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  121. package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
  122. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  123. package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
  124. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  125. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  126. package/dest/msg_validators/tx_validator/index.js +2 -0
  127. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  128. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  129. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  130. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  131. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  132. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  133. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  134. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  135. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  136. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
  137. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  138. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  139. package/dest/services/discv5/discV5_service.d.ts +1 -1
  140. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  141. package/dest/services/discv5/discV5_service.js +5 -2
  142. package/dest/services/dummy_service.d.ts +7 -5
  143. package/dest/services/dummy_service.d.ts.map +1 -1
  144. package/dest/services/dummy_service.js +9 -5
  145. package/dest/services/encoding.d.ts +6 -2
  146. package/dest/services/encoding.d.ts.map +1 -1
  147. package/dest/services/encoding.js +16 -9
  148. package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
  149. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  150. package/dest/services/gossipsub/topic_score_params.js +32 -10
  151. package/dest/services/libp2p/libp2p_service.d.ts +30 -22
  152. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  153. package/dest/services/libp2p/libp2p_service.js +241 -151
  154. package/dest/services/peer-manager/metrics.d.ts +3 -1
  155. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  156. package/dest/services/peer-manager/metrics.js +6 -0
  157. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  158. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  159. package/dest/services/peer-manager/peer_manager.js +24 -9
  160. package/dest/services/peer-manager/peer_scoring.d.ts +5 -2
  161. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  162. package/dest/services/peer-manager/peer_scoring.js +28 -10
  163. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +12 -8
  164. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  165. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +83 -106
  166. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -7
  167. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  168. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  169. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  170. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  171. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  172. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  173. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  174. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  175. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  176. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  177. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  178. package/dest/services/reqresp/reqresp.d.ts +1 -1
  179. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  180. package/dest/services/reqresp/reqresp.js +19 -10
  181. package/dest/services/service.d.ts +11 -4
  182. package/dest/services/service.d.ts.map +1 -1
  183. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
  184. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  185. package/dest/services/tx_collection/fast_tx_collection.js +65 -75
  186. package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
  187. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  188. package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
  189. package/dest/services/tx_collection/file_store_tx_source.d.ts +16 -6
  190. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  191. package/dest/services/tx_collection/file_store_tx_source.js +50 -9
  192. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  193. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  194. package/dest/services/tx_collection/instrumentation.js +2 -1
  195. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -7
  196. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  197. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  198. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  199. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  200. package/dest/services/tx_collection/request_tracker.js +84 -0
  201. package/dest/services/tx_collection/slow_tx_collection.d.ts +2 -2
  202. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  203. package/dest/services/tx_collection/slow_tx_collection.js +10 -8
  204. package/dest/services/tx_collection/tx_collection.d.ts +5 -7
  205. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  206. package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
  207. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  208. package/dest/services/tx_collection/tx_collection_sink.js +13 -22
  209. package/dest/services/tx_collection/tx_source.d.ts +13 -7
  210. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  211. package/dest/services/tx_collection/tx_source.js +26 -7
  212. package/dest/services/tx_file_store/tx_file_store.js +1 -1
  213. package/dest/services/tx_provider.d.ts +3 -3
  214. package/dest/services/tx_provider.d.ts.map +1 -1
  215. package/dest/services/tx_provider.js +4 -4
  216. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  217. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  218. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  219. package/dest/test-helpers/mock-pubsub.d.ts +11 -4
  220. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  221. package/dest/test-helpers/mock-pubsub.js +16 -3
  222. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  223. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  224. package/dest/test-helpers/reqresp-nodes.js +7 -3
  225. package/dest/test-helpers/testbench-utils.d.ts +6 -3
  226. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  227. package/dest/test-helpers/testbench-utils.js +23 -4
  228. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  229. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  230. package/dest/testbench/p2p_client_testbench_worker.js +56 -26
  231. package/dest/testbench/worker_client_manager.d.ts +3 -1
  232. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  233. package/dest/testbench/worker_client_manager.js +6 -3
  234. package/dest/util.d.ts +9 -5
  235. package/dest/util.d.ts.map +1 -1
  236. package/dest/util.js +2 -10
  237. package/package.json +14 -14
  238. package/src/client/factory.ts +56 -48
  239. package/src/client/interface.ts +20 -21
  240. package/src/client/p2p_client.ts +78 -132
  241. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +33 -14
  242. package/src/config.ts +125 -43
  243. package/src/errors/p2p-service.error.ts +11 -0
  244. package/src/errors/tx-pool.error.ts +12 -0
  245. package/src/index.ts +0 -1
  246. package/src/mem_pools/attestation_pool/attestation_pool.ts +12 -9
  247. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  248. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  249. package/src/mem_pools/index.ts +0 -3
  250. package/src/mem_pools/instrumentation.ts +17 -13
  251. package/src/mem_pools/tx_pool_v2/README.md +10 -2
  252. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +11 -0
  253. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  254. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +5 -4
  255. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  256. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  257. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  258. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -4
  259. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
  260. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +12 -9
  261. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  262. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  263. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  264. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  265. package/src/mem_pools/tx_pool_v2/interfaces.ts +24 -10
  266. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +159 -27
  267. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -46
  268. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +28 -8
  269. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +330 -149
  270. package/src/msg_validators/attestation_validator/README.md +49 -0
  271. package/src/msg_validators/attestation_validator/attestation_validator.ts +5 -4
  272. package/src/msg_validators/clock_tolerance.ts +4 -3
  273. package/src/msg_validators/proposal_validator/README.md +123 -0
  274. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
  275. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
  276. package/src/msg_validators/proposal_validator/proposal_validator.ts +69 -45
  277. package/src/msg_validators/tx_validator/README.md +119 -0
  278. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
  279. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  280. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  281. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  282. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  283. package/src/msg_validators/tx_validator/factory.ts +394 -78
  284. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  285. package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
  286. package/src/msg_validators/tx_validator/index.ts +2 -0
  287. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  288. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  289. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  290. package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
  291. package/src/services/discv5/discV5_service.ts +5 -2
  292. package/src/services/dummy_service.ts +12 -7
  293. package/src/services/encoding.ts +16 -8
  294. package/src/services/gossipsub/README.md +29 -14
  295. package/src/services/gossipsub/topic_score_params.ts +49 -13
  296. package/src/services/libp2p/libp2p_service.ts +262 -176
  297. package/src/services/peer-manager/metrics.ts +7 -0
  298. package/src/services/peer-manager/peer_manager.ts +28 -9
  299. package/src/services/peer-manager/peer_scoring.ts +21 -5
  300. package/src/services/reqresp/README.md +229 -0
  301. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  302. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +79 -112
  303. package/src/services/reqresp/batch-tx-requester/interface.ts +3 -6
  304. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  305. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  306. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  307. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  308. package/src/services/reqresp/reqresp.ts +22 -12
  309. package/src/services/service.ts +20 -3
  310. package/src/services/tx_collection/fast_tx_collection.ts +71 -76
  311. package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
  312. package/src/services/tx_collection/file_store_tx_source.ts +65 -9
  313. package/src/services/tx_collection/instrumentation.ts +7 -1
  314. package/src/services/tx_collection/proposal_tx_collector.ts +9 -13
  315. package/src/services/tx_collection/request_tracker.ts +127 -0
  316. package/src/services/tx_collection/slow_tx_collection.ts +8 -9
  317. package/src/services/tx_collection/tx_collection.ts +5 -6
  318. package/src/services/tx_collection/tx_collection_sink.ts +15 -29
  319. package/src/services/tx_collection/tx_source.ts +28 -8
  320. package/src/services/tx_file_store/tx_file_store.ts +1 -1
  321. package/src/services/tx_provider.ts +2 -2
  322. package/src/test-helpers/make-test-p2p-clients.ts +1 -3
  323. package/src/test-helpers/mock-pubsub.ts +20 -6
  324. package/src/test-helpers/reqresp-nodes.ts +7 -6
  325. package/src/test-helpers/testbench-utils.ts +32 -6
  326. package/src/testbench/p2p_client_testbench_worker.ts +62 -29
  327. package/src/testbench/worker_client_manager.ts +13 -6
  328. package/src/util.ts +15 -16
  329. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  330. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  331. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  332. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  333. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  334. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  335. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  336. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  337. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  338. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  339. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  340. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  341. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  342. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  343. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  344. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  345. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  346. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  347. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  348. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  349. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  350. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  351. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  352. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  353. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  354. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  355. package/dest/mem_pools/tx_pool/index.js +0 -2
  356. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  357. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  358. package/dest/mem_pools/tx_pool/priority.js +0 -15
  359. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  360. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  361. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  362. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  363. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  364. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  365. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  366. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  367. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  368. package/src/mem_pools/tx_pool/README.md +0 -270
  369. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  370. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  371. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  372. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  373. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  374. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  375. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  376. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  377. package/src/mem_pools/tx_pool/index.ts +0 -2
  378. package/src/mem_pools/tx_pool/priority.ts +0 -20
  379. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  380. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  381. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
@@ -2,18 +2,23 @@ import type { DateProvider } from '@aztec/foundation/timer';
2
2
  import type { PeerErrorSeverity } from '@aztec/stdlib/p2p';
3
3
 
4
4
  import type { PeerId } from '@libp2p/interface';
5
+ import { peerIdFromString } from '@libp2p/peer-id';
5
6
 
7
+ import type { ConnectionSampler } from '../connection-sampler/connection_sampler.js';
6
8
  import { DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD } from './config.js';
7
9
  import type { IPeerPenalizer } from './interface.js';
8
10
 
9
11
  export const RATE_LIMIT_EXCEEDED_PEER_CACHE_TTL = 1000; // 1s
10
12
 
11
13
  export interface IPeerCollection {
12
- getAllPeers(): Set<string>;
13
- getSmartPeers(): Set<string>;
14
14
  markPeerSmart(peerId: PeerId): void;
15
- getSmartPeersToQuery(): Array<string>;
16
- getDumbPeersToQuery(): Array<string>;
15
+ markPeerDumb(peerId: PeerId): void;
16
+
17
+ /** Sample next peer in round-robin fashion. No smart peers if returns undefined */
18
+ nextSmartPeerToQuery(): PeerId | undefined;
19
+ /** Sample next peer in round-robin fashion. No dumb peers if returns undefined */
20
+ nextDumbPeerToQuery(): PeerId | undefined;
21
+
17
22
  thereAreSomeDumbRatelimitExceededPeers(): boolean;
18
23
  penalisePeer(peerId: PeerId, severity: PeerErrorSeverity): void;
19
24
  unMarkPeerAsBad(peerId: PeerId): void;
@@ -28,8 +33,6 @@ export interface IPeerCollection {
28
33
  }
29
34
 
30
35
  export class PeerCollection implements IPeerCollection {
31
- private readonly peers;
32
-
33
36
  private readonly smartPeers = new Set<string>();
34
37
  private readonly inFlightPeers = new Set<string>();
35
38
  private readonly rateLimitExceededPeers = new Map<string, number>();
@@ -37,46 +40,64 @@ export class PeerCollection implements IPeerCollection {
37
40
  private readonly badPeers = new Set<string>();
38
41
 
39
42
  constructor(
40
- initialPeers: PeerId[],
43
+ private readonly connectionSampler: Pick<ConnectionSampler, 'getPeerListSortedByConnectionCountAsc'>,
41
44
  private readonly pinnedPeerId: PeerId | undefined,
42
45
  private readonly dateProvider: DateProvider,
43
46
  private readonly badPeerThreshold: number = DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD,
44
47
  private readonly peerPenalizer?: IPeerPenalizer,
45
48
  ) {
46
- this.peers = new Set(initialPeers.map(peer => peer.toString()));
47
-
48
- // Pinned peer is treaded specially, always mark it as in-flight
49
+ // Pinned peer is treated specially, always mark it as in-flight
49
50
  // and never return it as part of smart/dumb peers
50
51
  if (this.pinnedPeerId) {
51
52
  const peerIdStr = this.pinnedPeerId.toString();
52
53
  this.inFlightPeers.add(peerIdStr);
53
- this.peers.delete(peerIdStr);
54
54
  }
55
55
  }
56
56
 
57
- public getAllPeers(): Set<string> {
58
- return this.peers;
57
+ public markPeerSmart(peerId: PeerId): void {
58
+ this.smartPeers.add(peerId.toString());
59
59
  }
60
60
 
61
- public getSmartPeers(): Set<string> {
62
- return this.smartPeers;
61
+ public markPeerDumb(peerId: PeerId): void {
62
+ this.smartPeers.delete(peerId.toString());
63
63
  }
64
64
 
65
- public markPeerSmart(peerId: PeerId): void {
66
- this.smartPeers.add(peerId.toString());
65
+ // We keep track of all peers that are queried for peer sampling algorithm
66
+ private queriedSmartPeers: Set<string> = new Set<string>();
67
+ private queriedDumbPeers: Set<string> = new Set<string>();
68
+
69
+ private static nextPeer(allPeers: Set<string>, queried: Set<string>): PeerId | undefined {
70
+ if (allPeers.size === 0) {
71
+ return undefined;
72
+ }
73
+ const availablePeers = allPeers.difference(queried);
74
+ let [first] = availablePeers;
75
+ if (first === undefined) {
76
+ // We queried all peers. Start over
77
+ [first] = allPeers;
78
+ queried.clear();
79
+ }
80
+ queried.add(first);
81
+ return peerIdFromString(first);
67
82
  }
68
83
 
69
- public getSmartPeersToQuery(): Array<string> {
70
- return Array.from(
84
+ public nextSmartPeerToQuery(): PeerId | undefined {
85
+ return PeerCollection.nextPeer(this.availableSmartPeers, this.queriedSmartPeers);
86
+ }
87
+
88
+ public nextDumbPeerToQuery(): PeerId | undefined {
89
+ return PeerCollection.nextPeer(this.availableDumbPeers, this.queriedDumbPeers);
90
+ }
91
+
92
+ private get availableSmartPeers(): Set<string> {
93
+ return this.peers.intersection(
71
94
  this.smartPeers.difference(this.getBadPeers().union(this.inFlightPeers).union(this.getRateLimitExceededPeers())),
72
95
  );
73
96
  }
74
97
 
75
- public getDumbPeersToQuery(): Array<string> {
76
- return Array.from(
77
- this.peers.difference(
78
- this.smartPeers.union(this.getBadPeers()).union(this.inFlightPeers).union(this.getRateLimitExceededPeers()),
79
- ),
98
+ private get availableDumbPeers(): Set<string> {
99
+ return this.peers.difference(
100
+ this.smartPeers.union(this.getBadPeers()).union(this.inFlightPeers).union(this.getRateLimitExceededPeers()),
80
101
  );
81
102
  }
82
103
 
@@ -202,4 +223,27 @@ export class PeerCollection implements IPeerCollection {
202
223
 
203
224
  return minExpiry! - now;
204
225
  }
226
+
227
+ private orderedPeers: Set<string> = new Set();
228
+
229
+ private get peers(): Set<string> {
230
+ const pinnedStr = this.pinnedPeerId?.toString();
231
+ const currentlyConnected = new Set(
232
+ this.connectionSampler
233
+ .getPeerListSortedByConnectionCountAsc()
234
+ .map(p => p.toString())
235
+ .filter(p => p !== pinnedStr),
236
+ );
237
+
238
+ // Remove disconnected peers, preserving order of the rest.
239
+ this.orderedPeers = this.orderedPeers.intersection(currentlyConnected);
240
+
241
+ // Append newly connected peers at the end (lowest priority).
242
+ for (const peer of currentlyConnected) {
243
+ if (!this.orderedPeers.has(peer)) {
244
+ this.orderedPeers.add(peer);
245
+ }
246
+ }
247
+ return this.orderedPeers;
248
+ }
205
249
  }
@@ -1,7 +1,7 @@
1
1
  import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
2
2
  import { Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
3
3
 
4
- import { createTxReqRespValidator } from '../../../msg_validators/tx_validator/factory.js';
4
+ import { createTxValidatorForReqResponseReceivedTxs } from '../../../msg_validators/index.js';
5
5
 
6
6
  export interface BatchRequestTxValidatorConfig {
7
7
  l1ChainId: number;
@@ -29,7 +29,7 @@ export class BatchRequestTxValidator implements IBatchRequestTxValidator {
29
29
  }
30
30
 
31
31
  static createRequestedTxValidator(config: BatchRequestTxValidatorConfig): TxValidator {
32
- return createTxReqRespValidator(config.proofVerifier, {
32
+ return createTxValidatorForReqResponseReceivedTxs(config.proofVerifier, {
33
33
  l1ChainId: config.l1ChainId,
34
34
  rollupVersion: config.rollupVersion,
35
35
  });
@@ -97,9 +97,10 @@ export function prettyPrintRateLimitStatus(status: RateLimitStatus) {
97
97
  * 2. Individual rate limits for each peer.
98
98
  *
99
99
  * How it works:
100
- * - When a request comes in, it first checks against the global rate limit.
101
- * - If the global limit allows, it then checks against the specific peer's rate limit.
102
- * - The request is only allowed if both the global and peer-specific limits allow it.
100
+ * - When a request comes in, it first checks against the peer's individual rate limit.
101
+ * - If the peer limit allows, it then checks against the global rate limit.
102
+ * - The request is only allowed if both the peer-specific and global limits allow it.
103
+ * - Checking peer limit first ensures a rate-limited peer cannot exhaust the global quota.
103
104
  * - It automatically creates and manages rate limiters for new peers as they make requests.
104
105
  * - It periodically cleans up rate limiters for inactive peers to conserve memory.
105
106
  *
@@ -119,10 +120,6 @@ export class SubProtocolRateLimiter {
119
120
  }
120
121
 
121
122
  allow(peerId: PeerId): RateLimitStatus {
122
- if (!this.globalLimiter.allow()) {
123
- return RateLimitStatus.DeniedGlobal;
124
- }
125
-
126
123
  const peerIdStr = peerId.toString();
127
124
  let peerLimiter: PeerRateLimiter | undefined = this.peerLimiters.get(peerIdStr);
128
125
  if (!peerLimiter) {
@@ -135,10 +132,17 @@ export class SubProtocolRateLimiter {
135
132
  } else {
136
133
  peerLimiter.lastAccess = Date.now();
137
134
  }
138
- const peerLimitAllowed = peerLimiter.limiter.allow();
139
- if (!peerLimitAllowed) {
135
+
136
+ // Check peer limit first: a rate-limited peer must not consume global quota,
137
+ // otherwise one spamming peer can starve all others by exhausting the global bucket.
138
+ if (!peerLimiter.limiter.allow()) {
140
139
  return RateLimitStatus.DeniedPeer;
141
140
  }
141
+
142
+ if (!this.globalLimiter.allow()) {
143
+ return RateLimitStatus.DeniedGlobal;
144
+ }
145
+
142
146
  return RateLimitStatus.Allowed;
143
147
  }
144
148
 
@@ -16,7 +16,7 @@ import {
16
16
  IndividualReqRespTimeoutError,
17
17
  InvalidResponseError,
18
18
  } from '../../errors/reqresp.error.js';
19
- import { SnappyTransform } from '../encoding.js';
19
+ import { OversizedSnappyResponseError, SnappyTransform } from '../encoding.js';
20
20
  import type { PeerScoring } from '../peer-manager/peer_scoring.js';
21
21
  import {
22
22
  DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS,
@@ -320,7 +320,7 @@ export class ReqResp implements ReqRespInterface {
320
320
  };
321
321
 
322
322
  for (const index of indices) {
323
- this.logger.info(`Sending request ${index} to peer ${peerAsString}`);
323
+ this.logger.trace(`Sending request ${index} to peer ${peerAsString}`);
324
324
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]);
325
325
 
326
326
  // Check the status of the response buffer
@@ -553,16 +553,10 @@ export class ReqResp implements ReqRespInterface {
553
553
  data: message,
554
554
  };
555
555
  } catch (e: any) {
556
+ // All errors (invalid status bytes, oversized snappy responses, corrupt data, etc.)
557
+ // are re-thrown so the caller can penalize the peer via handleResponseError.
556
558
  this.logger.debug(`Reading message failed: ${e.message}`);
557
-
558
- let status = ReqRespStatus.UNKNOWN;
559
- if (e instanceof ReqRespStatusError) {
560
- status = e.status;
561
- }
562
-
563
- return {
564
- status,
565
- };
559
+ throw e;
566
560
  }
567
561
  }
568
562
 
@@ -627,7 +621,9 @@ export class ReqResp implements ReqRespInterface {
627
621
  // and that this stream should be dropped
628
622
  const isMessageToNotWarn =
629
623
  err instanceof Error &&
630
- ['stream reset', 'Cannot push value onto an ended pushable'].some(msg => err.message.includes(msg));
624
+ ['stream reset', 'Cannot push value onto an ended pushable', 'read ECONNRESET'].some(msg =>
625
+ err.message.includes(msg),
626
+ );
631
627
  const level = isMessageToNotWarn ? 'debug' : 'warn';
632
628
  this.logger[level]('Unknown stream error while handling the stream, aborting', {
633
629
  protocol,
@@ -778,6 +774,20 @@ export class ReqResp implements ReqRespInterface {
778
774
  return undefined;
779
775
  }
780
776
 
777
+ // Invalid status byte: the peer sent a status byte that doesn't match any known status code.
778
+ // This is a protocol violation, penalize harshly.
779
+ if (e instanceof ReqRespStatusError) {
780
+ this.logger.warn(`Invalid status byte from peer ${peerId.toString()} in ${subProtocol}: ${e.message}`, logTags);
781
+ return PeerErrorSeverity.LowToleranceError;
782
+ }
783
+
784
+ // Oversized snappy response: the peer is sending data that exceeds the allowed size.
785
+ // This is a protocol violation that wastes bandwidth, so penalize harshly.
786
+ if (e instanceof OversizedSnappyResponseError) {
787
+ this.logger.warn(`Oversized response from peer ${peerId.toString()} in ${subProtocol}: ${e.message}`, logTags);
788
+ return PeerErrorSeverity.LowToleranceError;
789
+ }
790
+
781
791
  return this.categorizeConnectionErrors(e, peerId, subProtocol);
782
792
  }
783
793
 
@@ -1,7 +1,13 @@
1
1
  import type { SlotNumber } from '@aztec/foundation/branded-types';
2
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
4
- 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';
5
11
  import type { Tx } from '@aztec/stdlib/tx';
6
12
 
7
13
  import type { PeerId } from '@libp2p/interface';
@@ -111,7 +117,12 @@ export interface P2PService {
111
117
  // Leaky abstraction: fix https://github.com/AztecProtocol/aztec-packages/issues/7963
112
118
  registerBlockReceivedCallback(callback: P2PBlockReceivedCallback): void;
113
119
 
114
- registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback): void;
120
+ registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback): void;
121
+
122
+ registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback): void;
123
+
124
+ /** Fires the all-nodes checkpoint callback for our own proposal (gossipsub doesn't deliver own messages). */
125
+ notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void>;
115
126
 
116
127
  /**
117
128
  * Registers a callback invoked when a duplicate proposal is detected (equivocation).
@@ -130,7 +141,10 @@ export interface P2PService {
130
141
 
131
142
  getPeers(includePending?: boolean): PeerInfo[];
132
143
 
133
- validate(txs: Tx[]): Promise<void>;
144
+ /** Returns the number of peers in the GossipSub mesh for a given topic type. */
145
+ getGossipMeshPeerCount(topicType: TopicType): number;
146
+
147
+ validateTxsReceivedInBlockProposal(txs: Tx[]): Promise<void>;
134
148
 
135
149
  addReqRespSubProtocol(
136
150
  subProtocol: ReqRespSubProtocol,
@@ -187,6 +201,9 @@ export interface PeerDiscoveryService extends EventEmitter {
187
201
  on(event: 'peer:discovered', listener: (enr: ENR) => void): this;
188
202
  emit(event: 'peer:discovered', enr: ENR): boolean;
189
203
 
204
+ on(event: 'ip:changed', listener: (ip: string) => void): this;
205
+ emit(event: 'ip:changed', ip: string): boolean;
206
+
190
207
  getStatus(): PeerDiscoveryState;
191
208
 
192
209
  getEnr(): ENR | undefined;
@@ -1,12 +1,9 @@
1
1
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { times } from '@aztec/foundation/collection';
3
- import { AbortError, TimeoutError } from '@aztec/foundation/error';
4
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
5
- import { promiseWithResolvers } from '@aztec/foundation/promise';
6
4
  import { sleep } from '@aztec/foundation/sleep';
7
5
  import { DateProvider, elapsed } from '@aztec/foundation/timer';
8
6
  import type { L2BlockInfo } from '@aztec/stdlib/block';
9
- import type { BlockProposal } from '@aztec/stdlib/p2p';
10
7
  import { type Tx, TxHash } from '@aztec/stdlib/tx';
11
8
 
12
9
  import type { PeerId } from '@libp2p/interface';
@@ -19,6 +16,7 @@ import {
19
16
  type MissingTxsCollector,
20
17
  SendBatchRequestCollector,
21
18
  } from './proposal_tx_collector.js';
19
+ import { RequestTracker } from './request_tracker.js';
22
20
  import type { FastCollectionRequest, FastCollectionRequestInput } from './tx_collection.js';
23
21
  import type { TxAddContext, TxCollectionSink } from './tx_collection_sink.js';
24
22
  import type { TxSource } from './tx_source.js';
@@ -47,7 +45,9 @@ export class FastTxCollection {
47
45
  }
48
46
 
49
47
  public async stop() {
50
- this.requests.forEach(request => request.promise.reject(new AbortError(`Stopped collection service`)));
48
+ this.requests.forEach(request => {
49
+ request.requestTracker.cancel();
50
+ });
51
51
  await Promise.resolve();
52
52
  }
53
53
 
@@ -74,82 +74,65 @@ export class FastTxCollection {
74
74
  ? { ...input.blockProposal.toBlockInfo(), blockNumber: input.blockNumber }
75
75
  : { ...input.block.toBlockInfo() };
76
76
 
77
- // This promise is used to await for the collection to finish during the main collectFast method.
78
- // It gets resolved in `foundTxs` when all txs have been collected, or rejected if the request is aborted or hits the deadline.
79
- const promise = promiseWithResolvers<void>();
80
- const timeoutTimer = setTimeout(() => promise.reject(new TimeoutError(`Timed out while collecting txs`)), timeout);
81
-
82
77
  const request: FastCollectionRequest = {
83
78
  ...input,
84
79
  blockInfo,
85
- promise,
86
- foundTxs: new Map<string, Tx>(),
87
- missingTxHashes: new Set(txHashes.map(t => t.toString())),
88
- deadline: opts.deadline,
80
+ requestTracker: RequestTracker.create(txHashes, opts.deadline, this.dateProvider),
89
81
  };
90
82
 
91
83
  const [duration] = await elapsed(() => this.collectFast(request, { ...opts }));
92
- clearTimeout(timeoutTimer);
93
84
 
94
85
  this.log.verbose(
95
- `Collected ${request.foundTxs.size} txs out of ${txHashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`,
86
+ `Collected ${request.requestTracker.collectedTxs.length} txs out of ${txHashes.length} for ${input.type} at slot ${blockInfo.slotNumber}`,
96
87
  {
97
88
  ...blockInfo,
98
89
  duration,
99
90
  requestType: input.type,
100
- missingTxs: [...request.missingTxHashes],
91
+ missingTxs: [...request.requestTracker.missingTxHashes],
101
92
  },
102
93
  );
103
- return [...request.foundTxs.values()];
94
+ return request.requestTracker.collectedTxs;
104
95
  }
105
96
 
106
- protected async collectFast(
107
- request: FastCollectionRequest,
108
- opts: { proposal?: BlockProposal; deadline: Date; pinnedPeer?: PeerId },
109
- ) {
97
+ protected async collectFast(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) {
110
98
  this.requests.add(request);
111
99
  const { blockInfo } = request;
112
100
 
113
101
  this.log.debug(
114
- `Starting fast collection of ${request.missingTxHashes.size} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
115
- { ...blockInfo, requestType: request.type, deadline: opts.deadline },
102
+ `Starting fast collection of ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
103
+ { ...blockInfo, requestType: request.type, deadline: request.requestTracker.deadline },
116
104
  );
117
105
 
118
106
  try {
119
107
  // Start blasting all nodes for the txs. We give them a little time to respond before we start reqresp.
120
- // And keep an eye on the request promise to ensure we don't wait longer than the deadline or return as soon
121
- // as we have collected all txs, whatever the source.
122
- const nodeCollectionPromise = this.collectFastFromNodes(request, opts);
108
+ // We race against the cancellation token to exit as soon as all txs are collected, the deadline expires,
109
+ // or the request is externally cancelled.
110
+ const nodeCollectionPromise = this.collectFastFromNodes(request);
123
111
  const waitBeforeReqResp = sleep(this.config.txCollectionFastNodesTimeoutBeforeReqRespMs);
124
- await Promise.race([request.promise.promise, waitBeforeReqResp]);
112
+ await Promise.race([request.requestTracker.cancellationToken, waitBeforeReqResp]);
125
113
 
126
- // If we have collected all txs, we can stop here
127
- if (request.missingTxHashes.size === 0) {
128
- this.log.debug(`All txs collected for slot ${blockInfo.slotNumber} without reqresp`, blockInfo);
114
+ // If we have collected all txs or the request was cancelled, we can stop here.
115
+ // Wait for node collection to settle so inner tasks finish before we return.
116
+ if (request.requestTracker.checkCancelled()) {
117
+ if (request.requestTracker.allFetched()) {
118
+ this.log.debug(`All txs collected for slot ${blockInfo.slotNumber} without reqresp`, blockInfo);
119
+ }
120
+ await nodeCollectionPromise;
129
121
  return;
130
122
  }
131
123
 
132
124
  // Start blasting reqresp for the remaining txs. Note that node collection keeps running in parallel.
133
125
  // We stop when we have collected all txs, timed out, or both node collection and reqresp have given up.
134
- const collectionPromise = Promise.allSettled([this.collectFastViaReqResp(request, opts), nodeCollectionPromise]);
135
- await Promise.race([collectionPromise, request.promise.promise]);
126
+ // Inner tasks observe requestTracker.checkCancelled() and stop themselves, so this settles shortly after cancellation.
127
+ await Promise.allSettled([this.collectFastViaReqResp(request, opts), nodeCollectionPromise]);
136
128
  } catch (err) {
137
- // Log and swallow all errors
138
- const logCtx = {
129
+ this.log.error(`Error collecting txs for ${request.type} for slot ${blockInfo.slotNumber}`, err, {
139
130
  ...blockInfo,
140
- errorMessage: err instanceof Error ? err.message : undefined,
141
- missingTxs: [...request.missingTxHashes].map(txHash => txHash.toString()),
142
- };
143
- if (err instanceof Error && err.name === 'TimeoutError') {
144
- this.log.warn(`Timed out collecting txs for ${request.type} at slot ${blockInfo.slotNumber}`, logCtx);
145
- } else if (err instanceof Error && err.name === 'AbortError') {
146
- this.log.warn(`Aborted collecting txs for ${request.type} at slot ${blockInfo.slotNumber}`, logCtx);
147
- } else {
148
- this.log.error(`Error collecting txs for ${request.type} for slot ${blockInfo.slotNumber}`, err, logCtx);
149
- }
131
+ missingTxs: request.requestTracker.missingTxHashes.values().map(txHash => txHash.toString()),
132
+ });
150
133
  } finally {
151
134
  // Ensure no unresolved promises and remove the request from the set
152
- request.promise.resolve();
135
+ request.requestTracker.cancel();
153
136
  this.requests.delete(request);
154
137
  }
155
138
  }
@@ -160,26 +143,28 @@ export class FastTxCollection {
160
143
  * the txs that have been requested less often whenever we need to send a new batch of requests. We ensure that no
161
144
  * tx is requested more than once at the same time to the same node.
162
145
  */
163
- private async collectFastFromNodes(request: FastCollectionRequest, opts: { deadline: Date }): Promise<void> {
146
+ private async collectFastFromNodes(request: FastCollectionRequest): Promise<void> {
164
147
  if (this.nodes.length === 0) {
165
148
  return;
166
149
  }
167
150
 
168
151
  // Keep a shared priority queue of all txs pending to be requested, sorted by the number of attempts made to collect them.
169
- const attemptsPerTx = [...request.missingTxHashes].map(txHash => ({ txHash, attempts: 0, found: false }));
152
+ const attemptsPerTx = [...request.requestTracker.missingTxHashes].map(txHash => ({
153
+ txHash,
154
+ attempts: 0,
155
+ found: false,
156
+ }));
170
157
 
171
158
  // Returns once we have finished all node loops. Each loop finishes when the deadline is hit, or all txs have been collected.
172
- await Promise.allSettled(this.nodes.map(node => this.collectFastFromNode(request, node, attemptsPerTx, opts)));
159
+ await Promise.allSettled(this.nodes.map(node => this.collectFastFromNode(request, node, attemptsPerTx)));
173
160
  }
174
161
 
175
162
  private async collectFastFromNode(
176
163
  request: FastCollectionRequest,
177
164
  node: TxSource,
178
165
  attemptsPerTx: { txHash: string; attempts: number; found: boolean }[],
179
- opts: { deadline: Date },
180
166
  ) {
181
- const notFinished = () =>
182
- this.dateProvider.now() <= +opts.deadline && request.missingTxHashes.size > 0 && this.requests.has(request);
167
+ const notFinished = () => !request.requestTracker.checkCancelled();
183
168
 
184
169
  const maxParallelRequests = this.config.txCollectionFastMaxParallelRequestsPerNode;
185
170
  const maxBatchSize = this.config.txCollectionNodeRpcMaxBatchSize;
@@ -196,7 +181,7 @@ export class FastTxCollection {
196
181
  if (!txToRequest) {
197
182
  // No more txs to process
198
183
  break;
199
- } else if (!request.missingTxHashes.has(txToRequest.txHash)) {
184
+ } else if (!request.requestTracker.isMissing(txToRequest.txHash)) {
200
185
  // Mark as found if it was found somewhere else, we'll then remove it from the array.
201
186
  // We don't delete it now since 'array.splice' is pretty expensive, so we do it after sorting.
202
187
  txToRequest.found = true;
@@ -225,10 +210,17 @@ export class FastTxCollection {
225
210
  return;
226
211
  }
227
212
 
213
+ const txHashes = batch.map(({ txHash }) => txHash);
228
214
  // Collect this batch from the node
229
215
  await this.txCollectionSink.collect(
230
- txHashes => node.getTxsByHash(txHashes),
231
- batch.map(({ txHash }) => TxHash.fromString(txHash)),
216
+ async () => {
217
+ const result = await node.getTxsByHash(txHashes.map(TxHash.fromString));
218
+ for (const tx of result.validTxs) {
219
+ request.requestTracker.markFetched(tx);
220
+ }
221
+ return result;
222
+ },
223
+ txHashes,
232
224
  {
233
225
  description: `fast ${node.getInfo()}`,
234
226
  node: node.getInfo(),
@@ -243,9 +235,12 @@ export class FastTxCollection {
243
235
  activeRequestsToThisNode.delete(requestedTx.txHash);
244
236
  }
245
237
 
246
- // Sleep a bit until hitting the node again (or not, depending on config)
238
+ // Sleep a bit until hitting the node again, but wake up immediately on cancellation
247
239
  if (notFinished()) {
248
- await sleep(this.config.txCollectionFastNodeIntervalMs);
240
+ await Promise.race([
241
+ sleep(this.config.txCollectionFastNodeIntervalMs),
242
+ request.requestTracker.cancellationToken,
243
+ ]);
249
244
  }
250
245
  }
251
246
  };
@@ -255,45 +250,50 @@ export class FastTxCollection {
255
250
  }
256
251
 
257
252
  private async collectFastViaReqResp(request: FastCollectionRequest, opts: { pinnedPeer?: PeerId }) {
258
- const timeoutMs = +request.deadline - this.dateProvider.now();
259
253
  const pinnedPeer = opts.pinnedPeer;
260
254
  const blockInfo = request.blockInfo;
261
255
  const slotNumber = blockInfo.slotNumber;
262
- if (timeoutMs < 100) {
256
+ if (request.requestTracker.timeoutMs < 100) {
263
257
  this.log.warn(
264
258
  `Not initiating fast reqresp for txs for ${request.type} at slot ${blockInfo.slotNumber} due to timeout`,
265
- { timeoutMs, ...blockInfo },
259
+ { timeoutMs: request.requestTracker.timeoutMs, ...blockInfo },
266
260
  );
267
261
  return;
268
262
  }
269
263
 
270
264
  this.log.debug(
271
- `Starting fast reqresp for ${request.missingTxHashes.size} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
272
- { ...blockInfo, timeoutMs, pinnedPeer },
265
+ `Starting fast reqresp for ${request.requestTracker.numberOfMissingTxs} txs for ${request.type} at slot ${blockInfo.slotNumber}`,
266
+ { ...blockInfo, timeoutMs: request.requestTracker.timeoutMs, pinnedPeer },
273
267
  );
274
268
 
275
269
  try {
276
270
  await this.txCollectionSink.collect(
277
- async txHashes => {
271
+ async () => {
272
+ let result: Tx[];
278
273
  if (request.type === 'proposal') {
279
- return await this.missingTxsCollector.collectTxs(txHashes, request.blockProposal, pinnedPeer, timeoutMs);
274
+ result = await this.missingTxsCollector.collectTxs(
275
+ request.requestTracker,
276
+ request.blockProposal,
277
+ pinnedPeer,
278
+ );
280
279
  } else if (request.type === 'block') {
281
280
  const blockTxsSource = {
282
281
  txHashes: request.block.body.txEffects.map(e => e.txHash),
283
282
  archive: request.block.archive.root,
284
283
  };
285
- return await this.missingTxsCollector.collectTxs(txHashes, blockTxsSource, pinnedPeer, timeoutMs);
284
+ result = await this.missingTxsCollector.collectTxs(request.requestTracker, blockTxsSource, pinnedPeer);
286
285
  } else {
287
286
  throw new Error(`Unknown request type: ${(request as any).type}`);
288
287
  }
288
+ return { validTxs: result, invalidTxHashes: [] };
289
289
  },
290
- Array.from(request.missingTxHashes).map(txHash => TxHash.fromString(txHash)),
290
+ Array.from(request.requestTracker.missingTxHashes),
291
291
  { description: `reqresp for slot ${slotNumber}`, method: 'fast-req-resp', ...opts, ...request.blockInfo },
292
292
  this.getAddContext(request),
293
293
  );
294
294
  } catch (err) {
295
295
  this.log.error(`Error sending fast reqresp request for txs`, err, {
296
- txs: [...request.missingTxHashes],
296
+ txs: [...request.requestTracker.missingTxHashes],
297
297
  ...blockInfo,
298
298
  });
299
299
  }
@@ -317,21 +317,18 @@ export class FastTxCollection {
317
317
  for (const tx of txs) {
318
318
  const txHash = tx.txHash.toString();
319
319
  // Remove the tx hash from the missing set, and add it to the found set.
320
- if (request.missingTxHashes.has(txHash)) {
321
- request.missingTxHashes.delete(txHash);
322
- request.foundTxs.set(txHash, tx);
320
+ if (request.requestTracker.markFetched(tx)) {
323
321
  this.log.trace(`Found tx ${txHash} for fast collection request`, {
324
322
  ...request.blockInfo,
325
323
  txHash: tx.txHash.toString(),
326
324
  type: request.type,
327
325
  });
328
- // If we found all txs for this request, we resolve the promise
329
- if (request.missingTxHashes.size === 0) {
326
+ if (request.requestTracker.allFetched()) {
330
327
  this.log.trace(`All txs found for fast collection request`, {
331
328
  ...request.blockInfo,
332
329
  type: request.type,
333
330
  });
334
- request.promise.resolve();
331
+ break;
335
332
  }
336
333
  }
337
334
  }
@@ -345,8 +342,7 @@ export class FastTxCollection {
345
342
  public stopCollectingForBlocksUpTo(blockNumber: BlockNumber): void {
346
343
  for (const request of this.requests) {
347
344
  if (request.blockInfo.blockNumber <= blockNumber) {
348
- request.promise.reject(new AbortError(`Stopped collecting txs up to block ${blockNumber}`));
349
- this.requests.delete(request);
345
+ request.requestTracker.cancel();
350
346
  }
351
347
  }
352
348
  }
@@ -358,8 +354,7 @@ export class FastTxCollection {
358
354
  public stopCollectingForBlocksAfter(blockNumber: BlockNumber): void {
359
355
  for (const request of this.requests) {
360
356
  if (request.blockInfo.blockNumber > blockNumber) {
361
- request.promise.reject(new AbortError(`Stopped collecting txs after block ${blockNumber}`));
362
- this.requests.delete(request);
357
+ request.requestTracker.cancel();
363
358
  }
364
359
  }
365
360
  }