@aztec/p2p 0.0.1-commit.8c0b8ff → 0.0.1-commit.8cb2d04d8

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 (270) hide show
  1. package/dest/client/factory.d.ts +2 -2
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +1 -0
  4. package/dest/client/interface.d.ts +9 -2
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +3 -2
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +30 -8
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +17 -6
  10. package/dest/config.d.ts +107 -103
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +17 -12
  13. package/dest/errors/p2p-service.error.d.ts +9 -0
  14. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  15. package/dest/errors/p2p-service.error.js +10 -0
  16. package/dest/index.d.ts +1 -2
  17. package/dest/index.d.ts.map +1 -1
  18. package/dest/index.js +0 -1
  19. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +7 -5
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/attestation_pool.js +16 -9
  22. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  23. package/dest/mem_pools/index.d.ts +1 -2
  24. package/dest/mem_pools/index.d.ts.map +1 -1
  25. package/dest/mem_pools/instrumentation.d.ts +4 -2
  26. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  27. package/dest/mem_pools/instrumentation.js +16 -14
  28. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  29. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +7 -5
  30. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/interfaces.js +1 -0
  32. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -6
  33. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +6 -2
  35. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  36. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -43
  38. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +1 -1
  39. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +3 -0
  41. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -1
  42. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +18 -1
  44. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +5 -2
  45. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
  47. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -2
  48. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  49. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  50. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  51. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  52. package/dest/msg_validators/clock_tolerance.js +54 -3
  53. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +2 -1
  54. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  55. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +2 -1
  56. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  57. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -1
  58. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  59. package/dest/msg_validators/proposal_validator/proposal_validator.js +19 -11
  60. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  61. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  62. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  63. package/dest/msg_validators/tx_validator/gas_validator.js +11 -9
  64. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  65. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  66. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  67. package/dest/services/data_store.d.ts +1 -1
  68. package/dest/services/data_store.d.ts.map +1 -1
  69. package/dest/services/data_store.js +5 -5
  70. package/dest/services/dummy_service.d.ts +6 -3
  71. package/dest/services/dummy_service.d.ts.map +1 -1
  72. package/dest/services/dummy_service.js +6 -1
  73. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  74. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  75. package/dest/services/gossipsub/topic_score_params.js +21 -4
  76. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  77. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  78. package/dest/services/libp2p/instrumentation.js +14 -0
  79. package/dest/services/libp2p/libp2p_service.d.ts +15 -25
  80. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  81. package/dest/services/libp2p/libp2p_service.js +150 -115
  82. package/dest/services/peer-manager/metrics.d.ts +3 -1
  83. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  84. package/dest/services/peer-manager/metrics.js +6 -0
  85. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  86. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  87. package/dest/services/peer-manager/peer_manager.js +39 -11
  88. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  89. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  90. package/dest/services/peer-manager/peer_scoring.js +32 -10
  91. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
  92. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  93. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +82 -101
  94. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
  95. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  96. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  97. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  98. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  99. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  100. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  101. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  102. package/dest/services/reqresp/config.d.ts +3 -3
  103. package/dest/services/reqresp/config.d.ts.map +1 -1
  104. package/dest/services/reqresp/interface.d.ts +14 -9
  105. package/dest/services/reqresp/interface.d.ts.map +1 -1
  106. package/dest/services/reqresp/interface.js +10 -11
  107. package/dest/services/reqresp/metrics.d.ts +1 -1
  108. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  109. package/dest/services/reqresp/metrics.js +0 -1
  110. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  111. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  112. package/dest/services/reqresp/protocols/index.js +0 -1
  113. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  114. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  115. package/dest/services/reqresp/protocols/tx.js +1 -3
  116. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  117. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  118. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  119. package/dest/services/reqresp/reqresp.d.ts +4 -2
  120. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  121. package/dest/services/reqresp/reqresp.js +13 -3
  122. package/dest/services/service.d.ts +5 -2
  123. package/dest/services/service.d.ts.map +1 -1
  124. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
  125. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  126. package/dest/services/tx_collection/fast_tx_collection.js +57 -73
  127. package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
  128. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  129. package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
  130. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  131. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  132. package/dest/services/tx_collection/request_tracker.js +84 -0
  133. package/dest/services/tx_collection/slow_tx_collection.js +1 -1
  134. package/dest/services/tx_collection/tx_collection.d.ts +3 -6
  135. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  136. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  137. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  138. package/dest/test-helpers/mock-pubsub.d.ts +11 -3
  139. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  140. package/dest/test-helpers/mock-pubsub.js +35 -10
  141. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  142. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  143. package/dest/test-helpers/reqresp-nodes.js +1 -2
  144. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  145. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  146. package/dest/test-helpers/testbench-utils.js +21 -2
  147. package/dest/testbench/p2p_client_testbench_worker.js +66 -15
  148. package/dest/testbench/worker_client_manager.d.ts +8 -1
  149. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  150. package/dest/testbench/worker_client_manager.js +51 -2
  151. package/dest/util.d.ts +1 -1
  152. package/package.json +14 -14
  153. package/src/client/factory.ts +2 -1
  154. package/src/client/interface.ts +9 -1
  155. package/src/client/p2p_client.ts +34 -9
  156. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -9
  157. package/src/config.ts +29 -17
  158. package/src/errors/p2p-service.error.ts +11 -0
  159. package/src/index.ts +0 -1
  160. package/src/mem_pools/attestation_pool/attestation_pool.ts +17 -12
  161. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  162. package/src/mem_pools/index.ts +0 -3
  163. package/src/mem_pools/instrumentation.ts +17 -13
  164. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  165. package/src/mem_pools/tx_pool_v2/interfaces.ts +7 -4
  166. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +12 -6
  167. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
  168. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +3 -0
  169. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +19 -1
  170. package/src/msg_validators/attestation_validator/README.md +1 -1
  171. package/src/msg_validators/attestation_validator/attestation_validator.ts +21 -9
  172. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -1
  173. package/src/msg_validators/clock_tolerance.ts +72 -3
  174. package/src/msg_validators/proposal_validator/README.md +4 -4
  175. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +4 -1
  176. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +4 -1
  177. package/src/msg_validators/proposal_validator/proposal_validator.ts +17 -10
  178. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  179. package/src/msg_validators/tx_validator/gas_validator.ts +25 -9
  180. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  181. package/src/services/data_store.ts +5 -13
  182. package/src/services/dummy_service.ts +8 -2
  183. package/src/services/gossipsub/topic_score_params.ts +36 -4
  184. package/src/services/libp2p/instrumentation.ts +14 -0
  185. package/src/services/libp2p/libp2p_service.ts +146 -130
  186. package/src/services/peer-manager/metrics.ts +7 -0
  187. package/src/services/peer-manager/peer_manager.ts +45 -11
  188. package/src/services/peer-manager/peer_scoring.ts +27 -5
  189. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  190. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +78 -111
  191. package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
  192. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  193. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  194. package/src/services/reqresp/config.ts +2 -2
  195. package/src/services/reqresp/interface.ts +21 -11
  196. package/src/services/reqresp/metrics.ts +0 -1
  197. package/src/services/reqresp/protocols/index.ts +0 -1
  198. package/src/services/reqresp/protocols/tx.ts +1 -3
  199. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  200. package/src/services/reqresp/reqresp.ts +21 -2
  201. package/src/services/service.ts +6 -1
  202. package/src/services/tx_collection/fast_tx_collection.ts +57 -83
  203. package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
  204. package/src/services/tx_collection/request_tracker.ts +127 -0
  205. package/src/services/tx_collection/slow_tx_collection.ts +1 -1
  206. package/src/services/tx_collection/tx_collection.ts +3 -5
  207. package/src/test-helpers/make-test-p2p-clients.ts +1 -1
  208. package/src/test-helpers/mock-pubsub.ts +31 -5
  209. package/src/test-helpers/reqresp-nodes.ts +3 -3
  210. package/src/test-helpers/testbench-utils.ts +29 -3
  211. package/src/testbench/p2p_client_testbench_worker.ts +71 -15
  212. package/src/testbench/worker_client_manager.ts +57 -2
  213. package/src/util.ts +1 -1
  214. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  215. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  216. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  217. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  218. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  219. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  220. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  221. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  222. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  223. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  224. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  225. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  226. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  227. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  228. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  229. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  230. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  231. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  232. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  233. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  234. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  235. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  236. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  237. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  238. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  239. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  240. package/dest/mem_pools/tx_pool/index.js +0 -2
  241. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  242. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  243. package/dest/mem_pools/tx_pool/priority.js +0 -15
  244. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  245. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  246. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  247. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  248. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  249. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  250. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  251. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  252. package/dest/services/reqresp/protocols/block.js +0 -32
  253. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  254. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  255. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  256. package/src/mem_pools/tx_pool/README.md +0 -270
  257. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  258. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  259. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  260. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  261. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  262. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  263. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  264. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  265. package/src/mem_pools/tx_pool/index.ts +0 -2
  266. package/src/mem_pools/tx_pool/priority.ts +0 -20
  267. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  268. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  269. package/src/services/reqresp/protocols/block.ts +0 -37
  270. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
@@ -370,7 +370,7 @@ 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, _initProto;
373
+ var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _initProto;
374
374
  import { BlockNumber } from '@aztec/foundation/branded-types';
375
375
  import { maxBy } from '@aztec/foundation/collection';
376
376
  import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
@@ -395,6 +395,7 @@ 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
401
  import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, createTxValidatorForReqResponseReceivedTxs } from '../../msg_validators/tx_validator/factory.js';
@@ -408,7 +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, pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
412
+ import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
412
413
  import { ReqResp } from '../reqresp/reqresp.js';
413
414
  import { P2PInstrumentation } from './instrumentation.js';
414
415
  _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
@@ -430,12 +431,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
430
431
  [Attributes.BLOCK_ARCHIVE]: request.archiveRoot.toString()
431
432
  })), _dec6 = trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
432
433
  [Attributes.TX_HASH]: requestedTxHash.toString()
433
- })), _dec7 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
434
- [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
435
- })), _dec8 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
436
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
437
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
438
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
439
434
  }));
440
435
  /**
441
436
  * Lib P2P implementation of the P2PService interface.
@@ -486,16 +481,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
486
481
  _dec6,
487
482
  2,
488
483
  "validateRequestedTxs"
489
- ],
490
- [
491
- _dec7,
492
- 2,
493
- "validateRequestedBlock"
494
- ],
495
- [
496
- _dec8,
497
- 2,
498
- "validateCheckpointAttestation"
499
484
  ]
500
485
  ], []));
501
486
  }
@@ -519,7 +504,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
519
504
  * Callback for when a checkpoint proposal is received from a peer.
520
505
  * @param checkpoint - The checkpoint proposal received from the peer.
521
506
  * @returns The attestations for the checkpoint, if any.
522
- */ checkpointReceivedCallback;
507
+ */ allNodesCheckpointReceivedCallback;
508
+ /**
509
+ * Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
510
+ * @param checkpoint - The checkpoint proposal received from the peer.
511
+ * @returns The attestations for the checkpoint, if any.
512
+ */ validatorCheckpointReceivedCallback;
523
513
  gossipSubEventHandler;
524
514
  instrumentation;
525
515
  telemetry;
@@ -541,13 +531,19 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
541
531
  this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
542
532
  this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
543
533
  this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
534
+ const p2pPropagationTime = config.attestationPropagationTime;
544
535
  const proposalValidatorOpts = {
545
536
  txsPermitted: !config.disableTransactions,
546
- maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint
537
+ maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
538
+ p2pPropagationTime
547
539
  };
548
540
  this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
549
541
  this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
550
- this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new CheckpointAttestationValidator(epochCache);
542
+ this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, {
543
+ l1PublishingTime: config.l1PublishingTime
544
+ }) : new CheckpointAttestationValidator(epochCache, {
545
+ l1PublishingTime: config.l1PublishingTime
546
+ });
551
547
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
552
548
  this.blockReceivedCallback = async (block)=>{
553
549
  this.logger.warn(`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`, {
@@ -555,8 +551,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
555
551
  });
556
552
  return true;
557
553
  };
558
- this.checkpointReceivedCallback = (checkpoint)=>{
559
- this.logger.debug(`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`);
554
+ this.allNodesCheckpointReceivedCallback = (_checkpoint)=>{
555
+ throw new CheckpointProposalReceivedCallbackNotRegisteredError();
556
+ };
557
+ this.validatorCheckpointReceivedCallback = (_checkpoint)=>{
560
558
  return Promise.resolve(undefined);
561
559
  };
562
560
  }
@@ -609,9 +607,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
609
607
  const l1Constants = epochCache.getL1Constants();
610
608
  const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
611
609
  slotDurationMs: l1Constants.slotDuration * 1000,
610
+ ethereumSlotDuration: l1Constants.ethereumSlotDuration,
612
611
  heartbeatIntervalMs: config.gossipsubInterval,
613
612
  targetCommitteeSize: l1Constants.targetCommitteeSize,
614
613
  blockDurationMs: config.blockDurationMs,
614
+ l1PublishingTime: config.l1PublishingTime,
615
+ p2pPropagationTime: config.attestationPropagationTime,
615
616
  expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot
616
617
  });
617
618
  const node = await createLibp2p({
@@ -726,6 +727,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
726
727
  const peerScoring = new PeerScoring(config, telemetry);
727
728
  const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
728
729
  const peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, reqresp, worldStateSynchronizer, protocolVersion, epochCache);
730
+ // Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
731
+ reqresp.setShouldRejectPeer((peerId)=>peerManager.shouldDisableP2PGossip(peerId));
729
732
  // Configure application-specific scoring for gossipsub.
730
733
  // The weight scales app score to align with gossipsub thresholds:
731
734
  // - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
@@ -752,13 +755,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
752
755
  // Create request response protocol handlers
753
756
  const txHandler = reqRespTxHandler(this.mempools);
754
757
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
755
- const blockHandler = reqRespBlockHandler(this.archiver);
756
758
  const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
757
759
  const requestResponseHandlers = {
758
760
  [ReqRespSubProtocol.PING]: pingHandler,
759
761
  [ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
760
- [ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
761
- [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this)
762
+ [ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this)
762
763
  };
763
764
  if (!this.config.disableTransactions) {
764
765
  const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.archiver, this.mempools.txPool);
@@ -771,8 +772,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
771
772
  const reqrespSubProtocolValidators = {
772
773
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
773
774
  [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
774
- [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
775
- [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this)
775
+ [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this)
776
776
  };
777
777
  await this.peerManager.initializePeers();
778
778
  await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
@@ -860,8 +860,14 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
860
860
  registerBlockReceivedCallback(callback) {
861
861
  this.blockReceivedCallback = callback;
862
862
  }
863
- registerCheckpointReceivedCallback(callback) {
864
- this.checkpointReceivedCallback = callback;
863
+ registerValidatorCheckpointReceivedCallback(callback) {
864
+ this.validatorCheckpointReceivedCallback = callback;
865
+ }
866
+ registerAllNodesCheckpointReceivedCallback(callback) {
867
+ this.allNodesCheckpointReceivedCallback = callback;
868
+ }
869
+ async notifyOwnCheckpointProposal(checkpoint) {
870
+ await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
865
871
  }
866
872
  /**
867
873
  * Registers a callback to be invoked when a duplicate proposal is detected.
@@ -927,6 +933,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
927
933
  if (!validator || !validator.addMessage(msgId)) {
928
934
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
929
935
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
936
+ if (topicType === TopicType.tx) {
937
+ this.logger.verbose(`Ignoring already-seen tx gossip message`, {
938
+ msgId,
939
+ source: source.toString()
940
+ });
941
+ }
930
942
  return {
931
943
  result: false,
932
944
  topicType
@@ -1032,29 +1044,79 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1032
1044
  return;
1033
1045
  }
1034
1046
  async validateReceivedMessage(validationFunc, msgId, source, topicType) {
1047
+ // Default to reject result with a penalty if validation function throws an error
1035
1048
  let resultAndObj = {
1036
- result: TopicValidatorResult.Reject
1049
+ result: TopicValidatorResult.Reject,
1050
+ severity: PeerErrorSeverity.MidToleranceError
1037
1051
  };
1038
1052
  const timer = new Timer();
1039
1053
  try {
1040
1054
  resultAndObj = await validationFunc();
1041
1055
  } catch (err) {
1042
- this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
1043
- this.logger.error(`Error deserializing and validating gossipsub message`, err, {
1056
+ this.logger.error(`Error validating gossipsub message`, err, {
1044
1057
  msgId,
1045
1058
  source: source.toString(),
1046
1059
  topicType
1047
1060
  });
1048
1061
  }
1062
+ const validationTimeMs = timer.ms();
1063
+ const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
1064
+ if (validationTimeMs > mcacheWindowMs * 0.75) {
1065
+ this.instrumentation.incSlowValidation(topicType);
1066
+ this.logger.warn(`Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` + `Message forwarding may be skipped if validation exceeds the window.`, {
1067
+ msgId,
1068
+ source: source.toString(),
1069
+ topicType,
1070
+ validationTimeMs,
1071
+ mcacheWindowMs
1072
+ });
1073
+ }
1049
1074
  if (resultAndObj.result === TopicValidatorResult.Accept) {
1075
+ this.logger.debug(`Message ${topicType} accepted by validator`, {
1076
+ msgId,
1077
+ source: source.toString(),
1078
+ topicType
1079
+ });
1050
1080
  this.instrumentation.recordMessageValidation(topicType, timer);
1081
+ } else if (resultAndObj.result === TopicValidatorResult.Reject) {
1082
+ this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
1083
+ msgId,
1084
+ source: source.toString(),
1085
+ topicType,
1086
+ severity: resultAndObj.severity
1087
+ });
1088
+ this.peerManager.penalizePeer(source, resultAndObj.severity);
1089
+ } else {
1090
+ this.logger.trace(`Message ${topicType} ignored by validator`, {
1091
+ msgId,
1092
+ source: source.toString(),
1093
+ topicType
1094
+ });
1051
1095
  }
1052
1096
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
1053
1097
  return resultAndObj;
1054
1098
  }
1099
+ tryDeserialize(deserializeFunc, msgId, source) {
1100
+ try {
1101
+ return deserializeFunc();
1102
+ } catch (err) {
1103
+ this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
1104
+ err,
1105
+ msgId,
1106
+ source: source.toString()
1107
+ });
1108
+ return undefined;
1109
+ }
1110
+ }
1055
1111
  async handleGossipedTx(payloadData, msgId, source) {
1056
1112
  const validationFunc = async ()=>{
1057
- const tx = Tx.fromBuffer(payloadData);
1113
+ const tx = this.tryDeserialize(()=>Tx.fromBuffer(payloadData), msgId, source);
1114
+ if (!tx) {
1115
+ return {
1116
+ result: TopicValidatorResult.Reject,
1117
+ severity: PeerErrorSeverity.LowToleranceError
1118
+ };
1119
+ }
1058
1120
  const currentBlockNumber = await this.archiver.getBlockNumber();
1059
1121
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1060
1122
  // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
@@ -1070,14 +1132,22 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1070
1132
  const txBlockNumber = BlockNumber(currentBlockNumber + 1);
1071
1133
  severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1072
1134
  }
1073
- this.peerManager.penalizePeer(source, severity);
1135
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
1136
+ validator: name,
1137
+ severity,
1138
+ source: source.toString()
1139
+ });
1074
1140
  return {
1075
- result: TopicValidatorResult.Reject
1141
+ result: TopicValidatorResult.Reject,
1142
+ severity
1076
1143
  };
1077
1144
  }
1078
1145
  // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
1079
1146
  const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
1080
1147
  if (canAdd === 'ignored') {
1148
+ this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
1149
+ source: source.toString()
1150
+ });
1081
1151
  return {
1082
1152
  result: TopicValidatorResult.Ignore,
1083
1153
  obj: tx
@@ -1087,10 +1157,15 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1087
1157
  const secondStageValidators = this.createSecondStageMessageValidators();
1088
1158
  const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
1089
1159
  if (!secondStageOutcome.allPassed) {
1090
- const { severity } = secondStageOutcome.failure;
1091
- this.peerManager.penalizePeer(source, severity);
1160
+ const { severity, name } = secondStageOutcome.failure;
1161
+ this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
1162
+ validator: name,
1163
+ severity,
1164
+ source: source.toString()
1165
+ });
1092
1166
  return {
1093
- result: TopicValidatorResult.Reject
1167
+ result: TopicValidatorResult.Reject,
1168
+ severity
1094
1169
  };
1095
1170
  }
1096
1171
  // Pool add: persist the tx
@@ -1102,7 +1177,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1102
1177
  });
1103
1178
  const wasAccepted = addResult.accepted.some((h)=>h.equals(txHash));
1104
1179
  const wasIgnored = addResult.ignored.some((h)=>h.equals(txHash));
1105
- this.logger.trace(`Validate propagated tx`, {
1180
+ this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
1106
1181
  wasAccepted,
1107
1182
  wasIgnored,
1108
1183
  [Attributes.P2P_ID]: source.toString()
@@ -1122,9 +1197,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1122
1197
  source: source.toString(),
1123
1198
  txHash: txHash.toString()
1124
1199
  });
1125
- this.peerManager.penalizePeer(source, PeerErrorSeverity.HighToleranceError);
1126
1200
  return {
1127
- result: TopicValidatorResult.Reject
1201
+ result: TopicValidatorResult.Reject,
1202
+ severity: PeerErrorSeverity.HighToleranceError
1128
1203
  };
1129
1204
  }
1130
1205
  };
@@ -1145,7 +1220,16 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1145
1220
  * Process a checkpoint attestation from a peer.
1146
1221
  * Validates the attestation and adds it to the pool.
1147
1222
  */ async processCheckpointAttestationFromPeer(payloadData, msgId, source) {
1148
- const { result, obj: attestation } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_attestation);
1223
+ const { result, obj: attestation } = await this.validateReceivedMessage(()=>{
1224
+ const attestation = this.tryDeserialize(()=>CheckpointAttestation.fromBuffer(payloadData), msgId, source);
1225
+ if (!attestation) {
1226
+ return Promise.resolve({
1227
+ result: TopicValidatorResult.Reject,
1228
+ severity: PeerErrorSeverity.LowToleranceError
1229
+ });
1230
+ }
1231
+ return this.validateAndStoreCheckpointAttestation(source, attestation);
1232
+ }, msgId, source, TopicType.checkpoint_attestation);
1149
1233
  if (result !== TopicValidatorResult.Accept || !attestation) {
1150
1234
  return;
1151
1235
  }
@@ -1160,9 +1244,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1160
1244
  const validationResult = await this.checkpointAttestationValidator.validate(attestation);
1161
1245
  if (validationResult.result === 'reject') {
1162
1246
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1163
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1164
1247
  return {
1165
- result: TopicValidatorResult.Reject
1248
+ result: TopicValidatorResult.Reject,
1249
+ severity: validationResult.severity
1166
1250
  };
1167
1251
  }
1168
1252
  if (validationResult.result === 'ignore') {
@@ -1189,9 +1273,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1189
1273
  obj: attestation
1190
1274
  };
1191
1275
  }
1192
- // Could not add (cap reached for signer), no need to re-broadcast
1276
+ // Could not add (cap reached for signer), penalize and do not re-broadcast
1193
1277
  if (!added) {
1194
- this.logger.warn(`Dropping checkpoint attestation due to cap`, {
1278
+ this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
1195
1279
  slot: slot.toString(),
1196
1280
  archive: attestation.archive.toString(),
1197
1281
  source: peerId.toString(),
@@ -1199,8 +1283,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1199
1283
  count
1200
1284
  });
1201
1285
  return {
1202
- result: TopicValidatorResult.Ignore,
1203
- obj: attestation
1286
+ result: TopicValidatorResult.Reject,
1287
+ severity: PeerErrorSeverity.HighToleranceError
1204
1288
  };
1205
1289
  }
1206
1290
  // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
@@ -1238,9 +1322,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1238
1322
  const validationResult = await this.blockProposalValidator.validate(block);
1239
1323
  if (validationResult.result === 'reject') {
1240
1324
  this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
1241
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1242
1325
  return {
1243
- result: TopicValidatorResult.Reject
1326
+ result: TopicValidatorResult.Reject,
1327
+ severity: validationResult.severity
1244
1328
  };
1245
1329
  }
1246
1330
  if (validationResult.result === 'ignore') {
@@ -1270,7 +1354,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1270
1354
  }
1271
1355
  // Too many blocks received for this slot and index, penalize peer and do not re-broadcast
1272
1356
  if (!added) {
1273
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1274
1357
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1275
1358
  ...block.toBlockInfo(),
1276
1359
  indexWithinCheckpoint: block.indexWithinCheckpoint,
@@ -1282,7 +1365,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1282
1365
  result: TopicValidatorResult.Reject,
1283
1366
  metadata: {
1284
1367
  isEquivocated
1285
- }
1368
+ },
1369
+ severity: PeerErrorSeverity.HighToleranceError
1286
1370
  };
1287
1371
  }
1288
1372
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1356,9 +1440,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1356
1440
  const validationResult = await this.checkpointProposalValidator.validate(checkpoint);
1357
1441
  if (validationResult.result === 'reject') {
1358
1442
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1359
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1360
1443
  return {
1361
- result: TopicValidatorResult.Reject
1444
+ result: TopicValidatorResult.Reject,
1445
+ severity: validationResult.severity
1362
1446
  };
1363
1447
  }
1364
1448
  if (validationResult.result === 'ignore') {
@@ -1375,18 +1459,20 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1375
1459
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1376
1460
  [Attributes.P2P_ID]: peerId.toString()
1377
1461
  });
1378
- const { result, obj, metadata: { isEquivocated } = {} } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1379
- if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1462
+ const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1463
+ const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1464
+ if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1380
1465
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1381
1466
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1382
1467
  [Attributes.P2P_ID]: peerId.toString(),
1383
1468
  isEquivocated,
1384
- result
1469
+ result: blockProposalResult.result
1385
1470
  });
1386
1471
  return {
1387
- result: TopicValidatorResult.Reject
1472
+ result: TopicValidatorResult.Reject,
1473
+ severity: 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError
1388
1474
  };
1389
- } else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1475
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1390
1476
  processBlock = true;
1391
1477
  }
1392
1478
  }
@@ -1413,7 +1499,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1413
1499
  // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1414
1500
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1415
1501
  if (!added) {
1416
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1417
1502
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1418
1503
  ...checkpoint.toCheckpointInfo(),
1419
1504
  count,
@@ -1425,7 +1510,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1425
1510
  metadata: {
1426
1511
  isEquivocated,
1427
1512
  processBlock
1428
- }
1513
+ },
1514
+ severity: PeerErrorSeverity.HighToleranceError
1429
1515
  };
1430
1516
  }
1431
1517
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1475,9 +1561,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1475
1561
  archive: checkpoint.archive.toString(),
1476
1562
  source: sender.toString()
1477
1563
  });
1564
+ await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
1478
1565
  // Call the checkpoint received callback with the core version (without lastBlock)
1479
1566
  // to validate and potentially generate attestations
1480
- const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
1567
+ const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
1481
1568
  if (attestations && attestations.length > 0) {
1482
1569
  // If the callback returned attestations, add them to the pool and propagate them
1483
1570
  await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
@@ -1597,45 +1684,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1597
1684
  return false;
1598
1685
  }
1599
1686
  }
1600
- /**
1601
- * Validates a BLOCK response.
1602
- *
1603
- * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1604
- * Penalizes on block number mismatch or hash mismatch.
1605
- *
1606
- * @param requestedBlockNumber - The requested block number.
1607
- * @param responseBlock - The block returned by the peer.
1608
- * @param peerId - The peer that returned the block.
1609
- * @returns True if the response is valid, false otherwise.
1610
- */ async validateRequestedBlock(requestedBlockNumber, responseBlock, peerId) {
1611
- try {
1612
- const reqNum = Number(requestedBlockNumber.toString());
1613
- if (responseBlock.number !== reqNum) {
1614
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1615
- return false;
1616
- }
1617
- const local = await this.archiver.getBlock(BlockNumber(reqNum));
1618
- if (!local) {
1619
- // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1620
- // TODO: Consider extending this validator to accept an expected hash or
1621
- // performing quorum-based checks when using P2P syncing prior to L1 sync.
1622
- this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1623
- return false;
1624
- }
1625
- const [localHash, respHash] = await Promise.all([
1626
- local.hash(),
1627
- responseBlock.hash()
1628
- ]);
1629
- if (!localHash.equals(respHash)) {
1630
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1631
- return false;
1632
- }
1633
- return true;
1634
- } catch (e) {
1635
- this.logger.warn(`Error validating requested block`, e);
1636
- return false;
1637
- }
1638
- }
1639
1687
  async validateRequestedTx(tx, peerId, txValidator, requested) {
1640
1688
  const penalize = (severity)=>this.peerManager.penalizePeer(peerId, severity);
1641
1689
  if (requested && !requested.has(tx.getTxHash().toString())) {
@@ -1776,19 +1824,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1776
1824
  }
1777
1825
  return PeerErrorSeverity.HighToleranceError;
1778
1826
  }
1779
- /**
1780
- * Validate a checkpoint attestation.
1781
- *
1782
- * @param attestation - The checkpoint attestation to validate.
1783
- * @returns True if the checkpoint attestation is valid, false otherwise.
1784
- */ async validateCheckpointAttestation(peerId, attestation) {
1785
- const result = await this.checkpointAttestationValidator.validate(attestation);
1786
- if (result.result === 'reject') {
1787
- this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1788
- this.peerManager.penalizePeer(peerId, result.severity);
1789
- }
1790
- return result;
1791
- }
1792
1827
  getPeerScore(peerId) {
1793
1828
  return this.node.services.pubsub.score.score(peerId.toString());
1794
1829
  }
@@ -6,6 +6,7 @@ export declare class PeerManagerMetrics {
6
6
  private sentGoodbyes;
7
7
  private receivedGoodbyes;
8
8
  private peerCount;
9
+ private healthyPeerCount;
9
10
  private lowScoreDisconnects;
10
11
  private peerConnectionDuration;
11
12
  private peerConnectedAt;
@@ -14,8 +15,9 @@ export declare class PeerManagerMetrics {
14
15
  recordGoodbyeSent(reason: GoodByeReason): void;
15
16
  recordGoodbyeReceived(reason: GoodByeReason): void;
16
17
  recordPeerCount(count: number): void;
18
+ recordHealthyPeerCount(count: number): void;
17
19
  recordLowScoreDisconnect(scoreState: 'Banned' | 'Disconnect'): void;
18
20
  peerConnected(id: PeerId): void;
19
21
  peerDisconnected(id: PeerId): void;
20
22
  }
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2VzL3BlZXItbWFuYWdlci9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFLTCxLQUFLLGVBQWUsRUFDcEIsS0FBSyxNQUFNLEVBSVosTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVoRCxPQUFPLEVBQUUsYUFBYSxFQUF1QixNQUFNLCtCQUErQixDQUFDO0FBRW5GLHFCQUFhLGtCQUFrQjthQVlYLGVBQWUsRUFBRSxlQUFlO0lBWGxELE9BQU8sQ0FBQyxZQUFZLENBQWdCO0lBQ3BDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBZ0I7SUFDeEMsT0FBTyxDQUFDLFNBQVMsQ0FBUTtJQUN6QixPQUFPLENBQUMsbUJBQW1CLENBQWdCO0lBQzNDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBWTtJQUUxQyxPQUFPLENBQUMsZUFBZSxDQUFrRDtJQUV6RSxTQUFnQixNQUFNLEVBQUUsTUFBTSxDQUFDO0lBRS9CLFlBQ2tCLGVBQWUsR0FBRSxlQUFzQyxFQUN2RSxJQUFJLFNBQWdCLEVBMEJyQjtJQUVNLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxhQUFhLFFBRTdDO0lBRU0scUJBQXFCLENBQUMsTUFBTSxFQUFFLGFBQWEsUUFFakQ7SUFFTSxlQUFlLENBQUMsS0FBSyxFQUFFLE1BQU0sUUFFbkM7SUFFTSx3QkFBd0IsQ0FBQyxVQUFVLEVBQUUsUUFBUSxHQUFHLFlBQVksUUFFbEU7SUFFTSxhQUFhLENBQUMsRUFBRSxFQUFFLE1BQU0sUUFFOUI7SUFFTSxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsTUFBTSxRQUtqQztDQUNGIn0=
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2VzL3BlZXItbWFuYWdlci9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFLTCxLQUFLLGVBQWUsRUFDcEIsS0FBSyxNQUFNLEVBSVosTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVoRCxPQUFPLEVBQUUsYUFBYSxFQUF1QixNQUFNLCtCQUErQixDQUFDO0FBRW5GLHFCQUFhLGtCQUFrQjthQWFYLGVBQWUsRUFBRSxlQUFlO0lBWmxELE9BQU8sQ0FBQyxZQUFZLENBQWdCO0lBQ3BDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBZ0I7SUFDeEMsT0FBTyxDQUFDLFNBQVMsQ0FBUTtJQUN6QixPQUFPLENBQUMsZ0JBQWdCLENBQVE7SUFDaEMsT0FBTyxDQUFDLG1CQUFtQixDQUFnQjtJQUMzQyxPQUFPLENBQUMsc0JBQXNCLENBQVk7SUFFMUMsT0FBTyxDQUFDLGVBQWUsQ0FBa0Q7SUFFekUsU0FBZ0IsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUUvQixZQUNrQixlQUFlLEdBQUUsZUFBc0MsRUFDdkUsSUFBSSxTQUFnQixFQTJCckI7SUFFTSxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsYUFBYSxRQUU3QztJQUVNLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxhQUFhLFFBRWpEO0lBRU0sZUFBZSxDQUFDLEtBQUssRUFBRSxNQUFNLFFBRW5DO0lBRU0sc0JBQXNCLENBQUMsS0FBSyxFQUFFLE1BQU0sUUFFMUM7SUFFTSx3QkFBd0IsQ0FBQyxVQUFVLEVBQUUsUUFBUSxHQUFHLFlBQVksUUFFbEU7SUFFTSxhQUFhLENBQUMsRUFBRSxFQUFFLE1BQU0sUUFFOUI7SUFFTSxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsTUFBTSxRQU1qQztDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,MAAM,EAIZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAuB,MAAM,+BAA+B,CAAC;AAEnF,qBAAa,kBAAkB;aAYX,eAAe,EAAE,eAAe;IAXlD,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,sBAAsB,CAAY;IAE1C,OAAO,CAAC,eAAe,CAAkD;IAEzE,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,YACkB,eAAe,GAAE,eAAsC,EACvE,IAAI,SAAgB,EA0BrB;IAEM,iBAAiB,CAAC,MAAM,EAAE,aAAa,QAE7C;IAEM,qBAAqB,CAAC,MAAM,EAAE,aAAa,QAEjD;IAEM,eAAe,CAAC,KAAK,EAAE,MAAM,QAEnC;IAEM,wBAAwB,CAAC,UAAU,EAAE,QAAQ,GAAG,YAAY,QAElE;IAEM,aAAa,CAAC,EAAE,EAAE,MAAM,QAE9B;IAEM,gBAAgB,CAAC,EAAE,EAAE,MAAM,QAKjC;CACF"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,MAAM,EAIZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAuB,MAAM,+BAA+B,CAAC;AAEnF,qBAAa,kBAAkB;aAaX,eAAe,EAAE,eAAe;IAZlD,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,sBAAsB,CAAY;IAE1C,OAAO,CAAC,eAAe,CAAkD;IAEzE,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,YACkB,eAAe,GAAE,eAAsC,EACvE,IAAI,SAAgB,EA2BrB;IAEM,iBAAiB,CAAC,MAAM,EAAE,aAAa,QAE7C;IAEM,qBAAqB,CAAC,MAAM,EAAE,aAAa,QAEjD;IAEM,eAAe,CAAC,KAAK,EAAE,MAAM,QAEnC;IAEM,sBAAsB,CAAC,KAAK,EAAE,MAAM,QAE1C;IAEM,wBAAwB,CAAC,UAAU,EAAE,QAAQ,GAAG,YAAY,QAElE;IAEM,aAAa,CAAC,EAAE,EAAE,MAAM,QAE9B;IAEM,gBAAgB,CAAC,EAAE,EAAE,MAAM,QAMjC;CACF"}
@@ -5,6 +5,7 @@ export class PeerManagerMetrics {
5
5
  sentGoodbyes;
6
6
  receivedGoodbyes;
7
7
  peerCount;
8
+ healthyPeerCount;
8
9
  lowScoreDisconnects;
9
10
  peerConnectionDuration;
10
11
  peerConnectedAt;
@@ -27,6 +28,7 @@ export class PeerManagerMetrics {
27
28
  this.sentGoodbyes = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_GOODBYES_SENT, goodbyeReasonAttrs);
28
29
  this.receivedGoodbyes = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_GOODBYES_RECEIVED, goodbyeReasonAttrs);
29
30
  this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT);
31
+ this.healthyPeerCount = meter.createGauge(Metrics.PEER_MANAGER_HEALTHY_PEER_COUNT);
30
32
  this.lowScoreDisconnects = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_LOW_SCORE_DISCONNECTS, {
31
33
  [Attributes.P2P_PEER_SCORE_STATE]: [
32
34
  'Banned',
@@ -48,6 +50,9 @@ export class PeerManagerMetrics {
48
50
  recordPeerCount(count) {
49
51
  this.peerCount.record(count);
50
52
  }
53
+ recordHealthyPeerCount(count) {
54
+ this.healthyPeerCount.record(count);
55
+ }
51
56
  recordLowScoreDisconnect(scoreState) {
52
57
  this.lowScoreDisconnects.add(1, {
53
58
  [Attributes.P2P_PEER_SCORE_STATE]: scoreState
@@ -60,6 +65,7 @@ export class PeerManagerMetrics {
60
65
  const connectedAt = this.peerConnectedAt.get(id.toString());
61
66
  if (connectedAt) {
62
67
  this.peerConnectionDuration.record(Date.now() - connectedAt);
68
+ this.peerConnectedAt.delete(id.toString());
63
69
  }
64
70
  }
65
71
  }
@@ -53,11 +53,15 @@ export declare class PeerManager implements PeerManagerInterface {
53
53
  heartbeat(): Promise<void>;
54
54
  setupDirectPeersIfValidator(): Promise<void>;
55
55
  /**
56
- * Cleans up expired timeouts.
56
+ * Cleans up expired timeouts and stale failed-auth-handshake entries.
57
57
  *
58
58
  * When peers fail to dial after a number of retries, they are temporarily timed out.
59
59
  * This function removes any peers that have been in the timed out state for too long.
60
60
  * To give them a chance to reconnect.
61
+ *
62
+ * Also evicts entries from the failed-auth-handshake map whose expiry window has passed.
63
+ * Without this, peers that probe once and never reconnect would leave their entries in the
64
+ * map forever, causing an unbounded memory leak.
61
65
  */
62
66
  private cleanupExpiredTimeouts;
63
67
  private processScheduledDisconnects;
@@ -171,4 +175,4 @@ export declare class PeerManager implements PeerManagerInterface {
171
175
  handleAuthRequestFromPeer(_authRequest: AuthRequest, peerId: PeerId): Promise<StatusMessage>;
172
176
  private updateAuthenticatedPeers;
173
177
  }
174
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvcGVlci1tYW5hZ2VyL3BlZXJfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRzlELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBR2hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RixPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRS9ELE9BQU8sS0FBSyxFQUFjLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBTTVELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRCxPQUFPLEVBQUUsV0FBVyxFQUFnQixNQUFNLDhCQUE4QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxhQUFhLEVBQXVCLE1BQU0saUNBQWlDLENBQUM7QUFDckYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0QsT0FBTyxFQUFrQixLQUFLLFdBQVcsRUFBRSxNQUFNLG1C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
178
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvcGVlci1tYW5hZ2VyL3BlZXJfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRzlELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBR2hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RixPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRS9ELE9BQU8sS0FBSyxFQUFjLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBTTVELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRCxPQUFPLEVBQUUsV0FBVyxFQUFnQixNQUFNLDhCQUE4QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxhQUFhLEVBQXVCLE1BQU0saUNBQWlDLENBQUM7QUFDckYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0QsT0FBTyxFQUFrQixLQUFLLFdBQVcsRUFBRSxNQUFNLG1C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