mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-04-01 07:11:04 +00:00
174 lines
5.2 KiB
JavaScript
174 lines
5.2 KiB
JavaScript
/* eslint-env mocha */
|
|
'use strict'
|
|
|
|
const chai = require('chai')
|
|
chai.use(require('dirty-chai'))
|
|
chai.use(require('chai-checkmark'))
|
|
const expect = chai.expect
|
|
const parallel = require('async/parallel')
|
|
const TCP = require('libp2p-tcp')
|
|
const multiplex = require('libp2p-mplex')
|
|
const pull = require('pull-stream')
|
|
const secio = require('libp2p-secio')
|
|
const PeerInfo = require('peer-info')
|
|
const PeerBook = require('peer-book')
|
|
const identify = require('../../src/identify')
|
|
const lp = require('pull-length-prefixed')
|
|
const sinon = require('sinon')
|
|
|
|
const utils = require('./utils')
|
|
const createInfos = utils.createInfos
|
|
const Switch = require('../../src/switch')
|
|
|
|
describe('Identify', () => {
|
|
let switchA
|
|
let switchB
|
|
let switchC
|
|
|
|
before((done) => createInfos(3, (err, infos) => {
|
|
expect(err).to.not.exist()
|
|
|
|
const peerA = infos[0]
|
|
const peerB = infos[1]
|
|
const peerC = infos[2]
|
|
|
|
peerA.multiaddrs.add('/ip4/127.0.0.1/tcp/9001')
|
|
peerB.multiaddrs.add('/ip4/127.0.0.1/tcp/9002')
|
|
peerC.multiaddrs.add('/ip4/127.0.0.1/tcp/9003')
|
|
|
|
switchA = new Switch(peerA, new PeerBook())
|
|
switchB = new Switch(peerB, new PeerBook())
|
|
switchC = new Switch(peerC, new PeerBook())
|
|
|
|
switchA.transport.add('tcp', new TCP())
|
|
switchB.transport.add('tcp', new TCP())
|
|
switchC.transport.add('tcp', new TCP())
|
|
|
|
switchA.connection.crypto(secio.tag, secio.encrypt)
|
|
switchB.connection.crypto(secio.tag, secio.encrypt)
|
|
switchC.connection.crypto(secio.tag, secio.encrypt)
|
|
|
|
switchA.connection.addStreamMuxer(multiplex)
|
|
switchB.connection.addStreamMuxer(multiplex)
|
|
switchC.connection.addStreamMuxer(multiplex)
|
|
|
|
switchA.connection.reuse()
|
|
switchB.connection.reuse()
|
|
switchC.connection.reuse()
|
|
|
|
parallel([
|
|
(cb) => switchA.transport.listen('tcp', {}, null, cb),
|
|
(cb) => switchB.transport.listen('tcp', {}, null, cb),
|
|
(cb) => switchC.transport.listen('tcp', {}, null, cb)
|
|
], done)
|
|
}))
|
|
|
|
after((done) => {
|
|
parallel([
|
|
(cb) => switchA.stop(cb),
|
|
(cb) => switchB.stop(cb),
|
|
(cb) => switchC.stop(cb)
|
|
], done)
|
|
})
|
|
|
|
afterEach(function (done) {
|
|
sinon.restore()
|
|
// Hangup everything
|
|
parallel([
|
|
(cb) => switchA.hangUp(switchB._peerInfo, cb),
|
|
(cb) => switchA.hangUp(switchC._peerInfo, cb),
|
|
(cb) => switchB.hangUp(switchA._peerInfo, cb),
|
|
(cb) => switchB.hangUp(switchC._peerInfo, cb),
|
|
(cb) => switchC.hangUp(switchA._peerInfo, cb),
|
|
(cb) => switchC.hangUp(switchB._peerInfo, cb)
|
|
], done)
|
|
})
|
|
|
|
it('should identify a good peer', (done) => {
|
|
switchA.handle('/id-test/1.0.0', (protocol, conn) => pull(conn, conn))
|
|
switchB.dial(switchA._peerInfo, '/id-test/1.0.0', (err, conn) => {
|
|
expect(err).to.not.exist()
|
|
|
|
const data = Buffer.from('data that can be had')
|
|
pull(
|
|
pull.values([data]),
|
|
conn,
|
|
pull.collect((err, values) => {
|
|
expect(err).to.not.exist()
|
|
expect(values).to.deep.equal([data])
|
|
done()
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
it('should get protocols for one another', (done) => {
|
|
// We need to reset the PeerInfo objects we use,
|
|
// since we share memory we can receive a false positive if not
|
|
const peerA = new PeerInfo(switchA._peerInfo.id)
|
|
switchA._peerInfo.multiaddrs.toArray().forEach((m) => {
|
|
peerA.multiaddrs.add(m)
|
|
})
|
|
switchB._peerBook.remove(switchA._peerInfo.id.toB58String())
|
|
switchA._peerBook.remove(switchB._peerInfo.id.toB58String())
|
|
|
|
switchA.handle('/id-test/1.0.0', (protocol, conn) => pull(conn, conn))
|
|
switchB.dial(peerA, '/id-test/1.0.0', (err) => {
|
|
expect(err).to.not.exist()
|
|
|
|
// Give identify a moment to run
|
|
setTimeout(() => {
|
|
const peerB = switchA._peerBook.get(switchB._peerInfo.id.toB58String())
|
|
const peerA = switchB._peerBook.get(switchA._peerInfo.id.toB58String())
|
|
expect(Array.from(peerB.protocols)).to.eql([
|
|
multiplex.multicodec,
|
|
identify.multicodec
|
|
])
|
|
expect(Array.from(peerA.protocols)).to.eql([
|
|
multiplex.multicodec,
|
|
identify.multicodec,
|
|
'/id-test/1.0.0'
|
|
])
|
|
|
|
done()
|
|
}, 500)
|
|
})
|
|
})
|
|
|
|
it('should close connection when identify fails', (done) => {
|
|
const stub = sinon.stub(identify, 'listener').callsFake((conn) => {
|
|
conn.getObservedAddrs((err, observedAddrs) => {
|
|
if (err) { return }
|
|
observedAddrs = observedAddrs[0]
|
|
|
|
// pretend to be another peer
|
|
const publicKey = switchC._peerInfo.id.pubKey.bytes
|
|
|
|
const msgSend = identify.message.encode({
|
|
protocolVersion: 'ipfs/0.1.0',
|
|
agentVersion: 'na',
|
|
publicKey: publicKey,
|
|
listenAddrs: switchC._peerInfo.multiaddrs.toArray().map((ma) => ma.buffer),
|
|
observedAddr: observedAddrs ? observedAddrs.buffer : Buffer.from('')
|
|
})
|
|
|
|
pull(
|
|
pull.values([msgSend]),
|
|
lp.encode(),
|
|
conn
|
|
)
|
|
})
|
|
})
|
|
|
|
expect(2).checks(done)
|
|
|
|
switchA.handle('/id-test/1.0.0', (protocol, conn) => pull(conn, conn))
|
|
switchB.dialFSM(switchA._peerInfo, '/id-test/1.0.0', (err, connFSM) => {
|
|
expect(err).to.not.exist().mark()
|
|
connFSM.once('close', () => {
|
|
expect(stub.called).to.eql(true).mark()
|
|
})
|
|
})
|
|
})
|
|
})
|