@aztec/p2p 0.0.1-commit.b6e433891 → 0.0.1-commit.b8a057fa

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 (413) hide show
  1. package/README.md +7 -6
  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 +22 -6
  5. package/dest/client/factory.d.ts +4 -3
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +35 -25
  8. package/dest/client/interface.d.ts +48 -11
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +34 -19
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +105 -46
  13. package/dest/config.d.ts +143 -107
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +72 -26
  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 +9 -16
  20. package/dest/errors/reqresp.error.d.ts.map +1 -1
  21. package/dest/errors/reqresp.error.js +10 -17
  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 +98 -56
  26. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool.js +269 -196
  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 +218 -59
  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 +9 -4
  37. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  38. package/dest/mem_pools/instrumentation.js +28 -9
  39. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -5
  40. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
  42. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -3
  43. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +6 -6
  45. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  48. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  49. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  50. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  51. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  52. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  53. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +33 -5
  54. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  56. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -2
  57. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  58. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
  59. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +15 -1
  60. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +31 -0
  62. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -3
  63. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +19 -8
  65. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +17 -4
  66. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +208 -118
  68. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +10 -3
  69. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  70. package/dest/msg_validators/attestation_validator/attestation_validator.js +38 -16
  71. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  72. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  73. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  74. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +8 -3
  75. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  76. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +2 -2
  77. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +8 -3
  78. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  79. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +8 -2
  80. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +25 -3
  81. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  82. package/dest/msg_validators/proposal_validator/proposal_validator.js +85 -15
  83. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  84. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  85. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +8 -15
  86. package/dest/msg_validators/tx_validator/allowed_public_setup.js +3 -3
  87. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  88. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  89. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  90. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  91. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  92. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  93. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  94. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  95. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  96. package/dest/msg_validators/tx_validator/data_validator.js +36 -2
  97. package/dest/msg_validators/tx_validator/factory.d.ts +14 -15
  98. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  99. package/dest/msg_validators/tx_validator/factory.js +36 -17
  100. package/dest/msg_validators/tx_validator/gas_validator.d.ts +47 -10
  101. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  102. package/dest/msg_validators/tx_validator/gas_validator.js +65 -48
  103. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  104. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  105. package/dest/msg_validators/tx_validator/index.js +2 -0
  106. package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
  107. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  108. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  110. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  111. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  112. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  113. package/dest/services/data_store.d.ts +1 -1
  114. package/dest/services/data_store.d.ts.map +1 -1
  115. package/dest/services/data_store.js +5 -5
  116. package/dest/services/discv5/discV5_service.d.ts +13 -2
  117. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  118. package/dest/services/discv5/discV5_service.js +119 -23
  119. package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
  120. package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
  121. package/dest/services/discv5/persisted_enr_store.js +145 -0
  122. package/dest/services/dummy_service.d.ts +15 -15
  123. package/dest/services/dummy_service.d.ts.map +1 -1
  124. package/dest/services/dummy_service.js +15 -16
  125. package/dest/services/encoding.d.ts +19 -6
  126. package/dest/services/encoding.d.ts.map +1 -1
  127. package/dest/services/encoding.js +25 -15
  128. package/dest/services/gossipsub/topic_score_params.d.ts +6 -12
  129. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  130. package/dest/services/gossipsub/topic_score_params.js +4 -14
  131. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  132. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  133. package/dest/services/libp2p/instrumentation.js +14 -0
  134. package/dest/services/libp2p/libp2p_service.d.ts +45 -40
  135. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  136. package/dest/services/libp2p/libp2p_service.js +388 -279
  137. package/dest/services/peer-manager/peer_manager.d.ts +20 -3
  138. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  139. package/dest/services/peer-manager/peer_manager.js +79 -23
  140. package/dest/services/peer-manager/peer_scoring.d.ts +34 -2
  141. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  142. package/dest/services/peer-manager/peer_scoring.js +102 -13
  143. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -8
  144. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  145. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +38 -44
  146. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +8 -5
  147. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  148. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  149. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  150. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  151. package/dest/services/reqresp/config.d.ts +15 -3
  152. package/dest/services/reqresp/config.d.ts.map +1 -1
  153. package/dest/services/reqresp/config.js +11 -0
  154. package/dest/services/reqresp/interface.d.ts +16 -18
  155. package/dest/services/reqresp/interface.d.ts.map +1 -1
  156. package/dest/services/reqresp/interface.js +10 -20
  157. package/dest/services/reqresp/metrics.d.ts +1 -1
  158. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  159. package/dest/services/reqresp/metrics.js +0 -1
  160. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  161. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  162. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  163. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  164. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  165. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
  166. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
  167. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  168. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
  169. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  170. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  171. package/dest/services/reqresp/protocols/index.js +0 -1
  172. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  173. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  174. package/dest/services/reqresp/protocols/tx.js +1 -3
  175. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  176. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  177. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  178. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  179. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  180. package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -13
  181. package/dest/services/reqresp/reqresp.d.ts +7 -29
  182. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  183. package/dest/services/reqresp/reqresp.js +59 -209
  184. package/dest/services/service.d.ts +25 -12
  185. package/dest/services/service.d.ts.map +1 -1
  186. package/dest/services/tx_collection/config.d.ts +2 -23
  187. package/dest/services/tx_collection/config.d.ts.map +1 -1
  188. package/dest/services/tx_collection/config.js +2 -55
  189. package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
  190. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  191. package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
  192. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  193. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  194. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  195. package/dest/services/tx_collection/index.d.ts +2 -3
  196. package/dest/services/tx_collection/index.d.ts.map +1 -1
  197. package/dest/services/tx_collection/index.js +0 -1
  198. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  199. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  200. package/dest/services/tx_collection/instrumentation.js +0 -2
  201. package/dest/services/tx_collection/tx_collection.d.ts +35 -51
  202. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  203. package/dest/services/tx_collection/tx_collection.js +275 -119
  204. package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
  205. package/dest/services/tx_collection/tx_collection_sink.js +2 -2
  206. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  207. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  208. package/dest/services/tx_collection/tx_source.js +13 -8
  209. package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
  210. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  211. package/dest/services/tx_file_store/tx_file_store.js +4 -14
  212. package/dest/services/tx_provider.d.ts +3 -1
  213. package/dest/services/tx_provider.d.ts.map +1 -1
  214. package/dest/services/tx_provider.js +3 -0
  215. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  216. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  217. package/dest/test-helpers/make-test-p2p-clients.js +5 -2
  218. package/dest/test-helpers/mock-pubsub.d.ts +23 -9
  219. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  220. package/dest/test-helpers/mock-pubsub.js +44 -44
  221. package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
  222. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  223. package/dest/test-helpers/reqresp-nodes.js +16 -18
  224. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  225. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  226. package/dest/test-helpers/test_tx_provider.js +3 -0
  227. package/dest/test-helpers/testbench-utils.d.ts +15 -14
  228. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  229. package/dest/test-helpers/testbench-utils.js +28 -13
  230. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  231. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  232. package/dest/testbench/p2p_client_testbench_worker.js +102 -41
  233. package/dest/testbench/worker_client_manager.d.ts +10 -6
  234. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  235. package/dest/testbench/worker_client_manager.js +51 -9
  236. package/dest/util.d.ts +11 -6
  237. package/dest/util.d.ts.map +1 -1
  238. package/dest/util.js +35 -14
  239. package/dest/versioning.d.ts +3 -6
  240. package/dest/versioning.d.ts.map +1 -1
  241. package/dest/versioning.js +3 -24
  242. package/package.json +16 -16
  243. package/src/bootstrap/bootstrap.ts +17 -3
  244. package/src/client/factory.ts +53 -24
  245. package/src/client/interface.ts +44 -17
  246. package/src/client/p2p_client.ts +125 -79
  247. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  248. package/src/config.ts +146 -34
  249. package/src/errors/p2p-service.error.ts +11 -0
  250. package/src/errors/reqresp.error.ts +13 -19
  251. package/src/index.ts +0 -1
  252. package/src/mem_pools/attestation_pool/attestation_pool.ts +324 -239
  253. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +238 -63
  254. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  255. package/src/mem_pools/index.ts +0 -3
  256. package/src/mem_pools/instrumentation.ts +18 -12
  257. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
  258. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
  259. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
  260. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  261. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  262. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  263. package/src/mem_pools/tx_pool_v2/interfaces.ts +31 -4
  264. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +20 -8
  265. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +35 -0
  266. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +22 -8
  267. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +233 -123
  268. package/src/msg_validators/attestation_validator/attestation_validator.ts +46 -15
  269. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +15 -7
  270. package/src/msg_validators/proposal_validator/README.md +1 -1
  271. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +15 -3
  272. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +26 -3
  273. package/src/msg_validators/proposal_validator/proposal_validator.ts +94 -12
  274. package/src/msg_validators/tx_validator/README.md +13 -3
  275. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
  276. package/src/msg_validators/tx_validator/allowed_public_setup.ts +3 -3
  277. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  278. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  279. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  280. package/src/msg_validators/tx_validator/data_validator.ts +44 -1
  281. package/src/msg_validators/tx_validator/factory.ts +44 -20
  282. package/src/msg_validators/tx_validator/gas_validator.ts +99 -54
  283. package/src/msg_validators/tx_validator/index.ts +2 -0
  284. package/src/msg_validators/tx_validator/phases_validator.ts +3 -3
  285. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  286. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  287. package/src/services/data_store.ts +5 -13
  288. package/src/services/discv5/discV5_service.ts +126 -14
  289. package/src/services/discv5/persisted_enr_store.ts +158 -0
  290. package/src/services/dummy_service.ts +20 -39
  291. package/src/services/encoding.ts +28 -20
  292. package/src/services/gossipsub/README.md +33 -11
  293. package/src/services/gossipsub/topic_score_params.ts +9 -18
  294. package/src/services/libp2p/instrumentation.ts +14 -0
  295. package/src/services/libp2p/libp2p_service.ts +439 -313
  296. package/src/services/peer-manager/peer_manager.ts +86 -22
  297. package/src/services/peer-manager/peer_scoring.ts +102 -8
  298. package/src/services/reqresp/README.md +2 -37
  299. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +42 -52
  300. package/src/services/reqresp/batch-tx-requester/interface.ts +11 -4
  301. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  302. package/src/services/reqresp/config.ts +19 -2
  303. package/src/services/reqresp/interface.ts +21 -47
  304. package/src/services/reqresp/metrics.ts +0 -1
  305. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  306. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -30
  307. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
  308. package/src/services/reqresp/protocols/index.ts +0 -1
  309. package/src/services/reqresp/protocols/tx.ts +1 -3
  310. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  311. package/src/services/reqresp/rate-limiter/rate_limits.ts +3 -13
  312. package/src/services/reqresp/reqresp.ts +69 -252
  313. package/src/services/service.ts +31 -28
  314. package/src/services/tx_collection/config.ts +3 -80
  315. package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
  316. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  317. package/src/services/tx_collection/index.ts +1 -6
  318. package/src/services/tx_collection/instrumentation.ts +1 -7
  319. package/src/services/tx_collection/tx_collection.ts +330 -173
  320. package/src/services/tx_collection/tx_collection_sink.ts +2 -2
  321. package/src/services/tx_collection/tx_source.ts +10 -8
  322. package/src/services/tx_file_store/tx_file_store.ts +5 -17
  323. package/src/services/tx_provider.ts +5 -0
  324. package/src/test-helpers/make-test-p2p-clients.ts +3 -0
  325. package/src/test-helpers/mock-pubsub.ts +46 -60
  326. package/src/test-helpers/reqresp-nodes.ts +12 -22
  327. package/src/test-helpers/test_tx_provider.ts +5 -0
  328. package/src/test-helpers/testbench-utils.ts +35 -26
  329. package/src/testbench/p2p_client_testbench_worker.ts +110 -55
  330. package/src/testbench/worker_client_manager.ts +59 -20
  331. package/src/util.ts +32 -17
  332. package/src/versioning.ts +3 -33
  333. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  334. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  335. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
  336. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  337. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  338. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  339. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  340. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  341. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  342. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  343. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  344. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  345. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  346. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  347. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  348. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  349. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  350. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  351. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  352. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  353. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  354. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  355. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  356. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  357. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  358. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  359. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  360. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  361. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  362. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  363. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  364. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  365. package/dest/mem_pools/tx_pool/index.js +0 -2
  366. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  367. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  368. package/dest/mem_pools/tx_pool/priority.js +0 -15
  369. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  370. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  371. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  372. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  373. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  374. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  375. package/dest/msg_validators/clock_tolerance.d.ts +0 -21
  376. package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
  377. package/dest/msg_validators/clock_tolerance.js +0 -38
  378. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  379. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  380. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  381. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  382. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  383. package/dest/services/reqresp/protocols/block.js +0 -32
  384. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -51
  385. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  386. package/dest/services/tx_collection/fast_tx_collection.js +0 -311
  387. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
  388. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  389. package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
  390. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
  391. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  392. package/dest/services/tx_collection/slow_tx_collection.js +0 -211
  393. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -344
  394. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  395. package/src/mem_pools/tx_pool/README.md +0 -270
  396. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  397. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  398. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  399. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  400. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  401. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  402. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  403. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  404. package/src/mem_pools/tx_pool/index.ts +0 -2
  405. package/src/mem_pools/tx_pool/priority.ts +0 -20
  406. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  407. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  408. package/src/msg_validators/clock_tolerance.ts +0 -52
  409. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  410. package/src/services/reqresp/protocols/block.ts +0 -37
  411. package/src/services/tx_collection/fast_tx_collection.ts +0 -361
  412. package/src/services/tx_collection/proposal_tx_collector.ts +0 -108
  413. 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,13 +41,28 @@ 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
  */
54
+ /** A tx that has just transitioned to mined, with the time it spent in the pool. */
55
+ export interface MinedTxInfo {
56
+ txHash: string;
57
+ /** Wall-clock ms from receipt into the pool to being marked mined. Undefined when the
58
+ * receive time is unknown (e.g. a tx hydrated from the DB on restart, receivedAt === 0). */
59
+ minedDelayMs?: number;
60
+ }
61
+
45
62
  export interface TxPoolV2Callbacks {
46
63
  onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
47
64
  onTxsRemoved: (txHashes: string[] | bigint[]) => void;
48
- onTxsMined: (txHashes: string[]) => void;
65
+ onTxsMined: (minedTxs: MinedTxInfo[]) => void;
49
66
  }
50
67
 
51
68
  /**
@@ -56,7 +73,10 @@ export interface TxPoolV2Callbacks {
56
73
  export class TxPoolV2Impl {
57
74
  // === Persistence ===
58
75
  #store: AztecAsyncKVStore;
76
+ /** Tx data without its proof. Proofs live in #proofsDB so a tx can be read without loading its proof. */
59
77
  #txsDB: AztecAsyncMap<string, Buffer>;
78
+ /** Tx proofs, keyed by tx hash. Written and deleted in lockstep with #txsDB. */
79
+ #proofsDB: AztecAsyncMap<string, Buffer>;
60
80
 
61
81
  // === Dependencies ===
62
82
  #l2BlockSource: L2BlockSource;
@@ -74,7 +94,7 @@ export class TxPoolV2Impl {
74
94
  #evictionManager: EvictionManager;
75
95
  #dateProvider: DateProvider;
76
96
  #instrumentation: TxPoolV2Instrumentation;
77
- #evictedTxHashes: Set<string> = new Set();
97
+ #evictedTxHashes: FifoSet<string>;
78
98
  #log: Logger;
79
99
  #callbacks: TxPoolV2Callbacks;
80
100
 
@@ -90,6 +110,7 @@ export class TxPoolV2Impl {
90
110
  ) {
91
111
  this.#store = store;
92
112
  this.#txsDB = store.openMap('txs');
113
+ this.#proofsDB = store.openMap('tx_proofs');
93
114
 
94
115
  this.#l2BlockSource = deps.l2BlockSource;
95
116
  this.#worldStateSynchronizer = deps.worldStateSynchronizer;
@@ -97,8 +118,9 @@ export class TxPoolV2Impl {
97
118
  this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
98
119
 
99
120
  this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
121
+ this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
100
122
  this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
101
- this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
123
+ this.#deletedPool = new DeletedPool(store, txHashStr => this.#deleteTxData(txHashStr), log);
102
124
  this.#dateProvider = dateProvider;
103
125
  this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
104
126
  this.#log = log;
@@ -116,6 +138,7 @@ export class TxPoolV2Impl {
116
138
 
117
139
  // Post-event eviction rules (run after events to check ALL pending txs)
118
140
  this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
141
+ this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
119
142
  this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
120
143
  this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
121
144
  // LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
@@ -138,46 +161,74 @@ export class TxPoolV2Impl {
138
161
  // Step 0: Hydrate deleted pool state
139
162
  await this.#deletedPool.hydrateFromDatabase();
140
163
 
141
- // Step 1: Load all transactions from DB (excluding soft-deleted)
142
- const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
164
+ // Step 1: Stream txs from DB, building metadata and mined status one at a time.
165
+ const minedMetas: TxMetaData[] = [];
166
+ const pendingMetas: TxMetaData[] = [];
167
+ const deserializationErrors: string[] = [];
143
168
 
144
- // Step 2: Check mined status for each tx
145
- await this.#markMinedStatusBatch(loaded.map(l => l.meta));
169
+ for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
170
+ // Skip soft-deleted transactions - they stay in DB but not in indices
171
+ if (this.#deletedPool.isSoftDeleted(txHashStr)) {
172
+ continue;
173
+ }
146
174
 
147
- // Step 3: Partition by mined status
148
- const mined: TxMetaData[] = [];
149
- const nonMined: { tx: Tx; meta: TxMetaData }[] = [];
150
- for (const entry of loaded) {
151
- if (entry.meta.minedL2BlockId !== undefined) {
152
- mined.push(entry.meta);
175
+ let meta: TxMetaData;
176
+ let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
177
+ try {
178
+ const tx = Tx.fromBuffer(buffer);
179
+ // Resolve allowed-setup-calls and the tx effect concurrently
180
+ // getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
181
+ // its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
182
+ const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
183
+ this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
184
+ return undefined;
185
+ });
186
+ const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
187
+ this.#checkAllowedSetupCalls(tx),
188
+ txEffectPromise,
189
+ ]);
190
+ meta = await buildTxMetaData(tx, allowedSetupCalls);
191
+ txEffect = fetchedTxEffect;
192
+ } catch (err) {
193
+ this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
194
+ deserializationErrors.push(txHashStr);
195
+ continue;
196
+ }
197
+
198
+ if (txEffect) {
199
+ meta.minedL2BlockId = {
200
+ number: txEffect.l2BlockNumber,
201
+ hash: txEffect.l2BlockHash.toString(),
202
+ };
203
+ }
204
+
205
+ if (meta.minedL2BlockId !== undefined) {
206
+ minedMetas.push(meta);
153
207
  } else {
154
- nonMined.push(entry);
208
+ pendingMetas.push(meta);
155
209
  }
156
210
  }
157
211
 
158
- // Step 4: Validate non-mined transactions
159
- const { valid, invalid } = await this.#revalidateMetadata(
160
- nonMined.map(e => e.meta),
161
- 'on startup',
162
- );
212
+ // Step 2: Validate non-mined transactions
213
+ const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
163
214
 
164
- // Step 5: Populate mined indices (these don't need conflict resolution)
165
- for (const meta of mined) {
215
+ // Step 3: Populate mined indices (these don't need conflict resolution)
216
+ for (const meta of minedMetas) {
166
217
  this.#indices.addMined(meta);
167
218
  }
168
219
 
169
- // Step 6: Rebuild pending pool by running pre-add rules for each tx
220
+ // Step 4: Rebuild pending pool by running pre-add rules for each tx
170
221
  // This resolves nullifier conflicts, fee payer balance issues, and pool size limits
171
222
  const { rejected } = await this.#rebuildPendingPool(valid);
172
223
 
173
- // Step 7: Delete invalid and rejected txs from DB only (indices were never populated for these)
224
+ // Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
174
225
  const toDelete = [...deserializationErrors, ...invalid, ...rejected];
175
226
  if (toDelete.length === 0) {
176
227
  return;
177
228
  }
178
229
  await this.#store.transactionAsync(async () => {
179
230
  for (const txHashStr of toDelete) {
180
- await this.#txsDB.delete(txHashStr);
231
+ await this.#deleteTxData(txHashStr);
181
232
  }
182
233
  });
183
234
  this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
@@ -423,10 +474,11 @@ export class TxPoolV2Impl {
423
474
  // Update protection for existing tx
424
475
  this.#indices.updateProtection(txHashStr, slotNumber);
425
476
  } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
426
- // Resurrect soft-deleted tx as protected
477
+ // Resurrect soft-deleted tx as protected. Load the proof too: #addTx rewrites both entries, so re-adding
478
+ // a proofless tx would wipe the stored proof.
427
479
  const buffer = await this.#txsDB.getAsync(txHashStr);
428
480
  if (buffer) {
429
- const tx = Tx.fromBuffer(buffer);
481
+ const tx = await this.#loadTxWithProof(txHashStr, buffer);
430
482
  await this.#addTx(tx, { protected: slotNumber });
431
483
  softDeletedHits++;
432
484
  } else {
@@ -516,7 +568,15 @@ export class TxPoolV2Impl {
516
568
  });
517
569
 
518
570
  if (found.length > 0) {
519
- this.#callbacks.onTxsMined(found.map(m => m.txHash));
571
+ // receivedAt is 0 for txs hydrated from the DB on restart (true receive time lost) — leave
572
+ // their delay undefined so the metric isn't polluted by epoch-sized values.
573
+ const now = this.#dateProvider.now();
574
+ this.#callbacks.onTxsMined(
575
+ found.map(m => ({
576
+ txHash: m.txHash,
577
+ minedDelayMs: m.receivedAt > 0 ? now - m.receivedAt : undefined,
578
+ })),
579
+ );
520
580
  }
521
581
 
522
582
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
@@ -541,29 +601,62 @@ export class TxPoolV2Impl {
541
601
  }
542
602
 
543
603
  this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
604
+ await this.#restoreUnprotectedToPending(txsToRestore, 'during prepareForSlot');
605
+ });
606
+ }
544
607
 
545
- // Step 4: Validate for pending pool
546
- const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
608
+ async unprotectTxs(txHashes: TxHash[], slotNumber: SlotNumber): Promise<void> {
609
+ const hashStrs = txHashes.map(h => h.toString());
547
610
 
548
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
549
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
611
+ await this.#store.transactionAsync(async () => {
612
+ // Only release entries still recorded at this exact slot. A tx that another, still-live proposal
613
+ // raised to a higher slot via updateProtection must keep that protection. Mined txs have no
614
+ // protection entry and so are never matched here.
615
+ const matching = this.#indices.findProtectedTxsAtSlot(hashStrs, slotNumber);
616
+ if (matching.length === 0) {
617
+ this.#log.debug(`Unprotecting txs for slot ${slotNumber}: no matching protections to release`);
618
+ return;
619
+ }
550
620
 
551
- // Step 6: Delete invalid txs and evict conflict losers
552
- await this.#deleteTxsBatch(invalid);
553
- await this.#evictTxs(toEvict, 'NullifierConflict');
621
+ this.#indices.clearProtection(matching);
554
622
 
555
- // Step 7: Run eviction rules (enforce pool size limit)
556
- if (added.length > 0) {
557
- const feePayers = added.map(meta => meta.feePayer);
558
- const uniqueFeePayers = new Set<string>(feePayers);
559
- await this.#evictionManager.evictAfterNewTxs(
560
- added.map(m => m.txHash),
561
- [...uniqueFeePayers],
562
- );
623
+ const txsToRestore = this.#indices.filterRestorable(matching);
624
+ if (txsToRestore.length === 0) {
625
+ return;
563
626
  }
627
+
628
+ this.#log.info(`Unprotecting ${txsToRestore.length} txs from failed proposal at slot ${slotNumber}`);
629
+ await this.#restoreUnprotectedToPending(txsToRestore, 'during unprotectTxs');
564
630
  });
565
631
  }
566
632
 
633
+ /**
634
+ * Returns just-unprotected txs to the pending pool: revalidates them, resolves nullifier
635
+ * conflicts, deletes losers, then enforces the pool size limit. Must run inside a store
636
+ * transaction; callers clear the protection entries before invoking.
637
+ */
638
+ async #restoreUnprotectedToPending(txsToRestore: TxMetaData[], context: string): Promise<void> {
639
+ // Step 1: Validate for pending pool
640
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, context);
641
+
642
+ // Step 2: Resolve nullifier conflicts and add winners to pending indices
643
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
644
+
645
+ // Step 3: Delete invalid txs and evict conflict losers
646
+ await this.#deleteTxsBatch(invalid);
647
+ await this.#evictTxs(toEvict, 'NullifierConflict');
648
+
649
+ // Step 4: Run eviction rules (enforce pool size limit)
650
+ if (added.length > 0) {
651
+ const feePayers = added.map(meta => meta.feePayer);
652
+ const uniqueFeePayers = new Set<string>(feePayers);
653
+ await this.#evictionManager.evictAfterNewTxs(
654
+ added.map(m => m.txHash),
655
+ [...uniqueFeePayers],
656
+ );
657
+ }
658
+ }
659
+
567
660
  async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
568
661
  // Step 1: Find transactions mined after the prune point
569
662
  const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
@@ -635,56 +728,113 @@ export class TxPoolV2Impl {
635
728
  async handleFinalizedBlock(block: BlockHeader): Promise<void> {
636
729
  const blockNumber = block.globalVariables.blockNumber;
637
730
 
638
- // Step 1: Find mined txs at or before finalized block
639
- const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
731
+ // Hold finalized txs for a configurable margin behind the finalized tip so a prover still
732
+ // proving an epoch with already-finalized blocks isn't starved of its txs. 0 deletes at the finalized tip.
733
+ const cutoffBlock = await this.#finalizationCutoffBlock(block);
640
734
 
641
- await this.#store.transactionAsync(async () => {
642
- // Step 2: Collect mined txs for archiving (before deletion)
643
- const txsToArchive: Tx[] = [];
644
- if (this.#archive.isEnabled()) {
645
- for (const txHashStr of minedTxsToFinalize) {
735
+ // Step 1: Find mined txs at or before the cutoff block
736
+ const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(cutoffBlock);
737
+
738
+ // Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
739
+ // mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
740
+ if (this.#archive.isEnabled()) {
741
+ for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
742
+ const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
743
+ const txsToArchive: Tx[] = [];
744
+ for (const txHashStr of chunk) {
646
745
  const buffer = await this.#txsDB.getAsync(txHashStr);
647
746
  if (buffer) {
648
747
  txsToArchive.push(Tx.fromBuffer(buffer));
649
748
  }
650
749
  }
750
+ if (txsToArchive.length > 0) {
751
+ await this.#archive.archiveTxs(txsToArchive);
752
+ }
651
753
  }
754
+ }
652
755
 
653
- // Step 3: Delete mined txs from active pool
756
+ // Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
757
+ // transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
758
+ await this.#store.transactionAsync(async () => {
654
759
  await this.#deleteTxsBatch(minedTxsToFinalize);
655
-
656
- // Step 4: Finalize soft-deleted txs
657
- await this.#deletedPool.finalizeBlock(blockNumber);
658
-
659
- // Step 5: Archive mined txs
660
- if (txsToArchive.length > 0) {
661
- await this.#archive.archiveTxs(txsToArchive);
662
- }
760
+ await this.#deletedPool.finalizeBlock(cutoffBlock);
663
761
  });
664
762
 
665
763
  if (minedTxsToFinalize.length > 0) {
666
- this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
764
+ this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${cutoffBlock}`, {
667
765
  txHashes: minedTxsToFinalize,
766
+ finalizedBlockNumber: blockNumber,
767
+ cutoffBlock,
668
768
  });
669
769
  }
670
770
  }
671
771
 
772
+ /**
773
+ * Resolves the block up to which finalized txs may be deleted, given `keepFinalizedTxsForSlots`.
774
+ * With a margin of 0 this is just the finalized block. Otherwise we keep txs whose block is within
775
+ * the margin (in slots) of the finalized tip: take the target slot `finalizedSlot - margin`, find the
776
+ * latest checkpoint at or before it with a single reverse range query (`limit: 1`), and use that
777
+ * checkpoint's last block as the cutoff. This rounds to a checkpoint boundary, so it can retain slightly
778
+ * more than the configured margin but never less, and never deletes past the finalized block.
779
+ */
780
+ async #finalizationCutoffBlock(block: BlockHeader): Promise<BlockNumber> {
781
+ const keepSlots = this.#config.keepFinalizedTxsForSlots;
782
+ if (keepSlots <= 0) {
783
+ return block.globalVariables.blockNumber;
784
+ }
785
+
786
+ // The goal here really is to ensure we keep transactions long enough for them to be proven.
787
+ // So we could be smart and calculate the number of slots until the end of the proof submission window.
788
+ // Our approach here is a lot simpler however and we just keep transactions for the configured number
789
+ // of slots past L1 finalisation. This means we may keep transactions in the mined pool for longer
790
+ // than strictly necessary.
791
+ const targetSlot = block.getSlot() - keepSlots;
792
+ if (targetSlot < 0) {
793
+ // The margin reaches past genesis: keep everything.
794
+ return BlockNumber(0);
795
+ }
796
+
797
+ const [checkpoint] = await this.#l2BlockSource.getCheckpointsData({
798
+ fromSlot: SlotNumber(targetSlot),
799
+ limit: 1,
800
+ reverse: true,
801
+ });
802
+ // No checkpoint at or before the target slot (e.g. early chain): keep everything.
803
+ return checkpoint ? BlockNumber(checkpoint.startBlock + checkpoint.blockCount - 1) : BlockNumber(0);
804
+ }
805
+
672
806
  // === Query Methods ===
673
807
 
674
- async getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
675
- const buffer = await this.#txsDB.getAsync(txHash.toString());
676
- return buffer ? Tx.fromBuffer(buffer) : undefined;
808
+ async getTxByHash(txHash: TxHash, opts: { includeProof?: boolean } = {}): Promise<Tx | undefined> {
809
+ const txHashStr = txHash.toString();
810
+ const buffer = await this.#txsDB.getAsync(txHashStr);
811
+ if (!buffer) {
812
+ return undefined;
813
+ }
814
+ return opts.includeProof === false ? Tx.fromBuffer(buffer) : this.#loadTxWithProof(txHashStr, buffer);
677
815
  }
678
816
 
679
- async getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
817
+ async getTxsByHash(txHashes: TxHash[], opts: { includeProof?: boolean } = {}): Promise<(Tx | undefined)[]> {
680
818
  const results: (Tx | undefined)[] = [];
681
819
  for (const h of txHashes) {
682
- const buffer = await this.#txsDB.getAsync(h.toString());
683
- results.push(buffer ? Tx.fromBuffer(buffer) : undefined);
820
+ results.push(await this.getTxByHash(h, opts));
684
821
  }
685
822
  return results;
686
823
  }
687
824
 
825
+ /** Deserializes a tx blob loaded from #txsDB together with its separately-stored proof. */
826
+ async #loadTxWithProof(txHashStr: string, buffer: Buffer): Promise<Tx> {
827
+ const proofBuffer = await this.#proofsDB.getAsync(txHashStr);
828
+ if (!proofBuffer) {
829
+ // #addTx always writes a proof entry (an empty proof serializes to a 4-byte sentinel), so a missing entry
830
+ // means the blob/proof invariant is broken. Return the proofless tx but flag it, since a consumer that needs
831
+ // the proof (eg serving peers) would otherwise fail far away from the root cause.
832
+ this.#log.warn(`Missing stored proof for tx ${txHashStr}`, { txHash: txHashStr });
833
+ return Tx.fromBuffer(buffer);
834
+ }
835
+ return Tx.fromBuffers(buffer, proofBuffer);
836
+ }
837
+
688
838
  hasTxs(txHashes: TxHash[]): boolean[] {
689
839
  return txHashes.map(h => {
690
840
  const hashStr = h.toString();
@@ -720,6 +870,11 @@ export class TxPoolV2Impl {
720
870
  return this.#indices.getPendingTxCount();
721
871
  }
722
872
 
873
+ hasEligiblePendingTxs(minCount: number): boolean {
874
+ const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
875
+ return this.#indices.hasEligiblePendingTxs(maxReceivedAt, minCount);
876
+ }
877
+
723
878
  getMinedTxHashes(): [TxHash, L2BlockId][] {
724
879
  return this.#indices.getMinedTxs().map(([hash, blockId]) => [TxHash.fromString(hash), blockId]);
725
880
  }
@@ -763,6 +918,9 @@ export class TxPoolV2Impl {
763
918
  if (config.minTxPoolAgeMs !== undefined) {
764
919
  this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
765
920
  }
921
+ if (config.keepFinalizedTxsForSlots !== undefined) {
922
+ this.#config.keepFinalizedTxsForSlots = config.keepFinalizedTxsForSlots;
923
+ }
766
924
  // Update eviction rules with new config
767
925
  this.#evictionManager.updateConfig(config);
768
926
  }
@@ -811,7 +969,8 @@ export class TxPoolV2Impl {
811
969
  const meta = precomputedMeta ?? (await buildTxMetaData(tx));
812
970
  meta.receivedAt = this.#dateProvider.now();
813
971
 
814
- await this.#txsDB.set(txHashStr, tx.toBuffer());
972
+ await this.#txsDB.set(txHashStr, tx.withoutProof().toBuffer());
973
+ await this.#proofsDB.set(txHashStr, tx.chonkProof.toBuffer());
815
974
  await this.#deletedPool.clearSoftDeleted(txHashStr);
816
975
  this.#callbacks.onTxsAdded([tx], opts);
817
976
 
@@ -850,6 +1009,12 @@ export class TxPoolV2Impl {
850
1009
  await this.#deletedPool.deleteTx(txHashStr);
851
1010
  }
852
1011
 
1012
+ /** Hard-deletes a tx's stored data (tx blob and proof) from the DB. */
1013
+ async #deleteTxData(txHashStr: string): Promise<void> {
1014
+ await this.#txsDB.delete(txHashStr);
1015
+ await this.#proofsDB.delete(txHashStr);
1016
+ }
1017
+
853
1018
  /** Deletes a batch of transactions, emitting callbacks individually for each. */
854
1019
  async #deleteTxsBatch(txHashes: string[]): Promise<void> {
855
1020
  for (const txHashStr of txHashes) {
@@ -865,21 +1030,11 @@ export class TxPoolV2Impl {
865
1030
  this.#instrumentation.recordEvictions(txHashes.length, reason);
866
1031
  for (const txHashStr of txHashes) {
867
1032
  this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
868
- this.#addToEvictedCache(txHashStr);
1033
+ this.#evictedTxHashes.add(txHashStr);
869
1034
  }
870
1035
  await this.#deleteTxsBatch(txHashes);
871
1036
  }
872
1037
 
873
- /** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
874
- #addToEvictedCache(txHashStr: string): void {
875
- if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
876
- // FIFO eviction: remove the first (oldest) entry
877
- const oldest = this.#evictedTxHashes.values().next().value!;
878
- this.#evictedTxHashes.delete(oldest);
879
- }
880
- this.#evictedTxHashes.add(txHashStr);
881
- }
882
-
883
1038
  // ============================================================================
884
1039
  // PRIVATE HELPERS - Validation & Conflict Resolution
885
1040
  // ============================================================================
@@ -974,51 +1129,6 @@ export class TxPoolV2Impl {
974
1129
  };
975
1130
  }
976
1131
 
977
- /** Loads all transactions from the database, returning loaded txs and deserialization errors */
978
- async #loadAllTxsFromDb(): Promise<{
979
- loaded: { tx: Tx; meta: TxMetaData }[];
980
- errors: string[];
981
- }> {
982
- const loaded: { tx: Tx; meta: TxMetaData }[] = [];
983
- const errors: string[] = [];
984
-
985
- for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
986
- // Skip soft-deleted transactions - they stay in DB but not in indices
987
- if (this.#deletedPool.isSoftDeleted(txHashStr)) {
988
- continue;
989
- }
990
-
991
- try {
992
- const tx = Tx.fromBuffer(buffer);
993
- const allowedSetupCalls = await this.#checkAllowedSetupCalls(tx);
994
- const meta = await buildTxMetaData(tx, allowedSetupCalls);
995
- loaded.push({ tx, meta });
996
- } catch (err) {
997
- this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
998
- errors.push(txHashStr);
999
- }
1000
- }
1001
-
1002
- return { loaded, errors };
1003
- }
1004
-
1005
- /** Queries block source and marks mined status on transaction metadata */
1006
- async #markMinedStatusBatch(metas: TxMetaData[]): Promise<void> {
1007
- for (const meta of metas) {
1008
- try {
1009
- const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
1010
- if (txEffect) {
1011
- meta.minedL2BlockId = {
1012
- number: txEffect.l2BlockNumber,
1013
- hash: txEffect.l2BlockHash.toString(),
1014
- };
1015
- }
1016
- } catch (err) {
1017
- this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, { err });
1018
- }
1019
- }
1020
- }
1021
-
1022
1132
  /**
1023
1133
  * Rebuilds the pending pool by processing each tx through pre-add rules.
1024
1134
  * Starts with an empty pending pool and adds txs one by one, resolving conflicts.
@@ -1093,7 +1203,7 @@ export class TxPoolV2Impl {
1093
1203
  const publicStateSource = new DatabasePublicStateSource(db);
1094
1204
  const balance = await publicStateSource.storageRead(
1095
1205
  ProtocolContractAddress.FeeJuice,
1096
- await computeFeePayerBalanceStorageSlot(AztecAddress.fromString(feePayer)),
1206
+ await computeFeePayerBalanceStorageSlot(AztecAddress.fromStringUnsafe(feePayer)),
1097
1207
  );
1098
1208
  return balance.toBigInt();
1099
1209
  },
@@ -3,19 +3,33 @@ import { NoCommitteeError } from '@aztec/ethereum/contracts';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import {
5
5
  type CheckpointAttestation,
6
+ type CoordinationSignatureContext,
6
7
  type P2PValidator,
7
8
  PeerErrorSeverity,
8
9
  type ValidationResult,
10
+ hasValidSignatureContext,
9
11
  } from '@aztec/stdlib/p2p';
10
-
11
- import { isWithinClockTolerance } from '../clock_tolerance.js';
12
+ import type { ConsensusTimetable } from '@aztec/stdlib/timetable';
12
13
 
13
14
  export class CheckpointAttestationValidator implements P2PValidator<CheckpointAttestation> {
14
15
  protected epochCache: EpochCacheInterface;
15
16
  protected logger: Logger;
17
+ private readonly timetable: ConsensusTimetable;
18
+ protected readonly signatureContext: CoordinationSignatureContext;
19
+ private readonly clockDisparityMs: number;
16
20
 
17
- constructor(epochCache: EpochCacheInterface) {
21
+ constructor(
22
+ epochCache: EpochCacheInterface,
23
+ timetable: ConsensusTimetable,
24
+ opts: {
25
+ signatureContext: CoordinationSignatureContext;
26
+ clockDisparityMs: number;
27
+ },
28
+ ) {
18
29
  this.epochCache = epochCache;
30
+ this.timetable = timetable;
31
+ this.signatureContext = opts.signatureContext;
32
+ this.clockDisparityMs = opts.clockDisparityMs;
19
33
  this.logger = createLogger('p2p:checkpoint-attestation-validator');
20
34
  }
21
35
 
@@ -23,19 +37,36 @@ export class CheckpointAttestationValidator implements P2PValidator<CheckpointAt
23
37
  const slotNumber = message.payload.header.slotNumber;
24
38
 
25
39
  try {
26
- // Use target slots since proposals target pipeline slots (slot + 1 when pipelining)
27
- const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();
40
+ // Cross-chain replay check: reject attestations that carry a foreign signing domain.
41
+ if (!hasValidSignatureContext(message.payload, this.signatureContext)) {
42
+ this.logger.warn(`Rejecting checkpoint attestation with foreign signature context for slot ${slotNumber}`, {
43
+ chainId: message.payload.signatureContext.chainId,
44
+ rollupAddress: message.payload.signatureContext.rollupAddress.toString(),
45
+ expectedChainId: this.signatureContext.chainId,
46
+ expectedRollupAddress: this.signatureContext.rollupAddress.toString(),
47
+ });
48
+ return { result: 'reject', severity: PeerErrorSeverity.LowToleranceError };
49
+ }
28
50
 
29
- if (slotNumber !== targetSlot && slotNumber !== nextSlot) {
30
- // Check if message is for previous slot and within clock tolerance
31
- if (!isWithinClockTolerance(slotNumber, targetSlot, this.epochCache)) {
32
- this.logger.warn(
33
- `Checkpoint attestation slot ${slotNumber} is not current (${targetSlot}) or next (${nextSlot}) slot`,
34
- );
35
- return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
36
- }
37
- this.logger.debug(`Ignoring checkpoint attestation for previous slot ${slotNumber} within clock tolerance`);
38
- return { result: 'ignore' };
51
+ // Accept attestations whose explicit per-slot receive window contains the current wall-clock time.
52
+ // The window spans the build-frame start (attestation_receive_start) to the attestation deadline
53
+ // (target_slot_start + S - 2E), widened by the configured clock-disparity tolerance on both ends, so
54
+ // it covers the build slot, the target slot, and clock-disparity grace. This is the sole arrival
55
+ // gate; attestations are otherwise attributed by content, not by current/next slot.
56
+ const startSeconds = this.timetable.getAttestationReceiveStart(slotNumber);
57
+ const deadlineSeconds = this.timetable.getAttestationDeadline(slotNumber);
58
+ const nowMs = Number(this.epochCache.getEpochAndSlotNow().nowMs);
59
+ if (
60
+ nowMs < startSeconds * 1000 - this.clockDisparityMs ||
61
+ nowMs > deadlineSeconds * 1000 + this.clockDisparityMs
62
+ ) {
63
+ this.logger.warn(`Checkpoint attestation slot ${slotNumber} is outside its receive window`, {
64
+ slotNumber,
65
+ nowMs,
66
+ windowStartSeconds: startSeconds,
67
+ windowDeadlineSeconds: deadlineSeconds,
68
+ });
69
+ return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
39
70
  }
40
71
 
41
72
  // Verify the signature is valid