@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,9 +1,11 @@
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 { Signature } from '@aztec/foundation/eth-signature';
5
+ import { CheckpointAttestation } from '@aztec/stdlib/p2p';
4
6
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
5
7
  import { makeBlockHeader, makeBlockProposal, makeCheckpointHeader, makeCheckpointProposal } from '@aztec/stdlib/testing';
6
- import { MAX_PROPOSALS_PER_POSITION, MAX_PROPOSALS_PER_SLOT } from './attestation_pool.js';
8
+ import { MAX_BLOCK_PROPOSALS_PER_POSITION, MAX_CHECKPOINT_PROPOSALS_PER_SLOT } from './attestation_pool.js';
7
9
  import { mockCheckpointAttestation } from './mocks.js';
8
10
  const NUMBER_OF_SIGNERS_PER_TEST = 4;
9
11
  export function describeAttestationPool(getAttestationPool) {
@@ -15,9 +17,17 @@ export function describeAttestationPool(getAttestationPool) {
15
17
  length: NUMBER_OF_SIGNERS_PER_TEST
16
18
  }, ()=>Secp256k1Signer.random());
17
19
  });
18
- const createCheckpointAttestationsForSlot = (slotNumber, archive)=>{
20
+ /**
21
+ * Build attestations from each signer over the *same* signed payload (same header,
22
+ * archive, feeAssetPriceModifier). Required by the new pool, which deduplicates by
23
+ * payload hash and treats attestations from different signers as distinct entries
24
+ * only when the payload itself matches.
25
+ */ const createCheckpointAttestationsForSlot = (slotNumber, archive)=>{
19
26
  const archiveToUse = archive ?? Fr.random();
20
- return signers.map((signer)=>mockCheckpointAttestation(signer, slotNumber, archiveToUse));
27
+ const sharedHeader = CheckpointHeader.random({
28
+ slotNumber: SlotNumber(slotNumber)
29
+ });
30
+ return signers.map((signer)=>mockCheckpointAttestation(signer, slotNumber, archiveToUse, sharedHeader));
21
31
  };
22
32
  const mockBlockProposalForPool = (signer, slotNumber, archive = Fr.random())=>{
23
33
  const header = makeBlockHeader(1, {
@@ -37,24 +47,69 @@ export function describeAttestationPool(getAttestationPool) {
37
47
  expect(a1Buffer.length).toBe(a2Buffer.length);
38
48
  expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
39
49
  };
50
+ /**
51
+ * Rewrites the attester signature into yParity form (27 -> 0, 28 -> 1), keeping (r, s). The recovery
52
+ * bit is unchanged so it still recovers to the same signer, mimicking a peer that gossips (or mutates
53
+ * in flight) a signature with a non-canonical recovery byte.
54
+ */ const toYParityForm = (attestation)=>{
55
+ const sig = attestation.signature;
56
+ const yParityV = sig.v === 27 ? 0 : sig.v === 28 ? 1 : sig.v;
57
+ return new CheckpointAttestation(attestation.payload, new Signature(sig.r, sig.s, yParityV), attestation.proposerSignature);
58
+ };
40
59
  describe('CheckpointAttestation', ()=>{
60
+ it('normalizes yParity (v=0/v=1) attester signatures on ingress from both gossip and own keys', async ()=>{
61
+ const slotNumber = 421;
62
+ const canonical = createCheckpointAttestationsForSlot(slotNumber);
63
+ const payloadHash = canonical[0].getPayloadHash();
64
+ const expectedSenders = new Set([
65
+ canonical[0].getSender().toString(),
66
+ canonical[1].getSender().toString()
67
+ ]);
68
+ const gossiped = toYParityForm(canonical[0]);
69
+ expect([
70
+ 0,
71
+ 1
72
+ ]).toContain(gossiped.signature.v);
73
+ await ap.tryAddCheckpointAttestation(gossiped);
74
+ const own = toYParityForm(canonical[1]);
75
+ expect([
76
+ 0,
77
+ 1
78
+ ]).toContain(own.signature.v);
79
+ await ap.addOwnCheckpointAttestations([
80
+ own
81
+ ]);
82
+ const retrieved = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
83
+ expect(retrieved.length).toBe(2);
84
+ for (const attestation of retrieved){
85
+ expect([
86
+ 27,
87
+ 28
88
+ ]).toContain(attestation.signature.v);
89
+ expect(expectedSenders.has(attestation.getSender().toString())).toBe(true);
90
+ }
91
+ });
41
92
  it('should add attestations to pool', async ()=>{
42
93
  const slotNumber = 420;
43
94
  const archive = Fr.random();
44
- const attestations = signers.slice(0, -1).map((signer)=>mockCheckpointAttestation(signer, slotNumber, archive));
95
+ const sharedHeader = CheckpointHeader.random({
96
+ slotNumber: SlotNumber(slotNumber)
97
+ });
98
+ const attestations = signers.slice(0, -1).map((signer)=>mockCheckpointAttestation(signer, slotNumber, archive, sharedHeader));
99
+ const payloadHash = attestations[0].getPayloadHash();
45
100
  await ap.addOwnCheckpointAttestations(attestations);
46
- const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString());
101
+ const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
47
102
  expect(retrievedAttestations.length).toBe(attestations.length);
48
103
  compareCheckpointAttestations(retrievedAttestations, attestations);
49
104
  const retrievedAttestationsForSlot = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
50
105
  expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
51
106
  compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
52
107
  // Add another one
53
- const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
108
+ const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive, sharedHeader);
54
109
  await ap.addOwnCheckpointAttestations([
55
110
  newAttestation
56
111
  ]);
57
- const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString());
112
+ const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
58
113
  expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
59
114
  compareCheckpointAttestations(retrievedAttestationsAfterAdd, [
60
115
  ...attestations,
@@ -68,7 +123,7 @@ export function describeAttestationPool(getAttestationPool) {
68
123
  ]);
69
124
  // Delete by slot
70
125
  await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
71
- const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString());
126
+ const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
72
127
  expect(retreivedAttestationsAfterDelete.length).toBe(0);
73
128
  });
74
129
  it('should handle duplicate proposals in a slot', async ()=>{
@@ -83,9 +138,10 @@ export function describeAttestationPool(getAttestationPool) {
83
138
  for(let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++){
84
139
  attestations.push(mockCheckpointAttestation(signer, slotNumber, archive, header));
85
140
  }
141
+ const payloadHash = attestations[0].getPayloadHash();
86
142
  // Add them to store and check we end up with only one
87
143
  await ap.addOwnCheckpointAttestations(attestations);
88
- const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString());
144
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
89
145
  expect(retreivedAttestations.length).toBe(1);
90
146
  expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
91
147
  expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
@@ -93,7 +149,7 @@ export function describeAttestationPool(getAttestationPool) {
93
149
  await ap.addOwnCheckpointAttestations([
94
150
  attestations[0]
95
151
  ]);
96
- expect(await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString())).toHaveLength(1);
152
+ expect(await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash)).toHaveLength(1);
97
153
  });
98
154
  it('should store attestations by differing slot', async ()=>{
99
155
  const slotNumbers = [
@@ -106,8 +162,8 @@ export function describeAttestationPool(getAttestationPool) {
106
162
  await ap.addOwnCheckpointAttestations(attestations);
107
163
  for (const attestation of attestations){
108
164
  const slot = attestation.payload.header.slotNumber;
109
- const archive = attestation.archive.toString();
110
- const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, archive);
165
+ const payloadHash = attestation.getPayloadHash();
166
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
111
167
  expect(retreivedAttestations.length).toBe(1);
112
168
  expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
113
169
  expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
@@ -130,8 +186,8 @@ export function describeAttestationPool(getAttestationPool) {
130
186
  await ap.addOwnCheckpointAttestations(attestations);
131
187
  for (const attestation of attestations){
132
188
  const slot = attestation.payload.header.slotNumber;
133
- const proposalId = attestation.archive.toString();
134
- const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, proposalId);
189
+ const payloadHash = attestation.getPayloadHash();
190
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
135
191
  expect(retreivedAttestations.length).toBe(1);
136
192
  expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
137
193
  expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
@@ -148,13 +204,14 @@ export function describeAttestationPool(getAttestationPool) {
148
204
  88,
149
205
  420
150
206
  ];
151
- const attestations = (await Promise.all(slotNumbers.map((slotNumber)=>createCheckpointAttestationsForSlot(slotNumber)))).flat();
152
- const proposalId = attestations[0].archive.toString();
207
+ const attestationsPerSlot = await Promise.all(slotNumbers.map((slotNumber)=>createCheckpointAttestationsForSlot(slotNumber)));
208
+ const attestations = attestationsPerSlot.flat();
209
+ const payloadHashForSlot1 = attestationsPerSlot[0][0].getPayloadHash();
153
210
  await ap.addOwnCheckpointAttestations(attestations);
154
- const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
211
+ const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), payloadHashForSlot1);
155
212
  expect(attestationsForSlot1.length).toBe(signers.length);
156
213
  await ap.deleteOlderThan(SlotNumber(73));
157
- const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
214
+ const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), payloadHashForSlot1);
158
215
  expect(attestationsForSlot1AfterDelete.length).toBe(0);
159
216
  });
160
217
  });
@@ -163,49 +220,81 @@ export function describeAttestationPool(getAttestationPool) {
163
220
  const slotNumber = 420;
164
221
  const archive = Fr.random();
165
222
  const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
166
- const proposalId = proposal.archive.toString();
167
223
  const result = await ap.tryAddBlockProposal(proposal);
168
224
  expect(result.added).toBe(true);
169
225
  expect(result.alreadyExists).toBe(false);
170
- expect(result.totalForPosition).toBe(1);
171
- const retrievedProposal = await ap.getBlockProposal(proposalId);
226
+ expect(result.count).toBe(1);
227
+ const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
172
228
  expect(retrievedProposal).toBeDefined();
173
229
  expect(retrievedProposal).toEqual(proposal);
174
230
  });
175
231
  it('should return undefined for non-existent block proposal', async ()=>{
176
232
  const nonExistentId = Fr.random().toString();
177
- const retrievedProposal = await ap.getBlockProposal(nonExistentId);
233
+ const retrievedProposal = await ap.getBlockProposalByArchive(nonExistentId);
178
234
  expect(retrievedProposal).toBeUndefined();
179
235
  });
180
- it('should return alreadyExists when adding proposal with same id', async ()=>{
236
+ it('should return alreadyExists when re-adding the same signed payload', async ()=>{
181
237
  const slotNumber = 420;
182
238
  const archive = Fr.random();
183
- const proposal1 = await mockBlockProposalForPool(signers[0], slotNumber, archive);
184
- const proposalId = proposal1.archive.toString();
185
- const result1 = await ap.tryAddBlockProposal(proposal1);
239
+ const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
240
+ const result1 = await ap.tryAddBlockProposal(proposal);
186
241
  expect(result1.added).toBe(true);
187
242
  expect(result1.alreadyExists).toBe(false);
188
- // Create a new proposal with same archive but different signer
189
- const proposal2 = await mockBlockProposalForPool(signers[1], slotNumber, archive);
190
- const result2 = await ap.tryAddBlockProposal(proposal2);
243
+ // Re-broadcasting the exact same proposal yields alreadyExists.
244
+ const result2 = await ap.tryAddBlockProposal(proposal);
191
245
  expect(result2.added).toBe(false);
192
246
  expect(result2.alreadyExists).toBe(true);
193
- // Should still have the first proposal
194
- const retrievedProposal = await ap.getBlockProposal(proposalId);
247
+ const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
195
248
  expect(retrievedProposal).toBeDefined();
196
- expect(retrievedProposal.toBuffer()).toEqual(proposal1.toBuffer());
249
+ expect(retrievedProposal.toBuffer()).toEqual(proposal.toBuffer());
197
250
  expect(retrievedProposal.getSender()?.toString()).toBe(signers[0].address.toString());
198
251
  });
252
+ it('should retain an exact duplicate block proposal only once', async ()=>{
253
+ const slotNumber = 420;
254
+ const proposal = await mockBlockProposalForPool(signers[0], slotNumber);
255
+ await ap.tryAddBlockProposal(proposal);
256
+ await ap.tryAddBlockProposal(proposal);
257
+ const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
258
+ expect(proposals.blockProposals.map((proposal)=>proposal.toBuffer())).toEqual([
259
+ proposal.withoutSignedTxs().toBuffer()
260
+ ]);
261
+ });
262
+ it('should retain all accepted block proposals at a position', async ()=>{
263
+ const slotNumber = 420;
264
+ const blockHeader = makeBlockHeader(1, {
265
+ slotNumber: SlotNumber(slotNumber)
266
+ });
267
+ const proposal1 = await makeBlockProposal({
268
+ signer: signers[0],
269
+ blockHeader,
270
+ archiveRoot: Fr.random(),
271
+ indexWithinCheckpoint: IndexWithinCheckpoint(1)
272
+ });
273
+ const proposal2 = await makeBlockProposal({
274
+ signer: signers[0],
275
+ blockHeader,
276
+ archiveRoot: Fr.random(),
277
+ indexWithinCheckpoint: IndexWithinCheckpoint(1)
278
+ });
279
+ await ap.tryAddBlockProposal(proposal1);
280
+ await ap.tryAddBlockProposal(proposal2);
281
+ const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
282
+ expect(proposals.blockProposals.map((proposal)=>proposal.toBuffer())).toEqual(expect.arrayContaining([
283
+ proposal1.withoutSignedTxs().toBuffer(),
284
+ proposal2.withoutSignedTxs().toBuffer()
285
+ ]));
286
+ expect(await ap.getBlockProposalByArchive(proposal2.archive.toString())).toBeDefined();
287
+ });
199
288
  });
200
289
  describe('CheckpointProposal in attestation pool', ()=>{
201
- const mockCheckpointProposalForPool = async (signer, slotNumber, archive = Fr.random())=>{
202
- const checkpointHeader = makeCheckpointHeader(1, {
290
+ const mockCheckpointProposalForPool = async (signer, slotNumber, archive = Fr.random(), checkpointHeader)=>{
291
+ const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, {
203
292
  slotNumber: SlotNumber(slotNumber)
204
293
  });
205
294
  const blockHeader = makeBlockHeader(1);
206
295
  const proposal = await makeCheckpointProposal({
207
296
  signer,
208
- checkpointHeader,
297
+ checkpointHeader: headerToUse,
209
298
  archiveRoot: archive,
210
299
  lastBlock: {
211
300
  blockHeader
@@ -218,12 +307,11 @@ export function describeAttestationPool(getAttestationPool) {
218
307
  const slotNumber = 420;
219
308
  const archive = Fr.random();
220
309
  const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
221
- const proposalId = proposal.archive.toString();
222
310
  const result = await ap.tryAddCheckpointProposal(proposal);
223
311
  expect(result.added).toBe(true);
224
312
  expect(result.alreadyExists).toBe(false);
225
- expect(result.totalForPosition).toBe(1);
226
- const retrievedProposal = await ap.getCheckpointProposal(proposalId);
313
+ expect(result.count).toBe(1);
314
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
227
315
  expect(retrievedProposal).toBeDefined();
228
316
  expect(retrievedProposal.toBuffer()).toEqual(proposal.toBuffer());
229
317
  });
@@ -239,55 +327,126 @@ export function describeAttestationPool(getAttestationPool) {
239
327
  checkpointHeader,
240
328
  archiveRoot: archive
241
329
  });
242
- const proposalId = proposal.archive.toString();
243
330
  // Add the checkpoint core - block extraction is now caller responsibility
244
331
  await ap.tryAddCheckpointProposal(proposal.toCore());
245
332
  // The checkpoint proposal should be stored
246
- const retrievedCheckpointProposal = await ap.getCheckpointProposal(proposalId);
333
+ const retrievedCheckpointProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
247
334
  expect(retrievedCheckpointProposal).toBeDefined();
248
335
  // No block proposal was extracted (it had none anyway)
249
- const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
336
+ const retrievedBlockProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
250
337
  expect(retrievedBlockProposal).toBeUndefined();
251
338
  });
252
339
  it('should return undefined for non-existent checkpoint proposal', async ()=>{
253
- const nonExistentId = Fr.random().toString();
254
- const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
340
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(99999));
255
341
  expect(retrievedProposal).toBeUndefined();
256
342
  });
257
- it('should return alreadyExists when adding proposal with same id', async ()=>{
343
+ it('should return alreadyExists when re-adding the same signed payload', async ()=>{
258
344
  const slotNumber = 420;
259
345
  const archive = Fr.random();
260
- const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
261
- const proposalId = proposal1.archive.toString();
262
- const result1 = await ap.tryAddCheckpointProposal(proposal1);
346
+ const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
347
+ const result1 = await ap.tryAddCheckpointProposal(proposal);
263
348
  expect(result1.added).toBe(true);
264
349
  expect(result1.alreadyExists).toBe(false);
265
- // Create a new proposal with same archive but different signer
266
- const proposal2 = await mockCheckpointProposalForPool(signers[1], slotNumber, archive);
267
- const result2 = await ap.tryAddCheckpointProposal(proposal2);
350
+ // Re-broadcasting the exact same signed payload yields alreadyExists.
351
+ const result2 = await ap.tryAddCheckpointProposal(proposal);
268
352
  expect(result2.added).toBe(false);
269
353
  expect(result2.alreadyExists).toBe(true);
270
- // Should still have the first proposal
271
- const retrievedProposal = await ap.getCheckpointProposal(proposalId);
354
+ // Should still have the first proposal stored at the slot
355
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
272
356
  expect(retrievedProposal).toBeDefined();
273
- expect(retrievedProposal.toBuffer()).toEqual(proposal1.toBuffer());
357
+ expect(retrievedProposal.toBuffer()).toEqual(proposal.toBuffer());
274
358
  expect(retrievedProposal.getSender()?.toString()).toBe(signers[0].address.toString());
275
359
  });
360
+ it('should treat distinct payloads at the same slot as equivocations (count = 2)', async ()=>{
361
+ const slotNumber = 420;
362
+ // Two proposals at the same slot but with different headers (distinct payloads).
363
+ const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
364
+ const proposal2 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
365
+ const result1 = await ap.tryAddCheckpointProposal(proposal1);
366
+ expect(result1.added).toBe(true);
367
+ expect(result1.count).toBe(1);
368
+ const result2 = await ap.tryAddCheckpointProposal(proposal2);
369
+ // The second distinct payload is tracked as an equivocation, count goes to 2,
370
+ // and both accepted payloads are retained by payload hash.
371
+ expect(result2.added).toBe(true);
372
+ expect(result2.alreadyExists).toBe(false);
373
+ expect(result2.count).toBe(2);
374
+ const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
375
+ const expectedProposal = [
376
+ proposal1,
377
+ proposal2
378
+ ].sort((a, b)=>a.getPayloadHash().localeCompare(b.getPayloadHash()))[0];
379
+ expect(retrievedProposal.toBuffer()).toEqual(expectedProposal.toBuffer());
380
+ const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
381
+ expect(proposals.checkpointProposals.map((proposal)=>proposal.toBuffer())).toEqual(expect.arrayContaining([
382
+ proposal1.toBuffer(),
383
+ proposal2.toBuffer()
384
+ ]));
385
+ });
386
+ it('should detect equivocation when only feeAssetPriceModifier differs', async ()=>{
387
+ const slotNumber = 420;
388
+ const archive = Fr.random();
389
+ // Same checkpoint header + archive, but two different feeAssetPriceModifier values.
390
+ // This is the audit-finding scenario: archive collides but the signed payload differs.
391
+ const sharedHeader = makeCheckpointHeader(1, {
392
+ slotNumber: SlotNumber(slotNumber)
393
+ });
394
+ const proposalA = await makeCheckpointProposal({
395
+ signer: signers[0],
396
+ checkpointHeader: sharedHeader,
397
+ archiveRoot: archive,
398
+ feeAssetPriceModifier: 50n
399
+ });
400
+ const proposalB = await makeCheckpointProposal({
401
+ signer: signers[0],
402
+ checkpointHeader: sharedHeader,
403
+ archiveRoot: archive,
404
+ feeAssetPriceModifier: -50n
405
+ });
406
+ const result1 = await ap.tryAddCheckpointProposal(proposalA.toCore());
407
+ expect(result1.count).toBe(1);
408
+ const result2 = await ap.tryAddCheckpointProposal(proposalB.toCore());
409
+ // The fix: archive collision no longer hides the equivocation; payload-hash dedup
410
+ // sees the distinct feeMod and bumps `count` to 2 so libp2p can fire the slash callback.
411
+ expect(result2.added).toBe(true);
412
+ expect(result2.alreadyExists).toBe(false);
413
+ expect(result2.count).toBe(2);
414
+ });
415
+ it('should delete retained proposals older than a given slot', async ()=>{
416
+ const oldSlot = 100;
417
+ const newSlot = 200;
418
+ const oldBlock = await mockBlockProposalForPool(signers[0], oldSlot);
419
+ const newBlock = await mockBlockProposalForPool(signers[1], newSlot);
420
+ const oldCheckpoint = await mockCheckpointProposalForPool(signers[0], oldSlot);
421
+ const newCheckpoint = await mockCheckpointProposalForPool(signers[1], newSlot);
422
+ await ap.tryAddBlockProposal(oldBlock);
423
+ await ap.tryAddBlockProposal(newBlock);
424
+ await ap.tryAddCheckpointProposal(oldCheckpoint);
425
+ await ap.tryAddCheckpointProposal(newCheckpoint);
426
+ await ap.deleteOlderThan(SlotNumber(newSlot));
427
+ expect(await ap.getProposalsForSlot(SlotNumber(oldSlot))).toEqual({
428
+ blockProposals: [],
429
+ checkpointProposals: []
430
+ });
431
+ const newProposals = await ap.getProposalsForSlot(SlotNumber(newSlot));
432
+ expect(newProposals.blockProposals.map((proposal)=>proposal.toBuffer())).toContainEqual(newBlock.withoutSignedTxs().toBuffer());
433
+ expect(newProposals.checkpointProposals.map((proposal)=>proposal.toBuffer())).toContainEqual(newCheckpoint.toBuffer());
434
+ });
276
435
  it('should return added=false when exceeding capacity', async ()=>{
277
436
  const slotNumber = 420;
278
- // Add MAX_PROPOSALS_PER_SLOT proposals
279
- for(let i = 0; i < MAX_PROPOSALS_PER_SLOT; i++){
437
+ // Add MAX_CHECKPOINT_PROPOSALS_PER_SLOT distinct proposals.
438
+ for(let i = 0; i < MAX_CHECKPOINT_PROPOSALS_PER_SLOT; i++){
280
439
  const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
281
440
  const result = await ap.tryAddCheckpointProposal(proposal);
282
441
  expect(result.added).toBe(true);
283
- expect(result.totalForPosition).toBe(i + 1);
442
+ expect(result.count).toBe(i + 1);
284
443
  }
285
- // The next proposal should not be added
444
+ // The next proposal should not be added.
286
445
  const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
287
446
  const result = await ap.tryAddCheckpointProposal(extraProposal);
288
447
  expect(result.added).toBe(false);
289
448
  expect(result.alreadyExists).toBe(false);
290
- expect(result.totalForPosition).toBe(MAX_PROPOSALS_PER_SLOT);
449
+ expect(result.count).toBe(MAX_CHECKPOINT_PROPOSALS_PER_SLOT);
291
450
  });
292
451
  });
293
452
  describe('Duplicate proposal detection', ()=>{
@@ -303,12 +462,12 @@ export function describeAttestationPool(getAttestationPool) {
303
462
  });
304
463
  };
305
464
  describe('tryAddBlockProposal duplicate detection', ()=>{
306
- it('should return totalForPosition=1 when pool is empty', async ()=>{
465
+ it('should return count=1 when pool is empty', async ()=>{
307
466
  const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
308
467
  const result = await ap.tryAddBlockProposal(proposal);
309
468
  expect(result.added).toBe(true);
310
469
  expect(result.alreadyExists).toBe(false);
311
- expect(result.totalForPosition).toBe(1);
470
+ expect(result.count).toBe(1);
312
471
  });
313
472
  it('should return alreadyExists when same proposal exists', async ()=>{
314
473
  const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
@@ -316,22 +475,22 @@ export function describeAttestationPool(getAttestationPool) {
316
475
  const result = await ap.tryAddBlockProposal(proposal);
317
476
  expect(result.added).toBe(false);
318
477
  expect(result.alreadyExists).toBe(true);
319
- expect(result.totalForPosition).toBe(1);
478
+ expect(result.count).toBe(1);
320
479
  });
321
- it('should detect duplicate via totalForPosition when different proposal exists at same position', async ()=>{
480
+ it('should detect duplicate via count when different proposal exists at same position', async ()=>{
322
481
  const slotNumber = 100;
323
482
  const indexWithinCheckpoint = 2;
324
483
  // Add first proposal
325
484
  const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
326
485
  const result1 = await ap.tryAddBlockProposal(proposal1);
327
- expect(result1.totalForPosition).toBe(1);
486
+ expect(result1.count).toBe(1);
328
487
  // Add a different proposal at same position - this is a duplicate (equivocation)
329
488
  const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
330
489
  const result2 = await ap.tryAddBlockProposal(proposal2);
331
490
  expect(result2.added).toBe(true);
332
491
  expect(result2.alreadyExists).toBe(false);
333
- // totalForPosition >= 2 indicates duplicate detection
334
- expect(result2.totalForPosition).toBe(2);
492
+ // count >= 2 indicates duplicate detection
493
+ expect(result2.count).toBe(2);
335
494
  });
336
495
  it('should not detect duplicate for different positions in same slot', async ()=>{
337
496
  const slotNumber = 100;
@@ -342,8 +501,8 @@ export function describeAttestationPool(getAttestationPool) {
342
501
  const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
343
502
  const result = await ap.tryAddBlockProposal(proposal2);
344
503
  expect(result.added).toBe(true);
345
- // totalForPosition = 1 means no duplicate for this position
346
- expect(result.totalForPosition).toBe(1);
504
+ // count = 1 means no duplicate for this position
505
+ expect(result.count).toBe(1);
347
506
  });
348
507
  it('should not detect duplicate for same position in different slots', async ()=>{
349
508
  const indexWithinCheckpoint = 0;
@@ -354,41 +513,41 @@ export function describeAttestationPool(getAttestationPool) {
354
513
  const proposal2 = await mockBlockProposalWithIndex(signers[1], 200, indexWithinCheckpoint);
355
514
  const result = await ap.tryAddBlockProposal(proposal2);
356
515
  expect(result.added).toBe(true);
357
- // totalForPosition = 1 means no duplicate for this position
358
- expect(result.totalForPosition).toBe(1);
516
+ // count = 1 means no duplicate for this position
517
+ expect(result.count).toBe(1);
359
518
  });
360
- it('should track multiple duplicates correctly via totalForPosition', async ()=>{
519
+ it('should track multiple duplicates correctly via count', async ()=>{
361
520
  const slotNumber = 100;
362
521
  const indexWithinCheckpoint = 0;
363
522
  // Add multiple proposals for same position
364
523
  const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
365
524
  const result1 = await ap.tryAddBlockProposal(proposal1);
366
- expect(result1.totalForPosition).toBe(1);
525
+ expect(result1.count).toBe(1);
367
526
  const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
368
527
  const result2 = await ap.tryAddBlockProposal(proposal2);
369
- expect(result2.totalForPosition).toBe(2);
370
- // Add a third proposal for same position
528
+ expect(result2.count).toBe(2);
529
+ // Third proposal for same position should be rejected (cap is 2)
371
530
  const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
372
531
  const result3 = await ap.tryAddBlockProposal(proposal3);
373
- expect(result3.added).toBe(true);
374
- expect(result3.totalForPosition).toBe(3);
532
+ expect(result3.added).toBe(false);
533
+ expect(result3.count).toBe(2);
375
534
  });
376
535
  it('should return added=false when exceeding capacity', async ()=>{
377
536
  const slotNumber = 100;
378
537
  const indexWithinCheckpoint = 0;
379
- // Add MAX_PROPOSALS_PER_POSITION proposals
380
- for(let i = 0; i < MAX_PROPOSALS_PER_POSITION; i++){
538
+ // Add MAX_BLOCK_PROPOSALS_PER_POSITION proposals
539
+ for(let i = 0; i < MAX_BLOCK_PROPOSALS_PER_POSITION; i++){
381
540
  const proposal = await mockBlockProposalWithIndex(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber, indexWithinCheckpoint);
382
541
  const result = await ap.tryAddBlockProposal(proposal);
383
542
  expect(result.added).toBe(true);
384
- expect(result.totalForPosition).toBe(i + 1);
543
+ expect(result.count).toBe(i + 1);
385
544
  }
386
545
  // The next proposal should not be added
387
546
  const extraProposal = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
388
547
  const result = await ap.tryAddBlockProposal(extraProposal);
389
548
  expect(result.added).toBe(false);
390
549
  expect(result.alreadyExists).toBe(false);
391
- expect(result.totalForPosition).toBe(MAX_PROPOSALS_PER_POSITION);
550
+ expect(result.count).toBe(MAX_BLOCK_PROPOSALS_PER_POSITION);
392
551
  });
393
552
  it('should clean up block position index when deleting old data', async ()=>{
394
553
  const slotNumber = 100;
@@ -396,16 +555,16 @@ export function describeAttestationPool(getAttestationPool) {
396
555
  // Add proposal
397
556
  const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
398
557
  await ap.tryAddBlockProposal(proposal1);
399
- // Verify it's tracked (adding another should show totalForPosition = 2)
558
+ // Verify it's tracked (adding another should show count = 2)
400
559
  const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
401
560
  let result = await ap.tryAddBlockProposal(proposal2);
402
- expect(result.totalForPosition).toBe(2);
561
+ expect(result.count).toBe(2);
403
562
  // Delete old data
404
563
  await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
405
- // Verify position index is cleaned up (totalForPosition should be 1 now)
564
+ // Verify position index is cleaned up (count should be 1 now)
406
565
  const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
407
566
  result = await ap.tryAddBlockProposal(proposal3);
408
- expect(result.totalForPosition).toBe(1);
567
+ expect(result.count).toBe(1);
409
568
  });
410
569
  it('should correctly delete block proposals at slot boundary', async ()=>{
411
570
  // Add proposals at slots 99, 100, and 101 with various indices
@@ -422,14 +581,14 @@ export function describeAttestationPool(getAttestationPool) {
422
581
  // Slot 99 proposals should have their index cleaned up
423
582
  const newProposal99 = await mockBlockProposalWithIndex(signers[0], 99, 0);
424
583
  const result99 = await ap.tryAddBlockProposal(newProposal99);
425
- expect(result99.totalForPosition).toBe(1); // Index was cleaned up
584
+ expect(result99.count).toBe(1); // Index was cleaned up
426
585
  // Slot 100 and 101 should still be tracked
427
586
  const newProposal100 = await mockBlockProposalWithIndex(signers[1], 100, 0);
428
587
  const result100 = await ap.tryAddBlockProposal(newProposal100);
429
- expect(result100.totalForPosition).toBe(2); // Still has the original
588
+ expect(result100.count).toBe(2); // Still has the original
430
589
  const newProposal101 = await mockBlockProposalWithIndex(signers[2], 101, 0);
431
590
  const result101 = await ap.tryAddBlockProposal(newProposal101);
432
- expect(result101.totalForPosition).toBe(2); // Still has the original
591
+ expect(result101.count).toBe(2); // Still has the original
433
592
  });
434
593
  it('should delete all indices for a given slot', async ()=>{
435
594
  const slotNumber = 50;
@@ -445,13 +604,13 @@ export function describeAttestationPool(getAttestationPool) {
445
604
  // All indices should be cleaned up
446
605
  const newProposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
447
606
  const result0 = await ap.tryAddBlockProposal(newProposal0);
448
- expect(result0.totalForPosition).toBe(1);
607
+ expect(result0.count).toBe(1);
449
608
  const newProposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
450
609
  const result1 = await ap.tryAddBlockProposal(newProposal1);
451
- expect(result1.totalForPosition).toBe(1);
610
+ expect(result1.count).toBe(1);
452
611
  const newProposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
453
612
  const result2 = await ap.tryAddBlockProposal(newProposal2);
454
- expect(result2.totalForPosition).toBe(1);
613
+ expect(result2.count).toBe(1);
455
614
  });
456
615
  it('should delete block proposals from storage when deleting old data', async ()=>{
457
616
  const oldSlot = 50;
@@ -462,25 +621,25 @@ export function describeAttestationPool(getAttestationPool) {
462
621
  await ap.tryAddBlockProposal(oldProposal);
463
622
  await ap.tryAddBlockProposal(newProposal);
464
623
  // Verify both proposals exist
465
- expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeDefined();
466
- expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
624
+ expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeDefined();
625
+ expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
467
626
  // Delete slots older than newSlot (should delete oldSlot)
468
627
  await ap.deleteOlderThan(SlotNumber(newSlot));
469
628
  // Old proposal should be deleted from storage
470
- expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeUndefined();
629
+ expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeUndefined();
471
630
  // New proposal should still exist
472
- expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
631
+ expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
473
632
  });
474
633
  });
475
634
  describe('tryAddCheckpointProposal duplicate detection', ()=>{
476
- const mockCheckpointProposalCoreForPool = async (signer, slotNumber, archive = Fr.random())=>{
477
- const checkpointHeader = makeCheckpointHeader(1, {
635
+ const mockCheckpointProposalCoreForPool = async (signer, slotNumber, archive = Fr.random(), checkpointHeader)=>{
636
+ const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, {
478
637
  slotNumber: SlotNumber(slotNumber)
479
638
  });
480
639
  const blockHeader = makeBlockHeader(1);
481
640
  const proposal = await makeCheckpointProposal({
482
641
  signer,
483
- checkpointHeader,
642
+ checkpointHeader: headerToUse,
484
643
  archiveRoot: archive,
485
644
  lastBlock: {
486
645
  blockHeader
@@ -488,12 +647,12 @@ export function describeAttestationPool(getAttestationPool) {
488
647
  });
489
648
  return proposal.toCore();
490
649
  };
491
- it('should return totalForPosition=1 when pool is empty', async ()=>{
650
+ it('should return count=1 when pool is empty', async ()=>{
492
651
  const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
493
652
  const result = await ap.tryAddCheckpointProposal(proposal);
494
653
  expect(result.added).toBe(true);
495
654
  expect(result.alreadyExists).toBe(false);
496
- expect(result.totalForPosition).toBe(1);
655
+ expect(result.count).toBe(1);
497
656
  });
498
657
  it('should return alreadyExists when same proposal exists', async ()=>{
499
658
  const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
@@ -501,21 +660,21 @@ export function describeAttestationPool(getAttestationPool) {
501
660
  const result = await ap.tryAddCheckpointProposal(proposal);
502
661
  expect(result.added).toBe(false);
503
662
  expect(result.alreadyExists).toBe(true);
504
- expect(result.totalForPosition).toBe(1);
663
+ expect(result.count).toBe(1);
505
664
  });
506
- it('should detect duplicate via totalForPosition when different proposal exists for same slot', async ()=>{
665
+ it('should detect duplicate via count when different proposal exists for same slot', async ()=>{
507
666
  const slotNumber = 100;
508
667
  // Add first proposal
509
668
  const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
510
669
  const result1 = await ap.tryAddCheckpointProposal(proposal1);
511
- expect(result1.totalForPosition).toBe(1);
670
+ expect(result1.count).toBe(1);
512
671
  // Add a different proposal for same slot - this is a duplicate (equivocation)
513
672
  const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
514
673
  const result2 = await ap.tryAddCheckpointProposal(proposal2);
515
674
  expect(result2.added).toBe(true);
516
675
  expect(result2.alreadyExists).toBe(false);
517
- // totalForPosition >= 2 indicates duplicate detection
518
- expect(result2.totalForPosition).toBe(2);
676
+ // count >= 2 indicates duplicate detection
677
+ expect(result2.count).toBe(2);
519
678
  });
520
679
  it('should not detect duplicate for different slots', async ()=>{
521
680
  // Add proposal at slot 100
@@ -525,23 +684,23 @@ export function describeAttestationPool(getAttestationPool) {
525
684
  const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], 200);
526
685
  const result = await ap.tryAddCheckpointProposal(proposal2);
527
686
  expect(result.added).toBe(true);
528
- // totalForPosition = 1 means no duplicate for this slot
529
- expect(result.totalForPosition).toBe(1);
687
+ // count = 1 means no duplicate for this slot
688
+ expect(result.count).toBe(1);
530
689
  });
531
- it('should track multiple duplicates correctly via totalForPosition', async ()=>{
690
+ it('should track multiple duplicates correctly via count', async ()=>{
532
691
  const slotNumber = 100;
533
692
  // Add multiple proposals for same slot
534
693
  const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
535
694
  const result1 = await ap.tryAddCheckpointProposal(proposal1);
536
- expect(result1.totalForPosition).toBe(1);
695
+ expect(result1.count).toBe(1);
537
696
  const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
538
697
  const result2 = await ap.tryAddCheckpointProposal(proposal2);
539
- expect(result2.totalForPosition).toBe(2);
540
- // Add a third proposal for same slot
698
+ expect(result2.count).toBe(2);
699
+ // Third proposal for same slot should be rejected (cap is 2)
541
700
  const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
542
701
  const result3 = await ap.tryAddCheckpointProposal(proposal3);
543
- expect(result3.added).toBe(true);
544
- expect(result3.totalForPosition).toBe(3);
702
+ expect(result3.added).toBe(false);
703
+ expect(result3.count).toBe(2);
545
704
  });
546
705
  it('should not count attestations as proposals for duplicate detection', async ()=>{
547
706
  const slotNumber = 100;
@@ -556,8 +715,8 @@ export function describeAttestationPool(getAttestationPool) {
556
715
  const result = await ap.tryAddCheckpointProposal(proposal);
557
716
  expect(result.added).toBe(true);
558
717
  expect(result.alreadyExists).toBe(false);
559
- // totalForPosition should be 1, NOT 2 - attestations should not count as proposals
560
- expect(result.totalForPosition).toBe(1);
718
+ // count should be 1, NOT 2 - attestations should not count as proposals
719
+ expect(result.count).toBe(1);
561
720
  });
562
721
  it('should not count attestations for different proposals as duplicates', async ()=>{
563
722
  const slotNumber = 100;
@@ -574,12 +733,12 @@ export function describeAttestationPool(getAttestationPool) {
574
733
  const proposal1 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber, archive1);
575
734
  const result1 = await ap.tryAddCheckpointProposal(proposal1);
576
735
  expect(result1.added).toBe(true);
577
- expect(result1.totalForPosition).toBe(1);
736
+ expect(result1.count).toBe(1);
578
737
  // Add the second checkpoint proposal - this IS a duplicate (different archive, same slot)
579
738
  const proposal2 = await mockCheckpointProposalCoreForPool(signers[3], slotNumber, archive2);
580
739
  const result2 = await ap.tryAddCheckpointProposal(proposal2);
581
740
  expect(result2.added).toBe(true);
582
- expect(result2.totalForPosition).toBe(2);
741
+ expect(result2.count).toBe(2);
583
742
  });
584
743
  });
585
744
  });