From 1bc31d47ea9c2b40e12407c02d283757347c3d5a Mon Sep 17 00:00:00 2001 From: achingbrain Date: Tue, 19 Apr 2022 13:36:47 +0100 Subject: [PATCH 1/2] fix: return self when asked for self Restores pre-1.x behaviour where when an RPC findNode request comes in, if it's asking for us, return our info instead of looking for closer peers which queries the routing table which may not have our peer id in it. --- src/rpc/handlers/find-node.ts | 36 ++++++++++++++++++----------- src/rpc/index.ts | 4 ++-- test/rpc/handlers/find-node.spec.ts | 34 ++++++++++++++++----------- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/rpc/handlers/find-node.ts b/src/rpc/handlers/find-node.ts index 34e6a5bd..3d69b55e 100644 --- a/src/rpc/handlers/find-node.ts +++ b/src/rpc/handlers/find-node.ts @@ -4,14 +4,14 @@ import { removePrivateAddresses, removePublicAddresses } from '../../utils.js' -import { pipe } from 'it-pipe' +import { equals as uint8ArrayEquals} from 'uint8arrays' +import { Components } from '@libp2p/interfaces/components' +import { protocols } from '@multiformats/multiaddr' +import type { Initializable } from '@libp2p/interfaces/components' +import type { PeerInfo } from '@libp2p/interfaces/peer-info' import type { DHTMessageHandler } from '../index.js' import type { PeerRouting } from '../../peer-routing/index.js' import type { PeerId } from '@libp2p/interfaces/peer-id' -import map from 'it-map' -import filter from 'it-filter' -import all from 'it-all' -import type { Initializable } from '@libp2p/interfaces/components' const log = logger('libp2p:kad-dht:rpc:handlers:find-node') @@ -23,6 +23,7 @@ export interface FindNodeHandlerInit { export class FindNodeHandler implements DHTMessageHandler, Initializable { private readonly peerRouting: PeerRouting private readonly lan: boolean + private components = new Components() constructor (init: FindNodeHandlerInit) { const { peerRouting, lan } = init @@ -30,8 +31,8 @@ export class FindNodeHandler implements DHTMessageHandler, Initializable { this.lan = Boolean(lan) } - init (): void { - + init (components: Components): void { + this.components = components } /** @@ -40,14 +41,21 @@ export class FindNodeHandler implements DHTMessageHandler, Initializable { async handle (peerId: PeerId, msg: Message) { log('incoming request from %p for peers closer to %b', peerId, msg.key) - const mapper = this.lan ? removePublicAddresses : removePrivateAddresses + let closer: PeerInfo[] = [] + + if (uint8ArrayEquals(this.components.getPeerId().toBytes(), msg.key)) { + closer = [{ + id: this.components.getPeerId(), + multiaddrs: this.components.getAddressManager().getAddresses().map(ma => ma.decapsulateCode(protocols('p2p').code)), + protocols: [] + }] + } else { + closer = await this.peerRouting.getCloserPeersOffline(msg.key, peerId) + } - const closer = await pipe( - await this.peerRouting.getCloserPeersOffline(msg.key, peerId), - (source) => map(source, mapper), - (source) => filter(source, ({ multiaddrs }) => multiaddrs.length > 0), - async (source) => await all(source) - ) + closer = closer + .map(this.lan ? removePublicAddresses : removePrivateAddresses) + .filter(({ multiaddrs }) => multiaddrs.length) const response = new Message(msg.type, new Uint8Array(0), msg.clusterLevel) diff --git a/src/rpc/index.ts b/src/rpc/index.ts index 982c6993..440e01da 100644 --- a/src/rpc/index.ts +++ b/src/rpc/index.ts @@ -16,7 +16,7 @@ import type { PeerRouting } from '../peer-routing' import type { Validators } from '@libp2p/interfaces/dht' import type { Components, Initializable } from '@libp2p/interfaces/components' -export interface DHTMessageHandler { +export interface DHTMessageHandler extends Initializable { handle: (peerId: PeerId, msg: Message) => Promise } @@ -29,7 +29,7 @@ export interface RPCInit { } export class RPC implements Initializable { - private readonly handlers: Record + private readonly handlers: Record private readonly routingTable: RoutingTable private readonly log: Logger diff --git a/test/rpc/handlers/find-node.spec.ts b/test/rpc/handlers/find-node.spec.ts index 413d5ed2..e5feaf86 100644 --- a/test/rpc/handlers/find-node.spec.ts +++ b/test/rpc/handlers/find-node.spec.ts @@ -5,10 +5,14 @@ import { Message, MESSAGE_TYPE } from '../../../src/message/index.js' import { FindNodeHandler } from '../../../src/rpc/handlers/find-node.js' import { Multiaddr } from '@multiformats/multiaddr' import { createPeerId } from '../../utils/create-peer-id.js' -import type { PeerId } from '@libp2p/interfaces/peer-id' -import type { DHTMessageHandler } from '../../../src/rpc/index.js' import { PeerRouting } from '../../../src/peer-routing/index.js' import Sinon, { SinonStubbedInstance } from 'sinon' +import { Components } from '@libp2p/interfaces/components' +import type { PeerId } from '@libp2p/interfaces/peer-id' +import type { DHTMessageHandler } from '../../../src/rpc/index.js' +import type { AddressManager } from '@libp2p/interfaces' +import { stubInterface } from 'ts-sinon' +import type { StubbedInstance } from 'ts-sinon' const T = MESSAGE_TYPE.FIND_NODE @@ -18,33 +22,33 @@ describe('rpc - handlers - FindNode', () => { let targetPeer: PeerId let handler: DHTMessageHandler let peerRouting: SinonStubbedInstance + let addressManager: StubbedInstance beforeEach(async () => { peerId = await createPeerId() sourcePeer = await createPeerId() targetPeer = await createPeerId() peerRouting = Sinon.createStubInstance(PeerRouting) + addressManager = stubInterface() handler = new FindNodeHandler({ peerRouting, lan: false }) + handler.init(new Components({ + peerId, + addressManager + })) }) it('returns self, if asked for self', async () => { const msg = new Message(T, peerId.multihash.bytes, 0) - peerRouting.getCloserPeersOffline - .withArgs(peerId.multihash.bytes, sourcePeer) - .resolves([{ - id: peerId, - multiaddrs: [ - new Multiaddr('/ip4/127.0.0.1/tcp/4002'), - new Multiaddr('/ip4/192.168.1.5/tcp/4002'), - new Multiaddr('/ip4/221.4.67.0/tcp/4002') - ], - protocols: [] - }]) + addressManager.getAddresses.returns([ + new Multiaddr(`/ip4/127.0.0.1/tcp/4002/p2p/${peerId.toString()}`), + new Multiaddr(`/ip4/192.168.1.5/tcp/4002/p2p/${peerId.toString()}`), + new Multiaddr(`/ip4/221.4.67.0/tcp/4002/p2p/${peerId.toString()}`) + ]) const response = await handler.handle(sourcePeer, msg) @@ -115,6 +119,10 @@ describe('rpc - handlers - FindNode', () => { peerRouting, lan: true }) + handler.init(new Components({ + peerId, + addressManager + })) const response = await handler.handle(sourcePeer, msg) From 8b836b7217aa6a6ff5235bcb59bce5a735052a16 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Tue, 19 Apr 2022 13:48:50 +0100 Subject: [PATCH 2/2] chore: linting --- src/rpc/handlers/find-node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/handlers/find-node.ts b/src/rpc/handlers/find-node.ts index 3d69b55e..d861edf7 100644 --- a/src/rpc/handlers/find-node.ts +++ b/src/rpc/handlers/find-node.ts @@ -4,7 +4,7 @@ import { removePrivateAddresses, removePublicAddresses } from '../../utils.js' -import { equals as uint8ArrayEquals} from 'uint8arrays' +import { equals as uint8ArrayEquals } from 'uint8arrays' import { Components } from '@libp2p/interfaces/components' import { protocols } from '@multiformats/multiaddr' import type { Initializable } from '@libp2p/interfaces/components'