Skip to content

Commit 4078082

Browse files
joeltgachingbrain
andauthored
fix: encapsulate /p2p-circuit multiaddrs when dialing a known peerid (#1680)
The logic for creating a dial target tries to ensure multiaddrs are encapsulated with `/p2p/${peerId}` IF the dial target's peer id is known. It uses `addr.getPeerId() != null` to check if this is already the case. ``` > multiaddr("/ip4/127.0.0.1/tcp/4001/p2p/12Dfoo...").getPeerId() '12Dfoo...' ``` However, circuit relay addresses return the **relay server's** peer id if they don't end in `/p2p/${destinationPeerId}`. ``` > multiaddr("/ip4/127.0.0.1/tcp/4001/p2p/12D3bar.../p2p-circuit").getPeerId() '12D3bar...' ``` Since the dialer then thinks the multiaddr already has a peer id, it doesn't encapsulate with `/p2p/${destinationPeerId}`, which ultimately results in failed dials to circuit relay destinations (`Circuit relay dial failed as addresses did not have peer id`). If I understand things right, the desired behavior is for circuit relay addresses to get encapsulated with the destination peer id. --------- Co-authored-by: achingbrain <[email protected]>
1 parent e5a28b9 commit 4078082

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/connection-manager/dial-queue.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ export class DialQueue {
337337
throw new CodeError('dial with more addresses than allowed', codes.ERR_TOO_MANY_ADDRESSES)
338338
}
339339

340-
// append peer id to multiaddrs if it is not already present
340+
// ensure the peer id is appended to the multiaddr
341341
if (peerId != null) {
342342
const peerIdMultiaddr = `/p2p/${peerId.toString()}`
343343
dedupedMultiaddrs = dedupedMultiaddrs.map(addr => {
@@ -349,7 +349,8 @@ export class DialQueue {
349349
return addr
350350
}
351351

352-
if (addressPeerId == null) {
352+
// append peer id to multiaddr if it is not already present
353+
if (addressPeerId !== peerId.toString()) {
353354
return {
354355
multiaddr: addr.multiaddr.encapsulate(peerIdMultiaddr),
355356
isCertified: addr.isCertified

test/circuit-relay/relay.node.ts

+20
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { Libp2p } from '@libp2p/interface-libp2p'
1717
import { pbStream } from 'it-pb-stream'
1818
import { HopMessage, Status } from '../../src/circuit-relay/pb/index.js'
1919
import { Circuit } from '@multiformats/mafmt'
20+
import { multiaddr } from '@multiformats/multiaddr'
2021

2122
describe('circuit-relay', () => {
2223
describe('flows with 1 listener', () => {
@@ -392,6 +393,25 @@ describe('circuit-relay', () => {
392393
await local.dial(ma)
393394
})
394395

396+
it('should be able to dial a peer from its relayed address without peer id', async () => {
397+
// discover relay and make reservation
398+
await remote.dial(relay1.getMultiaddrs()[0])
399+
await usingAsRelay(remote, relay1)
400+
401+
// get the relayed multiaddr without the remote's peer id
402+
const ma = getRelayAddress(remote)
403+
const maWithoutPeerId = multiaddr(`${ma.toString().split('/p2p-circuit')[0]}/p2p-circuit`)
404+
expect(maWithoutPeerId.getPeerId()).to.not.equal(remote.peerId.toString())
405+
406+
// ensure this is the only address we have for the peer
407+
await local.peerStore.addressBook.set(remote.peerId, [
408+
maWithoutPeerId
409+
])
410+
411+
// dial via peer id so we load the address from the address book
412+
await local.dial(remote.peerId)
413+
})
414+
395415
it('should not stay connected to a relay when not already connected and HOP fails', async () => {
396416
// dial the remote through the relay
397417
const relayedMultiaddr = relay1.getMultiaddrs()[0].encapsulate(`/p2p-circuit/p2p/${remote.peerId.toString()}`)

0 commit comments

Comments
 (0)