@aztec/p2p 0.0.1-commit.5de5ca79e → 0.0.1-commit.6201a7b05

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 (257) hide show
  1. package/dest/client/factory.d.ts +3 -2
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +22 -20
  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 -10
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +20 -7
  10. package/dest/config.d.ts +106 -99
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +16 -7
  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 +4 -2
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/attestation_pool.js +8 -5
  22. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  23. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  24. package/dest/mem_pools/attestation_pool/mocks.js +6 -4
  25. package/dest/mem_pools/index.d.ts +1 -2
  26. package/dest/mem_pools/index.d.ts.map +1 -1
  27. package/dest/mem_pools/instrumentation.d.ts +1 -1
  28. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  29. package/dest/mem_pools/instrumentation.js +17 -1
  30. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  31. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  32. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  33. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  34. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  35. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  36. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  37. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +4 -1
  38. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  39. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -2
  40. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
  42. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
  43. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +2 -1
  45. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
  46. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  47. package/dest/msg_validators/attestation_validator/attestation_validator.js +34 -10
  48. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  49. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  50. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  51. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  52. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  53. package/dest/msg_validators/clock_tolerance.js +57 -0
  54. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +4 -2
  55. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  56. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +4 -2
  57. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  58. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +6 -2
  59. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  60. package/dest/msg_validators/proposal_validator/proposal_validator.js +32 -9
  61. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  62. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  63. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  64. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  65. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  66. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  67. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  68. package/dest/msg_validators/tx_validator/factory.d.ts +2 -2
  69. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  70. package/dest/msg_validators/tx_validator/factory.js +11 -5
  71. package/dest/msg_validators/tx_validator/gas_validator.d.ts +36 -4
  72. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  73. package/dest/msg_validators/tx_validator/gas_validator.js +50 -33
  74. package/dest/msg_validators/tx_validator/phases_validator.js +1 -1
  75. package/dest/services/data_store.d.ts +1 -1
  76. package/dest/services/data_store.d.ts.map +1 -1
  77. package/dest/services/data_store.js +5 -5
  78. package/dest/services/dummy_service.d.ts +6 -3
  79. package/dest/services/dummy_service.d.ts.map +1 -1
  80. package/dest/services/dummy_service.js +6 -1
  81. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  82. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  83. package/dest/services/gossipsub/topic_score_params.js +21 -4
  84. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  85. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  86. package/dest/services/libp2p/instrumentation.js +14 -0
  87. package/dest/services/libp2p/libp2p_service.d.ts +20 -21
  88. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  89. package/dest/services/libp2p/libp2p_service.js +151 -110
  90. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  91. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  92. package/dest/services/peer-manager/peer_manager.js +33 -8
  93. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  94. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  95. package/dest/services/peer-manager/peer_scoring.js +32 -10
  96. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -1
  97. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  98. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +3 -0
  99. package/dest/services/reqresp/config.d.ts +3 -3
  100. package/dest/services/reqresp/config.d.ts.map +1 -1
  101. package/dest/services/reqresp/interface.d.ts +14 -9
  102. package/dest/services/reqresp/interface.d.ts.map +1 -1
  103. package/dest/services/reqresp/interface.js +10 -11
  104. package/dest/services/reqresp/metrics.d.ts +1 -1
  105. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  106. package/dest/services/reqresp/metrics.js +0 -1
  107. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  108. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  109. package/dest/services/reqresp/protocols/index.js +0 -1
  110. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  111. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  112. package/dest/services/reqresp/protocols/tx.js +1 -3
  113. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  114. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  115. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  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 +11 -2
  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/file_store_tx_source.d.ts +5 -4
  125. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  126. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  127. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  128. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  129. package/dest/services/tx_collection/tx_source.js +9 -7
  130. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  131. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  132. package/dest/test-helpers/make-test-p2p-clients.js +4 -1
  133. package/dest/test-helpers/mock-pubsub.d.ts +11 -3
  134. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  135. package/dest/test-helpers/mock-pubsub.js +36 -11
  136. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  137. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  138. package/dest/test-helpers/reqresp-nodes.js +5 -3
  139. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  140. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  141. package/dest/test-helpers/testbench-utils.js +1 -0
  142. package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
  143. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  144. package/dest/testbench/p2p_client_testbench_worker.js +72 -17
  145. package/dest/testbench/worker_client_manager.d.ts +8 -1
  146. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  147. package/dest/testbench/worker_client_manager.js +49 -1
  148. package/package.json +14 -14
  149. package/src/client/factory.ts +31 -21
  150. package/src/client/interface.ts +9 -1
  151. package/src/client/p2p_client.ts +34 -11
  152. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -6
  153. package/src/config.ts +27 -7
  154. package/src/errors/p2p-service.error.ts +11 -0
  155. package/src/index.ts +0 -1
  156. package/src/mem_pools/attestation_pool/attestation_pool.ts +9 -5
  157. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  158. package/src/mem_pools/index.ts +0 -3
  159. package/src/mem_pools/instrumentation.ts +5 -1
  160. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  161. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  162. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  163. package/src/mem_pools/tx_pool_v2/interfaces.ts +3 -0
  164. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +20 -8
  165. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +2 -0
  166. package/src/msg_validators/attestation_validator/attestation_validator.ts +38 -7
  167. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +12 -2
  168. package/src/msg_validators/clock_tolerance.ts +75 -0
  169. package/src/msg_validators/proposal_validator/README.md +1 -1
  170. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -2
  171. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +15 -2
  172. package/src/msg_validators/proposal_validator/proposal_validator.ts +33 -7
  173. package/src/msg_validators/tx_validator/README.md +11 -3
  174. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  175. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  176. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  177. package/src/msg_validators/tx_validator/factory.ts +10 -1
  178. package/src/msg_validators/tx_validator/gas_validator.ts +82 -33
  179. package/src/msg_validators/tx_validator/phases_validator.ts +1 -1
  180. package/src/services/data_store.ts +5 -13
  181. package/src/services/dummy_service.ts +8 -2
  182. package/src/services/gossipsub/topic_score_params.ts +36 -4
  183. package/src/services/libp2p/instrumentation.ts +14 -0
  184. package/src/services/libp2p/libp2p_service.ts +155 -117
  185. package/src/services/peer-manager/peer_manager.ts +38 -8
  186. package/src/services/peer-manager/peer_scoring.ts +27 -5
  187. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +3 -0
  188. package/src/services/reqresp/config.ts +2 -2
  189. package/src/services/reqresp/interface.ts +21 -11
  190. package/src/services/reqresp/metrics.ts +0 -1
  191. package/src/services/reqresp/protocols/index.ts +0 -1
  192. package/src/services/reqresp/protocols/tx.ts +1 -3
  193. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  194. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  195. package/src/services/reqresp/reqresp.ts +18 -1
  196. package/src/services/service.ts +6 -1
  197. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  198. package/src/services/tx_collection/tx_source.ts +8 -7
  199. package/src/test-helpers/make-test-p2p-clients.ts +2 -0
  200. package/src/test-helpers/mock-pubsub.ts +34 -5
  201. package/src/test-helpers/reqresp-nodes.ts +4 -2
  202. package/src/test-helpers/testbench-utils.ts +1 -0
  203. package/src/testbench/p2p_client_testbench_worker.ts +73 -12
  204. package/src/testbench/worker_client_manager.ts +55 -1
  205. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  206. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  207. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  208. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  209. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  210. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  211. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  212. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  213. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  214. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  215. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  216. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  217. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  218. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  219. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  220. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  221. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  222. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  223. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  224. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  225. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  226. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  227. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  228. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  229. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  230. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  231. package/dest/mem_pools/tx_pool/index.js +0 -2
  232. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  233. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  234. package/dest/mem_pools/tx_pool/priority.js +0 -15
  235. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  236. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  237. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  238. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  239. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  240. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  241. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  242. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  243. package/dest/services/reqresp/protocols/block.js +0 -32
  244. package/src/mem_pools/tx_pool/README.md +0 -270
  245. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  246. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  247. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  248. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  249. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  250. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  251. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  252. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  253. package/src/mem_pools/tx_pool/index.ts +0 -2
  254. package/src/mem_pools/tx_pool/priority.ts +0 -20
  255. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  256. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  257. package/src/services/reqresp/protocols/block.ts +0 -37
@@ -1,15 +1,14 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
- import { maxBy } from '@aztec/foundation/collection';
4
- import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import { maxBy, merge } from '@aztec/foundation/collection';
5
4
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
6
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
7
6
  import { Timer } from '@aztec/foundation/timer';
8
7
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
9
8
  import { protocolContractsHash } from '@aztec/protocol-contracts';
10
- import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
9
+ import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
11
10
  import type { ContractDataSource } from '@aztec/stdlib/contract';
12
- import { GasFees } from '@aztec/stdlib/gas';
11
+ import { type BlockMinFeesProvider, GasFees } from '@aztec/stdlib/gas';
13
12
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
14
13
  import {
15
14
  BlockProposal,
@@ -58,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
58
57
  import { createLibp2p } from 'libp2p';
59
58
 
60
59
  import type { P2PConfig } from '../../config.js';
60
+ import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
61
61
  import type { MemPools } from '../../mem_pools/interface.js';
62
62
  import {
63
63
  BlockProposalValidator,
@@ -104,7 +104,6 @@ import {
104
104
  ValidationError,
105
105
  pingHandler,
106
106
  reqGoodbyeHandler,
107
- reqRespBlockHandler,
108
107
  reqRespBlockTxsHandler,
109
108
  reqRespStatusHandler,
110
109
  reqRespTxHandler,
@@ -130,7 +129,7 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
130
129
  // REFACTOR: Unify with the type above
131
130
  type ReceivedMessageValidationResult<T, M = undefined> =
132
131
  | { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
133
- | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
132
+ | { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
134
133
 
135
134
  /**
136
135
  * Lib P2P implementation of the P2PService interface.
@@ -147,8 +146,6 @@ export class LibP2PService extends WithTracer implements P2PService {
147
146
  private protocolVersion = '';
148
147
  private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
149
148
 
150
- private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
151
-
152
149
  /** Callback invoked when a duplicate proposal is detected (triggers slashing). */
153
150
  private duplicateProposalCallback?: (info: {
154
151
  slot: SlotNumber;
@@ -171,7 +168,13 @@ export class LibP2PService extends WithTracer implements P2PService {
171
168
  * @param checkpoint - The checkpoint proposal received from the peer.
172
169
  * @returns The attestations for the checkpoint, if any.
173
170
  */
174
- private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
171
+ private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
172
+ /**
173
+ * Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
174
+ * @param checkpoint - The checkpoint proposal received from the peer.
175
+ * @returns The attestations for the checkpoint, if any.
176
+ */
177
+ private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
175
178
 
176
179
  private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
177
180
 
@@ -192,6 +195,7 @@ export class LibP2PService extends WithTracer implements P2PService {
192
195
  private epochCache: EpochCacheInterface,
193
196
  private proofVerifier: ClientProtocolCircuitVerifier,
194
197
  private worldStateSynchronizer: WorldStateSynchronizer,
198
+ private blockMinFeesProvider: BlockMinFeesProvider,
195
199
  telemetry: TelemetryClient,
196
200
  logger: Logger = createLogger('p2p:libp2p_service'),
197
201
  ) {
@@ -223,15 +227,26 @@ export class LibP2PService extends WithTracer implements P2PService {
223
227
  this.protocolVersion,
224
228
  );
225
229
 
230
+ const p2pPropagationTime = config.attestationPropagationTime;
226
231
  const proposalValidatorOpts = {
227
232
  txsPermitted: !config.disableTransactions,
228
233
  maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
234
+ p2pPropagationTime,
235
+ signatureContext: {
236
+ chainId: config.l1ChainId,
237
+ rollupAddress: config.l1Contracts.rollupAddress,
238
+ },
229
239
  };
230
240
  this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
231
241
  this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
242
+ const attestationValidatorOpts = {
243
+ l1PublishingTime: config.l1PublishingTime,
244
+ p2pPropagationTime,
245
+ signatureContext: proposalValidatorOpts.signatureContext,
246
+ };
232
247
  this.checkpointAttestationValidator = config.fishermanMode
233
- ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
234
- : new CheckpointAttestationValidator(epochCache);
248
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, attestationValidatorOpts)
249
+ : new CheckpointAttestationValidator(epochCache, attestationValidatorOpts);
235
250
 
236
251
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
237
252
 
@@ -243,18 +258,22 @@ export class LibP2PService extends WithTracer implements P2PService {
243
258
  return true;
244
259
  };
245
260
 
246
- this.checkpointReceivedCallback = (
247
- checkpoint: CheckpointProposalCore,
261
+ this.allNodesCheckpointReceivedCallback = (
262
+ _checkpoint: CheckpointProposalCore,
263
+ ): Promise<CheckpointAttestation[] | undefined> => {
264
+ throw new CheckpointProposalReceivedCallbackNotRegisteredError();
265
+ };
266
+
267
+ this.validatorCheckpointReceivedCallback = (
268
+ _checkpoint: CheckpointProposalCore,
248
269
  ): Promise<CheckpointAttestation[] | undefined> => {
249
- this.logger.debug(
250
- `Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
251
- );
252
270
  return Promise.resolve(undefined);
253
271
  };
254
272
  }
255
273
 
256
- public updateConfig(config: Partial<P2PReqRespConfig>) {
274
+ public updateConfig(config: Partial<P2PReqRespConfig & Pick<P2PConfig, 'skipIncomingProposals'>>) {
257
275
  this.reqresp.updateConfig(config);
276
+ this.config = merge(this.config, config);
258
277
  }
259
278
 
260
279
  /**
@@ -273,6 +292,7 @@ export class LibP2PService extends WithTracer implements P2PService {
273
292
  proofVerifier: ClientProtocolCircuitVerifier;
274
293
  worldStateSynchronizer: WorldStateSynchronizer;
275
294
  peerStore: AztecAsyncKVStore;
295
+ blockMinFeesProvider: BlockMinFeesProvider;
276
296
  telemetry: TelemetryClient;
277
297
  logger: Logger;
278
298
  packageVersion: string;
@@ -285,6 +305,7 @@ export class LibP2PService extends WithTracer implements P2PService {
285
305
  mempools,
286
306
  proofVerifier,
287
307
  peerStore,
308
+ blockMinFeesProvider,
288
309
  telemetry,
289
310
  logger,
290
311
  packageVersion,
@@ -338,9 +359,12 @@ export class LibP2PService extends WithTracer implements P2PService {
338
359
  const l1Constants = epochCache.getL1Constants();
339
360
  const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
340
361
  slotDurationMs: l1Constants.slotDuration * 1000,
362
+ ethereumSlotDuration: l1Constants.ethereumSlotDuration,
341
363
  heartbeatIntervalMs: config.gossipsubInterval,
342
364
  targetCommitteeSize: l1Constants.targetCommitteeSize,
343
365
  blockDurationMs: config.blockDurationMs,
366
+ l1PublishingTime: config.l1PublishingTime,
367
+ p2pPropagationTime: config.attestationPropagationTime,
344
368
  expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
345
369
  });
346
370
 
@@ -465,6 +489,9 @@ export class LibP2PService extends WithTracer implements P2PService {
465
489
  epochCache,
466
490
  );
467
491
 
492
+ // Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
493
+ reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
494
+
468
495
  // Configure application-specific scoring for gossipsub.
469
496
  // The weight scales app score to align with gossipsub thresholds:
470
497
  // - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
@@ -485,6 +512,7 @@ export class LibP2PService extends WithTracer implements P2PService {
485
512
  epochCache,
486
513
  proofVerifier,
487
514
  worldStateSynchronizer,
515
+ blockMinFeesProvider,
488
516
  telemetry,
489
517
  logger,
490
518
  );
@@ -510,14 +538,12 @@ export class LibP2PService extends WithTracer implements P2PService {
510
538
  // Create request response protocol handlers
511
539
  const txHandler = reqRespTxHandler(this.mempools);
512
540
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
513
- const blockHandler = reqRespBlockHandler(this.archiver);
514
541
  const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
515
542
 
516
543
  const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
517
544
  [ReqRespSubProtocol.PING]: pingHandler,
518
545
  [ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
519
546
  [ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
520
- [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
521
547
  };
522
548
 
523
549
  if (!this.config.disableTransactions) {
@@ -538,7 +564,6 @@ export class LibP2PService extends WithTracer implements P2PService {
538
564
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
539
565
  [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
540
566
  [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
541
- [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
542
567
  };
543
568
 
544
569
  await this.peerManager.initializePeers();
@@ -666,8 +691,16 @@ export class LibP2PService extends WithTracer implements P2PService {
666
691
  this.blockReceivedCallback = callback;
667
692
  }
668
693
 
669
- public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
670
- this.checkpointReceivedCallback = callback;
694
+ public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
695
+ this.validatorCheckpointReceivedCallback = callback;
696
+ }
697
+
698
+ public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
699
+ this.allNodesCheckpointReceivedCallback = callback;
700
+ }
701
+
702
+ public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
703
+ await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
671
704
  }
672
705
 
673
706
  /**
@@ -817,6 +850,15 @@ export class LibP2PService extends WithTracer implements P2PService {
817
850
 
818
851
  // Process the message, optionally within a linked span for trace propagation
819
852
  const processMessage = async () => {
853
+ if (
854
+ this.config.skipIncomingProposals &&
855
+ (msg.topic === this.topicStrings[TopicType.block_proposal] ||
856
+ msg.topic === this.topicStrings[TopicType.checkpoint_proposal])
857
+ ) {
858
+ this.logger.warn(`Ignoring incoming proposal (skipIncomingProposals is set)`, { topic: msg.topic });
859
+ this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
860
+ return;
861
+ }
820
862
  if (msg.topic === this.topicStrings[TopicType.tx]) {
821
863
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
822
864
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
@@ -882,30 +924,67 @@ export class LibP2PService extends WithTracer implements P2PService {
882
924
  source: PeerId,
883
925
  topicType: TopicType,
884
926
  ): Promise<ReceivedMessageValidationResult<T, M>> {
885
- let resultAndObj: ReceivedMessageValidationResult<T, M> = { result: TopicValidatorResult.Reject };
927
+ // Default to reject result with a penalty if validation function throws an error
928
+ let resultAndObj: ReceivedMessageValidationResult<T, M> = {
929
+ result: TopicValidatorResult.Reject,
930
+ severity: PeerErrorSeverity.MidToleranceError,
931
+ };
886
932
  const timer = new Timer();
887
933
  try {
888
934
  resultAndObj = await validationFunc();
889
935
  } catch (err) {
890
- this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
891
- this.logger.error(`Error deserializing and validating gossipsub message`, err, {
892
- msgId,
893
- source: source.toString(),
894
- topicType,
895
- });
936
+ this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
937
+ }
938
+
939
+ const validationTimeMs = timer.ms();
940
+ const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
941
+ if (validationTimeMs > mcacheWindowMs * 0.75) {
942
+ this.instrumentation.incSlowValidation(topicType);
943
+ this.logger.warn(
944
+ `Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` +
945
+ `Message forwarding may be skipped if validation exceeds the window.`,
946
+ { msgId, source: source.toString(), topicType, validationTimeMs, mcacheWindowMs },
947
+ );
896
948
  }
897
949
 
898
950
  if (resultAndObj.result === TopicValidatorResult.Accept) {
951
+ this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
899
952
  this.instrumentation.recordMessageValidation(topicType, timer);
953
+ } else if (resultAndObj.result === TopicValidatorResult.Reject) {
954
+ this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
955
+ msgId,
956
+ source: source.toString(),
957
+ topicType,
958
+ severity: resultAndObj.severity,
959
+ });
960
+ this.peerManager.penalizePeer(source, resultAndObj.severity);
961
+ } else {
962
+ this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
900
963
  }
901
964
 
902
965
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
903
966
  return resultAndObj;
904
967
  }
905
968
 
969
+ private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
970
+ try {
971
+ return deserializeFunc();
972
+ } catch (err) {
973
+ this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
974
+ err,
975
+ msgId,
976
+ source: source.toString(),
977
+ });
978
+ return undefined;
979
+ }
980
+ }
981
+
906
982
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
907
983
  const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
908
- const tx = Tx.fromBuffer(payloadData);
984
+ const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
985
+ if (!tx) {
986
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
987
+ }
909
988
 
910
989
  const currentBlockNumber = await this.archiver.getBlockNumber();
911
990
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
@@ -930,8 +1009,7 @@ export class LibP2PService extends WithTracer implements P2PService {
930
1009
  severity,
931
1010
  source: source.toString(),
932
1011
  });
933
- this.peerManager.penalizePeer(source, severity);
934
- return { result: TopicValidatorResult.Reject };
1012
+ return { result: TopicValidatorResult.Reject, severity };
935
1013
  }
936
1014
 
937
1015
  // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
@@ -953,8 +1031,7 @@ export class LibP2PService extends WithTracer implements P2PService {
953
1031
  severity,
954
1032
  source: source.toString(),
955
1033
  });
956
- this.peerManager.penalizePeer(source, severity);
957
- return { result: TopicValidatorResult.Reject };
1034
+ return { result: TopicValidatorResult.Reject, severity };
958
1035
  }
959
1036
 
960
1037
  // Pool add: persist the tx
@@ -979,8 +1056,7 @@ export class LibP2PService extends WithTracer implements P2PService {
979
1056
  source: source.toString(),
980
1057
  txHash: txHash.toString(),
981
1058
  });
982
- this.peerManager.penalizePeer(source, PeerErrorSeverity.HighToleranceError);
983
- return { result: TopicValidatorResult.Reject };
1059
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
984
1060
  }
985
1061
  };
986
1062
 
@@ -1010,7 +1086,16 @@ export class LibP2PService extends WithTracer implements P2PService {
1010
1086
  source: PeerId,
1011
1087
  ): Promise<void> {
1012
1088
  const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
1013
- () => this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)),
1089
+ () => {
1090
+ const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
1091
+ if (!attestation) {
1092
+ return Promise.resolve({
1093
+ result: TopicValidatorResult.Reject,
1094
+ severity: PeerErrorSeverity.LowToleranceError,
1095
+ });
1096
+ }
1097
+ return this.validateAndStoreCheckpointAttestation(source, attestation);
1098
+ },
1014
1099
  msgId,
1015
1100
  source,
1016
1101
  TopicType.checkpoint_attestation,
@@ -1043,8 +1128,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1043
1128
 
1044
1129
  if (validationResult.result === 'reject') {
1045
1130
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1046
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1047
- return { result: TopicValidatorResult.Reject };
1131
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1048
1132
  }
1049
1133
 
1050
1134
  if (validationResult.result === 'ignore') {
@@ -1070,16 +1154,16 @@ export class LibP2PService extends WithTracer implements P2PService {
1070
1154
  return { result: TopicValidatorResult.Ignore, obj: attestation };
1071
1155
  }
1072
1156
 
1073
- // Could not add (cap reached for signer), no need to re-broadcast
1157
+ // Could not add (cap reached for signer), penalize and do not re-broadcast
1074
1158
  if (!added) {
1075
- this.logger.warn(`Dropping checkpoint attestation due to cap`, {
1159
+ this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
1076
1160
  slot: slot.toString(),
1077
1161
  archive: attestation.archive.toString(),
1078
1162
  source: peerId.toString(),
1079
1163
  attester: attestation.getSender()?.toString(),
1080
1164
  count,
1081
1165
  });
1082
- return { result: TopicValidatorResult.Ignore, obj: attestation };
1166
+ return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
1083
1167
  }
1084
1168
 
1085
1169
  // Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
@@ -1134,8 +1218,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1134
1218
 
1135
1219
  if (validationResult.result === 'reject') {
1136
1220
  this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
1137
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1138
- return { result: TopicValidatorResult.Reject };
1221
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1139
1222
  }
1140
1223
 
1141
1224
  if (validationResult.result === 'ignore') {
@@ -1159,7 +1242,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1159
1242
 
1160
1243
  // Too many blocks received for this slot and index, penalize peer and do not re-broadcast
1161
1244
  if (!added) {
1162
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1163
1245
  this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
1164
1246
  ...block.toBlockInfo(),
1165
1247
  indexWithinCheckpoint: block.indexWithinCheckpoint,
@@ -1167,7 +1249,11 @@ export class LibP2PService extends WithTracer implements P2PService {
1167
1249
  proposer: block.getSender()?.toString(),
1168
1250
  source: peerId.toString(),
1169
1251
  });
1170
- return { result: TopicValidatorResult.Reject, metadata: { isEquivocated } };
1252
+ return {
1253
+ result: TopicValidatorResult.Reject,
1254
+ metadata: { isEquivocated },
1255
+ severity: PeerErrorSeverity.HighToleranceError,
1256
+ };
1171
1257
  }
1172
1258
 
1173
1259
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1260,8 +1346,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1260
1346
 
1261
1347
  if (validationResult.result === 'reject') {
1262
1348
  this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1263
- this.peerManager.penalizePeer(peerId, validationResult.severity);
1264
- return { result: TopicValidatorResult.Reject };
1349
+ return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
1265
1350
  }
1266
1351
 
1267
1352
  if (validationResult.result === 'ignore') {
@@ -1276,20 +1361,21 @@ export class LibP2PService extends WithTracer implements P2PService {
1276
1361
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1277
1362
  [Attributes.P2P_ID]: peerId.toString(),
1278
1363
  });
1279
- const {
1280
- result,
1281
- obj,
1282
- metadata: { isEquivocated } = {},
1283
- } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1284
- if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1364
+ const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
1365
+ const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
1366
+ if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
1285
1367
  this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
1286
1368
  [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1287
1369
  [Attributes.P2P_ID]: peerId.toString(),
1288
1370
  isEquivocated,
1289
- result,
1371
+ result: blockProposalResult.result,
1290
1372
  });
1291
- return { result: TopicValidatorResult.Reject };
1292
- } else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1373
+ return {
1374
+ result: TopicValidatorResult.Reject,
1375
+ severity:
1376
+ 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
1377
+ };
1378
+ } else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
1293
1379
  processBlock = true;
1294
1380
  }
1295
1381
  }
@@ -1316,13 +1402,17 @@ export class LibP2PService extends WithTracer implements P2PService {
1316
1402
  // Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
1317
1403
  // Note: We still return the checkpoint obj so the lastBlock can be processed if valid
1318
1404
  if (!added) {
1319
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
1320
1405
  this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1321
1406
  ...checkpoint.toCheckpointInfo(),
1322
1407
  count,
1323
1408
  source: peerId.toString(),
1324
1409
  });
1325
- return { result: TopicValidatorResult.Reject, obj: checkpoint, metadata: { isEquivocated, processBlock } };
1410
+ return {
1411
+ result: TopicValidatorResult.Reject,
1412
+ obj: checkpoint,
1413
+ metadata: { isEquivocated, processBlock },
1414
+ severity: PeerErrorSeverity.HighToleranceError,
1415
+ };
1326
1416
  }
1327
1417
 
1328
1418
  // If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
@@ -1367,9 +1457,11 @@ export class LibP2PService extends WithTracer implements P2PService {
1367
1457
  source: sender.toString(),
1368
1458
  });
1369
1459
 
1460
+ await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
1461
+
1370
1462
  // Call the checkpoint received callback with the core version (without lastBlock)
1371
1463
  // to validate and potentially generate attestations
1372
- const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
1464
+ const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
1373
1465
  if (attestations && attestations.length > 0) {
1374
1466
  // If the callback returned attestations, add them to the pool and propagate them
1375
1467
  await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
@@ -1517,53 +1609,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1517
1609
  }
1518
1610
  }
1519
1611
 
1520
- /**
1521
- * Validates a BLOCK response.
1522
- *
1523
- * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1524
- * Penalizes on block number mismatch or hash mismatch.
1525
- *
1526
- * @param requestedBlockNumber - The requested block number.
1527
- * @param responseBlock - The block returned by the peer.
1528
- * @param peerId - The peer that returned the block.
1529
- * @returns True if the response is valid, false otherwise.
1530
- */
1531
- @trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
1532
- [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
1533
- }))
1534
- protected async validateRequestedBlock(
1535
- requestedBlockNumber: Fr,
1536
- responseBlock: L2Block,
1537
- peerId: PeerId,
1538
- ): Promise<boolean> {
1539
- try {
1540
- const reqNum = Number(requestedBlockNumber.toString());
1541
- if (responseBlock.number !== reqNum) {
1542
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1543
- return false;
1544
- }
1545
-
1546
- const local = await this.archiver.getBlock(BlockNumber(reqNum));
1547
- if (!local) {
1548
- // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1549
- // TODO: Consider extending this validator to accept an expected hash or
1550
- // performing quorum-based checks when using P2P syncing prior to L1 sync.
1551
- this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1552
- return false;
1553
- }
1554
- const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
1555
- if (!localHash.equals(respHash)) {
1556
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1557
- return false;
1558
- }
1559
-
1560
- return true;
1561
- } catch (e) {
1562
- this.logger.warn(`Error validating requested block`, e);
1563
- return false;
1564
- }
1565
- }
1566
-
1567
1612
  protected async validateRequestedTx(
1568
1613
  tx: Tx,
1569
1614
  peerId: PeerId,
@@ -1590,15 +1635,8 @@ export class LibP2PService extends WithTracer implements P2PService {
1590
1635
  });
1591
1636
  }
1592
1637
 
1593
- private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
1594
- if (blockNumber === this.feesCache?.blockNumber) {
1595
- return this.feesCache.gasFees;
1596
- }
1597
-
1598
- const header = await this.archiver.getBlockHeader(blockNumber);
1599
- const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
1600
- this.feesCache = { blockNumber, gasFees };
1601
- return gasFees;
1638
+ private getGasFees(): Promise<GasFees> {
1639
+ return this.blockMinFeesProvider.getCurrentMinFees();
1602
1640
  }
1603
1641
 
1604
1642
  /**
@@ -1640,7 +1678,7 @@ export class LibP2PService extends WithTracer implements P2PService {
1640
1678
  currentBlockNumber: BlockNumber,
1641
1679
  nextSlotTimestamp: UInt64,
1642
1680
  ): Promise<Record<string, TransactionValidator>> {
1643
- const gasFees = await this.getGasFees(currentBlockNumber);
1681
+ const gasFees = await this.getGasFees();
1644
1682
  const allowedInSetup = [
1645
1683
  ...(await getDefaultAllowedSetupFunctions()),
1646
1684
  ...(this.config.txPublicSetupAllowListExtend ?? []),
@@ -226,20 +226,30 @@ export class PeerManager implements PeerManagerInterface {
226
226
  }
227
227
 
228
228
  /**
229
- * Cleans up expired timeouts.
229
+ * Cleans up expired timeouts and stale failed-auth-handshake entries.
230
230
  *
231
231
  * When peers fail to dial after a number of retries, they are temporarily timed out.
232
232
  * This function removes any peers that have been in the timed out state for too long.
233
233
  * To give them a chance to reconnect.
234
+ *
235
+ * Also evicts entries from the failed-auth-handshake map whose expiry window has passed.
236
+ * Without this, peers that probe once and never reconnect would leave their entries in the
237
+ * map forever, causing an unbounded memory leak.
234
238
  */
235
239
  private cleanupExpiredTimeouts() {
236
- // Clean up expired timeouts
237
240
  const now = this.dateProvider.now();
241
+
238
242
  for (const [peerId, timedOutPeer] of this.timedOutPeers.entries()) {
239
243
  if (now >= timedOutPeer.timeoutUntilMs) {
240
244
  this.timedOutPeers.delete(peerId);
241
245
  }
242
246
  }
247
+
248
+ for (const [id, entry] of this.failedAuthHandshakes.entries()) {
249
+ if (now - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
250
+ this.failedAuthHandshakes.delete(id);
251
+ }
252
+ }
243
253
  }
244
254
 
245
255
  /**
@@ -303,15 +313,20 @@ export class PeerManager implements PeerManagerInterface {
303
313
  */
304
314
  private handleDisconnectedPeerEvent(e: CustomEvent<PeerId>) {
305
315
  const peerId = e.detail;
316
+ const peerIdStr = peerId.toString();
306
317
  this.metrics.peerDisconnected(peerId);
307
- this.logger.verbose(`Disconnected from peer ${peerId.toString()}`);
308
- const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerId.toString());
318
+ this.logger.verbose(`Disconnected from peer ${peerIdStr}`);
319
+ const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerIdStr);
309
320
  if (validatorAddress !== undefined) {
310
321
  this.logger.info(
311
- `Removing authentication for validator ${validatorAddress} at peer id ${peerId.toString()} due to disconnection`,
322
+ `Removing authentication for validator ${validatorAddress} at peer id ${peerIdStr} due to disconnection`,
312
323
  );
313
324
  this.authenticatedValidatorAddressToPeerId.delete(validatorAddress.toString());
314
- this.authenticatedPeerIdToValidatorAddress.delete(peerId.toString());
325
+ this.authenticatedPeerIdToValidatorAddress.delete(peerIdStr);
326
+ }
327
+
328
+ if (this.peerScoring.getScoreState(peerIdStr) === PeerScoreState.Healthy) {
329
+ this.peerScoring.removePeer(peerIdStr);
315
330
  }
316
331
  }
317
332
 
@@ -713,6 +728,12 @@ export class PeerManager implements PeerManagerInterface {
713
728
  return;
714
729
  }
715
730
 
731
+ // Don't dial peers that have exceeded the auth failure threshold
732
+ if (!this.isNodeAllowedToConnect(peerId)) {
733
+ this.logger.trace(`Skipping peer ${peerId} due to failed auth handshake attempts`);
734
+ return;
735
+ }
736
+
716
737
  const [multiaddrTcp] = await Promise.all([enr.getFullMultiaddr('tcp')]);
717
738
 
718
739
  this.logger.trace(`Handling discovered peer ${peerId} at ${multiaddrTcp?.toString() ?? 'undefined address'}`);
@@ -970,14 +991,14 @@ export class PeerManager implements PeerManagerInterface {
970
991
  const peerIdStr = peerId.toString();
971
992
 
972
993
  const existingEntry = this.failedAuthHandshakes.get(peerIdStr);
994
+ const failureCount = (existingEntry?.count || 0) + 1;
973
995
  this.failedAuthHandshakes.set(peerIdStr, {
974
- count: (existingEntry?.count || 0) + 1,
996
+ count: failureCount,
975
997
  lastFailureTimestamp: now,
976
998
  });
977
999
 
978
1000
  const connections = this.libP2PNode.getConnections(peerId);
979
1001
  connections.forEach(conn => {
980
- // We mark the IP address
981
1002
  const address = conn.remoteAddr.nodeAddress().address;
982
1003
  const existingAddressEntry = this.failedAuthHandshakes.get(address);
983
1004
  this.failedAuthHandshakes.set(address, {
@@ -985,6 +1006,15 @@ export class PeerManager implements PeerManagerInterface {
985
1006
  lastFailureTimestamp: now,
986
1007
  });
987
1008
  });
1009
+
1010
+ // Ban the peer from being re-dialed for a cooldown period (exponential backoff)
1011
+ const banTimeMs = this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS;
1012
+ const backoffMs = banTimeMs * Math.pow(2, Math.min(failureCount - 1, 5));
1013
+ this.timedOutPeers.set(peerIdStr, {
1014
+ peerId: peerIdStr,
1015
+ timeoutUntilMs: now + backoffMs,
1016
+ });
1017
+ this.cachedPeers.delete(peerIdStr);
988
1018
  }
989
1019
 
990
1020
  /*