@aztec/p2p 0.0.1-commit.d3ec352c → 0.0.1-commit.d431d1c

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 (273) hide show
  1. package/dest/client/factory.d.ts +2 -2
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +2 -3
  4. package/dest/client/interface.d.ts +18 -5
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +11 -14
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +456 -124
  9. package/dest/config.d.ts +4 -7
  10. package/dest/config.d.ts.map +1 -1
  11. package/dest/config.js +10 -13
  12. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +61 -42
  13. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  14. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  15. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  16. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +239 -265
  17. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +21 -18
  18. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
  19. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +114 -109
  20. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -16
  21. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  22. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +89 -128
  23. package/dest/mem_pools/attestation_pool/mocks.d.ts +11 -8
  24. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/mocks.js +17 -13
  26. package/dest/mem_pools/instrumentation.d.ts +7 -1
  27. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  28. package/dest/mem_pools/instrumentation.js +30 -12
  29. package/dest/mem_pools/interface.d.ts +3 -4
  30. package/dest/mem_pools/interface.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +36 -27
  32. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  33. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +314 -335
  34. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +31 -0
  35. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
  36. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
  37. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +156 -0
  38. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
  39. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
  40. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
  41. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  42. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +115 -0
  43. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
  44. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  45. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
  46. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
  47. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  48. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +76 -0
  49. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
  50. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  51. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
  52. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
  53. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
  54. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
  55. package/dest/mem_pools/tx_pool/index.d.ts +1 -2
  56. package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
  57. package/dest/mem_pools/tx_pool/index.js +0 -1
  58. package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
  59. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  60. package/dest/mem_pools/tx_pool/priority.js +6 -1
  61. package/dest/mem_pools/tx_pool/tx_pool.d.ts +8 -4
  62. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  63. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  64. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  65. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +25 -20
  66. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -4
  67. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  68. package/dest/msg_validators/attestation_validator/attestation_validator.js +13 -11
  69. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
  70. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  71. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +7 -10
  72. package/dest/msg_validators/index.d.ts +2 -2
  73. package/dest/msg_validators/index.d.ts.map +1 -1
  74. package/dest/msg_validators/index.js +1 -1
  75. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
  76. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
  77. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
  78. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
  79. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
  80. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
  81. package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
  82. package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
  83. package/dest/msg_validators/proposal_validator/index.js +3 -0
  84. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
  85. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
  86. package/dest/msg_validators/proposal_validator/proposal_validator.js +73 -0
  87. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
  88. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
  89. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +157 -0
  90. package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
  91. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  92. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
  93. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  94. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  95. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  96. package/dest/msg_validators/tx_validator/factory.d.ts +2 -2
  97. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  98. package/dest/msg_validators/tx_validator/factory.js +1 -1
  99. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
  100. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
  101. package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
  102. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  103. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  104. package/dest/msg_validators/tx_validator/gas_validator.js +8 -14
  105. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  106. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  107. package/dest/msg_validators/tx_validator/index.js +1 -0
  108. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +2 -2
  109. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  110. package/dest/msg_validators/tx_validator/size_validator.d.ts +6 -0
  111. package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
  112. package/dest/msg_validators/tx_validator/size_validator.js +20 -0
  113. package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
  114. package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
  115. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +1 -1
  116. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  117. package/dest/services/dummy_service.d.ts +6 -2
  118. package/dest/services/dummy_service.d.ts.map +1 -1
  119. package/dest/services/dummy_service.js +3 -0
  120. package/dest/services/encoding.d.ts +1 -1
  121. package/dest/services/encoding.d.ts.map +1 -1
  122. package/dest/services/encoding.js +7 -6
  123. package/dest/services/libp2p/instrumentation.d.ts +1 -1
  124. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  125. package/dest/services/libp2p/instrumentation.js +20 -73
  126. package/dest/services/libp2p/libp2p_service.d.ts +30 -13
  127. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  128. package/dest/services/libp2p/libp2p_service.js +704 -150
  129. package/dest/services/peer-manager/metrics.d.ts +6 -1
  130. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  131. package/dest/services/peer-manager/metrics.js +18 -21
  132. package/dest/services/peer-manager/peer_manager.d.ts +2 -2
  133. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  134. package/dest/services/peer-manager/peer_manager.js +4 -12
  135. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  136. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  137. package/dest/services/peer-manager/peer_scoring.js +2 -5
  138. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -1
  139. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  140. package/dest/services/reqresp/constants.d.ts +12 -0
  141. package/dest/services/reqresp/constants.d.ts.map +1 -0
  142. package/dest/services/reqresp/constants.js +7 -0
  143. package/dest/services/reqresp/interface.d.ts +4 -4
  144. package/dest/services/reqresp/interface.d.ts.map +1 -1
  145. package/dest/services/reqresp/interface.js +3 -3
  146. package/dest/services/reqresp/metrics.d.ts +1 -1
  147. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  148. package/dest/services/reqresp/metrics.js +5 -21
  149. package/dest/services/reqresp/protocols/auth.d.ts +2 -2
  150. package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
  151. package/dest/services/reqresp/protocols/auth.js +2 -2
  152. package/dest/services/reqresp/protocols/block.js +1 -1
  153. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
  154. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  155. package/dest/services/reqresp/protocols/block_txs/bitvector.js +7 -0
  156. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +2 -2
  157. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  158. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +1 -1
  159. package/dest/services/reqresp/protocols/status.d.ts +1 -1
  160. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  161. package/dest/services/reqresp/protocols/status.js +4 -1
  162. package/dest/services/reqresp/protocols/tx.d.ts +2 -3
  163. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  164. package/dest/services/reqresp/reqresp.js +402 -24
  165. package/dest/services/service.d.ts +16 -3
  166. package/dest/services/service.d.ts.map +1 -1
  167. package/dest/services/tx_collection/config.js +1 -1
  168. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  169. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  170. package/dest/services/tx_collection/instrumentation.js +4 -14
  171. package/dest/services/tx_collection/slow_tx_collection.d.ts +3 -3
  172. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  173. package/dest/services/tx_collection/tx_collection.d.ts +4 -4
  174. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  175. package/dest/services/tx_collection/tx_collection.js +1 -1
  176. package/dest/services/tx_provider.d.ts +2 -1
  177. package/dest/services/tx_provider.d.ts.map +1 -1
  178. package/dest/services/tx_provider.js +11 -2
  179. package/dest/services/tx_provider_instrumentation.d.ts +5 -2
  180. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  181. package/dest/services/tx_provider_instrumentation.js +13 -13
  182. package/dest/test-helpers/mock-tx-helpers.js +1 -1
  183. package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
  184. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  185. package/dest/testbench/p2p_client_testbench_worker.js +29 -16
  186. package/dest/testbench/worker_client_manager.d.ts +1 -1
  187. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  188. package/dest/testbench/worker_client_manager.js +6 -1
  189. package/package.json +16 -16
  190. package/src/client/factory.ts +5 -10
  191. package/src/client/interface.ts +19 -4
  192. package/src/client/p2p_client.ts +92 -147
  193. package/src/config.ts +12 -18
  194. package/src/mem_pools/attestation_pool/attestation_pool.ts +68 -41
  195. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +241 -289
  196. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +163 -141
  197. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -164
  198. package/src/mem_pools/attestation_pool/mocks.ts +21 -15
  199. package/src/mem_pools/instrumentation.ts +38 -14
  200. package/src/mem_pools/interface.ts +2 -4
  201. package/src/mem_pools/tx_pool/README.md +270 -0
  202. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +363 -368
  203. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +131 -0
  204. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +207 -0
  205. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +159 -0
  206. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
  207. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +91 -0
  208. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
  209. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
  210. package/src/mem_pools/tx_pool/index.ts +0 -1
  211. package/src/mem_pools/tx_pool/priority.ts +8 -1
  212. package/src/mem_pools/tx_pool/tx_pool.ts +8 -3
  213. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +18 -13
  214. package/src/msg_validators/attestation_validator/attestation_validator.ts +17 -14
  215. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +9 -12
  216. package/src/msg_validators/index.ts +1 -1
  217. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
  218. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
  219. package/src/msg_validators/proposal_validator/index.ts +3 -0
  220. package/src/msg_validators/proposal_validator/proposal_validator.ts +85 -0
  221. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +191 -0
  222. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  223. package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
  224. package/src/msg_validators/tx_validator/data_validator.ts +12 -4
  225. package/src/msg_validators/tx_validator/factory.ts +1 -1
  226. package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
  227. package/src/msg_validators/tx_validator/gas_validator.ts +8 -25
  228. package/src/msg_validators/tx_validator/index.ts +1 -0
  229. package/src/msg_validators/tx_validator/metadata_validator.ts +13 -5
  230. package/src/msg_validators/tx_validator/size_validator.ts +18 -0
  231. package/src/msg_validators/tx_validator/test_utils.ts +1 -1
  232. package/src/msg_validators/tx_validator/timestamp_validator.ts +3 -1
  233. package/src/services/dummy_service.ts +6 -0
  234. package/src/services/encoding.ts +6 -5
  235. package/src/services/libp2p/instrumentation.ts +19 -73
  236. package/src/services/libp2p/libp2p_service.ts +338 -117
  237. package/src/services/peer-manager/metrics.ts +22 -21
  238. package/src/services/peer-manager/peer_manager.ts +5 -4
  239. package/src/services/peer-manager/peer_scoring.ts +1 -5
  240. package/src/services/reqresp/connection-sampler/connection_sampler.ts +3 -1
  241. package/src/services/reqresp/constants.ts +14 -0
  242. package/src/services/reqresp/interface.ts +3 -3
  243. package/src/services/reqresp/metrics.ts +7 -23
  244. package/src/services/reqresp/protocols/auth.ts +2 -2
  245. package/src/services/reqresp/protocols/block.ts +1 -1
  246. package/src/services/reqresp/protocols/block_txs/bitvector.ts +9 -0
  247. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
  248. package/src/services/reqresp/protocols/status.ts +7 -4
  249. package/src/services/reqresp/protocols/tx.ts +1 -2
  250. package/src/services/service.ts +19 -4
  251. package/src/services/tx_collection/config.ts +1 -1
  252. package/src/services/tx_collection/instrumentation.ts +4 -21
  253. package/src/services/tx_collection/slow_tx_collection.ts +2 -2
  254. package/src/services/tx_collection/tx_collection.ts +4 -4
  255. package/src/services/tx_provider.ts +17 -2
  256. package/src/services/tx_provider_instrumentation.ts +18 -14
  257. package/src/test-helpers/mock-pubsub.ts +1 -1
  258. package/src/test-helpers/mock-tx-helpers.ts +1 -1
  259. package/src/test-helpers/reqresp-nodes.ts +1 -1
  260. package/src/testbench/p2p_client_testbench_worker.ts +41 -21
  261. package/src/testbench/worker_client_manager.ts +6 -1
  262. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -81
  263. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
  264. package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -239
  265. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
  266. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
  267. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -82
  268. package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
  269. package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
  270. package/dest/msg_validators/block_proposal_validator/index.js +0 -1
  271. package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -285
  272. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -97
  273. package/src/msg_validators/block_proposal_validator/index.ts +0 -1
@@ -1,20 +1,22 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
- import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
- import { randomInt } from '@aztec/foundation/crypto';
4
- import { Fr } from '@aztec/foundation/fields';
2
+ import { BlockNumber } from '@aztec/foundation/branded-types';
3
+ import { randomInt } from '@aztec/foundation/crypto/random';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
6
6
  import { RunningPromise } from '@aztec/foundation/running-promise';
7
7
  import { Timer } from '@aztec/foundation/timer';
8
8
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
9
9
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
10
10
  import { protocolContractsHash } from '@aztec/protocol-contracts';
11
- import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
11
+ import type { EthAddress, L2BlockNew, L2BlockSource } from '@aztec/stdlib/block';
12
12
  import type { ContractDataSource } from '@aztec/stdlib/contract';
13
13
  import { GasFees } from '@aztec/stdlib/gas';
14
14
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
15
15
  import {
16
- BlockAttestation,
17
16
  BlockProposal,
17
+ CheckpointAttestation,
18
+ CheckpointProposal,
19
+ type CheckpointProposalCore,
18
20
  type Gossipable,
19
21
  P2PClientType,
20
22
  P2PMessage,
@@ -28,7 +30,14 @@ import { MerkleTreeId } from '@aztec/stdlib/trees';
28
30
  import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
29
31
  import type { UInt64 } from '@aztec/stdlib/types';
30
32
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
31
- import { Attributes, OtelMetricsAdapter, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
33
+ import {
34
+ Attributes,
35
+ OtelMetricsAdapter,
36
+ SpanStatusCode,
37
+ type TelemetryClient,
38
+ WithTracer,
39
+ trackSpan,
40
+ } from '@aztec/telemetry-client';
32
41
 
33
42
  import {
34
43
  type GossipSub,
@@ -53,9 +62,11 @@ import type { P2PConfig } from '../../config.js';
53
62
  import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
54
63
  import type { MemPools } from '../../mem_pools/interface.js';
55
64
  import {
56
- AttestationValidator,
57
65
  BlockProposalValidator,
66
+ CheckpointAttestationValidator,
67
+ CheckpointProposalValidator,
58
68
  FishermanAttestationValidator,
69
+ SizeTxValidator,
59
70
  } from '../../msg_validators/index.js';
60
71
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
61
72
  import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
@@ -101,7 +112,12 @@ import {
101
112
  reqRespTxHandler,
102
113
  } from '../reqresp/protocols/index.js';
103
114
  import { ReqResp } from '../reqresp/reqresp.js';
104
- import type { P2PBlockReceivedCallback, P2PService, PeerDiscoveryService } from '../service.js';
115
+ import type {
116
+ P2PBlockReceivedCallback,
117
+ P2PCheckpointReceivedCallback,
118
+ P2PService,
119
+ PeerDiscoveryService,
120
+ } from '../service.js';
105
121
  import { P2PInstrumentation } from './instrumentation.js';
106
122
 
107
123
  interface ValidationResult {
@@ -125,8 +141,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
125
141
  private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
126
142
 
127
143
  // Message validators
128
- private attestationValidator: AttestationValidator;
129
144
  private blockProposalValidator: BlockProposalValidator;
145
+ private checkpointProposalValidator: CheckpointProposalValidator;
146
+ private checkpointAttestationValidator: CheckpointAttestationValidator;
130
147
 
131
148
  private protocolVersion = '';
132
149
  private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
@@ -140,10 +157,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
140
157
  */
141
158
  private blockReceivedCallback: P2PBlockReceivedCallback;
142
159
 
160
+ /**
161
+ * Callback for when a checkpoint proposal is received from a peer.
162
+ * @param checkpoint - The checkpoint proposal received from the peer.
163
+ * @returns The attestations for the checkpoint, if any.
164
+ */
165
+ private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
166
+
143
167
  private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
144
168
 
145
169
  private instrumentation: P2PInstrumentation;
146
170
 
171
+ private telemetry: TelemetryClient;
172
+
147
173
  protected logger: Logger;
148
174
 
149
175
  constructor(
@@ -153,7 +179,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
153
179
  private peerDiscoveryService: PeerDiscoveryService,
154
180
  private reqresp: ReqRespInterface,
155
181
  private peerManager: PeerManagerInterface,
156
- protected mempools: MemPools<T>,
182
+ protected mempools: MemPools,
157
183
  private archiver: L2BlockSource & ContractDataSource,
158
184
  private epochCache: EpochCacheInterface,
159
185
  private proofVerifier: ClientProtocolCircuitVerifier,
@@ -162,6 +188,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
162
188
  logger: Logger = createLogger('p2p:libp2p_service'),
163
189
  ) {
164
190
  super(telemetry, 'LibP2PService');
191
+ this.telemetry = telemetry;
165
192
 
166
193
  // Create child logger with fisherman prefix if in fisherman mode
167
194
  this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
@@ -170,7 +197,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
170
197
 
171
198
  this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
172
199
  this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
173
- this.msgIdSeenValidators[TopicType.block_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
200
+ this.msgIdSeenValidators[TopicType.checkpoint_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
201
+ this.msgIdSeenValidators[TopicType.checkpoint_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
174
202
 
175
203
  const versions = getVersions(config);
176
204
  this.protocolVersion = compressComponentVersions(versions);
@@ -178,25 +206,40 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
178
206
 
179
207
  this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
180
208
  this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
181
- this.topicStrings[TopicType.block_attestation] = createTopicString(
182
- TopicType.block_attestation,
209
+ this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(
210
+ TopicType.checkpoint_proposal,
211
+ this.protocolVersion,
212
+ );
213
+ this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(
214
+ TopicType.checkpoint_attestation,
183
215
  this.protocolVersion,
184
216
  );
185
217
 
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
218
  this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
219
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
220
+ txsPermitted: !config.disableTransactions,
221
+ });
222
+ this.checkpointAttestationValidator = config.fishermanMode
223
+ ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
224
+ : new CheckpointAttestationValidator(epochCache);
191
225
 
192
226
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
193
227
 
194
- this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation[] | undefined> => {
228
+ this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
195
229
  this.logger.debug(
196
230
  `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
197
231
  { p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
198
232
  );
199
- return undefined;
233
+ return false;
234
+ };
235
+
236
+ this.checkpointReceivedCallback = (
237
+ checkpoint: CheckpointProposalCore,
238
+ ): Promise<CheckpointAttestation[] | undefined> => {
239
+ this.logger.debug(
240
+ `Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
241
+ );
242
+ return Promise.resolve(undefined);
200
243
  };
201
244
  }
202
245
 
@@ -215,7 +258,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
215
258
  config: P2PConfig,
216
259
  peerId: PeerId,
217
260
  deps: {
218
- mempools: MemPools<T>;
261
+ mempools: MemPools;
219
262
  l2BlockSource: L2BlockSource & ContractDataSource;
220
263
  epochCache: EpochCacheInterface;
221
264
  proofVerifier: ClientProtocolCircuitVerifier;
@@ -265,7 +308,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
265
308
 
266
309
  const txTopic = createTopicString(TopicType.tx, protocolVersion);
267
310
  const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
268
- const blockAttestationTopic = createTopicString(TopicType.block_attestation, protocolVersion);
311
+ const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
312
+ const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
269
313
 
270
314
  const preferredPeersEnrs: ENR[] = config.preferredPeers.map(enr => ENR.decodeTxt(enr));
271
315
  const directPeers = (
@@ -387,12 +431,17 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
387
431
  invalidMessageDeliveriesWeight: -20,
388
432
  invalidMessageDeliveriesDecay: 0.5,
389
433
  }),
390
- [blockAttestationTopic]: createTopicScoreParams({
434
+ [blockProposalTopic]: createTopicScoreParams({
435
+ topicWeight: 1,
436
+ invalidMessageDeliveriesWeight: -20,
437
+ invalidMessageDeliveriesDecay: 0.5,
438
+ }),
439
+ [checkpointProposalTopic]: createTopicScoreParams({
391
440
  topicWeight: 1,
392
441
  invalidMessageDeliveriesWeight: -20,
393
442
  invalidMessageDeliveriesDecay: 0.5,
394
443
  }),
395
- [blockProposalTopic]: createTopicScoreParams({
444
+ [checkpointAttestationTopic]: createTopicScoreParams({
396
445
  topicWeight: 1,
397
446
  invalidMessageDeliveriesWeight: -20,
398
447
  invalidMessageDeliveriesDecay: 0.5,
@@ -462,17 +511,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
462
511
  }
463
512
  const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
464
513
 
465
- await this.peerManager.initializePeers();
466
- if (!this.config.p2pDiscoveryDisabled) {
467
- await this.peerDiscoveryService.start();
468
- }
469
- await this.node.start();
470
-
471
- // Subscribe to standard GossipSub topics by default
472
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
473
- this.subscribeToTopic(this.topicStrings[topic]);
474
- }
475
-
476
514
  // Create request response protocol handlers
477
515
  const txHandler = reqRespTxHandler(this.mempools);
478
516
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
@@ -486,8 +524,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
486
524
  [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
487
525
  };
488
526
 
489
- // Only handle block transactions request if attestation pool is available to the client
490
- if (this.mempools.attestationPool && !this.config.disableTransactions) {
527
+ if (!this.config.disableTransactions) {
491
528
  const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
492
529
  requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
493
530
  }
@@ -496,10 +533,32 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
496
533
  requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
497
534
  }
498
535
 
536
+ // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
537
+ const reqrespSubProtocolValidators = {
538
+ ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
539
+ [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
540
+ [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
541
+ [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
542
+ };
543
+
544
+ await this.peerManager.initializePeers();
545
+
546
+ await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
547
+
548
+ await this.node.start();
549
+
550
+ // Subscribe to standard GossipSub topics by default
551
+ for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
552
+ this.subscribeToTopic(this.topicStrings[topic]);
553
+ }
554
+
499
555
  // add GossipSub listener
500
556
  this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
501
557
 
502
558
  // Start running promise for peer discovery and metrics collection
559
+ if (!this.config.p2pDiscoveryDisabled) {
560
+ await this.peerDiscoveryService.start();
561
+ }
503
562
  this.discoveryRunningPromise = new RunningPromise(
504
563
  async () => {
505
564
  await this.peerManager.heartbeat();
@@ -509,14 +568,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
509
568
  );
510
569
  this.discoveryRunningPromise.start();
511
570
 
512
- // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
513
- const reqrespSubProtocolValidators = {
514
- ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
515
- [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
516
- [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
517
- [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
518
- };
519
- await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
520
571
  this.logger.info(`Started P2P service`, {
521
572
  listen: this.config.listenAddress,
522
573
  port: this.config.p2pPort,
@@ -602,6 +653,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
602
653
  this.blockReceivedCallback = callback;
603
654
  }
604
655
 
656
+ public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
657
+ this.checkpointReceivedCallback = callback;
658
+ }
659
+
605
660
  /**
606
661
  * Subscribes to a topic.
607
662
  * @param topic - The topic to subscribe to.
@@ -623,7 +678,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
623
678
  if (!this.node.services.pubsub) {
624
679
  throw new Error('Pubsub service not available.');
625
680
  }
626
- const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages);
681
+ const isBlockProposal = topic === this.topicStrings[TopicType.block_proposal];
682
+ const traceContext =
683
+ this.config.debugP2PInstrumentMessages && isBlockProposal ? this.telemetry.getTraceContext() : undefined;
684
+ const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages, traceContext);
627
685
  const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
628
686
  return result.recipients.length;
629
687
  }
@@ -644,12 +702,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
644
702
  case this.topicStrings[TopicType.tx]:
645
703
  topicType = TopicType.tx;
646
704
  break;
647
- case this.topicStrings[TopicType.block_attestation]:
648
- topicType = TopicType.block_attestation;
649
- break;
650
705
  case this.topicStrings[TopicType.block_proposal]:
651
706
  topicType = TopicType.block_proposal;
652
707
  break;
708
+ case this.topicStrings[TopicType.checkpoint_proposal]:
709
+ topicType = TopicType.checkpoint_proposal;
710
+ break;
711
+ case this.topicStrings[TopicType.checkpoint_attestation]:
712
+ topicType = TopicType.checkpoint_attestation;
713
+ break;
653
714
  default:
654
715
  this.logger.error(`Received message on unknown topic: ${msg.topic}`);
655
716
  break;
@@ -708,23 +769,74 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
708
769
  return;
709
770
  }
710
771
 
772
+ // Determine topic type for attributes
711
773
  if (msg.topic === this.topicStrings[TopicType.tx]) {
712
774
  topicType = TopicType.tx;
713
- await this.handleGossipedTx(p2pMessage.payload, msgId, source);
775
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
776
+ topicType = TopicType.checkpoint_attestation;
777
+ } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
778
+ topicType = TopicType.block_proposal;
779
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
780
+ topicType = TopicType.checkpoint_proposal;
714
781
  }
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);
782
+
783
+ // Process the message, optionally within a linked span for trace propagation
784
+ const processMessage = async () => {
785
+ if (msg.topic === this.topicStrings[TopicType.tx]) {
786
+ await this.handleGossipedTx(p2pMessage.payload, msgId, source);
787
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
788
+ if (this.clientType === P2PClientType.Full) {
789
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
790
+ }
791
+ } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
792
+ await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
793
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
794
+ await this.handleGossipedCheckpointProposal(p2pMessage.payload, msgId, source);
795
+ } else {
796
+ this.logger.error(`Received message on unknown topic: ${msg.topic}`);
719
797
  }
720
- }
721
- if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
722
- topicType = TopicType.block_proposal;
723
- await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
798
+ };
799
+
800
+ const latency = p2pMessage.timestamp !== undefined ? msgReceivedTime - p2pMessage.timestamp.getTime() : undefined;
801
+ const propagatedContext = p2pMessage.traceContext
802
+ ? this.telemetry.extractPropagatedContext(p2pMessage.traceContext)
803
+ : undefined;
804
+
805
+ if (propagatedContext) {
806
+ await this.tracer.startActiveSpan(
807
+ 'LibP2PService.processMessage',
808
+ {
809
+ attributes: {
810
+ [Attributes.TOPIC_NAME]: topicType!,
811
+ [Attributes.PEER_ID]: source.toString(),
812
+ },
813
+ },
814
+ propagatedContext,
815
+ async span => {
816
+ try {
817
+ await processMessage();
818
+ span.setStatus({
819
+ code: SpanStatusCode.OK,
820
+ });
821
+ } catch (err) {
822
+ span.setStatus({
823
+ code: SpanStatusCode.ERROR,
824
+ message: String(err),
825
+ });
826
+ if (typeof err === 'string' || (err && err instanceof Error)) {
827
+ span.recordException(err);
828
+ }
829
+ throw err;
830
+ } finally {
831
+ span.end();
832
+ }
833
+ },
834
+ );
835
+ } else {
836
+ await processMessage();
724
837
  }
725
838
 
726
- if (p2pMessage.timestamp !== undefined && topicType !== undefined) {
727
- const latency = msgReceivedTime - p2pMessage.timestamp.getTime();
839
+ if (latency !== undefined && topicType !== undefined) {
728
840
  this.instrumentation.recordMessageLatency(topicType, latency);
729
841
  }
730
842
 
@@ -801,27 +913,29 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
801
913
  }
802
914
 
803
915
  /**
804
- * Process Attestation From Peer
805
- * When a proposal is received from a peer, we add it to the attestation pool, so it can be accessed by other services.
806
- *
807
- * @param attestation - The attestation to process.
916
+ * Process a checkpoint attestation from a peer.
917
+ * Validates the attestation and adds it to the pool.
808
918
  */
809
- private async processAttestationFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
810
- const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockAttestation>> = async () => {
811
- const attestation = BlockAttestation.fromBuffer(payloadData);
812
- const pool = this.mempools.attestationPool!;
813
- const isValid = await this.validateAttestation(source, attestation);
814
- const exists = isValid && (await pool.hasAttestation(attestation));
919
+ private async processCheckpointAttestationFromPeer(
920
+ payloadData: Buffer,
921
+ msgId: string,
922
+ source: PeerId,
923
+ ): Promise<void> {
924
+ const validationFunc: () => Promise<ReceivedMessageValidationResult<CheckpointAttestation>> = async () => {
925
+ const attestation = CheckpointAttestation.fromBuffer(payloadData);
926
+ const pool = this.mempools.attestationPool;
927
+ const isValid = await this.validateCheckpointAttestation(source, attestation);
928
+ const exists = isValid && (await pool.hasCheckpointAttestation(attestation));
815
929
 
816
930
  let canAdd = true;
817
931
  if (isValid && !exists) {
818
932
  const slot = attestation.payload.header.slotNumber;
819
933
  const { committee } = await this.epochCache.getCommittee(slot);
820
934
  const committeeSize = committee?.length ?? 0;
821
- canAdd = await pool.canAddAttestation(attestation, committeeSize);
935
+ canAdd = await pool.canAddCheckpointAttestation(attestation, committeeSize);
822
936
  }
823
937
 
824
- this.logger.trace(`Validate propagated block attestation`, {
938
+ this.logger.trace(`Validate propagated checkpoint attestation`, {
825
939
  isValid,
826
940
  exists,
827
941
  canAdd,
@@ -834,7 +948,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
834
948
  } else if (exists) {
835
949
  return { result: TopicValidatorResult.Ignore, obj: attestation };
836
950
  } else if (!canAdd) {
837
- this.logger.warn(`Dropping block attestation due to per-(slot, proposalId) attestation cap`, {
951
+ this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
838
952
  slot: attestation.payload.header.slotNumber.toString(),
839
953
  archive: attestation.archive.toString(),
840
954
  source: source.toString(),
@@ -845,11 +959,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
845
959
  }
846
960
  };
847
961
 
848
- const { result, obj: attestation } = await this.validateReceivedMessage<BlockAttestation>(
962
+ const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
849
963
  validationFunc,
850
964
  msgId,
851
965
  source,
852
- TopicType.block_attestation,
966
+ TopicType.checkpoint_attestation,
853
967
  );
854
968
 
855
969
  if (result !== TopicValidatorResult.Accept || !attestation) {
@@ -857,7 +971,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
857
971
  }
858
972
 
859
973
  this.logger.debug(
860
- `Received attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
974
+ `Received checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
861
975
  {
862
976
  p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
863
977
  slot: attestation.slotNumber,
@@ -866,7 +980,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
866
980
  },
867
981
  );
868
982
 
869
- await this.mempools.attestationPool!.addAttestations([attestation]);
983
+ await this.mempools.attestationPool.addCheckpointAttestations([attestation]);
870
984
  }
871
985
 
872
986
  private async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
@@ -875,16 +989,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
875
989
  const isValid = await this.validateBlockProposal(source, block);
876
990
  const pool = this.mempools.attestationPool;
877
991
 
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));
992
+ const exists = isValid && (await pool.hasBlockProposal(block));
993
+ const canAdd = isValid && (await pool.canAddProposal(block));
882
994
 
883
995
  this.logger.trace(`Validate propagated block proposal`, {
884
996
  isValid,
885
997
  exists,
886
998
  canAdd,
887
- [Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
999
+ [Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
888
1000
  [Attributes.P2P_ID]: source.toString(),
889
1001
  });
890
1002
 
@@ -920,6 +1032,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
920
1032
  }
921
1033
 
922
1034
  // REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
1035
+ // REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
1036
+ // should not be here as it does not deal with p2p networking.
923
1037
  @trackSpan('Libp2pService.processValidBlockProposal', async block => ({
924
1038
  [Attributes.SLOT_NUMBER]: block.slotNumber,
925
1039
  [Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
@@ -927,21 +1041,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
927
1041
  }))
928
1042
  private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
929
1043
  const slot = block.slotNumber;
930
- const previousSlot = SlotNumber(slot - 1);
931
1044
  this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
932
1045
  p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
933
- slot: block.slotNumber,
934
- archive: block.archive.toString(),
935
1046
  source: sender.toString(),
1047
+ ...block.toBlockInfo(),
936
1048
  });
937
- const attestationsForPreviousSlot = await this.mempools.attestationPool?.getAttestationsForSlot(previousSlot);
938
- if (attestationsForPreviousSlot !== undefined) {
939
- this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
940
- }
941
1049
 
942
- // Attempt to add proposal, then mark the txs in this proposal as non-evictable
1050
+ // Attempt to add proposal
943
1051
  try {
944
- await this.mempools.attestationPool?.addBlockProposal(block);
1052
+ await this.mempools.attestationPool.addBlockProposal(block);
945
1053
  } catch (err: unknown) {
946
1054
  // Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
947
1055
  if (err instanceof ProposalSlotCapExceededError) {
@@ -954,34 +1062,125 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
954
1062
  }
955
1063
  throw err;
956
1064
  }
1065
+
1066
+ // Mark the txs in this proposal as non-evictable
957
1067
  await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
958
- const attestations = await this.blockReceivedCallback(block, sender);
959
1068
 
960
- // TODO: fix up this pattern - the abstraction is not nice
961
- // The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
962
- if (attestations?.length) {
963
- for (const attestation of attestations) {
964
- this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber}`, {
965
- p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
966
- slot: attestation.slotNumber,
967
- archive: attestation.archive.toString(),
1069
+ // Call the block received callback to validate the proposal.
1070
+ // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1071
+ const isValid = await this.blockReceivedCallback(block, sender);
1072
+ if (!isValid) {
1073
+ this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1074
+ }
1075
+ }
1076
+
1077
+ /**
1078
+ * Handle a gossiped checkpoint proposal.
1079
+ * Validates and processes the checkpoint proposal, then triggers the callback for attestation.
1080
+ */
1081
+ private async handleGossipedCheckpointProposal(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
1082
+ // TODO(palla/mbps): This pattern is repeated across multiple message handlers, consider abstracting it.
1083
+ const validationFunc: () => Promise<ReceivedMessageValidationResult<CheckpointProposal>> = async () => {
1084
+ const checkpoint = CheckpointProposal.fromBuffer(payloadData);
1085
+ const isValid = await this.validateCheckpointProposal(source, checkpoint);
1086
+ const pool = this.mempools.attestationPool;
1087
+
1088
+ const exists = isValid && (await pool.hasCheckpointProposal(checkpoint));
1089
+ const canAdd = isValid && (await pool.canAddCheckpointProposal(checkpoint));
1090
+
1091
+ this.logger.trace(`Validate propagated checkpoint proposal`, {
1092
+ isValid,
1093
+ exists,
1094
+ canAdd,
1095
+ [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1096
+ [Attributes.P2P_ID]: source.toString(),
1097
+ });
1098
+
1099
+ if (!isValid) {
1100
+ return { result: TopicValidatorResult.Reject };
1101
+ } else if (exists) {
1102
+ return { result: TopicValidatorResult.Ignore, obj: checkpoint };
1103
+ } else if (!canAdd) {
1104
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
1105
+ this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1106
+ slot: checkpoint.slotNumber.toString(),
1107
+ archive: checkpoint.archive.toString(),
1108
+ source: source.toString(),
968
1109
  });
969
- await this.broadcastAttestation(attestation);
1110
+ return { result: TopicValidatorResult.Reject };
1111
+ } else {
1112
+ return { result: TopicValidatorResult.Accept, obj: checkpoint };
970
1113
  }
1114
+ };
1115
+
1116
+ const { result, obj: checkpoint } = await this.validateReceivedMessage<CheckpointProposal>(
1117
+ validationFunc,
1118
+ msgId,
1119
+ source,
1120
+ TopicType.checkpoint_proposal,
1121
+ );
1122
+
1123
+ if (result !== TopicValidatorResult.Accept || !checkpoint) {
1124
+ return;
971
1125
  }
1126
+
1127
+ await this.processValidCheckpointProposal(checkpoint, source);
972
1128
  }
973
1129
 
974
1130
  /**
975
- * Broadcast an attestation to all peers.
976
- * @param attestation - The attestation to broadcast.
1131
+ * Process a validated checkpoint proposal.
1132
+ * Extracts and processes the last block proposal (if present) first, then processes the checkpoint.
1133
+ * The block callback is invoked before the checkpoint callback.
977
1134
  */
978
- @trackSpan('Libp2pService.broadcastAttestation', async attestation => ({
979
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
980
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
981
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1135
+ @trackSpan('Libp2pService.processValidCheckpointProposal', async checkpoint => ({
1136
+ [Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
1137
+ [Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
1138
+ [Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then(i => i.toString()),
982
1139
  }))
983
- private async broadcastAttestation(attestation: BlockAttestation) {
984
- await this.propagate(attestation);
1140
+ private async processValidCheckpointProposal(checkpoint: CheckpointProposal, sender: PeerId) {
1141
+ const slot = checkpoint.slotNumber;
1142
+ this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
1143
+ p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
1144
+ slot: checkpoint.slotNumber,
1145
+ archive: checkpoint.archive.toString(),
1146
+ source: sender.toString(),
1147
+ });
1148
+
1149
+ // Extract block proposal before adding to pool (pool stores them separately)
1150
+ const blockProposal = checkpoint.getBlockProposal();
1151
+
1152
+ // Add proposal to the pool (this extracts and stores block proposal separately)
1153
+ await this.mempools.attestationPool.addCheckpointProposal(checkpoint);
1154
+
1155
+ // Mark txs as non-evictable if present (from the last block)
1156
+ if (checkpoint.txHashes.length > 0) {
1157
+ await this.mempools.txPool.markTxsAsNonEvictable(checkpoint.txHashes);
1158
+ }
1159
+
1160
+ // If there was a last block proposal, invoke the block callback first for validation.
1161
+ // Note: The block proposal is already stored in the pool by addCheckpointProposal.
1162
+ if (blockProposal) {
1163
+ const isValid = await this.blockReceivedCallback(blockProposal, sender);
1164
+ if (!isValid) {
1165
+ this.logger.warn(`Block proposal from checkpoint failed validation`, {
1166
+ slot: slot.toString(),
1167
+ archive: checkpoint.archive.toString(),
1168
+ blockNumber: blockProposal.blockNumber.toString(),
1169
+ });
1170
+ return;
1171
+ }
1172
+ }
1173
+
1174
+ // Call the checkpoint received callback with the core version (without lastBlock)
1175
+ // to validate and potentially generate attestations
1176
+ const attestations = await this.checkpointReceivedCallback(checkpoint.toCore(), sender);
1177
+ if (attestations && attestations.length > 0) {
1178
+ // If the callback returned attestations, add them to the pool and propagate them
1179
+ await this.mempools.attestationPool.addCheckpointAttestations(attestations);
1180
+ for (const attestation of attestations) {
1181
+ await this.propagate(attestation);
1182
+ }
1183
+ }
985
1184
  }
986
1185
 
987
1186
  /**
@@ -1047,7 +1246,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1047
1246
  }
1048
1247
 
1049
1248
  // 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());
1249
+ const proposal = await this.mempools.attestationPool.getBlockProposal(request.blockHash.toString());
1051
1250
  if (proposal) {
1052
1251
  // Build intersected indices
1053
1252
  const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
@@ -1138,7 +1337,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1138
1337
  }))
1139
1338
  private async validateRequestedBlock(
1140
1339
  requestedBlockNumber: Fr,
1141
- responseBlock: L2Block,
1340
+ responseBlock: L2BlockNew,
1142
1341
  peerId: PeerId,
1143
1342
  ): Promise<boolean> {
1144
1343
  try {
@@ -1172,6 +1371,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1172
1371
  private createRequestedTxValidator(): TxValidator {
1173
1372
  return new AggregateTxValidator(
1174
1373
  new DataTxValidator(),
1374
+ new SizeTxValidator(),
1175
1375
  new MetadataTxValidator({
1176
1376
  l1ChainId: new Fr(this.config.l1ChainId),
1177
1377
  rollupVersion: new Fr(this.config.rollupVersion),
@@ -1366,19 +1566,20 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1366
1566
  }
1367
1567
 
1368
1568
  /**
1369
- * Validate an attestation.
1569
+ * Validate a checkpoint attestation.
1370
1570
  *
1371
- * @param attestation - The attestation to validate.
1372
- * @returns True if the attestation is valid, false otherwise.
1571
+ * @param attestation - The checkpoint attestation to validate.
1572
+ * @returns True if the checkpoint attestation is valid, false otherwise.
1373
1573
  */
1374
- @trackSpan('Libp2pService.validateAttestation', async (_, attestation) => ({
1574
+ @trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
1375
1575
  [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1376
1576
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1377
1577
  [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1378
1578
  }))
1379
- public async validateAttestation(peerId: PeerId, attestation: BlockAttestation): Promise<boolean> {
1380
- const severity = await this.attestationValidator.validate(attestation);
1579
+ public async validateCheckpointAttestation(peerId: PeerId, attestation: CheckpointAttestation): Promise<boolean> {
1580
+ const severity = await this.checkpointAttestationValidator.validate(attestation);
1381
1581
  if (severity) {
1582
+ this.logger.debug(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1382
1583
  this.peerManager.penalizePeer(peerId, severity);
1383
1584
  return false;
1384
1585
  }
@@ -1393,7 +1594,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1393
1594
  * @returns True if the block proposal is valid, false otherwise.
1394
1595
  */
1395
1596
  @trackSpan('Libp2pService.validateBlockProposal', (_peerId, block) => ({
1396
- [Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
1597
+ [Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
1397
1598
  }))
1398
1599
  public async validateBlockProposal(peerId: PeerId, block: BlockProposal): Promise<boolean> {
1399
1600
  const severity = await this.blockProposalValidator.validate(block);
@@ -1406,6 +1607,26 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1406
1607
  return true;
1407
1608
  }
1408
1609
 
1610
+ /**
1611
+ * Validate a checkpoint proposal.
1612
+ *
1613
+ * @param checkpoint - The checkpoint proposal to validate.
1614
+ * @returns True if the checkpoint proposal is valid, false otherwise.
1615
+ */
1616
+ @trackSpan('Libp2pService.validateCheckpointProposal', (_peerId, checkpoint) => ({
1617
+ [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1618
+ }))
1619
+ public async validateCheckpointProposal(peerId: PeerId, checkpoint: CheckpointProposal): Promise<boolean> {
1620
+ const severity = await this.checkpointProposalValidator.validate(checkpoint);
1621
+ if (severity) {
1622
+ this.logger.debug(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1623
+ this.peerManager.penalizePeer(peerId, severity);
1624
+ return false;
1625
+ }
1626
+
1627
+ return true;
1628
+ }
1629
+
1409
1630
  public getPeerScore(peerId: PeerId): number {
1410
1631
  return this.node.services.pubsub.score.score(peerId.toString());
1411
1632
  }