@aztec/p2p 0.0.1-commit.e558bd1c → 0.0.1-commit.e5a3663dd

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 (468) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +10 -9
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +54 -15
  5. package/dest/client/interface.d.ts +47 -34
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +39 -51
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +173 -226
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +23 -10
  11. package/dest/config.d.ts +137 -92
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +113 -40
  14. package/dest/errors/p2p-service.error.d.ts +9 -0
  15. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  16. package/dest/errors/p2p-service.error.js +10 -0
  17. package/dest/errors/tx-pool.error.d.ts +8 -0
  18. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  19. package/dest/errors/tx-pool.error.js +9 -0
  20. package/dest/index.d.ts +2 -2
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +1 -1
  23. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +24 -13
  24. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.js +80 -43
  26. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +57 -57
  29. package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
  30. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  31. package/dest/mem_pools/attestation_pool/index.js +1 -1
  32. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  33. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  34. package/dest/mem_pools/attestation_pool/mocks.js +7 -5
  35. package/dest/mem_pools/index.d.ts +2 -2
  36. package/dest/mem_pools/index.d.ts.map +1 -1
  37. package/dest/mem_pools/instrumentation.d.ts +4 -2
  38. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  39. package/dest/mem_pools/instrumentation.js +33 -15
  40. package/dest/mem_pools/interface.d.ts +3 -3
  41. package/dest/mem_pools/interface.d.ts.map +1 -1
  42. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  43. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  44. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  45. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  46. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  48. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  49. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  50. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +7 -3
  51. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  52. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  54. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +3 -2
  55. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  56. package/dest/mem_pools/tx_pool_v2/eviction/index.js +2 -1
  57. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  58. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  59. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  60. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  61. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  62. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  63. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
  64. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +9 -7
  65. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  66. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +14 -6
  68. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  69. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  71. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  72. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  73. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  74. package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
  75. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  76. package/dest/mem_pools/tx_pool_v2/index.js +2 -1
  77. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  78. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  79. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  80. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +33 -12
  81. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  82. package/dest/mem_pools/tx_pool_v2/interfaces.js +5 -1
  83. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +81 -15
  84. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  85. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +147 -19
  86. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
  87. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  88. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +50 -45
  89. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +12 -5
  90. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  91. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +17 -6
  92. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +14 -5
  93. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  94. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +365 -189
  95. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
  96. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  97. package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
  98. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  99. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  100. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  101. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  102. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  103. package/dest/msg_validators/clock_tolerance.js +61 -3
  104. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -4
  105. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  106. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  107. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -4
  108. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  110. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +19 -8
  111. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  112. package/dest/msg_validators/proposal_validator/proposal_validator.js +88 -44
  113. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  114. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  116. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  117. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  118. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  119. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  120. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  121. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  122. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  123. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  124. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  125. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  126. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  127. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  128. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  129. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  130. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  131. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  132. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  133. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  134. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  135. package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
  136. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  137. package/dest/msg_validators/tx_validator/factory.js +247 -60
  138. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  139. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  140. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  141. package/dest/msg_validators/tx_validator/gas_validator.d.ts +99 -3
  142. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  143. package/dest/msg_validators/tx_validator/gas_validator.js +137 -53
  144. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  145. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  146. package/dest/msg_validators/tx_validator/index.js +2 -0
  147. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  148. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  149. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  150. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  151. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  152. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  153. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  154. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  155. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  156. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  157. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  158. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  159. package/dest/services/data_store.d.ts +1 -1
  160. package/dest/services/data_store.d.ts.map +1 -1
  161. package/dest/services/data_store.js +5 -5
  162. package/dest/services/dummy_service.d.ts +13 -6
  163. package/dest/services/dummy_service.d.ts.map +1 -1
  164. package/dest/services/dummy_service.js +13 -5
  165. package/dest/services/encoding.d.ts +7 -3
  166. package/dest/services/encoding.d.ts.map +1 -1
  167. package/dest/services/encoding.js +18 -11
  168. package/dest/services/gossipsub/index.d.ts +3 -0
  169. package/dest/services/gossipsub/index.d.ts.map +1 -0
  170. package/dest/services/gossipsub/index.js +2 -0
  171. package/dest/services/gossipsub/scoring.d.ts +21 -3
  172. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  173. package/dest/services/gossipsub/scoring.js +24 -7
  174. package/dest/services/gossipsub/topic_score_params.d.ts +184 -0
  175. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  176. package/dest/services/gossipsub/topic_score_params.js +363 -0
  177. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  178. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  179. package/dest/services/libp2p/instrumentation.js +14 -0
  180. package/dest/services/libp2p/libp2p_service.d.ts +42 -39
  181. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  182. package/dest/services/libp2p/libp2p_service.js +336 -269
  183. package/dest/services/peer-manager/metrics.d.ts +3 -1
  184. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  185. package/dest/services/peer-manager/metrics.js +6 -0
  186. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  187. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  188. package/dest/services/peer-manager/peer_manager.js +39 -11
  189. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  190. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  191. package/dest/services/peer-manager/peer_scoring.js +57 -12
  192. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +12 -8
  193. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  194. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +83 -106
  195. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -7
  196. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  197. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  198. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  199. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  200. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  201. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  202. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  203. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  204. package/dest/services/reqresp/config.d.ts +3 -3
  205. package/dest/services/reqresp/config.d.ts.map +1 -1
  206. package/dest/services/reqresp/interface.d.ts +23 -9
  207. package/dest/services/reqresp/interface.d.ts.map +1 -1
  208. package/dest/services/reqresp/interface.js +23 -10
  209. package/dest/services/reqresp/metrics.d.ts +1 -1
  210. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  211. package/dest/services/reqresp/metrics.js +0 -1
  212. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
  213. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  214. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
  215. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  216. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +15 -0
  217. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  218. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  219. package/dest/services/reqresp/protocols/index.js +0 -1
  220. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  221. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  222. package/dest/services/reqresp/protocols/tx.js +21 -3
  223. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  224. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  225. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  226. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  227. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  228. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  229. package/dest/services/reqresp/reqresp.d.ts +4 -2
  230. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  231. package/dest/services/reqresp/reqresp.js +40 -15
  232. package/dest/services/service.d.ts +26 -4
  233. package/dest/services/service.d.ts.map +1 -1
  234. package/dest/services/tx_collection/config.d.ts +19 -1
  235. package/dest/services/tx_collection/config.d.ts.map +1 -1
  236. package/dest/services/tx_collection/config.js +46 -0
  237. package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -4
  238. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  239. package/dest/services/tx_collection/fast_tx_collection.js +80 -76
  240. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  241. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  242. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  243. package/dest/services/tx_collection/file_store_tx_source.d.ts +38 -0
  244. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  245. package/dest/services/tx_collection/file_store_tx_source.js +100 -0
  246. package/dest/services/tx_collection/index.d.ts +2 -1
  247. package/dest/services/tx_collection/index.d.ts.map +1 -1
  248. package/dest/services/tx_collection/index.js +1 -0
  249. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  250. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  251. package/dest/services/tx_collection/instrumentation.js +2 -1
  252. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -7
  253. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  254. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  255. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  256. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  257. package/dest/services/tx_collection/request_tracker.js +84 -0
  258. package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
  259. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  260. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  261. package/dest/services/tx_collection/tx_collection.d.ts +23 -13
  262. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  263. package/dest/services/tx_collection/tx_collection.js +75 -3
  264. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  265. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  266. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  267. package/dest/services/tx_collection/tx_source.d.ts +13 -7
  268. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  269. package/dest/services/tx_collection/tx_source.js +26 -7
  270. package/dest/services/tx_file_store/config.d.ts +1 -3
  271. package/dest/services/tx_file_store/config.d.ts.map +1 -1
  272. package/dest/services/tx_file_store/config.js +0 -4
  273. package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
  274. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  275. package/dest/services/tx_file_store/tx_file_store.js +9 -6
  276. package/dest/services/tx_provider.d.ts +4 -4
  277. package/dest/services/tx_provider.d.ts.map +1 -1
  278. package/dest/services/tx_provider.js +9 -8
  279. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  280. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  281. package/dest/test-helpers/make-test-p2p-clients.js +4 -2
  282. package/dest/test-helpers/mock-pubsub.d.ts +40 -6
  283. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  284. package/dest/test-helpers/mock-pubsub.js +139 -13
  285. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  286. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  287. package/dest/test-helpers/reqresp-nodes.js +8 -5
  288. package/dest/test-helpers/testbench-utils.d.ts +35 -24
  289. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  290. package/dest/test-helpers/testbench-utils.js +125 -38
  291. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  292. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  293. package/dest/testbench/p2p_client_testbench_worker.js +84 -27
  294. package/dest/testbench/worker_client_manager.d.ts +10 -1
  295. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  296. package/dest/testbench/worker_client_manager.js +55 -3
  297. package/dest/util.d.ts +3 -3
  298. package/dest/util.d.ts.map +1 -1
  299. package/package.json +14 -14
  300. package/src/client/factory.ts +108 -26
  301. package/src/client/interface.ts +52 -34
  302. package/src/client/p2p_client.ts +201 -269
  303. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +35 -14
  304. package/src/config.ts +181 -46
  305. package/src/errors/p2p-service.error.ts +11 -0
  306. package/src/errors/tx-pool.error.ts +12 -0
  307. package/src/index.ts +1 -1
  308. package/src/mem_pools/attestation_pool/attestation_pool.ts +109 -53
  309. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +61 -57
  310. package/src/mem_pools/attestation_pool/index.ts +3 -3
  311. package/src/mem_pools/attestation_pool/mocks.ts +14 -8
  312. package/src/mem_pools/index.ts +1 -1
  313. package/src/mem_pools/instrumentation.ts +22 -14
  314. package/src/mem_pools/interface.ts +2 -2
  315. package/src/mem_pools/tx_pool_v2/README.md +85 -11
  316. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  317. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  318. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +7 -3
  319. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  320. package/src/mem_pools/tx_pool_v2/eviction/index.ts +5 -0
  321. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  322. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  323. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
  324. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +8 -8
  325. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -9
  326. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  327. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  328. package/src/mem_pools/tx_pool_v2/index.ts +2 -1
  329. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  330. package/src/mem_pools/tx_pool_v2/interfaces.ts +35 -12
  331. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +215 -27
  332. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +58 -45
  333. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +34 -8
  334. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +412 -187
  335. package/src/msg_validators/attestation_validator/README.md +49 -0
  336. package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
  337. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +12 -2
  338. package/src/msg_validators/clock_tolerance.ts +79 -3
  339. package/src/msg_validators/proposal_validator/README.md +123 -0
  340. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +23 -4
  341. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +34 -7
  342. package/src/msg_validators/proposal_validator/proposal_validator.ts +111 -47
  343. package/src/msg_validators/tx_validator/README.md +127 -0
  344. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
  345. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  346. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  347. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  348. package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
  349. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  350. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  351. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  352. package/src/msg_validators/tx_validator/factory.ts +396 -78
  353. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  354. package/src/msg_validators/tx_validator/gas_validator.ts +199 -54
  355. package/src/msg_validators/tx_validator/index.ts +2 -0
  356. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  357. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  358. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  359. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  360. package/src/services/data_store.ts +5 -13
  361. package/src/services/dummy_service.ts +19 -7
  362. package/src/services/encoding.ts +18 -10
  363. package/src/services/gossipsub/README.md +641 -0
  364. package/src/services/gossipsub/index.ts +2 -0
  365. package/src/services/gossipsub/scoring.ts +29 -5
  366. package/src/services/gossipsub/topic_score_params.ts +519 -0
  367. package/src/services/libp2p/instrumentation.ts +14 -0
  368. package/src/services/libp2p/libp2p_service.ts +358 -298
  369. package/src/services/peer-manager/metrics.ts +7 -0
  370. package/src/services/peer-manager/peer_manager.ts +45 -11
  371. package/src/services/peer-manager/peer_scoring.ts +52 -5
  372. package/src/services/reqresp/README.md +229 -0
  373. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  374. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +79 -112
  375. package/src/services/reqresp/batch-tx-requester/interface.ts +3 -6
  376. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  377. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  378. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  379. package/src/services/reqresp/config.ts +2 -2
  380. package/src/services/reqresp/interface.ts +45 -10
  381. package/src/services/reqresp/metrics.ts +0 -1
  382. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +2 -2
  383. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
  384. package/src/services/reqresp/protocols/index.ts +0 -1
  385. package/src/services/reqresp/protocols/tx.ts +23 -3
  386. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  387. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  388. package/src/services/reqresp/reqresp.ts +53 -16
  389. package/src/services/service.ts +37 -3
  390. package/src/services/tx_collection/config.ts +68 -0
  391. package/src/services/tx_collection/fast_tx_collection.ts +83 -76
  392. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  393. package/src/services/tx_collection/file_store_tx_source.ts +129 -0
  394. package/src/services/tx_collection/index.ts +1 -0
  395. package/src/services/tx_collection/instrumentation.ts +7 -1
  396. package/src/services/tx_collection/proposal_tx_collector.ts +9 -13
  397. package/src/services/tx_collection/request_tracker.ts +127 -0
  398. package/src/services/tx_collection/slow_tx_collection.ts +66 -33
  399. package/src/services/tx_collection/tx_collection.ts +114 -19
  400. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  401. package/src/services/tx_collection/tx_source.ts +28 -8
  402. package/src/services/tx_file_store/config.ts +0 -6
  403. package/src/services/tx_file_store/tx_file_store.ts +10 -8
  404. package/src/services/tx_provider.ts +10 -9
  405. package/src/test-helpers/make-test-p2p-clients.ts +6 -6
  406. package/src/test-helpers/mock-pubsub.ts +180 -14
  407. package/src/test-helpers/reqresp-nodes.ts +9 -9
  408. package/src/test-helpers/testbench-utils.ts +147 -43
  409. package/src/testbench/p2p_client_testbench_worker.ts +93 -30
  410. package/src/testbench/worker_client_manager.ts +68 -6
  411. package/src/util.ts +8 -2
  412. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  413. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  414. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  415. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  416. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  417. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  418. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  419. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  420. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  421. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  422. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  423. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  424. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  425. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  426. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  427. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  428. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  429. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  430. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  431. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  432. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  433. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  434. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  435. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  436. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  437. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  438. package/dest/mem_pools/tx_pool/index.js +0 -2
  439. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  440. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  441. package/dest/mem_pools/tx_pool/priority.js +0 -15
  442. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  443. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  444. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  445. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  446. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  447. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  448. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  449. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  450. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  451. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  452. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  453. package/dest/services/reqresp/protocols/block.js +0 -32
  454. package/src/mem_pools/tx_pool/README.md +0 -270
  455. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  456. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  457. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  458. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  459. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  460. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  461. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  462. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  463. package/src/mem_pools/tx_pool/index.ts +0 -2
  464. package/src/mem_pools/tx_pool/priority.ts +0 -20
  465. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  466. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  467. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
  468. package/src/services/reqresp/protocols/block.ts +0 -37
@@ -1,15 +1,14 @@
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
- import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import { maxBy, merge } from '@aztec/foundation/collection';
5
4
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
6
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
7
6
  import { Timer } from '@aztec/foundation/timer';
8
7
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
9
8
  import { protocolContractsHash } from '@aztec/protocol-contracts';
10
- import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
9
+ import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
11
10
  import type { ContractDataSource } from '@aztec/stdlib/contract';
12
- import { GasFees } from '@aztec/stdlib/gas';
11
+ import { type BlockMinFeesProvider, GasFees } from '@aztec/stdlib/gas';
13
12
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
14
13
  import {
15
14
  BlockProposal,
@@ -17,13 +16,12 @@ import {
17
16
  CheckpointProposal,
18
17
  type CheckpointProposalCore,
19
18
  type Gossipable,
20
- P2PClientType,
21
19
  P2PMessage,
22
- type ValidationResult as P2PValidationResult,
23
20
  PeerErrorSeverity,
21
+ PeerErrorSeverityByHarshness,
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';
@@ -45,7 +43,7 @@ import {
45
43
  type GossipsubMessage,
46
44
  gossipsub,
47
45
  } from '@chainsafe/libp2p-gossipsub';
48
- import { createPeerScoreParams, createTopicScoreParams } from '@chainsafe/libp2p-gossipsub/score';
46
+ import { createPeerScoreParams } from '@chainsafe/libp2p-gossipsub/score';
49
47
  import { SignaturePolicy } from '@chainsafe/libp2p-gossipsub/types';
50
48
  import { noise } from '@chainsafe/libp2p-noise';
51
49
  import { yamux } from '@chainsafe/libp2p-yamux';
@@ -59,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
59
57
  import { createLibp2p } from 'libp2p';
60
58
 
61
59
  import type { P2PConfig } from '../../config.js';
60
+ import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
62
61
  import type { MemPools } from '../../mem_pools/interface.js';
63
62
  import {
64
63
  BlockProposalValidator,
@@ -70,9 +69,11 @@ import {
70
69
  } from '../../msg_validators/index.js';
71
70
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
72
71
  import {
73
- type MessageValidator,
74
- createTxMessageValidators,
75
- createTxReqRespValidator,
72
+ type TransactionValidator,
73
+ createFirstStageTxValidationsForGossipedTransactions,
74
+ createSecondStageTxValidationsForGossipedTransactions,
75
+ createTxValidatorForBlockProposalReceivedTxs,
76
+ createTxValidatorForReqResponseReceivedTxs,
76
77
  } from '../../msg_validators/tx_validator/factory.js';
77
78
  import { GossipSubEvent } from '../../types/index.js';
78
79
  import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
@@ -80,13 +81,17 @@ import { getVersions } from '../../versioning.js';
80
81
  import { AztecDatastore } from '../data_store.js';
81
82
  import { DiscV5Service } from '../discv5/discV5_service.js';
82
83
  import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
83
- import { gossipScoreThresholds } from '../gossipsub/scoring.js';
84
+ import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring.js';
85
+ import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
84
86
  import type { PeerManagerInterface } from '../peer-manager/interface.js';
85
87
  import { PeerManager } from '../peer-manager/peer_manager.js';
86
88
  import { PeerScoring } from '../peer-manager/peer_scoring.js';
87
89
  import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
88
90
  import type { P2PReqRespConfig } from '../reqresp/config.js';
89
91
  import {
92
+ AuthRequest,
93
+ BlockTxsRequest,
94
+ BlockTxsResponse,
90
95
  DEFAULT_SUB_PROTOCOL_VALIDATORS,
91
96
  type ReqRespInterface,
92
97
  type ReqRespResponse,
@@ -94,17 +99,11 @@ import {
94
99
  type ReqRespSubProtocolHandler,
95
100
  type ReqRespSubProtocolHandlers,
96
101
  type ReqRespSubProtocolValidators,
102
+ StatusMessage,
97
103
  type SubProtocolMap,
98
104
  ValidationError,
99
- } from '../reqresp/index.js';
100
- import {
101
- AuthRequest,
102
- BlockTxsRequest,
103
- BlockTxsResponse,
104
- StatusMessage,
105
105
  pingHandler,
106
106
  reqGoodbyeHandler,
107
- reqRespBlockHandler,
108
107
  reqRespBlockTxsHandler,
109
108
  reqRespStatusHandler,
110
109
  reqRespTxHandler,
@@ -113,6 +112,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
113
112
  import type {
114
113
  P2PBlockReceivedCallback,
115
114
  P2PCheckpointReceivedCallback,
115
+ P2PDuplicateAttestationCallback,
116
116
  P2PService,
117
117
  PeerDiscoveryService,
118
118
  } from '../service.js';
@@ -129,12 +129,12 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
129
129
  // REFACTOR: Unify with the type above
130
130
  type ReceivedMessageValidationResult<T, M = undefined> =
131
131
  | { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
132
- | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
132
+ | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
133
133
 
134
134
  /**
135
135
  * Lib P2P implementation of the P2PService interface.
136
136
  */
137
- export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
137
+ export class LibP2PService extends WithTracer implements P2PService {
138
138
  private discoveryRunningPromise?: RunningPromise;
139
139
  private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
140
140
 
@@ -146,8 +146,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
146
146
  private protocolVersion = '';
147
147
  private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
148
148
 
149
- private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
150
-
151
149
  /** Callback invoked when a duplicate proposal is detected (triggers slashing). */
152
150
  private duplicateProposalCallback?: (info: {
153
151
  slot: SlotNumber;
@@ -155,6 +153,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
155
153
  type: 'checkpoint' | 'block';
156
154
  }) => void;
157
155
 
156
+ /** Callback invoked when a duplicate attestation is detected (triggers slashing). */
157
+ private duplicateAttestationCallback?: P2PDuplicateAttestationCallback;
158
+
158
159
  /**
159
160
  * Callback for when a block is received from a peer.
160
161
  * @param block - The block received from the peer.
@@ -167,7 +168,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
167
168
  * @param checkpoint - The checkpoint proposal received from the peer.
168
169
  * @returns The attestations for the checkpoint, if any.
169
170
  */
170
- private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
171
+ private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
172
+ /**
173
+ * Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
174
+ * @param checkpoint - The checkpoint proposal received from the peer.
175
+ * @returns The attestations for the checkpoint, if any.
176
+ */
177
+ private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
171
178
 
172
179
  private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
173
180
 
@@ -178,7 +185,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
178
185
  protected logger: Logger;
179
186
 
180
187
  constructor(
181
- private clientType: T,
182
188
  private config: P2PConfig,
183
189
  protected node: PubSubLibp2p,
184
190
  private peerDiscoveryService: PeerDiscoveryService,
@@ -189,6 +195,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
189
195
  private epochCache: EpochCacheInterface,
190
196
  private proofVerifier: ClientProtocolCircuitVerifier,
191
197
  private worldStateSynchronizer: WorldStateSynchronizer,
198
+ private blockMinFeesProvider: BlockMinFeesProvider,
192
199
  telemetry: TelemetryClient,
193
200
  logger: Logger = createLogger('p2p:libp2p_service'),
194
201
  ) {
@@ -220,36 +227,54 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
220
227
  this.protocolVersion,
221
228
  );
222
229
 
223
- this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
224
- this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
230
+ const p2pPropagationTime = config.attestationPropagationTime;
231
+ const proposalValidatorOpts = {
225
232
  txsPermitted: !config.disableTransactions,
226
- });
233
+ maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
234
+ maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
235
+ p2pPropagationTime,
236
+ signatureContext: {
237
+ chainId: config.l1ChainId,
238
+ rollupAddress: config.l1Contracts.rollupAddress,
239
+ },
240
+ };
241
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
242
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
243
+ const attestationValidatorOpts = {
244
+ l1PublishingTime: config.l1PublishingTime,
245
+ p2pPropagationTime,
246
+ signatureContext: proposalValidatorOpts.signatureContext,
247
+ };
227
248
  this.checkpointAttestationValidator = config.fishermanMode
228
- ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
229
- : new CheckpointAttestationValidator(epochCache);
249
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, attestationValidatorOpts)
250
+ : new CheckpointAttestationValidator(epochCache, attestationValidatorOpts);
230
251
 
231
252
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
232
253
 
233
254
  this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
234
- this.logger.debug(
235
- `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
255
+ this.logger.warn(
256
+ `Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`,
236
257
  { p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
237
258
  );
238
- return false;
259
+ return true;
239
260
  };
240
261
 
241
- this.checkpointReceivedCallback = (
242
- checkpoint: CheckpointProposalCore,
262
+ this.allNodesCheckpointReceivedCallback = (
263
+ _checkpoint: CheckpointProposalCore,
264
+ ): Promise<CheckpointAttestation[] | undefined> => {
265
+ throw new CheckpointProposalReceivedCallbackNotRegisteredError();
266
+ };
267
+
268
+ this.validatorCheckpointReceivedCallback = (
269
+ _checkpoint: CheckpointProposalCore,
243
270
  ): Promise<CheckpointAttestation[] | undefined> => {
244
- this.logger.debug(
245
- `Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
246
- );
247
271
  return Promise.resolve(undefined);
248
272
  };
249
273
  }
250
274
 
251
- public updateConfig(config: Partial<P2PReqRespConfig>) {
275
+ public updateConfig(config: Partial<P2PReqRespConfig & Pick<P2PConfig, 'skipIncomingProposals'>>) {
252
276
  this.reqresp.updateConfig(config);
277
+ this.config = merge(this.config, config);
253
278
  }
254
279
 
255
280
  /**
@@ -258,8 +283,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
258
283
  * @param txPool - The transaction pool to be accessed by the service.
259
284
  * @returns The new service.
260
285
  */
261
- public static async new<T extends P2PClientType>(
262
- clientType: T,
286
+ public static async new(
263
287
  config: P2PConfig,
264
288
  peerId: PeerId,
265
289
  deps: {
@@ -269,6 +293,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
269
293
  proofVerifier: ClientProtocolCircuitVerifier;
270
294
  worldStateSynchronizer: WorldStateSynchronizer;
271
295
  peerStore: AztecAsyncKVStore;
296
+ blockMinFeesProvider: BlockMinFeesProvider;
272
297
  telemetry: TelemetryClient;
273
298
  logger: Logger;
274
299
  packageVersion: string;
@@ -281,6 +306,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
281
306
  mempools,
282
307
  proofVerifier,
283
308
  peerStore,
309
+ blockMinFeesProvider,
284
310
  telemetry,
285
311
  logger,
286
312
  packageVersion,
@@ -311,11 +337,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
311
337
  const versions = getVersions(config);
312
338
  const protocolVersion = compressComponentVersions(versions);
313
339
 
314
- const txTopic = createTopicString(TopicType.tx, protocolVersion);
315
- const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
316
- const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
317
- const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
318
-
319
340
  const preferredPeersEnrs: ENR[] = config.preferredPeers.map(enr => ENR.decodeTxt(enr));
320
341
  const directPeers = (
321
342
  await Promise.all(
@@ -335,6 +356,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
335
356
 
336
357
  const announceTcpMultiaddr = config.p2pIp ? [convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')] : [];
337
358
 
359
+ // Create dynamic topic score params based on network configuration
360
+ const l1Constants = epochCache.getL1Constants();
361
+ const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
362
+ slotDurationMs: l1Constants.slotDuration * 1000,
363
+ ethereumSlotDuration: l1Constants.ethereumSlotDuration,
364
+ heartbeatIntervalMs: config.gossipsubInterval,
365
+ targetCommitteeSize: l1Constants.targetCommitteeSize,
366
+ blockDurationMs: config.blockDurationMs,
367
+ l1PublishingTime: config.l1PublishingTime,
368
+ p2pPropagationTime: config.attestationPropagationTime,
369
+ expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
370
+ });
371
+
338
372
  const node = await createLibp2p({
339
373
  start: false,
340
374
  peerId,
@@ -430,28 +464,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
430
464
  scoreParams: createPeerScoreParams({
431
465
  // IPColocation factor can be disabled for local testing - default to -5
432
466
  IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
433
- topics: {
434
- [txTopic]: createTopicScoreParams({
435
- topicWeight: 1,
436
- invalidMessageDeliveriesWeight: -20,
437
- invalidMessageDeliveriesDecay: 0.5,
438
- }),
439
- [blockProposalTopic]: createTopicScoreParams({
440
- topicWeight: 1,
441
- invalidMessageDeliveriesWeight: -20,
442
- invalidMessageDeliveriesDecay: 0.5,
443
- }),
444
- [checkpointProposalTopic]: createTopicScoreParams({
445
- topicWeight: 1,
446
- invalidMessageDeliveriesWeight: -20,
447
- invalidMessageDeliveriesDecay: 0.5,
448
- }),
449
- [checkpointAttestationTopic]: createTopicScoreParams({
450
- topicWeight: 1,
451
- invalidMessageDeliveriesWeight: -20,
452
- invalidMessageDeliveriesDecay: 0.5,
453
- }),
454
- },
467
+ topics: topicScoreParams,
455
468
  }),
456
469
  }) as (components: GossipSubComponents) => GossipSub,
457
470
  components: (components: { connectionManager: ConnectionManager }) => ({
@@ -477,13 +490,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
477
490
  epochCache,
478
491
  );
479
492
 
480
- // Update gossipsub score params
481
- node.services.pubsub.score.params.appSpecificWeight = 10;
493
+ // Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
494
+ reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
495
+
496
+ // Configure application-specific scoring for gossipsub.
497
+ // The weight scales app score to align with gossipsub thresholds:
498
+ // - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
499
+ // - Ban (-100) × 10 = -1000 = publishThreshold (cannot publish)
500
+ // Note: positive topic scores can offset penalties, so alignment is best-effort.
501
+ node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
482
502
  node.services.pubsub.score.params.appSpecificScore = (peerId: string) =>
483
503
  peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
484
504
 
485
505
  return new LibP2PService(
486
- clientType,
487
506
  config,
488
507
  node,
489
508
  peerDiscoveryService,
@@ -494,6 +513,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
494
513
  epochCache,
495
514
  proofVerifier,
496
515
  worldStateSynchronizer,
516
+ blockMinFeesProvider,
497
517
  telemetry,
498
518
  logger,
499
519
  );
@@ -519,14 +539,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
519
539
  // Create request response protocol handlers
520
540
  const txHandler = reqRespTxHandler(this.mempools);
521
541
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
522
- const blockHandler = reqRespBlockHandler(this.archiver);
523
542
  const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
524
543
 
525
544
  const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
526
545
  [ReqRespSubProtocol.PING]: pingHandler,
527
546
  [ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
528
547
  [ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
529
- [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
530
548
  };
531
549
 
532
550
  if (!this.config.disableTransactions) {
@@ -547,7 +565,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
547
565
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
548
566
  [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
549
567
  [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
550
- [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
551
568
  };
552
569
 
553
570
  await this.peerManager.initializePeers();
@@ -557,7 +574,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
557
574
  await this.node.start();
558
575
 
559
576
  // Subscribe to standard GossipSub topics by default
560
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
577
+ for (const topic of getTopicsForConfig(this.config.disableTransactions)) {
561
578
  this.subscribeToTopic(this.topicStrings[topic]);
562
579
  }
563
580
 
@@ -623,6 +640,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
623
640
  return this.peerManager.getPeers(includePending);
624
641
  }
625
642
 
643
+ public getGossipMeshPeerCount(topicType: TopicType): number {
644
+ return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
645
+ }
646
+
626
647
  private handleGossipSubEvent(e: CustomEvent<GossipsubMessage>) {
627
648
  this.logger.trace(`Received PUBSUB message.`);
628
649
 
@@ -671,8 +692,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
671
692
  this.blockReceivedCallback = callback;
672
693
  }
673
694
 
674
- public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
675
- this.checkpointReceivedCallback = callback;
695
+ public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
696
+ this.validatorCheckpointReceivedCallback = callback;
697
+ }
698
+
699
+ public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
700
+ this.allNodesCheckpointReceivedCallback = callback;
701
+ }
702
+
703
+ public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
704
+ await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
676
705
  }
677
706
 
678
707
  /**
@@ -685,6 +714,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
685
714
  this.duplicateProposalCallback = callback;
686
715
  }
687
716
 
717
+ /**
718
+ * Registers a callback to be invoked when a duplicate attestation is detected.
719
+ * A validator signing attestations for different proposals at the same slot.
720
+ * This callback is triggered on the first duplicate (when count goes from 1 to 2).
721
+ */
722
+ public registerDuplicateAttestationCallback(callback: P2PDuplicateAttestationCallback): void {
723
+ this.duplicateAttestationCallback = callback;
724
+ }
725
+
688
726
  /**
689
727
  * Subscribes to a topic.
690
728
  * @param topic - The topic to subscribe to.
@@ -749,6 +787,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
749
787
  if (!validator || !validator.addMessage(msgId)) {
750
788
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
751
789
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
790
+ if (topicType === TopicType.tx) {
791
+ this.logger.verbose(`Ignoring already-seen tx gossip message`, { msgId, source: source.toString() });
792
+ }
752
793
  return { result: false, topicType };
753
794
  }
754
795
 
@@ -810,12 +851,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
810
851
 
811
852
  // Process the message, optionally within a linked span for trace propagation
812
853
  const processMessage = async () => {
854
+ if (
855
+ this.config.skipIncomingProposals &&
856
+ (msg.topic === this.topicStrings[TopicType.block_proposal] ||
857
+ msg.topic === this.topicStrings[TopicType.checkpoint_proposal])
858
+ ) {
859
+ this.logger.warn(`Ignoring incoming proposal (skipIncomingProposals is set)`, { topic: msg.topic });
860
+ this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
861
+ return;
862
+ }
813
863
  if (msg.topic === this.topicStrings[TopicType.tx]) {
814
864
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
815
865
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
816
- if (this.clientType === P2PClientType.Full) {
817
- await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
818
- }
866
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
819
867
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
820
868
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
821
869
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
@@ -877,45 +925,139 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
877
925
  source: PeerId,
878
926
  topicType: TopicType,
879
927
  ): Promise<ReceivedMessageValidationResult<T, M>> {
880
- let resultAndObj: ReceivedMessageValidationResult<T, M> = { result: TopicValidatorResult.Reject };
928
+ // Default to reject result with a penalty if validation function throws an error
929
+ let resultAndObj: ReceivedMessageValidationResult<T, M> = {
930
+ result: TopicValidatorResult.Reject,
931
+ severity: PeerErrorSeverity.MidToleranceError,
932
+ };
881
933
  const timer = new Timer();
882
934
  try {
883
935
  resultAndObj = await validationFunc();
884
936
  } catch (err) {
885
- this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
886
- this.logger.error(`Error deserializing and validating gossipsub message`, err, {
887
- msgId,
888
- source: source.toString(),
889
- topicType,
890
- });
937
+ this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
938
+ }
939
+
940
+ const validationTimeMs = timer.ms();
941
+ const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
942
+ if (validationTimeMs > mcacheWindowMs * 0.75) {
943
+ this.instrumentation.incSlowValidation(topicType);
944
+ this.logger.warn(
945
+ `Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` +
946
+ `Message forwarding may be skipped if validation exceeds the window.`,
947
+ { msgId, source: source.toString(), topicType, validationTimeMs, mcacheWindowMs },
948
+ );
891
949
  }
892
950
 
893
951
  if (resultAndObj.result === TopicValidatorResult.Accept) {
952
+ this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
894
953
  this.instrumentation.recordMessageValidation(topicType, timer);
954
+ } else if (resultAndObj.result === TopicValidatorResult.Reject) {
955
+ this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
956
+ msgId,
957
+ source: source.toString(),
958
+ topicType,
959
+ severity: resultAndObj.severity,
960
+ });
961
+ this.peerManager.penalizePeer(source, resultAndObj.severity);
962
+ } else {
963
+ this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
895
964
  }
896
965
 
897
966
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
898
967
  return resultAndObj;
899
968
  }
900
969
 
970
+ private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
971
+ try {
972
+ return deserializeFunc();
973
+ } catch (err) {
974
+ this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
975
+ err,
976
+ msgId,
977
+ source: source.toString(),
978
+ });
979
+ return undefined;
980
+ }
981
+ }
982
+
901
983
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
902
984
  const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
903
- const tx = Tx.fromBuffer(payloadData);
904
- const isValid = await this.validatePropagatedTx(tx, source);
905
- const exists = isValid && (await this.mempools.txPool.hasTx(tx.getTxHash()));
985
+ const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
986
+ if (!tx) {
987
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
988
+ }
906
989
 
907
- this.logger.trace(`Validate propagated tx`, {
908
- isValid,
909
- exists,
990
+ const currentBlockNumber = await this.archiver.getBlockNumber();
991
+ const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
992
+
993
+ // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
994
+ const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
995
+ const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
996
+ if (!firstStageOutcome.allPassed) {
997
+ const { name } = firstStageOutcome.failure;
998
+ let { severity } = firstStageOutcome.failure;
999
+
1000
+ // Double spend validator has a special case handler. We perform more detailed examination
1001
+ // as to how recently the nullifier was entered into the tree and if the transaction should
1002
+ // have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
1003
+ if (name === 'doubleSpendValidator') {
1004
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1);
1005
+ severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1006
+ }
1007
+
1008
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
1009
+ validator: name,
1010
+ severity,
1011
+ source: source.toString(),
1012
+ });
1013
+ return { result: TopicValidatorResult.Reject, severity };
1014
+ }
1015
+
1016
+ // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
1017
+ const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
1018
+ if (canAdd === 'ignored') {
1019
+ this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
1020
+ source: source.toString(),
1021
+ });
1022
+ return { result: TopicValidatorResult.Ignore, obj: tx };
1023
+ }
1024
+
1025
+ // Stage 2: expensive proof verification
1026
+ const secondStageValidators = this.createSecondStageMessageValidators();
1027
+ const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
1028
+ if (!secondStageOutcome.allPassed) {
1029
+ const { severity, name } = secondStageOutcome.failure;
1030
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
1031
+ validator: name,
1032
+ severity,
1033
+ source: source.toString(),
1034
+ });
1035
+ return { result: TopicValidatorResult.Reject, severity };
1036
+ }
1037
+
1038
+ // Pool add: persist the tx
1039
+ const txHash = tx.getTxHash();
1040
+ const addResult = await this.mempools.txPool.addPendingTxs([tx], { source: 'gossip' });
1041
+
1042
+ const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
1043
+ const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
1044
+
1045
+ this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
1046
+ wasAccepted,
1047
+ wasIgnored,
910
1048
  [Attributes.P2P_ID]: source.toString(),
911
1049
  });
912
1050
 
913
- if (!isValid) {
914
- return { result: TopicValidatorResult.Reject };
915
- } else if (exists) {
1051
+ if (wasAccepted) {
1052
+ return { result: TopicValidatorResult.Accept, obj: tx };
1053
+ } else if (wasIgnored) {
916
1054
  return { result: TopicValidatorResult.Ignore, obj: tx };
917
1055
  } else {
918
- return { result: TopicValidatorResult.Accept, obj: tx };
1056
+ this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
1057
+ source: source.toString(),
1058
+ txHash: txHash.toString(),
1059
+ });
1060
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
919
1061
  }
920
1062
  };
921
1063
 
@@ -924,6 +1066,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
924
1066
  return;
925
1067
  }
926
1068
 
1069
+ // Tx was accepted into pool and will be propagated - just log and record metrics
927
1070
  const txHash = tx.getTxHash();
928
1071
  const txHashString = txHash.toString();
929
1072
  this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
@@ -931,13 +1074,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
931
1074
  txHash: txHashString,
932
1075
  });
933
1076
 
934
- if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
935
- this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
936
- return;
937
- }
938
-
939
1077
  this.instrumentation.incrementTxReceived(1);
940
- await this.mempools.txPool.addTxs([tx]);
941
1078
  }
942
1079
 
943
1080
  /**
@@ -950,7 +1087,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
950
1087
  source: PeerId,
951
1088
  ): Promise<void> {
952
1089
  const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
953
- () => this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)),
1090
+ () => {
1091
+ const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
1092
+ if (!attestation) {
1093
+ return Promise.resolve({
1094
+ result: TopicValidatorResult.Reject,
1095
+ severity: PeerErrorSeverity.LowToleranceError,
1096
+ });
1097
+ }
1098
+ return this.validateAndStoreCheckpointAttestation(source, attestation);
1099
+ },
954
1100
  msgId,
955
1101
  source,
956
1102
  TopicType.checkpoint_attestation,
@@ -983,48 +1129,60 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
983
1129
 
984
1130
  if (validationResult.result === 'reject') {
985
1131
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
986
- this.peerManager.penalizePeer(peerId, validationResult.severity);
987
- return { result: TopicValidatorResult.Reject };
1132
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
988
1133
  }
989
1134
 
990
1135
  if (validationResult.result === 'ignore') {
991
1136
  return { result: TopicValidatorResult.Ignore, obj: attestation };
992
1137
  }
993
1138
 
994
- // Get committee size for the attestation's slot
995
- const slot = attestation.payload.header.slotNumber;
996
- const { committee } = await this.epochCache.getCommittee(slot);
997
- const committeeSize = committee?.length ?? 0;
998
-
999
1139
  // Try to add the attestation: this handles existence check, cap check, and adding in one call
1000
- const { added, alreadyExists } = await this.mempools.attestationPool.tryAddCheckpointAttestation(
1001
- attestation,
1002
- committeeSize,
1003
- );
1140
+ // count is the number of attestations by this signer for this slot (for duplicate detection)
1141
+ const slot = attestation.payload.header.slotNumber;
1142
+ const { added, alreadyExists, count } =
1143
+ await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation);
1004
1144
 
1005
1145
  this.logger.trace(`Validate propagated checkpoint attestation`, {
1006
1146
  added,
1007
1147
  alreadyExists,
1148
+ count,
1008
1149
  [Attributes.SLOT_NUMBER]: slot.toString(),
1009
1150
  [Attributes.P2P_ID]: peerId.toString(),
1010
1151
  });
1011
1152
 
1012
- // Duplicate attestation received, no need to re-broadcast
1153
+ // Exact same attestation received, no need to re-broadcast
1013
1154
  if (alreadyExists) {
1014
1155
  return { result: TopicValidatorResult.Ignore, obj: attestation };
1015
1156
  }
1016
1157
 
1017
- // Could not add (cap reached), no need to re-broadcast
1158
+ // Could not add (cap reached for signer), penalize and do not re-broadcast
1018
1159
  if (!added) {
1019
- this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
1160
+ this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
1020
1161
  slot: slot.toString(),
1021
1162
  archive: attestation.archive.toString(),
1022
1163
  source: peerId.toString(),
1164
+ attester: attestation.getSender()?.toString(),
1165
+ count,
1023
1166
  });
1024
- return { result: TopicValidatorResult.Ignore, obj: attestation };
1167
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
1168
+ }
1169
+
1170
+ // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
1171
+ // count is the number of attestations by this signer for this slot
1172
+ if (count === 2) {
1173
+ const attester = attestation.getSender();
1174
+ if (attester) {
1175
+ this.logger.warn(`Detected duplicate attestation (equivocation) at slot ${slot}`, {
1176
+ slot: slot.toString(),
1177
+ archive: attestation.archive.toString(),
1178
+ source: peerId.toString(),
1179
+ attester: attester.toString(),
1180
+ });
1181
+ this.duplicateAttestationCallback?.({ slot, attester });
1182
+ }
1025
1183
  }
1026
1184
 
1027
- // Attestation was added successfully
1185
+ // Attestation was added successfully - accept it so other nodes can also detect the equivocation
1028
1186
  return { result: TopicValidatorResult.Accept, obj: attestation };
1029
1187
  }
1030
1188
 
@@ -1061,8 +1219,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1061
1219
 
1062
1220
  if (validationResult.result === 'reject') {
1063
1221
  this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
1064
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1065
- return { result: TopicValidatorResult.Reject };
1222
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1066
1223
  }
1067
1224
 
1068
1225
  if (validationResult.result === 'ignore') {
@@ -1070,8 +1227,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1070
1227
  }
1071
1228
 
1072
1229
  // Try to add the proposal: this handles existence check, cap check, and adding in one call
1073
- const { added, alreadyExists, totalForPosition } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1074
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1230
+ const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1231
+ const isEquivocated = count !== undefined && count > 1;
1075
1232
 
1076
1233
  // Duplicate proposal received, no need to re-broadcast
1077
1234
  if (alreadyExists) {
@@ -1086,15 +1243,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1086
1243
 
1087
1244
  // Too many blocks received for this slot and index, penalize peer and do not re-broadcast
1088
1245
  if (!added) {
1089
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1090
1246
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1091
1247
  ...block.toBlockInfo(),
1092
1248
  indexWithinCheckpoint: block.indexWithinCheckpoint,
1093
- totalForPosition,
1249
+ count,
1094
1250
  proposer: block.getSender()?.toString(),
1095
1251
  source: peerId.toString(),
1096
1252
  });
1097
- return { result: TopicValidatorResult.Reject, metadata: { isEquivocated } };
1253
+ return {
1254
+ result: TopicValidatorResult.Reject,
1255
+ metadata: { isEquivocated },
1256
+ severity: PeerErrorSeverity.HighToleranceError,
1257
+ };
1098
1258
  }
1099
1259
 
1100
1260
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1107,7 +1267,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1107
1267
  proposer: proposer?.toString(),
1108
1268
  });
1109
1269
  // Invoke the duplicate callback on the first duplicate spotted only
1110
- if (proposer && totalForPosition === 2) {
1270
+ if (proposer && count === 2) {
1111
1271
  this.duplicateProposalCallback?.({ slot: block.slotNumber, proposer, type: 'block' });
1112
1272
  }
1113
1273
  return { result: TopicValidatorResult.Accept, obj: block, metadata: { isEquivocated } };
@@ -1132,14 +1292,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1132
1292
  ...block.toBlockInfo(),
1133
1293
  });
1134
1294
 
1135
- // Mark the txs in this proposal as non-evictable
1136
- await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
1295
+ // Mark the txs in this proposal as protected
1296
+ await this.mempools.txPool.protectTxs(block.txHashes, block.blockHeader);
1137
1297
 
1138
1298
  // Call the block received callback to validate the proposal.
1139
1299
  // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1140
1300
  const isValid = await this.blockReceivedCallback(block, sender);
1141
1301
  if (!isValid) {
1142
- this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1302
+ this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1143
1303
  }
1144
1304
  }
1145
1305
 
@@ -1187,8 +1347,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1187
1347
 
1188
1348
  if (validationResult.result === 'reject') {
1189
1349
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1190
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1191
- return { result: TopicValidatorResult.Reject };
1350
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1192
1351
  }
1193
1352
 
1194
1353
  if (validationResult.result === 'ignore') {
@@ -1203,20 +1362,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1203
1362
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1204
1363
  [Attributes.P2P_ID]: peerId.toString(),
1205
1364
  });
1206
- const {
1207
- result,
1208
- obj,
1209
- metadata: { isEquivocated } = {},
1210
- } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1211
- if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1365
+ const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1366
+ const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1367
+ if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1212
1368
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1213
1369
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1214
1370
  [Attributes.P2P_ID]: peerId.toString(),
1215
1371
  isEquivocated,
1216
- result,
1372
+ result: blockProposalResult.result,
1217
1373
  });
1218
- return { result: TopicValidatorResult.Reject };
1219
- } else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1374
+ return {
1375
+ result: TopicValidatorResult.Reject,
1376
+ severity:
1377
+ 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
1378
+ };
1379
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1220
1380
  processBlock = true;
1221
1381
  }
1222
1382
  }
@@ -1224,8 +1384,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1224
1384
  // Try to add the checkpoint proposal core: this handles existence check, cap check, and adding in one call
1225
1385
  const checkpointCore = checkpoint.toCore();
1226
1386
  const tryAddResult = await this.mempools.attestationPool.tryAddCheckpointProposal(checkpointCore);
1227
- const { added, alreadyExists, totalForPosition } = tryAddResult;
1228
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1387
+ const { added, alreadyExists, count } = tryAddResult;
1388
+ const isEquivocated = count !== undefined && count > 1;
1229
1389
 
1230
1390
  // Duplicate proposal received, do not re-broadcast
1231
1391
  if (alreadyExists) {
@@ -1243,13 +1403,17 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1243
1403
  // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1244
1404
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1245
1405
  if (!added) {
1246
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1247
1406
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1248
1407
  ...checkpoint.toCheckpointInfo(),
1249
- totalForPosition,
1408
+ count,
1250
1409
  source: peerId.toString(),
1251
1410
  });
1252
- return { result: TopicValidatorResult.Reject, obj: checkpoint, metadata: { isEquivocated, processBlock } };
1411
+ return {
1412
+ result: TopicValidatorResult.Reject,
1413
+ obj: checkpoint,
1414
+ metadata: { isEquivocated, processBlock },
1415
+ severity: PeerErrorSeverity.HighToleranceError,
1416
+ };
1253
1417
  }
1254
1418
 
1255
1419
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1262,7 +1426,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1262
1426
  proposer: proposer?.toString(),
1263
1427
  });
1264
1428
  // Invoke the duplicate callback on the first duplicate spotted only
1265
- if (proposer && totalForPosition === 2) {
1429
+ if (proposer && count === 2) {
1266
1430
  this.duplicateProposalCallback?.({ slot: checkpoint.slotNumber, proposer, type: 'checkpoint' });
1267
1431
  }
1268
1432
  return {
@@ -1294,9 +1458,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1294
1458
  source: sender.toString(),
1295
1459
  });
1296
1460
 
1461
+ await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
1462
+
1297
1463
  // Call the checkpoint received callback with the core version (without lastBlock)
1298
1464
  // to validate and potentially generate attestations
1299
- const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
1465
+ const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
1300
1466
  if (attestations && attestations.length > 0) {
1301
1467
  // If the callback returned attestations, add them to the pool and propagate them
1302
1468
  await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
@@ -1444,53 +1610,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1444
1610
  }
1445
1611
  }
1446
1612
 
1447
- /**
1448
- * Validates a BLOCK response.
1449
- *
1450
- * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1451
- * Penalizes on block number mismatch or hash mismatch.
1452
- *
1453
- * @param requestedBlockNumber - The requested block number.
1454
- * @param responseBlock - The block returned by the peer.
1455
- * @param peerId - The peer that returned the block.
1456
- * @returns True if the response is valid, false otherwise.
1457
- */
1458
- @trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
1459
- [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
1460
- }))
1461
- protected async validateRequestedBlock(
1462
- requestedBlockNumber: Fr,
1463
- responseBlock: L2Block,
1464
- peerId: PeerId,
1465
- ): Promise<boolean> {
1466
- try {
1467
- const reqNum = Number(requestedBlockNumber.toString());
1468
- if (responseBlock.number !== reqNum) {
1469
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1470
- return false;
1471
- }
1472
-
1473
- const local = await this.archiver.getBlock(BlockNumber(reqNum));
1474
- if (!local) {
1475
- // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1476
- // TODO: Consider extending this validator to accept an expected hash or
1477
- // performing quorum-based checks when using P2P syncing prior to L1 sync.
1478
- this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1479
- return false;
1480
- }
1481
- const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
1482
- if (!localHash.equals(respHash)) {
1483
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1484
- return false;
1485
- }
1486
-
1487
- return true;
1488
- } catch (e) {
1489
- this.logger.warn(`Error validating requested block`, e);
1490
- return false;
1491
- }
1492
- }
1493
-
1494
1613
  protected async validateRequestedTx(
1495
1614
  tx: Tx,
1496
1615
  peerId: PeerId,
@@ -1511,52 +1630,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1511
1630
  }
1512
1631
 
1513
1632
  protected createRequestedTxValidator(): TxValidator {
1514
- return createTxReqRespValidator(this.proofVerifier, {
1633
+ return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
1515
1634
  l1ChainId: this.config.l1ChainId,
1516
1635
  rollupVersion: this.config.rollupVersion,
1517
1636
  });
1518
1637
  }
1519
1638
 
1520
- @trackSpan('Libp2pService.validatePropagatedTx', tx => ({
1521
- [Attributes.TX_HASH]: tx.getTxHash().toString(),
1522
- }))
1523
- private async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
1524
- const currentBlockNumber = await this.archiver.getBlockNumber();
1525
-
1526
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1527
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1528
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1529
-
1530
- for (const validator of messageValidators) {
1531
- const outcome = await this.runValidations(tx, validator);
1532
-
1533
- if (outcome.allPassed) {
1534
- continue;
1535
- }
1536
- const { name } = outcome.failure;
1537
- let { severity } = outcome.failure;
1538
-
1539
- // Double spend validator has a special case handler
1540
- if (name === 'doubleSpendValidator') {
1541
- const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1542
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1543
- }
1544
-
1545
- this.peerManager.penalizePeer(peerId, severity);
1546
- return false;
1547
- }
1548
- return true;
1549
- }
1550
-
1551
- private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
1552
- if (blockNumber === this.feesCache?.blockNumber) {
1553
- return this.feesCache.gasFees;
1554
- }
1555
-
1556
- const header = await this.archiver.getBlockHeader(blockNumber);
1557
- const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
1558
- this.feesCache = { blockNumber, gasFees };
1559
- return gasFees;
1639
+ private getGasFees(): Promise<GasFees> {
1640
+ return this.blockMinFeesProvider.getCurrentMinFees();
1560
1641
  }
1561
1642
 
1562
1643
  /**
@@ -1575,60 +1656,62 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1575
1656
  };
1576
1657
  }
1577
1658
 
1578
- public async validate(txs: Tx[]): Promise<void> {
1579
- const currentBlockNumber = await this.archiver.getBlockNumber();
1580
-
1581
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1582
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1583
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1659
+ public async validateTxsReceivedInBlockProposal(txs: Tx[]): Promise<void> {
1660
+ const validator = createTxValidatorForBlockProposalReceivedTxs(
1661
+ this.proofVerifier,
1662
+ { l1ChainId: this.config.l1ChainId, rollupVersion: this.config.rollupVersion },
1663
+ this.logger.getBindings(),
1664
+ );
1584
1665
 
1585
- await Promise.all(
1666
+ const results = await Promise.all(
1586
1667
  txs.map(async tx => {
1587
- for (const validator of messageValidators) {
1588
- const outcome = await this.runValidations(tx, validator);
1589
- if (!outcome.allPassed) {
1590
- throw new Error('Invalid tx detected', { cause: { outcome } });
1591
- }
1592
- }
1668
+ const result = await validator.validateTx(tx);
1669
+ return result.result !== 'invalid';
1593
1670
  }),
1594
1671
  );
1672
+ if (results.some(value => value === false)) {
1673
+ throw new Error('Invalid tx detected');
1674
+ }
1595
1675
  }
1596
1676
 
1597
- /**
1598
- * Create message validators for the given block number and timestamp.
1599
- *
1600
- * Each validator is a pair of a validator and a severity.
1601
- * If a validator fails, the peer is penalized with the severity of the validator.
1602
- *
1603
- * @param currentBlockNumber - The current synced block number.
1604
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
1605
- * @returns The message validators.
1606
- */
1607
- private async createMessageValidators(
1677
+ /** Creates the first stage (fast) validators for gossiped transactions. */
1678
+ protected async createFirstStageMessageValidators(
1608
1679
  currentBlockNumber: BlockNumber,
1609
1680
  nextSlotTimestamp: UInt64,
1610
- ): Promise<Record<string, MessageValidator>[]> {
1611
- const gasFees = await this.getGasFees(currentBlockNumber);
1612
- const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
1613
-
1614
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1615
-
1616
- return createTxMessageValidators(
1681
+ ): Promise<Record<string, TransactionValidator>> {
1682
+ const gasFees = await this.getGasFees();
1683
+ const allowedInSetup = [
1684
+ ...(await getDefaultAllowedSetupFunctions()),
1685
+ ...(this.config.txPublicSetupAllowListExtend ?? []),
1686
+ ];
1687
+ const blockNumber = BlockNumber(currentBlockNumber + 1);
1688
+ const l1Constants = await this.archiver.getL1Constants();
1689
+
1690
+ return createFirstStageTxValidationsForGossipedTransactions(
1617
1691
  nextSlotTimestamp,
1618
- blockNumberInWhichTheTxIsConsideredToBeIncluded,
1692
+ blockNumber,
1619
1693
  this.worldStateSynchronizer,
1620
1694
  gasFees,
1621
1695
  this.config.l1ChainId,
1622
1696
  this.config.rollupVersion,
1623
1697
  protocolContractsHash,
1624
1698
  this.archiver,
1625
- this.proofVerifier,
1626
1699
  !this.config.disableTransactions,
1627
1700
  allowedInSetup,
1628
1701
  this.logger.getBindings(),
1702
+ {
1703
+ rollupManaLimit: l1Constants.rollupManaLimit,
1704
+ maxBlockL2Gas: this.config.validateMaxL2BlockGas,
1705
+ maxBlockDAGas: this.config.validateMaxDABlockGas,
1706
+ },
1629
1707
  );
1630
1708
  }
1631
1709
 
1710
+ /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */
1711
+ protected createSecondStageMessageValidators(): Record<string, TransactionValidator> {
1712
+ return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
1713
+ }
1714
+
1632
1715
  /**
1633
1716
  * Run validations on a tx.
1634
1717
  * @param tx - The tx to validate.
@@ -1637,7 +1720,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1637
1720
  */
1638
1721
  private async runValidations(
1639
1722
  tx: Tx,
1640
- messageValidators: Record<string, MessageValidator>,
1723
+ messageValidators: Record<string, TransactionValidator>,
1641
1724
  ): Promise<ValidationOutcome> {
1642
1725
  const validationPromises = Object.entries(messageValidators).map(async ([name, { validator, severity }]) => {
1643
1726
  const { result } = await validator.validateTx(tx);
@@ -1646,8 +1729,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1646
1729
 
1647
1730
  // A promise that resolves when all validations have been run
1648
1731
  const allValidations = await Promise.all(validationPromises);
1649
- const failed = allValidations.find(x => !x.isValid);
1650
- if (failed) {
1732
+ const failures = allValidations.filter(x => !x.isValid);
1733
+ if (failures.length > 0) {
1734
+ // Pick the most severe failure (lowest tolerance = harshest penalty)
1735
+ const failed = maxBy(failures, f => PeerErrorSeverityByHarshness.indexOf(f.severity))!;
1651
1736
  return {
1652
1737
  allPassed: false,
1653
1738
  failure: {
@@ -1700,31 +1785,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1700
1785
  return PeerErrorSeverity.HighToleranceError;
1701
1786
  }
1702
1787
 
1703
- /**
1704
- * Validate a checkpoint attestation.
1705
- *
1706
- * @param attestation - The checkpoint attestation to validate.
1707
- * @returns True if the checkpoint attestation is valid, false otherwise.
1708
- */
1709
- @trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
1710
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1711
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1712
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1713
- }))
1714
- public async validateCheckpointAttestation(
1715
- peerId: PeerId,
1716
- attestation: CheckpointAttestation,
1717
- ): Promise<P2PValidationResult> {
1718
- const result = await this.checkpointAttestationValidator.validate(attestation);
1719
-
1720
- if (result.result === 'reject') {
1721
- this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1722
- this.peerManager.penalizePeer(peerId, result.severity);
1723
- }
1724
-
1725
- return result;
1726
- }
1727
-
1728
1788
  public getPeerScore(peerId: PeerId): number {
1729
1789
  return this.node.services.pubsub.score.score(peerId.toString());
1730
1790
  }