Skip to content

Commit 9e9a32b

Browse files
authored
fix: return self in FIND_NODE for self (#2512)
Partial revert of #2499 If a node is queried for it's own peer id, return it's own peer info. This is necessary because since libp2p/go-libp2p-kad-dht#820 go-libp2p-kad-dht won't add a peer to it's routing tables that doesn't have any DHT peers that are KAD-futher from it's own ID already.
1 parent 4afd7a9 commit 9e9a32b

File tree

5 files changed

+36
-12
lines changed

5 files changed

+36
-12
lines changed

packages/kad-dht/src/peer-routing/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ export class PeerRouting {
319319
if (output.length > 0) {
320320
this.log('getCloserPeersOffline found %d peer(s) closer to %b than %p', output.length, key, closerThan)
321321
} else {
322-
this.log('getCloserPeersOffline could not find peer closer to %b than %p', key, closerThan)
322+
this.log('getCloserPeersOffline could not find peer closer to %b than %p with %d peers in the routing table', key, closerThan, this.routingTable.size)
323323
}
324324

325325
return output

packages/kad-dht/src/rpc/handlers/find-node.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { CodeError } from '@libp2p/interface'
2+
import { protocols } from '@multiformats/multiaddr'
3+
import { equals as uint8ArrayEquals } from 'uint8arrays'
24
import { MessageType } from '../../message/dht.js'
35
import type { PeerInfoMapper } from '../../index.js'
46
import type { Message } from '../../message/dht.js'
57
import type { PeerRouting } from '../../peer-routing/index.js'
68
import type { DHTMessageHandler } from '../index.js'
79
import type { ComponentLogger, Logger, PeerId, PeerInfo } from '@libp2p/interface'
10+
import type { AddressManager } from '@libp2p/interface-internal'
811

912
export interface FindNodeHandlerInit {
1013
peerRouting: PeerRouting
@@ -14,20 +17,23 @@ export interface FindNodeHandlerInit {
1417

1518
export interface FindNodeHandlerComponents {
1619
peerId: PeerId
20+
addressManager: AddressManager
1721
logger: ComponentLogger
1822
}
1923

2024
export class FindNodeHandler implements DHTMessageHandler {
2125
private readonly peerRouting: PeerRouting
2226
private readonly peerInfoMapper: PeerInfoMapper
2327
private readonly peerId: PeerId
28+
private readonly addressManager: AddressManager
2429
private readonly log: Logger
2530

2631
constructor (components: FindNodeHandlerComponents, init: FindNodeHandlerInit) {
2732
const { peerRouting, logPrefix } = init
2833

2934
this.log = components.logger.forComponent(`${logPrefix}:rpc:handlers:find-node`)
3035
this.peerId = components.peerId
36+
this.addressManager = components.addressManager
3137
this.peerRouting = peerRouting
3238
this.peerInfoMapper = init.peerInfoMapper
3339
}
@@ -44,13 +50,19 @@ export class FindNodeHandler implements DHTMessageHandler {
4450

4551
const closer: PeerInfo[] = await this.peerRouting.getCloserPeersOffline(msg.key, peerId)
4652

53+
if (uint8ArrayEquals(this.peerId.toBytes(), msg.key)) {
54+
closer.push({
55+
id: this.peerId,
56+
multiaddrs: this.addressManager.getAddresses().map(ma => ma.decapsulateCode(protocols('p2p').code))
57+
})
58+
}
59+
4760
const response: Message = {
4861
type: MessageType.FIND_NODE,
4962
clusterLevel: msg.clusterLevel,
5063
closer: closer
5164
.map(this.peerInfoMapper)
5265
.filter(({ multiaddrs }) => multiaddrs.length)
53-
.filter(({ id }) => !id.equals(this.peerId))
5466
.map(peerInfo => ({
5567
id: peerInfo.id.toBytes(),
5668
multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)

packages/kad-dht/test/kad-dht.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ describe('KadDHT', () => {
800800
expect(res).to.not.be.empty()
801801
})
802802

803-
it('should not include itself in getClosestPeers PEER_RESPONSE', async function () {
803+
it.skip('should not include itself in getClosestPeers PEER_RESPONSE', async function () {
804804
this.timeout(240 * 1000)
805805

806806
const nDHTs = 30

packages/kad-dht/test/rpc/handlers/find-node.spec.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import { peerIdFromBytes } from '@libp2p/peer-id'
55
import { multiaddr } from '@multiformats/multiaddr'
66
import { expect } from 'aegir/chai'
77
import Sinon, { type SinonStubbedInstance } from 'sinon'
8+
import { stubInterface } from 'sinon-ts'
89
import { type Message, MessageType } from '../../../src/message/dht.js'
910
import { PeerRouting } from '../../../src/peer-routing/index.js'
1011
import { FindNodeHandler } from '../../../src/rpc/handlers/find-node.js'
1112
import { passthroughMapper, removePrivateAddressesMapper, removePublicAddressesMapper } from '../../../src/utils.js'
1213
import { createPeerId } from '../../utils/create-peer-id.js'
1314
import type { DHTMessageHandler } from '../../../src/rpc/index.js'
1415
import type { PeerId } from '@libp2p/interface'
16+
import type { AddressManager } from '@libp2p/interface-internal'
17+
import type { StubbedInstance } from 'sinon-ts'
1518

1619
const T = MessageType.FIND_NODE
1720

@@ -21,15 +24,18 @@ describe('rpc - handlers - FindNode', () => {
2124
let targetPeer: PeerId
2225
let handler: DHTMessageHandler
2326
let peerRouting: SinonStubbedInstance<PeerRouting>
27+
let addressManager: StubbedInstance<AddressManager>
2428

2529
beforeEach(async () => {
2630
peerId = await createPeerId()
2731
sourcePeer = await createPeerId()
2832
targetPeer = await createPeerId()
2933
peerRouting = Sinon.createStubInstance(PeerRouting)
34+
addressManager = stubInterface<AddressManager>()
3035

3136
handler = new FindNodeHandler({
3237
peerId,
38+
addressManager,
3339
logger: defaultLogger()
3440
}, {
3541
peerRouting,
@@ -38,14 +44,20 @@ describe('rpc - handlers - FindNode', () => {
3844
})
3945
})
4046

41-
it('returns nodes close to self but excludes self, if asked for self', async () => {
47+
it('returns nodes close to self and includes self, if asked for self', async () => {
4248
const msg: Message = {
4349
type: T,
4450
key: peerId.multihash.bytes,
4551
closer: [],
4652
providers: []
4753
}
4854

55+
addressManager.getAddresses.returns([
56+
multiaddr('/ip4/127.0.0.1/tcp/4002'),
57+
multiaddr('/ip4/192.168.1.5/tcp/4002'),
58+
multiaddr('/ip4/221.4.67.0/tcp/4002')
59+
])
60+
4961
peerRouting.getCloserPeersOffline
5062
.withArgs(peerId.multihash.bytes, peerId)
5163
.resolves([{
@@ -55,13 +67,6 @@ describe('rpc - handlers - FindNode', () => {
5567
multiaddr('/ip4/192.168.1.5/tcp/4002'),
5668
multiaddr('/ip4/221.4.67.0/tcp/4002')
5769
]
58-
}, {
59-
id: peerId, // self peer
60-
multiaddrs: [
61-
multiaddr('/ip4/127.0.0.1/tcp/4002'),
62-
multiaddr('/ip4/192.168.1.5/tcp/4002'),
63-
multiaddr('/ip4/221.4.67.0/tcp/4002')
64-
]
6570
}])
6671

6772
const response = await handler.handle(peerId, msg)
@@ -70,11 +75,14 @@ describe('rpc - handlers - FindNode', () => {
7075
throw new Error('No response received from handler')
7176
}
7277

73-
expect(response.closer).to.have.length(1)
78+
expect(response.closer).to.have.length(2)
7479
const peer = response.closer[0]
7580

7681
expect(peerIdFromBytes(peer.id).toString()).to.equal(targetPeer.toString())
7782
expect(peer.multiaddrs).to.not.be.empty()
83+
84+
const self = response.closer[1]
85+
expect(peerIdFromBytes(self.id).toString()).to.equal(peerId.toString())
7886
})
7987

8088
it('returns closer peers', async () => {
@@ -145,6 +153,7 @@ describe('rpc - handlers - FindNode', () => {
145153

146154
handler = new FindNodeHandler({
147155
peerId,
156+
addressManager,
148157
logger: defaultLogger()
149158
}, {
150159
peerRouting,
@@ -187,6 +196,7 @@ describe('rpc - handlers - FindNode', () => {
187196

188197
handler = new FindNodeHandler({
189198
peerId,
199+
addressManager,
190200
logger: defaultLogger()
191201
}, {
192202
peerRouting,

packages/kad-dht/test/rpc/index.node.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { passthroughMapper } from '../../src/utils.js'
2424
import { createPeerId } from '../utils/create-peer-id.js'
2525
import type { Validators } from '../../src/index.js'
2626
import type { Libp2pEvents, Connection, PeerId, PeerStore } from '@libp2p/interface'
27+
import type { AddressManager } from '@libp2p/interface-internal'
2728
import type { Datastore } from 'interface-datastore'
2829
import type { Duplex, Source } from 'it-stream-types'
2930

@@ -44,6 +45,7 @@ describe('rpc', () => {
4445
peerId,
4546
datastore,
4647
peerStore: stubInterface<PeerStore>(),
48+
addressManager: stubInterface<AddressManager>(),
4749
logger: defaultLogger()
4850
}
4951
components.peerStore = new PersistentPeerStore({

0 commit comments

Comments
 (0)