fix: make tests more reliable (#1139)

Try to use only public functions and properties to verify test behaviour
This commit is contained in:
Alex Potsides 2022-01-21 12:58:31 +00:00 committed by GitHub
parent 4c3bf01f35
commit b7e87066a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 103 additions and 192 deletions

View File

@ -592,7 +592,7 @@ const node = await Libp2p.create({
#### Configuring Transport Manager #### Configuring Transport Manager
The Transport Manager is responsible for managing the libp2p transports life cycle. This includes starting listeners for the provided listen addresses, closing these listeners and dialing using the provided transports. By default, if a libp2p node has a list of multiaddrs for listenning on and there are no valid transports for those multiaddrs, libp2p will throw an error on startup and shutdown. However, for some applications it is perfectly acceptable for libp2p nodes to start in dial only mode if all the listen multiaddrs failed. This error tolerance can be enabled as follows: The Transport Manager is responsible for managing the libp2p transports life cycle. This includes starting listeners for the provided listen addresses, closing these listeners and dialing using the provided transports. By default, if a libp2p node has a list of multiaddrs for listening on and there are no valid transports for those multiaddrs, libp2p will throw an error on startup and shutdown. However, for some applications it is perfectly acceptable for libp2p nodes to start in dial only mode if all the listen multiaddrs failed. This error tolerance can be enabled as follows:
```js ```js
const Libp2p = require('libp2p') const Libp2p = require('libp2p')

View File

@ -8,6 +8,7 @@ const log = Object.assign(debug('libp2p:auto-relay'), {
const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string')
const { toString: uint8ArrayToString } = require('uint8arrays/to-string') const { toString: uint8ArrayToString } = require('uint8arrays/to-string')
const { Multiaddr } = require('multiaddr') const { Multiaddr } = require('multiaddr')
const all = require('it-all')
const { relay: multicodec } = require('./multicodec') const { relay: multicodec } = require('./multicodec')
const { canHop } = require('./circuit/hop') const { canHop } = require('./circuit/hop')
@ -149,26 +150,27 @@ class AutoRelay {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async _addListenRelay (connection, id) { async _addListenRelay (connection, id) {
// Check if already listening on enough relays
if (this._listenRelays.size >= this.maxListeners) {
return
}
// Get peer known addresses and sort them per public addresses first
const remoteAddrs = await this._peerStore.addressBook.getMultiaddrsForPeer(
connection.remotePeer, this._addressSorter
)
if (!remoteAddrs || !remoteAddrs.length) {
return
}
const listenAddr = `${remoteAddrs[0].toString()}/p2p-circuit`
this._listenRelays.add(id)
// Attempt to listen on relay
try { try {
// Check if already listening on enough relays
if (this._listenRelays.size >= this.maxListeners) {
return
}
// Get peer known addresses and sort them per public addresses first
const remoteAddrs = await this._peerStore.addressBook.getMultiaddrsForPeer(
connection.remotePeer, this._addressSorter
)
if (!remoteAddrs || !remoteAddrs.length) {
return
}
const listenAddr = `${remoteAddrs[0].toString()}/p2p-circuit`
this._listenRelays.add(id)
// Attempt to listen on relay
await this._transportManager.listen([new Multiaddr(listenAddr)]) await this._transportManager.listen([new Multiaddr(listenAddr)])
// Announce multiaddrs will update on listen success by TransportManager event being triggered // Announce multiaddrs will update on listen success by TransportManager event being triggered
} catch (/** @type {any} */ err) { } catch (/** @type {any} */ err) {
this._onError(err) this._onError(err)
@ -206,13 +208,18 @@ class AutoRelay {
} }
const knownHopsToDial = [] const knownHopsToDial = []
const peers = await all(this._peerStore.getPeers())
// Check if we have known hop peers to use and attempt to listen on the already connected // Check if we have known hop peers to use and attempt to listen on the already connected
for await (const { id, metadata } of this._peerStore.getPeers()) { for await (const { id, metadata } of peers) {
const idStr = id.toB58String() const idStr = id.toB58String()
// Continue to next if listening on this or peer to ignore // Continue to next if listening on this or peer to ignore
if (this._listenRelays.has(idStr) || peersToIgnore.includes(idStr)) { if (this._listenRelays.has(idStr)) {
continue
}
if (peersToIgnore.includes(idStr)) {
continue continue
} }

View File

@ -2,8 +2,7 @@
/* eslint-env mocha */ /* eslint-env mocha */
const { expect } = require('aegir/utils/chai') const { expect } = require('aegir/utils/chai')
const delay = require('delay') const defer = require('p-defer')
const pDefer = require('p-defer')
const pWaitFor = require('p-wait-for') const pWaitFor = require('p-wait-for')
const sinon = require('sinon') const sinon = require('sinon')
const nock = require('nock') const nock = require('nock')
@ -19,11 +18,35 @@ const baseOptions = require('../utils/base-options')
const listenAddr = '/ip4/0.0.0.0/tcp/0' const listenAddr = '/ip4/0.0.0.0/tcp/0'
async function usingAsRelay (node, relay, opts) {
// Wait for peer to be used as a relay
await pWaitFor(() => {
for (const addr of node.multiaddrs) {
if (addr.toString().includes(`${relay.peerId.toB58String()}/p2p-circuit`)) {
return true
}
}
return false
}, opts)
}
async function discoveredRelayConfig (node, relay) {
await pWaitFor(async () => {
const protos = await node.peerStore.protoBook.get(relay.peerId)
const supportsRelay = protos.includes('/libp2p/circuit/relay/0.1.0')
const metadata = await node.peerStore.metadataBook.get(relay.peerId)
const supportsHop = metadata.has('hop_relay')
return supportsRelay && supportsHop
})
}
describe('auto-relay', () => { describe('auto-relay', () => {
describe('basics', () => { describe('basics', () => {
let libp2p let libp2p
let relayLibp2p let relayLibp2p
let autoRelay
beforeEach(async () => { beforeEach(async () => {
const peerIds = await createPeerId({ number: 2 }) const peerIds = await createPeerId({ number: 2 })
@ -59,10 +82,6 @@ describe('auto-relay', () => {
peerId peerId
}) })
}) })
autoRelay = libp2p.relay._autoRelay
expect(autoRelay.maxListeners).to.eql(1)
}) })
beforeEach(() => { beforeEach(() => {
@ -76,22 +95,15 @@ describe('auto-relay', () => {
}) })
it('should ask if node supports hop on protocol change (relay protocol) and add to listen multiaddrs', async () => { it('should ask if node supports hop on protocol change (relay protocol) and add to listen multiaddrs', async () => {
// Spy if a connected peer is being added as listen relay
sinon.spy(autoRelay, '_addListenRelay')
const originalMultiaddrsLength = relayLibp2p.multiaddrs.length
// Discover relay // Discover relay
await libp2p.peerStore.addressBook.add(relayLibp2p.peerId, relayLibp2p.multiaddrs) await libp2p.peerStore.addressBook.add(relayLibp2p.peerId, relayLibp2p.multiaddrs)
await libp2p.dial(relayLibp2p.peerId) await libp2p.dial(relayLibp2p.peerId)
// Wait for peer added as listen relay // Wait for peer added as listen relay
await pWaitFor(() => autoRelay._addListenRelay.callCount === 1) await discoveredRelayConfig(libp2p, relayLibp2p)
expect(autoRelay._listenRelays.size).to.equal(1)
// Wait for listen multiaddr update // Wait to start using peer as a relay
await pWaitFor(() => libp2p.multiaddrs.length === originalMultiaddrsLength + 1) await usingAsRelay(libp2p, relayLibp2p)
expect(libp2p.multiaddrs[originalMultiaddrsLength].getPeerId()).to.eql(relayLibp2p.peerId.toB58String())
// Peer has relay multicodec // Peer has relay multicodec
const knownProtocols = await libp2p.peerStore.protoBook.get(relayLibp2p.peerId) const knownProtocols = await libp2p.peerStore.protoBook.get(relayLibp2p.peerId)
@ -104,7 +116,6 @@ describe('auto-relay', () => {
let relayLibp2p1 let relayLibp2p1
let relayLibp2p2 let relayLibp2p2
let relayLibp2p3 let relayLibp2p3
let autoRelay1
beforeEach(async () => { beforeEach(async () => {
const peerIds = await createPeerId({ number: 4 }) const peerIds = await createPeerId({ number: 4 })
@ -144,10 +155,6 @@ describe('auto-relay', () => {
peerId peerId
}) })
}) })
autoRelay1 = relayLibp2p1.relay._autoRelay
expect(autoRelay1.maxListeners).to.eql(1)
}) })
beforeEach(() => { beforeEach(() => {
@ -161,27 +168,13 @@ describe('auto-relay', () => {
}) })
it('should ask if node supports hop on protocol change (relay protocol) and add to listen multiaddrs', async () => { it('should ask if node supports hop on protocol change (relay protocol) and add to listen multiaddrs', async () => {
// Spy if a connected peer is being added as listen relay
sinon.spy(autoRelay1, '_addListenRelay')
// Discover relay // Discover relay
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs)
const originalMultiaddrs1Length = relayLibp2p1.multiaddrs.length
const originalMultiaddrs2Length = relayLibp2p2.multiaddrs.length
await relayLibp2p1.dial(relayLibp2p2.peerId) await relayLibp2p1.dial(relayLibp2p2.peerId)
await discoveredRelayConfig(relayLibp2p1, relayLibp2p2)
// Wait for peer added as listen relay // Wait for peer added as listen relay
await pWaitFor(() => autoRelay1._addListenRelay.callCount === 1) await usingAsRelay(relayLibp2p1, relayLibp2p2)
expect(autoRelay1._listenRelays.size).to.equal(1)
// Wait for listen multiaddr update
await Promise.all([
pWaitFor(() => relayLibp2p1.multiaddrs.length === originalMultiaddrs1Length + 1),
pWaitFor(() => relayLibp2p2.multiaddrs.length === originalMultiaddrs2Length + 1)
])
expect(relayLibp2p1.multiaddrs[originalMultiaddrs1Length].getPeerId()).to.eql(relayLibp2p2.peerId.toB58String())
// Peer has relay multicodec // Peer has relay multicodec
const knownProtocols = await relayLibp2p1.peerStore.protoBook.get(relayLibp2p2.peerId) const knownProtocols = await relayLibp2p1.peerStore.protoBook.get(relayLibp2p2.peerId)
@ -189,52 +182,28 @@ describe('auto-relay', () => {
}) })
it('should be able to dial a peer from its relayed address previously added', async () => { it('should be able to dial a peer from its relayed address previously added', async () => {
const originalMultiaddrs1Length = relayLibp2p1.multiaddrs.length
const originalMultiaddrs2Length = relayLibp2p2.multiaddrs.length
// Discover relay // Discover relay
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs)
await relayLibp2p1.dial(relayLibp2p2.peerId) await relayLibp2p1.dial(relayLibp2p2.peerId)
await discoveredRelayConfig(relayLibp2p1, relayLibp2p2)
// Wait for listen multiaddr update // Wait for peer added as listen relay
await Promise.all([ await usingAsRelay(relayLibp2p1, relayLibp2p2)
pWaitFor(() => relayLibp2p1.multiaddrs.length === originalMultiaddrs1Length + 1),
pWaitFor(() => relayLibp2p2.multiaddrs.length === originalMultiaddrs2Length + 1)
])
expect(relayLibp2p1.multiaddrs[originalMultiaddrs1Length].getPeerId()).to.eql(relayLibp2p2.peerId.toB58String())
// Dial from the other through a relay // Dial from the other through a relay
const relayedMultiaddr2 = new Multiaddr(`${relayLibp2p1.multiaddrs[0]}/p2p/${relayLibp2p1.peerId.toB58String()}/p2p-circuit`) const relayedMultiaddr2 = new Multiaddr(`${relayLibp2p1.multiaddrs[0]}/p2p/${relayLibp2p1.peerId.toB58String()}/p2p-circuit`)
await libp2p.peerStore.addressBook.add(relayLibp2p2.peerId, [relayedMultiaddr2]) await libp2p.peerStore.addressBook.add(relayLibp2p2.peerId, [relayedMultiaddr2])
await libp2p.dial(relayLibp2p2.peerId) await libp2p.dial(relayLibp2p2.peerId)
}) })
it('should only add maxListeners relayed addresses', async () => { it('should only add maxListeners relayed addresses', async () => {
const originalMultiaddrs1Length = relayLibp2p1.multiaddrs.length
const originalMultiaddrs2Length = relayLibp2p2.multiaddrs.length
// Spy if a connected peer is being added as listen relay
sinon.spy(autoRelay1, '_addListenRelay')
sinon.spy(autoRelay1._listenRelays, 'add')
// Discover one relay and connect // Discover one relay and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs)
await relayLibp2p1.dial(relayLibp2p2.peerId) await relayLibp2p1.dial(relayLibp2p2.peerId)
await discoveredRelayConfig(relayLibp2p1, relayLibp2p2)
expect(relayLibp2p1.connectionManager.size).to.eql(1)
// Wait for peer added as listen relay // Wait for peer added as listen relay
await pWaitFor(() => autoRelay1._addListenRelay.callCount === 1 && autoRelay1._listenRelays.add.callCount === 1) await usingAsRelay(relayLibp2p1, relayLibp2p2)
expect(autoRelay1._listenRelays.size).to.equal(1)
// Wait for listen multiaddr update
await Promise.all([
pWaitFor(() => relayLibp2p1.multiaddrs.length === originalMultiaddrs1Length + 1),
pWaitFor(() => relayLibp2p2.multiaddrs.length === originalMultiaddrs2Length + 1)
])
expect(relayLibp2p1.multiaddrs[originalMultiaddrs1Length].getPeerId()).to.eql(relayLibp2p2.peerId.toB58String())
// Relay2 has relay multicodec // Relay2 has relay multicodec
const knownProtocols2 = await relayLibp2p1.peerStore.protoBook.get(relayLibp2p2.peerId) const knownProtocols2 = await relayLibp2p1.peerStore.protoBook.get(relayLibp2p2.peerId)
@ -243,14 +212,12 @@ describe('auto-relay', () => {
// Discover an extra relay and connect // Discover an extra relay and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs)
await relayLibp2p1.dial(relayLibp2p3.peerId) await relayLibp2p1.dial(relayLibp2p3.peerId)
await discoveredRelayConfig(relayLibp2p1, relayLibp2p3)
// Wait to guarantee the dialed peer is not added as a listen relay // Wait to guarantee the dialed peer is not added as a listen relay
await delay(300) await expect(usingAsRelay(relayLibp2p1, relayLibp2p3, {
timeout: 1000
expect(autoRelay1._addListenRelay.callCount).to.equal(2) })).to.eventually.be.rejected()
expect(autoRelay1._listenRelays.add.callCount).to.equal(1)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.connectionManager.size).to.eql(2)
// Relay2 has relay multicodec // Relay2 has relay multicodec
const knownProtocols3 = await relayLibp2p1.peerStore.protoBook.get(relayLibp2p3.peerId) const knownProtocols3 = await relayLibp2p1.peerStore.protoBook.get(relayLibp2p3.peerId)
@ -258,19 +225,16 @@ describe('auto-relay', () => {
}) })
it('should not listen on a relayed address if peer disconnects', async () => { it('should not listen on a relayed address if peer disconnects', async () => {
const originalMultiaddrs1Length = relayLibp2p1.multiaddrs.length
// Spy if identify push is fired on adding/removing listen addr // Spy if identify push is fired on adding/removing listen addr
sinon.spy(relayLibp2p1.identifyService, 'pushToPeerStore') sinon.spy(relayLibp2p1.identifyService, 'pushToPeerStore')
// Discover one relay and connect // Discover one relay and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs)
await relayLibp2p1.dial(relayLibp2p2.peerId) await relayLibp2p1.dial(relayLibp2p2.peerId)
await discoveredRelayConfig(relayLibp2p1, relayLibp2p2)
// Wait for listenning on the relay // Wait for listening on the relay
await pWaitFor(() => relayLibp2p1.multiaddrs.length === originalMultiaddrs1Length + 1) await usingAsRelay(relayLibp2p1, relayLibp2p2)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.multiaddrs[originalMultiaddrs1Length].getPeerId()).to.eql(relayLibp2p2.peerId.toB58String())
// Identify push for adding listen relay multiaddr // Identify push for adding listen relay multiaddr
expect(relayLibp2p1.identifyService.pushToPeerStore.callCount).to.equal(1) expect(relayLibp2p1.identifyService.pushToPeerStore.callCount).to.equal(1)
@ -279,107 +243,67 @@ describe('auto-relay', () => {
await relayLibp2p1.hangUp(relayLibp2p2.peerId) await relayLibp2p1.hangUp(relayLibp2p2.peerId)
// Wait for removed listening on the relay // Wait for removed listening on the relay
await pWaitFor(() => relayLibp2p1.multiaddrs.length === originalMultiaddrs1Length) await expect(usingAsRelay(relayLibp2p1, relayLibp2p2, {
expect(autoRelay1._listenRelays.size).to.equal(0) timeout: 1000
})).to.eventually.be.rejected()
// Identify push for removing listen relay multiaddr // Identify push for removing listen relay multiaddr
await pWaitFor(() => relayLibp2p1.identifyService.pushToPeerStore.callCount === 2) await pWaitFor(() => relayLibp2p1.identifyService.pushToPeerStore.callCount === 2)
}) })
it('should try to listen on other connected peers relayed address if one used relay disconnects', async () => { it('should try to listen on other connected peers relayed address if one used relay disconnects', async () => {
const originalMultiaddrs1Length = relayLibp2p1.multiaddrs.length
// Spy if a connected peer is being added as listen relay
sinon.spy(autoRelay1, '_addListenRelay')
sinon.spy(relayLibp2p1.transportManager, 'listen')
// Discover one relay and connect // Discover one relay and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs)
await relayLibp2p1.dial(relayLibp2p2.peerId) await relayLibp2p1.dial(relayLibp2p2.peerId)
await discoveredRelayConfig(relayLibp2p1, relayLibp2p2)
await usingAsRelay(relayLibp2p1, relayLibp2p2)
// Discover an extra relay and connect // Discover an extra relay and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs)
await relayLibp2p1.dial(relayLibp2p3.peerId) await relayLibp2p1.dial(relayLibp2p3.peerId)
await discoveredRelayConfig(relayLibp2p1, relayLibp2p3)
// Wait for both peer to be attempted to added as listen relay
await pWaitFor(() => autoRelay1._addListenRelay.callCount === 1)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.connectionManager.size).to.equal(2)
// Wait for listen multiaddr update
await pWaitFor(() => relayLibp2p1.multiaddrs.length === originalMultiaddrs1Length + 1)
expect(relayLibp2p1.multiaddrs[originalMultiaddrs1Length].getPeerId()).to.eql(relayLibp2p2.peerId.toB58String())
// Only one will be used for listening // Only one will be used for listening
expect(relayLibp2p1.transportManager.listen.callCount).to.equal(1) await expect(usingAsRelay(relayLibp2p1, relayLibp2p3, {
timeout: 1000
// Spy if relay from listen map was removed })).to.eventually.be.rejected()
sinon.spy(autoRelay1._listenRelays, 'delete')
// Disconnect from peer used for relay // Disconnect from peer used for relay
await relayLibp2p1.hangUp(relayLibp2p2.peerId) await relayLibp2p2.stop()
expect(autoRelay1._listenRelays.delete.callCount).to.equal(1)
expect(autoRelay1._addListenRelay.callCount).to.equal(1)
// Wait for other peer connected to be added as listen addr // Wait for other peer connected to be added as listen addr
await pWaitFor(() => relayLibp2p1.transportManager.listen.callCount === 2) await usingAsRelay(relayLibp2p1, relayLibp2p3)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.connectionManager.size).to.eql(1)
// Wait for listen multiaddr update
await pWaitFor(() => relayLibp2p1.multiaddrs.length === originalMultiaddrs1Length + 1)
expect(relayLibp2p1.multiaddrs[originalMultiaddrs1Length].getPeerId()).to.eql(relayLibp2p3.peerId.toB58String())
}) })
it('should try to listen on stored peers relayed address if one used relay disconnects and there are not enough connected', async () => { it('should try to listen on stored peers relayed address if one used relay disconnects and there are not enough connected', async () => {
// Spy if a connected peer is being added as listen relay
sinon.spy(autoRelay1, '_addListenRelay')
sinon.spy(relayLibp2p1.transportManager, 'listen')
// Discover one relay and connect // Discover one relay and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs)
await relayLibp2p1.dial(relayLibp2p2.peerId) await relayLibp2p1.dial(relayLibp2p2.peerId)
// Wait for peer to be used as a relay
await usingAsRelay(relayLibp2p1, relayLibp2p2)
// Discover an extra relay and connect to gather its Hop support // Discover an extra relay and connect to gather its Hop support
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs)
await relayLibp2p1.dial(relayLibp2p3.peerId) await relayLibp2p1.dial(relayLibp2p3.peerId)
// Wait for both peer to be attempted to added as listen relay // wait for identify for newly dialled peer
await pWaitFor(() => autoRelay1._addListenRelay.callCount === 2) await discoveredRelayConfig(relayLibp2p1, relayLibp2p3)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.connectionManager.size).to.equal(2)
// Only one will be used for listening
expect(relayLibp2p1.transportManager.listen.callCount).to.equal(1)
// Disconnect not used listen relay // Disconnect not used listen relay
await relayLibp2p1.hangUp(relayLibp2p3.peerId) await relayLibp2p1.hangUp(relayLibp2p3.peerId)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.connectionManager.size).to.equal(1)
// Spy on dial
sinon.spy(autoRelay1, '_tryToListenOnRelay')
sinon.spy(relayLibp2p1, 'dial')
// Remove peer used as relay from peerStore and disconnect it // Remove peer used as relay from peerStore and disconnect it
await relayLibp2p1.peerStore.delete(relayLibp2p2.peerId)
await relayLibp2p1.hangUp(relayLibp2p2.peerId) await relayLibp2p1.hangUp(relayLibp2p2.peerId)
expect(autoRelay1._listenRelays.size).to.equal(0) await relayLibp2p1.peerStore.delete(relayLibp2p2.peerId)
expect(relayLibp2p1.connectionManager.size).to.equal(0) await pWaitFor(() => relayLibp2p1.connectionManager.size === 0)
// Wait for other peer connected to be added as listen addr // Wait for other peer connected to be added as listen addr
await pWaitFor(() => relayLibp2p1.transportManager.listen.callCount === 2) await usingAsRelay(relayLibp2p1, relayLibp2p3)
await pWaitFor(() => autoRelay1._tryToListenOnRelay.callCount === 1)
await pWaitFor(() => autoRelay1._listenRelays.size === 1)
await pWaitFor(() => relayLibp2p1.connectionManager.size === 1)
}) })
it('should not fail when trying to dial unreachable peers to add as hop relay and replaced removed ones', async () => { it('should not fail when trying to dial unreachable peers to add as hop relay and replaced removed ones', async () => {
const defer = pDefer() const deferred = defer()
// Spy if a connected peer is being added as listen relay
sinon.spy(autoRelay1, '_addListenRelay')
sinon.spy(relayLibp2p1.transportManager, 'listen')
// Discover one relay and connect // Discover one relay and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p2.peerId, relayLibp2p2.multiaddrs)
@ -389,34 +313,28 @@ describe('auto-relay', () => {
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs)
await relayLibp2p1.dial(relayLibp2p3.peerId) await relayLibp2p1.dial(relayLibp2p3.peerId)
// Wait for both peer to be attempted to added as listen relay // Wait for peer to be used as a relay
await pWaitFor(() => autoRelay1._addListenRelay.callCount === 2) await usingAsRelay(relayLibp2p1, relayLibp2p2)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.connectionManager.size).to.equal(2)
// Only one will be used for listening // wait for identify for newly dialled peer
expect(relayLibp2p1.transportManager.listen.callCount).to.equal(1) await discoveredRelayConfig(relayLibp2p1, relayLibp2p3)
// Disconnect not used listen relay // Disconnect not used listen relay
await relayLibp2p1.hangUp(relayLibp2p3.peerId) await relayLibp2p1.hangUp(relayLibp2p3.peerId)
expect(autoRelay1._listenRelays.size).to.equal(1)
expect(relayLibp2p1.connectionManager.size).to.equal(1)
// Stub dial // Stub dial
sinon.stub(relayLibp2p1, 'dial').callsFake(() => { sinon.stub(relayLibp2p1, 'dial').callsFake(() => {
defer.resolve() deferred.resolve()
return Promise.reject(new Error('failed to dial')) return Promise.reject(new Error('failed to dial'))
}) })
// Remove peer used as relay from peerStore and disconnect it // Remove peer used as relay from peerStore and disconnect it
await relayLibp2p1.peerStore.delete(relayLibp2p2.peerId)
await relayLibp2p1.hangUp(relayLibp2p2.peerId) await relayLibp2p1.hangUp(relayLibp2p2.peerId)
expect(autoRelay1._listenRelays.size).to.equal(0) await relayLibp2p1.peerStore.delete(relayLibp2p2.peerId)
expect(relayLibp2p1.connectionManager.size).to.equal(0) expect(relayLibp2p1.connectionManager.size).to.equal(0)
// Wait for failed dial // Wait for failed dial
await defer.promise await deferred.promise
}) })
}) })
@ -424,8 +342,6 @@ describe('auto-relay', () => {
let relayLibp2p1 let relayLibp2p1
let relayLibp2p2 let relayLibp2p2
let relayLibp2p3 let relayLibp2p3
let autoRelay1
let autoRelay2
beforeEach(async () => { beforeEach(async () => {
const peerIds = await createPeerId({ number: 3 }) const peerIds = await createPeerId({ number: 3 })
@ -458,9 +374,6 @@ describe('auto-relay', () => {
peerId peerId
}) })
}) })
autoRelay1 = relayLibp2p1.relay._autoRelay
autoRelay2 = relayLibp2p2.relay._autoRelay
}) })
beforeEach(() => { beforeEach(() => {
@ -474,25 +387,15 @@ describe('auto-relay', () => {
}) })
it('should not add listener to a already relayed connection', async () => { it('should not add listener to a already relayed connection', async () => {
// Spy if a connected peer is being added as listen relay
sinon.spy(autoRelay1, '_addListenRelay')
sinon.spy(autoRelay2, '_addListenRelay')
// Relay 1 discovers Relay 3 and connect // Relay 1 discovers Relay 3 and connect
await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs) await relayLibp2p1.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs)
await relayLibp2p1.dial(relayLibp2p3.peerId) await relayLibp2p1.dial(relayLibp2p3.peerId)
await usingAsRelay(relayLibp2p1, relayLibp2p3)
// Wait for peer added as listen relay
await pWaitFor(() => autoRelay1._addListenRelay.callCount === 1)
expect(autoRelay1._listenRelays.size).to.equal(1)
// Relay 2 discovers Relay 3 and connect // Relay 2 discovers Relay 3 and connect
await relayLibp2p2.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs) await relayLibp2p2.peerStore.addressBook.add(relayLibp2p3.peerId, relayLibp2p3.multiaddrs)
await relayLibp2p2.dial(relayLibp2p3.peerId) await relayLibp2p2.dial(relayLibp2p3.peerId)
await usingAsRelay(relayLibp2p2, relayLibp2p3)
// Wait for peer added as listen relay
await pWaitFor(() => autoRelay2._addListenRelay.callCount === 1)
await pWaitFor(() => autoRelay2._listenRelays.size === 1)
// Relay 1 discovers Relay 2 relayed multiaddr via Relay 3 // Relay 1 discovers Relay 2 relayed multiaddr via Relay 3
const ma2RelayedBy3 = relayLibp2p2.multiaddrs[relayLibp2p2.multiaddrs.length - 1] const ma2RelayedBy3 = relayLibp2p2.multiaddrs[relayLibp2p2.multiaddrs.length - 1]
@ -500,8 +403,9 @@ describe('auto-relay', () => {
await relayLibp2p1.dial(relayLibp2p2.peerId) await relayLibp2p1.dial(relayLibp2p2.peerId)
// Peer not added as listen relay // Peer not added as listen relay
expect(autoRelay1._addListenRelay.callCount).to.equal(1) await expect(usingAsRelay(relayLibp2p1, relayLibp2p2, {
expect(autoRelay1._listenRelays.size).to.equal(1) timeout: 1000
})).to.eventually.be.rejected()
}) })
}) })