@aztec/p2p 0.0.1-commit.0c875d939 → 0.0.1-commit.10bd49492

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 (290) hide show
  1. package/dest/client/factory.d.ts +7 -7
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +24 -28
  4. package/dest/client/interface.d.ts +10 -19
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +7 -18
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +47 -96
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
  10. package/dest/config.d.ts +28 -15
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +76 -37
  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/mem_pools/attestation_pool/attestation_pool.d.ts +1 -1
  17. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  18. package/dest/mem_pools/attestation_pool/attestation_pool.js +5 -1
  19. package/dest/mem_pools/instrumentation.d.ts +4 -2
  20. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  21. package/dest/mem_pools/instrumentation.js +16 -14
  22. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  23. package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
  24. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  25. package/dest/mem_pools/tx_pool/priority.js +4 -3
  26. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  27. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
  29. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -1
  30. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +9 -0
  32. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  33. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  35. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +3 -3
  36. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  37. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  38. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  39. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  40. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  42. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  43. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  45. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +4 -4
  46. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +5 -5
  47. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  48. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +12 -6
  50. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  51. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  53. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  54. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  56. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  57. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  58. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  59. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  60. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  61. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  62. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +18 -6
  63. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
  65. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +46 -14
  66. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +99 -17
  68. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +5 -2
  69. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +38 -46
  71. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +6 -3
  72. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  73. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +9 -5
  74. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -5
  75. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  76. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +285 -149
  77. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  78. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  79. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  80. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  81. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  82. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  83. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  84. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  85. package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
  86. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  87. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  88. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  89. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  90. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  91. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  92. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  93. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  94. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  95. package/dest/msg_validators/tx_validator/factory.d.ts +125 -6
  96. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  97. package/dest/msg_validators/tx_validator/factory.js +226 -58
  98. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  99. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  100. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  101. package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
  102. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  103. package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
  104. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  105. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  106. package/dest/msg_validators/tx_validator/index.js +2 -0
  107. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  108. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  110. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  111. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  112. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  113. package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
  114. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
  116. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
  117. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  118. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  119. package/dest/services/dummy_service.d.ts +4 -4
  120. package/dest/services/dummy_service.d.ts.map +1 -1
  121. package/dest/services/dummy_service.js +4 -4
  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 +9 -8
  125. package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
  126. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  127. package/dest/services/gossipsub/topic_score_params.js +32 -10
  128. package/dest/services/libp2p/libp2p_service.d.ts +16 -13
  129. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  130. package/dest/services/libp2p/libp2p_service.js +111 -93
  131. package/dest/services/peer-manager/metrics.d.ts +3 -1
  132. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  133. package/dest/services/peer-manager/metrics.js +6 -0
  134. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  135. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  136. package/dest/services/peer-manager/peer_manager.js +2 -1
  137. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
  138. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  139. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +19 -46
  140. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
  141. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  142. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
  143. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  144. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
  145. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +17 -11
  146. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  147. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +49 -15
  148. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  149. package/dest/services/reqresp/reqresp.d.ts +1 -1
  150. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  151. package/dest/services/reqresp/reqresp.js +2 -1
  152. package/dest/services/service.d.ts +5 -3
  153. package/dest/services/service.d.ts.map +1 -1
  154. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
  155. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  156. package/dest/services/tx_collection/fast_tx_collection.js +39 -33
  157. package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
  158. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  159. package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
  160. package/dest/services/tx_collection/file_store_tx_source.d.ts +15 -6
  161. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  162. package/dest/services/tx_collection/file_store_tx_source.js +47 -16
  163. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  164. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  165. package/dest/services/tx_collection/instrumentation.js +2 -1
  166. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  167. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  168. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  169. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  170. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  171. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  172. package/dest/services/tx_collection/slow_tx_collection.d.ts +2 -2
  173. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  174. package/dest/services/tx_collection/slow_tx_collection.js +10 -8
  175. package/dest/services/tx_collection/tx_collection.d.ts +5 -4
  176. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  177. package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
  178. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  179. package/dest/services/tx_collection/tx_collection_sink.js +13 -22
  180. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  181. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  182. package/dest/services/tx_collection/tx_source.js +19 -2
  183. package/dest/services/tx_file_store/tx_file_store.js +1 -1
  184. package/dest/services/tx_provider.d.ts +3 -3
  185. package/dest/services/tx_provider.d.ts.map +1 -1
  186. package/dest/services/tx_provider.js +4 -4
  187. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  188. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  189. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  190. package/dest/test-helpers/mock-pubsub.d.ts +4 -4
  191. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  192. package/dest/test-helpers/mock-pubsub.js +8 -2
  193. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  194. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  195. package/dest/test-helpers/reqresp-nodes.js +2 -2
  196. package/dest/test-helpers/testbench-utils.d.ts +6 -3
  197. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  198. package/dest/test-helpers/testbench-utils.js +3 -2
  199. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  200. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  201. package/dest/testbench/p2p_client_testbench_worker.js +15 -14
  202. package/dest/testbench/worker_client_manager.d.ts +3 -1
  203. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  204. package/dest/testbench/worker_client_manager.js +6 -2
  205. package/dest/util.d.ts +3 -3
  206. package/dest/util.d.ts.map +1 -1
  207. package/package.json +14 -14
  208. package/src/client/factory.ts +35 -49
  209. package/src/client/interface.ts +11 -20
  210. package/src/client/p2p_client.ts +48 -126
  211. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +20 -11
  212. package/src/config.ts +108 -43
  213. package/src/errors/tx-pool.error.ts +12 -0
  214. package/src/mem_pools/attestation_pool/attestation_pool.ts +5 -4
  215. package/src/mem_pools/instrumentation.ts +17 -13
  216. package/src/mem_pools/tx_pool/README.md +1 -1
  217. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  218. package/src/mem_pools/tx_pool/priority.ts +6 -3
  219. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
  220. package/src/mem_pools/tx_pool_v2/README.md +10 -2
  221. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +11 -0
  222. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  223. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +3 -3
  224. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  225. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  226. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  227. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -4
  228. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
  229. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +12 -9
  230. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  231. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  232. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  233. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  234. package/src/mem_pools/tx_pool_v2/interfaces.ts +18 -6
  235. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +141 -25
  236. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -46
  237. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +15 -7
  238. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +318 -145
  239. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
  240. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
  241. package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
  242. package/src/msg_validators/tx_validator/README.md +115 -0
  243. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
  244. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  245. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  246. package/src/msg_validators/tx_validator/factory.ts +366 -77
  247. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  248. package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
  249. package/src/msg_validators/tx_validator/index.ts +2 -0
  250. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  251. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  252. package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
  253. package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
  254. package/src/services/dummy_service.ts +6 -6
  255. package/src/services/encoding.ts +7 -7
  256. package/src/services/gossipsub/README.md +29 -14
  257. package/src/services/gossipsub/topic_score_params.ts +49 -13
  258. package/src/services/libp2p/libp2p_service.ts +122 -101
  259. package/src/services/peer-manager/metrics.ts +7 -0
  260. package/src/services/peer-manager/peer_manager.ts +2 -1
  261. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +20 -48
  262. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
  263. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
  264. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +63 -24
  265. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  266. package/src/services/reqresp/reqresp.ts +3 -1
  267. package/src/services/service.ts +11 -2
  268. package/src/services/tx_collection/fast_tx_collection.ts +51 -30
  269. package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
  270. package/src/services/tx_collection/file_store_tx_source.ts +61 -17
  271. package/src/services/tx_collection/instrumentation.ts +7 -1
  272. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  273. package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
  274. package/src/services/tx_collection/slow_tx_collection.ts +8 -9
  275. package/src/services/tx_collection/tx_collection.ts +4 -3
  276. package/src/services/tx_collection/tx_collection_sink.ts +15 -29
  277. package/src/services/tx_collection/tx_source.ts +22 -3
  278. package/src/services/tx_file_store/tx_file_store.ts +1 -1
  279. package/src/services/tx_provider.ts +2 -2
  280. package/src/test-helpers/make-test-p2p-clients.ts +1 -3
  281. package/src/test-helpers/mock-pubsub.ts +13 -6
  282. package/src/test-helpers/reqresp-nodes.ts +3 -6
  283. package/src/test-helpers/testbench-utils.ts +4 -3
  284. package/src/testbench/p2p_client_testbench_worker.ts +24 -20
  285. package/src/testbench/worker_client_manager.ts +13 -5
  286. package/src/util.ts +8 -2
  287. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  288. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  289. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  290. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
@@ -9,6 +9,7 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
9
9
  import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
10
10
  import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
11
11
  import { BlockHeader, Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx';
12
+ import type { TelemetryClient } from '@aztec/telemetry-client';
12
13
 
13
14
  import { TxArchive } from './archive/index.js';
14
15
  import { DeletedPool } from './deleted_pool.js';
@@ -22,8 +23,12 @@ import {
22
23
  LowPriorityPreAddRule,
23
24
  NullifierConflictRule,
24
25
  type PoolOperations,
26
+ type PreAddContext,
25
27
  type PreAddPoolAccess,
28
+ TxPoolRejectionCode,
29
+ type TxPoolRejectionError,
26
30
  } from './eviction/index.js';
31
+ import { TxPoolV2Instrumentation } from './instrumentation.js';
27
32
  import {
28
33
  type AddTxsResult,
29
34
  DEFAULT_TX_POOL_V2_CONFIG,
@@ -40,6 +45,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
40
45
  export interface TxPoolV2Callbacks {
41
46
  onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
42
47
  onTxsRemoved: (txHashes: string[] | bigint[]) => void;
48
+ onTxsMined: (txHashes: string[]) => void;
43
49
  }
44
50
 
45
51
  /**
@@ -66,6 +72,8 @@ export class TxPoolV2Impl {
66
72
  #deletedPool: DeletedPool;
67
73
  #evictionManager: EvictionManager;
68
74
  #dateProvider: DateProvider;
75
+ #instrumentation: TxPoolV2Instrumentation;
76
+ #evictedTxHashes: Set<string> = new Set();
69
77
  #log: Logger;
70
78
  #callbacks: TxPoolV2Callbacks;
71
79
 
@@ -74,6 +82,7 @@ export class TxPoolV2Impl {
74
82
  archiveStore: AztecAsyncKVStore,
75
83
  deps: TxPoolV2Dependencies,
76
84
  callbacks: TxPoolV2Callbacks,
85
+ telemetry: TelemetryClient,
77
86
  config: Partial<TxPoolV2Config> = {},
78
87
  dateProvider: DateProvider,
79
88
  log: Logger,
@@ -89,6 +98,7 @@ export class TxPoolV2Impl {
89
98
  this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
90
99
  this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
91
100
  this.#dateProvider = dateProvider;
101
+ this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
92
102
  this.#log = log;
93
103
  this.#callbacks = callbacks;
94
104
 
@@ -171,13 +181,42 @@ export class TxPoolV2Impl {
171
181
  this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
172
182
  }
173
183
 
174
- async addPendingTxs(txs: Tx[], opts: { source?: string }): Promise<AddTxsResult> {
184
+ async addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
175
185
  const accepted: TxHash[] = [];
176
186
  const ignored: TxHash[] = [];
177
187
  const rejected: TxHash[] = [];
188
+ const errors = new Map<string, TxPoolRejectionError>();
178
189
  const acceptedPending = new Set<string>();
179
190
 
191
+ // Phase 1: Pre-compute all throwable I/O outside the transaction.
192
+ // If any pre-computation throws, the entire call fails before mutations happen.
193
+ const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
194
+
195
+ const validator = await this.#createTxValidator();
196
+
197
+ for (const tx of txs) {
198
+ const txHash = tx.getTxHash();
199
+ const txHashStr = txHash.toString();
200
+
201
+ const meta = await buildTxMetaData(tx);
202
+ const minedBlockId = await this.#getMinedBlockId(txHash);
203
+
204
+ // Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
205
+ let isValid = true;
206
+ if (!minedBlockId) {
207
+ isValid = await this.#validateMeta(meta, validator);
208
+ }
209
+
210
+ precomputed.set(txHashStr, { meta, minedBlockId, isValid });
211
+ }
212
+
213
+ // Phase 2: Apply mutations inside the transaction using only pre-computed results,
214
+ // in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
180
215
  const poolAccess = this.#createPreAddPoolAccess();
216
+ const preAddContext: PreAddContext | undefined =
217
+ opts.feeComparisonOnly !== undefined
218
+ ? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
219
+ : undefined;
181
220
 
182
221
  await this.#store.transactionAsync(async () => {
183
222
  for (const tx of txs) {
@@ -190,30 +229,46 @@ export class TxPoolV2Impl {
190
229
  continue;
191
230
  }
192
231
 
193
- // Check mined status first (applies to all paths)
194
- const minedBlockId = await this.#getMinedBlockId(txHash);
232
+ const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
195
233
  const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
196
234
 
197
235
  if (minedBlockId) {
198
236
  // Already mined - add directly (protection already set if pre-protected)
199
- await this.#addTx(tx, { mined: minedBlockId }, opts);
237
+ await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
200
238
  accepted.push(txHash);
201
239
  } else if (preProtectedSlot !== undefined) {
202
240
  // Pre-protected and not mined - add as protected (bypass validation)
203
- await this.#addTx(tx, { protected: preProtectedSlot }, opts);
241
+ await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
204
242
  accepted.push(txHash);
243
+ } else if (!isValid) {
244
+ // Failed pre-computed validation
245
+ rejected.push(txHash);
205
246
  } else {
206
- // Regular pending tx - validate and run pre-add rules
207
- const result = await this.#tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored);
247
+ // Regular pending tx - run pre-add rules using pre-computed metadata
248
+ const result = await this.#tryAddRegularPendingTx(
249
+ tx,
250
+ meta,
251
+ opts,
252
+ poolAccess,
253
+ acceptedPending,
254
+ ignored,
255
+ errors,
256
+ preAddContext,
257
+ );
208
258
  if (result.status === 'accepted') {
209
259
  acceptedPending.add(txHashStr);
210
- } else if (result.status === 'rejected') {
211
- rejected.push(txHash);
212
260
  } else {
213
261
  ignored.push(txHash);
214
262
  }
215
263
  }
216
264
  }
265
+
266
+ // Run post-add eviction rules for pending txs (inside transaction for atomicity)
267
+ if (acceptedPending.size > 0) {
268
+ const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
269
+ const uniqueFeePayers = new Set<string>(feePayers);
270
+ await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
271
+ }
217
272
  });
218
273
 
219
274
  // Build final accepted list for pending txs (excludes intra-batch evictions)
@@ -221,80 +276,100 @@ export class TxPoolV2Impl {
221
276
  accepted.push(TxHash.fromString(txHashStr));
222
277
  }
223
278
 
224
- // Run post-add eviction rules for pending txs
225
- if (acceptedPending.size > 0) {
226
- const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
227
- const uniqueFeePayers = new Set<string>(feePayers);
228
- await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
279
+ // Record metrics
280
+ if (ignored.length > 0) {
281
+ this.#instrumentation.recordIgnored(ignored.length);
282
+ }
283
+ if (rejected.length > 0) {
284
+ this.#instrumentation.recordRejected(rejected.length);
229
285
  }
230
286
 
231
- return { accepted, ignored, rejected };
287
+ return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
232
288
  }
233
289
 
234
- /** Validates and adds a regular pending tx. Returns status. */
290
+ /** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
235
291
  async #tryAddRegularPendingTx(
236
292
  tx: Tx,
293
+ precomputedMeta: TxMetaData,
237
294
  opts: { source?: string },
238
295
  poolAccess: PreAddPoolAccess,
239
296
  acceptedPending: Set<string>,
240
297
  ignored: TxHash[],
241
- ): Promise<{ status: 'accepted' | 'ignored' | 'rejected' }> {
242
- const txHash = tx.getTxHash();
243
- const txHashStr = txHash.toString();
244
-
245
- // Build metadata and validate using metadata
246
- const meta = await buildTxMetaData(tx);
247
- if (!(await this.#validateMeta(meta))) {
248
- return { status: 'rejected' };
249
- }
298
+ errors: Map<string, TxPoolRejectionError>,
299
+ preAddContext?: PreAddContext,
300
+ ): Promise<{ status: 'accepted' | 'ignored' }> {
301
+ const txHashStr = tx.getTxHash().toString();
250
302
 
251
303
  // Run pre-add rules
252
- const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
304
+ const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
253
305
 
254
306
  if (preAddResult.shouldIgnore) {
255
- this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
307
+ this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
308
+ if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
309
+ errors.set(txHashStr, preAddResult.reason);
310
+ }
256
311
  return { status: 'ignored' };
257
312
  }
258
313
 
259
- // Evict conflicts
260
- for (const evictHashStr of preAddResult.txHashesToEvict) {
261
- await this.#deleteTx(evictHashStr);
262
- this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
263
- evictedTxHash: evictHashStr,
264
- replacementTxHash: txHashStr,
265
- });
266
- if (acceptedPending.has(evictHashStr)) {
267
- // Evicted tx was from this batch - mark as ignored in result
268
- acceptedPending.delete(evictHashStr);
269
- ignored.push(TxHash.fromString(evictHashStr));
314
+ // Evict conflicts, grouped by rule name for metrics
315
+ if (preAddResult.evictions && preAddResult.evictions.length > 0) {
316
+ const byReason = new Map<string, string[]>();
317
+ for (const { txHash: evictHash, reason } of preAddResult.evictions) {
318
+ const group = byReason.get(reason);
319
+ if (group) {
320
+ group.push(evictHash);
321
+ } else {
322
+ byReason.set(reason, [evictHash]);
323
+ }
324
+ }
325
+ for (const [reason, hashes] of byReason) {
326
+ await this.#evictTxs(hashes, reason);
327
+ }
328
+ for (const evictHashStr of preAddResult.txHashesToEvict) {
329
+ this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
330
+ evictedTxHash: evictHashStr,
331
+ replacementTxHash: txHashStr,
332
+ });
333
+ if (acceptedPending.has(evictHashStr)) {
334
+ // Evicted tx was from this batch - mark as ignored in result
335
+ acceptedPending.delete(evictHashStr);
336
+ ignored.push(TxHash.fromString(evictHashStr));
337
+ }
270
338
  }
271
339
  }
272
340
 
341
+ // Randomly drop the transaction for testing purposes (report as accepted so it propagates)
342
+ if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
343
+ this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
344
+ return { status: 'accepted' };
345
+ }
346
+
273
347
  // Add the transaction
274
- await this.#addTx(tx, 'pending', opts);
348
+ await this.#addTx(tx, 'pending', opts, precomputedMeta);
275
349
  return { status: 'accepted' };
276
350
  }
277
351
 
278
- async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored' | 'rejected'> {
352
+ async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
279
353
  const txHashStr = tx.getTxHash().toString();
280
354
 
281
355
  // Check if already in pool
282
356
  if (this.#indices.has(txHashStr)) {
357
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
283
358
  return 'ignored';
284
359
  }
285
360
 
286
- // Build metadata and validate using metadata
361
+ // Build metadata and check pre-add rules
287
362
  const meta = await buildTxMetaData(tx);
288
- const validationResult = await this.#validateMeta(meta, undefined, 'can add pending');
289
- if (validationResult !== true) {
290
- return 'rejected';
291
- }
292
-
293
- // Use pre-add rules
294
363
  const poolAccess = this.#createPreAddPoolAccess();
295
364
  const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
296
365
 
297
- return preAddResult.shouldIgnore ? 'ignored' : 'accepted';
366
+ if (preAddResult.shouldIgnore) {
367
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
368
+ reason: preAddResult.reason?.message ?? 'no reason provided',
369
+ });
370
+ return 'ignored';
371
+ }
372
+ return 'accepted';
298
373
  }
299
374
 
300
375
  async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
@@ -327,22 +402,57 @@ export class TxPoolV2Impl {
327
402
  });
328
403
  }
329
404
 
330
- protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
405
+ async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
331
406
  const slotNumber = block.globalVariables.slotNumber;
332
407
  const missing: TxHash[] = [];
408
+ let softDeletedHits = 0;
409
+ let missingPreviouslyEvicted = 0;
333
410
 
334
- for (const txHash of txHashes) {
335
- const txHashStr = txHash.toString();
411
+ await this.#store.transactionAsync(async () => {
412
+ for (const txHash of txHashes) {
413
+ const txHashStr = txHash.toString();
336
414
 
337
- if (this.#indices.has(txHashStr)) {
338
- // Update protection for existing tx
339
- this.#indices.updateProtection(txHashStr, slotNumber);
340
- } else {
341
- // Pre-record protection for tx we don't have yet
342
- this.#indices.setProtection(txHashStr, slotNumber);
343
- missing.push(txHash);
415
+ if (this.#indices.has(txHashStr)) {
416
+ // Update protection for existing tx
417
+ this.#indices.updateProtection(txHashStr, slotNumber);
418
+ } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
419
+ // Resurrect soft-deleted tx as protected
420
+ const buffer = await this.#txsDB.getAsync(txHashStr);
421
+ if (buffer) {
422
+ const tx = Tx.fromBuffer(buffer);
423
+ await this.#addTx(tx, { protected: slotNumber });
424
+ softDeletedHits++;
425
+ } else {
426
+ // Data missing despite soft-delete flag — treat as truly missing
427
+ this.#indices.setProtection(txHashStr, slotNumber);
428
+ missing.push(txHash);
429
+ }
430
+ } else {
431
+ // Truly missing — pre-record protection for tx we don't have yet
432
+ this.#indices.setProtection(txHashStr, slotNumber);
433
+ missing.push(txHash);
434
+ if (this.#evictedTxHashes.has(txHashStr)) {
435
+ missingPreviouslyEvicted++;
436
+ }
437
+ }
344
438
  }
439
+ });
440
+
441
+ // Record metrics
442
+ if (softDeletedHits > 0) {
443
+ this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
444
+ }
445
+ if (missing.length > 0) {
446
+ this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
447
+ this.#instrumentation.recordMissingOnProtect(missing.length);
345
448
  }
449
+ if (missingPreviouslyEvicted > 0) {
450
+ this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
451
+ }
452
+
453
+ this.#log.info(
454
+ `Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
455
+ );
346
456
 
347
457
  return missing;
348
458
  }
@@ -387,57 +497,67 @@ export class TxPoolV2Impl {
387
497
  }
388
498
  }
389
499
 
390
- // Step 4: Mark txs as mined (only those we have in the pool)
391
- for (const meta of found) {
392
- this.#indices.markAsMined(meta, blockId);
393
- await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
394
- }
500
+ await this.#store.transactionAsync(async () => {
501
+ // Step 4: Mark txs as mined (only those we have in the pool)
502
+ for (const meta of found) {
503
+ this.#indices.markAsMined(meta, blockId);
504
+ await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
505
+ }
395
506
 
396
- // Step 5: Run eviction rules (remove pending txs with conflicting nullifiers/expired timestamps)
397
- await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
507
+ // Step 5: Run post-event eviction rules (inside transaction for atomicity)
508
+ await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
509
+ });
510
+
511
+ if (found.length > 0) {
512
+ this.#callbacks.onTxsMined(found.map(m => m.txHash));
513
+ }
398
514
 
399
515
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
400
516
  }
401
517
 
402
518
  async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
403
- // Step 0: Clean up slot-deleted txs from previous slots
404
- await this.#deletedPool.cleanupSlotDeleted(slotNumber);
519
+ await this.#store.transactionAsync(async () => {
520
+ // Step 0: Clean up slot-deleted txs from previous slots
521
+ await this.#deletedPool.cleanupSlotDeleted(slotNumber);
405
522
 
406
- // Step 1: Find expired protected txs
407
- const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
523
+ // Step 1: Find expired protected txs
524
+ const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
408
525
 
409
- // Step 2: Clear protection for all expired entries (including those without metadata)
410
- this.#indices.clearProtection(expiredProtected);
526
+ // Step 2: Clear protection for all expired entries (including those without metadata)
527
+ this.#indices.clearProtection(expiredProtected);
411
528
 
412
- // Step 3: Filter to only txs that have metadata and are not mined
413
- const txsToRestore = this.#indices.filterRestorable(expiredProtected);
414
- if (txsToRestore.length === 0) {
415
- return;
416
- }
529
+ // Step 3: Filter to only txs that have metadata and are not mined
530
+ const txsToRestore = this.#indices.filterRestorable(expiredProtected);
531
+ if (txsToRestore.length === 0) {
532
+ this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
533
+ return;
534
+ }
417
535
 
418
- this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
536
+ this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
419
537
 
420
- // Step 4: Validate for pending pool
421
- const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
538
+ // Step 4: Validate for pending pool
539
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
422
540
 
423
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
424
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
541
+ // Step 5: Resolve nullifier conflicts and add winners to pending indices
542
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
425
543
 
426
- // Step 6: Delete invalid and evicted txs
427
- await this.#deleteTxsBatch([...invalid, ...toEvict]);
544
+ // Step 6: Delete invalid txs and evict conflict losers
545
+ await this.#deleteTxsBatch(invalid);
546
+ await this.#evictTxs(toEvict, 'NullifierConflict');
428
547
 
429
- // Step 7: Run eviction rules (enforce pool size limit)
430
- if (added.length > 0) {
431
- const feePayers = added.map(meta => meta.feePayer);
432
- const uniqueFeePayers = new Set<string>(feePayers);
433
- await this.#evictionManager.evictAfterNewTxs(
434
- added.map(m => m.txHash),
435
- [...uniqueFeePayers],
436
- );
437
- }
548
+ // Step 7: Run eviction rules (enforce pool size limit)
549
+ if (added.length > 0) {
550
+ const feePayers = added.map(meta => meta.feePayer);
551
+ const uniqueFeePayers = new Set<string>(feePayers);
552
+ await this.#evictionManager.evictAfterNewTxs(
553
+ added.map(m => m.txHash),
554
+ [...uniqueFeePayers],
555
+ );
556
+ }
557
+ });
438
558
  }
439
559
 
440
- async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
560
+ async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
441
561
  // Step 1: Find transactions mined after the prune point
442
562
  const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
443
563
  if (txsToUnmine.length === 0) {
@@ -447,46 +567,60 @@ export class TxPoolV2Impl {
447
567
 
448
568
  this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
449
569
 
450
- // Step 2: Mark ALL un-mined txs with their original mined block number
451
- // This ensures they get soft-deleted if removed later, and only hard-deleted
452
- // when their original mined block is finalized
453
- await this.#deletedPool.markFromPrunedBlock(
454
- txsToUnmine.map(m => ({
455
- txHash: m.txHash,
456
- minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
457
- })),
458
- );
570
+ await this.#store.transactionAsync(async () => {
571
+ // Step 2: Mark ALL un-mined txs with their original mined block number
572
+ // This ensures they get soft-deleted if removed later, and only hard-deleted
573
+ // when their original mined block is finalized
574
+ await this.#deletedPool.markFromPrunedBlock(
575
+ txsToUnmine.map(m => ({
576
+ txHash: m.txHash,
577
+ minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
578
+ })),
579
+ );
459
580
 
460
- // Step 3: Unmine - clear mined status from metadata
461
- for (const meta of txsToUnmine) {
462
- this.#indices.markAsUnmined(meta);
463
- }
581
+ // Step 3: Unmine - clear mined status from metadata
582
+ for (const meta of txsToUnmine) {
583
+ this.#indices.markAsUnmined(meta);
584
+ }
585
+
586
+ // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
587
+ if (options?.deleteAllTxs) {
588
+ const allTxHashes = txsToUnmine.map(m => m.txHash);
589
+ await this.#deleteTxsBatch(allTxHashes);
590
+ this.#log.info(
591
+ `Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
592
+ );
593
+ return;
594
+ }
464
595
 
465
- // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
466
- const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
596
+ // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
597
+ const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
467
598
 
468
- // Step 4: Validate for pending pool
469
- const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
599
+ // Step 5: Validate for pending pool
600
+ const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
470
601
 
471
- // Step 6: Resolve nullifier conflicts and add winners to pending indices
472
- const { toEvict } = this.#applyNullifierConflictResolution(valid);
602
+ // Step 6: Resolve nullifier conflicts and add winners to pending indices
603
+ const { toEvict } = this.#applyNullifierConflictResolution(valid);
473
604
 
474
- // Step 7: Delete invalid and evicted txs
475
- await this.#deleteTxsBatch([...invalid, ...toEvict]);
605
+ // Step 7: Delete invalid txs and evict conflict losers
606
+ await this.#deleteTxsBatch(invalid);
607
+ await this.#evictTxs(toEvict, 'NullifierConflict');
476
608
 
477
- this.#log.info(
478
- `Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
479
- { txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
480
- );
609
+ this.#log.info(
610
+ `Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
611
+ { txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
612
+ );
481
613
 
482
- // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
483
- // This handles cases like existing pending txs with invalid fee payer balances
484
- await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
614
+ // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
615
+ // This handles cases like existing pending txs with invalid fee payer balances
616
+ await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
617
+ });
485
618
  }
486
619
 
487
620
  async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
488
- // Delete failed txs
489
- await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
621
+ await this.#store.transactionAsync(async () => {
622
+ await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
623
+ });
490
624
 
491
625
  this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
492
626
  }
@@ -497,27 +631,29 @@ export class TxPoolV2Impl {
497
631
  // Step 1: Find mined txs at or before finalized block
498
632
  const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
499
633
 
500
- // Step 2: Collect mined txs for archiving (before deletion)
501
- const txsToArchive: Tx[] = [];
502
- if (this.#archive.isEnabled()) {
503
- for (const txHashStr of minedTxsToFinalize) {
504
- const buffer = await this.#txsDB.getAsync(txHashStr);
505
- if (buffer) {
506
- txsToArchive.push(Tx.fromBuffer(buffer));
634
+ await this.#store.transactionAsync(async () => {
635
+ // Step 2: Collect mined txs for archiving (before deletion)
636
+ const txsToArchive: Tx[] = [];
637
+ if (this.#archive.isEnabled()) {
638
+ for (const txHashStr of minedTxsToFinalize) {
639
+ const buffer = await this.#txsDB.getAsync(txHashStr);
640
+ if (buffer) {
641
+ txsToArchive.push(Tx.fromBuffer(buffer));
642
+ }
507
643
  }
508
644
  }
509
- }
510
645
 
511
- // Step 3: Delete mined txs from active pool
512
- await this.#deleteTxsBatch(minedTxsToFinalize);
646
+ // Step 3: Delete mined txs from active pool
647
+ await this.#deleteTxsBatch(minedTxsToFinalize);
513
648
 
514
- // Step 4: Finalize soft-deleted txs
515
- await this.#deletedPool.finalizeBlock(blockNumber);
649
+ // Step 4: Finalize soft-deleted txs
650
+ await this.#deletedPool.finalizeBlock(blockNumber);
516
651
 
517
- // Step 5: Archive mined txs
518
- if (txsToArchive.length > 0) {
519
- await this.#archive.archiveTxs(txsToArchive);
520
- }
652
+ // Step 5: Archive mined txs
653
+ if (txsToArchive.length > 0) {
654
+ await this.#archive.archiveTxs(txsToArchive);
655
+ }
656
+ });
521
657
 
522
658
  if (minedTxsToFinalize.length > 0) {
523
659
  this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
@@ -637,8 +773,17 @@ export class TxPoolV2Impl {
637
773
 
638
774
  // === Metrics ===
639
775
 
640
- countTxs(): { pending: number; protected: number; mined: number } {
641
- return this.#indices.countTxs();
776
+ countTxs(): {
777
+ pending: number;
778
+ protected: number;
779
+ mined: number;
780
+ softDeleted: number;
781
+ totalMetadataBytes: number;
782
+ } {
783
+ return {
784
+ ...this.#indices.countTxs(),
785
+ softDeleted: this.#deletedPool.getSoftDeletedCount(),
786
+ };
642
787
  }
643
788
 
644
789
  // ============================================================================
@@ -653,9 +798,10 @@ export class TxPoolV2Impl {
653
798
  tx: Tx,
654
799
  state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
655
800
  opts: { source?: string } = {},
801
+ precomputedMeta?: TxMetaData,
656
802
  ): Promise<TxMetaData> {
657
803
  const txHashStr = tx.getTxHash().toString();
658
- const meta = await buildTxMetaData(tx);
804
+ const meta = precomputedMeta ?? (await buildTxMetaData(tx));
659
805
  meta.receivedAt = this.#dateProvider.now();
660
806
 
661
807
  await this.#txsDB.set(txHashStr, tx.toBuffer());
@@ -672,9 +818,11 @@ export class TxPoolV2Impl {
672
818
  }
673
819
 
674
820
  const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
675
- this.#log.verbose(`Added ${stateStr} tx ${txHashStr}`, {
821
+ this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
676
822
  eventName: 'tx-added-to-pool',
823
+ txHash: txHashStr,
677
824
  state: stateStr,
825
+ source: opts.source,
678
826
  });
679
827
 
680
828
  return meta;
@@ -702,6 +850,29 @@ export class TxPoolV2Impl {
702
850
  }
703
851
  }
704
852
 
853
+ /** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
854
+ async #evictTxs(txHashes: string[], reason: string): Promise<void> {
855
+ if (txHashes.length === 0) {
856
+ return;
857
+ }
858
+ this.#instrumentation.recordEvictions(txHashes.length, reason);
859
+ for (const txHashStr of txHashes) {
860
+ this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
861
+ this.#addToEvictedCache(txHashStr);
862
+ }
863
+ await this.#deleteTxsBatch(txHashes);
864
+ }
865
+
866
+ /** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
867
+ #addToEvictedCache(txHashStr: string): void {
868
+ if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
869
+ // FIFO eviction: remove the first (oldest) entry
870
+ const oldest = this.#evictedTxHashes.values().next().value!;
871
+ this.#evictedTxHashes.delete(oldest);
872
+ }
873
+ this.#evictedTxHashes.add(txHashStr);
874
+ }
875
+
705
876
  // ============================================================================
706
877
  // PRIVATE HELPERS - Validation & Conflict Resolution
707
878
  // ============================================================================
@@ -857,7 +1028,9 @@ export class TxPoolV2Impl {
857
1028
  if (preAddResult.shouldIgnore) {
858
1029
  // Transaction rejected - mark for deletion from DB
859
1030
  rejected.push(meta.txHash);
860
- this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason}`);
1031
+ this.#log.debug(
1032
+ `Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
1033
+ );
861
1034
  continue;
862
1035
  }
863
1036
 
@@ -893,7 +1066,7 @@ export class TxPoolV2Impl {
893
1066
  getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
894
1067
  getPendingTxCount: () => this.#indices.getPendingTxCount(),
895
1068
  getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
896
- deleteTxs: (txHashes: string[]) => this.#deleteTxsBatch(txHashes),
1069
+ deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
897
1070
  };
898
1071
  }
899
1072