@aztec/p2p 0.0.1-commit.7b97ef96e → 0.0.1-commit.7cbc774

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 (463) 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 +7 -7
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +39 -32
  8. package/dest/client/interface.d.ts +19 -17
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +16 -20
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +94 -105
  13. package/dest/config.d.ts +154 -106
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +134 -40
  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/index.d.ts +1 -2
  23. package/dest/index.d.ts.map +1 -1
  24. package/dest/index.js +0 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +99 -59
  26. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool.js +267 -197
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +181 -65
  31. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  32. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  33. package/dest/mem_pools/attestation_pool/mocks.js +6 -4
  34. package/dest/mem_pools/index.d.ts +1 -2
  35. package/dest/mem_pools/index.d.ts.map +1 -1
  36. package/dest/mem_pools/instrumentation.d.ts +4 -2
  37. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  38. package/dest/mem_pools/instrumentation.js +33 -15
  39. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  40. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +3 -2
  42. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
  43. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
  45. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  48. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  49. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  50. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  51. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
  52. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +4 -4
  54. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  55. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  56. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
  57. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
  58. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  59. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
  60. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
  61. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  62. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
  63. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  64. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  65. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  66. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +18 -9
  67. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  68. package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
  69. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +51 -11
  70. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  71. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +90 -19
  72. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  73. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  74. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -44
  75. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +5 -3
  76. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  77. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +6 -0
  78. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +3 -2
  79. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  80. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +256 -220
  81. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
  82. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  83. package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
  84. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  85. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  86. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  87. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  88. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  89. package/dest/msg_validators/clock_tolerance.js +61 -3
  90. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +10 -4
  91. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  92. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  93. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +10 -4
  94. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  96. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +21 -8
  97. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  98. package/dest/msg_validators/proposal_validator/proposal_validator.js +90 -44
  99. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  100. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +11 -18
  102. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  103. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/allowed_public_setup.js +25 -21
  105. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  106. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  107. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  108. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  109. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  110. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  111. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  112. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  113. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  114. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  115. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  116. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  117. package/dest/msg_validators/tx_validator/data_validator.js +36 -2
  118. package/dest/msg_validators/tx_validator/factory.d.ts +135 -7
  119. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  120. package/dest/msg_validators/tx_validator/factory.js +252 -61
  121. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  122. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  123. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  124. package/dest/msg_validators/tx_validator/gas_validator.d.ts +99 -3
  125. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  126. package/dest/msg_validators/tx_validator/gas_validator.js +137 -53
  127. package/dest/msg_validators/tx_validator/index.d.ts +5 -1
  128. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  129. package/dest/msg_validators/tx_validator/index.js +4 -0
  130. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  131. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  132. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  133. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  134. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  135. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  136. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  137. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  138. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  139. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  140. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  141. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  142. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  143. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  144. package/dest/msg_validators/tx_validator/tx_validation_cache.js +69 -0
  145. package/dest/services/data_store.d.ts +1 -1
  146. package/dest/services/data_store.d.ts.map +1 -1
  147. package/dest/services/data_store.js +5 -5
  148. package/dest/services/discv5/discV5_service.d.ts +2 -1
  149. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  150. package/dest/services/discv5/discV5_service.js +35 -8
  151. package/dest/services/dummy_service.d.ts +12 -17
  152. package/dest/services/dummy_service.d.ts.map +1 -1
  153. package/dest/services/dummy_service.js +13 -20
  154. package/dest/services/encoding.d.ts +6 -2
  155. package/dest/services/encoding.d.ts.map +1 -1
  156. package/dest/services/encoding.js +14 -8
  157. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  158. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  159. package/dest/services/gossipsub/topic_score_params.js +21 -4
  160. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  161. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  162. package/dest/services/libp2p/instrumentation.js +14 -0
  163. package/dest/services/libp2p/libp2p_service.d.ts +47 -55
  164. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  165. package/dest/services/libp2p/libp2p_service.js +344 -308
  166. package/dest/services/peer-manager/metrics.d.ts +3 -1
  167. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  168. package/dest/services/peer-manager/metrics.js +6 -0
  169. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  170. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  171. package/dest/services/peer-manager/peer_manager.js +40 -11
  172. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  173. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  174. package/dest/services/peer-manager/peer_scoring.js +32 -10
  175. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
  176. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  177. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +97 -107
  178. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +10 -6
  179. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  180. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  181. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  182. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  183. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  184. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  185. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  186. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  187. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  188. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  189. package/dest/services/reqresp/config.d.ts +3 -3
  190. package/dest/services/reqresp/config.d.ts.map +1 -1
  191. package/dest/services/reqresp/interface.d.ts +16 -18
  192. package/dest/services/reqresp/interface.d.ts.map +1 -1
  193. package/dest/services/reqresp/interface.js +10 -20
  194. package/dest/services/reqresp/metrics.d.ts +1 -1
  195. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  196. package/dest/services/reqresp/metrics.js +0 -1
  197. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  198. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  199. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +4 -2
  200. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  201. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  202. package/dest/services/reqresp/protocols/index.js +0 -1
  203. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  204. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  205. package/dest/services/reqresp/protocols/tx.js +1 -3
  206. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  207. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  208. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  209. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  210. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  211. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  212. package/dest/services/reqresp/reqresp.d.ts +7 -29
  213. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  214. package/dest/services/reqresp/reqresp.js +43 -215
  215. package/dest/services/service.d.ts +10 -13
  216. package/dest/services/service.d.ts.map +1 -1
  217. package/dest/services/tx_collection/config.d.ts +2 -23
  218. package/dest/services/tx_collection/config.d.ts.map +1 -1
  219. package/dest/services/tx_collection/config.js +2 -55
  220. package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
  221. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  222. package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
  223. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  224. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  225. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  226. package/dest/services/tx_collection/index.d.ts +2 -3
  227. package/dest/services/tx_collection/index.d.ts.map +1 -1
  228. package/dest/services/tx_collection/index.js +0 -1
  229. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  230. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  231. package/dest/services/tx_collection/instrumentation.js +0 -2
  232. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  233. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  234. package/dest/services/tx_collection/request_tracker.js +84 -0
  235. package/dest/services/tx_collection/tx_collection.d.ts +36 -55
  236. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  237. package/dest/services/tx_collection/tx_collection.js +275 -119
  238. package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
  239. package/dest/services/tx_collection/tx_collection_sink.js +2 -2
  240. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  241. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  242. package/dest/services/tx_collection/tx_source.js +9 -7
  243. package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
  244. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  245. package/dest/services/tx_file_store/tx_file_store.js +4 -14
  246. package/dest/services/tx_provider.d.ts +5 -3
  247. package/dest/services/tx_provider.d.ts.map +1 -1
  248. package/dest/services/tx_provider.js +7 -4
  249. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  250. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  251. package/dest/test-helpers/make-test-p2p-clients.js +5 -3
  252. package/dest/test-helpers/mock-pubsub.d.ts +24 -11
  253. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  254. package/dest/test-helpers/mock-pubsub.js +45 -45
  255. package/dest/test-helpers/reqresp-nodes.d.ts +5 -7
  256. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  257. package/dest/test-helpers/reqresp-nodes.js +17 -19
  258. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  259. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  260. package/dest/test-helpers/test_tx_provider.js +3 -0
  261. package/dest/test-helpers/testbench-utils.d.ts +13 -15
  262. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  263. package/dest/test-helpers/testbench-utils.js +42 -15
  264. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  265. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  266. package/dest/testbench/p2p_client_testbench_worker.js +88 -42
  267. package/dest/testbench/worker_client_manager.d.ts +12 -6
  268. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  269. package/dest/testbench/worker_client_manager.js +57 -11
  270. package/dest/util.d.ts +12 -7
  271. package/dest/util.d.ts.map +1 -1
  272. package/dest/util.js +35 -14
  273. package/dest/versioning.d.ts +3 -6
  274. package/dest/versioning.d.ts.map +1 -1
  275. package/dest/versioning.js +3 -24
  276. package/package.json +15 -14
  277. package/src/bootstrap/bootstrap.ts +9 -1
  278. package/src/client/factory.ts +74 -49
  279. package/src/client/interface.ts +20 -30
  280. package/src/client/p2p_client.ts +108 -156
  281. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  282. package/src/config.ts +227 -45
  283. package/src/errors/p2p-service.error.ts +11 -0
  284. package/src/errors/reqresp.error.ts +0 -25
  285. package/src/index.ts +0 -1
  286. package/src/mem_pools/attestation_pool/attestation_pool.ts +318 -242
  287. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +204 -68
  288. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  289. package/src/mem_pools/index.ts +0 -3
  290. package/src/mem_pools/instrumentation.ts +22 -14
  291. package/src/mem_pools/tx_pool_v2/README.md +9 -1
  292. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +3 -2
  293. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
  294. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  295. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  296. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
  297. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
  298. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
  299. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
  300. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
  301. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  302. package/src/mem_pools/tx_pool_v2/interfaces.ts +19 -8
  303. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +130 -23
  304. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
  305. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +17 -2
  306. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +267 -229
  307. package/src/msg_validators/attestation_validator/README.md +49 -0
  308. package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
  309. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +14 -7
  310. package/src/msg_validators/clock_tolerance.ts +79 -3
  311. package/src/msg_validators/proposal_validator/README.md +123 -0
  312. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +24 -4
  313. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +35 -7
  314. package/src/msg_validators/proposal_validator/proposal_validator.ts +114 -47
  315. package/src/msg_validators/tx_validator/README.md +127 -0
  316. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +6 -15
  317. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  318. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  319. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  320. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  321. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  322. package/src/msg_validators/tx_validator/data_validator.ts +44 -1
  323. package/src/msg_validators/tx_validator/factory.ts +407 -80
  324. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  325. package/src/msg_validators/tx_validator/gas_validator.ts +199 -54
  326. package/src/msg_validators/tx_validator/index.ts +4 -0
  327. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  328. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  329. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  330. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  331. package/src/msg_validators/tx_validator/tx_validation_cache.ts +102 -0
  332. package/src/services/data_store.ts +5 -13
  333. package/src/services/discv5/discV5_service.ts +38 -5
  334. package/src/services/dummy_service.ts +15 -44
  335. package/src/services/encoding.ts +14 -7
  336. package/src/services/gossipsub/topic_score_params.ts +36 -4
  337. package/src/services/libp2p/instrumentation.ts +14 -0
  338. package/src/services/libp2p/libp2p_service.ts +390 -360
  339. package/src/services/peer-manager/metrics.ts +7 -0
  340. package/src/services/peer-manager/peer_manager.ts +46 -11
  341. package/src/services/peer-manager/peer_scoring.ts +27 -5
  342. package/src/services/reqresp/README.md +215 -0
  343. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  344. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +97 -119
  345. package/src/services/reqresp/batch-tx-requester/interface.ts +13 -5
  346. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  347. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  348. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  349. package/src/services/reqresp/config.ts +2 -2
  350. package/src/services/reqresp/interface.ts +21 -47
  351. package/src/services/reqresp/metrics.ts +0 -1
  352. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +4 -2
  353. package/src/services/reqresp/protocols/index.ts +0 -1
  354. package/src/services/reqresp/protocols/tx.ts +1 -3
  355. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  356. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  357. package/src/services/reqresp/reqresp.ts +48 -261
  358. package/src/services/service.ts +13 -29
  359. package/src/services/tx_collection/config.ts +3 -80
  360. package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
  361. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  362. package/src/services/tx_collection/index.ts +1 -6
  363. package/src/services/tx_collection/instrumentation.ts +1 -7
  364. package/src/services/tx_collection/request_tracker.ts +127 -0
  365. package/src/services/tx_collection/tx_collection.ts +331 -176
  366. package/src/services/tx_collection/tx_collection_sink.ts +2 -2
  367. package/src/services/tx_collection/tx_source.ts +8 -7
  368. package/src/services/tx_file_store/tx_file_store.ts +5 -17
  369. package/src/services/tx_provider.ts +7 -2
  370. package/src/test-helpers/make-test-p2p-clients.ts +4 -3
  371. package/src/test-helpers/mock-pubsub.ts +49 -66
  372. package/src/test-helpers/reqresp-nodes.ts +15 -28
  373. package/src/test-helpers/test_tx_provider.ts +5 -0
  374. package/src/test-helpers/testbench-utils.ts +54 -29
  375. package/src/testbench/p2p_client_testbench_worker.ts +91 -61
  376. package/src/testbench/worker_client_manager.ts +72 -25
  377. package/src/util.ts +33 -18
  378. package/src/versioning.ts +3 -33
  379. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  380. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  381. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
  382. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  383. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  384. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  385. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  386. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  387. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  388. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  389. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  390. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  391. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  392. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  393. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  394. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  395. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  396. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  397. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  398. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  399. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  400. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  401. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  402. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  403. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  404. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  405. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  406. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  407. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  408. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  409. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  410. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  411. package/dest/mem_pools/tx_pool/index.js +0 -2
  412. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  413. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  414. package/dest/mem_pools/tx_pool/priority.js +0 -15
  415. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  416. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  417. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  418. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  419. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  420. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  421. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  422. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  423. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  424. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  425. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  426. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  427. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  428. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  429. package/dest/services/reqresp/protocols/block.js +0 -32
  430. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -54
  431. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  432. package/dest/services/tx_collection/fast_tx_collection.js +0 -327
  433. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  434. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  435. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  436. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -49
  437. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  438. package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
  439. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
  440. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  441. package/dest/services/tx_collection/slow_tx_collection.js +0 -211
  442. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -346
  443. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  444. package/src/mem_pools/tx_pool/README.md +0 -270
  445. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  446. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  447. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  448. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  449. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  450. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  451. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  452. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  453. package/src/mem_pools/tx_pool/index.ts +0 -2
  454. package/src/mem_pools/tx_pool/priority.ts +0 -20
  455. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  456. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  457. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
  458. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  459. package/src/services/reqresp/protocols/block.ts +0 -37
  460. package/src/services/tx_collection/fast_tx_collection.ts +0 -387
  461. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
  462. package/src/services/tx_collection/proposal_tx_collector.ts +0 -113
  463. package/src/services/tx_collection/slow_tx_collection.ts +0 -266
@@ -1,4 +1,5 @@
1
1
  import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { FifoSet } from '@aztec/foundation/fifo-set';
2
3
  import type { Logger } from '@aztec/foundation/log';
3
4
  import type { DateProvider } from '@aztec/foundation/timer';
4
5
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
@@ -17,6 +18,7 @@ import {
17
18
  EvictionManager,
18
19
  FeePayerBalanceEvictionRule,
19
20
  FeePayerBalancePreAddRule,
21
+ InsufficientFeePerGasEvictionRule,
20
22
  InvalidTxsAfterMiningRule,
21
23
  InvalidTxsAfterReorgRule,
22
24
  LowPriorityEvictionRule,
@@ -39,12 +41,20 @@ import {
39
41
  import { type TxMetaData, type TxState, buildTxMetaData, checkNullifierConflict } from './tx_metadata.js';
40
42
  import { TxPoolIndices } from './tx_pool_indices.js';
41
43
 
44
+ /**
45
+ * Maximum number of full transactions to load into memory at once when finalizing a block.
46
+ * Bounds peak memory while archiving and hard-deleting mined txs (~23k txs/epoch at 10 TPS would
47
+ * otherwise OOM the node).
48
+ */
49
+ const FINALIZE_BLOCK_CHUNK_SIZE = 100;
50
+
42
51
  /**
43
52
  * Callbacks for the implementation to notify the outer class about events and metrics.
44
53
  */
45
54
  export interface TxPoolV2Callbacks {
46
55
  onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
47
56
  onTxsRemoved: (txHashes: string[] | bigint[]) => void;
57
+ onTxsMined: (txHashes: string[]) => void;
48
58
  }
49
59
 
50
60
  /**
@@ -61,6 +71,7 @@ export class TxPoolV2Impl {
61
71
  #l2BlockSource: L2BlockSource;
62
72
  #worldStateSynchronizer: WorldStateSynchronizer;
63
73
  #createTxValidator: TxPoolV2Dependencies['createTxValidator'];
74
+ #checkAllowedSetupCalls: TxPoolV2Dependencies['checkAllowedSetupCalls'];
64
75
 
65
76
  // === In-Memory Indices ===
66
77
  #indices: TxPoolIndices = new TxPoolIndices();
@@ -72,7 +83,7 @@ export class TxPoolV2Impl {
72
83
  #evictionManager: EvictionManager;
73
84
  #dateProvider: DateProvider;
74
85
  #instrumentation: TxPoolV2Instrumentation;
75
- #evictedTxHashes: Set<string> = new Set();
86
+ #evictedTxHashes: FifoSet<string>;
76
87
  #log: Logger;
77
88
  #callbacks: TxPoolV2Callbacks;
78
89
 
@@ -92,8 +103,10 @@ export class TxPoolV2Impl {
92
103
  this.#l2BlockSource = deps.l2BlockSource;
93
104
  this.#worldStateSynchronizer = deps.worldStateSynchronizer;
94
105
  this.#createTxValidator = deps.createTxValidator;
106
+ this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
95
107
 
96
108
  this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
109
+ this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
97
110
  this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
98
111
  this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
99
112
  this.#dateProvider = dateProvider;
@@ -113,6 +126,7 @@ export class TxPoolV2Impl {
113
126
 
114
127
  // Post-event eviction rules (run after events to check ALL pending txs)
115
128
  this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
129
+ this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
116
130
  this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
117
131
  this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
118
132
  // LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
@@ -135,39 +149,67 @@ export class TxPoolV2Impl {
135
149
  // Step 0: Hydrate deleted pool state
136
150
  await this.#deletedPool.hydrateFromDatabase();
137
151
 
138
- // Step 1: Load all transactions from DB (excluding soft-deleted)
139
- const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
152
+ // Step 1: Stream txs from DB, building metadata and mined status one at a time.
153
+ const minedMetas: TxMetaData[] = [];
154
+ const pendingMetas: TxMetaData[] = [];
155
+ const deserializationErrors: string[] = [];
156
+
157
+ for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
158
+ // Skip soft-deleted transactions - they stay in DB but not in indices
159
+ if (this.#deletedPool.isSoftDeleted(txHashStr)) {
160
+ continue;
161
+ }
162
+
163
+ let meta: TxMetaData;
164
+ let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
165
+ try {
166
+ const tx = Tx.fromBuffer(buffer);
167
+ // Resolve allowed-setup-calls and the tx effect concurrently
168
+ // getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
169
+ // its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
170
+ const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
171
+ this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
172
+ return undefined;
173
+ });
174
+ const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
175
+ this.#checkAllowedSetupCalls(tx),
176
+ txEffectPromise,
177
+ ]);
178
+ meta = await buildTxMetaData(tx, allowedSetupCalls);
179
+ txEffect = fetchedTxEffect;
180
+ } catch (err) {
181
+ this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
182
+ deserializationErrors.push(txHashStr);
183
+ continue;
184
+ }
140
185
 
141
- // Step 2: Check mined status for each tx
142
- await this.#markMinedStatusBatch(loaded.map(l => l.meta));
186
+ if (txEffect) {
187
+ meta.minedL2BlockId = {
188
+ number: txEffect.l2BlockNumber,
189
+ hash: txEffect.l2BlockHash.toString(),
190
+ };
191
+ }
143
192
 
144
- // Step 3: Partition by mined status
145
- const mined: TxMetaData[] = [];
146
- const nonMined: { tx: Tx; meta: TxMetaData }[] = [];
147
- for (const entry of loaded) {
148
- if (entry.meta.minedL2BlockId !== undefined) {
149
- mined.push(entry.meta);
193
+ if (meta.minedL2BlockId !== undefined) {
194
+ minedMetas.push(meta);
150
195
  } else {
151
- nonMined.push(entry);
196
+ pendingMetas.push(meta);
152
197
  }
153
198
  }
154
199
 
155
- // Step 4: Validate non-mined transactions
156
- const { valid, invalid } = await this.#revalidateMetadata(
157
- nonMined.map(e => e.meta),
158
- 'on startup',
159
- );
200
+ // Step 2: Validate non-mined transactions
201
+ const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
160
202
 
161
- // Step 5: Populate mined indices (these don't need conflict resolution)
162
- for (const meta of mined) {
203
+ // Step 3: Populate mined indices (these don't need conflict resolution)
204
+ for (const meta of minedMetas) {
163
205
  this.#indices.addMined(meta);
164
206
  }
165
207
 
166
- // Step 6: Rebuild pending pool by running pre-add rules for each tx
208
+ // Step 4: Rebuild pending pool by running pre-add rules for each tx
167
209
  // This resolves nullifier conflicts, fee payer balance issues, and pool size limits
168
210
  const { rejected } = await this.#rebuildPendingPool(valid);
169
211
 
170
- // Step 7: Delete invalid and rejected txs from DB only (indices were never populated for these)
212
+ // Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
171
213
  const toDelete = [...deserializationErrors, ...invalid, ...rejected];
172
214
  if (toDelete.length === 0) {
173
215
  return;
@@ -187,9 +229,35 @@ export class TxPoolV2Impl {
187
229
  const errors = new Map<string, TxPoolRejectionError>();
188
230
  const acceptedPending = new Set<string>();
189
231
 
232
+ // Phase 1: Pre-compute all throwable I/O outside the transaction.
233
+ // If any pre-computation throws, the entire call fails before mutations happen.
234
+ const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
235
+
236
+ const validator = await this.#createTxValidator();
237
+
238
+ for (const tx of txs) {
239
+ const txHash = tx.getTxHash();
240
+ const txHashStr = txHash.toString();
241
+
242
+ const meta = await buildTxMetaData(tx);
243
+ const minedBlockId = await this.#getMinedBlockId(txHash);
244
+
245
+ // Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
246
+ let isValid = true;
247
+ if (!minedBlockId) {
248
+ isValid = await this.#validateMeta(meta, validator);
249
+ }
250
+
251
+ precomputed.set(txHashStr, { meta, minedBlockId, isValid });
252
+ }
253
+
254
+ // Phase 2: Apply mutations inside the transaction using only pre-computed results,
255
+ // in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
190
256
  const poolAccess = this.#createPreAddPoolAccess();
191
257
  const preAddContext: PreAddContext | undefined =
192
- opts.feeComparisonOnly !== undefined ? { feeComparisonOnly: opts.feeComparisonOnly } : undefined;
258
+ opts.feeComparisonOnly !== undefined
259
+ ? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
260
+ : undefined;
193
261
 
194
262
  await this.#store.transactionAsync(async () => {
195
263
  for (const tx of txs) {
@@ -202,22 +270,25 @@ export class TxPoolV2Impl {
202
270
  continue;
203
271
  }
204
272
 
205
- // Check mined status first (applies to all paths)
206
- const minedBlockId = await this.#getMinedBlockId(txHash);
273
+ const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
207
274
  const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
208
275
 
209
276
  if (minedBlockId) {
210
277
  // Already mined - add directly (protection already set if pre-protected)
211
- await this.#addTx(tx, { mined: minedBlockId }, opts);
278
+ await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
212
279
  accepted.push(txHash);
213
280
  } else if (preProtectedSlot !== undefined) {
214
281
  // Pre-protected and not mined - add as protected (bypass validation)
215
- await this.#addTx(tx, { protected: preProtectedSlot }, opts);
282
+ await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
216
283
  accepted.push(txHash);
284
+ } else if (!isValid) {
285
+ // Failed pre-computed validation
286
+ rejected.push(txHash);
217
287
  } else {
218
- // Regular pending tx - validate and run pre-add rules
288
+ // Regular pending tx - run pre-add rules using pre-computed metadata
219
289
  const result = await this.#tryAddRegularPendingTx(
220
290
  tx,
291
+ meta,
221
292
  opts,
222
293
  poolAccess,
223
294
  acceptedPending,
@@ -227,13 +298,18 @@ export class TxPoolV2Impl {
227
298
  );
228
299
  if (result.status === 'accepted') {
229
300
  acceptedPending.add(txHashStr);
230
- } else if (result.status === 'rejected') {
231
- rejected.push(txHash);
232
301
  } else {
233
302
  ignored.push(txHash);
234
303
  }
235
304
  }
236
305
  }
306
+
307
+ // Run post-add eviction rules for pending txs (inside transaction for atomicity)
308
+ if (acceptedPending.size > 0) {
309
+ const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
310
+ const uniqueFeePayers = new Set<string>(feePayers);
311
+ await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
312
+ }
237
313
  });
238
314
 
239
315
  // Build final accepted list for pending txs (excludes intra-batch evictions)
@@ -249,37 +325,24 @@ export class TxPoolV2Impl {
249
325
  this.#instrumentation.recordRejected(rejected.length);
250
326
  }
251
327
 
252
- // Run post-add eviction rules for pending txs
253
- if (acceptedPending.size > 0) {
254
- const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
255
- const uniqueFeePayers = new Set<string>(feePayers);
256
- await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
257
- }
258
-
259
328
  return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
260
329
  }
261
330
 
262
- /** Validates and adds a regular pending tx. Returns status. */
331
+ /** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
263
332
  async #tryAddRegularPendingTx(
264
333
  tx: Tx,
334
+ precomputedMeta: TxMetaData,
265
335
  opts: { source?: string },
266
336
  poolAccess: PreAddPoolAccess,
267
337
  acceptedPending: Set<string>,
268
338
  ignored: TxHash[],
269
339
  errors: Map<string, TxPoolRejectionError>,
270
340
  preAddContext?: PreAddContext,
271
- ): Promise<{ status: 'accepted' | 'ignored' | 'rejected' }> {
272
- const txHash = tx.getTxHash();
273
- const txHashStr = txHash.toString();
274
-
275
- // Build metadata and validate using metadata
276
- const meta = await buildTxMetaData(tx);
277
- if (!(await this.#validateMeta(meta))) {
278
- return { status: 'rejected' };
279
- }
341
+ ): Promise<{ status: 'accepted' | 'ignored' }> {
342
+ const txHashStr = tx.getTxHash().toString();
280
343
 
281
344
  // Run pre-add rules
282
- const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess, preAddContext);
345
+ const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
283
346
 
284
347
  if (preAddResult.shouldIgnore) {
285
348
  this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
@@ -316,50 +379,62 @@ export class TxPoolV2Impl {
316
379
  }
317
380
  }
318
381
 
382
+ // Randomly drop the transaction for testing purposes (report as accepted so it propagates)
383
+ if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
384
+ this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
385
+ return { status: 'accepted' };
386
+ }
387
+
319
388
  // Add the transaction
320
- await this.#addTx(tx, 'pending', opts);
389
+ await this.#addTx(tx, 'pending', opts, precomputedMeta);
321
390
  return { status: 'accepted' };
322
391
  }
323
392
 
324
- async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored' | 'rejected'> {
393
+ async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
325
394
  const txHashStr = tx.getTxHash().toString();
326
395
 
327
396
  // Check if already in pool
328
397
  if (this.#indices.has(txHashStr)) {
398
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
329
399
  return 'ignored';
330
400
  }
331
401
 
332
- // Build metadata and validate using metadata
402
+ // Build metadata and check pre-add rules
333
403
  const meta = await buildTxMetaData(tx);
334
- const validationResult = await this.#validateMeta(meta, undefined, 'can add pending');
335
- if (validationResult !== true) {
336
- return 'rejected';
337
- }
338
-
339
- // Use pre-add rules
340
404
  const poolAccess = this.#createPreAddPoolAccess();
341
405
  const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
342
406
 
343
- return preAddResult.shouldIgnore ? 'ignored' : 'accepted';
407
+ if (preAddResult.shouldIgnore) {
408
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
409
+ reason: preAddResult.reason?.message ?? 'no reason provided',
410
+ });
411
+ return 'ignored';
412
+ }
413
+ return 'accepted';
344
414
  }
345
415
 
346
416
  async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
347
417
  const slotNumber = block.globalVariables.slotNumber;
348
418
 
419
+ // Precompute setup-call allow-list flags outside the store transaction
420
+ const allowedFlags = await Promise.all(txs.map(tx => this.#checkAllowedSetupCalls(tx)));
421
+
349
422
  await this.#store.transactionAsync(async () => {
350
- for (const tx of txs) {
423
+ for (let i = 0; i < txs.length; i++) {
424
+ const tx = txs[i];
351
425
  const txHash = tx.getTxHash();
352
426
  const txHashStr = txHash.toString();
353
427
  const isNew = !this.#indices.has(txHashStr);
354
428
  const minedBlockId = await this.#getMinedBlockId(txHash);
355
429
 
356
430
  if (isNew) {
431
+ const meta = await buildTxMetaData(tx, allowedFlags[i]);
357
432
  // New tx - add as mined or protected (callback emitted by #addTx)
358
433
  if (minedBlockId) {
359
- await this.#addTx(tx, { mined: minedBlockId }, opts);
434
+ await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
360
435
  this.#indices.setProtection(txHashStr, slotNumber);
361
436
  } else {
362
- await this.#addTx(tx, { protected: slotNumber }, opts);
437
+ await this.#addTx(tx, { protected: slotNumber }, opts, meta);
363
438
  }
364
439
  } else {
365
440
  // Existing tx - update protection and mined status
@@ -379,33 +454,35 @@ export class TxPoolV2Impl {
379
454
  let softDeletedHits = 0;
380
455
  let missingPreviouslyEvicted = 0;
381
456
 
382
- for (const txHash of txHashes) {
383
- const txHashStr = txHash.toString();
457
+ await this.#store.transactionAsync(async () => {
458
+ for (const txHash of txHashes) {
459
+ const txHashStr = txHash.toString();
384
460
 
385
- if (this.#indices.has(txHashStr)) {
386
- // Update protection for existing tx
387
- this.#indices.updateProtection(txHashStr, slotNumber);
388
- } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
389
- // Resurrect soft-deleted tx as protected
390
- const buffer = await this.#txsDB.getAsync(txHashStr);
391
- if (buffer) {
392
- const tx = Tx.fromBuffer(buffer);
393
- await this.#addTx(tx, { protected: slotNumber });
394
- softDeletedHits++;
461
+ if (this.#indices.has(txHashStr)) {
462
+ // Update protection for existing tx
463
+ this.#indices.updateProtection(txHashStr, slotNumber);
464
+ } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
465
+ // Resurrect soft-deleted tx as protected
466
+ const buffer = await this.#txsDB.getAsync(txHashStr);
467
+ if (buffer) {
468
+ const tx = Tx.fromBuffer(buffer);
469
+ await this.#addTx(tx, { protected: slotNumber });
470
+ softDeletedHits++;
471
+ } else {
472
+ // Data missing despite soft-delete flag — treat as truly missing
473
+ this.#indices.setProtection(txHashStr, slotNumber);
474
+ missing.push(txHash);
475
+ }
395
476
  } else {
396
- // Data missing despite soft-delete flag treat as truly missing
477
+ // Truly missing pre-record protection for tx we don't have yet
397
478
  this.#indices.setProtection(txHashStr, slotNumber);
398
479
  missing.push(txHash);
399
- }
400
- } else {
401
- // Truly missing — pre-record protection for tx we don't have yet
402
- this.#indices.setProtection(txHashStr, slotNumber);
403
- missing.push(txHash);
404
- if (this.#evictedTxHashes.has(txHashStr)) {
405
- missingPreviouslyEvicted++;
480
+ if (this.#evictedTxHashes.has(txHashStr)) {
481
+ missingPreviouslyEvicted++;
482
+ }
406
483
  }
407
484
  }
408
- }
485
+ });
409
486
 
410
487
  // Record metrics
411
488
  if (softDeletedHits > 0) {
@@ -466,56 +543,64 @@ export class TxPoolV2Impl {
466
543
  }
467
544
  }
468
545
 
469
- // Step 4: Mark txs as mined (only those we have in the pool)
470
- for (const meta of found) {
471
- this.#indices.markAsMined(meta, blockId);
472
- await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
473
- }
546
+ await this.#store.transactionAsync(async () => {
547
+ // Step 4: Mark txs as mined (only those we have in the pool)
548
+ for (const meta of found) {
549
+ this.#indices.markAsMined(meta, blockId);
550
+ await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
551
+ }
474
552
 
475
- // Step 5: Run eviction rules (remove pending txs with conflicting nullifiers/expired timestamps)
476
- await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
553
+ // Step 5: Run post-event eviction rules (inside transaction for atomicity)
554
+ await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
555
+ });
556
+
557
+ if (found.length > 0) {
558
+ this.#callbacks.onTxsMined(found.map(m => m.txHash));
559
+ }
477
560
 
478
561
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
479
562
  }
480
563
 
481
564
  async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
482
- // Step 0: Clean up slot-deleted txs from previous slots
483
- await this.#deletedPool.cleanupSlotDeleted(slotNumber);
565
+ await this.#store.transactionAsync(async () => {
566
+ // Step 0: Clean up slot-deleted txs from previous slots
567
+ await this.#deletedPool.cleanupSlotDeleted(slotNumber);
484
568
 
485
- // Step 1: Find expired protected txs
486
- const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
569
+ // Step 1: Find expired protected txs
570
+ const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
487
571
 
488
- // Step 2: Clear protection for all expired entries (including those without metadata)
489
- this.#indices.clearProtection(expiredProtected);
572
+ // Step 2: Clear protection for all expired entries (including those without metadata)
573
+ this.#indices.clearProtection(expiredProtected);
490
574
 
491
- // Step 3: Filter to only txs that have metadata and are not mined
492
- const txsToRestore = this.#indices.filterRestorable(expiredProtected);
493
- if (txsToRestore.length === 0) {
494
- this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
495
- return;
496
- }
575
+ // Step 3: Filter to only txs that have metadata and are not mined
576
+ const txsToRestore = this.#indices.filterRestorable(expiredProtected);
577
+ if (txsToRestore.length === 0) {
578
+ this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
579
+ return;
580
+ }
497
581
 
498
- this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
582
+ this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
499
583
 
500
- // Step 4: Validate for pending pool
501
- const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
584
+ // Step 4: Validate for pending pool
585
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
502
586
 
503
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
504
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
587
+ // Step 5: Resolve nullifier conflicts and add winners to pending indices
588
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
505
589
 
506
- // Step 6: Delete invalid txs and evict conflict losers
507
- await this.#deleteTxsBatch(invalid);
508
- await this.#evictTxs(toEvict, 'NullifierConflict');
590
+ // Step 6: Delete invalid txs and evict conflict losers
591
+ await this.#deleteTxsBatch(invalid);
592
+ await this.#evictTxs(toEvict, 'NullifierConflict');
509
593
 
510
- // Step 7: Run eviction rules (enforce pool size limit)
511
- if (added.length > 0) {
512
- const feePayers = added.map(meta => meta.feePayer);
513
- const uniqueFeePayers = new Set<string>(feePayers);
514
- await this.#evictionManager.evictAfterNewTxs(
515
- added.map(m => m.txHash),
516
- [...uniqueFeePayers],
517
- );
518
- }
594
+ // Step 7: Run eviction rules (enforce pool size limit)
595
+ if (added.length > 0) {
596
+ const feePayers = added.map(meta => meta.feePayer);
597
+ const uniqueFeePayers = new Set<string>(feePayers);
598
+ await this.#evictionManager.evictAfterNewTxs(
599
+ added.map(m => m.txHash),
600
+ [...uniqueFeePayers],
601
+ );
602
+ }
603
+ });
519
604
  }
520
605
 
521
606
  async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
@@ -528,57 +613,60 @@ export class TxPoolV2Impl {
528
613
 
529
614
  this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
530
615
 
531
- // Step 2: Mark ALL un-mined txs with their original mined block number
532
- // This ensures they get soft-deleted if removed later, and only hard-deleted
533
- // when their original mined block is finalized
534
- await this.#deletedPool.markFromPrunedBlock(
535
- txsToUnmine.map(m => ({
536
- txHash: m.txHash,
537
- minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
538
- })),
539
- );
616
+ await this.#store.transactionAsync(async () => {
617
+ // Step 2: Mark ALL un-mined txs with their original mined block number
618
+ // This ensures they get soft-deleted if removed later, and only hard-deleted
619
+ // when their original mined block is finalized
620
+ await this.#deletedPool.markFromPrunedBlock(
621
+ txsToUnmine.map(m => ({
622
+ txHash: m.txHash,
623
+ minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
624
+ })),
625
+ );
540
626
 
541
- // Step 3: Unmine - clear mined status from metadata
542
- for (const meta of txsToUnmine) {
543
- this.#indices.markAsUnmined(meta);
544
- }
627
+ // Step 3: Unmine - clear mined status from metadata
628
+ for (const meta of txsToUnmine) {
629
+ this.#indices.markAsUnmined(meta);
630
+ }
545
631
 
546
- // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
547
- if (options?.deleteAllTxs) {
548
- const allTxHashes = txsToUnmine.map(m => m.txHash);
549
- await this.#deleteTxsBatch(allTxHashes);
550
- this.#log.info(
551
- `Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
552
- );
553
- return;
554
- }
632
+ // If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
633
+ if (options?.deleteAllTxs) {
634
+ const allTxHashes = txsToUnmine.map(m => m.txHash);
635
+ await this.#deleteTxsBatch(allTxHashes);
636
+ this.#log.info(
637
+ `Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
638
+ );
639
+ return;
640
+ }
555
641
 
556
- // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
557
- const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
642
+ // Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
643
+ const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
558
644
 
559
- // Step 5: Validate for pending pool
560
- const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
645
+ // Step 5: Validate for pending pool
646
+ const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
561
647
 
562
- // Step 6: Resolve nullifier conflicts and add winners to pending indices
563
- const { toEvict } = this.#applyNullifierConflictResolution(valid);
648
+ // Step 6: Resolve nullifier conflicts and add winners to pending indices
649
+ const { toEvict } = this.#applyNullifierConflictResolution(valid);
564
650
 
565
- // Step 7: Delete invalid txs and evict conflict losers
566
- await this.#deleteTxsBatch(invalid);
567
- await this.#evictTxs(toEvict, 'NullifierConflict');
651
+ // Step 7: Delete invalid txs and evict conflict losers
652
+ await this.#deleteTxsBatch(invalid);
653
+ await this.#evictTxs(toEvict, 'NullifierConflict');
568
654
 
569
- this.#log.info(
570
- `Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
571
- { txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
572
- );
655
+ this.#log.info(
656
+ `Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
657
+ { txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
658
+ );
573
659
 
574
- // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
575
- // This handles cases like existing pending txs with invalid fee payer balances
576
- await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
660
+ // Step 8: Run eviction rules for ALL pending txs (not just restored ones)
661
+ // This handles cases like existing pending txs with invalid fee payer balances
662
+ await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
663
+ });
577
664
  }
578
665
 
579
666
  async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
580
- // Delete failed txs
581
- await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
667
+ await this.#store.transactionAsync(async () => {
668
+ await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
669
+ });
582
670
 
583
671
  this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
584
672
  }
@@ -589,27 +677,30 @@ export class TxPoolV2Impl {
589
677
  // Step 1: Find mined txs at or before finalized block
590
678
  const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
591
679
 
592
- // Step 2: Collect mined txs for archiving (before deletion)
593
- const txsToArchive: Tx[] = [];
680
+ // Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
681
+ // mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
594
682
  if (this.#archive.isEnabled()) {
595
- for (const txHashStr of minedTxsToFinalize) {
596
- const buffer = await this.#txsDB.getAsync(txHashStr);
597
- if (buffer) {
598
- txsToArchive.push(Tx.fromBuffer(buffer));
683
+ for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
684
+ const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
685
+ const txsToArchive: Tx[] = [];
686
+ for (const txHashStr of chunk) {
687
+ const buffer = await this.#txsDB.getAsync(txHashStr);
688
+ if (buffer) {
689
+ txsToArchive.push(Tx.fromBuffer(buffer));
690
+ }
691
+ }
692
+ if (txsToArchive.length > 0) {
693
+ await this.#archive.archiveTxs(txsToArchive);
599
694
  }
600
695
  }
601
696
  }
602
697
 
603
- // Step 3: Delete mined txs from active pool
604
- await this.#deleteTxsBatch(minedTxsToFinalize);
605
-
606
- // Step 4: Finalize soft-deleted txs
607
- await this.#deletedPool.finalizeBlock(blockNumber);
608
-
609
- // Step 5: Archive mined txs
610
- if (txsToArchive.length > 0) {
611
- await this.#archive.archiveTxs(txsToArchive);
612
- }
698
+ // Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
699
+ // transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
700
+ await this.#store.transactionAsync(async () => {
701
+ await this.#deleteTxsBatch(minedTxsToFinalize);
702
+ await this.#deletedPool.finalizeBlock(blockNumber);
703
+ });
613
704
 
614
705
  if (minedTxsToFinalize.length > 0) {
615
706
  this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
@@ -754,9 +845,10 @@ export class TxPoolV2Impl {
754
845
  tx: Tx,
755
846
  state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
756
847
  opts: { source?: string } = {},
848
+ precomputedMeta?: TxMetaData,
757
849
  ): Promise<TxMetaData> {
758
850
  const txHashStr = tx.getTxHash().toString();
759
- const meta = await buildTxMetaData(tx);
851
+ const meta = precomputedMeta ?? (await buildTxMetaData(tx));
760
852
  meta.receivedAt = this.#dateProvider.now();
761
853
 
762
854
  await this.#txsDB.set(txHashStr, tx.toBuffer());
@@ -813,21 +905,11 @@ export class TxPoolV2Impl {
813
905
  this.#instrumentation.recordEvictions(txHashes.length, reason);
814
906
  for (const txHashStr of txHashes) {
815
907
  this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
816
- this.#addToEvictedCache(txHashStr);
908
+ this.#evictedTxHashes.add(txHashStr);
817
909
  }
818
910
  await this.#deleteTxsBatch(txHashes);
819
911
  }
820
912
 
821
- /** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
822
- #addToEvictedCache(txHashStr: string): void {
823
- if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
824
- // FIFO eviction: remove the first (oldest) entry
825
- const oldest = this.#evictedTxHashes.values().next().value!;
826
- this.#evictedTxHashes.delete(oldest);
827
- }
828
- this.#evictedTxHashes.add(txHashStr);
829
- }
830
-
831
913
  // ============================================================================
832
914
  // PRIVATE HELPERS - Validation & Conflict Resolution
833
915
  // ============================================================================
@@ -922,50 +1004,6 @@ export class TxPoolV2Impl {
922
1004
  };
923
1005
  }
924
1006
 
925
- /** Loads all transactions from the database, returning loaded txs and deserialization errors */
926
- async #loadAllTxsFromDb(): Promise<{
927
- loaded: { tx: Tx; meta: TxMetaData }[];
928
- errors: string[];
929
- }> {
930
- const loaded: { tx: Tx; meta: TxMetaData }[] = [];
931
- const errors: string[] = [];
932
-
933
- for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
934
- // Skip soft-deleted transactions - they stay in DB but not in indices
935
- if (this.#deletedPool.isSoftDeleted(txHashStr)) {
936
- continue;
937
- }
938
-
939
- try {
940
- const tx = Tx.fromBuffer(buffer);
941
- const meta = await buildTxMetaData(tx);
942
- loaded.push({ tx, meta });
943
- } catch (err) {
944
- this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
945
- errors.push(txHashStr);
946
- }
947
- }
948
-
949
- return { loaded, errors };
950
- }
951
-
952
- /** Queries block source and marks mined status on transaction metadata */
953
- async #markMinedStatusBatch(metas: TxMetaData[]): Promise<void> {
954
- for (const meta of metas) {
955
- try {
956
- const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
957
- if (txEffect) {
958
- meta.minedL2BlockId = {
959
- number: txEffect.l2BlockNumber,
960
- hash: txEffect.l2BlockHash.toString(),
961
- };
962
- }
963
- } catch (err) {
964
- this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, { err });
965
- }
966
- }
967
- }
968
-
969
1007
  /**
970
1008
  * Rebuilds the pending pool by processing each tx through pre-add rules.
971
1009
  * Starts with an empty pending pool and adds txs one by one, resolving conflicts.