@aztec/p2p 0.0.1-commit.1142ef1 → 0.0.1-commit.1a99e26c

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 (288) hide show
  1. package/dest/bootstrap/bootstrap.d.ts +4 -3
  2. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  3. package/dest/bootstrap/bootstrap.js +4 -4
  4. package/dest/client/factory.d.ts +1 -1
  5. package/dest/client/factory.d.ts.map +1 -1
  6. package/dest/client/factory.js +6 -5
  7. package/dest/client/p2p_client.js +1 -1
  8. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +2 -0
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +1 -0
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +305 -0
  11. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +73 -0
  12. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +1 -0
  13. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +8 -0
  14. package/dest/config.d.ts +8 -2
  15. package/dest/config.d.ts.map +1 -1
  16. package/dest/config.js +4 -2
  17. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  18. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  19. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +20 -9
  20. package/dest/mem_pools/attestation_pool/mocks.d.ts +4 -2
  21. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  22. package/dest/mem_pools/attestation_pool/mocks.js +8 -5
  23. package/dest/mem_pools/instrumentation.d.ts +1 -1
  24. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  25. package/dest/mem_pools/instrumentation.js +2 -2
  26. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +15 -10
  27. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +91 -50
  29. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +19 -5
  30. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +59 -3
  32. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +79 -5
  33. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +47 -0
  35. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
  36. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  37. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +122 -0
  38. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +2 -2
  39. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +4 -4
  41. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
  42. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +2 -0
  43. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +2 -2
  44. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  45. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
  46. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
  47. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
  48. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +3 -3
  49. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  50. package/dest/msg_validators/attestation_validator/attestation_validator.js +41 -10
  51. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -3
  52. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  53. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +18 -6
  54. package/dest/msg_validators/clock_tolerance.d.ts +21 -0
  55. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -0
  56. package/dest/msg_validators/clock_tolerance.js +37 -0
  57. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -3
  58. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  59. package/dest/msg_validators/proposal_validator/proposal_validator.js +55 -31
  60. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +3 -3
  61. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -1
  62. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +93 -64
  63. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +3 -2
  64. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  65. package/dest/msg_validators/tx_validator/block_header_validator.js +4 -3
  66. package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
  67. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  68. package/dest/msg_validators/tx_validator/data_validator.js +4 -1
  69. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +3 -2
  70. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  71. package/dest/msg_validators/tx_validator/double_spend_validator.js +3 -2
  72. package/dest/msg_validators/tx_validator/factory.d.ts +8 -3
  73. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  74. package/dest/msg_validators/tx_validator/factory.js +21 -11
  75. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
  76. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
  77. package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
  78. package/dest/msg_validators/tx_validator/gas_validator.d.ts +3 -2
  79. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  80. package/dest/msg_validators/tx_validator/gas_validator.js +11 -16
  81. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  82. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  83. package/dest/msg_validators/tx_validator/index.js +1 -0
  84. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
  85. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  86. package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
  87. package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
  88. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  89. package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
  90. package/dest/msg_validators/tx_validator/size_validator.d.ts +8 -0
  91. package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
  92. package/dest/msg_validators/tx_validator/size_validator.js +23 -0
  93. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
  94. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/timestamp_validator.js +2 -2
  96. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
  97. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
  99. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
  100. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -2
  102. package/dest/services/discv5/discV5_service.js +1 -1
  103. package/dest/services/dummy_service.d.ts +13 -1
  104. package/dest/services/dummy_service.d.ts.map +1 -1
  105. package/dest/services/dummy_service.js +39 -0
  106. package/dest/services/encoding.d.ts +1 -1
  107. package/dest/services/encoding.d.ts.map +1 -1
  108. package/dest/services/encoding.js +2 -3
  109. package/dest/services/libp2p/instrumentation.d.ts +1 -1
  110. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  111. package/dest/services/libp2p/instrumentation.js +19 -8
  112. package/dest/services/libp2p/libp2p_service.d.ts +13 -7
  113. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  114. package/dest/services/libp2p/libp2p_service.js +55 -46
  115. package/dest/services/peer-manager/metrics.d.ts +2 -2
  116. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  117. package/dest/services/peer-manager/metrics.js +20 -5
  118. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  119. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  120. package/dest/services/peer-manager/peer_scoring.js +8 -2
  121. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +47 -0
  122. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
  123. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +566 -0
  124. package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
  125. package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
  126. package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
  127. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +50 -0
  128. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
  129. package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
  130. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +37 -0
  131. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
  132. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +151 -0
  133. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +54 -0
  134. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
  135. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +139 -0
  136. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
  137. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
  138. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
  139. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
  140. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
  141. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
  142. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
  143. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  144. package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
  145. package/dest/services/reqresp/constants.d.ts +12 -0
  146. package/dest/services/reqresp/constants.d.ts.map +1 -0
  147. package/dest/services/reqresp/constants.js +7 -0
  148. package/dest/services/reqresp/interface.d.ts +3 -1
  149. package/dest/services/reqresp/interface.d.ts.map +1 -1
  150. package/dest/services/reqresp/metrics.d.ts +6 -5
  151. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  152. package/dest/services/reqresp/metrics.js +17 -5
  153. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
  154. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  155. package/dest/services/reqresp/protocols/block_txs/bitvector.js +12 -0
  156. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  157. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  158. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +14 -1
  159. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +15 -3
  160. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  161. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +33 -3
  162. package/dest/services/reqresp/protocols/status.d.ts +1 -1
  163. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  164. package/dest/services/reqresp/protocols/status.js +2 -1
  165. package/dest/services/reqresp/reqresp.d.ts +6 -1
  166. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  167. package/dest/services/reqresp/reqresp.js +58 -22
  168. package/dest/services/service.d.ts +4 -1
  169. package/dest/services/service.d.ts.map +1 -1
  170. package/dest/services/tx_collection/config.d.ts +4 -1
  171. package/dest/services/tx_collection/config.d.ts.map +1 -1
  172. package/dest/services/tx_collection/config.js +9 -1
  173. package/dest/services/tx_collection/fast_tx_collection.d.ts +6 -4
  174. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  175. package/dest/services/tx_collection/fast_tx_collection.js +16 -5
  176. package/dest/services/tx_collection/index.d.ts +2 -1
  177. package/dest/services/tx_collection/index.d.ts.map +1 -1
  178. package/dest/services/tx_collection/index.js +1 -0
  179. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  180. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  181. package/dest/services/tx_collection/instrumentation.js +9 -2
  182. package/dest/services/tx_collection/proposal_tx_collector.d.ts +48 -0
  183. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
  184. package/dest/services/tx_collection/proposal_tx_collector.js +50 -0
  185. package/dest/services/tx_collection/slow_tx_collection.d.ts +3 -3
  186. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  187. package/dest/services/tx_collection/tx_collection.d.ts +8 -8
  188. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  189. package/dest/services/tx_collection/tx_collection.js +5 -5
  190. package/dest/services/tx_provider.d.ts +3 -3
  191. package/dest/services/tx_provider.d.ts.map +1 -1
  192. package/dest/services/tx_provider_instrumentation.d.ts +1 -1
  193. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  194. package/dest/services/tx_provider_instrumentation.js +5 -5
  195. package/dest/test-helpers/index.d.ts +3 -1
  196. package/dest/test-helpers/index.d.ts.map +1 -1
  197. package/dest/test-helpers/index.js +2 -0
  198. package/dest/test-helpers/test_tx_provider.d.ts +40 -0
  199. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
  200. package/dest/test-helpers/test_tx_provider.js +41 -0
  201. package/dest/test-helpers/testbench-utils.d.ts +156 -0
  202. package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
  203. package/dest/test-helpers/testbench-utils.js +296 -0
  204. package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
  205. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  206. package/dest/testbench/p2p_client_testbench_worker.js +212 -132
  207. package/dest/testbench/worker_client_manager.d.ts +51 -6
  208. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  209. package/dest/testbench/worker_client_manager.js +226 -44
  210. package/package.json +16 -16
  211. package/src/bootstrap/bootstrap.ts +7 -4
  212. package/src/client/factory.ts +6 -10
  213. package/src/client/p2p_client.ts +6 -6
  214. package/src/client/test/tx_proposal_collector/README.md +227 -0
  215. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +336 -0
  216. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
  217. package/src/config.ts +8 -3
  218. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +17 -9
  219. package/src/mem_pools/attestation_pool/mocks.ts +6 -4
  220. package/src/mem_pools/instrumentation.ts +2 -1
  221. package/src/mem_pools/tx_pool/README.md +28 -13
  222. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +130 -75
  223. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +66 -5
  224. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +119 -4
  225. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +162 -0
  226. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +4 -2
  227. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
  228. package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -14
  229. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +14 -8
  230. package/src/msg_validators/clock_tolerance.ts +51 -0
  231. package/src/msg_validators/proposal_validator/proposal_validator.ts +31 -31
  232. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +91 -67
  233. package/src/msg_validators/tx_validator/block_header_validator.ts +7 -4
  234. package/src/msg_validators/tx_validator/data_validator.ts +6 -2
  235. package/src/msg_validators/tx_validator/double_spend_validator.ts +4 -3
  236. package/src/msg_validators/tx_validator/factory.ts +64 -23
  237. package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
  238. package/src/msg_validators/tx_validator/gas_validator.ts +17 -28
  239. package/src/msg_validators/tx_validator/index.ts +1 -0
  240. package/src/msg_validators/tx_validator/metadata_validator.ts +6 -3
  241. package/src/msg_validators/tx_validator/phases_validator.ts +5 -3
  242. package/src/msg_validators/tx_validator/size_validator.ts +22 -0
  243. package/src/msg_validators/tx_validator/timestamp_validator.ts +6 -3
  244. package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
  245. package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
  246. package/src/services/discv5/discV5_service.ts +1 -1
  247. package/src/services/dummy_service.ts +45 -0
  248. package/src/services/encoding.ts +2 -3
  249. package/src/services/libp2p/instrumentation.ts +20 -7
  250. package/src/services/libp2p/libp2p_service.ts +92 -66
  251. package/src/services/peer-manager/metrics.ts +21 -4
  252. package/src/services/peer-manager/peer_scoring.ts +4 -1
  253. package/src/services/reqresp/batch-tx-requester/README.md +305 -0
  254. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +706 -0
  255. package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
  256. package/src/services/reqresp/batch-tx-requester/interface.ts +57 -0
  257. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +209 -0
  258. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +205 -0
  259. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
  260. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
  261. package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
  262. package/src/services/reqresp/constants.ts +14 -0
  263. package/src/services/reqresp/interface.ts +3 -0
  264. package/src/services/reqresp/metrics.ts +34 -9
  265. package/src/services/reqresp/protocols/block_txs/bitvector.ts +16 -0
  266. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +16 -2
  267. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +46 -4
  268. package/src/services/reqresp/protocols/status.ts +5 -3
  269. package/src/services/reqresp/reqresp.ts +66 -19
  270. package/src/services/service.ts +4 -0
  271. package/src/services/tx_collection/config.ts +15 -1
  272. package/src/services/tx_collection/fast_tx_collection.ts +36 -13
  273. package/src/services/tx_collection/index.ts +5 -0
  274. package/src/services/tx_collection/instrumentation.ts +11 -2
  275. package/src/services/tx_collection/proposal_tx_collector.ts +114 -0
  276. package/src/services/tx_collection/slow_tx_collection.ts +2 -2
  277. package/src/services/tx_collection/tx_collection.ts +8 -8
  278. package/src/services/tx_provider.ts +2 -2
  279. package/src/services/tx_provider_instrumentation.ts +11 -5
  280. package/src/test-helpers/index.ts +2 -0
  281. package/src/test-helpers/test_tx_provider.ts +64 -0
  282. package/src/test-helpers/testbench-utils.ts +372 -0
  283. package/src/testbench/p2p_client_testbench_worker.ts +321 -126
  284. package/src/testbench/worker_client_manager.ts +304 -47
  285. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +0 -15
  286. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +0 -1
  287. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +0 -88
  288. package/src/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.ts +0 -108
@@ -0,0 +1,114 @@
1
+ import type { Logger } from '@aztec/foundation/log';
2
+ import type { DateProvider } from '@aztec/foundation/timer';
3
+ import type { BlockProposal } from '@aztec/stdlib/p2p';
4
+ import type { Tx, TxHash } from '@aztec/stdlib/tx';
5
+
6
+ import type { PeerId } from '@libp2p/interface';
7
+
8
+ import { BatchTxRequester } from '../reqresp/batch-tx-requester/batch_tx_requester.js';
9
+ import type { BatchTxRequesterConfig } from '../reqresp/batch-tx-requester/config.js';
10
+ import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
11
+ import type { IBatchRequestTxValidator } from '../reqresp/batch-tx-requester/tx_validator.js';
12
+ import { ReqRespSubProtocol } from '../reqresp/interface.js';
13
+ import { chunkTxHashesRequest } from '../reqresp/protocols/tx.js';
14
+
15
+ /**
16
+ * Strategy interface for collecting transactions for block proposals.
17
+ * Allows swapping between different tx collection implementations for benchmarking.
18
+ */
19
+ export interface ProposalTxCollector {
20
+ /**
21
+ * Collect transactions for a block proposal.
22
+ * @param txHashes - The transaction hashes to collect
23
+ * @param blockProposal - The block proposal containing the transactions
24
+ * @param pinnedPeer - Optional peer that sent the proposal (expected to have all txs)
25
+ * @param timeoutMs - Timeout in milliseconds
26
+ * @returns The collected transactions
27
+ */
28
+ collectTxs(
29
+ txHashes: TxHash[],
30
+ blockProposal: BlockProposal,
31
+ pinnedPeer: PeerId | undefined,
32
+ timeoutMs: number,
33
+ ): Promise<Tx[]>;
34
+ }
35
+
36
+ /**
37
+ * Collects transactions using the BatchTxRequester implementation.
38
+ * This uses a smart/dumb peer strategy with parallel workers.
39
+ */
40
+ export class BatchTxRequesterCollector implements ProposalTxCollector {
41
+ constructor(
42
+ private p2pService: BatchTxRequesterLibP2PService,
43
+ private log: Logger,
44
+ private dateProvider: DateProvider,
45
+ private txValidator?: IBatchRequestTxValidator,
46
+ private batchTxRequesterConfig?: Partial<BatchTxRequesterConfig>,
47
+ ) {}
48
+
49
+ async collectTxs(
50
+ txHashes: TxHash[],
51
+ blockProposal: BlockProposal,
52
+ pinnedPeer: PeerId | undefined,
53
+ timeoutMs: number,
54
+ ): Promise<Tx[]> {
55
+ const {
56
+ batchTxRequesterSmartParallelWorkerCount: smartParallelWorkerCount,
57
+ batchTxRequesterDumbParallelWorkerCount: dumbParallelWorkerCount,
58
+ batchTxRequesterTxBatchSize: txBatchSize,
59
+ batchTxRequesterBadPeerThreshold: badPeerThreshold,
60
+ } = this.batchTxRequesterConfig ?? {};
61
+
62
+ const batchRequester = new BatchTxRequester(
63
+ txHashes,
64
+ blockProposal,
65
+ pinnedPeer,
66
+ timeoutMs,
67
+ this.p2pService,
68
+ this.log,
69
+ this.dateProvider,
70
+ {
71
+ smartParallelWorkerCount,
72
+ dumbParallelWorkerCount,
73
+ txBatchSize,
74
+ badPeerThreshold,
75
+ txValidator: this.txValidator,
76
+ },
77
+ );
78
+
79
+ return await BatchTxRequester.collectAllTxs(batchRequester.run());
80
+ }
81
+ }
82
+
83
+ const DEFAULT_MAX_PEERS = 10;
84
+ const DEFAULT_MAX_RETRY_ATTEMPTS = 3;
85
+
86
+ /**
87
+ * Collects transactions using the sendBatchRequest implementation from ReqResp.
88
+ * This is the original implementation that balances requests across peers.
89
+ */
90
+ export class SendBatchRequestCollector implements ProposalTxCollector {
91
+ constructor(
92
+ private p2pService: BatchTxRequesterLibP2PService,
93
+ private maxPeers: number = DEFAULT_MAX_PEERS,
94
+ private maxRetryAttempts: number = DEFAULT_MAX_RETRY_ATTEMPTS,
95
+ ) {}
96
+
97
+ async collectTxs(
98
+ txHashes: TxHash[],
99
+ _blockProposal: BlockProposal,
100
+ pinnedPeer: PeerId | undefined,
101
+ timeoutMs: number,
102
+ ): Promise<Tx[]> {
103
+ const txs = await this.p2pService.reqResp.sendBatchRequest<ReqRespSubProtocol.TX>(
104
+ ReqRespSubProtocol.TX,
105
+ chunkTxHashesRequest(txHashes),
106
+ pinnedPeer,
107
+ timeoutMs,
108
+ this.maxPeers,
109
+ this.maxRetryAttempts,
110
+ );
111
+
112
+ return txs.flat();
113
+ }
114
+ }
@@ -4,7 +4,7 @@ import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { boundInclusive } from '@aztec/foundation/number';
5
5
  import { RunningPromise } from '@aztec/foundation/promise';
6
6
  import { DateProvider } from '@aztec/foundation/timer';
7
- import type { L2BlockNew } from '@aztec/stdlib/block';
7
+ import type { L2Block } from '@aztec/stdlib/block';
8
8
  import { type L1RollupConstants, getEpochAtSlot, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
9
9
  import { type Tx, TxHash } from '@aztec/stdlib/tx';
10
10
 
@@ -76,7 +76,7 @@ export class SlowTxCollection {
76
76
  }
77
77
 
78
78
  /** Starts collecting the given tx hashes for the given L2Block in the slow loop */
79
- public startCollecting(block: L2BlockNew, txHashes: TxHash[]) {
79
+ public startCollecting(block: L2Block, txHashes: TxHash[]) {
80
80
  const slot = block.header.getSlot();
81
81
  const deadline = this.getDeadlineForSlot(slot);
82
82
  if (+deadline < this.dateProvider.now()) {
@@ -3,7 +3,7 @@ import { compactArray } from '@aztec/foundation/collection';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { type PromiseWithResolvers, RunningPromise } from '@aztec/foundation/promise';
5
5
  import { DateProvider } from '@aztec/foundation/timer';
6
- import type { L2BlockInfo, L2BlockNew } from '@aztec/stdlib/block';
6
+ import type { L2Block, L2BlockInfo } from '@aztec/stdlib/block';
7
7
  import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
8
8
  import type { BlockProposal } from '@aztec/stdlib/p2p';
9
9
  import { Tx, TxHash } from '@aztec/stdlib/tx';
@@ -13,7 +13,7 @@ import type { PeerId } from '@libp2p/interface';
13
13
 
14
14
  import type { TxPool } from '../../mem_pools/index.js';
15
15
  import type { TxPoolEvents } from '../../mem_pools/tx_pool/tx_pool.js';
16
- import type { ReqRespInterface } from '../reqresp/interface.js';
16
+ import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
17
17
  import type { TxCollectionConfig } from './config.js';
18
18
  import { FastTxCollection } from './fast_tx_collection.js';
19
19
  import { SlowTxCollection } from './slow_tx_collection.js';
@@ -25,7 +25,7 @@ export type CollectionMethod = 'fast-req-resp' | 'fast-node-rpc' | 'slow-req-res
25
25
  export type MissingTxInfo = { blockNumber: BlockNumber; deadline: Date; readyForReqResp: boolean };
26
26
 
27
27
  export type FastCollectionRequestInput =
28
- | { type: 'block'; block: L2BlockNew }
28
+ | { type: 'block'; block: L2Block }
29
29
  | { type: 'proposal'; blockProposal: BlockProposal; blockNumber: BlockNumber };
30
30
 
31
31
  export type FastCollectionRequest = FastCollectionRequestInput & {
@@ -67,7 +67,7 @@ export class TxCollection {
67
67
  protected readonly handleTxsFound: TxPoolEvents['txs-added'];
68
68
 
69
69
  constructor(
70
- private readonly reqResp: Pick<ReqRespInterface, 'sendBatchRequest'>,
70
+ private readonly p2pService: BatchTxRequesterLibP2PService,
71
71
  private readonly nodes: TxSource[],
72
72
  private readonly constants: L1RollupConstants,
73
73
  private readonly txPool: TxPool,
@@ -79,7 +79,7 @@ export class TxCollection {
79
79
  this.txCollectionSink = new TxCollectionSink(this.txPool, telemetryClient, this.log);
80
80
 
81
81
  this.fastCollection = new FastTxCollection(
82
- this.reqResp,
82
+ this.p2pService,
83
83
  this.nodes,
84
84
  this.txCollectionSink,
85
85
  this.config,
@@ -88,7 +88,7 @@ export class TxCollection {
88
88
  );
89
89
 
90
90
  this.slowCollection = new SlowTxCollection(
91
- this.reqResp,
91
+ this.p2pService.reqResp,
92
92
  this.nodes,
93
93
  this.txCollectionSink,
94
94
  this.fastCollection,
@@ -146,7 +146,7 @@ export class TxCollection {
146
146
  }
147
147
 
148
148
  /** Starts collecting the given tx hashes for the given L2Block in the slow loop */
149
- public startCollecting(block: L2BlockNew, txHashes: TxHash[]) {
149
+ public startCollecting(block: L2Block, txHashes: TxHash[]) {
150
150
  return this.slowCollection.startCollecting(block, txHashes);
151
151
  }
152
152
 
@@ -162,7 +162,7 @@ export class TxCollection {
162
162
 
163
163
  /** Collects the set of txs for the given mined block as fast as possible */
164
164
  public collectFastForBlock(
165
- block: L2BlockNew,
165
+ block: L2Block,
166
166
  txHashes: TxHash[] | string[],
167
167
  opts: { deadline: Date; pinnedPeer?: PeerId },
168
168
  ) {
@@ -2,7 +2,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { compactArray } from '@aztec/foundation/collection';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { elapsed } from '@aztec/foundation/timer';
5
- import type { L2BlockInfo, L2BlockNew } from '@aztec/stdlib/block';
5
+ import type { L2Block, L2BlockInfo } from '@aztec/stdlib/block';
6
6
  import type { ITxProvider } from '@aztec/stdlib/interfaces/server';
7
7
  import type { BlockProposal } from '@aztec/stdlib/p2p';
8
8
  import { Tx, TxHash } from '@aztec/stdlib/tx';
@@ -68,7 +68,7 @@ export class TxProvider implements ITxProvider {
68
68
  }
69
69
 
70
70
  /** Gathers txs from the tx pool, remote rpc nodes, and reqresp. */
71
- public getTxsForBlock(block: L2BlockNew, opts: { deadline: Date }): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> {
71
+ public getTxsForBlock(block: L2Block, opts: { deadline: Date }): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> {
72
72
  return this.getOrderedTxsFromAllSources(
73
73
  { type: 'block', block },
74
74
  block.toBlockInfo(),
@@ -1,4 +1,10 @@
1
- import { type Histogram, Metrics, type TelemetryClient, type UpDownCounter } from '@aztec/telemetry-client';
1
+ import {
2
+ type Histogram,
3
+ Metrics,
4
+ type TelemetryClient,
5
+ type UpDownCounter,
6
+ createUpDownCounterWithDefault,
7
+ } from '@aztec/telemetry-client';
2
8
 
3
9
  export class TxProviderInstrumentation {
4
10
  private txFromProposalCount: UpDownCounter;
@@ -12,13 +18,13 @@ export class TxProviderInstrumentation {
12
18
  constructor(client: TelemetryClient, name: string) {
13
19
  const meter = client.getMeter(name);
14
20
 
15
- this.txFromProposalCount = meter.createUpDownCounter(Metrics.TX_PROVIDER_TXS_FROM_PROPOSALS_COUNT);
21
+ this.txFromProposalCount = createUpDownCounterWithDefault(meter, Metrics.TX_PROVIDER_TXS_FROM_PROPOSALS_COUNT);
16
22
 
17
- this.txFromMempoolCount = meter.createUpDownCounter(Metrics.TX_PROVIDER_TXS_FROM_MEMPOOL_COUNT);
23
+ this.txFromMempoolCount = createUpDownCounterWithDefault(meter, Metrics.TX_PROVIDER_TXS_FROM_MEMPOOL_COUNT);
18
24
 
19
- this.txFromP2PCount = meter.createUpDownCounter(Metrics.TX_PROVIDER_TXS_FROM_P2P_COUNT);
25
+ this.txFromP2PCount = createUpDownCounterWithDefault(meter, Metrics.TX_PROVIDER_TXS_FROM_P2P_COUNT);
20
26
 
21
- this.missingTxsCount = meter.createUpDownCounter(Metrics.TX_PROVIDER_MISSING_TXS_COUNT);
27
+ this.missingTxsCount = createUpDownCounterWithDefault(meter, Metrics.TX_PROVIDER_MISSING_TXS_COUNT);
22
28
 
23
29
  this.fractionOfTxsRequestedFromP2P = meter.createHistogram(Metrics.TX_PROVIDER_P2P_TXS_REQUESTED_FRACTION);
24
30
 
@@ -4,3 +4,5 @@ export * from './make-enrs.js';
4
4
  export * from './make-test-p2p-clients.js';
5
5
  export * from './reqresp-nodes.js';
6
6
  export * from './mock-pubsub.js';
7
+ export * from './test_tx_provider.js';
8
+ export * from './testbench-utils.js';
@@ -0,0 +1,64 @@
1
+ import type { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import type { L2Block } from '@aztec/stdlib/block';
3
+ import type { ITxProvider } from '@aztec/stdlib/interfaces/server';
4
+ import type { BlockProposal } from '@aztec/stdlib/p2p';
5
+ import { type Tx, TxHash } from '@aztec/stdlib/tx';
6
+
7
+ import type { PeerId } from '@libp2p/interface';
8
+
9
+ /**
10
+ * Test transaction provider that can be seeded with transactions.
11
+ * Returns seeded txs when requested by hash, useful for testing block
12
+ * proposal handling without requiring a full P2P network.
13
+ */
14
+ export class TestTxProvider implements ITxProvider {
15
+ private txs: Map<string, Tx> = new Map();
16
+
17
+ /** Seed transactions that will be returned when requested. */
18
+ seed(txs: Tx[]) {
19
+ for (const tx of txs) {
20
+ this.txs.set(tx.getTxHash().toString(), tx);
21
+ }
22
+ }
23
+
24
+ /** Clear all seeded transactions. */
25
+ clear() {
26
+ this.txs.clear();
27
+ }
28
+
29
+ /** Returns txs from the seeded collection given their hashes. */
30
+ getAvailableTxs(txHashes: TxHash[]): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> {
31
+ return this.getTxsByHashes(txHashes);
32
+ }
33
+
34
+ /** Get txs for a block proposal, returning any seeded txs that match the requested hashes. */
35
+ getTxsForBlockProposal(
36
+ blockProposal: BlockProposal,
37
+ _blockNumber: BlockNumber,
38
+ _opts: { pinnedPeer: PeerId | undefined; deadline: Date },
39
+ ): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> {
40
+ return this.getTxsByHashes(blockProposal.txHashes);
41
+ }
42
+
43
+ /** Get txs for a block, returning any seeded txs that match the tx effects in the block. */
44
+ getTxsForBlock(block: L2Block, _opts: { deadline: Date }): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> {
45
+ const txHashes = block.body.txEffects.map(txEffect => txEffect.txHash);
46
+ return this.getTxsByHashes(txHashes);
47
+ }
48
+
49
+ private getTxsByHashes(txHashes: TxHash[]): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> {
50
+ const txs: Tx[] = [];
51
+ const missingTxs: TxHash[] = [];
52
+
53
+ for (const txHash of txHashes) {
54
+ const tx = this.txs.get(txHash.toString());
55
+ if (tx) {
56
+ txs.push(tx);
57
+ } else {
58
+ missingTxs.push(txHash);
59
+ }
60
+ }
61
+
62
+ return Promise.resolve({ txs, missingTxs });
63
+ }
64
+ }
@@ -0,0 +1,372 @@
1
+ import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
+ import { type BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import type { Logger } from '@aztec/foundation/log';
4
+ import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
5
+ import type {
6
+ BlockProposal,
7
+ CheckpointAttestation,
8
+ CheckpointProposal,
9
+ CheckpointProposalCore,
10
+ } from '@aztec/stdlib/p2p';
11
+ import { type BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
12
+
13
+ import EventEmitter from 'events';
14
+
15
+ import type { AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js';
16
+ import type { TxPool } from '../mem_pools/tx_pool/index.js';
17
+ import { RateLimitStatus } from '../services/reqresp/rate-limiter/rate_limiter.js';
18
+
19
+ /**
20
+ * In-memory TxPool implementation for testing.
21
+ * Provides basic tx storage without persistence.
22
+ */
23
+ export class InMemoryTxPool extends EventEmitter implements TxPool {
24
+ private txsByHash = new Map<string, Tx>();
25
+ private logger: Logger | null = null;
26
+
27
+ setLogger(logger: Logger): void {
28
+ this.logger = logger;
29
+ }
30
+
31
+ setTxs(txs: Tx[]): number {
32
+ this.txsByHash.clear();
33
+ return this.appendTxs(txs);
34
+ }
35
+
36
+ appendTxs(txs: Tx[]): number {
37
+ let added = 0;
38
+ for (const tx of txs) {
39
+ const key = tx.getTxHash().toString();
40
+ if (!this.txsByHash.has(key)) {
41
+ added += 1;
42
+ }
43
+ this.txsByHash.set(key, tx);
44
+ }
45
+ return added;
46
+ }
47
+
48
+ clearTxs(): void {
49
+ this.txsByHash.clear();
50
+ }
51
+
52
+ resetState(): void {
53
+ this.txsByHash.clear();
54
+ this.removeAllListeners();
55
+ }
56
+
57
+ addTxs(txs: Tx[], opts?: { source?: string }): Promise<number> {
58
+ const newTxs: Tx[] = [];
59
+ let added = 0;
60
+ for (const tx of txs) {
61
+ const key = tx.getTxHash().toString();
62
+ if (!this.txsByHash.has(key)) {
63
+ newTxs.push(tx);
64
+ added += 1;
65
+ }
66
+ this.txsByHash.set(key, tx);
67
+ }
68
+ if (newTxs.length > 0) {
69
+ this.emit('txs-added', { txs: newTxs, source: opts?.source });
70
+ }
71
+ return Promise.resolve(added);
72
+ }
73
+
74
+ getTxByHash(hash: TxHash): Promise<Tx | undefined> {
75
+ return Promise.resolve(this.txsByHash.get(hash.toString()));
76
+ }
77
+
78
+ getTxsByHash(hashes: TxHash[]): Promise<(Tx | undefined)[]> {
79
+ const result = hashes.map(h => this.txsByHash.get(h.toString()));
80
+ const found = result.filter(tx => tx !== undefined).length;
81
+ this.logger?.debug(`[TxPool] getTxsByHash: requested ${hashes.length}, found ${found}`);
82
+ return Promise.resolve(result);
83
+ }
84
+
85
+ hasTxs(hashes: TxHash[]): Promise<boolean[]> {
86
+ return Promise.resolve(hashes.map(h => this.txsByHash.has(h.toString())));
87
+ }
88
+
89
+ hasTx(hash: TxHash): Promise<boolean> {
90
+ return Promise.resolve(this.txsByHash.has(hash.toString()));
91
+ }
92
+
93
+ getArchivedTxByHash(_hash: TxHash): Promise<Tx | undefined> {
94
+ return Promise.resolve(undefined);
95
+ }
96
+
97
+ async markAsMined(_txHashes: TxHash[], _blockHeader: BlockHeader): Promise<void> {}
98
+
99
+ async markMinedAsPending(_txHashes: TxHash[], _latestBlock: BlockNumber): Promise<void> {}
100
+
101
+ deleteTxs(txHashes: TxHash[], _opts?: { permanently?: boolean }): Promise<void> {
102
+ for (const txHash of txHashes) {
103
+ this.txsByHash.delete(txHash.toString());
104
+ }
105
+ return Promise.resolve();
106
+ }
107
+
108
+ getAllTxs(): Promise<Tx[]> {
109
+ return Promise.resolve([...this.txsByHash.values()]);
110
+ }
111
+
112
+ getAllTxHashes(): Promise<TxHash[]> {
113
+ return Promise.resolve([...this.txsByHash.keys()].map(key => TxHash.fromString(key)));
114
+ }
115
+
116
+ getPendingTxHashes(): Promise<TxHash[]> {
117
+ return Promise.resolve([...this.txsByHash.keys()].map(key => TxHash.fromString(key)));
118
+ }
119
+
120
+ getPendingTxCount(): Promise<number> {
121
+ return Promise.resolve(this.txsByHash.size);
122
+ }
123
+
124
+ getMinedTxHashes(): Promise<[tx: TxHash, blockNumber: BlockNumber][]> {
125
+ return Promise.resolve([]);
126
+ }
127
+
128
+ getTxStatus(hash: TxHash): Promise<'pending' | 'mined' | 'deleted' | undefined> {
129
+ return Promise.resolve(this.txsByHash.has(hash.toString()) ? 'pending' : undefined);
130
+ }
131
+
132
+ updateConfig(_config: { maxPendingTxCount?: number; archivedTxLimit?: number }): void {}
133
+
134
+ isEmpty(): Promise<boolean> {
135
+ return Promise.resolve(this.txsByHash.size === 0);
136
+ }
137
+
138
+ async markTxsAsNonEvictable(_txHashes: TxHash[]): Promise<void> {}
139
+
140
+ async clearNonEvictableTxs(): Promise<void> {}
141
+
142
+ cleanupDeletedMinedTxs(_blockNumber: BlockNumber): Promise<number> {
143
+ return Promise.resolve(0);
144
+ }
145
+ }
146
+
147
+ /**
148
+ * In-memory AttestationPool implementation for testing.
149
+ */
150
+ export class InMemoryAttestationPool implements AttestationPool {
151
+ private proposals = new Map<string, BlockProposal>();
152
+
153
+ addBlockProposal(blockProposal: BlockProposal): Promise<void> {
154
+ this.proposals.set(blockProposal.archive.toString(), blockProposal);
155
+ return Promise.resolve();
156
+ }
157
+
158
+ getBlockProposal(id: string): Promise<BlockProposal | undefined> {
159
+ return Promise.resolve(this.proposals.get(id));
160
+ }
161
+
162
+ hasBlockProposal(idOrProposal: string | BlockProposal): Promise<boolean> {
163
+ const id = typeof idOrProposal === 'string' ? idOrProposal : idOrProposal.archive.toString();
164
+ return Promise.resolve(this.proposals.has(id));
165
+ }
166
+
167
+ canAddProposal(_block: BlockProposal): Promise<boolean> {
168
+ return Promise.resolve(true);
169
+ }
170
+
171
+ async addCheckpointProposal(_proposal: CheckpointProposal): Promise<void> {}
172
+
173
+ getCheckpointProposal(_id: string): Promise<CheckpointProposalCore | undefined> {
174
+ return Promise.resolve(undefined);
175
+ }
176
+
177
+ hasCheckpointProposal(_idOrProposal: string | CheckpointProposal): Promise<boolean> {
178
+ return Promise.resolve(false);
179
+ }
180
+
181
+ async addCheckpointAttestations(_attestations: CheckpointAttestation[]): Promise<void> {}
182
+
183
+ async deleteCheckpointAttestationsOlderThan(_slot: SlotNumber): Promise<void> {}
184
+
185
+ getCheckpointAttestationsForSlot(_slot: SlotNumber): Promise<CheckpointAttestation[]> {
186
+ return Promise.resolve([]);
187
+ }
188
+
189
+ getCheckpointAttestationsForSlotAndProposal(
190
+ _slot: SlotNumber,
191
+ _proposalId: string,
192
+ ): Promise<CheckpointAttestation[]> {
193
+ return Promise.resolve([]);
194
+ }
195
+
196
+ hasCheckpointAttestation(_attestation: CheckpointAttestation): Promise<boolean> {
197
+ return Promise.resolve(false);
198
+ }
199
+
200
+ canAddCheckpointProposal(_proposal: CheckpointProposal): Promise<boolean> {
201
+ return Promise.resolve(true);
202
+ }
203
+
204
+ canAddCheckpointAttestation(_attestation: CheckpointAttestation, _committeeSize: number): Promise<boolean> {
205
+ return Promise.resolve(true);
206
+ }
207
+
208
+ hasReachedCheckpointProposalCap(_slot: SlotNumber): Promise<boolean> {
209
+ return Promise.resolve(false);
210
+ }
211
+
212
+ hasReachedCheckpointAttestationCap(_slot: SlotNumber, _proposalId: string, _committeeSize: number): Promise<boolean> {
213
+ return Promise.resolve(false);
214
+ }
215
+
216
+ isEmpty(): Promise<boolean> {
217
+ return Promise.resolve(this.proposals.size === 0);
218
+ }
219
+
220
+ resetState(): void {
221
+ this.proposals.clear();
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Creates a mock EpochCache for testing.
227
+ */
228
+ export function createMockEpochCache(): EpochCacheInterface {
229
+ return {
230
+ getCommittee: () => Promise.resolve({ committee: [], seed: 1n, epoch: EpochNumber.ZERO, isEscapeHatchOpen: false }),
231
+ getProposerIndexEncoding: () => '0x' as `0x${string}`,
232
+ getEpochAndSlotNow: () => ({ epoch: EpochNumber.ZERO, slot: SlotNumber.ZERO, ts: 0n, nowMs: 0n }),
233
+ computeProposerIndex: () => 0n,
234
+ getCurrentAndNextSlot: () => ({ currentSlot: SlotNumber.ZERO, nextSlot: SlotNumber.ZERO }),
235
+ getProposerAttesterAddressInSlot: () => Promise.resolve(undefined),
236
+ getEpochAndSlotInNextL1Slot: () => ({ epoch: EpochNumber.ZERO, slot: SlotNumber.ZERO, ts: 0n, now: 0n }),
237
+ isInCommittee: () => Promise.resolve(false),
238
+ getRegisteredValidators: () => Promise.resolve([]),
239
+ filterInCommittee: () => Promise.resolve([]),
240
+ };
241
+ }
242
+
243
+ /**
244
+ * Creates a mock WorldStateSynchronizer for testing.
245
+ */
246
+ export function createMockWorldStateSynchronizer(): WorldStateSynchronizer {
247
+ return {
248
+ status: () =>
249
+ Promise.resolve({
250
+ syncSummary: {
251
+ latestBlockNumber: 0,
252
+ latestBlockHash: '',
253
+ finalizedBlockNumber: 0,
254
+ treesAreSynched: false,
255
+ oldestHistoricBlockNumber: 0,
256
+ },
257
+ }),
258
+ } as WorldStateSynchronizer;
259
+ }
260
+
261
+ /**
262
+ * Unlimited rate limit configuration for benchmarks.
263
+ */
264
+ export const UNLIMITED_RATE_LIMIT_QUOTA = {
265
+ peerLimit: { quotaTimeMs: 1000, quotaCount: 10_000 },
266
+ globalLimit: { quotaTimeMs: 1000, quotaCount: 100_000 },
267
+ };
268
+
269
+ /**
270
+ * Installs unlimited rate limits on a ReqResp instance.
271
+ * Used in benchmarks to avoid rate limiting affecting results.
272
+ *
273
+ * Note: Uses `as any` because rateLimiter is private. This is acceptable
274
+ * in test code where we need to override internal behavior.
275
+ */
276
+ export function installUnlimitedRateLimitsOnReqResp(reqResp: any): void {
277
+ const rateLimiter = reqResp.rateLimiter;
278
+ rateLimiter.getRateLimits = () => UNLIMITED_RATE_LIMIT_QUOTA;
279
+ rateLimiter.allow = () => RateLimitStatus.Allowed;
280
+ }
281
+
282
+ /**
283
+ * Distribution patterns for benchmark transaction distribution.
284
+ */
285
+ export type DistributionPattern = 'uniform' | 'sparse' | 'pinned-only';
286
+
287
+ /**
288
+ * Collector implementation types for benchmarking.
289
+ */
290
+ export type CollectorType = 'batch-requester' | 'send-batch-request';
291
+
292
+ /**
293
+ * Display names for collector types (for output/logging only).
294
+ */
295
+ export const COLLECTOR_DISPLAY_NAMES: Record<CollectorType, string> = {
296
+ 'batch-requester': 'batch-requester (new)',
297
+ 'send-batch-request': 'send-batch-request (old)',
298
+ };
299
+
300
+ /**
301
+ * Benchmark timing constants.
302
+ */
303
+ export const BENCHMARK_CONSTANTS = {
304
+ /** Time to wait for peers to connect before starting benchmark */
305
+ PEER_DISCOVERY_WAIT_MS: 10_000,
306
+ /** Maximum time to wait for peer connections */
307
+ MAX_PEER_WAIT_MS: 60_000,
308
+ /** Interval between peer connection checks */
309
+ PEER_CHECK_INTERVAL_MS: 500,
310
+ /** Default worker ready timeout */
311
+ WORKER_READY_TIMEOUT_MS: 30_000,
312
+ /** Graceful shutdown timeout before force kill */
313
+ GRACEFUL_SHUTDOWN_TIMEOUT_MS: 5_000,
314
+ /** Overall cleanup timeout */
315
+ CLEANUP_TIMEOUT_MS: 10_000,
316
+ /** Buffer time for internal timeout to ensure we return before outer timeout */
317
+ TIMEOUT_BUFFER_MS: 5_000,
318
+ /** Minimum internal timeout regardless of buffer */
319
+ MIN_INTERNAL_TIMEOUT_MS: 1_000,
320
+ /** Fixed max peers for fair benchmarking */
321
+ FIXED_MAX_PEERS: 10,
322
+ /** Fixed max retry attempts for fair benchmarking */
323
+ FIXED_MAX_RETRY_ATTEMPTS: 3,
324
+ } as const;
325
+
326
+ /**
327
+ * Filters transactions based on distribution pattern for benchmark responders.
328
+ *
329
+ * @param allTxs - All transactions to filter
330
+ * @param peerIndex - Index of the current peer (0 = aggregator)
331
+ * @param peerCount - Total number of peers
332
+ * @param distribution - Distribution pattern to apply
333
+ * @param pinnedPeerIndex - Index of the pinned peer (for pinned-only distribution)
334
+ * @returns Filtered transactions for this peer
335
+ */
336
+ export function filterTxsByDistribution(
337
+ allTxs: Tx[],
338
+ peerIndex: number,
339
+ peerCount: number,
340
+ distribution: DistributionPattern,
341
+ pinnedPeerIndex: number = 1,
342
+ ): Tx[] {
343
+ if (peerIndex === 0) {
344
+ return [];
345
+ }
346
+
347
+ const responderCount = peerCount - 1;
348
+
349
+ switch (distribution) {
350
+ case 'uniform':
351
+ return allTxs;
352
+
353
+ case 'sparse': {
354
+ const responderIndex = peerIndex - 1;
355
+ return allTxs.filter((_, txIndex) => {
356
+ const bucket = txIndex % responderCount;
357
+ return bucket === responderIndex || bucket === (responderIndex + 1) % responderCount;
358
+ });
359
+ }
360
+
361
+ case 'pinned-only':
362
+ return peerIndex === pinnedPeerIndex ? allTxs : [];
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Calculates the internal timeout for collector operations.
368
+ * Ensures we return before the outer timeout while maintaining a minimum.
369
+ */
370
+ export function calculateInternalTimeout(timeoutMs: number): number {
371
+ return Math.max(timeoutMs - BENCHMARK_CONSTANTS.TIMEOUT_BUFFER_MS, BENCHMARK_CONSTANTS.MIN_INTERNAL_TIMEOUT_MS);
372
+ }