@aztec/p2p 0.0.1-commit.e558bd1c → 0.0.1-commit.e57c76e

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 (521) hide show
  1. package/README.md +129 -3
  2. package/dest/bootstrap/bootstrap.d.ts +1 -1
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  4. package/dest/bootstrap/bootstrap.js +9 -1
  5. package/dest/client/factory.d.ts +11 -10
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +58 -16
  8. package/dest/client/interface.d.ts +51 -36
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +48 -57
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +219 -236
  13. package/dest/config.d.ts +161 -94
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +150 -41
  16. package/dest/errors/p2p-service.error.d.ts +9 -0
  17. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  18. package/dest/errors/p2p-service.error.js +10 -0
  19. package/dest/errors/reqresp.error.d.ts +1 -20
  20. package/dest/errors/reqresp.error.d.ts.map +1 -1
  21. package/dest/errors/reqresp.error.js +0 -21
  22. package/dest/errors/tx-pool.error.d.ts +8 -0
  23. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  24. package/dest/errors/tx-pool.error.js +9 -0
  25. package/dest/index.d.ts +2 -2
  26. package/dest/index.d.ts.map +1 -1
  27. package/dest/index.js +1 -1
  28. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -55
  29. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/attestation_pool.js +295 -195
  31. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  32. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  33. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +231 -115
  34. package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
  35. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  36. package/dest/mem_pools/attestation_pool/index.js +1 -1
  37. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  38. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  39. package/dest/mem_pools/attestation_pool/mocks.js +7 -5
  40. package/dest/mem_pools/index.d.ts +2 -2
  41. package/dest/mem_pools/index.d.ts.map +1 -1
  42. package/dest/mem_pools/instrumentation.d.ts +4 -2
  43. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  44. package/dest/mem_pools/instrumentation.js +33 -15
  45. package/dest/mem_pools/interface.d.ts +3 -3
  46. package/dest/mem_pools/interface.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -5
  48. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
  50. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  51. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  52. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  53. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  54. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  56. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  57. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  58. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +7 -3
  59. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  60. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  62. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +3 -2
  63. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/eviction/index.js +2 -1
  65. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  66. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  68. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  69. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  71. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
  72. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +9 -7
  73. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  74. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  75. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +14 -6
  76. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  77. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  78. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  79. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  80. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  81. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  82. package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
  83. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  84. package/dest/mem_pools/tx_pool_v2/index.js +2 -1
  85. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  86. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  87. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  88. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +33 -12
  89. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  90. package/dest/mem_pools/tx_pool_v2/interfaces.js +5 -1
  91. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +81 -15
  92. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  93. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +147 -19
  94. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
  95. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  96. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +50 -45
  97. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +12 -5
  98. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  99. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +17 -6
  100. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +14 -5
  101. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  102. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +407 -241
  103. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
  104. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  105. package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
  106. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  107. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  108. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  109. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  110. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  111. package/dest/msg_validators/clock_tolerance.js +56 -3
  112. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +10 -4
  113. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  114. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  115. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +10 -4
  116. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  117. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  118. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +21 -8
  119. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  120. package/dest/msg_validators/proposal_validator/proposal_validator.js +90 -44
  121. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  122. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  123. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +11 -18
  124. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  125. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  126. package/dest/msg_validators/tx_validator/allowed_public_setup.js +25 -21
  127. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  128. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  129. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  130. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  131. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  132. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  133. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  134. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  135. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  136. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  137. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  138. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  139. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  140. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  141. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  142. package/dest/msg_validators/tx_validator/data_validator.js +36 -2
  143. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  144. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  145. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  146. package/dest/msg_validators/tx_validator/factory.d.ts +135 -7
  147. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  148. package/dest/msg_validators/tx_validator/factory.js +252 -61
  149. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  150. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  151. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  152. package/dest/msg_validators/tx_validator/gas_validator.d.ts +99 -3
  153. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  154. package/dest/msg_validators/tx_validator/gas_validator.js +137 -53
  155. package/dest/msg_validators/tx_validator/index.d.ts +5 -1
  156. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  157. package/dest/msg_validators/tx_validator/index.js +4 -0
  158. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  159. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  160. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  161. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  162. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  163. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  164. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  165. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  166. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  167. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  168. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  169. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  170. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  171. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  172. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  173. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  174. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  175. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  176. package/dest/services/data_store.d.ts +1 -1
  177. package/dest/services/data_store.d.ts.map +1 -1
  178. package/dest/services/data_store.js +5 -5
  179. package/dest/services/discv5/discV5_service.d.ts +2 -1
  180. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  181. package/dest/services/discv5/discV5_service.js +35 -8
  182. package/dest/services/dummy_service.d.ts +18 -18
  183. package/dest/services/dummy_service.d.ts.map +1 -1
  184. package/dest/services/dummy_service.js +19 -20
  185. package/dest/services/encoding.d.ts +7 -3
  186. package/dest/services/encoding.d.ts.map +1 -1
  187. package/dest/services/encoding.js +18 -11
  188. package/dest/services/gossipsub/index.d.ts +3 -0
  189. package/dest/services/gossipsub/index.d.ts.map +1 -0
  190. package/dest/services/gossipsub/index.js +2 -0
  191. package/dest/services/gossipsub/scoring.d.ts +21 -3
  192. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  193. package/dest/services/gossipsub/scoring.js +24 -7
  194. package/dest/services/gossipsub/topic_score_params.d.ts +184 -0
  195. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  196. package/dest/services/gossipsub/topic_score_params.js +363 -0
  197. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  198. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  199. package/dest/services/libp2p/instrumentation.js +14 -0
  200. package/dest/services/libp2p/libp2p_service.d.ts +56 -55
  201. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  202. package/dest/services/libp2p/libp2p_service.js +449 -397
  203. package/dest/services/peer-manager/metrics.d.ts +3 -1
  204. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  205. package/dest/services/peer-manager/metrics.js +6 -0
  206. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  207. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  208. package/dest/services/peer-manager/peer_manager.js +40 -11
  209. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  210. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  211. package/dest/services/peer-manager/peer_scoring.js +57 -12
  212. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +5 -8
  213. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  214. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +95 -127
  215. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +11 -11
  216. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  217. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  218. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  219. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  220. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  221. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  222. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  223. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  224. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  225. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  226. package/dest/services/reqresp/config.d.ts +3 -3
  227. package/dest/services/reqresp/config.d.ts.map +1 -1
  228. package/dest/services/reqresp/interface.d.ts +25 -18
  229. package/dest/services/reqresp/interface.d.ts.map +1 -1
  230. package/dest/services/reqresp/interface.js +23 -19
  231. package/dest/services/reqresp/metrics.d.ts +1 -1
  232. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  233. package/dest/services/reqresp/metrics.js +0 -1
  234. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  235. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  236. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  237. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
  238. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  239. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
  240. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +18 -7
  241. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  242. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +57 -24
  243. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  244. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  245. package/dest/services/reqresp/protocols/index.js +0 -1
  246. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  247. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  248. package/dest/services/reqresp/protocols/tx.js +21 -3
  249. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  250. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  251. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  252. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  253. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  254. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  255. package/dest/services/reqresp/reqresp.d.ts +7 -29
  256. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  257. package/dest/services/reqresp/reqresp.js +53 -218
  258. package/dest/services/service.d.ts +30 -14
  259. package/dest/services/service.d.ts.map +1 -1
  260. package/dest/services/tx_collection/config.d.ts +11 -14
  261. package/dest/services/tx_collection/config.d.ts.map +1 -1
  262. package/dest/services/tx_collection/config.js +26 -33
  263. package/dest/services/tx_collection/file_store_tx_collection.d.ts +37 -0
  264. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  265. package/dest/services/tx_collection/file_store_tx_collection.js +127 -0
  266. package/dest/services/tx_collection/file_store_tx_source.d.ts +38 -0
  267. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  268. package/dest/services/tx_collection/file_store_tx_source.js +100 -0
  269. package/dest/services/tx_collection/index.d.ts +3 -3
  270. package/dest/services/tx_collection/index.d.ts.map +1 -1
  271. package/dest/services/tx_collection/index.js +1 -1
  272. package/dest/services/tx_collection/instrumentation.js +1 -2
  273. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  274. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  275. package/dest/services/tx_collection/request_tracker.js +84 -0
  276. package/dest/services/tx_collection/tx_collection.d.ts +45 -51
  277. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  278. package/dest/services/tx_collection/tx_collection.js +296 -68
  279. package/dest/services/tx_collection/tx_collection_sink.d.ts +19 -9
  280. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  281. package/dest/services/tx_collection/tx_collection_sink.js +28 -31
  282. package/dest/services/tx_collection/tx_source.d.ts +13 -7
  283. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  284. package/dest/services/tx_collection/tx_source.js +26 -7
  285. package/dest/services/tx_file_store/config.d.ts +1 -3
  286. package/dest/services/tx_file_store/config.d.ts.map +1 -1
  287. package/dest/services/tx_file_store/config.js +0 -4
  288. package/dest/services/tx_file_store/tx_file_store.d.ts +4 -5
  289. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  290. package/dest/services/tx_file_store/tx_file_store.js +13 -20
  291. package/dest/services/tx_provider.d.ts +6 -4
  292. package/dest/services/tx_provider.d.ts.map +1 -1
  293. package/dest/services/tx_provider.js +12 -8
  294. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  295. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  296. package/dest/test-helpers/make-test-p2p-clients.js +5 -3
  297. package/dest/test-helpers/mock-pubsub.d.ts +46 -6
  298. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  299. package/dest/test-helpers/mock-pubsub.js +115 -14
  300. package/dest/test-helpers/reqresp-nodes.d.ts +5 -7
  301. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  302. package/dest/test-helpers/reqresp-nodes.js +19 -20
  303. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  304. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  305. package/dest/test-helpers/test_tx_provider.js +3 -0
  306. package/dest/test-helpers/testbench-utils.d.ts +46 -37
  307. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  308. package/dest/test-helpers/testbench-utils.js +142 -50
  309. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  310. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  311. package/dest/testbench/p2p_client_testbench_worker.js +93 -47
  312. package/dest/testbench/worker_client_manager.d.ts +12 -6
  313. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  314. package/dest/testbench/worker_client_manager.js +57 -11
  315. package/dest/util.d.ts +13 -8
  316. package/dest/util.d.ts.map +1 -1
  317. package/dest/util.js +35 -14
  318. package/dest/versioning.d.ts +3 -6
  319. package/dest/versioning.d.ts.map +1 -1
  320. package/dest/versioning.js +3 -24
  321. package/package.json +15 -14
  322. package/src/bootstrap/bootstrap.ts +9 -1
  323. package/src/client/factory.ts +124 -27
  324. package/src/client/interface.ts +58 -44
  325. package/src/client/p2p_client.ts +256 -299
  326. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  327. package/src/config.ts +260 -46
  328. package/src/errors/p2p-service.error.ts +11 -0
  329. package/src/errors/reqresp.error.ts +0 -25
  330. package/src/errors/tx-pool.error.ts +12 -0
  331. package/src/index.ts +1 -1
  332. package/src/mem_pools/attestation_pool/attestation_pool.ts +363 -236
  333. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +258 -118
  334. package/src/mem_pools/attestation_pool/index.ts +3 -3
  335. package/src/mem_pools/attestation_pool/mocks.ts +14 -8
  336. package/src/mem_pools/index.ts +1 -1
  337. package/src/mem_pools/instrumentation.ts +22 -14
  338. package/src/mem_pools/interface.ts +2 -2
  339. package/src/mem_pools/tx_pool_v2/README.md +85 -11
  340. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
  341. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  342. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  343. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +7 -3
  344. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  345. package/src/mem_pools/tx_pool_v2/eviction/index.ts +5 -0
  346. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  347. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  348. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
  349. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +8 -8
  350. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -9
  351. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  352. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  353. package/src/mem_pools/tx_pool_v2/index.ts +2 -1
  354. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  355. package/src/mem_pools/tx_pool_v2/interfaces.ts +35 -12
  356. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +215 -27
  357. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +58 -45
  358. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +34 -8
  359. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +448 -240
  360. package/src/msg_validators/attestation_validator/README.md +49 -0
  361. package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
  362. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +14 -7
  363. package/src/msg_validators/clock_tolerance.ts +73 -3
  364. package/src/msg_validators/proposal_validator/README.md +123 -0
  365. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +24 -4
  366. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +35 -7
  367. package/src/msg_validators/proposal_validator/proposal_validator.ts +114 -47
  368. package/src/msg_validators/tx_validator/README.md +127 -0
  369. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +8 -17
  370. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  371. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  372. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  373. package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
  374. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  375. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  376. package/src/msg_validators/tx_validator/data_validator.ts +44 -1
  377. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  378. package/src/msg_validators/tx_validator/factory.ts +407 -80
  379. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  380. package/src/msg_validators/tx_validator/gas_validator.ts +199 -54
  381. package/src/msg_validators/tx_validator/index.ts +4 -0
  382. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  383. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  384. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  385. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  386. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  387. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  388. package/src/services/data_store.ts +5 -13
  389. package/src/services/discv5/discV5_service.ts +38 -5
  390. package/src/services/dummy_service.ts +26 -45
  391. package/src/services/encoding.ts +18 -10
  392. package/src/services/gossipsub/README.md +641 -0
  393. package/src/services/gossipsub/index.ts +2 -0
  394. package/src/services/gossipsub/scoring.ts +29 -5
  395. package/src/services/gossipsub/topic_score_params.ts +519 -0
  396. package/src/services/libp2p/instrumentation.ts +14 -0
  397. package/src/services/libp2p/libp2p_service.ts +497 -453
  398. package/src/services/peer-manager/metrics.ts +7 -0
  399. package/src/services/peer-manager/peer_manager.ts +46 -11
  400. package/src/services/peer-manager/peer_scoring.ts +52 -5
  401. package/src/services/reqresp/README.md +215 -0
  402. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  403. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +92 -138
  404. package/src/services/reqresp/batch-tx-requester/interface.ts +14 -10
  405. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  406. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  407. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  408. package/src/services/reqresp/config.ts +2 -2
  409. package/src/services/reqresp/interface.ts +45 -46
  410. package/src/services/reqresp/metrics.ts +0 -1
  411. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  412. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +36 -32
  413. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +64 -20
  414. package/src/services/reqresp/protocols/index.ts +0 -1
  415. package/src/services/reqresp/protocols/tx.ts +23 -3
  416. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  417. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  418. package/src/services/reqresp/reqresp.ts +61 -264
  419. package/src/services/service.ts +43 -30
  420. package/src/services/tx_collection/config.ts +40 -49
  421. package/src/services/tx_collection/file_store_tx_collection.ts +153 -0
  422. package/src/services/tx_collection/file_store_tx_source.ts +129 -0
  423. package/src/services/tx_collection/index.ts +2 -6
  424. package/src/services/tx_collection/instrumentation.ts +1 -1
  425. package/src/services/tx_collection/request_tracker.ts +127 -0
  426. package/src/services/tx_collection/tx_collection.ts +362 -110
  427. package/src/services/tx_collection/tx_collection_sink.ts +32 -36
  428. package/src/services/tx_collection/tx_source.ts +28 -8
  429. package/src/services/tx_file_store/config.ts +0 -6
  430. package/src/services/tx_file_store/tx_file_store.ts +15 -25
  431. package/src/services/tx_provider.ts +15 -9
  432. package/src/test-helpers/make-test-p2p-clients.ts +7 -6
  433. package/src/test-helpers/mock-pubsub.ts +137 -14
  434. package/src/test-helpers/reqresp-nodes.ts +17 -29
  435. package/src/test-helpers/test_tx_provider.ts +5 -0
  436. package/src/test-helpers/testbench-utils.ts +168 -68
  437. package/src/testbench/p2p_client_testbench_worker.ts +99 -62
  438. package/src/testbench/worker_client_manager.ts +72 -25
  439. package/src/util.ts +40 -19
  440. package/src/versioning.ts +3 -33
  441. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  442. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  443. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
  444. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  445. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  446. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  447. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  448. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  449. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  450. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  451. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  452. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  453. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  454. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  455. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  456. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  457. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  458. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  459. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  460. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  461. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  462. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  463. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  464. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  465. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  466. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  467. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  468. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  469. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  470. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  471. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  472. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  473. package/dest/mem_pools/tx_pool/index.js +0 -2
  474. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  475. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  476. package/dest/mem_pools/tx_pool/priority.js +0 -15
  477. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  478. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  479. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  480. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  481. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  482. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  483. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  484. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  485. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  486. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  487. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  488. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  489. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  490. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  491. package/dest/services/reqresp/protocols/block.js +0 -32
  492. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -52
  493. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  494. package/dest/services/tx_collection/fast_tx_collection.js +0 -307
  495. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
  496. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  497. package/dest/services/tx_collection/proposal_tx_collector.js +0 -49
  498. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -53
  499. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  500. package/dest/services/tx_collection/slow_tx_collection.js +0 -177
  501. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -336
  502. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  503. package/src/mem_pools/tx_pool/README.md +0 -270
  504. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  505. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  506. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  507. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  508. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  509. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  510. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  511. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  512. package/src/mem_pools/tx_pool/index.ts +0 -2
  513. package/src/mem_pools/tx_pool/priority.ts +0 -20
  514. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  515. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  516. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
  517. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  518. package/src/services/reqresp/protocols/block.ts +0 -37
  519. package/src/services/tx_collection/fast_tx_collection.ts +0 -354
  520. package/src/services/tx_collection/proposal_tx_collector.ts +0 -112
  521. package/src/services/tx_collection/slow_tx_collection.ts +0 -233
@@ -1,13 +1,22 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { FifoSet } from '@aztec/foundation/fifo-set';
1
3
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
2
4
  import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
3
5
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
4
6
  import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
5
7
  import { Tx, TxHash } from '@aztec/stdlib/tx';
6
8
  import { TxArchive } from './archive/index.js';
7
- import { EvictionManager, FeePayerBalanceEvictionRule, FeePayerBalancePreAddRule, InvalidTxsAfterMiningRule, InvalidTxsAfterReorgRule, LowPriorityEvictionRule, LowPriorityPreAddRule, NullifierConflictRule } from './eviction/index.js';
9
+ import { DeletedPool } from './deleted_pool.js';
10
+ import { EvictionManager, FeePayerBalanceEvictionRule, FeePayerBalancePreAddRule, InsufficientFeePerGasEvictionRule, InvalidTxsAfterMiningRule, InvalidTxsAfterReorgRule, LowPriorityEvictionRule, LowPriorityPreAddRule, NullifierConflictRule, TxPoolRejectionCode } from './eviction/index.js';
11
+ import { TxPoolV2Instrumentation } from './instrumentation.js';
8
12
  import { DEFAULT_TX_POOL_V2_CONFIG } from './interfaces.js';
9
13
  import { buildTxMetaData, checkNullifierConflict } from './tx_metadata.js';
10
14
  import { TxPoolIndices } from './tx_pool_indices.js';
15
+ /**
16
+ * Maximum number of full transactions to load into memory at once when finalizing a block.
17
+ * Bounds peak memory while archiving and hard-deleting mined txs (~23k txs/epoch at 10 TPS would
18
+ * otherwise OOM the node).
19
+ */ const FINALIZE_BLOCK_CHUNK_SIZE = 100;
11
20
  /**
12
21
  * Implementation of TxPoolV2 logic.
13
22
  *
@@ -19,26 +28,36 @@ import { TxPoolIndices } from './tx_pool_indices.js';
19
28
  // === Dependencies ===
20
29
  #l2BlockSource;
21
30
  #worldStateSynchronizer;
22
- #pendingTxValidator;
31
+ #createTxValidator;
32
+ #checkAllowedSetupCalls;
23
33
  // === In-Memory Indices ===
24
34
  #indices = new TxPoolIndices();
25
35
  // === Config & Services ===
26
36
  #config;
27
37
  #archive;
38
+ #deletedPool;
28
39
  #evictionManager;
40
+ #dateProvider;
41
+ #instrumentation;
42
+ #evictedTxHashes;
29
43
  #log;
30
44
  #callbacks;
31
- constructor(store, archiveStore, deps, callbacks, config = {}, log){
45
+ constructor(store, archiveStore, deps, callbacks, telemetry, config = {}, dateProvider, log){
32
46
  this.#store = store;
33
47
  this.#txsDB = store.openMap('txs');
34
48
  this.#l2BlockSource = deps.l2BlockSource;
35
49
  this.#worldStateSynchronizer = deps.worldStateSynchronizer;
36
- this.#pendingTxValidator = deps.pendingTxValidator;
50
+ this.#createTxValidator = deps.createTxValidator;
51
+ this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
37
52
  this.#config = {
38
53
  ...DEFAULT_TX_POOL_V2_CONFIG,
39
54
  ...config
40
55
  };
56
+ this.#evictedTxHashes = FifoSet.withLimit(this.#config.evictedTxCacheSize);
41
57
  this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
58
+ this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
59
+ this.#dateProvider = dateProvider;
60
+ this.#instrumentation = new TxPoolV2Instrumentation(telemetry, ()=>this.#indices.getTotalMetadataBytes());
42
61
  this.#log = log;
43
62
  this.#callbacks = callbacks;
44
63
  // Setup eviction manager with rules
@@ -51,6 +70,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
51
70
  }));
52
71
  // Post-event eviction rules (run after events to check ALL pending txs)
53
72
  this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
73
+ this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
54
74
  this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
55
75
  this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
56
76
  // LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
@@ -69,30 +89,65 @@ import { TxPoolIndices } from './tx_pool_indices.js';
69
89
  * Note: Protected status is lost on restart. All non-mined txs are rebuilt as pending
70
90
  * by running pre-add rules to resolve nullifier conflicts, balance checks, and pool size limits.
71
91
  */ async hydrateFromDatabase() {
72
- // Step 1: Load all transactions from DB
73
- const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
74
- // Step 2: Check mined status for each tx
75
- await this.#markMinedStatusBatch(loaded.map((l)=>l.meta));
76
- // Step 3: Partition by mined status
77
- const mined = [];
78
- const nonMined = [];
79
- for (const entry of loaded){
80
- if (entry.meta.minedL2BlockId !== undefined) {
81
- mined.push(entry.meta);
92
+ // Step 0: Hydrate deleted pool state
93
+ await this.#deletedPool.hydrateFromDatabase();
94
+ // Step 1: Stream txs from DB, building metadata and mined status one at a time.
95
+ const minedMetas = [];
96
+ const pendingMetas = [];
97
+ const deserializationErrors = [];
98
+ for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()){
99
+ // Skip soft-deleted transactions - they stay in DB but not in indices
100
+ if (this.#deletedPool.isSoftDeleted(txHashStr)) {
101
+ continue;
102
+ }
103
+ let meta;
104
+ let txEffect;
105
+ try {
106
+ const tx = Tx.fromBuffer(buffer);
107
+ // Resolve allowed-setup-calls and the tx effect concurrently
108
+ // getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
109
+ // its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
110
+ const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch((err)=>{
111
+ this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, {
112
+ err
113
+ });
114
+ return undefined;
115
+ });
116
+ const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
117
+ this.#checkAllowedSetupCalls(tx),
118
+ txEffectPromise
119
+ ]);
120
+ meta = await buildTxMetaData(tx, allowedSetupCalls);
121
+ txEffect = fetchedTxEffect;
122
+ } catch (err) {
123
+ this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, {
124
+ err
125
+ });
126
+ deserializationErrors.push(txHashStr);
127
+ continue;
128
+ }
129
+ if (txEffect) {
130
+ meta.minedL2BlockId = {
131
+ number: txEffect.l2BlockNumber,
132
+ hash: txEffect.l2BlockHash.toString()
133
+ };
134
+ }
135
+ if (meta.minedL2BlockId !== undefined) {
136
+ minedMetas.push(meta);
82
137
  } else {
83
- nonMined.push(entry);
138
+ pendingMetas.push(meta);
84
139
  }
85
140
  }
86
- // Step 4: Validate non-mined transactions
87
- const { valid, invalid } = await this.#validateTxBatch(nonMined, 'on startup');
88
- // Step 5: Populate mined indices (these don't need conflict resolution)
89
- for (const meta of mined){
141
+ // Step 2: Validate non-mined transactions
142
+ const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
143
+ // Step 3: Populate mined indices (these don't need conflict resolution)
144
+ for (const meta of minedMetas){
90
145
  this.#indices.addMined(meta);
91
146
  }
92
- // Step 6: Rebuild pending pool by running pre-add rules for each tx
147
+ // Step 4: Rebuild pending pool by running pre-add rules for each tx
93
148
  // This resolves nullifier conflicts, fee payer balance issues, and pool size limits
94
149
  const { rejected } = await this.#rebuildPendingPool(valid);
95
- // Step 7: Delete invalid and rejected txs from DB only (indices were never populated for these)
150
+ // Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
96
151
  const toDelete = [
97
152
  ...deserializationErrors,
98
153
  ...invalid,
@@ -106,14 +161,43 @@ import { TxPoolIndices } from './tx_pool_indices.js';
106
161
  await this.#txsDB.delete(txHashStr);
107
162
  }
108
163
  });
109
- this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`);
164
+ this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, {
165
+ txHashes: toDelete
166
+ });
110
167
  }
111
168
  async addPendingTxs(txs, opts) {
112
169
  const accepted = [];
113
170
  const ignored = [];
114
171
  const rejected = [];
172
+ const errors = new Map();
115
173
  const acceptedPending = new Set();
174
+ // Phase 1: Pre-compute all throwable I/O outside the transaction.
175
+ // If any pre-computation throws, the entire call fails before mutations happen.
176
+ const precomputed = new Map();
177
+ const validator = await this.#createTxValidator();
178
+ for (const tx of txs){
179
+ const txHash = tx.getTxHash();
180
+ const txHashStr = txHash.toString();
181
+ const meta = await buildTxMetaData(tx);
182
+ const minedBlockId = await this.#getMinedBlockId(txHash);
183
+ // Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
184
+ let isValid = true;
185
+ if (!minedBlockId) {
186
+ isValid = await this.#validateMeta(meta, validator);
187
+ }
188
+ precomputed.set(txHashStr, {
189
+ meta,
190
+ minedBlockId,
191
+ isValid
192
+ });
193
+ }
194
+ // Phase 2: Apply mutations inside the transaction using only pre-computed results,
195
+ // in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
116
196
  const poolAccess = this.#createPreAddPoolAccess();
197
+ const preAddContext = opts.feeComparisonOnly !== undefined ? {
198
+ feeComparisonOnly: opts.feeComparisonOnly,
199
+ priceBumpPercentage: this.#config.priceBumpPercentage
200
+ } : undefined;
117
201
  await this.#store.transactionAsync(async ()=>{
118
202
  for (const tx of txs){
119
203
  const txHash = tx.getTxHash();
@@ -123,82 +207,112 @@ import { TxPoolIndices } from './tx_pool_indices.js';
123
207
  ignored.push(txHash);
124
208
  continue;
125
209
  }
126
- // Check mined status first (applies to all paths)
127
- const minedBlockId = await this.#getMinedBlockId(txHash);
210
+ const { meta, minedBlockId, isValid } = precomputed.get(txHashStr);
128
211
  const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
129
212
  if (minedBlockId) {
130
213
  // Already mined - add directly (protection already set if pre-protected)
131
214
  await this.#addTx(tx, {
132
215
  mined: minedBlockId
133
- }, opts);
216
+ }, opts, meta);
134
217
  accepted.push(txHash);
135
218
  } else if (preProtectedSlot !== undefined) {
136
219
  // Pre-protected and not mined - add as protected (bypass validation)
137
220
  await this.#addTx(tx, {
138
221
  protected: preProtectedSlot
139
- }, opts);
222
+ }, opts, meta);
140
223
  accepted.push(txHash);
224
+ } else if (!isValid) {
225
+ // Failed pre-computed validation
226
+ rejected.push(txHash);
141
227
  } else {
142
- // Regular pending tx - validate and run pre-add rules
143
- const result = await this.#tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored);
228
+ // Regular pending tx - run pre-add rules using pre-computed metadata
229
+ const result = await this.#tryAddRegularPendingTx(tx, meta, opts, poolAccess, acceptedPending, ignored, errors, preAddContext);
144
230
  if (result.status === 'accepted') {
145
231
  acceptedPending.add(txHashStr);
146
- } else if (result.status === 'rejected') {
147
- rejected.push(txHash);
148
232
  } else {
149
233
  ignored.push(txHash);
150
234
  }
151
235
  }
152
236
  }
237
+ // Run post-add eviction rules for pending txs (inside transaction for atomicity)
238
+ if (acceptedPending.size > 0) {
239
+ const feePayers = Array.from(acceptedPending).map((txHash)=>this.#indices.getMetadata(txHash).feePayer);
240
+ const uniqueFeePayers = new Set(feePayers);
241
+ await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [
242
+ ...uniqueFeePayers
243
+ ]);
244
+ }
153
245
  });
154
246
  // Build final accepted list for pending txs (excludes intra-batch evictions)
155
247
  for (const txHashStr of acceptedPending){
156
248
  accepted.push(TxHash.fromString(txHashStr));
157
249
  }
158
- // Run post-add eviction rules for pending txs
159
- if (acceptedPending.size > 0) {
160
- const feePayers = Array.from(acceptedPending).map((txHash)=>this.#indices.getMetadata(txHash).feePayer);
161
- const uniqueFeePayers = new Set(feePayers);
162
- await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [
163
- ...uniqueFeePayers
164
- ]);
250
+ // Record metrics
251
+ if (ignored.length > 0) {
252
+ this.#instrumentation.recordIgnored(ignored.length);
253
+ }
254
+ if (rejected.length > 0) {
255
+ this.#instrumentation.recordRejected(rejected.length);
165
256
  }
166
257
  return {
167
258
  accepted,
168
259
  ignored,
169
- rejected
260
+ rejected,
261
+ ...errors.size > 0 ? {
262
+ errors
263
+ } : {}
170
264
  };
171
265
  }
172
- /** Validates and adds a regular pending tx. Returns status. */ async #tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored) {
173
- const txHash = tx.getTxHash();
174
- const txHashStr = txHash.toString();
175
- // Validate transaction
176
- if (!await this.#validateTx(tx)) {
177
- return {
178
- status: 'rejected'
179
- };
180
- }
181
- // Build metadata and run pre-add rules
182
- const meta = await buildTxMetaData(tx);
183
- const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
266
+ /** Adds a validated pending tx, running pre-add rules and evicting conflicts. */ async #tryAddRegularPendingTx(tx, precomputedMeta, opts, poolAccess, acceptedPending, ignored, errors, preAddContext) {
267
+ const txHashStr = tx.getTxHash().toString();
268
+ // Run pre-add rules
269
+ const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
184
270
  if (preAddResult.shouldIgnore) {
185
- this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
271
+ this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
272
+ if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
273
+ errors.set(txHashStr, preAddResult.reason);
274
+ }
186
275
  return {
187
276
  status: 'ignored'
188
277
  };
189
278
  }
190
- // Evict conflicts
191
- for (const evictHashStr of preAddResult.txHashesToEvict){
192
- await this.#deleteTx(evictHashStr);
193
- this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`);
194
- if (acceptedPending.has(evictHashStr)) {
195
- // Evicted tx was from this batch - mark as ignored in result
196
- acceptedPending.delete(evictHashStr);
197
- ignored.push(TxHash.fromString(evictHashStr));
279
+ // Evict conflicts, grouped by rule name for metrics
280
+ if (preAddResult.evictions && preAddResult.evictions.length > 0) {
281
+ const byReason = new Map();
282
+ for (const { txHash: evictHash, reason } of preAddResult.evictions){
283
+ const group = byReason.get(reason);
284
+ if (group) {
285
+ group.push(evictHash);
286
+ } else {
287
+ byReason.set(reason, [
288
+ evictHash
289
+ ]);
290
+ }
291
+ }
292
+ for (const [reason, hashes] of byReason){
293
+ await this.#evictTxs(hashes, reason);
198
294
  }
295
+ for (const evictHashStr of preAddResult.txHashesToEvict){
296
+ this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
297
+ evictedTxHash: evictHashStr,
298
+ replacementTxHash: txHashStr
299
+ });
300
+ if (acceptedPending.has(evictHashStr)) {
301
+ // Evicted tx was from this batch - mark as ignored in result
302
+ acceptedPending.delete(evictHashStr);
303
+ ignored.push(TxHash.fromString(evictHashStr));
304
+ }
305
+ }
306
+ }
307
+ // Randomly drop the transaction for testing purposes (report as accepted so it propagates)
308
+ if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
309
+ this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
310
+ return {
311
+ status: 'accepted'
312
+ };
199
313
  }
200
314
  // Add the transaction
201
- await this.#addTx(tx, 'pending', opts);
315
+ await this.#addTx(tx, 'pending', opts, precomputedMeta);
202
316
  return {
203
317
  status: 'accepted'
204
318
  };
@@ -207,38 +321,44 @@ import { TxPoolIndices } from './tx_pool_indices.js';
207
321
  const txHashStr = tx.getTxHash().toString();
208
322
  // Check if already in pool
209
323
  if (this.#indices.has(txHashStr)) {
324
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
210
325
  return 'ignored';
211
326
  }
212
- // Validate transaction (no logging for dry-run check)
213
- const validationResult = await this.#pendingTxValidator.validateTx(tx);
214
- if (validationResult.result !== 'valid') {
215
- return 'rejected';
216
- }
217
- // Build metadata and use pre-add rules
327
+ // Build metadata and check pre-add rules
218
328
  const meta = await buildTxMetaData(tx);
219
329
  const poolAccess = this.#createPreAddPoolAccess();
220
330
  const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
221
- return preAddResult.shouldIgnore ? 'ignored' : 'accepted';
331
+ if (preAddResult.shouldIgnore) {
332
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
333
+ reason: preAddResult.reason?.message ?? 'no reason provided'
334
+ });
335
+ return 'ignored';
336
+ }
337
+ return 'accepted';
222
338
  }
223
339
  async addProtectedTxs(txs, block, opts) {
224
340
  const slotNumber = block.globalVariables.slotNumber;
341
+ // Precompute setup-call allow-list flags outside the store transaction
342
+ const allowedFlags = await Promise.all(txs.map((tx)=>this.#checkAllowedSetupCalls(tx)));
225
343
  await this.#store.transactionAsync(async ()=>{
226
- for (const tx of txs){
344
+ for(let i = 0; i < txs.length; i++){
345
+ const tx = txs[i];
227
346
  const txHash = tx.getTxHash();
228
347
  const txHashStr = txHash.toString();
229
348
  const isNew = !this.#indices.has(txHashStr);
230
349
  const minedBlockId = await this.#getMinedBlockId(txHash);
231
350
  if (isNew) {
351
+ const meta = await buildTxMetaData(tx, allowedFlags[i]);
232
352
  // New tx - add as mined or protected (callback emitted by #addTx)
233
353
  if (minedBlockId) {
234
354
  await this.#addTx(tx, {
235
355
  mined: minedBlockId
236
- }, opts);
356
+ }, opts, meta);
237
357
  this.#indices.setProtection(txHashStr, slotNumber);
238
358
  } else {
239
359
  await this.#addTx(tx, {
240
360
  protected: slotNumber
241
- }, opts);
361
+ }, opts, meta);
242
362
  }
243
363
  } else {
244
364
  // Existing tx - update protection and mined status
@@ -251,20 +371,53 @@ import { TxPoolIndices } from './tx_pool_indices.js';
251
371
  }
252
372
  });
253
373
  }
254
- protectTxs(txHashes, block) {
374
+ async protectTxs(txHashes, block) {
255
375
  const slotNumber = block.globalVariables.slotNumber;
256
376
  const missing = [];
257
- for (const txHash of txHashes){
258
- const txHashStr = txHash.toString();
259
- if (this.#indices.has(txHashStr)) {
260
- // Update protection for existing tx
261
- this.#indices.updateProtection(txHashStr, slotNumber);
262
- } else {
263
- // Pre-record protection for tx we don't have yet
264
- this.#indices.setProtection(txHashStr, slotNumber);
265
- missing.push(txHash);
377
+ let softDeletedHits = 0;
378
+ let missingPreviouslyEvicted = 0;
379
+ await this.#store.transactionAsync(async ()=>{
380
+ for (const txHash of txHashes){
381
+ const txHashStr = txHash.toString();
382
+ if (this.#indices.has(txHashStr)) {
383
+ // Update protection for existing tx
384
+ this.#indices.updateProtection(txHashStr, slotNumber);
385
+ } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
386
+ // Resurrect soft-deleted tx as protected
387
+ const buffer = await this.#txsDB.getAsync(txHashStr);
388
+ if (buffer) {
389
+ const tx = Tx.fromBuffer(buffer);
390
+ await this.#addTx(tx, {
391
+ protected: slotNumber
392
+ });
393
+ softDeletedHits++;
394
+ } else {
395
+ // Data missing despite soft-delete flag — treat as truly missing
396
+ this.#indices.setProtection(txHashStr, slotNumber);
397
+ missing.push(txHash);
398
+ }
399
+ } else {
400
+ // Truly missing — pre-record protection for tx we don't have yet
401
+ this.#indices.setProtection(txHashStr, slotNumber);
402
+ missing.push(txHash);
403
+ if (this.#evictedTxHashes.has(txHashStr)) {
404
+ missingPreviouslyEvicted++;
405
+ }
406
+ }
266
407
  }
408
+ });
409
+ // Record metrics
410
+ if (softDeletedHits > 0) {
411
+ this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
267
412
  }
413
+ if (missing.length > 0) {
414
+ this.#log.debug(`protectTxs missing tx hashes: ${missing.map((h)=>h.toString()).join(', ')}`);
415
+ this.#instrumentation.recordMissingOnProtect(missing.length);
416
+ }
417
+ if (missingPreviouslyEvicted > 0) {
418
+ this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
419
+ }
420
+ this.#log.info(`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`);
268
421
  return missing;
269
422
  }
270
423
  async addMinedTxs(txs, block, opts) {
@@ -283,6 +436,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
283
436
  mined: blockId
284
437
  }, opts);
285
438
  }
439
+ await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
286
440
  }
287
441
  });
288
442
  }
@@ -302,44 +456,53 @@ import { TxPoolIndices } from './tx_pool_indices.js';
302
456
  found.push(meta);
303
457
  }
304
458
  }
305
- // Step 4: Mark txs as mined (only those we have in the pool)
306
- for (const meta of found){
307
- this.#indices.markAsMined(meta, blockId);
459
+ await this.#store.transactionAsync(async ()=>{
460
+ // Step 4: Mark txs as mined (only those we have in the pool)
461
+ for (const meta of found){
462
+ this.#indices.markAsMined(meta, blockId);
463
+ await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
464
+ }
465
+ // Step 5: Run post-event eviction rules (inside transaction for atomicity)
466
+ await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
467
+ });
468
+ if (found.length > 0) {
469
+ this.#callbacks.onTxsMined(found.map((m)=>m.txHash));
308
470
  }
309
- // Step 5: Run eviction rules (remove pending txs with conflicting nullifiers/expired timestamps)
310
- await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
311
471
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
312
472
  }
313
473
  async prepareForSlot(slotNumber) {
314
- // Step 1: Find expired protected txs
315
- const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
316
- // Step 2: Clear protection for all expired entries (including those without metadata)
317
- this.#indices.clearProtection(expiredProtected);
318
- // Step 3: Filter to only txs that have metadata and are not mined
319
- const txsToRestore = this.#indices.filterRestorable(expiredProtected);
320
- if (txsToRestore.length === 0) {
321
- return;
322
- }
323
- this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
324
- // Step 4: Validate for pending pool
325
- const { valid, invalid } = await this.#loadAndValidateTxs(txsToRestore, 'during prepareForSlot');
326
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
327
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
328
- // Step 6: Delete invalid and evicted txs
329
- await this.#deleteTxsBatch([
330
- ...invalid,
331
- ...toEvict
332
- ]);
333
- // Step 7: Run eviction rules (enforce pool size limit)
334
- if (added.length > 0) {
335
- const feePayers = added.map((meta)=>meta.feePayer);
336
- const uniqueFeePayers = new Set(feePayers);
337
- await this.#evictionManager.evictAfterNewTxs(added.map((m)=>m.txHash), [
338
- ...uniqueFeePayers
339
- ]);
340
- }
474
+ await this.#store.transactionAsync(async ()=>{
475
+ // Step 0: Clean up slot-deleted txs from previous slots
476
+ await this.#deletedPool.cleanupSlotDeleted(slotNumber);
477
+ // Step 1: Find expired protected txs
478
+ const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
479
+ // Step 2: Clear protection for all expired entries (including those without metadata)
480
+ this.#indices.clearProtection(expiredProtected);
481
+ // Step 3: Filter to only txs that have metadata and are not mined
482
+ const txsToRestore = this.#indices.filterRestorable(expiredProtected);
483
+ if (txsToRestore.length === 0) {
484
+ this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
485
+ return;
486
+ }
487
+ this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
488
+ // Step 4: Validate for pending pool
489
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
490
+ // Step 5: Resolve nullifier conflicts and add winners to pending indices
491
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
492
+ // Step 6: Delete invalid txs and evict conflict losers
493
+ await this.#deleteTxsBatch(invalid);
494
+ await this.#evictTxs(toEvict, 'NullifierConflict');
495
+ // Step 7: Run eviction rules (enforce pool size limit)
496
+ if (added.length > 0) {
497
+ const feePayers = added.map((meta)=>meta.feePayer);
498
+ const uniqueFeePayers = new Set(feePayers);
499
+ await this.#evictionManager.evictAfterNewTxs(added.map((m)=>m.txHash), [
500
+ ...uniqueFeePayers
501
+ ]);
502
+ }
503
+ });
341
504
  }
342
- async handlePrunedBlocks(latestBlock) {
505
+ async handlePrunedBlocks(latestBlock, options) {
343
506
  // Step 1: Find transactions mined after the prune point
344
507
  const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
345
508
  if (txsToUnmine.length === 0) {
@@ -347,54 +510,84 @@ import { TxPoolIndices } from './tx_pool_indices.js';
347
510
  return;
348
511
  }
349
512
  this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
350
- // Step 2: Unmine - clear mined status from metadata
351
- for (const meta of txsToUnmine){
352
- this.#indices.markAsUnmined(meta);
353
- }
354
- // Step 3: Filter out protected txs (they'll be handled by prepareForSlot)
355
- const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
356
- // Step 4: Validate for pending pool
357
- const { valid, invalid } = await this.#loadAndValidateTxs(unprotectedTxs, 'during handlePrunedBlocks');
358
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
359
- const { toEvict } = this.#applyNullifierConflictResolution(valid);
360
- // Step 6: Delete invalid and evicted txs
361
- await this.#deleteTxsBatch([
362
- ...invalid,
363
- ...toEvict
364
- ]);
365
- // Step 7: Run eviction rules for ALL pending txs (not just restored ones)
366
- // This handles cases like existing pending txs with invalid fee payer balances
367
- await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
513
+ await this.#store.transactionAsync(async ()=>{
514
+ // Step 2: Mark ALL un-mined txs with their original mined block number
515
+ // This ensures they get soft-deleted if removed later, and only hard-deleted
516
+ // when their original mined block is finalized
517
+ await this.#deletedPool.markFromPrunedBlock(txsToUnmine.map((m)=>({
518
+ txHash: m.txHash,
519
+ minedAtBlock: BlockNumber(m.minedL2BlockId.number)
520
+ })));
521
+ // Step 3: Unmine - clear mined status from metadata
522
+ for (const meta of txsToUnmine){
523
+ this.#indices.markAsUnmined(meta);
524
+ }
525
+ // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
526
+ if (options?.deleteAllTxs) {
527
+ const allTxHashes = txsToUnmine.map((m)=>m.txHash);
528
+ await this.#deleteTxsBatch(allTxHashes);
529
+ this.#log.info(`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`);
530
+ return;
531
+ }
532
+ // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
533
+ const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
534
+ // Step 5: Validate for pending pool
535
+ const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
536
+ // Step 6: Resolve nullifier conflicts and add winners to pending indices
537
+ const { toEvict } = this.#applyNullifierConflictResolution(valid);
538
+ // Step 7: Delete invalid txs and evict conflict losers
539
+ await this.#deleteTxsBatch(invalid);
540
+ await this.#evictTxs(toEvict, 'NullifierConflict');
541
+ this.#log.info(`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`, {
542
+ txHashesRestored: valid.map((m)=>m.txHash),
543
+ txHashesInvalid: invalid,
544
+ txHashesEvicted: toEvict
545
+ });
546
+ // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
547
+ // This handles cases like existing pending txs with invalid fee payer balances
548
+ await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
549
+ });
368
550
  }
369
551
  async handleFailedExecution(txHashes) {
370
- // Delete failed txs
371
- await this.#deleteTxsBatch(txHashes.map((h)=>h.toString()));
372
- this.#log.info(`Deleted ${txHashes.length} failed txs`);
552
+ await this.#store.transactionAsync(async ()=>{
553
+ await this.#deleteTxsBatch(txHashes.map((h)=>h.toString()));
554
+ });
555
+ this.#log.info(`Deleted ${txHashes.length} failed txs`, {
556
+ txHashes: txHashes.map((h)=>h.toString())
557
+ });
373
558
  }
374
559
  async handleFinalizedBlock(block) {
375
560
  const blockNumber = block.globalVariables.blockNumber;
376
- // Step 1: Find txs mined at or before finalized block
377
- const txsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
378
- if (txsToFinalize.length === 0) {
379
- return;
380
- }
381
- // Step 2: Collect txs for archiving (before deletion)
382
- const txsToArchive = [];
561
+ // Step 1: Find mined txs at or before finalized block
562
+ const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
563
+ // Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
564
+ // mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
383
565
  if (this.#archive.isEnabled()) {
384
- for (const txHashStr of txsToFinalize){
385
- const buffer = await this.#txsDB.getAsync(txHashStr);
386
- if (buffer) {
387
- txsToArchive.push(Tx.fromBuffer(buffer));
566
+ for(let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE){
567
+ const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
568
+ const txsToArchive = [];
569
+ for (const txHashStr of chunk){
570
+ const buffer = await this.#txsDB.getAsync(txHashStr);
571
+ if (buffer) {
572
+ txsToArchive.push(Tx.fromBuffer(buffer));
573
+ }
574
+ }
575
+ if (txsToArchive.length > 0) {
576
+ await this.#archive.archiveTxs(txsToArchive);
388
577
  }
389
578
  }
390
579
  }
391
- // Step 3: Delete from active pool
392
- await this.#deleteTxsBatch(txsToFinalize);
393
- // Step 4: Archive
394
- if (txsToArchive.length > 0) {
395
- await this.#archive.archiveTxs(txsToArchive);
580
+ // Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
581
+ // transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
582
+ await this.#store.transactionAsync(async ()=>{
583
+ await this.#deleteTxsBatch(minedTxsToFinalize);
584
+ await this.#deletedPool.finalizeBlock(blockNumber);
585
+ });
586
+ if (minedTxsToFinalize.length > 0) {
587
+ this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
588
+ txHashes: minedTxsToFinalize
589
+ });
396
590
  }
397
- this.#log.info(`Finalized ${txsToFinalize.length} txs from blocks up to ${blockNumber}`);
398
591
  }
399
592
  // === Query Methods ===
400
593
  async getTxByHash(txHash) {
@@ -410,20 +603,34 @@ import { TxPoolIndices } from './tx_pool_indices.js';
410
603
  return results;
411
604
  }
412
605
  hasTxs(txHashes) {
413
- return txHashes.map((h)=>this.#indices.has(h.toString()));
606
+ return txHashes.map((h)=>{
607
+ const hashStr = h.toString();
608
+ return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
609
+ });
414
610
  }
415
611
  getTxStatus(txHash) {
416
- const meta = this.#indices.getMetadata(txHash.toString());
417
- if (!meta) {
418
- return undefined;
612
+ const txHashStr = txHash.toString();
613
+ const meta = this.#indices.getMetadata(txHashStr);
614
+ if (meta) {
615
+ return this.#indices.getTxState(meta);
616
+ }
617
+ // Check if soft-deleted
618
+ if (this.#deletedPool.isSoftDeleted(txHashStr)) {
619
+ return 'deleted';
419
620
  }
420
- return this.#indices.getTxState(meta);
621
+ return undefined;
421
622
  }
422
623
  getPendingTxHashes() {
423
624
  return [
424
625
  ...this.#indices.iteratePendingByPriority('desc')
425
626
  ].map((hash)=>TxHash.fromString(hash));
426
627
  }
628
+ getEligiblePendingTxHashes() {
629
+ const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
630
+ return [
631
+ ...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)
632
+ ].map((hash)=>TxHash.fromString(hash));
633
+ }
427
634
  getPendingTxCount() {
428
635
  return this.#indices.getPendingTxCount();
429
636
  }
@@ -463,6 +670,9 @@ import { TxPoolIndices } from './tx_pool_indices.js';
463
670
  this.#config.archivedTxLimit = config.archivedTxLimit;
464
671
  this.#archive.updateLimit(config.archivedTxLimit);
465
672
  }
673
+ if (config.minTxPoolAgeMs !== undefined) {
674
+ this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
675
+ }
466
676
  // Update eviction rules with new config
467
677
  this.#evictionManager.updateConfig(config);
468
678
  }
@@ -477,7 +687,10 @@ import { TxPoolIndices } from './tx_pool_indices.js';
477
687
  }
478
688
  // === Metrics ===
479
689
  countTxs() {
480
- return this.#indices.countTxs();
690
+ return {
691
+ ...this.#indices.countTxs(),
692
+ softDeleted: this.#deletedPool.getSoftDeletedCount()
693
+ };
481
694
  }
482
695
  // ============================================================================
483
696
  // PRIVATE HELPERS - Transaction Management
@@ -485,10 +698,12 @@ import { TxPoolIndices } from './tx_pool_indices.js';
485
698
  /**
486
699
  * Adds a new transaction to the pool with the specified state.
487
700
  * Emits onTxsAdded callback immediately after DB write.
488
- */ async #addTx(tx, state, opts = {}) {
701
+ */ async #addTx(tx, state, opts = {}, precomputedMeta) {
489
702
  const txHashStr = tx.getTxHash().toString();
490
- const meta = await buildTxMetaData(tx);
703
+ const meta = precomputedMeta ?? await buildTxMetaData(tx);
704
+ meta.receivedAt = this.#dateProvider.now();
491
705
  await this.#txsDB.set(txHashStr, tx.toBuffer());
706
+ await this.#deletedPool.clearSoftDeleted(txHashStr);
492
707
  this.#callbacks.onTxsAdded([
493
708
  tx
494
709
  ], opts);
@@ -501,64 +716,66 @@ import { TxPoolIndices } from './tx_pool_indices.js';
501
716
  this.#indices.addMined(meta);
502
717
  }
503
718
  const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
504
- this.#log.verbose(`Added ${stateStr} tx ${txHashStr}`, {
719
+ this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
505
720
  eventName: 'tx-added-to-pool',
506
- state: stateStr
721
+ txHash: txHashStr,
722
+ state: stateStr,
723
+ source: opts.source
507
724
  });
508
725
  return meta;
509
726
  }
510
727
  /**
511
728
  * Deletes a transaction from both indices and DB.
512
729
  * Emits onTxsRemoved callback immediately after DB delete.
730
+ */ /**
731
+ * Deletes a transaction from the pool.
732
+ * Delegates to DeletedPool which decides soft vs hard delete based on whether
733
+ * the tx is from a pruned block.
513
734
  */ async #deleteTx(txHashStr) {
514
735
  this.#indices.remove(txHashStr);
515
- await this.#txsDB.delete(txHashStr);
516
736
  this.#callbacks.onTxsRemoved([
517
737
  txHashStr
518
738
  ]);
739
+ await this.#deletedPool.deleteTx(txHashStr);
519
740
  }
520
741
  /** Deletes a batch of transactions, emitting callbacks individually for each. */ async #deleteTxsBatch(txHashes) {
521
742
  for (const txHashStr of txHashes){
522
743
  await this.#deleteTx(txHashStr);
523
744
  }
524
745
  }
746
+ /** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */ async #evictTxs(txHashes, reason) {
747
+ if (txHashes.length === 0) {
748
+ return;
749
+ }
750
+ this.#instrumentation.recordEvictions(txHashes.length, reason);
751
+ for (const txHashStr of txHashes){
752
+ this.#log.debug(`Evicting tx ${txHashStr}`, {
753
+ txHash: txHashStr,
754
+ reason
755
+ });
756
+ this.#evictedTxHashes.add(txHashStr);
757
+ }
758
+ await this.#deleteTxsBatch(txHashes);
759
+ }
525
760
  // ============================================================================
526
761
  // PRIVATE HELPERS - Validation & Conflict Resolution
527
762
  // ============================================================================
528
- /** Validates a single transaction, returning true if valid */ async #validateTx(tx, context) {
529
- const result = await this.#pendingTxValidator.validateTx(tx);
763
+ /** Validates transaction metadata, returning true if valid */ async #validateMeta(meta, validator, context) {
764
+ const txValidator = validator ?? await this.#createTxValidator();
765
+ const result = await txValidator.validateTx(meta);
530
766
  if (result.result !== 'valid') {
531
767
  const contextStr = context ? ` ${context}` : '';
532
- this.#log.info(`Tx ${tx.getTxHash()}${contextStr} failed validation: ${result.reason?.join(', ')}`);
768
+ this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
533
769
  return false;
534
770
  }
535
771
  return true;
536
772
  }
537
- /** Loads transactions from DB, returning loaded txs and missing hashes */ async #loadTxsFromDb(metas) {
538
- const loaded = [];
539
- const missing = [];
540
- for (const meta of metas){
541
- const buffer = await this.#txsDB.getAsync(meta.txHash);
542
- if (!buffer) {
543
- this.#log.warn(`Tx ${meta.txHash} not found in DB`);
544
- missing.push(meta.txHash);
545
- continue;
546
- }
547
- loaded.push({
548
- tx: Tx.fromBuffer(buffer),
549
- meta
550
- });
551
- }
552
- return {
553
- loaded,
554
- missing
555
- };
556
- }
557
- /** Validates a batch of transactions, returning valid and invalid groups */ async #validateTxBatch(txs, context) {
773
+ /** Validates metadata directly */ async #revalidateMetadata(metas, context) {
558
774
  const valid = [];
559
775
  const invalid = [];
560
- for (const { tx, meta } of txs){
561
- if (await this.#validateTx(tx, context)) {
776
+ const validator = await this.#createTxValidator();
777
+ for (const meta of metas){
778
+ if (await this.#validateMeta(meta, validator, context)) {
562
779
  valid.push(meta);
563
780
  } else {
564
781
  invalid.push(meta.txHash);
@@ -569,17 +786,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
569
786
  invalid
570
787
  };
571
788
  }
572
- /** Loads transactions from DB and validates them */ async #loadAndValidateTxs(metas, context) {
573
- const { loaded, missing } = await this.#loadTxsFromDb(metas);
574
- const { valid, invalid } = await this.#validateTxBatch(loaded, context);
575
- return {
576
- valid,
577
- invalid: [
578
- ...missing,
579
- ...invalid
580
- ]
581
- };
582
- }
583
789
  /**
584
790
  * Resolves nullifier conflicts between incoming txs and existing pending txs.
585
791
  * Modifies the pending indices during iteration to maintain consistent state
@@ -631,46 +837,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
631
837
  hash: txEffect.l2BlockHash.toString()
632
838
  };
633
839
  }
634
- /** Loads all transactions from the database, returning loaded txs and deserialization errors */ async #loadAllTxsFromDb() {
635
- const loaded = [];
636
- const errors = [];
637
- for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()){
638
- try {
639
- const tx = Tx.fromBuffer(buffer);
640
- const meta = await buildTxMetaData(tx);
641
- loaded.push({
642
- tx,
643
- meta
644
- });
645
- } catch (err) {
646
- this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, {
647
- err
648
- });
649
- errors.push(txHashStr);
650
- }
651
- }
652
- return {
653
- loaded,
654
- errors
655
- };
656
- }
657
- /** Queries block source and marks mined status on transaction metadata */ async #markMinedStatusBatch(metas) {
658
- for (const meta of metas){
659
- try {
660
- const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
661
- if (txEffect) {
662
- meta.minedL2BlockId = {
663
- number: txEffect.l2BlockNumber,
664
- hash: txEffect.l2BlockHash.toString()
665
- };
666
- }
667
- } catch (err) {
668
- this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, {
669
- err
670
- });
671
- }
672
- }
673
- }
674
840
  /**
675
841
  * Rebuilds the pending pool by processing each tx through pre-add rules.
676
842
  * Starts with an empty pending pool and adds txs one by one, resolving conflicts.
@@ -685,7 +851,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
685
851
  if (preAddResult.shouldIgnore) {
686
852
  // Transaction rejected - mark for deletion from DB
687
853
  rejected.push(meta.txHash);
688
- this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason}`);
854
+ this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`);
689
855
  continue;
690
856
  }
691
857
  // Evict any conflicting txs identified by pre-add rules
@@ -721,7 +887,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
721
887
  getFeePayerPendingTxs: (feePayer)=>this.#indices.getFeePayerPendingTxs(feePayer),
722
888
  getPendingTxCount: ()=>this.#indices.getPendingTxCount(),
723
889
  getLowestPriorityPending: (limit)=>this.#indices.getLowestPriorityPending(limit),
724
- deleteTxs: (txHashes)=>this.#deleteTxsBatch(txHashes)
890
+ deleteTxs: (txHashes, reason)=>this.#evictTxs(txHashes, reason ?? 'unknown')
725
891
  };
726
892
  }
727
893
  #createPreAddPoolAccess() {