@aztec/p2p 0.0.1-commit.c80b6263 → 0.0.1-commit.cf93bcc56

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 (310) hide show
  1. package/dest/client/factory.d.ts +7 -6
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +47 -10
  4. package/dest/client/interface.d.ts +40 -22
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +37 -41
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +134 -145
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +2 -2
  10. package/dest/config.d.ts +28 -4
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +19 -2
  13. package/dest/errors/tx-pool.error.d.ts +8 -0
  14. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  15. package/dest/errors/tx-pool.error.js +9 -0
  16. package/dest/index.d.ts +2 -1
  17. package/dest/index.d.ts.map +1 -1
  18. package/dest/index.js +1 -0
  19. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -88
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/attestation_pool.js +441 -3
  22. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  24. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
  25. package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
  26. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/index.js +1 -2
  28. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  29. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  31. package/dest/mem_pools/index.d.ts +3 -2
  32. package/dest/mem_pools/index.d.ts.map +1 -1
  33. package/dest/mem_pools/index.js +1 -1
  34. package/dest/mem_pools/interface.d.ts +5 -5
  35. package/dest/mem_pools/interface.d.ts.map +1 -1
  36. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  37. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
  38. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
  39. package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
  40. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
  41. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
  42. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
  43. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  44. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  45. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  46. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
  47. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
  48. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +128 -0
  49. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
  50. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  51. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +93 -0
  52. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
  53. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
  54. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +95 -0
  55. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
  56. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
  57. package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
  58. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +174 -0
  59. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
  60. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +25 -0
  61. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
  62. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  63. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +65 -0
  64. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
  65. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  66. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +93 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
  68. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  69. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +74 -0
  70. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
  71. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
  72. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +73 -0
  73. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
  74. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
  75. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
  76. package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
  77. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
  78. package/dest/mem_pools/tx_pool_v2/index.js +5 -0
  79. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  80. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  81. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  82. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +207 -0
  83. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
  84. package/dest/mem_pools/tx_pool_v2/interfaces.js +8 -0
  85. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +97 -0
  86. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
  87. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +152 -0
  88. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
  89. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
  90. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
  91. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +108 -0
  92. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
  93. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +355 -0
  94. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +58 -0
  95. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
  96. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +161 -0
  97. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +75 -0
  98. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
  99. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +871 -0
  100. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -3
  101. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  102. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +3 -3
  103. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
  105. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  106. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  107. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +18 -5
  108. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/block_header_validator.js +2 -2
  110. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  111. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  112. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  113. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  114. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  116. package/dest/services/data_store.d.ts +1 -1
  117. package/dest/services/data_store.d.ts.map +1 -1
  118. package/dest/services/data_store.js +10 -6
  119. package/dest/services/dummy_service.d.ts +10 -2
  120. package/dest/services/dummy_service.d.ts.map +1 -1
  121. package/dest/services/dummy_service.js +6 -0
  122. package/dest/services/encoding.d.ts +2 -2
  123. package/dest/services/encoding.d.ts.map +1 -1
  124. package/dest/services/encoding.js +4 -3
  125. package/dest/services/gossipsub/index.d.ts +3 -0
  126. package/dest/services/gossipsub/index.d.ts.map +1 -0
  127. package/dest/services/gossipsub/index.js +2 -0
  128. package/dest/services/gossipsub/scoring.d.ts +21 -3
  129. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  130. package/dest/services/gossipsub/scoring.js +24 -7
  131. package/dest/services/gossipsub/topic_score_params.d.ts +161 -0
  132. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  133. package/dest/services/gossipsub/topic_score_params.js +324 -0
  134. package/dest/services/index.d.ts +2 -1
  135. package/dest/services/index.d.ts.map +1 -1
  136. package/dest/services/index.js +1 -0
  137. package/dest/services/libp2p/libp2p_service.d.ts +84 -35
  138. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  139. package/dest/services/libp2p/libp2p_service.js +375 -280
  140. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  141. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  142. package/dest/services/peer-manager/peer_scoring.js +25 -2
  143. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -4
  144. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  145. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +9 -9
  146. package/dest/services/reqresp/interface.d.ts +10 -1
  147. package/dest/services/reqresp/interface.d.ts.map +1 -1
  148. package/dest/services/reqresp/interface.js +15 -1
  149. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
  150. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  151. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +17 -12
  152. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +25 -14
  153. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  154. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +40 -24
  155. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  156. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  157. package/dest/services/reqresp/protocols/tx.js +20 -0
  158. package/dest/services/reqresp/reqresp.d.ts +1 -1
  159. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  160. package/dest/services/reqresp/reqresp.js +11 -4
  161. package/dest/services/service.d.ts +35 -1
  162. package/dest/services/service.d.ts.map +1 -1
  163. package/dest/services/tx_collection/config.d.ts +22 -4
  164. package/dest/services/tx_collection/config.d.ts.map +1 -1
  165. package/dest/services/tx_collection/config.js +49 -3
  166. package/dest/services/tx_collection/fast_tx_collection.d.ts +6 -5
  167. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  168. package/dest/services/tx_collection/fast_tx_collection.js +27 -17
  169. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  170. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  171. package/dest/services/tx_collection/file_store_tx_collection.js +165 -0
  172. package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
  173. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  174. package/dest/services/tx_collection/file_store_tx_source.js +79 -0
  175. package/dest/services/tx_collection/index.d.ts +3 -2
  176. package/dest/services/tx_collection/index.d.ts.map +1 -1
  177. package/dest/services/tx_collection/index.js +1 -0
  178. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  179. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  180. package/dest/services/tx_collection/instrumentation.js +2 -1
  181. package/dest/services/tx_collection/proposal_tx_collector.d.ts +12 -12
  182. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  183. package/dest/services/tx_collection/proposal_tx_collector.js +4 -5
  184. package/dest/services/tx_collection/slow_tx_collection.d.ts +6 -2
  185. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  186. package/dest/services/tx_collection/slow_tx_collection.js +55 -23
  187. package/dest/services/tx_collection/tx_collection.d.ts +19 -7
  188. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  189. package/dest/services/tx_collection/tx_collection.js +75 -3
  190. package/dest/services/tx_collection/tx_collection_sink.d.ts +15 -6
  191. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  192. package/dest/services/tx_collection/tx_collection_sink.js +13 -7
  193. package/dest/services/tx_file_store/config.d.ts +16 -0
  194. package/dest/services/tx_file_store/config.d.ts.map +1 -0
  195. package/dest/services/tx_file_store/config.js +22 -0
  196. package/dest/services/tx_file_store/index.d.ts +4 -0
  197. package/dest/services/tx_file_store/index.d.ts.map +1 -0
  198. package/dest/services/tx_file_store/index.js +3 -0
  199. package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
  200. package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
  201. package/dest/services/tx_file_store/instrumentation.js +29 -0
  202. package/dest/services/tx_file_store/tx_file_store.d.ts +48 -0
  203. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
  204. package/dest/services/tx_file_store/tx_file_store.js +152 -0
  205. package/dest/services/tx_provider.d.ts +3 -3
  206. package/dest/services/tx_provider.d.ts.map +1 -1
  207. package/dest/services/tx_provider.js +5 -4
  208. package/dest/test-helpers/make-test-p2p-clients.d.ts +3 -3
  209. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  210. package/dest/test-helpers/mock-pubsub.d.ts +27 -1
  211. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  212. package/dest/test-helpers/mock-pubsub.js +97 -2
  213. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  214. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  215. package/dest/test-helpers/reqresp-nodes.js +2 -1
  216. package/dest/test-helpers/testbench-utils.d.ts +43 -38
  217. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  218. package/dest/test-helpers/testbench-utils.js +130 -60
  219. package/dest/testbench/p2p_client_testbench_worker.js +5 -5
  220. package/package.json +14 -14
  221. package/src/client/factory.ts +89 -14
  222. package/src/client/interface.ts +49 -22
  223. package/src/client/p2p_client.ts +170 -168
  224. package/src/client/test/tx_proposal_collector/README.md +4 -4
  225. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +2 -2
  226. package/src/config.ts +41 -2
  227. package/src/errors/tx-pool.error.ts +12 -0
  228. package/src/index.ts +1 -0
  229. package/src/mem_pools/attestation_pool/attestation_pool.ts +496 -91
  230. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
  231. package/src/mem_pools/attestation_pool/index.ts +9 -2
  232. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  233. package/src/mem_pools/index.ts +4 -1
  234. package/src/mem_pools/interface.ts +4 -4
  235. package/src/mem_pools/tx_pool/README.md +1 -1
  236. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  237. package/src/mem_pools/tx_pool_v2/README.md +275 -0
  238. package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
  239. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
  240. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  241. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +160 -0
  242. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +121 -0
  243. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +122 -0
  244. package/src/mem_pools/tx_pool_v2/eviction/index.ts +27 -0
  245. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +209 -0
  246. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
  247. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
  248. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +87 -0
  249. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +90 -0
  250. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +31 -0
  251. package/src/mem_pools/tx_pool_v2/index.ts +12 -0
  252. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  253. package/src/mem_pools/tx_pool_v2/interfaces.ts +239 -0
  254. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +242 -0
  255. package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
  256. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +444 -0
  257. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +223 -0
  258. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1042 -0
  259. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +2 -2
  260. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +2 -2
  261. package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
  262. package/src/msg_validators/tx_validator/block_header_validator.ts +18 -8
  263. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  264. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  265. package/src/services/data_store.ts +10 -7
  266. package/src/services/dummy_service.ts +12 -0
  267. package/src/services/encoding.ts +4 -3
  268. package/src/services/gossipsub/README.md +626 -0
  269. package/src/services/gossipsub/index.ts +2 -0
  270. package/src/services/gossipsub/scoring.ts +29 -5
  271. package/src/services/gossipsub/topic_score_params.ts +451 -0
  272. package/src/services/index.ts +1 -0
  273. package/src/services/libp2p/libp2p_service.ts +377 -282
  274. package/src/services/peer-manager/peer_scoring.ts +25 -0
  275. package/src/services/reqresp/batch-tx-requester/README.md +14 -14
  276. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +12 -12
  277. package/src/services/reqresp/interface.ts +26 -1
  278. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +24 -15
  279. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -24
  280. package/src/services/reqresp/protocols/tx.ts +22 -0
  281. package/src/services/reqresp/reqresp.ts +13 -3
  282. package/src/services/service.ts +40 -0
  283. package/src/services/tx_collection/config.ts +74 -6
  284. package/src/services/tx_collection/fast_tx_collection.ts +28 -26
  285. package/src/services/tx_collection/file_store_tx_collection.ts +198 -0
  286. package/src/services/tx_collection/file_store_tx_source.ts +104 -0
  287. package/src/services/tx_collection/index.ts +2 -1
  288. package/src/services/tx_collection/instrumentation.ts +7 -1
  289. package/src/services/tx_collection/proposal_tx_collector.ts +12 -14
  290. package/src/services/tx_collection/slow_tx_collection.ts +64 -30
  291. package/src/services/tx_collection/tx_collection.ts +109 -13
  292. package/src/services/tx_collection/tx_collection_sink.ts +17 -7
  293. package/src/services/tx_file_store/config.ts +37 -0
  294. package/src/services/tx_file_store/index.ts +3 -0
  295. package/src/services/tx_file_store/instrumentation.ts +36 -0
  296. package/src/services/tx_file_store/tx_file_store.ts +175 -0
  297. package/src/services/tx_provider.ts +8 -7
  298. package/src/test-helpers/make-test-p2p-clients.ts +3 -3
  299. package/src/test-helpers/mock-pubsub.ts +133 -3
  300. package/src/test-helpers/reqresp-nodes.ts +2 -1
  301. package/src/test-helpers/testbench-utils.ts +129 -71
  302. package/src/testbench/p2p_client_testbench_worker.ts +5 -5
  303. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
  304. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  305. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
  306. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
  307. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  308. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
  309. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
  310. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
@@ -14,6 +14,21 @@ import type { PeerId } from '@libp2p/interface';
14
14
 
15
15
  import type { P2PConfig } from '../../config.js';
16
16
 
17
+ /**
18
+ * Application-level peer penalties.
19
+ *
20
+ * These scores are multiplied by appSpecificWeight (10) when contributing to gossipsub score.
21
+ * The values are designed to align with gossipsub thresholds:
22
+ *
23
+ * - LowToleranceError (50): 1 error → app score -50 → gossipsub -500 → gossipThreshold
24
+ * - MidToleranceError (10): 5 errors → app score -50 → gossipsub -500 → gossipThreshold
25
+ * - HighToleranceError (2): 25 errors → app score -50 → gossipsub -500 → gossipThreshold
26
+ *
27
+ * Examples of each severity:
28
+ * - LowToleranceError: Invalid messages, deserialization errors, manipulation attempts
29
+ * - MidToleranceError: Hash mismatches, protocol violations
30
+ * - HighToleranceError: Rate limit exceeded, failed responses, transient errors
31
+ */
17
32
  const DefaultPeerPenalties = {
18
33
  [PeerErrorSeverity.LowToleranceError]: 50,
19
34
  [PeerErrorSeverity.MidToleranceError]: 10,
@@ -26,6 +41,16 @@ export enum PeerScoreState {
26
41
  Healthy,
27
42
  }
28
43
 
44
+ /**
45
+ * Score thresholds for peer states.
46
+ *
47
+ * These values align with gossipsub thresholds when multiplied by appSpecificWeight (10):
48
+ * - MIN_SCORE_BEFORE_DISCONNECT (-50) × 10 = -500 = gossipThreshold
49
+ * - MIN_SCORE_BEFORE_BAN (-100) × 10 = -1000 = publishThreshold
50
+ *
51
+ * This ensures that when a peer is disconnected at the application level,
52
+ * they also stop receiving gossip, and when banned, they cannot publish.
53
+ */
29
54
  // TODO: move into config / constants
30
55
  const MIN_SCORE_BEFORE_BAN = -100;
31
56
  const MIN_SCORE_BEFORE_DISCONNECT = -50;
@@ -1,14 +1,14 @@
1
1
  # BatchTxRequester
2
2
 
3
- The `BatchTxRequester` is a specialized P2P service that aggressively fetches missing transactions from peers when a node receives a block proposal but lacks some of the referenced transactions. This is critical for validators who need all transactions to attest to a proposal.
3
+ The `BatchTxRequester` is a specialized P2P service that aggressively fetches missing transactions from peers when a node lacks some of the referenced transactions. It serves two pathways: (1) block proposals, where validators need all transactions to attest, and (2) block proving, where provers need all transactions to generate proofs.
4
4
 
5
5
  ## Overview
6
6
 
7
- When a validator receives a block proposal, they must verify all transactions in the block. If some transactions are missing from the local mempool (e.g., due to gossip delays), the `BatchTxRequester` kicks in to fetch them via direct peer-to-peer requests before the attestation deadline.
7
+ When a validator receives a block proposal or a prover needs to prove a block, they must have all transactions. If some transactions are missing from the local mempool (e.g., due to gossip delays), the `BatchTxRequester` kicks in to fetch them via direct peer-to-peer requests before the deadline.
8
8
 
9
9
  ```
10
10
  ┌─────────────────────────────────────────────────────────────────────────────┐
11
- Block Proposal Received
11
+ Block Proposal or Block Received
12
12
  │ (contains hashes of N transactions) │
13
13
  └─────────────────────────────────────────────────────────────────────────────┘
14
14
 
@@ -71,7 +71,7 @@ The requester classifies peers into three categories to optimize fetching:
71
71
  ### Blind Phase → Smart Phase Transition
72
72
 
73
73
  Peers transition from "dumb" to "smart" when they respond with a valid `BlockTxsResponse` containing:
74
- 1. A matching `blockHash`
74
+ 1. A matching `archiveRoot`
75
75
  2. A non-empty `txIndices` BitVector indicating which transactions they have
76
76
  3. At least one transaction we're still missing
77
77
 
@@ -81,10 +81,10 @@ Peers transition from "dumb" to "smart" when they respond with a valid `BlockTxs
81
81
  │ ┌────────────────────────────────────────────────────────────────────────┐ │
82
82
  │ │ Initial State: All peers are "dumb" (except pinned peer) │ │
83
83
  │ │ │ │
84
- │ │ Request: [blockHash, txHashes (full list), txIndices (BitVector)] │ │
84
+ │ │ Request: [archiveRoot, txHashes (full list), txIndices (BitVector)] │ │
85
85
  │ │ └─ Include full hashes because peer may not have proposal │ │
86
86
  │ │ │ │
87
- │ │ Response: [blockHash, txs[], txIndices (what peer has)] │ │
87
+ │ │ Response: [archiveRoot, txs[], txIndices (what peer has)] │ │
88
88
  │ │ └─ Tells us exactly which txs this peer can provide │ │
89
89
  │ └────────────────────────────────────────────────────────────────────────┘ │
90
90
  └──────────────────────────────────────────────────────────────────────────────┘
@@ -97,10 +97,10 @@ Peers transition from "dumb" to "smart" when they respond with a valid `BlockTxs
97
97
  │ ┌────────────────────────────────────────────────────────────────────────┐ │
98
98
  │ │ Peer promoted to "smart" - we know exactly what they have │ │
99
99
  │ │ │ │
100
- │ │ Request: [blockHash, txIndices (BitVector only)] │ │
100
+ │ │ Request: [archiveRoot, txIndices (BitVector only)] │ │
101
101
  │ │ └─ No need for full hashes, peer has the proposal │ │
102
102
  │ │ │ │
103
- │ │ Response: [blockHash, txs[], txIndices (updated availability)] │ │
103
+ │ │ Response: [archiveRoot, txs[], txIndices (updated availability)] │ │
104
104
  │ │ └─ May have received more txs since last response │ │
105
105
  │ └────────────────────────────────────────────────────────────────────────┘ │
106
106
  └──────────────────────────────────────────────────────────────────────────────┘
@@ -152,7 +152,7 @@ The `BatchTxRequester` runs three types of workers concurrently:
152
152
 
153
153
  ```typescript
154
154
  class BlockTxsRequest {
155
- blockHash: Fr; // 32-byte hash of the proposed block header
155
+ archiveRoot: Fr; // Archive root after the proposed block is applied
156
156
  txHashes: TxHashArray; // Full tx hashes (for dumb peers without proposal)
157
157
  txIndices: BitVector; // Which txs from proposal we're requesting (1 = want)
158
158
  }
@@ -162,7 +162,7 @@ class BlockTxsRequest {
162
162
 
163
163
  ```typescript
164
164
  class BlockTxsResponse {
165
- blockHash: Fr; // Echo back the block hash
165
+ archiveRoot: Fr; // Echo back the proposal archive root
166
166
  txs: TxArray; // Actual transaction data
167
167
  txIndices: BitVector; // Which txs the peer has available (1 = have)
168
168
  }
@@ -230,8 +230,8 @@ Request to peer fails
230
230
  ```typescript
231
231
  const requester = new BatchTxRequester(
232
232
  missingTxHashes, // TxHash[] - what we need
233
- blockProposal, // BlockProposal - the proposal we're attesting to
234
- pinnedPeer, // PeerId | undefined - who sent us the proposal
233
+ blockTxsSource, // BlockTxsSource - the proposal or block we need txs for
234
+ pinnedPeer, // PeerId | undefined - peer expected to have the txs
235
235
  timeoutMs, // number - how long to try
236
236
  p2pService, // BatchTxRequesterLibP2PService
237
237
  );
@@ -268,14 +268,14 @@ const txs = await BatchTxRequester.collectAllTxs(requester.run());
268
268
  ┌───────────────────────────────────┐ ┌─────────────────────────────────────┐
269
269
  │ FastTxCollection │ │ SlowTxCollection │
270
270
  │ │ │ │
271
- │ Time-critical: attestations │ │ Background: unproven blocks │
271
+ │ Time-critical: proposals/proving │ │ Background: unproven blocks │
272
272
  │ │ │ │
273
273
  │ 1. Try RPC nodes first (fast) │ │ Periodic polling of RPC nodes │
274
274
  │ 2. Fall back to BatchTxRequester │ │ and peers for missing txs │
275
275
  │ │ │ │
276
276
  └───────────────────┬───────────────┘ └─────────────────────────────────────┘
277
277
 
278
- │ For 'proposal' requests
278
+ │ For 'proposal' and 'block' requests
279
279
 
280
280
  ┌─────────────────────────────────────────────────────────────────────────────┐
281
281
  │ BatchTxRequester │
@@ -4,14 +4,14 @@ import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/queue';
5
5
  import { sleep } from '@aztec/foundation/sleep';
6
6
  import { DateProvider, executeTimeout } from '@aztec/foundation/timer';
7
- import { type BlockProposal, PeerErrorSeverity } from '@aztec/stdlib/p2p';
7
+ import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
8
8
  import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
9
9
 
10
10
  import type { PeerId } from '@libp2p/interface';
11
11
  import { peerIdFromString } from '@libp2p/peer-id';
12
12
 
13
13
  import { ReqRespSubProtocol } from '.././interface.js';
14
- import { BlockTxsRequest, BlockTxsResponse } from '.././protocols/index.js';
14
+ import { BlockTxsRequest, BlockTxsResponse, type BlockTxsSource } from '.././protocols/index.js';
15
15
  import { ReqRespStatus } from '.././status.js';
16
16
  import {
17
17
  DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD,
@@ -42,7 +42,7 @@ import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_val
42
42
  * - Is the peer which was unable to send us successful response N times in a row
43
43
  * */
44
44
  export class BatchTxRequester {
45
- private readonly blockProposal: BlockProposal;
45
+ private readonly blockTxsSource: BlockTxsSource;
46
46
  private readonly pinnedPeer: PeerId | undefined;
47
47
  private readonly timeoutMs: number;
48
48
  private readonly p2pService: BatchTxRequesterLibP2PService;
@@ -61,7 +61,7 @@ export class BatchTxRequester {
61
61
 
62
62
  constructor(
63
63
  missingTxs: TxHash[],
64
- blockProposal: BlockProposal,
64
+ blockTxsSource: BlockTxsSource,
65
65
  pinnedPeer: PeerId | undefined,
66
66
  timeoutMs: number,
67
67
  p2pService: BatchTxRequesterLibP2PService,
@@ -69,7 +69,7 @@ export class BatchTxRequester {
69
69
  dateProvider?: DateProvider,
70
70
  opts?: BatchTxRequesterOptions,
71
71
  ) {
72
- this.blockProposal = blockProposal;
72
+ this.blockTxsSource = blockTxsSource;
73
73
  this.pinnedPeer = pinnedPeer;
74
74
  this.timeoutMs = timeoutMs;
75
75
  this.p2pService = p2pService;
@@ -205,7 +205,7 @@ export class BatchTxRequester {
205
205
  return;
206
206
  }
207
207
 
208
- const request = BlockTxsRequest.fromBlockProposalAndMissingTxs(this.blockProposal, txs);
208
+ const request = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
209
209
  if (!request) {
210
210
  return;
211
211
  }
@@ -249,8 +249,8 @@ export class BatchTxRequester {
249
249
  // If peer is dumb peer, we don't know yet if they received full blockProposal
250
250
  // there is solid chance that peer didn't receive proposal yet, thus we must send full hashes
251
251
  const includeFullHashesInRequestNotJustIndices = true;
252
- const blockRequest = BlockTxsRequest.fromBlockProposalAndMissingTxs(
253
- this.blockProposal,
252
+ const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(
253
+ this.blockTxsSource,
254
254
  txs,
255
255
  includeFullHashesInRequestNotJustIndices,
256
256
  );
@@ -342,7 +342,7 @@ export class BatchTxRequester {
342
342
 
343
343
  const makeRequest = (pid: PeerId) => {
344
344
  const txs = this.txsMetadata.getTxsToRequestFromThePeer(pid);
345
- const blockRequest = BlockTxsRequest.fromBlockProposalAndMissingTxs(this.blockProposal, txs);
345
+ const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
346
346
  if (!blockRequest) {
347
347
  return undefined;
348
348
  }
@@ -605,9 +605,9 @@ export class BatchTxRequester {
605
605
  }
606
606
 
607
607
  private isBlockResponseValid(response: BlockTxsResponse): boolean {
608
- const blockIdsMatch = this.blockProposal.archive.toString() === response.blockHash.toString();
608
+ const archiveRootsMatch = this.blockTxsSource.archive.toString() === response.archiveRoot.toString();
609
609
  const peerHasSomeTxsFromProposal = !response.txIndices.isEmpty();
610
- return blockIdsMatch && peerHasSomeTxsFromProposal;
610
+ return archiveRootsMatch && peerHasSomeTxsFromProposal;
611
611
  }
612
612
 
613
613
  private peerHasSomeTxsWeAreMissing(_peerId: PeerId, response: BlockTxsResponse): boolean {
@@ -624,7 +624,7 @@ export class BatchTxRequester {
624
624
  private extractHashesPeerHasFromResponse(response: BlockTxsResponse): Array<TxHash> {
625
625
  const hashes: TxHash[] = [];
626
626
  const indicesOfHashesPeerHas = new Set(response.txIndices.getTrueIndices());
627
- this.blockProposal.txHashes.forEach((hash, idx) => {
627
+ this.blockTxsSource.txHashes.forEach((hash, idx) => {
628
628
  if (indicesOfHashesPeerHas.has(idx)) {
629
629
  hashes.push(hash);
630
630
  }
@@ -1,5 +1,6 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { L2Block } from '@aztec/stdlib/block';
3
+ import { MAX_L2_BLOCK_SIZE_KB } from '@aztec/stdlib/p2p';
3
4
  import { TxArray, TxHashArray } from '@aztec/stdlib/tx';
4
5
 
5
6
  import type { PeerId } from '@libp2p/interface';
@@ -7,8 +8,13 @@ import type { PeerId } from '@libp2p/interface';
7
8
  import type { P2PReqRespConfig } from './config.js';
8
9
  import type { ConnectionSampler } from './connection-sampler/connection_sampler.js';
9
10
  import { AuthRequest, AuthResponse } from './protocols/auth.js';
10
- import { BlockTxsRequest, BlockTxsResponse } from './protocols/block_txs/block_txs_reqresp.js';
11
+ import {
12
+ BlockTxsRequest,
13
+ BlockTxsResponse,
14
+ calculateBlockTxsResponseSize,
15
+ } from './protocols/block_txs/block_txs_reqresp.js';
11
16
  import { StatusMessage } from './protocols/status.js';
17
+ import { calculateTxResponseSize } from './protocols/tx.js';
12
18
  import type { ReqRespStatus } from './status.js';
13
19
 
14
20
  /*
@@ -211,6 +217,25 @@ export const subProtocolMap = {
211
217
  },
212
218
  };
213
219
 
220
+ /**
221
+ * Type for a function that calculates the expected response size in KB for a given request.
222
+ */
223
+ export type ExpectedResponseSizeCalculator = (requestBuffer: Buffer) => number;
224
+
225
+ /**
226
+ * Map of sub-protocols to their expected response size calculators.
227
+ * These are used to validate that responses don't exceed expected sizes based on request parameters.
228
+ */
229
+ export const subProtocolSizeCalculators: Record<ReqRespSubProtocol, ExpectedResponseSizeCalculator> = {
230
+ [ReqRespSubProtocol.TX]: calculateTxResponseSize,
231
+ [ReqRespSubProtocol.BLOCK_TXS]: calculateBlockTxsResponseSize,
232
+ [ReqRespSubProtocol.BLOCK]: () => MAX_L2_BLOCK_SIZE_KB,
233
+ [ReqRespSubProtocol.STATUS]: () => 1,
234
+ [ReqRespSubProtocol.PING]: () => 1,
235
+ [ReqRespSubProtocol.AUTH]: () => 1,
236
+ [ReqRespSubProtocol.GOODBYE]: () => 1, // No response expected, but provide minimal limit
237
+ };
238
+
214
239
  export interface ReqRespInterface {
215
240
  start(
216
241
  subProtocolHandlers: Partial<ReqRespSubProtocolHandlers>,
@@ -1,10 +1,11 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
+ import type { L2BlockSource } from '@aztec/stdlib/block';
2
3
  import { TxArray } from '@aztec/stdlib/tx';
3
4
 
4
5
  import type { PeerId } from '@libp2p/interface';
5
6
 
6
- import type { AttestationPool } from '../../../../mem_pools/attestation_pool/attestation_pool.js';
7
- import type { TxPool } from '../../../../mem_pools/index.js';
7
+ import type { AttestationPoolApi } from '../../../../mem_pools/attestation_pool/attestation_pool.js';
8
+ import type { TxPoolV2 } from '../../../../mem_pools/tx_pool_v2/interfaces.js';
8
9
  import type { ReqRespSubProtocolHandler } from '../../interface.js';
9
10
  import { ReqRespStatus, ReqRespStatusError } from '../../status.js';
10
11
  import { BitVector } from './bitvector.js';
@@ -13,10 +14,15 @@ import { BlockTxsRequest, BlockTxsResponse } from './block_txs_reqresp.js';
13
14
  /**
14
15
  * Handler for block txs requests
15
16
  * @param attestationPool - the attestation pool to check for block proposals
16
- * @param mempools - the mempools containing the tx pool
17
+ * @param archiver - the archiver to look up blocks by archive root
18
+ * @param txPool - the tx pool to fetch transactions from
17
19
  * @returns the BlockTxs request handler
18
20
  */
19
- export function reqRespBlockTxsHandler(attestationPool: AttestationPool, txPool: TxPool): ReqRespSubProtocolHandler {
21
+ export function reqRespBlockTxsHandler(
22
+ attestationPool: AttestationPoolApi,
23
+ archiver: L2BlockSource,
24
+ txPool: TxPoolV2,
25
+ ): ReqRespSubProtocolHandler {
20
26
  /**
21
27
  * Handler for block txs requests
22
28
  * @param msg - the block txs request message
@@ -30,37 +36,40 @@ export function reqRespBlockTxsHandler(attestationPool: AttestationPool, txPool:
30
36
  } catch (err: any) {
31
37
  throw new ReqRespStatusError(ReqRespStatus.BADLY_FORMED_REQUEST, { cause: err });
32
38
  }
33
-
34
- const blockProposal = await attestationPool.getBlockProposal(request.blockHash.toString());
39
+ // First try attestation pool, then fall back to archiver
40
+ let txHashes = (await attestationPool.getBlockProposal(request.archiveRoot.toString()))?.txHashes;
41
+ if (!txHashes) {
42
+ txHashes = (await archiver.getL2BlockByArchive(request.archiveRoot))?.body.txEffects.map(effect => effect.txHash);
43
+ }
35
44
 
36
45
  let requestedTxsHashes;
37
46
  if (request.txHashes.length > 0) {
38
47
  requestedTxsHashes = request.txHashes;
39
48
  }
40
49
 
41
- // This is scenario in which we don't have this block proposal the peer is requesting from us
50
+ // This is scenario in which we don't have this block the peer is requesting from us
42
51
  // But peer has sent requested tx hashes, so we can send them the transactions
43
- if (!blockProposal && requestedTxsHashes !== undefined) {
52
+ if (!txHashes && requestedTxsHashes !== undefined) {
44
53
  const responseTxs = (await txPool.getTxsByHash(requestedTxsHashes)).filter(tx => !!tx);
45
54
  const response = new BlockTxsResponse(Fr.zero(), new TxArray(...responseTxs), BitVector.init(0, []));
46
55
  return response.toBuffer();
47
56
  }
48
57
 
49
- // If don't have this block proposal and peer has not sent requested tx hashes
50
- if (!blockProposal) {
58
+ // If we don't have this block and peer has not sent requested tx hashes
59
+ if (!txHashes) {
51
60
  throw new ReqRespStatusError(ReqRespStatus.NOT_FOUND);
52
61
  }
53
62
 
54
- const txsAvailableInPool = await txPool.hasTxs(blockProposal.txHashes);
55
- //Map txs in the pool to their indices in the block proposal
63
+ const txsAvailableInPool = await txPool.hasTxs(txHashes);
64
+ // Map txs in the pool to their indices in the block
56
65
  const availableIndices = txsAvailableInPool.map((hasTx, idx) => (hasTx ? idx : -1)).filter(idx => idx !== -1);
57
- const responseBitVector = BitVector.init(blockProposal.txHashes.length, availableIndices);
66
+ const responseBitVector = BitVector.init(txHashes.length, availableIndices);
58
67
 
59
68
  const requestedIndices = new Set(request.txIndices.getTrueIndices());
60
- requestedTxsHashes = blockProposal.txHashes.filter((_, idx) => requestedIndices.has(idx));
69
+ requestedTxsHashes = txHashes.filter((_, idx) => requestedIndices.has(idx));
61
70
 
62
71
  const responseTxs = (await txPool.getTxsByHash(requestedTxsHashes)).filter(tx => !!tx);
63
- const response = new BlockTxsResponse(request.blockHash, new TxArray(...responseTxs), responseBitVector);
72
+ const response = new BlockTxsResponse(request.archiveRoot, new TxArray(...responseTxs), responseBitVector);
64
73
 
65
74
  return response.toBuffer();
66
75
  };
@@ -1,17 +1,23 @@
1
1
  import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
3
- import type { BlockProposal } from '@aztec/stdlib/p2p';
4
- import { TxArray, TxHash, TxHashArray } from '@aztec/stdlib/tx';
3
+ import { MAX_TX_SIZE_KB } from '@aztec/stdlib/p2p';
4
+ import { TxArray, type TxHash, TxHashArray } from '@aztec/stdlib/tx';
5
5
 
6
6
  import { BitVector } from './bitvector.js';
7
7
 
8
+ /** Minimal interface for a block source that provides tx hashes and an archive root. */
9
+ export interface BlockTxsSource {
10
+ txHashes: TxHash[];
11
+ archive: Fr;
12
+ }
13
+
8
14
  /**
9
15
  * Request message for requesting specific transactions from a block
10
16
  */
11
17
  export class BlockTxsRequest {
12
18
  constructor(
13
- // 32 byte hash of the proposed block header
14
- readonly blockHash: Fr,
19
+ // Archive root after the proposed block is applied (proposal identifier)
20
+ readonly archiveRoot: Fr,
15
21
  // Hashes of txs we are requesting
16
22
  readonly txHashes: TxHashArray,
17
23
  // BitVector indicating which txs from the proposal we are requesting
@@ -22,16 +28,17 @@ export class BlockTxsRequest {
22
28
  ) {}
23
29
 
24
30
  /**
25
- * Crates new BlockTxsRequest given proposal and missing tx hashes
31
+ * Creates new BlockTxsRequest given a block txs source and missing tx hashes.
26
32
  *
27
- * @param: blockProposal - The block proposal for which we are making request
28
- * @param: missingTxHashes - Tx hashes from the proposal we are missing
29
- * @param: includeFullTxHashes - Whether to include full list of missing tx hashes in the request or just Bitvector indices
33
+ * @param blockTxsSource - The block or proposal for which we are making the request
34
+ * @param missingTxHashes - Tx hashes from the source we are missing
35
+ * @param includeFullTxHashes - Whether to include full list of missing tx hashes in the request or just Bitvector indices
30
36
  *
31
- * @returns undefined if there were no missingTxHashes matching BlockProposal hashes, otherwise
32
- * returns new BlockTxsRequest*/
33
- static fromBlockProposalAndMissingTxs(
34
- blockProposal: BlockProposal,
37
+ * @returns undefined if there were no missingTxHashes matching the source hashes, otherwise
38
+ * returns new BlockTxsRequest
39
+ */
40
+ static fromTxsSourceAndMissingTxs(
41
+ blockTxsSource: BlockTxsSource,
35
42
  missingTxHashes: TxHash[],
36
43
  includeFullTxHashes = false,
37
44
  ): BlockTxsRequest | undefined {
@@ -41,19 +48,19 @@ export class BlockTxsRequest {
41
48
 
42
49
  const missingHashesSet = new Set(missingTxHashes.map(t => t.toString()));
43
50
 
44
- // We cannot request txs that are not part of the block proposal
45
- if (!missingHashesSet.isSubsetOf(new Set(blockProposal.txHashes.map(t => t.toString())))) {
51
+ // We cannot request txs that are not part of the block
52
+ if (!missingHashesSet.isSubsetOf(new Set(blockTxsSource.txHashes.map(t => t.toString())))) {
46
53
  return undefined;
47
54
  }
48
55
 
49
- const missingIndices = blockProposal.txHashes
56
+ const missingIndices = blockTxsSource.txHashes
50
57
  .map((hash, idx) => (missingHashesSet.has(hash.toString()) ? idx : -1))
51
58
  .filter(i => i != -1);
52
59
 
53
- const requestBitVector = BitVector.init(blockProposal.txHashes.length, missingIndices);
60
+ const requestBitVector = BitVector.init(blockTxsSource.txHashes.length, missingIndices);
54
61
  const hashes = includeFullTxHashes ? new TxHashArray(...missingTxHashes) : new TxHashArray();
55
62
 
56
- return new BlockTxsRequest(blockProposal.archive, hashes, requestBitVector);
63
+ return new BlockTxsRequest(blockTxsSource.archive, hashes, requestBitVector);
57
64
  }
58
65
 
59
66
  /**
@@ -63,11 +70,11 @@ export class BlockTxsRequest {
63
70
  */
64
71
  static fromBuffer(buffer: Buffer | BufferReader): BlockTxsRequest {
65
72
  const reader = BufferReader.asReader(buffer);
66
- const blockHash = Fr.fromBuffer(reader);
73
+ const archiveRoot = Fr.fromBuffer(reader);
67
74
  const txHashes = TxHashArray.fromBuffer(reader);
68
75
  const txIndices = BitVector.fromBuffer(reader);
69
76
 
70
- return new BlockTxsRequest(blockHash, txHashes, txIndices);
77
+ return new BlockTxsRequest(archiveRoot, txHashes, txIndices);
71
78
  }
72
79
 
73
80
  /**
@@ -75,7 +82,7 @@ export class BlockTxsRequest {
75
82
  * @returns Buffer representation of the BlockTxRequest object
76
83
  */
77
84
  toBuffer(): Buffer {
78
- return serializeToBuffer([this.blockHash, this.txHashes.toBuffer(), this.txIndices.toBuffer()]);
85
+ return serializeToBuffer([this.archiveRoot, this.txHashes.toBuffer(), this.txIndices.toBuffer()]);
79
86
  }
80
87
  }
81
88
 
@@ -84,7 +91,7 @@ export class BlockTxsRequest {
84
91
  */
85
92
  export class BlockTxsResponse {
86
93
  constructor(
87
- readonly blockHash: Fr,
94
+ readonly archiveRoot: Fr,
88
95
  readonly txs: TxArray, // List of transactions we requested and peer has
89
96
  // BitVector indicating which txs from the proposal are available at the peer
90
97
  // 1 means the tx is available, 0 means it is not
@@ -98,11 +105,11 @@ export class BlockTxsResponse {
98
105
  */
99
106
  static fromBuffer(buffer: Buffer | BufferReader): BlockTxsResponse {
100
107
  const reader = BufferReader.asReader(buffer);
101
- const blockHash = Fr.fromBuffer(reader);
108
+ const archiveRoot = Fr.fromBuffer(reader);
102
109
  const txs = TxArray.fromBuffer(reader);
103
110
  const txIndices = BitVector.fromBuffer(reader);
104
111
 
105
- return new BlockTxsResponse(blockHash, txs, txIndices);
112
+ return new BlockTxsResponse(archiveRoot, txs, txIndices);
106
113
  }
107
114
 
108
115
  /**
@@ -112,10 +119,26 @@ export class BlockTxsResponse {
112
119
  * @returns Buffer representation of the BlockTxResponse object
113
120
  */
114
121
  toBuffer(): Buffer {
115
- return serializeToBuffer([this.blockHash, this.txs.toBuffer(), this.txIndices.toBuffer()]);
122
+ return serializeToBuffer([this.archiveRoot, this.txs.toBuffer(), this.txIndices.toBuffer()]);
116
123
  }
117
124
 
118
125
  static empty(): BlockTxsResponse {
119
126
  return new BlockTxsResponse(Fr.ZERO, new TxArray(), BitVector.init(0, []));
120
127
  }
121
128
  }
129
+
130
+ /**
131
+ * Calculate the expected response size for a BLOCK_TXS request.
132
+ * @param requestBuffer - The serialized request buffer containing BlockTxsRequest
133
+ * @returns Expected response size in KB
134
+ */
135
+ export function calculateBlockTxsResponseSize(requestBuffer: Buffer): number {
136
+ try {
137
+ const request = BlockTxsRequest.fromBuffer(requestBuffer);
138
+ const requestedTxCount = request.txIndices.getTrueIndices().length;
139
+ return requestedTxCount * MAX_TX_SIZE_KB + 1; // +1 KB overhead for serialization
140
+ } catch {
141
+ // If we can't parse the request, fall back to allowing a single transaction response
142
+ return MAX_TX_SIZE_KB + 1;
143
+ }
144
+ }
@@ -1,4 +1,5 @@
1
1
  import { chunk } from '@aztec/foundation/collection';
2
+ import { MAX_TX_SIZE_KB } from '@aztec/stdlib/p2p';
2
3
  import { TxArray, TxHash, TxHashArray } from '@aztec/stdlib/tx';
3
4
 
4
5
  import type { PeerId } from '@libp2p/interface';
@@ -55,3 +56,24 @@ export function reqRespTxHandler(mempools: MemPools): ReqRespSubProtocolHandler
55
56
  export function chunkTxHashesRequest(hashes: TxHash[], chunkSize = 1): Array<TxHashArray> {
56
57
  return chunk(hashes, chunkSize).map(chunk => new TxHashArray(...chunk));
57
58
  }
59
+
60
+ /**
61
+ * Calculate the expected response size for a TX request.
62
+ * @param requestBuffer - The serialized request buffer containing TxHashArray
63
+ * @returns Expected response size in KB
64
+ */
65
+ export function calculateTxResponseSize(requestBuffer: Buffer): number {
66
+ try {
67
+ const txHashes = TxHashArray.fromBuffer(requestBuffer);
68
+ // TxHashArray.fromBuffer returns empty array on parse failure, so check for that
69
+ if (txHashes.length === 0 && requestBuffer.length > 0) {
70
+ // If we got an empty array but had a non-empty buffer, parsing likely failed
71
+ // Fall back to allowing a single transaction response
72
+ return MAX_TX_SIZE_KB + 1;
73
+ }
74
+ return Math.max(txHashes.length, 1) * MAX_TX_SIZE_KB + 1; // +1 KB overhead, at least 1 tx
75
+ } catch {
76
+ // If we can't parse the request, fall back to allowing a single transaction response
77
+ return MAX_TX_SIZE_KB + 1;
78
+ }
79
+ }
@@ -36,6 +36,7 @@ import {
36
36
  type ReqRespSubProtocolValidators,
37
37
  type SubProtocolMap,
38
38
  responseFromBuffer,
39
+ subProtocolSizeCalculators,
39
40
  } from './interface.js';
40
41
  import { ReqRespMetrics } from './metrics.js';
41
42
  import {
@@ -437,6 +438,9 @@ export class ReqResp implements ReqRespInterface {
437
438
  try {
438
439
  this.metrics.recordRequestSent(subProtocol);
439
440
 
441
+ // Calculate expected response size based on the request payload
442
+ const expectedSizeKb = subProtocolSizeCalculators[subProtocol](payload);
443
+
440
444
  this.logger.trace(`Sending request to peer ${peerId.toString()} on sub protocol ${subProtocol}`);
441
445
  stream = await this.connectionSampler.dialProtocol(peerId, subProtocol, dialTimeout);
442
446
  this.logger.trace(
@@ -444,11 +448,14 @@ export class ReqResp implements ReqRespInterface {
444
448
  );
445
449
 
446
450
  const timeoutErr = new IndividualReqRespTimeoutError();
451
+ // Create a wrapper to pass the expected size to readMessage
452
+ const readMessageWithSizeLimit = (source: AsyncIterable<Uint8ArrayList>) =>
453
+ this.readMessage(source, expectedSizeKb);
447
454
  const [_, resp] = await executeTimeout(
448
455
  signal =>
449
456
  Promise.all([
450
457
  pipeline([payload], stream!.sink, { signal }),
451
- pipeline(stream!.source, this.readMessage.bind(this), { signal }),
458
+ pipeline(stream!.source, readMessageWithSizeLimit, { signal }),
452
459
  ]),
453
460
  this.individualRequestTimeoutMs,
454
461
  () => timeoutErr,
@@ -510,8 +517,11 @@ export class ReqResp implements ReqRespInterface {
510
517
  * The message is split into two components
511
518
  * - The first chunk should contain a control byte, indicating the status of the response see `ReqRespStatus`
512
519
  * - The second chunk should contain the response data
520
+ *
521
+ * @param source - The async iterable source of data chunks
522
+ * @param maxSizeKb - Optional maximum expected size in KB for the decompressed response
513
523
  */
514
- private async readMessage(source: AsyncIterable<Uint8ArrayList>): Promise<ReqRespResponse> {
524
+ private async readMessage(source: AsyncIterable<Uint8ArrayList>, maxSizeKb?: number): Promise<ReqRespResponse> {
515
525
  let status: ReqRespStatus | undefined;
516
526
  const chunks: Uint8Array[] = [];
517
527
 
@@ -536,7 +546,7 @@ export class ReqResp implements ReqRespInterface {
536
546
  }
537
547
 
538
548
  const messageData = Buffer.concat(chunks);
539
- const message: Buffer = this.snappyTransform.inboundTransformData(messageData);
549
+ const message: Buffer = this.snappyTransform.inboundTransformData(messageData, undefined, maxSizeKb);
540
550
 
541
551
  return {
542
552
  status: status ?? ReqRespStatus.UNKNOWN,
@@ -1,3 +1,4 @@
1
+ import type { SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
2
3
  import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
3
4
  import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore, Gossipable } from '@aztec/stdlib/p2p';
@@ -43,6 +44,32 @@ export type P2PCheckpointReceivedCallback = (
43
44
 
44
45
  export type AuthReceivedCallback = (peerId: PeerId, authRequest: AuthRequest) => Promise<AuthResponse | undefined>;
45
46
 
47
+ /** Minimal info passed to the duplicate proposal callback. */
48
+ export type DuplicateProposalInfo = {
49
+ slot: SlotNumber;
50
+ proposer: EthAddress;
51
+ type: 'checkpoint' | 'block';
52
+ };
53
+
54
+ /**
55
+ * Callback for when a duplicate proposal is detected (equivocation).
56
+ * Invoked on the first duplicate (when count goes from 1 to 2).
57
+ */
58
+ export type P2PDuplicateProposalCallback = (info: DuplicateProposalInfo) => void;
59
+
60
+ /** Minimal info passed to the duplicate attestation callback. */
61
+ export type DuplicateAttestationInfo = {
62
+ slot: SlotNumber;
63
+ attester: EthAddress;
64
+ };
65
+
66
+ /**
67
+ * Callback for when a duplicate attestation is detected (equivocation).
68
+ * A validator signing attestations for different proposals at the same slot.
69
+ * Invoked on the first duplicate (when count goes from 1 to 2).
70
+ */
71
+ export type P2PDuplicateAttestationCallback = (info: DuplicateAttestationInfo) => void;
72
+
46
73
  /**
47
74
  * The interface for a P2P service implementation.
48
75
  */
@@ -86,6 +113,19 @@ export interface P2PService {
86
113
 
87
114
  registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback): void;
88
115
 
116
+ /**
117
+ * Registers a callback invoked when a duplicate proposal is detected (equivocation).
118
+ * The callback is triggered on the first duplicate (when count goes from 1 to 2).
119
+ */
120
+ registerDuplicateProposalCallback(callback: P2PDuplicateProposalCallback): void;
121
+
122
+ /**
123
+ * Registers a callback invoked when a duplicate attestation is detected (equivocation).
124
+ * A validator signing attestations for different proposals at the same slot.
125
+ * The callback is triggered on the first duplicate (when count goes from 1 to 2).
126
+ */
127
+ registerDuplicateAttestationCallback(callback: P2PDuplicateAttestationCallback): void;
128
+
89
129
  getEnr(): ENR | undefined;
90
130
 
91
131
  getPeers(includePending?: boolean): PeerInfo[];