@aztec/p2p 0.51.0 → 0.52.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 (36) hide show
  1. package/dest/client/index.d.ts.map +1 -1
  2. package/dest/client/index.js +1 -1
  3. package/dest/client/p2p_client.d.ts +6 -0
  4. package/dest/client/p2p_client.d.ts.map +1 -1
  5. package/dest/client/p2p_client.js +6 -1
  6. package/dest/mocks/index.d.ts +28 -0
  7. package/dest/mocks/index.d.ts.map +1 -0
  8. package/dest/mocks/index.js +78 -0
  9. package/dest/service/dummy_service.d.ts +12 -0
  10. package/dest/service/dummy_service.d.ts.map +1 -1
  11. package/dest/service/dummy_service.js +14 -1
  12. package/dest/service/libp2p_service.d.ts +24 -1
  13. package/dest/service/libp2p_service.d.ts.map +1 -1
  14. package/dest/service/libp2p_service.js +52 -4
  15. package/dest/service/reqresp/handlers.d.ts +12 -2
  16. package/dest/service/reqresp/handlers.d.ts.map +1 -1
  17. package/dest/service/reqresp/handlers.js +13 -3
  18. package/dest/service/reqresp/interface.d.ts +56 -8
  19. package/dest/service/reqresp/interface.d.ts.map +1 -1
  20. package/dest/service/reqresp/interface.js +57 -8
  21. package/dest/service/reqresp/reqresp.d.ts +16 -4
  22. package/dest/service/reqresp/reqresp.d.ts.map +1 -1
  23. package/dest/service/reqresp/reqresp.js +22 -14
  24. package/dest/service/service.d.ts +9 -0
  25. package/dest/service/service.d.ts.map +1 -1
  26. package/dest/service/service.js +1 -1
  27. package/package.json +6 -6
  28. package/src/client/index.ts +2 -0
  29. package/src/client/p2p_client.ts +12 -0
  30. package/src/mocks/index.ts +101 -0
  31. package/src/service/dummy_service.ts +18 -0
  32. package/src/service/libp2p_service.ts +75 -1
  33. package/src/service/reqresp/handlers.ts +14 -4
  34. package/src/service/reqresp/interface.ts +95 -8
  35. package/src/service/reqresp/reqresp.ts +36 -19
  36. package/src/service/service.ts +14 -0
@@ -1,11 +1,59 @@
1
- export declare enum ReqRespType {
2
- Status = "status",
3
- Ping = "ping",
4
- /** Ask peers for specific transactions */
5
- TxsByHash = "txs_by_hash"
6
- }
1
+ /// <reference types="node" resolution-mode="require"/>
7
2
  export declare const PING_PROTOCOL = "/aztec/ping/0.1.0";
8
3
  export declare const STATUS_PROTOCOL = "/aztec/status/0.1.0";
9
- export type SubProtocol = typeof PING_PROTOCOL | typeof STATUS_PROTOCOL;
10
- export type SubProtocolHandler = (msg: string) => Uint8Array;
4
+ export declare const TX_REQ_PROTOCOL = "/aztec/tx_req/0.1.0";
5
+ export type ReqRespSubProtocol = typeof PING_PROTOCOL | typeof STATUS_PROTOCOL | typeof TX_REQ_PROTOCOL;
6
+ /**
7
+ * A handler for a sub protocol
8
+ * The message will arrive as a buffer, and the handler must return a buffer
9
+ */
10
+ export type ReqRespSubProtocolHandler = (msg: Buffer) => Promise<Uint8Array>;
11
+ /**
12
+ * A type mapping from supprotocol to it's handling funciton
13
+ */
14
+ export type ReqRespSubProtocolHandlers = Record<ReqRespSubProtocol, ReqRespSubProtocolHandler>;
15
+ /**
16
+ * Sub protocol map determines the request and response types for each
17
+ * Req Resp protocol
18
+ */
19
+ export type SubProtocolMap = {
20
+ [S in ReqRespSubProtocol]: RequestResponsePair<any, any>;
21
+ };
22
+ /**
23
+ * Default sub protocol handlers - this SHOULD be overwritten by the service,
24
+ */
25
+ export declare const DEFAULT_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers;
26
+ /**
27
+ * The Request Response Pair interface defines the methods that each
28
+ * request response pair must implement
29
+ */
30
+ interface RequestResponsePair<Req, Res> {
31
+ request: new (...args: any[]) => Req;
32
+ /**
33
+ * The response must implement the static fromBuffer method (generic serialisation)
34
+ */
35
+ response: {
36
+ new (...args: any[]): Res;
37
+ fromBuffer(buffer: Buffer): Res;
38
+ };
39
+ }
40
+ /**
41
+ * RequestableBuffer is a wrapper around a buffer that allows it to be
42
+ * used in generic request response protocols
43
+ *
44
+ * An instance of the RequestResponsePair defined above
45
+ */
46
+ export declare class RequestableBuffer {
47
+ buffer: Buffer;
48
+ constructor(buffer: Buffer);
49
+ toBuffer(): Buffer;
50
+ static fromBuffer(buffer: Buffer): RequestableBuffer;
51
+ }
52
+ /**
53
+ * A mapping from each protocol to their request and response types
54
+ * This defines the request and response types for each sub protocol, used primarily
55
+ * as a type rather than an object
56
+ */
57
+ export declare const subProtocolMap: SubProtocolMap;
58
+ export {};
11
59
  //# sourceMappingURL=interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/interface.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,0CAA0C;IAC1C,SAAS,gBAAgB;CAC1B;AAED,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,GAAG,OAAO,eAAe,CAAC;AAExE,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/interface.ts"],"names":[],"mappings":";AAKA,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAGrD,MAAM,MAAM,kBAAkB,GAAG,OAAO,aAAa,GAAG,OAAO,eAAe,GAAG,OAAO,eAAe,CAAC;AAExG;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,kBAAkB,EAAE,yBAAyB,CAAC,CAAC;AAE/F;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;KAC1B,CAAC,IAAI,kBAAkB,GAAG,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC;CACzD,CAAC;AAUF;;GAEG;AACH,eAAO,MAAM,6BAA6B,EAAE,0BAI3C,CAAC;AAEF;;;GAGG;AACH,UAAU,mBAAmB,CAAC,GAAG,EAAE,GAAG;IACpC,OAAO,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACrC;;OAEG;IACH,QAAQ,EAAE;QACR,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;QAC1B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;KACjC,CAAC;CACH;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IACT,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM;IAEjC,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM;CAGjC;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAa5B,CAAC"}
@@ -1,10 +1,59 @@
1
- export var ReqRespType;
2
- (function (ReqRespType) {
3
- ReqRespType["Status"] = "status";
4
- ReqRespType["Ping"] = "ping";
5
- /** Ask peers for specific transactions */
6
- ReqRespType["TxsByHash"] = "txs_by_hash";
7
- })(ReqRespType || (ReqRespType = {}));
1
+ import { Tx, TxHash } from '@aztec/circuit-types';
2
+ /*
3
+ * Request Response Sub Protocols
4
+ */
8
5
  export const PING_PROTOCOL = '/aztec/ping/0.1.0';
9
6
  export const STATUS_PROTOCOL = '/aztec/status/0.1.0';
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2UvcmVxcmVzcC9pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFOLElBQVksV0FLWDtBQUxELFdBQVksV0FBVztJQUNyQixnQ0FBaUIsQ0FBQTtJQUNqQiw0QkFBYSxDQUFBO0lBQ2IsMENBQTBDO0lBQzFDLHdDQUF5QixDQUFBO0FBQzNCLENBQUMsRUFMVyxXQUFXLEtBQVgsV0FBVyxRQUt0QjtBQUVELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxtQkFBbUIsQ0FBQztBQUNqRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcscUJBQXFCLENBQUMifQ==
7
+ export const TX_REQ_PROTOCOL = '/aztec/tx_req/0.1.0';
8
+ /**
9
+ * Default handler for unimplemented sub protocols, this SHOULD be overwritten
10
+ * by the service, but is provided as a fallback
11
+ */
12
+ const defaultHandler = (_msg) => {
13
+ return Promise.resolve(Uint8Array.from(Buffer.from('unimplemented')));
14
+ };
15
+ /**
16
+ * Default sub protocol handlers - this SHOULD be overwritten by the service,
17
+ */
18
+ export const DEFAULT_SUB_PROTOCOL_HANDLERS = {
19
+ [PING_PROTOCOL]: defaultHandler,
20
+ [STATUS_PROTOCOL]: defaultHandler,
21
+ [TX_REQ_PROTOCOL]: defaultHandler,
22
+ };
23
+ /**
24
+ * RequestableBuffer is a wrapper around a buffer that allows it to be
25
+ * used in generic request response protocols
26
+ *
27
+ * An instance of the RequestResponsePair defined above
28
+ */
29
+ export class RequestableBuffer {
30
+ constructor(buffer) {
31
+ this.buffer = buffer;
32
+ }
33
+ toBuffer() {
34
+ return this.buffer;
35
+ }
36
+ static fromBuffer(buffer) {
37
+ return new RequestableBuffer(buffer);
38
+ }
39
+ }
40
+ /**
41
+ * A mapping from each protocol to their request and response types
42
+ * This defines the request and response types for each sub protocol, used primarily
43
+ * as a type rather than an object
44
+ */
45
+ export const subProtocolMap = {
46
+ [PING_PROTOCOL]: {
47
+ request: RequestableBuffer,
48
+ response: RequestableBuffer,
49
+ },
50
+ [STATUS_PROTOCOL]: {
51
+ request: RequestableBuffer,
52
+ response: RequestableBuffer,
53
+ },
54
+ [TX_REQ_PROTOCOL]: {
55
+ request: TxHash,
56
+ response: Tx,
57
+ },
58
+ };
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2UvcmVxcmVzcC9pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVsRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxtQkFBbUIsQ0FBQztBQUNqRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcscUJBQXFCLENBQUM7QUFDckQsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLHFCQUFxQixDQUFDO0FBd0JyRDs7O0dBR0c7QUFDSCxNQUFNLGNBQWMsR0FBRyxDQUFDLElBQVMsRUFBdUIsRUFBRTtJQUN4RCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4RSxDQUFDLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUErQjtJQUN2RSxDQUFDLGFBQWEsQ0FBQyxFQUFFLGNBQWM7SUFDL0IsQ0FBQyxlQUFlLENBQUMsRUFBRSxjQUFjO0lBQ2pDLENBQUMsZUFBZSxDQUFDLEVBQUUsY0FBYztDQUNsQyxDQUFDO0FBaUJGOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUM1QixZQUFtQixNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtJQUFHLENBQUM7SUFFckMsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFjO1FBQzlCLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0Y7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFtQjtJQUM1QyxDQUFDLGFBQWEsQ0FBQyxFQUFFO1FBQ2YsT0FBTyxFQUFFLGlCQUFpQjtRQUMxQixRQUFRLEVBQUUsaUJBQWlCO0tBQzVCO0lBQ0QsQ0FBQyxlQUFlLENBQUMsRUFBRTtRQUNqQixPQUFPLEVBQUUsaUJBQWlCO1FBQzFCLFFBQVEsRUFBRSxpQkFBaUI7S0FDNUI7SUFDRCxDQUFDLGVBQWUsQ0FBQyxFQUFFO1FBQ2pCLE9BQU8sRUFBRSxNQUFNO1FBQ2YsUUFBUSxFQUFFLEVBQUU7S0FDYjtDQUNGLENBQUMifQ==
@@ -2,16 +2,28 @@
2
2
  import { type Logger } from '@aztec/foundation/log';
3
3
  import { type PeerId } from '@libp2p/interface';
4
4
  import { type Libp2p } from 'libp2p';
5
- import { type SubProtocol } from './interface.js';
5
+ import { type ReqRespSubProtocol, type ReqRespSubProtocolHandlers } from './interface.js';
6
+ /**
7
+ * The Request Response Service
8
+ *
9
+ * It allows nodes to request specific information from their peers, its use case covers recovering
10
+ * information that was missed during a syncronisation or a gossip event.
11
+ *
12
+ * This service implements the request response sub protocol, it is heavily inspired from
13
+ * ethereum implementations of the same name.
14
+ *
15
+ * see: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-reqresp-domain
16
+ */
6
17
  export declare class ReqResp {
7
18
  protected readonly libp2p: Libp2p;
8
19
  protected readonly logger: Logger;
9
20
  private abortController;
21
+ private subProtocolHandlers;
10
22
  constructor(libp2p: Libp2p);
11
23
  /**
12
24
  * Start the reqresp service
13
25
  */
14
- start(): Promise<void>;
26
+ start(subProtocolHandlers: ReqRespSubProtocolHandlers): Promise<void>;
15
27
  /**
16
28
  * Stop the reqresp service
17
29
  */
@@ -23,7 +35,7 @@ export declare class ReqResp {
23
35
  * @param payload - The payload to send
24
36
  * @returns - The response from the peer, otherwise undefined
25
37
  */
26
- sendRequest(subProtocol: SubProtocol, payload: Buffer): Promise<Buffer | undefined>;
38
+ sendRequest(subProtocol: ReqRespSubProtocol, payload: Buffer): Promise<Buffer | undefined>;
27
39
  /**
28
40
  * Sends a request to a specific peer
29
41
  *
@@ -32,7 +44,7 @@ export declare class ReqResp {
32
44
  * @param payload - The payload to send
33
45
  * @returns If the request is successful, the response is returned, otherwise undefined
34
46
  */
35
- sendRequestToPeer(peerId: PeerId, subProtocol: SubProtocol, payload: Buffer): Promise<Buffer | undefined>;
47
+ sendRequestToPeer(peerId: PeerId, subProtocol: ReqRespSubProtocol, payload: Buffer): Promise<Buffer | undefined>;
36
48
  /**
37
49
  * Read a message returned from a stream into a single buffer
38
50
  */
@@ -1 +1 @@
1
- {"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/reqresp.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,MAAM,EAAqB,MAAM,uBAAuB,CAAC;AAEvE,OAAO,EAA2B,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIrC,OAAO,EAAkC,KAAK,WAAW,EAA2B,MAAM,gBAAgB,CAAC;AAU3G,qBAAa,OAAO;IAKN,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAJ7C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,eAAe,CAA0C;gBAElC,MAAM,EAAE,MAAM;IAI7C;;OAEG;IACG,KAAK;IAOX;;OAEG;IACG,IAAI;IASV;;;;;;OAMG;IACG,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAgBzF;;;;;;;OAOG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAY/G;;OAEG;YACW,WAAW;IASzB;;;;;OAKG;YACW,aAAa;CAkB5B"}
1
+ {"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/reqresp.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,MAAM,EAAqB,MAAM,uBAAuB,CAAC;AAEvE,OAAO,EAA2B,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAChC,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;GAUG;AACH,qBAAa,OAAO;IAON,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAN7C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,eAAe,CAA0C;IAEjE,OAAO,CAAC,mBAAmB,CAA6D;gBAEzD,MAAM,EAAE,MAAM;IAI7C;;OAEG;IACG,KAAK,CAAC,mBAAmB,EAAE,0BAA0B;IAQ3D;;OAEG;IACG,IAAI;IASV;;;;;;OAMG;IACG,WAAW,CAAC,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiBhG;;;;;;;OAOG;IACG,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAY9B;;OAEG;YACW,WAAW;IASzB;;;;;OAKG;YACW,aAAa;CAqB5B"}
@@ -1,27 +1,32 @@
1
1
  // @attribution: lodestar impl for inspiration
2
2
  import { createDebugLogger } from '@aztec/foundation/log';
3
3
  import { pipe } from 'it-pipe';
4
- import { pingHandler, statusHandler } from './handlers.js';
5
- import { PING_PROTOCOL, STATUS_PROTOCOL } from './interface.js';
4
+ import { DEFAULT_SUB_PROTOCOL_HANDLERS, } from './interface.js';
6
5
  /**
7
- * A mapping from a protocol to a handler function
6
+ * The Request Response Service
7
+ *
8
+ * It allows nodes to request specific information from their peers, its use case covers recovering
9
+ * information that was missed during a syncronisation or a gossip event.
10
+ *
11
+ * This service implements the request response sub protocol, it is heavily inspired from
12
+ * ethereum implementations of the same name.
13
+ *
14
+ * see: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-reqresp-domain
8
15
  */
9
- const SUB_PROTOCOL_HANDLERS = {
10
- [PING_PROTOCOL]: pingHandler,
11
- [STATUS_PROTOCOL]: statusHandler,
12
- };
13
16
  export class ReqResp {
14
17
  constructor(libp2p) {
15
18
  this.libp2p = libp2p;
16
19
  this.abortController = new AbortController();
20
+ this.subProtocolHandlers = DEFAULT_SUB_PROTOCOL_HANDLERS;
17
21
  this.logger = createDebugLogger('aztec:p2p:reqresp');
18
22
  }
19
23
  /**
20
24
  * Start the reqresp service
21
25
  */
22
- async start() {
26
+ async start(subProtocolHandlers) {
27
+ this.subProtocolHandlers = subProtocolHandlers;
23
28
  // Register all protocol handlers
24
- for (const subProtocol of Object.keys(SUB_PROTOCOL_HANDLERS)) {
29
+ for (const subProtocol of Object.keys(this.subProtocolHandlers)) {
25
30
  await this.libp2p.handle(subProtocol, this.streamHandler.bind(this, subProtocol));
26
31
  }
27
32
  }
@@ -30,7 +35,7 @@ export class ReqResp {
30
35
  */
31
36
  async stop() {
32
37
  // Unregister all handlers
33
- for (const protocol of Object.keys(SUB_PROTOCOL_HANDLERS)) {
38
+ for (const protocol of Object.keys(this.subProtocolHandlers)) {
34
39
  await this.libp2p.unhandle(protocol);
35
40
  }
36
41
  await this.libp2p.stop();
@@ -50,7 +55,8 @@ export class ReqResp {
50
55
  for (const peer of peers) {
51
56
  const response = await this.sendRequestToPeer(peer, subProtocol, payload);
52
57
  // If we get a response, return it, otherwise we iterate onto the next peer
53
- if (response) {
58
+ // We do not consider it a success if we have an empty buffer
59
+ if (response && response.length > 0) {
54
60
  return response;
55
61
  }
56
62
  }
@@ -93,11 +99,13 @@ export class ReqResp {
93
99
  * @param param0 - The incoming stream data
94
100
  */
95
101
  async streamHandler(protocol, { stream }) {
102
+ // Store a reference to from this for the async generator
103
+ const handler = this.subProtocolHandlers[protocol];
96
104
  try {
97
105
  await pipe(stream, async function* (source) {
98
106
  for await (const chunkList of source) {
99
- const msg = Buffer.from(chunkList.subarray()).toString();
100
- yield SUB_PROTOCOL_HANDLERS[protocol](msg);
107
+ const msg = Buffer.from(chunkList.subarray());
108
+ yield handler(msg);
101
109
  }
102
110
  }, stream);
103
111
  }
@@ -109,4 +117,4 @@ export class ReqResp {
109
117
  }
110
118
  }
111
119
  }
112
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlL3JlcXJlc3AvcmVxcmVzcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4Q0FBOEM7QUFDOUMsT0FBTyxFQUFlLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHdkUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUkvQixPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBNkMsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzRzs7R0FFRztBQUNILE1BQU0scUJBQXFCLEdBQTRDO0lBQ3JFLENBQUMsYUFBYSxDQUFDLEVBQUUsV0FBVztJQUM1QixDQUFDLGVBQWUsQ0FBQyxFQUFFLGFBQWE7Q0FDakMsQ0FBQztBQUVGLE1BQU0sT0FBTyxPQUFPO0lBS2xCLFlBQStCLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBRnJDLG9CQUFlLEdBQW9CLElBQUksZUFBZSxFQUFFLENBQUM7UUFHL0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxLQUFLO1FBQ1QsaUNBQWlDO1FBQ2pDLEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLENBQUM7WUFDN0QsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFdBQTBCLENBQUMsQ0FBQyxDQUFDO1FBQ25HLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsSUFBSTtRQUNSLDBCQUEwQjtRQUMxQixLQUFL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
120
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlL3JlcXJlc3AvcmVxcmVzcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4Q0FBOEM7QUFDOUMsT0FBTyxFQUFlLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHdkUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUkvQixPQUFPLEVBQ0wsNkJBQTZCLEdBRzlCLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEI7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sT0FBTyxPQUFPO0lBT2xCLFlBQStCLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBSnJDLG9CQUFlLEdBQW9CLElBQUksZUFBZSxFQUFFLENBQUM7UUFFekQsd0JBQW1CLEdBQStCLDZCQUE2QixDQUFDO1FBR3RGLElBQUksQ0FBQyxNQUFNLEdBQUcsaUJBQWlCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsS0FBSyxDQUFDLG1CQUErQztRQUN6RCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsbUJBQW1CLENBQUM7UUFDL0MsaUNBQWlDO1FBQ2pDLEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDO1lBQ2hFLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxXQUFpQyxDQUFDLENBQUMsQ0FBQztRQUMxRyxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLElBQUk7UUFDUiwwQkFBMEI7UUFDMUIsS0FBSyxNQUFNLFFBQVEsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUM7WUFDN0QsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQUMsV0FBK0IsRUFBRSxPQUFlO1FBQ2hFLG1CQUFtQjtRQUNuQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXJDLGtDQUFrQztRQUNsQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFFMUUsMkVBQTJFO1lBQzNFLDZEQUE2RDtZQUM3RCxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNwQyxPQUFPLFFBQVEsQ0FBQztZQUNsQixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUNyQixNQUFjLEVBQ2QsV0FBK0IsRUFDL0IsT0FBZTtRQUVmLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBRW5FLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMvRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztZQUN2RSxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFxQztRQUM3RCxNQUFNLE1BQU0sR0FBaUIsRUFBRSxDQUFDO1FBQ2hDLElBQUksS0FBSyxFQUFFLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ2pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNwQyxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssS0FBSyxDQUFDLGFBQWEsQ0FBQyxRQUE0QixFQUFFLEVBQUUsTUFBTSxFQUFzQjtRQUN0Rix5REFBeUQ7UUFDekQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRW5ELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUNSLE1BQU0sRUFDTixLQUFLLFNBQVMsQ0FBQyxFQUFFLE1BQVc7Z0JBQzFCLElBQUksS0FBSyxFQUFFLE1BQU0sU0FBUyxJQUFJLE1BQU0sRUFBRSxDQUFDO29CQUNyQyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO29CQUM5QyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDckIsQ0FBQztZQUNILENBQUMsRUFDRCxNQUFNLENBQ1AsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLENBQUM7Z0JBQVMsQ0FBQztZQUNULE1BQU0sTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLENBQUM7SUFDSCxDQUFDO0NBQ0YifQ==
@@ -3,6 +3,7 @@ import type { BlockAttestation, BlockProposal, Gossipable } from '@aztec/circuit
3
3
  import type { ENR } from '@chainsafe/enr';
4
4
  import type { PeerId } from '@libp2p/interface';
5
5
  import type EventEmitter from 'events';
6
+ import { type ReqRespSubProtocol, type SubProtocolMap } from './reqresp/interface.js';
6
7
  export declare enum PeerDiscoveryState {
7
8
  RUNNING = "running",
8
9
  STOPPED = "stopped"
@@ -26,6 +27,14 @@ export interface P2PService {
26
27
  * @param message - The message to be propagated.
27
28
  */
28
29
  propagate<T extends Gossipable>(message: T): void;
30
+ /**
31
+ * Request information from peers via the request response protocol.
32
+ *
33
+ * @param protocol - The request response protocol to use
34
+ * @param request - The request type, corresponding to the protocol
35
+ * @returns The response type, corresponding to the protocol
36
+ */
37
+ sendRequest<Protocol extends ReqRespSubProtocol>(protocol: Protocol, request: InstanceType<SubProtocolMap[Protocol]['request']>): Promise<InstanceType<SubProtocolMap[Protocol]['response']> | undefined>;
29
38
  registerBlockReceivedCallback(callback: (block: BlockProposal) => Promise<BlockAttestation>): void;
30
39
  getEnr(): ENR | undefined;
31
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExF,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,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;IAGlD,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAEnG,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;CAC3B;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/service/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExF,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;IAG3E,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAEnG,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;CAC3B;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"}
@@ -3,4 +3,4 @@ export var PeerDiscoveryState;
3
3
  PeerDiscoveryState["RUNNING"] = "running";
4
4
  PeerDiscoveryState["STOPPED"] = "stopped";
5
5
  })(PeerDiscoveryState || (PeerDiscoveryState = {}));
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsTUFBTSxDQUFOLElBQVksa0JBR1g7QUFIRCxXQUFZLGtCQUFrQjtJQUM1Qix5Q0FBbUIsQ0FBQTtJQUNuQix5Q0FBbUIsQ0FBQTtBQUNyQixDQUFDLEVBSFcsa0JBQWtCLEtBQWxCLGtCQUFrQixRQUc3QiJ9
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBUUEsTUFBTSxDQUFOLElBQVksa0JBR1g7QUFIRCxXQUFZLGtCQUFrQjtJQUM1Qix5Q0FBbUIsQ0FBQTtJQUNuQix5Q0FBbUIsQ0FBQTtBQUNyQixDQUFDLEVBSFcsa0JBQWtCLEtBQWxCLGtCQUFrQixRQUc3QiJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -56,11 +56,11 @@
56
56
  "testTimeout": 15000
57
57
  },
58
58
  "dependencies": {
59
- "@aztec/circuit-types": "0.51.0",
60
- "@aztec/circuits.js": "0.51.0",
61
- "@aztec/foundation": "0.51.0",
62
- "@aztec/kv-store": "0.51.0",
63
- "@aztec/telemetry-client": "0.51.0",
59
+ "@aztec/circuit-types": "0.52.0",
60
+ "@aztec/circuits.js": "0.52.0",
61
+ "@aztec/foundation": "0.52.0",
62
+ "@aztec/kv-store": "0.52.0",
63
+ "@aztec/telemetry-client": "0.52.0",
64
64
  "@chainsafe/discv5": "9.0.0",
65
65
  "@chainsafe/enr": "3.0.0",
66
66
  "@chainsafe/libp2p-gossipsub": "13.0.0",
@@ -23,6 +23,7 @@ export const createP2PClient = async (
23
23
 
24
24
  if (config.p2pEnabled) {
25
25
  // If announceTcpAddress or announceUdpAddress are not provided, query for public IP if config allows
26
+
26
27
  const {
27
28
  tcpAnnounceAddress: configTcpAnnounceAddress,
28
29
  udpAnnounceAddress: configUdpAnnounceAddress,
@@ -68,6 +69,7 @@ export const createP2PClient = async (
68
69
  // Create peer discovery service
69
70
  const peerId = await createLibP2PPeerId(config.peerIdPrivateKey);
70
71
  const discoveryService = new DiscV5Service(peerId, config);
72
+
71
73
  p2pService = await LibP2PService.new(config, discoveryService, peerId, txPool, attestationsPool, store);
72
74
  } else {
73
75
  p2pService = new DummyP2PService();
@@ -15,6 +15,7 @@ import { type ENR } from '@chainsafe/enr';
15
15
 
16
16
  import { type AttestationPool } from '../attestation_pool/attestation_pool.js';
17
17
  import { getP2PConfigEnvVars } from '../config.js';
18
+ import { TX_REQ_PROTOCOL } from '../service/reqresp/interface.js';
18
19
  import type { P2PService } from '../service/service.js';
19
20
  import { type TxPool } from '../tx_pool/index.js';
20
21
 
@@ -71,6 +72,12 @@ export interface P2P {
71
72
  // ^ This pattern is not my favorite (md)
72
73
  registerBlockProposalHandler(handler: (block: BlockProposal) => Promise<BlockAttestation>): void;
73
74
 
75
+ /**
76
+ * Request a transaction from another peer by its tx hash.
77
+ * @param txHash - Hash of the tx to query.
78
+ */
79
+ requestTxByHash(txHash: TxHash): Promise<Tx | undefined>;
80
+
74
81
  /**
75
82
  * Verifies the 'tx' and, if valid, adds it to local tx pool and forwards it to other peers.
76
83
  * @param tx - The transaction.
@@ -276,6 +283,11 @@ export class P2PClient implements P2P {
276
283
  this.p2pService.registerBlockReceivedCallback(handler);
277
284
  }
278
285
 
286
+ public requestTxByHash(txHash: TxHash): Promise<Tx | undefined> {
287
+ // Underlying I want to use the libp2p service to just have a request method where the subprotocol is defined here
288
+ return this.p2pService.sendRequest(TX_REQ_PROTOCOL, txHash);
289
+ }
290
+
279
291
  /**
280
292
  * Returns all transactions in the transaction pool.
281
293
  * @returns An array of Txs.
@@ -0,0 +1,101 @@
1
+ import { noise } from '@chainsafe/libp2p-noise';
2
+ import { yamux } from '@chainsafe/libp2p-yamux';
3
+ import { bootstrap } from '@libp2p/bootstrap';
4
+ import { tcp } from '@libp2p/tcp';
5
+ import { type Libp2p, type Libp2pOptions, createLibp2p } from 'libp2p';
6
+
7
+ import { pingHandler, statusHandler } from '../service/reqresp/handlers.js';
8
+ import {
9
+ PING_PROTOCOL,
10
+ type ReqRespSubProtocolHandlers,
11
+ STATUS_PROTOCOL,
12
+ TX_REQ_PROTOCOL,
13
+ } from '../service/reqresp/interface.js';
14
+ import { ReqResp } from '../service/reqresp/reqresp.js';
15
+
16
+ /**
17
+ * Creates a libp2p node, pre configured.
18
+ * @param boostrapAddrs - an optional list of bootstrap addresses
19
+ * @returns Lip2p node
20
+ */
21
+ export async function createLibp2pNode(boostrapAddrs: string[] = []): Promise<Libp2p> {
22
+ const options: Libp2pOptions = {
23
+ addresses: {
24
+ listen: ['/ip4/0.0.0.0/tcp/0'],
25
+ },
26
+ connectionEncryption: [noise()],
27
+ streamMuxers: [yamux()],
28
+ transports: [tcp()],
29
+ };
30
+
31
+ if (boostrapAddrs.length > 0) {
32
+ options.peerDiscovery = [
33
+ bootstrap({
34
+ list: boostrapAddrs,
35
+ }),
36
+ ];
37
+ }
38
+
39
+ return await createLibp2p(options);
40
+ }
41
+
42
+ /**
43
+ * A p2p / req resp node pairing the req node will always contain the p2p node.
44
+ * they are provided as a pair to allow access the p2p node directly
45
+ */
46
+ export type ReqRespNode = {
47
+ p2p: Libp2p;
48
+ req: ReqResp;
49
+ };
50
+
51
+ // Mock sub protocol handlers
52
+ export const MOCK_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = {
53
+ [PING_PROTOCOL]: pingHandler,
54
+ [STATUS_PROTOCOL]: statusHandler,
55
+ [TX_REQ_PROTOCOL]: (_msg: any) => Promise.resolve(Uint8Array.from(Buffer.from('tx'))),
56
+ };
57
+
58
+ /**
59
+ * @param numberOfNodes - the number of nodes to create
60
+ * @returns An array of the created nodes
61
+ */
62
+ export const createNodes = async (numberOfNodes: number): Promise<ReqRespNode[]> => {
63
+ return await Promise.all(Array.from({ length: numberOfNodes }, () => createReqResp()));
64
+ };
65
+
66
+ // TODO: think about where else this can go
67
+ export const startNodes = async (nodes: ReqRespNode[], subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS) => {
68
+ for (const node of nodes) {
69
+ await node.req.start(subProtocolHandlers);
70
+ }
71
+ };
72
+
73
+ export const stopNodes = async (nodes: ReqRespNode[]): Promise<void> => {
74
+ for (const node of nodes) {
75
+ await node.req.stop();
76
+ await node.p2p.stop();
77
+ }
78
+ };
79
+
80
+ // Create a req resp node, exposing the underlying p2p node
81
+ export const createReqResp = async (): Promise<ReqRespNode> => {
82
+ const p2p = await createLibp2pNode();
83
+ const req = new ReqResp(p2p);
84
+ return {
85
+ p2p,
86
+ req,
87
+ };
88
+ };
89
+
90
+ // Given a node list; hand shake all of the nodes with each other
91
+ export const connectToPeers = async (nodes: ReqRespNode[]): Promise<void> => {
92
+ for (const node of nodes) {
93
+ for (const otherNode of nodes) {
94
+ if (node === otherNode) {
95
+ continue;
96
+ }
97
+ const addr = otherNode.p2p.getMultiaddrs()[0];
98
+ await node.p2p.dial(addr);
99
+ }
100
+ }
101
+ };
@@ -3,6 +3,7 @@ import type { BlockAttestation, BlockProposal, Gossipable, TxHash } from '@aztec
3
3
  import type { PeerId } from '@libp2p/interface';
4
4
  import EventEmitter from 'events';
5
5
 
6
+ import { type ReqRespSubProtocol, type SubProtocolMap } from './reqresp/interface.js';
6
7
  import { type P2PService, type PeerDiscoveryService, PeerDiscoveryState } from './service.js';
7
8
 
8
9
  /**
@@ -42,6 +43,23 @@ export class DummyP2PService implements P2PService {
42
43
  */
43
44
  public registerBlockReceivedCallback(_: (block: BlockProposal) => Promise<BlockAttestation>) {}
44
45
 
46
+ /**
47
+ * Sends a request to a peer.
48
+ * @param _protocol - The protocol to send the request on.
49
+ * @param _request - The request to send.
50
+ * @returns The response from the peer, otherwise undefined.
51
+ */
52
+ public sendRequest<Protocol extends ReqRespSubProtocol>(
53
+ _protocol: Protocol,
54
+ _request: InstanceType<SubProtocolMap[Protocol]['request']>,
55
+ ): Promise<InstanceType<SubProtocolMap[Protocol]['response']> | undefined> {
56
+ return Promise.resolve(undefined);
57
+ }
58
+
59
+ /**
60
+ * Returns the ENR of the peer.
61
+ * @returns The ENR of the peer, otherwise undefined.
62
+ */
45
63
  public getEnr(): undefined {
46
64
  return undefined;
47
65
  }