@aztec/p2p 0.0.1-commit.1bb068fb5 → 0.0.1-commit.1dcfe2301

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 (413) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +7 -7
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +32 -28
  5. package/dest/client/interface.d.ts +18 -20
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +9 -19
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +81 -104
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +20 -10
  11. package/dest/config.d.ts +126 -103
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +93 -39
  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 +1 -2
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +0 -1
  23. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +7 -5
  24. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.js +16 -9
  26. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  27. package/dest/mem_pools/index.d.ts +1 -2
  28. package/dest/mem_pools/index.d.ts.map +1 -1
  29. package/dest/mem_pools/instrumentation.d.ts +4 -2
  30. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  31. package/dest/mem_pools/instrumentation.js +16 -14
  32. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -1
  33. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +9 -0
  35. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  36. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  38. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  39. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +5 -4
  41. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  42. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  44. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  45. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  46. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  48. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  50. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +4 -4
  51. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +7 -7
  52. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  53. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  54. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +12 -6
  55. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  56. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  57. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  58. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  59. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  60. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  61. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  62. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  63. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  64. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  65. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  66. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  67. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +24 -10
  68. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  69. package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
  70. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +54 -15
  71. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  72. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +112 -20
  73. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +5 -2
  74. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  75. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +38 -46
  76. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -4
  77. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  78. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +12 -5
  79. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -5
  80. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  81. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +296 -153
  82. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +5 -2
  83. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  84. package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
  85. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -2
  86. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  87. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  88. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  89. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  90. package/dest/msg_validators/clock_tolerance.js +54 -3
  91. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +7 -4
  92. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  93. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  94. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +7 -4
  95. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  96. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  97. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +15 -8
  98. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  99. package/dest/msg_validators/proposal_validator/proposal_validator.js +67 -47
  100. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  101. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  102. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  103. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  104. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  105. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  106. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  107. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  108. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  109. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  110. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  111. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  112. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  113. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  114. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  116. package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
  117. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  118. package/dest/msg_validators/tx_validator/factory.js +247 -60
  119. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  120. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  121. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  122. package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
  123. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  124. package/dest/msg_validators/tx_validator/gas_validator.js +112 -43
  125. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  126. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  127. package/dest/msg_validators/tx_validator/index.js +2 -0
  128. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  129. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  130. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  131. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  132. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  133. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  134. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  135. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  136. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  137. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
  138. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  139. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  140. package/dest/services/data_store.d.ts +1 -1
  141. package/dest/services/data_store.d.ts.map +1 -1
  142. package/dest/services/data_store.js +5 -5
  143. package/dest/services/dummy_service.d.ts +8 -5
  144. package/dest/services/dummy_service.d.ts.map +1 -1
  145. package/dest/services/dummy_service.js +10 -5
  146. package/dest/services/encoding.d.ts +6 -2
  147. package/dest/services/encoding.d.ts.map +1 -1
  148. package/dest/services/encoding.js +16 -9
  149. package/dest/services/gossipsub/topic_score_params.d.ts +30 -7
  150. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  151. package/dest/services/gossipsub/topic_score_params.js +53 -14
  152. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  153. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  154. package/dest/services/libp2p/instrumentation.js +14 -0
  155. package/dest/services/libp2p/libp2p_service.d.ts +29 -36
  156. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  157. package/dest/services/libp2p/libp2p_service.js +236 -197
  158. package/dest/services/peer-manager/metrics.d.ts +3 -1
  159. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  160. package/dest/services/peer-manager/metrics.js +6 -0
  161. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  162. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  163. package/dest/services/peer-manager/peer_manager.js +39 -11
  164. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  165. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  166. package/dest/services/peer-manager/peer_scoring.js +32 -10
  167. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +12 -8
  168. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  169. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +83 -106
  170. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -7
  171. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  172. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  173. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  174. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  175. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  176. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  177. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  178. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  179. package/dest/services/reqresp/config.d.ts +3 -3
  180. package/dest/services/reqresp/config.d.ts.map +1 -1
  181. package/dest/services/reqresp/interface.d.ts +14 -9
  182. package/dest/services/reqresp/interface.d.ts.map +1 -1
  183. package/dest/services/reqresp/interface.js +10 -11
  184. package/dest/services/reqresp/metrics.d.ts +1 -1
  185. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  186. package/dest/services/reqresp/metrics.js +0 -1
  187. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  188. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  189. package/dest/services/reqresp/protocols/index.js +0 -1
  190. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  191. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  192. package/dest/services/reqresp/protocols/tx.js +1 -3
  193. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  194. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  195. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  196. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  197. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  198. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  199. package/dest/services/reqresp/reqresp.d.ts +4 -2
  200. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  201. package/dest/services/reqresp/reqresp.js +30 -12
  202. package/dest/services/service.d.ts +9 -4
  203. package/dest/services/service.d.ts.map +1 -1
  204. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
  205. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  206. package/dest/services/tx_collection/fast_tx_collection.js +65 -75
  207. package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
  208. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  209. package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
  210. package/dest/services/tx_collection/file_store_tx_source.d.ts +16 -6
  211. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  212. package/dest/services/tx_collection/file_store_tx_source.js +50 -9
  213. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  214. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  215. package/dest/services/tx_collection/instrumentation.js +2 -1
  216. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -7
  217. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  218. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  219. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  220. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  221. package/dest/services/tx_collection/request_tracker.js +84 -0
  222. package/dest/services/tx_collection/slow_tx_collection.d.ts +2 -2
  223. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  224. package/dest/services/tx_collection/slow_tx_collection.js +10 -8
  225. package/dest/services/tx_collection/tx_collection.d.ts +5 -7
  226. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  227. package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
  228. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  229. package/dest/services/tx_collection/tx_collection_sink.js +13 -22
  230. package/dest/services/tx_collection/tx_source.d.ts +13 -7
  231. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  232. package/dest/services/tx_collection/tx_source.js +26 -7
  233. package/dest/services/tx_file_store/tx_file_store.js +1 -1
  234. package/dest/services/tx_provider.d.ts +3 -3
  235. package/dest/services/tx_provider.d.ts.map +1 -1
  236. package/dest/services/tx_provider.js +4 -4
  237. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  238. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  239. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  240. package/dest/test-helpers/mock-pubsub.d.ts +14 -6
  241. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  242. package/dest/test-helpers/mock-pubsub.js +43 -12
  243. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  244. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  245. package/dest/test-helpers/reqresp-nodes.js +3 -4
  246. package/dest/test-helpers/testbench-utils.d.ts +6 -3
  247. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  248. package/dest/test-helpers/testbench-utils.js +24 -4
  249. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  250. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  251. package/dest/testbench/p2p_client_testbench_worker.js +78 -26
  252. package/dest/testbench/worker_client_manager.d.ts +10 -1
  253. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  254. package/dest/testbench/worker_client_manager.js +55 -3
  255. package/dest/util.d.ts +3 -3
  256. package/dest/util.d.ts.map +1 -1
  257. package/package.json +14 -14
  258. package/src/client/factory.ts +55 -47
  259. package/src/client/interface.ts +20 -21
  260. package/src/client/p2p_client.ts +89 -135
  261. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +33 -14
  262. package/src/config.ts +139 -45
  263. package/src/errors/p2p-service.error.ts +11 -0
  264. package/src/errors/tx-pool.error.ts +12 -0
  265. package/src/index.ts +0 -1
  266. package/src/mem_pools/attestation_pool/attestation_pool.ts +17 -12
  267. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  268. package/src/mem_pools/index.ts +0 -3
  269. package/src/mem_pools/instrumentation.ts +17 -13
  270. package/src/mem_pools/tx_pool_v2/README.md +10 -2
  271. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +11 -0
  272. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  273. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +5 -4
  274. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  275. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  276. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  277. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -4
  278. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +8 -8
  279. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +12 -9
  280. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  281. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  282. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  283. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  284. package/src/mem_pools/tx_pool_v2/interfaces.ts +24 -10
  285. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +160 -28
  286. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -46
  287. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +28 -8
  288. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +330 -149
  289. package/src/msg_validators/attestation_validator/README.md +49 -0
  290. package/src/msg_validators/attestation_validator/attestation_validator.ts +21 -9
  291. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -1
  292. package/src/msg_validators/clock_tolerance.ts +72 -3
  293. package/src/msg_validators/proposal_validator/README.md +123 -0
  294. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +17 -4
  295. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +23 -7
  296. package/src/msg_validators/proposal_validator/proposal_validator.ts +79 -49
  297. package/src/msg_validators/tx_validator/README.md +119 -0
  298. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
  299. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  300. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  301. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  302. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  303. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  304. package/src/msg_validators/tx_validator/factory.ts +394 -78
  305. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  306. package/src/msg_validators/tx_validator/gas_validator.ts +145 -33
  307. package/src/msg_validators/tx_validator/index.ts +2 -0
  308. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  309. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  310. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  311. package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
  312. package/src/services/data_store.ts +5 -13
  313. package/src/services/dummy_service.ts +13 -7
  314. package/src/services/encoding.ts +16 -8
  315. package/src/services/gossipsub/README.md +29 -14
  316. package/src/services/gossipsub/topic_score_params.ts +85 -17
  317. package/src/services/libp2p/instrumentation.ts +14 -0
  318. package/src/services/libp2p/libp2p_service.ts +251 -225
  319. package/src/services/peer-manager/metrics.ts +7 -0
  320. package/src/services/peer-manager/peer_manager.ts +45 -11
  321. package/src/services/peer-manager/peer_scoring.ts +27 -5
  322. package/src/services/reqresp/README.md +229 -0
  323. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  324. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +79 -112
  325. package/src/services/reqresp/batch-tx-requester/interface.ts +3 -6
  326. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  327. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  328. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  329. package/src/services/reqresp/config.ts +2 -2
  330. package/src/services/reqresp/interface.ts +21 -11
  331. package/src/services/reqresp/metrics.ts +0 -1
  332. package/src/services/reqresp/protocols/index.ts +0 -1
  333. package/src/services/reqresp/protocols/tx.ts +1 -3
  334. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  335. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  336. package/src/services/reqresp/reqresp.ts +40 -13
  337. package/src/services/service.ts +17 -3
  338. package/src/services/tx_collection/fast_tx_collection.ts +71 -76
  339. package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
  340. package/src/services/tx_collection/file_store_tx_source.ts +65 -9
  341. package/src/services/tx_collection/instrumentation.ts +7 -1
  342. package/src/services/tx_collection/proposal_tx_collector.ts +9 -13
  343. package/src/services/tx_collection/request_tracker.ts +127 -0
  344. package/src/services/tx_collection/slow_tx_collection.ts +8 -9
  345. package/src/services/tx_collection/tx_collection.ts +5 -6
  346. package/src/services/tx_collection/tx_collection_sink.ts +15 -29
  347. package/src/services/tx_collection/tx_source.ts +28 -8
  348. package/src/services/tx_file_store/tx_file_store.ts +1 -1
  349. package/src/services/tx_provider.ts +2 -2
  350. package/src/test-helpers/make-test-p2p-clients.ts +1 -3
  351. package/src/test-helpers/mock-pubsub.ts +44 -11
  352. package/src/test-helpers/reqresp-nodes.ts +5 -8
  353. package/src/test-helpers/testbench-utils.ts +33 -6
  354. package/src/testbench/p2p_client_testbench_worker.ts +89 -29
  355. package/src/testbench/worker_client_manager.ts +68 -6
  356. package/src/util.ts +8 -2
  357. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  358. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  359. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  360. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  361. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  362. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  363. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  364. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  365. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  366. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  367. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  368. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  369. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  370. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  371. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  372. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  373. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  374. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  375. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  376. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  377. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  378. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  379. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  380. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  381. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  382. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  383. package/dest/mem_pools/tx_pool/index.js +0 -2
  384. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  385. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  386. package/dest/mem_pools/tx_pool/priority.js +0 -15
  387. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  388. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  389. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  390. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  391. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  392. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  393. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  394. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  395. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  396. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  397. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  398. package/dest/services/reqresp/protocols/block.js +0 -32
  399. package/src/mem_pools/tx_pool/README.md +0 -270
  400. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  401. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  402. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  403. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  404. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  405. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  406. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  407. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  408. package/src/mem_pools/tx_pool/index.ts +0 -2
  409. package/src/mem_pools/tx_pool/priority.ts +0 -20
  410. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  411. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  412. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
  413. package/src/services/reqresp/protocols/block.ts +0 -37
@@ -1,12 +1,12 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
- import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import { maxBy } from '@aztec/foundation/collection';
4
4
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
5
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
6
6
  import { Timer } from '@aztec/foundation/timer';
7
7
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
8
8
  import { protocolContractsHash } from '@aztec/protocol-contracts';
9
- import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
9
+ import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
10
10
  import type { ContractDataSource } from '@aztec/stdlib/contract';
11
11
  import { GasFees } from '@aztec/stdlib/gas';
12
12
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
@@ -16,13 +16,12 @@ import {
16
16
  CheckpointProposal,
17
17
  type CheckpointProposalCore,
18
18
  type Gossipable,
19
- P2PClientType,
20
19
  P2PMessage,
21
- type ValidationResult as P2PValidationResult,
22
20
  PeerErrorSeverity,
21
+ PeerErrorSeverityByHarshness,
23
22
  TopicType,
24
23
  createTopicString,
25
- getTopicsForClientAndConfig,
24
+ getTopicsForConfig,
26
25
  metricsTopicStrToLabels,
27
26
  } from '@aztec/stdlib/p2p';
28
27
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -58,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
58
57
  import { createLibp2p } from 'libp2p';
59
58
 
60
59
  import type { P2PConfig } from '../../config.js';
60
+ import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
61
61
  import type { MemPools } from '../../mem_pools/interface.js';
62
62
  import {
63
63
  BlockProposalValidator,
@@ -69,9 +69,11 @@ import {
69
69
  } from '../../msg_validators/index.js';
70
70
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
71
71
  import {
72
- type MessageValidator,
73
- createTxMessageValidators,
74
- createTxReqRespValidator,
72
+ type TransactionValidator,
73
+ createFirstStageTxValidationsForGossipedTransactions,
74
+ createSecondStageTxValidationsForGossipedTransactions,
75
+ createTxValidatorForBlockProposalReceivedTxs,
76
+ createTxValidatorForReqResponseReceivedTxs,
75
77
  } from '../../msg_validators/tx_validator/factory.js';
76
78
  import { GossipSubEvent } from '../../types/index.js';
77
79
  import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
@@ -87,6 +89,9 @@ 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,
@@ -130,12 +129,12 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
130
129
  // REFACTOR: Unify with the type above
131
130
  type ReceivedMessageValidationResult<T, M = undefined> =
132
131
  | { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
133
- | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
132
+ | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
134
133
 
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
 
@@ -171,7 +170,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
171
170
  * @param checkpoint - The checkpoint proposal received from the peer.
172
171
  * @returns The attestations for the checkpoint, if any.
173
172
  */
174
- private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
173
+ private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
174
+ /**
175
+ * Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
176
+ * @param checkpoint - The checkpoint proposal received from the peer.
177
+ * @returns The attestations for the checkpoint, if any.
178
+ */
179
+ private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
175
180
 
176
181
  private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
177
182
 
@@ -182,7 +187,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
182
187
  protected logger: Logger;
183
188
 
184
189
  constructor(
185
- private clientType: T,
186
190
  private config: P2PConfig,
187
191
  protected node: PubSubLibp2p,
188
192
  private peerDiscoveryService: PeerDiscoveryService,
@@ -224,30 +228,39 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
224
228
  this.protocolVersion,
225
229
  );
226
230
 
227
- this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
228
- this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
231
+ const p2pPropagationTime = config.attestationPropagationTime;
232
+ const proposalValidatorOpts = {
229
233
  txsPermitted: !config.disableTransactions,
230
- });
234
+ maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
235
+ p2pPropagationTime,
236
+ };
237
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
238
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
231
239
  this.checkpointAttestationValidator = config.fishermanMode
232
- ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
233
- : new CheckpointAttestationValidator(epochCache);
240
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, {
241
+ l1PublishingTime: config.l1PublishingTime,
242
+ })
243
+ : new CheckpointAttestationValidator(epochCache, { l1PublishingTime: config.l1PublishingTime });
234
244
 
235
245
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
236
246
 
237
247
  this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
238
- this.logger.debug(
239
- `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
248
+ this.logger.warn(
249
+ `Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`,
240
250
  { p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
241
251
  );
242
- return false;
252
+ return true;
243
253
  };
244
254
 
245
- this.checkpointReceivedCallback = (
246
- checkpoint: CheckpointProposalCore,
255
+ this.allNodesCheckpointReceivedCallback = (
256
+ _checkpoint: CheckpointProposalCore,
257
+ ): Promise<CheckpointAttestation[] | undefined> => {
258
+ throw new CheckpointProposalReceivedCallbackNotRegisteredError();
259
+ };
260
+
261
+ this.validatorCheckpointReceivedCallback = (
262
+ _checkpoint: CheckpointProposalCore,
247
263
  ): Promise<CheckpointAttestation[] | undefined> => {
248
- this.logger.debug(
249
- `Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
250
- );
251
264
  return Promise.resolve(undefined);
252
265
  };
253
266
  }
@@ -262,8 +275,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
262
275
  * @param txPool - The transaction pool to be accessed by the service.
263
276
  * @returns The new service.
264
277
  */
265
- public static async new<T extends P2PClientType>(
266
- clientType: T,
278
+ public static async new(
267
279
  config: P2PConfig,
268
280
  peerId: PeerId,
269
281
  deps: {
@@ -338,9 +350,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
338
350
  const l1Constants = epochCache.getL1Constants();
339
351
  const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
340
352
  slotDurationMs: l1Constants.slotDuration * 1000,
353
+ ethereumSlotDuration: l1Constants.ethereumSlotDuration,
341
354
  heartbeatIntervalMs: config.gossipsubInterval,
342
355
  targetCommitteeSize: l1Constants.targetCommitteeSize,
343
356
  blockDurationMs: config.blockDurationMs,
357
+ l1PublishingTime: config.l1PublishingTime,
358
+ p2pPropagationTime: config.attestationPropagationTime,
359
+ expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
344
360
  });
345
361
 
346
362
  const node = await createLibp2p({
@@ -464,6 +480,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
464
480
  epochCache,
465
481
  );
466
482
 
483
+ // Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
484
+ reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
485
+
467
486
  // Configure application-specific scoring for gossipsub.
468
487
  // The weight scales app score to align with gossipsub thresholds:
469
488
  // - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
@@ -474,7 +493,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
474
493
  peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
475
494
 
476
495
  return new LibP2PService(
477
- clientType,
478
496
  config,
479
497
  node,
480
498
  peerDiscoveryService,
@@ -510,14 +528,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
510
528
  // Create request response protocol handlers
511
529
  const txHandler = reqRespTxHandler(this.mempools);
512
530
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
513
- const blockHandler = reqRespBlockHandler(this.archiver);
514
531
  const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
515
532
 
516
533
  const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
517
534
  [ReqRespSubProtocol.PING]: pingHandler,
518
535
  [ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
519
536
  [ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
520
- [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
521
537
  };
522
538
 
523
539
  if (!this.config.disableTransactions) {
@@ -538,7 +554,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
538
554
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
539
555
  [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
540
556
  [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
541
- [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
542
557
  };
543
558
 
544
559
  await this.peerManager.initializePeers();
@@ -548,7 +563,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
548
563
  await this.node.start();
549
564
 
550
565
  // Subscribe to standard GossipSub topics by default
551
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
566
+ for (const topic of getTopicsForConfig(this.config.disableTransactions)) {
552
567
  this.subscribeToTopic(this.topicStrings[topic]);
553
568
  }
554
569
 
@@ -614,6 +629,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
614
629
  return this.peerManager.getPeers(includePending);
615
630
  }
616
631
 
632
+ public getGossipMeshPeerCount(topicType: TopicType): number {
633
+ return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
634
+ }
635
+
617
636
  private handleGossipSubEvent(e: CustomEvent<GossipsubMessage>) {
618
637
  this.logger.trace(`Received PUBSUB message.`);
619
638
 
@@ -662,8 +681,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
662
681
  this.blockReceivedCallback = callback;
663
682
  }
664
683
 
665
- public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
666
- this.checkpointReceivedCallback = callback;
684
+ public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
685
+ this.validatorCheckpointReceivedCallback = callback;
686
+ }
687
+
688
+ public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
689
+ this.allNodesCheckpointReceivedCallback = callback;
690
+ }
691
+
692
+ public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
693
+ await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
667
694
  }
668
695
 
669
696
  /**
@@ -749,6 +776,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
749
776
  if (!validator || !validator.addMessage(msgId)) {
750
777
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
751
778
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
779
+ if (topicType === TopicType.tx) {
780
+ this.logger.verbose(`Ignoring already-seen tx gossip message`, { msgId, source: source.toString() });
781
+ }
752
782
  return { result: false, topicType };
753
783
  }
754
784
 
@@ -813,9 +843,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
813
843
  if (msg.topic === this.topicStrings[TopicType.tx]) {
814
844
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
815
845
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
816
- if (this.clientType === P2PClientType.Full) {
817
- await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
818
- }
846
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
819
847
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
820
848
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
821
849
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
@@ -877,47 +905,124 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
877
905
  source: PeerId,
878
906
  topicType: TopicType,
879
907
  ): Promise<ReceivedMessageValidationResult<T, M>> {
880
- let resultAndObj: ReceivedMessageValidationResult<T, M> = { result: TopicValidatorResult.Reject };
908
+ // Default to reject result with a penalty if validation function throws an error
909
+ let resultAndObj: ReceivedMessageValidationResult<T, M> = {
910
+ result: TopicValidatorResult.Reject,
911
+ severity: PeerErrorSeverity.MidToleranceError,
912
+ };
881
913
  const timer = new Timer();
882
914
  try {
883
915
  resultAndObj = await validationFunc();
884
916
  } 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
- });
917
+ this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
918
+ }
919
+
920
+ const validationTimeMs = timer.ms();
921
+ const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
922
+ if (validationTimeMs > mcacheWindowMs * 0.75) {
923
+ this.instrumentation.incSlowValidation(topicType);
924
+ this.logger.warn(
925
+ `Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` +
926
+ `Message forwarding may be skipped if validation exceeds the window.`,
927
+ { msgId, source: source.toString(), topicType, validationTimeMs, mcacheWindowMs },
928
+ );
891
929
  }
892
930
 
893
931
  if (resultAndObj.result === TopicValidatorResult.Accept) {
932
+ this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
894
933
  this.instrumentation.recordMessageValidation(topicType, timer);
934
+ } else if (resultAndObj.result === TopicValidatorResult.Reject) {
935
+ this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
936
+ msgId,
937
+ source: source.toString(),
938
+ topicType,
939
+ severity: resultAndObj.severity,
940
+ });
941
+ this.peerManager.penalizePeer(source, resultAndObj.severity);
942
+ } else {
943
+ this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
895
944
  }
896
945
 
897
946
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
898
947
  return resultAndObj;
899
948
  }
900
949
 
950
+ private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
951
+ try {
952
+ return deserializeFunc();
953
+ } catch (err) {
954
+ this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
955
+ err,
956
+ msgId,
957
+ source: source.toString(),
958
+ });
959
+ return undefined;
960
+ }
961
+ }
962
+
901
963
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
902
964
  const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
903
- const tx = Tx.fromBuffer(payloadData);
904
- const isValid = await this.validatePropagatedTx(tx, source);
905
- if (!isValid) {
906
- this.logger.trace(`Rejecting invalid propagated tx`, {
907
- [Attributes.P2P_ID]: source.toString(),
965
+ const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
966
+ if (!tx) {
967
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
968
+ }
969
+
970
+ const currentBlockNumber = await this.archiver.getBlockNumber();
971
+ const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
972
+
973
+ // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
974
+ const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
975
+ const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
976
+ if (!firstStageOutcome.allPassed) {
977
+ const { name } = firstStageOutcome.failure;
978
+ let { severity } = firstStageOutcome.failure;
979
+
980
+ // Double spend validator has a special case handler. We perform more detailed examination
981
+ // as to how recently the nullifier was entered into the tree and if the transaction should
982
+ // have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
983
+ if (name === 'doubleSpendValidator') {
984
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1);
985
+ severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
986
+ }
987
+
988
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
989
+ validator: name,
990
+ severity,
991
+ source: source.toString(),
908
992
  });
909
- return { result: TopicValidatorResult.Reject };
993
+ return { result: TopicValidatorResult.Reject, severity };
994
+ }
995
+
996
+ // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
997
+ const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
998
+ if (canAdd === 'ignored') {
999
+ this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
1000
+ source: source.toString(),
1001
+ });
1002
+ return { result: TopicValidatorResult.Ignore, obj: tx };
910
1003
  }
911
1004
 
912
- // Propagate only on pool acceptance
1005
+ // Stage 2: expensive proof verification
1006
+ const secondStageValidators = this.createSecondStageMessageValidators();
1007
+ const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
1008
+ if (!secondStageOutcome.allPassed) {
1009
+ const { severity, name } = secondStageOutcome.failure;
1010
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
1011
+ validator: name,
1012
+ severity,
1013
+ source: source.toString(),
1014
+ });
1015
+ return { result: TopicValidatorResult.Reject, severity };
1016
+ }
1017
+
1018
+ // Pool add: persist the tx
913
1019
  const txHash = tx.getTxHash();
914
1020
  const addResult = await this.mempools.txPool.addPendingTxs([tx], { source: 'gossip' });
915
1021
 
916
1022
  const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
917
1023
  const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
918
1024
 
919
- this.logger.trace(`Validate propagated tx`, {
920
- isValid,
1025
+ this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
921
1026
  wasAccepted,
922
1027
  wasIgnored,
923
1028
  [Attributes.P2P_ID]: source.toString(),
@@ -928,7 +1033,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
928
1033
  } else if (wasIgnored) {
929
1034
  return { result: TopicValidatorResult.Ignore, obj: tx };
930
1035
  } else {
931
- return { result: TopicValidatorResult.Reject };
1036
+ this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
1037
+ source: source.toString(),
1038
+ txHash: txHash.toString(),
1039
+ });
1040
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
932
1041
  }
933
1042
  };
934
1043
 
@@ -958,7 +1067,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
958
1067
  source: PeerId,
959
1068
  ): Promise<void> {
960
1069
  const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
961
- () => this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)),
1070
+ () => {
1071
+ const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
1072
+ if (!attestation) {
1073
+ return Promise.resolve({
1074
+ result: TopicValidatorResult.Reject,
1075
+ severity: PeerErrorSeverity.LowToleranceError,
1076
+ });
1077
+ }
1078
+ return this.validateAndStoreCheckpointAttestation(source, attestation);
1079
+ },
962
1080
  msgId,
963
1081
  source,
964
1082
  TopicType.checkpoint_attestation,
@@ -991,8 +1109,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
991
1109
 
992
1110
  if (validationResult.result === 'reject') {
993
1111
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
994
- this.peerManager.penalizePeer(peerId, validationResult.severity);
995
- return { result: TopicValidatorResult.Reject };
1112
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
996
1113
  }
997
1114
 
998
1115
  if (validationResult.result === 'ignore') {
@@ -1018,16 +1135,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1018
1135
  return { result: TopicValidatorResult.Ignore, obj: attestation };
1019
1136
  }
1020
1137
 
1021
- // Could not add (cap reached for signer), no need to re-broadcast
1138
+ // Could not add (cap reached for signer), penalize and do not re-broadcast
1022
1139
  if (!added) {
1023
- this.logger.warn(`Dropping checkpoint attestation due to cap`, {
1140
+ this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
1024
1141
  slot: slot.toString(),
1025
1142
  archive: attestation.archive.toString(),
1026
1143
  source: peerId.toString(),
1027
1144
  attester: attestation.getSender()?.toString(),
1028
1145
  count,
1029
1146
  });
1030
- return { result: TopicValidatorResult.Ignore, obj: attestation };
1147
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
1031
1148
  }
1032
1149
 
1033
1150
  // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
@@ -1082,8 +1199,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1082
1199
 
1083
1200
  if (validationResult.result === 'reject') {
1084
1201
  this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
1085
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1086
- return { result: TopicValidatorResult.Reject };
1202
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1087
1203
  }
1088
1204
 
1089
1205
  if (validationResult.result === 'ignore') {
@@ -1107,7 +1223,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1107
1223
 
1108
1224
  // Too many blocks received for this slot and index, penalize peer and do not re-broadcast
1109
1225
  if (!added) {
1110
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1111
1226
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1112
1227
  ...block.toBlockInfo(),
1113
1228
  indexWithinCheckpoint: block.indexWithinCheckpoint,
@@ -1115,7 +1230,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1115
1230
  proposer: block.getSender()?.toString(),
1116
1231
  source: peerId.toString(),
1117
1232
  });
1118
- return { result: TopicValidatorResult.Reject, metadata: { isEquivocated } };
1233
+ return {
1234
+ result: TopicValidatorResult.Reject,
1235
+ metadata: { isEquivocated },
1236
+ severity: PeerErrorSeverity.HighToleranceError,
1237
+ };
1119
1238
  }
1120
1239
 
1121
1240
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1160,7 +1279,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1160
1279
  // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1161
1280
  const isValid = await this.blockReceivedCallback(block, sender);
1162
1281
  if (!isValid) {
1163
- this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1282
+ this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1164
1283
  }
1165
1284
  }
1166
1285
 
@@ -1208,8 +1327,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1208
1327
 
1209
1328
  if (validationResult.result === 'reject') {
1210
1329
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1211
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1212
- return { result: TopicValidatorResult.Reject };
1330
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1213
1331
  }
1214
1332
 
1215
1333
  if (validationResult.result === 'ignore') {
@@ -1224,20 +1342,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1224
1342
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1225
1343
  [Attributes.P2P_ID]: peerId.toString(),
1226
1344
  });
1227
- const {
1228
- result,
1229
- obj,
1230
- metadata: { isEquivocated } = {},
1231
- } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1232
- if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1345
+ const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1346
+ const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1347
+ if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1233
1348
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1234
1349
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1235
1350
  [Attributes.P2P_ID]: peerId.toString(),
1236
1351
  isEquivocated,
1237
- result,
1352
+ result: blockProposalResult.result,
1238
1353
  });
1239
- return { result: TopicValidatorResult.Reject };
1240
- } else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1354
+ return {
1355
+ result: TopicValidatorResult.Reject,
1356
+ severity:
1357
+ 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
1358
+ };
1359
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1241
1360
  processBlock = true;
1242
1361
  }
1243
1362
  }
@@ -1264,13 +1383,17 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1264
1383
  // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1265
1384
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1266
1385
  if (!added) {
1267
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1268
1386
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1269
1387
  ...checkpoint.toCheckpointInfo(),
1270
1388
  count,
1271
1389
  source: peerId.toString(),
1272
1390
  });
1273
- return { result: TopicValidatorResult.Reject, obj: checkpoint, metadata: { isEquivocated, processBlock } };
1391
+ return {
1392
+ result: TopicValidatorResult.Reject,
1393
+ obj: checkpoint,
1394
+ metadata: { isEquivocated, processBlock },
1395
+ severity: PeerErrorSeverity.HighToleranceError,
1396
+ };
1274
1397
  }
1275
1398
 
1276
1399
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1315,9 +1438,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1315
1438
  source: sender.toString(),
1316
1439
  });
1317
1440
 
1441
+ await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
1442
+
1318
1443
  // Call the checkpoint received callback with the core version (without lastBlock)
1319
1444
  // to validate and potentially generate attestations
1320
- const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
1445
+ const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
1321
1446
  if (attestations && attestations.length > 0) {
1322
1447
  // If the callback returned attestations, add them to the pool and propagate them
1323
1448
  await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
@@ -1465,53 +1590,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1465
1590
  }
1466
1591
  }
1467
1592
 
1468
- /**
1469
- * Validates a BLOCK response.
1470
- *
1471
- * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1472
- * Penalizes on block number mismatch or hash mismatch.
1473
- *
1474
- * @param requestedBlockNumber - The requested block number.
1475
- * @param responseBlock - The block returned by the peer.
1476
- * @param peerId - The peer that returned the block.
1477
- * @returns True if the response is valid, false otherwise.
1478
- */
1479
- @trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
1480
- [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
1481
- }))
1482
- protected async validateRequestedBlock(
1483
- requestedBlockNumber: Fr,
1484
- responseBlock: L2Block,
1485
- peerId: PeerId,
1486
- ): Promise<boolean> {
1487
- try {
1488
- const reqNum = Number(requestedBlockNumber.toString());
1489
- if (responseBlock.number !== reqNum) {
1490
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1491
- return false;
1492
- }
1493
-
1494
- const local = await this.archiver.getBlock(BlockNumber(reqNum));
1495
- if (!local) {
1496
- // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1497
- // TODO: Consider extending this validator to accept an expected hash or
1498
- // performing quorum-based checks when using P2P syncing prior to L1 sync.
1499
- this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1500
- return false;
1501
- }
1502
- const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
1503
- if (!localHash.equals(respHash)) {
1504
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1505
- return false;
1506
- }
1507
-
1508
- return true;
1509
- } catch (e) {
1510
- this.logger.warn(`Error validating requested block`, e);
1511
- return false;
1512
- }
1513
- }
1514
-
1515
1593
  protected async validateRequestedTx(
1516
1594
  tx: Tx,
1517
1595
  peerId: PeerId,
@@ -1532,43 +1610,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1532
1610
  }
1533
1611
 
1534
1612
  protected createRequestedTxValidator(): TxValidator {
1535
- return createTxReqRespValidator(this.proofVerifier, {
1613
+ return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
1536
1614
  l1ChainId: this.config.l1ChainId,
1537
1615
  rollupVersion: this.config.rollupVersion,
1538
1616
  });
1539
1617
  }
1540
1618
 
1541
- @trackSpan('Libp2pService.validatePropagatedTx', tx => ({
1542
- [Attributes.TX_HASH]: tx.getTxHash().toString(),
1543
- }))
1544
- protected async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
1545
- const currentBlockNumber = await this.archiver.getBlockNumber();
1546
-
1547
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1548
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1549
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1550
-
1551
- for (const validator of messageValidators) {
1552
- const outcome = await this.runValidations(tx, validator);
1553
-
1554
- if (outcome.allPassed) {
1555
- continue;
1556
- }
1557
- const { name } = outcome.failure;
1558
- let { severity } = outcome.failure;
1559
-
1560
- // Double spend validator has a special case handler
1561
- if (name === 'doubleSpendValidator') {
1562
- const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1563
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1564
- }
1565
-
1566
- this.peerManager.penalizePeer(peerId, severity);
1567
- return false;
1568
- }
1569
- return true;
1570
- }
1571
-
1572
1619
  private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
1573
1620
  if (blockNumber === this.feesCache?.blockNumber) {
1574
1621
  return this.feesCache.gasFees;
@@ -1596,60 +1643,62 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1596
1643
  };
1597
1644
  }
1598
1645
 
1599
- public async validate(txs: Tx[]): Promise<void> {
1600
- const currentBlockNumber = await this.archiver.getBlockNumber();
1601
-
1602
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1603
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1604
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1646
+ public async validateTxsReceivedInBlockProposal(txs: Tx[]): Promise<void> {
1647
+ const validator = createTxValidatorForBlockProposalReceivedTxs(
1648
+ this.proofVerifier,
1649
+ { l1ChainId: this.config.l1ChainId, rollupVersion: this.config.rollupVersion },
1650
+ this.logger.getBindings(),
1651
+ );
1605
1652
 
1606
- await Promise.all(
1653
+ const results = await Promise.all(
1607
1654
  txs.map(async tx => {
1608
- for (const validator of messageValidators) {
1609
- const outcome = await this.runValidations(tx, validator);
1610
- if (!outcome.allPassed) {
1611
- throw new Error('Invalid tx detected', { cause: { outcome } });
1612
- }
1613
- }
1655
+ const result = await validator.validateTx(tx);
1656
+ return result.result !== 'invalid';
1614
1657
  }),
1615
1658
  );
1659
+ if (results.some(value => value === false)) {
1660
+ throw new Error('Invalid tx detected');
1661
+ }
1616
1662
  }
1617
1663
 
1618
- /**
1619
- * Create message validators for the given block number and timestamp.
1620
- *
1621
- * Each validator is a pair of a validator and a severity.
1622
- * If a validator fails, the peer is penalized with the severity of the validator.
1623
- *
1624
- * @param currentBlockNumber - The current synced block number.
1625
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
1626
- * @returns The message validators.
1627
- */
1628
- private async createMessageValidators(
1664
+ /** Creates the first stage (fast) validators for gossiped transactions. */
1665
+ protected async createFirstStageMessageValidators(
1629
1666
  currentBlockNumber: BlockNumber,
1630
1667
  nextSlotTimestamp: UInt64,
1631
- ): Promise<Record<string, MessageValidator>[]> {
1668
+ ): Promise<Record<string, TransactionValidator>> {
1632
1669
  const gasFees = await this.getGasFees(currentBlockNumber);
1633
- const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
1634
-
1635
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1636
-
1637
- return createTxMessageValidators(
1670
+ const allowedInSetup = [
1671
+ ...(await getDefaultAllowedSetupFunctions()),
1672
+ ...(this.config.txPublicSetupAllowListExtend ?? []),
1673
+ ];
1674
+ const blockNumber = BlockNumber(currentBlockNumber + 1);
1675
+ const l1Constants = await this.archiver.getL1Constants();
1676
+
1677
+ return createFirstStageTxValidationsForGossipedTransactions(
1638
1678
  nextSlotTimestamp,
1639
- blockNumberInWhichTheTxIsConsideredToBeIncluded,
1679
+ blockNumber,
1640
1680
  this.worldStateSynchronizer,
1641
1681
  gasFees,
1642
1682
  this.config.l1ChainId,
1643
1683
  this.config.rollupVersion,
1644
1684
  protocolContractsHash,
1645
1685
  this.archiver,
1646
- this.proofVerifier,
1647
1686
  !this.config.disableTransactions,
1648
1687
  allowedInSetup,
1649
1688
  this.logger.getBindings(),
1689
+ {
1690
+ rollupManaLimit: l1Constants.rollupManaLimit,
1691
+ maxBlockL2Gas: this.config.validateMaxL2BlockGas,
1692
+ maxBlockDAGas: this.config.validateMaxDABlockGas,
1693
+ },
1650
1694
  );
1651
1695
  }
1652
1696
 
1697
+ /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */
1698
+ protected createSecondStageMessageValidators(): Record<string, TransactionValidator> {
1699
+ return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
1700
+ }
1701
+
1653
1702
  /**
1654
1703
  * Run validations on a tx.
1655
1704
  * @param tx - The tx to validate.
@@ -1658,7 +1707,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1658
1707
  */
1659
1708
  private async runValidations(
1660
1709
  tx: Tx,
1661
- messageValidators: Record<string, MessageValidator>,
1710
+ messageValidators: Record<string, TransactionValidator>,
1662
1711
  ): Promise<ValidationOutcome> {
1663
1712
  const validationPromises = Object.entries(messageValidators).map(async ([name, { validator, severity }]) => {
1664
1713
  const { result } = await validator.validateTx(tx);
@@ -1667,8 +1716,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1667
1716
 
1668
1717
  // A promise that resolves when all validations have been run
1669
1718
  const allValidations = await Promise.all(validationPromises);
1670
- const failed = allValidations.find(x => !x.isValid);
1671
- if (failed) {
1719
+ const failures = allValidations.filter(x => !x.isValid);
1720
+ if (failures.length > 0) {
1721
+ // Pick the most severe failure (lowest tolerance = harshest penalty)
1722
+ const failed = maxBy(failures, f => PeerErrorSeverityByHarshness.indexOf(f.severity))!;
1672
1723
  return {
1673
1724
  allPassed: false,
1674
1725
  failure: {
@@ -1721,31 +1772,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1721
1772
  return PeerErrorSeverity.HighToleranceError;
1722
1773
  }
1723
1774
 
1724
- /**
1725
- * Validate a checkpoint attestation.
1726
- *
1727
- * @param attestation - The checkpoint attestation to validate.
1728
- * @returns True if the checkpoint attestation is valid, false otherwise.
1729
- */
1730
- @trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
1731
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1732
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1733
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1734
- }))
1735
- public async validateCheckpointAttestation(
1736
- peerId: PeerId,
1737
- attestation: CheckpointAttestation,
1738
- ): Promise<P2PValidationResult> {
1739
- const result = await this.checkpointAttestationValidator.validate(attestation);
1740
-
1741
- if (result.result === 'reject') {
1742
- this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1743
- this.peerManager.penalizePeer(peerId, result.severity);
1744
- }
1745
-
1746
- return result;
1747
- }
1748
-
1749
1775
  public getPeerScore(peerId: PeerId): number {
1750
1776
  return this.node.services.pubsub.score.score(peerId.toString());
1751
1777
  }