@aztec/p2p 5.0.0-private.20260319 → 5.0.0-rc.2

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 (411) hide show
  1. package/README.md +4 -1
  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 +33 -24
  8. package/dest/client/interface.d.ts +43 -11
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +33 -19
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +100 -44
  13. package/dest/config.d.ts +137 -107
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +64 -23
  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 +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 +265 -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 +175 -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 +1 -1
  37. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  38. package/dest/mem_pools/instrumentation.js +17 -1
  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 +22 -5
  54. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -2
  56. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  57. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
  58. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +7 -1
  59. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  60. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +10 -0
  61. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +8 -3
  62. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  63. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +7 -4
  64. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +8 -3
  65. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  66. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +153 -111
  67. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +10 -3
  68. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  69. package/dest/msg_validators/attestation_validator/attestation_validator.js +38 -16
  70. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  71. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  72. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  73. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +8 -3
  74. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  75. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +2 -2
  76. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +8 -3
  77. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  78. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +8 -2
  79. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +25 -3
  80. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  81. package/dest/msg_validators/proposal_validator/proposal_validator.js +77 -14
  82. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  83. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  84. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +8 -15
  85. package/dest/msg_validators/tx_validator/allowed_public_setup.js +3 -3
  86. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  87. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  88. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  89. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  90. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  91. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  92. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  93. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  94. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/data_validator.js +36 -2
  96. package/dest/msg_validators/tx_validator/factory.d.ts +14 -15
  97. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/factory.js +36 -17
  99. package/dest/msg_validators/tx_validator/gas_validator.d.ts +47 -10
  100. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/gas_validator.js +65 -48
  102. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  103. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/index.js +2 -0
  105. package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
  106. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  107. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  108. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  109. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  110. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  111. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  112. package/dest/services/data_store.d.ts +1 -1
  113. package/dest/services/data_store.d.ts.map +1 -1
  114. package/dest/services/data_store.js +5 -5
  115. package/dest/services/discv5/discV5_service.d.ts +13 -2
  116. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  117. package/dest/services/discv5/discV5_service.js +119 -23
  118. package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
  119. package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
  120. package/dest/services/discv5/persisted_enr_store.js +145 -0
  121. package/dest/services/dummy_service.d.ts +15 -15
  122. package/dest/services/dummy_service.d.ts.map +1 -1
  123. package/dest/services/dummy_service.js +15 -16
  124. package/dest/services/encoding.d.ts +8 -8
  125. package/dest/services/encoding.d.ts.map +1 -1
  126. package/dest/services/encoding.js +11 -15
  127. package/dest/services/gossipsub/topic_score_params.d.ts +6 -12
  128. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  129. package/dest/services/gossipsub/topic_score_params.js +4 -14
  130. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  131. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  132. package/dest/services/libp2p/instrumentation.js +14 -0
  133. package/dest/services/libp2p/libp2p_service.d.ts +44 -39
  134. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  135. package/dest/services/libp2p/libp2p_service.js +383 -278
  136. package/dest/services/peer-manager/peer_manager.d.ts +20 -3
  137. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  138. package/dest/services/peer-manager/peer_manager.js +79 -23
  139. package/dest/services/peer-manager/peer_scoring.d.ts +34 -2
  140. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  141. package/dest/services/peer-manager/peer_scoring.js +102 -13
  142. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -8
  143. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  144. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +38 -44
  145. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +8 -5
  146. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  147. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  148. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  149. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  150. package/dest/services/reqresp/config.d.ts +3 -3
  151. package/dest/services/reqresp/config.d.ts.map +1 -1
  152. package/dest/services/reqresp/interface.d.ts +16 -18
  153. package/dest/services/reqresp/interface.d.ts.map +1 -1
  154. package/dest/services/reqresp/interface.js +10 -20
  155. package/dest/services/reqresp/metrics.d.ts +1 -1
  156. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  157. package/dest/services/reqresp/metrics.js +0 -1
  158. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  159. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  160. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  161. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  162. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  163. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
  164. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
  165. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  166. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
  167. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  168. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  169. package/dest/services/reqresp/protocols/index.js +0 -1
  170. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  171. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  172. package/dest/services/reqresp/protocols/tx.js +1 -3
  173. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  174. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  175. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  176. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  177. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  178. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  179. package/dest/services/reqresp/reqresp.d.ts +7 -29
  180. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  181. package/dest/services/reqresp/reqresp.js +26 -207
  182. package/dest/services/service.d.ts +25 -12
  183. package/dest/services/service.d.ts.map +1 -1
  184. package/dest/services/tx_collection/config.d.ts +2 -23
  185. package/dest/services/tx_collection/config.d.ts.map +1 -1
  186. package/dest/services/tx_collection/config.js +2 -55
  187. package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
  188. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  189. package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
  190. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  191. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  192. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  193. package/dest/services/tx_collection/index.d.ts +2 -3
  194. package/dest/services/tx_collection/index.d.ts.map +1 -1
  195. package/dest/services/tx_collection/index.js +0 -1
  196. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  197. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  198. package/dest/services/tx_collection/instrumentation.js +0 -2
  199. package/dest/services/tx_collection/tx_collection.d.ts +35 -51
  200. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  201. package/dest/services/tx_collection/tx_collection.js +275 -119
  202. package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
  203. package/dest/services/tx_collection/tx_collection_sink.js +2 -2
  204. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  205. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  206. package/dest/services/tx_collection/tx_source.js +13 -8
  207. package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
  208. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  209. package/dest/services/tx_file_store/tx_file_store.js +4 -14
  210. package/dest/services/tx_provider.d.ts +3 -1
  211. package/dest/services/tx_provider.d.ts.map +1 -1
  212. package/dest/services/tx_provider.js +3 -0
  213. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  214. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  215. package/dest/test-helpers/make-test-p2p-clients.js +5 -2
  216. package/dest/test-helpers/mock-pubsub.d.ts +23 -9
  217. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  218. package/dest/test-helpers/mock-pubsub.js +44 -44
  219. package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
  220. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  221. package/dest/test-helpers/reqresp-nodes.js +16 -18
  222. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  223. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  224. package/dest/test-helpers/test_tx_provider.js +3 -0
  225. package/dest/test-helpers/testbench-utils.d.ts +14 -14
  226. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  227. package/dest/test-helpers/testbench-utils.js +25 -13
  228. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  229. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  230. package/dest/testbench/p2p_client_testbench_worker.js +102 -41
  231. package/dest/testbench/worker_client_manager.d.ts +10 -6
  232. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  233. package/dest/testbench/worker_client_manager.js +51 -9
  234. package/dest/util.d.ts +11 -6
  235. package/dest/util.d.ts.map +1 -1
  236. package/dest/util.js +35 -14
  237. package/dest/versioning.d.ts +3 -6
  238. package/dest/versioning.d.ts.map +1 -1
  239. package/dest/versioning.js +3 -24
  240. package/package.json +16 -16
  241. package/src/bootstrap/bootstrap.ts +17 -3
  242. package/src/client/factory.ts +52 -24
  243. package/src/client/interface.ts +38 -17
  244. package/src/client/p2p_client.ts +118 -76
  245. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  246. package/src/config.ts +130 -31
  247. package/src/errors/p2p-service.error.ts +11 -0
  248. package/src/errors/reqresp.error.ts +0 -25
  249. package/src/index.ts +0 -1
  250. package/src/mem_pools/attestation_pool/attestation_pool.ts +319 -238
  251. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +198 -62
  252. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  253. package/src/mem_pools/index.ts +0 -3
  254. package/src/mem_pools/instrumentation.ts +5 -1
  255. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
  256. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
  257. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
  258. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  259. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  260. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  261. package/src/mem_pools/tx_pool_v2/interfaces.ts +18 -4
  262. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +20 -8
  263. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +12 -0
  264. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +8 -4
  265. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +163 -117
  266. package/src/msg_validators/attestation_validator/attestation_validator.ts +46 -15
  267. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +15 -7
  268. package/src/msg_validators/proposal_validator/README.md +1 -1
  269. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +15 -3
  270. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +26 -3
  271. package/src/msg_validators/proposal_validator/proposal_validator.ts +89 -11
  272. package/src/msg_validators/tx_validator/README.md +13 -3
  273. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
  274. package/src/msg_validators/tx_validator/allowed_public_setup.ts +3 -3
  275. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  276. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  277. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  278. package/src/msg_validators/tx_validator/data_validator.ts +44 -1
  279. package/src/msg_validators/tx_validator/factory.ts +44 -20
  280. package/src/msg_validators/tx_validator/gas_validator.ts +99 -54
  281. package/src/msg_validators/tx_validator/index.ts +2 -0
  282. package/src/msg_validators/tx_validator/phases_validator.ts +3 -3
  283. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  284. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  285. package/src/services/data_store.ts +5 -13
  286. package/src/services/discv5/discV5_service.ts +126 -14
  287. package/src/services/discv5/persisted_enr_store.ts +158 -0
  288. package/src/services/dummy_service.ts +20 -39
  289. package/src/services/encoding.ts +11 -21
  290. package/src/services/gossipsub/README.md +33 -11
  291. package/src/services/gossipsub/topic_score_params.ts +9 -18
  292. package/src/services/libp2p/instrumentation.ts +14 -0
  293. package/src/services/libp2p/libp2p_service.ts +436 -311
  294. package/src/services/peer-manager/peer_manager.ts +86 -22
  295. package/src/services/peer-manager/peer_scoring.ts +102 -8
  296. package/src/services/reqresp/README.md +0 -14
  297. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +42 -52
  298. package/src/services/reqresp/batch-tx-requester/interface.ts +11 -4
  299. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  300. package/src/services/reqresp/config.ts +2 -2
  301. package/src/services/reqresp/interface.ts +21 -47
  302. package/src/services/reqresp/metrics.ts +0 -1
  303. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  304. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -30
  305. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
  306. package/src/services/reqresp/protocols/index.ts +0 -1
  307. package/src/services/reqresp/protocols/tx.ts +1 -3
  308. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  309. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  310. package/src/services/reqresp/reqresp.ts +29 -252
  311. package/src/services/service.ts +31 -28
  312. package/src/services/tx_collection/config.ts +3 -80
  313. package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
  314. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  315. package/src/services/tx_collection/index.ts +1 -6
  316. package/src/services/tx_collection/instrumentation.ts +1 -7
  317. package/src/services/tx_collection/tx_collection.ts +330 -173
  318. package/src/services/tx_collection/tx_collection_sink.ts +2 -2
  319. package/src/services/tx_collection/tx_source.ts +10 -8
  320. package/src/services/tx_file_store/tx_file_store.ts +5 -17
  321. package/src/services/tx_provider.ts +5 -0
  322. package/src/test-helpers/make-test-p2p-clients.ts +3 -0
  323. package/src/test-helpers/mock-pubsub.ts +46 -60
  324. package/src/test-helpers/reqresp-nodes.ts +12 -22
  325. package/src/test-helpers/test_tx_provider.ts +5 -0
  326. package/src/test-helpers/testbench-utils.ts +31 -26
  327. package/src/testbench/p2p_client_testbench_worker.ts +110 -55
  328. package/src/testbench/worker_client_manager.ts +59 -20
  329. package/src/util.ts +32 -17
  330. package/src/versioning.ts +3 -33
  331. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  332. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  333. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
  334. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  335. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  336. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  337. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  338. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  339. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  340. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  341. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  342. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  343. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  344. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  345. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  346. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  347. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  348. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  349. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  350. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  351. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  352. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  353. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  354. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  355. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  356. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  357. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  358. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  359. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  360. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  361. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  362. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  363. package/dest/mem_pools/tx_pool/index.js +0 -2
  364. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  365. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  366. package/dest/mem_pools/tx_pool/priority.js +0 -15
  367. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  368. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  369. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  370. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  371. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  372. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  373. package/dest/msg_validators/clock_tolerance.d.ts +0 -21
  374. package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
  375. package/dest/msg_validators/clock_tolerance.js +0 -38
  376. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  377. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  378. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  379. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  380. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  381. package/dest/services/reqresp/protocols/block.js +0 -32
  382. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -51
  383. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  384. package/dest/services/tx_collection/fast_tx_collection.js +0 -311
  385. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
  386. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  387. package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
  388. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
  389. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  390. package/dest/services/tx_collection/slow_tx_collection.js +0 -211
  391. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -344
  392. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  393. package/src/mem_pools/tx_pool/README.md +0 -270
  394. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  395. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  396. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  397. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  398. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  399. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  400. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  401. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  402. package/src/mem_pools/tx_pool/index.ts +0 -2
  403. package/src/mem_pools/tx_pool/priority.ts +0 -20
  404. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  405. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  406. package/src/msg_validators/clock_tolerance.ts +0 -52
  407. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  408. package/src/services/reqresp/protocols/block.ts +0 -37
  409. package/src/services/tx_collection/fast_tx_collection.ts +0 -361
  410. package/src/services/tx_collection/proposal_tx_collector.ts +0 -108
  411. 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,6 +41,13 @@ 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
  */
@@ -56,7 +65,10 @@ export interface TxPoolV2Callbacks {
56
65
  export class TxPoolV2Impl {
57
66
  // === Persistence ===
58
67
  #store: AztecAsyncKVStore;
68
+ /** Tx data without its proof. Proofs live in #proofsDB so a tx can be read without loading its proof. */
59
69
  #txsDB: AztecAsyncMap<string, Buffer>;
70
+ /** Tx proofs, keyed by tx hash. Written and deleted in lockstep with #txsDB. */
71
+ #proofsDB: AztecAsyncMap<string, Buffer>;
60
72
 
61
73
  // === Dependencies ===
62
74
  #l2BlockSource: L2BlockSource;
@@ -74,7 +86,7 @@ export class TxPoolV2Impl {
74
86
  #evictionManager: EvictionManager;
75
87
  #dateProvider: DateProvider;
76
88
  #instrumentation: TxPoolV2Instrumentation;
77
- #evictedTxHashes: Set<string> = new Set();
89
+ #evictedTxHashes: FifoSet<string>;
78
90
  #log: Logger;
79
91
  #callbacks: TxPoolV2Callbacks;
80
92
 
@@ -90,6 +102,7 @@ export class TxPoolV2Impl {
90
102
  ) {
91
103
  this.#store = store;
92
104
  this.#txsDB = store.openMap('txs');
105
+ this.#proofsDB = store.openMap('tx_proofs');
93
106
 
94
107
  this.#l2BlockSource = deps.l2BlockSource;
95
108
  this.#worldStateSynchronizer = deps.worldStateSynchronizer;
@@ -97,8 +110,9 @@ export class TxPoolV2Impl {
97
110
  this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
98
111
 
99
112
  this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
113
+ this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
100
114
  this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
101
- this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
115
+ this.#deletedPool = new DeletedPool(store, txHashStr => this.#deleteTxData(txHashStr), log);
102
116
  this.#dateProvider = dateProvider;
103
117
  this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
104
118
  this.#log = log;
@@ -116,6 +130,7 @@ export class TxPoolV2Impl {
116
130
 
117
131
  // Post-event eviction rules (run after events to check ALL pending txs)
118
132
  this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
133
+ this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
119
134
  this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
120
135
  this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
121
136
  // LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
@@ -138,46 +153,74 @@ export class TxPoolV2Impl {
138
153
  // Step 0: Hydrate deleted pool state
139
154
  await this.#deletedPool.hydrateFromDatabase();
140
155
 
141
- // Step 1: Load all transactions from DB (excluding soft-deleted)
142
- const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
156
+ // Step 1: Stream txs from DB, building metadata and mined status one at a time.
157
+ const minedMetas: TxMetaData[] = [];
158
+ const pendingMetas: TxMetaData[] = [];
159
+ const deserializationErrors: string[] = [];
143
160
 
144
- // Step 2: Check mined status for each tx
145
- await this.#markMinedStatusBatch(loaded.map(l => l.meta));
161
+ for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
162
+ // Skip soft-deleted transactions - they stay in DB but not in indices
163
+ if (this.#deletedPool.isSoftDeleted(txHashStr)) {
164
+ continue;
165
+ }
146
166
 
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);
167
+ let meta: TxMetaData;
168
+ let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
169
+ try {
170
+ const tx = Tx.fromBuffer(buffer);
171
+ // Resolve allowed-setup-calls and the tx effect concurrently
172
+ // getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
173
+ // its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
174
+ const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
175
+ this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
176
+ return undefined;
177
+ });
178
+ const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
179
+ this.#checkAllowedSetupCalls(tx),
180
+ txEffectPromise,
181
+ ]);
182
+ meta = await buildTxMetaData(tx, allowedSetupCalls);
183
+ txEffect = fetchedTxEffect;
184
+ } catch (err) {
185
+ this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
186
+ deserializationErrors.push(txHashStr);
187
+ continue;
188
+ }
189
+
190
+ if (txEffect) {
191
+ meta.minedL2BlockId = {
192
+ number: txEffect.l2BlockNumber,
193
+ hash: txEffect.l2BlockHash.toString(),
194
+ };
195
+ }
196
+
197
+ if (meta.minedL2BlockId !== undefined) {
198
+ minedMetas.push(meta);
153
199
  } else {
154
- nonMined.push(entry);
200
+ pendingMetas.push(meta);
155
201
  }
156
202
  }
157
203
 
158
- // Step 4: Validate non-mined transactions
159
- const { valid, invalid } = await this.#revalidateMetadata(
160
- nonMined.map(e => e.meta),
161
- 'on startup',
162
- );
204
+ // Step 2: Validate non-mined transactions
205
+ const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
163
206
 
164
- // Step 5: Populate mined indices (these don't need conflict resolution)
165
- for (const meta of mined) {
207
+ // Step 3: Populate mined indices (these don't need conflict resolution)
208
+ for (const meta of minedMetas) {
166
209
  this.#indices.addMined(meta);
167
210
  }
168
211
 
169
- // Step 6: Rebuild pending pool by running pre-add rules for each tx
212
+ // Step 4: Rebuild pending pool by running pre-add rules for each tx
170
213
  // This resolves nullifier conflicts, fee payer balance issues, and pool size limits
171
214
  const { rejected } = await this.#rebuildPendingPool(valid);
172
215
 
173
- // Step 7: Delete invalid and rejected txs from DB only (indices were never populated for these)
216
+ // Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
174
217
  const toDelete = [...deserializationErrors, ...invalid, ...rejected];
175
218
  if (toDelete.length === 0) {
176
219
  return;
177
220
  }
178
221
  await this.#store.transactionAsync(async () => {
179
222
  for (const txHashStr of toDelete) {
180
- await this.#txsDB.delete(txHashStr);
223
+ await this.#deleteTxData(txHashStr);
181
224
  }
182
225
  });
183
226
  this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
@@ -423,10 +466,11 @@ export class TxPoolV2Impl {
423
466
  // Update protection for existing tx
424
467
  this.#indices.updateProtection(txHashStr, slotNumber);
425
468
  } else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
426
- // Resurrect soft-deleted tx as protected
469
+ // Resurrect soft-deleted tx as protected. Load the proof too: #addTx rewrites both entries, so re-adding
470
+ // a proofless tx would wipe the stored proof.
427
471
  const buffer = await this.#txsDB.getAsync(txHashStr);
428
472
  if (buffer) {
429
- const tx = Tx.fromBuffer(buffer);
473
+ const tx = await this.#loadTxWithProof(txHashStr, buffer);
430
474
  await this.#addTx(tx, { protected: slotNumber });
431
475
  softDeletedHits++;
432
476
  } else {
@@ -541,29 +585,62 @@ export class TxPoolV2Impl {
541
585
  }
542
586
 
543
587
  this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
588
+ await this.#restoreUnprotectedToPending(txsToRestore, 'during prepareForSlot');
589
+ });
590
+ }
544
591
 
545
- // Step 4: Validate for pending pool
546
- const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
592
+ async unprotectTxs(txHashes: TxHash[], slotNumber: SlotNumber): Promise<void> {
593
+ const hashStrs = txHashes.map(h => h.toString());
547
594
 
548
- // Step 5: Resolve nullifier conflicts and add winners to pending indices
549
- const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
595
+ await this.#store.transactionAsync(async () => {
596
+ // Only release entries still recorded at this exact slot. A tx that another, still-live proposal
597
+ // raised to a higher slot via updateProtection must keep that protection. Mined txs have no
598
+ // protection entry and so are never matched here.
599
+ const matching = this.#indices.findProtectedTxsAtSlot(hashStrs, slotNumber);
600
+ if (matching.length === 0) {
601
+ this.#log.debug(`Unprotecting txs for slot ${slotNumber}: no matching protections to release`);
602
+ return;
603
+ }
550
604
 
551
- // Step 6: Delete invalid txs and evict conflict losers
552
- await this.#deleteTxsBatch(invalid);
553
- await this.#evictTxs(toEvict, 'NullifierConflict');
605
+ this.#indices.clearProtection(matching);
554
606
 
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
- );
607
+ const txsToRestore = this.#indices.filterRestorable(matching);
608
+ if (txsToRestore.length === 0) {
609
+ return;
563
610
  }
611
+
612
+ this.#log.info(`Unprotecting ${txsToRestore.length} txs from failed proposal at slot ${slotNumber}`);
613
+ await this.#restoreUnprotectedToPending(txsToRestore, 'during unprotectTxs');
564
614
  });
565
615
  }
566
616
 
617
+ /**
618
+ * Returns just-unprotected txs to the pending pool: revalidates them, resolves nullifier
619
+ * conflicts, deletes losers, then enforces the pool size limit. Must run inside a store
620
+ * transaction; callers clear the protection entries before invoking.
621
+ */
622
+ async #restoreUnprotectedToPending(txsToRestore: TxMetaData[], context: string): Promise<void> {
623
+ // Step 1: Validate for pending pool
624
+ const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, context);
625
+
626
+ // Step 2: Resolve nullifier conflicts and add winners to pending indices
627
+ const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
628
+
629
+ // Step 3: Delete invalid txs and evict conflict losers
630
+ await this.#deleteTxsBatch(invalid);
631
+ await this.#evictTxs(toEvict, 'NullifierConflict');
632
+
633
+ // Step 4: Run eviction rules (enforce pool size limit)
634
+ if (added.length > 0) {
635
+ const feePayers = added.map(meta => meta.feePayer);
636
+ const uniqueFeePayers = new Set<string>(feePayers);
637
+ await this.#evictionManager.evictAfterNewTxs(
638
+ added.map(m => m.txHash),
639
+ [...uniqueFeePayers],
640
+ );
641
+ }
642
+ }
643
+
567
644
  async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
568
645
  // Step 1: Find transactions mined after the prune point
569
646
  const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
@@ -638,28 +715,29 @@ export class TxPoolV2Impl {
638
715
  // Step 1: Find mined txs at or before finalized block
639
716
  const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
640
717
 
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) {
718
+ // Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
719
+ // mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
720
+ if (this.#archive.isEnabled()) {
721
+ for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
722
+ const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
723
+ const txsToArchive: Tx[] = [];
724
+ for (const txHashStr of chunk) {
646
725
  const buffer = await this.#txsDB.getAsync(txHashStr);
647
726
  if (buffer) {
648
727
  txsToArchive.push(Tx.fromBuffer(buffer));
649
728
  }
650
729
  }
730
+ if (txsToArchive.length > 0) {
731
+ await this.#archive.archiveTxs(txsToArchive);
732
+ }
651
733
  }
734
+ }
652
735
 
653
- // Step 3: Delete mined txs from active pool
736
+ // Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
737
+ // transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
738
+ await this.#store.transactionAsync(async () => {
654
739
  await this.#deleteTxsBatch(minedTxsToFinalize);
655
-
656
- // Step 4: Finalize soft-deleted txs
657
740
  await this.#deletedPool.finalizeBlock(blockNumber);
658
-
659
- // Step 5: Archive mined txs
660
- if (txsToArchive.length > 0) {
661
- await this.#archive.archiveTxs(txsToArchive);
662
- }
663
741
  });
664
742
 
665
743
  if (minedTxsToFinalize.length > 0) {
@@ -671,20 +749,36 @@ export class TxPoolV2Impl {
671
749
 
672
750
  // === Query Methods ===
673
751
 
674
- async getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
675
- const buffer = await this.#txsDB.getAsync(txHash.toString());
676
- return buffer ? Tx.fromBuffer(buffer) : undefined;
752
+ async getTxByHash(txHash: TxHash, opts: { includeProof?: boolean } = {}): Promise<Tx | undefined> {
753
+ const txHashStr = txHash.toString();
754
+ const buffer = await this.#txsDB.getAsync(txHashStr);
755
+ if (!buffer) {
756
+ return undefined;
757
+ }
758
+ return opts.includeProof === false ? Tx.fromBuffer(buffer) : this.#loadTxWithProof(txHashStr, buffer);
677
759
  }
678
760
 
679
- async getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
761
+ async getTxsByHash(txHashes: TxHash[], opts: { includeProof?: boolean } = {}): Promise<(Tx | undefined)[]> {
680
762
  const results: (Tx | undefined)[] = [];
681
763
  for (const h of txHashes) {
682
- const buffer = await this.#txsDB.getAsync(h.toString());
683
- results.push(buffer ? Tx.fromBuffer(buffer) : undefined);
764
+ results.push(await this.getTxByHash(h, opts));
684
765
  }
685
766
  return results;
686
767
  }
687
768
 
769
+ /** Deserializes a tx blob loaded from #txsDB together with its separately-stored proof. */
770
+ async #loadTxWithProof(txHashStr: string, buffer: Buffer): Promise<Tx> {
771
+ const proofBuffer = await this.#proofsDB.getAsync(txHashStr);
772
+ if (!proofBuffer) {
773
+ // #addTx always writes a proof entry (an empty proof serializes to a 4-byte sentinel), so a missing entry
774
+ // means the blob/proof invariant is broken. Return the proofless tx but flag it, since a consumer that needs
775
+ // the proof (eg serving peers) would otherwise fail far away from the root cause.
776
+ this.#log.warn(`Missing stored proof for tx ${txHashStr}`, { txHash: txHashStr });
777
+ return Tx.fromBuffer(buffer);
778
+ }
779
+ return Tx.fromBuffers(buffer, proofBuffer);
780
+ }
781
+
688
782
  hasTxs(txHashes: TxHash[]): boolean[] {
689
783
  return txHashes.map(h => {
690
784
  const hashStr = h.toString();
@@ -811,7 +905,8 @@ export class TxPoolV2Impl {
811
905
  const meta = precomputedMeta ?? (await buildTxMetaData(tx));
812
906
  meta.receivedAt = this.#dateProvider.now();
813
907
 
814
- await this.#txsDB.set(txHashStr, tx.toBuffer());
908
+ await this.#txsDB.set(txHashStr, tx.withoutProof().toBuffer());
909
+ await this.#proofsDB.set(txHashStr, tx.chonkProof.toBuffer());
815
910
  await this.#deletedPool.clearSoftDeleted(txHashStr);
816
911
  this.#callbacks.onTxsAdded([tx], opts);
817
912
 
@@ -850,6 +945,12 @@ export class TxPoolV2Impl {
850
945
  await this.#deletedPool.deleteTx(txHashStr);
851
946
  }
852
947
 
948
+ /** Hard-deletes a tx's stored data (tx blob and proof) from the DB. */
949
+ async #deleteTxData(txHashStr: string): Promise<void> {
950
+ await this.#txsDB.delete(txHashStr);
951
+ await this.#proofsDB.delete(txHashStr);
952
+ }
953
+
853
954
  /** Deletes a batch of transactions, emitting callbacks individually for each. */
854
955
  async #deleteTxsBatch(txHashes: string[]): Promise<void> {
855
956
  for (const txHashStr of txHashes) {
@@ -865,21 +966,11 @@ export class TxPoolV2Impl {
865
966
  this.#instrumentation.recordEvictions(txHashes.length, reason);
866
967
  for (const txHashStr of txHashes) {
867
968
  this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
868
- this.#addToEvictedCache(txHashStr);
969
+ this.#evictedTxHashes.add(txHashStr);
869
970
  }
870
971
  await this.#deleteTxsBatch(txHashes);
871
972
  }
872
973
 
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
974
  // ============================================================================
884
975
  // PRIVATE HELPERS - Validation & Conflict Resolution
885
976
  // ============================================================================
@@ -974,51 +1065,6 @@ export class TxPoolV2Impl {
974
1065
  };
975
1066
  }
976
1067
 
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
1068
  /**
1023
1069
  * Rebuilds the pending pool by processing each tx through pre-add rules.
1024
1070
  * Starts with an empty pending pool and adds txs one by one, resolving conflicts.
@@ -1093,7 +1139,7 @@ export class TxPoolV2Impl {
1093
1139
  const publicStateSource = new DatabasePublicStateSource(db);
1094
1140
  const balance = await publicStateSource.storageRead(
1095
1141
  ProtocolContractAddress.FeeJuice,
1096
- await computeFeePayerBalanceStorageSlot(AztecAddress.fromString(feePayer)),
1142
+ await computeFeePayerBalanceStorageSlot(AztecAddress.fromStringUnsafe(feePayer)),
1097
1143
  );
1098
1144
  return balance.toBigInt();
1099
1145
  },
@@ -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
@@ -1,5 +1,11 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
- import { type CheckpointAttestation, PeerErrorSeverity, type ValidationResult } from '@aztec/stdlib/p2p';
2
+ import {
3
+ type CheckpointAttestation,
4
+ type CoordinationSignatureContext,
5
+ PeerErrorSeverity,
6
+ type ValidationResult,
7
+ } from '@aztec/stdlib/p2p';
8
+ import type { ConsensusTimetable } from '@aztec/stdlib/timetable';
3
9
  import { Attributes, Metrics, type TelemetryClient, createUpDownCounterWithDefault } from '@aztec/telemetry-client';
4
10
 
5
11
  import type { AttestationPoolApi } from '../../mem_pools/attestation_pool/attestation_pool.js';
@@ -18,10 +24,15 @@ export class FishermanAttestationValidator extends CheckpointAttestationValidato
18
24
 
19
25
  constructor(
20
26
  epochCache: EpochCacheInterface,
27
+ timetable: ConsensusTimetable,
21
28
  private attestationPool: AttestationPoolApi,
22
29
  telemetryClient: TelemetryClient,
30
+ opts: {
31
+ signatureContext: CoordinationSignatureContext;
32
+ clockDisparityMs: number;
33
+ },
23
34
  ) {
24
- super(epochCache);
35
+ super(epochCache, timetable, opts);
25
36
  this.logger = this.logger.createChild('[FISHERMAN]');
26
37
 
27
38
  const meter = telemetryClient.getMeter('FishermanAttestationValidator');
@@ -54,8 +65,7 @@ export class FishermanAttestationValidator extends CheckpointAttestationValidato
54
65
  return { result: 'accept' };
55
66
  }
56
67
 
57
- const proposalId = message.archive.toString();
58
- const proposal = await this.attestationPool.getCheckpointProposal(proposalId);
68
+ const proposal = await this.attestationPool.getCheckpointProposal(message.payload.header.slotNumber);
59
69
 
60
70
  if (proposal) {
61
71
  // Compare the attestation payload with the proposal payload
@@ -84,9 +94,7 @@ export class FishermanAttestationValidator extends CheckpointAttestationValidato
84
94
  }
85
95
  } else {
86
96
  // We might receive attestations before proposals in some cases
87
- this.logger.debug(
88
- `Received attestation for slot ${slotNumberBigInt} but proposal not found yet. ` + `Proposal ID: ${proposalId}`,
89
- );
97
+ this.logger.debug(`Received attestation for slot ${slotNumberBigInt} but proposal not found yet.`);
90
98
  }
91
99
 
92
100
  return { result: 'accept' };
@@ -53,7 +53,7 @@ Only runs on validator nodes. Non-validator nodes use a default handler that tri
53
53
 
54
54
  **Escape hatch**: during escape hatch periods (`isEscapeHatchOpenAtSlot`), re-execution and slashing are both disabled, and the proposal is rejected locally.
55
55
 
56
- **Conditional re-execution**: rules 22-24 only run when at least one condition is true: `fishermanMode` enabled, `slashBroadcastedInvalidBlockPenalty > 0` with `validatorReexecute`, committee membership with `validatorReexecute`, `alwaysReexecuteBlockProposals`, or `blobClient.canUpload()`.
56
+ **Conditional re-execution**: rules 22-24 only run when at least one condition is true: `fishermanMode` enabled, `slashBroadcastedInvalidBlockPenalty > 0`, committee membership, `alwaysReexecuteBlockProposals`, or `blobClient.canUpload()`.
57
57
 
58
58
  **Slashing**: only `state_mismatch` and `failed_txs` trigger on-chain slashing (`OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL`, gated by `slashBroadcastedInvalidBlockPenalty > 0`). Unknown errors during re-execution do NOT slash.
59
59
 
@@ -1,13 +1,25 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
- import type { BlockProposal, P2PValidator, ValidationResult } from '@aztec/stdlib/p2p';
2
+ import type { BlockProposal, CoordinationSignatureContext, P2PValidator, ValidationResult } from '@aztec/stdlib/p2p';
3
+ import type { ConsensusTimetable } from '@aztec/stdlib/timetable';
3
4
 
4
5
  import { ProposalValidator } from '../proposal_validator/proposal_validator.js';
5
6
 
6
7
  export class BlockProposalValidator implements P2PValidator<BlockProposal> {
7
8
  private proposalValidator: ProposalValidator;
8
9
 
9
- constructor(epochCache: EpochCacheInterface, opts: { txsPermitted: boolean; maxTxsPerBlock?: number }) {
10
- this.proposalValidator = new ProposalValidator(epochCache, opts, 'p2p:block_proposal_validator');
10
+ constructor(
11
+ epochCache: EpochCacheInterface,
12
+ timetable: ConsensusTimetable,
13
+ opts: {
14
+ txsPermitted: boolean;
15
+ maxTxsPerBlock?: number;
16
+ maxBlocksPerCheckpoint?: number;
17
+ skipSlotValidation?: boolean;
18
+ signatureContext: CoordinationSignatureContext;
19
+ clockDisparityMs: number;
20
+ },
21
+ ) {
22
+ this.proposalValidator = new ProposalValidator(epochCache, timetable, opts, 'p2p:block_proposal_validator');
11
23
  }
12
24
 
13
25
  async validate(proposal: BlockProposal): Promise<ValidationResult> {