@aztec/p2p 0.0.1-commit.db765a8 → 0.0.1-commit.ddcf04837

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 (331) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +2 -2
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +25 -11
  5. package/dest/client/interface.d.ts +9 -2
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +3 -2
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +46 -38
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +17 -6
  11. package/dest/config.d.ts +120 -94
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +72 -8
  14. package/dest/errors/p2p-service.error.d.ts +9 -0
  15. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  16. package/dest/errors/p2p-service.error.js +10 -0
  17. package/dest/index.d.ts +1 -2
  18. package/dest/index.d.ts.map +1 -1
  19. package/dest/index.js +0 -1
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +7 -5
  21. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  22. package/dest/mem_pools/attestation_pool/attestation_pool.js +11 -8
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  24. package/dest/mem_pools/index.d.ts +1 -2
  25. package/dest/mem_pools/index.d.ts.map +1 -1
  26. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  27. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +2 -1
  29. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
  30. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  32. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
  33. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
  35. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
  36. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
  38. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +9 -5
  39. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  41. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +25 -10
  42. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +39 -12
  44. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  45. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  46. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -43
  47. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
  48. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +3 -0
  50. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
  51. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +21 -6
  53. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +5 -2
  54. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  55. package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
  56. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -2
  57. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  58. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  59. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  60. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  61. package/dest/msg_validators/clock_tolerance.js +54 -3
  62. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  63. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  64. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  65. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  66. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  67. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  68. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +14 -9
  69. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  70. package/dest/msg_validators/proposal_validator/proposal_validator.js +65 -55
  71. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
  72. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  73. package/dest/msg_validators/tx_validator/allowed_public_setup.js +21 -32
  74. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  75. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  76. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  77. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  78. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  79. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  80. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  81. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  82. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  83. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  84. package/dest/msg_validators/tx_validator/factory.d.ts +23 -4
  85. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  86. package/dest/msg_validators/tx_validator/factory.js +36 -10
  87. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  88. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  89. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  90. package/dest/msg_validators/tx_validator/gas_validator.d.ts +13 -4
  91. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  92. package/dest/msg_validators/tx_validator/gas_validator.js +49 -17
  93. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  94. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/index.js +1 -0
  96. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  97. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  99. package/dest/msg_validators/tx_validator/phases_validator.d.ts +21 -1
  100. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/phases_validator.js +49 -2
  102. package/dest/services/data_store.d.ts +1 -1
  103. package/dest/services/data_store.d.ts.map +1 -1
  104. package/dest/services/data_store.js +5 -5
  105. package/dest/services/dummy_service.d.ts +6 -3
  106. package/dest/services/dummy_service.d.ts.map +1 -1
  107. package/dest/services/dummy_service.js +6 -1
  108. package/dest/services/encoding.d.ts +5 -1
  109. package/dest/services/encoding.d.ts.map +1 -1
  110. package/dest/services/encoding.js +7 -1
  111. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  112. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  113. package/dest/services/gossipsub/topic_score_params.js +21 -4
  114. package/dest/services/libp2p/libp2p_service.d.ts +15 -25
  115. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  116. package/dest/services/libp2p/libp2p_service.js +160 -126
  117. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  118. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  119. package/dest/services/peer-manager/peer_manager.js +37 -10
  120. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  121. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  122. package/dest/services/peer-manager/peer_scoring.js +32 -10
  123. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
  124. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  125. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +69 -65
  126. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
  127. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  128. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  129. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  130. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  131. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
  132. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  133. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
  134. package/dest/services/reqresp/config.d.ts +3 -3
  135. package/dest/services/reqresp/config.d.ts.map +1 -1
  136. package/dest/services/reqresp/interface.d.ts +14 -9
  137. package/dest/services/reqresp/interface.d.ts.map +1 -1
  138. package/dest/services/reqresp/interface.js +10 -11
  139. package/dest/services/reqresp/metrics.d.ts +1 -1
  140. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  141. package/dest/services/reqresp/metrics.js +0 -1
  142. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  143. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  144. package/dest/services/reqresp/protocols/index.js +0 -1
  145. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  146. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  147. package/dest/services/reqresp/protocols/tx.js +1 -3
  148. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  149. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  150. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  151. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  152. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  153. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  154. package/dest/services/reqresp/reqresp.d.ts +4 -2
  155. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  156. package/dest/services/reqresp/reqresp.js +28 -11
  157. package/dest/services/service.d.ts +5 -2
  158. package/dest/services/service.d.ts.map +1 -1
  159. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
  160. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  161. package/dest/services/tx_collection/fast_tx_collection.js +57 -73
  162. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  163. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  164. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  165. package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
  166. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  167. package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
  168. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  169. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  170. package/dest/services/tx_collection/request_tracker.js +84 -0
  171. package/dest/services/tx_collection/slow_tx_collection.js +1 -1
  172. package/dest/services/tx_collection/tx_collection.d.ts +3 -6
  173. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  174. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  175. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  176. package/dest/services/tx_collection/tx_source.js +9 -7
  177. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  178. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  179. package/dest/test-helpers/mock-pubsub.d.ts +11 -3
  180. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  181. package/dest/test-helpers/mock-pubsub.js +35 -10
  182. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  183. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  184. package/dest/test-helpers/reqresp-nodes.js +1 -2
  185. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  186. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  187. package/dest/test-helpers/testbench-utils.js +23 -3
  188. package/dest/testbench/p2p_client_testbench_worker.js +68 -16
  189. package/dest/testbench/worker_client_manager.d.ts +10 -1
  190. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  191. package/dest/testbench/worker_client_manager.js +55 -3
  192. package/dest/util.d.ts +1 -1
  193. package/package.json +14 -14
  194. package/src/client/factory.ts +43 -14
  195. package/src/client/interface.ts +9 -1
  196. package/src/client/p2p_client.ts +50 -39
  197. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -9
  198. package/src/config.ts +106 -6
  199. package/src/errors/p2p-service.error.ts +11 -0
  200. package/src/index.ts +0 -1
  201. package/src/mem_pools/attestation_pool/attestation_pool.ts +12 -8
  202. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  203. package/src/mem_pools/index.ts +0 -3
  204. package/src/mem_pools/tx_pool_v2/README.md +9 -1
  205. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -1
  206. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
  207. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  208. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
  209. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
  210. package/src/mem_pools/tx_pool_v2/interfaces.ts +9 -4
  211. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +60 -14
  212. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
  213. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +13 -1
  214. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +23 -6
  215. package/src/msg_validators/attestation_validator/README.md +49 -0
  216. package/src/msg_validators/attestation_validator/attestation_validator.ts +21 -9
  217. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -1
  218. package/src/msg_validators/clock_tolerance.ts +72 -3
  219. package/src/msg_validators/proposal_validator/README.md +123 -0
  220. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +17 -4
  221. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +23 -7
  222. package/src/msg_validators/proposal_validator/proposal_validator.ts +74 -58
  223. package/src/msg_validators/tx_validator/README.md +5 -1
  224. package/src/msg_validators/tx_validator/allowed_public_setup.ts +16 -35
  225. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  226. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  227. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  228. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  229. package/src/msg_validators/tx_validator/factory.ts +43 -3
  230. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  231. package/src/msg_validators/tx_validator/gas_validator.ts +65 -16
  232. package/src/msg_validators/tx_validator/index.ts +1 -0
  233. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  234. package/src/msg_validators/tx_validator/phases_validator.ts +60 -1
  235. package/src/services/data_store.ts +5 -13
  236. package/src/services/dummy_service.ts +8 -2
  237. package/src/services/encoding.ts +9 -1
  238. package/src/services/gossipsub/topic_score_params.ts +36 -4
  239. package/src/services/libp2p/libp2p_service.ts +160 -142
  240. package/src/services/peer-manager/peer_manager.ts +43 -10
  241. package/src/services/peer-manager/peer_scoring.ts +27 -5
  242. package/src/services/reqresp/README.md +229 -0
  243. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  244. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +64 -69
  245. package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
  246. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  247. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
  248. package/src/services/reqresp/config.ts +2 -2
  249. package/src/services/reqresp/interface.ts +21 -11
  250. package/src/services/reqresp/metrics.ts +0 -1
  251. package/src/services/reqresp/protocols/index.ts +0 -1
  252. package/src/services/reqresp/protocols/tx.ts +1 -3
  253. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  254. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  255. package/src/services/reqresp/reqresp.ts +37 -12
  256. package/src/services/service.ts +6 -1
  257. package/src/services/tx_collection/fast_tx_collection.ts +57 -83
  258. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  259. package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
  260. package/src/services/tx_collection/request_tracker.ts +127 -0
  261. package/src/services/tx_collection/slow_tx_collection.ts +1 -1
  262. package/src/services/tx_collection/tx_collection.ts +3 -5
  263. package/src/services/tx_collection/tx_source.ts +8 -7
  264. package/src/test-helpers/make-test-p2p-clients.ts +1 -1
  265. package/src/test-helpers/mock-pubsub.ts +31 -5
  266. package/src/test-helpers/reqresp-nodes.ts +3 -3
  267. package/src/test-helpers/testbench-utils.ts +30 -3
  268. package/src/testbench/p2p_client_testbench_worker.ts +72 -15
  269. package/src/testbench/worker_client_manager.ts +68 -6
  270. package/src/util.ts +1 -1
  271. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  272. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  273. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  274. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  275. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  276. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  277. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  278. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  279. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  280. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  281. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  282. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  283. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  284. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  285. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  286. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  287. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  288. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  289. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  290. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  291. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  292. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  293. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  294. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  295. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  296. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  297. package/dest/mem_pools/tx_pool/index.js +0 -2
  298. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  299. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  300. package/dest/mem_pools/tx_pool/priority.js +0 -15
  301. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  302. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  303. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  304. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  305. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  306. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  307. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -24
  308. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  309. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -378
  310. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  311. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  312. package/dest/services/reqresp/protocols/block.js +0 -32
  313. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  314. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  315. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  316. package/src/mem_pools/tx_pool/README.md +0 -270
  317. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  318. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  319. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  320. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  321. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  322. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  323. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  324. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  325. package/src/mem_pools/tx_pool/index.ts +0 -2
  326. package/src/mem_pools/tx_pool/priority.ts +0 -20
  327. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  328. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  329. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -373
  330. package/src/services/reqresp/protocols/block.ts +0 -37
  331. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
@@ -26,10 +26,10 @@ export type TryAddResult = {
26
26
  count: number;
27
27
  };
28
28
 
29
- export const MAX_CHECKPOINT_PROPOSALS_PER_SLOT = 5;
30
- export const MAX_BLOCK_PROPOSALS_PER_POSITION = 3;
29
+ export const MAX_CHECKPOINT_PROPOSALS_PER_SLOT = 2;
30
+ export const MAX_BLOCK_PROPOSALS_PER_POSITION = 2;
31
31
  /** Maximum attestations a single signer can make per slot before being rejected. */
32
- export const MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER = 3;
32
+ export const MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER = 2;
33
33
 
34
34
  /** Public API interface for attestation pools. Used for typing mocks and test implementations. */
35
35
  export type AttestationPoolApi = Pick<
@@ -154,14 +154,16 @@ export class AttestationPool {
154
154
  /** Maximum indexWithinCheckpoint value (2^10 - 1 = 1023). */
155
155
  private static readonly MAX_INDEX = (1 << AttestationPool.INDEX_BITS) - 1;
156
156
 
157
- /** Creates a position key for block proposals: (slot << 10) | indexWithinCheckpoint. */
157
+ /** Creates a position key for block proposals: slot * 1024 + indexWithinCheckpoint.
158
+ * Uses multiplication instead of bit-shift to avoid 32-bit signed integer overflow
159
+ * (bit-shift overflows after slot ~2^21, roughly 278 days of uptime). */
158
160
  private getBlockPositionKey(slot: number, indexWithinCheckpoint: number): number {
159
161
  if (indexWithinCheckpoint > AttestationPool.MAX_INDEX) {
160
162
  throw new Error(
161
163
  `Value for indexWithinCheckpoint ${indexWithinCheckpoint} exceeds maximum ${AttestationPool.MAX_INDEX}`,
162
164
  );
163
165
  }
164
- return (slot << AttestationPool.INDEX_BITS) | indexWithinCheckpoint;
166
+ return slot * (1 << AttestationPool.INDEX_BITS) + indexWithinCheckpoint;
165
167
  }
166
168
 
167
169
  /**
@@ -278,7 +280,7 @@ export class AttestationPool {
278
280
  * @returns Result indicating whether the proposal was added and duplicate detection info
279
281
  */
280
282
  public async tryAddCheckpointProposal(proposal: CheckpointProposalCore): Promise<TryAddResult> {
281
- return await this.store.transactionAsync(async () => {
283
+ const result = await this.store.transactionAsync(async () => {
282
284
  const proposalId = proposal.archive.toString();
283
285
 
284
286
  // Check if already exists
@@ -304,6 +306,8 @@ export class AttestationPool {
304
306
 
305
307
  return { added: true, alreadyExists: false, count: count + 1 };
306
308
  });
309
+
310
+ return result;
307
311
  }
308
312
 
309
313
  /** Internal method - must be called within a transaction. */
@@ -345,7 +349,7 @@ export class AttestationPool {
345
349
  await this.store.transactionAsync(async () => {
346
350
  for (const attestation of attestations) {
347
351
  const slotNumber = attestation.payload.header.slotNumber;
348
- const proposalId = attestation.archive;
352
+ const proposalId = attestation.archive.toString();
349
353
  const sender = attestation.getSender();
350
354
 
351
355
  // Skip attestations with invalid signatures
@@ -452,7 +456,7 @@ export class AttestationPool {
452
456
 
453
457
  // Delete block proposals for slots < oldestSlot, using blockProposalsForSlotAndIndex as index
454
458
  // Key format: (slot << INDEX_BITS) | indexWithinCheckpoint
455
- const blockPositionEndKey = oldestSlot << AttestationPool.INDEX_BITS;
459
+ const blockPositionEndKey = oldestSlot * (1 << AttestationPool.INDEX_BITS);
456
460
  for await (const positionKey of this.blockProposalsForSlotAndIndex.keysAsync({ end: blockPositionEndKey })) {
457
461
  const proposalIds = await toArray(this.blockProposalsForSlotAndIndex.getValuesAsync(positionKey));
458
462
  for (const proposalId of proposalIds) {
@@ -446,12 +446,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
446
446
  const result2 = await ap.tryAddBlockProposal(proposal2);
447
447
  expect(result2.count).toBe(2);
448
448
 
449
- // Add a third proposal for same position
449
+ // Third proposal for same position should be rejected (cap is 2)
450
450
  const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
451
451
  const result3 = await ap.tryAddBlockProposal(proposal3);
452
452
 
453
- expect(result3.added).toBe(true);
454
- expect(result3.count).toBe(3);
453
+ expect(result3.added).toBe(false);
454
+ expect(result3.count).toBe(2);
455
455
  });
456
456
 
457
457
  it('should return added=false when exceeding capacity', async () => {
@@ -666,12 +666,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
666
666
  const result2 = await ap.tryAddCheckpointProposal(proposal2);
667
667
  expect(result2.count).toBe(2);
668
668
 
669
- // Add a third proposal for same slot
669
+ // Third proposal for same slot should be rejected (cap is 2)
670
670
  const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
671
671
  const result3 = await ap.tryAddCheckpointProposal(proposal3);
672
672
 
673
- expect(result3.added).toBe(true);
674
- expect(result3.count).toBe(3);
673
+ expect(result3.added).toBe(false);
674
+ expect(result3.count).toBe(2);
675
675
  });
676
676
 
677
677
  it('should not count attestations as proposals for duplicate detection', async () => {
@@ -1,6 +1,3 @@
1
1
  export { AttestationPool, type AttestationPoolApi } from './attestation_pool/attestation_pool.js';
2
2
  export { type MemPools } from './interface.js';
3
- // Old TxPool exports - kept temporarily for external consumers
4
- export { type TxPool } from './tx_pool/tx_pool.js';
5
- // New TxPoolV2 exports
6
3
  export { type TxPoolV2, type TxPoolV2Config, type TxPoolV2Events, type AddTxsResult } from './tx_pool_v2/index.js';
@@ -158,7 +158,7 @@ Checked before adding a transaction to the pending pool:
158
158
 
159
159
  | Rule | Purpose |
160
160
  |------|---------|
161
- | `NullifierConflictRule` | Handles transactions with conflicting nullifiers. Higher priority tx wins. |
161
+ | `NullifierConflictRule` | Handles transactions with conflicting nullifiers. Higher priority tx wins. For RPC submissions, a configurable price bump percentage is required. |
162
162
  | `FeePayerBalancePreAddRule` | Ensures fee payer has sufficient balance for all their pending txs. |
163
163
  | `LowPriorityPreAddRule` | Rejects txs when pool is full and new tx has lowest priority. |
164
164
 
@@ -233,6 +233,14 @@ await pool.updateConfig({
233
233
  });
234
234
  ```
235
235
 
236
+ ### Price Bump (RPC Transaction Replacement)
237
+
238
+ When a transaction is submitted via RPC and clashes on nullifiers with an existing pool transaction, the incoming tx must pay at least `priceBumpPercentage`% more in priority fee (i.e. `>= existingFee + existingFee * bump / 100`) to replace it. This prevents spam via small fee increments. The same bump applies when the pool is full and the incoming tx needs to evict the lowest-priority tx.
239
+
240
+ - **Env var**: `P2P_RPC_PRICE_BUMP_PERCENTAGE` (default: 10)
241
+ - **Scope**: RPC submissions only. P2P gossip uses `comparePriority` (fee + hash tiebreaker) with no bump.
242
+ - Even with a 0% bump, a replacement tx must pay at least 1 unit more than the existing fee.
243
+
236
244
  ## Return Values
237
245
 
238
246
  ### AddTxsResult
@@ -29,7 +29,8 @@ export class FeePayerBalanceEvictionRule implements EvictionRule {
29
29
 
30
30
  if (context.event === EvictionEvent.BLOCK_MINED) {
31
31
  const blockNumber = context.block.getBlockNumber();
32
- await this.worldState.syncImmediate(blockNumber);
32
+ const blockHash = await context.block.hash();
33
+ await this.worldState.syncImmediate(blockNumber, blockHash);
33
34
  return await this.evictForFeePayers(context.feePayers, this.worldState.getSnapshot(blockNumber), pool);
34
35
  }
35
36
 
@@ -100,7 +100,15 @@ export type TxPoolRejectionError =
100
100
  availableBalance: bigint;
101
101
  feeLimit: bigint;
102
102
  }
103
- | { code: typeof TxPoolRejectionCode.NULLIFIER_CONFLICT; message: string; conflictingTxHash: string }
103
+ | {
104
+ code: typeof TxPoolRejectionCode.NULLIFIER_CONFLICT;
105
+ message: string;
106
+ conflictingTxHash: string;
107
+ /** Minimum fee needed to replace the conflicting tx (only set when price bump applies). */
108
+ minimumPriceBumpFee?: bigint;
109
+ /** Incoming tx's priority fee. */
110
+ txPriorityFee?: bigint;
111
+ }
104
112
  | { code: typeof TxPoolRejectionCode.INTERNAL_ERROR; message: string };
105
113
 
106
114
  /**
@@ -121,6 +129,8 @@ export interface PreAddResult {
121
129
  export interface PreAddContext {
122
130
  /** If true, compare priority fee only (no tx hash tiebreaker). Used for RPC submissions. */
123
131
  feeComparisonOnly?: boolean;
132
+ /** Percentage-based price bump required for tx replacement. Only set for RPC submissions. */
133
+ priceBumpPercentage?: bigint;
124
134
  }
125
135
 
126
136
  /**
@@ -1,5 +1,5 @@
1
- import { Fr } from '@aztec/foundation/curves/bn254';
2
1
  import { createLogger } from '@aztec/foundation/log';
2
+ import { BlockHash } from '@aztec/stdlib/block';
3
3
  import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
4
4
  import { MerkleTreeId } from '@aztec/stdlib/trees';
5
5
 
@@ -33,14 +33,14 @@ export class InvalidTxsAfterReorgRule implements EvictionRule {
33
33
  const pendingTxs = pool.getPendingTxs();
34
34
 
35
35
  // Deduplicate block hashes to reduce redundant DB lookups
36
- const uniqueBlockHashes = new Map<string, Fr>();
36
+ const uniqueBlockHashes = new Map<string, BlockHash>();
37
37
  const txsByBlockHash = new Map<string, string[]>();
38
38
 
39
39
  for (const meta of pendingTxs) {
40
40
  const blockHashStr = meta.anchorBlockHeaderHash;
41
41
  if (!txsByBlockHash.has(blockHashStr)) {
42
42
  txsByBlockHash.set(blockHashStr, []);
43
- uniqueBlockHashes.set(blockHashStr, Fr.fromHexString(blockHashStr));
43
+ uniqueBlockHashes.set(blockHashStr, BlockHash.fromString(blockHashStr));
44
44
  }
45
45
  txsByBlockHash.get(blockHashStr)!.push(meta.txHash);
46
46
  }
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from '@aztec/foundation/log';
2
2
 
3
- import { type TxMetaData, comparePriority } from '../tx_metadata.js';
3
+ import { type TxMetaData, comparePriority, getMinimumPriceBumpFee } from '../tx_metadata.js';
4
4
  import {
5
5
  type EvictionConfig,
6
6
  type PreAddContext,
@@ -48,10 +48,14 @@ export class LowPriorityPreAddRule implements PreAddRule {
48
48
  }
49
49
 
50
50
  // Compare incoming tx against lowest priority tx.
51
- // feeOnly mode (RPC): use strict fee comparison only — avoids churn from hash ordering
52
- // Default (gossip): use full comparePriority (fee + tx hash tiebreaker) for determinism
51
+ // feeOnly mode (RPC): use strict fee comparison only — avoids churn from hash ordering.
52
+ // When price bump is also set, require the bumped fee threshold.
53
+ // Default (gossip): use full comparePriority (fee + tx hash tiebreaker) for determinism.
53
54
  const isHigherPriority = context?.feeComparisonOnly
54
- ? incomingMeta.priorityFee > lowestPriorityMeta.priorityFee
55
+ ? context.priceBumpPercentage !== undefined
56
+ ? incomingMeta.priorityFee >=
57
+ getMinimumPriceBumpFee(lowestPriorityMeta.priorityFee, context.priceBumpPercentage)
58
+ : incomingMeta.priorityFee > lowestPriorityMeta.priorityFee
55
59
  : comparePriority(incomingMeta, lowestPriorityMeta) > 0;
56
60
 
57
61
  if (isHigherPriority) {
@@ -66,6 +70,11 @@ export class LowPriorityPreAddRule implements PreAddRule {
66
70
  }
67
71
 
68
72
  // Incoming tx has equal or lower priority - ignore it (it would be evicted anyway)
73
+ const minimumFee =
74
+ context?.feeComparisonOnly && context.priceBumpPercentage !== undefined
75
+ ? getMinimumPriceBumpFee(lowestPriorityMeta.priorityFee, context.priceBumpPercentage)
76
+ : lowestPriorityMeta.priorityFee + 1n;
77
+
69
78
  this.log.debug(
70
79
  `Pool at capacity (${currentCount}/${this.maxPoolSize}), ignoring ${incomingMeta.txHash} ` +
71
80
  `(priority ${incomingMeta.priorityFee}) - lower than existing minimum (priority ${lowestPriorityMeta.priorityFee})`,
@@ -75,8 +84,8 @@ export class LowPriorityPreAddRule implements PreAddRule {
75
84
  txHashesToEvict: [],
76
85
  reason: {
77
86
  code: TxPoolRejectionCode.LOW_PRIORITY_FEE,
78
- message: `Tx does not meet minimum priority fee. Required: ${lowestPriorityMeta.priorityFee + 1n}, got: ${incomingMeta.priorityFee}`,
79
- minimumPriorityFee: lowestPriorityMeta.priorityFee + 1n,
87
+ message: `Tx does not meet minimum priority fee. Required: ${minimumFee}, got: ${incomingMeta.priorityFee}`,
88
+ minimumPriorityFee: minimumFee,
80
89
  txPriorityFee: incomingMeta.priorityFee,
81
90
  },
82
91
  });
@@ -15,11 +15,12 @@ export class NullifierConflictRule implements PreAddRule {
15
15
 
16
16
  private log = createLogger('p2p:tx_pool_v2:nullifier_conflict_rule');
17
17
 
18
- check(incomingMeta: TxMetaData, poolAccess: PreAddPoolAccess, _context?: PreAddContext): Promise<PreAddResult> {
18
+ check(incomingMeta: TxMetaData, poolAccess: PreAddPoolAccess, context?: PreAddContext): Promise<PreAddResult> {
19
19
  const result = checkNullifierConflict(
20
20
  incomingMeta,
21
21
  nullifier => poolAccess.getTxHashByNullifier(nullifier),
22
22
  txHash => poolAccess.getMetadata(txHash),
23
+ context?.priceBumpPercentage,
23
24
  );
24
25
 
25
26
  if (result.shouldIgnore) {
@@ -46,6 +46,8 @@ export type TxPoolV2Config = {
46
46
  evictedTxCacheSize: number;
47
47
  /** The probability (0-1) that a transaction is discarded. 0 disables dropping. For testing purposes only. */
48
48
  dropTransactionsProbability: number;
49
+ /** Minimum percentage fee increase required to replace an existing tx via RPC (0 = no bump). */
50
+ priceBumpPercentage: bigint;
49
51
  };
50
52
 
51
53
  /**
@@ -57,6 +59,7 @@ export const DEFAULT_TX_POOL_V2_CONFIG: TxPoolV2Config = {
57
59
  minTxPoolAgeMs: 2_000,
58
60
  evictedTxCacheSize: 10_000,
59
61
  dropTransactionsProbability: 0,
62
+ priceBumpPercentage: 10n,
60
63
  };
61
64
 
62
65
  /**
@@ -69,6 +72,8 @@ export type TxPoolV2Dependencies = {
69
72
  worldStateSynchronizer: WorldStateSynchronizer;
70
73
  /** Factory that creates a validator for re-validating pool transactions using metadata */
71
74
  createTxValidator: () => Promise<TxValidator<TxMetaData>>;
75
+ /** Checks whether a tx's setup-phase calls are on the allow list. Precomputed at receipt time. */
76
+ checkAllowedSetupCalls: (tx: Tx) => Promise<boolean>;
72
77
  };
73
78
 
74
79
  /**
@@ -155,10 +160,10 @@ export interface TxPoolV2 extends TypedEventEmitter<TxPoolV2Events> {
155
160
  handleMinedBlock(block: L2Block): Promise<void>;
156
161
 
157
162
  /**
158
- * Prepares the pool for a new slot.
159
- * Unprotects transactions from earlier slots and validates them before
160
- * returning to pending state.
161
- * @param slotNumber - The slot number to prepare for
163
+ * Prepares the pool for a new slot by unprotecting transactions from earlier
164
+ * slots and re-validating them before returning to pending state.
165
+ * @param slotNumber - The pipeline slot we are building for (i.e. the slot
166
+ * the resulting blocks will target on L1).
162
167
  */
163
168
  prepareForSlot(slotNumber: SlotNumber): Promise<void>;
164
169
 
@@ -1,3 +1,4 @@
1
+ import { minBigint } from '@aztec/foundation/bigint';
1
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
3
  import { Fr } from '@aztec/foundation/curves/bn254';
3
4
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
@@ -6,7 +7,6 @@ import { Gas } from '@aztec/stdlib/gas';
6
7
  import { type Tx, TxHash } from '@aztec/stdlib/tx';
7
8
 
8
9
  import { getFeePayerBalanceDelta } from '../../msg_validators/tx_validator/fee_payer_balance.js';
9
- import { getTxPriorityFee } from '../tx_pool/priority.js';
10
10
  import { type PreAddResult, TxPoolRejectionCode } from './eviction/interfaces.js';
11
11
 
12
12
  /** Validator-compatible data interface, mirroring the subset of PrivateKernelTailCircuitPublicInputs used by validators. */
@@ -67,6 +67,9 @@ export type TxMetaData = {
67
67
  /** Timestamp by which the transaction must be included (for expiration checks) */
68
68
  readonly expirationTimestamp: bigint;
69
69
 
70
+ /** Whether the tx's setup-phase calls pass the allow list check. Computed at receipt time. */
71
+ readonly allowedSetupCalls: boolean;
72
+
70
73
  /** Validator-compatible data, providing the same access patterns as Tx.data */
71
74
  readonly data: TxMetaValidationData;
72
75
 
@@ -84,8 +87,12 @@ export type TxState = 'pending' | 'protected' | 'mined' | 'deleted';
84
87
  * Builds TxMetaData from a full Tx object.
85
88
  * Extracts all relevant fields for efficient in-memory storage and querying.
86
89
  * Fr values are captured in closures for zero-cost re-validation.
90
+ *
91
+ * @param allowedSetupCalls - Whether the tx's setup-phase calls pass the allow list.
92
+ * For gossip/RPC txs this is always `true` (already validated by PhasesTxValidator).
93
+ * For req/resp txs this should be computed by the caller using the phases validator.
87
94
  */
88
- export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
95
+ export async function buildTxMetaData(tx: Tx, allowedSetupCalls: boolean = true): Promise<TxMetaData> {
89
96
  const txHashObj = tx.getTxHash();
90
97
  const txHash = txHashObj.toString();
91
98
  const txHashBigInt = txHashObj.toBigInt();
@@ -112,6 +119,7 @@ export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
112
119
  feeLimit,
113
120
  nullifiers,
114
121
  expirationTimestamp,
122
+ allowedSetupCalls,
115
123
  receivedAt: 0,
116
124
  estimatedSizeBytes,
117
125
  data: {
@@ -158,13 +166,13 @@ export function txHashFromBigInt(value: bigint): string {
158
166
  }
159
167
 
160
168
  /** Minimal fields required for priority comparison. */
161
- type PriorityComparable = Pick<TxMetaData, 'txHashBigInt' | 'priorityFee'>;
169
+ export type PriorityComparable = Pick<TxMetaData, 'txHash' | 'txHashBigInt' | 'priorityFee'>;
162
170
 
163
171
  /**
164
172
  * Compares two priority fees in ascending order.
165
173
  * Returns negative if a < b, positive if a > b, 0 if equal.
166
174
  */
167
- export function compareFee(a: bigint, b: bigint): number {
175
+ export function compareFee(a: bigint, b: bigint): -1 | 0 | 1 {
168
176
  return a < b ? -1 : a > b ? 1 : 0;
169
177
  }
170
178
 
@@ -173,7 +181,7 @@ export function compareFee(a: bigint, b: bigint): number {
173
181
  * Uses field element comparison for deterministic ordering.
174
182
  * Returns negative if a < b, positive if a > b, 0 if equal.
175
183
  */
176
- export function compareTxHash(a: bigint, b: bigint): number {
184
+ export function compareTxHash(a: bigint, b: bigint): -1 | 0 | 1 {
177
185
  return Fr.cmpAsBigInt(a, b);
178
186
  }
179
187
 
@@ -182,7 +190,7 @@ export function compareTxHash(a: bigint, b: bigint): number {
182
190
  * Returns negative if a < b, positive if a > b, 0 if equal.
183
191
  * Use with sort() for ascending order, or negate/reverse for descending.
184
192
  */
185
- export function comparePriority(a: PriorityComparable, b: PriorityComparable): number {
193
+ export function comparePriority(a: PriorityComparable, b: PriorityComparable): -1 | 0 | 1 {
186
194
  const feeComparison = compareFee(a.priorityFee, b.priorityFee);
187
195
  if (feeComparison !== 0) {
188
196
  return feeComparison;
@@ -190,21 +198,38 @@ export function comparePriority(a: PriorityComparable, b: PriorityComparable): n
190
198
  return compareTxHash(a.txHashBigInt, b.txHashBigInt);
191
199
  }
192
200
 
201
+ /**
202
+ * Returns the minimum fee required to replace an existing tx with the given price bump percentage.
203
+ * Uses integer arithmetic: `existingFee + existingFee * priceBumpPercentage / 100`.
204
+ */
205
+ export function getMinimumPriceBumpFee(existingFee: bigint, priceBumpPercentage: bigint): bigint {
206
+ const bump = (existingFee * priceBumpPercentage) / 100n;
207
+ // Ensure the minimum bump is at least 1, so that replacement always requires
208
+ // paying strictly more — even with 0% bump or zero existing fee.
209
+ const effectiveBump = bump > 0n ? bump : 1n;
210
+ return existingFee + effectiveBump;
211
+ }
212
+
193
213
  /**
194
214
  * Checks for nullifier conflicts between an incoming transaction and existing pool state.
195
215
  *
196
216
  * When the incoming tx shares nullifiers with existing pending txs:
197
- * - If the incoming tx has strictly higher priority, mark conflicting txs for eviction
198
- * - If any conflicting tx has equal or higher priority, ignore the incoming tx
217
+ * - If the incoming tx meets or exceeds the required priority, mark conflicting txs for eviction
218
+ * - Otherwise, ignore the incoming tx
219
+ *
220
+ * When `priceBumpPercentage` is provided (RPC path), uses fee-only comparison with the
221
+ * percentage bump instead of `comparePriority`.
199
222
  *
200
223
  * @param incomingMeta - Metadata for the incoming transaction
201
224
  * @param getTxHashByNullifier - Accessor to find which tx uses a nullifier
202
225
  * @param getMetadata - Accessor to get metadata for a tx hash
226
+ * @param priceBumpPercentage - Optional percentage bump required for fee-based replacement
203
227
  */
204
228
  export function checkNullifierConflict(
205
229
  incomingMeta: TxMetaData,
206
230
  getTxHashByNullifier: (nullifier: string) => string | undefined,
207
231
  getMetadata: (txHash: string) => TxMetaData | undefined,
232
+ priceBumpPercentage?: bigint,
208
233
  ): PreAddResult {
209
234
  const txHashesToEvict: string[] = [];
210
235
 
@@ -225,19 +250,32 @@ export function checkNullifierConflict(
225
250
  continue;
226
251
  }
227
252
 
228
- // If incoming tx has strictly higher priority, mark for eviction
229
- // Otherwise, ignore incoming tx (ties go to existing tx)
230
- // Use comparePriority for deterministic ordering (includes txHash as tiebreaker)
231
- if (comparePriority(incomingMeta, conflictingMeta) > 0) {
253
+ // When price bump is set (RPC path), require the incoming fee to meet the bumped threshold.
254
+ // Otherwise (P2P path), use full comparePriority with tx hash tiebreaker.
255
+ const isHigherPriority =
256
+ priceBumpPercentage !== undefined
257
+ ? incomingMeta.priorityFee >= getMinimumPriceBumpFee(conflictingMeta.priorityFee, priceBumpPercentage)
258
+ : comparePriority(incomingMeta, conflictingMeta) > 0;
259
+
260
+ if (isHigherPriority) {
232
261
  txHashesToEvict.push(conflictingHashStr);
233
262
  } else {
263
+ const minimumFee =
264
+ priceBumpPercentage !== undefined
265
+ ? getMinimumPriceBumpFee(conflictingMeta.priorityFee, priceBumpPercentage)
266
+ : undefined;
234
267
  return {
235
268
  shouldIgnore: true,
236
269
  txHashesToEvict: [],
237
270
  reason: {
238
271
  code: TxPoolRejectionCode.NULLIFIER_CONFLICT,
239
- message: `Nullifier conflict with existing tx ${conflictingHashStr}`,
272
+ message:
273
+ minimumFee !== undefined
274
+ ? `Nullifier conflict with existing tx ${conflictingHashStr}. Minimum required fee: ${minimumFee}, got: ${incomingMeta.priorityFee}`
275
+ : `Nullifier conflict with existing tx ${conflictingHashStr}`,
240
276
  conflictingTxHash: conflictingHashStr,
277
+ minimumPriceBumpFee: minimumFee,
278
+ txPriorityFee: minimumFee !== undefined ? incomingMeta.priorityFee : undefined,
241
279
  },
242
280
  };
243
281
  }
@@ -253,7 +291,7 @@ export function stubTxMetaValidationData(overrides: { expirationTimestamp?: bigi
253
291
  expirationTimestamp: overrides.expirationTimestamp ?? 0n,
254
292
  constants: {
255
293
  anchorBlockHeader: {
256
- hash: () => Promise.resolve(new BlockHash(Fr.ZERO)),
294
+ hash: () => Promise.resolve(BlockHash.ZERO),
257
295
  globalVariables: { blockNumber: BlockNumber(0) },
258
296
  },
259
297
  txContext: {
@@ -274,6 +312,7 @@ export function stubTxMetaData(
274
312
  nullifiers?: string[];
275
313
  expirationTimestamp?: bigint;
276
314
  anchorBlockHeaderHash?: string;
315
+ allowedSetupCalls?: boolean;
277
316
  } = {},
278
317
  ): TxMetaData {
279
318
  const txHashBigInt = Fr.fromHexString(txHash).toBigInt();
@@ -290,8 +329,15 @@ export function stubTxMetaData(
290
329
  feeLimit: overrides.feeLimit ?? 100n,
291
330
  nullifiers: overrides.nullifiers ?? [`0x${normalizedTxHash.slice(2)}null1`],
292
331
  expirationTimestamp,
332
+ allowedSetupCalls: overrides.allowedSetupCalls ?? true,
293
333
  receivedAt: 0,
294
334
  estimatedSizeBytes: 0,
295
335
  data: stubTxMetaValidationData({ expirationTimestamp }),
296
336
  };
297
337
  }
338
+
339
+ /** Returns the priority fee for a tx, based on the L2 priority fee capped by the max fee per gas. */
340
+ function getTxPriorityFee(tx: Tx): bigint {
341
+ const { maxPriorityFeesPerGas: priorityFees, maxFeesPerGas } = tx.getGasSettings();
342
+ return minBigint(maxFeesPerGas.feePerL2Gas, priorityFees.feePerL2Gas);
343
+ }
@@ -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, txHashFromBigInt } 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 txHash bigints grouped by priority fee */
26
- #pendingByPriority: Map<bigint, Set<bigint>> = 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
- const feeCompareFn = order === 'desc' ? (a: bigint, b: bigint) => compareFee(b, a) : compareFee;
77
- const hashCompareFn =
78
- order === 'desc' ? (a: bigint, b: bigint) => compareTxHash(b, a) : (a: bigint, b: bigint) => compareTxHash(a, b);
79
-
80
- const sortedFees = [...this.#pendingByPriority.keys()].sort(feeCompareFn);
81
-
82
- for (const fee of sortedFees) {
83
- const hashesAtFee = this.#pendingByPriority.get(fee)!;
84
- const sortedHashes = [...hashesAtFee].sort(hashCompareFn);
85
- for (const hashBigInt of sortedHashes) {
86
- const hash = txHashFromBigInt(hashBigInt);
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 txHashBigInt of hashSet) {
269
- const meta = this.#metadata.get(txHashFromBigInt(txHashBigInt));
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;
@@ -408,13 +397,12 @@ export class TxPoolIndices {
408
397
  }
409
398
  feePayerSet.add(meta.txHash);
410
399
 
411
- // Add to priority bucket
412
- let prioritySet = this.#pendingByPriority.get(meta.priorityFee);
413
- if (!prioritySet) {
414
- prioritySet = new Set();
415
- this.#pendingByPriority.set(meta.priorityFee, prioritySet);
416
- }
417
- prioritySet.add(meta.txHashBigInt);
400
+ insertIntoSortedArray(
401
+ this.#pendingByPriority,
402
+ { txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
403
+ comparePriority,
404
+ false,
405
+ );
418
406
  }
419
407
 
420
408
  #removeFromPendingIndices(meta: TxMetaData): void {
@@ -432,13 +420,11 @@ export class TxPoolIndices {
432
420
  }
433
421
  }
434
422
 
435
- // Remove from priority map
436
- const hashSet = this.#pendingByPriority.get(meta.priorityFee);
437
- if (hashSet) {
438
- hashSet.delete(meta.txHashBigInt);
439
- if (hashSet.size === 0) {
440
- this.#pendingByPriority.delete(meta.priorityFee);
441
- }
442
- }
423
+ // Remove from priority array
424
+ removeFromSortedArray(
425
+ this.#pendingByPriority,
426
+ { txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
427
+ comparePriority,
428
+ );
443
429
  }
444
430
  }
@@ -11,7 +11,14 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien
11
11
  import EventEmitter from 'node:events';
12
12
 
13
13
  import { PoolInstrumentation, PoolName } from '../instrumentation.js';
14
- import type { AddTxsResult, TxPoolV2, TxPoolV2Config, TxPoolV2Dependencies, TxPoolV2Events } from './interfaces.js';
14
+ import type {
15
+ AddTxsResult,
16
+ PoolReadAccess,
17
+ TxPoolV2,
18
+ TxPoolV2Config,
19
+ TxPoolV2Dependencies,
20
+ TxPoolV2Events,
21
+ } from './interfaces.js';
15
22
  import type { TxState } from './tx_metadata.js';
16
23
  import { TxPoolV2Impl } from './tx_pool_v2_impl.js';
17
24
 
@@ -165,6 +172,11 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
165
172
  return this.#queue.put(() => Promise.resolve(this.#impl.getLowestPriorityPending(limit)));
166
173
  }
167
174
 
175
+ /** Returns read-only access to the pool. Used for testing. */
176
+ getPoolReadAccess(): PoolReadAccess {
177
+ return this.#impl.getPoolReadAccess();
178
+ }
179
+
168
180
  // === Configuration ===
169
181
 
170
182
  updateConfig(config: Partial<TxPoolV2Config>): Promise<void> {