@aztec/p2p 0.0.1-commit.a89ec08 → 0.0.1-commit.aa0c64f

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 (427) hide show
  1. package/README.md +7 -6
  2. package/dest/bootstrap/bootstrap.d.ts +1 -1
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  4. package/dest/bootstrap/bootstrap.js +22 -6
  5. package/dest/client/factory.d.ts +5 -4
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +33 -23
  8. package/dest/client/interface.d.ts +48 -11
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +34 -19
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +105 -44
  13. package/dest/config.d.ts +147 -111
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +78 -32
  16. package/dest/errors/p2p-service.error.d.ts +9 -0
  17. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  18. package/dest/errors/p2p-service.error.js +10 -0
  19. package/dest/errors/reqresp.error.d.ts +9 -16
  20. package/dest/errors/reqresp.error.d.ts.map +1 -1
  21. package/dest/errors/reqresp.error.js +10 -17
  22. package/dest/index.d.ts +1 -2
  23. package/dest/index.d.ts.map +1 -1
  24. package/dest/index.js +0 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +101 -59
  26. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool.js +274 -197
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +224 -65
  31. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  32. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  33. package/dest/mem_pools/attestation_pool/mocks.js +6 -4
  34. package/dest/mem_pools/index.d.ts +1 -2
  35. package/dest/mem_pools/index.d.ts.map +1 -1
  36. package/dest/mem_pools/instrumentation.d.ts +12 -5
  37. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  38. package/dest/mem_pools/instrumentation.js +38 -17
  39. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -5
  40. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
  42. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -3
  43. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +6 -6
  45. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  48. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  49. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  50. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  51. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  52. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  53. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +39 -9
  54. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
  56. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +9 -7
  57. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  58. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
  59. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +15 -1
  60. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +55 -41
  62. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -3
  63. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +20 -6
  65. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +17 -3
  66. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +225 -118
  68. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +10 -3
  69. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  70. package/dest/msg_validators/attestation_validator/attestation_validator.js +38 -15
  71. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  72. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  73. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  74. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +8 -3
  75. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  76. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +2 -2
  77. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +8 -3
  78. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  79. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +8 -2
  80. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +25 -3
  81. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  82. package/dest/msg_validators/proposal_validator/proposal_validator.js +85 -15
  83. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  84. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  85. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +8 -15
  86. package/dest/msg_validators/tx_validator/allowed_public_setup.js +3 -3
  87. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  88. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  89. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  90. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  91. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  92. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  93. package/dest/msg_validators/tx_validator/data_validator.js +1 -0
  94. package/dest/msg_validators/tx_validator/factory.d.ts +14 -15
  95. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  96. package/dest/msg_validators/tx_validator/factory.js +29 -16
  97. package/dest/msg_validators/tx_validator/gas_validator.d.ts +47 -10
  98. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  99. package/dest/msg_validators/tx_validator/gas_validator.js +65 -48
  100. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  101. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  102. package/dest/msg_validators/tx_validator/index.js +2 -0
  103. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  104. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  105. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  106. package/dest/msg_validators/tx_validator/phases_validator.js +2 -2
  107. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  108. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  110. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  111. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  112. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  113. package/dest/services/data_store.d.ts +1 -1
  114. package/dest/services/data_store.d.ts.map +1 -1
  115. package/dest/services/data_store.js +5 -5
  116. package/dest/services/discv5/discV5_service.d.ts +13 -2
  117. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  118. package/dest/services/discv5/discV5_service.js +119 -23
  119. package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
  120. package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
  121. package/dest/services/discv5/persisted_enr_store.js +145 -0
  122. package/dest/services/dummy_service.d.ts +15 -15
  123. package/dest/services/dummy_service.d.ts.map +1 -1
  124. package/dest/services/dummy_service.js +15 -16
  125. package/dest/services/encoding.d.ts +19 -6
  126. package/dest/services/encoding.d.ts.map +1 -1
  127. package/dest/services/encoding.js +25 -15
  128. package/dest/services/gossipsub/topic_score_params.d.ts +6 -12
  129. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  130. package/dest/services/gossipsub/topic_score_params.js +4 -14
  131. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  132. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  133. package/dest/services/libp2p/instrumentation.js +14 -0
  134. package/dest/services/libp2p/libp2p_service.d.ts +45 -47
  135. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  136. package/dest/services/libp2p/libp2p_service.js +409 -303
  137. package/dest/services/peer-manager/metrics.d.ts +3 -1
  138. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  139. package/dest/services/peer-manager/metrics.js +6 -0
  140. package/dest/services/peer-manager/peer_manager.d.ts +20 -3
  141. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  142. package/dest/services/peer-manager/peer_manager.js +83 -26
  143. package/dest/services/peer-manager/peer_scoring.d.ts +34 -2
  144. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  145. package/dest/services/peer-manager/peer_scoring.js +102 -13
  146. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -8
  147. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  148. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +94 -122
  149. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +10 -6
  150. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  151. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  152. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  153. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  154. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  155. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  156. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  157. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  158. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  159. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  160. package/dest/services/reqresp/config.d.ts +15 -3
  161. package/dest/services/reqresp/config.d.ts.map +1 -1
  162. package/dest/services/reqresp/config.js +11 -0
  163. package/dest/services/reqresp/interface.d.ts +16 -18
  164. package/dest/services/reqresp/interface.d.ts.map +1 -1
  165. package/dest/services/reqresp/interface.js +10 -20
  166. package/dest/services/reqresp/metrics.d.ts +1 -1
  167. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  168. package/dest/services/reqresp/metrics.js +0 -1
  169. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  170. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  171. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  172. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  173. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  174. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
  175. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
  176. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  177. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
  178. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  179. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  180. package/dest/services/reqresp/protocols/index.js +0 -1
  181. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  182. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  183. package/dest/services/reqresp/protocols/tx.js +1 -3
  184. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  185. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  186. package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -13
  187. package/dest/services/reqresp/reqresp.d.ts +7 -29
  188. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  189. package/dest/services/reqresp/reqresp.js +60 -209
  190. package/dest/services/service.d.ts +25 -12
  191. package/dest/services/service.d.ts.map +1 -1
  192. package/dest/services/tx_collection/config.d.ts +2 -23
  193. package/dest/services/tx_collection/config.d.ts.map +1 -1
  194. package/dest/services/tx_collection/config.js +2 -55
  195. package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
  196. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  197. package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
  198. package/dest/services/tx_collection/index.d.ts +2 -3
  199. package/dest/services/tx_collection/index.d.ts.map +1 -1
  200. package/dest/services/tx_collection/index.js +0 -1
  201. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  202. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  203. package/dest/services/tx_collection/instrumentation.js +0 -2
  204. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  205. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  206. package/dest/services/tx_collection/request_tracker.js +84 -0
  207. package/dest/services/tx_collection/tx_collection.d.ts +36 -55
  208. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  209. package/dest/services/tx_collection/tx_collection.js +275 -119
  210. package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
  211. package/dest/services/tx_collection/tx_collection_sink.js +2 -2
  212. package/dest/services/tx_collection/tx_source.d.ts +1 -1
  213. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  214. package/dest/services/tx_collection/tx_source.js +4 -1
  215. package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
  216. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  217. package/dest/services/tx_file_store/tx_file_store.js +4 -14
  218. package/dest/services/tx_provider.d.ts +3 -1
  219. package/dest/services/tx_provider.d.ts.map +1 -1
  220. package/dest/services/tx_provider.js +3 -0
  221. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  222. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  223. package/dest/test-helpers/make-test-p2p-clients.js +5 -2
  224. package/dest/test-helpers/mock-pubsub.d.ts +23 -9
  225. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  226. package/dest/test-helpers/mock-pubsub.js +44 -44
  227. package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
  228. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  229. package/dest/test-helpers/reqresp-nodes.js +16 -18
  230. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  231. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  232. package/dest/test-helpers/test_tx_provider.js +3 -0
  233. package/dest/test-helpers/testbench-utils.d.ts +15 -14
  234. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  235. package/dest/test-helpers/testbench-utils.js +47 -14
  236. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  237. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  238. package/dest/testbench/p2p_client_testbench_worker.js +102 -40
  239. package/dest/testbench/worker_client_manager.d.ts +10 -6
  240. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  241. package/dest/testbench/worker_client_manager.js +53 -10
  242. package/dest/util.d.ts +12 -7
  243. package/dest/util.d.ts.map +1 -1
  244. package/dest/util.js +35 -14
  245. package/dest/versioning.d.ts +3 -6
  246. package/dest/versioning.d.ts.map +1 -1
  247. package/dest/versioning.js +3 -24
  248. package/package.json +16 -16
  249. package/src/bootstrap/bootstrap.ts +17 -3
  250. package/src/client/factory.ts +50 -25
  251. package/src/client/interface.ts +44 -17
  252. package/src/client/p2p_client.ts +125 -77
  253. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  254. package/src/config.ts +156 -44
  255. package/src/errors/p2p-service.error.ts +11 -0
  256. package/src/errors/reqresp.error.ts +13 -19
  257. package/src/index.ts +0 -1
  258. package/src/mem_pools/attestation_pool/attestation_pool.ts +329 -243
  259. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +244 -69
  260. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  261. package/src/mem_pools/index.ts +0 -3
  262. package/src/mem_pools/instrumentation.ts +27 -17
  263. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
  264. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
  265. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
  266. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  267. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  268. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  269. package/src/mem_pools/tx_pool_v2/interfaces.ts +38 -8
  270. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +24 -12
  271. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +62 -41
  272. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +23 -6
  273. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +250 -122
  274. package/src/msg_validators/attestation_validator/README.md +1 -1
  275. package/src/msg_validators/attestation_validator/attestation_validator.ts +46 -14
  276. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +15 -7
  277. package/src/msg_validators/proposal_validator/README.md +4 -4
  278. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +15 -3
  279. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +26 -3
  280. package/src/msg_validators/proposal_validator/proposal_validator.ts +95 -12
  281. package/src/msg_validators/tx_validator/README.md +13 -3
  282. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
  283. package/src/msg_validators/tx_validator/allowed_public_setup.ts +3 -3
  284. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  285. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  286. package/src/msg_validators/tx_validator/data_validator.ts +2 -0
  287. package/src/msg_validators/tx_validator/factory.ts +37 -20
  288. package/src/msg_validators/tx_validator/gas_validator.ts +99 -54
  289. package/src/msg_validators/tx_validator/index.ts +2 -0
  290. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  291. package/src/msg_validators/tx_validator/phases_validator.ts +2 -2
  292. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  293. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  294. package/src/services/data_store.ts +5 -13
  295. package/src/services/discv5/discV5_service.ts +126 -14
  296. package/src/services/discv5/persisted_enr_store.ts +158 -0
  297. package/src/services/dummy_service.ts +20 -39
  298. package/src/services/encoding.ts +28 -20
  299. package/src/services/gossipsub/README.md +33 -11
  300. package/src/services/gossipsub/topic_score_params.ts +9 -18
  301. package/src/services/libp2p/instrumentation.ts +14 -0
  302. package/src/services/libp2p/libp2p_service.ts +457 -341
  303. package/src/services/peer-manager/metrics.ts +7 -0
  304. package/src/services/peer-manager/peer_manager.ts +91 -25
  305. package/src/services/peer-manager/peer_scoring.ts +102 -8
  306. package/src/services/reqresp/README.md +2 -37
  307. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  308. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +91 -137
  309. package/src/services/reqresp/batch-tx-requester/interface.ts +13 -5
  310. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  311. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  312. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  313. package/src/services/reqresp/config.ts +19 -2
  314. package/src/services/reqresp/interface.ts +21 -47
  315. package/src/services/reqresp/metrics.ts +0 -1
  316. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  317. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -30
  318. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
  319. package/src/services/reqresp/protocols/index.ts +0 -1
  320. package/src/services/reqresp/protocols/tx.ts +1 -3
  321. package/src/services/reqresp/rate-limiter/rate_limits.ts +3 -13
  322. package/src/services/reqresp/reqresp.ts +71 -252
  323. package/src/services/service.ts +31 -28
  324. package/src/services/tx_collection/config.ts +3 -80
  325. package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
  326. package/src/services/tx_collection/index.ts +1 -6
  327. package/src/services/tx_collection/instrumentation.ts +1 -7
  328. package/src/services/tx_collection/request_tracker.ts +127 -0
  329. package/src/services/tx_collection/tx_collection.ts +331 -176
  330. package/src/services/tx_collection/tx_collection_sink.ts +2 -2
  331. package/src/services/tx_collection/tx_source.ts +2 -1
  332. package/src/services/tx_file_store/tx_file_store.ts +5 -17
  333. package/src/services/tx_provider.ts +5 -0
  334. package/src/test-helpers/make-test-p2p-clients.ts +4 -1
  335. package/src/test-helpers/mock-pubsub.ts +46 -60
  336. package/src/test-helpers/reqresp-nodes.ts +13 -23
  337. package/src/test-helpers/test_tx_provider.ts +5 -0
  338. package/src/test-helpers/testbench-utils.ts +62 -28
  339. package/src/testbench/p2p_client_testbench_worker.ts +110 -57
  340. package/src/testbench/worker_client_manager.ts +61 -21
  341. package/src/util.ts +33 -18
  342. package/src/versioning.ts +3 -33
  343. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  344. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  345. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -304
  346. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  347. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  348. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  349. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  350. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  351. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  352. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  353. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  354. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  355. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  356. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  357. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  358. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  359. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  360. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  361. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  362. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  363. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  364. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  365. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  366. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  367. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  368. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  369. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  370. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  371. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  372. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  373. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  374. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  375. package/dest/mem_pools/tx_pool/index.js +0 -2
  376. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  377. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  378. package/dest/mem_pools/tx_pool/priority.js +0 -15
  379. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  380. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  381. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  382. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  383. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  384. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  385. package/dest/msg_validators/clock_tolerance.d.ts +0 -21
  386. package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
  387. package/dest/msg_validators/clock_tolerance.js +0 -37
  388. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  389. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  390. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  391. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  392. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  393. package/dest/services/reqresp/protocols/block.js +0 -32
  394. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -54
  395. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  396. package/dest/services/tx_collection/fast_tx_collection.js +0 -327
  397. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  398. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  399. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  400. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -49
  401. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  402. package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
  403. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
  404. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  405. package/dest/services/tx_collection/slow_tx_collection.js +0 -211
  406. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -345
  407. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  408. package/src/mem_pools/tx_pool/README.md +0 -270
  409. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  410. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  411. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  412. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  413. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  414. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  415. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  416. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  417. package/src/mem_pools/tx_pool/index.ts +0 -2
  418. package/src/mem_pools/tx_pool/priority.ts +0 -20
  419. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  420. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  421. package/src/msg_validators/clock_tolerance.ts +0 -51
  422. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  423. package/src/services/reqresp/protocols/block.ts +0 -37
  424. package/src/services/tx_collection/fast_tx_collection.ts +0 -387
  425. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
  426. package/src/services/tx_collection/proposal_tx_collector.ts +0 -113
  427. package/src/services/tx_collection/slow_tx_collection.ts +0 -266
@@ -20,6 +20,7 @@ import type {
20
20
  TxPoolV2Events,
21
21
  } from './interfaces.js';
22
22
  import type { TxState } from './tx_metadata.js';
23
+ import type { MinedTxInfo } from './tx_pool_v2_impl.js';
23
24
  import { TxPoolV2Impl } from './tx_pool_v2_impl.js';
24
25
 
25
26
  /**
@@ -56,15 +57,23 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
56
57
  // Create callbacks that the impl uses to notify us about events and metrics
57
58
  const callbacks = {
58
59
  onTxsAdded: (txs: Tx[], opts: { source?: string }) => {
59
- this.#metrics?.transactionsAdded(txs);
60
60
  this.emit('txs-added', { txs, ...opts });
61
61
  },
62
62
  onTxsRemoved: (txHashes: string[] | bigint[]) => {
63
- this.#metrics?.transactionsRemoved(txHashes);
64
63
  // Convert to TxHash objects for the event
65
64
  const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : TxHash.fromBigInt(h)));
66
65
  this.emit('txs-removed', { txHashes: hashes });
67
66
  },
67
+ onTxsMined: (minedTxs: MinedTxInfo[]) => {
68
+ // Pending-to-mined delay is derived from the tx's persisted receivedAt at the mined
69
+ // transition (see TxPoolV2Impl.handleMinedBlock), not the add/remove timestamp map —
70
+ // so eviction no longer pollutes MEMPOOL_TX_MINED_DELAY.
71
+ for (const { minedDelayMs } of minedTxs) {
72
+ if (minedDelayMs !== undefined) {
73
+ this.#metrics?.recordMinedDelay(minedDelayMs);
74
+ }
75
+ }
76
+ },
68
77
  };
69
78
 
70
79
  // Create the implementation
@@ -107,6 +116,10 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
107
116
  return this.#queue.put(() => this.#impl.prepareForSlot(slotNumber));
108
117
  }
109
118
 
119
+ unprotectTxs(txHashes: TxHash[], slotNumber: SlotNumber): Promise<void> {
120
+ return this.#queue.put(() => this.#impl.unprotectTxs(txHashes, slotNumber));
121
+ }
122
+
110
123
  handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
111
124
  return this.#queue.put(() => this.#impl.handlePrunedBlocks(latestBlock, options));
112
125
  }
@@ -121,12 +134,12 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
121
134
 
122
135
  // === Queries ===
123
136
 
124
- getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
125
- return this.#queue.put(() => this.#impl.getTxByHash(txHash));
137
+ getTxByHash(txHash: TxHash, opts?: { includeProof?: boolean }): Promise<Tx | undefined> {
138
+ return this.#queue.put(() => this.#impl.getTxByHash(txHash, opts));
126
139
  }
127
140
 
128
- getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
129
- return this.#queue.put(() => this.#impl.getTxsByHash(txHashes));
141
+ getTxsByHash(txHashes: TxHash[], opts?: { includeProof?: boolean }): Promise<(Tx | undefined)[]> {
142
+ return this.#queue.put(() => this.#impl.getTxsByHash(txHashes, opts));
130
143
  }
131
144
 
132
145
  hasTxs(txHashes: TxHash[]): Promise<boolean[]> {
@@ -149,6 +162,10 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
149
162
  return this.#queue.put(() => Promise.resolve(this.#impl.getPendingTxCount()));
150
163
  }
151
164
 
165
+ hasEligiblePendingTxs(minCount: number): Promise<boolean> {
166
+ return this.#queue.put(() => Promise.resolve(this.#impl.hasEligiblePendingTxs(minCount)));
167
+ }
168
+
152
169
  getMinedTxHashes(): Promise<[TxHash, L2BlockId][]> {
153
170
  return this.#queue.put(() => Promise.resolve(this.#impl.getMinedTxHashes()));
154
171
  }
@@ -1,4 +1,5 @@
1
1
  import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { FifoSet } from '@aztec/foundation/fifo-set';
2
3
  import type { Logger } from '@aztec/foundation/log';
3
4
  import type { DateProvider } from '@aztec/foundation/timer';
4
5
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
@@ -17,6 +18,7 @@ import {
17
18
  EvictionManager,
18
19
  FeePayerBalanceEvictionRule,
19
20
  FeePayerBalancePreAddRule,
21
+ InsufficientFeePerGasEvictionRule,
20
22
  InvalidTxsAfterMiningRule,
21
23
  InvalidTxsAfterReorgRule,
22
24
  LowPriorityEvictionRule,
@@ -39,12 +41,28 @@ import {
39
41
  import { type TxMetaData, type TxState, buildTxMetaData, checkNullifierConflict } from './tx_metadata.js';
40
42
  import { TxPoolIndices } from './tx_pool_indices.js';
41
43
 
44
+ /**
45
+ * Maximum number of full transactions to load into memory at once when finalizing a block.
46
+ * Bounds peak memory while archiving and hard-deleting mined txs (~23k txs/epoch at 10 TPS would
47
+ * otherwise OOM the node).
48
+ */
49
+ const FINALIZE_BLOCK_CHUNK_SIZE = 100;
50
+
42
51
  /**
43
52
  * Callbacks for the implementation to notify the outer class about events and metrics.
44
53
  */
54
+ /** A tx that has just transitioned to mined, with the time it spent in the pool. */
55
+ export interface MinedTxInfo {
56
+ txHash: string;
57
+ /** Wall-clock ms from receipt into the pool to being marked mined. Undefined when the
58
+ * receive time is unknown (e.g. a tx hydrated from the DB on restart, receivedAt === 0). */
59
+ minedDelayMs?: number;
60
+ }
61
+
45
62
  export interface TxPoolV2Callbacks {
46
63
  onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
47
64
  onTxsRemoved: (txHashes: string[] | bigint[]) => void;
65
+ onTxsMined: (minedTxs: MinedTxInfo[]) => void;
48
66
  }
49
67
 
50
68
  /**
@@ -55,7 +73,10 @@ export interface TxPoolV2Callbacks {
55
73
  export class TxPoolV2Impl {
56
74
  // === Persistence ===
57
75
  #store: AztecAsyncKVStore;
76
+ /** Tx data without its proof. Proofs live in #proofsDB so a tx can be read without loading its proof. */
58
77
  #txsDB: AztecAsyncMap<string, Buffer>;
78
+ /** Tx proofs, keyed by tx hash. Written and deleted in lockstep with #txsDB. */
79
+ #proofsDB: AztecAsyncMap<string, Buffer>;
59
80
 
60
81
  // === Dependencies ===
61
82
  #l2BlockSource: L2BlockSource;
@@ -73,7 +94,7 @@ export class TxPoolV2Impl {
73
94
  #evictionManager: EvictionManager;
74
95
  #dateProvider: DateProvider;
75
96
  #instrumentation: TxPoolV2Instrumentation;
76
- #evictedTxHashes: Set<string> = new Set();
97
+ #evictedTxHashes: FifoSet<string>;
77
98
  #log: Logger;
78
99
  #callbacks: TxPoolV2Callbacks;
79
100
 
@@ -89,6 +110,7 @@ export class TxPoolV2Impl {
89
110
  ) {
90
111
  this.#store = store;
91
112
  this.#txsDB = store.openMap('txs');
113
+ this.#proofsDB = store.openMap('tx_proofs');
92
114
 
93
115
  this.#l2BlockSource = deps.l2BlockSource;
94
116
  this.#worldStateSynchronizer = deps.worldStateSynchronizer;
@@ -96,8 +118,9 @@ export class TxPoolV2Impl {
96
118
  this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
97
119
 
98
120
  this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
121
+ this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
99
122
  this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
100
- this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
123
+ this.#deletedPool = new DeletedPool(store, txHashStr => this.#deleteTxData(txHashStr), log);
101
124
  this.#dateProvider = dateProvider;
102
125
  this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
103
126
  this.#log = log;
@@ -115,6 +138,7 @@ export class TxPoolV2Impl {
115
138
 
116
139
  // Post-event eviction rules (run after events to check ALL pending txs)
117
140
  this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
141
+ this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
118
142
  this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
119
143
  this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
120
144
  // LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
@@ -137,46 +161,74 @@ export class TxPoolV2Impl {
137
161
  // Step 0: Hydrate deleted pool state
138
162
  await this.#deletedPool.hydrateFromDatabase();
139
163
 
140
- // Step 1: Load all transactions from DB (excluding soft-deleted)
141
- const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
164
+ // Step 1: Stream txs from DB, building metadata and mined status one at a time.
165
+ const minedMetas: TxMetaData[] = [];
166
+ const pendingMetas: TxMetaData[] = [];
167
+ const deserializationErrors: string[] = [];
142
168
 
143
- // Step 2: Check mined status for each tx
144
- await this.#markMinedStatusBatch(loaded.map(l => l.meta));
169
+ for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
170
+ // Skip soft-deleted transactions - they stay in DB but not in indices
171
+ if (this.#deletedPool.isSoftDeleted(txHashStr)) {
172
+ continue;
173
+ }
145
174
 
146
- // Step 3: Partition by mined status
147
- const mined: TxMetaData[] = [];
148
- const nonMined: { tx: Tx; meta: TxMetaData }[] = [];
149
- for (const entry of loaded) {
150
- if (entry.meta.minedL2BlockId !== undefined) {
151
- mined.push(entry.meta);
175
+ let meta: TxMetaData;
176
+ let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
177
+ try {
178
+ const tx = Tx.fromBuffer(buffer);
179
+ // Resolve allowed-setup-calls and the tx effect concurrently
180
+ // getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
181
+ // its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
182
+ const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
183
+ this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
184
+ return undefined;
185
+ });
186
+ const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
187
+ this.#checkAllowedSetupCalls(tx),
188
+ txEffectPromise,
189
+ ]);
190
+ meta = await buildTxMetaData(tx, allowedSetupCalls);
191
+ txEffect = fetchedTxEffect;
192
+ } catch (err) {
193
+ this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
194
+ deserializationErrors.push(txHashStr);
195
+ continue;
196
+ }
197
+
198
+ if (txEffect) {
199
+ meta.minedL2BlockId = {
200
+ number: txEffect.l2BlockNumber,
201
+ hash: txEffect.l2BlockHash.toString(),
202
+ };
203
+ }
204
+
205
+ if (meta.minedL2BlockId !== undefined) {
206
+ minedMetas.push(meta);
152
207
  } else {
153
- nonMined.push(entry);
208
+ pendingMetas.push(meta);
154
209
  }
155
210
  }
156
211
 
157
- // Step 4: Validate non-mined transactions
158
- const { valid, invalid } = await this.#revalidateMetadata(
159
- nonMined.map(e => e.meta),
160
- 'on startup',
161
- );
212
+ // Step 2: Validate non-mined transactions
213
+ const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
162
214
 
163
- // Step 5: Populate mined indices (these don't need conflict resolution)
164
- for (const meta of mined) {
215
+ // Step 3: Populate mined indices (these don't need conflict resolution)
216
+ for (const meta of minedMetas) {
165
217
  this.#indices.addMined(meta);
166
218
  }
167
219
 
168
- // Step 6: Rebuild pending pool by running pre-add rules for each tx
220
+ // Step 4: Rebuild pending pool by running pre-add rules for each tx
169
221
  // This resolves nullifier conflicts, fee payer balance issues, and pool size limits
170
222
  const { rejected } = await this.#rebuildPendingPool(valid);
171
223
 
172
- // Step 7: Delete invalid and rejected txs from DB only (indices were never populated for these)
224
+ // Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
173
225
  const toDelete = [...deserializationErrors, ...invalid, ...rejected];
174
226
  if (toDelete.length === 0) {
175
227
  return;
176
228
  }
177
229
  await this.#store.transactionAsync(async () => {
178
230
  for (const txHashStr of toDelete) {
179
- await this.#txsDB.delete(txHashStr);
231
+ await this.#deleteTxData(txHashStr);
180
232
  }
181
233
  });
182
234
  this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
@@ -339,6 +391,12 @@ export class TxPoolV2Impl {
339
391
  }
340
392
  }
341
393
 
394
+ // Randomly drop the transaction for testing purposes (report as accepted so it propagates)
395
+ if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
396
+ this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
397
+ return { status: 'accepted' };
398
+ }
399
+
342
400
  // Add the transaction
343
401
  await this.#addTx(tx, 'pending', opts, precomputedMeta);
344
402
  return { status: 'accepted' };
@@ -349,6 +407,7 @@ export class TxPoolV2Impl {
349
407
 
350
408
  // Check if already in pool
351
409
  if (this.#indices.has(txHashStr)) {
410
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
352
411
  return 'ignored';
353
412
  }
354
413
 
@@ -357,7 +416,13 @@ export class TxPoolV2Impl {
357
416
  const poolAccess = this.#createPreAddPoolAccess();
358
417
  const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
359
418
 
360
- return preAddResult.shouldIgnore ? 'ignored' : 'accepted';
419
+ if (preAddResult.shouldIgnore) {
420
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
421
+ reason: preAddResult.reason?.message ?? 'no reason provided',
422
+ });
423
+ return 'ignored';
424
+ }
425
+ return 'accepted';
361
426
  }
362
427
 
363
428
  async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
@@ -409,10 +474,11 @@ export class TxPoolV2Impl {
409
474
  // Update protection for existing tx
410
475
  this.#indices.updateProtection(txHashStr, slotNumber);
411
476
  } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
412
- // Resurrect soft-deleted tx as protected
477
+ // Resurrect soft-deleted tx as protected. Load the proof too: #addTx rewrites both entries, so re-adding
478
+ // a proofless tx would wipe the stored proof.
413
479
  const buffer = await this.#txsDB.getAsync(txHashStr);
414
480
  if (buffer) {
415
- const tx = Tx.fromBuffer(buffer);
481
+ const tx = await this.#loadTxWithProof(txHashStr, buffer);
416
482
  await this.#addTx(tx, { protected: slotNumber });
417
483
  softDeletedHits++;
418
484
  } else {
@@ -501,6 +567,18 @@ export class TxPoolV2Impl {
501
567
  await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
502
568
  });
503
569
 
570
+ if (found.length > 0) {
571
+ // receivedAt is 0 for txs hydrated from the DB on restart (true receive time lost) — leave
572
+ // their delay undefined so the metric isn't polluted by epoch-sized values.
573
+ const now = this.#dateProvider.now();
574
+ this.#callbacks.onTxsMined(
575
+ found.map(m => ({
576
+ txHash: m.txHash,
577
+ minedDelayMs: m.receivedAt > 0 ? now - m.receivedAt : undefined,
578
+ })),
579
+ );
580
+ }
581
+
504
582
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
505
583
  }
506
584
 
@@ -523,29 +601,62 @@ export class TxPoolV2Impl {
523
601
  }
524
602
 
525
603
  this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
604
+ await this.#restoreUnprotectedToPending(txsToRestore, 'during prepareForSlot');
605
+ });
606
+ }
526
607
 
527
- // Step 4: Validate for pending pool
528
- const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
608
+ async unprotectTxs(txHashes: TxHash[], slotNumber: SlotNumber): Promise<void> {
609
+ const hashStrs = txHashes.map(h => h.toString());
529
610
 
530
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
531
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
611
+ await this.#store.transactionAsync(async () => {
612
+ // Only release entries still recorded at this exact slot. A tx that another, still-live proposal
613
+ // raised to a higher slot via updateProtection must keep that protection. Mined txs have no
614
+ // protection entry and so are never matched here.
615
+ const matching = this.#indices.findProtectedTxsAtSlot(hashStrs, slotNumber);
616
+ if (matching.length === 0) {
617
+ this.#log.debug(`Unprotecting txs for slot ${slotNumber}: no matching protections to release`);
618
+ return;
619
+ }
532
620
 
533
- // Step 6: Delete invalid txs and evict conflict losers
534
- await this.#deleteTxsBatch(invalid);
535
- await this.#evictTxs(toEvict, 'NullifierConflict');
621
+ this.#indices.clearProtection(matching);
536
622
 
537
- // Step 7: Run eviction rules (enforce pool size limit)
538
- if (added.length > 0) {
539
- const feePayers = added.map(meta => meta.feePayer);
540
- const uniqueFeePayers = new Set<string>(feePayers);
541
- await this.#evictionManager.evictAfterNewTxs(
542
- added.map(m => m.txHash),
543
- [...uniqueFeePayers],
544
- );
623
+ const txsToRestore = this.#indices.filterRestorable(matching);
624
+ if (txsToRestore.length === 0) {
625
+ return;
545
626
  }
627
+
628
+ this.#log.info(`Unprotecting ${txsToRestore.length} txs from failed proposal at slot ${slotNumber}`);
629
+ await this.#restoreUnprotectedToPending(txsToRestore, 'during unprotectTxs');
546
630
  });
547
631
  }
548
632
 
633
+ /**
634
+ * Returns just-unprotected txs to the pending pool: revalidates them, resolves nullifier
635
+ * conflicts, deletes losers, then enforces the pool size limit. Must run inside a store
636
+ * transaction; callers clear the protection entries before invoking.
637
+ */
638
+ async #restoreUnprotectedToPending(txsToRestore: TxMetaData[], context: string): Promise<void> {
639
+ // Step 1: Validate for pending pool
640
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, context);
641
+
642
+ // Step 2: Resolve nullifier conflicts and add winners to pending indices
643
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
644
+
645
+ // Step 3: Delete invalid txs and evict conflict losers
646
+ await this.#deleteTxsBatch(invalid);
647
+ await this.#evictTxs(toEvict, 'NullifierConflict');
648
+
649
+ // Step 4: Run eviction rules (enforce pool size limit)
650
+ if (added.length > 0) {
651
+ const feePayers = added.map(meta => meta.feePayer);
652
+ const uniqueFeePayers = new Set<string>(feePayers);
653
+ await this.#evictionManager.evictAfterNewTxs(
654
+ added.map(m => m.txHash),
655
+ [...uniqueFeePayers],
656
+ );
657
+ }
658
+ }
659
+
549
660
  async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
550
661
  // Step 1: Find transactions mined after the prune point
551
662
  const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
@@ -617,56 +728,113 @@ export class TxPoolV2Impl {
617
728
  async handleFinalizedBlock(block: BlockHeader): Promise<void> {
618
729
  const blockNumber = block.globalVariables.blockNumber;
619
730
 
620
- // Step 1: Find mined txs at or before finalized block
621
- const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
731
+ // Hold finalized txs for a configurable margin behind the finalized tip so a prover still
732
+ // proving an epoch with already-finalized blocks isn't starved of its txs. 0 deletes at the finalized tip.
733
+ const cutoffBlock = await this.#finalizationCutoffBlock(block);
622
734
 
623
- await this.#store.transactionAsync(async () => {
624
- // Step 2: Collect mined txs for archiving (before deletion)
625
- const txsToArchive: Tx[] = [];
626
- if (this.#archive.isEnabled()) {
627
- for (const txHashStr of minedTxsToFinalize) {
735
+ // Step 1: Find mined txs at or before the cutoff block
736
+ const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(cutoffBlock);
737
+
738
+ // Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
739
+ // mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
740
+ if (this.#archive.isEnabled()) {
741
+ for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
742
+ const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
743
+ const txsToArchive: Tx[] = [];
744
+ for (const txHashStr of chunk) {
628
745
  const buffer = await this.#txsDB.getAsync(txHashStr);
629
746
  if (buffer) {
630
747
  txsToArchive.push(Tx.fromBuffer(buffer));
631
748
  }
632
749
  }
750
+ if (txsToArchive.length > 0) {
751
+ await this.#archive.archiveTxs(txsToArchive);
752
+ }
633
753
  }
754
+ }
634
755
 
635
- // Step 3: Delete mined txs from active pool
756
+ // Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
757
+ // transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
758
+ await this.#store.transactionAsync(async () => {
636
759
  await this.#deleteTxsBatch(minedTxsToFinalize);
637
-
638
- // Step 4: Finalize soft-deleted txs
639
- await this.#deletedPool.finalizeBlock(blockNumber);
640
-
641
- // Step 5: Archive mined txs
642
- if (txsToArchive.length > 0) {
643
- await this.#archive.archiveTxs(txsToArchive);
644
- }
760
+ await this.#deletedPool.finalizeBlock(cutoffBlock);
645
761
  });
646
762
 
647
763
  if (minedTxsToFinalize.length > 0) {
648
- this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
764
+ this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${cutoffBlock}`, {
649
765
  txHashes: minedTxsToFinalize,
766
+ finalizedBlockNumber: blockNumber,
767
+ cutoffBlock,
650
768
  });
651
769
  }
652
770
  }
653
771
 
772
+ /**
773
+ * Resolves the block up to which finalized txs may be deleted, given `keepFinalizedTxsForSlots`.
774
+ * With a margin of 0 this is just the finalized block. Otherwise we keep txs whose block is within
775
+ * the margin (in slots) of the finalized tip: take the target slot `finalizedSlot - margin`, find the
776
+ * latest checkpoint at or before it with a single reverse range query (`limit: 1`), and use that
777
+ * checkpoint's last block as the cutoff. This rounds to a checkpoint boundary, so it can retain slightly
778
+ * more than the configured margin but never less, and never deletes past the finalized block.
779
+ */
780
+ async #finalizationCutoffBlock(block: BlockHeader): Promise<BlockNumber> {
781
+ const keepSlots = this.#config.keepFinalizedTxsForSlots;
782
+ if (keepSlots <= 0) {
783
+ return block.globalVariables.blockNumber;
784
+ }
785
+
786
+ // The goal here really is to ensure we keep transactions long enough for them to be proven.
787
+ // So we could be smart and calculate the number of slots until the end of the proof submission window.
788
+ // Our approach here is a lot simpler however and we just keep transactions for the configured number
789
+ // of slots past L1 finalisation. This means we may keep transactions in the mined pool for longer
790
+ // than strictly necessary.
791
+ const targetSlot = block.getSlot() - keepSlots;
792
+ if (targetSlot < 0) {
793
+ // The margin reaches past genesis: keep everything.
794
+ return BlockNumber(0);
795
+ }
796
+
797
+ const [checkpoint] = await this.#l2BlockSource.getCheckpointsData({
798
+ fromSlot: SlotNumber(targetSlot),
799
+ limit: 1,
800
+ reverse: true,
801
+ });
802
+ // No checkpoint at or before the target slot (e.g. early chain): keep everything.
803
+ return checkpoint ? BlockNumber(checkpoint.startBlock + checkpoint.blockCount - 1) : BlockNumber(0);
804
+ }
805
+
654
806
  // === Query Methods ===
655
807
 
656
- async getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
657
- const buffer = await this.#txsDB.getAsync(txHash.toString());
658
- return buffer ? Tx.fromBuffer(buffer) : undefined;
808
+ async getTxByHash(txHash: TxHash, opts: { includeProof?: boolean } = {}): Promise<Tx | undefined> {
809
+ const txHashStr = txHash.toString();
810
+ const buffer = await this.#txsDB.getAsync(txHashStr);
811
+ if (!buffer) {
812
+ return undefined;
813
+ }
814
+ return opts.includeProof === false ? Tx.fromBuffer(buffer) : this.#loadTxWithProof(txHashStr, buffer);
659
815
  }
660
816
 
661
- async getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
817
+ async getTxsByHash(txHashes: TxHash[], opts: { includeProof?: boolean } = {}): Promise<(Tx | undefined)[]> {
662
818
  const results: (Tx | undefined)[] = [];
663
819
  for (const h of txHashes) {
664
- const buffer = await this.#txsDB.getAsync(h.toString());
665
- results.push(buffer ? Tx.fromBuffer(buffer) : undefined);
820
+ results.push(await this.getTxByHash(h, opts));
666
821
  }
667
822
  return results;
668
823
  }
669
824
 
825
+ /** Deserializes a tx blob loaded from #txsDB together with its separately-stored proof. */
826
+ async #loadTxWithProof(txHashStr: string, buffer: Buffer): Promise<Tx> {
827
+ const proofBuffer = await this.#proofsDB.getAsync(txHashStr);
828
+ if (!proofBuffer) {
829
+ // #addTx always writes a proof entry (an empty proof serializes to a 4-byte sentinel), so a missing entry
830
+ // means the blob/proof invariant is broken. Return the proofless tx but flag it, since a consumer that needs
831
+ // the proof (eg serving peers) would otherwise fail far away from the root cause.
832
+ this.#log.warn(`Missing stored proof for tx ${txHashStr}`, { txHash: txHashStr });
833
+ return Tx.fromBuffer(buffer);
834
+ }
835
+ return Tx.fromBuffers(buffer, proofBuffer);
836
+ }
837
+
670
838
  hasTxs(txHashes: TxHash[]): boolean[] {
671
839
  return txHashes.map(h => {
672
840
  const hashStr = h.toString();
@@ -702,6 +870,11 @@ export class TxPoolV2Impl {
702
870
  return this.#indices.getPendingTxCount();
703
871
  }
704
872
 
873
+ hasEligiblePendingTxs(minCount: number): boolean {
874
+ const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
875
+ return this.#indices.hasEligiblePendingTxs(maxReceivedAt, minCount);
876
+ }
877
+
705
878
  getMinedTxHashes(): [TxHash, L2BlockId][] {
706
879
  return this.#indices.getMinedTxs().map(([hash, blockId]) => [TxHash.fromString(hash), blockId]);
707
880
  }
@@ -745,6 +918,9 @@ export class TxPoolV2Impl {
745
918
  if (config.minTxPoolAgeMs !== undefined) {
746
919
  this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
747
920
  }
921
+ if (config.keepFinalizedTxsForSlots !== undefined) {
922
+ this.#config.keepFinalizedTxsForSlots = config.keepFinalizedTxsForSlots;
923
+ }
748
924
  // Update eviction rules with new config
749
925
  this.#evictionManager.updateConfig(config);
750
926
  }
@@ -793,7 +969,8 @@ export class TxPoolV2Impl {
793
969
  const meta = precomputedMeta ?? (await buildTxMetaData(tx));
794
970
  meta.receivedAt = this.#dateProvider.now();
795
971
 
796
- await this.#txsDB.set(txHashStr, tx.toBuffer());
972
+ await this.#txsDB.set(txHashStr, tx.withoutProof().toBuffer());
973
+ await this.#proofsDB.set(txHashStr, tx.chonkProof.toBuffer());
797
974
  await this.#deletedPool.clearSoftDeleted(txHashStr);
798
975
  this.#callbacks.onTxsAdded([tx], opts);
799
976
 
@@ -832,6 +1009,12 @@ export class TxPoolV2Impl {
832
1009
  await this.#deletedPool.deleteTx(txHashStr);
833
1010
  }
834
1011
 
1012
+ /** Hard-deletes a tx's stored data (tx blob and proof) from the DB. */
1013
+ async #deleteTxData(txHashStr: string): Promise<void> {
1014
+ await this.#txsDB.delete(txHashStr);
1015
+ await this.#proofsDB.delete(txHashStr);
1016
+ }
1017
+
835
1018
  /** Deletes a batch of transactions, emitting callbacks individually for each. */
836
1019
  async #deleteTxsBatch(txHashes: string[]): Promise<void> {
837
1020
  for (const txHashStr of txHashes) {
@@ -847,21 +1030,11 @@ export class TxPoolV2Impl {
847
1030
  this.#instrumentation.recordEvictions(txHashes.length, reason);
848
1031
  for (const txHashStr of txHashes) {
849
1032
  this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
850
- this.#addToEvictedCache(txHashStr);
1033
+ this.#evictedTxHashes.add(txHashStr);
851
1034
  }
852
1035
  await this.#deleteTxsBatch(txHashes);
853
1036
  }
854
1037
 
855
- /** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
856
- #addToEvictedCache(txHashStr: string): void {
857
- if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
858
- // FIFO eviction: remove the first (oldest) entry
859
- const oldest = this.#evictedTxHashes.values().next().value!;
860
- this.#evictedTxHashes.delete(oldest);
861
- }
862
- this.#evictedTxHashes.add(txHashStr);
863
- }
864
-
865
1038
  // ============================================================================
866
1039
  // PRIVATE HELPERS - Validation & Conflict Resolution
867
1040
  // ============================================================================
@@ -956,51 +1129,6 @@ export class TxPoolV2Impl {
956
1129
  };
957
1130
  }
958
1131
 
959
- /** Loads all transactions from the database, returning loaded txs and deserialization errors */
960
- async #loadAllTxsFromDb(): Promise<{
961
- loaded: { tx: Tx; meta: TxMetaData }[];
962
- errors: string[];
963
- }> {
964
- const loaded: { tx: Tx; meta: TxMetaData }[] = [];
965
- const errors: string[] = [];
966
-
967
- for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
968
- // Skip soft-deleted transactions - they stay in DB but not in indices
969
- if (this.#deletedPool.isSoftDeleted(txHashStr)) {
970
- continue;
971
- }
972
-
973
- try {
974
- const tx = Tx.fromBuffer(buffer);
975
- const allowedSetupCalls = await this.#checkAllowedSetupCalls(tx);
976
- const meta = await buildTxMetaData(tx, allowedSetupCalls);
977
- loaded.push({ tx, meta });
978
- } catch (err) {
979
- this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
980
- errors.push(txHashStr);
981
- }
982
- }
983
-
984
- return { loaded, errors };
985
- }
986
-
987
- /** Queries block source and marks mined status on transaction metadata */
988
- async #markMinedStatusBatch(metas: TxMetaData[]): Promise<void> {
989
- for (const meta of metas) {
990
- try {
991
- const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
992
- if (txEffect) {
993
- meta.minedL2BlockId = {
994
- number: txEffect.l2BlockNumber,
995
- hash: txEffect.l2BlockHash.toString(),
996
- };
997
- }
998
- } catch (err) {
999
- this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, { err });
1000
- }
1001
- }
1002
- }
1003
-
1004
1132
  /**
1005
1133
  * Rebuilds the pending pool by processing each tx through pre-add rules.
1006
1134
  * Starts with an empty pending pool and adds txs one by one, resolving conflicts.
@@ -1075,7 +1203,7 @@ export class TxPoolV2Impl {
1075
1203
  const publicStateSource = new DatabasePublicStateSource(db);
1076
1204
  const balance = await publicStateSource.storageRead(
1077
1205
  ProtocolContractAddress.FeeJuice,
1078
- await computeFeePayerBalanceStorageSlot(AztecAddress.fromString(feePayer)),
1206
+ await computeFeePayerBalanceStorageSlot(AztecAddress.fromStringUnsafe(feePayer)),
1079
1207
  );
1080
1208
  return balance.toBigInt();
1081
1209
  },
@@ -24,7 +24,7 @@ This module validates `CheckpointAttestation` gossipsub messages. Attestations a
24
24
  |---|------|-------------|
25
25
  | 8 | Sender recoverable (pool-side) | Silent drop |
26
26
  | 9 | Not a duplicate (same slot + proposalId + signer) | IGNORE |
27
- | 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` = 3 | IGNORE |
27
+ | 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` = 2 | IGNORE |
28
28
 
29
29
  Own attestations added via `addOwnCheckpointAttestations` bypass the per-signer cap.
30
30