mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-05-31 11:11:23 +00:00
Returning `undefined` makes the address length check in [dialler/index.js](https://github.com/libp2p/js-libp2p/blob/master/src/dialer/index.js#L73-L75) fail with `cannot read property length of undefined` so the change here is to always return an array, but it might be empty if we don't know any multiaddrs for the given peer.
401 lines
10 KiB
JavaScript
401 lines
10 KiB
JavaScript
'use strict'
|
|
/* eslint-env mocha */
|
|
|
|
const chai = require('chai')
|
|
chai.use(require('dirty-chai'))
|
|
const { expect } = chai
|
|
|
|
const pDefer = require('p-defer')
|
|
const multiaddr = require('multiaddr')
|
|
|
|
const PeerStore = require('../../src/peer-store')
|
|
|
|
const peerUtils = require('../utils/creators/peer')
|
|
const {
|
|
codes: { ERR_INVALID_PARAMETERS }
|
|
} = require('../../src/errors')
|
|
|
|
const addr1 = multiaddr('/ip4/127.0.0.1/tcp/8000')
|
|
const addr2 = multiaddr('/ip4/127.0.0.1/tcp/8001')
|
|
const addr3 = multiaddr('/ip4/127.0.0.1/tcp/8002')
|
|
|
|
const arraysAreEqual = (a, b) => a.length === b.length && a.sort().every((item, index) => b[index] === item)
|
|
|
|
describe('addressBook', () => {
|
|
let peerId
|
|
|
|
before(async () => {
|
|
[peerId] = await peerUtils.createPeerId()
|
|
})
|
|
|
|
describe('addressBook.set', () => {
|
|
let peerStore, ab
|
|
|
|
beforeEach(() => {
|
|
peerStore = new PeerStore()
|
|
ab = peerStore.addressBook
|
|
})
|
|
|
|
afterEach(() => {
|
|
peerStore.removeAllListeners()
|
|
})
|
|
|
|
it('throwns invalid parameters error if invalid PeerId is provided', () => {
|
|
try {
|
|
ab.set('invalid peerId')
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('invalid peerId should throw error')
|
|
})
|
|
|
|
it('throwns invalid parameters error if no addresses provided', () => {
|
|
try {
|
|
ab.set(peerId)
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('no addresses should throw error')
|
|
})
|
|
|
|
it('throwns invalid parameters error if invalid multiaddrs are provided', () => {
|
|
try {
|
|
ab.set(peerId, ['invalid multiaddr'])
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('invalid multiaddrs should throw error')
|
|
})
|
|
|
|
it('replaces the stored content by default and emit change event', () => {
|
|
const defer = pDefer()
|
|
const supportedMultiaddrs = [addr1, addr2]
|
|
|
|
peerStore.once('change:multiaddrs', ({ peerId, multiaddrs }) => {
|
|
expect(peerId).to.exist()
|
|
expect(multiaddrs).to.eql(supportedMultiaddrs)
|
|
defer.resolve()
|
|
})
|
|
|
|
ab.set(peerId, supportedMultiaddrs)
|
|
const addresses = ab.get(peerId)
|
|
const multiaddrs = addresses.map((mi) => mi.multiaddr)
|
|
expect(multiaddrs).to.have.deep.members(supportedMultiaddrs)
|
|
|
|
return defer.promise
|
|
})
|
|
|
|
it('emits on set if not storing the exact same content', async () => {
|
|
const defer = pDefer()
|
|
|
|
const supportedMultiaddrsA = [addr1, addr2]
|
|
const supportedMultiaddrsB = [addr2]
|
|
|
|
let changeCounter = 0
|
|
peerStore.on('change:multiaddrs', () => {
|
|
changeCounter++
|
|
if (changeCounter > 1) {
|
|
defer.resolve()
|
|
}
|
|
})
|
|
|
|
// set 1
|
|
ab.set(peerId, supportedMultiaddrsA)
|
|
|
|
// set 2 (same content)
|
|
ab.set(peerId, supportedMultiaddrsB)
|
|
const addresses = ab.get(peerId)
|
|
const multiaddrs = addresses.map((mi) => mi.multiaddr)
|
|
expect(multiaddrs).to.have.deep.members(supportedMultiaddrsB)
|
|
|
|
await defer.promise
|
|
})
|
|
|
|
it('does not emit on set if it is storing the exact same content', async () => {
|
|
const defer = pDefer()
|
|
|
|
const supportedMultiaddrs = [addr1, addr2]
|
|
|
|
let changeCounter = 0
|
|
peerStore.on('change:multiaddrs', () => {
|
|
changeCounter++
|
|
if (changeCounter > 1) {
|
|
defer.reject()
|
|
}
|
|
})
|
|
|
|
// set 1
|
|
ab.set(peerId, supportedMultiaddrs)
|
|
|
|
// set 2 (same content)
|
|
ab.set(peerId, supportedMultiaddrs)
|
|
|
|
// Wait 50ms for incorrect second event
|
|
setTimeout(() => {
|
|
defer.resolve()
|
|
}, 50)
|
|
|
|
await defer.promise
|
|
})
|
|
})
|
|
|
|
describe('addressBook.add', () => {
|
|
let peerStore, ab
|
|
|
|
beforeEach(() => {
|
|
peerStore = new PeerStore()
|
|
ab = peerStore.addressBook
|
|
})
|
|
|
|
afterEach(() => {
|
|
peerStore.removeAllListeners()
|
|
})
|
|
|
|
it('throwns invalid parameters error if invalid PeerId is provided', () => {
|
|
try {
|
|
ab.add('invalid peerId')
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('invalid peerId should throw error')
|
|
})
|
|
|
|
it('throwns invalid parameters error if no addresses provided', () => {
|
|
try {
|
|
ab.add(peerId)
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('no addresses provided should throw error')
|
|
})
|
|
|
|
it('throwns invalid parameters error if invalid multiaddrs are provided', () => {
|
|
try {
|
|
ab.add(peerId, ['invalid multiaddr'])
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('invalid multiaddr should throw error')
|
|
})
|
|
|
|
it('adds the new content and emits change event', () => {
|
|
const defer = pDefer()
|
|
|
|
const supportedMultiaddrsA = [addr1, addr2]
|
|
const supportedMultiaddrsB = [addr3]
|
|
const finalMultiaddrs = supportedMultiaddrsA.concat(supportedMultiaddrsB)
|
|
|
|
let changeTrigger = 2
|
|
peerStore.on('change:multiaddrs', ({ multiaddrs }) => {
|
|
changeTrigger--
|
|
if (changeTrigger === 0 && arraysAreEqual(multiaddrs, finalMultiaddrs)) {
|
|
defer.resolve()
|
|
}
|
|
})
|
|
|
|
// Replace
|
|
ab.set(peerId, supportedMultiaddrsA)
|
|
let addresses = ab.get(peerId)
|
|
let multiaddrs = addresses.map((mi) => mi.multiaddr)
|
|
expect(multiaddrs).to.have.deep.members(supportedMultiaddrsA)
|
|
|
|
// Add
|
|
ab.add(peerId, supportedMultiaddrsB)
|
|
addresses = ab.get(peerId)
|
|
multiaddrs = addresses.map((mi) => mi.multiaddr)
|
|
expect(multiaddrs).to.have.deep.members(finalMultiaddrs)
|
|
|
|
return defer.promise
|
|
})
|
|
|
|
it('emits on add if the content to add not exists', async () => {
|
|
const defer = pDefer()
|
|
|
|
const supportedMultiaddrsA = [addr1]
|
|
const supportedMultiaddrsB = [addr2]
|
|
const finalMultiaddrs = supportedMultiaddrsA.concat(supportedMultiaddrsB)
|
|
|
|
let changeCounter = 0
|
|
peerStore.on('change:multiaddrs', () => {
|
|
changeCounter++
|
|
if (changeCounter > 1) {
|
|
defer.resolve()
|
|
}
|
|
})
|
|
|
|
// set 1
|
|
ab.set(peerId, supportedMultiaddrsA)
|
|
|
|
// set 2 (content already existing)
|
|
ab.add(peerId, supportedMultiaddrsB)
|
|
const addresses = ab.get(peerId)
|
|
const multiaddrs = addresses.map((mi) => mi.multiaddr)
|
|
expect(multiaddrs).to.have.deep.members(finalMultiaddrs)
|
|
|
|
await defer.promise
|
|
})
|
|
|
|
it('does not emit on add if the content to add already exists', async () => {
|
|
const defer = pDefer()
|
|
|
|
const supportedMultiaddrsA = [addr1, addr2]
|
|
const supportedMultiaddrsB = [addr2]
|
|
|
|
let changeCounter = 0
|
|
peerStore.on('change:multiaddrs', () => {
|
|
changeCounter++
|
|
if (changeCounter > 1) {
|
|
defer.reject()
|
|
}
|
|
})
|
|
|
|
// set 1
|
|
ab.set(peerId, supportedMultiaddrsA)
|
|
|
|
// set 2 (content already existing)
|
|
ab.add(peerId, supportedMultiaddrsB)
|
|
|
|
// Wait 50ms for incorrect second event
|
|
setTimeout(() => {
|
|
defer.resolve()
|
|
}, 50)
|
|
|
|
await defer.promise
|
|
})
|
|
})
|
|
|
|
describe('addressBook.get', () => {
|
|
let peerStore, ab
|
|
|
|
beforeEach(() => {
|
|
peerStore = new PeerStore()
|
|
ab = peerStore.addressBook
|
|
})
|
|
|
|
it('throwns invalid parameters error if invalid PeerId is provided', () => {
|
|
try {
|
|
ab.get('invalid peerId')
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('invalid peerId should throw error')
|
|
})
|
|
|
|
it('returns undefined if no multiaddrs are known for the provided peer', () => {
|
|
const addresses = ab.get(peerId)
|
|
|
|
expect(addresses).to.not.exist()
|
|
})
|
|
|
|
it('returns the multiaddrs stored', () => {
|
|
const supportedMultiaddrs = [addr1, addr2]
|
|
|
|
ab.set(peerId, supportedMultiaddrs)
|
|
|
|
const addresses = ab.get(peerId)
|
|
const multiaddrs = addresses.map((mi) => mi.multiaddr)
|
|
expect(multiaddrs).to.have.deep.members(supportedMultiaddrs)
|
|
})
|
|
})
|
|
|
|
describe('addressBook.getMultiaddrsForPeer', () => {
|
|
let peerStore, ab
|
|
|
|
beforeEach(() => {
|
|
peerStore = new PeerStore()
|
|
ab = peerStore.addressBook
|
|
})
|
|
|
|
it('throwns invalid parameters error if invalid PeerId is provided', () => {
|
|
try {
|
|
ab.getMultiaddrsForPeer('invalid peerId')
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('invalid peerId should throw error')
|
|
})
|
|
|
|
it('returns empty array if no multiaddrs are known for the provided peer', () => {
|
|
const addresses = ab.getMultiaddrsForPeer(peerId)
|
|
|
|
expect(addresses).to.be.empty()
|
|
})
|
|
|
|
it('returns the multiaddrs stored', () => {
|
|
const supportedMultiaddrs = [addr1, addr2]
|
|
|
|
ab.set(peerId, supportedMultiaddrs)
|
|
|
|
const multiaddrs = ab.getMultiaddrsForPeer(peerId)
|
|
multiaddrs.forEach((m) => {
|
|
expect(m.getPeerId()).to.equal(peerId.toB58String())
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('addressBook.delete', () => {
|
|
let peerStore, ab
|
|
|
|
beforeEach(() => {
|
|
peerStore = new PeerStore()
|
|
ab = peerStore.addressBook
|
|
})
|
|
|
|
it('throwns invalid parameters error if invalid PeerId is provided', () => {
|
|
try {
|
|
ab.delete('invalid peerId')
|
|
} catch (err) {
|
|
expect(err.code).to.equal(ERR_INVALID_PARAMETERS)
|
|
return
|
|
}
|
|
throw new Error('invalid peerId should throw error')
|
|
})
|
|
|
|
it('returns false if no records exist for the peer and no event is emitted', () => {
|
|
const defer = pDefer()
|
|
|
|
peerStore.on('change:multiaddrs', () => {
|
|
defer.reject()
|
|
})
|
|
|
|
const deleted = ab.delete(peerId)
|
|
|
|
expect(deleted).to.equal(false)
|
|
|
|
// Wait 50ms for incorrect invalid event
|
|
setTimeout(() => {
|
|
defer.resolve()
|
|
}, 50)
|
|
|
|
return defer.promise
|
|
})
|
|
|
|
it('returns true if the record exists and an event is emitted', () => {
|
|
const defer = pDefer()
|
|
|
|
const supportedMultiaddrs = [addr1, addr2]
|
|
ab.set(peerId, supportedMultiaddrs)
|
|
|
|
// Listen after set
|
|
peerStore.on('change:multiaddrs', ({ multiaddrs }) => {
|
|
expect(multiaddrs.length).to.eql(0)
|
|
defer.resolve()
|
|
})
|
|
|
|
const deleted = ab.delete(peerId)
|
|
|
|
expect(deleted).to.equal(true)
|
|
|
|
return defer.promise
|
|
})
|
|
})
|
|
})
|