@aztec/p2p 0.0.1-commit.f2ce05ee → 0.0.1-commit.f5a9928

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 (522) hide show
  1. package/README.md +130 -3
  2. package/dest/bootstrap/bootstrap.d.ts +1 -1
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  4. package/dest/bootstrap/bootstrap.js +22 -6
  5. package/dest/client/factory.d.ts +11 -10
  6. package/dest/client/factory.d.ts.map +1 -1
  7. package/dest/client/factory.js +64 -17
  8. package/dest/client/interface.d.ts +86 -40
  9. package/dest/client/interface.d.ts.map +1 -1
  10. package/dest/client/p2p_client.d.ts +67 -64
  11. package/dest/client/p2p_client.d.ts.map +1 -1
  12. package/dest/client/p2p_client.js +251 -251
  13. package/dest/config.d.ts +173 -94
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/config.js +158 -44
  16. package/dest/errors/p2p-service.error.d.ts +9 -0
  17. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  18. package/dest/errors/p2p-service.error.js +10 -0
  19. package/dest/errors/reqresp.error.d.ts +9 -16
  20. package/dest/errors/reqresp.error.d.ts.map +1 -1
  21. package/dest/errors/reqresp.error.js +10 -17
  22. package/dest/errors/tx-pool.error.d.ts +8 -0
  23. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  24. package/dest/errors/tx-pool.error.js +9 -0
  25. package/dest/index.d.ts +2 -2
  26. package/dest/index.d.ts.map +1 -1
  27. package/dest/index.js +1 -1
  28. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +106 -55
  29. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  30. package/dest/mem_pools/attestation_pool/attestation_pool.js +302 -195
  31. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  32. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  33. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +274 -115
  34. package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
  35. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
  36. package/dest/mem_pools/attestation_pool/index.js +1 -1
  37. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  38. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  39. package/dest/mem_pools/attestation_pool/mocks.js +7 -5
  40. package/dest/mem_pools/index.d.ts +2 -2
  41. package/dest/mem_pools/index.d.ts.map +1 -1
  42. package/dest/mem_pools/instrumentation.d.ts +12 -5
  43. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  44. package/dest/mem_pools/instrumentation.js +38 -17
  45. package/dest/mem_pools/interface.d.ts +3 -3
  46. package/dest/mem_pools/interface.d.ts.map +1 -1
  47. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +10 -5
  48. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +29 -20
  50. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
  51. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
  52. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
  53. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  54. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  55. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  56. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  57. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  58. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +8 -4
  59. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  60. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +15 -5
  62. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +3 -2
  63. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/eviction/index.js +2 -1
  65. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  66. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  67. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +64 -0
  68. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
  69. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  71. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +1 -1
  72. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -1
  73. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +6 -5
  74. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +1 -1
  75. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
  76. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +9 -8
  77. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  78. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  79. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +15 -6
  80. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  81. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  82. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
  83. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  84. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  85. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
  86. package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
  87. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  88. package/dest/mem_pools/tx_pool_v2/index.js +2 -1
  89. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +25 -0
  90. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  91. package/dest/mem_pools/tx_pool_v2/instrumentation.js +67 -0
  92. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +62 -16
  93. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  94. package/dest/mem_pools/tx_pool_v2/interfaces.js +6 -1
  95. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +81 -15
  96. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  97. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +147 -19
  98. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +26 -3
  99. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  100. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +79 -43
  101. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +27 -7
  102. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  103. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +94 -32
  104. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +62 -9
  105. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  106. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +537 -246
  107. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +10 -3
  108. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  109. package/dest/msg_validators/attestation_validator/attestation_validator.js +38 -15
  110. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  111. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  112. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
  113. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +12 -5
  114. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  115. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +11 -3
  116. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +12 -5
  117. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  118. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +23 -3
  119. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +36 -9
  120. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  121. package/dest/msg_validators/proposal_validator/proposal_validator.js +130 -48
  122. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
  123. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  124. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +11 -18
  125. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  126. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  127. package/dest/msg_validators/tx_validator/allowed_public_setup.js +25 -21
  128. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  129. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  130. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  131. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  132. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
  133. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  134. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  135. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
  136. package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
  137. package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
  138. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  139. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  140. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  141. package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
  142. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  143. package/dest/msg_validators/tx_validator/data_validator.js +36 -2
  144. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
  145. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
  146. package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
  147. package/dest/msg_validators/tx_validator/factory.d.ts +133 -7
  148. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  149. package/dest/msg_validators/tx_validator/factory.js +261 -61
  150. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  151. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  152. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  153. package/dest/msg_validators/tx_validator/gas_validator.d.ts +104 -3
  154. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  155. package/dest/msg_validators/tx_validator/gas_validator.js +137 -53
  156. package/dest/msg_validators/tx_validator/index.d.ts +5 -1
  157. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  158. package/dest/msg_validators/tx_validator/index.js +4 -0
  159. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  160. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  161. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  162. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  163. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  164. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  165. package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
  166. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  167. package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
  168. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
  169. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  170. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  171. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
  172. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
  173. package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
  174. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
  175. package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
  176. package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
  177. package/dest/services/data_store.d.ts +1 -1
  178. package/dest/services/data_store.d.ts.map +1 -1
  179. package/dest/services/data_store.js +5 -5
  180. package/dest/services/discv5/discV5_service.d.ts +13 -2
  181. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  182. package/dest/services/discv5/discV5_service.js +119 -23
  183. package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
  184. package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
  185. package/dest/services/discv5/persisted_enr_store.js +145 -0
  186. package/dest/services/dummy_service.d.ts +25 -19
  187. package/dest/services/dummy_service.d.ts.map +1 -1
  188. package/dest/services/dummy_service.js +28 -20
  189. package/dest/services/encoding.d.ts +24 -7
  190. package/dest/services/encoding.d.ts.map +1 -1
  191. package/dest/services/encoding.js +43 -26
  192. package/dest/services/gossipsub/topic_score_params.d.ts +23 -17
  193. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  194. package/dest/services/gossipsub/topic_score_params.js +36 -24
  195. package/dest/services/libp2p/instrumentation.d.ts +6 -1
  196. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  197. package/dest/services/libp2p/instrumentation.js +21 -0
  198. package/dest/services/libp2p/libp2p_service.d.ts +71 -60
  199. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  200. package/dest/services/libp2p/libp2p_service.js +602 -407
  201. package/dest/services/peer-manager/metrics.d.ts +3 -1
  202. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  203. package/dest/services/peer-manager/metrics.js +6 -0
  204. package/dest/services/peer-manager/peer_manager.d.ts +31 -3
  205. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  206. package/dest/services/peer-manager/peer_manager.js +127 -26
  207. package/dest/services/peer-manager/peer_scoring.d.ts +34 -2
  208. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  209. package/dest/services/peer-manager/peer_scoring.js +102 -13
  210. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +5 -8
  211. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  212. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +95 -127
  213. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +11 -11
  214. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  215. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
  216. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  217. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
  218. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  219. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  220. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  221. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
  222. package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
  223. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
  224. package/dest/services/reqresp/config.d.ts +15 -3
  225. package/dest/services/reqresp/config.d.ts.map +1 -1
  226. package/dest/services/reqresp/config.js +11 -0
  227. package/dest/services/reqresp/interface.d.ts +25 -18
  228. package/dest/services/reqresp/interface.d.ts.map +1 -1
  229. package/dest/services/reqresp/interface.js +23 -19
  230. package/dest/services/reqresp/metrics.d.ts +1 -1
  231. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  232. package/dest/services/reqresp/metrics.js +0 -1
  233. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
  234. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  235. package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
  236. package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
  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 +31 -28
  239. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +18 -7
  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 +57 -24
  242. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  243. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  244. package/dest/services/reqresp/protocols/index.js +0 -1
  245. package/dest/services/reqresp/protocols/tx.d.ts +7 -1
  246. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  247. package/dest/services/reqresp/protocols/tx.js +21 -3
  248. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  249. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  250. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  251. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  252. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  253. package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -13
  254. package/dest/services/reqresp/reqresp.d.ts +7 -29
  255. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  256. package/dest/services/reqresp/reqresp.js +85 -219
  257. package/dest/services/service.d.ts +63 -19
  258. package/dest/services/service.d.ts.map +1 -1
  259. package/dest/services/tx_collection/config.d.ts +11 -14
  260. package/dest/services/tx_collection/config.d.ts.map +1 -1
  261. package/dest/services/tx_collection/config.js +26 -33
  262. package/dest/services/tx_collection/file_store_tx_collection.d.ts +37 -0
  263. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
  264. package/dest/services/tx_collection/file_store_tx_collection.js +127 -0
  265. package/dest/services/tx_collection/file_store_tx_source.d.ts +38 -0
  266. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
  267. package/dest/services/tx_collection/file_store_tx_source.js +100 -0
  268. package/dest/services/tx_collection/index.d.ts +3 -3
  269. package/dest/services/tx_collection/index.d.ts.map +1 -1
  270. package/dest/services/tx_collection/index.js +1 -1
  271. package/dest/services/tx_collection/instrumentation.js +1 -2
  272. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  273. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  274. package/dest/services/tx_collection/request_tracker.js +84 -0
  275. package/dest/services/tx_collection/tx_collection.d.ts +45 -51
  276. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  277. package/dest/services/tx_collection/tx_collection.js +296 -68
  278. package/dest/services/tx_collection/tx_collection_sink.d.ts +19 -9
  279. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  280. package/dest/services/tx_collection/tx_collection_sink.js +28 -31
  281. package/dest/services/tx_collection/tx_source.d.ts +13 -7
  282. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  283. package/dest/services/tx_collection/tx_source.js +29 -7
  284. package/dest/services/tx_file_store/config.d.ts +1 -3
  285. package/dest/services/tx_file_store/config.d.ts.map +1 -1
  286. package/dest/services/tx_file_store/config.js +0 -4
  287. package/dest/services/tx_file_store/tx_file_store.d.ts +4 -5
  288. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  289. package/dest/services/tx_file_store/tx_file_store.js +13 -20
  290. package/dest/services/tx_provider.d.ts +6 -4
  291. package/dest/services/tx_provider.d.ts.map +1 -1
  292. package/dest/services/tx_provider.js +12 -8
  293. package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
  294. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  295. package/dest/test-helpers/make-test-p2p-clients.js +5 -3
  296. package/dest/test-helpers/mock-pubsub.d.ts +56 -6
  297. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  298. package/dest/test-helpers/mock-pubsub.js +128 -14
  299. package/dest/test-helpers/reqresp-nodes.d.ts +5 -7
  300. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  301. package/dest/test-helpers/reqresp-nodes.js +17 -19
  302. package/dest/test-helpers/test_tx_provider.d.ts +3 -1
  303. package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
  304. package/dest/test-helpers/test_tx_provider.js +3 -0
  305. package/dest/test-helpers/testbench-utils.d.ts +49 -37
  306. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  307. package/dest/test-helpers/testbench-utils.js +142 -50
  308. package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
  309. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  310. package/dest/testbench/p2p_client_testbench_worker.js +112 -49
  311. package/dest/testbench/worker_client_manager.d.ts +12 -6
  312. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  313. package/dest/testbench/worker_client_manager.js +57 -11
  314. package/dest/util.d.ts +13 -8
  315. package/dest/util.d.ts.map +1 -1
  316. package/dest/util.js +35 -14
  317. package/dest/versioning.d.ts +3 -6
  318. package/dest/versioning.d.ts.map +1 -1
  319. package/dest/versioning.js +3 -24
  320. package/package.json +17 -17
  321. package/src/bootstrap/bootstrap.ts +17 -3
  322. package/src/client/factory.ts +129 -28
  323. package/src/client/interface.ts +88 -48
  324. package/src/client/p2p_client.ts +284 -317
  325. package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
  326. package/src/config.ts +280 -49
  327. package/src/errors/p2p-service.error.ts +11 -0
  328. package/src/errors/reqresp.error.ts +13 -19
  329. package/src/errors/tx-pool.error.ts +12 -0
  330. package/src/index.ts +1 -1
  331. package/src/mem_pools/attestation_pool/attestation_pool.ts +373 -236
  332. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +298 -119
  333. package/src/mem_pools/attestation_pool/index.ts +3 -3
  334. package/src/mem_pools/attestation_pool/mocks.ts +14 -8
  335. package/src/mem_pools/index.ts +1 -1
  336. package/src/mem_pools/instrumentation.ts +27 -17
  337. package/src/mem_pools/interface.ts +2 -2
  338. package/src/mem_pools/tx_pool_v2/README.md +85 -11
  339. package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +30 -20
  340. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
  341. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  342. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +6 -4
  343. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +21 -6
  344. package/src/mem_pools/tx_pool_v2/eviction/index.ts +5 -0
  345. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +67 -0
  346. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
  347. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -6
  348. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +8 -10
  349. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -10
  350. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
  351. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
  352. package/src/mem_pools/tx_pool_v2/index.ts +2 -1
  353. package/src/mem_pools/tx_pool_v2/instrumentation.ts +96 -0
  354. package/src/mem_pools/tx_pool_v2/interfaces.ts +63 -16
  355. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +215 -27
  356. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +91 -43
  357. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +122 -33
  358. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +602 -242
  359. package/src/msg_validators/attestation_validator/README.md +49 -0
  360. package/src/msg_validators/attestation_validator/attestation_validator.ts +46 -14
  361. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +15 -7
  362. package/src/msg_validators/proposal_validator/README.md +123 -0
  363. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +26 -4
  364. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +43 -7
  365. package/src/msg_validators/proposal_validator/proposal_validator.ts +155 -49
  366. package/src/msg_validators/tx_validator/README.md +129 -0
  367. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +8 -17
  368. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  369. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  370. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  371. package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
  372. package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
  373. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  374. package/src/msg_validators/tx_validator/data_validator.ts +44 -1
  375. package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
  376. package/src/msg_validators/tx_validator/factory.ts +413 -80
  377. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  378. package/src/msg_validators/tx_validator/gas_validator.ts +195 -54
  379. package/src/msg_validators/tx_validator/index.ts +4 -0
  380. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  381. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  382. package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
  383. package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
  384. package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
  385. package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
  386. package/src/services/data_store.ts +5 -13
  387. package/src/services/discv5/discV5_service.ts +126 -14
  388. package/src/services/discv5/persisted_enr_store.ts +158 -0
  389. package/src/services/dummy_service.ts +38 -46
  390. package/src/services/encoding.ts +42 -26
  391. package/src/services/gossipsub/README.md +59 -22
  392. package/src/services/gossipsub/topic_score_params.ts +58 -31
  393. package/src/services/libp2p/instrumentation.ts +22 -0
  394. package/src/services/libp2p/libp2p_service.ts +687 -466
  395. package/src/services/peer-manager/metrics.ts +7 -0
  396. package/src/services/peer-manager/peer_manager.ts +140 -25
  397. package/src/services/peer-manager/peer_scoring.ts +102 -8
  398. package/src/services/reqresp/README.md +194 -0
  399. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  400. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +92 -138
  401. package/src/services/reqresp/batch-tx-requester/interface.ts +14 -10
  402. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
  403. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  404. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
  405. package/src/services/reqresp/config.ts +19 -2
  406. package/src/services/reqresp/interface.ts +45 -46
  407. package/src/services/reqresp/metrics.ts +0 -1
  408. package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
  409. package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +36 -32
  410. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +64 -20
  411. package/src/services/reqresp/protocols/index.ts +0 -1
  412. package/src/services/reqresp/protocols/tx.ts +23 -3
  413. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  414. package/src/services/reqresp/rate-limiter/rate_limits.ts +3 -13
  415. package/src/services/reqresp/reqresp.ts +100 -263
  416. package/src/services/service.ts +80 -35
  417. package/src/services/tx_collection/config.ts +40 -49
  418. package/src/services/tx_collection/file_store_tx_collection.ts +153 -0
  419. package/src/services/tx_collection/file_store_tx_source.ts +129 -0
  420. package/src/services/tx_collection/index.ts +2 -6
  421. package/src/services/tx_collection/instrumentation.ts +1 -1
  422. package/src/services/tx_collection/request_tracker.ts +127 -0
  423. package/src/services/tx_collection/tx_collection.ts +362 -110
  424. package/src/services/tx_collection/tx_collection_sink.ts +32 -36
  425. package/src/services/tx_collection/tx_source.ts +29 -8
  426. package/src/services/tx_file_store/config.ts +0 -6
  427. package/src/services/tx_file_store/tx_file_store.ts +15 -25
  428. package/src/services/tx_provider.ts +15 -9
  429. package/src/test-helpers/make-test-p2p-clients.ts +7 -6
  430. package/src/test-helpers/mock-pubsub.ts +152 -14
  431. package/src/test-helpers/reqresp-nodes.ts +15 -28
  432. package/src/test-helpers/test_tx_provider.ts +5 -0
  433. package/src/test-helpers/testbench-utils.ts +171 -68
  434. package/src/testbench/p2p_client_testbench_worker.ts +121 -64
  435. package/src/testbench/worker_client_manager.ts +72 -25
  436. package/src/util.ts +40 -19
  437. package/src/versioning.ts +3 -33
  438. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
  439. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
  440. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
  441. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
  442. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
  443. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
  444. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  445. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  446. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  447. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  448. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  449. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  450. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  451. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  452. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  453. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  454. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  455. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
  456. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  457. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  458. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  459. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  460. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  461. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  462. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  463. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  464. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  465. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  466. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  467. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  468. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  469. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  470. package/dest/mem_pools/tx_pool/index.js +0 -2
  471. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  472. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  473. package/dest/mem_pools/tx_pool/priority.js +0 -15
  474. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  475. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  476. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  477. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  478. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  479. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
  480. package/dest/msg_validators/clock_tolerance.d.ts +0 -21
  481. package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
  482. package/dest/msg_validators/clock_tolerance.js +0 -37
  483. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  484. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  485. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  486. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
  487. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  488. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
  489. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  490. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  491. package/dest/services/reqresp/protocols/block.js +0 -32
  492. package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -52
  493. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
  494. package/dest/services/tx_collection/fast_tx_collection.js +0 -307
  495. package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
  496. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
  497. package/dest/services/tx_collection/proposal_tx_collector.js +0 -49
  498. package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -53
  499. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
  500. package/dest/services/tx_collection/slow_tx_collection.js +0 -177
  501. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -336
  502. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
  503. package/src/mem_pools/tx_pool/README.md +0 -270
  504. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  505. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  506. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  507. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
  508. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  509. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  510. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  511. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  512. package/src/mem_pools/tx_pool/index.ts +0 -2
  513. package/src/mem_pools/tx_pool/priority.ts +0 -20
  514. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  515. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
  516. package/src/msg_validators/clock_tolerance.ts +0 -51
  517. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
  518. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
  519. package/src/services/reqresp/protocols/block.ts +0 -37
  520. package/src/services/tx_collection/fast_tx_collection.ts +0 -354
  521. package/src/services/tx_collection/proposal_tx_collector.ts +0 -112
  522. package/src/services/tx_collection/slow_tx_collection.ts +0 -233
@@ -1,7 +1,9 @@
1
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, CheckpointProposalCore } from '@aztec/stdlib/p2p';
4
+ import { Signature } from '@aztec/foundation/eth-signature';
5
+ import type { BlockProposal, CheckpointProposalCore } from '@aztec/stdlib/p2p';
6
+ import { CheckpointAttestation } from '@aztec/stdlib/p2p';
5
7
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
6
8
  import {
7
9
  makeBlockHeader,
@@ -10,7 +12,11 @@ import {
10
12
  makeCheckpointProposal,
11
13
  } from '@aztec/stdlib/testing';
12
14
 
13
- import { type AttestationPool, MAX_PROPOSALS_PER_POSITION, MAX_PROPOSALS_PER_SLOT } from './attestation_pool.js';
15
+ import {
16
+ type AttestationPool,
17
+ MAX_BLOCK_PROPOSALS_PER_POSITION,
18
+ MAX_CHECKPOINT_PROPOSALS_PER_SLOT,
19
+ } from './attestation_pool.js';
14
20
  import { mockCheckpointAttestation } from './mocks.js';
15
21
 
16
22
  const NUMBER_OF_SIGNERS_PER_TEST = 4;
@@ -24,9 +30,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
24
30
  signers = Array.from({ length: NUMBER_OF_SIGNERS_PER_TEST }, () => Secp256k1Signer.random());
25
31
  });
26
32
 
33
+ /**
34
+ * Build attestations from each signer over the *same* signed payload (same header,
35
+ * archive, feeAssetPriceModifier). Required by the new pool, which deduplicates by
36
+ * payload hash and treats attestations from different signers as distinct entries
37
+ * only when the payload itself matches.
38
+ */
27
39
  const createCheckpointAttestationsForSlot = (slotNumber: number, archive?: Fr) => {
28
40
  const archiveToUse = archive ?? Fr.random();
29
- return signers.map(signer => mockCheckpointAttestation(signer, slotNumber, archiveToUse));
41
+ const sharedHeader = CheckpointHeader.random({ slotNumber: SlotNumber(slotNumber) });
42
+ return signers.map(signer => mockCheckpointAttestation(signer, slotNumber, archiveToUse, sharedHeader));
30
43
  };
31
44
 
32
45
  const mockBlockProposalForPool = (
@@ -51,17 +64,58 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
51
64
  expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
52
65
  };
53
66
 
67
+ /**
68
+ * Rewrites the attester signature into yParity form (27 -> 0, 28 -> 1), keeping (r, s). The recovery
69
+ * bit is unchanged so it still recovers to the same signer, mimicking a peer that gossips (or mutates
70
+ * in flight) a signature with a non-canonical recovery byte.
71
+ */
72
+ const toYParityForm = (attestation: CheckpointAttestation): CheckpointAttestation => {
73
+ const sig = attestation.signature;
74
+ const yParityV = sig.v === 27 ? 0 : sig.v === 28 ? 1 : sig.v;
75
+ return new CheckpointAttestation(
76
+ attestation.payload,
77
+ new Signature(sig.r, sig.s, yParityV),
78
+ attestation.proposerSignature,
79
+ );
80
+ };
81
+
54
82
  describe('CheckpointAttestation', () => {
83
+ it('normalizes yParity (v=0/v=1) attester signatures on ingress from both gossip and own keys', async () => {
84
+ const slotNumber = 421;
85
+ const canonical = createCheckpointAttestationsForSlot(slotNumber);
86
+ const payloadHash = canonical[0].getPayloadHash();
87
+ const expectedSenders = new Set([canonical[0].getSender()!.toString(), canonical[1].getSender()!.toString()]);
88
+
89
+ const gossiped = toYParityForm(canonical[0]);
90
+ expect([0, 1]).toContain(gossiped.signature.v);
91
+ await ap.tryAddCheckpointAttestation(gossiped);
92
+
93
+ const own = toYParityForm(canonical[1]);
94
+ expect([0, 1]).toContain(own.signature.v);
95
+ await ap.addOwnCheckpointAttestations([own]);
96
+
97
+ const retrieved = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
98
+ expect(retrieved.length).toBe(2);
99
+ for (const attestation of retrieved) {
100
+ expect([27, 28]).toContain(attestation.signature.v);
101
+ expect(expectedSenders.has(attestation.getSender()!.toString())).toBe(true);
102
+ }
103
+ });
104
+
55
105
  it('should add attestations to pool', async () => {
56
106
  const slotNumber = 420;
57
107
  const archive = Fr.random();
58
- const attestations = signers.slice(0, -1).map(signer => mockCheckpointAttestation(signer, slotNumber, archive));
108
+ const sharedHeader = CheckpointHeader.random({ slotNumber: SlotNumber(slotNumber) });
109
+ const attestations = signers
110
+ .slice(0, -1)
111
+ .map(signer => mockCheckpointAttestation(signer, slotNumber, archive, sharedHeader));
112
+ const payloadHash = attestations[0].getPayloadHash();
59
113
 
60
114
  await ap.addOwnCheckpointAttestations(attestations);
61
115
 
62
116
  const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
63
117
  SlotNumber(slotNumber),
64
- archive.toString(),
118
+ payloadHash,
65
119
  );
66
120
  expect(retrievedAttestations.length).toBe(attestations.length);
67
121
  compareCheckpointAttestations(retrievedAttestations, attestations);
@@ -71,11 +125,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
71
125
  compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
72
126
 
73
127
  // Add another one
74
- const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
128
+ const newAttestation = mockCheckpointAttestation(
129
+ signers[NUMBER_OF_SIGNERS_PER_TEST - 1],
130
+ slotNumber,
131
+ archive,
132
+ sharedHeader,
133
+ );
75
134
  await ap.addOwnCheckpointAttestations([newAttestation]);
76
135
  const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(
77
136
  SlotNumber(slotNumber),
78
- archive.toString(),
137
+ payloadHash,
79
138
  );
80
139
  expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
81
140
  compareCheckpointAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
@@ -88,7 +147,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
88
147
 
89
148
  const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
90
149
  SlotNumber(slotNumber),
91
- archive.toString(),
150
+ payloadHash,
92
151
  );
93
152
  expect(retreivedAttestationsAfterDelete.length).toBe(0);
94
153
  });
@@ -104,13 +163,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
104
163
  for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
105
164
  attestations.push(mockCheckpointAttestation(signer, slotNumber, archive, header));
106
165
  }
166
+ const payloadHash = attestations[0].getPayloadHash();
107
167
 
108
168
  // Add them to store and check we end up with only one
109
169
  await ap.addOwnCheckpointAttestations(attestations);
110
170
 
111
171
  const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
112
172
  SlotNumber(slotNumber),
113
- archive.toString(),
173
+ payloadHash,
114
174
  );
115
175
  expect(retreivedAttestations.length).toBe(1);
116
176
  expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
@@ -118,9 +178,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
118
178
 
119
179
  // Try adding them on another operation and check they are still not duplicated
120
180
  await ap.addOwnCheckpointAttestations([attestations[0]]);
121
- expect(
122
- await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString()),
123
- ).toHaveLength(1);
181
+ expect(await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash)).toHaveLength(1);
124
182
  });
125
183
 
126
184
  it('should store attestations by differing slot', async () => {
@@ -131,9 +189,9 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
131
189
 
132
190
  for (const attestation of attestations) {
133
191
  const slot = attestation.payload.header.slotNumber;
134
- const archive = attestation.archive.toString();
192
+ const payloadHash = attestation.getPayloadHash();
135
193
 
136
- const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, archive);
194
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
137
195
  expect(retreivedAttestations.length).toBe(1);
138
196
  expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
139
197
  expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
@@ -149,9 +207,9 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
149
207
 
150
208
  for (const attestation of attestations) {
151
209
  const slot = attestation.payload.header.slotNumber;
152
- const proposalId = attestation.archive.toString();
210
+ const payloadHash = attestation.getPayloadHash();
153
211
 
154
- const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, proposalId);
212
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
155
213
  expect(retreivedAttestations.length).toBe(1);
156
214
  expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
157
215
  expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
@@ -160,21 +218,25 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
160
218
 
161
219
  it('should delete attestations older than a given slot', async () => {
162
220
  const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420];
163
- const attestations = (
164
- await Promise.all(slotNumbers.map(slotNumber => createCheckpointAttestationsForSlot(slotNumber)))
165
- ).flat();
166
- const proposalId = attestations[0].archive.toString();
221
+ const attestationsPerSlot = await Promise.all(
222
+ slotNumbers.map(slotNumber => createCheckpointAttestationsForSlot(slotNumber)),
223
+ );
224
+ const attestations = attestationsPerSlot.flat();
225
+ const payloadHashForSlot1 = attestationsPerSlot[0][0].getPayloadHash();
167
226
 
168
227
  await ap.addOwnCheckpointAttestations(attestations);
169
228
 
170
- const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
229
+ const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(
230
+ SlotNumber(1),
231
+ payloadHashForSlot1,
232
+ );
171
233
  expect(attestationsForSlot1.length).toBe(signers.length);
172
234
 
173
235
  await ap.deleteOlderThan(SlotNumber(73));
174
236
 
175
237
  const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
176
238
  SlotNumber(1),
177
- proposalId,
239
+ payloadHashForSlot1,
178
240
  );
179
241
  expect(attestationsForSlot1AfterDelete.length).toBe(0);
180
242
  });
@@ -185,15 +247,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
185
247
  const slotNumber = 420;
186
248
  const archive = Fr.random();
187
249
  const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
188
- const proposalId = proposal.archive.toString();
189
250
 
190
251
  const result = await ap.tryAddBlockProposal(proposal);
191
252
 
192
253
  expect(result.added).toBe(true);
193
254
  expect(result.alreadyExists).toBe(false);
194
- expect(result.totalForPosition).toBe(1);
255
+ expect(result.count).toBe(1);
195
256
 
196
- const retrievedProposal = await ap.getBlockProposal(proposalId);
257
+ const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
197
258
 
198
259
  expect(retrievedProposal).toBeDefined();
199
260
  expect(retrievedProposal!).toEqual(proposal);
@@ -201,33 +262,68 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
201
262
 
202
263
  it('should return undefined for non-existent block proposal', async () => {
203
264
  const nonExistentId = Fr.random().toString();
204
- const retrievedProposal = await ap.getBlockProposal(nonExistentId);
265
+ const retrievedProposal = await ap.getBlockProposalByArchive(nonExistentId);
205
266
  expect(retrievedProposal).toBeUndefined();
206
267
  });
207
268
 
208
- it('should return alreadyExists when adding proposal with same id', async () => {
269
+ it('should return alreadyExists when re-adding the same signed payload', async () => {
209
270
  const slotNumber = 420;
210
271
  const archive = Fr.random();
211
- const proposal1 = await mockBlockProposalForPool(signers[0], slotNumber, archive);
212
- const proposalId = proposal1.archive.toString();
272
+ const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
213
273
 
214
- const result1 = await ap.tryAddBlockProposal(proposal1);
274
+ const result1 = await ap.tryAddBlockProposal(proposal);
215
275
  expect(result1.added).toBe(true);
216
276
  expect(result1.alreadyExists).toBe(false);
217
277
 
218
- // Create a new proposal with same archive but different signer
219
- const proposal2 = await mockBlockProposalForPool(signers[1], slotNumber, archive);
220
-
221
- const result2 = await ap.tryAddBlockProposal(proposal2);
278
+ // Re-broadcasting the exact same proposal yields alreadyExists.
279
+ const result2 = await ap.tryAddBlockProposal(proposal);
222
280
  expect(result2.added).toBe(false);
223
281
  expect(result2.alreadyExists).toBe(true);
224
282
 
225
- // Should still have the first proposal
226
- const retrievedProposal = await ap.getBlockProposal(proposalId);
283
+ const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
227
284
  expect(retrievedProposal).toBeDefined();
228
- expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer());
285
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
229
286
  expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
230
287
  });
288
+
289
+ it('should retain an exact duplicate block proposal only once', async () => {
290
+ const slotNumber = 420;
291
+ const proposal = await mockBlockProposalForPool(signers[0], slotNumber);
292
+
293
+ await ap.tryAddBlockProposal(proposal);
294
+ await ap.tryAddBlockProposal(proposal);
295
+
296
+ const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
297
+ expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual([
298
+ proposal.withoutSignedTxs().toBuffer(),
299
+ ]);
300
+ });
301
+
302
+ it('should retain all accepted block proposals at a position', async () => {
303
+ const slotNumber = 420;
304
+ const blockHeader = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) });
305
+ const proposal1 = await makeBlockProposal({
306
+ signer: signers[0],
307
+ blockHeader,
308
+ archiveRoot: Fr.random(),
309
+ indexWithinCheckpoint: IndexWithinCheckpoint(1),
310
+ });
311
+ const proposal2 = await makeBlockProposal({
312
+ signer: signers[0],
313
+ blockHeader,
314
+ archiveRoot: Fr.random(),
315
+ indexWithinCheckpoint: IndexWithinCheckpoint(1),
316
+ });
317
+
318
+ await ap.tryAddBlockProposal(proposal1);
319
+ await ap.tryAddBlockProposal(proposal2);
320
+
321
+ const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
322
+ expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual(
323
+ expect.arrayContaining([proposal1.withoutSignedTxs().toBuffer(), proposal2.withoutSignedTxs().toBuffer()]),
324
+ );
325
+ expect(await ap.getBlockProposalByArchive(proposal2.archive.toString())).toBeDefined();
326
+ });
231
327
  });
232
328
 
233
329
  describe('CheckpointProposal in attestation pool', () => {
@@ -235,12 +331,13 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
235
331
  signer: Secp256k1Signer,
236
332
  slotNumber: number,
237
333
  archive: Fr = Fr.random(),
334
+ checkpointHeader?: CheckpointHeader,
238
335
  ): Promise<CheckpointProposalCore> => {
239
- const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
336
+ const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
240
337
  const blockHeader = makeBlockHeader(1);
241
338
  const proposal = await makeCheckpointProposal({
242
339
  signer,
243
- checkpointHeader,
340
+ checkpointHeader: headerToUse,
244
341
  archiveRoot: archive,
245
342
  lastBlock: { blockHeader },
246
343
  });
@@ -252,15 +349,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
252
349
  const slotNumber = 420;
253
350
  const archive = Fr.random();
254
351
  const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
255
- const proposalId = proposal.archive.toString();
256
352
 
257
353
  const result = await ap.tryAddCheckpointProposal(proposal);
258
354
 
259
355
  expect(result.added).toBe(true);
260
356
  expect(result.alreadyExists).toBe(false);
261
- expect(result.totalForPosition).toBe(1);
357
+ expect(result.count).toBe(1);
262
358
 
263
- const retrievedProposal = await ap.getCheckpointProposal(proposalId);
359
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
264
360
 
265
361
  expect(retrievedProposal).toBeDefined();
266
362
  expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
@@ -277,67 +373,149 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
277
373
  archiveRoot: archive,
278
374
  // No lastBlock
279
375
  });
280
- const proposalId = proposal.archive.toString();
281
376
 
282
377
  // Add the checkpoint core - block extraction is now caller responsibility
283
378
  await ap.tryAddCheckpointProposal(proposal.toCore());
284
379
 
285
380
  // The checkpoint proposal should be stored
286
- const retrievedCheckpointProposal = await ap.getCheckpointProposal(proposalId);
381
+ const retrievedCheckpointProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
287
382
  expect(retrievedCheckpointProposal).toBeDefined();
288
383
 
289
384
  // No block proposal was extracted (it had none anyway)
290
- const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
385
+ const retrievedBlockProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
291
386
  expect(retrievedBlockProposal).toBeUndefined();
292
387
  });
293
388
 
294
389
  it('should return undefined for non-existent checkpoint proposal', async () => {
295
- const nonExistentId = Fr.random().toString();
296
- const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
390
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(99999));
297
391
  expect(retrievedProposal).toBeUndefined();
298
392
  });
299
393
 
300
- it('should return alreadyExists when adding proposal with same id', async () => {
394
+ it('should return alreadyExists when re-adding the same signed payload', async () => {
301
395
  const slotNumber = 420;
302
396
  const archive = Fr.random();
303
- const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
304
- const proposalId = proposal1.archive.toString();
397
+ const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
305
398
 
306
- const result1 = await ap.tryAddCheckpointProposal(proposal1);
399
+ const result1 = await ap.tryAddCheckpointProposal(proposal);
307
400
  expect(result1.added).toBe(true);
308
401
  expect(result1.alreadyExists).toBe(false);
309
402
 
310
- // Create a new proposal with same archive but different signer
311
- const proposal2 = await mockCheckpointProposalForPool(signers[1], slotNumber, archive);
312
-
313
- const result2 = await ap.tryAddCheckpointProposal(proposal2);
403
+ // Re-broadcasting the exact same signed payload yields alreadyExists.
404
+ const result2 = await ap.tryAddCheckpointProposal(proposal);
314
405
  expect(result2.added).toBe(false);
315
406
  expect(result2.alreadyExists).toBe(true);
316
407
 
317
- // Should still have the first proposal
318
- const retrievedProposal = await ap.getCheckpointProposal(proposalId);
408
+ // Should still have the first proposal stored at the slot
409
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
319
410
  expect(retrievedProposal).toBeDefined();
320
- expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer());
411
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
321
412
  expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
322
413
  });
323
414
 
415
+ it('should treat distinct payloads at the same slot as equivocations (count = 2)', async () => {
416
+ const slotNumber = 420;
417
+ // Two proposals at the same slot but with different headers (distinct payloads).
418
+ const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
419
+ const proposal2 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
420
+
421
+ const result1 = await ap.tryAddCheckpointProposal(proposal1);
422
+ expect(result1.added).toBe(true);
423
+ expect(result1.count).toBe(1);
424
+
425
+ const result2 = await ap.tryAddCheckpointProposal(proposal2);
426
+ // The second distinct payload is tracked as an equivocation, count goes to 2,
427
+ // and both accepted payloads are retained by payload hash.
428
+ expect(result2.added).toBe(true);
429
+ expect(result2.alreadyExists).toBe(false);
430
+ expect(result2.count).toBe(2);
431
+
432
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
433
+ const expectedProposal = [proposal1, proposal2].sort((a, b) =>
434
+ a.getPayloadHash().localeCompare(b.getPayloadHash()),
435
+ )[0];
436
+ expect(retrievedProposal!.toBuffer()).toEqual(expectedProposal.toBuffer());
437
+
438
+ const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
439
+ expect(proposals.checkpointProposals.map(proposal => proposal.toBuffer())).toEqual(
440
+ expect.arrayContaining([proposal1.toBuffer(), proposal2.toBuffer()]),
441
+ );
442
+ });
443
+
444
+ it('should detect equivocation when only feeAssetPriceModifier differs', async () => {
445
+ const slotNumber = 420;
446
+ const archive = Fr.random();
447
+ // Same checkpoint header + archive, but two different feeAssetPriceModifier values.
448
+ // This is the audit-finding scenario: archive collides but the signed payload differs.
449
+ const sharedHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
450
+ const proposalA = await makeCheckpointProposal({
451
+ signer: signers[0],
452
+ checkpointHeader: sharedHeader,
453
+ archiveRoot: archive,
454
+ feeAssetPriceModifier: 50n,
455
+ });
456
+ const proposalB = await makeCheckpointProposal({
457
+ signer: signers[0],
458
+ checkpointHeader: sharedHeader,
459
+ archiveRoot: archive,
460
+ feeAssetPriceModifier: -50n,
461
+ });
462
+
463
+ const result1 = await ap.tryAddCheckpointProposal(proposalA.toCore());
464
+ expect(result1.count).toBe(1);
465
+
466
+ const result2 = await ap.tryAddCheckpointProposal(proposalB.toCore());
467
+ // The fix: archive collision no longer hides the equivocation; payload-hash dedup
468
+ // sees the distinct feeMod and bumps `count` to 2 so libp2p can fire the slash callback.
469
+ expect(result2.added).toBe(true);
470
+ expect(result2.alreadyExists).toBe(false);
471
+ expect(result2.count).toBe(2);
472
+ });
473
+
474
+ it('should delete retained proposals older than a given slot', async () => {
475
+ const oldSlot = 100;
476
+ const newSlot = 200;
477
+ const oldBlock = await mockBlockProposalForPool(signers[0], oldSlot);
478
+ const newBlock = await mockBlockProposalForPool(signers[1], newSlot);
479
+ const oldCheckpoint = await mockCheckpointProposalForPool(signers[0], oldSlot);
480
+ const newCheckpoint = await mockCheckpointProposalForPool(signers[1], newSlot);
481
+
482
+ await ap.tryAddBlockProposal(oldBlock);
483
+ await ap.tryAddBlockProposal(newBlock);
484
+ await ap.tryAddCheckpointProposal(oldCheckpoint);
485
+ await ap.tryAddCheckpointProposal(newCheckpoint);
486
+
487
+ await ap.deleteOlderThan(SlotNumber(newSlot));
488
+
489
+ expect(await ap.getProposalsForSlot(SlotNumber(oldSlot))).toEqual({
490
+ blockProposals: [],
491
+ checkpointProposals: [],
492
+ });
493
+ const newProposals = await ap.getProposalsForSlot(SlotNumber(newSlot));
494
+ expect(newProposals.blockProposals.map(proposal => proposal.toBuffer())).toContainEqual(
495
+ newBlock.withoutSignedTxs().toBuffer(),
496
+ );
497
+ expect(newProposals.checkpointProposals.map(proposal => proposal.toBuffer())).toContainEqual(
498
+ newCheckpoint.toBuffer(),
499
+ );
500
+ });
501
+
324
502
  it('should return added=false when exceeding capacity', async () => {
325
503
  const slotNumber = 420;
326
504
 
327
- // Add MAX_PROPOSALS_PER_SLOT proposals
328
- for (let i = 0; i < MAX_PROPOSALS_PER_SLOT; i++) {
505
+ // Add MAX_CHECKPOINT_PROPOSALS_PER_SLOT distinct proposals.
506
+ for (let i = 0; i < MAX_CHECKPOINT_PROPOSALS_PER_SLOT; i++) {
329
507
  const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
330
508
  const result = await ap.tryAddCheckpointProposal(proposal);
331
509
  expect(result.added).toBe(true);
332
- expect(result.totalForPosition).toBe(i + 1);
510
+ expect(result.count).toBe(i + 1);
333
511
  }
334
512
 
335
- // The next proposal should not be added
513
+ // The next proposal should not be added.
336
514
  const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
337
515
  const result = await ap.tryAddCheckpointProposal(extraProposal);
338
516
  expect(result.added).toBe(false);
339
517
  expect(result.alreadyExists).toBe(false);
340
- expect(result.totalForPosition).toBe(MAX_PROPOSALS_PER_SLOT);
518
+ expect(result.count).toBe(MAX_CHECKPOINT_PROPOSALS_PER_SLOT);
341
519
  });
342
520
  });
343
521
 
@@ -358,13 +536,13 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
358
536
  };
359
537
 
360
538
  describe('tryAddBlockProposal duplicate detection', () => {
361
- it('should return totalForPosition=1 when pool is empty', async () => {
539
+ it('should return count=1 when pool is empty', async () => {
362
540
  const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
363
541
  const result = await ap.tryAddBlockProposal(proposal);
364
542
 
365
543
  expect(result.added).toBe(true);
366
544
  expect(result.alreadyExists).toBe(false);
367
- expect(result.totalForPosition).toBe(1);
545
+ expect(result.count).toBe(1);
368
546
  });
369
547
 
370
548
  it('should return alreadyExists when same proposal exists', async () => {
@@ -375,17 +553,17 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
375
553
 
376
554
  expect(result.added).toBe(false);
377
555
  expect(result.alreadyExists).toBe(true);
378
- expect(result.totalForPosition).toBe(1);
556
+ expect(result.count).toBe(1);
379
557
  });
380
558
 
381
- it('should detect duplicate via totalForPosition when different proposal exists at same position', async () => {
559
+ it('should detect duplicate via count when different proposal exists at same position', async () => {
382
560
  const slotNumber = 100;
383
561
  const indexWithinCheckpoint = 2;
384
562
 
385
563
  // Add first proposal
386
564
  const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
387
565
  const result1 = await ap.tryAddBlockProposal(proposal1);
388
- expect(result1.totalForPosition).toBe(1);
566
+ expect(result1.count).toBe(1);
389
567
 
390
568
  // Add a different proposal at same position - this is a duplicate (equivocation)
391
569
  const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
@@ -393,8 +571,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
393
571
 
394
572
  expect(result2.added).toBe(true);
395
573
  expect(result2.alreadyExists).toBe(false);
396
- // totalForPosition >= 2 indicates duplicate detection
397
- expect(result2.totalForPosition).toBe(2);
574
+ // count >= 2 indicates duplicate detection
575
+ expect(result2.count).toBe(2);
398
576
  });
399
577
 
400
578
  it('should not detect duplicate for different positions in same slot', async () => {
@@ -409,8 +587,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
409
587
  const result = await ap.tryAddBlockProposal(proposal2);
410
588
 
411
589
  expect(result.added).toBe(true);
412
- // totalForPosition = 1 means no duplicate for this position
413
- expect(result.totalForPosition).toBe(1);
590
+ // count = 1 means no duplicate for this position
591
+ expect(result.count).toBe(1);
414
592
  });
415
593
 
416
594
  it('should not detect duplicate for same position in different slots', async () => {
@@ -425,37 +603,37 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
425
603
  const result = await ap.tryAddBlockProposal(proposal2);
426
604
 
427
605
  expect(result.added).toBe(true);
428
- // totalForPosition = 1 means no duplicate for this position
429
- expect(result.totalForPosition).toBe(1);
606
+ // count = 1 means no duplicate for this position
607
+ expect(result.count).toBe(1);
430
608
  });
431
609
 
432
- it('should track multiple duplicates correctly via totalForPosition', async () => {
610
+ it('should track multiple duplicates correctly via count', async () => {
433
611
  const slotNumber = 100;
434
612
  const indexWithinCheckpoint = 0;
435
613
 
436
614
  // Add multiple proposals for same position
437
615
  const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
438
616
  const result1 = await ap.tryAddBlockProposal(proposal1);
439
- expect(result1.totalForPosition).toBe(1);
617
+ expect(result1.count).toBe(1);
440
618
 
441
619
  const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
442
620
  const result2 = await ap.tryAddBlockProposal(proposal2);
443
- expect(result2.totalForPosition).toBe(2);
621
+ expect(result2.count).toBe(2);
444
622
 
445
- // Add a third proposal for same position
623
+ // Third proposal for same position should be rejected (cap is 2)
446
624
  const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
447
625
  const result3 = await ap.tryAddBlockProposal(proposal3);
448
626
 
449
- expect(result3.added).toBe(true);
450
- expect(result3.totalForPosition).toBe(3);
627
+ expect(result3.added).toBe(false);
628
+ expect(result3.count).toBe(2);
451
629
  });
452
630
 
453
631
  it('should return added=false when exceeding capacity', async () => {
454
632
  const slotNumber = 100;
455
633
  const indexWithinCheckpoint = 0;
456
634
 
457
- // Add MAX_PROPOSALS_PER_POSITION proposals
458
- for (let i = 0; i < MAX_PROPOSALS_PER_POSITION; i++) {
635
+ // Add MAX_BLOCK_PROPOSALS_PER_POSITION proposals
636
+ for (let i = 0; i < MAX_BLOCK_PROPOSALS_PER_POSITION; i++) {
459
637
  const proposal = await mockBlockProposalWithIndex(
460
638
  signers[i % NUMBER_OF_SIGNERS_PER_TEST],
461
639
  slotNumber,
@@ -463,7 +641,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
463
641
  );
464
642
  const result = await ap.tryAddBlockProposal(proposal);
465
643
  expect(result.added).toBe(true);
466
- expect(result.totalForPosition).toBe(i + 1);
644
+ expect(result.count).toBe(i + 1);
467
645
  }
468
646
 
469
647
  // The next proposal should not be added
@@ -471,7 +649,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
471
649
  const result = await ap.tryAddBlockProposal(extraProposal);
472
650
  expect(result.added).toBe(false);
473
651
  expect(result.alreadyExists).toBe(false);
474
- expect(result.totalForPosition).toBe(MAX_PROPOSALS_PER_POSITION);
652
+ expect(result.count).toBe(MAX_BLOCK_PROPOSALS_PER_POSITION);
475
653
  });
476
654
 
477
655
  it('should clean up block position index when deleting old data', async () => {
@@ -482,18 +660,18 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
482
660
  const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
483
661
  await ap.tryAddBlockProposal(proposal1);
484
662
 
485
- // Verify it's tracked (adding another should show totalForPosition = 2)
663
+ // Verify it's tracked (adding another should show count = 2)
486
664
  const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
487
665
  let result = await ap.tryAddBlockProposal(proposal2);
488
- expect(result.totalForPosition).toBe(2);
666
+ expect(result.count).toBe(2);
489
667
 
490
668
  // Delete old data
491
669
  await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
492
670
 
493
- // Verify position index is cleaned up (totalForPosition should be 1 now)
671
+ // Verify position index is cleaned up (count should be 1 now)
494
672
  const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
495
673
  result = await ap.tryAddBlockProposal(proposal3);
496
- expect(result.totalForPosition).toBe(1);
674
+ expect(result.count).toBe(1);
497
675
  });
498
676
 
499
677
  it('should correctly delete block proposals at slot boundary', async () => {
@@ -514,16 +692,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
514
692
  // Slot 99 proposals should have their index cleaned up
515
693
  const newProposal99 = await mockBlockProposalWithIndex(signers[0], 99, 0);
516
694
  const result99 = await ap.tryAddBlockProposal(newProposal99);
517
- expect(result99.totalForPosition).toBe(1); // Index was cleaned up
695
+ expect(result99.count).toBe(1); // Index was cleaned up
518
696
 
519
697
  // Slot 100 and 101 should still be tracked
520
698
  const newProposal100 = await mockBlockProposalWithIndex(signers[1], 100, 0);
521
699
  const result100 = await ap.tryAddBlockProposal(newProposal100);
522
- expect(result100.totalForPosition).toBe(2); // Still has the original
700
+ expect(result100.count).toBe(2); // Still has the original
523
701
 
524
702
  const newProposal101 = await mockBlockProposalWithIndex(signers[2], 101, 0);
525
703
  const result101 = await ap.tryAddBlockProposal(newProposal101);
526
- expect(result101.totalForPosition).toBe(2); // Still has the original
704
+ expect(result101.count).toBe(2); // Still has the original
527
705
  });
528
706
 
529
707
  it('should delete all indices for a given slot', async () => {
@@ -544,15 +722,15 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
544
722
  // All indices should be cleaned up
545
723
  const newProposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
546
724
  const result0 = await ap.tryAddBlockProposal(newProposal0);
547
- expect(result0.totalForPosition).toBe(1);
725
+ expect(result0.count).toBe(1);
548
726
 
549
727
  const newProposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
550
728
  const result1 = await ap.tryAddBlockProposal(newProposal1);
551
- expect(result1.totalForPosition).toBe(1);
729
+ expect(result1.count).toBe(1);
552
730
 
553
731
  const newProposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
554
732
  const result2 = await ap.tryAddBlockProposal(newProposal2);
555
- expect(result2.totalForPosition).toBe(1);
733
+ expect(result2.count).toBe(1);
556
734
  });
557
735
 
558
736
  it('should delete block proposals from storage when deleting old data', async () => {
@@ -567,17 +745,17 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
567
745
  await ap.tryAddBlockProposal(newProposal);
568
746
 
569
747
  // Verify both proposals exist
570
- expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeDefined();
571
- expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
748
+ expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeDefined();
749
+ expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
572
750
 
573
751
  // Delete slots older than newSlot (should delete oldSlot)
574
752
  await ap.deleteOlderThan(SlotNumber(newSlot));
575
753
 
576
754
  // Old proposal should be deleted from storage
577
- expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeUndefined();
755
+ expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeUndefined();
578
756
 
579
757
  // New proposal should still exist
580
- expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
758
+ expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
581
759
  });
582
760
  });
583
761
 
@@ -586,25 +764,26 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
586
764
  signer: Secp256k1Signer,
587
765
  slotNumber: number,
588
766
  archive: Fr = Fr.random(),
767
+ checkpointHeader?: CheckpointHeader,
589
768
  ): Promise<CheckpointProposalCore> => {
590
- const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
769
+ const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
591
770
  const blockHeader = makeBlockHeader(1);
592
771
  const proposal = await makeCheckpointProposal({
593
772
  signer,
594
- checkpointHeader,
773
+ checkpointHeader: headerToUse,
595
774
  archiveRoot: archive,
596
775
  lastBlock: { blockHeader },
597
776
  });
598
777
  return proposal.toCore();
599
778
  };
600
779
 
601
- it('should return totalForPosition=1 when pool is empty', async () => {
780
+ it('should return count=1 when pool is empty', async () => {
602
781
  const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
603
782
  const result = await ap.tryAddCheckpointProposal(proposal);
604
783
 
605
784
  expect(result.added).toBe(true);
606
785
  expect(result.alreadyExists).toBe(false);
607
- expect(result.totalForPosition).toBe(1);
786
+ expect(result.count).toBe(1);
608
787
  });
609
788
 
610
789
  it('should return alreadyExists when same proposal exists', async () => {
@@ -615,16 +794,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
615
794
 
616
795
  expect(result.added).toBe(false);
617
796
  expect(result.alreadyExists).toBe(true);
618
- expect(result.totalForPosition).toBe(1);
797
+ expect(result.count).toBe(1);
619
798
  });
620
799
 
621
- it('should detect duplicate via totalForPosition when different proposal exists for same slot', async () => {
800
+ it('should detect duplicate via count when different proposal exists for same slot', async () => {
622
801
  const slotNumber = 100;
623
802
 
624
803
  // Add first proposal
625
804
  const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
626
805
  const result1 = await ap.tryAddCheckpointProposal(proposal1);
627
- expect(result1.totalForPosition).toBe(1);
806
+ expect(result1.count).toBe(1);
628
807
 
629
808
  // Add a different proposal for same slot - this is a duplicate (equivocation)
630
809
  const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
@@ -632,8 +811,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
632
811
 
633
812
  expect(result2.added).toBe(true);
634
813
  expect(result2.alreadyExists).toBe(false);
635
- // totalForPosition >= 2 indicates duplicate detection
636
- expect(result2.totalForPosition).toBe(2);
814
+ // count >= 2 indicates duplicate detection
815
+ expect(result2.count).toBe(2);
637
816
  });
638
817
 
639
818
  it('should not detect duplicate for different slots', async () => {
@@ -646,28 +825,28 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
646
825
  const result = await ap.tryAddCheckpointProposal(proposal2);
647
826
 
648
827
  expect(result.added).toBe(true);
649
- // totalForPosition = 1 means no duplicate for this slot
650
- expect(result.totalForPosition).toBe(1);
828
+ // count = 1 means no duplicate for this slot
829
+ expect(result.count).toBe(1);
651
830
  });
652
831
 
653
- it('should track multiple duplicates correctly via totalForPosition', async () => {
832
+ it('should track multiple duplicates correctly via count', async () => {
654
833
  const slotNumber = 100;
655
834
 
656
835
  // Add multiple proposals for same slot
657
836
  const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
658
837
  const result1 = await ap.tryAddCheckpointProposal(proposal1);
659
- expect(result1.totalForPosition).toBe(1);
838
+ expect(result1.count).toBe(1);
660
839
 
661
840
  const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
662
841
  const result2 = await ap.tryAddCheckpointProposal(proposal2);
663
- expect(result2.totalForPosition).toBe(2);
842
+ expect(result2.count).toBe(2);
664
843
 
665
- // Add a third proposal for same slot
844
+ // Third proposal for same slot should be rejected (cap is 2)
666
845
  const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
667
846
  const result3 = await ap.tryAddCheckpointProposal(proposal3);
668
847
 
669
- expect(result3.added).toBe(true);
670
- expect(result3.totalForPosition).toBe(3);
848
+ expect(result3.added).toBe(false);
849
+ expect(result3.count).toBe(2);
671
850
  });
672
851
 
673
852
  it('should not count attestations as proposals for duplicate detection', async () => {
@@ -684,8 +863,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
684
863
 
685
864
  expect(result.added).toBe(true);
686
865
  expect(result.alreadyExists).toBe(false);
687
- // totalForPosition should be 1, NOT 2 - attestations should not count as proposals
688
- expect(result.totalForPosition).toBe(1);
866
+ // count should be 1, NOT 2 - attestations should not count as proposals
867
+ expect(result.count).toBe(1);
689
868
  });
690
869
 
691
870
  it('should not count attestations for different proposals as duplicates', async () => {
@@ -703,14 +882,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
703
882
  const result1 = await ap.tryAddCheckpointProposal(proposal1);
704
883
 
705
884
  expect(result1.added).toBe(true);
706
- expect(result1.totalForPosition).toBe(1);
885
+ expect(result1.count).toBe(1);
707
886
 
708
887
  // Add the second checkpoint proposal - this IS a duplicate (different archive, same slot)
709
888
  const proposal2 = await mockCheckpointProposalCoreForPool(signers[3], slotNumber, archive2);
710
889
  const result2 = await ap.tryAddCheckpointProposal(proposal2);
711
890
 
712
891
  expect(result2.added).toBe(true);
713
- expect(result2.totalForPosition).toBe(2);
892
+ expect(result2.count).toBe(2);
714
893
  });
715
894
  });
716
895
  });