@aztec/p2p 0.0.1-commit.f295ac2 → 0.0.1-commit.f8ca9b2f3

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 (443) hide show
  1. package/dest/bootstrap/bootstrap.d.ts +4 -3
  2. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  3. package/dest/bootstrap/bootstrap.js +4 -4
  4. package/dest/client/factory.d.ts +5 -5
  5. package/dest/client/factory.d.ts.map +1 -1
  6. package/dest/client/factory.js +47 -13
  7. package/dest/client/interface.d.ts +33 -15
  8. package/dest/client/interface.d.ts.map +1 -1
  9. package/dest/client/p2p_client.d.ts +35 -36
  10. package/dest/client/p2p_client.d.ts.map +1 -1
  11. package/dest/client/p2p_client.js +115 -139
  12. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +2 -0
  13. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +1 -0
  14. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +305 -0
  15. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +73 -0
  16. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +1 -0
  17. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +8 -0
  18. package/dest/config.d.ts +24 -3
  19. package/dest/config.d.ts.map +1 -1
  20. package/dest/config.js +16 -2
  21. package/dest/index.d.ts +2 -1
  22. package/dest/index.d.ts.map +1 -1
  23. package/dest/index.js +1 -0
  24. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +102 -88
  25. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  26. package/dest/mem_pools/attestation_pool/attestation_pool.js +436 -3
  27. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
  28. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
  30. package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
  31. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  32. package/dest/mem_pools/attestation_pool/index.js +1 -2
  33. package/dest/mem_pools/index.d.ts +3 -2
  34. package/dest/mem_pools/index.d.ts.map +1 -1
  35. package/dest/mem_pools/index.js +1 -1
  36. package/dest/mem_pools/instrumentation.d.ts +1 -1
  37. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  38. package/dest/mem_pools/instrumentation.js +2 -2
  39. package/dest/mem_pools/interface.d.ts +5 -5
  40. package/dest/mem_pools/interface.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +3 -3
  42. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +3 -2
  44. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -1
  45. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +3 -2
  46. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +3 -3
  48. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +8 -1
  50. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +3 -3
  51. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +2 -0
  53. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
  54. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
  55. package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
  56. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
  57. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
  58. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
  59. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +87 -0
  60. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  61. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +180 -0
  62. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
  63. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
  64. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +119 -0
  65. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
  66. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +90 -0
  68. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
  69. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
  70. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +89 -0
  71. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
  72. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
  73. package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
  74. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +131 -0
  75. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
  76. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +17 -0
  77. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
  78. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  79. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +63 -0
  80. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
  81. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  82. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +91 -0
  83. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
  84. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  85. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +70 -0
  86. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
  87. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
  88. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +63 -0
  89. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
  90. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
  91. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
  92. package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
  93. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
  94. package/dest/mem_pools/tx_pool_v2/index.js +5 -0
  95. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +197 -0
  96. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
  97. package/dest/mem_pools/tx_pool_v2/interfaces.js +6 -0
  98. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +93 -0
  99. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
  100. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +127 -0
  101. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
  102. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
  103. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
  104. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +99 -0
  105. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
  106. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +332 -0
  107. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +55 -0
  108. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
  109. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +156 -0
  110. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +69 -0
  111. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
  112. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +751 -0
  113. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +3 -3
  114. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/attestation_validator/attestation_validator.js +41 -10
  116. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
  117. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  118. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +18 -6
  119. package/dest/msg_validators/clock_tolerance.d.ts +21 -0
  120. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -0
  121. package/dest/msg_validators/clock_tolerance.js +37 -0
  122. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -3
  123. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  124. package/dest/msg_validators/proposal_validator/proposal_validator.js +55 -31
  125. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +3 -3
  126. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -1
  127. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +93 -64
  128. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +3 -3
  129. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  130. package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
  131. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  132. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  133. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +20 -6
  134. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  135. package/dest/msg_validators/tx_validator/block_header_validator.js +4 -3
  136. package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
  137. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  138. package/dest/msg_validators/tx_validator/data_validator.js +4 -1
  139. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +15 -4
  140. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  141. package/dest/msg_validators/tx_validator/double_spend_validator.js +7 -6
  142. package/dest/msg_validators/tx_validator/factory.d.ts +8 -3
  143. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  144. package/dest/msg_validators/tx_validator/factory.js +21 -11
  145. package/dest/msg_validators/tx_validator/gas_validator.d.ts +3 -2
  146. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  147. package/dest/msg_validators/tx_validator/gas_validator.js +3 -2
  148. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  149. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  150. package/dest/msg_validators/tx_validator/index.js +1 -0
  151. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
  152. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  153. package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
  154. package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
  155. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  156. package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
  157. package/dest/msg_validators/tx_validator/size_validator.d.ts +8 -0
  158. package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
  159. package/dest/msg_validators/tx_validator/size_validator.js +23 -0
  160. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +22 -5
  161. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  162. package/dest/msg_validators/tx_validator/timestamp_validator.js +4 -4
  163. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
  164. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
  165. package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
  166. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
  167. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  168. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -2
  169. package/dest/services/data_store.d.ts +1 -1
  170. package/dest/services/data_store.d.ts.map +1 -1
  171. package/dest/services/data_store.js +10 -6
  172. package/dest/services/discv5/discV5_service.js +1 -1
  173. package/dest/services/dummy_service.d.ts +22 -2
  174. package/dest/services/dummy_service.d.ts.map +1 -1
  175. package/dest/services/dummy_service.js +45 -0
  176. package/dest/services/encoding.d.ts +2 -2
  177. package/dest/services/encoding.d.ts.map +1 -1
  178. package/dest/services/encoding.js +4 -5
  179. package/dest/services/gossipsub/index.d.ts +3 -0
  180. package/dest/services/gossipsub/index.d.ts.map +1 -0
  181. package/dest/services/gossipsub/index.js +2 -0
  182. package/dest/services/gossipsub/scoring.d.ts +21 -3
  183. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  184. package/dest/services/gossipsub/scoring.js +24 -7
  185. package/dest/services/gossipsub/topic_score_params.d.ts +161 -0
  186. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  187. package/dest/services/gossipsub/topic_score_params.js +324 -0
  188. package/dest/services/index.d.ts +2 -1
  189. package/dest/services/index.d.ts.map +1 -1
  190. package/dest/services/index.js +1 -0
  191. package/dest/services/libp2p/instrumentation.d.ts +1 -1
  192. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  193. package/dest/services/libp2p/instrumentation.js +14 -3
  194. package/dest/services/libp2p/libp2p_service.d.ts +91 -36
  195. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  196. package/dest/services/libp2p/libp2p_service.js +407 -303
  197. package/dest/services/peer-manager/metrics.d.ts +2 -2
  198. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  199. package/dest/services/peer-manager/metrics.js +20 -5
  200. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  201. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  202. package/dest/services/peer-manager/peer_scoring.js +33 -4
  203. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +47 -0
  204. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
  205. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +566 -0
  206. package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
  207. package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
  208. package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
  209. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +50 -0
  210. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
  211. package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
  212. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +37 -0
  213. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
  214. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +151 -0
  215. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +54 -0
  216. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
  217. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +139 -0
  218. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
  219. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
  220. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
  221. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
  222. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
  223. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
  224. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
  225. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  226. package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
  227. package/dest/services/reqresp/interface.d.ts +14 -3
  228. package/dest/services/reqresp/interface.d.ts.map +1 -1
  229. package/dest/services/reqresp/interface.js +17 -3
  230. package/dest/services/reqresp/metrics.d.ts +6 -5
  231. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  232. package/dest/services/reqresp/metrics.js +17 -5
  233. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
  234. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  235. package/dest/services/reqresp/protocols/block_txs/bitvector.js +5 -0
  236. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
  237. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  238. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +27 -9
  239. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +29 -6
  240. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  241. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +59 -13
  242. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  243. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  244. package/dest/services/reqresp/protocols/tx.js +20 -0
  245. package/dest/services/reqresp/reqresp.d.ts +6 -1
  246. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  247. package/dest/services/reqresp/reqresp.js +69 -26
  248. package/dest/services/service.d.ts +38 -1
  249. package/dest/services/service.d.ts.map +1 -1
  250. package/dest/services/tx_collection/config.d.ts +10 -1
  251. package/dest/services/tx_collection/config.d.ts.map +1 -1
  252. package/dest/services/tx_collection/config.js +25 -1
  253. package/dest/services/tx_collection/fast_tx_collection.d.ts +7 -4
  254. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  255. package/dest/services/tx_collection/fast_tx_collection.js +34 -13
  256. package/dest/services/tx_collection/file_store_tx_collection.d.ts +44 -0
  257. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  258. package/dest/services/tx_collection/file_store_tx_collection.js +118 -0
  259. package/dest/services/tx_collection/file_store_tx_source.d.ts +27 -0
  260. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  261. package/dest/services/tx_collection/file_store_tx_source.js +57 -0
  262. package/dest/services/tx_collection/index.d.ts +3 -1
  263. package/dest/services/tx_collection/index.d.ts.map +1 -1
  264. package/dest/services/tx_collection/index.js +2 -0
  265. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  266. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  267. package/dest/services/tx_collection/instrumentation.js +9 -2
  268. package/dest/services/tx_collection/proposal_tx_collector.d.ts +48 -0
  269. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
  270. package/dest/services/tx_collection/proposal_tx_collector.js +49 -0
  271. package/dest/services/tx_collection/slow_tx_collection.d.ts +5 -3
  272. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  273. package/dest/services/tx_collection/slow_tx_collection.js +48 -19
  274. package/dest/services/tx_collection/tx_collection.d.ts +23 -13
  275. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  276. package/dest/services/tx_collection/tx_collection.js +62 -6
  277. package/dest/services/tx_collection/tx_collection_sink.d.ts +15 -6
  278. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  279. package/dest/services/tx_collection/tx_collection_sink.js +13 -7
  280. package/dest/services/tx_file_store/config.d.ts +16 -0
  281. package/dest/services/tx_file_store/config.d.ts.map +1 -0
  282. package/dest/services/tx_file_store/config.js +22 -0
  283. package/dest/services/tx_file_store/index.d.ts +4 -0
  284. package/dest/services/tx_file_store/index.d.ts.map +1 -0
  285. package/dest/services/tx_file_store/index.js +3 -0
  286. package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
  287. package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
  288. package/dest/services/tx_file_store/instrumentation.js +29 -0
  289. package/dest/services/tx_file_store/tx_file_store.d.ts +47 -0
  290. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
  291. package/dest/services/tx_file_store/tx_file_store.js +149 -0
  292. package/dest/services/tx_provider.d.ts +5 -5
  293. package/dest/services/tx_provider.d.ts.map +1 -1
  294. package/dest/services/tx_provider.js +5 -4
  295. package/dest/services/tx_provider_instrumentation.d.ts +1 -1
  296. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  297. package/dest/services/tx_provider_instrumentation.js +5 -5
  298. package/dest/test-helpers/index.d.ts +3 -1
  299. package/dest/test-helpers/index.d.ts.map +1 -1
  300. package/dest/test-helpers/index.js +2 -0
  301. package/dest/test-helpers/make-test-p2p-clients.d.ts +3 -3
  302. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  303. package/dest/test-helpers/mock-pubsub.d.ts +27 -1
  304. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  305. package/dest/test-helpers/mock-pubsub.js +97 -2
  306. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  307. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  308. package/dest/test-helpers/reqresp-nodes.js +2 -1
  309. package/dest/test-helpers/test_tx_provider.d.ts +40 -0
  310. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
  311. package/dest/test-helpers/test_tx_provider.js +41 -0
  312. package/dest/test-helpers/testbench-utils.d.ts +158 -0
  313. package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
  314. package/dest/test-helpers/testbench-utils.js +360 -0
  315. package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
  316. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  317. package/dest/testbench/p2p_client_testbench_worker.js +213 -134
  318. package/dest/testbench/worker_client_manager.d.ts +51 -6
  319. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  320. package/dest/testbench/worker_client_manager.js +226 -44
  321. package/package.json +14 -14
  322. package/src/bootstrap/bootstrap.ts +7 -4
  323. package/src/client/factory.ts +78 -22
  324. package/src/client/interface.ts +39 -14
  325. package/src/client/p2p_client.ts +155 -166
  326. package/src/client/test/tx_proposal_collector/README.md +227 -0
  327. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +336 -0
  328. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
  329. package/src/config.ts +38 -2
  330. package/src/index.ts +1 -0
  331. package/src/mem_pools/attestation_pool/attestation_pool.ts +488 -91
  332. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
  333. package/src/mem_pools/attestation_pool/index.ts +9 -2
  334. package/src/mem_pools/index.ts +4 -1
  335. package/src/mem_pools/instrumentation.ts +2 -1
  336. package/src/mem_pools/interface.ts +4 -4
  337. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +2 -2
  338. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +2 -1
  339. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +2 -1
  340. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +10 -7
  341. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +4 -2
  342. package/src/mem_pools/tx_pool_v2/README.md +259 -0
  343. package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
  344. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
  345. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +234 -0
  346. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +147 -0
  347. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +118 -0
  348. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +111 -0
  349. package/src/mem_pools/tx_pool_v2/eviction/index.ts +23 -0
  350. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +164 -0
  351. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
  352. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
  353. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +86 -0
  354. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +72 -0
  355. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +31 -0
  356. package/src/mem_pools/tx_pool_v2/index.ts +12 -0
  357. package/src/mem_pools/tx_pool_v2/interfaces.ts +227 -0
  358. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +207 -0
  359. package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
  360. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +417 -0
  361. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +212 -0
  362. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +895 -0
  363. package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -14
  364. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +16 -10
  365. package/src/msg_validators/clock_tolerance.ts +51 -0
  366. package/src/msg_validators/proposal_validator/proposal_validator.ts +31 -31
  367. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +91 -67
  368. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +2 -2
  369. package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
  370. package/src/msg_validators/tx_validator/block_header_validator.ts +21 -8
  371. package/src/msg_validators/tx_validator/data_validator.ts +6 -2
  372. package/src/msg_validators/tx_validator/double_spend_validator.ts +15 -9
  373. package/src/msg_validators/tx_validator/factory.ts +64 -23
  374. package/src/msg_validators/tx_validator/gas_validator.ts +9 -3
  375. package/src/msg_validators/tx_validator/index.ts +1 -0
  376. package/src/msg_validators/tx_validator/metadata_validator.ts +6 -3
  377. package/src/msg_validators/tx_validator/phases_validator.ts +5 -3
  378. package/src/msg_validators/tx_validator/size_validator.ts +22 -0
  379. package/src/msg_validators/tx_validator/timestamp_validator.ts +25 -17
  380. package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
  381. package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
  382. package/src/services/data_store.ts +10 -7
  383. package/src/services/discv5/discV5_service.ts +1 -1
  384. package/src/services/dummy_service.ts +57 -0
  385. package/src/services/encoding.ts +4 -5
  386. package/src/services/gossipsub/README.md +626 -0
  387. package/src/services/gossipsub/index.ts +2 -0
  388. package/src/services/gossipsub/scoring.ts +29 -5
  389. package/src/services/gossipsub/topic_score_params.ts +451 -0
  390. package/src/services/index.ts +1 -0
  391. package/src/services/libp2p/instrumentation.ts +15 -2
  392. package/src/services/libp2p/libp2p_service.ts +437 -316
  393. package/src/services/peer-manager/metrics.ts +21 -4
  394. package/src/services/peer-manager/peer_scoring.ts +29 -1
  395. package/src/services/reqresp/batch-tx-requester/README.md +305 -0
  396. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +706 -0
  397. package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
  398. package/src/services/reqresp/batch-tx-requester/interface.ts +57 -0
  399. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +209 -0
  400. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +205 -0
  401. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
  402. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
  403. package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
  404. package/src/services/reqresp/interface.ts +31 -3
  405. package/src/services/reqresp/metrics.ts +34 -9
  406. package/src/services/reqresp/protocols/block_txs/bitvector.ts +7 -0
  407. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +35 -12
  408. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +74 -9
  409. package/src/services/reqresp/protocols/tx.ts +22 -0
  410. package/src/services/reqresp/reqresp.ts +79 -22
  411. package/src/services/service.ts +44 -0
  412. package/src/services/tx_collection/config.ts +41 -1
  413. package/src/services/tx_collection/fast_tx_collection.ts +44 -19
  414. package/src/services/tx_collection/file_store_tx_collection.ts +152 -0
  415. package/src/services/tx_collection/file_store_tx_source.ts +70 -0
  416. package/src/services/tx_collection/index.ts +6 -0
  417. package/src/services/tx_collection/instrumentation.ts +11 -2
  418. package/src/services/tx_collection/proposal_tx_collector.ts +112 -0
  419. package/src/services/tx_collection/slow_tx_collection.ts +57 -28
  420. package/src/services/tx_collection/tx_collection.ts +86 -20
  421. package/src/services/tx_collection/tx_collection_sink.ts +17 -7
  422. package/src/services/tx_file_store/config.ts +37 -0
  423. package/src/services/tx_file_store/index.ts +3 -0
  424. package/src/services/tx_file_store/instrumentation.ts +36 -0
  425. package/src/services/tx_file_store/tx_file_store.ts +173 -0
  426. package/src/services/tx_provider.ts +10 -9
  427. package/src/services/tx_provider_instrumentation.ts +11 -5
  428. package/src/test-helpers/index.ts +2 -0
  429. package/src/test-helpers/make-test-p2p-clients.ts +3 -3
  430. package/src/test-helpers/mock-pubsub.ts +133 -3
  431. package/src/test-helpers/reqresp-nodes.ts +2 -1
  432. package/src/test-helpers/test_tx_provider.ts +64 -0
  433. package/src/test-helpers/testbench-utils.ts +422 -0
  434. package/src/testbench/p2p_client_testbench_worker.ts +322 -127
  435. package/src/testbench/worker_client_manager.ts +304 -47
  436. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
  437. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  438. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
  439. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
  440. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  441. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
  442. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
  443. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
@@ -1,7 +1,7 @@
1
- import { SlotNumber } from '@aztec/foundation/branded-types';
1
+ import { IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
2
2
  import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
- import type { BlockProposal, CheckpointAttestation, CheckpointProposal } from '@aztec/stdlib/p2p';
4
+ import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore } from '@aztec/stdlib/p2p';
5
5
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
6
6
  import {
7
7
  makeBlockHeader,
@@ -10,8 +10,11 @@ import {
10
10
  makeCheckpointProposal,
11
11
  } from '@aztec/stdlib/testing';
12
12
 
13
- import type { AttestationPool } from './attestation_pool.js';
14
- import { MAX_PROPOSALS_PER_SLOT } from './kv_attestation_pool.js';
13
+ import {
14
+ type AttestationPool,
15
+ MAX_BLOCK_PROPOSALS_PER_POSITION,
16
+ MAX_CHECKPOINT_PROPOSALS_PER_SLOT,
17
+ } from './attestation_pool.js';
15
18
  import { mockCheckpointAttestation } from './mocks.js';
16
19
 
17
20
  const NUMBER_OF_SIGNERS_PER_TEST = 4;
@@ -58,7 +61,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
58
61
  const archive = Fr.random();
59
62
  const attestations = signers.slice(0, -1).map(signer => mockCheckpointAttestation(signer, slotNumber, archive));
60
63
 
61
- await ap.addCheckpointAttestations(attestations);
64
+ await ap.addOwnCheckpointAttestations(attestations);
62
65
 
63
66
  const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
64
67
  SlotNumber(slotNumber),
@@ -67,42 +70,31 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
67
70
  expect(retrievedAttestations.length).toBe(attestations.length);
68
71
  compareCheckpointAttestations(retrievedAttestations, attestations);
69
72
 
70
- // Check hasCheckpointAttestation for added attestations
71
- for (const attestation of attestations) {
72
- expect(await ap.hasCheckpointAttestation(attestation)).toBe(true);
73
- }
74
-
75
73
  const retrievedAttestationsForSlot = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
76
74
  expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
77
75
  compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
78
76
 
79
77
  // Add another one
80
78
  const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
81
- await ap.addCheckpointAttestations([newAttestation]);
79
+ await ap.addOwnCheckpointAttestations([newAttestation]);
82
80
  const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(
83
81
  SlotNumber(slotNumber),
84
82
  archive.toString(),
85
83
  );
86
84
  expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
87
85
  compareCheckpointAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
88
- expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(true);
89
86
  const retrievedAttestationsForSlotAfterAdd = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
90
87
  expect(retrievedAttestationsForSlotAfterAdd.length).toBe(attestations.length + 1);
91
88
  compareCheckpointAttestations(retrievedAttestationsForSlotAfterAdd, [...attestations, newAttestation]);
92
89
 
93
90
  // Delete by slot
94
- await ap.deleteCheckpointAttestationsOlderThan(SlotNumber(slotNumber + 1));
91
+ await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
95
92
 
96
93
  const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
97
94
  SlotNumber(slotNumber),
98
95
  archive.toString(),
99
96
  );
100
97
  expect(retreivedAttestationsAfterDelete.length).toBe(0);
101
- // Check hasCheckpointAttestation after deletion
102
- for (const attestation of attestations) {
103
- expect(await ap.hasCheckpointAttestation(attestation)).toBe(false);
104
- }
105
- expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(false);
106
98
  });
107
99
 
108
100
  it('should handle duplicate proposals in a slot', async () => {
@@ -118,7 +110,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
118
110
  }
119
111
 
120
112
  // Add them to store and check we end up with only one
121
- await ap.addCheckpointAttestations(attestations);
113
+ await ap.addOwnCheckpointAttestations(attestations);
122
114
 
123
115
  const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
124
116
  SlotNumber(slotNumber),
@@ -129,7 +121,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
129
121
  expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
130
122
 
131
123
  // Try adding them on another operation and check they are still not duplicated
132
- await ap.addCheckpointAttestations([attestations[0]]);
124
+ await ap.addOwnCheckpointAttestations([attestations[0]]);
133
125
  expect(
134
126
  await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString()),
135
127
  ).toHaveLength(1);
@@ -139,7 +131,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
139
131
  const slotNumbers = [1, 2, 3, 4];
140
132
  const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i]));
141
133
 
142
- await ap.addCheckpointAttestations(attestations);
134
+ await ap.addOwnCheckpointAttestations(attestations);
143
135
 
144
136
  for (const attestation of attestations) {
145
137
  const slot = attestation.payload.header.slotNumber;
@@ -157,7 +149,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
157
149
  const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()];
158
150
  const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i], archives[i]));
159
151
 
160
- await ap.addCheckpointAttestations(attestations);
152
+ await ap.addOwnCheckpointAttestations(attestations);
161
153
 
162
154
  for (const attestation of attestations) {
163
155
  const slot = attestation.payload.header.slotNumber;
@@ -177,12 +169,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
177
169
  ).flat();
178
170
  const proposalId = attestations[0].archive.toString();
179
171
 
180
- await ap.addCheckpointAttestations(attestations);
172
+ await ap.addOwnCheckpointAttestations(attestations);
181
173
 
182
174
  const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
183
175
  expect(attestationsForSlot1.length).toBe(signers.length);
184
176
 
185
- await ap.deleteCheckpointAttestationsOlderThan(SlotNumber(73));
177
+ await ap.deleteOlderThan(SlotNumber(73));
186
178
 
187
179
  const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
188
180
  SlotNumber(1),
@@ -199,119 +191,86 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
199
191
  const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
200
192
  const proposalId = proposal.archive.toString();
201
193
 
202
- await ap.addBlockProposal(proposal);
194
+ const result = await ap.tryAddBlockProposal(proposal);
195
+
196
+ expect(result.added).toBe(true);
197
+ expect(result.alreadyExists).toBe(false);
198
+ expect(result.count).toBe(1);
203
199
 
204
200
  const retrievedProposal = await ap.getBlockProposal(proposalId);
205
201
 
206
202
  expect(retrievedProposal).toBeDefined();
207
203
  expect(retrievedProposal!).toEqual(proposal);
208
-
209
- // Check hasBlockProposal with both id and object
210
- expect(await ap.hasBlockProposal(proposalId)).toBe(true);
211
- expect(await ap.hasBlockProposal(proposal)).toBe(true);
212
204
  });
213
205
 
214
206
  it('should return undefined for non-existent block proposal', async () => {
215
207
  const nonExistentId = Fr.random().toString();
216
208
  const retrievedProposal = await ap.getBlockProposal(nonExistentId);
217
209
  expect(retrievedProposal).toBeUndefined();
218
-
219
- // Check hasBlockProposal returns false for non-existent proposal
220
- expect(await ap.hasBlockProposal(nonExistentId)).toBe(false);
221
210
  });
222
211
 
223
- it('should update block proposal if added twice with same id', async () => {
212
+ it('should return alreadyExists when adding proposal with same id', async () => {
224
213
  const slotNumber = 420;
225
214
  const archive = Fr.random();
226
215
  const proposal1 = await mockBlockProposalForPool(signers[0], slotNumber, archive);
227
216
  const proposalId = proposal1.archive.toString();
228
217
 
229
- await ap.addBlockProposal(proposal1);
218
+ const result1 = await ap.tryAddBlockProposal(proposal1);
219
+ expect(result1.added).toBe(true);
220
+ expect(result1.alreadyExists).toBe(false);
230
221
 
231
222
  // Create a new proposal with same archive but different signer
232
223
  const proposal2 = await mockBlockProposalForPool(signers[1], slotNumber, archive);
233
224
 
234
- await ap.addBlockProposal(proposal2);
235
-
236
- const retrievedProposal = await ap.getBlockProposal(proposalId);
237
- expect(retrievedProposal).toBeDefined();
238
- // Should have the second proposal
239
- expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
240
- expect(retrievedProposal!.getSender()?.toString()).toBe(signers[1].address.toString());
241
- });
242
-
243
- it('should handle block proposals with different slots and same archive', async () => {
244
- const archive = Fr.random();
245
- const proposal1 = await mockBlockProposalForPool(signers[0], 100, archive);
246
- const proposal2 = await mockBlockProposalForPool(signers[1], 200, archive);
247
- const proposalId = archive.toString();
248
-
249
- await ap.addBlockProposal(proposal1);
250
- await ap.addBlockProposal(proposal2);
225
+ const result2 = await ap.tryAddBlockProposal(proposal2);
226
+ expect(result2.added).toBe(false);
227
+ expect(result2.alreadyExists).toBe(true);
251
228
 
252
- // Should get the latest one added
229
+ // Should still have the first proposal
253
230
  const retrievedProposal = await ap.getBlockProposal(proposalId);
254
231
  expect(retrievedProposal).toBeDefined();
255
- expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
256
- expect(retrievedProposal!.slotNumber).toBe(SlotNumber(200));
232
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer());
233
+ expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
257
234
  });
258
235
  });
259
236
 
260
237
  describe('CheckpointProposal in attestation pool', () => {
261
- const mockCheckpointProposalForPool = (
238
+ const mockCheckpointProposalForPool = async (
262
239
  signer: Secp256k1Signer,
263
240
  slotNumber: number,
264
241
  archive: Fr = Fr.random(),
265
- ): Promise<CheckpointProposal> => {
242
+ ): Promise<CheckpointProposalCore> => {
266
243
  const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
267
244
  const blockHeader = makeBlockHeader(1);
268
- return makeCheckpointProposal({
245
+ const proposal = await makeCheckpointProposal({
269
246
  signer,
270
247
  checkpointHeader,
271
248
  archiveRoot: archive,
272
249
  lastBlock: { blockHeader },
273
250
  });
251
+ // Return the core version since tryAddCheckpointProposal now takes CheckpointProposalCore
252
+ return proposal.toCore();
274
253
  };
275
254
 
276
- it('should add and retrieve checkpoint proposal as core (without lastBlock)', async () => {
255
+ it('should add and retrieve checkpoint proposal', async () => {
277
256
  const slotNumber = 420;
278
257
  const archive = Fr.random();
279
258
  const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
280
259
  const proposalId = proposal.archive.toString();
281
260
 
282
- await ap.addCheckpointProposal(proposal);
261
+ const result = await ap.tryAddCheckpointProposal(proposal);
262
+
263
+ expect(result.added).toBe(true);
264
+ expect(result.alreadyExists).toBe(false);
265
+ expect(result.count).toBe(1);
283
266
 
284
267
  const retrievedProposal = await ap.getCheckpointProposal(proposalId);
285
268
 
286
269
  expect(retrievedProposal).toBeDefined();
287
- // Should return core version (without lastBlock)
288
- expect(retrievedProposal!.toBuffer()).toEqual(proposal.toCore().toBuffer());
289
-
290
- // Check hasCheckpointProposal with both id and object
291
- expect(await ap.hasCheckpointProposal(proposalId)).toBe(true);
292
- expect(await ap.hasCheckpointProposal(proposal)).toBe(true);
293
- });
294
-
295
- it('should extract and store block proposal when adding checkpoint proposal with lastBlock', async () => {
296
- const slotNumber = 420;
297
- const archive = Fr.random();
298
- const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
299
- const proposalId = proposal.archive.toString();
300
-
301
- // Verify the proposal has a lastBlock
302
- const expectedBlockProposal = proposal.getBlockProposal();
303
- expect(expectedBlockProposal).toBeDefined();
304
-
305
- await ap.addCheckpointProposal(proposal);
306
-
307
- // The block proposal should be stored separately and retrievable
308
- const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
309
- expect(retrievedBlockProposal).toBeDefined();
310
- expect(retrievedBlockProposal!.archive.toString()).toBe(archive.toString());
311
- expect(retrievedBlockProposal!.blockHeader.toBuffer()).toEqual(expectedBlockProposal!.blockHeader.toBuffer());
270
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
312
271
  });
313
272
 
314
- it('should not store block proposal when checkpoint proposal has no lastBlock', async () => {
273
+ it('should handle checkpoint proposal without lastBlock (caller extracts and adds block separately)', async () => {
315
274
  const slotNumber = 420;
316
275
  const archive = Fr.random();
317
276
  const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
@@ -324,13 +283,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
324
283
  });
325
284
  const proposalId = proposal.archive.toString();
326
285
 
327
- await ap.addCheckpointProposal(proposal);
286
+ // Add the checkpoint core - block extraction is now caller responsibility
287
+ await ap.tryAddCheckpointProposal(proposal.toCore());
328
288
 
329
289
  // The checkpoint proposal should be stored
330
290
  const retrievedCheckpointProposal = await ap.getCheckpointProposal(proposalId);
331
291
  expect(retrievedCheckpointProposal).toBeDefined();
332
292
 
333
- // But no block proposal should be stored (archive key won't have a block proposal)
293
+ // No block proposal was extracted (it had none anyway)
334
294
  const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
335
295
  expect(retrievedBlockProposal).toBeUndefined();
336
296
  });
@@ -339,43 +299,423 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
339
299
  const nonExistentId = Fr.random().toString();
340
300
  const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
341
301
  expect(retrievedProposal).toBeUndefined();
342
-
343
- // Check hasCheckpointProposal returns false for non-existent proposal
344
- expect(await ap.hasCheckpointProposal(nonExistentId)).toBe(false);
345
302
  });
346
303
 
347
- it('should update checkpoint proposal if added twice with same id', async () => {
304
+ it('should return alreadyExists when adding proposal with same id', async () => {
348
305
  const slotNumber = 420;
349
306
  const archive = Fr.random();
350
307
  const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
351
308
  const proposalId = proposal1.archive.toString();
352
309
 
353
- await ap.addCheckpointProposal(proposal1);
310
+ const result1 = await ap.tryAddCheckpointProposal(proposal1);
311
+ expect(result1.added).toBe(true);
312
+ expect(result1.alreadyExists).toBe(false);
354
313
 
355
314
  // Create a new proposal with same archive but different signer
356
315
  const proposal2 = await mockCheckpointProposalForPool(signers[1], slotNumber, archive);
357
316
 
358
- await ap.addCheckpointProposal(proposal2);
317
+ const result2 = await ap.tryAddCheckpointProposal(proposal2);
318
+ expect(result2.added).toBe(false);
319
+ expect(result2.alreadyExists).toBe(true);
359
320
 
321
+ // Should still have the first proposal
360
322
  const retrievedProposal = await ap.getCheckpointProposal(proposalId);
361
323
  expect(retrievedProposal).toBeDefined();
362
- // Should have the second proposal (as core)
363
- expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toCore().toBuffer());
364
- expect(retrievedProposal!.getSender()?.toString()).toBe(signers[1].address.toString());
324
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer());
325
+ expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
365
326
  });
366
327
 
367
- it('should throw ProposalSlotCapExceededError when exceeding capacity', async () => {
328
+ it('should return added=false when exceeding capacity', async () => {
368
329
  const slotNumber = 420;
369
330
 
370
- // Add MAX_PROPOSALS_PER_SLOT proposals
371
- for (let i = 0; i < MAX_PROPOSALS_PER_SLOT; i++) {
331
+ // Add MAX_CHECKPOINT_PROPOSALS_PER_SLOT proposals
332
+ for (let i = 0; i < MAX_CHECKPOINT_PROPOSALS_PER_SLOT; i++) {
372
333
  const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
373
- await ap.addCheckpointProposal(proposal);
334
+ const result = await ap.tryAddCheckpointProposal(proposal);
335
+ expect(result.added).toBe(true);
336
+ expect(result.count).toBe(i + 1);
374
337
  }
375
338
 
376
- // The next proposal should throw
339
+ // The next proposal should not be added
377
340
  const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
378
- await expect(ap.addCheckpointProposal(extraProposal)).rejects.toThrow('Maximum checkpoint proposals per slot');
341
+ const result = await ap.tryAddCheckpointProposal(extraProposal);
342
+ expect(result.added).toBe(false);
343
+ expect(result.alreadyExists).toBe(false);
344
+ expect(result.count).toBe(MAX_CHECKPOINT_PROPOSALS_PER_SLOT);
345
+ });
346
+ });
347
+
348
+ describe('Duplicate proposal detection', () => {
349
+ const mockBlockProposalWithIndex = (
350
+ signer: Secp256k1Signer,
351
+ slotNumber: number,
352
+ indexWithinCheckpoint: number,
353
+ archive: Fr = Fr.random(),
354
+ ): Promise<BlockProposal> => {
355
+ const header = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) });
356
+ return makeBlockProposal({
357
+ signer,
358
+ blockHeader: header,
359
+ archiveRoot: archive,
360
+ indexWithinCheckpoint: IndexWithinCheckpoint(indexWithinCheckpoint),
361
+ });
362
+ };
363
+
364
+ describe('tryAddBlockProposal duplicate detection', () => {
365
+ it('should return count=1 when pool is empty', async () => {
366
+ const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
367
+ const result = await ap.tryAddBlockProposal(proposal);
368
+
369
+ expect(result.added).toBe(true);
370
+ expect(result.alreadyExists).toBe(false);
371
+ expect(result.count).toBe(1);
372
+ });
373
+
374
+ it('should return alreadyExists when same proposal exists', async () => {
375
+ const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
376
+ await ap.tryAddBlockProposal(proposal);
377
+
378
+ const result = await ap.tryAddBlockProposal(proposal);
379
+
380
+ expect(result.added).toBe(false);
381
+ expect(result.alreadyExists).toBe(true);
382
+ expect(result.count).toBe(1);
383
+ });
384
+
385
+ it('should detect duplicate via count when different proposal exists at same position', async () => {
386
+ const slotNumber = 100;
387
+ const indexWithinCheckpoint = 2;
388
+
389
+ // Add first proposal
390
+ const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
391
+ const result1 = await ap.tryAddBlockProposal(proposal1);
392
+ expect(result1.count).toBe(1);
393
+
394
+ // Add a different proposal at same position - this is a duplicate (equivocation)
395
+ const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
396
+ const result2 = await ap.tryAddBlockProposal(proposal2);
397
+
398
+ expect(result2.added).toBe(true);
399
+ expect(result2.alreadyExists).toBe(false);
400
+ // count >= 2 indicates duplicate detection
401
+ expect(result2.count).toBe(2);
402
+ });
403
+
404
+ it('should not detect duplicate for different positions in same slot', async () => {
405
+ const slotNumber = 100;
406
+
407
+ // Add proposal at index 0
408
+ const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
409
+ await ap.tryAddBlockProposal(proposal1);
410
+
411
+ // Add proposal at index 1 (different position)
412
+ const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
413
+ const result = await ap.tryAddBlockProposal(proposal2);
414
+
415
+ expect(result.added).toBe(true);
416
+ // count = 1 means no duplicate for this position
417
+ expect(result.count).toBe(1);
418
+ });
419
+
420
+ it('should not detect duplicate for same position in different slots', async () => {
421
+ const indexWithinCheckpoint = 0;
422
+
423
+ // Add proposal at slot 100
424
+ const proposal1 = await mockBlockProposalWithIndex(signers[0], 100, indexWithinCheckpoint);
425
+ await ap.tryAddBlockProposal(proposal1);
426
+
427
+ // Add proposal at slot 200 (different slot)
428
+ const proposal2 = await mockBlockProposalWithIndex(signers[1], 200, indexWithinCheckpoint);
429
+ const result = await ap.tryAddBlockProposal(proposal2);
430
+
431
+ expect(result.added).toBe(true);
432
+ // count = 1 means no duplicate for this position
433
+ expect(result.count).toBe(1);
434
+ });
435
+
436
+ it('should track multiple duplicates correctly via count', async () => {
437
+ const slotNumber = 100;
438
+ const indexWithinCheckpoint = 0;
439
+
440
+ // Add multiple proposals for same position
441
+ const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
442
+ const result1 = await ap.tryAddBlockProposal(proposal1);
443
+ expect(result1.count).toBe(1);
444
+
445
+ const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
446
+ const result2 = await ap.tryAddBlockProposal(proposal2);
447
+ expect(result2.count).toBe(2);
448
+
449
+ // Add a third proposal for same position
450
+ const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
451
+ const result3 = await ap.tryAddBlockProposal(proposal3);
452
+
453
+ expect(result3.added).toBe(true);
454
+ expect(result3.count).toBe(3);
455
+ });
456
+
457
+ it('should return added=false when exceeding capacity', async () => {
458
+ const slotNumber = 100;
459
+ const indexWithinCheckpoint = 0;
460
+
461
+ // Add MAX_BLOCK_PROPOSALS_PER_POSITION proposals
462
+ for (let i = 0; i < MAX_BLOCK_PROPOSALS_PER_POSITION; i++) {
463
+ const proposal = await mockBlockProposalWithIndex(
464
+ signers[i % NUMBER_OF_SIGNERS_PER_TEST],
465
+ slotNumber,
466
+ indexWithinCheckpoint,
467
+ );
468
+ const result = await ap.tryAddBlockProposal(proposal);
469
+ expect(result.added).toBe(true);
470
+ expect(result.count).toBe(i + 1);
471
+ }
472
+
473
+ // The next proposal should not be added
474
+ const extraProposal = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
475
+ const result = await ap.tryAddBlockProposal(extraProposal);
476
+ expect(result.added).toBe(false);
477
+ expect(result.alreadyExists).toBe(false);
478
+ expect(result.count).toBe(MAX_BLOCK_PROPOSALS_PER_POSITION);
479
+ });
480
+
481
+ it('should clean up block position index when deleting old data', async () => {
482
+ const slotNumber = 100;
483
+ const indexWithinCheckpoint = 0;
484
+
485
+ // Add proposal
486
+ const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
487
+ await ap.tryAddBlockProposal(proposal1);
488
+
489
+ // Verify it's tracked (adding another should show count = 2)
490
+ const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
491
+ let result = await ap.tryAddBlockProposal(proposal2);
492
+ expect(result.count).toBe(2);
493
+
494
+ // Delete old data
495
+ await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
496
+
497
+ // Verify position index is cleaned up (count should be 1 now)
498
+ const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
499
+ result = await ap.tryAddBlockProposal(proposal3);
500
+ expect(result.count).toBe(1);
501
+ });
502
+
503
+ it('should correctly delete block proposals at slot boundary', async () => {
504
+ // Add proposals at slots 99, 100, and 101 with various indices
505
+ const proposalSlot99Idx0 = await mockBlockProposalWithIndex(signers[0], 99, 0);
506
+ const proposalSlot99Idx1 = await mockBlockProposalWithIndex(signers[1], 99, 1);
507
+ const proposalSlot100Idx0 = await mockBlockProposalWithIndex(signers[2], 100, 0);
508
+ const proposalSlot101Idx0 = await mockBlockProposalWithIndex(signers[3], 101, 0);
509
+
510
+ await ap.tryAddBlockProposal(proposalSlot99Idx0);
511
+ await ap.tryAddBlockProposal(proposalSlot99Idx1);
512
+ await ap.tryAddBlockProposal(proposalSlot100Idx0);
513
+ await ap.tryAddBlockProposal(proposalSlot101Idx0);
514
+
515
+ // Delete slots older than 100 (should delete slot 99 only)
516
+ await ap.deleteOlderThan(SlotNumber(100));
517
+
518
+ // Slot 99 proposals should have their index cleaned up
519
+ const newProposal99 = await mockBlockProposalWithIndex(signers[0], 99, 0);
520
+ const result99 = await ap.tryAddBlockProposal(newProposal99);
521
+ expect(result99.count).toBe(1); // Index was cleaned up
522
+
523
+ // Slot 100 and 101 should still be tracked
524
+ const newProposal100 = await mockBlockProposalWithIndex(signers[1], 100, 0);
525
+ const result100 = await ap.tryAddBlockProposal(newProposal100);
526
+ expect(result100.count).toBe(2); // Still has the original
527
+
528
+ const newProposal101 = await mockBlockProposalWithIndex(signers[2], 101, 0);
529
+ const result101 = await ap.tryAddBlockProposal(newProposal101);
530
+ expect(result101.count).toBe(2); // Still has the original
531
+ });
532
+
533
+ it('should delete all indices for a given slot', async () => {
534
+ const slotNumber = 50;
535
+
536
+ // Add proposals at multiple indices for the same slot
537
+ const proposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
538
+ const proposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
539
+ const proposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
540
+
541
+ await ap.tryAddBlockProposal(proposal0);
542
+ await ap.tryAddBlockProposal(proposal1);
543
+ await ap.tryAddBlockProposal(proposal2);
544
+
545
+ // Delete slots older than slotNumber + 1
546
+ await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
547
+
548
+ // All indices should be cleaned up
549
+ const newProposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
550
+ const result0 = await ap.tryAddBlockProposal(newProposal0);
551
+ expect(result0.count).toBe(1);
552
+
553
+ const newProposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
554
+ const result1 = await ap.tryAddBlockProposal(newProposal1);
555
+ expect(result1.count).toBe(1);
556
+
557
+ const newProposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
558
+ const result2 = await ap.tryAddBlockProposal(newProposal2);
559
+ expect(result2.count).toBe(1);
560
+ });
561
+
562
+ it('should delete block proposals from storage when deleting old data', async () => {
563
+ const oldSlot = 50;
564
+ const newSlot = 100;
565
+
566
+ // Add proposals at old and new slots
567
+ const oldProposal = await mockBlockProposalWithIndex(signers[0], oldSlot, 0);
568
+ const newProposal = await mockBlockProposalWithIndex(signers[1], newSlot, 0);
569
+
570
+ await ap.tryAddBlockProposal(oldProposal);
571
+ await ap.tryAddBlockProposal(newProposal);
572
+
573
+ // Verify both proposals exist
574
+ expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeDefined();
575
+ expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
576
+
577
+ // Delete slots older than newSlot (should delete oldSlot)
578
+ await ap.deleteOlderThan(SlotNumber(newSlot));
579
+
580
+ // Old proposal should be deleted from storage
581
+ expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeUndefined();
582
+
583
+ // New proposal should still exist
584
+ expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
585
+ });
586
+ });
587
+
588
+ describe('tryAddCheckpointProposal duplicate detection', () => {
589
+ const mockCheckpointProposalCoreForPool = async (
590
+ signer: Secp256k1Signer,
591
+ slotNumber: number,
592
+ archive: Fr = Fr.random(),
593
+ ): Promise<CheckpointProposalCore> => {
594
+ const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
595
+ const blockHeader = makeBlockHeader(1);
596
+ const proposal = await makeCheckpointProposal({
597
+ signer,
598
+ checkpointHeader,
599
+ archiveRoot: archive,
600
+ lastBlock: { blockHeader },
601
+ });
602
+ return proposal.toCore();
603
+ };
604
+
605
+ it('should return count=1 when pool is empty', async () => {
606
+ const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
607
+ const result = await ap.tryAddCheckpointProposal(proposal);
608
+
609
+ expect(result.added).toBe(true);
610
+ expect(result.alreadyExists).toBe(false);
611
+ expect(result.count).toBe(1);
612
+ });
613
+
614
+ it('should return alreadyExists when same proposal exists', async () => {
615
+ const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
616
+ await ap.tryAddCheckpointProposal(proposal);
617
+
618
+ const result = await ap.tryAddCheckpointProposal(proposal);
619
+
620
+ expect(result.added).toBe(false);
621
+ expect(result.alreadyExists).toBe(true);
622
+ expect(result.count).toBe(1);
623
+ });
624
+
625
+ it('should detect duplicate via count when different proposal exists for same slot', async () => {
626
+ const slotNumber = 100;
627
+
628
+ // Add first proposal
629
+ const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
630
+ const result1 = await ap.tryAddCheckpointProposal(proposal1);
631
+ expect(result1.count).toBe(1);
632
+
633
+ // Add a different proposal for same slot - this is a duplicate (equivocation)
634
+ const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
635
+ const result2 = await ap.tryAddCheckpointProposal(proposal2);
636
+
637
+ expect(result2.added).toBe(true);
638
+ expect(result2.alreadyExists).toBe(false);
639
+ // count >= 2 indicates duplicate detection
640
+ expect(result2.count).toBe(2);
641
+ });
642
+
643
+ it('should not detect duplicate for different slots', async () => {
644
+ // Add proposal at slot 100
645
+ const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], 100);
646
+ await ap.tryAddCheckpointProposal(proposal1);
647
+
648
+ // Add proposal at slot 200 (different slot)
649
+ const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], 200);
650
+ const result = await ap.tryAddCheckpointProposal(proposal2);
651
+
652
+ expect(result.added).toBe(true);
653
+ // count = 1 means no duplicate for this slot
654
+ expect(result.count).toBe(1);
655
+ });
656
+
657
+ it('should track multiple duplicates correctly via count', async () => {
658
+ const slotNumber = 100;
659
+
660
+ // Add multiple proposals for same slot
661
+ const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
662
+ const result1 = await ap.tryAddCheckpointProposal(proposal1);
663
+ expect(result1.count).toBe(1);
664
+
665
+ const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
666
+ const result2 = await ap.tryAddCheckpointProposal(proposal2);
667
+ expect(result2.count).toBe(2);
668
+
669
+ // Add a third proposal for same slot
670
+ const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
671
+ const result3 = await ap.tryAddCheckpointProposal(proposal3);
672
+
673
+ expect(result3.added).toBe(true);
674
+ expect(result3.count).toBe(3);
675
+ });
676
+
677
+ it('should not count attestations as proposals for duplicate detection', async () => {
678
+ const slotNumber = 100;
679
+ const archive = Fr.random();
680
+
681
+ // Attestation arrives BEFORE the checkpoint proposal (race condition in p2p)
682
+ const attestation = mockCheckpointAttestation(signers[0], slotNumber, archive);
683
+ await ap.addOwnCheckpointAttestations([attestation]);
684
+
685
+ // Now the checkpoint proposal arrives - this should NOT be detected as a duplicate
686
+ const proposal = await mockCheckpointProposalCoreForPool(signers[1], slotNumber, archive);
687
+ const result = await ap.tryAddCheckpointProposal(proposal);
688
+
689
+ expect(result.added).toBe(true);
690
+ expect(result.alreadyExists).toBe(false);
691
+ // count should be 1, NOT 2 - attestations should not count as proposals
692
+ expect(result.count).toBe(1);
693
+ });
694
+
695
+ it('should not count attestations for different proposals as duplicates', async () => {
696
+ const slotNumber = 100;
697
+ const archive1 = Fr.random();
698
+ const archive2 = Fr.random();
699
+
700
+ // Add attestations for two different proposals in the same slot
701
+ const attestation1 = mockCheckpointAttestation(signers[0], slotNumber, archive1);
702
+ const attestation2 = mockCheckpointAttestation(signers[1], slotNumber, archive2);
703
+ await ap.addOwnCheckpointAttestations([attestation1, attestation2]);
704
+
705
+ // Add the first checkpoint proposal - should not be affected by attestations
706
+ const proposal1 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber, archive1);
707
+ const result1 = await ap.tryAddCheckpointProposal(proposal1);
708
+
709
+ expect(result1.added).toBe(true);
710
+ expect(result1.count).toBe(1);
711
+
712
+ // Add the second checkpoint proposal - this IS a duplicate (different archive, same slot)
713
+ const proposal2 = await mockCheckpointProposalCoreForPool(signers[3], slotNumber, archive2);
714
+ const result2 = await ap.tryAddCheckpointProposal(proposal2);
715
+
716
+ expect(result2.added).toBe(true);
717
+ expect(result2.count).toBe(2);
718
+ });
379
719
  });
380
720
  });
381
721
  }