@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,235 @@
1
+ import { filter, map, sort, take } from '@aztec/foundation/iterable';
2
+ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
3
+
4
+ import { type Batch, type Datastore, Key, type KeyQuery, type Pair, type Query } from 'interface-datastore';
5
+ import type { AwaitIterable } from 'interface-store';
6
+
7
+ type MemoryItem = {
8
+ lastAccessedMs: number;
9
+ data: Uint8Array;
10
+ };
11
+
12
+ type BatchOp = {
13
+ type: 'put' | 'del';
14
+ key: Key;
15
+ value?: Uint8Array;
16
+ };
17
+
18
+ class KeyNotFoundError extends Error {
19
+ code: string;
20
+ constructor(message: string) {
21
+ super(message);
22
+ this.code = 'ERR_NOT_FOUND';
23
+ }
24
+ }
25
+
26
+ export class AztecDatastore implements Datastore {
27
+ #memoryDatastore: Map<string, MemoryItem>;
28
+ #dbDatastore: AztecAsyncMap<string, Uint8Array>;
29
+
30
+ #batchOps: BatchOp[] = [];
31
+
32
+ private maxMemoryItems: number;
33
+
34
+ constructor(db: AztecAsyncKVStore, { maxMemoryItems } = { maxMemoryItems: 50 }) {
35
+ this.#memoryDatastore = new Map();
36
+ this.#dbDatastore = db.openMap('p2p_datastore');
37
+
38
+ this.maxMemoryItems = maxMemoryItems;
39
+ }
40
+
41
+ async has(key: Key): Promise<boolean> {
42
+ return this.#memoryDatastore.has(key.toString()) || (await this.#dbDatastore.hasAsync(key.toString()));
43
+ }
44
+
45
+ async get(key: Key): Promise<Uint8Array> {
46
+ const keyStr = key.toString();
47
+ const memoryItem = this.#memoryDatastore.get(keyStr);
48
+ if (memoryItem) {
49
+ memoryItem.lastAccessedMs = Date.now();
50
+ return memoryItem.data;
51
+ }
52
+ const dbItem = await this.#dbDatastore.getAsync(keyStr);
53
+
54
+ if (!dbItem) {
55
+ throw new KeyNotFoundError(`Key not found`);
56
+ }
57
+
58
+ return Uint8Array.from(dbItem);
59
+ }
60
+
61
+ put(key: Key, val: Uint8Array): Promise<Key> {
62
+ return this._put(key, val);
63
+ }
64
+
65
+ async *putMany(source: AwaitIterable<Pair>): AwaitIterable<Key> {
66
+ for await (const { key, value } of source) {
67
+ await this.put(key, value);
68
+ yield key;
69
+ }
70
+ }
71
+
72
+ async *getMany(source: AwaitIterable<Key>): AwaitIterable<Pair> {
73
+ for await (const key of source) {
74
+ yield {
75
+ key,
76
+ value: await this.get(key),
77
+ };
78
+ }
79
+ }
80
+
81
+ async *deleteMany(source: AwaitIterable<Key>): AwaitIterable<Key> {
82
+ for await (const key of source) {
83
+ await this.delete(key);
84
+ yield key;
85
+ }
86
+ }
87
+
88
+ async delete(key: Key): Promise<void> {
89
+ this.#memoryDatastore.delete(key.toString());
90
+ await this.#dbDatastore.delete(key.toString());
91
+ }
92
+
93
+ batch(): Batch {
94
+ return {
95
+ put: (key, value) => {
96
+ this.#batchOps.push({
97
+ type: 'put',
98
+ key,
99
+ value,
100
+ });
101
+ },
102
+ delete: key => {
103
+ this.#batchOps.push({
104
+ type: 'del',
105
+ key,
106
+ });
107
+ },
108
+ commit: async () => {
109
+ for (const op of this.#batchOps) {
110
+ if (op.type === 'put' && op.value) {
111
+ await this.put(op.key, op.value);
112
+ } else if (op.type === 'del') {
113
+ await this.delete(op.key);
114
+ }
115
+ }
116
+ this.#batchOps = []; // Clear operations after commit
117
+ },
118
+ };
119
+ }
120
+
121
+ query(q: Query): AwaitIterable<Pair> {
122
+ let it = this.all(); //
123
+ const { prefix, filters, orders, offset, limit } = q;
124
+
125
+ if (prefix != null) {
126
+ it = filter(it, e => e.key.toString().startsWith(`${prefix}`));
127
+ }
128
+
129
+ if (Array.isArray(filters)) {
130
+ it = filters.reduce((it, f) => filter(it, f), it);
131
+ }
132
+
133
+ if (Array.isArray(orders)) {
134
+ it = orders.reduce((it, f) => sort(it, f), it);
135
+ }
136
+
137
+ if (offset != null) {
138
+ let i = 0;
139
+ it = filter(it, () => i++ >= offset);
140
+ }
141
+
142
+ if (limit != null) {
143
+ it = take(it, limit);
144
+ }
145
+
146
+ return it;
147
+ }
148
+
149
+ queryKeys(q: KeyQuery): AsyncIterable<Key> {
150
+ let it = map(this.all(), ({ key }) => key);
151
+ const { prefix, filters, orders, offset, limit } = q;
152
+ if (prefix != null) {
153
+ it = filter(it, e => e.toString().startsWith(`${prefix}`));
154
+ }
155
+
156
+ if (Array.isArray(filters)) {
157
+ it = filters.reduce((it, f) => filter(it, f), it);
158
+ }
159
+
160
+ if (Array.isArray(orders)) {
161
+ it = orders.reduce((it, f) => sort(it, f), it);
162
+ }
163
+
164
+ if (offset != null) {
165
+ let i = 0;
166
+ it = filter(it, () => i++ >= offset);
167
+ }
168
+
169
+ if (limit != null) {
170
+ it = take(it, limit);
171
+ }
172
+
173
+ return it;
174
+ }
175
+
176
+ private async _put(key: Key, val: Uint8Array): Promise<Key> {
177
+ const keyStr = key.toString();
178
+ while (this.#memoryDatastore.size >= this.maxMemoryItems) {
179
+ this.pruneMemoryDatastore();
180
+ }
181
+ const memoryItem = this.#memoryDatastore.get(keyStr);
182
+ if (memoryItem) {
183
+ // update existing
184
+ memoryItem.lastAccessedMs = Date.now();
185
+ memoryItem.data = val;
186
+ } else {
187
+ // new entry
188
+ this.#memoryDatastore.set(keyStr, { data: val, lastAccessedMs: Date.now() });
189
+ }
190
+
191
+ // Always add to DB
192
+ await this.#dbDatastore.set(keyStr, val);
193
+
194
+ return key;
195
+ }
196
+
197
+ private async *all(): AsyncIterable<Pair> {
198
+ for (const [key, value] of this.#memoryDatastore.entries()) {
199
+ yield {
200
+ key: new Key(key),
201
+ value: value.data,
202
+ };
203
+ }
204
+
205
+ for await (const [key, value] of this.#dbDatastore.entriesAsync()) {
206
+ if (!this.#memoryDatastore.has(key)) {
207
+ yield {
208
+ key: new Key(key),
209
+ value,
210
+ };
211
+ }
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Prune memory store
217
+ */
218
+ private pruneMemoryDatastore(): void {
219
+ let oldestAccessedMs = Date.now() + 1000;
220
+ let oldestKey: string | undefined = undefined;
221
+ let oldestValue: Uint8Array | undefined = undefined;
222
+
223
+ for (const [key, value] of this.#memoryDatastore) {
224
+ if (value.lastAccessedMs < oldestAccessedMs) {
225
+ oldestAccessedMs = value.lastAccessedMs;
226
+ oldestKey = key;
227
+ oldestValue = value.data;
228
+ }
229
+ }
230
+
231
+ if (oldestKey && oldestValue) {
232
+ this.#memoryDatastore.delete(oldestKey);
233
+ }
234
+ }
235
+ }
@@ -0,0 +1,256 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import { sleep } from '@aztec/foundation/sleep';
3
+ import { type ComponentsVersions, checkCompressedComponentVersion } from '@aztec/stdlib/versioning';
4
+ import { OtelMetricsAdapter, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
5
+
6
+ import { Discv5, type Discv5EventEmitter } from '@chainsafe/discv5';
7
+ import { ENR, SignableENR } from '@chainsafe/enr';
8
+ import type { PeerId } from '@libp2p/interface';
9
+ import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
10
+ import EventEmitter from 'events';
11
+
12
+ import type { P2PConfig } from '../../config.js';
13
+ import { AZTEC_ENR_KEY, Discv5Event, PeerEvent } from '../../types/index.js';
14
+ import { convertToMultiaddr } from '../../util.js';
15
+ import { setAztecEnrKey } from '../../versioning.js';
16
+ import { type PeerDiscoveryService, PeerDiscoveryState } from '../service.js';
17
+
18
+ const delayBeforeStart = 2000; // 2sec
19
+
20
+ /**
21
+ * Peer discovery service using Discv5.
22
+ */
23
+ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService {
24
+ /** The Discv5 instance */
25
+ private discv5: Discv5 & Discv5EventEmitter;
26
+
27
+ /** This instance's ENR */
28
+ private enr: SignableENR;
29
+
30
+ /** Version identifiers. */
31
+ private versions: ComponentsVersions;
32
+
33
+ /** UDP listen addr */
34
+ private listenMultiAddrUdp: Multiaddr;
35
+
36
+ private currentState = PeerDiscoveryState.STOPPED;
37
+
38
+ public readonly bootstrapNodes: string[] = [];
39
+ private bootstrapNodePeerIds: PeerId[] = [];
40
+ private bootstrapNodeEnrs: ENR[] = [];
41
+
42
+ private startTime = 0;
43
+
44
+ constructor(
45
+ private peerId: PeerId,
46
+ private config: P2PConfig,
47
+ telemetry: TelemetryClient = getTelemetryClient(),
48
+ private logger = createLogger('p2p:discv5_service'),
49
+ ) {
50
+ super();
51
+ const { tcpAnnounceAddress, udpAnnounceAddress, udpListenAddress, bootstrapNodes } = config;
52
+ this.bootstrapNodes = bootstrapNodes ?? [];
53
+ this.bootstrapNodeEnrs = this.bootstrapNodes.map(x => ENR.decodeTxt(x));
54
+ // create ENR from PeerId
55
+ this.enr = SignableENR.createFromPeerId(peerId);
56
+ // Add aztec identification to ENR
57
+ this.versions = setAztecEnrKey(this.enr, config);
58
+
59
+ if (!tcpAnnounceAddress) {
60
+ throw new Error('You need to provide at least a TCP announce address.');
61
+ }
62
+
63
+ const multiAddrTcp = multiaddr(`${convertToMultiaddr(tcpAnnounceAddress, 'tcp')}/p2p/${peerId.toString()}`);
64
+ // if no udp announce address is provided, use the tcp announce address
65
+ const multiAddrUdp = multiaddr(
66
+ `${convertToMultiaddr(udpAnnounceAddress || tcpAnnounceAddress, 'udp')}/p2p/${peerId.toString()}`,
67
+ );
68
+
69
+ this.listenMultiAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
70
+
71
+ // set location multiaddr in ENR record
72
+ this.enr.setLocationMultiaddr(multiAddrUdp);
73
+ this.enr.setLocationMultiaddr(multiAddrTcp);
74
+
75
+ const metricsRegistry = new OtelMetricsAdapter(telemetry);
76
+ this.discv5 = Discv5.create({
77
+ enr: this.enr,
78
+ peerId,
79
+ bindAddrs: { ip4: this.listenMultiAddrUdp },
80
+ config: {
81
+ lookupTimeout: 2000,
82
+ requestTimeout: 2000,
83
+ allowUnverifiedSessions: true,
84
+ },
85
+ metricsRegistry,
86
+ });
87
+
88
+ // Hook onto the onEstablished method to check the peer's version from the ENR,
89
+ // so we don't add it to our dht if it doesn't have the correct version.
90
+ // In addition, we'll hook onto onDiscovered to to repeat the same check there,
91
+ // just in case. Note that not adding the peer to the dht could lead to it
92
+ // being "readded" constantly, we'll need to keep an eye on whether this
93
+ // turns out to be a problem or not.
94
+ const origOnEstablished = this.discv5.onEstablished.bind(this.discv5);
95
+ this.discv5.onEstablished = (...args: unknown[]) => {
96
+ const enr = args[1] as ENR;
97
+ // A special case is for bootnodes. If this is a bootnode and we have been told to skip version checks
98
+ // then proceed straight to handling the event
99
+ if (!this.config.bootstrapNodeEnrVersionCheck && this.isOurBootnode(enr)) {
100
+ return origOnEstablished(...args);
101
+ }
102
+ if (this.validateEnr(enr)) {
103
+ return origOnEstablished(...args);
104
+ }
105
+ };
106
+
107
+ this.discv5.on(Discv5Event.DISCOVERED, this.onDiscovered.bind(this));
108
+ this.discv5.on(Discv5Event.ENR_ADDED, this.onEnrAdded.bind(this));
109
+ }
110
+
111
+ public async start(): Promise<void> {
112
+ if (this.currentState === PeerDiscoveryState.RUNNING) {
113
+ throw new Error('DiscV5Service already started');
114
+ }
115
+ this.logger.debug('Starting DiscV5');
116
+ await this.discv5.start();
117
+ this.startTime = Date.now();
118
+
119
+ this.logger.info(`DiscV5 service started`, {
120
+ nodeId: this.enr.nodeId,
121
+ peerId: this.peerId,
122
+ enrUdp: await this.enr.getFullMultiaddr('udp'),
123
+ enrTcp: await this.enr.getFullMultiaddr('tcp'),
124
+ versions: this.versions,
125
+ });
126
+ this.currentState = PeerDiscoveryState.RUNNING;
127
+
128
+ // Add bootnode ENR if provided
129
+ if (this.bootstrapNodes?.length) {
130
+ // Do this conversion once since it involves an async function call
131
+ this.bootstrapNodePeerIds = await Promise.all(this.bootstrapNodeEnrs.map(enr => enr.peerId()));
132
+ this.logger.info(`Adding ${this.bootstrapNodes} bootstrap nodes ENRs: ${this.bootstrapNodes.join(', ')}`);
133
+ for (const enr of this.bootstrapNodeEnrs) {
134
+ try {
135
+ if (this.config.bootstrapNodeEnrVersionCheck) {
136
+ const value = enr.kvs.get(AZTEC_ENR_KEY);
137
+ if (!value) {
138
+ throw new Error('ENR does not contain aztec key');
139
+ }
140
+ checkCompressedComponentVersion(Buffer.from(value).toString(), this.versions);
141
+ }
142
+ this.discv5.addEnr(enr);
143
+ } catch (e) {
144
+ this.logger.error(`Error adding bootratrap node ${enr.encodeTxt()}`, e);
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ public async runRandomNodesQuery(): Promise<void> {
151
+ if (this.currentState !== PeerDiscoveryState.RUNNING) {
152
+ throw new Error('DiscV5Service not running');
153
+ }
154
+
155
+ // First, wait some time before starting the peer discovery
156
+ // reference: https://github.com/ChainSafe/lodestar/issues/3423
157
+ const msSinceStart = Date.now() - this.startTime;
158
+ if (Date.now() - this.startTime <= delayBeforeStart) {
159
+ await sleep(delayBeforeStart - msSinceStart);
160
+ }
161
+
162
+ try {
163
+ await this.discv5.findRandomNode();
164
+ } catch (err) {
165
+ this.logger.error(`Error running discV5 random node query: ${err}`);
166
+ }
167
+ }
168
+
169
+ public getAllPeers(): ENR[] {
170
+ return this.discv5.kadValues();
171
+ }
172
+
173
+ public getEnr(): ENR {
174
+ return this.enr.toENR();
175
+ }
176
+
177
+ public getPeerId(): PeerId {
178
+ return this.peerId;
179
+ }
180
+
181
+ public getStatus(): PeerDiscoveryState {
182
+ return this.currentState;
183
+ }
184
+
185
+ public isBootstrapPeer(peerId: PeerId): boolean {
186
+ return this.bootstrapNodePeerIds.some(node => node.equals(peerId));
187
+ }
188
+
189
+ public async stop(): Promise<void> {
190
+ await this.discv5.off(Discv5Event.DISCOVERED, this.onDiscovered);
191
+ await this.discv5.off(Discv5Event.ENR_ADDED, this.onEnrAdded);
192
+
193
+ await this.discv5.stop();
194
+
195
+ this.currentState = PeerDiscoveryState.STOPPED;
196
+ }
197
+
198
+ private async onEnrAdded(enr: ENR) {
199
+ const multiAddrTcp = await enr.getFullMultiaddr('tcp');
200
+ const multiAddrUdp = await enr.getFullMultiaddr('udp');
201
+ this.logger.debug(`Added ENR ${enr.encodeTxt()}`, { multiAddrTcp, multiAddrUdp, nodeId: enr.nodeId });
202
+ this.onDiscovered(enr);
203
+ }
204
+
205
+ private isOurBootnode(enr: ENR) {
206
+ return this.bootstrapNodeEnrs.some(x => x.nodeId === enr.nodeId);
207
+ }
208
+
209
+ private onDiscovered(enr: ENR) {
210
+ // Find out if this is one of our bootnodes
211
+ if (this.isOurBootnode(enr)) {
212
+ // it is, what we do here depends
213
+ if (!this.config.bootstrapNodesAsFullPeers) {
214
+ // we don't consider bootnodes as full peers, don't perform any checks and don't emit anything
215
+ return;
216
+ }
217
+ if (!this.config.bootstrapNodeEnrVersionCheck) {
218
+ // we do consider bootnodes to be full peers and we have been told to NOT version check them, so emit
219
+ this.logger.trace(`Skipping version check for bootnode ${enr.nodeId}`);
220
+ this.emit(PeerEvent.DISCOVERED, enr);
221
+ return;
222
+ }
223
+ // here, we do consider bootnodes as full peers and we must version check so we continue to regular validation
224
+ }
225
+ if (this.validateEnr(enr)) {
226
+ this.emit(PeerEvent.DISCOVERED, enr);
227
+ }
228
+ }
229
+
230
+ private validateEnr(enr: ENR): boolean {
231
+ // Check the peer is an aztec peer
232
+ const value = enr.kvs.get(AZTEC_ENR_KEY);
233
+ if (!value) {
234
+ this.logger.warn(`Peer node ${enr.nodeId} does not have aztec key in ENR`);
235
+ return false;
236
+ }
237
+
238
+ // And check it has the correct version
239
+ let compressedVersion;
240
+ try {
241
+ compressedVersion = Buffer.from(value).toString();
242
+ checkCompressedComponentVersion(compressedVersion, this.versions);
243
+ return true;
244
+ } catch (err: any) {
245
+ if (err.name === 'ComponentsVersionsError') {
246
+ this.logger.debug(`Peer node ${enr.nodeId} has incorrect version: ${err.message}`, {
247
+ compressedVersion,
248
+ expected: this.versions,
249
+ });
250
+ } else {
251
+ this.logger.error(`Error checking peer version`, err);
252
+ }
253
+ }
254
+ return false;
255
+ }
256
+ }
@@ -0,0 +1,134 @@
1
+ import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
2
+ import type { BlockAttestation, BlockProposal, Gossipable } from '@aztec/stdlib/p2p';
3
+ import { TxHash } from '@aztec/stdlib/tx';
4
+
5
+ import type { PeerId } from '@libp2p/interface';
6
+ import EventEmitter from 'events';
7
+
8
+ import type { ReqRespSubProtocol, SubProtocolMap } from './reqresp/interface.js';
9
+ import { type P2PService, type PeerDiscoveryService, PeerDiscoveryState } from './service.js';
10
+
11
+ /**
12
+ * A dummy implementation of the P2P Service.
13
+ */
14
+ export class DummyP2PService implements P2PService {
15
+ /** Returns an empty array for peers. */
16
+ getPeers(): PeerInfo[] {
17
+ return [];
18
+ }
19
+
20
+ /**
21
+ * Starts the dummy implementation.
22
+ * @returns A resolved promise.
23
+ */
24
+ public start() {
25
+ return Promise.resolve();
26
+ }
27
+
28
+ /**
29
+ * Stops the dummy implementation.
30
+ * @returns A resolved promise.
31
+ */
32
+ public stop() {
33
+ return Promise.resolve();
34
+ }
35
+
36
+ /**
37
+ * Called to have the given message propagated through the P2P network.
38
+ * @param _ - The message to be propagated.
39
+ */
40
+ public propagate<T extends Gossipable>(_: T) {}
41
+
42
+ /**
43
+ * Called upon receipt of settled transactions.
44
+ * @param _ - The hashes of the settled transactions.
45
+ */
46
+ public settledTxs(_: TxHash[]) {}
47
+
48
+ /**
49
+ * Register a callback into the validator client for when a block proposal is received
50
+ */
51
+ public registerBlockReceivedCallback(_: (block: BlockProposal) => Promise<BlockAttestation>) {}
52
+
53
+ /**
54
+ * Sends a request to a peer.
55
+ * @param _protocol - The protocol to send the request on.
56
+ * @param _request - The request to send.
57
+ * @returns The response from the peer, otherwise undefined.
58
+ */
59
+ public sendRequest<Protocol extends ReqRespSubProtocol>(
60
+ _protocol: Protocol,
61
+ _request: InstanceType<SubProtocolMap[Protocol]['request']>,
62
+ ): Promise<InstanceType<SubProtocolMap[Protocol]['response']> | undefined> {
63
+ return Promise.resolve(undefined);
64
+ }
65
+
66
+ /**
67
+ * Sends a batch request to a peer.
68
+ * @param _protocol - The protocol to send the request on.
69
+ * @param _requests - The requests to send.
70
+ * @returns The responses from the peer, otherwise undefined.
71
+ */
72
+ public sendBatchRequest<Protocol extends ReqRespSubProtocol>(
73
+ _protocol: Protocol,
74
+ _requests: InstanceType<SubProtocolMap[Protocol]['request']>[],
75
+ ): Promise<InstanceType<SubProtocolMap[Protocol]['response']>[]> {
76
+ return Promise.resolve([]);
77
+ }
78
+
79
+ /**
80
+ * Returns the ENR of the peer.
81
+ * @returns The ENR of the peer, otherwise undefined.
82
+ */
83
+ public getEnr(): undefined {
84
+ return undefined;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * A dummy implementation of the Peer Discovery Service.
90
+ */
91
+ export class DummyPeerDiscoveryService extends EventEmitter implements PeerDiscoveryService {
92
+ private currentState = PeerDiscoveryState.STOPPED;
93
+ public bootstrapNodes: string[] = [];
94
+
95
+ /**
96
+ * Starts the dummy implementation.
97
+ * @returns A resolved promise.
98
+ */
99
+ public start() {
100
+ this.currentState = PeerDiscoveryState.RUNNING;
101
+ return Promise.resolve();
102
+ }
103
+ /**
104
+ * Stops the dummy implementation.
105
+ * @returns A resolved promise.
106
+ */
107
+ public stop() {
108
+ this.currentState = PeerDiscoveryState.STOPPED;
109
+ return Promise.resolve();
110
+ }
111
+ /**
112
+ * Called to discover peers in the network.
113
+ * @returns An array of discovered peer addresses.
114
+ */
115
+ public getAllPeers() {
116
+ return [];
117
+ }
118
+
119
+ public runRandomNodesQuery(): Promise<void> {
120
+ return Promise.resolve();
121
+ }
122
+
123
+ public isBootstrapPeer(_: PeerId): boolean {
124
+ return false;
125
+ }
126
+
127
+ public getStatus(): PeerDiscoveryState {
128
+ return this.currentState;
129
+ }
130
+
131
+ public getEnr(): undefined {
132
+ return undefined;
133
+ }
134
+ }
@@ -0,0 +1,79 @@
1
+ // Taken from lodestar: https://github.com/ChainSafe/lodestar
2
+ import { sha256 } from '@aztec/foundation/crypto';
3
+
4
+ import type { RPC } from '@chainsafe/libp2p-gossipsub/message';
5
+ import type { DataTransform } from '@chainsafe/libp2p-gossipsub/types';
6
+ import type { Message } from '@libp2p/interface';
7
+ import { compressSync, uncompressSync } from 'snappy';
8
+ import xxhashFactory from 'xxhash-wasm';
9
+
10
+ // Load WASM
11
+ const xxhash = await xxhashFactory();
12
+
13
+ // Use salt to prevent msgId from being mined for collisions
14
+ const h64Seed = BigInt(Math.floor(Math.random() * 1e9));
15
+
16
+ // Shared buffer to convert msgId to string
17
+ const sharedMsgIdBuf = Buffer.alloc(20);
18
+
19
+ /**
20
+ * The function used to generate a gossipsub message id
21
+ * We use the first 8 bytes of SHA256(data) for content addressing
22
+ */
23
+ export function fastMsgIdFn(rpcMsg: RPC.Message): string {
24
+ if (rpcMsg.data) {
25
+ return xxhash.h64Raw(rpcMsg.data, h64Seed).toString(16);
26
+ }
27
+ return '0000000000000000';
28
+ }
29
+
30
+ export function msgIdToStrFn(msgId: Uint8Array): string {
31
+ // This happens serially, no need to reallocate the buffer
32
+ sharedMsgIdBuf.set(msgId);
33
+ return `0x${sharedMsgIdBuf.toString('hex')}`;
34
+ }
35
+
36
+ /**
37
+ * Get the message identifier from a libp2p message
38
+ *
39
+ * Follows similarly to:
40
+ * https://github.com/ethereum/consensus-specs/blob/v1.1.0-alpha.7/specs/altair/p2p-interface.md#topics-and-messages
41
+ *
42
+ * @param message - The libp2p message
43
+ * @returns The message identifier
44
+ */
45
+ export function getMsgIdFn(message: Message) {
46
+ const { topic } = message;
47
+
48
+ const vec = [Buffer.from(topic), message.data];
49
+ return sha256(Buffer.concat(vec)).subarray(0, 20);
50
+ }
51
+
52
+ /**
53
+ * Snappy transform for libp2p gossipsub
54
+ */
55
+ export class SnappyTransform implements DataTransform {
56
+ // Topic string included to satisfy DataTransform interface
57
+ inboundTransform(_topicStr: string, data: Uint8Array): Uint8Array {
58
+ return this.inboundTransformNoTopic(Buffer.from(data));
59
+ }
60
+
61
+ public inboundTransformNoTopic(data: Buffer): Buffer {
62
+ if (data.length === 0) {
63
+ return data;
64
+ }
65
+ return Buffer.from(uncompressSync(data, { asBuffer: true }));
66
+ }
67
+
68
+ // Topic string included to satisfy DataTransform interface
69
+ outboundTransform(_topicStr: string, data: Uint8Array): Uint8Array {
70
+ return this.outboundTransformNoTopic(Buffer.from(data));
71
+ }
72
+
73
+ public outboundTransformNoTopic(data: Buffer): Buffer {
74
+ if (data.length === 0) {
75
+ return data;
76
+ }
77
+ return Buffer.from(compressSync(data));
78
+ }
79
+ }