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

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 (423) 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 +52 -14
  5. package/dest/client/interface.d.ts +47 -34
  6. package/dest/client/interface.d.ts.map +1 -1
  7. package/dest/client/p2p_client.d.ts +39 -51
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +164 -224
  10. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +20 -10
  11. package/dest/config.d.ts +52 -16
  12. package/dest/config.d.ts.map +1 -1
  13. package/dest/config.js +100 -37
  14. package/dest/errors/p2p-service.error.d.ts +9 -0
  15. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  16. package/dest/errors/p2p-service.error.js +10 -0
  17. package/dest/errors/tx-pool.error.d.ts +8 -0
  18. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  19. package/dest/errors/tx-pool.error.js +9 -0
  20. package/dest/index.d.ts +2 -2
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +1 -1
  23. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +21 -12
  24. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/attestation_pool.js +75 -40
  26. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  27. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +57 -57
  29. package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
  30. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  31. package/dest/mem_pools/attestation_pool/index.js +1 -1
  32. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  33. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  34. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  35. package/dest/mem_pools/index.d.ts +2 -2
  36. package/dest/mem_pools/index.d.ts.map +1 -1
  37. package/dest/mem_pools/instrumentation.d.ts +4 -2
  38. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  39. package/dest/mem_pools/instrumentation.js +16 -14
  40. package/dest/mem_pools/interface.d.ts +3 -3
  41. package/dest/mem_pools/interface.d.ts.map +1 -1
  42. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  43. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  44. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  45. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  46. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  48. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  49. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  50. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +7 -3
  51. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  52. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  53. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
  54. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  55. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  56. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  57. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  58. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  59. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  60. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
  61. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +7 -5
  62. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  63. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +14 -6
  65. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  66. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  68. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  69. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  71. package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
  72. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  73. package/dest/mem_pools/tx_pool_v2/index.js +2 -1
  74. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  75. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  76. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  77. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +30 -12
  78. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  79. package/dest/mem_pools/tx_pool_v2/interfaces.js +5 -1
  80. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +78 -15
  81. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  82. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +144 -19
  83. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
  84. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  85. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +50 -45
  86. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +12 -5
  87. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  88. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +17 -6
  89. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +14 -5
  90. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  91. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +364 -189
  92. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
  93. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  94. package/dest/msg_validators/attestation_validator/attestation_validator.js +5 -4
  95. package/dest/msg_validators/clock_tolerance.d.ts +1 -1
  96. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  97. package/dest/msg_validators/clock_tolerance.js +4 -3
  98. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  99. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  100. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  101. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  102. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  103. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  104. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  105. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  106. package/dest/msg_validators/proposal_validator/proposal_validator.js +53 -41
  107. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  108. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  110. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  111. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  112. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  113. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  114. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  115. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  116. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  117. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  118. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  119. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  120. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  121. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  122. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  123. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  124. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  125. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  126. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  127. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  128. package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
  129. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  130. package/dest/msg_validators/tx_validator/factory.js +247 -60
  131. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  132. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  133. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  134. package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
  135. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  136. package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
  137. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  138. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  139. package/dest/msg_validators/tx_validator/index.js +2 -0
  140. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  141. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  142. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  143. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  144. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  145. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  146. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  147. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  148. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  149. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  150. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  151. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  152. package/dest/services/dummy_service.d.ts +12 -6
  153. package/dest/services/dummy_service.d.ts.map +1 -1
  154. package/dest/services/dummy_service.js +12 -5
  155. package/dest/services/encoding.d.ts +7 -3
  156. package/dest/services/encoding.d.ts.map +1 -1
  157. package/dest/services/encoding.js +18 -11
  158. package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
  159. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  160. package/dest/services/gossipsub/topic_score_params.js +32 -10
  161. package/dest/services/libp2p/libp2p_service.d.ts +37 -23
  162. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  163. package/dest/services/libp2p/libp2p_service.js +274 -173
  164. package/dest/services/peer-manager/metrics.d.ts +3 -1
  165. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  166. package/dest/services/peer-manager/metrics.js +6 -0
  167. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  168. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  169. package/dest/services/peer-manager/peer_manager.js +24 -9
  170. package/dest/services/peer-manager/peer_scoring.d.ts +5 -2
  171. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  172. package/dest/services/peer-manager/peer_scoring.js +28 -10
  173. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +12 -8
  174. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  175. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +83 -106
  176. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -7
  177. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  178. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  179. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  180. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  181. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  182. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  183. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  184. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  185. package/dest/services/reqresp/interface.d.ts +10 -1
  186. package/dest/services/reqresp/interface.d.ts.map +1 -1
  187. package/dest/services/reqresp/interface.js +15 -1
  188. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
  189. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  190. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
  191. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  192. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +15 -0
  193. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  194. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  195. package/dest/services/reqresp/protocols/tx.js +20 -0
  196. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  197. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  198. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  199. package/dest/services/reqresp/reqresp.d.ts +1 -1
  200. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  201. package/dest/services/reqresp/reqresp.js +30 -14
  202. package/dest/services/service.d.ts +26 -4
  203. package/dest/services/service.d.ts.map +1 -1
  204. package/dest/services/tx_collection/config.d.ts +19 -1
  205. package/dest/services/tx_collection/config.d.ts.map +1 -1
  206. package/dest/services/tx_collection/config.js +46 -0
  207. package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -4
  208. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  209. package/dest/services/tx_collection/fast_tx_collection.js +80 -76
  210. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  211. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  212. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  213. package/dest/services/tx_collection/file_store_tx_source.d.ts +38 -0
  214. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  215. package/dest/services/tx_collection/file_store_tx_source.js +100 -0
  216. package/dest/services/tx_collection/index.d.ts +2 -1
  217. package/dest/services/tx_collection/index.d.ts.map +1 -1
  218. package/dest/services/tx_collection/index.js +1 -0
  219. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  220. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  221. package/dest/services/tx_collection/instrumentation.js +2 -1
  222. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -7
  223. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  224. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  225. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  226. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  227. package/dest/services/tx_collection/request_tracker.js +84 -0
  228. package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
  229. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  230. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  231. package/dest/services/tx_collection/tx_collection.d.ts +23 -13
  232. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  233. package/dest/services/tx_collection/tx_collection.js +75 -3
  234. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  235. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  236. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  237. package/dest/services/tx_collection/tx_source.d.ts +13 -7
  238. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  239. package/dest/services/tx_collection/tx_source.js +26 -7
  240. package/dest/services/tx_file_store/config.d.ts +1 -3
  241. package/dest/services/tx_file_store/config.d.ts.map +1 -1
  242. package/dest/services/tx_file_store/config.js +0 -4
  243. package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
  244. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  245. package/dest/services/tx_file_store/tx_file_store.js +9 -6
  246. package/dest/services/tx_provider.d.ts +4 -4
  247. package/dest/services/tx_provider.d.ts.map +1 -1
  248. package/dest/services/tx_provider.js +9 -8
  249. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  250. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  251. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  252. package/dest/test-helpers/mock-pubsub.d.ts +30 -4
  253. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  254. package/dest/test-helpers/mock-pubsub.js +105 -4
  255. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  256. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  257. package/dest/test-helpers/reqresp-nodes.js +2 -2
  258. package/dest/test-helpers/testbench-utils.d.ts +35 -24
  259. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  260. package/dest/test-helpers/testbench-utils.js +115 -38
  261. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  262. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  263. package/dest/testbench/p2p_client_testbench_worker.js +57 -27
  264. package/dest/testbench/worker_client_manager.d.ts +3 -1
  265. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  266. package/dest/testbench/worker_client_manager.js +6 -3
  267. package/dest/util.d.ts +3 -3
  268. package/dest/util.d.ts.map +1 -1
  269. package/package.json +14 -14
  270. package/src/client/factory.ts +102 -25
  271. package/src/client/interface.ts +52 -34
  272. package/src/client/p2p_client.ts +190 -266
  273. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +33 -14
  274. package/src/config.ts +149 -43
  275. package/src/errors/p2p-service.error.ts +11 -0
  276. package/src/errors/tx-pool.error.ts +12 -0
  277. package/src/index.ts +1 -1
  278. package/src/mem_pools/attestation_pool/attestation_pool.ts +104 -50
  279. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +61 -57
  280. package/src/mem_pools/attestation_pool/index.ts +3 -3
  281. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  282. package/src/mem_pools/index.ts +1 -1
  283. package/src/mem_pools/instrumentation.ts +17 -13
  284. package/src/mem_pools/interface.ts +2 -2
  285. package/src/mem_pools/tx_pool_v2/README.md +85 -11
  286. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  287. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  288. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +7 -3
  289. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
  290. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  291. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  292. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
  293. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
  294. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -9
  295. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  296. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  297. package/src/mem_pools/tx_pool_v2/index.ts +2 -1
  298. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  299. package/src/mem_pools/tx_pool_v2/interfaces.ts +32 -12
  300. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +209 -27
  301. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +58 -45
  302. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +34 -8
  303. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +410 -187
  304. package/src/msg_validators/attestation_validator/README.md +49 -0
  305. package/src/msg_validators/attestation_validator/attestation_validator.ts +5 -4
  306. package/src/msg_validators/clock_tolerance.ts +4 -3
  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 +69 -45
  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/contract_instance_validator.ts +56 -0
  317. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  318. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  319. package/src/msg_validators/tx_validator/factory.ts +394 -78
  320. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  321. package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
  322. package/src/msg_validators/tx_validator/index.ts +2 -0
  323. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  324. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  325. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  326. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  327. package/src/services/dummy_service.ts +18 -7
  328. package/src/services/encoding.ts +18 -10
  329. package/src/services/gossipsub/README.md +29 -14
  330. package/src/services/gossipsub/topic_score_params.ts +49 -13
  331. package/src/services/libp2p/libp2p_service.ts +288 -198
  332. package/src/services/peer-manager/metrics.ts +7 -0
  333. package/src/services/peer-manager/peer_manager.ts +28 -9
  334. package/src/services/peer-manager/peer_scoring.ts +21 -5
  335. package/src/services/reqresp/README.md +229 -0
  336. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  337. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +79 -112
  338. package/src/services/reqresp/batch-tx-requester/interface.ts +3 -6
  339. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  340. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  341. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  342. package/src/services/reqresp/interface.ts +26 -1
  343. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +2 -2
  344. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
  345. package/src/services/reqresp/protocols/tx.ts +22 -0
  346. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  347. package/src/services/reqresp/reqresp.ts +35 -15
  348. package/src/services/service.ts +37 -3
  349. package/src/services/tx_collection/config.ts +68 -0
  350. package/src/services/tx_collection/fast_tx_collection.ts +83 -76
  351. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  352. package/src/services/tx_collection/file_store_tx_source.ts +129 -0
  353. package/src/services/tx_collection/index.ts +1 -0
  354. package/src/services/tx_collection/instrumentation.ts +7 -1
  355. package/src/services/tx_collection/proposal_tx_collector.ts +9 -13
  356. package/src/services/tx_collection/request_tracker.ts +127 -0
  357. package/src/services/tx_collection/slow_tx_collection.ts +66 -33
  358. package/src/services/tx_collection/tx_collection.ts +114 -19
  359. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  360. package/src/services/tx_collection/tx_source.ts +28 -8
  361. package/src/services/tx_file_store/config.ts +0 -6
  362. package/src/services/tx_file_store/tx_file_store.ts +10 -8
  363. package/src/services/tx_provider.ts +10 -9
  364. package/src/test-helpers/make-test-p2p-clients.ts +4 -6
  365. package/src/test-helpers/mock-pubsub.ts +146 -9
  366. package/src/test-helpers/reqresp-nodes.ts +3 -6
  367. package/src/test-helpers/testbench-utils.ts +137 -43
  368. package/src/testbench/p2p_client_testbench_worker.ts +63 -30
  369. package/src/testbench/worker_client_manager.ts +13 -6
  370. package/src/util.ts +8 -2
  371. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  372. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  373. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  374. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  375. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  376. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  377. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  378. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  379. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  380. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  381. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  382. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  383. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  384. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  385. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  386. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  387. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  388. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  389. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  390. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  391. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  392. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  393. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  394. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  395. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  396. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  397. package/dest/mem_pools/tx_pool/index.js +0 -2
  398. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  399. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  400. package/dest/mem_pools/tx_pool/priority.js +0 -15
  401. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  402. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  403. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  404. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  405. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  406. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  407. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  408. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  409. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  410. package/src/mem_pools/tx_pool/README.md +0 -270
  411. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  412. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  413. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  414. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  415. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  416. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  417. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  418. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  419. package/src/mem_pools/tx_pool/index.ts +0 -2
  420. package/src/mem_pools/tx_pool/priority.ts +0 -20
  421. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  422. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  423. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
@@ -370,15 +370,15 @@ 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, _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';
@@ -395,9 +395,10 @@ import { mplex } from '@libp2p/mplex';
395
395
  import { tcp } from '@libp2p/tcp';
396
396
  import { ENR } from '@nethermindeth/enr';
397
397
  import { createLibp2p } from 'libp2p';
398
+ import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
398
399
  import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, DoubleSpendTxValidator, FishermanAttestationValidator, getDefaultAllowedSetupFunctions } from '../../msg_validators/index.js';
399
400
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
400
- import { createTxMessageValidators, createTxReqRespValidator } from '../../msg_validators/tx_validator/factory.js';
401
+ import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, createTxValidatorForReqResponseReceivedTxs } from '../../msg_validators/tx_validator/factory.js';
401
402
  import { GossipSubEvent } from '../../types/index.js';
402
403
  import { convertToMultiaddr } from '../../util.js';
403
404
  import { getVersions } from '../../versioning.js';
@@ -408,8 +409,7 @@ import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring
408
409
  import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
409
410
  import { PeerManager } from '../peer-manager/peer_manager.js';
410
411
  import { PeerScoring } from '../peer-manager/peer_scoring.js';
411
- import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/index.js';
412
- import { pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
412
+ import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
413
413
  import { ReqResp } from '../reqresp/reqresp.js';
414
414
  import { P2PInstrumentation } from './instrumentation.js';
415
415
  _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
@@ -433,17 +433,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
433
433
  [Attributes.TX_HASH]: requestedTxHash.toString()
434
434
  })), _dec7 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
435
435
  [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
436
- })), _dec8 = trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
437
- [Attributes.TX_HASH]: tx.getTxHash().toString()
438
- })), _dec9 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
439
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
440
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
441
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
442
436
  }));
443
437
  /**
444
438
  * Lib P2P implementation of the P2PService interface.
445
439
  */ export class LibP2PService extends WithTracer {
446
- clientType;
447
440
  config;
448
441
  node;
449
442
  peerDiscoveryService;
@@ -495,16 +488,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
495
488
  _dec7,
496
489
  2,
497
490
  "validateRequestedBlock"
498
- ],
499
- [
500
- _dec8,
501
- 2,
502
- "validatePropagatedTx"
503
- ],
504
- [
505
- _dec9,
506
- 2,
507
- "validateCheckpointAttestation"
508
491
  ]
509
492
  ], []));
510
493
  }
@@ -518,6 +501,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
518
501
  topicStrings;
519
502
  feesCache;
520
503
  /** Callback invoked when a duplicate proposal is detected (triggers slashing). */ duplicateProposalCallback;
504
+ /** Callback invoked when a duplicate attestation is detected (triggers slashing). */ duplicateAttestationCallback;
521
505
  /**
522
506
  * Callback for when a block is received from a peer.
523
507
  * @param block - The block received from the peer.
@@ -527,13 +511,18 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
527
511
  * Callback for when a checkpoint proposal is received from a peer.
528
512
  * @param checkpoint - The checkpoint proposal received from the peer.
529
513
  * @returns The attestations for the checkpoint, if any.
530
- */ checkpointReceivedCallback;
514
+ */ allNodesCheckpointReceivedCallback;
515
+ /**
516
+ * Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
517
+ * @param checkpoint - The checkpoint proposal received from the peer.
518
+ * @returns The attestations for the checkpoint, if any.
519
+ */ validatorCheckpointReceivedCallback;
531
520
  gossipSubEventHandler;
532
521
  instrumentation;
533
522
  telemetry;
534
523
  logger;
535
- constructor(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
536
- 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 = {};
524
+ constructor(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
525
+ 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 = {};
537
526
  this.telemetry = telemetry;
538
527
  // Create child logger with fisherman prefix if in fisherman mode
539
528
  this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
@@ -549,22 +538,24 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
549
538
  this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
550
539
  this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
551
540
  this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
552
- this.blockProposalValidator = new BlockProposalValidator(epochCache, {
553
- txsPermitted: !config.disableTransactions
554
- });
555
- this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
556
- txsPermitted: !config.disableTransactions
557
- });
541
+ const proposalValidatorOpts = {
542
+ txsPermitted: !config.disableTransactions,
543
+ maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint
544
+ };
545
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
546
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
558
547
  this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new CheckpointAttestationValidator(epochCache);
559
548
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
560
549
  this.blockReceivedCallback = async (block)=>{
561
- this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`, {
550
+ this.logger.warn(`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`, {
562
551
  p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier()
563
552
  });
564
- return false;
553
+ return true;
554
+ };
555
+ this.allNodesCheckpointReceivedCallback = (_checkpoint)=>{
556
+ throw new CheckpointProposalReceivedCallbackNotRegisteredError();
565
557
  };
566
- this.checkpointReceivedCallback = (checkpoint)=>{
567
- this.logger.debug(`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`);
558
+ this.validatorCheckpointReceivedCallback = (_checkpoint)=>{
568
559
  return Promise.resolve(undefined);
569
560
  };
570
561
  }
@@ -576,7 +567,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
576
567
  * @param config - The configuration to use when creating the service.
577
568
  * @param txPool - The transaction pool to be accessed by the service.
578
569
  * @returns The new service.
579
- */ static async new(clientType, config, peerId, deps) {
570
+ */ static async new(config, peerId, deps) {
580
571
  const { worldStateSynchronizer, epochCache, l2BlockSource, mempools, proofVerifier, peerStore, telemetry, logger, packageVersion } = deps;
581
572
  const { p2pPort, maxPeerCount, listenAddress } = config;
582
573
  const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
@@ -619,7 +610,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
619
610
  slotDurationMs: l1Constants.slotDuration * 1000,
620
611
  heartbeatIntervalMs: config.gossipsubInterval,
621
612
  targetCommitteeSize: l1Constants.targetCommitteeSize,
622
- blockDurationMs: config.blockDurationMs
613
+ blockDurationMs: config.blockDurationMs,
614
+ expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot
623
615
  });
624
616
  const node = await createLibp2p({
625
617
  start: false,
@@ -740,7 +732,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
740
732
  // Note: positive topic scores can offset penalties, so alignment is best-effort.
741
733
  node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
742
734
  node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
743
- return new LibP2PService(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
735
+ return new LibP2PService(config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
744
736
  }
745
737
  /**
746
738
  * Starts the LibP2P service.
@@ -785,7 +777,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
785
777
  await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
786
778
  await this.node.start();
787
779
  // Subscribe to standard GossipSub topics by default
788
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
780
+ for (const topic of getTopicsForConfig(this.config.disableTransactions)){
789
781
  this.subscribeToTopic(this.topicStrings[topic]);
790
782
  }
791
783
  // add GossipSub listener
@@ -833,6 +825,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
833
825
  getPeers(includePending) {
834
826
  return this.peerManager.getPeers(includePending);
835
827
  }
828
+ getGossipMeshPeerCount(topicType) {
829
+ return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
830
+ }
836
831
  handleGossipSubEvent(e) {
837
832
  this.logger.trace(`Received PUBSUB message.`);
838
833
  const safeJob = async ()=>{
@@ -864,8 +859,14 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
864
859
  registerBlockReceivedCallback(callback) {
865
860
  this.blockReceivedCallback = callback;
866
861
  }
867
- registerCheckpointReceivedCallback(callback) {
868
- this.checkpointReceivedCallback = callback;
862
+ registerValidatorCheckpointReceivedCallback(callback) {
863
+ this.validatorCheckpointReceivedCallback = callback;
864
+ }
865
+ registerAllNodesCheckpointReceivedCallback(callback) {
866
+ this.allNodesCheckpointReceivedCallback = callback;
867
+ }
868
+ async notifyOwnCheckpointProposal(checkpoint) {
869
+ await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
869
870
  }
870
871
  /**
871
872
  * Registers a callback to be invoked when a duplicate proposal is detected.
@@ -874,6 +875,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
874
875
  this.duplicateProposalCallback = callback;
875
876
  }
876
877
  /**
878
+ * Registers a callback to be invoked when a duplicate attestation is detected.
879
+ * A validator signing attestations for different proposals at the same slot.
880
+ * This callback is triggered on the first duplicate (when count goes from 1 to 2).
881
+ */ registerDuplicateAttestationCallback(callback) {
882
+ this.duplicateAttestationCallback = callback;
883
+ }
884
+ /**
877
885
  * Subscribes to a topic.
878
886
  * @param topic - The topic to subscribe to.
879
887
  */ subscribeToTopic(topic) {
@@ -924,6 +932,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
924
932
  if (!validator || !validator.addMessage(msgId)) {
925
933
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
926
934
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
935
+ if (topicType === TopicType.tx) {
936
+ this.logger.verbose(`Ignoring already-seen tx gossip message`, {
937
+ msgId,
938
+ source: source.toString()
939
+ });
940
+ }
927
941
  return {
928
942
  result: false,
929
943
  topicType
@@ -984,9 +998,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
984
998
  if (msg.topic === this.topicStrings[TopicType.tx]) {
985
999
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
986
1000
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
987
- if (this.clientType === P2PClientType.Full) {
988
- await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
989
- }
1001
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
990
1002
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
991
1003
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
992
1004
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
@@ -1031,49 +1043,150 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1031
1043
  return;
1032
1044
  }
1033
1045
  async validateReceivedMessage(validationFunc, msgId, source, topicType) {
1046
+ // Default to reject result with a penalty if validation function throws an error
1034
1047
  let resultAndObj = {
1035
- result: TopicValidatorResult.Reject
1048
+ result: TopicValidatorResult.Reject,
1049
+ severity: PeerErrorSeverity.MidToleranceError
1036
1050
  };
1037
1051
  const timer = new Timer();
1038
1052
  try {
1039
1053
  resultAndObj = await validationFunc();
1040
1054
  } catch (err) {
1041
- this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
1042
- this.logger.error(`Error deserializing and validating gossipsub message`, err, {
1055
+ this.logger.error(`Error validating gossipsub message`, err, {
1043
1056
  msgId,
1044
1057
  source: source.toString(),
1045
1058
  topicType
1046
1059
  });
1047
1060
  }
1048
1061
  if (resultAndObj.result === TopicValidatorResult.Accept) {
1062
+ this.logger.debug(`Message ${topicType} accepted by validator`, {
1063
+ msgId,
1064
+ source: source.toString(),
1065
+ topicType
1066
+ });
1049
1067
  this.instrumentation.recordMessageValidation(topicType, timer);
1068
+ } else if (resultAndObj.result === TopicValidatorResult.Reject) {
1069
+ this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
1070
+ msgId,
1071
+ source: source.toString(),
1072
+ topicType,
1073
+ severity: resultAndObj.severity
1074
+ });
1075
+ this.peerManager.penalizePeer(source, resultAndObj.severity);
1076
+ } else {
1077
+ this.logger.trace(`Message ${topicType} ignored by validator`, {
1078
+ msgId,
1079
+ source: source.toString(),
1080
+ topicType
1081
+ });
1050
1082
  }
1051
1083
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
1052
1084
  return resultAndObj;
1053
1085
  }
1086
+ tryDeserialize(deserializeFunc, msgId, source) {
1087
+ try {
1088
+ return deserializeFunc();
1089
+ } catch (err) {
1090
+ this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
1091
+ err,
1092
+ msgId,
1093
+ source: source.toString()
1094
+ });
1095
+ return undefined;
1096
+ }
1097
+ }
1054
1098
  async handleGossipedTx(payloadData, msgId, source) {
1055
1099
  const validationFunc = async ()=>{
1056
- const tx = Tx.fromBuffer(payloadData);
1057
- const isValid = await this.validatePropagatedTx(tx, source);
1058
- const exists = isValid && await this.mempools.txPool.hasTx(tx.getTxHash());
1059
- this.logger.trace(`Validate propagated tx`, {
1060
- isValid,
1061
- exists,
1100
+ const tx = this.tryDeserialize(()=>Tx.fromBuffer(payloadData), msgId, source);
1101
+ if (!tx) {
1102
+ return {
1103
+ result: TopicValidatorResult.Reject,
1104
+ severity: PeerErrorSeverity.LowToleranceError
1105
+ };
1106
+ }
1107
+ const currentBlockNumber = await this.archiver.getBlockNumber();
1108
+ const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1109
+ // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
1110
+ const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
1111
+ const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
1112
+ if (!firstStageOutcome.allPassed) {
1113
+ const { name } = firstStageOutcome.failure;
1114
+ let { severity } = firstStageOutcome.failure;
1115
+ // Double spend validator has a special case handler. We perform more detailed examination
1116
+ // as to how recently the nullifier was entered into the tree and if the transaction should
1117
+ // have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
1118
+ if (name === 'doubleSpendValidator') {
1119
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1);
1120
+ severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1121
+ }
1122
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
1123
+ validator: name,
1124
+ severity,
1125
+ source: source.toString()
1126
+ });
1127
+ return {
1128
+ result: TopicValidatorResult.Reject,
1129
+ severity
1130
+ };
1131
+ }
1132
+ // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
1133
+ const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
1134
+ if (canAdd === 'ignored') {
1135
+ this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
1136
+ source: source.toString()
1137
+ });
1138
+ return {
1139
+ result: TopicValidatorResult.Ignore,
1140
+ obj: tx
1141
+ };
1142
+ }
1143
+ // Stage 2: expensive proof verification
1144
+ const secondStageValidators = this.createSecondStageMessageValidators();
1145
+ const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
1146
+ if (!secondStageOutcome.allPassed) {
1147
+ const { severity, name } = secondStageOutcome.failure;
1148
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
1149
+ validator: name,
1150
+ severity,
1151
+ source: source.toString()
1152
+ });
1153
+ return {
1154
+ result: TopicValidatorResult.Reject,
1155
+ severity
1156
+ };
1157
+ }
1158
+ // Pool add: persist the tx
1159
+ const txHash = tx.getTxHash();
1160
+ const addResult = await this.mempools.txPool.addPendingTxs([
1161
+ tx
1162
+ ], {
1163
+ source: 'gossip'
1164
+ });
1165
+ const wasAccepted = addResult.accepted.some((h)=>h.equals(txHash));
1166
+ const wasIgnored = addResult.ignored.some((h)=>h.equals(txHash));
1167
+ this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
1168
+ wasAccepted,
1169
+ wasIgnored,
1062
1170
  [Attributes.P2P_ID]: source.toString()
1063
1171
  });
1064
- if (!isValid) {
1172
+ if (wasAccepted) {
1065
1173
  return {
1066
- result: TopicValidatorResult.Reject
1174
+ result: TopicValidatorResult.Accept,
1175
+ obj: tx
1067
1176
  };
1068
- } else if (exists) {
1177
+ } else if (wasIgnored) {
1069
1178
  return {
1070
1179
  result: TopicValidatorResult.Ignore,
1071
1180
  obj: tx
1072
1181
  };
1073
1182
  } else {
1183
+ this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
1184
+ source: source.toString(),
1185
+ txHash: txHash.toString()
1186
+ });
1074
1187
  return {
1075
- result: TopicValidatorResult.Accept,
1076
- obj: tx
1188
+ result: TopicValidatorResult.Reject,
1189
+ severity: PeerErrorSeverity.HighToleranceError
1077
1190
  };
1078
1191
  }
1079
1192
  };
@@ -1081,26 +1194,29 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1081
1194
  if (result !== TopicValidatorResult.Accept || !tx) {
1082
1195
  return;
1083
1196
  }
1197
+ // Tx was accepted into pool and will be propagated - just log and record metrics
1084
1198
  const txHash = tx.getTxHash();
1085
1199
  const txHashString = txHash.toString();
1086
1200
  this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
1087
1201
  source: source.toString(),
1088
1202
  txHash: txHashString
1089
1203
  });
1090
- if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
1091
- this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
1092
- return;
1093
- }
1094
1204
  this.instrumentation.incrementTxReceived(1);
1095
- await this.mempools.txPool.addTxs([
1096
- tx
1097
- ]);
1098
1205
  }
1099
1206
  /**
1100
1207
  * Process a checkpoint attestation from a peer.
1101
1208
  * Validates the attestation and adds it to the pool.
1102
1209
  */ async processCheckpointAttestationFromPeer(payloadData, msgId, source) {
1103
- const { result, obj: attestation } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_attestation);
1210
+ const { result, obj: attestation } = await this.validateReceivedMessage(()=>{
1211
+ const attestation = this.tryDeserialize(()=>CheckpointAttestation.fromBuffer(payloadData), msgId, source);
1212
+ if (!attestation) {
1213
+ return Promise.resolve({
1214
+ result: TopicValidatorResult.Reject,
1215
+ severity: PeerErrorSeverity.LowToleranceError
1216
+ });
1217
+ }
1218
+ return this.validateAndStoreCheckpointAttestation(source, attestation);
1219
+ }, msgId, source, TopicType.checkpoint_attestation);
1104
1220
  if (result !== TopicValidatorResult.Accept || !attestation) {
1105
1221
  return;
1106
1222
  }
@@ -1115,9 +1231,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1115
1231
  const validationResult = await this.checkpointAttestationValidator.validate(attestation);
1116
1232
  if (validationResult.result === 'reject') {
1117
1233
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1118
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1119
1234
  return {
1120
- result: TopicValidatorResult.Reject
1235
+ result: TopicValidatorResult.Reject,
1236
+ severity: validationResult.severity
1121
1237
  };
1122
1238
  }
1123
1239
  if (validationResult.result === 'ignore') {
@@ -1126,38 +1242,56 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1126
1242
  obj: attestation
1127
1243
  };
1128
1244
  }
1129
- // Get committee size for the attestation's slot
1130
- const slot = attestation.payload.header.slotNumber;
1131
- const { committee } = await this.epochCache.getCommittee(slot);
1132
- const committeeSize = committee?.length ?? 0;
1133
1245
  // Try to add the attestation: this handles existence check, cap check, and adding in one call
1134
- const { added, alreadyExists } = await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation, committeeSize);
1246
+ // count is the number of attestations by this signer for this slot (for duplicate detection)
1247
+ const slot = attestation.payload.header.slotNumber;
1248
+ const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation);
1135
1249
  this.logger.trace(`Validate propagated checkpoint attestation`, {
1136
1250
  added,
1137
1251
  alreadyExists,
1252
+ count,
1138
1253
  [Attributes.SLOT_NUMBER]: slot.toString(),
1139
1254
  [Attributes.P2P_ID]: peerId.toString()
1140
1255
  });
1141
- // Duplicate attestation received, no need to re-broadcast
1256
+ // Exact same attestation received, no need to re-broadcast
1142
1257
  if (alreadyExists) {
1143
1258
  return {
1144
1259
  result: TopicValidatorResult.Ignore,
1145
1260
  obj: attestation
1146
1261
  };
1147
1262
  }
1148
- // Could not add (cap reached), no need to re-broadcast
1263
+ // Could not add (cap reached for signer), penalize and do not re-broadcast
1149
1264
  if (!added) {
1150
- this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
1265
+ this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
1151
1266
  slot: slot.toString(),
1152
1267
  archive: attestation.archive.toString(),
1153
- source: peerId.toString()
1268
+ source: peerId.toString(),
1269
+ attester: attestation.getSender()?.toString(),
1270
+ count
1154
1271
  });
1155
1272
  return {
1156
- result: TopicValidatorResult.Ignore,
1157
- obj: attestation
1273
+ result: TopicValidatorResult.Reject,
1274
+ severity: PeerErrorSeverity.HighToleranceError
1158
1275
  };
1159
1276
  }
1160
- // Attestation was added successfully
1277
+ // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
1278
+ // count is the number of attestations by this signer for this slot
1279
+ if (count === 2) {
1280
+ const attester = attestation.getSender();
1281
+ if (attester) {
1282
+ this.logger.warn(`Detected duplicate attestation (equivocation) at slot ${slot}`, {
1283
+ slot: slot.toString(),
1284
+ archive: attestation.archive.toString(),
1285
+ source: peerId.toString(),
1286
+ attester: attester.toString()
1287
+ });
1288
+ this.duplicateAttestationCallback?.({
1289
+ slot,
1290
+ attester
1291
+ });
1292
+ }
1293
+ }
1294
+ // Attestation was added successfully - accept it so other nodes can also detect the equivocation
1161
1295
  return {
1162
1296
  result: TopicValidatorResult.Accept,
1163
1297
  obj: attestation
@@ -1175,9 +1309,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1175
1309
  const validationResult = await this.blockProposalValidator.validate(block);
1176
1310
  if (validationResult.result === 'reject') {
1177
1311
  this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
1178
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1179
1312
  return {
1180
- result: TopicValidatorResult.Reject
1313
+ result: TopicValidatorResult.Reject,
1314
+ severity: validationResult.severity
1181
1315
  };
1182
1316
  }
1183
1317
  if (validationResult.result === 'ignore') {
@@ -1187,8 +1321,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1187
1321
  };
1188
1322
  }
1189
1323
  // Try to add the proposal: this handles existence check, cap check, and adding in one call
1190
- const { added, alreadyExists, totalForPosition } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1191
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1324
+ const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
1325
+ const isEquivocated = count !== undefined && count > 1;
1192
1326
  // Duplicate proposal received, no need to re-broadcast
1193
1327
  if (alreadyExists) {
1194
1328
  this.logger.debug(`Ignoring duplicate block proposal received`, {
@@ -1207,11 +1341,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1207
1341
  }
1208
1342
  // Too many blocks received for this slot and index, penalize peer and do not re-broadcast
1209
1343
  if (!added) {
1210
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1211
1344
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1212
1345
  ...block.toBlockInfo(),
1213
1346
  indexWithinCheckpoint: block.indexWithinCheckpoint,
1214
- totalForPosition,
1347
+ count,
1215
1348
  proposer: block.getSender()?.toString(),
1216
1349
  source: peerId.toString()
1217
1350
  });
@@ -1219,7 +1352,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1219
1352
  result: TopicValidatorResult.Reject,
1220
1353
  metadata: {
1221
1354
  isEquivocated
1222
- }
1355
+ },
1356
+ severity: PeerErrorSeverity.HighToleranceError
1223
1357
  };
1224
1358
  }
1225
1359
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1232,7 +1366,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1232
1366
  proposer: proposer?.toString()
1233
1367
  });
1234
1368
  // Invoke the duplicate callback on the first duplicate spotted only
1235
- if (proposer && totalForPosition === 2) {
1369
+ if (proposer && count === 2) {
1236
1370
  this.duplicateProposalCallback?.({
1237
1371
  slot: block.slotNumber,
1238
1372
  proposer,
@@ -1262,13 +1396,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1262
1396
  source: sender.toString(),
1263
1397
  ...block.toBlockInfo()
1264
1398
  });
1265
- // Mark the txs in this proposal as non-evictable
1266
- await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
1399
+ // Mark the txs in this proposal as protected
1400
+ await this.mempools.txPool.protectTxs(block.txHashes, block.blockHeader);
1267
1401
  // Call the block received callback to validate the proposal.
1268
1402
  // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1269
1403
  const isValid = await this.blockReceivedCallback(block, sender);
1270
1404
  if (!isValid) {
1271
- this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1405
+ this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1272
1406
  }
1273
1407
  }
1274
1408
  /**
@@ -1293,9 +1427,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1293
1427
  const validationResult = await this.checkpointProposalValidator.validate(checkpoint);
1294
1428
  if (validationResult.result === 'reject') {
1295
1429
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1296
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1297
1430
  return {
1298
- result: TopicValidatorResult.Reject
1431
+ result: TopicValidatorResult.Reject,
1432
+ severity: validationResult.severity
1299
1433
  };
1300
1434
  }
1301
1435
  if (validationResult.result === 'ignore') {
@@ -1312,26 +1446,28 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1312
1446
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1313
1447
  [Attributes.P2P_ID]: peerId.toString()
1314
1448
  });
1315
- const { result, obj, metadata: { isEquivocated } = {} } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1316
- if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1449
+ const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1450
+ const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1451
+ if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1317
1452
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1318
1453
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1319
1454
  [Attributes.P2P_ID]: peerId.toString(),
1320
1455
  isEquivocated,
1321
- result
1456
+ result: blockProposalResult.result
1322
1457
  });
1323
1458
  return {
1324
- result: TopicValidatorResult.Reject
1459
+ result: TopicValidatorResult.Reject,
1460
+ severity: 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError
1325
1461
  };
1326
- } else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1462
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1327
1463
  processBlock = true;
1328
1464
  }
1329
1465
  }
1330
1466
  // Try to add the checkpoint proposal core: this handles existence check, cap check, and adding in one call
1331
1467
  const checkpointCore = checkpoint.toCore();
1332
1468
  const tryAddResult = await this.mempools.attestationPool.tryAddCheckpointProposal(checkpointCore);
1333
- const { added, alreadyExists, totalForPosition } = tryAddResult;
1334
- const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
1469
+ const { added, alreadyExists, count } = tryAddResult;
1470
+ const isEquivocated = count !== undefined && count > 1;
1335
1471
  // Duplicate proposal received, do not re-broadcast
1336
1472
  if (alreadyExists) {
1337
1473
  this.logger.debug(`Ignoring duplicate checkpoint proposal received`, {
@@ -1350,10 +1486,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1350
1486
  // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1351
1487
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1352
1488
  if (!added) {
1353
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1354
1489
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1355
1490
  ...checkpoint.toCheckpointInfo(),
1356
- totalForPosition,
1491
+ count,
1357
1492
  source: peerId.toString()
1358
1493
  });
1359
1494
  return {
@@ -1362,7 +1497,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1362
1497
  metadata: {
1363
1498
  isEquivocated,
1364
1499
  processBlock
1365
- }
1500
+ },
1501
+ severity: PeerErrorSeverity.HighToleranceError
1366
1502
  };
1367
1503
  }
1368
1504
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1375,7 +1511,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1375
1511
  proposer: proposer?.toString()
1376
1512
  });
1377
1513
  // Invoke the duplicate callback on the first duplicate spotted only
1378
- if (proposer && totalForPosition === 2) {
1514
+ if (proposer && count === 2) {
1379
1515
  this.duplicateProposalCallback?.({
1380
1516
  slot: checkpoint.slotNumber,
1381
1517
  proposer,
@@ -1412,9 +1548,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1412
1548
  archive: checkpoint.archive.toString(),
1413
1549
  source: sender.toString()
1414
1550
  });
1551
+ await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
1415
1552
  // Call the checkpoint received callback with the core version (without lastBlock)
1416
1553
  // to validate and potentially generate attestations
1417
- const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
1554
+ const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
1418
1555
  if (attestations && attestations.length > 0) {
1419
1556
  // If the callback returned attestations, add them to the pool and propagate them
1420
1557
  await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
@@ -1586,33 +1723,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1586
1723
  }
1587
1724
  }
1588
1725
  createRequestedTxValidator() {
1589
- return createTxReqRespValidator(this.proofVerifier, {
1726
+ return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
1590
1727
  l1ChainId: this.config.l1ChainId,
1591
1728
  rollupVersion: this.config.rollupVersion
1592
1729
  });
1593
1730
  }
1594
- async validatePropagatedTx(tx, peerId) {
1595
- const currentBlockNumber = await this.archiver.getBlockNumber();
1596
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1597
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1598
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1599
- for (const validator of messageValidators){
1600
- const outcome = await this.runValidations(tx, validator);
1601
- if (outcome.allPassed) {
1602
- continue;
1603
- }
1604
- const { name } = outcome.failure;
1605
- let { severity } = outcome.failure;
1606
- // Double spend validator has a special case handler
1607
- if (name === 'doubleSpendValidator') {
1608
- const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1609
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1610
- }
1611
- this.peerManager.penalizePeer(peerId, severity);
1612
- return false;
1613
- }
1614
- return true;
1615
- }
1616
1731
  async getGasFees(blockNumber) {
1617
1732
  if (blockNumber === this.feesCache?.blockNumber) {
1618
1733
  return this.feesCache.gasFees;
@@ -1639,38 +1754,35 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1639
1754
  peerScoring: this.peerManager
1640
1755
  };
1641
1756
  }
1642
- async validate(txs) {
1643
- const currentBlockNumber = await this.archiver.getBlockNumber();
1644
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1645
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1646
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1647
- await Promise.all(txs.map(async (tx)=>{
1648
- for (const validator of messageValidators){
1649
- const outcome = await this.runValidations(tx, validator);
1650
- if (!outcome.allPassed) {
1651
- throw new Error('Invalid tx detected', {
1652
- cause: {
1653
- outcome
1654
- }
1655
- });
1656
- }
1657
- }
1757
+ async validateTxsReceivedInBlockProposal(txs) {
1758
+ const validator = createTxValidatorForBlockProposalReceivedTxs(this.proofVerifier, {
1759
+ l1ChainId: this.config.l1ChainId,
1760
+ rollupVersion: this.config.rollupVersion
1761
+ }, this.logger.getBindings());
1762
+ const results = await Promise.all(txs.map(async (tx)=>{
1763
+ const result = await validator.validateTx(tx);
1764
+ return result.result !== 'invalid';
1658
1765
  }));
1766
+ if (results.some((value)=>value === false)) {
1767
+ throw new Error('Invalid tx detected');
1768
+ }
1659
1769
  }
1660
- /**
1661
- * Create message validators for the given block number and timestamp.
1662
- *
1663
- * Each validator is a pair of a validator and a severity.
1664
- * If a validator fails, the peer is penalized with the severity of the validator.
1665
- *
1666
- * @param currentBlockNumber - The current synced block number.
1667
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
1668
- * @returns The message validators.
1669
- */ async createMessageValidators(currentBlockNumber, nextSlotTimestamp) {
1770
+ /** Creates the first stage (fast) validators for gossiped transactions. */ async createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp) {
1670
1771
  const gasFees = await this.getGasFees(currentBlockNumber);
1671
- const allowedInSetup = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
1672
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1673
- 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());
1772
+ const allowedInSetup = [
1773
+ ...await getDefaultAllowedSetupFunctions(),
1774
+ ...this.config.txPublicSetupAllowListExtend ?? []
1775
+ ];
1776
+ const blockNumber = BlockNumber(currentBlockNumber + 1);
1777
+ const l1Constants = await this.archiver.getL1Constants();
1778
+ return createFirstStageTxValidationsForGossipedTransactions(nextSlotTimestamp, blockNumber, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings(), {
1779
+ rollupManaLimit: l1Constants.rollupManaLimit,
1780
+ maxBlockL2Gas: this.config.validateMaxL2BlockGas,
1781
+ maxBlockDAGas: this.config.validateMaxDABlockGas
1782
+ });
1783
+ }
1784
+ /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */ createSecondStageMessageValidators() {
1785
+ return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
1674
1786
  }
1675
1787
  /**
1676
1788
  * Run validations on a tx.
@@ -1688,8 +1800,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1688
1800
  });
1689
1801
  // A promise that resolves when all validations have been run
1690
1802
  const allValidations = await Promise.all(validationPromises);
1691
- const failed = allValidations.find((x)=>!x.isValid);
1692
- if (failed) {
1803
+ const failures = allValidations.filter((x)=>!x.isValid);
1804
+ if (failures.length > 0) {
1805
+ // Pick the most severe failure (lowest tolerance = harshest penalty)
1806
+ const failed = maxBy(failures, (f)=>PeerErrorSeverityByHarshness.indexOf(f.severity));
1693
1807
  return {
1694
1808
  allPassed: false,
1695
1809
  failure: {
@@ -1736,19 +1850,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1736
1850
  }
1737
1851
  return PeerErrorSeverity.HighToleranceError;
1738
1852
  }
1739
- /**
1740
- * Validate a checkpoint attestation.
1741
- *
1742
- * @param attestation - The checkpoint attestation to validate.
1743
- * @returns True if the checkpoint attestation is valid, false otherwise.
1744
- */ async validateCheckpointAttestation(peerId, attestation) {
1745
- const result = await this.checkpointAttestationValidator.validate(attestation);
1746
- if (result.result === 'reject') {
1747
- this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1748
- this.peerManager.penalizePeer(peerId, result.severity);
1749
- }
1750
- return result;
1751
- }
1752
1853
  getPeerScore(peerId) {
1753
1854
  return this.node.services.pubsub.score.score(peerId.toString());
1754
1855
  }