@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,86 @@
1
+ import { median } from '@aztec/foundation/collection';
2
+ import { createLogger } from '@aztec/foundation/log';
3
+ import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
4
+ const DefaultPeerPenalties = {
5
+ [PeerErrorSeverity.LowToleranceError]: 50,
6
+ [PeerErrorSeverity.MidToleranceError]: 10,
7
+ [PeerErrorSeverity.HighToleranceError]: 2
8
+ };
9
+ export var PeerScoreState = /*#__PURE__*/ function(PeerScoreState) {
10
+ PeerScoreState[PeerScoreState["Banned"] = 0] = "Banned";
11
+ PeerScoreState[PeerScoreState["Disconnect"] = 1] = "Disconnect";
12
+ PeerScoreState[PeerScoreState["Healthy"] = 2] = "Healthy";
13
+ return PeerScoreState;
14
+ }({});
15
+ // TODO: move into config / constants
16
+ const MIN_SCORE_BEFORE_BAN = -100;
17
+ const MIN_SCORE_BEFORE_DISCONNECT = -50;
18
+ export class PeerScoring {
19
+ logger = createLogger('p2p:peer-scoring');
20
+ scores = new Map();
21
+ lastUpdateTime = new Map();
22
+ decayInterval = 1000 * 60;
23
+ decayFactor = 0.9;
24
+ peerPenalties;
25
+ constructor(config){
26
+ const orderedValues = config.peerPenaltyValues?.sort((a, b)=>a - b);
27
+ this.peerPenalties = {
28
+ [PeerErrorSeverity.HighToleranceError]: orderedValues?.[0] ?? DefaultPeerPenalties[PeerErrorSeverity.HighToleranceError],
29
+ [PeerErrorSeverity.MidToleranceError]: orderedValues?.[1] ?? DefaultPeerPenalties[PeerErrorSeverity.MidToleranceError],
30
+ [PeerErrorSeverity.LowToleranceError]: orderedValues?.[2] ?? DefaultPeerPenalties[PeerErrorSeverity.LowToleranceError]
31
+ };
32
+ }
33
+ penalizePeer(peerId, penalty) {
34
+ const id = peerId.toString();
35
+ const penaltyValue = this.peerPenalties[penalty];
36
+ const newScore = this.updateScore(id, -penaltyValue);
37
+ this.logger.verbose(`Penalizing peer ${id} with ${penalty} (new score is ${newScore})`);
38
+ return newScore;
39
+ }
40
+ updateScore(peerId, scoreDelta) {
41
+ const currentTime = Date.now();
42
+ const lastUpdate = this.lastUpdateTime.get(peerId) || currentTime;
43
+ const timePassed = currentTime - lastUpdate;
44
+ const decayPeriods = Math.floor(timePassed / this.decayInterval);
45
+ let currentScore = this.scores.get(peerId) || 0;
46
+ // Apply decay
47
+ currentScore *= Math.pow(this.decayFactor, decayPeriods);
48
+ // Apply new score delta
49
+ currentScore += scoreDelta;
50
+ this.scores.set(peerId, currentScore);
51
+ this.lastUpdateTime.set(peerId, currentTime);
52
+ return currentScore;
53
+ }
54
+ decayAllScores() {
55
+ const currentTime = Date.now();
56
+ for (const [peerId, lastUpdate] of this.lastUpdateTime.entries()){
57
+ const timePassed = currentTime - lastUpdate;
58
+ const decayPeriods = Math.floor(timePassed / this.decayInterval);
59
+ if (decayPeriods > 0) {
60
+ let score = this.scores.get(peerId) || 0;
61
+ score *= Math.pow(this.decayFactor, decayPeriods);
62
+ this.scores.set(peerId, score);
63
+ this.lastUpdateTime.set(peerId, currentTime);
64
+ }
65
+ }
66
+ }
67
+ getScore(peerId) {
68
+ return this.scores.get(peerId) || 0;
69
+ }
70
+ getScoreState(peerId) {
71
+ // TODO(#11329): permanently store banned peers?
72
+ const score = this.getScore(peerId);
73
+ if (score < MIN_SCORE_BEFORE_BAN) {
74
+ return 0;
75
+ }
76
+ if (score < MIN_SCORE_BEFORE_DISCONNECT) {
77
+ return 1;
78
+ }
79
+ return 2;
80
+ }
81
+ getStats() {
82
+ return {
83
+ medianScore: median(Array.from(this.scores.values())) ?? 0
84
+ };
85
+ }
86
+ }
@@ -0,0 +1,16 @@
1
+ import { type ConfigMapping } from '@aztec/foundation/config';
2
+ export declare const DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS = 2000;
3
+ export declare const DEFAULT_OVERALL_REQUEST_TIMEOUT_MS = 4000;
4
+ export declare const DEFAULT_P2P_REQRESP_CONFIG: P2PReqRespConfig;
5
+ export interface P2PReqRespConfig {
6
+ /**
7
+ * The overall timeout for a request response operation.
8
+ */
9
+ overallRequestTimeoutMs: number;
10
+ /**
11
+ * The timeout for an individual request response peer interaction.
12
+ */
13
+ individualRequestTimeoutMs: number;
14
+ }
15
+ export declare const p2pReqRespConfigMappings: Record<keyof P2PReqRespConfig, ConfigMapping>;
16
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,0BAA0B,CAAC;AAElF,eAAO,MAAM,qCAAqC,OAAO,CAAC;AAC1D,eAAO,MAAM,kCAAkC,OAAO,CAAC;AAGvD,eAAO,MAAM,0BAA0B,EAAE,gBAGxC,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,gBAAgB,EAAE,aAAa,CAWlF,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { numberConfigHelper } from '@aztec/foundation/config';
2
+ export const DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS = 2000;
3
+ export const DEFAULT_OVERALL_REQUEST_TIMEOUT_MS = 4000;
4
+ // For use in tests.
5
+ export const DEFAULT_P2P_REQRESP_CONFIG = {
6
+ overallRequestTimeoutMs: DEFAULT_OVERALL_REQUEST_TIMEOUT_MS,
7
+ individualRequestTimeoutMs: DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS
8
+ };
9
+ export const p2pReqRespConfigMappings = {
10
+ overallRequestTimeoutMs: {
11
+ env: 'P2P_REQRESP_OVERALL_REQUEST_TIMEOUT_MS',
12
+ description: 'The overall timeout for a request response operation.',
13
+ ...numberConfigHelper(DEFAULT_OVERALL_REQUEST_TIMEOUT_MS)
14
+ },
15
+ individualRequestTimeoutMs: {
16
+ env: 'P2P_REQRESP_INDIVIDUAL_REQUEST_TIMEOUT_MS',
17
+ description: 'The timeout for an individual request response peer interaction.',
18
+ ...numberConfigHelper(DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS)
19
+ }
20
+ };
@@ -0,0 +1,45 @@
1
+ import type { PeerId } from '@libp2p/interface';
2
+ import type { ConnectionSampler } from './connection_sampler.js';
3
+ /**
4
+ * Manages batches of peers for parallel request processing.
5
+ * Tracks active peers and provides deterministic peer assignment for requests.
6
+ *
7
+ * Example with 3 peers and 10 requests:
8
+ *
9
+ * Peers: [P1] [P2] [P3]
10
+ * ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
11
+ * Requests: 0,1,2,9 | 3,4,5 | 6,7,8
12
+ *
13
+ * Each peer handles a bucket of consecutive requests.
14
+ * If a peer fails, it is replaced while maintaining the same bucket.
15
+ */
16
+ export declare class BatchConnectionSampler {
17
+ private readonly connectionSampler;
18
+ private readonly logger;
19
+ private readonly batch;
20
+ private readonly requestsPerPeer;
21
+ constructor(connectionSampler: ConnectionSampler, batchSize: number, maxPeers: number);
22
+ /**
23
+ * Gets the peer responsible for handling a specific request index
24
+ *
25
+ * @param index - The request index
26
+ * @returns The peer assigned to handle this request
27
+ */
28
+ getPeerForRequest(index: number): PeerId | undefined;
29
+ /**
30
+ * Removes a peer and replaces it with a new one, maintaining the same position
31
+ * in the batch array to keep request distribution consistent
32
+ *
33
+ * @param peerId - The peer to remove and replace
34
+ */
35
+ removePeerAndReplace(peerId: PeerId): void;
36
+ /**
37
+ * Gets the number of active peers
38
+ */
39
+ get activePeerCount(): number;
40
+ /**
41
+ * Gets the number of requests each peer is assigned to handle
42
+ */
43
+ get requestsPerBucket(): number;
44
+ }
45
+ //# sourceMappingURL=batch_connection_sampler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch_connection_sampler.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/connection-sampler/batch_connection_sampler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;;;;;;;;;GAYG;AACH,qBAAa,sBAAsB;IAKrB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAJ9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwD;IAC/E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAEZ,iBAAiB,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAetG;;;;;OAKG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAUpD;;;;;OAKG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAmB1C;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,MAAM,CAE9B;CACF"}
@@ -0,0 +1,88 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ /**
3
+ * Manages batches of peers for parallel request processing.
4
+ * Tracks active peers and provides deterministic peer assignment for requests.
5
+ *
6
+ * Example with 3 peers and 10 requests:
7
+ *
8
+ * Peers: [P1] [P2] [P3]
9
+ * ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
10
+ * Requests: 0,1,2,9 | 3,4,5 | 6,7,8
11
+ *
12
+ * Each peer handles a bucket of consecutive requests.
13
+ * If a peer fails, it is replaced while maintaining the same bucket.
14
+ */ export class BatchConnectionSampler {
15
+ connectionSampler;
16
+ logger;
17
+ batch;
18
+ requestsPerPeer;
19
+ constructor(connectionSampler, batchSize, maxPeers){
20
+ this.connectionSampler = connectionSampler;
21
+ this.logger = createLogger('p2p:reqresp:batch-connection-sampler');
22
+ this.batch = [];
23
+ if (maxPeers <= 0) {
24
+ throw new Error('Max peers cannot be 0');
25
+ }
26
+ if (batchSize <= 0) {
27
+ throw new Error('Batch size cannot be 0');
28
+ }
29
+ // Calculate how many requests each peer should handle, cannot be 0
30
+ this.requestsPerPeer = Math.max(1, Math.floor(batchSize / maxPeers));
31
+ // Sample initial peers
32
+ this.batch = this.connectionSampler.samplePeersBatch(maxPeers);
33
+ }
34
+ /**
35
+ * Gets the peer responsible for handling a specific request index
36
+ *
37
+ * @param index - The request index
38
+ * @returns The peer assigned to handle this request
39
+ */ getPeerForRequest(index) {
40
+ if (this.batch.length === 0) {
41
+ return undefined;
42
+ }
43
+ // Calculate which peer bucket this index belongs to
44
+ const peerIndex = Math.floor(index / this.requestsPerPeer) % this.batch.length;
45
+ return this.batch[peerIndex];
46
+ }
47
+ /**
48
+ * Removes a peer and replaces it with a new one, maintaining the same position
49
+ * in the batch array to keep request distribution consistent
50
+ *
51
+ * @param peerId - The peer to remove and replace
52
+ */ removePeerAndReplace(peerId) {
53
+ const index = this.batch.findIndex((p)=>p === peerId);
54
+ if (index === -1) {
55
+ return;
56
+ }
57
+ const excluding = new Map([
58
+ [
59
+ peerId.toString(),
60
+ true
61
+ ]
62
+ ]);
63
+ const newPeer = this.connectionSampler.getPeer(excluding);
64
+ if (newPeer) {
65
+ this.batch[index] = newPeer;
66
+ this.logger.trace(`Replaced peer ${peerId} with ${newPeer}`, {
67
+ peerId,
68
+ newPeer
69
+ });
70
+ } else {
71
+ // If we couldn't get a replacement, remove the peer and compact the array
72
+ this.batch.splice(index, 1);
73
+ this.logger.trace(`Removed peer ${peerId}`, {
74
+ peerId
75
+ });
76
+ }
77
+ }
78
+ /**
79
+ * Gets the number of active peers
80
+ */ get activePeerCount() {
81
+ return this.batch.length;
82
+ }
83
+ /**
84
+ * Gets the number of requests each peer is assigned to handle
85
+ */ get requestsPerBucket() {
86
+ return this.requestsPerPeer;
87
+ }
88
+ }
@@ -0,0 +1,61 @@
1
+ import type { Libp2p, PeerId, Stream } from '@libp2p/interface';
2
+ export declare class RandomSampler {
3
+ random(max: number): number;
4
+ }
5
+ /**
6
+ * A class that samples peers from the libp2p node and returns a peer that we don't already have a connection open to.
7
+ * If we already have a connection open, we try to sample a different peer.
8
+ * We do this MAX_SAMPLE_ATTEMPTS times, if we still don't find a peer we just go for it.
9
+ *
10
+ * @dev Close must always be called on connections, else memory leak
11
+ */
12
+ export declare class ConnectionSampler {
13
+ private readonly libp2p;
14
+ private readonly cleanupIntervalMs;
15
+ private readonly sampler;
16
+ private readonly logger;
17
+ private cleanupInterval;
18
+ private abortController;
19
+ private readonly activeConnectionsCount;
20
+ private readonly streams;
21
+ private dialQueue;
22
+ constructor(libp2p: Libp2p, cleanupIntervalMs?: number, // Default to 1 minute
23
+ sampler?: RandomSampler);
24
+ /**
25
+ * Stops the cleanup job and closes all active connections
26
+ */
27
+ stop(): Promise<void>;
28
+ /**
29
+ *
30
+ * @param excluding - The peers to exclude from the sampling
31
+ * This is to prevent sampling with replacement
32
+ * @returns
33
+ */
34
+ getPeer(excluding?: Map<string, boolean>): PeerId | undefined;
35
+ /**
36
+ * Samples a batch of unique peers from the libp2p node, prioritizing peers without active connections
37
+ *
38
+ * @param numberToSample - The number of peers to sample
39
+ * @returns Array of unique sampled peers, prioritizing those without active connections
40
+ */
41
+ samplePeersBatch(numberToSample: number): PeerId[];
42
+ /**
43
+ * Dials a protocol and returns the stream
44
+ *
45
+ * @param peerId - The peer id
46
+ * @param protocol - The protocol
47
+ * @returns The stream
48
+ */
49
+ dialProtocol(peerId: PeerId, protocol: string): Promise<Stream>;
50
+ /**
51
+ * Closes a stream and updates the active connections count
52
+ *
53
+ * @param streamId - The stream id
54
+ */
55
+ close(streamId: string): Promise<void>;
56
+ /**
57
+ * Cleans up stale connections that we have lost accounting for
58
+ */
59
+ private cleanupStaleConnections;
60
+ }
61
+ //# sourceMappingURL=connection_sampler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection_sampler.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/connection-sampler/connection_sampler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAShE,qBAAa,aAAa;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM;CAGnB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAY1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;IACzE,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,eAAe,CAA0C;IAEjE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAkC;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IAGnE,OAAO,CAAC,SAAS,CAAkC;gBAGhC,MAAM,EAAE,MAAM,EACd,iBAAiB,GAAE,MAAc,EAAE,sBAAsB;IACzD,OAAO,GAAE,aAAmC;IAO/D;;OAEG;IACG,IAAI;IAaV;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS;IA+B7D;;;;;OAKG;IACH,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE;IAkClD;;;;;;OAMG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBrE;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B5C;;OAEG;YACW,uBAAuB;CAetC"}
@@ -0,0 +1,181 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import { SerialQueue } from '@aztec/foundation/queue';
3
+ const MAX_SAMPLE_ATTEMPTS = 4;
4
+ export class RandomSampler {
5
+ random(max) {
6
+ return Math.floor(Math.random() * max);
7
+ }
8
+ }
9
+ /**
10
+ * A class that samples peers from the libp2p node and returns a peer that we don't already have a connection open to.
11
+ * If we already have a connection open, we try to sample a different peer.
12
+ * We do this MAX_SAMPLE_ATTEMPTS times, if we still don't find a peer we just go for it.
13
+ *
14
+ * @dev Close must always be called on connections, else memory leak
15
+ */ export class ConnectionSampler {
16
+ libp2p;
17
+ cleanupIntervalMs;
18
+ sampler;
19
+ logger;
20
+ cleanupInterval;
21
+ abortController;
22
+ activeConnectionsCount;
23
+ streams;
24
+ // Serial queue to ensure that we only dial one peer at a time
25
+ dialQueue;
26
+ constructor(libp2p, cleanupIntervalMs = 60000, sampler = new RandomSampler()){
27
+ this.libp2p = libp2p;
28
+ this.cleanupIntervalMs = cleanupIntervalMs;
29
+ this.sampler = sampler;
30
+ this.logger = createLogger('p2p:reqresp:connection-sampler');
31
+ this.abortController = new AbortController();
32
+ this.activeConnectionsCount = new Map();
33
+ this.streams = new Map();
34
+ this.dialQueue = new SerialQueue();
35
+ this.cleanupInterval = setInterval(()=>void this.cleanupStaleConnections(), this.cleanupIntervalMs);
36
+ this.dialQueue.start();
37
+ }
38
+ /**
39
+ * Stops the cleanup job and closes all active connections
40
+ */ async stop() {
41
+ this.logger.info('Stopping connection sampler');
42
+ clearInterval(this.cleanupInterval);
43
+ this.abortController.abort();
44
+ await this.dialQueue.end();
45
+ // Close all active streams
46
+ const closePromises = Array.from(this.streams.keys()).map((streamId)=>this.close(streamId));
47
+ await Promise.all(closePromises);
48
+ this.logger.info('Connection sampler stopped');
49
+ }
50
+ /**
51
+ *
52
+ * @param excluding - The peers to exclude from the sampling
53
+ * This is to prevent sampling with replacement
54
+ * @returns
55
+ */ getPeer(excluding) {
56
+ // In libp2p getPeers performs a shallow copy, so this array can be sliced from safetly
57
+ const peers = this.libp2p.getPeers();
58
+ if (peers.length === 0) {
59
+ return undefined;
60
+ }
61
+ let randomIndex = this.sampler.random(peers.length);
62
+ let attempts = 0;
63
+ // Keep sampling while:
64
+ // - we haven't exceeded max attempts AND
65
+ // - either the peer has active connections OR is in the exclusion list
66
+ while(attempts < MAX_SAMPLE_ATTEMPTS && ((this.activeConnectionsCount.get(peers[randomIndex]) ?? 0) > 0 || (excluding?.get(peers[randomIndex]?.toString()) ?? false))){
67
+ peers.splice(randomIndex, 1);
68
+ randomIndex = this.sampler.random(peers.length);
69
+ attempts++;
70
+ }
71
+ this.logger.trace(`Sampled peer in ${attempts} attempts`, {
72
+ attempts,
73
+ peer: peers[randomIndex]?.toString()
74
+ });
75
+ return peers[randomIndex];
76
+ }
77
+ /**
78
+ * Samples a batch of unique peers from the libp2p node, prioritizing peers without active connections
79
+ *
80
+ * @param numberToSample - The number of peers to sample
81
+ * @returns Array of unique sampled peers, prioritizing those without active connections
82
+ */ samplePeersBatch(numberToSample) {
83
+ const peers = this.libp2p.getPeers();
84
+ const sampledPeers = [];
85
+ const peersWithConnections = []; // Hold onto peers with active connections incase we need to sample more
86
+ for (const peer of peers){
87
+ const activeConnections = this.activeConnectionsCount.get(peer) ?? 0;
88
+ if (activeConnections === 0) {
89
+ if (sampledPeers.push(peer) === numberToSample) {
90
+ return sampledPeers;
91
+ }
92
+ } else {
93
+ peersWithConnections.push(peer);
94
+ }
95
+ }
96
+ // If we still need more peers, sample from those with connections
97
+ while(sampledPeers.length < numberToSample && peersWithConnections.length > 0){
98
+ const randomIndex = this.sampler.random(peersWithConnections.length);
99
+ const [peer] = peersWithConnections.splice(randomIndex, 1);
100
+ sampledPeers.push(peer);
101
+ }
102
+ this.logger.trace(`Batch sampled ${sampledPeers.length} unique peers`, {
103
+ peers: sampledPeers,
104
+ withoutConnections: sampledPeers.length - peersWithConnections.length,
105
+ withConnections: peersWithConnections.length
106
+ });
107
+ return sampledPeers;
108
+ }
109
+ // Set of passthrough functions to keep track of active connections
110
+ /**
111
+ * Dials a protocol and returns the stream
112
+ *
113
+ * @param peerId - The peer id
114
+ * @param protocol - The protocol
115
+ * @returns The stream
116
+ */ async dialProtocol(peerId, protocol) {
117
+ // Dialling at the same time can cause race conditions where two different streams
118
+ // end up with the same id, hence a serial queue
119
+ const stream = await this.dialQueue.put(()=>this.libp2p.dialProtocol(peerId, protocol, {
120
+ signal: this.abortController.signal
121
+ }));
122
+ this.streams.set(stream.id, {
123
+ stream,
124
+ peerId
125
+ });
126
+ const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 0) + 1;
127
+ this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
128
+ this.logger.trace(`Dialed protocol ${protocol} with peer ${peerId.toString()}`, {
129
+ streamId: stream.id,
130
+ peerId: peerId.toString(),
131
+ activeConnectionsCount: updatedActiveConnectionsCount
132
+ });
133
+ return stream;
134
+ }
135
+ /**
136
+ * Closes a stream and updates the active connections count
137
+ *
138
+ * @param streamId - The stream id
139
+ */ async close(streamId) {
140
+ try {
141
+ const streamAndPeerId = this.streams.get(streamId);
142
+ if (!streamAndPeerId) {
143
+ this.logger.warn(`Stream ${streamId} not found`);
144
+ return;
145
+ }
146
+ const { stream, peerId } = streamAndPeerId;
147
+ const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 1) - 1;
148
+ this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
149
+ this.logger.trace(`Closing connection to peer ${peerId.toString()}`, {
150
+ streamId,
151
+ peerId: peerId.toString(),
152
+ protocol: stream.protocol,
153
+ activeConnectionsCount: updatedActiveConnectionsCount
154
+ });
155
+ await stream?.close();
156
+ } catch (error) {
157
+ this.logger.error(`Failed to close connection to peer with stream id ${streamId}`, error);
158
+ } finally{
159
+ this.streams.delete(streamId);
160
+ }
161
+ }
162
+ /**
163
+ * Cleans up stale connections that we have lost accounting for
164
+ */ async cleanupStaleConnections() {
165
+ // Look for streams without anything in the activeConnectionsCount
166
+ // If we find anything, close the stream
167
+ for (const [streamId, { peerId }] of this.streams.entries()){
168
+ try {
169
+ // Check if we have lost track of accounting
170
+ if (this.activeConnectionsCount.get(peerId) === 0) {
171
+ await this.close(streamId);
172
+ this.logger.debug(`Cleaned up stale connection ${streamId} to peer ${peerId.toString()}`);
173
+ }
174
+ } catch (error) {
175
+ this.logger.error(`Error cleaning up stale connection ${streamId}`, {
176
+ error
177
+ });
178
+ }
179
+ }
180
+ }
181
+ }
@@ -0,0 +1,6 @@
1
+ export {};
2
+ /**
3
+ * Request Response protocol allows nodes to ask their peers for data
4
+ * that they missed via the traditional gossip protocol.
5
+ */
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/index.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Request Response protocol allows nodes to ask their peers for data
3
+ * that they missed via the traditional gossip protocol.
4
+ */
@@ -0,0 +1,116 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ import type { PeerId } from '@libp2p/interface';
4
+ import type { ReqRespStatus } from './status.js';
5
+ export declare const PING_PROTOCOL = "/aztec/req/ping/0.1.0";
6
+ export declare const STATUS_PROTOCOL = "/aztec/req/status/0.1.0";
7
+ export declare const GOODBYE_PROTOCOL = "/aztec/req/goodbye/0.1.0";
8
+ export declare const TX_REQ_PROTOCOL = "/aztec/req/tx/0.1.0";
9
+ export declare const BLOCK_REQ_PROTOCOL = "/aztec/req/block/0.1.0";
10
+ export declare enum ReqRespSubProtocol {
11
+ PING = "/aztec/req/ping/0.1.0",
12
+ STATUS = "/aztec/req/status/0.1.0",
13
+ GOODBYE = "/aztec/req/goodbye/0.1.0",
14
+ TX = "/aztec/req/tx/0.1.0",
15
+ BLOCK = "/aztec/req/block/0.1.0"
16
+ }
17
+ /**
18
+ * A handler for a sub protocol
19
+ * The message will arrive as a buffer, and the handler must return a buffer
20
+ */
21
+ export type ReqRespSubProtocolHandler = (peerId: PeerId, msg: Buffer) => Promise<Buffer>;
22
+ /**
23
+ * A type mapping from supprotocol to it's rate limits
24
+ */
25
+ export type ReqRespSubProtocolRateLimits = Record<ReqRespSubProtocol, ProtocolRateLimitQuota>;
26
+ /**
27
+ * The response from the ReqResp protocol
28
+ * Consists of a status (Error code) and data
29
+ */
30
+ export interface ReqRespResponse {
31
+ status: ReqRespStatus;
32
+ data: Buffer;
33
+ }
34
+ /**
35
+ * A rate limit quota
36
+ */
37
+ export interface RateLimitQuota {
38
+ /**
39
+ * The time window in ms
40
+ */
41
+ quotaTimeMs: number;
42
+ /**
43
+ * The number of requests allowed within the time window
44
+ */
45
+ quotaCount: number;
46
+ }
47
+ export interface ProtocolRateLimitQuota {
48
+ /**
49
+ * The rate limit quota for a single peer
50
+ */
51
+ peerLimit: RateLimitQuota;
52
+ /**
53
+ * The rate limit quota for the global peer set
54
+ */
55
+ globalLimit: RateLimitQuota;
56
+ }
57
+ export declare const noopValidator: () => Promise<boolean>;
58
+ /**
59
+ * A type mapping from supprotocol to it's handling function
60
+ */
61
+ export type ReqRespSubProtocolHandlers = Record<ReqRespSubProtocol, ReqRespSubProtocolHandler>;
62
+ type ResponseValidator<RequestIdentifier, Response> = (request: RequestIdentifier, response: Response, peerId: PeerId) => Promise<boolean>;
63
+ export type ReqRespSubProtocolValidators = {
64
+ [S in ReqRespSubProtocol]: ResponseValidator<any, any>;
65
+ };
66
+ export declare const DEFAULT_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators;
67
+ /**
68
+ * Sub protocol map determines the request and response types for each
69
+ * Req Resp protocol
70
+ */
71
+ export type SubProtocolMap = {
72
+ [S in ReqRespSubProtocol]: RequestResponsePair<any, any>;
73
+ };
74
+ /**
75
+ * Default sub protocol handlers - this SHOULD be overwritten by the service,
76
+ */
77
+ export declare const DEFAULT_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers;
78
+ /**
79
+ * The Request Response Pair interface defines the methods that each
80
+ * request response pair must implement
81
+ */
82
+ interface RequestResponsePair<Req extends {
83
+ toBuffer(): Buffer;
84
+ }, Res> {
85
+ /**
86
+ * The request must implement the toBuffer method (generic serialisation)
87
+ */
88
+ request: new (...args: any[]) => Req;
89
+ /**
90
+ * The response must implement the static fromBuffer method (generic serialisation)
91
+ */
92
+ response: {
93
+ new (...args: any[]): Res;
94
+ fromBuffer(buffer: Buffer): Res;
95
+ };
96
+ }
97
+ /**
98
+ * RequestableBuffer is a wrapper around a buffer that allows it to be
99
+ * used in generic request response protocols
100
+ *
101
+ * An instance of the RequestResponsePair defined above
102
+ */
103
+ export declare class RequestableBuffer {
104
+ buffer: Buffer;
105
+ constructor(buffer: Buffer);
106
+ toBuffer(): Buffer;
107
+ static fromBuffer(buffer: Buffer): RequestableBuffer;
108
+ }
109
+ /**
110
+ * A mapping from each protocol to their request and response types
111
+ * This defines the request and response types for each sub protocol, used primarily
112
+ * as a type rather than an object
113
+ */
114
+ export declare const subProtocolMap: SubProtocolMap;
115
+ export {};
116
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/interface.ts"],"names":[],"mappings":";;AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,eAAO,MAAM,aAAa,0BAA0B,CAAC;AACrD,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAC3D,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,kBAAkB,2BAA2B,CAAC;AAE3D,oBAAY,kBAAkB;IAC5B,IAAI,0BAAgB;IACpB,MAAM,4BAAkB;IACxB,OAAO,6BAAmB;IAC1B,EAAE,wBAAkB;IACpB,KAAK,2BAAqB;CAC3B;AAED;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEzF;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;AAE9F;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,SAAS,EAAE,cAAc,CAAC;IAC1B;;OAEG;IACH,WAAW,EAAE,cAAc,CAAC;CAC7B;AAED,eAAO,MAAM,aAAa,wBAA8B,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,kBAAkB,EAAE,yBAAyB,CAAC,CAAC;AAE/F,KAAK,iBAAiB,CAAC,iBAAiB,EAAE,QAAQ,IAAI,CACpD,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,4BAA4B,GAAG;KACxC,CAAC,IAAI,kBAAkB,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;CACvD,CAAC;AAEF,eAAO,MAAM,+BAA+B,EAAE,4BAM7C,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;KAC1B,CAAC,IAAI,kBAAkB,GAAG,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC;CACzD,CAAC;AAUF;;GAEG;AACH,eAAO,MAAM,6BAA6B,EAAE,0BAM3C,CAAC;AAEF;;;GAGG;AACH,UAAU,mBAAmB,CAAC,GAAG,SAAS;IAAE,QAAQ,IAAI,MAAM,CAAA;CAAE,EAAE,GAAG;IACnE;;OAEG;IACH,OAAO,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACrC;;OAEG;IACH,QAAQ,EAAE;QACR,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;QAC1B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;KACjC,CAAC;CACH;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IACT,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM;IAEjC,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM;CAGjC;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAqB5B,CAAC"}