@aztec/p2p 0.0.1-commit.96bb3f7 → 0.0.1-commit.993d52e

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 (509) 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 +10 -10
  5. package/dest/client/factory.d.ts.map +1 -1
  6. package/dest/client/factory.js +45 -18
  7. package/dest/client/interface.d.ts +46 -33
  8. package/dest/client/interface.d.ts.map +1 -1
  9. package/dest/client/p2p_client.d.ts +41 -51
  10. package/dest/client/p2p_client.d.ts.map +1 -1
  11. package/dest/client/p2p_client.js +157 -201
  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 +304 -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 +38 -3
  19. package/dest/config.d.ts.map +1 -1
  20. package/dest/config.js +28 -4
  21. package/dest/errors/tx-pool.error.d.ts +8 -0
  22. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  23. package/dest/errors/tx-pool.error.js +9 -0
  24. package/dest/index.d.ts +2 -1
  25. package/dest/index.d.ts.map +1 -1
  26. package/dest/index.js +1 -0
  27. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -88
  28. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  29. package/dest/mem_pools/attestation_pool/attestation_pool.js +441 -3
  30. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
  31. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  32. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +373 -96
  33. package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
  34. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  35. package/dest/mem_pools/attestation_pool/index.js +1 -2
  36. package/dest/mem_pools/attestation_pool/mocks.d.ts +4 -2
  37. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  38. package/dest/mem_pools/attestation_pool/mocks.js +8 -5
  39. package/dest/mem_pools/index.d.ts +3 -2
  40. package/dest/mem_pools/index.d.ts.map +1 -1
  41. package/dest/mem_pools/index.js +1 -1
  42. package/dest/mem_pools/instrumentation.d.ts +1 -1
  43. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  44. package/dest/mem_pools/instrumentation.js +2 -2
  45. package/dest/mem_pools/interface.d.ts +5 -5
  46. package/dest/mem_pools/interface.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +15 -10
  48. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +91 -50
  50. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +19 -5
  51. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +59 -3
  53. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +79 -5
  54. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +47 -0
  56. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
  57. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  58. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +122 -0
  59. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +2 -2
  60. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  62. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +4 -4
  63. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +2 -0
  65. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +2 -2
  66. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
  68. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
  69. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
  70. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
  71. package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
  72. package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
  73. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
  74. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
  75. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
  76. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  77. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  78. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  79. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
  80. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
  81. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +128 -0
  82. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
  83. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  84. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +93 -0
  85. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
  86. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
  87. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +97 -0
  88. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
  89. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
  90. package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
  91. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +180 -0
  92. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
  93. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +25 -0
  94. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
  95. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  96. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +65 -0
  97. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
  98. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  99. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +93 -0
  100. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
  101. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  102. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +78 -0
  103. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
  104. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
  105. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +75 -0
  106. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
  107. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
  108. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
  109. package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
  110. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
  111. package/dest/mem_pools/tx_pool_v2/index.js +5 -0
  112. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  113. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  114. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  115. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +211 -0
  116. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
  117. package/dest/mem_pools/tx_pool_v2/interfaces.js +9 -0
  118. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +128 -0
  119. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
  120. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +210 -0
  121. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
  122. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
  123. package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
  124. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +108 -0
  125. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
  126. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +354 -0
  127. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +60 -0
  128. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
  129. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +161 -0
  130. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +77 -0
  131. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
  132. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +899 -0
  133. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +3 -3
  134. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  135. package/dest/msg_validators/attestation_validator/attestation_validator.js +41 -10
  136. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
  137. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  138. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +18 -6
  139. package/dest/msg_validators/clock_tolerance.d.ts +21 -0
  140. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -0
  141. package/dest/msg_validators/clock_tolerance.js +37 -0
  142. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +2 -1
  143. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  144. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +2 -1
  145. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  146. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +5 -3
  147. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  148. package/dest/msg_validators/proposal_validator/proposal_validator.js +65 -31
  149. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +4 -3
  150. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -1
  151. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +257 -62
  152. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  153. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  154. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  155. package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
  156. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  157. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  158. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +20 -6
  159. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  160. package/dest/msg_validators/tx_validator/block_header_validator.js +4 -3
  161. package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
  162. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  163. package/dest/msg_validators/tx_validator/data_validator.js +4 -1
  164. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +15 -4
  165. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  166. package/dest/msg_validators/tx_validator/double_spend_validator.js +7 -6
  167. package/dest/msg_validators/tx_validator/factory.d.ts +118 -5
  168. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  169. package/dest/msg_validators/tx_validator/factory.js +228 -57
  170. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
  171. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
  172. package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
  173. package/dest/msg_validators/tx_validator/gas_validator.d.ts +59 -3
  174. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  175. package/dest/msg_validators/tx_validator/gas_validator.js +84 -52
  176. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  177. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  178. package/dest/msg_validators/tx_validator/index.js +2 -0
  179. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
  180. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  181. package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
  182. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  183. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  184. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  185. package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
  186. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  187. package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
  188. package/dest/msg_validators/tx_validator/size_validator.d.ts +8 -0
  189. package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
  190. package/dest/msg_validators/tx_validator/size_validator.js +23 -0
  191. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +22 -5
  192. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  193. package/dest/msg_validators/tx_validator/timestamp_validator.js +8 -8
  194. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
  195. package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
  196. package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
  197. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
  198. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  199. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -2
  200. package/dest/services/data_store.d.ts +1 -1
  201. package/dest/services/data_store.d.ts.map +1 -1
  202. package/dest/services/data_store.js +10 -6
  203. package/dest/services/discv5/discV5_service.js +1 -1
  204. package/dest/services/dummy_service.d.ts +24 -4
  205. package/dest/services/dummy_service.d.ts.map +1 -1
  206. package/dest/services/dummy_service.js +46 -1
  207. package/dest/services/encoding.d.ts +3 -3
  208. package/dest/services/encoding.d.ts.map +1 -1
  209. package/dest/services/encoding.js +13 -13
  210. package/dest/services/gossipsub/index.d.ts +3 -0
  211. package/dest/services/gossipsub/index.d.ts.map +1 -0
  212. package/dest/services/gossipsub/index.js +2 -0
  213. package/dest/services/gossipsub/scoring.d.ts +21 -3
  214. package/dest/services/gossipsub/scoring.d.ts.map +1 -1
  215. package/dest/services/gossipsub/scoring.js +24 -7
  216. package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
  217. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
  218. package/dest/services/gossipsub/topic_score_params.js +346 -0
  219. package/dest/services/index.d.ts +2 -1
  220. package/dest/services/index.d.ts.map +1 -1
  221. package/dest/services/index.js +1 -0
  222. package/dest/services/libp2p/instrumentation.d.ts +1 -1
  223. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  224. package/dest/services/libp2p/instrumentation.js +19 -8
  225. package/dest/services/libp2p/libp2p_service.d.ts +101 -43
  226. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  227. package/dest/services/libp2p/libp2p_service.js +459 -365
  228. package/dest/services/peer-manager/metrics.d.ts +2 -2
  229. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  230. package/dest/services/peer-manager/metrics.js +20 -5
  231. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  232. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  233. package/dest/services/peer-manager/peer_scoring.js +33 -4
  234. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +48 -0
  235. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
  236. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +562 -0
  237. package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
  238. package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
  239. package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
  240. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +46 -0
  241. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
  242. package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
  243. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +34 -0
  244. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
  245. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +130 -0
  246. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +54 -0
  247. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
  248. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +139 -0
  249. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
  250. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
  251. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
  252. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
  253. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
  254. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
  255. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
  256. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  257. package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
  258. package/dest/services/reqresp/constants.d.ts +12 -0
  259. package/dest/services/reqresp/constants.d.ts.map +1 -0
  260. package/dest/services/reqresp/constants.js +7 -0
  261. package/dest/services/reqresp/interface.d.ts +12 -1
  262. package/dest/services/reqresp/interface.d.ts.map +1 -1
  263. package/dest/services/reqresp/interface.js +15 -1
  264. package/dest/services/reqresp/metrics.d.ts +6 -5
  265. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  266. package/dest/services/reqresp/metrics.js +17 -5
  267. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
  268. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  269. package/dest/services/reqresp/protocols/block_txs/bitvector.js +12 -0
  270. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
  271. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
  272. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +27 -9
  273. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +29 -6
  274. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  275. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +59 -13
  276. package/dest/services/reqresp/protocols/status.d.ts +1 -1
  277. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  278. package/dest/services/reqresp/protocols/status.js +2 -1
  279. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  280. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  281. package/dest/services/reqresp/protocols/tx.js +20 -0
  282. package/dest/services/reqresp/reqresp.d.ts +6 -1
  283. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  284. package/dest/services/reqresp/reqresp.js +69 -26
  285. package/dest/services/service.d.ts +42 -3
  286. package/dest/services/service.d.ts.map +1 -1
  287. package/dest/services/tx_collection/config.d.ts +22 -1
  288. package/dest/services/tx_collection/config.d.ts.map +1 -1
  289. package/dest/services/tx_collection/config.js +55 -1
  290. package/dest/services/tx_collection/fast_tx_collection.d.ts +7 -4
  291. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  292. package/dest/services/tx_collection/fast_tx_collection.js +71 -44
  293. package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
  294. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  295. package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
  296. package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
  297. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  298. package/dest/services/tx_collection/file_store_tx_source.js +90 -0
  299. package/dest/services/tx_collection/index.d.ts +3 -1
  300. package/dest/services/tx_collection/index.d.ts.map +1 -1
  301. package/dest/services/tx_collection/index.js +2 -0
  302. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  303. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  304. package/dest/services/tx_collection/instrumentation.js +10 -2
  305. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  306. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  307. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  308. package/dest/services/tx_collection/proposal_tx_collector.d.ts +49 -0
  309. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
  310. package/dest/services/tx_collection/proposal_tx_collector.js +50 -0
  311. package/dest/services/tx_collection/slow_tx_collection.d.ts +9 -5
  312. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  313. package/dest/services/tx_collection/slow_tx_collection.js +60 -26
  314. package/dest/services/tx_collection/tx_collection.d.ts +29 -16
  315. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  316. package/dest/services/tx_collection/tx_collection.js +79 -7
  317. package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
  318. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  319. package/dest/services/tx_collection/tx_collection_sink.js +26 -29
  320. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  321. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  322. package/dest/services/tx_collection/tx_source.js +19 -2
  323. package/dest/services/tx_file_store/config.d.ts +16 -0
  324. package/dest/services/tx_file_store/config.d.ts.map +1 -0
  325. package/dest/services/tx_file_store/config.js +22 -0
  326. package/dest/services/tx_file_store/index.d.ts +4 -0
  327. package/dest/services/tx_file_store/index.d.ts.map +1 -0
  328. package/dest/services/tx_file_store/index.js +3 -0
  329. package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
  330. package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
  331. package/dest/services/tx_file_store/instrumentation.js +29 -0
  332. package/dest/services/tx_file_store/tx_file_store.d.ts +48 -0
  333. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
  334. package/dest/services/tx_file_store/tx_file_store.js +152 -0
  335. package/dest/services/tx_provider.d.ts +6 -6
  336. package/dest/services/tx_provider.d.ts.map +1 -1
  337. package/dest/services/tx_provider.js +9 -8
  338. package/dest/services/tx_provider_instrumentation.d.ts +1 -1
  339. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  340. package/dest/services/tx_provider_instrumentation.js +5 -5
  341. package/dest/test-helpers/index.d.ts +3 -1
  342. package/dest/test-helpers/index.d.ts.map +1 -1
  343. package/dest/test-helpers/index.js +2 -0
  344. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  345. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  346. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  347. package/dest/test-helpers/mock-pubsub.d.ts +30 -4
  348. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  349. package/dest/test-helpers/mock-pubsub.js +105 -4
  350. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  351. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  352. package/dest/test-helpers/reqresp-nodes.js +4 -3
  353. package/dest/test-helpers/test_tx_provider.d.ts +40 -0
  354. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
  355. package/dest/test-helpers/test_tx_provider.js +41 -0
  356. package/dest/test-helpers/testbench-utils.d.ts +163 -0
  357. package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
  358. package/dest/test-helpers/testbench-utils.js +366 -0
  359. package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
  360. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  361. package/dest/testbench/p2p_client_testbench_worker.js +219 -139
  362. package/dest/testbench/worker_client_manager.d.ts +51 -6
  363. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  364. package/dest/testbench/worker_client_manager.js +226 -44
  365. package/dest/util.d.ts +2 -2
  366. package/dest/util.d.ts.map +1 -1
  367. package/package.json +16 -16
  368. package/src/bootstrap/bootstrap.ts +7 -4
  369. package/src/client/factory.ts +83 -36
  370. package/src/client/interface.ts +56 -34
  371. package/src/client/p2p_client.ts +197 -252
  372. package/src/client/test/tx_proposal_collector/README.md +227 -0
  373. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +345 -0
  374. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
  375. package/src/config.ts +58 -4
  376. package/src/errors/tx-pool.error.ts +12 -0
  377. package/src/index.ts +1 -0
  378. package/src/mem_pools/attestation_pool/attestation_pool.ts +496 -91
  379. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +460 -112
  380. package/src/mem_pools/attestation_pool/index.ts +9 -2
  381. package/src/mem_pools/attestation_pool/mocks.ts +7 -4
  382. package/src/mem_pools/index.ts +4 -1
  383. package/src/mem_pools/instrumentation.ts +2 -1
  384. package/src/mem_pools/interface.ts +4 -4
  385. package/src/mem_pools/tx_pool/README.md +29 -14
  386. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +130 -75
  387. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +66 -5
  388. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +119 -4
  389. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +162 -0
  390. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  391. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +4 -2
  392. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
  393. package/src/mem_pools/tx_pool_v2/README.md +283 -0
  394. package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
  395. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
  396. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  397. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +160 -0
  398. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +121 -0
  399. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +125 -0
  400. package/src/mem_pools/tx_pool_v2/eviction/index.ts +27 -0
  401. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +219 -0
  402. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
  403. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
  404. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +91 -0
  405. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +99 -0
  406. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +32 -0
  407. package/src/mem_pools/tx_pool_v2/index.ts +12 -0
  408. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  409. package/src/mem_pools/tx_pool_v2/interfaces.ts +242 -0
  410. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +327 -0
  411. package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
  412. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +444 -0
  413. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +223 -0
  414. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1079 -0
  415. package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -14
  416. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +16 -10
  417. package/src/msg_validators/clock_tolerance.ts +51 -0
  418. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +1 -1
  419. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +1 -1
  420. package/src/msg_validators/proposal_validator/proposal_validator.ts +46 -32
  421. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +233 -66
  422. package/src/msg_validators/tx_validator/README.md +115 -0
  423. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
  424. package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
  425. package/src/msg_validators/tx_validator/block_header_validator.ts +21 -8
  426. package/src/msg_validators/tx_validator/data_validator.ts +6 -2
  427. package/src/msg_validators/tx_validator/double_spend_validator.ts +15 -9
  428. package/src/msg_validators/tx_validator/factory.ts +372 -55
  429. package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
  430. package/src/msg_validators/tx_validator/gas_validator.ts +106 -54
  431. package/src/msg_validators/tx_validator/index.ts +2 -0
  432. package/src/msg_validators/tx_validator/metadata_validator.ts +6 -3
  433. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  434. package/src/msg_validators/tx_validator/phases_validator.ts +5 -3
  435. package/src/msg_validators/tx_validator/size_validator.ts +22 -0
  436. package/src/msg_validators/tx_validator/timestamp_validator.ts +29 -21
  437. package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
  438. package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
  439. package/src/services/data_store.ts +10 -7
  440. package/src/services/discv5/discV5_service.ts +1 -1
  441. package/src/services/dummy_service.ts +59 -2
  442. package/src/services/encoding.ts +11 -12
  443. package/src/services/gossipsub/README.md +641 -0
  444. package/src/services/gossipsub/index.ts +2 -0
  445. package/src/services/gossipsub/scoring.ts +29 -5
  446. package/src/services/gossipsub/topic_score_params.ts +487 -0
  447. package/src/services/index.ts +1 -0
  448. package/src/services/libp2p/instrumentation.ts +20 -7
  449. package/src/services/libp2p/libp2p_service.ts +508 -393
  450. package/src/services/peer-manager/metrics.ts +21 -4
  451. package/src/services/peer-manager/peer_scoring.ts +29 -1
  452. package/src/services/reqresp/batch-tx-requester/README.md +305 -0
  453. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +706 -0
  454. package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
  455. package/src/services/reqresp/batch-tx-requester/interface.ts +53 -0
  456. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +161 -0
  457. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +205 -0
  458. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
  459. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
  460. package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
  461. package/src/services/reqresp/constants.ts +14 -0
  462. package/src/services/reqresp/interface.ts +29 -1
  463. package/src/services/reqresp/metrics.ts +34 -9
  464. package/src/services/reqresp/protocols/block_txs/bitvector.ts +16 -0
  465. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +35 -12
  466. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +74 -9
  467. package/src/services/reqresp/protocols/status.ts +5 -3
  468. package/src/services/reqresp/protocols/tx.ts +22 -0
  469. package/src/services/reqresp/reqresp.ts +79 -22
  470. package/src/services/service.ts +55 -2
  471. package/src/services/tx_collection/config.ts +83 -1
  472. package/src/services/tx_collection/fast_tx_collection.ts +93 -47
  473. package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
  474. package/src/services/tx_collection/file_store_tx_source.ts +117 -0
  475. package/src/services/tx_collection/index.ts +6 -0
  476. package/src/services/tx_collection/instrumentation.ts +17 -2
  477. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  478. package/src/services/tx_collection/proposal_tx_collector.ts +113 -0
  479. package/src/services/tx_collection/slow_tx_collection.ts +68 -35
  480. package/src/services/tx_collection/tx_collection.ts +121 -24
  481. package/src/services/tx_collection/tx_collection_sink.ts +30 -34
  482. package/src/services/tx_collection/tx_source.ts +22 -3
  483. package/src/services/tx_file_store/config.ts +37 -0
  484. package/src/services/tx_file_store/index.ts +3 -0
  485. package/src/services/tx_file_store/instrumentation.ts +36 -0
  486. package/src/services/tx_file_store/tx_file_store.ts +175 -0
  487. package/src/services/tx_provider.ts +12 -11
  488. package/src/services/tx_provider_instrumentation.ts +11 -5
  489. package/src/test-helpers/index.ts +2 -0
  490. package/src/test-helpers/make-test-p2p-clients.ts +3 -5
  491. package/src/test-helpers/mock-pubsub.ts +146 -9
  492. package/src/test-helpers/reqresp-nodes.ts +4 -6
  493. package/src/test-helpers/test_tx_provider.ts +64 -0
  494. package/src/test-helpers/testbench-utils.ts +430 -0
  495. package/src/testbench/p2p_client_testbench_worker.ts +333 -135
  496. package/src/testbench/worker_client_manager.ts +304 -47
  497. package/src/util.ts +7 -1
  498. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
  499. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  500. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
  501. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
  502. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  503. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
  504. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +0 -15
  505. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +0 -1
  506. package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +0 -88
  507. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
  508. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
  509. package/src/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.ts +0 -108
@@ -1,11 +1,20 @@
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';
5
- import { makeBlockProposal, makeCheckpointProposal, makeL2BlockHeader } from '@aztec/stdlib/testing';
6
-
7
- import type { AttestationPool } from './attestation_pool.js';
8
- import { MAX_PROPOSALS_PER_SLOT } from './kv_attestation_pool.js';
4
+ import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore } from '@aztec/stdlib/p2p';
5
+ import { CheckpointHeader } from '@aztec/stdlib/rollup';
6
+ import {
7
+ makeBlockHeader,
8
+ makeBlockProposal,
9
+ makeCheckpointHeader,
10
+ makeCheckpointProposal,
11
+ } from '@aztec/stdlib/testing';
12
+
13
+ import {
14
+ type AttestationPool,
15
+ MAX_BLOCK_PROPOSALS_PER_POSITION,
16
+ MAX_CHECKPOINT_PROPOSALS_PER_SLOT,
17
+ } from './attestation_pool.js';
9
18
  import { mockCheckpointAttestation } from './mocks.js';
10
19
 
11
20
  const NUMBER_OF_SIGNERS_PER_TEST = 4;
@@ -29,7 +38,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
29
38
  slotNumber: number,
30
39
  archive: Fr = Fr.random(),
31
40
  ): Promise<BlockProposal> => {
32
- const header = makeL2BlockHeader(1, 2, slotNumber);
41
+ const header = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) });
33
42
  return makeBlockProposal({
34
43
  signer,
35
44
  blockHeader: header,
@@ -52,7 +61,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
52
61
  const archive = Fr.random();
53
62
  const attestations = signers.slice(0, -1).map(signer => mockCheckpointAttestation(signer, slotNumber, archive));
54
63
 
55
- await ap.addCheckpointAttestations(attestations);
64
+ await ap.addOwnCheckpointAttestations(attestations);
56
65
 
57
66
  const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
58
67
  SlotNumber(slotNumber),
@@ -61,57 +70,47 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
61
70
  expect(retrievedAttestations.length).toBe(attestations.length);
62
71
  compareCheckpointAttestations(retrievedAttestations, attestations);
63
72
 
64
- // Check hasCheckpointAttestation for added attestations
65
- for (const attestation of attestations) {
66
- expect(await ap.hasCheckpointAttestation(attestation)).toBe(true);
67
- }
68
-
69
73
  const retrievedAttestationsForSlot = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
70
74
  expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
71
75
  compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
72
76
 
73
77
  // Add another one
74
78
  const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
75
- await ap.addCheckpointAttestations([newAttestation]);
79
+ await ap.addOwnCheckpointAttestations([newAttestation]);
76
80
  const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(
77
81
  SlotNumber(slotNumber),
78
82
  archive.toString(),
79
83
  );
80
84
  expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
81
85
  compareCheckpointAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
82
- expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(true);
83
86
  const retrievedAttestationsForSlotAfterAdd = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
84
87
  expect(retrievedAttestationsForSlotAfterAdd.length).toBe(attestations.length + 1);
85
88
  compareCheckpointAttestations(retrievedAttestationsForSlotAfterAdd, [...attestations, newAttestation]);
86
89
 
87
90
  // Delete by slot
88
- await ap.deleteCheckpointAttestationsOlderThan(SlotNumber(slotNumber + 1));
91
+ await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
89
92
 
90
93
  const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
91
94
  SlotNumber(slotNumber),
92
95
  archive.toString(),
93
96
  );
94
97
  expect(retreivedAttestationsAfterDelete.length).toBe(0);
95
- // Check hasCheckpointAttestation after deletion
96
- for (const attestation of attestations) {
97
- expect(await ap.hasCheckpointAttestation(attestation)).toBe(false);
98
- }
99
- expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(false);
100
98
  });
101
99
 
102
100
  it('should handle duplicate proposals in a slot', async () => {
103
101
  const slotNumber = 420;
104
102
  const archive = Fr.random();
103
+ const header = CheckpointHeader.random({ slotNumber: SlotNumber(slotNumber) });
105
104
 
106
- // Use the same signer for all attestations
105
+ // Use the same signer and header for all attestations
107
106
  const attestations: CheckpointAttestation[] = [];
108
107
  const signer = signers[0];
109
108
  for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
110
- attestations.push(mockCheckpointAttestation(signer, slotNumber, archive));
109
+ attestations.push(mockCheckpointAttestation(signer, slotNumber, archive, header));
111
110
  }
112
111
 
113
112
  // Add them to store and check we end up with only one
114
- await ap.addCheckpointAttestations(attestations);
113
+ await ap.addOwnCheckpointAttestations(attestations);
115
114
 
116
115
  const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
117
116
  SlotNumber(slotNumber),
@@ -122,7 +121,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
122
121
  expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
123
122
 
124
123
  // Try adding them on another operation and check they are still not duplicated
125
- await ap.addCheckpointAttestations([attestations[0]]);
124
+ await ap.addOwnCheckpointAttestations([attestations[0]]);
126
125
  expect(
127
126
  await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString()),
128
127
  ).toHaveLength(1);
@@ -132,7 +131,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
132
131
  const slotNumbers = [1, 2, 3, 4];
133
132
  const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i]));
134
133
 
135
- await ap.addCheckpointAttestations(attestations);
134
+ await ap.addOwnCheckpointAttestations(attestations);
136
135
 
137
136
  for (const attestation of attestations) {
138
137
  const slot = attestation.payload.header.slotNumber;
@@ -150,7 +149,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
150
149
  const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()];
151
150
  const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i], archives[i]));
152
151
 
153
- await ap.addCheckpointAttestations(attestations);
152
+ await ap.addOwnCheckpointAttestations(attestations);
154
153
 
155
154
  for (const attestation of attestations) {
156
155
  const slot = attestation.payload.header.slotNumber;
@@ -170,12 +169,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
170
169
  ).flat();
171
170
  const proposalId = attestations[0].archive.toString();
172
171
 
173
- await ap.addCheckpointAttestations(attestations);
172
+ await ap.addOwnCheckpointAttestations(attestations);
174
173
 
175
174
  const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
176
175
  expect(attestationsForSlot1.length).toBe(signers.length);
177
176
 
178
- await ap.deleteCheckpointAttestationsOlderThan(SlotNumber(73));
177
+ await ap.deleteOlderThan(SlotNumber(73));
179
178
 
180
179
  const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
181
180
  SlotNumber(1),
@@ -192,137 +191,106 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
192
191
  const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
193
192
  const proposalId = proposal.archive.toString();
194
193
 
195
- 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);
196
199
 
197
200
  const retrievedProposal = await ap.getBlockProposal(proposalId);
198
201
 
199
202
  expect(retrievedProposal).toBeDefined();
200
203
  expect(retrievedProposal!).toEqual(proposal);
201
-
202
- // Check hasBlockProposal with both id and object
203
- expect(await ap.hasBlockProposal(proposalId)).toBe(true);
204
- expect(await ap.hasBlockProposal(proposal)).toBe(true);
205
204
  });
206
205
 
207
206
  it('should return undefined for non-existent block proposal', async () => {
208
207
  const nonExistentId = Fr.random().toString();
209
208
  const retrievedProposal = await ap.getBlockProposal(nonExistentId);
210
209
  expect(retrievedProposal).toBeUndefined();
211
-
212
- // Check hasBlockProposal returns false for non-existent proposal
213
- expect(await ap.hasBlockProposal(nonExistentId)).toBe(false);
214
210
  });
215
211
 
216
- it('should update block proposal if added twice with same id', async () => {
212
+ it('should return alreadyExists when adding proposal with same id', async () => {
217
213
  const slotNumber = 420;
218
214
  const archive = Fr.random();
219
215
  const proposal1 = await mockBlockProposalForPool(signers[0], slotNumber, archive);
220
216
  const proposalId = proposal1.archive.toString();
221
217
 
222
- await ap.addBlockProposal(proposal1);
218
+ const result1 = await ap.tryAddBlockProposal(proposal1);
219
+ expect(result1.added).toBe(true);
220
+ expect(result1.alreadyExists).toBe(false);
223
221
 
224
222
  // Create a new proposal with same archive but different signer
225
223
  const proposal2 = await mockBlockProposalForPool(signers[1], slotNumber, archive);
226
224
 
227
- await ap.addBlockProposal(proposal2);
228
-
229
- const retrievedProposal = await ap.getBlockProposal(proposalId);
230
- expect(retrievedProposal).toBeDefined();
231
- // Should have the second proposal
232
- expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
233
- expect(retrievedProposal!.getSender()?.toString()).toBe(signers[1].address.toString());
234
- });
235
-
236
- it('should handle block proposals with different slots and same archive', async () => {
237
- const archive = Fr.random();
238
- const proposal1 = await mockBlockProposalForPool(signers[0], 100, archive);
239
- const proposal2 = await mockBlockProposalForPool(signers[1], 200, archive);
240
- const proposalId = archive.toString();
241
-
242
- await ap.addBlockProposal(proposal1);
243
- await ap.addBlockProposal(proposal2);
225
+ const result2 = await ap.tryAddBlockProposal(proposal2);
226
+ expect(result2.added).toBe(false);
227
+ expect(result2.alreadyExists).toBe(true);
244
228
 
245
- // Should get the latest one added
229
+ // Should still have the first proposal
246
230
  const retrievedProposal = await ap.getBlockProposal(proposalId);
247
231
  expect(retrievedProposal).toBeDefined();
248
- expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
249
- expect(retrievedProposal!.slotNumber).toBe(SlotNumber(200));
232
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer());
233
+ expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
250
234
  });
251
235
  });
252
236
 
253
237
  describe('CheckpointProposal in attestation pool', () => {
254
- const mockCheckpointProposalForPool = (
238
+ const mockCheckpointProposalForPool = async (
255
239
  signer: Secp256k1Signer,
256
240
  slotNumber: number,
257
241
  archive: Fr = Fr.random(),
258
- ): Promise<CheckpointProposal> => {
259
- const header = makeL2BlockHeader(1, 2, slotNumber);
260
- return makeCheckpointProposal({
242
+ ): Promise<CheckpointProposalCore> => {
243
+ const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
244
+ const blockHeader = makeBlockHeader(1);
245
+ const proposal = await makeCheckpointProposal({
261
246
  signer,
262
- checkpointHeader: header.toCheckpointHeader(),
247
+ checkpointHeader,
263
248
  archiveRoot: archive,
264
- lastBlock: { blockHeader: header },
249
+ lastBlock: { blockHeader },
265
250
  });
251
+ // Return the core version since tryAddCheckpointProposal now takes CheckpointProposalCore
252
+ return proposal.toCore();
266
253
  };
267
254
 
268
- it('should add and retrieve checkpoint proposal as core (without lastBlock)', async () => {
255
+ it('should add and retrieve checkpoint proposal', async () => {
269
256
  const slotNumber = 420;
270
257
  const archive = Fr.random();
271
258
  const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
272
259
  const proposalId = proposal.archive.toString();
273
260
 
274
- 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);
275
266
 
276
267
  const retrievedProposal = await ap.getCheckpointProposal(proposalId);
277
268
 
278
269
  expect(retrievedProposal).toBeDefined();
279
- // Should return core version (without lastBlock)
280
- expect(retrievedProposal!.toBuffer()).toEqual(proposal.toCore().toBuffer());
281
-
282
- // Check hasCheckpointProposal with both id and object
283
- expect(await ap.hasCheckpointProposal(proposalId)).toBe(true);
284
- expect(await ap.hasCheckpointProposal(proposal)).toBe(true);
285
- });
286
-
287
- it('should extract and store block proposal when adding checkpoint proposal with lastBlock', async () => {
288
- const slotNumber = 420;
289
- const archive = Fr.random();
290
- const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
291
- const proposalId = proposal.archive.toString();
292
-
293
- // Verify the proposal has a lastBlock
294
- const expectedBlockProposal = proposal.getBlockProposal();
295
- expect(expectedBlockProposal).toBeDefined();
296
-
297
- await ap.addCheckpointProposal(proposal);
298
-
299
- // The block proposal should be stored separately and retrievable
300
- const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
301
- expect(retrievedBlockProposal).toBeDefined();
302
- expect(retrievedBlockProposal!.archive.toString()).toBe(archive.toString());
303
- expect(retrievedBlockProposal!.blockHeader.toBuffer()).toEqual(expectedBlockProposal!.blockHeader.toBuffer());
270
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
304
271
  });
305
272
 
306
- 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 () => {
307
274
  const slotNumber = 420;
308
275
  const archive = Fr.random();
309
- const header = makeL2BlockHeader(1, 2, slotNumber);
276
+ const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
310
277
  // Create a checkpoint proposal WITHOUT lastBlock
311
278
  const proposal = await makeCheckpointProposal({
312
279
  signer: signers[0],
313
- checkpointHeader: header.toCheckpointHeader(),
280
+ checkpointHeader,
314
281
  archiveRoot: archive,
315
282
  // No lastBlock
316
283
  });
317
284
  const proposalId = proposal.archive.toString();
318
285
 
319
- await ap.addCheckpointProposal(proposal);
286
+ // Add the checkpoint core - block extraction is now caller responsibility
287
+ await ap.tryAddCheckpointProposal(proposal.toCore());
320
288
 
321
289
  // The checkpoint proposal should be stored
322
290
  const retrievedCheckpointProposal = await ap.getCheckpointProposal(proposalId);
323
291
  expect(retrievedCheckpointProposal).toBeDefined();
324
292
 
325
- // 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)
326
294
  const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
327
295
  expect(retrievedBlockProposal).toBeUndefined();
328
296
  });
@@ -331,43 +299,423 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
331
299
  const nonExistentId = Fr.random().toString();
332
300
  const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
333
301
  expect(retrievedProposal).toBeUndefined();
334
-
335
- // Check hasCheckpointProposal returns false for non-existent proposal
336
- expect(await ap.hasCheckpointProposal(nonExistentId)).toBe(false);
337
302
  });
338
303
 
339
- it('should update checkpoint proposal if added twice with same id', async () => {
304
+ it('should return alreadyExists when adding proposal with same id', async () => {
340
305
  const slotNumber = 420;
341
306
  const archive = Fr.random();
342
307
  const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
343
308
  const proposalId = proposal1.archive.toString();
344
309
 
345
- await ap.addCheckpointProposal(proposal1);
310
+ const result1 = await ap.tryAddCheckpointProposal(proposal1);
311
+ expect(result1.added).toBe(true);
312
+ expect(result1.alreadyExists).toBe(false);
346
313
 
347
314
  // Create a new proposal with same archive but different signer
348
315
  const proposal2 = await mockCheckpointProposalForPool(signers[1], slotNumber, archive);
349
316
 
350
- await ap.addCheckpointProposal(proposal2);
317
+ const result2 = await ap.tryAddCheckpointProposal(proposal2);
318
+ expect(result2.added).toBe(false);
319
+ expect(result2.alreadyExists).toBe(true);
351
320
 
321
+ // Should still have the first proposal
352
322
  const retrievedProposal = await ap.getCheckpointProposal(proposalId);
353
323
  expect(retrievedProposal).toBeDefined();
354
- // Should have the second proposal (as core)
355
- expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toCore().toBuffer());
356
- 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());
357
326
  });
358
327
 
359
- it('should throw ProposalSlotCapExceededError when exceeding capacity', async () => {
328
+ it('should return added=false when exceeding capacity', async () => {
360
329
  const slotNumber = 420;
361
330
 
362
- // Add MAX_PROPOSALS_PER_SLOT proposals
363
- 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++) {
364
333
  const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
365
- await ap.addCheckpointProposal(proposal);
334
+ const result = await ap.tryAddCheckpointProposal(proposal);
335
+ expect(result.added).toBe(true);
336
+ expect(result.count).toBe(i + 1);
366
337
  }
367
338
 
368
- // The next proposal should throw
339
+ // The next proposal should not be added
369
340
  const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
370
- 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
+ });
371
719
  });
372
720
  });
373
721
  }