@aztec/p2p 0.0.1-commit.f2ce05ee → 0.0.1-commit.f504929

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 (326) hide show
  1. package/dest/client/factory.d.ts +8 -8
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +37 -13
  4. package/dest/client/interface.d.ts +39 -33
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +37 -50
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +138 -199
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
  10. package/dest/config.d.ts +29 -15
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +39 -35
  13. package/dest/errors/tx-pool.error.d.ts +8 -0
  14. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  15. package/dest/errors/tx-pool.error.js +9 -0
  16. package/dest/index.d.ts +2 -1
  17. package/dest/index.d.ts.map +1 -1
  18. package/dest/index.js +1 -0
  19. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +21 -12
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/attestation_pool.js +72 -38
  22. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  24. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +53 -53
  25. package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
  26. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  27. package/dest/mem_pools/attestation_pool/index.js +1 -1
  28. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  29. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  31. package/dest/mem_pools/index.d.ts +2 -1
  32. package/dest/mem_pools/index.d.ts.map +1 -1
  33. package/dest/mem_pools/instrumentation.d.ts +4 -2
  34. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  35. package/dest/mem_pools/instrumentation.js +16 -14
  36. package/dest/mem_pools/interface.d.ts +3 -3
  37. package/dest/mem_pools/interface.d.ts.map +1 -1
  38. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  39. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  40. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  41. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  42. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  43. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  45. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +5 -2
  48. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  49. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  50. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  51. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  52. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  54. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +48 -5
  55. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  56. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  57. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
  58. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +7 -5
  59. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  60. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +14 -6
  62. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  63. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +14 -4
  65. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  66. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
  68. package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
  69. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/index.js +2 -1
  71. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  72. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  73. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  74. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +22 -8
  75. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  76. package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
  77. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +56 -8
  78. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  79. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +108 -10
  80. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
  81. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  82. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +36 -14
  83. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -4
  84. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  85. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +14 -6
  86. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +14 -5
  87. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  88. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +344 -184
  89. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +2 -1
  90. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  91. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +2 -1
  92. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  93. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -1
  94. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  95. package/dest/msg_validators/proposal_validator/proposal_validator.js +10 -0
  96. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +2 -1
  97. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -1
  98. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +166 -0
  99. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  100. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  102. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  103. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/allowed_public_setup.js +25 -10
  105. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  106. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  107. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  108. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  109. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  110. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  111. package/dest/msg_validators/tx_validator/factory.d.ts +114 -6
  112. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  113. package/dest/msg_validators/tx_validator/factory.js +219 -58
  114. package/dest/msg_validators/tx_validator/gas_validator.d.ts +58 -3
  115. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  116. package/dest/msg_validators/tx_validator/gas_validator.js +73 -36
  117. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  118. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  119. package/dest/msg_validators/tx_validator/index.js +1 -0
  120. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  121. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  122. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  123. package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
  124. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  125. package/dest/msg_validators/tx_validator/phases_validator.js +25 -24
  126. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  127. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  128. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  129. package/dest/services/dummy_service.d.ts +9 -5
  130. package/dest/services/dummy_service.d.ts.map +1 -1
  131. package/dest/services/dummy_service.js +7 -4
  132. package/dest/services/encoding.d.ts +3 -3
  133. package/dest/services/encoding.d.ts.map +1 -1
  134. package/dest/services/encoding.js +11 -10
  135. package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
  136. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  137. package/dest/services/gossipsub/topic_score_params.js +32 -10
  138. package/dest/services/libp2p/libp2p_service.d.ts +25 -14
  139. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  140. package/dest/services/libp2p/libp2p_service.js +143 -114
  141. package/dest/services/peer-manager/metrics.d.ts +3 -1
  142. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  143. package/dest/services/peer-manager/metrics.js +6 -0
  144. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  145. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  146. package/dest/services/peer-manager/peer_manager.js +2 -1
  147. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
  148. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  149. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +19 -46
  150. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
  151. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  152. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
  153. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  154. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
  155. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +17 -11
  156. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  157. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +49 -15
  158. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  159. package/dest/services/reqresp/interface.d.ts +10 -1
  160. package/dest/services/reqresp/interface.d.ts.map +1 -1
  161. package/dest/services/reqresp/interface.js +15 -1
  162. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
  163. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  164. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
  165. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  166. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +15 -0
  167. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  168. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  169. package/dest/services/reqresp/protocols/tx.js +20 -0
  170. package/dest/services/reqresp/reqresp.d.ts +1 -1
  171. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  172. package/dest/services/reqresp/reqresp.js +13 -5
  173. package/dest/services/service.d.ts +22 -3
  174. package/dest/services/service.d.ts.map +1 -1
  175. package/dest/services/tx_collection/config.d.ts +19 -1
  176. package/dest/services/tx_collection/config.d.ts.map +1 -1
  177. package/dest/services/tx_collection/config.js +46 -0
  178. package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -1
  179. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  180. package/dest/services/tx_collection/fast_tx_collection.js +56 -36
  181. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  182. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  183. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  184. package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
  185. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  186. package/dest/services/tx_collection/file_store_tx_source.js +90 -0
  187. package/dest/services/tx_collection/index.d.ts +2 -1
  188. package/dest/services/tx_collection/index.d.ts.map +1 -1
  189. package/dest/services/tx_collection/index.js +1 -0
  190. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  191. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  192. package/dest/services/tx_collection/instrumentation.js +2 -1
  193. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  194. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  195. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  196. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  197. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  198. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  199. package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
  200. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  201. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  202. package/dest/services/tx_collection/tx_collection.d.ts +23 -10
  203. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  204. package/dest/services/tx_collection/tx_collection.js +75 -3
  205. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  206. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  207. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  208. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  209. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  210. package/dest/services/tx_collection/tx_source.js +19 -2
  211. package/dest/services/tx_file_store/config.d.ts +1 -3
  212. package/dest/services/tx_file_store/config.d.ts.map +1 -1
  213. package/dest/services/tx_file_store/config.js +0 -4
  214. package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
  215. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  216. package/dest/services/tx_file_store/tx_file_store.js +9 -6
  217. package/dest/services/tx_provider.d.ts +4 -4
  218. package/dest/services/tx_provider.d.ts.map +1 -1
  219. package/dest/services/tx_provider.js +9 -8
  220. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  221. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  222. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  223. package/dest/test-helpers/mock-pubsub.d.ts +30 -4
  224. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  225. package/dest/test-helpers/mock-pubsub.js +105 -4
  226. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  227. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  228. package/dest/test-helpers/reqresp-nodes.js +2 -2
  229. package/dest/test-helpers/testbench-utils.d.ts +35 -24
  230. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  231. package/dest/test-helpers/testbench-utils.js +93 -35
  232. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  233. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  234. package/dest/testbench/p2p_client_testbench_worker.js +14 -14
  235. package/dest/util.d.ts +2 -2
  236. package/dest/util.d.ts.map +1 -1
  237. package/package.json +14 -14
  238. package/src/client/factory.ts +71 -23
  239. package/src/client/interface.ts +43 -33
  240. package/src/client/p2p_client.ts +164 -243
  241. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -10
  242. package/src/config.ts +60 -42
  243. package/src/errors/tx-pool.error.ts +12 -0
  244. package/src/index.ts +1 -0
  245. package/src/mem_pools/attestation_pool/attestation_pool.ts +100 -48
  246. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +57 -53
  247. package/src/mem_pools/attestation_pool/index.ts +3 -3
  248. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  249. package/src/mem_pools/index.ts +3 -0
  250. package/src/mem_pools/instrumentation.ts +17 -13
  251. package/src/mem_pools/interface.ts +2 -2
  252. package/src/mem_pools/tx_pool/README.md +1 -1
  253. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  254. package/src/mem_pools/tx_pool_v2/README.md +76 -10
  255. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  256. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  257. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +5 -2
  258. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  259. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  260. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +49 -4
  261. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
  262. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
  263. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -9
  264. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +24 -6
  265. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +3 -3
  266. package/src/mem_pools/tx_pool_v2/index.ts +2 -1
  267. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  268. package/src/mem_pools/tx_pool_v2/interfaces.ts +23 -8
  269. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +153 -17
  270. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -16
  271. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +21 -7
  272. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +388 -182
  273. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +1 -1
  274. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +1 -1
  275. package/src/msg_validators/proposal_validator/proposal_validator.ts +15 -1
  276. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +144 -1
  277. package/src/msg_validators/tx_validator/README.md +115 -0
  278. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
  279. package/src/msg_validators/tx_validator/allowed_public_setup.ts +27 -13
  280. package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
  281. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  282. package/src/msg_validators/tx_validator/factory.ts +353 -77
  283. package/src/msg_validators/tx_validator/gas_validator.ts +90 -27
  284. package/src/msg_validators/tx_validator/index.ts +1 -0
  285. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  286. package/src/msg_validators/tx_validator/phases_validator.ts +25 -29
  287. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  288. package/src/services/dummy_service.ts +12 -6
  289. package/src/services/encoding.ts +9 -9
  290. package/src/services/gossipsub/README.md +29 -14
  291. package/src/services/gossipsub/topic_score_params.ts +49 -13
  292. package/src/services/libp2p/libp2p_service.ts +153 -123
  293. package/src/services/peer-manager/metrics.ts +7 -0
  294. package/src/services/peer-manager/peer_manager.ts +2 -1
  295. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +20 -48
  296. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
  297. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
  298. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +63 -24
  299. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  300. package/src/services/reqresp/interface.ts +26 -1
  301. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +2 -2
  302. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
  303. package/src/services/reqresp/protocols/tx.ts +22 -0
  304. package/src/services/reqresp/reqresp.ts +16 -4
  305. package/src/services/service.ts +31 -2
  306. package/src/services/tx_collection/config.ts +68 -0
  307. package/src/services/tx_collection/fast_tx_collection.ts +65 -32
  308. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  309. package/src/services/tx_collection/file_store_tx_source.ts +117 -0
  310. package/src/services/tx_collection/index.ts +1 -0
  311. package/src/services/tx_collection/instrumentation.ts +7 -1
  312. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  313. package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
  314. package/src/services/tx_collection/slow_tx_collection.ts +66 -33
  315. package/src/services/tx_collection/tx_collection.ts +113 -16
  316. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  317. package/src/services/tx_collection/tx_source.ts +22 -3
  318. package/src/services/tx_file_store/config.ts +0 -6
  319. package/src/services/tx_file_store/tx_file_store.ts +10 -8
  320. package/src/services/tx_provider.ts +10 -9
  321. package/src/test-helpers/make-test-p2p-clients.ts +3 -5
  322. package/src/test-helpers/mock-pubsub.ts +146 -9
  323. package/src/test-helpers/reqresp-nodes.ts +2 -5
  324. package/src/test-helpers/testbench-utils.ts +108 -40
  325. package/src/testbench/p2p_client_testbench_worker.ts +23 -20
  326. package/src/util.ts +7 -1
@@ -1,6 +1,5 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
- import { randomInt } from '@aztec/foundation/crypto/random';
4
3
  import { Fr } from '@aztec/foundation/curves/bn254';
5
4
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
6
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
@@ -17,13 +16,12 @@ import {
17
16
  CheckpointProposal,
18
17
  type CheckpointProposalCore,
19
18
  type Gossipable,
20
- P2PClientType,
21
19
  P2PMessage,
22
20
  type ValidationResult as P2PValidationResult,
23
21
  PeerErrorSeverity,
24
22
  TopicType,
25
23
  createTopicString,
26
- getTopicsForClientAndConfig,
24
+ getTopicsForConfig,
27
25
  metricsTopicStrToLabels,
28
26
  } from '@aztec/stdlib/p2p';
29
27
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -70,9 +68,11 @@ import {
70
68
  } from '../../msg_validators/index.js';
71
69
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
72
70
  import {
73
- type MessageValidator,
74
- createTxMessageValidators,
75
- createTxReqRespValidator,
71
+ type TransactionValidator,
72
+ createFirstStageTxValidationsForGossipedTransactions,
73
+ createSecondStageTxValidationsForGossipedTransactions,
74
+ createTxValidatorForBlockProposalReceivedTxs,
75
+ createTxValidatorForReqResponseReceivedTxs,
76
76
  } from '../../msg_validators/tx_validator/factory.js';
77
77
  import { GossipSubEvent } from '../../types/index.js';
78
78
  import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
@@ -88,6 +88,9 @@ import { PeerScoring } from '../peer-manager/peer_scoring.js';
88
88
  import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
89
89
  import type { P2PReqRespConfig } from '../reqresp/config.js';
90
90
  import {
91
+ AuthRequest,
92
+ BlockTxsRequest,
93
+ BlockTxsResponse,
91
94
  DEFAULT_SUB_PROTOCOL_VALIDATORS,
92
95
  type ReqRespInterface,
93
96
  type ReqRespResponse,
@@ -95,14 +98,9 @@ import {
95
98
  type ReqRespSubProtocolHandler,
96
99
  type ReqRespSubProtocolHandlers,
97
100
  type ReqRespSubProtocolValidators,
101
+ StatusMessage,
98
102
  type SubProtocolMap,
99
103
  ValidationError,
100
- } from '../reqresp/index.js';
101
- import {
102
- AuthRequest,
103
- BlockTxsRequest,
104
- BlockTxsResponse,
105
- StatusMessage,
106
104
  pingHandler,
107
105
  reqGoodbyeHandler,
108
106
  reqRespBlockHandler,
@@ -114,6 +112,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
114
112
  import type {
115
113
  P2PBlockReceivedCallback,
116
114
  P2PCheckpointReceivedCallback,
115
+ P2PDuplicateAttestationCallback,
117
116
  P2PService,
118
117
  PeerDiscoveryService,
119
118
  } from '../service.js';
@@ -135,7 +134,7 @@ type ReceivedMessageValidationResult<T, M = undefined> =
135
134
  /**
136
135
  * Lib P2P implementation of the P2PService interface.
137
136
  */
138
- export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
137
+ export class LibP2PService extends WithTracer implements P2PService {
139
138
  private discoveryRunningPromise?: RunningPromise;
140
139
  private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
141
140
 
@@ -156,6 +155,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
156
155
  type: 'checkpoint' | 'block';
157
156
  }) => void;
158
157
 
158
+ /** Callback invoked when a duplicate attestation is detected (triggers slashing). */
159
+ private duplicateAttestationCallback?: P2PDuplicateAttestationCallback;
160
+
159
161
  /**
160
162
  * Callback for when a block is received from a peer.
161
163
  * @param block - The block received from the peer.
@@ -179,7 +181,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
179
181
  protected logger: Logger;
180
182
 
181
183
  constructor(
182
- private clientType: T,
183
184
  private config: P2PConfig,
184
185
  protected node: PubSubLibp2p,
185
186
  private peerDiscoveryService: PeerDiscoveryService,
@@ -221,9 +222,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
221
222
  this.protocolVersion,
222
223
  );
223
224
 
224
- this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
225
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, {
226
+ txsPermitted: !config.disableTransactions,
227
+ maxTxsPerBlock: config.maxTxsPerBlock,
228
+ });
225
229
  this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
226
230
  txsPermitted: !config.disableTransactions,
231
+ maxTxsPerBlock: config.maxTxsPerBlock,
227
232
  });
228
233
  this.checkpointAttestationValidator = config.fishermanMode
229
234
  ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
@@ -259,8 +264,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
259
264
  * @param txPool - The transaction pool to be accessed by the service.
260
265
  * @returns The new service.
261
266
  */
262
- public static async new<T extends P2PClientType>(
263
- clientType: T,
267
+ public static async new(
264
268
  config: P2PConfig,
265
269
  peerId: PeerId,
266
270
  deps: {
@@ -338,6 +342,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
338
342
  heartbeatIntervalMs: config.gossipsubInterval,
339
343
  targetCommitteeSize: l1Constants.targetCommitteeSize,
340
344
  blockDurationMs: config.blockDurationMs,
345
+ expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
341
346
  });
342
347
 
343
348
  const node = await createLibp2p({
@@ -471,7 +476,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
471
476
  peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
472
477
 
473
478
  return new LibP2PService(
474
- clientType,
475
479
  config,
476
480
  node,
477
481
  peerDiscoveryService,
@@ -545,7 +549,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
545
549
  await this.node.start();
546
550
 
547
551
  // Subscribe to standard GossipSub topics by default
548
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
552
+ for (const topic of getTopicsForConfig(this.config.disableTransactions)) {
549
553
  this.subscribeToTopic(this.topicStrings[topic]);
550
554
  }
551
555
 
@@ -611,6 +615,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
611
615
  return this.peerManager.getPeers(includePending);
612
616
  }
613
617
 
618
+ public getGossipMeshPeerCount(topicType: TopicType): number {
619
+ return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
620
+ }
621
+
614
622
  private handleGossipSubEvent(e: CustomEvent<GossipsubMessage>) {
615
623
  this.logger.trace(`Received PUBSUB message.`);
616
624
 
@@ -673,6 +681,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
673
681
  this.duplicateProposalCallback = callback;
674
682
  }
675
683
 
684
+ /**
685
+ * Registers a callback to be invoked when a duplicate attestation is detected.
686
+ * A validator signing attestations for different proposals at the same slot.
687
+ * This callback is triggered on the first duplicate (when count goes from 1 to 2).
688
+ */
689
+ public registerDuplicateAttestationCallback(callback: P2PDuplicateAttestationCallback): void {
690
+ this.duplicateAttestationCallback = callback;
691
+ }
692
+
676
693
  /**
677
694
  * Subscribes to a topic.
678
695
  * @param topic - The topic to subscribe to.
@@ -801,9 +818,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
801
818
  if (msg.topic === this.topicStrings[TopicType.tx]) {
802
819
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
803
820
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
804
- if (this.clientType === P2PClientType.Full) {
805
- await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
806
- }
821
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
807
822
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
808
823
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
809
824
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
@@ -889,21 +904,63 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
889
904
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
890
905
  const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
891
906
  const tx = Tx.fromBuffer(payloadData);
892
- const isValid = await this.validatePropagatedTx(tx, source);
893
- const exists = isValid && (await this.mempools.txPool.hasTx(tx.getTxHash()));
907
+
908
+ const currentBlockNumber = await this.archiver.getBlockNumber();
909
+ const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
910
+
911
+ // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
912
+ const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
913
+ const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
914
+ if (!firstStageOutcome.allPassed) {
915
+ const { name } = firstStageOutcome.failure;
916
+ let { severity } = firstStageOutcome.failure;
917
+
918
+ // Double spend validator has a special case handler. We perform more detailed examination
919
+ // as to how recently the nullifier was entered into the tree and if the transaction should
920
+ // have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
921
+ if (name === 'doubleSpendValidator') {
922
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1);
923
+ severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
924
+ }
925
+
926
+ this.peerManager.penalizePeer(source, severity);
927
+ return { result: TopicValidatorResult.Reject };
928
+ }
929
+
930
+ // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
931
+ const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
932
+ if (canAdd === 'ignored') {
933
+ return { result: TopicValidatorResult.Ignore, obj: tx };
934
+ }
935
+
936
+ // Stage 2: expensive proof verification
937
+ const secondStageValidators = this.createSecondStageMessageValidators();
938
+ const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
939
+ if (!secondStageOutcome.allPassed) {
940
+ const { severity } = secondStageOutcome.failure;
941
+ this.peerManager.penalizePeer(source, severity);
942
+ return { result: TopicValidatorResult.Reject };
943
+ }
944
+
945
+ // Pool add: persist the tx
946
+ const txHash = tx.getTxHash();
947
+ const addResult = await this.mempools.txPool.addPendingTxs([tx], { source: 'gossip' });
948
+
949
+ const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
950
+ const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
894
951
 
895
952
  this.logger.trace(`Validate propagated tx`, {
896
- isValid,
897
- exists,
953
+ wasAccepted,
954
+ wasIgnored,
898
955
  [Attributes.P2P_ID]: source.toString(),
899
956
  });
900
957
 
901
- if (!isValid) {
902
- return { result: TopicValidatorResult.Reject };
903
- } else if (exists) {
958
+ if (wasAccepted) {
959
+ return { result: TopicValidatorResult.Accept, obj: tx };
960
+ } else if (wasIgnored) {
904
961
  return { result: TopicValidatorResult.Ignore, obj: tx };
905
962
  } else {
906
- return { result: TopicValidatorResult.Accept, obj: tx };
963
+ return { result: TopicValidatorResult.Reject };
907
964
  }
908
965
  };
909
966
 
@@ -912,6 +969,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
912
969
  return;
913
970
  }
914
971
 
972
+ // Tx was accepted into pool and will be propagated - just log and record metrics
915
973
  const txHash = tx.getTxHash();
916
974
  const txHashString = txHash.toString();
917
975
  this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
@@ -919,13 +977,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
919
977
  txHash: txHashString,
920
978
  });
921
979
 
922
- if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
923
- this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
924
- return;
925
- }
926
-
927
980
  this.instrumentation.incrementTxReceived(1);
928
- await this.mempools.txPool.addTxs([tx]);
929
981
  }
930
982
 
931
983
  /**
@@ -979,40 +1031,53 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
979
1031
  return { result: TopicValidatorResult.Ignore, obj: attestation };
980
1032
  }
981
1033
 
982
- // Get committee size for the attestation's slot
983
- const slot = attestation.payload.header.slotNumber;
984
- const { committee } = await this.epochCache.getCommittee(slot);
985
- const committeeSize = committee?.length ?? 0;
986
-
987
1034
  // Try to add the attestation: this handles existence check, cap check, and adding in one call
988
- const { added, alreadyExists } = await this.mempools.attestationPool.tryAddCheckpointAttestation(
989
- attestation,
990
- committeeSize,
991
- );
1035
+ // count is the number of attestations by this signer for this slot (for duplicate detection)
1036
+ const slot = attestation.payload.header.slotNumber;
1037
+ const { added, alreadyExists, count } =
1038
+ await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation);
992
1039
 
993
1040
  this.logger.trace(`Validate propagated checkpoint attestation`, {
994
1041
  added,
995
1042
  alreadyExists,
1043
+ count,
996
1044
  [Attributes.SLOT_NUMBER]: slot.toString(),
997
1045
  [Attributes.P2P_ID]: peerId.toString(),
998
1046
  });
999
1047
 
1000
- // Duplicate attestation received, no need to re-broadcast
1048
+ // Exact same attestation received, no need to re-broadcast
1001
1049
  if (alreadyExists) {
1002
1050
  return { result: TopicValidatorResult.Ignore, obj: attestation };
1003
1051
  }
1004
1052
 
1005
- // Could not add (cap reached), no need to re-broadcast
1053
+ // Could not add (cap reached for signer), no need to re-broadcast
1006
1054
  if (!added) {
1007
- this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
1055
+ this.logger.warn(`Dropping checkpoint attestation due to cap`, {
1008
1056
  slot: slot.toString(),
1009
1057
  archive: attestation.archive.toString(),
1010
1058
  source: peerId.toString(),
1059
+ attester: attestation.getSender()?.toString(),
1060
+ count,
1011
1061
  });
1012
1062
  return { result: TopicValidatorResult.Ignore, obj: attestation };
1013
1063
  }
1014
1064
 
1015
- // Attestation was added successfully
1065
+ // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
1066
+ // count is the number of attestations by this signer for this slot
1067
+ if (count === 2) {
1068
+ const attester = attestation.getSender();
1069
+ if (attester) {
1070
+ this.logger.warn(`Detected duplicate attestation (equivocation) at slot ${slot}`, {
1071
+ slot: slot.toString(),
1072
+ archive: attestation.archive.toString(),
1073
+ source: peerId.toString(),
1074
+ attester: attester.toString(),
1075
+ });
1076
+ this.duplicateAttestationCallback?.({ slot, attester });
1077
+ }
1078
+ }
1079
+
1080
+ // Attestation was added successfully - accept it so other nodes can also detect the equivocation
1016
1081
  return { result: TopicValidatorResult.Accept, obj: attestation };
1017
1082
  }
1018
1083
 
@@ -1058,8 +1123,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1058
1123
  }
1059
1124
 
1060
1125
  // Try to add the proposal: this handles existence check, cap check, and adding in one call
1061
- const { added, alreadyExists, totalForPosition } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1062
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1126
+ const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1127
+ const isEquivocated = count !== undefined && count > 1;
1063
1128
 
1064
1129
  // Duplicate proposal received, no need to re-broadcast
1065
1130
  if (alreadyExists) {
@@ -1078,7 +1143,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1078
1143
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1079
1144
  ...block.toBlockInfo(),
1080
1145
  indexWithinCheckpoint: block.indexWithinCheckpoint,
1081
- totalForPosition,
1146
+ count,
1082
1147
  proposer: block.getSender()?.toString(),
1083
1148
  source: peerId.toString(),
1084
1149
  });
@@ -1095,7 +1160,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1095
1160
  proposer: proposer?.toString(),
1096
1161
  });
1097
1162
  // Invoke the duplicate callback on the first duplicate spotted only
1098
- if (proposer && totalForPosition === 2) {
1163
+ if (proposer && count === 2) {
1099
1164
  this.duplicateProposalCallback?.({ slot: block.slotNumber, proposer, type: 'block' });
1100
1165
  }
1101
1166
  return { result: TopicValidatorResult.Accept, obj: block, metadata: { isEquivocated } };
@@ -1120,8 +1185,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1120
1185
  ...block.toBlockInfo(),
1121
1186
  });
1122
1187
 
1123
- // Mark the txs in this proposal as non-evictable
1124
- await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
1188
+ // Mark the txs in this proposal as protected
1189
+ await this.mempools.txPool.protectTxs(block.txHashes, block.blockHeader);
1125
1190
 
1126
1191
  // Call the block received callback to validate the proposal.
1127
1192
  // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
@@ -1212,8 +1277,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1212
1277
  // Try to add the checkpoint proposal core: this handles existence check, cap check, and adding in one call
1213
1278
  const checkpointCore = checkpoint.toCore();
1214
1279
  const tryAddResult = await this.mempools.attestationPool.tryAddCheckpointProposal(checkpointCore);
1215
- const { added, alreadyExists, totalForPosition } = tryAddResult;
1216
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1280
+ const { added, alreadyExists, count } = tryAddResult;
1281
+ const isEquivocated = count !== undefined && count > 1;
1217
1282
 
1218
1283
  // Duplicate proposal received, do not re-broadcast
1219
1284
  if (alreadyExists) {
@@ -1234,7 +1299,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1234
1299
  this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1235
1300
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1236
1301
  ...checkpoint.toCheckpointInfo(),
1237
- totalForPosition,
1302
+ count,
1238
1303
  source: peerId.toString(),
1239
1304
  });
1240
1305
  return { result: TopicValidatorResult.Reject, obj: checkpoint, metadata: { isEquivocated, processBlock } };
@@ -1250,7 +1315,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1250
1315
  proposer: proposer?.toString(),
1251
1316
  });
1252
1317
  // Invoke the duplicate callback on the first duplicate spotted only
1253
- if (proposer && totalForPosition === 2) {
1318
+ if (proposer && count === 2) {
1254
1319
  this.duplicateProposalCallback?.({ slot: checkpoint.slotNumber, proposer, type: 'checkpoint' });
1255
1320
  }
1256
1321
  return {
@@ -1499,43 +1564,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1499
1564
  }
1500
1565
 
1501
1566
  protected createRequestedTxValidator(): TxValidator {
1502
- return createTxReqRespValidator(this.proofVerifier, {
1567
+ return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
1503
1568
  l1ChainId: this.config.l1ChainId,
1504
1569
  rollupVersion: this.config.rollupVersion,
1505
1570
  });
1506
1571
  }
1507
1572
 
1508
- @trackSpan('Libp2pService.validatePropagatedTx', tx => ({
1509
- [Attributes.TX_HASH]: tx.getTxHash().toString(),
1510
- }))
1511
- private async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
1512
- const currentBlockNumber = await this.archiver.getBlockNumber();
1513
-
1514
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1515
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1516
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1517
-
1518
- for (const validator of messageValidators) {
1519
- const outcome = await this.runValidations(tx, validator);
1520
-
1521
- if (outcome.allPassed) {
1522
- continue;
1523
- }
1524
- const { name } = outcome.failure;
1525
- let { severity } = outcome.failure;
1526
-
1527
- // Double spend validator has a special case handler
1528
- if (name === 'doubleSpendValidator') {
1529
- const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1530
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1531
- }
1532
-
1533
- this.peerManager.penalizePeer(peerId, severity);
1534
- return false;
1535
- }
1536
- return true;
1537
- }
1538
-
1539
1573
  private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
1540
1574
  if (blockNumber === this.feesCache?.blockNumber) {
1541
1575
  return this.feesCache.gasFees;
@@ -1563,60 +1597,56 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1563
1597
  };
1564
1598
  }
1565
1599
 
1566
- public async validate(txs: Tx[]): Promise<void> {
1567
- const currentBlockNumber = await this.archiver.getBlockNumber();
1568
-
1569
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1570
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1571
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1600
+ public async validateTxsReceivedInBlockProposal(txs: Tx[]): Promise<void> {
1601
+ const validator = createTxValidatorForBlockProposalReceivedTxs(
1602
+ this.proofVerifier,
1603
+ { l1ChainId: this.config.l1ChainId, rollupVersion: this.config.rollupVersion },
1604
+ this.logger.getBindings(),
1605
+ );
1572
1606
 
1573
- await Promise.all(
1607
+ const results = await Promise.all(
1574
1608
  txs.map(async tx => {
1575
- for (const validator of messageValidators) {
1576
- const outcome = await this.runValidations(tx, validator);
1577
- if (!outcome.allPassed) {
1578
- throw new Error('Invalid tx detected', { cause: { outcome } });
1579
- }
1580
- }
1609
+ const result = await validator.validateTx(tx);
1610
+ return result.result !== 'invalid';
1581
1611
  }),
1582
1612
  );
1613
+ if (results.some(value => value === false)) {
1614
+ throw new Error('Invalid tx detected');
1615
+ }
1583
1616
  }
1584
1617
 
1585
- /**
1586
- * Create message validators for the given block number and timestamp.
1587
- *
1588
- * Each validator is a pair of a validator and a severity.
1589
- * If a validator fails, the peer is penalized with the severity of the validator.
1590
- *
1591
- * @param currentBlockNumber - The current synced block number.
1592
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
1593
- * @returns The message validators.
1594
- */
1595
- private async createMessageValidators(
1618
+ /** Creates the first stage (fast) validators for gossiped transactions. */
1619
+ protected async createFirstStageMessageValidators(
1596
1620
  currentBlockNumber: BlockNumber,
1597
1621
  nextSlotTimestamp: UInt64,
1598
- ): Promise<Record<string, MessageValidator>[]> {
1622
+ ): Promise<Record<string, TransactionValidator>> {
1599
1623
  const gasFees = await this.getGasFees(currentBlockNumber);
1600
- const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
1624
+ const allowedInSetup = [
1625
+ ...(await getDefaultAllowedSetupFunctions()),
1626
+ ...(this.config.txPublicSetupAllowListExtend ?? []),
1627
+ ];
1628
+ const blockNumber = BlockNumber(currentBlockNumber + 1);
1601
1629
 
1602
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1603
-
1604
- return createTxMessageValidators(
1630
+ return createFirstStageTxValidationsForGossipedTransactions(
1605
1631
  nextSlotTimestamp,
1606
- blockNumberInWhichTheTxIsConsideredToBeIncluded,
1632
+ blockNumber,
1607
1633
  this.worldStateSynchronizer,
1608
1634
  gasFees,
1609
1635
  this.config.l1ChainId,
1610
1636
  this.config.rollupVersion,
1611
1637
  protocolContractsHash,
1612
1638
  this.archiver,
1613
- this.proofVerifier,
1614
1639
  !this.config.disableTransactions,
1615
1640
  allowedInSetup,
1616
1641
  this.logger.getBindings(),
1617
1642
  );
1618
1643
  }
1619
1644
 
1645
+ /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */
1646
+ protected createSecondStageMessageValidators(): Record<string, TransactionValidator> {
1647
+ return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
1648
+ }
1649
+
1620
1650
  /**
1621
1651
  * Run validations on a tx.
1622
1652
  * @param tx - The tx to validate.
@@ -1625,7 +1655,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1625
1655
  */
1626
1656
  private async runValidations(
1627
1657
  tx: Tx,
1628
- messageValidators: Record<string, MessageValidator>,
1658
+ messageValidators: Record<string, TransactionValidator>,
1629
1659
  ): Promise<ValidationOutcome> {
1630
1660
  const validationPromises = Object.entries(messageValidators).map(async ([name, { validator, severity }]) => {
1631
1661
  const { result } = await validator.validateTx(tx);
@@ -18,6 +18,7 @@ export class PeerManagerMetrics {
18
18
  private sentGoodbyes: UpDownCounter;
19
19
  private receivedGoodbyes: UpDownCounter;
20
20
  private peerCount: Gauge;
21
+ private healthyPeerCount: Gauge;
21
22
  private lowScoreDisconnects: UpDownCounter;
22
23
  private peerConnectionDuration: Histogram;
23
24
 
@@ -49,6 +50,7 @@ export class PeerManagerMetrics {
49
50
  goodbyeReasonAttrs,
50
51
  );
51
52
  this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT);
53
+ this.healthyPeerCount = meter.createGauge(Metrics.PEER_MANAGER_HEALTHY_PEER_COUNT);
52
54
  this.lowScoreDisconnects = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_LOW_SCORE_DISCONNECTS, {
53
55
  [Attributes.P2P_PEER_SCORE_STATE]: ['Banned', 'Disconnect'],
54
56
  });
@@ -67,6 +69,10 @@ export class PeerManagerMetrics {
67
69
  this.peerCount.record(count);
68
70
  }
69
71
 
72
+ public recordHealthyPeerCount(count: number) {
73
+ this.healthyPeerCount.record(count);
74
+ }
75
+
70
76
  public recordLowScoreDisconnect(scoreState: 'Banned' | 'Disconnect') {
71
77
  this.lowScoreDisconnects.add(1, { [Attributes.P2P_PEER_SCORE_STATE]: scoreState });
72
78
  }
@@ -79,6 +85,7 @@ export class PeerManagerMetrics {
79
85
  const connectedAt = this.peerConnectedAt.get(id.toString());
80
86
  if (connectedAt) {
81
87
  this.peerConnectionDuration.record(Date.now() - connectedAt);
88
+ this.peerConnectedAt.delete(id.toString());
82
89
  }
83
90
  }
84
91
  }
@@ -515,7 +515,8 @@ export class PeerManager implements PeerManagerInterface {
515
515
  ...this.peerScoring.getStats(),
516
516
  });
517
517
 
518
- this.metrics.recordPeerCount(healthyConnections.length);
518
+ this.metrics.recordPeerCount(connections.length);
519
+ this.metrics.recordHealthyPeerCount(healthyConnections.length);
519
520
 
520
521
  // Exit if no peers to connect
521
522
  if (peersToConnect <= 0) {