@aztec/p2p 0.0.1-commit.181e2d196 → 0.0.1-commit.189eedb3

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 (455) hide show
  1. package/README.md +129 -3
  2. package/dest/bootstrap/bootstrap.d.ts +1 -1
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  4. package/dest/bootstrap/bootstrap.js +9 -1
  5. package/dest/client/factory.d.ts +5 -4
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +33 -15
  8. package/dest/client/interface.d.ts +14 -5
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +13 -9
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +93 -49
  13. package/dest/config.d.ts +148 -96
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +114 -10
  16. package/dest/errors/p2p-service.error.d.ts +9 -0
  17. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  18. package/dest/errors/p2p-service.error.js +10 -0
  19. package/dest/errors/reqresp.error.d.ts +1 -20
  20. package/dest/errors/reqresp.error.d.ts.map +1 -1
  21. package/dest/errors/reqresp.error.js +0 -21
  22. package/dest/index.d.ts +1 -2
  23. package/dest/index.d.ts.map +1 -1
  24. package/dest/index.js +0 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +99 -59
  26. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool.js +265 -199
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +181 -65
  31. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  32. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  33. package/dest/mem_pools/attestation_pool/mocks.js +6 -4
  34. package/dest/mem_pools/index.d.ts +1 -2
  35. package/dest/mem_pools/index.d.ts.map +1 -1
  36. package/dest/mem_pools/instrumentation.d.ts +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/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  43. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +2 -1
  45. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  48. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  49. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  50. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  51. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
  52. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  54. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
  55. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  56. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
  57. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
  58. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  59. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
  60. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +12 -5
  61. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  62. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  63. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +29 -11
  64. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  65. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +46 -16
  66. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  67. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  68. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -43
  69. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
  70. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  71. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +3 -0
  72. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
  73. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  74. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +94 -88
  75. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
  76. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  77. package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
  78. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  79. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  80. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  81. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  82. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  83. package/dest/msg_validators/clock_tolerance.js +56 -3
  84. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -4
  85. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  86. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  87. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -4
  88. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  89. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  90. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +20 -9
  91. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  92. package/dest/msg_validators/proposal_validator/proposal_validator.js +88 -52
  93. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  94. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +8 -15
  96. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
  97. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/allowed_public_setup.js +21 -32
  99. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  100. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  101. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  102. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  103. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  104. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  105. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  106. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  107. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  108. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  109. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  110. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  111. package/dest/msg_validators/tx_validator/data_validator.js +36 -2
  112. package/dest/msg_validators/tx_validator/factory.d.ts +27 -7
  113. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  114. package/dest/msg_validators/tx_validator/factory.js +47 -17
  115. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  116. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  117. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  118. package/dest/msg_validators/tx_validator/gas_validator.d.ts +48 -7
  119. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  120. package/dest/msg_validators/tx_validator/gas_validator.js +88 -41
  121. package/dest/msg_validators/tx_validator/index.d.ts +4 -1
  122. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  123. package/dest/msg_validators/tx_validator/index.js +3 -0
  124. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  125. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  126. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  127. package/dest/msg_validators/tx_validator/phases_validator.d.ts +21 -1
  128. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  129. package/dest/msg_validators/tx_validator/phases_validator.js +49 -2
  130. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  131. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  132. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  133. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  134. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  135. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  136. package/dest/services/data_store.d.ts +1 -1
  137. package/dest/services/data_store.d.ts.map +1 -1
  138. package/dest/services/data_store.js +5 -5
  139. package/dest/services/discv5/discV5_service.d.ts +2 -1
  140. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  141. package/dest/services/discv5/discV5_service.js +35 -8
  142. package/dest/services/dummy_service.d.ts +11 -15
  143. package/dest/services/dummy_service.d.ts.map +1 -1
  144. package/dest/services/dummy_service.js +12 -16
  145. package/dest/services/encoding.d.ts +5 -1
  146. package/dest/services/encoding.d.ts.map +1 -1
  147. package/dest/services/encoding.js +7 -1
  148. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  149. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  150. package/dest/services/gossipsub/topic_score_params.js +21 -4
  151. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  152. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  153. package/dest/services/libp2p/instrumentation.js +14 -0
  154. package/dest/services/libp2p/libp2p_service.d.ts +36 -46
  155. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  156. package/dest/services/libp2p/libp2p_service.js +311 -276
  157. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  158. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  159. package/dest/services/peer-manager/peer_manager.js +38 -10
  160. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  161. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  162. package/dest/services/peer-manager/peer_scoring.js +32 -10
  163. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -8
  164. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  165. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +81 -86
  166. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +10 -6
  167. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  168. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  169. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  170. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  171. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
  172. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  173. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
  174. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  175. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  176. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  177. package/dest/services/reqresp/config.d.ts +3 -3
  178. package/dest/services/reqresp/config.d.ts.map +1 -1
  179. package/dest/services/reqresp/interface.d.ts +16 -18
  180. package/dest/services/reqresp/interface.d.ts.map +1 -1
  181. package/dest/services/reqresp/interface.js +10 -20
  182. package/dest/services/reqresp/metrics.d.ts +1 -1
  183. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  184. package/dest/services/reqresp/metrics.js +0 -1
  185. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  186. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  187. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  188. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  189. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  190. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
  191. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
  192. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  193. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
  194. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  195. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  196. package/dest/services/reqresp/protocols/index.js +0 -1
  197. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  198. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  199. package/dest/services/reqresp/protocols/tx.js +1 -3
  200. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  201. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  202. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  203. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  204. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  205. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  206. package/dest/services/reqresp/reqresp.d.ts +7 -29
  207. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  208. package/dest/services/reqresp/reqresp.js +41 -214
  209. package/dest/services/service.d.ts +9 -12
  210. package/dest/services/service.d.ts.map +1 -1
  211. package/dest/services/tx_collection/config.d.ts +2 -23
  212. package/dest/services/tx_collection/config.d.ts.map +1 -1
  213. package/dest/services/tx_collection/config.js +2 -55
  214. package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
  215. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  216. package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
  217. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  218. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  219. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  220. package/dest/services/tx_collection/index.d.ts +2 -3
  221. package/dest/services/tx_collection/index.d.ts.map +1 -1
  222. package/dest/services/tx_collection/index.js +0 -1
  223. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  224. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  225. package/dest/services/tx_collection/instrumentation.js +0 -2
  226. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  227. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  228. package/dest/services/tx_collection/request_tracker.js +84 -0
  229. package/dest/services/tx_collection/tx_collection.d.ts +36 -55
  230. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  231. package/dest/services/tx_collection/tx_collection.js +275 -119
  232. package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
  233. package/dest/services/tx_collection/tx_collection_sink.js +2 -2
  234. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  235. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  236. package/dest/services/tx_collection/tx_source.js +9 -7
  237. package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
  238. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  239. package/dest/services/tx_file_store/tx_file_store.js +4 -14
  240. package/dest/services/tx_provider.d.ts +3 -1
  241. package/dest/services/tx_provider.d.ts.map +1 -1
  242. package/dest/services/tx_provider.js +3 -0
  243. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  244. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  245. package/dest/test-helpers/make-test-p2p-clients.js +5 -2
  246. package/dest/test-helpers/mock-pubsub.d.ts +23 -9
  247. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  248. package/dest/test-helpers/mock-pubsub.js +44 -44
  249. package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
  250. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  251. package/dest/test-helpers/reqresp-nodes.js +16 -18
  252. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  253. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  254. package/dest/test-helpers/test_tx_provider.js +3 -0
  255. package/dest/test-helpers/testbench-utils.d.ts +12 -14
  256. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  257. package/dest/test-helpers/testbench-utils.js +40 -15
  258. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  259. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  260. package/dest/testbench/p2p_client_testbench_worker.js +85 -39
  261. package/dest/testbench/worker_client_manager.d.ts +12 -6
  262. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  263. package/dest/testbench/worker_client_manager.js +57 -11
  264. package/dest/util.d.ts +12 -7
  265. package/dest/util.d.ts.map +1 -1
  266. package/dest/util.js +35 -14
  267. package/dest/versioning.d.ts +3 -6
  268. package/dest/versioning.d.ts.map +1 -1
  269. package/dest/versioning.js +3 -24
  270. package/package.json +15 -14
  271. package/src/bootstrap/bootstrap.ts +9 -1
  272. package/src/client/factory.ts +57 -8
  273. package/src/client/interface.ts +15 -11
  274. package/src/client/p2p_client.ts +106 -70
  275. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  276. package/src/config.ts +195 -7
  277. package/src/errors/p2p-service.error.ts +11 -0
  278. package/src/errors/reqresp.error.ts +0 -25
  279. package/src/index.ts +0 -1
  280. package/src/mem_pools/attestation_pool/attestation_pool.ts +316 -241
  281. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +204 -68
  282. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  283. package/src/mem_pools/index.ts +0 -3
  284. package/src/mem_pools/instrumentation.ts +5 -1
  285. package/src/mem_pools/tx_pool_v2/README.md +9 -1
  286. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
  287. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -1
  288. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  289. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  290. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
  291. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  292. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
  293. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
  294. package/src/mem_pools/tx_pool_v2/interfaces.ts +12 -4
  295. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +72 -20
  296. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
  297. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +13 -1
  298. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +96 -94
  299. package/src/msg_validators/attestation_validator/README.md +49 -0
  300. package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
  301. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +14 -7
  302. package/src/msg_validators/clock_tolerance.ts +73 -3
  303. package/src/msg_validators/proposal_validator/README.md +123 -0
  304. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +24 -4
  305. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +35 -7
  306. package/src/msg_validators/proposal_validator/proposal_validator.ts +109 -56
  307. package/src/msg_validators/tx_validator/README.md +15 -3
  308. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
  309. package/src/msg_validators/tx_validator/allowed_public_setup.ts +16 -35
  310. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  311. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  312. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  313. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  314. package/src/msg_validators/tx_validator/data_validator.ts +44 -1
  315. package/src/msg_validators/tx_validator/factory.ts +61 -10
  316. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  317. package/src/msg_validators/tx_validator/gas_validator.ts +121 -39
  318. package/src/msg_validators/tx_validator/index.ts +3 -0
  319. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  320. package/src/msg_validators/tx_validator/phases_validator.ts +60 -1
  321. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  322. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  323. package/src/services/data_store.ts +5 -13
  324. package/src/services/discv5/discV5_service.ts +38 -5
  325. package/src/services/dummy_service.ts +14 -39
  326. package/src/services/encoding.ts +9 -1
  327. package/src/services/gossipsub/topic_score_params.ts +36 -4
  328. package/src/services/libp2p/instrumentation.ts +14 -0
  329. package/src/services/libp2p/libp2p_service.ts +339 -313
  330. package/src/services/peer-manager/peer_manager.ts +44 -10
  331. package/src/services/peer-manager/peer_scoring.ts +27 -5
  332. package/src/services/reqresp/README.md +215 -0
  333. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  334. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +77 -95
  335. package/src/services/reqresp/batch-tx-requester/interface.ts +13 -5
  336. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  337. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
  338. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  339. package/src/services/reqresp/config.ts +2 -2
  340. package/src/services/reqresp/interface.ts +21 -47
  341. package/src/services/reqresp/metrics.ts +0 -1
  342. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  343. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -30
  344. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
  345. package/src/services/reqresp/protocols/index.ts +0 -1
  346. package/src/services/reqresp/protocols/tx.ts +1 -3
  347. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  348. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  349. package/src/services/reqresp/reqresp.ts +45 -260
  350. package/src/services/service.ts +12 -28
  351. package/src/services/tx_collection/config.ts +3 -80
  352. package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
  353. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  354. package/src/services/tx_collection/index.ts +1 -6
  355. package/src/services/tx_collection/instrumentation.ts +1 -7
  356. package/src/services/tx_collection/request_tracker.ts +127 -0
  357. package/src/services/tx_collection/tx_collection.ts +331 -176
  358. package/src/services/tx_collection/tx_collection_sink.ts +2 -2
  359. package/src/services/tx_collection/tx_source.ts +8 -7
  360. package/src/services/tx_file_store/tx_file_store.ts +5 -17
  361. package/src/services/tx_provider.ts +5 -0
  362. package/src/test-helpers/make-test-p2p-clients.ts +4 -1
  363. package/src/test-helpers/mock-pubsub.ts +46 -60
  364. package/src/test-helpers/reqresp-nodes.ts +13 -23
  365. package/src/test-helpers/test_tx_provider.ts +5 -0
  366. package/src/test-helpers/testbench-utils.ts +51 -28
  367. package/src/testbench/p2p_client_testbench_worker.ts +89 -55
  368. package/src/testbench/worker_client_manager.ts +72 -25
  369. package/src/util.ts +33 -18
  370. package/src/versioning.ts +3 -33
  371. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  372. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  373. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -304
  374. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  375. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  376. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  377. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  378. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  379. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  380. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  381. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  382. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  383. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  384. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  385. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  386. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  387. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  388. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  389. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  390. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  391. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  392. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  393. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  394. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  395. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  396. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  397. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  398. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  399. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  400. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  401. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  402. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  403. package/dest/mem_pools/tx_pool/index.js +0 -2
  404. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  405. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  406. package/dest/mem_pools/tx_pool/priority.js +0 -15
  407. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  408. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  409. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  410. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  411. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  412. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  413. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -24
  414. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  415. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -378
  416. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  417. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  418. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  419. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  420. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  421. package/dest/services/reqresp/protocols/block.js +0 -32
  422. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -54
  423. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  424. package/dest/services/tx_collection/fast_tx_collection.js +0 -327
  425. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  426. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  427. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  428. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -49
  429. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  430. package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
  431. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
  432. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  433. package/dest/services/tx_collection/slow_tx_collection.js +0 -211
  434. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -345
  435. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  436. package/src/mem_pools/tx_pool/README.md +0 -270
  437. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  438. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  439. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  440. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  441. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  442. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  443. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  444. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  445. package/src/mem_pools/tx_pool/index.ts +0 -2
  446. package/src/mem_pools/tx_pool/priority.ts +0 -20
  447. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  448. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  449. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -373
  450. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  451. package/src/services/reqresp/protocols/block.ts +0 -37
  452. package/src/services/tx_collection/fast_tx_collection.ts +0 -387
  453. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
  454. package/src/services/tx_collection/proposal_tx_collector.ts +0 -113
  455. 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
  */
@@ -62,6 +71,7 @@ export class TxPoolV2Impl {
62
71
  #l2BlockSource: L2BlockSource;
63
72
  #worldStateSynchronizer: WorldStateSynchronizer;
64
73
  #createTxValidator: TxPoolV2Dependencies['createTxValidator'];
74
+ #checkAllowedSetupCalls: TxPoolV2Dependencies['checkAllowedSetupCalls'];
65
75
 
66
76
  // === In-Memory Indices ===
67
77
  #indices: TxPoolIndices = new TxPoolIndices();
@@ -73,7 +83,7 @@ export class TxPoolV2Impl {
73
83
  #evictionManager: EvictionManager;
74
84
  #dateProvider: DateProvider;
75
85
  #instrumentation: TxPoolV2Instrumentation;
76
- #evictedTxHashes: Set<string> = new Set();
86
+ #evictedTxHashes: FifoSet<string>;
77
87
  #log: Logger;
78
88
  #callbacks: TxPoolV2Callbacks;
79
89
 
@@ -93,8 +103,10 @@ export class TxPoolV2Impl {
93
103
  this.#l2BlockSource = deps.l2BlockSource;
94
104
  this.#worldStateSynchronizer = deps.worldStateSynchronizer;
95
105
  this.#createTxValidator = deps.createTxValidator;
106
+ this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
96
107
 
97
108
  this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
109
+ this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
98
110
  this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
99
111
  this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
100
112
  this.#dateProvider = dateProvider;
@@ -114,6 +126,7 @@ export class TxPoolV2Impl {
114
126
 
115
127
  // Post-event eviction rules (run after events to check ALL pending txs)
116
128
  this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
129
+ this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
117
130
  this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
118
131
  this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
119
132
  // LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
@@ -136,39 +149,67 @@ export class TxPoolV2Impl {
136
149
  // Step 0: Hydrate deleted pool state
137
150
  await this.#deletedPool.hydrateFromDatabase();
138
151
 
139
- // Step 1: Load all transactions from DB (excluding soft-deleted)
140
- const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
152
+ // Step 1: Stream txs from DB, building metadata and mined status one at a time.
153
+ const minedMetas: TxMetaData[] = [];
154
+ const pendingMetas: TxMetaData[] = [];
155
+ const deserializationErrors: string[] = [];
141
156
 
142
- // Step 2: Check mined status for each tx
143
- await this.#markMinedStatusBatch(loaded.map(l => l.meta));
157
+ for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
158
+ // Skip soft-deleted transactions - they stay in DB but not in indices
159
+ if (this.#deletedPool.isSoftDeleted(txHashStr)) {
160
+ continue;
161
+ }
144
162
 
145
- // Step 3: Partition by mined status
146
- const mined: TxMetaData[] = [];
147
- const nonMined: { tx: Tx; meta: TxMetaData }[] = [];
148
- for (const entry of loaded) {
149
- if (entry.meta.minedL2BlockId !== undefined) {
150
- mined.push(entry.meta);
163
+ let meta: TxMetaData;
164
+ let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
165
+ try {
166
+ const tx = Tx.fromBuffer(buffer);
167
+ // Resolve allowed-setup-calls and the tx effect concurrently
168
+ // getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
169
+ // its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
170
+ const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
171
+ this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
172
+ return undefined;
173
+ });
174
+ const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
175
+ this.#checkAllowedSetupCalls(tx),
176
+ txEffectPromise,
177
+ ]);
178
+ meta = await buildTxMetaData(tx, allowedSetupCalls);
179
+ txEffect = fetchedTxEffect;
180
+ } catch (err) {
181
+ this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
182
+ deserializationErrors.push(txHashStr);
183
+ continue;
184
+ }
185
+
186
+ if (txEffect) {
187
+ meta.minedL2BlockId = {
188
+ number: txEffect.l2BlockNumber,
189
+ hash: txEffect.l2BlockHash.toString(),
190
+ };
191
+ }
192
+
193
+ if (meta.minedL2BlockId !== undefined) {
194
+ minedMetas.push(meta);
151
195
  } else {
152
- nonMined.push(entry);
196
+ pendingMetas.push(meta);
153
197
  }
154
198
  }
155
199
 
156
- // Step 4: Validate non-mined transactions
157
- const { valid, invalid } = await this.#revalidateMetadata(
158
- nonMined.map(e => e.meta),
159
- 'on startup',
160
- );
200
+ // Step 2: Validate non-mined transactions
201
+ const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
161
202
 
162
- // Step 5: Populate mined indices (these don't need conflict resolution)
163
- for (const meta of mined) {
203
+ // Step 3: Populate mined indices (these don't need conflict resolution)
204
+ for (const meta of minedMetas) {
164
205
  this.#indices.addMined(meta);
165
206
  }
166
207
 
167
- // Step 6: Rebuild pending pool by running pre-add rules for each tx
208
+ // Step 4: Rebuild pending pool by running pre-add rules for each tx
168
209
  // This resolves nullifier conflicts, fee payer balance issues, and pool size limits
169
210
  const { rejected } = await this.#rebuildPendingPool(valid);
170
211
 
171
- // Step 7: Delete invalid and rejected txs from DB only (indices were never populated for these)
212
+ // Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
172
213
  const toDelete = [...deserializationErrors, ...invalid, ...rejected];
173
214
  if (toDelete.length === 0) {
174
215
  return;
@@ -214,7 +255,9 @@ export class TxPoolV2Impl {
214
255
  // in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
215
256
  const poolAccess = this.#createPreAddPoolAccess();
216
257
  const preAddContext: PreAddContext | undefined =
217
- opts.feeComparisonOnly !== undefined ? { feeComparisonOnly: opts.feeComparisonOnly } : undefined;
258
+ opts.feeComparisonOnly !== undefined
259
+ ? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
260
+ : undefined;
218
261
 
219
262
  await this.#store.transactionAsync(async () => {
220
263
  for (const tx of txs) {
@@ -352,6 +395,7 @@ export class TxPoolV2Impl {
352
395
 
353
396
  // Check if already in pool
354
397
  if (this.#indices.has(txHashStr)) {
398
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
355
399
  return 'ignored';
356
400
  }
357
401
 
@@ -360,26 +404,37 @@ export class TxPoolV2Impl {
360
404
  const poolAccess = this.#createPreAddPoolAccess();
361
405
  const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
362
406
 
363
- return preAddResult.shouldIgnore ? 'ignored' : 'accepted';
407
+ if (preAddResult.shouldIgnore) {
408
+ this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
409
+ reason: preAddResult.reason?.message ?? 'no reason provided',
410
+ });
411
+ return 'ignored';
412
+ }
413
+ return 'accepted';
364
414
  }
365
415
 
366
416
  async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
367
417
  const slotNumber = block.globalVariables.slotNumber;
368
418
 
419
+ // Precompute setup-call allow-list flags outside the store transaction
420
+ const allowedFlags = await Promise.all(txs.map(tx => this.#checkAllowedSetupCalls(tx)));
421
+
369
422
  await this.#store.transactionAsync(async () => {
370
- for (const tx of txs) {
423
+ for (let i = 0; i < txs.length; i++) {
424
+ const tx = txs[i];
371
425
  const txHash = tx.getTxHash();
372
426
  const txHashStr = txHash.toString();
373
427
  const isNew = !this.#indices.has(txHashStr);
374
428
  const minedBlockId = await this.#getMinedBlockId(txHash);
375
429
 
376
430
  if (isNew) {
431
+ const meta = await buildTxMetaData(tx, allowedFlags[i]);
377
432
  // New tx - add as mined or protected (callback emitted by #addTx)
378
433
  if (minedBlockId) {
379
- await this.#addTx(tx, { mined: minedBlockId }, opts);
434
+ await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
380
435
  this.#indices.setProtection(txHashStr, slotNumber);
381
436
  } else {
382
- await this.#addTx(tx, { protected: slotNumber }, opts);
437
+ await this.#addTx(tx, { protected: slotNumber }, opts, meta);
383
438
  }
384
439
  } else {
385
440
  // Existing tx - update protection and mined status
@@ -622,28 +677,29 @@ export class TxPoolV2Impl {
622
677
  // Step 1: Find mined txs at or before finalized block
623
678
  const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
624
679
 
625
- await this.#store.transactionAsync(async () => {
626
- // Step 2: Collect mined txs for archiving (before deletion)
627
- const txsToArchive: Tx[] = [];
628
- if (this.#archive.isEnabled()) {
629
- for (const txHashStr of minedTxsToFinalize) {
680
+ // Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
681
+ // mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
682
+ if (this.#archive.isEnabled()) {
683
+ for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
684
+ const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
685
+ const txsToArchive: Tx[] = [];
686
+ for (const txHashStr of chunk) {
630
687
  const buffer = await this.#txsDB.getAsync(txHashStr);
631
688
  if (buffer) {
632
689
  txsToArchive.push(Tx.fromBuffer(buffer));
633
690
  }
634
691
  }
692
+ if (txsToArchive.length > 0) {
693
+ await this.#archive.archiveTxs(txsToArchive);
694
+ }
635
695
  }
696
+ }
636
697
 
637
- // Step 3: Delete mined txs from active pool
698
+ // Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
699
+ // transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
700
+ await this.#store.transactionAsync(async () => {
638
701
  await this.#deleteTxsBatch(minedTxsToFinalize);
639
-
640
- // Step 4: Finalize soft-deleted txs
641
702
  await this.#deletedPool.finalizeBlock(blockNumber);
642
-
643
- // Step 5: Archive mined txs
644
- if (txsToArchive.length > 0) {
645
- await this.#archive.archiveTxs(txsToArchive);
646
- }
647
703
  });
648
704
 
649
705
  if (minedTxsToFinalize.length > 0) {
@@ -849,21 +905,11 @@ export class TxPoolV2Impl {
849
905
  this.#instrumentation.recordEvictions(txHashes.length, reason);
850
906
  for (const txHashStr of txHashes) {
851
907
  this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
852
- this.#addToEvictedCache(txHashStr);
908
+ this.#evictedTxHashes.add(txHashStr);
853
909
  }
854
910
  await this.#deleteTxsBatch(txHashes);
855
911
  }
856
912
 
857
- /** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
858
- #addToEvictedCache(txHashStr: string): void {
859
- if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
860
- // FIFO eviction: remove the first (oldest) entry
861
- const oldest = this.#evictedTxHashes.values().next().value!;
862
- this.#evictedTxHashes.delete(oldest);
863
- }
864
- this.#evictedTxHashes.add(txHashStr);
865
- }
866
-
867
913
  // ============================================================================
868
914
  // PRIVATE HELPERS - Validation & Conflict Resolution
869
915
  // ============================================================================
@@ -958,50 +1004,6 @@ export class TxPoolV2Impl {
958
1004
  };
959
1005
  }
960
1006
 
961
- /** Loads all transactions from the database, returning loaded txs and deserialization errors */
962
- async #loadAllTxsFromDb(): Promise<{
963
- loaded: { tx: Tx; meta: TxMetaData }[];
964
- errors: string[];
965
- }> {
966
- const loaded: { tx: Tx; meta: TxMetaData }[] = [];
967
- const errors: string[] = [];
968
-
969
- for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
970
- // Skip soft-deleted transactions - they stay in DB but not in indices
971
- if (this.#deletedPool.isSoftDeleted(txHashStr)) {
972
- continue;
973
- }
974
-
975
- try {
976
- const tx = Tx.fromBuffer(buffer);
977
- const meta = await buildTxMetaData(tx);
978
- loaded.push({ tx, meta });
979
- } catch (err) {
980
- this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
981
- errors.push(txHashStr);
982
- }
983
- }
984
-
985
- return { loaded, errors };
986
- }
987
-
988
- /** Queries block source and marks mined status on transaction metadata */
989
- async #markMinedStatusBatch(metas: TxMetaData[]): Promise<void> {
990
- for (const meta of metas) {
991
- try {
992
- const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
993
- if (txEffect) {
994
- meta.minedL2BlockId = {
995
- number: txEffect.l2BlockNumber,
996
- hash: txEffect.l2BlockHash.toString(),
997
- };
998
- }
999
- } catch (err) {
1000
- this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, { err });
1001
- }
1002
- }
1003
- }
1004
-
1005
1007
  /**
1006
1008
  * Rebuilds the pending pool by processing each tx through pre-add rules.
1007
1009
  * Starts with an empty pending pool and adds txs one by one, resolving conflicts.
@@ -0,0 +1,49 @@
1
+ # Attestation Validation
2
+
3
+ This module validates `CheckpointAttestation` gossipsub messages. Attestations are signatures from committee members endorsing a checkpoint proposal.
4
+
5
+ **Topic**: `checkpoint_attestation` | **Snappy size limit**: 5 KB
6
+
7
+ ## Stage 1: AttestationValidator (Gossipsub Validation)
8
+
9
+ | # | Rule | Consequence | Severity | File |
10
+ |---|------|-------------|----------|------|
11
+ | 1 | **Slot timeliness**: `currentSlot` or `nextSlot`. Previous slot within 500ms: IGNORE. Older: REJECT. | REJECT or IGNORE | HighToleranceError | `attestation_validator.ts` |
12
+ | 2 | **Attester signature**: `getSender()` must recover valid address | REJECT | LowToleranceError | same |
13
+ | 3 | **Attester in committee**: recovered address in committee for slot | REJECT | HighToleranceError | same |
14
+ | 4 | **Proposer exists**: `getProposerAttesterAddressInSlot` must return defined | REJECT | HighToleranceError | same |
15
+ | 5 | **Proposer signature**: `getProposer()` must recover valid address | REJECT | LowToleranceError | same |
16
+ | 6 | **Proposer matches expected**: recovered proposer = expected for slot | REJECT | HighToleranceError | same |
17
+ | 7 | **NoCommitteeError**: committee unavailable | REJECT | LowToleranceError | same |
18
+
19
+ **Fisherman mode extension** (`FishermanAttestationValidator`): if a checkpoint proposal for the same archive exists in pool, the attestation's `ConsensusPayload` must `.equals()` the stored proposal's payload. On mismatch: REJECT + LowToleranceError.
20
+
21
+ ## Stage 2: Pool Admission
22
+
23
+ | # | Rule | Consequence |
24
+ |---|------|-------------|
25
+ | 8 | Sender recoverable (pool-side) | Silent drop |
26
+ | 9 | Not a duplicate (same slot + proposalId + signer) | IGNORE |
27
+ | 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` = 2 | IGNORE |
28
+
29
+ Own attestations added via `addOwnCheckpointAttestations` bypass the per-signer cap.
30
+
31
+ ## Stage 3: Equivocation Detection
32
+
33
+ When a signer's attestation count for a slot reaches exactly 2 (different proposals): `duplicateAttestationCallback` fires -> `WANT_TO_SLASH_EVENT` with `OffenseType.DUPLICATE_ATTESTATION`. Attestation still ACCEPTED and rebroadcast. Callback fires once (not again at count 3+).
34
+
35
+ ## Validation at L1 Checkpoint Submission (Archiver)
36
+
37
+ | Rule | Consequence | File |
38
+ |------|-------------|------|
39
+ | Each attestation must have recoverable signature (or address-only is allowed but does not count toward quorum) | Checkpoint rejected as invalid | `archiver/src/modules/validation.ts` |
40
+ | Attestation at index `i` must correspond to committee member at index `i` | Checkpoint rejected as invalid | same |
41
+ | Valid attestation count >= floor(committee * 2/3) + 1 | Checkpoint rejected as invalid | same |
42
+ | No committee / escape hatch open | Accepted unconditionally | same |
43
+
44
+ Note: `skipValidateCheckpointAttestations` config flag bypasses all archiver attestation validation.
45
+
46
+ ## Gossipsub Topic Scoring
47
+
48
+ P3 enabled with expected messages per slot = `targetCommitteeSize`. Conservative threshold (30% of convergence value). Max P3 penalty = -34 per topic.
49
+
@@ -3,19 +3,35 @@ 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
12
 
11
- import { isWithinClockTolerance } from '../clock_tolerance.js';
13
+ import { PipeliningWindow, isWithinClockTolerance } from '../clock_tolerance.js';
12
14
 
13
15
  export class CheckpointAttestationValidator implements P2PValidator<CheckpointAttestation> {
14
16
  protected epochCache: EpochCacheInterface;
15
17
  protected logger: Logger;
18
+ private readonly pipeliningWindow: PipeliningWindow;
19
+ protected readonly signatureContext: CoordinationSignatureContext;
16
20
 
17
- constructor(epochCache: EpochCacheInterface) {
21
+ constructor(
22
+ epochCache: EpochCacheInterface,
23
+ opts: {
24
+ l1PublishingTime?: number;
25
+ p2pPropagationTime?: number;
26
+ signatureContext: CoordinationSignatureContext;
27
+ },
28
+ ) {
18
29
  this.epochCache = epochCache;
30
+ this.pipeliningWindow = new PipeliningWindow(epochCache, {
31
+ l1PublishingTime: opts.l1PublishingTime,
32
+ p2pPropagationTime: opts.p2pPropagationTime,
33
+ });
34
+ this.signatureContext = opts.signatureContext;
19
35
  this.logger = createLogger('p2p:checkpoint-attestation-validator');
20
36
  }
21
37
 
@@ -23,18 +39,34 @@ export class CheckpointAttestationValidator implements P2PValidator<CheckpointAt
23
39
  const slotNumber = message.payload.header.slotNumber;
24
40
 
25
41
  try {
26
- const { currentSlot, nextSlot } = this.epochCache.getCurrentAndNextSlot();
42
+ // Cross-chain replay check: reject attestations that carry a foreign signing domain.
43
+ if (!hasValidSignatureContext(message.payload, this.signatureContext)) {
44
+ this.logger.warn(`Rejecting checkpoint attestation with foreign signature context for slot ${slotNumber}`, {
45
+ chainId: message.payload.signatureContext.chainId,
46
+ rollupAddress: message.payload.signatureContext.rollupAddress.toString(),
47
+ expectedChainId: this.signatureContext.chainId,
48
+ expectedRollupAddress: this.signatureContext.rollupAddress.toString(),
49
+ });
50
+ return { result: 'reject', severity: PeerErrorSeverity.LowToleranceError };
51
+ }
52
+
53
+ // Use target slots since proposals target pipeline slots (slot + 1 when pipelining).
54
+ const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();
27
55
 
28
- if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
29
- // Check if message is for previous slot and within clock tolerance
30
- if (!isWithinClockTolerance(slotNumber, currentSlot, this.epochCache)) {
56
+ if (slotNumber !== targetSlot && slotNumber !== nextSlot) {
57
+ // When pipelining, accept attestations for the current slot (built in the previous slot)
58
+ // until the target slot reaches its L1 publish cutoff.
59
+ if (this.pipeliningWindow.acceptsAttestation(slotNumber)) {
60
+ // Fall through to remaining validation (signature, committee, etc.)
61
+ } else if (!isWithinClockTolerance(slotNumber, targetSlot, this.epochCache)) {
31
62
  this.logger.warn(
32
- `Checkpoint attestation slot ${slotNumber} is not current (${currentSlot}) or next (${nextSlot}) slot`,
63
+ `Checkpoint attestation slot ${slotNumber} is not current (${targetSlot}) or next (${nextSlot}) slot`,
33
64
  );
34
65
  return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
66
+ } else {
67
+ this.logger.debug(`Ignoring checkpoint attestation for previous slot ${slotNumber} within clock tolerance`);
68
+ return { result: 'ignore' };
35
69
  }
36
- this.logger.debug(`Ignoring checkpoint attestation for previous slot ${slotNumber} within clock tolerance`);
37
- return { result: 'ignore' };
38
70
  }
39
71
 
40
72
  // Verify the signature is valid
@@ -1,5 +1,10 @@
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';
3
8
  import { Attributes, Metrics, type TelemetryClient, createUpDownCounterWithDefault } from '@aztec/telemetry-client';
4
9
 
5
10
  import type { AttestationPoolApi } from '../../mem_pools/attestation_pool/attestation_pool.js';
@@ -20,8 +25,13 @@ export class FishermanAttestationValidator extends CheckpointAttestationValidato
20
25
  epochCache: EpochCacheInterface,
21
26
  private attestationPool: AttestationPoolApi,
22
27
  telemetryClient: TelemetryClient,
28
+ opts: {
29
+ l1PublishingTime?: number;
30
+ p2pPropagationTime?: number;
31
+ signatureContext: CoordinationSignatureContext;
32
+ },
23
33
  ) {
24
- super(epochCache);
34
+ super(epochCache, opts);
25
35
  this.logger = this.logger.createChild('[FISHERMAN]');
26
36
 
27
37
  const meter = telemetryClient.getMeter('FishermanAttestationValidator');
@@ -54,8 +64,7 @@ export class FishermanAttestationValidator extends CheckpointAttestationValidato
54
64
  return { result: 'accept' };
55
65
  }
56
66
 
57
- const proposalId = message.archive.toString();
58
- const proposal = await this.attestationPool.getCheckpointProposal(proposalId);
67
+ const proposal = await this.attestationPool.getCheckpointProposal(message.payload.header.slotNumber);
59
68
 
60
69
  if (proposal) {
61
70
  // Compare the attestation payload with the proposal payload
@@ -84,9 +93,7 @@ export class FishermanAttestationValidator extends CheckpointAttestationValidato
84
93
  }
85
94
  } else {
86
95
  // 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
- );
96
+ this.logger.debug(`Received attestation for slot ${slotNumberBigInt} but proposal not found yet.`);
90
97
  }
91
98
 
92
99
  return { result: 'accept' };
@@ -1,5 +1,6 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { DEFAULT_P2P_PROPAGATION_TIME, createPipelinedCheckpointTimingModel } from '@aztec/stdlib/timetable';
3
4
 
4
5
  /**
5
6
  * Maximum clock disparity tolerance for P2P message validation (in milliseconds).
@@ -36,10 +37,11 @@ export function isWithinClockTolerance(
36
37
  }
37
38
 
38
39
  // Check how far we are into the current slot (in milliseconds)
39
- const { ts: slotStartTs, nowMs, slot } = epochCache.getEpochAndSlotNow();
40
+ const { ts: slotStartTs, nowMs } = epochCache.getEpochAndSlotNow();
41
+ const targetSlot = epochCache.getTargetSlot();
40
42
 
41
- // Sanity check: ensure the epoch cache's current slot matches the expected current slot
42
- if (slot !== currentSlot) {
43
+ // Sanity check: ensure the epoch cache's target slot matches the expected current slot
44
+ if (targetSlot !== currentSlot) {
43
45
  return false;
44
46
  }
45
47
 
@@ -49,3 +51,71 @@ export function isWithinClockTolerance(
49
51
 
50
52
  return elapsedMs < MAXIMUM_GOSSIP_CLOCK_DISPARITY_MS;
51
53
  }
54
+
55
+ /**
56
+ * Checks if a straggler message for the previous target slot should be accepted.
57
+ *
58
+ * Proposals and attestations carry the target slot N. Most of the time the receiver is either
59
+ * still in the build slot N-1 (accepted via the main `slotNumber === targetSlot` match) or in the
60
+ * target slot N (accepted again via `targetSlot`). Stragglers that arrive after the receiver has
61
+ * rolled past the target slot fall to this check: accept `messageSlot === slotNow` while we're
62
+ * still within the first `windowSeconds + clock-disparity` of the slot.
63
+ *
64
+ * Under the early-pipelining schedule `windowSeconds` is small (0 for proposals,
65
+ * `2*p2pPropagationTime` for attestations) since the proposer collects everything
66
+ * before the slot boundary.
67
+ *
68
+ * @param messageSlot - The slot number from the received message
69
+ * @param epochCache - EpochCache to get timing state
70
+ * @param windowSeconds - How far into the current slot we still accept previous-target messages
71
+ * @returns true if the message is for the current wallclock slot and we're within the grace period
72
+ */
73
+ function isWithinPipeliningWindow(
74
+ messageSlot: SlotNumber,
75
+ epochCache: EpochCacheInterface,
76
+ windowSeconds: number,
77
+ ): boolean {
78
+ const currentSlot = epochCache.getSlotNow();
79
+ if (messageSlot !== currentSlot) {
80
+ return false;
81
+ }
82
+
83
+ const { ts: slotStartTs, nowMs } = epochCache.getEpochAndSlotNow();
84
+ const slotStartMs = slotStartTs * 1000n;
85
+ const elapsedMs = Number(nowMs - slotStartMs);
86
+ const windowMs = windowSeconds * 1000 + MAXIMUM_GOSSIP_CLOCK_DISPARITY_MS;
87
+
88
+ return elapsedMs < windowMs;
89
+ }
90
+
91
+ export class PipeliningWindow {
92
+ private readonly proposalWindowIntoTargetSlot: number;
93
+ private readonly attestationWindowIntoTargetSlot: number;
94
+
95
+ constructor(
96
+ private readonly epochCache: EpochCacheInterface,
97
+ opts: {
98
+ p2pPropagationTime?: number;
99
+ l1PublishingTime?: number;
100
+ } = {},
101
+ ) {
102
+ const l1Constants = epochCache.getL1Constants();
103
+ const checkpointTiming = createPipelinedCheckpointTimingModel({
104
+ aztecSlotDuration: l1Constants.slotDuration,
105
+ ethereumSlotDuration: l1Constants.ethereumSlotDuration,
106
+ l1PublishingTime: opts.l1PublishingTime ?? l1Constants.ethereumSlotDuration,
107
+ p2pPropagationTime: opts.p2pPropagationTime ?? DEFAULT_P2P_PROPAGATION_TIME,
108
+ });
109
+
110
+ this.proposalWindowIntoTargetSlot = checkpointTiming.proposalWindowIntoTargetSlot;
111
+ this.attestationWindowIntoTargetSlot = checkpointTiming.attestationWindowIntoTargetSlot;
112
+ }
113
+
114
+ public acceptsProposal(messageSlot: SlotNumber): boolean {
115
+ return isWithinPipeliningWindow(messageSlot, this.epochCache, this.proposalWindowIntoTargetSlot);
116
+ }
117
+
118
+ public acceptsAttestation(messageSlot: SlotNumber): boolean {
119
+ return isWithinPipeliningWindow(messageSlot, this.epochCache, this.attestationWindowIntoTargetSlot);
120
+ }
121
+ }