@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,35 @@
1
+ import { type ConfigMapping, numberConfigHelper } from '@aztec/foundation/config';
2
+
3
+ export const DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS = 2000;
4
+ export const DEFAULT_OVERALL_REQUEST_TIMEOUT_MS = 4000;
5
+
6
+ // For use in tests.
7
+ export const DEFAULT_P2P_REQRESP_CONFIG: P2PReqRespConfig = {
8
+ overallRequestTimeoutMs: DEFAULT_OVERALL_REQUEST_TIMEOUT_MS,
9
+ individualRequestTimeoutMs: DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS,
10
+ };
11
+
12
+ export interface P2PReqRespConfig {
13
+ /**
14
+ * The overall timeout for a request response operation.
15
+ */
16
+ overallRequestTimeoutMs: number;
17
+
18
+ /**
19
+ * The timeout for an individual request response peer interaction.
20
+ */
21
+ individualRequestTimeoutMs: number;
22
+ }
23
+
24
+ export const p2pReqRespConfigMappings: Record<keyof P2PReqRespConfig, ConfigMapping> = {
25
+ overallRequestTimeoutMs: {
26
+ env: 'P2P_REQRESP_OVERALL_REQUEST_TIMEOUT_MS',
27
+ description: 'The overall timeout for a request response operation.',
28
+ ...numberConfigHelper(DEFAULT_OVERALL_REQUEST_TIMEOUT_MS),
29
+ },
30
+ individualRequestTimeoutMs: {
31
+ env: 'P2P_REQRESP_INDIVIDUAL_REQUEST_TIMEOUT_MS',
32
+ description: 'The timeout for an individual request response peer interaction.',
33
+ ...numberConfigHelper(DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS),
34
+ },
35
+ };
@@ -0,0 +1,94 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+
3
+ import type { PeerId } from '@libp2p/interface';
4
+
5
+ import type { ConnectionSampler } from './connection_sampler.js';
6
+
7
+ /**
8
+ * Manages batches of peers for parallel request processing.
9
+ * Tracks active peers and provides deterministic peer assignment for requests.
10
+ *
11
+ * Example with 3 peers and 10 requests:
12
+ *
13
+ * Peers: [P1] [P2] [P3]
14
+ * ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
15
+ * Requests: 0,1,2,9 | 3,4,5 | 6,7,8
16
+ *
17
+ * Each peer handles a bucket of consecutive requests.
18
+ * If a peer fails, it is replaced while maintaining the same bucket.
19
+ */
20
+ export class BatchConnectionSampler {
21
+ private readonly logger = createLogger('p2p:reqresp:batch-connection-sampler');
22
+ private readonly batch: PeerId[] = [];
23
+ private readonly requestsPerPeer: number;
24
+
25
+ constructor(private readonly connectionSampler: ConnectionSampler, batchSize: number, maxPeers: number) {
26
+ if (maxPeers <= 0) {
27
+ throw new Error('Max peers cannot be 0');
28
+ }
29
+ if (batchSize <= 0) {
30
+ throw new Error('Batch size cannot be 0');
31
+ }
32
+
33
+ // Calculate how many requests each peer should handle, cannot be 0
34
+ this.requestsPerPeer = Math.max(1, Math.floor(batchSize / maxPeers));
35
+
36
+ // Sample initial peers
37
+ this.batch = this.connectionSampler.samplePeersBatch(maxPeers);
38
+ }
39
+
40
+ /**
41
+ * Gets the peer responsible for handling a specific request index
42
+ *
43
+ * @param index - The request index
44
+ * @returns The peer assigned to handle this request
45
+ */
46
+ getPeerForRequest(index: number): PeerId | undefined {
47
+ if (this.batch.length === 0) {
48
+ return undefined;
49
+ }
50
+
51
+ // Calculate which peer bucket this index belongs to
52
+ const peerIndex = Math.floor(index / this.requestsPerPeer) % this.batch.length;
53
+ return this.batch[peerIndex];
54
+ }
55
+
56
+ /**
57
+ * Removes a peer and replaces it with a new one, maintaining the same position
58
+ * in the batch array to keep request distribution consistent
59
+ *
60
+ * @param peerId - The peer to remove and replace
61
+ */
62
+ removePeerAndReplace(peerId: PeerId): void {
63
+ const index = this.batch.findIndex(p => p === peerId);
64
+ if (index === -1) {
65
+ return;
66
+ }
67
+
68
+ const excluding = new Map([[peerId.toString(), true]]);
69
+ const newPeer = this.connectionSampler.getPeer(excluding);
70
+
71
+ if (newPeer) {
72
+ this.batch[index] = newPeer;
73
+ this.logger.trace(`Replaced peer ${peerId} with ${newPeer}`, { peerId, newPeer });
74
+ } else {
75
+ // If we couldn't get a replacement, remove the peer and compact the array
76
+ this.batch.splice(index, 1);
77
+ this.logger.trace(`Removed peer ${peerId}`, { peerId });
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Gets the number of active peers
83
+ */
84
+ get activePeerCount(): number {
85
+ return this.batch.length;
86
+ }
87
+
88
+ /**
89
+ * Gets the number of requests each peer is assigned to handle
90
+ */
91
+ get requestsPerBucket(): number {
92
+ return this.requestsPerPeer;
93
+ }
94
+ }
@@ -0,0 +1,217 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import { SerialQueue } from '@aztec/foundation/queue';
3
+
4
+ import type { Libp2p, PeerId, Stream } from '@libp2p/interface';
5
+
6
+ const MAX_SAMPLE_ATTEMPTS = 4;
7
+
8
+ interface StreamAndPeerId {
9
+ stream: Stream;
10
+ peerId: PeerId;
11
+ }
12
+
13
+ export class RandomSampler {
14
+ random(max: number) {
15
+ return Math.floor(Math.random() * max);
16
+ }
17
+ }
18
+
19
+ /**
20
+ * A class that samples peers from the libp2p node and returns a peer that we don't already have a connection open to.
21
+ * If we already have a connection open, we try to sample a different peer.
22
+ * We do this MAX_SAMPLE_ATTEMPTS times, if we still don't find a peer we just go for it.
23
+ *
24
+ * @dev Close must always be called on connections, else memory leak
25
+ */
26
+ export class ConnectionSampler {
27
+ private readonly logger = createLogger('p2p:reqresp:connection-sampler');
28
+ private cleanupInterval: NodeJS.Timeout;
29
+ private abortController: AbortController = new AbortController();
30
+
31
+ private readonly activeConnectionsCount: Map<PeerId, number> = new Map();
32
+ private readonly streams: Map<string, StreamAndPeerId> = new Map();
33
+
34
+ // Serial queue to ensure that we only dial one peer at a time
35
+ private dialQueue: SerialQueue = new SerialQueue();
36
+
37
+ constructor(
38
+ private readonly libp2p: Libp2p,
39
+ private readonly cleanupIntervalMs: number = 60000, // Default to 1 minute
40
+ private readonly sampler: RandomSampler = new RandomSampler(), // Allow randomness to be mocked for testing
41
+ ) {
42
+ this.cleanupInterval = setInterval(() => void this.cleanupStaleConnections(), this.cleanupIntervalMs);
43
+
44
+ this.dialQueue.start();
45
+ }
46
+
47
+ /**
48
+ * Stops the cleanup job and closes all active connections
49
+ */
50
+ async stop() {
51
+ this.logger.info('Stopping connection sampler');
52
+ clearInterval(this.cleanupInterval);
53
+
54
+ this.abortController.abort();
55
+ await this.dialQueue.end();
56
+
57
+ // Close all active streams
58
+ const closePromises = Array.from(this.streams.keys()).map(streamId => this.close(streamId));
59
+ await Promise.all(closePromises);
60
+ this.logger.info('Connection sampler stopped');
61
+ }
62
+
63
+ /**
64
+ *
65
+ * @param excluding - The peers to exclude from the sampling
66
+ * This is to prevent sampling with replacement
67
+ * @returns
68
+ */
69
+ getPeer(excluding?: Map<string, boolean>): PeerId | undefined {
70
+ // In libp2p getPeers performs a shallow copy, so this array can be sliced from safetly
71
+ const peers = this.libp2p.getPeers();
72
+
73
+ if (peers.length === 0) {
74
+ return undefined;
75
+ }
76
+
77
+ let randomIndex = this.sampler.random(peers.length);
78
+ let attempts = 0;
79
+
80
+ // Keep sampling while:
81
+ // - we haven't exceeded max attempts AND
82
+ // - either the peer has active connections OR is in the exclusion list
83
+ while (
84
+ attempts < MAX_SAMPLE_ATTEMPTS &&
85
+ ((this.activeConnectionsCount.get(peers[randomIndex]) ?? 0) > 0 ||
86
+ (excluding?.get(peers[randomIndex]?.toString()) ?? false))
87
+ ) {
88
+ peers.splice(randomIndex, 1);
89
+ randomIndex = this.sampler.random(peers.length);
90
+ attempts++;
91
+ }
92
+
93
+ this.logger.trace(`Sampled peer in ${attempts} attempts`, {
94
+ attempts,
95
+ peer: peers[randomIndex]?.toString(),
96
+ });
97
+ return peers[randomIndex];
98
+ }
99
+
100
+ /**
101
+ * Samples a batch of unique peers from the libp2p node, prioritizing peers without active connections
102
+ *
103
+ * @param numberToSample - The number of peers to sample
104
+ * @returns Array of unique sampled peers, prioritizing those without active connections
105
+ */
106
+ samplePeersBatch(numberToSample: number): PeerId[] {
107
+ const peers = this.libp2p.getPeers();
108
+ const sampledPeers: PeerId[] = [];
109
+ const peersWithConnections: PeerId[] = []; // Hold onto peers with active connections incase we need to sample more
110
+
111
+ for (const peer of peers) {
112
+ const activeConnections = this.activeConnectionsCount.get(peer) ?? 0;
113
+ if (activeConnections === 0) {
114
+ if (sampledPeers.push(peer) === numberToSample) {
115
+ return sampledPeers;
116
+ }
117
+ } else {
118
+ peersWithConnections.push(peer);
119
+ }
120
+ }
121
+
122
+ // If we still need more peers, sample from those with connections
123
+ while (sampledPeers.length < numberToSample && peersWithConnections.length > 0) {
124
+ const randomIndex = this.sampler.random(peersWithConnections.length);
125
+ const [peer] = peersWithConnections.splice(randomIndex, 1);
126
+ sampledPeers.push(peer);
127
+ }
128
+
129
+ this.logger.trace(`Batch sampled ${sampledPeers.length} unique peers`, {
130
+ peers: sampledPeers,
131
+ withoutConnections: sampledPeers.length - peersWithConnections.length,
132
+ withConnections: peersWithConnections.length,
133
+ });
134
+
135
+ return sampledPeers;
136
+ }
137
+
138
+ // Set of passthrough functions to keep track of active connections
139
+
140
+ /**
141
+ * Dials a protocol and returns the stream
142
+ *
143
+ * @param peerId - The peer id
144
+ * @param protocol - The protocol
145
+ * @returns The stream
146
+ */
147
+ async dialProtocol(peerId: PeerId, protocol: string): Promise<Stream> {
148
+ // Dialling at the same time can cause race conditions where two different streams
149
+ // end up with the same id, hence a serial queue
150
+ const stream = await this.dialQueue.put(() =>
151
+ this.libp2p.dialProtocol(peerId, protocol, { signal: this.abortController.signal }),
152
+ );
153
+
154
+ this.streams.set(stream.id, { stream, peerId });
155
+ const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 0) + 1;
156
+ this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
157
+
158
+ this.logger.trace(`Dialed protocol ${protocol} with peer ${peerId.toString()}`, {
159
+ streamId: stream.id,
160
+ peerId: peerId.toString(),
161
+ activeConnectionsCount: updatedActiveConnectionsCount,
162
+ });
163
+ return stream;
164
+ }
165
+
166
+ /**
167
+ * Closes a stream and updates the active connections count
168
+ *
169
+ * @param streamId - The stream id
170
+ */
171
+ async close(streamId: string): Promise<void> {
172
+ try {
173
+ const streamAndPeerId = this.streams.get(streamId);
174
+ if (!streamAndPeerId) {
175
+ this.logger.warn(`Stream ${streamId} not found`);
176
+ return;
177
+ }
178
+
179
+ const { stream, peerId } = streamAndPeerId;
180
+
181
+ const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 1) - 1;
182
+ this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
183
+
184
+ this.logger.trace(`Closing connection to peer ${peerId.toString()}`, {
185
+ streamId,
186
+ peerId: peerId.toString(),
187
+ protocol: stream.protocol,
188
+ activeConnectionsCount: updatedActiveConnectionsCount,
189
+ });
190
+
191
+ await stream?.close();
192
+ } catch (error) {
193
+ this.logger.error(`Failed to close connection to peer with stream id ${streamId}`, error);
194
+ } finally {
195
+ this.streams.delete(streamId);
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Cleans up stale connections that we have lost accounting for
201
+ */
202
+ private async cleanupStaleConnections() {
203
+ // Look for streams without anything in the activeConnectionsCount
204
+ // If we find anything, close the stream
205
+ for (const [streamId, { peerId }] of this.streams.entries()) {
206
+ try {
207
+ // Check if we have lost track of accounting
208
+ if (this.activeConnectionsCount.get(peerId) === 0) {
209
+ await this.close(streamId);
210
+ this.logger.debug(`Cleaned up stale connection ${streamId} to peer ${peerId.toString()}`);
211
+ }
212
+ } catch (error) {
213
+ this.logger.error(`Error cleaning up stale connection ${streamId}`, { error });
214
+ }
215
+ }
216
+ }
217
+ }
@@ -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,185 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import { L2Block } from '@aztec/stdlib/block';
3
+ import { Tx, TxHash } from '@aztec/stdlib/tx';
4
+
5
+ import type { PeerId } from '@libp2p/interface';
6
+
7
+ import type { ReqRespStatus } from './status.js';
8
+
9
+ /*
10
+ * Request Response Sub Protocols
11
+ */
12
+ export const PING_PROTOCOL = '/aztec/req/ping/0.1.0';
13
+ export const STATUS_PROTOCOL = '/aztec/req/status/0.1.0';
14
+ export const GOODBYE_PROTOCOL = '/aztec/req/goodbye/0.1.0';
15
+ export const TX_REQ_PROTOCOL = '/aztec/req/tx/0.1.0';
16
+ export const BLOCK_REQ_PROTOCOL = '/aztec/req/block/0.1.0';
17
+
18
+ export enum ReqRespSubProtocol {
19
+ PING = PING_PROTOCOL,
20
+ STATUS = STATUS_PROTOCOL,
21
+ GOODBYE = GOODBYE_PROTOCOL,
22
+ TX = TX_REQ_PROTOCOL,
23
+ BLOCK = BLOCK_REQ_PROTOCOL,
24
+ }
25
+
26
+ /**
27
+ * A handler for a sub protocol
28
+ * The message will arrive as a buffer, and the handler must return a buffer
29
+ */
30
+ export type ReqRespSubProtocolHandler = (peerId: PeerId, msg: Buffer) => Promise<Buffer>;
31
+
32
+ /**
33
+ * A type mapping from supprotocol to it's rate limits
34
+ */
35
+ export type ReqRespSubProtocolRateLimits = Record<ReqRespSubProtocol, ProtocolRateLimitQuota>;
36
+
37
+ /**
38
+ * The response from the ReqResp protocol
39
+ * Consists of a status (Error code) and data
40
+ */
41
+ export interface ReqRespResponse {
42
+ status: ReqRespStatus;
43
+ data: Buffer;
44
+ }
45
+
46
+ /**
47
+ * A rate limit quota
48
+ */
49
+ export interface RateLimitQuota {
50
+ /**
51
+ * The time window in ms
52
+ */
53
+ quotaTimeMs: number;
54
+ /**
55
+ * The number of requests allowed within the time window
56
+ */
57
+ quotaCount: number;
58
+ }
59
+
60
+ export interface ProtocolRateLimitQuota {
61
+ /**
62
+ * The rate limit quota for a single peer
63
+ */
64
+ peerLimit: RateLimitQuota;
65
+ /**
66
+ * The rate limit quota for the global peer set
67
+ */
68
+ globalLimit: RateLimitQuota;
69
+ }
70
+
71
+ export const noopValidator = () => Promise.resolve(true);
72
+
73
+ /**
74
+ * A type mapping from supprotocol to it's handling function
75
+ */
76
+ export type ReqRespSubProtocolHandlers = Record<ReqRespSubProtocol, ReqRespSubProtocolHandler>;
77
+
78
+ type ResponseValidator<RequestIdentifier, Response> = (
79
+ request: RequestIdentifier,
80
+ response: Response,
81
+ peerId: PeerId,
82
+ ) => Promise<boolean>;
83
+
84
+ export type ReqRespSubProtocolValidators = {
85
+ [S in ReqRespSubProtocol]: ResponseValidator<any, any>;
86
+ };
87
+
88
+ export const DEFAULT_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = {
89
+ [ReqRespSubProtocol.PING]: noopValidator,
90
+ [ReqRespSubProtocol.STATUS]: noopValidator,
91
+ [ReqRespSubProtocol.TX]: noopValidator,
92
+ [ReqRespSubProtocol.GOODBYE]: noopValidator,
93
+ [ReqRespSubProtocol.BLOCK]: noopValidator,
94
+ };
95
+
96
+ /**
97
+ * Sub protocol map determines the request and response types for each
98
+ * Req Resp protocol
99
+ */
100
+ export type SubProtocolMap = {
101
+ [S in ReqRespSubProtocol]: RequestResponsePair<any, any>;
102
+ };
103
+
104
+ /**
105
+ * Default handler for unimplemented sub protocols, this SHOULD be overwritten
106
+ * by the service, but is provided as a fallback
107
+ */
108
+ const defaultHandler = (_msg: any): Promise<Buffer> => {
109
+ return Promise.resolve(Buffer.from('unimplemented'));
110
+ };
111
+
112
+ /**
113
+ * Default sub protocol handlers - this SHOULD be overwritten by the service,
114
+ */
115
+ export const DEFAULT_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = {
116
+ [ReqRespSubProtocol.PING]: defaultHandler,
117
+ [ReqRespSubProtocol.STATUS]: defaultHandler,
118
+ [ReqRespSubProtocol.TX]: defaultHandler,
119
+ [ReqRespSubProtocol.GOODBYE]: defaultHandler,
120
+ [ReqRespSubProtocol.BLOCK]: defaultHandler,
121
+ };
122
+
123
+ /**
124
+ * The Request Response Pair interface defines the methods that each
125
+ * request response pair must implement
126
+ */
127
+ interface RequestResponsePair<Req extends { toBuffer(): Buffer }, Res> {
128
+ /**
129
+ * The request must implement the toBuffer method (generic serialisation)
130
+ */
131
+ request: new (...args: any[]) => Req;
132
+ /**
133
+ * The response must implement the static fromBuffer method (generic serialisation)
134
+ */
135
+ response: {
136
+ new (...args: any[]): Res;
137
+ fromBuffer(buffer: Buffer): Res;
138
+ };
139
+ }
140
+
141
+ /**
142
+ * RequestableBuffer is a wrapper around a buffer that allows it to be
143
+ * used in generic request response protocols
144
+ *
145
+ * An instance of the RequestResponsePair defined above
146
+ */
147
+ export class RequestableBuffer {
148
+ constructor(public buffer: Buffer) {}
149
+
150
+ toBuffer() {
151
+ return this.buffer;
152
+ }
153
+
154
+ static fromBuffer(buffer: Buffer) {
155
+ return new RequestableBuffer(buffer);
156
+ }
157
+ }
158
+
159
+ /**
160
+ * A mapping from each protocol to their request and response types
161
+ * This defines the request and response types for each sub protocol, used primarily
162
+ * as a type rather than an object
163
+ */
164
+ export const subProtocolMap: SubProtocolMap = {
165
+ [ReqRespSubProtocol.PING]: {
166
+ request: RequestableBuffer,
167
+ response: RequestableBuffer,
168
+ },
169
+ [ReqRespSubProtocol.STATUS]: {
170
+ request: RequestableBuffer,
171
+ response: RequestableBuffer,
172
+ },
173
+ [ReqRespSubProtocol.TX]: {
174
+ request: TxHash,
175
+ response: Tx,
176
+ },
177
+ [ReqRespSubProtocol.GOODBYE]: {
178
+ request: RequestableBuffer,
179
+ response: RequestableBuffer,
180
+ },
181
+ [ReqRespSubProtocol.BLOCK]: {
182
+ request: Fr, // block number
183
+ response: L2Block,
184
+ },
185
+ };
@@ -0,0 +1,57 @@
1
+ // Request response metrics
2
+ import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
3
+ import type { TelemetryClient, Tracer, UpDownCounter } from '@aztec/telemetry-client';
4
+
5
+ export class ReqRespMetrics {
6
+ public readonly tracer: Tracer;
7
+
8
+ private readonly sentRequests: UpDownCounter;
9
+ private readonly receivedRequests: UpDownCounter;
10
+
11
+ private readonly failedOutboundRequests: UpDownCounter;
12
+ private readonly failedInboundRequests: UpDownCounter;
13
+
14
+ constructor(readonly telemetryClient: TelemetryClient, name = 'ReqResp') {
15
+ this.tracer = telemetryClient.getTracer(name);
16
+
17
+ const meter = telemetryClient.getMeter(name);
18
+ this.sentRequests = meter.createUpDownCounter(Metrics.P2P_REQ_RESP_SENT_REQUESTS, {
19
+ description: 'Number of requests sent to peers',
20
+ unit: 'requests',
21
+ valueType: ValueType.INT,
22
+ });
23
+ this.receivedRequests = meter.createUpDownCounter(Metrics.P2P_REQ_RESP_RECEIVED_REQUESTS, {
24
+ description: 'Number of requests received from peers',
25
+ unit: 'requests',
26
+ valueType: ValueType.INT,
27
+ });
28
+
29
+ this.failedOutboundRequests = meter.createUpDownCounter(Metrics.P2P_REQ_RESP_FAILED_OUTBOUND_REQUESTS, {
30
+ description: 'Number of failed outbound requests - nodes not getting valid responses',
31
+ unit: 'requests',
32
+ valueType: ValueType.INT,
33
+ });
34
+
35
+ this.failedInboundRequests = meter.createUpDownCounter(Metrics.P2P_REQ_RESP_FAILED_INBOUND_REQUESTS, {
36
+ description: 'Number of failed inbound requests - node failing to respond to requests',
37
+ unit: 'requests',
38
+ valueType: ValueType.INT,
39
+ });
40
+ }
41
+
42
+ public recordRequestSent(protocol: string) {
43
+ this.sentRequests.add(1, { [Attributes.P2P_REQ_RESP_PROTOCOL]: protocol });
44
+ }
45
+
46
+ public recordRequestReceived(protocol: string) {
47
+ this.receivedRequests.add(1, { [Attributes.P2P_REQ_RESP_PROTOCOL]: protocol });
48
+ }
49
+
50
+ public recordRequestError(protocol: string) {
51
+ this.failedOutboundRequests.add(1, { [Attributes.P2P_REQ_RESP_PROTOCOL]: protocol });
52
+ }
53
+
54
+ public recordResponseError(protocol: string) {
55
+ this.failedInboundRequests.add(1, { [Attributes.P2P_REQ_RESP_PROTOCOL]: protocol });
56
+ }
57
+ }
@@ -0,0 +1,15 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import type { L2BlockSource } from '@aztec/stdlib/block';
3
+
4
+ import type { PeerId } from '@libp2p/interface';
5
+
6
+ import type { ReqRespSubProtocolHandler } from '../interface.js';
7
+
8
+ export function reqRespBlockHandler(l2BlockSource: L2BlockSource): ReqRespSubProtocolHandler {
9
+ return async (_peerId: PeerId, msg: Buffer) => {
10
+ const blockNumber = Fr.fromBuffer(msg);
11
+
12
+ const foundBlock = await l2BlockSource.getBlock(Number(blockNumber));
13
+ return foundBlock ? foundBlock.toBuffer() : Buffer.alloc(0);
14
+ };
15
+ }