@aztec/p2p 0.0.0-test.0

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 (311) hide show
  1. package/README.md +7 -0
  2. package/dest/bootstrap/bootstrap.d.ts +38 -0
  3. package/dest/bootstrap/bootstrap.d.ts.map +1 -0
  4. package/dest/bootstrap/bootstrap.js +123 -0
  5. package/dest/client/factory.d.ts +21 -0
  6. package/dest/client/factory.d.ts.map +1 -0
  7. package/dest/client/factory.js +37 -0
  8. package/dest/client/index.d.ts +3 -0
  9. package/dest/client/index.d.ts.map +1 -0
  10. package/dest/client/index.js +2 -0
  11. package/dest/client/p2p_client.d.ts +314 -0
  12. package/dest/client/p2p_client.d.ts.map +1 -0
  13. package/dest/client/p2p_client.js +505 -0
  14. package/dest/config.d.ts +180 -0
  15. package/dest/config.d.ts.map +1 -0
  16. package/dest/config.js +193 -0
  17. package/dest/enr/generate-enr.d.ts +9 -0
  18. package/dest/enr/generate-enr.d.ts.map +1 -0
  19. package/dest/enr/generate-enr.js +30 -0
  20. package/dest/enr/index.d.ts +2 -0
  21. package/dest/enr/index.d.ts.map +1 -0
  22. package/dest/enr/index.js +1 -0
  23. package/dest/errors/reqresp.error.d.ts +28 -0
  24. package/dest/errors/reqresp.error.d.ts.map +1 -0
  25. package/dest/errors/reqresp.error.js +30 -0
  26. package/dest/index.d.ts +8 -0
  27. package/dest/index.d.ts.map +1 -0
  28. package/dest/index.js +7 -0
  29. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +57 -0
  30. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -0
  31. package/dest/mem_pools/attestation_pool/attestation_pool.js +6 -0
  32. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +3 -0
  33. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -0
  34. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +195 -0
  35. package/dest/mem_pools/attestation_pool/index.d.ts +3 -0
  36. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -0
  37. package/dest/mem_pools/attestation_pool/index.js +2 -0
  38. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +22 -0
  39. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -0
  40. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +112 -0
  41. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -0
  42. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -0
  43. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +129 -0
  44. package/dest/mem_pools/attestation_pool/mocks.d.ts +19 -0
  45. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -0
  46. package/dest/mem_pools/attestation_pool/mocks.js +33 -0
  47. package/dest/mem_pools/index.d.ts +4 -0
  48. package/dest/mem_pools/index.d.ts.map +1 -0
  49. package/dest/mem_pools/index.js +1 -0
  50. package/dest/mem_pools/instrumentation.d.ts +30 -0
  51. package/dest/mem_pools/instrumentation.d.ts.map +1 -0
  52. package/dest/mem_pools/instrumentation.js +84 -0
  53. package/dest/mem_pools/interface.d.ts +11 -0
  54. package/dest/mem_pools/interface.d.ts.map +1 -0
  55. package/dest/mem_pools/interface.js +3 -0
  56. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +66 -0
  57. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -0
  58. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +245 -0
  59. package/dest/mem_pools/tx_pool/index.d.ts +4 -0
  60. package/dest/mem_pools/tx_pool/index.d.ts.map +1 -0
  61. package/dest/mem_pools/tx_pool/index.js +3 -0
  62. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +56 -0
  63. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -0
  64. package/dest/mem_pools/tx_pool/memory_tx_pool.js +141 -0
  65. package/dest/mem_pools/tx_pool/priority.d.ts +8 -0
  66. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -0
  67. package/dest/mem_pools/tx_pool/priority.js +10 -0
  68. package/dest/mem_pools/tx_pool/tx_pool.d.ts +66 -0
  69. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -0
  70. package/dest/mem_pools/tx_pool/tx_pool.js +3 -0
  71. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +7 -0
  72. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -0
  73. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +169 -0
  74. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +8 -0
  75. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -0
  76. package/dest/msg_validators/attestation_validator/attestation_validator.js +19 -0
  77. package/dest/msg_validators/attestation_validator/index.d.ts +2 -0
  78. package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -0
  79. package/dest/msg_validators/attestation_validator/index.js +1 -0
  80. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +8 -0
  81. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -0
  82. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +21 -0
  83. package/dest/msg_validators/block_proposal_validator/index.d.ts +2 -0
  84. package/dest/msg_validators/block_proposal_validator/index.d.ts.map +1 -0
  85. package/dest/msg_validators/block_proposal_validator/index.js +1 -0
  86. package/dest/msg_validators/index.d.ts +4 -0
  87. package/dest/msg_validators/index.d.ts.map +1 -0
  88. package/dest/msg_validators/index.js +3 -0
  89. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +7 -0
  90. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -0
  91. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +31 -0
  92. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +11 -0
  93. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -0
  94. package/dest/msg_validators/tx_validator/block_header_validator.js +26 -0
  95. package/dest/msg_validators/tx_validator/data_validator.d.ts +6 -0
  96. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -0
  97. package/dest/msg_validators/tx_validator/data_validator.js +107 -0
  98. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +12 -0
  99. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -0
  100. package/dest/msg_validators/tx_validator/double_spend_validator.js +41 -0
  101. package/dest/msg_validators/tx_validator/index.d.ts +7 -0
  102. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -0
  103. package/dest/msg_validators/tx_validator/index.js +6 -0
  104. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +10 -0
  105. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -0
  106. package/dest/msg_validators/tx_validator/metadata_validator.js +44 -0
  107. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +9 -0
  108. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -0
  109. package/dest/msg_validators/tx_validator/tx_proof_validator.js +25 -0
  110. package/dest/services/data_store.d.ts +27 -0
  111. package/dest/services/data_store.d.ts.map +1 -0
  112. package/dest/services/data_store.js +188 -0
  113. package/dest/services/discv5/discV5_service.d.ts +42 -0
  114. package/dest/services/discv5/discV5_service.d.ts.map +1 -0
  115. package/dest/services/discv5/discV5_service.js +214 -0
  116. package/dest/services/dummy_service.d.ts +85 -0
  117. package/dest/services/dummy_service.d.ts.map +1 -0
  118. package/dest/services/dummy_service.js +92 -0
  119. package/dest/services/encoding.d.ts +31 -0
  120. package/dest/services/encoding.d.ts.map +1 -0
  121. package/dest/services/encoding.js +66 -0
  122. package/dest/services/gossipsub/scoring.d.ts +7 -0
  123. package/dest/services/gossipsub/scoring.d.ts.map +1 -0
  124. package/dest/services/gossipsub/scoring.js +10 -0
  125. package/dest/services/index.d.ts +3 -0
  126. package/dest/services/index.d.ts.map +1 -0
  127. package/dest/services/index.js +2 -0
  128. package/dest/services/libp2p/libp2p_service.d.ts +186 -0
  129. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -0
  130. package/dest/services/libp2p/libp2p_service.js +712 -0
  131. package/dest/services/peer-manager/metrics.d.ts +12 -0
  132. package/dest/services/peer-manager/metrics.d.ts.map +1 -0
  133. package/dest/services/peer-manager/metrics.js +33 -0
  134. package/dest/services/peer-manager/peer_manager.d.ts +94 -0
  135. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -0
  136. package/dest/services/peer-manager/peer_manager.js +445 -0
  137. package/dest/services/peer-manager/peer_scoring.d.ts +28 -0
  138. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -0
  139. package/dest/services/peer-manager/peer_scoring.js +86 -0
  140. package/dest/services/reqresp/config.d.ts +16 -0
  141. package/dest/services/reqresp/config.d.ts.map +1 -0
  142. package/dest/services/reqresp/config.js +20 -0
  143. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +45 -0
  144. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -0
  145. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +88 -0
  146. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +61 -0
  147. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -0
  148. package/dest/services/reqresp/connection-sampler/connection_sampler.js +181 -0
  149. package/dest/services/reqresp/index.d.ts +6 -0
  150. package/dest/services/reqresp/index.d.ts.map +1 -0
  151. package/dest/services/reqresp/index.js +4 -0
  152. package/dest/services/reqresp/interface.d.ts +116 -0
  153. package/dest/services/reqresp/interface.d.ts.map +1 -0
  154. package/dest/services/reqresp/interface.js +84 -0
  155. package/dest/services/reqresp/metrics.d.ts +15 -0
  156. package/dest/services/reqresp/metrics.d.ts.map +1 -0
  157. package/dest/services/reqresp/metrics.js +55 -0
  158. package/dest/services/reqresp/protocols/block.d.ts +4 -0
  159. package/dest/services/reqresp/protocols/block.d.ts.map +1 -0
  160. package/dest/services/reqresp/protocols/block.js +8 -0
  161. package/dest/services/reqresp/protocols/goodbye.d.ts +51 -0
  162. package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -0
  163. package/dest/services/reqresp/protocols/goodbye.js +87 -0
  164. package/dest/services/reqresp/protocols/index.d.ts +9 -0
  165. package/dest/services/reqresp/protocols/index.d.ts.map +1 -0
  166. package/dest/services/reqresp/protocols/index.js +7 -0
  167. package/dest/services/reqresp/protocols/ping.d.ts +9 -0
  168. package/dest/services/reqresp/protocols/ping.d.ts.map +1 -0
  169. package/dest/services/reqresp/protocols/ping.js +7 -0
  170. package/dest/services/reqresp/protocols/status.d.ts +9 -0
  171. package/dest/services/reqresp/protocols/status.d.ts.map +1 -0
  172. package/dest/services/reqresp/protocols/status.js +7 -0
  173. package/dest/services/reqresp/protocols/tx.d.ts +13 -0
  174. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -0
  175. package/dest/services/reqresp/protocols/tx.js +20 -0
  176. package/dest/services/reqresp/rate-limiter/index.d.ts +2 -0
  177. package/dest/services/reqresp/rate-limiter/index.d.ts.map +1 -0
  178. package/dest/services/reqresp/rate-limiter/index.js +1 -0
  179. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +102 -0
  180. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -0
  181. package/dest/services/reqresp/rate-limiter/rate_limiter.js +184 -0
  182. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +3 -0
  183. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -0
  184. package/dest/services/reqresp/rate-limiter/rate_limits.js +54 -0
  185. package/dest/services/reqresp/reqresp.d.ts +166 -0
  186. package/dest/services/reqresp/reqresp.d.ts.map +1 -0
  187. package/dest/services/reqresp/reqresp.js +516 -0
  188. package/dest/services/reqresp/status.d.ts +31 -0
  189. package/dest/services/reqresp/status.d.ts.map +1 -0
  190. package/dest/services/reqresp/status.js +51 -0
  191. package/dest/services/service.d.ts +87 -0
  192. package/dest/services/service.d.ts.map +1 -0
  193. package/dest/services/service.js +5 -0
  194. package/dest/test-helpers/generate-peer-id-private-keys.d.ts +7 -0
  195. package/dest/test-helpers/generate-peer-id-private-keys.d.ts.map +1 -0
  196. package/dest/test-helpers/generate-peer-id-private-keys.js +13 -0
  197. package/dest/test-helpers/get-ports.d.ts +7 -0
  198. package/dest/test-helpers/get-ports.d.ts.map +1 -0
  199. package/dest/test-helpers/get-ports.js +8 -0
  200. package/dest/test-helpers/index.d.ts +6 -0
  201. package/dest/test-helpers/index.d.ts.map +1 -0
  202. package/dest/test-helpers/index.js +5 -0
  203. package/dest/test-helpers/make-enrs.d.ts +16 -0
  204. package/dest/test-helpers/make-enrs.d.ts.map +1 -0
  205. package/dest/test-helpers/make-enrs.js +32 -0
  206. package/dest/test-helpers/make-test-p2p-clients.d.ts +36 -0
  207. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -0
  208. package/dest/test-helpers/make-test-p2p-clients.js +68 -0
  209. package/dest/test-helpers/reqresp-nodes.d.ts +66 -0
  210. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -0
  211. package/dest/test-helpers/reqresp-nodes.js +207 -0
  212. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -0
  213. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -0
  214. package/dest/testbench/p2p_client_testbench_worker.js +132 -0
  215. package/dest/testbench/parse_log_file.d.ts +2 -0
  216. package/dest/testbench/parse_log_file.d.ts.map +1 -0
  217. package/dest/testbench/parse_log_file.js +131 -0
  218. package/dest/testbench/testbench.d.ts +2 -0
  219. package/dest/testbench/testbench.d.ts.map +1 -0
  220. package/dest/testbench/testbench.js +61 -0
  221. package/dest/testbench/worker_client_manager.d.ts +56 -0
  222. package/dest/testbench/worker_client_manager.d.ts.map +1 -0
  223. package/dest/testbench/worker_client_manager.js +266 -0
  224. package/dest/types/index.d.ts +32 -0
  225. package/dest/types/index.d.ts.map +1 -0
  226. package/dest/types/index.js +28 -0
  227. package/dest/util.d.ts +53 -0
  228. package/dest/util.d.ts.map +1 -0
  229. package/dest/util.js +140 -0
  230. package/dest/versioning.d.ts +12 -0
  231. package/dest/versioning.d.ts.map +1 -0
  232. package/dest/versioning.js +33 -0
  233. package/package.json +127 -0
  234. package/src/bootstrap/bootstrap.ts +146 -0
  235. package/src/client/factory.ts +89 -0
  236. package/src/client/index.ts +2 -0
  237. package/src/client/p2p_client.ts +754 -0
  238. package/src/config.ts +371 -0
  239. package/src/enr/generate-enr.ts +39 -0
  240. package/src/enr/index.ts +1 -0
  241. package/src/errors/reqresp.error.ts +35 -0
  242. package/src/index.ts +7 -0
  243. package/src/mem_pools/attestation_pool/attestation_pool.ts +62 -0
  244. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +230 -0
  245. package/src/mem_pools/attestation_pool/index.ts +2 -0
  246. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +159 -0
  247. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +161 -0
  248. package/src/mem_pools/attestation_pool/mocks.ts +44 -0
  249. package/src/mem_pools/index.ts +3 -0
  250. package/src/mem_pools/instrumentation.ts +126 -0
  251. package/src/mem_pools/interface.ts +12 -0
  252. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +309 -0
  253. package/src/mem_pools/tx_pool/index.ts +3 -0
  254. package/src/mem_pools/tx_pool/memory_tx_pool.ts +174 -0
  255. package/src/mem_pools/tx_pool/priority.ts +13 -0
  256. package/src/mem_pools/tx_pool/tx_pool.ts +76 -0
  257. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +130 -0
  258. package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -0
  259. package/src/msg_validators/attestation_validator/index.ts +1 -0
  260. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +29 -0
  261. package/src/msg_validators/block_proposal_validator/index.ts +1 -0
  262. package/src/msg_validators/index.ts +3 -0
  263. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +32 -0
  264. package/src/msg_validators/tx_validator/block_header_validator.ts +25 -0
  265. package/src/msg_validators/tx_validator/data_validator.ts +106 -0
  266. package/src/msg_validators/tx_validator/double_spend_validator.ts +38 -0
  267. package/src/msg_validators/tx_validator/index.ts +6 -0
  268. package/src/msg_validators/tx_validator/metadata_validator.ts +48 -0
  269. package/src/msg_validators/tx_validator/tx_proof_validator.ts +18 -0
  270. package/src/services/data_store.ts +235 -0
  271. package/src/services/discv5/discV5_service.ts +256 -0
  272. package/src/services/dummy_service.ts +134 -0
  273. package/src/services/encoding.ts +79 -0
  274. package/src/services/gossipsub/scoring.ts +13 -0
  275. package/src/services/index.ts +2 -0
  276. package/src/services/libp2p/libp2p_service.ts +871 -0
  277. package/src/services/peer-manager/metrics.ts +41 -0
  278. package/src/services/peer-manager/peer_manager.ts +530 -0
  279. package/src/services/peer-manager/peer_scoring.ts +105 -0
  280. package/src/services/reqresp/config.ts +35 -0
  281. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +94 -0
  282. package/src/services/reqresp/connection-sampler/connection_sampler.ts +217 -0
  283. package/src/services/reqresp/index.ts +4 -0
  284. package/src/services/reqresp/interface.ts +185 -0
  285. package/src/services/reqresp/metrics.ts +57 -0
  286. package/src/services/reqresp/protocols/block.ts +15 -0
  287. package/src/services/reqresp/protocols/goodbye.ts +101 -0
  288. package/src/services/reqresp/protocols/index.ts +8 -0
  289. package/src/services/reqresp/protocols/ping.ts +8 -0
  290. package/src/services/reqresp/protocols/status.ts +8 -0
  291. package/src/services/reqresp/protocols/tx.ts +29 -0
  292. package/src/services/reqresp/rate-limiter/index.ts +1 -0
  293. package/src/services/reqresp/rate-limiter/rate_limiter.ts +228 -0
  294. package/src/services/reqresp/rate-limiter/rate_limits.ts +55 -0
  295. package/src/services/reqresp/reqresp.ts +661 -0
  296. package/src/services/reqresp/status.ts +59 -0
  297. package/src/services/service.ts +112 -0
  298. package/src/test-helpers/generate-peer-id-private-keys.ts +15 -0
  299. package/src/test-helpers/get-ports.ts +8 -0
  300. package/src/test-helpers/index.ts +5 -0
  301. package/src/test-helpers/make-enrs.ts +44 -0
  302. package/src/test-helpers/make-test-p2p-clients.ts +122 -0
  303. package/src/test-helpers/reqresp-nodes.ts +289 -0
  304. package/src/testbench/README.md +20 -0
  305. package/src/testbench/p2p_client_testbench_worker.ts +152 -0
  306. package/src/testbench/parse_log_file.ts +175 -0
  307. package/src/testbench/testbench.ts +66 -0
  308. package/src/testbench/worker_client_manager.ts +318 -0
  309. package/src/types/index.ts +36 -0
  310. package/src/util.ts +196 -0
  311. package/src/versioning.ts +50 -0
@@ -0,0 +1,230 @@
1
+ import { Secp256k1Signer } from '@aztec/foundation/crypto';
2
+ import { Fr } from '@aztec/foundation/fields';
3
+ import type { BlockAttestation } from '@aztec/stdlib/p2p';
4
+ import { TxHash } from '@aztec/stdlib/tx';
5
+
6
+ import { jest } from '@jest/globals';
7
+ import { type MockProxy, mock } from 'jest-mock-extended';
8
+
9
+ import type { PoolInstrumentation } from '../instrumentation.js';
10
+ import type { AttestationPool } from './attestation_pool.js';
11
+ import { mockAttestation } from './mocks.js';
12
+
13
+ const NUMBER_OF_SIGNERS_PER_TEST = 4;
14
+
15
+ export function describeAttestationPool(getAttestationPool: () => AttestationPool) {
16
+ let ap: AttestationPool;
17
+ let signers: Secp256k1Signer[];
18
+
19
+ // Check that metrics are recorded correctly
20
+ let metricsMock: MockProxy<PoolInstrumentation<BlockAttestation>>;
21
+
22
+ beforeEach(() => {
23
+ ap = getAttestationPool();
24
+ signers = Array.from({ length: NUMBER_OF_SIGNERS_PER_TEST }, () => Secp256k1Signer.random());
25
+
26
+ metricsMock = mock<PoolInstrumentation<BlockAttestation>>();
27
+ // Can i overwrite this like this??
28
+ (ap as any).metrics = metricsMock;
29
+ });
30
+
31
+ const createAttestationsForSlot = (slotNumber: number) => {
32
+ const archive = Fr.random();
33
+ return Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive)));
34
+ };
35
+
36
+ // We compare buffers as the objects can have cached values attached to them which are not serialised
37
+ // using array containing as the kv store does not respect insertion order
38
+ const compareAttestations = (a1: BlockAttestation[], a2: BlockAttestation[]) => {
39
+ const a1Buffer = a1.map(attestation => attestation.toBuffer());
40
+ const a2Buffer = a2.map(attestation => attestation.toBuffer());
41
+ expect(a1Buffer.length).toBe(a2Buffer.length);
42
+ expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
43
+ };
44
+
45
+ it('should add attestations to pool', async () => {
46
+ const slotNumber = 420;
47
+ const archive = Fr.random();
48
+ const attestations = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive)));
49
+
50
+ await ap.addAttestations(attestations);
51
+
52
+ // Check metrics have been updated.
53
+ expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
54
+
55
+ const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString());
56
+
57
+ expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
58
+
59
+ compareAttestations(retreivedAttestations, attestations);
60
+
61
+ // Delete by slot
62
+ await ap.deleteAttestationsForSlot(BigInt(slotNumber));
63
+
64
+ expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length);
65
+
66
+ const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString());
67
+ expect(retreivedAttestationsAfterDelete.length).toBe(0);
68
+ });
69
+
70
+ it('Should handle duplicate proposals in a slot', async () => {
71
+ const slotNumber = 420;
72
+ const archive = Fr.random();
73
+ const txs = [0, 1, 2, 3, 4, 5].map(() => TxHash.random());
74
+
75
+ // Use the same signer for all attestations
76
+ const attestations: BlockAttestation[] = [];
77
+ const signer = signers[0];
78
+ for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
79
+ attestations.push(await mockAttestation(signer, slotNumber, archive, txs));
80
+ }
81
+
82
+ await ap.addAttestations(attestations);
83
+
84
+ const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString());
85
+ expect(retreivedAttestations.length).toBe(1);
86
+ expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
87
+ expect(retreivedAttestations[0].payload.txHashes).toEqual(txs);
88
+ expect((await retreivedAttestations[0].getSender()).toString()).toEqual(signer.address.toString());
89
+ });
90
+
91
+ it('Should store attestations by differing slot', async () => {
92
+ const slotNumbers = [1, 2, 3, 4];
93
+ const attestations = await Promise.all(signers.map((signer, i) => mockAttestation(signer, slotNumbers[i])));
94
+
95
+ await ap.addAttestations(attestations);
96
+
97
+ for (const attestation of attestations) {
98
+ const slot = attestation.payload.header.globalVariables.slotNumber;
99
+ const archive = attestation.archive.toString();
100
+
101
+ const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), archive);
102
+ expect(retreivedAttestations.length).toBe(1);
103
+ expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
104
+ expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot);
105
+ }
106
+ });
107
+
108
+ it('Should store attestations by differing slot and archive', async () => {
109
+ const slotNumbers = [1, 1, 2, 3];
110
+ const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()];
111
+ const attestations = await Promise.all(
112
+ signers.map((signer, i) => mockAttestation(signer, slotNumbers[i], archives[i])),
113
+ );
114
+
115
+ await ap.addAttestations(attestations);
116
+
117
+ for (const attestation of attestations) {
118
+ const slot = attestation.payload.header.globalVariables.slotNumber;
119
+ const proposalId = attestation.archive.toString();
120
+
121
+ const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), proposalId);
122
+ expect(retreivedAttestations.length).toBe(1);
123
+ expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
124
+ expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot);
125
+ }
126
+ });
127
+
128
+ it('Should delete attestations', async () => {
129
+ const slotNumber = 420;
130
+ const archive = Fr.random();
131
+ const attestations = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive)));
132
+ const proposalId = attestations[0].archive.toString();
133
+
134
+ await ap.addAttestations(attestations);
135
+
136
+ expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
137
+
138
+ const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
139
+ expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
140
+ compareAttestations(retreivedAttestations, attestations);
141
+
142
+ await ap.deleteAttestations(attestations);
143
+
144
+ expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length);
145
+
146
+ const gottenAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
147
+ expect(gottenAfterDelete.length).toBe(0);
148
+ });
149
+
150
+ it('Should blanket delete attestations per slot', async () => {
151
+ const slotNumber = 420;
152
+ const archive = Fr.random();
153
+ const attestations = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive)));
154
+ const proposalId = attestations[0].archive.toString();
155
+
156
+ await ap.addAttestations(attestations);
157
+
158
+ const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
159
+ expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
160
+ compareAttestations(retreivedAttestations, attestations);
161
+
162
+ await ap.deleteAttestationsForSlot(BigInt(slotNumber));
163
+
164
+ const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
165
+ expect(retreivedAttestationsAfterDelete.length).toBe(0);
166
+ });
167
+
168
+ it('Should blanket delete attestations per slot and proposal', async () => {
169
+ const slotNumber = 420;
170
+ const archive = Fr.random();
171
+ const attestations = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive)));
172
+ const proposalId = attestations[0].archive.toString();
173
+
174
+ // Add another set of attestations with a different proposalId, yet the same slot
175
+ const archive2 = Fr.random();
176
+ const attestations2 = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive2)));
177
+ const proposalId2 = attestations2[0].archive.toString();
178
+
179
+ await ap.addAttestations(attestations);
180
+ await ap.addAttestations(attestations2);
181
+
182
+ expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
183
+ expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations2.length);
184
+
185
+ const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
186
+ expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
187
+ compareAttestations(retreivedAttestations, attestations);
188
+
189
+ await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId);
190
+
191
+ expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length);
192
+
193
+ const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
194
+ expect(retreivedAttestationsAfterDelete.length).toBe(0);
195
+
196
+ const retreivedAttestationsAfterDeleteForOtherProposal = await ap.getAttestationsForSlot(
197
+ BigInt(slotNumber),
198
+ proposalId2,
199
+ );
200
+ expect(retreivedAttestationsAfterDeleteForOtherProposal.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
201
+ compareAttestations(retreivedAttestationsAfterDeleteForOtherProposal, attestations2);
202
+ });
203
+
204
+ it('Should delete attestations older than a given slot', async () => {
205
+ const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420];
206
+ const attestations = (
207
+ await Promise.all(slotNumbers.map(slotNumber => createAttestationsForSlot(slotNumber)))
208
+ ).flat();
209
+ const proposalId = attestations[0].archive.toString();
210
+
211
+ await ap.addAttestations(attestations);
212
+
213
+ const attestationsForSlot1 = await ap.getAttestationsForSlot(BigInt(1), proposalId);
214
+ expect(attestationsForSlot1.length).toBe(signers.length);
215
+
216
+ const deleteAttestationsSpy = jest.spyOn(ap, 'deleteAttestationsForSlot');
217
+
218
+ await ap.deleteAttestationsOlderThan(BigInt(73));
219
+
220
+ const attestationsForSlot1AfterDelete = await ap.getAttestationsForSlot(BigInt(1), proposalId);
221
+ expect(attestationsForSlot1AfterDelete.length).toBe(0);
222
+
223
+ expect(deleteAttestationsSpy).toHaveBeenCalledTimes(5);
224
+ expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(1));
225
+ expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(2));
226
+ expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(3));
227
+ expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(69));
228
+ expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(72));
229
+ });
230
+ }
@@ -0,0 +1,2 @@
1
+ export * from './attestation_pool.js';
2
+ export * from './memory_attestation_pool.js';
@@ -0,0 +1,159 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import { toArray } from '@aztec/foundation/iterable';
3
+ import { createLogger } from '@aztec/foundation/log';
4
+ import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
5
+ import { BlockAttestation } from '@aztec/stdlib/p2p';
6
+ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
7
+
8
+ import { PoolInstrumentation, PoolName } from '../instrumentation.js';
9
+ import type { AttestationPool } from './attestation_pool.js';
10
+
11
+ export class KvAttestationPool implements AttestationPool {
12
+ private metrics: PoolInstrumentation<BlockAttestation>;
13
+
14
+ private attestations: AztecAsyncMap<string, Buffer>;
15
+ private proposalsForSlot: AztecAsyncMultiMap<string, string>;
16
+ private attestationsForProposal: AztecAsyncMultiMap<string, string>;
17
+
18
+ constructor(
19
+ private store: AztecAsyncKVStore,
20
+ telemetry: TelemetryClient = getTelemetryClient(),
21
+ private log = createLogger('aztec:attestation_pool'),
22
+ ) {
23
+ this.attestations = store.openMap('attestations');
24
+ this.proposalsForSlot = store.openMultiMap('proposals_for_slot');
25
+ this.attestationsForProposal = store.openMultiMap('attestations_for_proposal');
26
+
27
+ this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL);
28
+ }
29
+
30
+ private getProposalKey(slot: number | bigint | Fr | string, proposalId: Fr | string | Buffer): string {
31
+ const slotStr = typeof slot === 'string' ? slot : new Fr(slot).toString();
32
+ const proposalIdStr =
33
+ typeof proposalId === 'string'
34
+ ? proposalId
35
+ : Buffer.isBuffer(proposalId)
36
+ ? Fr.fromBuffer(proposalId).toString()
37
+ : proposalId.toString();
38
+
39
+ return `${slotStr}-${proposalIdStr}`;
40
+ }
41
+
42
+ private getAttestationKey(slot: number | bigint | Fr | string, proposalId: Fr | string, address: string): string {
43
+ return `${this.getProposalKey(slot, proposalId)}-${address}`;
44
+ }
45
+
46
+ public async addAttestations(attestations: BlockAttestation[]): Promise<void> {
47
+ await this.store.transactionAsync(async () => {
48
+ for (const attestation of attestations) {
49
+ const slotNumber = attestation.payload.header.globalVariables.slotNumber;
50
+ const proposalId = attestation.archive;
51
+ const address = (await attestation.getSender()).toString();
52
+
53
+ await this.attestations.set(this.getAttestationKey(slotNumber, proposalId, address), attestation.toBuffer());
54
+
55
+ await this.proposalsForSlot.set(slotNumber.toString(), proposalId.toString());
56
+ await this.attestationsForProposal.set(
57
+ this.getProposalKey(slotNumber, proposalId),
58
+ this.getAttestationKey(slotNumber, proposalId, address),
59
+ );
60
+
61
+ this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`);
62
+ }
63
+ });
64
+
65
+ this.metrics.recordAddedObjects(attestations.length);
66
+ }
67
+
68
+ public async getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]> {
69
+ const attestationIds = await toArray(
70
+ this.attestationsForProposal.getValuesAsync(this.getProposalKey(slot, proposalId)),
71
+ );
72
+ const attestations: BlockAttestation[] = [];
73
+
74
+ // alternatively iterate this.attestaions starting from slot-proposal-EthAddress.zero
75
+ for (const id of attestationIds) {
76
+ const buf = await this.attestations.getAsync(id);
77
+
78
+ if (!buf) {
79
+ // this should not happen unless we lost writes
80
+ throw new Error('Attestation not found ' + id);
81
+ }
82
+
83
+ const attestation = BlockAttestation.fromBuffer(buf);
84
+ attestations.push(attestation);
85
+ }
86
+
87
+ return attestations;
88
+ }
89
+
90
+ public async deleteAttestationsOlderThan(oldestSlot: bigint): Promise<void> {
91
+ const olderThan = await toArray(this.proposalsForSlot.keysAsync({ end: new Fr(oldestSlot).toString() }));
92
+ for (const oldSlot of olderThan) {
93
+ await this.deleteAttestationsForSlot(BigInt(oldSlot));
94
+ }
95
+ }
96
+
97
+ public async deleteAttestationsForSlot(slot: bigint): Promise<void> {
98
+ const slotFr = new Fr(slot);
99
+ let numberOfAttestations = 0;
100
+ await this.store.transactionAsync(async () => {
101
+ const proposalIds = await toArray(this.proposalsForSlot.getValuesAsync(slotFr.toString()));
102
+ for (const proposalId of proposalIds) {
103
+ const attestations = await toArray(
104
+ this.attestationsForProposal.getValuesAsync(this.getProposalKey(slotFr, proposalId)),
105
+ );
106
+
107
+ numberOfAttestations += attestations.length;
108
+ for (const attestation of attestations) {
109
+ await this.attestations.delete(attestation);
110
+ }
111
+
112
+ await this.attestationsForProposal.delete(this.getProposalKey(slotFr, proposalId));
113
+ }
114
+ });
115
+
116
+ this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
117
+ this.metrics.recordRemovedObjects(numberOfAttestations);
118
+ }
119
+
120
+ public async deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void> {
121
+ let numberOfAttestations = 0;
122
+ await this.store.transactionAsync(async () => {
123
+ const slotString = new Fr(slot).toString();
124
+ const attestations = await toArray(
125
+ this.attestationsForProposal.getValuesAsync(this.getProposalKey(slot, proposalId)),
126
+ );
127
+
128
+ numberOfAttestations += attestations.length;
129
+ for (const attestation of attestations) {
130
+ await this.attestations.delete(attestation);
131
+ }
132
+
133
+ await this.proposalsForSlot.deleteValue(slotString, proposalId);
134
+ await this.attestationsForProposal.delete(this.getProposalKey(slotString, proposalId));
135
+ });
136
+
137
+ this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
138
+ this.metrics.recordRemovedObjects(numberOfAttestations);
139
+ }
140
+
141
+ public async deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
142
+ await this.store.transactionAsync(async () => {
143
+ for (const attestation of attestations) {
144
+ const slotNumber = attestation.payload.header.globalVariables.slotNumber;
145
+ const proposalId = attestation.archive;
146
+ const address = (await attestation.getSender()).toString();
147
+
148
+ await this.attestations.delete(this.getAttestationKey(slotNumber, proposalId, address));
149
+ await this.attestationsForProposal.deleteValue(
150
+ this.getProposalKey(slotNumber, proposalId),
151
+ this.getAttestationKey(slotNumber, proposalId, address),
152
+ );
153
+
154
+ this.log.debug(`Deleted attestation for slot ${slotNumber} from ${address}`);
155
+ }
156
+ });
157
+ this.metrics.recordRemovedObjects(attestations.length);
158
+ }
159
+ }
@@ -0,0 +1,161 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import type { BlockAttestation } from '@aztec/stdlib/p2p';
3
+ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
4
+
5
+ import { PoolInstrumentation, PoolName } from '../instrumentation.js';
6
+ import type { AttestationPool } from './attestation_pool.js';
7
+
8
+ export class InMemoryAttestationPool implements AttestationPool {
9
+ private metrics: PoolInstrumentation<BlockAttestation>;
10
+
11
+ private attestations: Map</*slot=*/ bigint, Map</*proposalId*/ string, Map</*address=*/ string, BlockAttestation>>>;
12
+
13
+ constructor(telemetry: TelemetryClient = getTelemetryClient(), private log = createLogger('p2p:attestation_pool')) {
14
+ this.attestations = new Map();
15
+ this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL);
16
+ }
17
+
18
+ public getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]> {
19
+ const slotAttestationMap = this.attestations.get(slot);
20
+ if (slotAttestationMap) {
21
+ const proposalAttestationMap = slotAttestationMap.get(proposalId);
22
+ if (proposalAttestationMap) {
23
+ return Promise.resolve(Array.from(proposalAttestationMap.values()));
24
+ }
25
+ }
26
+ return Promise.resolve([]);
27
+ }
28
+
29
+ public async addAttestations(attestations: BlockAttestation[]): Promise<void> {
30
+ for (const attestation of attestations) {
31
+ // Perf: order and group by slot before insertion
32
+ const slotNumber = attestation.payload.header.globalVariables.slotNumber;
33
+
34
+ const proposalId = attestation.archive.toString();
35
+ const address = await attestation.getSender();
36
+
37
+ const slotAttestationMap = getSlotOrDefault(this.attestations, slotNumber.toBigInt());
38
+ const proposalAttestationMap = getProposalOrDefault(slotAttestationMap, proposalId);
39
+ proposalAttestationMap.set(address.toString(), attestation);
40
+
41
+ this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`);
42
+ }
43
+
44
+ // TODO: set these to pending or something ????
45
+ this.metrics.recordAddedObjects(attestations.length);
46
+ return Promise.resolve();
47
+ }
48
+
49
+ #getNumberOfAttestationsInSlot(slot: bigint): number {
50
+ let total = 0;
51
+ const slotAttestationMap = getSlotOrDefault(this.attestations, slot);
52
+
53
+ if (slotAttestationMap) {
54
+ for (const proposalAttestationMap of slotAttestationMap.values() ?? []) {
55
+ total += proposalAttestationMap.size;
56
+ }
57
+ }
58
+ return total;
59
+ }
60
+
61
+ public async deleteAttestationsOlderThan(oldestSlot: bigint): Promise<void> {
62
+ const olderThan = [];
63
+
64
+ // Entries are iterated in insertion order, so we can break as soon as we find a slot that is older than the oldestSlot.
65
+ // Note: this will only prune correctly if attestations are added in order of rising slot, it is important that we do not allow
66
+ // insertion of attestations that are old. #(https://github.com/AztecProtocol/aztec-packages/issues/10322)
67
+ const slots = this.attestations.keys();
68
+ for (const slot of slots) {
69
+ if (slot < oldestSlot) {
70
+ olderThan.push(slot);
71
+ } else {
72
+ break;
73
+ }
74
+ }
75
+
76
+ for (const oldSlot of olderThan) {
77
+ await this.deleteAttestationsForSlot(oldSlot);
78
+ }
79
+ return Promise.resolve();
80
+ }
81
+
82
+ public deleteAttestationsForSlot(slot: bigint): Promise<void> {
83
+ // We count the number of attestations we are removing
84
+ const numberOfAttestations = this.#getNumberOfAttestationsInSlot(slot);
85
+
86
+ this.attestations.delete(slot);
87
+ this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
88
+
89
+ this.metrics.recordRemovedObjects(numberOfAttestations);
90
+ return Promise.resolve();
91
+ }
92
+
93
+ public deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void> {
94
+ const slotAttestationMap = getSlotOrDefault(this.attestations, slot);
95
+ if (slotAttestationMap) {
96
+ if (slotAttestationMap.has(proposalId)) {
97
+ const numberOfAttestations = slotAttestationMap.get(proposalId)?.size ?? 0;
98
+
99
+ slotAttestationMap.delete(proposalId);
100
+
101
+ this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
102
+ this.metrics.recordRemovedObjects(numberOfAttestations);
103
+ }
104
+ }
105
+ return Promise.resolve();
106
+ }
107
+
108
+ public async deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
109
+ for (const attestation of attestations) {
110
+ const slotNumber = attestation.payload.header.globalVariables.slotNumber;
111
+ const slotAttestationMap = this.attestations.get(slotNumber.toBigInt());
112
+ if (slotAttestationMap) {
113
+ const proposalId = attestation.archive.toString();
114
+ const proposalAttestationMap = getProposalOrDefault(slotAttestationMap, proposalId);
115
+ if (proposalAttestationMap) {
116
+ const address = await attestation.getSender();
117
+ proposalAttestationMap.delete(address.toString());
118
+ this.log.debug(`Deleted attestation for slot ${slotNumber} from ${address}`);
119
+ }
120
+ }
121
+ }
122
+ this.metrics.recordRemovedObjects(attestations.length);
123
+ return Promise.resolve();
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Get Slot or Default
129
+ *
130
+ * Fetch the slot mapping, if it does not exist, then create a mapping and return it
131
+ * @param map - The map to fetch from
132
+ * @param slot - The slot to fetch
133
+ * @returns The slot mapping
134
+ */
135
+ function getSlotOrDefault(
136
+ map: Map<bigint, Map<string, Map<string, BlockAttestation>>>,
137
+ slot: bigint,
138
+ ): Map<string, Map<string, BlockAttestation>> {
139
+ if (!map.has(slot)) {
140
+ map.set(slot, new Map<string, Map<string, BlockAttestation>>());
141
+ }
142
+ return map.get(slot)!;
143
+ }
144
+
145
+ /**
146
+ * Get Proposal or Default
147
+ *
148
+ * Fetch the proposal mapping, if it does not exist, then create a mapping and return it
149
+ * @param map - The map to fetch from
150
+ * @param proposalId - The proposal id to fetch
151
+ * @returns The proposal mapping
152
+ */
153
+ function getProposalOrDefault(
154
+ map: Map<string, Map<string, BlockAttestation>>,
155
+ proposalId: string,
156
+ ): Map<string, BlockAttestation> {
157
+ if (!map.has(proposalId)) {
158
+ map.set(proposalId, new Map<string, BlockAttestation>());
159
+ }
160
+ return map.get(proposalId)!;
161
+ }
@@ -0,0 +1,44 @@
1
+ import type { Secp256k1Signer } from '@aztec/foundation/crypto';
2
+ import { Fr } from '@aztec/foundation/fields';
3
+ import {
4
+ BlockAttestation,
5
+ ConsensusPayload,
6
+ SignatureDomainSeparator,
7
+ getHashedSignaturePayloadEthSignedMessage,
8
+ } from '@aztec/stdlib/p2p';
9
+ import { makeHeader } from '@aztec/stdlib/testing';
10
+ import { TxHash } from '@aztec/stdlib/tx';
11
+
12
+ import { type LocalAccount, generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
13
+
14
+ /** Generate Account
15
+ *
16
+ * Create a random signer
17
+ * @returns A random viem signer
18
+ */
19
+ export const generateAccount = (): LocalAccount => {
20
+ const privateKey = generatePrivateKey();
21
+ return privateKeyToAccount(privateKey);
22
+ };
23
+
24
+ /** Mock Attestation
25
+ *
26
+ * @param signer A viem signer to create a signature
27
+ * @param slot The slot number the attestation is for
28
+ * @returns A Block Attestation
29
+ */
30
+ export const mockAttestation = async (
31
+ signer: Secp256k1Signer,
32
+ slot: number = 0,
33
+ archive: Fr = Fr.random(),
34
+ txs: TxHash[] = [0, 1, 2, 3, 4, 5].map(() => TxHash.random()),
35
+ ): Promise<BlockAttestation> => {
36
+ // Use arbitrary numbers for all other than slot
37
+ const header = makeHeader(1, 2, slot);
38
+ const payload = new ConsensusPayload(header, archive, txs);
39
+
40
+ const hash = await getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
41
+ const signature = signer.sign(hash);
42
+
43
+ return new BlockAttestation(payload, signature);
44
+ };
@@ -0,0 +1,3 @@
1
+ export { type AttestationPool } from './attestation_pool/attestation_pool.js';
2
+ export { type MemPools } from './interface.js';
3
+ export { type TxPool } from './tx_pool/tx_pool.js';