@aztec/p2p 0.0.1-commit.7cf39cb55 → 0.0.1-commit.7ffbba4

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 (286) 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 +19 -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 +41 -96
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
  10. package/dest/config.d.ts +22 -15
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +66 -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/attestation_pool/mocks.d.ts +2 -2
  20. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  22. package/dest/mem_pools/instrumentation.d.ts +4 -2
  23. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  24. package/dest/mem_pools/instrumentation.js +16 -14
  25. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  26. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -1
  27. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +9 -0
  29. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  30. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  32. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +3 -3
  33. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  34. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  35. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  36. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  37. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  38. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  39. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  40. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  42. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +4 -4
  43. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +5 -5
  44. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  45. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +12 -6
  47. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  48. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  50. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  51. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  53. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  54. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  56. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  57. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  58. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  59. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +18 -6
  60. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
  62. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +46 -14
  63. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +99 -17
  65. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +5 -2
  66. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +38 -46
  68. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +6 -3
  69. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +9 -5
  71. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -5
  72. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  73. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +277 -148
  74. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  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 +10 -2
  77. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  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 +16 -2
  80. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  81. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  82. package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
  83. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  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 +3 -3
  86. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  87. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  88. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  89. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  90. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  91. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  92. package/dest/msg_validators/tx_validator/factory.d.ts +114 -6
  93. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  94. package/dest/msg_validators/tx_validator/factory.js +219 -58
  95. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  96. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  97. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  98. package/dest/msg_validators/tx_validator/gas_validator.d.ts +58 -3
  99. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  100. package/dest/msg_validators/tx_validator/gas_validator.js +73 -36
  101. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  102. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  103. package/dest/msg_validators/tx_validator/index.js +2 -0
  104. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  105. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  106. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  107. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  108. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  109. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  110. package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
  111. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  112. package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
  113. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
  114. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  116. package/dest/services/dummy_service.d.ts +4 -4
  117. package/dest/services/dummy_service.d.ts.map +1 -1
  118. package/dest/services/dummy_service.js +4 -4
  119. package/dest/services/encoding.d.ts +2 -2
  120. package/dest/services/encoding.d.ts.map +1 -1
  121. package/dest/services/encoding.js +9 -8
  122. package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
  123. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  124. package/dest/services/gossipsub/topic_score_params.js +32 -10
  125. package/dest/services/libp2p/libp2p_service.d.ts +16 -13
  126. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  127. package/dest/services/libp2p/libp2p_service.js +84 -90
  128. package/dest/services/peer-manager/metrics.d.ts +3 -1
  129. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  130. package/dest/services/peer-manager/metrics.js +6 -0
  131. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  132. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  133. package/dest/services/peer-manager/peer_manager.js +2 -1
  134. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
  135. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  136. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +19 -46
  137. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
  138. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  139. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
  140. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  141. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
  142. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +17 -11
  143. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  144. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +49 -15
  145. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  146. package/dest/services/reqresp/reqresp.d.ts +1 -1
  147. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  148. package/dest/services/reqresp/reqresp.js +2 -1
  149. package/dest/services/service.d.ts +5 -3
  150. package/dest/services/service.d.ts.map +1 -1
  151. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
  152. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  153. package/dest/services/tx_collection/fast_tx_collection.js +39 -33
  154. package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
  155. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  156. package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
  157. package/dest/services/tx_collection/file_store_tx_source.d.ts +15 -6
  158. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  159. package/dest/services/tx_collection/file_store_tx_source.js +47 -16
  160. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  161. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  162. package/dest/services/tx_collection/instrumentation.js +2 -1
  163. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  164. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  165. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  166. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  167. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  168. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  169. package/dest/services/tx_collection/slow_tx_collection.d.ts +2 -2
  170. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  171. package/dest/services/tx_collection/slow_tx_collection.js +10 -8
  172. package/dest/services/tx_collection/tx_collection.d.ts +5 -4
  173. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  174. package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
  175. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  176. package/dest/services/tx_collection/tx_collection_sink.js +13 -22
  177. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  178. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  179. package/dest/services/tx_collection/tx_source.js +19 -2
  180. package/dest/services/tx_file_store/tx_file_store.js +1 -1
  181. package/dest/services/tx_provider.d.ts +3 -3
  182. package/dest/services/tx_provider.d.ts.map +1 -1
  183. package/dest/services/tx_provider.js +4 -4
  184. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  185. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  186. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  187. package/dest/test-helpers/mock-pubsub.d.ts +4 -4
  188. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  189. package/dest/test-helpers/mock-pubsub.js +8 -2
  190. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  191. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  192. package/dest/test-helpers/reqresp-nodes.js +2 -2
  193. package/dest/test-helpers/testbench-utils.d.ts +6 -3
  194. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  195. package/dest/test-helpers/testbench-utils.js +1 -1
  196. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  197. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  198. package/dest/testbench/p2p_client_testbench_worker.js +15 -14
  199. package/dest/testbench/worker_client_manager.d.ts +3 -1
  200. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  201. package/dest/testbench/worker_client_manager.js +6 -2
  202. package/dest/util.d.ts +3 -3
  203. package/dest/util.d.ts.map +1 -1
  204. package/package.json +14 -14
  205. package/src/client/factory.ts +29 -49
  206. package/src/client/interface.ts +11 -20
  207. package/src/client/p2p_client.ts +47 -126
  208. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +20 -11
  209. package/src/config.ts +92 -43
  210. package/src/errors/tx-pool.error.ts +12 -0
  211. package/src/mem_pools/attestation_pool/attestation_pool.ts +5 -4
  212. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  213. package/src/mem_pools/instrumentation.ts +17 -13
  214. package/src/mem_pools/tx_pool/README.md +1 -1
  215. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  216. package/src/mem_pools/tx_pool_v2/README.md +10 -2
  217. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +11 -0
  218. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  219. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +3 -3
  220. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  221. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  222. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  223. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -4
  224. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
  225. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +12 -9
  226. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  227. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  228. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  229. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  230. package/src/mem_pools/tx_pool_v2/interfaces.ts +18 -6
  231. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +141 -25
  232. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -46
  233. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +15 -7
  234. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +310 -144
  235. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
  236. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
  237. package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
  238. package/src/msg_validators/tx_validator/README.md +115 -0
  239. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
  240. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  241. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  242. package/src/msg_validators/tx_validator/factory.ts +353 -77
  243. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  244. package/src/msg_validators/tx_validator/gas_validator.ts +90 -27
  245. package/src/msg_validators/tx_validator/index.ts +2 -0
  246. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  247. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  248. package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
  249. package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
  250. package/src/services/dummy_service.ts +6 -6
  251. package/src/services/encoding.ts +7 -7
  252. package/src/services/gossipsub/README.md +29 -14
  253. package/src/services/gossipsub/topic_score_params.ts +49 -13
  254. package/src/services/libp2p/libp2p_service.ts +95 -96
  255. package/src/services/peer-manager/metrics.ts +7 -0
  256. package/src/services/peer-manager/peer_manager.ts +2 -1
  257. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +20 -48
  258. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
  259. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
  260. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +63 -24
  261. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  262. package/src/services/reqresp/reqresp.ts +3 -1
  263. package/src/services/service.ts +11 -2
  264. package/src/services/tx_collection/fast_tx_collection.ts +51 -30
  265. package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
  266. package/src/services/tx_collection/file_store_tx_source.ts +61 -17
  267. package/src/services/tx_collection/instrumentation.ts +7 -1
  268. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  269. package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
  270. package/src/services/tx_collection/slow_tx_collection.ts +8 -9
  271. package/src/services/tx_collection/tx_collection.ts +4 -3
  272. package/src/services/tx_collection/tx_collection_sink.ts +15 -29
  273. package/src/services/tx_collection/tx_source.ts +22 -3
  274. package/src/services/tx_file_store/tx_file_store.ts +1 -1
  275. package/src/services/tx_provider.ts +2 -2
  276. package/src/test-helpers/make-test-p2p-clients.ts +1 -3
  277. package/src/test-helpers/mock-pubsub.ts +13 -6
  278. package/src/test-helpers/reqresp-nodes.ts +3 -6
  279. package/src/test-helpers/testbench-utils.ts +3 -3
  280. package/src/testbench/p2p_client_testbench_worker.ts +24 -20
  281. package/src/testbench/worker_client_manager.ts +13 -5
  282. package/src/util.ts +8 -2
  283. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  284. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  285. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  286. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
@@ -0,0 +1,69 @@
1
+ import {
2
+ Attributes,
3
+ type Meter,
4
+ Metrics,
5
+ type ObservableGauge,
6
+ type ObservableResult,
7
+ type TelemetryClient,
8
+ type UpDownCounter,
9
+ createUpDownCounterWithDefault,
10
+ } from '@aztec/telemetry-client';
11
+
12
+ /** Callback that returns the current estimated metadata memory in bytes. */
13
+ export type MetadataMemoryCallback = () => number;
14
+
15
+ /** Instrumentation for TxPoolV2Impl internal operations. */
16
+ export class TxPoolV2Instrumentation {
17
+ #evictedCounter: UpDownCounter;
18
+ #ignoredCounter: UpDownCounter;
19
+ #rejectedCounter: UpDownCounter;
20
+ #softDeletedHitsCounter: UpDownCounter;
21
+ #missingOnProtectCounter: UpDownCounter;
22
+ #missingPreviouslyEvictedCounter: UpDownCounter;
23
+ #metadataMemoryGauge: ObservableGauge;
24
+
25
+ constructor(telemetry: TelemetryClient, metadataMemoryCallback: MetadataMemoryCallback) {
26
+ const meter: Meter = telemetry.getMeter('TxPoolV2Impl');
27
+
28
+ this.#evictedCounter = createUpDownCounterWithDefault(meter, Metrics.MEMPOOL_TX_POOL_V2_EVICTED_COUNT);
29
+ this.#ignoredCounter = createUpDownCounterWithDefault(meter, Metrics.MEMPOOL_TX_POOL_V2_IGNORED_COUNT);
30
+ this.#rejectedCounter = createUpDownCounterWithDefault(meter, Metrics.MEMPOOL_TX_POOL_V2_REJECTED_COUNT);
31
+ this.#softDeletedHitsCounter = createUpDownCounterWithDefault(meter, Metrics.MEMPOOL_TX_POOL_V2_SOFT_DELETED_HITS);
32
+ this.#missingOnProtectCounter = createUpDownCounterWithDefault(
33
+ meter,
34
+ Metrics.MEMPOOL_TX_POOL_V2_MISSING_ON_PROTECT,
35
+ );
36
+ this.#missingPreviouslyEvictedCounter = createUpDownCounterWithDefault(
37
+ meter,
38
+ Metrics.MEMPOOL_TX_POOL_V2_MISSING_PREVIOUSLY_EVICTED,
39
+ );
40
+ this.#metadataMemoryGauge = meter.createObservableGauge(Metrics.MEMPOOL_TX_POOL_V2_METADATA_MEMORY);
41
+ this.#metadataMemoryGauge.addCallback((result: ObservableResult) => {
42
+ result.observe(metadataMemoryCallback());
43
+ });
44
+ }
45
+
46
+ recordEvictions(count: number, reason: string) {
47
+ this.#evictedCounter.add(count, { [Attributes.TX_POOL_EVICTION_REASON]: reason });
48
+ }
49
+
50
+ recordIgnored(count: number) {
51
+ this.#ignoredCounter.add(count);
52
+ }
53
+
54
+ recordRejected(count: number) {
55
+ this.#rejectedCounter.add(count);
56
+ }
57
+
58
+ recordSoftDeletedHits(count: number) {
59
+ this.#softDeletedHitsCounter.add(count);
60
+ }
61
+
62
+ recordMissingOnProtect(count: number) {
63
+ this.#missingOnProtectCounter.add(count);
64
+ }
65
+
66
+ recordMissingPreviouslyEvicted(count: number) {
67
+ this.#missingPreviouslyEvictedCounter.add(count);
68
+ }
69
+ }
@@ -4,6 +4,7 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
4
4
  import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
5
5
  import type { BlockHeader, Tx, TxHash, TxValidator } from '@aztec/stdlib/tx';
6
6
 
7
+ import type { TxPoolRejectionError } from './eviction/interfaces.js';
7
8
  import type { TxMetaData, TxState } from './tx_metadata.js';
8
9
 
9
10
  /**
@@ -17,6 +18,8 @@ export type AddTxsResult = {
17
18
  ignored: TxHash[];
18
19
  /** Transactions rejected because they failed validation (e.g., invalid proof, expired timestamp) */
19
20
  rejected: TxHash[];
21
+ /** Optional rejection errors, only present when there are rejections with structured errors. */
22
+ errors?: Map<string, TxPoolRejectionError>;
20
23
  };
21
24
 
22
25
  /**
@@ -39,6 +42,12 @@ export type TxPoolV2Config = {
39
42
  archivedTxLimit: number;
40
43
  /** Minimum age (ms) a transaction must have been in the pool before it's eligible for block building */
41
44
  minTxPoolAgeMs: number;
45
+ /** Maximum number of evicted tx hashes to remember for metrics tracking */
46
+ evictedTxCacheSize: number;
47
+ /** The probability (0-1) that a transaction is discarded. 0 disables dropping. For testing purposes only. */
48
+ dropTransactionsProbability: number;
49
+ /** Minimum percentage fee increase required to replace an existing tx via RPC (0 = no bump). */
50
+ priceBumpPercentage: bigint;
42
51
  };
43
52
 
44
53
  /**
@@ -48,6 +57,9 @@ export const DEFAULT_TX_POOL_V2_CONFIG: TxPoolV2Config = {
48
57
  maxPendingTxCount: 0, // 0 = disabled
49
58
  archivedTxLimit: 0, // 0 = disabled
50
59
  minTxPoolAgeMs: 2_000,
60
+ evictedTxCacheSize: 10_000,
61
+ dropTransactionsProbability: 0,
62
+ priceBumpPercentage: 10n,
51
63
  };
52
64
 
53
65
  /**
@@ -98,15 +110,15 @@ export interface TxPoolV2 extends TypedEventEmitter<TxPoolV2Events> {
98
110
  * @param opts - Optional metadata (e.g., source for logging)
99
111
  * @returns Result categorizing each transaction as accepted, rejected, or ignored
100
112
  */
101
- addPendingTxs(txs: Tx[], opts?: { source?: string }): Promise<AddTxsResult>;
113
+ addPendingTxs(txs: Tx[], opts?: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult>;
102
114
 
103
115
  /**
104
- * Checks if a transaction can be added without modifying the pool.
105
- * Performs the same validation as addPendingTxs but doesn't persist changes.
116
+ * Checks if the pool would accept a transaction without modifying state.
117
+ * Used as a pre-check before expensive proof verification.
106
118
  * @param tx - Transaction to check
107
- * @returns Result: 'accepted', 'ignored' (if already in pool or undesirable), or 'rejected' (if validation fails)
119
+ * @returns 'accepted' if the pool would accept, 'ignored' if already in pool or undesirable
108
120
  */
109
- canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored' | 'rejected'>;
121
+ canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'>;
110
122
 
111
123
  /**
112
124
  * Adds transactions as immediately protected for a given slot.
@@ -159,7 +171,7 @@ export interface TxPoolV2 extends TypedEventEmitter<TxPoolV2Events> {
159
171
  * and validates them before returning to pending.
160
172
  * @param latestBlock - The latest valid block ID after the prune
161
173
  */
162
- handlePrunedBlocks(latestBlock: L2BlockId): Promise<void>;
174
+ handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void>;
163
175
 
164
176
  /**
165
177
  * Handles failed transaction execution.
@@ -2,16 +2,19 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
4
4
  import { BlockHash, type L2BlockId } from '@aztec/stdlib/block';
5
- import type { Tx } from '@aztec/stdlib/tx';
5
+ import { Gas } from '@aztec/stdlib/gas';
6
+ import { type Tx, TxHash } from '@aztec/stdlib/tx';
6
7
 
7
8
  import { getFeePayerBalanceDelta } from '../../msg_validators/tx_validator/fee_payer_balance.js';
8
9
  import { getTxPriorityFee } from '../tx_pool/priority.js';
9
- import type { PreAddResult } from './eviction/interfaces.js';
10
+ import { type PreAddResult, TxPoolRejectionCode } from './eviction/interfaces.js';
10
11
 
11
12
  /** Validator-compatible data interface, mirroring the subset of PrivateKernelTailCircuitPublicInputs used by validators. */
12
13
  export type TxMetaValidationData = {
13
14
  getNonEmptyNullifiers(): Fr[];
14
- includeByTimestamp: bigint;
15
+ expirationTimestamp: bigint;
16
+ /** Whether the tx has public calls. Used to select the correct L2 gas minimum. */
17
+ forPublic?: unknown;
15
18
  constants: {
16
19
  anchorBlockHeader: {
17
20
  hash(): Promise<BlockHash>;
@@ -19,6 +22,9 @@ export type TxMetaValidationData = {
19
22
  blockNumber: BlockNumber;
20
23
  };
21
24
  };
25
+ txContext: {
26
+ gasSettings: { gasLimits: Gas };
27
+ };
22
28
  };
23
29
  };
24
30
 
@@ -34,6 +40,9 @@ export type TxMetaData = {
34
40
  /** The transaction hash as hex string */
35
41
  readonly txHash: string;
36
42
 
43
+ /** The transaction hash as bigint (for efficient Fr conversion in comparisons) */
44
+ readonly txHashBigInt: bigint;
45
+
37
46
  /** Block ID (number and hash) in which the transaction was mined (undefined if not mined) */
38
47
  minedL2BlockId?: L2BlockId;
39
48
 
@@ -56,13 +65,16 @@ export type TxMetaData = {
56
65
  readonly nullifiers: readonly string[];
57
66
 
58
67
  /** Timestamp by which the transaction must be included (for expiration checks) */
59
- readonly includeByTimestamp: bigint;
68
+ readonly expirationTimestamp: bigint;
60
69
 
61
70
  /** Validator-compatible data, providing the same access patterns as Tx.data */
62
71
  readonly data: TxMetaValidationData;
63
72
 
64
73
  /** Timestamp (ms) when the tx was received into the pool. 0 for hydrated txs (always eligible). */
65
74
  receivedAt: number;
75
+
76
+ /** Estimated memory footprint of this metadata object in bytes */
77
+ readonly estimatedSizeBytes: number;
66
78
  };
67
79
 
68
80
  /** Transaction state derived from TxMetaData fields and pool protection status */
@@ -74,49 +86,85 @@ export type TxState = 'pending' | 'protected' | 'mined' | 'deleted';
74
86
  * Fr values are captured in closures for zero-cost re-validation.
75
87
  */
76
88
  export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
77
- const txHash = tx.getTxHash().toString();
89
+ const txHashObj = tx.getTxHash();
90
+ const txHash = txHashObj.toString();
91
+ const txHashBigInt = txHashObj.toBigInt();
78
92
  const nullifierFrs = tx.data.getNonEmptyNullifiers();
79
93
  const nullifiers = nullifierFrs.map(n => n.toString());
80
94
  const anchorBlockHeaderHashFr = await tx.data.constants.anchorBlockHeader.hash();
81
95
  const anchorBlockHeaderHash = anchorBlockHeaderHashFr.toString();
82
- const includeByTimestamp = tx.data.includeByTimestamp;
96
+ const expirationTimestamp = tx.data.expirationTimestamp;
83
97
  const anchorBlockNumber = tx.data.constants.anchorBlockHeader.globalVariables.blockNumber;
84
98
  const priorityFee = getTxPriorityFee(tx);
85
99
  const feePayer = tx.data.feePayer.toString();
86
100
 
87
101
  const { feeLimit, claimAmount } = await getFeePayerBalanceDelta(tx, ProtocolContractAddress.FeeJuice);
88
102
 
103
+ const estimatedSizeBytes = estimateTxMetaDataSize(nullifiers.length);
104
+
89
105
  return {
90
106
  txHash,
107
+ txHashBigInt,
91
108
  anchorBlockHeaderHash,
92
109
  priorityFee,
93
110
  feePayer,
94
111
  claimAmount,
95
112
  feeLimit,
96
113
  nullifiers,
97
- includeByTimestamp,
114
+ expirationTimestamp,
98
115
  receivedAt: 0,
116
+ estimatedSizeBytes,
99
117
  data: {
100
118
  getNonEmptyNullifiers: () => nullifierFrs,
101
- includeByTimestamp,
119
+ expirationTimestamp,
120
+ forPublic: !!tx.data.forPublic,
102
121
  constants: {
103
122
  anchorBlockHeader: {
104
123
  hash: () => Promise.resolve(anchorBlockHeaderHashFr),
105
124
  globalVariables: { blockNumber: anchorBlockNumber },
106
125
  },
126
+ txContext: {
127
+ gasSettings: { gasLimits: tx.data.constants.txContext.gasSettings.gasLimits },
128
+ },
107
129
  },
108
130
  },
109
131
  };
110
132
  }
111
133
 
134
+ // V8 JS object overhead (~64 bytes for a plain object with hidden class).
135
+ // String overhead: ~32 bytes header + 1 byte per ASCII char (V8 one-byte strings).
136
+ // Hex string (0x + 64 hex chars = 66 chars): ~98 bytes per string.
137
+ // bigint: ~32 bytes. number: 8 bytes. Fr: ~80 bytes (32 data + object overhead).
138
+ const OBJECT_OVERHEAD = 64;
139
+ const HEX_STRING_BYTES = 98;
140
+ const BIGINT_BYTES = 32;
141
+ const FR_BYTES = 80;
142
+ // Fixed cost: object shell + txHash + anchorBlockHeaderHash + feePayer (3 hex strings)
143
+ // + txHashBigInt + priorityFee + claimAmount + feeLimit + includeByTimestamp (5 bigints)
144
+ // + receivedAt (number, 8 bytes) + estimatedSizeBytes (number, 8 bytes)
145
+ // + data closure object (~OBJECT_OVERHEAD + anchorBlockHeaderHashFr Fr + anchorBlockNumber number)
146
+ const FIXED_METADATA_BYTES =
147
+ OBJECT_OVERHEAD + 3 * HEX_STRING_BYTES + 5 * BIGINT_BYTES + 8 + 8 + OBJECT_OVERHEAD + FR_BYTES + 8;
148
+
149
+ /** Estimates the in-memory size of a TxMetaData object based on the number of nullifiers. */
150
+ function estimateTxMetaDataSize(nullifierCount: number): number {
151
+ // Per nullifier: one hex string in nullifiers[] + one Fr in the captured nullifierFrs[]
152
+ return FIXED_METADATA_BYTES + nullifierCount * (HEX_STRING_BYTES + FR_BYTES);
153
+ }
154
+
155
+ /** Converts a txHash bigint back to the canonical 0x-prefixed 64-char hex string. */
156
+ export function txHashFromBigInt(value: bigint): string {
157
+ return TxHash.fromBigInt(value).toString();
158
+ }
159
+
112
160
  /** Minimal fields required for priority comparison. */
113
- type PriorityComparable = Pick<TxMetaData, 'txHash' | 'priorityFee'>;
161
+ export type PriorityComparable = Pick<TxMetaData, 'txHash' | 'txHashBigInt' | 'priorityFee'>;
114
162
 
115
163
  /**
116
164
  * Compares two priority fees in ascending order.
117
165
  * Returns negative if a < b, positive if a > b, 0 if equal.
118
166
  */
119
- export function compareFee(a: bigint, b: bigint): number {
167
+ export function compareFee(a: bigint, b: bigint): -1 | 0 | 1 {
120
168
  return a < b ? -1 : a > b ? 1 : 0;
121
169
  }
122
170
 
@@ -125,10 +173,8 @@ export function compareFee(a: bigint, b: bigint): number {
125
173
  * Uses field element comparison for deterministic ordering.
126
174
  * Returns negative if a < b, positive if a > b, 0 if equal.
127
175
  */
128
- export function compareTxHash(a: string, b: string): number {
129
- const fieldA = Fr.fromHexString(a);
130
- const fieldB = Fr.fromHexString(b);
131
- return fieldA.cmp(fieldB);
176
+ export function compareTxHash(a: bigint, b: bigint): -1 | 0 | 1 {
177
+ return Fr.cmpAsBigInt(a, b);
132
178
  }
133
179
 
134
180
  /**
@@ -136,29 +182,46 @@ export function compareTxHash(a: string, b: string): number {
136
182
  * Returns negative if a < b, positive if a > b, 0 if equal.
137
183
  * Use with sort() for ascending order, or negate/reverse for descending.
138
184
  */
139
- export function comparePriority(a: PriorityComparable, b: PriorityComparable): number {
185
+ export function comparePriority(a: PriorityComparable, b: PriorityComparable): -1 | 0 | 1 {
140
186
  const feeComparison = compareFee(a.priorityFee, b.priorityFee);
141
187
  if (feeComparison !== 0) {
142
188
  return feeComparison;
143
189
  }
144
- return compareTxHash(a.txHash, b.txHash);
190
+ return compareTxHash(a.txHashBigInt, b.txHashBigInt);
191
+ }
192
+
193
+ /**
194
+ * Returns the minimum fee required to replace an existing tx with the given price bump percentage.
195
+ * Uses integer arithmetic: `existingFee + existingFee * priceBumpPercentage / 100`.
196
+ */
197
+ export function getMinimumPriceBumpFee(existingFee: bigint, priceBumpPercentage: bigint): bigint {
198
+ const bump = (existingFee * priceBumpPercentage) / 100n;
199
+ // Ensure the minimum bump is at least 1, so that replacement always requires
200
+ // paying strictly more — even with 0% bump or zero existing fee.
201
+ const effectiveBump = bump > 0n ? bump : 1n;
202
+ return existingFee + effectiveBump;
145
203
  }
146
204
 
147
205
  /**
148
206
  * Checks for nullifier conflicts between an incoming transaction and existing pool state.
149
207
  *
150
208
  * When the incoming tx shares nullifiers with existing pending txs:
151
- * - If the incoming tx has strictly higher priority, mark conflicting txs for eviction
152
- * - If any conflicting tx has equal or higher priority, ignore the incoming tx
209
+ * - If the incoming tx meets or exceeds the required priority, mark conflicting txs for eviction
210
+ * - Otherwise, ignore the incoming tx
211
+ *
212
+ * When `priceBumpPercentage` is provided (RPC path), uses fee-only comparison with the
213
+ * percentage bump instead of `comparePriority`.
153
214
  *
154
215
  * @param incomingMeta - Metadata for the incoming transaction
155
216
  * @param getTxHashByNullifier - Accessor to find which tx uses a nullifier
156
217
  * @param getMetadata - Accessor to get metadata for a tx hash
218
+ * @param priceBumpPercentage - Optional percentage bump required for fee-based replacement
157
219
  */
158
220
  export function checkNullifierConflict(
159
221
  incomingMeta: TxMetaData,
160
222
  getTxHashByNullifier: (nullifier: string) => string | undefined,
161
223
  getMetadata: (txHash: string) => TxMetaData | undefined,
224
+ priceBumpPercentage?: bigint,
162
225
  ): PreAddResult {
163
226
  const txHashesToEvict: string[] = [];
164
227
 
@@ -179,16 +242,33 @@ export function checkNullifierConflict(
179
242
  continue;
180
243
  }
181
244
 
182
- // If incoming tx has strictly higher priority, mark for eviction
183
- // Otherwise, ignore incoming tx (ties go to existing tx)
184
- // Use comparePriority for deterministic ordering (includes txHash as tiebreaker)
185
- if (comparePriority(incomingMeta, conflictingMeta) > 0) {
245
+ // When price bump is set (RPC path), require the incoming fee to meet the bumped threshold.
246
+ // Otherwise (P2P path), use full comparePriority with tx hash tiebreaker.
247
+ const isHigherPriority =
248
+ priceBumpPercentage !== undefined
249
+ ? incomingMeta.priorityFee >= getMinimumPriceBumpFee(conflictingMeta.priorityFee, priceBumpPercentage)
250
+ : comparePriority(incomingMeta, conflictingMeta) > 0;
251
+
252
+ if (isHigherPriority) {
186
253
  txHashesToEvict.push(conflictingHashStr);
187
254
  } else {
255
+ const minimumFee =
256
+ priceBumpPercentage !== undefined
257
+ ? getMinimumPriceBumpFee(conflictingMeta.priorityFee, priceBumpPercentage)
258
+ : undefined;
188
259
  return {
189
260
  shouldIgnore: true,
190
261
  txHashesToEvict: [],
191
- reason: `nullifier conflict with ${conflictingHashStr}`,
262
+ reason: {
263
+ code: TxPoolRejectionCode.NULLIFIER_CONFLICT,
264
+ message:
265
+ minimumFee !== undefined
266
+ ? `Nullifier conflict with existing tx ${conflictingHashStr}. Minimum required fee: ${minimumFee}, got: ${incomingMeta.priorityFee}`
267
+ : `Nullifier conflict with existing tx ${conflictingHashStr}`,
268
+ conflictingTxHash: conflictingHashStr,
269
+ minimumPriceBumpFee: minimumFee,
270
+ txPriorityFee: minimumFee !== undefined ? incomingMeta.priorityFee : undefined,
271
+ },
192
272
  };
193
273
  }
194
274
  }
@@ -197,15 +277,51 @@ export function checkNullifierConflict(
197
277
  }
198
278
 
199
279
  /** Creates a stub TxMetaValidationData for tests that don't exercise validators. */
200
- export function stubTxMetaValidationData(overrides: { includeByTimestamp?: bigint } = {}): TxMetaValidationData {
280
+ export function stubTxMetaValidationData(overrides: { expirationTimestamp?: bigint } = {}): TxMetaValidationData {
201
281
  return {
202
282
  getNonEmptyNullifiers: () => [],
203
- includeByTimestamp: overrides.includeByTimestamp ?? 0n,
283
+ expirationTimestamp: overrides.expirationTimestamp ?? 0n,
204
284
  constants: {
205
285
  anchorBlockHeader: {
206
286
  hash: () => Promise.resolve(new BlockHash(Fr.ZERO)),
207
287
  globalVariables: { blockNumber: BlockNumber(0) },
208
288
  },
289
+ txContext: {
290
+ gasSettings: { gasLimits: Gas.empty() },
291
+ },
209
292
  },
210
293
  };
211
294
  }
295
+
296
+ /** Creates a stub TxMetaData for tests. All fields have sensible defaults and can be overridden. */
297
+ export function stubTxMetaData(
298
+ txHash: string,
299
+ overrides: {
300
+ priorityFee?: bigint;
301
+ feePayer?: string;
302
+ claimAmount?: bigint;
303
+ feeLimit?: bigint;
304
+ nullifiers?: string[];
305
+ expirationTimestamp?: bigint;
306
+ anchorBlockHeaderHash?: string;
307
+ } = {},
308
+ ): TxMetaData {
309
+ const txHashBigInt = Fr.fromHexString(txHash).toBigInt();
310
+ // Normalize to canonical zero-padded hex so txHashFromBigInt(txHashBigInt) === normalizedTxHash
311
+ const normalizedTxHash = txHashFromBigInt(txHashBigInt);
312
+ const expirationTimestamp = overrides.expirationTimestamp ?? 0n;
313
+ return {
314
+ txHash: normalizedTxHash,
315
+ txHashBigInt,
316
+ anchorBlockHeaderHash: overrides.anchorBlockHeaderHash ?? '0x1234',
317
+ priorityFee: overrides.priorityFee ?? 100n,
318
+ feePayer: overrides.feePayer ?? '0xfeepayer',
319
+ claimAmount: overrides.claimAmount ?? 0n,
320
+ feeLimit: overrides.feeLimit ?? 100n,
321
+ nullifiers: overrides.nullifiers ?? [`0x${normalizedTxHash.slice(2)}null1`],
322
+ expirationTimestamp,
323
+ receivedAt: 0,
324
+ estimatedSizeBytes: 0,
325
+ data: stubTxMetaValidationData({ expirationTimestamp }),
326
+ };
327
+ }
@@ -1,7 +1,8 @@
1
+ import { insertIntoSortedArray, removeFromSortedArray } from '@aztec/foundation/array';
1
2
  import { SlotNumber } from '@aztec/foundation/branded-types';
2
3
  import type { L2BlockId } from '@aztec/stdlib/block';
3
4
 
4
- import { type TxMetaData, type TxState, compareFee, compareTxHash } from './tx_metadata.js';
5
+ import { type PriorityComparable, type TxMetaData, type TxState, comparePriority } from './tx_metadata.js';
5
6
 
6
7
  /**
7
8
  * Manages in-memory indices for the transaction pool.
@@ -22,8 +23,8 @@ export class TxPoolIndices {
22
23
  #nullifierToTxHash: Map<string, string> = new Map();
23
24
  /** Fee payer to txHashes index (pending txs only) */
24
25
  #feePayerToTxHashes: Map<string, Set<string>> = new Map();
25
- /** Pending txHashes grouped by priority fee */
26
- #pendingByPriority: Map<bigint, Set<string>> = new Map();
26
+ /** Pending transactions sorted ascending by priority fee, ties broken by txHash */
27
+ #pendingByPriority: PriorityComparable[] = [];
27
28
  /** Protected transactions: txHash -> slotNumber */
28
29
  #protectedTransactions: Map<string, SlotNumber> = new Map();
29
30
 
@@ -73,20 +74,14 @@ export class TxPoolIndices {
73
74
  * @param order - 'desc' for highest priority first, 'asc' for lowest priority first
74
75
  */
75
76
  *iteratePendingByPriority(order: 'asc' | 'desc', filter?: (hash: string) => boolean): Generator<string> {
76
- // Use compareFee from tx_metadata, swap args for descending order
77
- const feeCompareFn = order === 'desc' ? (a: bigint, b: bigint) => compareFee(b, a) : compareFee;
78
- const hashCompareFn = order === 'desc' ? (a: string, b: string) => compareTxHash(b, a) : compareTxHash;
79
-
80
- const sortedFees = [...this.#pendingByPriority.keys()].sort(feeCompareFn);
81
-
82
- for (const fee of sortedFees) {
83
- const hashesAtFee = this.#pendingByPriority.get(fee)!;
84
- // Use compareTxHash from tx_metadata, swap args for descending order
85
- const sortedHashes = [...hashesAtFee].sort(hashCompareFn);
86
- for (const hash of sortedHashes) {
87
- if (filter === undefined || filter(hash)) {
88
- yield hash;
89
- }
77
+ const arr = this.#pendingByPriority;
78
+ const start = order === 'asc' ? 0 : arr.length - 1;
79
+ const step = order === 'asc' ? 1 : -1;
80
+ const inBounds = order === 'asc' ? (i: number) => i < arr.length : (i: number) => i >= 0;
81
+
82
+ for (let i = start; inBounds(i); i += step) {
83
+ if (filter === undefined || filter(arr[i].txHash)) {
84
+ yield arr[i].txHash;
90
85
  }
91
86
  }
92
87
  }
@@ -227,11 +222,7 @@ export class TxPoolIndices {
227
222
 
228
223
  /** Gets the count of pending transactions */
229
224
  getPendingTxCount(): number {
230
- let count = 0;
231
- for (const hashes of this.#pendingByPriority.values()) {
232
- count += hashes.size;
233
- }
234
- return count;
225
+ return this.#pendingByPriority.length;
235
226
  }
236
227
 
237
228
  /** Gets the lowest priority pending transaction hashes (up to limit) */
@@ -264,12 +255,10 @@ export class TxPoolIndices {
264
255
  /** Gets all pending transactions */
265
256
  getPendingTxs(): TxMetaData[] {
266
257
  const result: TxMetaData[] = [];
267
- for (const hashSet of this.#pendingByPriority.values()) {
268
- for (const txHash of hashSet) {
269
- const meta = this.#metadata.get(txHash);
270
- if (meta) {
271
- result.push(meta);
272
- }
258
+ for (const entry of this.#pendingByPriority) {
259
+ const meta = this.#metadata.get(entry.txHash);
260
+ if (meta) {
261
+ result.push(meta);
273
262
  }
274
263
  }
275
264
  return result;
@@ -348,13 +337,15 @@ export class TxPoolIndices {
348
337
  // METRICS
349
338
  // ============================================================================
350
339
 
351
- /** Counts transactions by state */
352
- countTxs(): { pending: number; protected: number; mined: number } {
340
+ /** Counts transactions by state and estimates total metadata memory usage */
341
+ countTxs(): { pending: number; protected: number; mined: number; totalMetadataBytes: number } {
353
342
  let pending = 0;
354
343
  let protected_ = 0;
355
344
  let mined = 0;
345
+ let totalMetadataBytes = 0;
356
346
 
357
347
  for (const meta of this.#metadata.values()) {
348
+ totalMetadataBytes += meta.estimatedSizeBytes;
358
349
  const state = this.getTxState(meta);
359
350
  if (state === 'pending') {
360
351
  pending++;
@@ -365,7 +356,16 @@ export class TxPoolIndices {
365
356
  }
366
357
  }
367
358
 
368
- return { pending, protected: protected_, mined };
359
+ return { pending, protected: protected_, mined, totalMetadataBytes };
360
+ }
361
+
362
+ /** Returns the estimated total memory consumed by all metadata objects */
363
+ getTotalMetadataBytes(): number {
364
+ let total = 0;
365
+ for (const meta of this.#metadata.values()) {
366
+ total += meta.estimatedSizeBytes;
367
+ }
368
+ return total;
369
369
  }
370
370
 
371
371
  /** Gets all mined transactions with their block IDs */
@@ -397,13 +397,12 @@ export class TxPoolIndices {
397
397
  }
398
398
  feePayerSet.add(meta.txHash);
399
399
 
400
- // Add to priority bucket
401
- let prioritySet = this.#pendingByPriority.get(meta.priorityFee);
402
- if (!prioritySet) {
403
- prioritySet = new Set();
404
- this.#pendingByPriority.set(meta.priorityFee, prioritySet);
405
- }
406
- prioritySet.add(meta.txHash);
400
+ insertIntoSortedArray(
401
+ this.#pendingByPriority,
402
+ { txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
403
+ comparePriority,
404
+ false,
405
+ );
407
406
  }
408
407
 
409
408
  #removeFromPendingIndices(meta: TxMetaData): void {
@@ -421,13 +420,11 @@ export class TxPoolIndices {
421
420
  }
422
421
  }
423
422
 
424
- // Remove from priority map
425
- const hashSet = this.#pendingByPriority.get(meta.priorityFee);
426
- if (hashSet) {
427
- hashSet.delete(meta.txHash);
428
- if (hashSet.size === 0) {
429
- this.#pendingByPriority.delete(meta.priorityFee);
430
- }
431
- }
423
+ // Remove from priority array
424
+ removeFromSortedArray(
425
+ this.#pendingByPriority,
426
+ { txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
427
+ comparePriority,
428
+ );
432
429
  }
433
430
  }
@@ -58,10 +58,13 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
58
58
  const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : TxHash.fromBigInt(h)));
59
59
  this.emit('txs-removed', { txHashes: hashes });
60
60
  },
61
+ onTxsMined: (txHashes: string[]) => {
62
+ this.#metrics?.transactionsRemoved(txHashes);
63
+ },
61
64
  };
62
65
 
63
66
  // Create the implementation
64
- this.#impl = new TxPoolV2Impl(store, archiveStore, deps, callbacks, config, dateProvider, log);
67
+ this.#impl = new TxPoolV2Impl(store, archiveStore, deps, callbacks, telemetry, config, dateProvider, log);
65
68
  }
66
69
 
67
70
  // ============================================================================
@@ -70,11 +73,11 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
70
73
 
71
74
  // === Core Operations ===
72
75
 
73
- addPendingTxs(txs: Tx[], opts: { source?: string } = {}): Promise<AddTxsResult> {
76
+ addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean } = {}): Promise<AddTxsResult> {
74
77
  return this.#queue.put(() => this.#impl.addPendingTxs(txs, opts));
75
78
  }
76
79
 
77
- canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored' | 'rejected'> {
80
+ canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
78
81
  return this.#queue.put(() => this.#impl.canAddPendingTx(tx));
79
82
  }
80
83
 
@@ -83,7 +86,7 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
83
86
  }
84
87
 
85
88
  protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
86
- return this.#queue.put(() => Promise.resolve(this.#impl.protectTxs(txHashes, block)));
89
+ return this.#queue.put(() => this.#impl.protectTxs(txHashes, block));
87
90
  }
88
91
 
89
92
  addMinedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string } = {}): Promise<void> {
@@ -100,8 +103,8 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
100
103
  return this.#queue.put(() => this.#impl.prepareForSlot(slotNumber));
101
104
  }
102
105
 
103
- handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
104
- return this.#queue.put(() => this.#impl.handlePrunedBlocks(latestBlock));
106
+ handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
107
+ return this.#queue.put(() => this.#impl.handlePrunedBlocks(latestBlock, options));
105
108
  }
106
109
 
107
110
  handleFailedExecution(txHashes: TxHash[]): Promise<void> {
@@ -195,7 +198,12 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
195
198
  this.#queue.put(() => {
196
199
  const counts = this.#impl.countTxs();
197
200
  return Promise.resolve({
198
- itemCount: { pending: counts.pending, protected: counts.protected, mined: counts.mined },
201
+ itemCount: {
202
+ pending: counts.pending,
203
+ protected: counts.protected,
204
+ mined: counts.mined,
205
+ softDeleted: counts.softDeleted,
206
+ },
199
207
  });
200
208
  }),
201
209
  () => this.#store.estimateSize(),