@aztec/p2p 3.0.0-canary.a9708bd → 3.0.0-devnet.2-patch.1

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 (294) hide show
  1. package/dest/bootstrap/bootstrap.d.ts +1 -1
  2. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  3. package/dest/bootstrap/bootstrap.js +14 -4
  4. package/dest/client/factory.d.ts +2 -1
  5. package/dest/client/factory.d.ts.map +1 -1
  6. package/dest/client/factory.js +8 -3
  7. package/dest/client/index.d.ts +1 -1
  8. package/dest/client/interface.d.ts +8 -6
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +11 -34
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +68 -46
  13. package/dest/config.d.ts +65 -56
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +21 -5
  16. package/dest/enr/generate-enr.d.ts +2 -2
  17. package/dest/enr/generate-enr.d.ts.map +1 -1
  18. package/dest/enr/generate-enr.js +1 -1
  19. package/dest/enr/index.d.ts +1 -1
  20. package/dest/errors/attestation-pool.error.d.ts +7 -0
  21. package/dest/errors/attestation-pool.error.d.ts.map +1 -0
  22. package/dest/errors/attestation-pool.error.js +12 -0
  23. package/dest/errors/reqresp.error.d.ts +1 -1
  24. package/dest/errors/reqresp.error.d.ts.map +1 -1
  25. package/dest/index.d.ts +1 -1
  26. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +43 -6
  27. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +72 -46
  31. package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
  32. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +15 -6
  33. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
  34. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +73 -18
  35. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +13 -6
  36. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  37. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +69 -11
  38. package/dest/mem_pools/attestation_pool/mocks.d.ts +226 -5
  39. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  40. package/dest/mem_pools/attestation_pool/mocks.js +9 -7
  41. package/dest/mem_pools/index.d.ts +1 -1
  42. package/dest/mem_pools/instrumentation.d.ts +3 -1
  43. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  44. package/dest/mem_pools/instrumentation.js +11 -2
  45. package/dest/mem_pools/interface.d.ts +1 -1
  46. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +17 -40
  47. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  48. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +103 -44
  49. package/dest/mem_pools/tx_pool/index.d.ts +1 -1
  50. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +19 -6
  51. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool/memory_tx_pool.js +88 -9
  53. package/dest/mem_pools/tx_pool/priority.d.ts +1 -1
  54. package/dest/mem_pools/tx_pool/tx_pool.d.ts +21 -6
  55. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  56. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  57. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  58. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +132 -7
  59. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -2
  60. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  61. package/dest/msg_validators/attestation_validator/attestation_validator.js +32 -5
  62. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
  63. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
  64. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +67 -0
  65. package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
  66. package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
  67. package/dest/msg_validators/attestation_validator/index.js +1 -0
  68. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +5 -2
  69. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
  70. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +56 -9
  71. package/dest/msg_validators/block_proposal_validator/index.d.ts +1 -1
  72. package/dest/msg_validators/index.d.ts +1 -1
  73. package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +1 -1
  74. package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -1
  75. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
  76. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  77. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
  78. package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
  79. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  80. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
  81. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  82. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  83. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  84. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  85. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +1 -1
  86. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  87. package/dest/msg_validators/tx_validator/double_spend_validator.js +1 -1
  88. package/dest/msg_validators/tx_validator/factory.d.ts +4 -3
  89. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  90. package/dest/msg_validators/tx_validator/factory.js +11 -5
  91. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  92. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  93. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  94. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/index.js +1 -0
  96. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -6
  97. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/metadata_validator.js +6 -24
  99. package/dest/msg_validators/tx_validator/phases_validator.d.ts +1 -1
  100. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  101. package/dest/msg_validators/tx_validator/phases_validator.js +3 -1
  102. package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
  103. package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +13 -0
  105. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -0
  106. package/dest/msg_validators/tx_validator/timestamp_validator.js +32 -0
  107. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +1 -1
  108. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +1 -1
  110. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  111. package/dest/services/data_store.d.ts +1 -1
  112. package/dest/services/data_store.d.ts.map +1 -1
  113. package/dest/services/discv5/discV5_service.d.ts +3 -3
  114. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  115. package/dest/services/discv5/discV5_service.js +2 -2
  116. package/dest/services/dummy_service.d.ts +2 -2
  117. package/dest/services/dummy_service.d.ts.map +1 -1
  118. package/dest/services/encoding.d.ts +25 -4
  119. package/dest/services/encoding.d.ts.map +1 -1
  120. package/dest/services/encoding.js +74 -6
  121. package/dest/services/gossipsub/scoring.d.ts +1 -1
  122. package/dest/services/index.d.ts +1 -1
  123. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  124. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  125. package/dest/services/libp2p/instrumentation.js +9 -2
  126. package/dest/services/libp2p/libp2p_service.d.ts +29 -69
  127. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  128. package/dest/services/libp2p/libp2p_service.js +375 -133
  129. package/dest/services/peer-manager/interface.d.ts +1 -1
  130. package/dest/services/peer-manager/metrics.d.ts +3 -1
  131. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  132. package/dest/services/peer-manager/metrics.js +11 -0
  133. package/dest/services/peer-manager/peer_manager.d.ts +1 -32
  134. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  135. package/dest/services/peer-manager/peer_manager.js +27 -12
  136. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  137. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  138. package/dest/services/peer-manager/peer_scoring.js +40 -2
  139. package/dest/services/reqresp/config.d.ts +1 -1
  140. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +1 -1
  141. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
  142. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -4
  143. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  144. package/dest/services/reqresp/index.d.ts +1 -1
  145. package/dest/services/reqresp/interface.d.ts +2 -11
  146. package/dest/services/reqresp/interface.d.ts.map +1 -1
  147. package/dest/services/reqresp/interface.js +1 -18
  148. package/dest/services/reqresp/metrics.d.ts +1 -1
  149. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  150. package/dest/services/reqresp/protocols/auth.d.ts +2 -2
  151. package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
  152. package/dest/services/reqresp/protocols/auth.js +2 -2
  153. package/dest/services/reqresp/protocols/block.d.ts +1 -1
  154. package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
  155. package/dest/services/reqresp/protocols/block.js +3 -2
  156. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
  157. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  158. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
  159. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +4 -6
  160. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  161. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +1 -1
  162. package/dest/services/reqresp/protocols/block_txs/index.d.ts +1 -1
  163. package/dest/services/reqresp/protocols/goodbye.d.ts +1 -1
  164. package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
  165. package/dest/services/reqresp/protocols/index.d.ts +1 -1
  166. package/dest/services/reqresp/protocols/ping.d.ts +1 -1
  167. package/dest/services/reqresp/protocols/status.d.ts +6 -5
  168. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  169. package/dest/services/reqresp/protocols/status.js +4 -3
  170. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  171. package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
  172. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +2 -2
  173. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  174. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  175. package/dest/services/reqresp/reqresp.d.ts +1 -41
  176. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  177. package/dest/services/reqresp/reqresp.js +14 -10
  178. package/dest/services/reqresp/status.d.ts +2 -2
  179. package/dest/services/reqresp/status.d.ts.map +1 -1
  180. package/dest/services/service.d.ts +2 -2
  181. package/dest/services/service.d.ts.map +1 -1
  182. package/dest/services/tx_collection/config.d.ts +1 -1
  183. package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -9
  184. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  185. package/dest/services/tx_collection/fast_tx_collection.js +6 -1
  186. package/dest/services/tx_collection/index.d.ts +1 -1
  187. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  188. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  189. package/dest/services/tx_collection/slow_tx_collection.d.ts +6 -7
  190. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  191. package/dest/services/tx_collection/slow_tx_collection.js +2 -1
  192. package/dest/services/tx_collection/tx_collection.d.ts +12 -11
  193. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  194. package/dest/services/tx_collection/tx_collection.js +3 -2
  195. package/dest/services/tx_collection/tx_collection_sink.d.ts +3 -3
  196. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  197. package/dest/services/tx_collection/tx_collection_sink.js +34 -4
  198. package/dest/services/tx_collection/tx_source.d.ts +1 -1
  199. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  200. package/dest/services/tx_collection/tx_source.js +2 -2
  201. package/dest/services/tx_provider.d.ts +5 -4
  202. package/dest/services/tx_provider.d.ts.map +1 -1
  203. package/dest/services/tx_provider.js +8 -4
  204. package/dest/services/tx_provider_instrumentation.d.ts +1 -1
  205. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  206. package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
  207. package/dest/test-helpers/get-ports.d.ts +1 -1
  208. package/dest/test-helpers/get-ports.d.ts.map +1 -1
  209. package/dest/test-helpers/index.d.ts +1 -1
  210. package/dest/test-helpers/make-enrs.d.ts +1 -1
  211. package/dest/test-helpers/make-enrs.js +1 -1
  212. package/dest/test-helpers/make-test-p2p-clients.d.ts +2 -2
  213. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  214. package/dest/test-helpers/mock-pubsub.d.ts +4 -4
  215. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  216. package/dest/test-helpers/mock-tx-helpers.d.ts +12 -0
  217. package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -0
  218. package/dest/test-helpers/mock-tx-helpers.js +19 -0
  219. package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
  220. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  221. package/dest/test-helpers/reqresp-nodes.js +4 -3
  222. package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
  223. package/dest/testbench/p2p_client_testbench_worker.js +16 -9
  224. package/dest/testbench/parse_log_file.d.ts +1 -1
  225. package/dest/testbench/testbench.d.ts +1 -1
  226. package/dest/testbench/testbench.js +2 -2
  227. package/dest/testbench/worker_client_manager.d.ts +1 -1
  228. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  229. package/dest/types/index.d.ts +1 -1
  230. package/dest/util.d.ts +2 -1
  231. package/dest/util.d.ts.map +1 -1
  232. package/dest/util.js +11 -2
  233. package/dest/versioning.d.ts +2 -2
  234. package/dest/versioning.d.ts.map +1 -1
  235. package/dest/versioning.js +2 -2
  236. package/package.json +21 -21
  237. package/src/bootstrap/bootstrap.ts +15 -4
  238. package/src/client/factory.ts +17 -3
  239. package/src/client/interface.ts +8 -5
  240. package/src/client/p2p_client.ts +88 -74
  241. package/src/config.ts +33 -6
  242. package/src/enr/generate-enr.ts +1 -1
  243. package/src/errors/attestation-pool.error.ts +13 -0
  244. package/src/mem_pools/attestation_pool/attestation_pool.ts +46 -5
  245. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +89 -48
  246. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +107 -24
  247. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +98 -19
  248. package/src/mem_pools/attestation_pool/mocks.ts +11 -8
  249. package/src/mem_pools/instrumentation.ts +13 -0
  250. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +116 -48
  251. package/src/mem_pools/tx_pool/memory_tx_pool.ts +98 -12
  252. package/src/mem_pools/tx_pool/tx_pool.ts +20 -5
  253. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +115 -7
  254. package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -6
  255. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +91 -0
  256. package/src/msg_validators/attestation_validator/index.ts +1 -0
  257. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +63 -18
  258. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  259. package/src/msg_validators/tx_validator/block_header_validator.ts +2 -2
  260. package/src/msg_validators/tx_validator/double_spend_validator.ts +1 -1
  261. package/src/msg_validators/tx_validator/factory.ts +13 -6
  262. package/src/msg_validators/tx_validator/index.ts +1 -0
  263. package/src/msg_validators/tx_validator/metadata_validator.ts +8 -42
  264. package/src/msg_validators/tx_validator/phases_validator.ts +3 -1
  265. package/src/msg_validators/tx_validator/test_utils.ts +1 -1
  266. package/src/msg_validators/tx_validator/timestamp_validator.ts +47 -0
  267. package/src/services/discv5/discV5_service.ts +2 -2
  268. package/src/services/dummy_service.ts +1 -1
  269. package/src/services/encoding.ts +81 -6
  270. package/src/services/libp2p/instrumentation.ts +10 -1
  271. package/src/services/libp2p/libp2p_service.ts +427 -157
  272. package/src/services/peer-manager/metrics.ts +10 -0
  273. package/src/services/peer-manager/peer_manager.ts +22 -14
  274. package/src/services/peer-manager/peer_scoring.ts +46 -3
  275. package/src/services/reqresp/interface.ts +1 -22
  276. package/src/services/reqresp/protocols/auth.ts +2 -2
  277. package/src/services/reqresp/protocols/block.ts +3 -2
  278. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
  279. package/src/services/reqresp/protocols/status.ts +9 -8
  280. package/src/services/reqresp/reqresp.ts +15 -11
  281. package/src/services/service.ts +1 -1
  282. package/src/services/tx_collection/fast_tx_collection.ts +8 -5
  283. package/src/services/tx_collection/slow_tx_collection.ts +7 -6
  284. package/src/services/tx_collection/tx_collection.ts +12 -10
  285. package/src/services/tx_collection/tx_collection_sink.ts +34 -3
  286. package/src/services/tx_collection/tx_source.ts +2 -2
  287. package/src/services/tx_provider.ts +9 -7
  288. package/src/test-helpers/make-enrs.ts +1 -1
  289. package/src/test-helpers/mock-tx-helpers.ts +24 -0
  290. package/src/test-helpers/reqresp-nodes.ts +3 -2
  291. package/src/testbench/p2p_client_testbench_worker.ts +12 -5
  292. package/src/testbench/testbench.ts +2 -2
  293. package/src/util.ts +12 -2
  294. package/src/versioning.ts +3 -3
@@ -1,12 +1,14 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
- import { randomInt } from '@aztec/foundation/crypto';
2
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { randomInt } from '@aztec/foundation/crypto/random';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
5
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
4
- import { SerialQueue } from '@aztec/foundation/queue';
5
6
  import { RunningPromise } from '@aztec/foundation/running-promise';
6
7
  import { Timer } from '@aztec/foundation/timer';
7
8
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
8
- import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
9
- import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
9
+ import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
10
+ import { protocolContractsHash } from '@aztec/protocol-contracts';
11
+ import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
10
12
  import type { ContractDataSource } from '@aztec/stdlib/contract';
11
13
  import { GasFees } from '@aztec/stdlib/gas';
12
14
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
@@ -23,12 +25,11 @@ import {
23
25
  metricsTopicStrToLabels,
24
26
  } from '@aztec/stdlib/p2p';
25
27
  import { MerkleTreeId } from '@aztec/stdlib/trees';
26
- import { Tx, type TxHash, type TxValidationResult } from '@aztec/stdlib/tx';
28
+ import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
27
29
  import type { UInt64 } from '@aztec/stdlib/types';
28
30
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
29
31
  import { Attributes, OtelMetricsAdapter, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
30
32
 
31
- import { ENR } from '@chainsafe/enr';
32
33
  import {
33
34
  type GossipSub,
34
35
  type GossipSubComponents,
@@ -43,18 +44,29 @@ import { bootstrap } from '@libp2p/bootstrap';
43
44
  import { identify } from '@libp2p/identify';
44
45
  import { type Message, type MultiaddrConnection, type PeerId, TopicValidatorResult } from '@libp2p/interface';
45
46
  import type { ConnectionManager } from '@libp2p/interface-internal';
46
- import '@libp2p/kad-dht';
47
47
  import { mplex } from '@libp2p/mplex';
48
48
  import { tcp } from '@libp2p/tcp';
49
+ import { ENR } from '@nethermindeth/enr';
49
50
  import { createLibp2p } from 'libp2p';
50
51
 
51
52
  import type { P2PConfig } from '../../config.js';
53
+ import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
52
54
  import type { MemPools } from '../../mem_pools/interface.js';
53
- import { AttestationValidator, BlockProposalValidator } from '../../msg_validators/index.js';
55
+ import {
56
+ AttestationValidator,
57
+ BlockProposalValidator,
58
+ FishermanAttestationValidator,
59
+ } from '../../msg_validators/index.js';
54
60
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
55
61
  import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
56
62
  import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
57
- import { DoubleSpendTxValidator, TxProofValidator } from '../../msg_validators/tx_validator/index.js';
63
+ import {
64
+ AggregateTxValidator,
65
+ DataTxValidator,
66
+ DoubleSpendTxValidator,
67
+ MetadataTxValidator,
68
+ TxProofValidator,
69
+ } from '../../msg_validators/tx_validator/index.js';
58
70
  import { GossipSubEvent } from '../../types/index.js';
59
71
  import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
60
72
  import { getVersions } from '../../versioning.js';
@@ -80,6 +92,8 @@ import { reqRespBlockTxsHandler } from '../reqresp/protocols/block_txs/block_txs
80
92
  import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
81
93
  import {
82
94
  AuthRequest,
95
+ BlockTxsRequest,
96
+ BlockTxsResponse,
83
97
  StatusMessage,
84
98
  pingHandler,
85
99
  reqRespBlockHandler,
@@ -98,11 +112,15 @@ interface ValidationResult {
98
112
 
99
113
  type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: ValidationResult };
100
114
 
115
+ // REFACTOR: Unify with the type above
116
+ type ReceivedMessageValidationResult<T> =
117
+ | { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject> }
118
+ | { obj?: undefined; result: TopicValidatorResult.Reject };
119
+
101
120
  /**
102
121
  * Lib P2P implementation of the P2PService interface.
103
122
  */
104
123
  export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
105
- private jobQueue: SerialQueue = new SerialQueue();
106
124
  private discoveryRunningPromise?: RunningPromise;
107
125
  private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
108
126
 
@@ -113,7 +131,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
113
131
  private protocolVersion = '';
114
132
  private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
115
133
 
116
- private feesCache: { blockNumber: number; gasFees: GasFees } | undefined;
134
+ private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
117
135
 
118
136
  /**
119
137
  * Callback for when a block is received from a peer.
@@ -126,6 +144,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
126
144
 
127
145
  private instrumentation: P2PInstrumentation;
128
146
 
147
+ protected logger: Logger;
148
+
129
149
  constructor(
130
150
  private clientType: T,
131
151
  private config: P2PConfig,
@@ -139,10 +159,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
139
159
  private proofVerifier: ClientProtocolCircuitVerifier,
140
160
  private worldStateSynchronizer: WorldStateSynchronizer,
141
161
  telemetry: TelemetryClient,
142
- protected logger = createLogger('p2p:libp2p_service'),
162
+ logger: Logger = createLogger('p2p:libp2p_service'),
143
163
  ) {
144
164
  super(telemetry, 'LibP2PService');
145
165
 
166
+ // Create child logger with fisherman prefix if in fisherman mode
167
+ this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
168
+
146
169
  this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
147
170
 
148
171
  this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
@@ -160,15 +183,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
160
183
  this.protocolVersion,
161
184
  );
162
185
 
163
- this.attestationValidator = new AttestationValidator(epochCache);
164
- this.blockProposalValidator = new BlockProposalValidator(epochCache);
186
+ // Use FishermanAttestationValidator in fisherman mode to validate attestation payloads against proposals
187
+ this.attestationValidator = config.fishermanMode
188
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool!, telemetry)
189
+ : new AttestationValidator(epochCache);
190
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
165
191
 
166
192
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
167
193
 
168
194
  this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation[] | undefined> => {
169
195
  this.logger.debug(
170
- `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber.toNumber()} from peer.`,
171
- { p2pMessageIdentifier: await block.p2pMessageIdentifier() },
196
+ `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
197
+ { p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
172
198
  );
173
199
  return undefined;
174
200
  };
@@ -273,7 +299,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
273
299
  // The connection attempts to the node on TCP layer are not necessarily valid Aztec peers so we want to have a bit of leeway here
274
300
  // If we hit the limit, the connection will be temporarily accepted and immediately dropped.
275
301
  // Docs: https://nodejs.org/api/net.html#servermaxconnections
276
- maxConnections: Math.ceil(maxPeerCount * 1.5),
302
+ maxConnections: maxPeerCount * 2,
277
303
  // socket option: the maximum length of the queue of pending connections
278
304
  // https://nodejs.org/dist/latest-v22.x/docs/api/net.html#serverlisten
279
305
  // it's not safe if we increase this number
@@ -284,7 +310,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
284
310
  // In case closeAbove is reached, the server stops listening altogether
285
311
  // It's important that there is enough difference between closeAbove and listenAbove,
286
312
  // otherwise the server.listener will flap between being closed and open potentially degrading perf even more
287
- closeAbove: maxPeerCount * 2,
313
+ closeAbove: maxPeerCount * 3,
288
314
  listenBelow: Math.floor(maxPeerCount * 0.9),
289
315
  },
290
316
  }),
@@ -294,8 +320,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
294
320
  streamMuxers: [yamux(), mplex()],
295
321
  connectionEncryption: [noise()],
296
322
  connectionManager: {
297
- minConnections: 0,
298
- maxConnections: maxPeerCount,
323
+ minConnections: 0, // Disable libp2p peer dialing, we do it manually
324
+ // We set maxConnections above maxPeerCount because if we hit limit of maxPeerCount
325
+ // libp2p will start aggressively rejecting all new connections, preventing network discovery and crawling.
326
+ maxConnections: maxPeerCount * 2,
299
327
  maxParallelDials: 100,
300
328
  dialTimeout: 30_000,
301
329
  maxPeerAddrsToDial: 5,
@@ -379,7 +407,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
379
407
  logger: createLibp2pComponentLogger(logger.module),
380
408
  });
381
409
 
382
- const peerScoring = new PeerScoring(config);
410
+ const peerScoring = new PeerScoring(config, telemetry);
383
411
  const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
384
412
 
385
413
  const peerManager = new PeerManager(
@@ -434,9 +462,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
434
462
  }
435
463
  const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
436
464
 
437
- // Start job queue, peer discovery service and libp2p node
438
- this.jobQueue.start();
439
-
440
465
  await this.peerManager.initializePeers();
441
466
  if (!this.config.p2pDiscoveryDisabled) {
442
467
  await this.peerDiscoveryService.start();
@@ -453,10 +478,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
453
478
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
454
479
  const blockHandler = reqRespBlockHandler(this.archiver);
455
480
  const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
456
- // In case P2P client doesnt'have attestation pool,
457
- // const blockTxsHandler = this.mempools.attestationPool
458
- // ? reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool)
459
- // : def;
460
481
 
461
482
  const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
462
483
  [ReqRespSubProtocol.PING]: pingHandler,
@@ -466,7 +487,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
466
487
  };
467
488
 
468
489
  // Only handle block transactions request if attestation pool is available to the client
469
- if (this.mempools.attestationPool) {
490
+ if (this.mempools.attestationPool && !this.config.disableTransactions) {
470
491
  const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
471
492
  requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
472
493
  }
@@ -478,9 +499,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
478
499
  // add GossipSub listener
479
500
  this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
480
501
 
481
- // Start running promise for peer discovery
502
+ // Start running promise for peer discovery and metrics collection
482
503
  this.discoveryRunningPromise = new RunningPromise(
483
- () => this.peerManager.heartbeat(),
504
+ async () => {
505
+ await this.peerManager.heartbeat();
506
+ },
484
507
  this.logger,
485
508
  this.config.peerCheckIntervalMS,
486
509
  );
@@ -489,8 +512,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
489
512
  // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
490
513
  const reqrespSubProtocolValidators = {
491
514
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
492
- // TODO(#11336): A request validator for blocks
493
- [ReqRespSubProtocol.TX]: this.validateRequestedTx.bind(this),
515
+ [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
516
+ [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
517
+ [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
494
518
  };
495
519
  await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
496
520
  this.logger.info(`Started P2P service`, {
@@ -512,9 +536,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
512
536
  // Stop peer manager
513
537
  this.logger.debug('Stopping peer manager...');
514
538
  await this.peerManager.stop();
515
-
516
- this.logger.debug('Stopping job queue...');
517
- await this.jobQueue.end();
518
539
  this.logger.debug('Stopping running promise...');
519
540
  await this.discoveryRunningPromise?.stop();
520
541
  this.logger.debug('Stopping peer discovery service...');
@@ -602,16 +623,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
602
623
  if (!this.node.services.pubsub) {
603
624
  throw new Error('Pubsub service not available.');
604
625
  }
605
- const p2pMessage = await P2PMessage.fromGossipable(message);
606
- this.logger.debug(`Publishing message`, {
607
- topic,
608
- messageId: p2pMessage.id,
609
- });
626
+ const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages);
610
627
  const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
611
-
612
628
  return result.recipients.length;
613
629
  }
614
630
 
631
+ /**
632
+ * Checks if this message has already been seen, based on its msgId computed from hashing the message data.
633
+ * Note that we do not rely on the seenCache from gossipsub since we want to keep a longer history of seen
634
+ * messages to avoid tx echoes across the network.
635
+ */
615
636
  protected preValidateReceivedMessage(
616
637
  msg: Message,
617
638
  msgId: string,
@@ -647,82 +668,122 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
647
668
  return { result: true, topicType };
648
669
  }
649
670
 
671
+ /**
672
+ * Safely deserializes a P2PMessage from raw message data.
673
+ * @param msgId - The message ID.
674
+ * @param source - The peer ID of the message source.
675
+ * @param data - The raw message data.
676
+ * @returns The deserialized P2PMessage or undefined if deserialization fails.
677
+ */
678
+ private safelyDeserializeP2PMessage(msgId: string, source: PeerId, data: Uint8Array): P2PMessage | undefined {
679
+ try {
680
+ return P2PMessage.fromMessageData(Buffer.from(data), this.config.debugP2PInstrumentMessages);
681
+ } catch (err) {
682
+ this.logger.error(`Error deserializing P2PMessage`, err, {
683
+ msgId,
684
+ source: source.toString(),
685
+ });
686
+ this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Reject);
687
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
688
+ return undefined;
689
+ }
690
+ }
691
+
650
692
  /**
651
693
  * Handles a new gossip message that was received by the client.
652
694
  * @param topic - The message's topic.
653
695
  * @param data - The message data
654
696
  */
655
697
  protected async handleNewGossipMessage(msg: Message, msgId: string, source: PeerId) {
656
- const p2pMessage = P2PMessage.fromMessageData(Buffer.from(msg.data));
657
- const currentTime = new Date();
658
- const messageLatency = currentTime.getTime() - p2pMessage.publishTime.getTime();
659
- this.logger.debug(`Received message`, {
660
- topic: msg.topic,
661
- messageId: p2pMessage.id,
662
- messageLatency,
663
- });
698
+ const msgReceivedTime = Date.now();
699
+ let topicType: TopicType | undefined;
700
+ const p2pMessage = this.safelyDeserializeP2PMessage(msgId, source, msg.data);
701
+ if (!p2pMessage) {
702
+ return;
703
+ }
664
704
 
665
705
  const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
666
706
 
667
707
  if (!preValidationResult.result) {
668
708
  return;
669
- } else if (preValidationResult.topicType !== undefined) {
670
- // guard against clock skew & DST
671
- if (messageLatency > 0) {
672
- this.instrumentation.recordMessageLatency(preValidationResult.topicType, messageLatency);
673
- }
674
709
  }
675
710
 
676
711
  if (msg.topic === this.topicStrings[TopicType.tx]) {
712
+ topicType = TopicType.tx;
677
713
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
678
714
  }
679
- if (msg.topic === this.topicStrings[TopicType.block_attestation] && this.clientType === P2PClientType.Full) {
680
- await this.processAttestationFromPeer(p2pMessage.payload, msgId, source);
715
+ if (msg.topic === this.topicStrings[TopicType.block_attestation]) {
716
+ topicType = TopicType.block_attestation;
717
+ if (this.clientType === P2PClientType.Full) {
718
+ await this.processAttestationFromPeer(p2pMessage.payload, msgId, source);
719
+ }
681
720
  }
682
721
  if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
722
+ topicType = TopicType.block_proposal;
683
723
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
684
724
  }
685
725
 
726
+ if (p2pMessage.timestamp !== undefined && topicType !== undefined) {
727
+ const latency = msgReceivedTime - p2pMessage.timestamp.getTime();
728
+ this.instrumentation.recordMessageLatency(topicType, latency);
729
+ }
730
+
686
731
  return;
687
732
  }
688
733
 
689
734
  protected async validateReceivedMessage<T>(
690
- validationFunc: () => Promise<{ result: boolean; obj: T }>,
735
+ validationFunc: () => Promise<ReceivedMessageValidationResult<T>>,
691
736
  msgId: string,
692
737
  source: PeerId,
693
738
  topicType: TopicType,
694
- ): Promise<{ result: boolean; obj: T | undefined }> {
695
- let resultAndObj: { result: boolean; obj: T | undefined } = { result: false, obj: undefined };
739
+ ): Promise<ReceivedMessageValidationResult<T>> {
740
+ let resultAndObj: ReceivedMessageValidationResult<T> = { result: TopicValidatorResult.Reject };
696
741
  const timer = new Timer();
697
742
  try {
698
743
  resultAndObj = await validationFunc();
699
744
  } catch (err) {
700
- this.logger.error(`Error deserializing and validating message `, err);
745
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
746
+ this.logger.error(`Error deserializing and validating gossipsub message`, err, {
747
+ msgId,
748
+ source: source.toString(),
749
+ topicType,
750
+ });
701
751
  }
702
752
 
703
- if (resultAndObj.result) {
753
+ if (resultAndObj.result === TopicValidatorResult.Accept) {
704
754
  this.instrumentation.recordMessageValidation(topicType, timer);
705
755
  }
706
756
 
707
- this.node.services.pubsub.reportMessageValidationResult(
708
- msgId,
709
- source.toString(),
710
- resultAndObj.result && resultAndObj.obj ? TopicValidatorResult.Accept : TopicValidatorResult.Reject,
711
- );
757
+ this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
712
758
  return resultAndObj;
713
759
  }
714
760
 
715
761
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
716
- const validationFunc = async () => {
762
+ const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
717
763
  const tx = Tx.fromBuffer(payloadData);
718
- const result = await this.validatePropagatedTx(tx, source);
719
- return { result, obj: tx };
764
+ const isValid = await this.validatePropagatedTx(tx, source);
765
+ const exists = isValid && (await this.mempools.txPool.hasTx(tx.getTxHash()));
766
+
767
+ this.logger.trace(`Validate propagated tx`, {
768
+ isValid,
769
+ exists,
770
+ [Attributes.P2P_ID]: source.toString(),
771
+ });
772
+
773
+ if (!isValid) {
774
+ return { result: TopicValidatorResult.Reject };
775
+ } else if (exists) {
776
+ return { result: TopicValidatorResult.Ignore, obj: tx };
777
+ } else {
778
+ return { result: TopicValidatorResult.Accept, obj: tx };
779
+ }
720
780
  };
721
781
 
722
782
  const { result, obj: tx } = await this.validateReceivedMessage<Tx>(validationFunc, msgId, source, TopicType.tx);
723
- if (!result || !tx) {
783
+ if (result !== TopicValidatorResult.Accept || !tx) {
724
784
  return;
725
785
  }
786
+
726
787
  const txHash = tx.getTxHash();
727
788
  const txHashString = txHash.toString();
728
789
  this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
@@ -731,10 +792,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
731
792
  });
732
793
 
733
794
  if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
734
- this.logger.debug(`Intentionally dropping tx ${txHashString} (probability rule)`);
795
+ this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
735
796
  return;
736
797
  }
737
798
 
799
+ this.instrumentation.incrementTxReceived(1);
738
800
  await this.mempools.txPool.addTxs([tx]);
739
801
  }
740
802
 
@@ -745,14 +807,42 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
745
807
  * @param attestation - The attestation to process.
746
808
  */
747
809
  private async processAttestationFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
748
- const validationFunc = async () => {
810
+ const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockAttestation>> = async () => {
749
811
  const attestation = BlockAttestation.fromBuffer(payloadData);
750
- const result = await this.validateAttestation(source, attestation);
751
- this.logger.trace(`validatePropagatedAttestation: ${result}`, {
812
+ const pool = this.mempools.attestationPool!;
813
+ const isValid = await this.validateAttestation(source, attestation);
814
+ const exists = isValid && (await pool.hasAttestation(attestation));
815
+
816
+ let canAdd = true;
817
+ if (isValid && !exists) {
818
+ const slot = attestation.payload.header.slotNumber;
819
+ const { committee } = await this.epochCache.getCommittee(slot);
820
+ const committeeSize = committee?.length ?? 0;
821
+ canAdd = await pool.canAddAttestation(attestation, committeeSize);
822
+ }
823
+
824
+ this.logger.trace(`Validate propagated block attestation`, {
825
+ isValid,
826
+ exists,
827
+ canAdd,
752
828
  [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
753
829
  [Attributes.P2P_ID]: source.toString(),
754
830
  });
755
- return { result, obj: attestation };
831
+
832
+ if (!isValid) {
833
+ return { result: TopicValidatorResult.Reject };
834
+ } else if (exists) {
835
+ return { result: TopicValidatorResult.Ignore, obj: attestation };
836
+ } else if (!canAdd) {
837
+ this.logger.warn(`Dropping block attestation due to per-(slot, proposalId) attestation cap`, {
838
+ slot: attestation.payload.header.slotNumber.toString(),
839
+ archive: attestation.archive.toString(),
840
+ source: source.toString(),
841
+ });
842
+ return { result: TopicValidatorResult.Ignore, obj: attestation };
843
+ } else {
844
+ return { result: TopicValidatorResult.Accept, obj: attestation };
845
+ }
756
846
  };
757
847
 
758
848
  const { result, obj: attestation } = await this.validateReceivedMessage<BlockAttestation>(
@@ -761,31 +851,58 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
761
851
  source,
762
852
  TopicType.block_attestation,
763
853
  );
764
- if (!result || !attestation) {
854
+
855
+ if (result !== TopicValidatorResult.Accept || !attestation) {
765
856
  return;
766
857
  }
858
+
767
859
  this.logger.debug(
768
- `Received attestation for block ${attestation.blockNumber} slot ${attestation.slotNumber.toNumber()} from external peer ${source.toString()}`,
860
+ `Received attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
769
861
  {
770
- p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
771
- slot: attestation.slotNumber.toNumber(),
862
+ p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
863
+ slot: attestation.slotNumber,
772
864
  archive: attestation.archive.toString(),
773
- block: attestation.blockNumber,
774
865
  source: source.toString(),
775
866
  },
776
867
  );
868
+
777
869
  await this.mempools.attestationPool!.addAttestations([attestation]);
778
870
  }
779
871
 
780
872
  private async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
781
- const validationFunc = async () => {
873
+ const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockProposal>> = async () => {
782
874
  const block = BlockProposal.fromBuffer(payloadData);
783
- const result = await this.validateBlockProposal(source, block);
784
- this.logger.trace(`validatePropagatedBlock: ${result}`, {
875
+ const isValid = await this.validateBlockProposal(source, block);
876
+ const pool = this.mempools.attestationPool;
877
+
878
+ // Note that we dont have an attestation pool if we're a prover node, but we still
879
+ // subscribe to block proposal topics in order to prevent their txs from being cleared.
880
+ const exists = isValid && (await pool?.hasBlockProposal(block));
881
+ const canAdd = isValid && (await pool?.canAddProposal(block));
882
+
883
+ this.logger.trace(`Validate propagated block proposal`, {
884
+ isValid,
885
+ exists,
886
+ canAdd,
785
887
  [Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
786
888
  [Attributes.P2P_ID]: source.toString(),
787
889
  });
788
- return { result, obj: block };
890
+
891
+ if (!isValid) {
892
+ return { result: TopicValidatorResult.Reject };
893
+ } else if (exists) {
894
+ return { result: TopicValidatorResult.Ignore, obj: block };
895
+ } else if (!canAdd) {
896
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
897
+ this.logger.warn(`Penalizing peer for block proposal exceeding per-slot cap`, {
898
+ slot: block.slotNumber.toString(),
899
+ archive: block.archive.toString(),
900
+ source: source.toString(),
901
+ });
902
+ return { result: TopicValidatorResult.Reject };
903
+ } else {
904
+ return { result: TopicValidatorResult.Accept, obj: block };
905
+ }
789
906
  };
790
907
 
791
908
  const { result, obj: block } = await this.validateReceivedMessage<BlockProposal>(
@@ -794,6 +911,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
794
911
  source,
795
912
  TopicType.block_proposal,
796
913
  );
914
+
797
915
  if (!result || !block) {
798
916
  return;
799
917
  }
@@ -803,48 +921,51 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
803
921
 
804
922
  // REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
805
923
  @trackSpan('Libp2pService.processValidBlockProposal', async block => ({
806
- [Attributes.BLOCK_NUMBER]: block.blockNumber,
807
- [Attributes.SLOT_NUMBER]: block.slotNumber.toNumber(),
924
+ [Attributes.SLOT_NUMBER]: block.slotNumber,
808
925
  [Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
809
- [Attributes.P2P_ID]: await block.p2pMessageIdentifier().then(i => i.toString()),
926
+ [Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then(i => i.toString()),
810
927
  }))
811
928
  private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
812
- const slot = block.slotNumber.toBigInt();
813
- const previousSlot = slot - 1n;
814
- const epoch = slot / 32n;
815
- this.logger.verbose(
816
- `Received block ${block.blockNumber} for slot ${slot} epoch ${epoch} from external peer ${sender.toString()}.`,
817
- {
818
- p2pMessageIdentifier: await block.p2pMessageIdentifier(),
819
- slot: block.slotNumber.toNumber(),
820
- archive: block.archive.toString(),
821
- block: block.blockNumber,
822
- source: sender.toString(),
823
- },
824
- );
929
+ const slot = block.slotNumber;
930
+ const previousSlot = SlotNumber(slot - 1);
931
+ this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
932
+ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
933
+ slot: block.slotNumber,
934
+ archive: block.archive.toString(),
935
+ source: sender.toString(),
936
+ });
825
937
  const attestationsForPreviousSlot = await this.mempools.attestationPool?.getAttestationsForSlot(previousSlot);
826
938
  if (attestationsForPreviousSlot !== undefined) {
827
939
  this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
828
940
  }
829
941
 
830
- // Mark the txs in this proposal as non-evictable
942
+ // Attempt to add proposal, then mark the txs in this proposal as non-evictable
943
+ try {
944
+ await this.mempools.attestationPool?.addBlockProposal(block);
945
+ } catch (err: unknown) {
946
+ // Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
947
+ if (err instanceof ProposalSlotCapExceededError) {
948
+ this.logger.warn(`Dropping block proposal due to per-slot proposal cap`, {
949
+ slot: String(slot),
950
+ archive: block.archive.toString(),
951
+ error: (err as Error).message,
952
+ });
953
+ return;
954
+ }
955
+ throw err;
956
+ }
831
957
  await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
832
- await this.mempools.attestationPool?.addBlockProposal(block);
833
958
  const attestations = await this.blockReceivedCallback(block, sender);
834
959
 
835
960
  // TODO: fix up this pattern - the abstraction is not nice
836
- // The attestation can be undefined if no handler is registered / the validator deems the block invalid
961
+ // The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
837
962
  if (attestations?.length) {
838
963
  for (const attestation of attestations) {
839
- this.logger.verbose(
840
- `Broadcasting attestation for block ${attestation.blockNumber} slot ${attestation.slotNumber.toNumber()}`,
841
- {
842
- p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
843
- slot: attestation.slotNumber.toNumber(),
844
- archive: attestation.archive.toString(),
845
- block: attestation.blockNumber,
846
- },
847
- );
964
+ this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber}`, {
965
+ p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
966
+ slot: attestation.slotNumber,
967
+ archive: attestation.archive.toString(),
968
+ });
848
969
  await this.broadcastAttestation(attestation);
849
970
  }
850
971
  }
@@ -855,10 +976,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
855
976
  * @param attestation - The attestation to broadcast.
856
977
  */
857
978
  @trackSpan('Libp2pService.broadcastAttestation', async attestation => ({
858
- [Attributes.BLOCK_NUMBER]: attestation.blockNumber,
859
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
979
+ [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
860
980
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
861
- [Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
981
+ [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
862
982
  }))
863
983
  private async broadcastAttestation(attestation: BlockAttestation) {
864
984
  await this.propagate(attestation);
@@ -869,15 +989,100 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
869
989
  * @param message - The message to propagate.
870
990
  */
871
991
  public async propagate<T extends Gossipable>(message: T) {
872
- const p2pMessageIdentifier = await message.p2pMessageIdentifier();
992
+ const p2pMessageIdentifier = await message.p2pMessageLoggingIdentifier();
873
993
  this.logger.trace(`Message ${p2pMessageIdentifier} queued`, { p2pMessageIdentifier });
874
- void this.jobQueue
875
- .put(async () => {
876
- await this.sendToPeers(message);
877
- })
878
- .catch(error => {
879
- this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
880
- });
994
+ void this.sendToPeers(message).catch(error => {
995
+ this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
996
+ });
997
+ }
998
+
999
+ /**
1000
+ * Validate the requested block transactions. Allow partial returns.
1001
+ * @param request - The block transactions request.
1002
+ * @param response - The block transactions response.
1003
+ * @param peerId - The ID of the peer that made the request.
1004
+ * @returns True if the requested block transactions are valid, false otherwise.
1005
+ */
1006
+ @trackSpan('Libp2pService.validateRequestedBlockTxs', request => ({
1007
+ [Attributes.BLOCK_HASH]: request.blockHash.toString(),
1008
+ }))
1009
+ private async validateRequestedBlockTxs(
1010
+ request: BlockTxsRequest,
1011
+ response: BlockTxsResponse,
1012
+ peerId: PeerId,
1013
+ ): Promise<boolean> {
1014
+ const requestedTxValidator = this.createRequestedTxValidator();
1015
+
1016
+ try {
1017
+ if (!response.blockHash.equals(request.blockHash)) {
1018
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1019
+ throw new ValidationError(
1020
+ `Received block txs for unexpected block: expected ${request.blockHash.toString()}, got ${response.blockHash.toString()}`,
1021
+ );
1022
+ }
1023
+
1024
+ if (response.txIndices.getLength() !== request.txIndices.getLength()) {
1025
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1026
+ throw new ValidationError(
1027
+ `Received block txs with mismatched bitvector length: expected ${request.txIndices.getLength()}, got ${response.txIndices.getLength()}`,
1028
+ );
1029
+ }
1030
+
1031
+ // Check no duplicates and not exceeding returnable count
1032
+ const requestedIndices = new Set(request.txIndices.getTrueIndices());
1033
+ const availableIndices = new Set(response.txIndices.getTrueIndices());
1034
+ const maxReturnable = [...requestedIndices].filter(i => availableIndices.has(i)).length;
1035
+
1036
+ const returnedHashes = await Promise.all(response.txs.map(tx => tx.getTxHash().toString()));
1037
+ const uniqueReturned = new Set(returnedHashes.map(h => h.toString()));
1038
+ if (uniqueReturned.size !== returnedHashes.length) {
1039
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1040
+ throw new ValidationError(`Received duplicate txs in block txs response`);
1041
+ }
1042
+ if (response.txs.length > maxReturnable) {
1043
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1044
+ throw new ValidationError(
1045
+ `Received more txs (${response.txs.length}) than requested-and-available (${maxReturnable})`,
1046
+ );
1047
+ }
1048
+
1049
+ // Given proposal (should have locally), ensure returned txs are valid subset and match request indices
1050
+ const proposal = await this.mempools.attestationPool?.getBlockProposal(request.blockHash.toString());
1051
+ if (proposal) {
1052
+ // Build intersected indices
1053
+ const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
1054
+
1055
+ // Enforce subset membership and preserve increasing order by index.
1056
+ const hashToIndexInProposal = new Map<string, number>(
1057
+ proposal.txHashes.map((h, i) => [h.toString(), i] as [string, number]),
1058
+ );
1059
+ const allowedIndexSet = new Set(intersectIdx);
1060
+ const indices = returnedHashes.map(h => hashToIndexInProposal.get(h));
1061
+ const allAllowed = indices.every(idx => idx !== undefined && allowedIndexSet.has(idx));
1062
+ const strictlyIncreasing = indices.every((idx, i) => (i === 0 ? idx !== undefined : idx! > indices[i - 1]!));
1063
+ if (!allAllowed || !strictlyIncreasing) {
1064
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1065
+ throw new ValidationError('Returned txs do not match expected subset/order for requested indices');
1066
+ }
1067
+ } else {
1068
+ // No local proposal, cannot check the membership/order of the returned txs
1069
+ this.logger.warn(
1070
+ `Block proposal not found for block hash ${request.blockHash.toString()}; cannot validate membership/order of returned txs`,
1071
+ );
1072
+ return false;
1073
+ }
1074
+
1075
+ await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator)));
1076
+ return true;
1077
+ } catch (e: any) {
1078
+ if (e instanceof ValidationError) {
1079
+ this.logger.warn(`Failed validation for requested block txs from peer ${peerId.toString()}`);
1080
+ } else {
1081
+ this.logger.error(`Error during validation of requested block txs`, e);
1082
+ }
1083
+
1084
+ return false;
1085
+ }
881
1086
  }
882
1087
 
883
1088
  /**
@@ -890,47 +1095,113 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
890
1095
  * ReqRespSubProtocol.TX subprotocol validation.
891
1096
  *
892
1097
  * @param requestedTxHash - The collection of the txs that was requested.
893
- * @param responseTx - The collectin of txs that was received as a response to the request.
1098
+ * @param responseTx - The collection of txs that was received as a response to the request.
894
1099
  * @param peerId - The peer ID of the peer that sent the tx.
895
1100
  * @returns True if the whole collection of txs is valid, false otherwise.
896
1101
  */
897
- //TODO: (mralj) - this is somewhat naive implementation, if single tx is invlid we consider the whole response invalid.
898
- // I think we should still extract the valid txs and return them, so that we can still use the response.
899
1102
  @trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx) => ({
900
1103
  [Attributes.TX_HASH]: requestedTxHash.toString(),
901
1104
  }))
902
- private async validateRequestedTx(requestedTxHash: TxHash[], responseTx: Tx[], peerId: PeerId): Promise<boolean> {
1105
+ private async validateRequestedTxs(requestedTxHash: TxHash[], responseTx: Tx[], peerId: PeerId): Promise<boolean> {
903
1106
  const requested = new Set(requestedTxHash.map(h => h.toString()));
1107
+ const requestedTxValidator = this.createRequestedTxValidator();
904
1108
 
905
- const proofValidator = new TxProofValidator(this.proofVerifier);
906
-
1109
+ //TODO: (mralj) - this is somewhat naive implementation, if single tx is invlid we consider the whole response invalid.
1110
+ // I think we should still extract the valid txs and return them, so that we can still use the response.
907
1111
  try {
908
- await Promise.all(
909
- responseTx.map(async tx => {
910
- if (!requested.has(tx.getTxHash().toString())) {
911
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
912
- throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
913
- }
914
-
915
- const { result } = await proofValidator.validateTx(tx);
916
- if (result === 'invalid') {
917
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
918
- throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
919
- }
920
- }),
921
- );
1112
+ await Promise.all(responseTx.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
922
1113
  return true;
923
1114
  } catch (e: any) {
924
1115
  if (e instanceof ValidationError) {
925
- this.logger.debug(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`);
1116
+ this.logger.warn(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`);
926
1117
  } else {
927
- this.logger.warn(`Error during validation of requested txs`, e);
1118
+ this.logger.error(`Error during validation of requested txs`, e);
928
1119
  }
929
1120
 
930
1121
  return false;
931
1122
  }
932
1123
  }
933
1124
 
1125
+ /**
1126
+ * Validates a BLOCK response.
1127
+ *
1128
+ * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1129
+ * Penalizes on block number mismatch or hash mismatch.
1130
+ *
1131
+ * @param requestedBlockNumber - The requested block number.
1132
+ * @param responseBlock - The block returned by the peer.
1133
+ * @param peerId - The peer that returned the block.
1134
+ * @returns True if the response is valid, false otherwise.
1135
+ */
1136
+ @trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
1137
+ [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
1138
+ }))
1139
+ private async validateRequestedBlock(
1140
+ requestedBlockNumber: Fr,
1141
+ responseBlock: L2Block,
1142
+ peerId: PeerId,
1143
+ ): Promise<boolean> {
1144
+ try {
1145
+ const reqNum = Number(requestedBlockNumber.toString());
1146
+ if (responseBlock.number !== reqNum) {
1147
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1148
+ return false;
1149
+ }
1150
+
1151
+ const local = await this.archiver.getBlock(BlockNumber(reqNum));
1152
+ if (!local) {
1153
+ // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1154
+ // TODO: Consider extending this validator to accept an expected hash or
1155
+ // performing quorum-based checks when using P2P syncing prior to L1 sync.
1156
+ this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1157
+ return false;
1158
+ }
1159
+ const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
1160
+ if (!localHash.equals(respHash)) {
1161
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1162
+ return false;
1163
+ }
1164
+
1165
+ return true;
1166
+ } catch (e) {
1167
+ this.logger.warn(`Error validating requested block`, e);
1168
+ return false;
1169
+ }
1170
+ }
1171
+
1172
+ private createRequestedTxValidator(): TxValidator {
1173
+ return new AggregateTxValidator(
1174
+ new DataTxValidator(),
1175
+ new MetadataTxValidator({
1176
+ l1ChainId: new Fr(this.config.l1ChainId),
1177
+ rollupVersion: new Fr(this.config.rollupVersion),
1178
+ protocolContractsHash,
1179
+ vkTreeRoot: getVKTreeRoot(),
1180
+ }),
1181
+ new TxProofValidator(this.proofVerifier),
1182
+ );
1183
+ }
1184
+
1185
+ private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
1186
+ const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity);
1187
+
1188
+ if (!(await tx.validateTxHash())) {
1189
+ penalize(PeerErrorSeverity.MidToleranceError);
1190
+ throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
1191
+ }
1192
+
1193
+ if (requested && !requested.has(tx.getTxHash().toString())) {
1194
+ penalize(PeerErrorSeverity.MidToleranceError);
1195
+ throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
1196
+ }
1197
+
1198
+ const { result } = await txValidator.validateTx(tx);
1199
+ if (result === 'invalid') {
1200
+ penalize(PeerErrorSeverity.LowToleranceError);
1201
+ throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
1202
+ }
1203
+ }
1204
+
934
1205
  @trackSpan('Libp2pService.validatePropagatedTx', tx => ({
935
1206
  [Attributes.TX_HASH]: tx.getTxHash().toString(),
936
1207
  }))
@@ -952,7 +1223,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
952
1223
 
953
1224
  // Double spend validator has a special case handler
954
1225
  if (name === 'doubleSpendValidator') {
955
- const txBlockNumber = currentBlockNumber + 1; // tx is expected to be in the next block
1226
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
956
1227
  severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
957
1228
  }
958
1229
 
@@ -962,7 +1233,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
962
1233
  return true;
963
1234
  }
964
1235
 
965
- private async getGasFees(blockNumber: number): Promise<GasFees> {
1236
+ private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
966
1237
  if (blockNumber === this.feesCache?.blockNumber) {
967
1238
  return this.feesCache.gasFees;
968
1239
  }
@@ -1003,13 +1274,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1003
1274
  * @returns The message validators.
1004
1275
  */
1005
1276
  private async createMessageValidators(
1006
- currentBlockNumber: number,
1277
+ currentBlockNumber: BlockNumber,
1007
1278
  nextSlotTimestamp: UInt64,
1008
1279
  ): Promise<Record<string, MessageValidator>[]> {
1009
1280
  const gasFees = await this.getGasFees(currentBlockNumber);
1010
1281
  const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
1011
1282
 
1012
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
1283
+ const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1013
1284
 
1014
1285
  return createTxMessageValidators(
1015
1286
  nextSlotTimestamp,
@@ -1018,7 +1289,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1018
1289
  gasFees,
1019
1290
  this.config.l1ChainId,
1020
1291
  this.config.rollupVersion,
1021
- protocolContractTreeRoot,
1292
+ protocolContractsHash,
1022
1293
  this.archiver,
1023
1294
  this.proofVerifier,
1024
1295
  !this.config.disableTransactions,
@@ -1071,7 +1342,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1071
1342
  * @param peerId - The peer ID of the peer that sent the tx.
1072
1343
  * @returns Severity
1073
1344
  */
1074
- private async handleDoubleSpendFailure(tx: Tx, blockNumber: number): Promise<PeerErrorSeverity> {
1345
+ private async handleDoubleSpendFailure(tx: Tx, blockNumber: BlockNumber): Promise<PeerErrorSeverity> {
1075
1346
  if (blockNumber <= this.config.doubleSpendSeverePeerPenaltyWindow) {
1076
1347
  return PeerErrorSeverity.HighToleranceError;
1077
1348
  }
@@ -1079,7 +1350,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1079
1350
  const snapshotValidator = new DoubleSpendTxValidator({
1080
1351
  nullifiersExist: async (nullifiers: Buffer[]) => {
1081
1352
  const merkleTree = this.worldStateSynchronizer.getSnapshot(
1082
- blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow,
1353
+ BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow),
1083
1354
  );
1084
1355
  const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
1085
1356
  return indices.map(index => index !== undefined);
@@ -1101,10 +1372,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1101
1372
  * @returns True if the attestation is valid, false otherwise.
1102
1373
  */
1103
1374
  @trackSpan('Libp2pService.validateAttestation', async (_, attestation) => ({
1104
- [Attributes.BLOCK_NUMBER]: attestation.blockNumber,
1105
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
1375
+ [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1106
1376
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1107
- [Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
1377
+ [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1108
1378
  }))
1109
1379
  public async validateAttestation(peerId: PeerId, attestation: BlockAttestation): Promise<boolean> {
1110
1380
  const severity = await this.attestationValidator.validate(attestation);
@@ -1147,7 +1417,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1147
1417
  private async sendToPeers<T extends Gossipable>(message: T) {
1148
1418
  const parent = message.constructor as typeof Gossipable;
1149
1419
 
1150
- const identifier = await message.p2pMessageIdentifier().then(i => i.toString());
1420
+ const identifier = await message.p2pMessageLoggingIdentifier().then(i => i.toString());
1151
1421
  this.logger.trace(`Sending message ${identifier}`, { p2pMessageIdentifier: identifier });
1152
1422
 
1153
1423
  const recipientsNum = await this.publishToTopic(this.topicStrings[parent.p2pTopic], message);