diff --git a/packages/reqresp/src/ReqResp.ts b/packages/reqresp/src/ReqResp.ts index 1e42debba4e2..dc1459d87497 100644 --- a/packages/reqresp/src/ReqResp.ts +++ b/packages/reqresp/src/ReqResp.ts @@ -57,8 +57,6 @@ export class ReqResp { private readonly protocolPrefix: string; /** `${protocolPrefix}/${method}/${version}/${encoding}` */ - // Use any to avoid TS error on registering protocol - // Type 'unknown' is not assignable to type 'Resp' private readonly registeredProtocols = new Map(); private readonly dialOnlyProtocols = new Map(); @@ -79,28 +77,29 @@ export class ReqResp { * * Made it explicit method to avoid any developer mistake */ - registerDialOnlyProtocol(protocol: DialOnlyProtocol, opts?: ReqRespRegisterOpts): void { + registerDialOnlyProtocol(protocol: DialOnlyProtocol): void { const protocolID = this.formatProtocolID(protocol); - // libp2p will throw on error on duplicates, allow to overwrite behavior - if (opts?.ignoreIfDuplicate && this.registeredProtocols.has(protocolID)) { - return; - } - this.registeredProtocols.set(protocolID, protocol); this.dialOnlyProtocols.set(protocolID, true); } /** * Register protocol as supported and to libp2p. - * async because libp2p registar persists the new protocol list in the peer-store. + * async because libp2p registrar persists the new protocol list in the peer-store. * Throws if the same protocol is registered twice. * Can be called at any time, no concept of started / stopped */ async registerProtocol(protocol: Protocol, opts?: ReqRespRegisterOpts): Promise { const protocolID = this.formatProtocolID(protocol); + + // libp2p will throw if handler for protocol is already registered, allow to overwrite behavior + if (opts?.ignoreIfDuplicate && this.registeredProtocols.has(protocolID)) { + return; + } + const {handler: _handler, inboundRateLimits, ...rest} = protocol; - this.registerDialOnlyProtocol(rest, opts); + this.registerDialOnlyProtocol(rest); this.dialOnlyProtocols.set(protocolID, false); if (inboundRateLimits) { @@ -112,7 +111,7 @@ export class ReqResp { /** * Remove protocol as supported and from libp2p. - * async because libp2p registar persists the new protocol list in the peer-store. + * async because libp2p registrar persists the new protocol list in the peer-store. * Does NOT throw if the protocolID is unknown. * Can be called at any time, no concept of started / stopped */ diff --git a/packages/reqresp/test/unit/ReqResp.test.ts b/packages/reqresp/test/unit/ReqResp.test.ts index b62b1883cce1..8d78a46f292f 100644 --- a/packages/reqresp/test/unit/ReqResp.test.ts +++ b/packages/reqresp/test/unit/ReqResp.test.ts @@ -63,5 +63,13 @@ describe("ResResp", () => { expect(reqresp.getRegisteredProtocols()).toEqual(["/eth2/beacon_chain/req/number_to_string/1/ssz_snappy"]); expect(libp2p.handle).toHaveBeenCalledOnce(); }); + + it("should not register handler twice for same protocol if ignoreIfDuplicate=true", async () => { + await reqresp.registerProtocol(numberToStringProtocol, {ignoreIfDuplicate: true}); + expect(libp2p.handle).toHaveBeenCalledOnce(); + + await reqresp.registerProtocol(numberToStringProtocol, {ignoreIfDuplicate: true}); + expect(libp2p.handle).toHaveBeenCalledOnce(); + }); }); });