Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

fix: return self when asked for self #318

Merged
merged 2 commits into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions src/rpc/handlers/find-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand All @@ -23,15 +23,16 @@ 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
this.peerRouting = peerRouting
this.lan = Boolean(lan)
}

init (): void {

init (components: Components): void {
this.components = components
}

/**
Expand All @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions src/rpc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Message | undefined>
}

Expand All @@ -29,7 +29,7 @@ export interface RPCInit {
}

export class RPC implements Initializable {
private readonly handlers: Record<string, DHTMessageHandler & Initializable>
private readonly handlers: Record<string, DHTMessageHandler>
private readonly routingTable: RoutingTable
private readonly log: Logger

Expand Down
34 changes: 21 additions & 13 deletions test/rpc/handlers/find-node.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -18,33 +22,33 @@ describe('rpc - handlers - FindNode', () => {
let targetPeer: PeerId
let handler: DHTMessageHandler
let peerRouting: SinonStubbedInstance<PeerRouting>
let addressManager: StubbedInstance<AddressManager>

beforeEach(async () => {
peerId = await createPeerId()
sourcePeer = await createPeerId()
targetPeer = await createPeerId()
peerRouting = Sinon.createStubInstance(PeerRouting)
addressManager = stubInterface<AddressManager>()

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)

Expand Down Expand Up @@ -115,6 +119,10 @@ describe('rpc - handlers - FindNode', () => {
peerRouting,
lan: true
})
handler.init(new Components({
peerId,
addressManager
}))

const response = await handler.handle(sourcePeer, msg)

Expand Down