@aztec/p2p 0.75.0 → 0.76.1

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 (102) hide show
  1. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  2. package/dest/bootstrap/bootstrap.js +9 -4
  3. package/dest/client/factory.d.ts +4 -2
  4. package/dest/client/factory.d.ts.map +1 -1
  5. package/dest/client/factory.js +4 -4
  6. package/dest/config.d.ts +30 -14
  7. package/dest/config.d.ts.map +1 -1
  8. package/dest/config.js +30 -14
  9. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +2 -2
  10. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  11. package/dest/msg_validators/attestation_validator/attestation_validator.js +1 -1
  12. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +2 -2
  13. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
  14. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +1 -1
  15. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts +2 -2
  16. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts.map +1 -1
  17. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.js +1 -1
  18. package/dest/services/discv5/discV5_service.d.ts +5 -1
  19. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  20. package/dest/services/discv5/discV5_service.js +65 -18
  21. package/dest/services/dummy_service.d.ts +1 -0
  22. package/dest/services/dummy_service.d.ts.map +1 -1
  23. package/dest/services/dummy_service.js +2 -1
  24. package/dest/services/libp2p/libp2p_logger.d.ts +7 -0
  25. package/dest/services/libp2p/libp2p_logger.d.ts.map +1 -0
  26. package/dest/services/libp2p/libp2p_logger.js +67 -0
  27. package/dest/services/libp2p/libp2p_service.d.ts +3 -3
  28. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  29. package/dest/services/libp2p/libp2p_service.js +42 -10
  30. package/dest/services/reqresp/interface.d.ts +9 -0
  31. package/dest/services/reqresp/interface.d.ts.map +1 -1
  32. package/dest/services/reqresp/interface.js +1 -1
  33. package/dest/services/reqresp/protocols/goodbye.js +2 -2
  34. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  35. package/dest/services/reqresp/rate-limiter/rate_limiter.js +4 -2
  36. package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -3
  37. package/dest/services/reqresp/reqresp.d.ts +7 -2
  38. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  39. package/dest/services/reqresp/reqresp.js +90 -21
  40. package/dest/services/reqresp/status.d.ts +31 -0
  41. package/dest/services/reqresp/status.d.ts.map +1 -0
  42. package/dest/services/reqresp/status.js +52 -0
  43. package/dest/services/service.d.ts +1 -0
  44. package/dest/services/service.d.ts.map +1 -1
  45. package/dest/services/types.d.ts +1 -7
  46. package/dest/services/types.d.ts.map +1 -1
  47. package/dest/services/types.js +2 -10
  48. package/dest/test-helpers/generate-peer-id-private-keys.d.ts +7 -0
  49. package/dest/test-helpers/generate-peer-id-private-keys.d.ts.map +1 -0
  50. package/dest/test-helpers/generate-peer-id-private-keys.js +15 -0
  51. package/dest/test-helpers/get-ports.d.ts +7 -0
  52. package/dest/test-helpers/get-ports.d.ts.map +1 -0
  53. package/dest/test-helpers/get-ports.js +8 -0
  54. package/dest/test-helpers/index.d.ts +6 -0
  55. package/dest/test-helpers/index.d.ts.map +1 -0
  56. package/dest/test-helpers/index.js +6 -0
  57. package/dest/test-helpers/make-enrs.d.ts +16 -0
  58. package/dest/test-helpers/make-enrs.d.ts.map +1 -0
  59. package/dest/test-helpers/make-enrs.js +35 -0
  60. package/dest/test-helpers/make-test-p2p-clients.d.ts +37 -0
  61. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -0
  62. package/dest/test-helpers/make-test-p2p-clients.js +71 -0
  63. package/dest/{mocks/index.d.ts → test-helpers/reqresp-nodes.d.ts} +6 -5
  64. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -0
  65. package/dest/test-helpers/reqresp-nodes.js +183 -0
  66. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -0
  67. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -0
  68. package/dest/testbench/p2p_client_testbench_worker.js +125 -0
  69. package/dest/versioning.d.ts +12 -0
  70. package/dest/versioning.d.ts.map +1 -0
  71. package/dest/versioning.js +38 -0
  72. package/package.json +10 -8
  73. package/src/bootstrap/bootstrap.ts +9 -3
  74. package/src/client/factory.ts +12 -5
  75. package/src/config.ts +56 -29
  76. package/src/msg_validators/attestation_validator/attestation_validator.ts +3 -3
  77. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +3 -3
  78. package/src/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.ts +3 -3
  79. package/src/services/discv5/discV5_service.ts +67 -18
  80. package/src/services/dummy_service.ts +2 -0
  81. package/src/services/libp2p/libp2p_logger.ts +78 -0
  82. package/src/services/libp2p/libp2p_service.ts +47 -10
  83. package/src/services/reqresp/interface.ts +11 -0
  84. package/src/services/reqresp/protocols/goodbye.ts +1 -1
  85. package/src/services/reqresp/rate-limiter/rate_limiter.ts +3 -1
  86. package/src/services/reqresp/rate-limiter/rate_limits.ts +2 -2
  87. package/src/services/reqresp/reqresp.ts +120 -25
  88. package/src/services/reqresp/status.ts +59 -0
  89. package/src/services/service.ts +2 -0
  90. package/src/services/types.ts +2 -10
  91. package/src/test-helpers/generate-peer-id-private-keys.ts +15 -0
  92. package/src/test-helpers/get-ports.ts +8 -0
  93. package/src/test-helpers/index.ts +5 -0
  94. package/src/test-helpers/make-enrs.ts +44 -0
  95. package/src/test-helpers/make-test-p2p-clients.ts +124 -0
  96. package/src/{mocks/index.ts → test-helpers/reqresp-nodes.ts} +10 -5
  97. package/src/testbench/README.md +20 -0
  98. package/src/testbench/p2p_client_testbench_worker.ts +156 -0
  99. package/src/testbench/scripts/run_testbench.sh +7 -0
  100. package/src/versioning.ts +50 -0
  101. package/dest/mocks/index.d.ts.map +0 -1
  102. package/dest/mocks/index.js +0 -181
@@ -9,9 +9,10 @@ import { CollectiveReqRespTimeoutError, IndividualReqRespTimeoutError, InvalidRe
9
9
  import { SnappyTransform } from '../encoding.js';
10
10
  import { BatchConnectionSampler } from './connection-sampler/batch_connection_sampler.js';
11
11
  import { ConnectionSampler } from './connection-sampler/connection_sampler.js';
12
- import { DEFAULT_SUB_PROTOCOL_HANDLERS, DEFAULT_SUB_PROTOCOL_VALIDATORS, subProtocolMap, } from './interface.js';
12
+ import { DEFAULT_SUB_PROTOCOL_HANDLERS, DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, subProtocolMap, } from './interface.js';
13
13
  import { ReqRespMetrics } from './metrics.js';
14
14
  import { RequestResponseRateLimiter } from './rate-limiter/rate_limiter.js';
15
+ import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqRespStatus } from './status.js';
15
16
  /**
16
17
  * The Request Response Service
17
18
  *
@@ -133,10 +134,14 @@ let ReqResp = (() => {
133
134
  attemptedPeers.set(peer.toString(), true);
134
135
  this.logger.trace(`Sending request to peer: ${peer.toString()}`);
135
136
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffer);
137
+ if (response && response.status !== ReqRespStatus.SUCCESS) {
138
+ this.logger.debug(`Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(response.status)}`);
139
+ continue;
140
+ }
136
141
  // If we get a response, return it, otherwise we iterate onto the next peer
137
142
  // We do not consider it a success if we have an empty buffer
138
- if (response && response.length > 0) {
139
- const object = subProtocolMap[subProtocol].response.fromBuffer(response);
143
+ if (response && response.data.length > 0) {
144
+ const object = subProtocolMap[subProtocol].response.fromBuffer(response.data);
140
145
  // The response validator handles peer punishment within
141
146
  const isValid = await responseValidator(request, object, peer);
142
147
  if (!isValid) {
@@ -222,8 +227,16 @@ let ReqResp = (() => {
222
227
  const peerResults = [];
223
228
  for (const index of indices) {
224
229
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]);
225
- if (response && response.length > 0) {
226
- const object = subProtocolMap[subProtocol].response.fromBuffer(response);
230
+ // Check the status of the response buffer
231
+ if (response && response.status !== ReqRespStatus.SUCCESS) {
232
+ this.logger.debug(`Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(response.status)}`);
233
+ // If we hit a rate limit or some failure, we remove the peer and return the results,
234
+ // they will be split among remaining peers and the new sampled peer
235
+ batchSampler.removePeerAndReplace(peer);
236
+ return { peer, results: peerResults };
237
+ }
238
+ if (response && response.data.length > 0) {
239
+ const object = subProtocolMap[subProtocol].response.fromBuffer(response.data);
227
240
  const isValid = await responseValidator(requests[index], object, peer);
228
241
  if (isValid) {
229
242
  peerResults.push({ index, response: object });
@@ -331,7 +344,14 @@ let ReqResp = (() => {
331
344
  * Categorize the error and log it.
332
345
  */
333
346
  categorizeError(e, peerId, subProtocol) {
334
- // Non pubishable errors
347
+ // Non punishable errors - we do not expect a response for goodbye messages
348
+ if (subProtocol === ReqRespSubProtocol.GOODBYE) {
349
+ this.logger.debug('Error encountered on goodbye sub protocol, no penalty', {
350
+ peerId: peerId.toString(),
351
+ subProtocol,
352
+ });
353
+ return undefined;
354
+ }
335
355
  // We do not punish a collective timeout, as the node triggers this interupt, independent of the peer's behaviour
336
356
  const logTags = {
337
357
  peerId: peerId.toString(),
@@ -365,14 +385,42 @@ let ReqResp = (() => {
365
385
  }
366
386
  /**
367
387
  * Read a message returned from a stream into a single buffer
388
+ *
389
+ * The message is split into two components
390
+ * - The first chunk should contain a control byte, indicating the status of the response see `ReqRespStatus`
391
+ * - The second chunk should contain the response data
368
392
  */
369
393
  async readMessage(source) {
394
+ let statusBuffer;
370
395
  const chunks = [];
371
- for await (const chunk of source) {
372
- chunks.push(chunk.subarray());
396
+ try {
397
+ for await (const chunk of source) {
398
+ if (statusBuffer === undefined) {
399
+ const firstChunkBuffer = chunk.subarray();
400
+ statusBuffer = parseStatusChunk(firstChunkBuffer);
401
+ }
402
+ else {
403
+ chunks.push(chunk.subarray());
404
+ }
405
+ }
406
+ const messageData = Buffer.concat(chunks);
407
+ const message = this.snappyTransform.inboundTransformNoTopic(messageData);
408
+ return {
409
+ status: statusBuffer ?? ReqRespStatus.UNKNOWN,
410
+ data: message,
411
+ };
412
+ }
413
+ catch (e) {
414
+ this.logger.debug(`Reading message failed: ${e.message}`);
415
+ let status = ReqRespStatus.UNKNOWN;
416
+ if (e instanceof ReqRespStatusError) {
417
+ status = e.status;
418
+ }
419
+ return {
420
+ status,
421
+ data: Buffer.from([]),
422
+ };
373
423
  }
374
- const messageData = Buffer.concat(chunks);
375
- return this.snappyTransform.inboundTransformNoTopic(messageData);
376
424
  }
377
425
  /**
378
426
  * Stream Handler
@@ -392,32 +440,53 @@ let ReqResp = (() => {
392
440
  */
393
441
  async streamHandler(protocol, { stream, connection }) {
394
442
  this.metrics.recordRequestReceived(protocol);
395
- // Store a reference to from this for the async generator
396
- if (!this.rateLimiter.allow(protocol, connection.remotePeer)) {
397
- this.logger.warn(`Rate limit exceeded for ${protocol} from ${connection.remotePeer}`);
398
- // TODO(#8483): handle changing peer scoring for failed rate limit, maybe differentiate between global and peer limits here when punishing
399
- await stream.close();
400
- return;
401
- }
402
- const handler = this.subProtocolHandlers[protocol];
403
- const transform = this.snappyTransform;
404
443
  try {
444
+ // Store a reference to from this for the async generator
445
+ if (!this.rateLimiter.allow(protocol, connection.remotePeer)) {
446
+ this.logger.warn(`Rate limit exceeded for ${protocol} from ${connection.remotePeer}`);
447
+ throw new ReqRespStatusError(ReqRespStatus.RATE_LIMIT_EXCEEDED);
448
+ }
449
+ const handler = this.subProtocolHandlers[protocol];
450
+ const transform = this.snappyTransform;
451
+ this.logger.info(`Stream handler for ${protocol}`);
405
452
  await pipe(stream, async function* (source) {
406
453
  for await (const chunkList of source) {
407
454
  const msg = Buffer.from(chunkList.subarray());
408
455
  const response = await handler(connection.remotePeer, msg);
456
+ if (protocol === ReqRespSubProtocol.GOODBYE) {
457
+ // Don't respond
458
+ await stream.close();
459
+ return;
460
+ }
461
+ // Send success code first, then the response
462
+ const successChunk = Buffer.from([ReqRespStatus.SUCCESS]);
463
+ yield new Uint8Array(successChunk);
409
464
  yield new Uint8Array(transform.outboundTransformNoTopic(response));
410
465
  }
411
466
  }, stream);
412
467
  }
413
468
  catch (e) {
414
- this.logger.warn(e);
469
+ this.logger.warn('Reqresp Response error: ', e);
415
470
  this.metrics.recordResponseError(protocol);
471
+ // If we receive a known error, we use the error status in the response chunk, otherwise we categorize as unknown
472
+ let errorStatus = ReqRespStatus.UNKNOWN;
473
+ if (e instanceof ReqRespStatusError) {
474
+ errorStatus = e.status;
475
+ }
476
+ const sendErrorChunk = this.sendErrorChunk(errorStatus);
477
+ // Return and yield the response chunk
478
+ await pipe(stream, async function* (_source) {
479
+ yield* sendErrorChunk;
480
+ }, stream);
416
481
  }
417
482
  finally {
418
483
  await stream.close();
419
484
  }
420
485
  }
486
+ async *sendErrorChunk(error) {
487
+ const errorChunk = Buffer.from([error]);
488
+ yield new Uint8Array(errorChunk);
489
+ }
421
490
  },
422
491
  (() => {
423
492
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
@@ -441,4 +510,4 @@ let ReqResp = (() => {
441
510
  _a;
442
511
  })();
443
512
  export { ReqResp };
444
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9yZXFyZXNwL3JlcXJlc3AudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhDQUE4QztBQUM5QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN6RCxPQUFPLEVBQWUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxVQUFVLEVBQXdCLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRzFHLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFJL0IsT0FBTyxFQUNMLDZCQUE2QixFQUM3Qiw2QkFBNkIsRUFDN0Isb0JBQW9CLEdBQ3JCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR2pELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQzFGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQy9FLE9BQU8sRUFDTCw2QkFBNkIsRUFDN0IsK0JBQStCLEVBSy9CLGNBQWMsR0FDZixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDOUMsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFNUU7Ozs7Ozs7Ozs7Ozs7R0FhRztJQUNVLE9BQU87Ozs7OztzQkFBUCxPQUFPO1lBaUJsQixZQUNFLE1BQXdCLEVBQ2hCLE1BQWMsRUFDZCxXQUF3QixFQUNoQyxrQkFBbUMsa0JBQWtCLEVBQUU7Z0JBRi9DLFdBQU0sSUFuQkwsbURBQU8sRUFtQlIsTUFBTSxFQUFRO2dCQUNkLGdC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
513
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9yZXFyZXNwL3JlcXJlc3AudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhDQUE4QztBQUM5QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN6RCxPQUFPLEVBQWUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxVQUFVLEVBQXdCLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRzFHLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFJL0IsT0FBTyxFQUNMLDZCQUE2QixFQUM3Qiw2QkFBNkIsRUFDN0Isb0JBQW9CLEdBQ3JCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR2pELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQzFGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQy9FLE9BQU8sRUFDTCw2QkFBNkIsRUFDN0IsK0JBQStCLEVBRS9CLGtCQUFrQixFQUlsQixjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzlDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFNUc7Ozs7Ozs7Ozs7Ozs7R0FhRztJQUNVLE9BQU87Ozs7OztzQkFBUCxPQUFPO1lBaUJsQixZQUNFLE1BQXdCLEVBQ2hC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
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The error codes for the ReqResp protocol
3
+ */
4
+ export declare enum ReqRespStatus {
5
+ SUCCESS = 0,
6
+ RATE_LIMIT_EXCEEDED = 1,
7
+ BADLY_FORMED_REQUEST = 2,
8
+ UNKNOWN = 127
9
+ }
10
+ export declare class ReqRespStatusError extends Error {
11
+ /**
12
+ * The status code
13
+ */
14
+ status: ReqRespStatus;
15
+ constructor(status: ReqRespStatus);
16
+ }
17
+ /**
18
+ * Parse the status chunk
19
+ * @param chunk
20
+ * @returns
21
+ *
22
+ * @throws ReqRespStatusError if the chunk is not valid
23
+ */
24
+ export declare function parseStatusChunk(chunk: Uint8Array): ReqRespStatus;
25
+ /**
26
+ * Pretty print the ReqResp status
27
+ * @param status
28
+ * @returns
29
+ */
30
+ export declare function prettyPrintReqRespStatus(status: ReqRespStatus): "SUCCESS" | "RATE_LIMIT_EXCEEDED" | "BADLY_FORMED_REQUEST" | "UNKNOWN";
31
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,aAAa;IACvB,OAAO,IAAI;IACX,mBAAmB,IAAI;IACvB,oBAAoB,IAAI;IACxB,OAAO,MAAM;CACd;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;gBAEV,MAAM,EAAE,aAAa;CAIlC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAWjE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,0EAW7D"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The error codes for the ReqResp protocol
3
+ */
4
+ export var ReqRespStatus;
5
+ (function (ReqRespStatus) {
6
+ ReqRespStatus[ReqRespStatus["SUCCESS"] = 0] = "SUCCESS";
7
+ ReqRespStatus[ReqRespStatus["RATE_LIMIT_EXCEEDED"] = 1] = "RATE_LIMIT_EXCEEDED";
8
+ ReqRespStatus[ReqRespStatus["BADLY_FORMED_REQUEST"] = 2] = "BADLY_FORMED_REQUEST";
9
+ ReqRespStatus[ReqRespStatus["UNKNOWN"] = 127] = "UNKNOWN";
10
+ })(ReqRespStatus || (ReqRespStatus = {}));
11
+ export class ReqRespStatusError extends Error {
12
+ constructor(status) {
13
+ super(`ReqResp Error: ${prettyPrintReqRespStatus(status)}`);
14
+ this.status = status;
15
+ }
16
+ }
17
+ /**
18
+ * Parse the status chunk
19
+ * @param chunk
20
+ * @returns
21
+ *
22
+ * @throws ReqRespStatusError if the chunk is not valid
23
+ */
24
+ export function parseStatusChunk(chunk) {
25
+ if (chunk.length !== 1) {
26
+ throw new ReqRespStatusError(ReqRespStatus.UNKNOWN);
27
+ }
28
+ const status = chunk[0];
29
+ // Check if status is a valid ReqRespStatus value
30
+ if (!(status in ReqRespStatus)) {
31
+ throw new ReqRespStatusError(ReqRespStatus.UNKNOWN);
32
+ }
33
+ return status;
34
+ }
35
+ /**
36
+ * Pretty print the ReqResp status
37
+ * @param status
38
+ * @returns
39
+ */
40
+ export function prettyPrintReqRespStatus(status) {
41
+ switch (status) {
42
+ case ReqRespStatus.SUCCESS:
43
+ return 'SUCCESS';
44
+ case ReqRespStatus.RATE_LIMIT_EXCEEDED:
45
+ return 'RATE_LIMIT_EXCEEDED';
46
+ case ReqRespStatus.BADLY_FORMED_REQUEST:
47
+ return 'BADLY_FORMED_REQUEST';
48
+ case ReqRespStatus.UNKNOWN:
49
+ return 'UNKNOWN';
50
+ }
51
+ }
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdHVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2VzL3JlcXJlc3Avc3RhdHVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksYUFLWDtBQUxELFdBQVksYUFBYTtJQUN2Qix1REFBVyxDQUFBO0lBQ1gsK0VBQXVCLENBQUE7SUFDdkIsaUZBQXdCLENBQUE7SUFDeEIseURBQWEsQ0FBQTtBQUNmLENBQUMsRUFMVyxhQUFhLEtBQWIsYUFBYSxRQUt4QjtBQUVELE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxLQUFLO0lBTTNDLFlBQVksTUFBcUI7UUFDL0IsS0FBSyxDQUFDLGtCQUFrQix3QkFBd0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztDQUNGO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEtBQWlCO0lBQ2hELElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksa0JBQWtCLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEIsaURBQWlEO0lBQ2pELElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUMsRUFBRSxDQUFDO1FBQy9CLE1BQU0sSUFBSSxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUNELE9BQU8sTUFBdUIsQ0FBQztBQUNqQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxNQUFxQjtJQUM1RCxRQUFRLE1BQU0sRUFBRSxDQUFDO1FBQ2YsS0FBSyxhQUFhLENBQUMsT0FBTztZQUN4QixPQUFPLFNBQVMsQ0FBQztRQUNuQixLQUFLLGFBQWEsQ0FBQyxtQkFBbUI7WUFDcEMsT0FBTyxxQkFBcUIsQ0FBQztRQUMvQixLQUFLLGFBQWEsQ0FBQyxvQkFBb0I7WUFDckMsT0FBTyxzQkFBc0IsQ0FBQztRQUNoQyxLQUFLLGFBQWEsQ0FBQyxPQUFPO1lBQ3hCLE9BQU8sU0FBUyxDQUFDO0lBQ3JCLENBQUM7QUFDSCxDQUFDIn0=
@@ -81,5 +81,6 @@ export interface PeerDiscoveryService extends EventEmitter {
81
81
  emit(event: 'peer:discovered', enr: ENR): boolean;
82
82
  getStatus(): PeerDiscoveryState;
83
83
  getEnr(): ENR | undefined;
84
+ bootstrapNodes: string[];
84
85
  }
85
86
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAElG,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEtF,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAElD;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,SAAS,kBAAkB,EAC7C,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,gBAAgB,CAAC,QAAQ,SAAS,kBAAkB,EAClD,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAC5D,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;IAG7E,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;IAE/G,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;IAE1B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;SAEK;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;SAEK;IACL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,IAAI,GAAG,EAAE,CAAC;IAErB;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;IAElD,SAAS,IAAI,kBAAkB,CAAC;IAEhC,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;CAC3B"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAElG,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEtF,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAElD;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,SAAS,kBAAkB,EAC7C,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,gBAAgB,CAAC,QAAQ,SAAS,kBAAkB,EAClD,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAC5D,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;IAG7E,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;IAE/G,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;IAE1B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;SAEK;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;SAEK;IACL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,IAAI,GAAG,EAAE,CAAC;IAErB;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;IAElD,SAAS,IAAI,kBAAkB,CAAC;IAEhC,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;IAE1B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B"}
@@ -28,11 +28,5 @@ export declare enum GossipSubEvent {
28
28
  /**
29
29
  * Aztec network specific types
30
30
  */
31
- export declare const AZTEC_ENR_KEY = "aztec_network";
32
- export declare enum AztecENR {
33
- devnet = 1,
34
- testnet = 2,
35
- mainnet = 3
36
- }
37
- export declare const AZTEC_NET = AztecENR.devnet;
31
+ export declare const AZTEC_ENR_KEY = "aztec";
38
32
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/services/types.ts"],"names":[],"mappings":"AAAA;;qDAEqD;AAErD;;GAEG;AACH,oBAAY,SAAS;IACnB,UAAU,oBAAoB;IAC9B,SAAS,iBAAiB;IAC1B,YAAY,oBAAoB;CACjC;AAED;;GAEG;AACH,oBAAY,WAAW;IACrB,UAAU,eAAe;IACzB,SAAS,aAAa;CACvB;AAED;;GAEG;AACH,oBAAY,cAAc;IACxB,OAAO,sBAAsB;CAC9B;AAED;;qDAEqD;AACrD;;GAEG;AACH,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,oBAAY,QAAQ;IAClB,MAAM,IAAO;IACb,OAAO,IAAO;IACd,OAAO,IAAO;CACf;AAGD,eAAO,MAAM,SAAS,kBAAkB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/services/types.ts"],"names":[],"mappings":"AAAA;;qDAEqD;AAErD;;GAEG;AACH,oBAAY,SAAS;IACnB,UAAU,oBAAoB;IAC9B,SAAS,iBAAiB;IAC1B,YAAY,oBAAoB;CACjC;AAED;;GAEG;AACH,oBAAY,WAAW;IACrB,UAAU,eAAe;IACzB,SAAS,aAAa;CACvB;AAED;;GAEG;AACH,oBAAY,cAAc;IACxB,OAAO,sBAAsB;CAC9B;AAED;;qDAEqD;AAErD;;GAEG;AACH,eAAO,MAAM,aAAa,UAAU,CAAC"}
@@ -31,13 +31,5 @@ export var GossipSubEvent;
31
31
  /**
32
32
  * Aztec network specific types
33
33
  */
34
- export const AZTEC_ENR_KEY = 'aztec_network';
35
- export var AztecENR;
36
- (function (AztecENR) {
37
- AztecENR[AztecENR["devnet"] = 1] = "devnet";
38
- AztecENR[AztecENR["testnet"] = 2] = "testnet";
39
- AztecENR[AztecENR["mainnet"] = 3] = "mainnet";
40
- })(AztecENR || (AztecENR = {}));
41
- // TODO: Make this an env var
42
- export const AZTEC_NET = AztecENR.devnet;
43
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O3FEQUVxRDtBQUVyRDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLFNBSVg7QUFKRCxXQUFZLFNBQVM7SUFDbkIsMkNBQThCLENBQUE7SUFDOUIsdUNBQTBCLENBQUE7SUFDMUIsNkNBQWdDLENBQUE7QUFDbEMsQ0FBQyxFQUpXLFNBQVMsS0FBVCxTQUFTLFFBSXBCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxXQUdYO0FBSEQsV0FBWSxXQUFXO0lBQ3JCLHdDQUF5QixDQUFBO0lBQ3pCLHFDQUFzQixDQUFBO0FBQ3hCLENBQUMsRUFIVyxXQUFXLEtBQVgsV0FBVyxRQUd0QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksY0FFWDtBQUZELFdBQVksY0FBYztJQUN4QiwrQ0FBNkIsQ0FBQTtBQUMvQixDQUFDLEVBRlcsY0FBYyxLQUFkLGNBQWMsUUFFekI7QUFFRDs7cURBRXFEO0FBQ3JEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLGVBQWUsQ0FBQztBQUU3QyxNQUFNLENBQU4sSUFBWSxRQUlYO0FBSkQsV0FBWSxRQUFRO0lBQ2xCLDJDQUFhLENBQUE7SUFDYiw2Q0FBYyxDQUFBO0lBQ2QsNkNBQWMsQ0FBQTtBQUNoQixDQUFDLEVBSlcsUUFBUSxLQUFSLFFBQVEsUUFJbkI7QUFFRCw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMifQ==
34
+ export const AZTEC_ENR_KEY = 'aztec';
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O3FEQUVxRDtBQUVyRDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLFNBSVg7QUFKRCxXQUFZLFNBQVM7SUFDbkIsMkNBQThCLENBQUE7SUFDOUIsdUNBQTBCLENBQUE7SUFDMUIsNkNBQWdDLENBQUE7QUFDbEMsQ0FBQyxFQUpXLFNBQVMsS0FBVCxTQUFTLFFBSXBCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxXQUdYO0FBSEQsV0FBWSxXQUFXO0lBQ3JCLHdDQUF5QixDQUFBO0lBQ3pCLHFDQUFzQixDQUFBO0FBQ3hCLENBQUMsRUFIVyxXQUFXLEtBQVgsV0FBVyxRQUd0QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksY0FFWDtBQUZELFdBQVksY0FBYztJQUN4QiwrQ0FBNkIsQ0FBQTtBQUMvQixDQUFDLEVBRlcsY0FBYyxLQUFkLGNBQWMsUUFFekI7QUFFRDs7cURBRXFEO0FBRXJEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyJ9
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Generate a list of peer id private keys
3
+ * @param numberOfPeers - The number of peer id private keys to generate
4
+ * @returns A list of peer id private keys
5
+ */
6
+ export declare function generatePeerIdPrivateKeys(numberOfPeers: number): string[];
7
+ //# sourceMappingURL=generate-peer-id-private-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-peer-id-private-keys.d.ts","sourceRoot":"","sources":["../../src/test-helpers/generate-peer-id-private-keys.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAOzE"}
@@ -0,0 +1,15 @@
1
+ import { generatePrivateKey } from 'viem/accounts';
2
+ /**
3
+ * Generate a list of peer id private keys
4
+ * @param numberOfPeers - The number of peer id private keys to generate
5
+ * @returns A list of peer id private keys
6
+ */
7
+ export function generatePeerIdPrivateKeys(numberOfPeers) {
8
+ const peerIdPrivateKeys = [];
9
+ for (let i = 0; i < numberOfPeers; i++) {
10
+ // magic number is multiaddr prefix: https://multiformats.io/multiaddr/
11
+ peerIdPrivateKeys.push('08021220' + generatePrivateKey().slice(2, 68));
12
+ }
13
+ return peerIdPrivateKeys;
14
+ }
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGUtcGVlci1pZC1wcml2YXRlLWtleXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC1oZWxwZXJzL2dlbmVyYXRlLXBlZXItaWQtcHJpdmF0ZS1rZXlzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLHlCQUF5QixDQUFDLGFBQXFCO0lBQzdELE1BQU0saUJBQWlCLEdBQWEsRUFBRSxDQUFDO0lBQ3ZDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN2Qyx1RUFBdUU7UUFDdkUsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxrQkFBa0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBQ0QsT0FBTyxpQkFBaUIsQ0FBQztBQUMzQixDQUFDIn0=
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Get a list of ports for a given number of peers
3
+ * @param numberOfPeers - The number of peers to get ports for
4
+ * @returns A list of ports
5
+ */
6
+ export declare const getPorts: (numberOfPeers: number) => Promise<number[]>;
7
+ //# sourceMappingURL=get-ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-ports.d.ts","sourceRoot":"","sources":["../../src/test-helpers/get-ports.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,QAAQ,kBAAmB,MAAM,sBAAwE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import getPort from 'get-port';
2
+ /**
3
+ * Get a list of ports for a given number of peers
4
+ * @param numberOfPeers - The number of peers to get ports for
5
+ * @returns A list of ports
6
+ */
7
+ export const getPorts = (numberOfPeers) => Promise.all(Array.from({ length: numberOfPeers }, () => getPort()));
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXBvcnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QtaGVscGVycy9nZXQtcG9ydHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxPQUFPLE1BQU0sVUFBVSxDQUFDO0FBRS9COzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxhQUFxQixFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDIn0=
@@ -0,0 +1,6 @@
1
+ export * from './generate-peer-id-private-keys.js';
2
+ export * from './get-ports.js';
3
+ export * from './make-enrs.js';
4
+ export * from './make-test-p2p-clients.js';
5
+ export * from './reqresp-nodes.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-helpers/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './generate-peer-id-private-keys.js';
2
+ export * from './get-ports.js';
3
+ export * from './make-enrs.js';
4
+ export * from './make-test-p2p-clients.js';
5
+ export * from './reqresp-nodes.js';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC1oZWxwZXJzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsb0NBQW9DLENBQUM7QUFDbkQsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGdCQUFnQixDQUFDO0FBQy9CLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyxvQkFBb0IsQ0FBQyJ9
@@ -0,0 +1,16 @@
1
+ import { type ChainConfig } from '@aztec/circuit-types/config';
2
+ /**
3
+ * Make a list of ENRs for a given list of p2p private keys and ports
4
+ * @param p2pPrivateKeys - The private keys of the p2p nodes
5
+ * @param ports - The ports of the p2p nodes
6
+ * @returns A list of ENRs
7
+ */
8
+ export declare function makeEnrs(p2pPrivateKeys: string[], ports: number[], config: ChainConfig): Promise<string[]>;
9
+ /**
10
+ * Make an ENR for a given p2p private key and port
11
+ * @param p2pPrivateKey - The private key of the p2p node
12
+ * @param port - The port of the p2p node
13
+ * @returns The ENR of the p2p node
14
+ */
15
+ export declare function makeEnr(p2pPrivateKey: string, port: number, config: ChainConfig): Promise<string>;
16
+ //# sourceMappingURL=make-enrs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-enrs.d.ts","sourceRoot":"","sources":["../../src/test-helpers/make-enrs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAQ/D;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,qBAM5F;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,mBAerF"}
@@ -0,0 +1,35 @@
1
+ import { SignableENR } from '@chainsafe/enr';
2
+ import { multiaddr } from '@multiformats/multiaddr';
3
+ import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js';
4
+ import { setAztecEnrKey } from '../versioning.js';
5
+ /**
6
+ * Make a list of ENRs for a given list of p2p private keys and ports
7
+ * @param p2pPrivateKeys - The private keys of the p2p nodes
8
+ * @param ports - The ports of the p2p nodes
9
+ * @returns A list of ENRs
10
+ */
11
+ export async function makeEnrs(p2pPrivateKeys, ports, config) {
12
+ return await Promise.all(p2pPrivateKeys.map((pk, i) => {
13
+ return makeEnr(pk, ports[i], config);
14
+ }));
15
+ }
16
+ /**
17
+ * Make an ENR for a given p2p private key and port
18
+ * @param p2pPrivateKey - The private key of the p2p node
19
+ * @param port - The port of the p2p node
20
+ * @returns The ENR of the p2p node
21
+ */
22
+ export async function makeEnr(p2pPrivateKey, port, config) {
23
+ const peerId = await createLibP2PPeerIdFromPrivateKey(p2pPrivateKey);
24
+ const enr = SignableENR.createFromPeerId(peerId);
25
+ const udpAnnounceAddress = `127.0.0.1:${port}`;
26
+ const tcpAnnounceAddress = `127.0.0.1:${port}`;
27
+ const udpPublicAddr = multiaddr(convertToMultiaddr(udpAnnounceAddress, 'udp'));
28
+ const tcpPublicAddr = multiaddr(convertToMultiaddr(tcpAnnounceAddress, 'tcp'));
29
+ // ENRS must include the network and a discoverable address (udp for discv5)
30
+ setAztecEnrKey(enr, config);
31
+ enr.setLocationMultiaddr(udpPublicAddr);
32
+ enr.setLocationMultiaddr(tcpPublicAddr);
33
+ return enr.encodeTxt();
34
+ }
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFrZS1lbnJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QtaGVscGVycy9tYWtlLWVucnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDbEYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWxEOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxRQUFRLENBQUMsY0FBd0IsRUFBRSxLQUFlLEVBQUUsTUFBbUI7SUFDM0YsT0FBTyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ3RCLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDM0IsT0FBTyxPQUFPLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN2QyxDQUFDLENBQUMsQ0FDSCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxPQUFPLENBQUMsYUFBcUIsRUFBRSxJQUFZLEVBQUUsTUFBbUI7SUFDcEYsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQ0FBZ0MsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNyRSxNQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFakQsTUFBTSxrQkFBa0IsR0FBRyxhQUFhLElBQUksRUFBRSxDQUFDO0lBQy9DLE1BQU0sa0JBQWtCLEdBQUcsYUFBYSxJQUFJLEVBQUUsQ0FBQztJQUMvQyxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMvRSxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUUvRSw0RUFBNEU7SUFDNUUsY0FBYyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM1QixHQUFHLENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDeEMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRXhDLE9BQU8sR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3pCLENBQUMifQ==
@@ -0,0 +1,37 @@
1
+ import { P2PClientType, type WorldStateSynchronizer } from '@aztec/circuit-types';
2
+ import { type EpochCache } from '@aztec/epoch-cache';
3
+ import { type Logger } from '@aztec/foundation/log';
4
+ import { type P2PClient } from '../client/p2p_client.js';
5
+ import { type P2PConfig } from '../config.js';
6
+ import { type AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js';
7
+ import { type EpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js';
8
+ import { type TxPool } from '../mem_pools/tx_pool/index.js';
9
+ interface MakeTestP2PClientOptions {
10
+ mockAttestationPool: AttestationPool;
11
+ mockEpochProofQuotePool: EpochProofQuotePool;
12
+ mockTxPool: TxPool;
13
+ mockEpochCache: EpochCache;
14
+ mockWorldState: WorldStateSynchronizer;
15
+ alwaysTrueVerifier?: boolean;
16
+ p2pBaseConfig: P2PConfig;
17
+ p2pConfigOverrides?: Partial<P2PConfig>;
18
+ logger?: Logger;
19
+ }
20
+ /**
21
+ * Creates a single P2P client for testing purposes.
22
+ * @param peerIdPrivateKey - The private key of the peer.
23
+ * @param port - The port to run the client on.
24
+ * @param peers - The peers to connect to.
25
+ * @param options - The options for the client.
26
+ * @returns The created client.
27
+ */
28
+ export declare function makeTestP2PClient(peerIdPrivateKey: string, port: number, peers: string[], { alwaysTrueVerifier, p2pBaseConfig, p2pConfigOverrides, mockAttestationPool, mockEpochProofQuotePool, mockTxPool, mockEpochCache, mockWorldState, logger, }: MakeTestP2PClientOptions): Promise<P2PClient<P2PClientType.Full>>;
29
+ /**
30
+ * Creates a number of P2P clients for testing purposes.
31
+ * @param numberOfPeers - The number of clients to create.
32
+ * @param options - The options for the clients.
33
+ * @returns The created clients.
34
+ */
35
+ export declare function makeTestP2PClients(numberOfPeers: number, testConfig: MakeTestP2PClientOptions): Promise<P2PClient<P2PClientType.Full>[]>;
36
+ export {};
37
+ //# sourceMappingURL=make-test-p2p-clients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-test-p2p-clients.d.ts","sourceRoot":"","sources":["../../src/test-helpers/make-test-p2p-clients.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAKlE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACzF,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,+DAA+D,CAAC;AACzG,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAM5D,UAAU,wBAAwB;IAChC,mBAAmB,EAAE,eAAe,CAAC;IACrC,uBAAuB,EAAE,mBAAmB,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,sBAAsB,CAAC;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,EAAE,SAAS,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,EACE,kBAAyB,EACzB,aAAa,EACb,kBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,UAAU,EACV,cAAc,EACd,cAAc,EACd,MAAwC,GACzC,EAAE,wBAAwB,0CA8C5B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB,4CAiBnG"}