@aztec/p2p 0.0.1-commit.87a0206 → 0.0.1-commit.88c5703d4

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 (372) hide show
  1. package/README.md +129 -3
  2. package/dest/client/factory.d.ts +9 -9
  3. package/dest/client/factory.d.ts.map +1 -1
  4. package/dest/client/factory.js +50 -13
  5. package/dest/client/interface.d.ts +39 -33
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +37 -50
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +148 -223
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
  11. package/dest/config.d.ts +48 -17
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +92 -38
  14. package/dest/errors/tx-pool.error.d.ts +8 -0
  15. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  16. package/dest/errors/tx-pool.error.js +9 -0
  17. package/dest/index.d.ts +2 -1
  18. package/dest/index.d.ts.map +1 -1
  19. package/dest/index.js +1 -0
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +21 -12
  21. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  22. package/dest/mem_pools/attestation_pool/attestation_pool.js +72 -38
  23. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  24. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +53 -53
  26. package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
  27. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  28. package/dest/mem_pools/attestation_pool/index.js +1 -1
  29. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  30. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  31. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  32. package/dest/mem_pools/index.d.ts +2 -1
  33. package/dest/mem_pools/index.d.ts.map +1 -1
  34. package/dest/mem_pools/instrumentation.d.ts +4 -2
  35. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  36. package/dest/mem_pools/instrumentation.js +16 -14
  37. package/dest/mem_pools/interface.d.ts +3 -3
  38. package/dest/mem_pools/interface.d.ts.map +1 -1
  39. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  40. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +2 -1
  42. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  43. package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
  44. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  45. package/dest/mem_pools/tx_pool/priority.js +4 -4
  46. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  47. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  48. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
  49. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  50. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  51. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  52. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  53. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  54. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  55. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  56. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  57. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +7 -3
  58. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  59. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  60. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  61. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  62. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  63. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  64. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  65. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  66. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
  68. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +7 -5
  69. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  70. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  71. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +14 -6
  72. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  73. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  74. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  75. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  76. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  77. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  78. package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
  79. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  80. package/dest/mem_pools/tx_pool_v2/index.js +2 -1
  81. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  82. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  83. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  84. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +26 -8
  85. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  86. package/dest/mem_pools/tx_pool_v2/interfaces.js +5 -1
  87. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +78 -15
  88. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  89. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +139 -18
  90. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
  91. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  92. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +50 -45
  93. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +12 -5
  94. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  95. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +17 -6
  96. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +14 -5
  97. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  98. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +364 -189
  99. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  100. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  102. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  103. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  104. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  105. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  106. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  107. package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
  108. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  109. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  110. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  111. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  112. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  113. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  114. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  115. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  116. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  117. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  118. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  119. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  120. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  121. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  122. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  123. package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
  124. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  125. package/dest/msg_validators/tx_validator/factory.js +240 -59
  126. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  127. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  128. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  129. package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
  130. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  131. package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
  132. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  133. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  134. package/dest/msg_validators/tx_validator/index.js +2 -0
  135. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  136. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  137. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  138. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  139. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  140. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  141. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  142. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  143. package/dest/msg_validators/tx_validator/phases_validator.js +71 -23
  144. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  145. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  146. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  147. package/dest/services/dummy_service.d.ts +9 -5
  148. package/dest/services/dummy_service.d.ts.map +1 -1
  149. package/dest/services/dummy_service.js +7 -4
  150. package/dest/services/encoding.d.ts +3 -3
  151. package/dest/services/encoding.d.ts.map +1 -1
  152. package/dest/services/encoding.js +11 -10
  153. package/dest/services/gossipsub/index.d.ts +3 -0
  154. package/dest/services/gossipsub/index.d.ts.map +1 -0
  155. package/dest/services/gossipsub/index.js +2 -0
  156. package/dest/services/gossipsub/scoring.d.ts +21 -3
  157. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  158. package/dest/services/gossipsub/scoring.js +24 -7
  159. package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
  160. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  161. package/dest/services/gossipsub/topic_score_params.js +346 -0
  162. package/dest/services/libp2p/libp2p_service.d.ts +25 -14
  163. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  164. package/dest/services/libp2p/libp2p_service.js +195 -153
  165. package/dest/services/peer-manager/metrics.d.ts +3 -1
  166. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  167. package/dest/services/peer-manager/metrics.js +6 -0
  168. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  169. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  170. package/dest/services/peer-manager/peer_manager.js +2 -1
  171. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  172. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  173. package/dest/services/peer-manager/peer_scoring.js +25 -2
  174. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -4
  175. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  176. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +45 -55
  177. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -6
  178. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  179. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  180. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  181. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  182. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  183. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  184. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  185. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  186. package/dest/services/reqresp/interface.d.ts +10 -1
  187. package/dest/services/reqresp/interface.d.ts.map +1 -1
  188. package/dest/services/reqresp/interface.js +15 -1
  189. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
  190. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  191. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
  192. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  193. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +15 -0
  194. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  195. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  196. package/dest/services/reqresp/protocols/tx.js +20 -0
  197. package/dest/services/reqresp/reqresp.d.ts +1 -1
  198. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  199. package/dest/services/reqresp/reqresp.js +14 -6
  200. package/dest/services/service.d.ts +22 -3
  201. package/dest/services/service.d.ts.map +1 -1
  202. package/dest/services/tx_collection/config.d.ts +19 -1
  203. package/dest/services/tx_collection/config.d.ts.map +1 -1
  204. package/dest/services/tx_collection/config.js +46 -0
  205. package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -1
  206. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  207. package/dest/services/tx_collection/fast_tx_collection.js +56 -36
  208. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  209. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  210. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  211. package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
  212. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  213. package/dest/services/tx_collection/file_store_tx_source.js +90 -0
  214. package/dest/services/tx_collection/index.d.ts +2 -1
  215. package/dest/services/tx_collection/index.d.ts.map +1 -1
  216. package/dest/services/tx_collection/index.js +1 -0
  217. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  218. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  219. package/dest/services/tx_collection/instrumentation.js +2 -1
  220. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  221. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  222. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  223. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  224. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  225. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  226. package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
  227. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  228. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  229. package/dest/services/tx_collection/tx_collection.d.ts +23 -10
  230. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  231. package/dest/services/tx_collection/tx_collection.js +75 -3
  232. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  233. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  234. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  235. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  236. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  237. package/dest/services/tx_collection/tx_source.js +19 -2
  238. package/dest/services/tx_file_store/config.d.ts +1 -3
  239. package/dest/services/tx_file_store/config.d.ts.map +1 -1
  240. package/dest/services/tx_file_store/config.js +0 -4
  241. package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
  242. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  243. package/dest/services/tx_file_store/tx_file_store.js +9 -6
  244. package/dest/services/tx_provider.d.ts +4 -4
  245. package/dest/services/tx_provider.d.ts.map +1 -1
  246. package/dest/services/tx_provider.js +9 -8
  247. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  248. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  249. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  250. package/dest/test-helpers/mock-pubsub.d.ts +30 -4
  251. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  252. package/dest/test-helpers/mock-pubsub.js +105 -4
  253. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  254. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  255. package/dest/test-helpers/reqresp-nodes.js +4 -3
  256. package/dest/test-helpers/testbench-utils.d.ts +35 -24
  257. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  258. package/dest/test-helpers/testbench-utils.js +104 -36
  259. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  260. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  261. package/dest/testbench/p2p_client_testbench_worker.js +16 -15
  262. package/dest/testbench/worker_client_manager.d.ts +3 -1
  263. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  264. package/dest/testbench/worker_client_manager.js +6 -2
  265. package/dest/util.d.ts +3 -3
  266. package/dest/util.d.ts.map +1 -1
  267. package/package.json +14 -14
  268. package/src/client/factory.ts +96 -24
  269. package/src/client/interface.ts +43 -33
  270. package/src/client/p2p_client.ts +172 -265
  271. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +20 -11
  272. package/src/config.ts +141 -44
  273. package/src/errors/tx-pool.error.ts +12 -0
  274. package/src/index.ts +1 -0
  275. package/src/mem_pools/attestation_pool/attestation_pool.ts +100 -48
  276. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +57 -53
  277. package/src/mem_pools/attestation_pool/index.ts +3 -3
  278. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  279. package/src/mem_pools/index.ts +3 -0
  280. package/src/mem_pools/instrumentation.ts +17 -13
  281. package/src/mem_pools/interface.ts +2 -2
  282. package/src/mem_pools/tx_pool/README.md +1 -1
  283. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +2 -1
  284. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  285. package/src/mem_pools/tx_pool/priority.ts +4 -4
  286. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
  287. package/src/mem_pools/tx_pool_v2/README.md +85 -11
  288. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  289. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  290. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +7 -3
  291. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  292. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  293. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  294. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
  295. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
  296. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -9
  297. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  298. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  299. package/src/mem_pools/tx_pool_v2/index.ts +2 -1
  300. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  301. package/src/mem_pools/tx_pool_v2/interfaces.ts +28 -8
  302. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +202 -26
  303. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +58 -45
  304. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +34 -8
  305. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +410 -187
  306. package/src/msg_validators/attestation_validator/README.md +49 -0
  307. package/src/msg_validators/proposal_validator/README.md +123 -0
  308. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
  309. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
  310. package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
  311. package/src/msg_validators/tx_validator/README.md +119 -0
  312. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
  313. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  314. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  315. package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
  316. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  317. package/src/msg_validators/tx_validator/factory.ts +387 -78
  318. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  319. package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
  320. package/src/msg_validators/tx_validator/index.ts +2 -0
  321. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  322. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  323. package/src/msg_validators/tx_validator/phases_validator.ts +81 -26
  324. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  325. package/src/services/dummy_service.ts +12 -6
  326. package/src/services/encoding.ts +9 -9
  327. package/src/services/gossipsub/README.md +641 -0
  328. package/src/services/gossipsub/index.ts +2 -0
  329. package/src/services/gossipsub/scoring.ts +29 -5
  330. package/src/services/gossipsub/topic_score_params.ts +487 -0
  331. package/src/services/libp2p/libp2p_service.ts +206 -164
  332. package/src/services/peer-manager/metrics.ts +7 -0
  333. package/src/services/peer-manager/peer_manager.ts +2 -1
  334. package/src/services/peer-manager/peer_scoring.ts +25 -0
  335. package/src/services/reqresp/README.md +229 -0
  336. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +49 -57
  337. package/src/services/reqresp/batch-tx-requester/interface.ts +3 -5
  338. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  339. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  340. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  341. package/src/services/reqresp/interface.ts +26 -1
  342. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +2 -2
  343. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
  344. package/src/services/reqresp/protocols/tx.ts +22 -0
  345. package/src/services/reqresp/reqresp.ts +17 -5
  346. package/src/services/service.ts +31 -2
  347. package/src/services/tx_collection/config.ts +68 -0
  348. package/src/services/tx_collection/fast_tx_collection.ts +65 -32
  349. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  350. package/src/services/tx_collection/file_store_tx_source.ts +117 -0
  351. package/src/services/tx_collection/index.ts +1 -0
  352. package/src/services/tx_collection/instrumentation.ts +7 -1
  353. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  354. package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
  355. package/src/services/tx_collection/slow_tx_collection.ts +66 -33
  356. package/src/services/tx_collection/tx_collection.ts +113 -16
  357. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  358. package/src/services/tx_collection/tx_source.ts +22 -3
  359. package/src/services/tx_file_store/config.ts +0 -6
  360. package/src/services/tx_file_store/tx_file_store.ts +10 -8
  361. package/src/services/tx_provider.ts +10 -9
  362. package/src/test-helpers/make-test-p2p-clients.ts +4 -6
  363. package/src/test-helpers/mock-pubsub.ts +146 -9
  364. package/src/test-helpers/reqresp-nodes.ts +5 -7
  365. package/src/test-helpers/testbench-utils.ts +118 -40
  366. package/src/testbench/p2p_client_testbench_worker.ts +25 -21
  367. package/src/testbench/worker_client_manager.ts +13 -5
  368. package/src/util.ts +8 -2
  369. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  370. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  371. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  372. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
@@ -370,21 +370,21 @@ function applyDecs2203RFactory() {
370
370
  function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
371
371
  return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
372
372
  }
373
- var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _initProto;
373
+ var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto;
374
374
  import { BlockNumber } from '@aztec/foundation/branded-types';
375
- import { randomInt } from '@aztec/foundation/crypto/random';
375
+ import { maxBy } from '@aztec/foundation/collection';
376
376
  import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
377
377
  import { RunningPromise } from '@aztec/foundation/running-promise';
378
378
  import { Timer } from '@aztec/foundation/timer';
379
379
  import { protocolContractsHash } from '@aztec/protocol-contracts';
380
380
  import { GasFees } from '@aztec/stdlib/gas';
381
- import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
381
+ import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PMessage, PeerErrorSeverity, PeerErrorSeverityByHarshness, TopicType, createTopicString, getTopicsForConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
382
382
  import { MerkleTreeId } from '@aztec/stdlib/trees';
383
383
  import { Tx } from '@aztec/stdlib/tx';
384
384
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
385
385
  import { Attributes, OtelMetricsAdapter, SpanStatusCode, WithTracer, trackSpan } from '@aztec/telemetry-client';
386
386
  import { gossipsub } from '@chainsafe/libp2p-gossipsub';
387
- import { createPeerScoreParams, createTopicScoreParams } from '@chainsafe/libp2p-gossipsub/score';
387
+ import { createPeerScoreParams } from '@chainsafe/libp2p-gossipsub/score';
388
388
  import { SignaturePolicy } from '@chainsafe/libp2p-gossipsub/types';
389
389
  import { noise } from '@chainsafe/libp2p-noise';
390
390
  import { yamux } from '@chainsafe/libp2p-yamux';
@@ -397,18 +397,18 @@ import { ENR } from '@nethermindeth/enr';
397
397
  import { createLibp2p } from 'libp2p';
398
398
  import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, DoubleSpendTxValidator, FishermanAttestationValidator, getDefaultAllowedSetupFunctions } from '../../msg_validators/index.js';
399
399
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
400
- import { createTxMessageValidators, createTxReqRespValidator } from '../../msg_validators/tx_validator/factory.js';
400
+ import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, createTxValidatorForReqResponseReceivedTxs } from '../../msg_validators/tx_validator/factory.js';
401
401
  import { GossipSubEvent } from '../../types/index.js';
402
402
  import { convertToMultiaddr } from '../../util.js';
403
403
  import { getVersions } from '../../versioning.js';
404
404
  import { AztecDatastore } from '../data_store.js';
405
405
  import { DiscV5Service } from '../discv5/discV5_service.js';
406
406
  import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
407
- import { gossipScoreThresholds } from '../gossipsub/scoring.js';
407
+ import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring.js';
408
+ import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
408
409
  import { PeerManager } from '../peer-manager/peer_manager.js';
409
410
  import { PeerScoring } from '../peer-manager/peer_scoring.js';
410
- import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/index.js';
411
- import { pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
411
+ import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
412
412
  import { ReqResp } from '../reqresp/reqresp.js';
413
413
  import { P2PInstrumentation } from './instrumentation.js';
414
414
  _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
@@ -432,9 +432,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
432
432
  [Attributes.TX_HASH]: requestedTxHash.toString()
433
433
  })), _dec7 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
434
434
  [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
435
- })), _dec8 = trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
436
- [Attributes.TX_HASH]: tx.getTxHash().toString()
437
- })), _dec9 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
435
+ })), _dec8 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
438
436
  [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
439
437
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
440
438
  [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
@@ -442,7 +440,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
442
440
  /**
443
441
  * Lib P2P implementation of the P2PService interface.
444
442
  */ export class LibP2PService extends WithTracer {
445
- clientType;
446
443
  config;
447
444
  node;
448
445
  peerDiscoveryService;
@@ -498,11 +495,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
498
495
  [
499
496
  _dec8,
500
497
  2,
501
- "validatePropagatedTx"
502
- ],
503
- [
504
- _dec9,
505
- 2,
506
498
  "validateCheckpointAttestation"
507
499
  ]
508
500
  ], []));
@@ -517,6 +509,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
517
509
  topicStrings;
518
510
  feesCache;
519
511
  /** Callback invoked when a duplicate proposal is detected (triggers slashing). */ duplicateProposalCallback;
512
+ /** Callback invoked when a duplicate attestation is detected (triggers slashing). */ duplicateAttestationCallback;
520
513
  /**
521
514
  * Callback for when a block is received from a peer.
522
515
  * @param block - The block received from the peer.
@@ -531,8 +524,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
531
524
  instrumentation;
532
525
  telemetry;
533
526
  logger;
534
- constructor(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
535
- super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.msgIdSeenValidators = (_initProto(this), {}), this.protocolVersion = '', this.topicStrings = {};
527
+ constructor(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
528
+ super(telemetry, 'LibP2PService'), this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.msgIdSeenValidators = (_initProto(this), {}), this.protocolVersion = '', this.topicStrings = {};
536
529
  this.telemetry = telemetry;
537
530
  // Create child logger with fisherman prefix if in fisherman mode
538
531
  this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
@@ -548,19 +541,19 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
548
541
  this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
549
542
  this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
550
543
  this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
551
- this.blockProposalValidator = new BlockProposalValidator(epochCache, {
552
- txsPermitted: !config.disableTransactions
553
- });
554
- this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
555
- txsPermitted: !config.disableTransactions
556
- });
544
+ const proposalValidatorOpts = {
545
+ txsPermitted: !config.disableTransactions,
546
+ maxTxsPerBlock: config.validateMaxTxsPerBlock
547
+ };
548
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
549
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
557
550
  this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new CheckpointAttestationValidator(epochCache);
558
551
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
559
552
  this.blockReceivedCallback = async (block)=>{
560
- this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`, {
553
+ this.logger.warn(`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`, {
561
554
  p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier()
562
555
  });
563
- return false;
556
+ return true;
564
557
  };
565
558
  this.checkpointReceivedCallback = (checkpoint)=>{
566
559
  this.logger.debug(`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`);
@@ -575,7 +568,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
575
568
  * @param config - The configuration to use when creating the service.
576
569
  * @param txPool - The transaction pool to be accessed by the service.
577
570
  * @returns The new service.
578
- */ static async new(clientType, config, peerId, deps) {
571
+ */ static async new(config, peerId, deps) {
579
572
  const { worldStateSynchronizer, epochCache, l2BlockSource, mempools, proofVerifier, peerStore, telemetry, logger, packageVersion } = deps;
580
573
  const { p2pPort, maxPeerCount, listenAddress } = config;
581
574
  const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
@@ -595,10 +588,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
595
588
  }
596
589
  const versions = getVersions(config);
597
590
  const protocolVersion = compressComponentVersions(versions);
598
- const txTopic = createTopicString(TopicType.tx, protocolVersion);
599
- const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
600
- const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
601
- const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
602
591
  const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
603
592
  const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
604
593
  const peerId = await enr.peerId();
@@ -616,6 +605,15 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
616
605
  const announceTcpMultiaddr = config.p2pIp ? [
617
606
  convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')
618
607
  ] : [];
608
+ // Create dynamic topic score params based on network configuration
609
+ const l1Constants = epochCache.getL1Constants();
610
+ const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
611
+ slotDurationMs: l1Constants.slotDuration * 1000,
612
+ heartbeatIntervalMs: config.gossipsubInterval,
613
+ targetCommitteeSize: l1Constants.targetCommitteeSize,
614
+ blockDurationMs: config.blockDurationMs,
615
+ expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot
616
+ });
619
617
  const node = await createLibp2p({
620
618
  start: false,
621
619
  peerId,
@@ -716,28 +714,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
716
714
  scoreParams: createPeerScoreParams({
717
715
  // IPColocation factor can be disabled for local testing - default to -5
718
716
  IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
719
- topics: {
720
- [txTopic]: createTopicScoreParams({
721
- topicWeight: 1,
722
- invalidMessageDeliveriesWeight: -20,
723
- invalidMessageDeliveriesDecay: 0.5
724
- }),
725
- [blockProposalTopic]: createTopicScoreParams({
726
- topicWeight: 1,
727
- invalidMessageDeliveriesWeight: -20,
728
- invalidMessageDeliveriesDecay: 0.5
729
- }),
730
- [checkpointProposalTopic]: createTopicScoreParams({
731
- topicWeight: 1,
732
- invalidMessageDeliveriesWeight: -20,
733
- invalidMessageDeliveriesDecay: 0.5
734
- }),
735
- [checkpointAttestationTopic]: createTopicScoreParams({
736
- topicWeight: 1,
737
- invalidMessageDeliveriesWeight: -20,
738
- invalidMessageDeliveriesDecay: 0.5
739
- })
740
- }
717
+ topics: topicScoreParams
741
718
  })
742
719
  }),
743
720
  components: (components)=>({
@@ -749,10 +726,14 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
749
726
  const peerScoring = new PeerScoring(config, telemetry);
750
727
  const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
751
728
  const peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, reqresp, worldStateSynchronizer, protocolVersion, epochCache);
752
- // Update gossipsub score params
753
- node.services.pubsub.score.params.appSpecificWeight = 10;
729
+ // Configure application-specific scoring for gossipsub.
730
+ // The weight scales app score to align with gossipsub thresholds:
731
+ // - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
732
+ // - Ban (-100) × 10 = -1000 = publishThreshold (cannot publish)
733
+ // Note: positive topic scores can offset penalties, so alignment is best-effort.
734
+ node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
754
735
  node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
755
- return new LibP2PService(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
736
+ return new LibP2PService(config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
756
737
  }
757
738
  /**
758
739
  * Starts the LibP2P service.
@@ -797,7 +778,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
797
778
  await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
798
779
  await this.node.start();
799
780
  // Subscribe to standard GossipSub topics by default
800
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
781
+ for (const topic of getTopicsForConfig(this.config.disableTransactions)){
801
782
  this.subscribeToTopic(this.topicStrings[topic]);
802
783
  }
803
784
  // add GossipSub listener
@@ -845,6 +826,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
845
826
  getPeers(includePending) {
846
827
  return this.peerManager.getPeers(includePending);
847
828
  }
829
+ getGossipMeshPeerCount(topicType) {
830
+ return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
831
+ }
848
832
  handleGossipSubEvent(e) {
849
833
  this.logger.trace(`Received PUBSUB message.`);
850
834
  const safeJob = async ()=>{
@@ -886,6 +870,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
886
870
  this.duplicateProposalCallback = callback;
887
871
  }
888
872
  /**
873
+ * Registers a callback to be invoked when a duplicate attestation is detected.
874
+ * A validator signing attestations for different proposals at the same slot.
875
+ * This callback is triggered on the first duplicate (when count goes from 1 to 2).
876
+ */ registerDuplicateAttestationCallback(callback) {
877
+ this.duplicateAttestationCallback = callback;
878
+ }
879
+ /**
889
880
  * Subscribes to a topic.
890
881
  * @param topic - The topic to subscribe to.
891
882
  */ subscribeToTopic(topic) {
@@ -936,6 +927,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
936
927
  if (!validator || !validator.addMessage(msgId)) {
937
928
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
938
929
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
930
+ if (topicType === TopicType.tx) {
931
+ this.logger.verbose(`Ignoring already-seen tx gossip message`, {
932
+ msgId,
933
+ source: source.toString()
934
+ });
935
+ }
939
936
  return {
940
937
  result: false,
941
938
  topicType
@@ -996,9 +993,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
996
993
  if (msg.topic === this.topicStrings[TopicType.tx]) {
997
994
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
998
995
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
999
- if (this.clientType === P2PClientType.Full) {
1000
- await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
1001
- }
996
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
1002
997
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
1003
998
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
1004
999
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
@@ -1066,47 +1061,99 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1066
1061
  async handleGossipedTx(payloadData, msgId, source) {
1067
1062
  const validationFunc = async ()=>{
1068
1063
  const tx = Tx.fromBuffer(payloadData);
1069
- const isValid = await this.validatePropagatedTx(tx, source);
1070
- const exists = isValid && await this.mempools.txPool.hasTx(tx.getTxHash());
1071
- this.logger.trace(`Validate propagated tx`, {
1072
- isValid,
1073
- exists,
1074
- [Attributes.P2P_ID]: source.toString()
1075
- });
1076
- if (!isValid) {
1064
+ const currentBlockNumber = await this.archiver.getBlockNumber();
1065
+ const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1066
+ // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
1067
+ const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
1068
+ const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
1069
+ if (!firstStageOutcome.allPassed) {
1070
+ const { name } = firstStageOutcome.failure;
1071
+ let { severity } = firstStageOutcome.failure;
1072
+ // Double spend validator has a special case handler. We perform more detailed examination
1073
+ // as to how recently the nullifier was entered into the tree and if the transaction should
1074
+ // have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
1075
+ if (name === 'doubleSpendValidator') {
1076
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1);
1077
+ severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1078
+ }
1079
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
1080
+ validator: name,
1081
+ severity,
1082
+ source: source.toString()
1083
+ });
1084
+ this.peerManager.penalizePeer(source, severity);
1077
1085
  return {
1078
1086
  result: TopicValidatorResult.Reject
1079
1087
  };
1080
- } else if (exists) {
1088
+ }
1089
+ // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
1090
+ const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
1091
+ if (canAdd === 'ignored') {
1092
+ this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
1093
+ source: source.toString()
1094
+ });
1081
1095
  return {
1082
1096
  result: TopicValidatorResult.Ignore,
1083
1097
  obj: tx
1084
1098
  };
1085
- } else {
1099
+ }
1100
+ // Stage 2: expensive proof verification
1101
+ const secondStageValidators = this.createSecondStageMessageValidators();
1102
+ const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
1103
+ if (!secondStageOutcome.allPassed) {
1104
+ const { severity, name } = secondStageOutcome.failure;
1105
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
1106
+ validator: name,
1107
+ severity,
1108
+ source: source.toString()
1109
+ });
1110
+ this.peerManager.penalizePeer(source, severity);
1111
+ return {
1112
+ result: TopicValidatorResult.Reject
1113
+ };
1114
+ }
1115
+ // Pool add: persist the tx
1116
+ const txHash = tx.getTxHash();
1117
+ const addResult = await this.mempools.txPool.addPendingTxs([
1118
+ tx
1119
+ ], {
1120
+ source: 'gossip'
1121
+ });
1122
+ const wasAccepted = addResult.accepted.some((h)=>h.equals(txHash));
1123
+ const wasIgnored = addResult.ignored.some((h)=>h.equals(txHash));
1124
+ this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
1125
+ wasAccepted,
1126
+ wasIgnored,
1127
+ [Attributes.P2P_ID]: source.toString()
1128
+ });
1129
+ if (wasAccepted) {
1086
1130
  return {
1087
1131
  result: TopicValidatorResult.Accept,
1088
1132
  obj: tx
1089
1133
  };
1134
+ } else if (wasIgnored) {
1135
+ return {
1136
+ result: TopicValidatorResult.Ignore,
1137
+ obj: tx
1138
+ };
1139
+ } else {
1140
+ return {
1141
+ result: TopicValidatorResult.Reject
1142
+ };
1090
1143
  }
1091
1144
  };
1092
1145
  const { result, obj: tx } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.tx);
1093
1146
  if (result !== TopicValidatorResult.Accept || !tx) {
1094
1147
  return;
1095
1148
  }
1149
+ // Tx was accepted into pool and will be propagated - just log and record metrics
1096
1150
  const txHash = tx.getTxHash();
1097
1151
  const txHashString = txHash.toString();
1098
1152
  this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
1099
1153
  source: source.toString(),
1100
1154
  txHash: txHashString
1101
1155
  });
1102
- if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
1103
- this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
1104
- return;
1105
- }
1106
1156
  this.instrumentation.incrementTxReceived(1);
1107
- await this.mempools.txPool.addTxs([
1108
- tx
1109
- ]);
1110
1157
  }
1111
1158
  /**
1112
1159
  * Process a checkpoint attestation from a peer.
@@ -1138,38 +1185,56 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1138
1185
  obj: attestation
1139
1186
  };
1140
1187
  }
1141
- // Get committee size for the attestation's slot
1142
- const slot = attestation.payload.header.slotNumber;
1143
- const { committee } = await this.epochCache.getCommittee(slot);
1144
- const committeeSize = committee?.length ?? 0;
1145
1188
  // Try to add the attestation: this handles existence check, cap check, and adding in one call
1146
- const { added, alreadyExists } = await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation, committeeSize);
1189
+ // count is the number of attestations by this signer for this slot (for duplicate detection)
1190
+ const slot = attestation.payload.header.slotNumber;
1191
+ const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation);
1147
1192
  this.logger.trace(`Validate propagated checkpoint attestation`, {
1148
1193
  added,
1149
1194
  alreadyExists,
1195
+ count,
1150
1196
  [Attributes.SLOT_NUMBER]: slot.toString(),
1151
1197
  [Attributes.P2P_ID]: peerId.toString()
1152
1198
  });
1153
- // Duplicate attestation received, no need to re-broadcast
1199
+ // Exact same attestation received, no need to re-broadcast
1154
1200
  if (alreadyExists) {
1155
1201
  return {
1156
1202
  result: TopicValidatorResult.Ignore,
1157
1203
  obj: attestation
1158
1204
  };
1159
1205
  }
1160
- // Could not add (cap reached), no need to re-broadcast
1206
+ // Could not add (cap reached for signer), no need to re-broadcast
1161
1207
  if (!added) {
1162
- this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
1208
+ this.logger.warn(`Dropping checkpoint attestation due to cap`, {
1163
1209
  slot: slot.toString(),
1164
1210
  archive: attestation.archive.toString(),
1165
- source: peerId.toString()
1211
+ source: peerId.toString(),
1212
+ attester: attestation.getSender()?.toString(),
1213
+ count
1166
1214
  });
1167
1215
  return {
1168
1216
  result: TopicValidatorResult.Ignore,
1169
1217
  obj: attestation
1170
1218
  };
1171
1219
  }
1172
- // Attestation was added successfully
1220
+ // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
1221
+ // count is the number of attestations by this signer for this slot
1222
+ if (count === 2) {
1223
+ const attester = attestation.getSender();
1224
+ if (attester) {
1225
+ this.logger.warn(`Detected duplicate attestation (equivocation) at slot ${slot}`, {
1226
+ slot: slot.toString(),
1227
+ archive: attestation.archive.toString(),
1228
+ source: peerId.toString(),
1229
+ attester: attester.toString()
1230
+ });
1231
+ this.duplicateAttestationCallback?.({
1232
+ slot,
1233
+ attester
1234
+ });
1235
+ }
1236
+ }
1237
+ // Attestation was added successfully - accept it so other nodes can also detect the equivocation
1173
1238
  return {
1174
1239
  result: TopicValidatorResult.Accept,
1175
1240
  obj: attestation
@@ -1199,8 +1264,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1199
1264
  };
1200
1265
  }
1201
1266
  // Try to add the proposal: this handles existence check, cap check, and adding in one call
1202
- const { added, alreadyExists, totalForPosition } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1203
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1267
+ const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1268
+ const isEquivocated = count !== undefined && count > 1;
1204
1269
  // Duplicate proposal received, no need to re-broadcast
1205
1270
  if (alreadyExists) {
1206
1271
  this.logger.debug(`Ignoring duplicate block proposal received`, {
@@ -1223,7 +1288,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1223
1288
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1224
1289
  ...block.toBlockInfo(),
1225
1290
  indexWithinCheckpoint: block.indexWithinCheckpoint,
1226
- totalForPosition,
1291
+ count,
1227
1292
  proposer: block.getSender()?.toString(),
1228
1293
  source: peerId.toString()
1229
1294
  });
@@ -1244,7 +1309,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1244
1309
  proposer: proposer?.toString()
1245
1310
  });
1246
1311
  // Invoke the duplicate callback on the first duplicate spotted only
1247
- if (proposer && totalForPosition === 2) {
1312
+ if (proposer && count === 2) {
1248
1313
  this.duplicateProposalCallback?.({
1249
1314
  slot: block.slotNumber,
1250
1315
  proposer,
@@ -1274,13 +1339,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1274
1339
  source: sender.toString(),
1275
1340
  ...block.toBlockInfo()
1276
1341
  });
1277
- // Mark the txs in this proposal as non-evictable
1278
- await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
1342
+ // Mark the txs in this proposal as protected
1343
+ await this.mempools.txPool.protectTxs(block.txHashes, block.blockHeader);
1279
1344
  // Call the block received callback to validate the proposal.
1280
1345
  // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1281
1346
  const isValid = await this.blockReceivedCallback(block, sender);
1282
1347
  if (!isValid) {
1283
- this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1348
+ this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1284
1349
  }
1285
1350
  }
1286
1351
  /**
@@ -1342,8 +1407,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1342
1407
  // Try to add the checkpoint proposal core: this handles existence check, cap check, and adding in one call
1343
1408
  const checkpointCore = checkpoint.toCore();
1344
1409
  const tryAddResult = await this.mempools.attestationPool.tryAddCheckpointProposal(checkpointCore);
1345
- const { added, alreadyExists, totalForPosition } = tryAddResult;
1346
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1410
+ const { added, alreadyExists, count } = tryAddResult;
1411
+ const isEquivocated = count !== undefined && count > 1;
1347
1412
  // Duplicate proposal received, do not re-broadcast
1348
1413
  if (alreadyExists) {
1349
1414
  this.logger.debug(`Ignoring duplicate checkpoint proposal received`, {
@@ -1365,7 +1430,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1365
1430
  this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1366
1431
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1367
1432
  ...checkpoint.toCheckpointInfo(),
1368
- totalForPosition,
1433
+ count,
1369
1434
  source: peerId.toString()
1370
1435
  });
1371
1436
  return {
@@ -1387,7 +1452,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1387
1452
  proposer: proposer?.toString()
1388
1453
  });
1389
1454
  // Invoke the duplicate callback on the first duplicate spotted only
1390
- if (proposer && totalForPosition === 2) {
1455
+ if (proposer && count === 2) {
1391
1456
  this.duplicateProposalCallback?.({
1392
1457
  slot: checkpoint.slotNumber,
1393
1458
  proposer,
@@ -1598,33 +1663,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1598
1663
  }
1599
1664
  }
1600
1665
  createRequestedTxValidator() {
1601
- return createTxReqRespValidator(this.proofVerifier, {
1666
+ return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
1602
1667
  l1ChainId: this.config.l1ChainId,
1603
1668
  rollupVersion: this.config.rollupVersion
1604
1669
  });
1605
1670
  }
1606
- async validatePropagatedTx(tx, peerId) {
1607
- const currentBlockNumber = await this.archiver.getBlockNumber();
1608
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1609
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1610
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1611
- for (const validator of messageValidators){
1612
- const outcome = await this.runValidations(tx, validator);
1613
- if (outcome.allPassed) {
1614
- continue;
1615
- }
1616
- const { name } = outcome.failure;
1617
- let { severity } = outcome.failure;
1618
- // Double spend validator has a special case handler
1619
- if (name === 'doubleSpendValidator') {
1620
- const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1621
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1622
- }
1623
- this.peerManager.penalizePeer(peerId, severity);
1624
- return false;
1625
- }
1626
- return true;
1627
- }
1628
1671
  async getGasFees(blockNumber) {
1629
1672
  if (blockNumber === this.feesCache?.blockNumber) {
1630
1673
  return this.feesCache.gasFees;
@@ -1651,38 +1694,35 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1651
1694
  peerScoring: this.peerManager
1652
1695
  };
1653
1696
  }
1654
- async validate(txs) {
1655
- const currentBlockNumber = await this.archiver.getBlockNumber();
1656
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1657
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1658
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1659
- await Promise.all(txs.map(async (tx)=>{
1660
- for (const validator of messageValidators){
1661
- const outcome = await this.runValidations(tx, validator);
1662
- if (!outcome.allPassed) {
1663
- throw new Error('Invalid tx detected', {
1664
- cause: {
1665
- outcome
1666
- }
1667
- });
1668
- }
1669
- }
1697
+ async validateTxsReceivedInBlockProposal(txs) {
1698
+ const validator = createTxValidatorForBlockProposalReceivedTxs(this.proofVerifier, {
1699
+ l1ChainId: this.config.l1ChainId,
1700
+ rollupVersion: this.config.rollupVersion
1701
+ }, this.logger.getBindings());
1702
+ const results = await Promise.all(txs.map(async (tx)=>{
1703
+ const result = await validator.validateTx(tx);
1704
+ return result.result !== 'invalid';
1670
1705
  }));
1706
+ if (results.some((value)=>value === false)) {
1707
+ throw new Error('Invalid tx detected');
1708
+ }
1671
1709
  }
1672
- /**
1673
- * Create message validators for the given block number and timestamp.
1674
- *
1675
- * Each validator is a pair of a validator and a severity.
1676
- * If a validator fails, the peer is penalized with the severity of the validator.
1677
- *
1678
- * @param currentBlockNumber - The current synced block number.
1679
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
1680
- * @returns The message validators.
1681
- */ async createMessageValidators(currentBlockNumber, nextSlotTimestamp) {
1710
+ /** Creates the first stage (fast) validators for gossiped transactions. */ async createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp) {
1682
1711
  const gasFees = await this.getGasFees(currentBlockNumber);
1683
- const allowedInSetup = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
1684
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1685
- return createTxMessageValidators(nextSlotTimestamp, blockNumberInWhichTheTxIsConsideredToBeIncluded, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, this.proofVerifier, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings());
1712
+ const allowedInSetup = [
1713
+ ...await getDefaultAllowedSetupFunctions(),
1714
+ ...this.config.txPublicSetupAllowListExtend ?? []
1715
+ ];
1716
+ const blockNumber = BlockNumber(currentBlockNumber + 1);
1717
+ const l1Constants = await this.archiver.getL1Constants();
1718
+ return createFirstStageTxValidationsForGossipedTransactions(nextSlotTimestamp, blockNumber, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings(), {
1719
+ rollupManaLimit: l1Constants.rollupManaLimit,
1720
+ maxBlockL2Gas: this.config.validateMaxL2BlockGas,
1721
+ maxBlockDAGas: this.config.validateMaxDABlockGas
1722
+ });
1723
+ }
1724
+ /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */ createSecondStageMessageValidators() {
1725
+ return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
1686
1726
  }
1687
1727
  /**
1688
1728
  * Run validations on a tx.
@@ -1700,8 +1740,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1700
1740
  });
1701
1741
  // A promise that resolves when all validations have been run
1702
1742
  const allValidations = await Promise.all(validationPromises);
1703
- const failed = allValidations.find((x)=>!x.isValid);
1704
- if (failed) {
1743
+ const failures = allValidations.filter((x)=>!x.isValid);
1744
+ if (failures.length > 0) {
1745
+ // Pick the most severe failure (lowest tolerance = harshest penalty)
1746
+ const failed = maxBy(failures, (f)=>PeerErrorSeverityByHarshness.indexOf(f.severity));
1705
1747
  return {
1706
1748
  allPassed: false,
1707
1749
  failure: {