mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-03-18 16:40:51 +00:00
BREAKING CHANGES: top level types were updated, multiaddr@9.0.0 is used, dialer and keychain internal property names changed and connectionManager minPeers is not supported anymore
178 lines
6.1 KiB
JavaScript
178 lines
6.1 KiB
JavaScript
'use strict'
|
|
/* eslint-env mocha */
|
|
|
|
const { expect } = require('aegir/utils/chai')
|
|
const sinon = require('sinon')
|
|
|
|
const { Multiaddr } = require('multiaddr')
|
|
const Resolver = require('multiaddr/src/resolvers/dns')
|
|
|
|
const { codes: ErrorCodes } = require('../../src/errors')
|
|
|
|
const peerUtils = require('../utils/creators/peer')
|
|
const baseOptions = require('../utils/base-options.browser')
|
|
|
|
const { MULTIADDRS_WEBSOCKETS } = require('../fixtures/browser')
|
|
const relayAddr = MULTIADDRS_WEBSOCKETS[0]
|
|
|
|
const getDnsaddrStub = (peerId) => [
|
|
[`dnsaddr=/dnsaddr/ams-1.bootstrap.libp2p.io/p2p/${peerId}`],
|
|
[`dnsaddr=/dnsaddr/ams-2.bootstrap.libp2p.io/p2p/${peerId}`],
|
|
[`dnsaddr=/dnsaddr/lon-1.bootstrap.libp2p.io/p2p/${peerId}`],
|
|
[`dnsaddr=/dnsaddr/nrt-1.bootstrap.libp2p.io/p2p/${peerId}`],
|
|
[`dnsaddr=/dnsaddr/nyc-1.bootstrap.libp2p.io/p2p/${peerId}`],
|
|
[`dnsaddr=/dnsaddr/sfo-2.bootstrap.libp2p.io/p2p/${peerId}`]
|
|
]
|
|
|
|
const relayedAddr = (peerId) => `${relayAddr}/p2p-circuit/p2p/${peerId}`
|
|
|
|
const getDnsRelayedAddrStub = (peerId) => [
|
|
[`dnsaddr=${relayedAddr(peerId)}`]
|
|
]
|
|
|
|
describe('Dialing (resolvable addresses)', () => {
|
|
let libp2p, remoteLibp2p
|
|
|
|
beforeEach(async () => {
|
|
[libp2p, remoteLibp2p] = await peerUtils.createPeer({
|
|
number: 2,
|
|
config: {
|
|
...baseOptions,
|
|
addresses: {
|
|
listen: [new Multiaddr(`${relayAddr}/p2p-circuit`)]
|
|
},
|
|
config: {
|
|
...baseOptions.config,
|
|
peerDiscovery: {
|
|
autoDial: false
|
|
}
|
|
}
|
|
},
|
|
started: true,
|
|
populateAddressBooks: false
|
|
})
|
|
})
|
|
|
|
afterEach(async () => {
|
|
sinon.restore()
|
|
await Promise.all([libp2p, remoteLibp2p].map(n => n.stop()))
|
|
})
|
|
|
|
it('resolves dnsaddr to ws local address', async () => {
|
|
const remoteId = remoteLibp2p.peerId.toB58String()
|
|
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
|
const relayedAddrFetched = new Multiaddr(relayedAddr(remoteId))
|
|
|
|
// Transport spy
|
|
const transport = libp2p.transportManager._transports.get('Circuit')
|
|
sinon.spy(transport, 'dial')
|
|
|
|
// Resolver stub
|
|
const stub = sinon.stub(Resolver.prototype, 'resolveTxt')
|
|
stub.onCall(0).returns(Promise.resolve(getDnsRelayedAddrStub(remoteId)))
|
|
|
|
// Dial with address resolve
|
|
const connection = await libp2p.dial(dialAddr)
|
|
expect(connection).to.exist()
|
|
expect(connection.remoteAddr.equals(relayedAddrFetched))
|
|
|
|
const dialArgs = transport.dial.firstCall.args
|
|
expect(dialArgs[0].equals(relayedAddrFetched)).to.eql(true)
|
|
})
|
|
|
|
it('resolves a dnsaddr recursively', async () => {
|
|
const remoteId = remoteLibp2p.peerId.toB58String()
|
|
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
|
const relayedAddrFetched = new Multiaddr(relayedAddr(remoteId))
|
|
|
|
// Transport spy
|
|
const transport = libp2p.transportManager._transports.get('Circuit')
|
|
sinon.spy(transport, 'dial')
|
|
|
|
// Resolver stub
|
|
const stub = sinon.stub(Resolver.prototype, 'resolveTxt')
|
|
let firstCall = false
|
|
stub.callsFake(() => {
|
|
if (!firstCall) {
|
|
firstCall = true
|
|
// Return an array of dnsaddr
|
|
return Promise.resolve(getDnsaddrStub(remoteId))
|
|
}
|
|
return Promise.resolve(getDnsRelayedAddrStub(remoteId))
|
|
})
|
|
|
|
// Dial with address resolve
|
|
const connection = await libp2p.dial(dialAddr)
|
|
expect(connection).to.exist()
|
|
expect(connection.remoteAddr.equals(relayedAddrFetched))
|
|
|
|
const dialArgs = transport.dial.firstCall.args
|
|
expect(dialArgs[0].equals(relayedAddrFetched)).to.eql(true)
|
|
})
|
|
|
|
// TODO: Temporary solution does not resolve dns4/dns6
|
|
// Resolver just returns the received multiaddrs
|
|
it('stops recursive resolve if finds dns4/dns6 and dials it', async () => {
|
|
const remoteId = remoteLibp2p.peerId.toB58String()
|
|
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
|
|
|
// Stub resolver
|
|
const dnsMa = new Multiaddr(`/dns4/ams-1.remote.libp2p.io/tcp/443/wss/p2p/${remoteId}`)
|
|
const stubResolve = sinon.stub(Resolver.prototype, 'resolveTxt')
|
|
stubResolve.returns(Promise.resolve([
|
|
[`dnsaddr=${dnsMa}`]
|
|
]))
|
|
|
|
// Stub transport
|
|
const transport = libp2p.transportManager._transports.get('WebSockets')
|
|
const stubTransport = sinon.stub(transport, 'dial')
|
|
stubTransport.callsFake((multiaddr) => {
|
|
expect(multiaddr.equals(dnsMa)).to.eql(true)
|
|
})
|
|
|
|
await libp2p.dial(dialAddr)
|
|
})
|
|
|
|
it('resolves a dnsaddr recursively not failing if one address fails to resolve', async () => {
|
|
const remoteId = remoteLibp2p.peerId.toB58String()
|
|
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
|
const relayedAddrFetched = new Multiaddr(relayedAddr(remoteId))
|
|
|
|
// Transport spy
|
|
const transport = libp2p.transportManager._transports.get('Circuit')
|
|
sinon.spy(transport, 'dial')
|
|
|
|
// Resolver stub
|
|
const stub = sinon.stub(Resolver.prototype, 'resolveTxt')
|
|
stub.onCall(0).callsFake(() => Promise.resolve(getDnsaddrStub(remoteId)))
|
|
stub.onCall(1).callsFake(() => Promise.reject(new Error()))
|
|
stub.callsFake(() => Promise.resolve(getDnsRelayedAddrStub(remoteId)))
|
|
|
|
// Dial with address resolve
|
|
const connection = await libp2p.dial(dialAddr)
|
|
expect(connection).to.exist()
|
|
expect(connection.remoteAddr.equals(relayedAddrFetched))
|
|
|
|
const dialArgs = transport.dial.firstCall.args
|
|
expect(dialArgs[0].equals(relayedAddrFetched)).to.eql(true)
|
|
})
|
|
|
|
it('fails to dial if resolve fails and there are no addresses to dial', async () => {
|
|
const remoteId = remoteLibp2p.peerId.toB58String()
|
|
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
|
|
|
// Stub resolver
|
|
const stubResolve = sinon.stub(Resolver.prototype, 'resolveTxt')
|
|
stubResolve.returns(Promise.reject(new Error()))
|
|
|
|
// Stub transport
|
|
const transport = libp2p.transportManager._transports.get('WebSockets')
|
|
const spy = sinon.spy(transport, 'dial')
|
|
|
|
await expect(libp2p.dial(dialAddr))
|
|
.to.eventually.be.rejectedWith(Error)
|
|
.and.to.have.nested.property('.code', ErrorCodes.ERR_NO_VALID_ADDRESSES)
|
|
expect(spy.callCount).to.eql(0)
|
|
})
|
|
})
|