@aztec/p2p 0.74.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

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 (217) hide show
  1. package/dest/bootstrap/bootstrap.js +41 -29
  2. package/dest/client/factory.js +8 -10
  3. package/dest/client/index.js +0 -1
  4. package/dest/client/p2p_client.js +513 -507
  5. package/dest/config.js +44 -39
  6. package/dest/errors/reqresp.error.js +6 -10
  7. package/dest/index.js +0 -1
  8. package/dest/mem_pools/attestation_pool/attestation_pool.js +6 -2
  9. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +64 -32
  10. package/dest/mem_pools/attestation_pool/index.js +0 -1
  11. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +22 -19
  12. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +22 -26
  13. package/dest/mem_pools/attestation_pool/mocks.js +10 -6
  14. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js +1 -2
  15. package/dest/mem_pools/epoch_proof_quote_pool/index.js +0 -1
  16. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js +5 -4
  17. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.js +2 -3
  18. package/dest/mem_pools/index.js +1 -2
  19. package/dest/mem_pools/instrumentation.js +37 -42
  20. package/dest/mem_pools/interface.js +3 -2
  21. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +127 -134
  22. package/dest/mem_pools/tx_pool/index.js +0 -1
  23. package/dest/mem_pools/tx_pool/memory_tx_pool.js +45 -43
  24. package/dest/mem_pools/tx_pool/priority.js +1 -3
  25. package/dest/mem_pools/tx_pool/tx_pool.js +3 -2
  26. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +107 -37
  27. package/dest/mocks/index.js +47 -38
  28. package/dest/msg_validators/attestation_validator/attestation_validator.js +3 -3
  29. package/dest/msg_validators/attestation_validator/index.js +0 -1
  30. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +2 -2
  31. package/dest/msg_validators/block_proposal_validator/index.js +0 -1
  32. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.js +2 -2
  33. package/dest/msg_validators/epoch_proof_quote_validator/index.js +0 -1
  34. package/dest/msg_validators/index.js +0 -1
  35. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +9 -11
  36. package/dest/msg_validators/tx_validator/block_header_validator.js +17 -12
  37. package/dest/msg_validators/tx_validator/data_validator.js +41 -32
  38. package/dest/msg_validators/tx_validator/double_spend_validator.js +22 -14
  39. package/dest/msg_validators/tx_validator/index.js +0 -1
  40. package/dest/msg_validators/tx_validator/metadata_validator.js +29 -26
  41. package/dest/msg_validators/tx_validator/tx_proof_validator.js +17 -12
  42. package/dest/services/data_store.js +57 -57
  43. package/dest/services/discv5/discV5_service.js +31 -23
  44. package/dest/services/dummy_service.js +40 -58
  45. package/dest/services/encoding.js +10 -9
  46. package/dest/services/index.js +0 -1
  47. package/dest/services/libp2p/libp2p_service.js +709 -695
  48. package/dest/services/peer-manager/metrics.js +14 -7
  49. package/dest/services/peer-manager/peer_manager.js +340 -342
  50. package/dest/services/peer-manager/peer_scoring.js +20 -18
  51. package/dest/services/reqresp/config.js +4 -5
  52. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +35 -28
  53. package/dest/services/reqresp/connection-sampler/connection_sampler.js +60 -59
  54. package/dest/services/reqresp/index.js +1 -3
  55. package/dest/services/reqresp/interface.js +25 -30
  56. package/dest/services/reqresp/metrics.js +23 -10
  57. package/dest/services/reqresp/protocols/block.js +1 -2
  58. package/dest/services/reqresp/protocols/goodbye.js +35 -40
  59. package/dest/services/reqresp/protocols/index.js +1 -3
  60. package/dest/services/reqresp/protocols/ping.js +1 -3
  61. package/dest/services/reqresp/protocols/status.js +1 -3
  62. package/dest/services/reqresp/protocols/tx.js +5 -8
  63. package/dest/services/reqresp/rate-limiter/index.js +0 -1
  64. package/dest/services/reqresp/rate-limiter/rate_limiter.js +42 -36
  65. package/dest/services/reqresp/rate-limiter/rate_limits.js +16 -17
  66. package/dest/services/reqresp/reqresp.js +461 -395
  67. package/dest/services/reqresp/status.js +51 -0
  68. package/dest/services/service.js +3 -4
  69. package/dest/services/types.js +16 -23
  70. package/dest/util.js +23 -34
  71. package/package.json +8 -8
  72. package/src/client/p2p_client.ts +159 -125
  73. package/src/mem_pools/index.ts +3 -3
  74. package/src/mem_pools/instrumentation.ts +3 -2
  75. package/src/services/reqresp/interface.ts +11 -0
  76. package/src/services/reqresp/rate-limiter/rate_limiter.ts +3 -1
  77. package/src/services/reqresp/rate-limiter/rate_limits.ts +2 -2
  78. package/src/services/reqresp/reqresp.ts +111 -24
  79. package/src/services/reqresp/status.ts +59 -0
  80. package/dest/bootstrap/bootstrap.d.ts +0 -38
  81. package/dest/bootstrap/bootstrap.d.ts.map +0 -1
  82. package/dest/client/factory.d.ts +0 -19
  83. package/dest/client/factory.d.ts.map +0 -1
  84. package/dest/client/index.d.ts +0 -3
  85. package/dest/client/index.d.ts.map +0 -1
  86. package/dest/client/p2p_client.d.ts +0 -321
  87. package/dest/client/p2p_client.d.ts.map +0 -1
  88. package/dest/config.d.ts +0 -171
  89. package/dest/config.d.ts.map +0 -1
  90. package/dest/errors/reqresp.error.d.ts +0 -28
  91. package/dest/errors/reqresp.error.d.ts.map +0 -1
  92. package/dest/index.d.ts +0 -9
  93. package/dest/index.d.ts.map +0 -1
  94. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +0 -57
  95. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +0 -1
  96. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +0 -3
  97. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +0 -1
  98. package/dest/mem_pools/attestation_pool/index.d.ts +0 -3
  99. package/dest/mem_pools/attestation_pool/index.d.ts.map +0 -1
  100. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -22
  101. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  102. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -17
  103. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  104. package/dest/mem_pools/attestation_pool/mocks.d.ts +0 -18
  105. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +0 -1
  106. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts +0 -7
  107. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts.map +0 -1
  108. package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts +0 -4
  109. package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts.map +0 -1
  110. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts +0 -12
  111. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts.map +0 -1
  112. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts +0 -8
  113. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts.map +0 -1
  114. package/dest/mem_pools/index.d.ts +0 -5
  115. package/dest/mem_pools/index.d.ts.map +0 -1
  116. package/dest/mem_pools/instrumentation.d.ts +0 -31
  117. package/dest/mem_pools/instrumentation.d.ts.map +0 -1
  118. package/dest/mem_pools/interface.d.ts +0 -13
  119. package/dest/mem_pools/interface.d.ts.map +0 -1
  120. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -66
  121. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  122. package/dest/mem_pools/tx_pool/index.d.ts +0 -4
  123. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  124. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -56
  125. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
  126. package/dest/mem_pools/tx_pool/priority.d.ts +0 -8
  127. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  128. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -66
  129. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  130. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  131. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  132. package/dest/mocks/index.d.ts +0 -54
  133. package/dest/mocks/index.d.ts.map +0 -1
  134. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +0 -8
  135. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +0 -1
  136. package/dest/msg_validators/attestation_validator/index.d.ts +0 -2
  137. package/dest/msg_validators/attestation_validator/index.d.ts.map +0 -1
  138. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -8
  139. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
  140. package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
  141. package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
  142. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts +0 -8
  143. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts.map +0 -1
  144. package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts +0 -2
  145. package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts.map +0 -1
  146. package/dest/msg_validators/index.d.ts +0 -4
  147. package/dest/msg_validators/index.d.ts.map +0 -1
  148. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +0 -7
  149. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +0 -1
  150. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +0 -11
  151. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +0 -1
  152. package/dest/msg_validators/tx_validator/data_validator.d.ts +0 -6
  153. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +0 -1
  154. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +0 -12
  155. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +0 -1
  156. package/dest/msg_validators/tx_validator/index.d.ts +0 -7
  157. package/dest/msg_validators/tx_validator/index.d.ts.map +0 -1
  158. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +0 -10
  159. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +0 -1
  160. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +0 -8
  161. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +0 -1
  162. package/dest/services/data_store.d.ts +0 -27
  163. package/dest/services/data_store.d.ts.map +0 -1
  164. package/dest/services/discv5/discV5_service.d.ts +0 -36
  165. package/dest/services/discv5/discV5_service.d.ts.map +0 -1
  166. package/dest/services/dummy_service.d.ts +0 -82
  167. package/dest/services/dummy_service.d.ts.map +0 -1
  168. package/dest/services/encoding.d.ts +0 -31
  169. package/dest/services/encoding.d.ts.map +0 -1
  170. package/dest/services/index.d.ts +0 -3
  171. package/dest/services/index.d.ts.map +0 -1
  172. package/dest/services/libp2p/libp2p_service.d.ts +0 -225
  173. package/dest/services/libp2p/libp2p_service.d.ts.map +0 -1
  174. package/dest/services/peer-manager/metrics.d.ts +0 -12
  175. package/dest/services/peer-manager/metrics.d.ts.map +0 -1
  176. package/dest/services/peer-manager/peer_manager.d.ts +0 -76
  177. package/dest/services/peer-manager/peer_manager.d.ts.map +0 -1
  178. package/dest/services/peer-manager/peer_scoring.d.ts +0 -28
  179. package/dest/services/peer-manager/peer_scoring.d.ts.map +0 -1
  180. package/dest/services/reqresp/config.d.ts +0 -16
  181. package/dest/services/reqresp/config.d.ts.map +0 -1
  182. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -45
  183. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  184. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +0 -61
  185. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +0 -1
  186. package/dest/services/reqresp/index.d.ts +0 -6
  187. package/dest/services/reqresp/index.d.ts.map +0 -1
  188. package/dest/services/reqresp/interface.d.ts +0 -107
  189. package/dest/services/reqresp/interface.d.ts.map +0 -1
  190. package/dest/services/reqresp/metrics.d.ts +0 -15
  191. package/dest/services/reqresp/metrics.d.ts.map +0 -1
  192. package/dest/services/reqresp/protocols/block.d.ts +0 -4
  193. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  194. package/dest/services/reqresp/protocols/goodbye.d.ts +0 -51
  195. package/dest/services/reqresp/protocols/goodbye.d.ts.map +0 -1
  196. package/dest/services/reqresp/protocols/index.d.ts +0 -9
  197. package/dest/services/reqresp/protocols/index.d.ts.map +0 -1
  198. package/dest/services/reqresp/protocols/ping.d.ts +0 -9
  199. package/dest/services/reqresp/protocols/ping.d.ts.map +0 -1
  200. package/dest/services/reqresp/protocols/status.d.ts +0 -9
  201. package/dest/services/reqresp/protocols/status.d.ts.map +0 -1
  202. package/dest/services/reqresp/protocols/tx.d.ts +0 -13
  203. package/dest/services/reqresp/protocols/tx.d.ts.map +0 -1
  204. package/dest/services/reqresp/rate-limiter/index.d.ts +0 -2
  205. package/dest/services/reqresp/rate-limiter/index.d.ts.map +0 -1
  206. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +0 -102
  207. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +0 -1
  208. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +0 -3
  209. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +0 -1
  210. package/dest/services/reqresp/reqresp.d.ts +0 -161
  211. package/dest/services/reqresp/reqresp.d.ts.map +0 -1
  212. package/dest/services/service.d.ts +0 -85
  213. package/dest/services/service.d.ts.map +0 -1
  214. package/dest/services/types.d.ts +0 -38
  215. package/dest/services/types.d.ts.map +0 -1
  216. package/dest/util.d.ts +0 -53
  217. package/dest/util.d.ts.map +0 -1
@@ -3,6 +3,8 @@ import { Fr } from '@aztec/foundation/fields';
3
3
 
4
4
  import { type PeerId } from '@libp2p/interface';
5
5
 
6
+ import { type ReqRespStatus } from './status.js';
7
+
6
8
  /*
7
9
  * Request Response Sub Protocols
8
10
  */
@@ -31,6 +33,15 @@ export type ReqRespSubProtocolHandler = (peerId: PeerId, msg: Buffer) => Promise
31
33
  */
32
34
  export type ReqRespSubProtocolRateLimits = Record<ReqRespSubProtocol, ProtocolRateLimitQuota>;
33
35
 
36
+ /**
37
+ * The response from the ReqResp protocol
38
+ * Consists of a status (Error code) and data
39
+ */
40
+ export interface ReqRespResponse {
41
+ status: ReqRespStatus;
42
+ data: Buffer;
43
+ }
44
+
34
45
  /**
35
46
  * A rate limit quota
36
47
  */
@@ -200,9 +200,11 @@ export class RequestResponseRateLimiter {
200
200
 
201
201
  switch (rateLimitStatus) {
202
202
  case RateLimitStatus.DeniedPeer:
203
- this.peerScoring.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
203
+ // Hitting a peer specific limit, we should lightly penalise the peer
204
+ this.peerScoring.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
204
205
  return false;
205
206
  case RateLimitStatus.DeniedGlobal:
207
+ // Hitting a global limit, we should not penalise the peer
206
208
  return false;
207
209
  default:
208
210
  return true;
@@ -25,11 +25,11 @@ export const DEFAULT_RATE_LIMITS: ReqRespSubProtocolRateLimits = {
25
25
  [ReqRespSubProtocol.TX]: {
26
26
  peerLimit: {
27
27
  quotaTimeMs: 1000,
28
- quotaCount: 5,
28
+ quotaCount: 10,
29
29
  },
30
30
  globalLimit: {
31
31
  quotaTimeMs: 1000,
32
- quotaCount: 10,
32
+ quotaCount: 20,
33
33
  },
34
34
  },
35
35
  [ReqRespSubProtocol.BLOCK]: {
@@ -22,7 +22,8 @@ import { ConnectionSampler } from './connection-sampler/connection_sampler.js';
22
22
  import {
23
23
  DEFAULT_SUB_PROTOCOL_HANDLERS,
24
24
  DEFAULT_SUB_PROTOCOL_VALIDATORS,
25
- type ReqRespSubProtocol,
25
+ type ReqRespResponse,
26
+ ReqRespSubProtocol,
26
27
  type ReqRespSubProtocolHandlers,
27
28
  type ReqRespSubProtocolValidators,
28
29
  type SubProtocolMap,
@@ -30,6 +31,7 @@ import {
30
31
  } from './interface.js';
31
32
  import { ReqRespMetrics } from './metrics.js';
32
33
  import { RequestResponseRateLimiter } from './rate-limiter/rate_limiter.js';
34
+ import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqRespStatus } from './status.js';
33
35
 
34
36
  /**
35
37
  * The Request Response Service
@@ -190,10 +192,17 @@ export class ReqResp {
190
192
  this.logger.trace(`Sending request to peer: ${peer.toString()}`);
191
193
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffer);
192
194
 
195
+ if (response && response.status !== ReqRespStatus.SUCCESS) {
196
+ this.logger.debug(
197
+ `Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(response.status)}`,
198
+ );
199
+ continue;
200
+ }
201
+
193
202
  // If we get a response, return it, otherwise we iterate onto the next peer
194
203
  // We do not consider it a success if we have an empty buffer
195
- if (response && response.length > 0) {
196
- const object = subProtocolMap[subProtocol].response.fromBuffer(response);
204
+ if (response && response.data.length > 0) {
205
+ const object = subProtocolMap[subProtocol].response.fromBuffer(response.data);
197
206
  // The response validator handles peer punishment within
198
207
  const isValid = await responseValidator(request, object, peer);
199
208
  if (!isValid) {
@@ -311,8 +320,22 @@ export class ReqResp {
311
320
  for (const index of indices) {
312
321
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]);
313
322
 
314
- if (response && response.length > 0) {
315
- const object = subProtocolMap[subProtocol].response.fromBuffer(response);
323
+ // Check the status of the response buffer
324
+ if (response && response.status !== ReqRespStatus.SUCCESS) {
325
+ this.logger.debug(
326
+ `Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(
327
+ response.status,
328
+ )}`,
329
+ );
330
+
331
+ // If we hit a rate limit or some failure, we remove the peer and return the results,
332
+ // they will be split among remaining peers and the new sampled peer
333
+ batchSampler.removePeerAndReplace(peer);
334
+ return { peer, results: peerResults };
335
+ }
336
+
337
+ if (response && response.data.length > 0) {
338
+ const object = subProtocolMap[subProtocol].response.fromBuffer(response.data);
316
339
  const isValid = await responseValidator(requests[index], object, peer);
317
340
 
318
341
  if (isValid) {
@@ -394,7 +417,7 @@ export class ReqResp {
394
417
  peerId: PeerId,
395
418
  subProtocol: ReqRespSubProtocol,
396
419
  payload: Buffer,
397
- ): Promise<Buffer | undefined> {
420
+ ): Promise<ReqRespResponse | undefined> {
398
421
  let stream: Stream | undefined;
399
422
  try {
400
423
  this.metrics.recordRequestSent(subProtocol);
@@ -402,8 +425,8 @@ export class ReqResp {
402
425
  stream = await this.connectionSampler.dialProtocol(peerId, subProtocol);
403
426
 
404
427
  // Open the stream with a timeout
405
- const result = await executeTimeout<Buffer>(
406
- (): Promise<Buffer> => pipe([payload], stream!, this.readMessage.bind(this)),
428
+ const result = await executeTimeout<ReqRespResponse>(
429
+ (): Promise<ReqRespResponse> => pipe([payload], stream!, this.readMessage.bind(this)),
407
430
  this.individualRequestTimeoutMs,
408
431
  () => new IndividualReqRespTimeoutError(),
409
432
  );
@@ -447,7 +470,15 @@ export class ReqResp {
447
470
  * Categorize the error and log it.
448
471
  */
449
472
  private categorizeError(e: any, peerId: PeerId, subProtocol: ReqRespSubProtocol): PeerErrorSeverity | undefined {
450
- // Non pubishable errors
473
+ // Non punishable errors - we do not expect a response for goodbye messages
474
+ if (subProtocol === ReqRespSubProtocol.GOODBYE) {
475
+ this.logger.debug('Error encountered on goodbye sub protocol, no penalty', {
476
+ peerId: peerId.toString(),
477
+ subProtocol,
478
+ });
479
+ return undefined;
480
+ }
481
+
451
482
  // We do not punish a collective timeout, as the node triggers this interupt, independent of the peer's behaviour
452
483
  const logTags = {
453
484
  peerId: peerId.toString(),
@@ -492,14 +523,45 @@ export class ReqResp {
492
523
 
493
524
  /**
494
525
  * Read a message returned from a stream into a single buffer
526
+ *
527
+ * The message is split into two components
528
+ * - The first chunk should contain a control byte, indicating the status of the response see `ReqRespStatus`
529
+ * - The second chunk should contain the response data
495
530
  */
496
- private async readMessage(source: AsyncIterable<Uint8ArrayList>): Promise<Buffer> {
531
+ private async readMessage(source: AsyncIterable<Uint8ArrayList>): Promise<ReqRespResponse> {
532
+ let statusBuffer: ReqRespStatus | undefined;
497
533
  const chunks: Uint8Array[] = [];
498
- for await (const chunk of source) {
499
- chunks.push(chunk.subarray());
534
+
535
+ try {
536
+ for await (const chunk of source) {
537
+ if (statusBuffer === undefined) {
538
+ const firstChunkBuffer = chunk.subarray();
539
+ statusBuffer = parseStatusChunk(firstChunkBuffer);
540
+ } else {
541
+ chunks.push(chunk.subarray());
542
+ }
543
+ }
544
+
545
+ const messageData = Buffer.concat(chunks);
546
+ const message: Buffer = this.snappyTransform.inboundTransformNoTopic(messageData);
547
+
548
+ return {
549
+ status: statusBuffer ?? ReqRespStatus.UNKNOWN,
550
+ data: message,
551
+ };
552
+ } catch (e: any) {
553
+ this.logger.debug(`Reading message failed: ${e.message}`);
554
+
555
+ let status = ReqRespStatus.UNKNOWN;
556
+ if (e instanceof ReqRespStatusError) {
557
+ status = e.status;
558
+ }
559
+
560
+ return {
561
+ status,
562
+ data: Buffer.from([]),
563
+ };
500
564
  }
501
- const messageData = Buffer.concat(chunks);
502
- return this.snappyTransform.inboundTransformNoTopic(messageData);
503
565
  }
504
566
 
505
567
  /**
@@ -525,25 +587,28 @@ export class ReqResp {
525
587
  private async streamHandler(protocol: ReqRespSubProtocol, { stream, connection }: IncomingStreamData) {
526
588
  this.metrics.recordRequestReceived(protocol);
527
589
 
528
- // Store a reference to from this for the async generator
529
- if (!this.rateLimiter.allow(protocol, connection.remotePeer)) {
530
- this.logger.warn(`Rate limit exceeded for ${protocol} from ${connection.remotePeer}`);
590
+ try {
591
+ // Store a reference to from this for the async generator
592
+ if (!this.rateLimiter.allow(protocol, connection.remotePeer)) {
593
+ this.logger.warn(`Rate limit exceeded for ${protocol} from ${connection.remotePeer}`);
531
594
 
532
- // TODO(#8483): handle changing peer scoring for failed rate limit, maybe differentiate between global and peer limits here when punishing
533
- await stream.close();
534
- return;
535
- }
595
+ throw new ReqRespStatusError(ReqRespStatus.RATE_LIMIT_EXCEEDED);
596
+ }
536
597
 
537
- const handler = this.subProtocolHandlers[protocol];
538
- const transform = this.snappyTransform;
598
+ const handler = this.subProtocolHandlers[protocol];
599
+ const transform = this.snappyTransform;
539
600
 
540
- try {
541
601
  await pipe(
542
602
  stream,
543
603
  async function* (source: any) {
544
604
  for await (const chunkList of source) {
545
605
  const msg = Buffer.from(chunkList.subarray());
546
606
  const response = await handler(connection.remotePeer, msg);
607
+
608
+ // Send success code first, then the response
609
+ const successChunk = Buffer.from([ReqRespStatus.SUCCESS]);
610
+ yield new Uint8Array(successChunk);
611
+
547
612
  yield new Uint8Array(transform.outboundTransformNoTopic(response));
548
613
  }
549
614
  },
@@ -552,8 +617,30 @@ export class ReqResp {
552
617
  } catch (e: any) {
553
618
  this.logger.warn(e);
554
619
  this.metrics.recordResponseError(protocol);
620
+
621
+ // If we receive a known error, we use the error status in the response chunk, otherwise we categorize as unknown
622
+ let errorStatus = ReqRespStatus.UNKNOWN;
623
+ if (e instanceof ReqRespStatusError) {
624
+ errorStatus = e.status;
625
+ }
626
+
627
+ const sendErrorChunk = this.sendErrorChunk(errorStatus);
628
+
629
+ // Return and yield the response chunk
630
+ await pipe(
631
+ stream,
632
+ async function* (_source: any) {
633
+ yield* sendErrorChunk;
634
+ },
635
+ stream,
636
+ );
555
637
  } finally {
556
638
  await stream.close();
557
639
  }
558
640
  }
641
+
642
+ private async *sendErrorChunk(error: ReqRespStatus): AsyncIterable<Uint8Array> {
643
+ const errorChunk = Buffer.from([error]);
644
+ yield new Uint8Array(errorChunk);
645
+ }
559
646
  }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The error codes for the ReqResp protocol
3
+ */
4
+ export enum ReqRespStatus {
5
+ SUCCESS = 0,
6
+ RATE_LIMIT_EXCEEDED = 1,
7
+ BADLY_FORMED_REQUEST = 2,
8
+ UNKNOWN = 127,
9
+ }
10
+
11
+ export class ReqRespStatusError extends Error {
12
+ /**
13
+ * The status code
14
+ */
15
+ status: ReqRespStatus;
16
+
17
+ constructor(status: ReqRespStatus) {
18
+ super(`ReqResp Error: ${prettyPrintReqRespStatus(status)}`);
19
+ this.status = status;
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Parse the status chunk
25
+ * @param chunk
26
+ * @returns
27
+ *
28
+ * @throws ReqRespStatusError if the chunk is not valid
29
+ */
30
+ export function parseStatusChunk(chunk: Uint8Array): ReqRespStatus {
31
+ if (chunk.length !== 1) {
32
+ throw new ReqRespStatusError(ReqRespStatus.UNKNOWN);
33
+ }
34
+
35
+ const status = chunk[0];
36
+ // Check if status is a valid ReqRespStatus value
37
+ if (!(status in ReqRespStatus)) {
38
+ throw new ReqRespStatusError(ReqRespStatus.UNKNOWN);
39
+ }
40
+ return status as ReqRespStatus;
41
+ }
42
+
43
+ /**
44
+ * Pretty print the ReqResp status
45
+ * @param status
46
+ * @returns
47
+ */
48
+ export function prettyPrintReqRespStatus(status: ReqRespStatus) {
49
+ switch (status) {
50
+ case ReqRespStatus.SUCCESS:
51
+ return 'SUCCESS';
52
+ case ReqRespStatus.RATE_LIMIT_EXCEEDED:
53
+ return 'RATE_LIMIT_EXCEEDED';
54
+ case ReqRespStatus.BADLY_FORMED_REQUEST:
55
+ return 'BADLY_FORMED_REQUEST';
56
+ case ReqRespStatus.UNKNOWN:
57
+ return 'UNKNOWN';
58
+ }
59
+ }
@@ -1,38 +0,0 @@
1
- import { type P2PBootstrapApi } from '@aztec/circuit-types/interfaces';
2
- import { type AztecAsyncKVStore } from '@aztec/kv-store';
3
- import { type TelemetryClient } from '@aztec/telemetry-client';
4
- import type { PeerId } from '@libp2p/interface';
5
- import type { BootnodeConfig } from '../config.js';
6
- /**
7
- * Encapsulates a 'Bootstrap' node, used for the purpose of assisting new joiners in acquiring peers.
8
- */
9
- export declare class BootstrapNode implements P2PBootstrapApi {
10
- private store;
11
- private telemetry;
12
- private logger;
13
- private node?;
14
- private peerId?;
15
- constructor(store: AztecAsyncKVStore, telemetry: TelemetryClient, logger?: import("@aztec/foundation/log").Logger);
16
- /**
17
- * Starts the bootstrap node.
18
- * @param config - A partial P2P configuration. No need for TCP values as well as aztec node specific values.
19
- * @returns An empty promise.
20
- */
21
- start(config: BootnodeConfig): Promise<void>;
22
- /**
23
- * Stops the bootstrap node.
24
- * @returns And empty promise.
25
- */
26
- stop(): Promise<void>;
27
- private assertNodeStarted;
28
- private assertPeerId;
29
- /**
30
- * Returns the peerId of this node.
31
- * @returns The node's peer Id
32
- */
33
- getPeerId(): PeerId;
34
- getENR(): any;
35
- getEncodedEnr(): Promise<any>;
36
- getRoutingTable(): Promise<any>;
37
- }
38
- //# sourceMappingURL=bootstrap.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/bootstrap/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAInF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD;;GAEG;AACH,qBAAa,aAAc,YAAW,eAAe;IAKjD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,IAAI,CAAC,CAA0C;IACvD,OAAO,CAAC,MAAM,CAAC,CAAS;gBAGd,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,eAAe,EAC1B,MAAM,yCAAgC;IAGhD;;;;OAIG;IACU,KAAK,CAAC,MAAM,EAAE,cAAc;IAgDzC;;;OAGG;IACU,IAAI;IAOjB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IAMpB;;;OAGG;IACI,SAAS;IAKT,MAAM;IAKN,aAAa;IAKb,eAAe;CAIvB"}
@@ -1,19 +0,0 @@
1
- import { type ClientProtocolCircuitVerifier, type L2BlockSource, P2PClientType, type WorldStateSynchronizer } from '@aztec/circuit-types';
2
- import { type EpochCache } from '@aztec/epoch-cache';
3
- import { type AztecAsyncKVStore } from '@aztec/kv-store';
4
- import { type DataStoreConfig } from '@aztec/kv-store/config';
5
- import { type TelemetryClient } from '@aztec/telemetry-client';
6
- import { P2PClient } from '../client/p2p_client.js';
7
- import { type P2PConfig } from '../config.js';
8
- import { type AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js';
9
- import { type EpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js';
10
- import { type TxPool } from '../mem_pools/tx_pool/index.js';
11
- type P2PClientDeps<T extends P2PClientType> = {
12
- txPool?: TxPool;
13
- store?: AztecAsyncKVStore;
14
- attestationPool?: T extends P2PClientType.Full ? AttestationPool : undefined;
15
- epochProofQuotePool?: EpochProofQuotePool;
16
- };
17
- export declare const createP2PClient: <T extends P2PClientType>(clientType: T, _config: P2PConfig & DataStoreConfig, l2BlockSource: L2BlockSource, proofVerifier: ClientProtocolCircuitVerifier, worldStateSynchronizer: WorldStateSynchronizer, epochCache: EpochCache, telemetry?: TelemetryClient, deps?: P2PClientDeps<T>) => Promise<P2PClient<T>>;
18
- export {};
19
- //# sourceMappingURL=factory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/client/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,aAAa,EAClB,aAAa,EACb,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAEnF,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAEzF,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,+DAA+D,CAAC;AAGzG,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAM3E,KAAK,aAAa,CAAC,CAAC,SAAS,aAAa,IAAI;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,eAAe,CAAC,EAAE,CAAC,SAAS,aAAa,CAAC,IAAI,GAAG,eAAe,GAAG,SAAS,CAAC;IAC7E,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C,CAAC;AAEF,eAAO,MAAM,eAAe,wCACd,CAAC,WACJ,SAAS,GAAG,eAAe,iBACrB,aAAa,iBACb,6BAA6B,0BACpB,sBAAsB,cAClC,UAAU,cACX,eAAe,SACpB,cAAc,CAAC,CAAC,0BA+CvB,CAAC"}
@@ -1,3 +0,0 @@
1
- export * from './p2p_client.js';
2
- export * from './factory.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC"}