@aztec/p2p 0.0.1-commit.fce3e4f → 0.0.1-commit.fffb133c

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 (282) hide show
  1. package/dest/client/factory.d.ts +2 -2
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +2 -3
  4. package/dest/client/interface.d.ts +18 -5
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +16 -19
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +460 -127
  9. package/dest/config.d.ts +4 -7
  10. package/dest/config.d.ts.map +1 -1
  11. package/dest/config.js +10 -13
  12. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +61 -42
  13. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  14. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  15. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  16. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +239 -265
  17. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +21 -18
  18. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
  19. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +114 -109
  20. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -16
  21. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  22. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +89 -128
  23. package/dest/mem_pools/attestation_pool/mocks.d.ts +11 -8
  24. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  25. package/dest/mem_pools/attestation_pool/mocks.js +17 -13
  26. package/dest/mem_pools/instrumentation.d.ts +7 -1
  27. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  28. package/dest/mem_pools/instrumentation.js +30 -12
  29. package/dest/mem_pools/interface.d.ts +3 -4
  30. package/dest/mem_pools/interface.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +37 -27
  32. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  33. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +314 -335
  34. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +32 -0
  35. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
  36. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
  37. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +157 -0
  38. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
  39. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
  40. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
  41. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  42. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +122 -0
  43. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
  44. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  45. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
  46. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
  47. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  48. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +78 -0
  49. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
  50. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  51. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
  52. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
  53. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
  54. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
  55. package/dest/mem_pools/tx_pool/index.d.ts +1 -2
  56. package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
  57. package/dest/mem_pools/tx_pool/index.js +0 -1
  58. package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
  59. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  60. package/dest/mem_pools/tx_pool/priority.js +6 -1
  61. package/dest/mem_pools/tx_pool/tx_pool.d.ts +11 -6
  62. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  63. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  64. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  65. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +30 -24
  66. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -4
  67. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  68. package/dest/msg_validators/attestation_validator/attestation_validator.js +52 -19
  69. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
  70. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  71. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +18 -14
  72. package/dest/msg_validators/clock_tolerance.d.ts +21 -0
  73. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -0
  74. package/dest/msg_validators/clock_tolerance.js +37 -0
  75. package/dest/msg_validators/index.d.ts +2 -2
  76. package/dest/msg_validators/index.d.ts.map +1 -1
  77. package/dest/msg_validators/index.js +1 -1
  78. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
  79. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
  80. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
  81. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
  82. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
  83. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
  84. package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
  85. package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
  86. package/dest/msg_validators/proposal_validator/index.js +3 -0
  87. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
  88. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
  89. package/dest/msg_validators/proposal_validator/proposal_validator.js +104 -0
  90. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
  91. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
  92. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +212 -0
  93. package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
  94. package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
  95. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
  96. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
  97. package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
  98. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  99. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  100. package/dest/msg_validators/tx_validator/factory.d.ts +4 -3
  101. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  102. package/dest/msg_validators/tx_validator/factory.js +1 -1
  103. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
  104. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
  105. package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
  106. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  107. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  108. package/dest/msg_validators/tx_validator/gas_validator.js +8 -14
  109. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  110. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  111. package/dest/msg_validators/tx_validator/index.js +1 -0
  112. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +2 -2
  113. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  114. package/dest/msg_validators/tx_validator/size_validator.d.ts +6 -0
  115. package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
  116. package/dest/msg_validators/tx_validator/size_validator.js +20 -0
  117. package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
  118. package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
  119. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
  120. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  121. package/dest/services/dummy_service.d.ts +6 -2
  122. package/dest/services/dummy_service.d.ts.map +1 -1
  123. package/dest/services/dummy_service.js +3 -0
  124. package/dest/services/encoding.d.ts +1 -1
  125. package/dest/services/encoding.d.ts.map +1 -1
  126. package/dest/services/encoding.js +7 -6
  127. package/dest/services/libp2p/instrumentation.d.ts +1 -1
  128. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  129. package/dest/services/libp2p/instrumentation.js +20 -73
  130. package/dest/services/libp2p/libp2p_service.d.ts +31 -14
  131. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  132. package/dest/services/libp2p/libp2p_service.js +722 -168
  133. package/dest/services/peer-manager/metrics.d.ts +6 -1
  134. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  135. package/dest/services/peer-manager/metrics.js +18 -21
  136. package/dest/services/peer-manager/peer_manager.d.ts +2 -2
  137. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  138. package/dest/services/peer-manager/peer_manager.js +4 -12
  139. package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
  140. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  141. package/dest/services/peer-manager/peer_scoring.js +2 -5
  142. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -1
  143. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  144. package/dest/services/reqresp/constants.d.ts +12 -0
  145. package/dest/services/reqresp/constants.d.ts.map +1 -0
  146. package/dest/services/reqresp/constants.js +7 -0
  147. package/dest/services/reqresp/interface.d.ts +2 -2
  148. package/dest/services/reqresp/interface.d.ts.map +1 -1
  149. package/dest/services/reqresp/interface.js +1 -1
  150. package/dest/services/reqresp/metrics.d.ts +1 -1
  151. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  152. package/dest/services/reqresp/metrics.js +5 -21
  153. package/dest/services/reqresp/protocols/auth.d.ts +2 -2
  154. package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
  155. package/dest/services/reqresp/protocols/auth.js +2 -2
  156. package/dest/services/reqresp/protocols/block.d.ts +1 -1
  157. package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
  158. package/dest/services/reqresp/protocols/block.js +3 -2
  159. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
  160. package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
  161. package/dest/services/reqresp/protocols/block_txs/bitvector.js +7 -0
  162. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +2 -2
  163. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
  164. package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +1 -1
  165. package/dest/services/reqresp/protocols/status.d.ts +5 -4
  166. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  167. package/dest/services/reqresp/protocols/status.js +7 -3
  168. package/dest/services/reqresp/protocols/tx.d.ts +2 -3
  169. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  170. package/dest/services/reqresp/reqresp.js +402 -24
  171. package/dest/services/service.d.ts +16 -3
  172. package/dest/services/service.d.ts.map +1 -1
  173. package/dest/services/tx_collection/config.js +1 -1
  174. package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -3
  175. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  176. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  177. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  178. package/dest/services/tx_collection/instrumentation.js +4 -14
  179. package/dest/services/tx_collection/slow_tx_collection.d.ts +4 -3
  180. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  181. package/dest/services/tx_collection/tx_collection.d.ts +7 -6
  182. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  183. package/dest/services/tx_provider.d.ts +4 -2
  184. package/dest/services/tx_provider.d.ts.map +1 -1
  185. package/dest/services/tx_provider.js +11 -2
  186. package/dest/services/tx_provider_instrumentation.d.ts +5 -2
  187. package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
  188. package/dest/services/tx_provider_instrumentation.js +13 -13
  189. package/dest/test-helpers/mock-tx-helpers.js +1 -1
  190. package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
  191. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  192. package/dest/testbench/p2p_client_testbench_worker.js +31 -17
  193. package/dest/testbench/worker_client_manager.d.ts +1 -1
  194. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  195. package/dest/testbench/worker_client_manager.js +6 -1
  196. package/package.json +18 -18
  197. package/src/client/factory.ts +5 -10
  198. package/src/client/interface.ts +19 -4
  199. package/src/client/p2p_client.ts +101 -154
  200. package/src/config.ts +12 -18
  201. package/src/mem_pools/attestation_pool/attestation_pool.ts +68 -41
  202. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +241 -289
  203. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +163 -141
  204. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -164
  205. package/src/mem_pools/attestation_pool/mocks.ts +21 -15
  206. package/src/mem_pools/instrumentation.ts +38 -14
  207. package/src/mem_pools/interface.ts +2 -4
  208. package/src/mem_pools/tx_pool/README.md +270 -0
  209. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +367 -371
  210. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +132 -0
  211. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +208 -0
  212. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +162 -0
  213. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
  214. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +93 -0
  215. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
  216. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
  217. package/src/mem_pools/tx_pool/index.ts +0 -1
  218. package/src/mem_pools/tx_pool/priority.ts +8 -1
  219. package/src/mem_pools/tx_pool/tx_pool.ts +11 -5
  220. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +23 -17
  221. package/src/msg_validators/attestation_validator/attestation_validator.ts +37 -22
  222. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +13 -16
  223. package/src/msg_validators/clock_tolerance.ts +51 -0
  224. package/src/msg_validators/index.ts +1 -1
  225. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
  226. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
  227. package/src/msg_validators/proposal_validator/index.ts +3 -0
  228. package/src/msg_validators/proposal_validator/proposal_validator.ts +92 -0
  229. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +230 -0
  230. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  231. package/src/msg_validators/tx_validator/block_header_validator.ts +4 -2
  232. package/src/msg_validators/tx_validator/data_validator.ts +12 -4
  233. package/src/msg_validators/tx_validator/factory.ts +3 -2
  234. package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
  235. package/src/msg_validators/tx_validator/gas_validator.ts +8 -25
  236. package/src/msg_validators/tx_validator/index.ts +1 -0
  237. package/src/msg_validators/tx_validator/metadata_validator.ts +13 -5
  238. package/src/msg_validators/tx_validator/size_validator.ts +18 -0
  239. package/src/msg_validators/tx_validator/test_utils.ts +1 -1
  240. package/src/msg_validators/tx_validator/timestamp_validator.ts +5 -2
  241. package/src/services/dummy_service.ts +6 -0
  242. package/src/services/encoding.ts +6 -5
  243. package/src/services/libp2p/instrumentation.ts +19 -73
  244. package/src/services/libp2p/libp2p_service.ts +369 -138
  245. package/src/services/peer-manager/metrics.ts +22 -21
  246. package/src/services/peer-manager/peer_manager.ts +5 -4
  247. package/src/services/peer-manager/peer_scoring.ts +1 -5
  248. package/src/services/reqresp/connection-sampler/connection_sampler.ts +3 -1
  249. package/src/services/reqresp/constants.ts +14 -0
  250. package/src/services/reqresp/interface.ts +1 -1
  251. package/src/services/reqresp/metrics.ts +7 -23
  252. package/src/services/reqresp/protocols/auth.ts +2 -2
  253. package/src/services/reqresp/protocols/block.ts +3 -2
  254. package/src/services/reqresp/protocols/block_txs/bitvector.ts +9 -0
  255. package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
  256. package/src/services/reqresp/protocols/status.ts +16 -12
  257. package/src/services/reqresp/protocols/tx.ts +1 -2
  258. package/src/services/service.ts +19 -4
  259. package/src/services/tx_collection/config.ts +1 -1
  260. package/src/services/tx_collection/fast_tx_collection.ts +3 -2
  261. package/src/services/tx_collection/instrumentation.ts +4 -21
  262. package/src/services/tx_collection/slow_tx_collection.ts +3 -3
  263. package/src/services/tx_collection/tx_collection.ts +6 -5
  264. package/src/services/tx_provider.ts +19 -3
  265. package/src/services/tx_provider_instrumentation.ts +18 -14
  266. package/src/test-helpers/mock-pubsub.ts +1 -1
  267. package/src/test-helpers/mock-tx-helpers.ts +1 -1
  268. package/src/test-helpers/reqresp-nodes.ts +1 -1
  269. package/src/testbench/p2p_client_testbench_worker.ts +42 -22
  270. package/src/testbench/worker_client_manager.ts +6 -1
  271. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -80
  272. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
  273. package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -238
  274. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
  275. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
  276. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -82
  277. package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
  278. package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
  279. package/dest/msg_validators/block_proposal_validator/index.js +0 -1
  280. package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -283
  281. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -97
  282. package/src/msg_validators/block_proposal_validator/index.ts +0 -1
@@ -1,22 +1,18 @@
1
1
  import { SlotNumber } from '@aztec/foundation/branded-types';
2
- import { Secp256k1Signer } from '@aztec/foundation/crypto';
3
- import { Fr } from '@aztec/foundation/fields';
4
- import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
2
+ import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
+ import type { BlockProposal, CheckpointAttestation, CheckpointProposal } from '@aztec/stdlib/p2p';
5
+ import { CheckpointHeader } from '@aztec/stdlib/rollup';
5
6
  import {
6
- BlockProposal as BlockProposalClass,
7
- ConsensusPayload,
8
- SignatureDomainSeparator,
9
- getHashedSignaturePayloadEthSignedMessage,
10
- } from '@aztec/stdlib/p2p';
11
- import { makeL2BlockHeader } from '@aztec/stdlib/testing';
12
- import { TxHash } from '@aztec/stdlib/tx';
13
-
14
- import { jest } from '@jest/globals';
15
- import { type MockProxy, mock } from 'jest-mock-extended';
16
-
17
- import type { PoolInstrumentation } from '../instrumentation.js';
7
+ makeBlockHeader,
8
+ makeBlockProposal,
9
+ makeCheckpointHeader,
10
+ makeCheckpointProposal,
11
+ } from '@aztec/stdlib/testing';
12
+
18
13
  import type { AttestationPool } from './attestation_pool.js';
19
- import { mockAttestation } from './mocks.js';
14
+ import { MAX_PROPOSALS_PER_SLOT } from './kv_attestation_pool.js';
15
+ import { mockCheckpointAttestation } from './mocks.js';
20
16
 
21
17
  const NUMBER_OF_SIGNERS_PER_TEST = 4;
22
18
 
@@ -24,273 +20,183 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
24
20
  let ap: AttestationPool;
25
21
  let signers: Secp256k1Signer[];
26
22
 
27
- // Check that metrics are recorded correctly
28
- let metricsMock: MockProxy<PoolInstrumentation<BlockAttestation>>;
29
-
30
23
  beforeEach(() => {
31
24
  ap = getAttestationPool();
32
25
  signers = Array.from({ length: NUMBER_OF_SIGNERS_PER_TEST }, () => Secp256k1Signer.random());
33
-
34
- metricsMock = mock<PoolInstrumentation<BlockAttestation>>();
35
- // Can i overwrite this like this??
36
- (ap as any).metrics = metricsMock;
37
26
  });
38
27
 
39
- const createAttestationsForSlot = (slotNumber: number) => {
40
- const archive = Fr.random();
41
- return signers.map(signer => mockAttestation(signer, slotNumber, archive));
28
+ const createCheckpointAttestationsForSlot = (slotNumber: number, archive?: Fr) => {
29
+ const archiveToUse = archive ?? Fr.random();
30
+ return signers.map(signer => mockCheckpointAttestation(signer, slotNumber, archiveToUse));
42
31
  };
43
32
 
44
- const mockBlockProposal = (signer: Secp256k1Signer, slotNumber: number, archive: Fr = Fr.random()): BlockProposal => {
45
- const header = makeL2BlockHeader(1, 2, slotNumber);
46
- const payload = new ConsensusPayload(header.toCheckpointHeader(), archive);
47
-
48
- const hash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
49
- const signature = signer.sign(hash);
50
-
51
- const txHashes = [TxHash.random(), TxHash.random()]; // Mock tx hashes
52
-
53
- return new BlockProposalClass(payload, signature, txHashes);
33
+ const mockBlockProposalForPool = (
34
+ signer: Secp256k1Signer,
35
+ slotNumber: number,
36
+ archive: Fr = Fr.random(),
37
+ ): Promise<BlockProposal> => {
38
+ const header = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) });
39
+ return makeBlockProposal({
40
+ signer,
41
+ blockHeader: header,
42
+ archiveRoot: archive,
43
+ });
54
44
  };
55
45
 
56
- // We compare buffers as the objects can have cached values attached to them which are not serialised
57
- // using array containing as the kv store does not respect insertion order
58
- const compareAttestations = (a1: BlockAttestation[], a2: BlockAttestation[]) => {
46
+ // Compare checkpoint attestations buffers
47
+ // Using array containing as the kv store does not respect insertion order
48
+ const compareCheckpointAttestations = (a1: CheckpointAttestation[], a2: CheckpointAttestation[]) => {
59
49
  const a1Buffer = a1.map(attestation => attestation.toBuffer());
60
50
  const a2Buffer = a2.map(attestation => attestation.toBuffer());
61
51
  expect(a1Buffer.length).toBe(a2Buffer.length);
62
52
  expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
63
53
  };
64
54
 
65
- it('should add attestations to pool', async () => {
66
- const slotNumber = 420;
67
- const archive = Fr.random();
68
- const attestations = signers.slice(0, -1).map(signer => mockAttestation(signer, slotNumber, archive));
69
-
70
- await ap.addAttestations(attestations);
71
-
72
- const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(
73
- SlotNumber(slotNumber),
74
- archive.toString(),
75
- );
76
- expect(retrievedAttestations.length).toBe(attestations.length);
77
- compareAttestations(retrievedAttestations, attestations);
78
-
79
- // Check hasAttestation for added attestations
80
- for (const attestation of attestations) {
81
- expect(await ap.hasAttestation(attestation)).toBe(true);
82
- }
83
-
84
- const retrievedAttestationsForSlot = await ap.getAttestationsForSlot(SlotNumber(slotNumber));
85
- expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
86
- compareAttestations(retrievedAttestationsForSlot, attestations);
87
-
88
- // Add another one
89
- const newAttestation = mockAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
90
- await ap.addAttestations([newAttestation]);
91
- const retrievedAttestationsAfterAdd = await ap.getAttestationsForSlotAndProposal(
92
- SlotNumber(slotNumber),
93
- archive.toString(),
94
- );
95
- expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
96
- compareAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
97
- expect(await ap.hasAttestation(newAttestation)).toBe(true);
98
- const retrievedAttestationsForSlotAfterAdd = await ap.getAttestationsForSlot(SlotNumber(slotNumber));
99
- expect(retrievedAttestationsForSlotAfterAdd.length).toBe(attestations.length + 1);
100
- compareAttestations(retrievedAttestationsForSlotAfterAdd, [...attestations, newAttestation]);
101
-
102
- // Delete by slot
103
- await ap.deleteAttestationsForSlot(SlotNumber(slotNumber));
104
-
105
- const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
106
- SlotNumber(slotNumber),
107
- archive.toString(),
108
- );
109
- expect(retreivedAttestationsAfterDelete.length).toBe(0);
110
- // Check hasAttestation after deletion
111
- for (const attestation of attestations) {
112
- expect(await ap.hasAttestation(attestation)).toBe(false);
113
- }
114
- expect(await ap.hasAttestation(newAttestation)).toBe(false);
115
- });
116
-
117
- it('should handle duplicate proposals in a slot', async () => {
118
- const slotNumber = 420;
119
- const archive = Fr.random();
120
-
121
- // Use the same signer for all attestations
122
- const attestations: BlockAttestation[] = [];
123
- const signer = signers[0];
124
- for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
125
- attestations.push(mockAttestation(signer, slotNumber, archive));
126
- }
127
-
128
- // Add them to store and check we end up with only one
129
- await ap.addAttestations(attestations);
130
-
131
- const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(
132
- SlotNumber(slotNumber),
133
- archive.toString(),
134
- );
135
- expect(retreivedAttestations.length).toBe(1);
136
- expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
137
- expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
138
-
139
- // Try adding them on another operation and check they are still not duplicated
140
- await ap.addAttestations([attestations[0]]);
141
- expect(await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString())).toHaveLength(1);
142
- });
55
+ describe('CheckpointAttestation', () => {
56
+ it('should add attestations to pool', async () => {
57
+ const slotNumber = 420;
58
+ const archive = Fr.random();
59
+ const attestations = signers.slice(0, -1).map(signer => mockCheckpointAttestation(signer, slotNumber, archive));
143
60
 
144
- it('should store attestations by differing slot', async () => {
145
- const slotNumbers = [1, 2, 3, 4];
146
- const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i]));
61
+ await ap.addCheckpointAttestations(attestations);
147
62
 
148
- await ap.addAttestations(attestations);
63
+ const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
64
+ SlotNumber(slotNumber),
65
+ archive.toString(),
66
+ );
67
+ expect(retrievedAttestations.length).toBe(attestations.length);
68
+ compareCheckpointAttestations(retrievedAttestations, attestations);
149
69
 
150
- for (const attestation of attestations) {
151
- const slot = attestation.payload.header.slotNumber;
152
- const archive = attestation.archive.toString();
70
+ // Check hasCheckpointAttestation for added attestations
71
+ for (const attestation of attestations) {
72
+ expect(await ap.hasCheckpointAttestation(attestation)).toBe(true);
73
+ }
153
74
 
154
- const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot, archive);
155
- expect(retreivedAttestations.length).toBe(1);
156
- expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
157
- expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
158
- }
159
- });
75
+ const retrievedAttestationsForSlot = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
76
+ expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
77
+ compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
78
+
79
+ // Add another one
80
+ const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
81
+ await ap.addCheckpointAttestations([newAttestation]);
82
+ const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(
83
+ SlotNumber(slotNumber),
84
+ archive.toString(),
85
+ );
86
+ expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
87
+ compareCheckpointAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
88
+ expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(true);
89
+ const retrievedAttestationsForSlotAfterAdd = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
90
+ expect(retrievedAttestationsForSlotAfterAdd.length).toBe(attestations.length + 1);
91
+ compareCheckpointAttestations(retrievedAttestationsForSlotAfterAdd, [...attestations, newAttestation]);
92
+
93
+ // Delete by slot
94
+ await ap.deleteCheckpointAttestationsOlderThan(SlotNumber(slotNumber + 1));
95
+
96
+ const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
97
+ SlotNumber(slotNumber),
98
+ archive.toString(),
99
+ );
100
+ expect(retreivedAttestationsAfterDelete.length).toBe(0);
101
+ // Check hasCheckpointAttestation after deletion
102
+ for (const attestation of attestations) {
103
+ expect(await ap.hasCheckpointAttestation(attestation)).toBe(false);
104
+ }
105
+ expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(false);
106
+ });
160
107
 
161
- it('should store attestations by differing slot and archive', async () => {
162
- const slotNumbers = [1, 1, 2, 3];
163
- const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()];
164
- const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i], archives[i]));
108
+ it('should handle duplicate proposals in a slot', async () => {
109
+ const slotNumber = 420;
110
+ const archive = Fr.random();
111
+ const header = CheckpointHeader.random({ slotNumber: SlotNumber(slotNumber) });
165
112
 
166
- await ap.addAttestations(attestations);
113
+ // Use the same signer and header for all attestations
114
+ const attestations: CheckpointAttestation[] = [];
115
+ const signer = signers[0];
116
+ for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
117
+ attestations.push(mockCheckpointAttestation(signer, slotNumber, archive, header));
118
+ }
167
119
 
168
- for (const attestation of attestations) {
169
- const slot = attestation.payload.header.slotNumber;
170
- const proposalId = attestation.archive.toString();
120
+ // Add them to store and check we end up with only one
121
+ await ap.addCheckpointAttestations(attestations);
171
122
 
172
- const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot, proposalId);
123
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
124
+ SlotNumber(slotNumber),
125
+ archive.toString(),
126
+ );
173
127
  expect(retreivedAttestations.length).toBe(1);
174
- expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
175
- expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
176
- }
177
- });
178
-
179
- it('should delete attestations', async () => {
180
- const slotNumber = 420;
181
- const archive = Fr.random();
182
- const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
183
- const proposalId = attestations[0].archive.toString();
184
-
185
- await ap.addAttestations(attestations);
186
-
187
- const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
188
- expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
189
- compareAttestations(retreivedAttestations, attestations);
190
-
191
- // Check hasAttestation before deletion
192
- for (const attestation of attestations) {
193
- expect(await ap.hasAttestation(attestation)).toBe(true);
194
- }
195
-
196
- await ap.deleteAttestations(attestations);
128
+ expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
129
+ expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
130
+
131
+ // Try adding them on another operation and check they are still not duplicated
132
+ await ap.addCheckpointAttestations([attestations[0]]);
133
+ expect(
134
+ await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString()),
135
+ ).toHaveLength(1);
136
+ });
197
137
 
198
- const gottenAfterDelete = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
199
- expect(gottenAfterDelete.length).toBe(0);
138
+ it('should store attestations by differing slot', async () => {
139
+ const slotNumbers = [1, 2, 3, 4];
140
+ const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i]));
200
141
 
201
- // Check hasAttestation after deletion
202
- for (const attestation of attestations) {
203
- expect(await ap.hasAttestation(attestation)).toBe(false);
204
- }
205
- });
142
+ await ap.addCheckpointAttestations(attestations);
206
143
 
207
- it('should blanket delete attestations per slot', async () => {
208
- const slotNumber = 420;
209
- const archive = Fr.random();
210
- const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
211
- const proposalId = attestations[0].archive.toString();
212
-
213
- await ap.addAttestations(attestations);
144
+ for (const attestation of attestations) {
145
+ const slot = attestation.payload.header.slotNumber;
146
+ const archive = attestation.archive.toString();
214
147
 
215
- const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
216
- expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
217
- compareAttestations(retreivedAttestations, attestations);
148
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, archive);
149
+ expect(retreivedAttestations.length).toBe(1);
150
+ expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
151
+ expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
152
+ }
153
+ });
218
154
 
219
- await ap.deleteAttestationsForSlot(SlotNumber(slotNumber));
155
+ it('should store attestations by differing slot and archive', async () => {
156
+ const slotNumbers = [1, 1, 2, 3];
157
+ const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()];
158
+ const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i], archives[i]));
220
159
 
221
- const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
222
- SlotNumber(slotNumber),
223
- proposalId,
224
- );
225
- expect(retreivedAttestationsAfterDelete.length).toBe(0);
226
- });
160
+ await ap.addCheckpointAttestations(attestations);
227
161
 
228
- it('should blanket delete attestations per slot and proposal', async () => {
229
- const slotNumber = 420;
230
- const archive = Fr.random();
231
- const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
232
- const proposalId = attestations[0].archive.toString();
233
-
234
- // Add another set of attestations with a different proposalId, yet the same slot
235
- const archive2 = Fr.random();
236
- const attestations2 = signers.map(signer => mockAttestation(signer, slotNumber, archive2));
237
- const proposalId2 = attestations2[0].archive.toString();
238
-
239
- await ap.addAttestations(attestations);
240
- await ap.addAttestations(attestations2);
241
-
242
- const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
243
- expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
244
- compareAttestations(retreivedAttestations, attestations);
245
-
246
- await ap.deleteAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
247
-
248
- const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
249
- SlotNumber(slotNumber),
250
- proposalId,
251
- );
252
- expect(retreivedAttestationsAfterDelete.length).toBe(0);
253
-
254
- const retreivedAttestationsAfterDeleteForOtherProposal = await ap.getAttestationsForSlotAndProposal(
255
- SlotNumber(slotNumber),
256
- proposalId2,
257
- );
258
- expect(retreivedAttestationsAfterDeleteForOtherProposal.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
259
- compareAttestations(retreivedAttestationsAfterDeleteForOtherProposal, attestations2);
260
- });
261
-
262
- it('should delete attestations older than a given slot', async () => {
263
- const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420];
264
- const attestations = (
265
- await Promise.all(slotNumbers.map(slotNumber => createAttestationsForSlot(slotNumber)))
266
- ).flat();
267
- const proposalId = attestations[0].archive.toString();
162
+ for (const attestation of attestations) {
163
+ const slot = attestation.payload.header.slotNumber;
164
+ const proposalId = attestation.archive.toString();
268
165
 
269
- await ap.addAttestations(attestations);
166
+ const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, proposalId);
167
+ expect(retreivedAttestations.length).toBe(1);
168
+ expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
169
+ expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
170
+ }
171
+ });
270
172
 
271
- const attestationsForSlot1 = await ap.getAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
272
- expect(attestationsForSlot1.length).toBe(signers.length);
173
+ it('should delete attestations older than a given slot', async () => {
174
+ const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420];
175
+ const attestations = (
176
+ await Promise.all(slotNumbers.map(slotNumber => createCheckpointAttestationsForSlot(slotNumber)))
177
+ ).flat();
178
+ const proposalId = attestations[0].archive.toString();
273
179
 
274
- const deleteAttestationsSpy = jest.spyOn(ap, 'deleteAttestationsForSlot');
180
+ await ap.addCheckpointAttestations(attestations);
275
181
 
276
- await ap.deleteAttestationsOlderThan(SlotNumber(73));
182
+ const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
183
+ expect(attestationsForSlot1.length).toBe(signers.length);
277
184
 
278
- const attestationsForSlot1AfterDelete = await ap.getAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
279
- expect(attestationsForSlot1AfterDelete.length).toBe(0);
185
+ await ap.deleteCheckpointAttestationsOlderThan(SlotNumber(73));
280
186
 
281
- expect(deleteAttestationsSpy).toHaveBeenCalledTimes(5);
282
- expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(1));
283
- expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(2));
284
- expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(3));
285
- expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(69));
286
- expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(72));
187
+ const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
188
+ SlotNumber(1),
189
+ proposalId,
190
+ );
191
+ expect(attestationsForSlot1AfterDelete.length).toBe(0);
192
+ });
287
193
  });
288
194
 
289
195
  describe('BlockProposal in attestation pool', () => {
290
196
  it('should add and retrieve block proposal', async () => {
291
197
  const slotNumber = 420;
292
198
  const archive = Fr.random();
293
- const proposal = mockBlockProposal(signers[0], slotNumber, archive);
199
+ const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
294
200
  const proposalId = proposal.archive.toString();
295
201
 
296
202
  await ap.addBlockProposal(proposal);
@@ -317,13 +223,13 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
317
223
  it('should update block proposal if added twice with same id', async () => {
318
224
  const slotNumber = 420;
319
225
  const archive = Fr.random();
320
- const proposal1 = mockBlockProposal(signers[0], slotNumber, archive);
226
+ const proposal1 = await mockBlockProposalForPool(signers[0], slotNumber, archive);
321
227
  const proposalId = proposal1.archive.toString();
322
228
 
323
229
  await ap.addBlockProposal(proposal1);
324
230
 
325
231
  // Create a new proposal with same archive but different signer
326
- const proposal2 = mockBlockProposal(signers[1], slotNumber, archive);
232
+ const proposal2 = await mockBlockProposalForPool(signers[1], slotNumber, archive);
327
233
 
328
234
  await ap.addBlockProposal(proposal2);
329
235
 
@@ -336,8 +242,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
336
242
 
337
243
  it('should handle block proposals with different slots and same archive', async () => {
338
244
  const archive = Fr.random();
339
- const proposal1 = mockBlockProposal(signers[0], 100, archive);
340
- const proposal2 = mockBlockProposal(signers[1], 200, archive);
245
+ const proposal1 = await mockBlockProposalForPool(signers[0], 100, archive);
246
+ const proposal2 = await mockBlockProposalForPool(signers[1], 200, archive);
341
247
  const proposalId = archive.toString();
342
248
 
343
249
  await ap.addBlockProposal(proposal1);
@@ -349,81 +255,127 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
349
255
  expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
350
256
  expect(retrievedProposal!.slotNumber).toBe(SlotNumber(200));
351
257
  });
258
+ });
352
259
 
353
- it('should delete block proposal when deleting attestations for slot and proposal', async () => {
260
+ describe('CheckpointProposal in attestation pool', () => {
261
+ const mockCheckpointProposalForPool = (
262
+ signer: Secp256k1Signer,
263
+ slotNumber: number,
264
+ archive: Fr = Fr.random(),
265
+ ): Promise<CheckpointProposal> => {
266
+ const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
267
+ const blockHeader = makeBlockHeader(1);
268
+ return makeCheckpointProposal({
269
+ signer,
270
+ checkpointHeader,
271
+ archiveRoot: archive,
272
+ lastBlock: { blockHeader },
273
+ });
274
+ };
275
+
276
+ it('should add and retrieve checkpoint proposal as core (without lastBlock)', async () => {
354
277
  const slotNumber = 420;
355
278
  const archive = Fr.random();
356
- const proposal = mockBlockProposal(signers[0], slotNumber, archive);
279
+ const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
357
280
  const proposalId = proposal.archive.toString();
358
281
 
359
- // Add proposal and some attestations
360
- await ap.addBlockProposal(proposal);
361
- const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
362
- await ap.addAttestations(attestations);
282
+ await ap.addCheckpointProposal(proposal);
283
+
284
+ const retrievedProposal = await ap.getCheckpointProposal(proposalId);
363
285
 
364
- // Verify proposal exists
365
- let retrievedProposal = await ap.getBlockProposal(proposalId);
366
286
  expect(retrievedProposal).toBeDefined();
367
- expect(await ap.hasBlockProposal(proposalId)).toBe(true);
287
+ // Should return core version (without lastBlock)
288
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal.toCore().toBuffer());
368
289
 
369
- // Delete attestations for slot and proposal
370
- await ap.deleteAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
290
+ // Check hasCheckpointProposal with both id and object
291
+ expect(await ap.hasCheckpointProposal(proposalId)).toBe(true);
292
+ expect(await ap.hasCheckpointProposal(proposal)).toBe(true);
293
+ });
371
294
 
372
- // Proposal should be deleted
373
- retrievedProposal = await ap.getBlockProposal(proposalId);
374
- expect(retrievedProposal).toBeUndefined();
375
- expect(await ap.hasBlockProposal(proposalId)).toBe(false);
295
+ it('should extract and store block proposal when adding checkpoint proposal with lastBlock', async () => {
296
+ const slotNumber = 420;
297
+ const archive = Fr.random();
298
+ const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
299
+ const proposalId = proposal.archive.toString();
300
+
301
+ // Verify the proposal has a lastBlock
302
+ const expectedBlockProposal = proposal.getBlockProposal();
303
+ expect(expectedBlockProposal).toBeDefined();
304
+
305
+ await ap.addCheckpointProposal(proposal);
306
+
307
+ // The block proposal should be stored separately and retrievable
308
+ const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
309
+ expect(retrievedBlockProposal).toBeDefined();
310
+ expect(retrievedBlockProposal!.archive.toString()).toBe(archive.toString());
311
+ expect(retrievedBlockProposal!.blockHeader.toBuffer()).toEqual(expectedBlockProposal!.blockHeader.toBuffer());
376
312
  });
377
313
 
378
- it('should delete block proposal when deleting attestations for slot', async () => {
314
+ it('should not store block proposal when checkpoint proposal has no lastBlock', async () => {
379
315
  const slotNumber = 420;
380
316
  const archive = Fr.random();
381
- const proposal = mockBlockProposal(signers[0], slotNumber, archive);
317
+ const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
318
+ // Create a checkpoint proposal WITHOUT lastBlock
319
+ const proposal = await makeCheckpointProposal({
320
+ signer: signers[0],
321
+ checkpointHeader,
322
+ archiveRoot: archive,
323
+ // No lastBlock
324
+ });
382
325
  const proposalId = proposal.archive.toString();
383
326
 
384
- // Add proposal
385
- await ap.addBlockProposal(proposal);
327
+ await ap.addCheckpointProposal(proposal);
386
328
 
387
- // Verify proposal exists
388
- let retrievedProposal = await ap.getBlockProposal(proposalId);
389
- expect(retrievedProposal).toBeDefined();
390
- expect(await ap.hasBlockProposal(proposal)).toBe(true);
329
+ // The checkpoint proposal should be stored
330
+ const retrievedCheckpointProposal = await ap.getCheckpointProposal(proposalId);
331
+ expect(retrievedCheckpointProposal).toBeDefined();
391
332
 
392
- // Delete attestations for slot
393
- await ap.deleteAttestationsForSlot(SlotNumber(slotNumber));
333
+ // But no block proposal should be stored (archive key won't have a block proposal)
334
+ const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
335
+ expect(retrievedBlockProposal).toBeUndefined();
336
+ });
394
337
 
395
- // Proposal should be deleted
396
- retrievedProposal = await ap.getBlockProposal(proposalId);
338
+ it('should return undefined for non-existent checkpoint proposal', async () => {
339
+ const nonExistentId = Fr.random().toString();
340
+ const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
397
341
  expect(retrievedProposal).toBeUndefined();
398
- expect(await ap.hasBlockProposal(proposal)).toBe(false);
342
+
343
+ // Check hasCheckpointProposal returns false for non-existent proposal
344
+ expect(await ap.hasCheckpointProposal(nonExistentId)).toBe(false);
399
345
  });
400
346
 
401
- it('should be able to fetch both block proposal and attestations', async () => {
347
+ it('should update checkpoint proposal if added twice with same id', async () => {
402
348
  const slotNumber = 420;
403
349
  const archive = Fr.random();
404
- const proposal = mockBlockProposal(signers[0], slotNumber, archive);
405
- const proposalId = proposal.archive.toString();
350
+ const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
351
+ const proposalId = proposal1.archive.toString();
406
352
 
407
- // Add proposal first
408
- await ap.addBlockProposal(proposal);
353
+ await ap.addCheckpointProposal(proposal1);
409
354
 
410
- // Add attestations for the same proposal
411
- const attestations = signers.slice(1).map(signer => mockAttestation(signer, slotNumber, archive));
412
- await ap.addAttestations(attestations);
355
+ // Create a new proposal with same archive but different signer
356
+ const proposal2 = await mockCheckpointProposalForPool(signers[1], slotNumber, archive);
413
357
 
414
- // Retrieve both proposal and attestations
415
- const retrievedProposal = await ap.getBlockProposal(proposalId);
416
- const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
358
+ await ap.addCheckpointProposal(proposal2);
417
359
 
360
+ const retrievedProposal = await ap.getCheckpointProposal(proposalId);
418
361
  expect(retrievedProposal).toBeDefined();
419
- expect(retrievedProposal).toEqual(proposal);
420
- expect(await ap.hasBlockProposal(proposalId)).toBe(true);
362
+ // Should have the second proposal (as core)
363
+ expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toCore().toBuffer());
364
+ expect(retrievedProposal!.getSender()?.toString()).toBe(signers[1].address.toString());
365
+ });
421
366
 
422
- compareAttestations(retrievedAttestations, attestations);
423
- // Check hasAttestation for all attestations
424
- for (const attestation of attestations) {
425
- expect(await ap.hasAttestation(attestation)).toBe(true);
367
+ it('should throw ProposalSlotCapExceededError when exceeding capacity', async () => {
368
+ const slotNumber = 420;
369
+
370
+ // Add MAX_PROPOSALS_PER_SLOT proposals
371
+ for (let i = 0; i < MAX_PROPOSALS_PER_SLOT; i++) {
372
+ const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
373
+ await ap.addCheckpointProposal(proposal);
426
374
  }
375
+
376
+ // The next proposal should throw
377
+ const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
378
+ await expect(ap.addCheckpointProposal(extraProposal)).rejects.toThrow('Maximum checkpoint proposals per slot');
427
379
  });
428
380
  });
429
381
  }