@aztec/p2p 0.0.1-commit.2448fdb → 0.0.1-commit.2606882

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 (402) hide show
  1. package/dest/bootstrap/bootstrap.d.ts +1 -1
  2. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  3. package/dest/bootstrap/bootstrap.js +9 -1
  4. package/dest/client/factory.d.ts +5 -4
  5. package/dest/client/factory.d.ts.map +1 -1
  6. package/dest/client/factory.js +26 -21
  7. package/dest/client/interface.d.ts +14 -5
  8. package/dest/client/interface.d.ts.map +1 -1
  9. package/dest/client/p2p_client.d.ts +13 -9
  10. package/dest/client/p2p_client.d.ts.map +1 -1
  11. package/dest/client/p2p_client.js +78 -20
  12. package/dest/config.d.ts +135 -105
  13. package/dest/config.d.ts.map +1 -1
  14. package/dest/config.js +59 -14
  15. package/dest/errors/p2p-service.error.d.ts +9 -0
  16. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  17. package/dest/errors/p2p-service.error.js +10 -0
  18. package/dest/errors/reqresp.error.d.ts +1 -20
  19. package/dest/errors/reqresp.error.d.ts.map +1 -1
  20. package/dest/errors/reqresp.error.js +0 -21
  21. package/dest/index.d.ts +1 -2
  22. package/dest/index.d.ts.map +1 -1
  23. package/dest/index.js +0 -1
  24. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +99 -59
  25. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  26. package/dest/mem_pools/attestation_pool/attestation_pool.js +267 -197
  27. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +181 -65
  30. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  31. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  32. package/dest/mem_pools/attestation_pool/mocks.js +6 -4
  33. package/dest/mem_pools/index.d.ts +1 -2
  34. package/dest/mem_pools/index.d.ts.map +1 -1
  35. package/dest/mem_pools/instrumentation.d.ts +4 -2
  36. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  37. package/dest/mem_pools/instrumentation.js +33 -15
  38. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -5
  39. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
  41. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  42. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  44. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  45. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  46. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  47. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  48. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +10 -5
  49. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  50. package/dest/mem_pools/tx_pool_v2/interfaces.js +1 -0
  51. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +9 -7
  52. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
  54. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  55. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  56. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -43
  57. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +1 -1
  58. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  59. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +3 -0
  60. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -1
  61. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  62. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +93 -85
  63. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
  64. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  65. package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
  66. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  67. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  68. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  69. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  70. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  71. package/dest/msg_validators/clock_tolerance.js +56 -3
  72. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -2
  73. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  74. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -2
  75. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  76. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +10 -2
  77. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  78. package/dest/msg_validators/proposal_validator/proposal_validator.js +46 -12
  79. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  80. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  81. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +8 -15
  82. package/dest/msg_validators/tx_validator/allowed_public_setup.js +3 -3
  83. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  84. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  85. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  86. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  87. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  88. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  89. package/dest/msg_validators/tx_validator/data_validator.js +1 -0
  90. package/dest/msg_validators/tx_validator/factory.d.ts +6 -5
  91. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  92. package/dest/msg_validators/tx_validator/factory.js +14 -10
  93. package/dest/msg_validators/tx_validator/gas_validator.d.ts +36 -4
  94. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/gas_validator.js +50 -33
  96. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  97. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/index.js +2 -0
  99. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  100. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  102. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  103. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  105. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  106. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  107. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  108. package/dest/services/data_store.d.ts +1 -1
  109. package/dest/services/data_store.d.ts.map +1 -1
  110. package/dest/services/data_store.js +5 -5
  111. package/dest/services/discv5/discV5_service.d.ts +2 -1
  112. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  113. package/dest/services/discv5/discV5_service.js +35 -8
  114. package/dest/services/dummy_service.d.ts +11 -15
  115. package/dest/services/dummy_service.d.ts.map +1 -1
  116. package/dest/services/dummy_service.js +12 -16
  117. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  118. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  119. package/dest/services/gossipsub/topic_score_params.js +21 -4
  120. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  121. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  122. package/dest/services/libp2p/instrumentation.js +14 -0
  123. package/dest/services/libp2p/libp2p_service.d.ts +36 -46
  124. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  125. package/dest/services/libp2p/libp2p_service.js +289 -265
  126. package/dest/services/peer-manager/metrics.d.ts +3 -1
  127. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  128. package/dest/services/peer-manager/metrics.js +6 -0
  129. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  130. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  131. package/dest/services/peer-manager/peer_manager.js +40 -11
  132. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  133. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  134. package/dest/services/peer-manager/peer_scoring.js +32 -10
  135. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -8
  136. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  137. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +94 -122
  138. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +10 -6
  139. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  140. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  141. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  142. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  143. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  144. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  145. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  146. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  147. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  148. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  149. package/dest/services/reqresp/config.d.ts +3 -3
  150. package/dest/services/reqresp/config.d.ts.map +1 -1
  151. package/dest/services/reqresp/interface.d.ts +16 -18
  152. package/dest/services/reqresp/interface.d.ts.map +1 -1
  153. package/dest/services/reqresp/interface.js +10 -20
  154. package/dest/services/reqresp/metrics.d.ts +1 -1
  155. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  156. package/dest/services/reqresp/metrics.js +0 -1
  157. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  158. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  159. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  160. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  161. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  162. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
  163. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
  164. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  165. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
  166. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  167. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  168. package/dest/services/reqresp/protocols/index.js +0 -1
  169. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  170. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  171. package/dest/services/reqresp/protocols/tx.js +1 -3
  172. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  173. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  174. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  175. package/dest/services/reqresp/reqresp.d.ts +7 -29
  176. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  177. package/dest/services/reqresp/reqresp.js +27 -207
  178. package/dest/services/service.d.ts +9 -12
  179. package/dest/services/service.d.ts.map +1 -1
  180. package/dest/services/tx_collection/config.d.ts +2 -23
  181. package/dest/services/tx_collection/config.d.ts.map +1 -1
  182. package/dest/services/tx_collection/config.js +2 -55
  183. package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
  184. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  185. package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
  186. package/dest/services/tx_collection/index.d.ts +2 -3
  187. package/dest/services/tx_collection/index.d.ts.map +1 -1
  188. package/dest/services/tx_collection/index.js +0 -1
  189. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  190. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  191. package/dest/services/tx_collection/instrumentation.js +0 -2
  192. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  193. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  194. package/dest/services/tx_collection/request_tracker.js +84 -0
  195. package/dest/services/tx_collection/tx_collection.d.ts +36 -55
  196. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  197. package/dest/services/tx_collection/tx_collection.js +275 -119
  198. package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
  199. package/dest/services/tx_collection/tx_collection_sink.js +2 -2
  200. package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
  201. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  202. package/dest/services/tx_file_store/tx_file_store.js +4 -14
  203. package/dest/services/tx_provider.d.ts +3 -1
  204. package/dest/services/tx_provider.d.ts.map +1 -1
  205. package/dest/services/tx_provider.js +3 -0
  206. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  207. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  208. package/dest/test-helpers/make-test-p2p-clients.js +5 -2
  209. package/dest/test-helpers/mock-pubsub.d.ts +23 -9
  210. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  211. package/dest/test-helpers/mock-pubsub.js +44 -44
  212. package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
  213. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  214. package/dest/test-helpers/reqresp-nodes.js +16 -18
  215. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  216. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  217. package/dest/test-helpers/test_tx_provider.js +3 -0
  218. package/dest/test-helpers/testbench-utils.d.ts +12 -14
  219. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  220. package/dest/test-helpers/testbench-utils.js +38 -14
  221. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  222. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  223. package/dest/testbench/p2p_client_testbench_worker.js +83 -38
  224. package/dest/testbench/worker_client_manager.d.ts +10 -6
  225. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  226. package/dest/testbench/worker_client_manager.js +53 -10
  227. package/dest/util.d.ts +12 -7
  228. package/dest/util.d.ts.map +1 -1
  229. package/dest/util.js +35 -14
  230. package/dest/versioning.d.ts +3 -6
  231. package/dest/versioning.d.ts.map +1 -1
  232. package/dest/versioning.js +3 -24
  233. package/package.json +15 -14
  234. package/src/bootstrap/bootstrap.ts +9 -1
  235. package/src/client/factory.ts +45 -24
  236. package/src/client/interface.ts +15 -11
  237. package/src/client/p2p_client.ts +91 -41
  238. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  239. package/src/config.ts +117 -17
  240. package/src/errors/p2p-service.error.ts +11 -0
  241. package/src/errors/reqresp.error.ts +0 -25
  242. package/src/index.ts +0 -1
  243. package/src/mem_pools/attestation_pool/attestation_pool.ts +318 -242
  244. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +204 -68
  245. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  246. package/src/mem_pools/index.ts +0 -3
  247. package/src/mem_pools/instrumentation.ts +22 -14
  248. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
  249. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  250. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  251. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  252. package/src/mem_pools/tx_pool_v2/interfaces.ts +10 -4
  253. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +24 -12
  254. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
  255. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +3 -0
  256. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +94 -91
  257. package/src/msg_validators/attestation_validator/README.md +1 -1
  258. package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
  259. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +14 -7
  260. package/src/msg_validators/clock_tolerance.ts +73 -3
  261. package/src/msg_validators/proposal_validator/README.md +4 -4
  262. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +12 -2
  263. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +17 -2
  264. package/src/msg_validators/proposal_validator/proposal_validator.ts +54 -10
  265. package/src/msg_validators/tx_validator/README.md +11 -3
  266. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
  267. package/src/msg_validators/tx_validator/allowed_public_setup.ts +3 -3
  268. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  269. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  270. package/src/msg_validators/tx_validator/data_validator.ts +2 -0
  271. package/src/msg_validators/tx_validator/factory.ts +18 -7
  272. package/src/msg_validators/tx_validator/gas_validator.ts +82 -33
  273. package/src/msg_validators/tx_validator/index.ts +2 -0
  274. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  275. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  276. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  277. package/src/services/data_store.ts +5 -13
  278. package/src/services/discv5/discV5_service.ts +38 -5
  279. package/src/services/dummy_service.ts +14 -39
  280. package/src/services/gossipsub/topic_score_params.ts +36 -4
  281. package/src/services/libp2p/instrumentation.ts +14 -0
  282. package/src/services/libp2p/libp2p_service.ts +315 -302
  283. package/src/services/peer-manager/metrics.ts +7 -0
  284. package/src/services/peer-manager/peer_manager.ts +46 -11
  285. package/src/services/peer-manager/peer_scoring.ts +27 -5
  286. package/src/services/reqresp/README.md +0 -14
  287. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  288. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +91 -137
  289. package/src/services/reqresp/batch-tx-requester/interface.ts +13 -5
  290. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  291. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  292. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  293. package/src/services/reqresp/config.ts +2 -2
  294. package/src/services/reqresp/interface.ts +21 -47
  295. package/src/services/reqresp/metrics.ts +0 -1
  296. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  297. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -30
  298. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
  299. package/src/services/reqresp/protocols/index.ts +0 -1
  300. package/src/services/reqresp/protocols/tx.ts +1 -3
  301. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  302. package/src/services/reqresp/reqresp.ts +31 -252
  303. package/src/services/service.ts +12 -28
  304. package/src/services/tx_collection/config.ts +3 -80
  305. package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
  306. package/src/services/tx_collection/index.ts +1 -6
  307. package/src/services/tx_collection/instrumentation.ts +1 -7
  308. package/src/services/tx_collection/request_tracker.ts +127 -0
  309. package/src/services/tx_collection/tx_collection.ts +331 -176
  310. package/src/services/tx_collection/tx_collection_sink.ts +2 -2
  311. package/src/services/tx_file_store/tx_file_store.ts +5 -17
  312. package/src/services/tx_provider.ts +5 -0
  313. package/src/test-helpers/make-test-p2p-clients.ts +4 -1
  314. package/src/test-helpers/mock-pubsub.ts +46 -60
  315. package/src/test-helpers/reqresp-nodes.ts +13 -23
  316. package/src/test-helpers/test_tx_provider.ts +5 -0
  317. package/src/test-helpers/testbench-utils.ts +50 -28
  318. package/src/testbench/p2p_client_testbench_worker.ts +88 -55
  319. package/src/testbench/worker_client_manager.ts +61 -21
  320. package/src/util.ts +33 -18
  321. package/src/versioning.ts +3 -33
  322. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  323. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  324. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -304
  325. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  326. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  327. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  328. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  329. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  330. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  331. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  332. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  333. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  334. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  335. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  336. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  337. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  338. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  339. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  340. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  341. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  342. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  343. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  344. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  345. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  346. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  347. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  348. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  349. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  350. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  351. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  352. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  353. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  354. package/dest/mem_pools/tx_pool/index.js +0 -2
  355. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  356. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  357. package/dest/mem_pools/tx_pool/priority.js +0 -15
  358. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  359. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  360. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  361. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  362. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  363. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  364. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  365. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  366. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  367. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  368. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  369. package/dest/services/reqresp/protocols/block.js +0 -32
  370. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -54
  371. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  372. package/dest/services/tx_collection/fast_tx_collection.js +0 -327
  373. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  374. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  375. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  376. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -49
  377. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  378. package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
  379. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
  380. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  381. package/dest/services/tx_collection/slow_tx_collection.js +0 -211
  382. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -345
  383. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  384. package/src/mem_pools/tx_pool/README.md +0 -270
  385. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  386. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  387. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  388. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  389. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  390. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  391. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  392. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  393. package/src/mem_pools/tx_pool/index.ts +0 -2
  394. package/src/mem_pools/tx_pool/priority.ts +0 -20
  395. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  396. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  397. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  398. package/src/services/reqresp/protocols/block.ts +0 -37
  399. package/src/services/tx_collection/fast_tx_collection.ts +0 -387
  400. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
  401. package/src/services/tx_collection/proposal_tx_collector.ts +0 -113
  402. package/src/services/tx_collection/slow_tx_collection.ts +0 -266
@@ -4,11 +4,13 @@ import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import {
5
5
  type BlockProposal,
6
6
  type CheckpointProposalCore,
7
+ type CoordinationSignatureContext,
7
8
  PeerErrorSeverity,
8
9
  type ValidationResult,
10
+ hasValidSignatureContext,
9
11
  } from '@aztec/stdlib/p2p';
10
12
 
11
- import { isWithinClockTolerance } from '../clock_tolerance.js';
13
+ import { PipeliningWindow, isWithinClockTolerance } from '../clock_tolerance.js';
12
14
 
13
15
  /** Validates header-level and tx-level fields of block and checkpoint proposals. */
14
16
  export class ProposalValidator {
@@ -16,32 +18,63 @@ export class ProposalValidator {
16
18
  private logger: Logger;
17
19
  private txsPermitted: boolean;
18
20
  private maxTxsPerBlock?: number;
21
+ private maxBlocksPerCheckpoint?: number;
22
+ private pipeliningWindow: PipeliningWindow;
23
+ private skipSlotValidation: boolean;
24
+ private signatureContext: CoordinationSignatureContext;
19
25
 
20
26
  constructor(
21
27
  epochCache: EpochCacheInterface,
22
- opts: { txsPermitted: boolean; maxTxsPerBlock?: number },
28
+ opts: {
29
+ txsPermitted: boolean;
30
+ maxTxsPerBlock?: number;
31
+ maxBlocksPerCheckpoint?: number;
32
+ p2pPropagationTime?: number;
33
+ skipSlotValidation?: boolean;
34
+ signatureContext: CoordinationSignatureContext;
35
+ },
23
36
  loggerName: string,
24
37
  ) {
25
38
  this.epochCache = epochCache;
26
39
  this.txsPermitted = opts.txsPermitted;
27
40
  this.maxTxsPerBlock = opts.maxTxsPerBlock;
41
+ this.maxBlocksPerCheckpoint = opts.maxBlocksPerCheckpoint;
42
+ this.pipeliningWindow = new PipeliningWindow(epochCache, { p2pPropagationTime: opts.p2pPropagationTime });
43
+ this.skipSlotValidation = opts.skipSlotValidation ?? false;
44
+ this.signatureContext = opts.signatureContext;
28
45
  this.logger = createLogger(loggerName);
29
46
  }
30
47
 
31
48
  /** Validates header-level fields: slot, signature, and proposer. */
32
49
  public async validate(proposal: BlockProposal | CheckpointProposalCore): Promise<ValidationResult> {
33
50
  try {
34
- // Slot check
35
- const { currentSlot, nextSlot } = this.epochCache.getCurrentAndNextSlot();
51
+ // Cross-chain replay check: reject proposals that carry a foreign signing domain.
52
+ if (!hasValidSignatureContext(proposal, this.signatureContext)) {
53
+ this.logger.warn(`Penalizing peer for proposal with foreign signature context`, {
54
+ chainId: proposal.signatureContext.chainId,
55
+ rollupAddress: proposal.signatureContext.rollupAddress.toString(),
56
+ expectedChainId: this.signatureContext.chainId,
57
+ expectedRollupAddress: this.signatureContext.rollupAddress.toString(),
58
+ });
59
+ return { result: 'reject', severity: PeerErrorSeverity.LowToleranceError };
60
+ }
61
+
62
+ // Slot check: use target slots since proposals target pipeline slots (slot + 1 when pipelining).
63
+ const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();
64
+
36
65
  const slotNumber = proposal.slotNumber;
37
- if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
38
- // Check if message is for previous slot and within clock tolerance
39
- if (!isWithinClockTolerance(slotNumber, currentSlot, this.epochCache)) {
40
- this.logger.warn(`Penalizing peer for invalid slot number ${slotNumber}`, { currentSlot, nextSlot });
66
+ if (!this.skipSlotValidation && slotNumber !== targetSlot && slotNumber !== nextSlot) {
67
+ // When pipelining, accept proposals for the current slot (built in the previous slot)
68
+ // if they're still within the shared proposal acceptance window.
69
+ if (this.pipeliningWindow.acceptsProposal(slotNumber)) {
70
+ // Fall through to remaining validation (signature, proposer, etc.)
71
+ } else if (!isWithinClockTolerance(slotNumber, targetSlot, this.epochCache)) {
72
+ this.logger.warn(`Penalizing peer for invalid slot number ${slotNumber}`, { targetSlot, nextSlot });
41
73
  return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
74
+ } else {
75
+ this.logger.verbose(`Ignoring proposal for previous slot ${slotNumber} within clock tolerance`);
76
+ return { result: 'ignore' };
42
77
  }
43
- this.logger.verbose(`Ignoring proposal for previous slot ${slotNumber} within clock tolerance`);
44
- return { result: 'ignore' };
45
78
  }
46
79
 
47
80
  // Signature validity
@@ -61,6 +94,17 @@ export class ProposalValidator {
61
94
  return { result: 'reject', severity: PeerErrorSeverity.MidToleranceError };
62
95
  }
63
96
 
97
+ if (
98
+ this.maxBlocksPerCheckpoint !== undefined &&
99
+ 'indexWithinCheckpoint' in proposal &&
100
+ proposal.indexWithinCheckpoint >= this.maxBlocksPerCheckpoint
101
+ ) {
102
+ this.logger.warn(
103
+ `Penalizing peer for proposal with indexWithinCheckpoint ${proposal.indexWithinCheckpoint} >= max ${this.maxBlocksPerCheckpoint}`,
104
+ );
105
+ return { result: 'reject', severity: PeerErrorSeverity.MidToleranceError };
106
+ }
107
+
64
108
  return { result: 'accept' };
65
109
  } catch (e) {
66
110
  if (e instanceof NoCommitteeError) {
@@ -75,7 +75,7 @@ This validator is invoked on **every** transaction potentially entering the pend
75
75
  - Startup hydration — revalidating persisted non-mined txs on node restart
76
76
 
77
77
  Runs:
78
- - DoubleSpend, BlockHeader, GasLimits, Timestamp, AllowedSetupCalls
78
+ - DoubleSpend, BlockHeader, GasLimits, MaxFeePerGas, Timestamp, AllowedSetupCalls
79
79
 
80
80
  Operates on `TxMetaData` (pre-built by the pool) rather than full `Tx` objects.
81
81
 
@@ -91,8 +91,9 @@ The `AllowedSetupCallsMetaValidator` checks a precomputed boolean flag (`TxMetaD
91
91
  | `MetadataTxValidator` | Chain ID, rollup version, protocol contracts hash, VK tree root | 4.18 us |
92
92
  | `TimestampTxValidator` | Transaction has not expired (expiration timestamp vs next slot) | 1.56 us |
93
93
  | `DoubleSpendTxValidator` | Nullifiers do not already exist in the nullifier tree | 106.08 us |
94
- | `GasTxValidator` | Gas limits are within bounds (delegates to `GasLimitsValidator`), max fee per gas meets current block fees, and fee payer has sufficient FeeJuice balance | 1.02 ms |
94
+ | `GasTxValidator` | Gas limits are within bounds (delegates to `GasLimitsValidator`), max fee per gas meets current block fees (delegates to `MaxFeePerGasValidator`), and fee payer has sufficient FeeJuice balance | 1.02 ms |
95
95
  | `GasLimitsValidator` | Gas limits are >= fixed minimums and <= AVM max processable L2 gas. Used standalone in pool migration; also called internally by `GasTxValidator` | 3–10 us |
96
+ | `MaxFeePerGasValidator` | Max fee per gas >= current block gas fees on both dimensions (DA and L2). Used standalone in pool migration; also called internally by `GasTxValidator` | 3–10 us |
96
97
  | `PhasesTxValidator` | Public function calls in setup phase are on the allow list | 10.12–13.12 us |
97
98
  | `AllowedSetupCallsMetaValidator` | Checks the precomputed `allowedSetupCalls` flag on `TxMetaData`. Used in pool migration instead of the full `PhasesTxValidator` | — |
98
99
  | `BlockHeaderTxValidator` | Transaction's anchor block hash exists in the archive tree | 98.88 us |
@@ -110,10 +111,17 @@ The `AllowedSetupCallsMetaValidator` checks a precomputed boolean flag (`TxMetaD
110
111
  | DoubleSpend | Stage 1 | Yes | — | Yes | Yes |
111
112
  | Gas (balance + limits) | Stage 1 | Optional* | — | Yes | — |
112
113
  | GasLimits (standalone) | — | — | — | — | Yes |
114
+ | MaxFeePerGas (standalone) | — | — | — | — | Yes |
113
115
  | Phases | Stage 1 | Yes | — | Yes | — |
114
116
  | AllowedSetupCalls | — | — | — | — | Yes |
115
117
  | BlockHeader | Stage 1 | Yes | — | Yes | Yes |
116
118
  | Proof | Stage 2 | Optional** | Yes | — | — |
117
119
 
118
- \* Gas balance check is skipped when `skipFeeEnforcement` is set (testing/dev). `GasTxValidator` internally delegates to `GasLimitsValidator` as its first step, so gas limits are checked wherever `GasTxValidator` runs. Pool migration uses `GasLimitsValidator` standalone because it doesn't need the balance or fee-per-gas checks.
120
+ \* Gas balance check is skipped when `skipFeeEnforcement` is set (testing/dev). `GasTxValidator` internally delegates to `GasLimitsValidator` and `MaxFeePerGasValidator` as its first steps, so gas limits and fee-per-gas are checked wherever `GasTxValidator` runs. Pool migration uses `GasLimitsValidator` and `MaxFeePerGasValidator` standalone because it doesn't need the balance check.
119
121
  \** Proof verification is skipped for simulations (no verifier provided).
122
+
123
+ ## Fee-Per-Gas Rejection Strategy
124
+
125
+ The `MaxFeePerGasValidator` and `InsufficientFeePerGasEvictionRule` reject and evict transactions whose `maxFeesPerGas` falls below the current block's gas fees. This is a simple strategy: if a tx can't pay the current fees, it gets rejected on entry and evicted after each new block.
126
+
127
+ **Caveat**: This may evict transactions that would become valid again if block fees drop. A more nuanced approach would be to define a threshold (e.g., 50%) and only reject/evict when the tx's max fee falls below that fraction of the current fees. The current approach is simpler and ensures the pool doesn't accumulate transactions with low max fees that are unlikely to be mined soon.
@@ -11,22 +11,13 @@ export class AggregateTxValidator<T> implements TxValidator<T> {
11
11
  }
12
12
 
13
13
  async validateTx(tx: T): Promise<TxValidationResult> {
14
- const aggregate: { result: string; reason?: string[] } = { result: 'valid', reason: [] };
14
+ const reasons: string[] = [];
15
15
  for (const validator of this.validators) {
16
16
  const result = await validator.validateTx(tx);
17
17
  if (result.result === 'invalid') {
18
- aggregate.result = 'invalid';
19
- aggregate.reason!.push(...result.reason);
20
- } else if (result.result === 'skipped') {
21
- if (aggregate.result === 'valid') {
22
- aggregate.result = 'skipped';
23
- }
24
- aggregate.reason!.push(...result.reason);
18
+ reasons.push(...result.reason);
25
19
  }
26
20
  }
27
- if (aggregate.result === 'valid') {
28
- delete aggregate.reason;
29
- }
30
- return aggregate as TxValidationResult;
21
+ return reasons.length > 0 ? { result: 'invalid', reason: reasons } : { result: 'valid' };
31
22
  }
32
23
  }
@@ -1,6 +1,6 @@
1
1
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
2
- import { AuthRegistryArtifact } from '@aztec/protocol-contracts/auth-registry';
3
2
  import { FeeJuiceArtifact } from '@aztec/protocol-contracts/fee-juice';
3
+ import { AuthRegistryArtifact, STANDARD_AUTH_REGISTRY_ADDRESS } from '@aztec/standard-contracts/auth-registry';
4
4
  import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
5
5
 
6
6
  import { buildAllowedElement } from './allowed_setup_helpers.js';
@@ -12,12 +12,12 @@ export async function getDefaultAllowedSetupFunctions(): Promise<AllowedElement[
12
12
  if (defaultAllowedSetupFunctions === undefined) {
13
13
  defaultAllowedSetupFunctions = await Promise.all([
14
14
  // AuthRegistry: needed for authwit support via private path (set_authorized_private enqueues _set_authorized)
15
- buildAllowedElement(AuthRegistryArtifact, { address: ProtocolContractAddress.AuthRegistry }, '_set_authorized', {
15
+ buildAllowedElement(AuthRegistryArtifact, { address: STANDARD_AUTH_REGISTRY_ADDRESS }, '_set_authorized', {
16
16
  onlySelf: true,
17
17
  rejectNullMsgSender: true,
18
18
  }),
19
19
  // AuthRegistry: needed for authwit support via public path (PublicFeePaymentMethod calls set_authorized directly)
20
- buildAllowedElement(AuthRegistryArtifact, { address: ProtocolContractAddress.AuthRegistry }, 'set_authorized', {
20
+ buildAllowedElement(AuthRegistryArtifact, { address: STANDARD_AUTH_REGISTRY_ADDRESS }, 'set_authorized', {
21
21
  rejectNullMsgSender: true,
22
22
  }),
23
23
  // FeeJuice: needed for claiming on the same tx as a spend (claim_and_end_setup enqueues this)
@@ -15,7 +15,7 @@ export class ArchiveCache implements ArchiveSource {
15
15
  }
16
16
 
17
17
  public async getArchiveIndices(archives: BlockHash[]): Promise<(bigint | undefined)[]> {
18
- const toCheckDb = archives.filter(n => !this.archives.has(n.toString())).map(n => n.toFr());
18
+ const toCheckDb = archives.filter(n => !this.archives.has(n.toString()));
19
19
  const dbHits = await this.db.findLeafIndices(MerkleTreeId.ARCHIVE, toCheckDb);
20
20
  dbHits.forEach((x, index) => {
21
21
  if (x !== undefined) {
@@ -0,0 +1,31 @@
1
+ import type { Tx, TxValidationResult, TxValidator } from '@aztec/stdlib/tx';
2
+
3
+ import type { ITxValidationCache } from './tx_validation_cache.js';
4
+
5
+ /** Wraps a {@link TxValidator} to cache its results in a shared {@link ITxValidationCache}. */
6
+ export class CachedTxValidator<T extends Tx> implements TxValidator<T> {
7
+ constructor(
8
+ private readonly inner: TxValidator<T>,
9
+ private readonly validatorSymbol: symbol,
10
+ private readonly cache: ITxValidationCache,
11
+ ) {}
12
+
13
+ public static new<T extends Tx>(
14
+ inner: TxValidator<T> & { identifier: symbol },
15
+ cache?: ITxValidationCache,
16
+ ): TxValidator<T> {
17
+ return CachedTxValidator.newWithIdentifier(inner, inner.identifier, cache);
18
+ }
19
+
20
+ public static newWithIdentifier<T extends Tx>(
21
+ inner: TxValidator<T>,
22
+ identifier: symbol,
23
+ cache?: ITxValidationCache,
24
+ ): TxValidator<T> {
25
+ return cache ? new CachedTxValidator(inner, identifier, cache) : inner;
26
+ }
27
+
28
+ public validateTx(tx: T): Promise<TxValidationResult> {
29
+ return this.cache.getOrValidate(this.validatorSymbol, tx, () => this.inner.validateTx(tx));
30
+ }
31
+ }
@@ -20,6 +20,8 @@ import {
20
20
  } from '@aztec/stdlib/tx';
21
21
 
22
22
  export class DataTxValidator implements TxValidator<Tx> {
23
+ public readonly identifier: symbol = Symbol('DataTxValidator');
24
+
23
25
  #log: Logger;
24
26
 
25
27
  constructor(bindings?: LoggerBindings) {
@@ -53,10 +53,11 @@ import type { TxMetaData } from '../../mem_pools/tx_pool_v2/tx_metadata.js';
53
53
  import { AggregateTxValidator } from './aggregate_tx_validator.js';
54
54
  import { ArchiveCache } from './archive_cache.js';
55
55
  import { type ArchiveSource, BlockHeaderTxValidator } from './block_header_validator.js';
56
+ import { CachedTxValidator } from './cached_tx_validator.js';
56
57
  import { ContractInstanceTxValidator } from './contract_instance_validator.js';
57
58
  import { DataTxValidator } from './data_validator.js';
58
59
  import { DoubleSpendTxValidator, type NullifierSource } from './double_spend_validator.js';
59
- import { GasLimitsValidator, GasTxValidator } from './gas_validator.js';
60
+ import { GasLimitsValidator, GasTxValidator, MaxFeePerGasValidator } from './gas_validator.js';
60
61
  import { MetadataTxValidator } from './metadata_validator.js';
61
62
  import { NullifierCache } from './nullifier_cache.js';
62
63
  import { AllowedSetupCallsMetaValidator, PhasesTxValidator } from './phases_validator.js';
@@ -64,6 +65,7 @@ import { SizeTxValidator } from './size_validator.js';
64
65
  import { TimestampTxValidator } from './timestamp_validator.js';
65
66
  import { TxPermittedValidator } from './tx_permitted_validator.js';
66
67
  import { TxProofValidator } from './tx_proof_validator.js';
68
+ import { TxValidationCache } from './tx_validation_cache.js';
67
69
 
68
70
  /**
69
71
  * A validator paired with a peer penalty severity.
@@ -210,8 +212,9 @@ function createTxValidatorForMinimumTxIntegrityChecks(
210
212
  rollupVersion: number;
211
213
  },
212
214
  bindings?: LoggerBindings,
215
+ cache?: TxValidationCache,
213
216
  ): TxValidator {
214
- return new AggregateTxValidator(
217
+ const aggregate = new AggregateTxValidator(
215
218
  new MetadataTxValidator(
216
219
  {
217
220
  l1ChainId: new Fr(l1ChainId),
@@ -222,10 +225,14 @@ function createTxValidatorForMinimumTxIntegrityChecks(
222
225
  bindings,
223
226
  ),
224
227
  new SizeTxValidator(bindings),
225
- new DataTxValidator(bindings),
228
+ CachedTxValidator.new(new DataTxValidator(bindings), cache),
226
229
  new ContractInstanceTxValidator(bindings),
227
- new TxProofValidator(verifier, bindings),
230
+ CachedTxValidator.new(new TxProofValidator(verifier, bindings), cache),
228
231
  );
232
+
233
+ // This validator is not state-dependent so we can cache it.
234
+ const identifier = Symbol('TxValidatorForMinimumTxIntegrityChecks');
235
+ return CachedTxValidator.newWithIdentifier(aggregate, identifier, cache);
229
236
  }
230
237
 
231
238
  /**
@@ -234,7 +241,7 @@ function createTxValidatorForMinimumTxIntegrityChecks(
234
241
  * are invalid against current state. State-dependent checks happen when the tx
235
242
  * enters the pending pool or during block building.
236
243
  */
237
- export function createTxValidatorForReqResponseReceivedTxs(
244
+ export function createTxValidatorForOnDemandReceivedTxs(
238
245
  verifier: ClientProtocolCircuitVerifier,
239
246
  {
240
247
  l1ChainId,
@@ -244,8 +251,9 @@ export function createTxValidatorForReqResponseReceivedTxs(
244
251
  rollupVersion: number;
245
252
  },
246
253
  bindings?: LoggerBindings,
254
+ cache?: TxValidationCache,
247
255
  ): TxValidator {
248
- return createTxValidatorForMinimumTxIntegrityChecks(verifier, { l1ChainId, rollupVersion }, bindings);
256
+ return createTxValidatorForMinimumTxIntegrityChecks(verifier, { l1ChainId, rollupVersion }, bindings, cache);
249
257
  }
250
258
 
251
259
  /**
@@ -263,8 +271,9 @@ export function createTxValidatorForBlockProposalReceivedTxs(
263
271
  rollupVersion: number;
264
272
  },
265
273
  bindings?: LoggerBindings,
274
+ cache?: TxValidationCache,
266
275
  ): TxValidator {
267
- return createTxValidatorForMinimumTxIntegrityChecks(verifier, { l1ChainId, rollupVersion }, bindings);
276
+ return createTxValidatorForMinimumTxIntegrityChecks(verifier, { l1ChainId, rollupVersion }, bindings, cache);
268
277
  }
269
278
 
270
279
  /**
@@ -423,6 +432,7 @@ export async function createTxValidatorForTransactionsEnteringPendingTxPool(
423
432
  timestamp: bigint,
424
433
  blockNumber: BlockNumber,
425
434
  gasLimitOpts: { rollupManaLimit?: number; maxBlockL2Gas?: number; maxBlockDAGas?: number },
435
+ gasFees: GasFees,
426
436
  bindings?: LoggerBindings,
427
437
  ): Promise<TxValidator<TxMetaData>> {
428
438
  await worldStateSynchronizer.syncImmediate();
@@ -440,6 +450,7 @@ export async function createTxValidatorForTransactionsEnteringPendingTxPool(
440
450
  };
441
451
  return new AggregateTxValidator<TxMetaData>(
442
452
  new GasLimitsValidator<TxMetaData>({ ...gasLimitOpts, bindings }),
453
+ new MaxFeePerGasValidator<TxMetaData>(gasFees, bindings),
443
454
  new TimestampTxValidator<TxMetaData>({ timestamp, blockNumber }, bindings),
444
455
  new DoubleSpendTxValidator<TxMetaData>(nullifierSource, bindings),
445
456
  new BlockHeaderTxValidator<TxMetaData>(archiveSource, bindings),
@@ -36,6 +36,18 @@ export interface HasGasLimitData {
36
36
  };
37
37
  }
38
38
 
39
+ /** Structural interface for types that carry max fee per gas data, used by {@link MaxFeePerGasValidator}. */
40
+ export interface HasMaxFeePerGasData {
41
+ txHash: { toString(): string };
42
+ data: {
43
+ constants: {
44
+ txContext: {
45
+ gasSettings: { maxFeesPerGas: GasFees };
46
+ };
47
+ };
48
+ };
49
+ }
50
+
39
51
  /**
40
52
  * Validates that a transaction's gas limits are within acceptable bounds.
41
53
  *
@@ -87,7 +99,12 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
87
99
  gasLimits,
88
100
  minGasLimits,
89
101
  });
90
- return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_GAS_LIMIT] };
102
+ return {
103
+ result: 'invalid',
104
+ reason: [
105
+ `${TX_ERROR_INSUFFICIENT_GAS_LIMIT} (required=da:${minGasLimits.daGas},l2:${minGasLimits.l2Gas} got=da:${gasLimits.daGas},l2:${gasLimits.l2Gas})`,
106
+ ],
107
+ };
91
108
  }
92
109
 
93
110
  if (gasLimits.l2Gas > this.#effectiveMaxL2Gas) {
@@ -97,7 +114,10 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
97
114
  rollupManaLimit: this.#rollupManaLimit,
98
115
  maxBlockL2Gas: this.#maxBlockL2Gas,
99
116
  });
100
- return { result: 'invalid', reason: [TX_ERROR_GAS_LIMIT_TOO_HIGH] };
117
+ return {
118
+ result: 'invalid',
119
+ reason: [`${TX_ERROR_GAS_LIMIT_TOO_HIGH} (l2Gas=${gasLimits.l2Gas}, max=${this.#effectiveMaxL2Gas})`],
120
+ };
101
121
  }
102
122
 
103
123
  if (gasLimits.daGas > this.#effectiveMaxDAGas) {
@@ -106,22 +126,70 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
106
126
  effectiveMaxDAGas: this.#effectiveMaxDAGas,
107
127
  maxBlockDAGas: this.#maxBlockDAGas,
108
128
  });
109
- return { result: 'invalid', reason: [TX_ERROR_GAS_LIMIT_TOO_HIGH] };
129
+ return {
130
+ result: 'invalid',
131
+ reason: [`${TX_ERROR_GAS_LIMIT_TOO_HIGH} (daGas=${gasLimits.daGas}, max=${this.#effectiveMaxDAGas})`],
132
+ };
110
133
  }
111
134
 
112
135
  return { result: 'valid' };
113
136
  }
114
137
  }
115
138
 
139
+ /**
140
+ * Validates that a transaction's max fee per gas meets the current block's gas fees.
141
+ *
142
+ * Rejects transactions whose maxFeesPerGas is below the current block's gas fees
143
+ * on either dimension (DA or L2). This is a cheap, stateless check.
144
+ *
145
+ * Generic over T so it can validate both full {@link Tx} objects and {@link TxMetaData}
146
+ * (used during pending pool migration).
147
+ *
148
+ * Used by: pending pool migration (via factory), and indirectly by {@link GasTxValidator}.
149
+ */
150
+ export class MaxFeePerGasValidator<T extends HasMaxFeePerGasData> implements TxValidator<T> {
151
+ #log: Logger;
152
+ #gasFees: GasFees;
153
+
154
+ constructor(gasFees: GasFees, bindings?: LoggerBindings) {
155
+ this.#log = createLogger('sequencer:tx_validator:tx_gas', bindings);
156
+ this.#gasFees = gasFees;
157
+ }
158
+
159
+ validateTx(tx: T): Promise<TxValidationResult> {
160
+ return Promise.resolve(this.validateMaxFeePerGas(tx));
161
+ }
162
+
163
+ /** Checks maxFeesPerGas >= current block gas fees on both dimensions. */
164
+ validateMaxFeePerGas(tx: T): TxValidationResult {
165
+ const maxFeesPerGas = tx.data.constants.txContext.gasSettings.maxFeesPerGas;
166
+ const notEnoughMaxFees =
167
+ maxFeesPerGas.feePerDaGas < this.#gasFees.feePerDaGas || maxFeesPerGas.feePerL2Gas < this.#gasFees.feePerL2Gas;
168
+
169
+ if (notEnoughMaxFees) {
170
+ this.#log.verbose(`Rejecting transaction ${tx.txHash.toString()} due to insufficient fee per gas`, {
171
+ txMaxFeesPerGas: maxFeesPerGas.toInspect(),
172
+ currentGasFees: this.#gasFees.toInspect(),
173
+ });
174
+ return {
175
+ result: 'invalid',
176
+ reason: [
177
+ `${TX_ERROR_INSUFFICIENT_FEE_PER_GAS} (maxFee=da:${maxFeesPerGas.feePerDaGas},l2:${maxFeesPerGas.feePerL2Gas} required=da:${this.#gasFees.feePerDaGas},l2:${this.#gasFees.feePerL2Gas})`,
178
+ ],
179
+ };
180
+ }
181
+ return { result: 'valid' };
182
+ }
183
+ }
184
+
116
185
  /**
117
186
  * Validates that a transaction can pay its gas fees.
118
187
  *
119
188
  * Runs three checks in order:
120
189
  * 1. **Gas limits** (delegates to {@link GasLimitsValidator}) — rejects if limits are
121
190
  * out of bounds.
122
- * 2. **Max fee per gas** — skips (not rejects) the tx if its maxFeesPerGas is below
123
- * the current block's gas fees. We skip rather than reject because the tx may
124
- * become eligible in a later block with lower fees.
191
+ * 2. **Max fee per gas** — rejects the tx if its maxFeesPerGas is below
192
+ * the current block's gas fees.
125
193
  * 3. **Fee payer balance** — reads the fee payer's FeeJuice balance from public state,
126
194
  * adds any pending claim from a setup-phase `_increase_public_balance` call, and
127
195
  * rejects if the total is less than the tx's fee limit (gasLimits * maxFeePerGas).
@@ -155,37 +223,15 @@ export class GasTxValidator implements TxValidator<Tx> {
155
223
  bindings: this.bindings,
156
224
  }).validateGasLimit(tx);
157
225
  if (gasLimitValidation.result === 'invalid') {
158
- return Promise.resolve(gasLimitValidation);
226
+ return gasLimitValidation;
159
227
  }
160
- if (this.#shouldSkip(tx)) {
161
- return Promise.resolve({ result: 'skipped', reason: [TX_ERROR_INSUFFICIENT_FEE_PER_GAS] });
228
+ const maxFeeValidation = new MaxFeePerGasValidator(this.#gasFees, this.bindings).validateMaxFeePerGas(tx);
229
+ if (maxFeeValidation.result === 'invalid') {
230
+ return maxFeeValidation;
162
231
  }
163
232
  return await this.validateTxFee(tx);
164
233
  }
165
234
 
166
- /**
167
- * Check whether the tx's max fees are valid for the current block, and skip if not.
168
- * We skip instead of invalidating since the tx may become eligible later.
169
- * Note that circuits check max fees even if fee payer is unset, so we
170
- * keep this validation even if the tx does not pay fees.
171
- */
172
- #shouldSkip(tx: Tx): boolean {
173
- const gasSettings = tx.data.constants.txContext.gasSettings;
174
-
175
- // Skip the tx if its max fees are not enough for the current block's gas fees.
176
- const maxFeesPerGas = gasSettings.maxFeesPerGas;
177
- const notEnoughMaxFees =
178
- maxFeesPerGas.feePerDaGas < this.#gasFees.feePerDaGas || maxFeesPerGas.feePerL2Gas < this.#gasFees.feePerL2Gas;
179
-
180
- if (notEnoughMaxFees) {
181
- this.#log.verbose(`Skipping transaction ${tx.getTxHash().toString()} due to insufficient fee per gas`, {
182
- txMaxFeesPerGas: maxFeesPerGas.toInspect(),
183
- currentGasFees: this.#gasFees.toInspect(),
184
- });
185
- }
186
- return notEnoughMaxFees;
187
- }
188
-
189
235
  /**
190
236
  * Checks the fee payer has enough FeeJuice balance to cover the tx's fee limit.
191
237
  * Accounts for any pending claim from a setup-phase `_increase_public_balance` call.
@@ -212,7 +258,10 @@ export class GasTxValidator implements TxValidator<Tx> {
212
258
  balance,
213
259
  feeLimit,
214
260
  });
215
- return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE] };
261
+ return {
262
+ result: 'invalid',
263
+ reason: [`${TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE} (required=${feeLimit}, available=${balance})`],
264
+ };
216
265
  }
217
266
  return { result: 'valid' };
218
267
  }
@@ -14,3 +14,5 @@ export * from './tx_permitted_validator.js';
14
14
  export * from './timestamp_validator.js';
15
15
  export * from './size_validator.js';
16
16
  export * from './factory.js';
17
+ export * from './tx_validation_cache.js';
18
+ export * from './cached_tx_validator.js';
@@ -28,16 +28,24 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
28
28
  validateTx(tx: T): Promise<TxValidationResult> {
29
29
  const errors = [];
30
30
  if (!this.#hasCorrectL1ChainId(tx)) {
31
- errors.push(TX_ERROR_INCORRECT_L1_CHAIN_ID);
31
+ errors.push(
32
+ `${TX_ERROR_INCORRECT_L1_CHAIN_ID} (tx: ${tx.data.constants.txContext.chainId.toNumber()}, expected: ${this.values.l1ChainId.toNumber()})`,
33
+ );
32
34
  }
33
35
  if (!this.#hasCorrectRollupVersion(tx)) {
34
- errors.push(TX_ERROR_INCORRECT_ROLLUP_VERSION);
36
+ errors.push(
37
+ `${TX_ERROR_INCORRECT_ROLLUP_VERSION} (tx: ${tx.data.constants.txContext.version.toNumber()}, expected: ${this.values.rollupVersion.toNumber()})`,
38
+ );
35
39
  }
36
40
  if (!this.#hasCorrectVkTreeRoot(tx)) {
37
- errors.push(TX_ERROR_INCORRECT_VK_TREE_ROOT);
41
+ errors.push(
42
+ `${TX_ERROR_INCORRECT_VK_TREE_ROOT} (tx: ${tx.data.constants.vkTreeRoot.toString()}, expected: ${this.values.vkTreeRoot.toString()})`,
43
+ );
38
44
  }
39
45
  if (!this.#hasCorrectprotocolContractsHash(tx)) {
40
- errors.push(TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH);
46
+ errors.push(
47
+ `${TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH} (tx: ${tx.data.constants.protocolContractsHash.toString()}, expected: ${this.values.protocolContractsHash.toString()})`,
48
+ );
41
49
  }
42
50
  return Promise.resolve(errors.length > 0 ? { result: 'invalid', reason: errors } : { result: 'valid' });
43
51
  }
@@ -3,6 +3,8 @@ import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/ser
3
3
  import { TX_ERROR_INVALID_PROOF, Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
4
4
 
5
5
  export class TxProofValidator implements TxValidator<Tx> {
6
+ public readonly identifier: symbol = Symbol('TxProofValidator');
7
+
6
8
  #log: Logger;
7
9
 
8
10
  constructor(
@@ -0,0 +1,101 @@
1
+ import { LruMap } from '@aztec/foundation/collection';
2
+ import { type Logger, createLogger } from '@aztec/foundation/log';
3
+ import type { Tx, TxValidationResult } from '@aztec/stdlib/tx';
4
+
5
+ import { createHash } from 'node:crypto';
6
+
7
+ /**
8
+ * Minimal interface consumed by {@link CachedTxValidator}.
9
+ * Keeping the dependency on an interface lets callers (and tests) substitute any cache implementation.
10
+ */
11
+ export interface ITxValidationCache {
12
+ /** Returns the cached promise if present, otherwise calls `validate`, caches its promise, and returns it. */
13
+ getOrValidate(
14
+ validatorSymbol: symbol,
15
+ tx: Tx,
16
+ validate: () => Promise<TxValidationResult>,
17
+ ): Promise<TxValidationResult>;
18
+ }
19
+
20
+ /**
21
+ * Caches per-validator tx validation results to avoid redundant work across repeated validation calls.
22
+ *
23
+ * The cache key is composed from the validator symbol and tx hash, ensuring results are
24
+ * scoped to the specific validator that produced them.
25
+ *
26
+ * Promises are stored before they are awaited, so concurrent calls for the same pair share
27
+ * a single in-flight validation rather than launching duplicate work.
28
+ *
29
+ * Entries are evicted in least-recently-used order once the cache reaches `maxSize`.
30
+ */
31
+ export class TxValidationCache implements ITxValidationCache {
32
+ #log: Logger;
33
+
34
+ private readonly entries: LruMap<string, Promise<TxValidationResult>>;
35
+ // Remember hashes for known Tx object references to skip rehashing on subsequent lookups.
36
+ // WeakMap holds keys weakly, so an entry doesn't keep the Tx alive once nothing else references it.
37
+ private readonly txHashesCache: WeakMap<Tx, string> = new WeakMap();
38
+
39
+ constructor(maxSize: number) {
40
+ this.entries = new LruMap(maxSize);
41
+ this.#log = createLogger('p2p:tx_validation_cache');
42
+ }
43
+
44
+ /**
45
+ * Computes the cache key scoping a validation result to a specific validator and tx.
46
+ *
47
+ * @param validatorSymbol - The symbol of the validator.
48
+ * @param tx - The tx to compute the key for.
49
+ * @returns The cache key.
50
+ *
51
+ * Note: the key should NOT use the tx.hash because it can't be trusted at this point.
52
+ */
53
+ public key(validatorSymbol: symbol, tx: Tx): string {
54
+ // Serializing the tx dominates cost (~5 ms). If we have already hashed this object, skip toBuffer + hash.
55
+ let hash = this.txHashesCache.get(tx);
56
+ if (hash === undefined) {
57
+ hash = createHash('sha256').update(tx.toBuffer()).digest('hex');
58
+ this.txHashesCache.set(tx, hash);
59
+ }
60
+ return `${Symbol.keyFor(validatorSymbol) ?? validatorSymbol.toString()}:${hash}`;
61
+ }
62
+
63
+ /** Returns the cached promise for the given key, or undefined if not cached. Refreshes recency. */
64
+ public get(key: string): Promise<TxValidationResult> | undefined {
65
+ return this.entries.get(key);
66
+ }
67
+
68
+ /** Stores a validation promise under the given key, evicting the LRU entry if at capacity. */
69
+ public set(key: string, result: Promise<TxValidationResult>): void {
70
+ this.entries.set(key, result);
71
+ }
72
+
73
+ /** Removes the cached validation promise for the given key. */
74
+ public delete(key: string): void {
75
+ this.entries.delete(key);
76
+ }
77
+
78
+ /**
79
+ * Returns the cached promise if present, otherwise calls `validate`, stores its promise
80
+ * immediately (before awaiting), and returns it.
81
+ */
82
+ public getOrValidate(
83
+ validatorSymbol: symbol,
84
+ tx: Tx,
85
+ validate: () => Promise<TxValidationResult>,
86
+ ): Promise<TxValidationResult> {
87
+ const key = this.key(validatorSymbol, tx);
88
+ const cached = this.get(key);
89
+ if (cached !== undefined) {
90
+ this.#log.debug('Returning cached tx validation result', {
91
+ validator: validatorSymbol.toString(),
92
+ txHash: tx.txHash.toString(),
93
+ key: key,
94
+ });
95
+ return cached;
96
+ }
97
+ const promise = validate();
98
+ this.set(key, promise);
99
+ return promise;
100
+ }
101
+ }