mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-06-29 00:41:34 +00:00
refactor: add core modules to libp2p (#400)
* refactor: add js-libp2p-connection-manager to repo Co-authored-by: David Dias <daviddias.p@gmail.com> Co-authored-by: Jacob Heun <jacobheun@gmail.com> Co-authored-by: Pedro Teixeira <i@pgte.me> Co-authored-by: Vasco Santos <vasco.santos@ua.pt> * test(conn-mgr): only run in node * refactor: add js-libp2p-identify to repo Co-authored-by: David Dias <daviddias.p@gmail.com> Co-authored-by: Friedel Ziegelmayer <dignifiedquire@gmail.com> Co-authored-by: Hugo Dias <hugomrdias@gmail.com> Co-authored-by: Jacob Heun <jacobheun@gmail.com> Co-authored-by: Maciej Krüger <mkg20001@gmail.com> Co-authored-by: Richard Littauer <richard.littauer@gmail.com> Co-authored-by: Vasco Santos <vasco.santos@moxy.studio> Co-authored-by: Yusef Napora <yusef@protocol.ai> Co-authored-by: ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com> * refactor: add libp2p-pnet to repo Co-authored-by: Jacob Heun <jacobheun@gmail.com> Co-authored-by: Vasco Santos <vasco.santos@moxy.studio> * refactor: add libp2p-ping to repo Co-authored-by: David Dias <daviddias.p@gmail.com> Co-authored-by: Francisco Baio Dias <xicombd@gmail.com> Co-authored-by: Friedel Ziegelmayer <dignifiedquire@gmail.com> Co-authored-by: Hugo Dias <mail@hugodias.me> Co-authored-by: Jacob Heun <jacobheun@gmail.com> Co-authored-by: João Antunes <j.goncalo.antunes@gmail.com> Co-authored-by: Richard Littauer <richard.littauer@gmail.com> Co-authored-by: Vasco Santos <vasco.santos@moxy.studio> Co-authored-by: Vasco Santos <vasco.santos@ua.pt> Co-authored-by: ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com> * refactor: add libp2p-circuit to repo Co-authored-by: David Dias <daviddias.p@gmail.com> Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com> Co-authored-by: Friedel Ziegelmayer <dignifiedquire@gmail.com> Co-authored-by: Hugo Dias <mail@hugodias.me> Co-authored-by: Jacob Heun <jacobheun@gmail.com> Co-authored-by: Maciej Krüger <mkg20001@gmail.com> Co-authored-by: Oli Evans <oli@tableflip.io> Co-authored-by: Pedro Teixeira <i@pgte.me> Co-authored-by: Vasco Santos <vasco.santos@ua.pt> Co-authored-by: Victor Bjelkholm <victorbjelkholm@gmail.com> Co-authored-by: Yusef Napora <yusef@napora.org> Co-authored-by: dirkmc <dirk@mccormick.cx> * test(switch): avoid using instanceof * chore(switch): update bignumber dep * refactor(circuit): clean up tests * refactor(switch): consolidate get peer utils * test(identify): do deep checks of addresses * test(identify): bump timeout for identify test * test(switch): tidy up limit dialer test * refactor(switch): remove redundant circuit tests * chore: add coverage script * refactor(circuit): consolidate get peer info * docs: reference original repositories in each sub readme * docs: fix comment * refactor: clean up sub package.json files and readmes
This commit is contained in:
303
test/circuit/dialer.spec.js
Normal file
303
test/circuit/dialer.spec.js
Normal file
@ -0,0 +1,303 @@
|
||||
/* eslint-env mocha */
|
||||
/* eslint max-nested-callbacks: ["error", 5] */
|
||||
|
||||
'use strict'
|
||||
|
||||
const Dialer = require('../../src/circuit/circuit/dialer')
|
||||
const nodes = require('./fixtures/nodes')
|
||||
const Connection = require('interface-connection').Connection
|
||||
const multiaddr = require('multiaddr')
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerId = require('peer-id')
|
||||
const pull = require('pull-stream/pull')
|
||||
const values = require('pull-stream/sources/values')
|
||||
const asyncMap = require('pull-stream/throughs/async-map')
|
||||
const pair = require('pull-pair/duplex')
|
||||
const pb = require('pull-protocol-buffers')
|
||||
|
||||
const proto = require('../../src/circuit/protocol')
|
||||
const utilsFactory = require('../../src/circuit/circuit/utils')
|
||||
|
||||
const sinon = require('sinon')
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const expect = chai.expect
|
||||
chai.use(dirtyChai)
|
||||
|
||||
describe(`dialer tests`, function () {
|
||||
let dialer
|
||||
|
||||
beforeEach(() => {
|
||||
dialer = sinon.createStubInstance(Dialer)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
describe(`.dial`, function () {
|
||||
beforeEach(function () {
|
||||
dialer.relayPeers = new Map()
|
||||
dialer.relayPeers.set(nodes.node2.id, new Connection())
|
||||
dialer.relayPeers.set(nodes.node3.id, new Connection())
|
||||
dialer.dial.callThrough()
|
||||
})
|
||||
|
||||
it(`fail on non circuit addr`, function () {
|
||||
const dstMa = multiaddr(`/ipfs/${nodes.node4.id}`)
|
||||
expect(() => dialer.dial(dstMa, (err) => {
|
||||
err.to.match(/invalid circuit address/)
|
||||
}))
|
||||
})
|
||||
|
||||
it(`dial a peer`, function (done) {
|
||||
const dstMa = multiaddr(`/p2p-circuit/ipfs/${nodes.node3.id}`)
|
||||
dialer._dialPeer.callsFake(function (dstMa, relay, callback) {
|
||||
return callback(null, dialer.relayPeers.get(nodes.node3.id))
|
||||
})
|
||||
|
||||
dialer.dial(dstMa, (err, conn) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(conn).to.be.an.instanceOf(Connection)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`dial a peer over the specified relay`, function (done) {
|
||||
const dstMa = multiaddr(`/ipfs/${nodes.node3.id}/p2p-circuit/ipfs/${nodes.node4.id}`)
|
||||
dialer._dialPeer.callsFake(function (dstMa, relay, callback) {
|
||||
expect(relay.toString()).to.equal(`/ipfs/${nodes.node3.id}`)
|
||||
return callback(null, new Connection())
|
||||
})
|
||||
|
||||
dialer.dial(dstMa, (err, conn) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(conn).to.be.an.instanceOf(Connection)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`.canHop`, function () {
|
||||
let fromConn = null
|
||||
const peer = new PeerInfo(PeerId.createFromB58String('QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA'))
|
||||
|
||||
let p = null
|
||||
beforeEach(function () {
|
||||
p = pair()
|
||||
fromConn = new Connection(p[0])
|
||||
|
||||
dialer.relayPeers = new Map()
|
||||
dialer.relayConns = new Map()
|
||||
dialer.utils = utilsFactory({})
|
||||
dialer.canHop.callThrough()
|
||||
dialer._dialRelayHelper.callThrough()
|
||||
})
|
||||
|
||||
it(`should handle successful CAN_HOP`, (done) => {
|
||||
dialer._dialRelay.callsFake((_, cb) => {
|
||||
pull(
|
||||
values([{
|
||||
type: proto.CircuitRelay.type.HOP,
|
||||
code: proto.CircuitRelay.Status.SUCCESS
|
||||
}]),
|
||||
pb.encode(proto.CircuitRelay),
|
||||
p[1]
|
||||
)
|
||||
cb(null, fromConn)
|
||||
})
|
||||
|
||||
dialer.canHop(peer, (err) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(dialer.relayPeers.has(peer.id.toB58String())).to.be.ok()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`should handle failed CAN_HOP`, function (done) {
|
||||
dialer._dialRelay.callsFake((_, cb) => {
|
||||
pull(
|
||||
values([{
|
||||
type: proto.CircuitRelay.type.HOP,
|
||||
code: proto.CircuitRelay.Status.HOP_CANT_SPEAK_RELAY
|
||||
}]),
|
||||
pb.encode(proto.CircuitRelay),
|
||||
p[1]
|
||||
)
|
||||
cb(null, fromConn)
|
||||
})
|
||||
|
||||
dialer.canHop(peer, (err) => {
|
||||
expect(err).to.exist()
|
||||
expect(dialer.relayPeers.has(peer.id.toB58String())).not.to.be.ok()
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`._dialPeer`, function () {
|
||||
beforeEach(function () {
|
||||
dialer.relayPeers = new Map()
|
||||
dialer.relayPeers.set(nodes.node1.id, new Connection())
|
||||
dialer.relayPeers.set(nodes.node2.id, new Connection())
|
||||
dialer.relayPeers.set(nodes.node3.id, new Connection())
|
||||
dialer._dialPeer.callThrough()
|
||||
})
|
||||
|
||||
it(`should dial a peer over any relay`, function (done) {
|
||||
const dstMa = multiaddr(`/ipfs/${nodes.node4.id}`)
|
||||
dialer._negotiateRelay.callsFake(function (conn, dstMa, callback) {
|
||||
if (conn === dialer.relayPeers.get(nodes.node3.id)) {
|
||||
return callback(null, dialer.relayPeers.get(nodes.node3.id))
|
||||
}
|
||||
|
||||
callback(new Error(`error`))
|
||||
})
|
||||
|
||||
dialer._dialPeer(dstMa, (err, conn) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(conn).to.be.an.instanceOf(Connection)
|
||||
expect(conn).to.deep.equal(dialer.relayPeers.get(nodes.node3.id))
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`should fail dialing a peer over any relay`, function (done) {
|
||||
const dstMa = multiaddr(`/ipfs/${nodes.node4.id}`)
|
||||
dialer._negotiateRelay.callsFake(function (conn, dstMa, callback) {
|
||||
callback(new Error(`error`))
|
||||
})
|
||||
|
||||
dialer._dialPeer(dstMa, (err, conn) => {
|
||||
expect(conn).to.be.undefined()
|
||||
expect(err).to.not.be.null()
|
||||
expect(err).to.equal(`no relay peers were found or all relays failed to dial`)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`._negotiateRelay`, function () {
|
||||
const dstMa = multiaddr(`/ipfs/${nodes.node4.id}`)
|
||||
|
||||
let conn = null
|
||||
let peer = null
|
||||
let p = null
|
||||
|
||||
before((done) => {
|
||||
PeerId.createFromJSON(nodes.node4, (_, peerId) => {
|
||||
PeerInfo.create(peerId, (err, peerInfo) => {
|
||||
peer = peerInfo
|
||||
peer.multiaddrs.add(`/p2p-circuit/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`)
|
||||
done(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
dialer.swarm = {
|
||||
_peerInfo: peer
|
||||
}
|
||||
dialer.utils = utilsFactory({})
|
||||
dialer.relayConns = new Map()
|
||||
dialer._negotiateRelay.callThrough()
|
||||
dialer._dialRelayHelper.callThrough()
|
||||
peer = new PeerInfo(PeerId.createFromB58String(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`))
|
||||
p = pair()
|
||||
conn = new Connection(p[1])
|
||||
})
|
||||
|
||||
it(`should write the correct dst addr`, function (done) {
|
||||
dialer._dialRelay.callsFake((_, cb) => {
|
||||
pull(
|
||||
p[0],
|
||||
pb.decode(proto.CircuitRelay),
|
||||
asyncMap((msg, cb) => {
|
||||
expect(msg.dstPeer.addrs[0]).to.deep.equal(dstMa.buffer)
|
||||
cb(null, {
|
||||
type: proto.CircuitRelay.Type.STATUS,
|
||||
code: proto.CircuitRelay.Status.SUCCESS
|
||||
})
|
||||
}),
|
||||
pb.encode(proto.CircuitRelay),
|
||||
p[0]
|
||||
)
|
||||
cb(null, conn)
|
||||
})
|
||||
|
||||
dialer._negotiateRelay(peer, dstMa, done)
|
||||
})
|
||||
|
||||
it(`should negotiate relay`, function (done) {
|
||||
dialer._dialRelay.callsFake((_, cb) => {
|
||||
pull(
|
||||
p[0],
|
||||
pb.decode(proto.CircuitRelay),
|
||||
asyncMap((msg, cb) => {
|
||||
expect(msg.dstPeer.addrs[0]).to.deep.equal(dstMa.buffer)
|
||||
cb(null, {
|
||||
type: proto.CircuitRelay.Type.STATUS,
|
||||
code: proto.CircuitRelay.Status.SUCCESS
|
||||
})
|
||||
}),
|
||||
pb.encode(proto.CircuitRelay),
|
||||
p[0]
|
||||
)
|
||||
cb(null, conn)
|
||||
})
|
||||
|
||||
dialer._negotiateRelay(peer, dstMa, (err, conn) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(conn).to.be.instanceOf(Connection)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`should fail with an invalid peer id`, function (done) {
|
||||
const dstMa = multiaddr('/ip4/127.0.0.1/tcp/4001')
|
||||
dialer._dialRelay.callsFake((_, cb) => {
|
||||
pull(
|
||||
p[0],
|
||||
pb.decode(proto.CircuitRelay),
|
||||
asyncMap((msg, cb) => {
|
||||
expect(msg.dstPeer.addrs[0]).to.deep.equal(dstMa.buffer)
|
||||
cb(null, {
|
||||
type: proto.CircuitRelay.Type.STATUS,
|
||||
code: proto.CircuitRelay.Status.SUCCESS
|
||||
})
|
||||
}),
|
||||
pb.encode(proto.CircuitRelay),
|
||||
p[0]
|
||||
)
|
||||
cb(null, conn)
|
||||
})
|
||||
|
||||
dialer._negotiateRelay(peer, dstMa, (err, conn) => {
|
||||
expect(err).to.exist()
|
||||
expect(conn).to.not.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`should handle failed relay negotiation`, function (done) {
|
||||
dialer._dialRelay.callsFake((_, cb) => {
|
||||
cb(null, conn)
|
||||
pull(
|
||||
values([{
|
||||
type: proto.CircuitRelay.Type.STATUS,
|
||||
code: proto.CircuitRelay.Status.MALFORMED_MESSAGE
|
||||
}]),
|
||||
pb.encode(proto.CircuitRelay),
|
||||
p[0]
|
||||
)
|
||||
})
|
||||
|
||||
dialer._negotiateRelay(peer, dstMa, (err, conn) => {
|
||||
expect(err).to.not.be.null()
|
||||
expect(err).to.be.an.instanceOf(Error)
|
||||
expect(err.message).to.be.equal(`Got 400 error code trying to dial over relay`)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
25
test/circuit/fixtures/nodes.js
Normal file
25
test/circuit/fixtures/nodes.js
Normal file
@ -0,0 +1,25 @@
|
||||
'use strict'
|
||||
|
||||
exports.node1 = {
|
||||
id: 'QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE',
|
||||
privKey: 'CAASpwkwggSjAgEAAoIBAQDJwzJPar4nylKY71Mm5q2BOED8uPf1ILvIi15VwVZWqter6flnlii/RKEcBypPbFqJHHa56MvybgQgrFmHKwDjnJvq4jyOZfR+o/D/99Ft1p2FAEBjImSXAgNpK4YsbyV5r0Q1+Avcj++aWWlLu6enUrL9WGzeUkf0U5L6XwXEPRUQdEojAIQi241P1hyqXX5gKAZVGqcPtKb6p1db3fcXodkS1G6JR90TopJHCqTCECp3SB9c6LlG7KXU92sIHJBlhOEEzGkEI1pM1SWnNnW5VLEypU7P56ifzzp4QxPNiJeC+cmE5SrgR3cXP44iKOuNVRJwBpCh5oNYqECzgqJ9AgMBAAECggEBAJpCdqXHrAmKJCqv2HiGqCODGhTfax1s4IYNIJwaTOPIjUrwgfKUGSVb2H4wcEX3RyVLsO6lMcFyIg/FFlJFK9HavE8SmFAbXZqxx6I9HE+JZjf5IEFrW1Mlg+wWDejNNe7adSF6O79wATaWo+32VNGWZilTQTGd4UvJ1jc9DZCh8zZeNhm4C6exXD45gMB0HI1t2ZNl47scsBEE4rV+s7F7y8Yk/tIsf0wSI/H8KSXS5I9aFxr3Z9c3HOfbVwhnIfNUDqcFTeU5BnhByYNLJ4v9xGj7puidcabVXkt2zLmm/LHbKVeGzec9LW5D+KkuB/pKaslsCXN6bVlu+SbVr9UCgYEA7MXfzZw36vDyfn4LPCN0wgzz11uh3cm31QzOPlWpA7hIsL/eInpvc8wa9yBRC1sRk41CedPHn913MR6EJi0Ne6/B1QOmRYBUjr60VPRNdTXCAiLykjXg6+TZ+AKnxlUGK1hjTo8krhpWq7iD/JchVlLoqDAXGFHvSxN0H3WEUm8CgYEA2iWC9w1v+YHfT2PXcLxYde9EuLVkIS4TM7Kb0N3wr/4+K4xWjVXuaJJLJoAbihNAZw0Y+2s1PswDUEpSG0jXeNXLs6XcQxYSEAu/pFdvHFeg2BfwVQoeEFlWyTJR29uti9/APaXMo8FSVAPPR5lKZLStJDM9hEfAPfUaHyic39MCgYAKQbwjNQw7Ejr+/cjQzxxkt5jskFyftfhPs2FP0/ghYB9OANHHnpQraQEWCYFZQ5WsVac2jdUM+NQL/a1t1e/Klt+HscPHKPsAwAQh1f9w/2YrH4ZwjQL0VRKYKs1HyzEcOZT7tzm4jQ2KHNEi5Q0dpzPK7WJivFHoZ6xVHIsh4wKBgAQq20mk9BKsLHvzyFXbA0WdgI6WyIbpvmwqaVegJcz26nEiiTTCA3/z64OcxunoXD6bvXJwJeBBPX73LIJg7dzdGLsh3AdcEJRF5S9ajEDaW7RFIM4/FzvwuPu2/mFY3QPjDmUfGb23H7+DIx6XCxjJatVaNT6lsEJ+wDUALZ8JAoGAO0YJSEziA7y0dXPK5azkJUMJ5yaN+zRDmoBnEggza34rQW0s16NnIR0EBzKGwbpNyePlProv4dQEaLF1kboKsSYvV2rW2ftLVdNqBHEUYFRC9ofPctCxwM1YU21TI2/k1squ+swApg2EHMev2+WKd+jpVPIbCIvJ3AjiAKZtiGQ=',
|
||||
pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJwzJPar4nylKY71Mm5q2BOED8uPf1ILvIi15VwVZWqter6flnlii/RKEcBypPbFqJHHa56MvybgQgrFmHKwDjnJvq4jyOZfR+o/D/99Ft1p2FAEBjImSXAgNpK4YsbyV5r0Q1+Avcj++aWWlLu6enUrL9WGzeUkf0U5L6XwXEPRUQdEojAIQi241P1hyqXX5gKAZVGqcPtKb6p1db3fcXodkS1G6JR90TopJHCqTCECp3SB9c6LlG7KXU92sIHJBlhOEEzGkEI1pM1SWnNnW5VLEypU7P56ifzzp4QxPNiJeC+cmE5SrgR3cXP44iKOuNVRJwBpCh5oNYqECzgqJ9AgMBAAE='
|
||||
}
|
||||
|
||||
exports.node2 = {
|
||||
id: 'QmYJjAri5soV8RbeQcHaYYcTAYTET17QTvcoFMyKvRDTXe',
|
||||
privKey: 'CAASpgkwggSiAgEAAoIBAQDt7YgUeBQsoN/lrgo690mB7yEh8G9iXhZiDecgZCLRRSl3v2cH9w4WjhoW9erfnVbdoTqkCK+se8uK01ySi/ubQQDPcrjacXTa6wAuRTbCG/0bUR9RxKtxZZBS1HaY7L923ulgGDTiVaRQ3JQqhzmQkaU0ikNcluSGaw0kmhXP6JmcL+wndKgW5VD9etcp2Qlk8uUFC/GAO90cOAuER3wnI3ocHGm9on9zyb97g4TDzIfjSaTW4Wanmx2yVbURQxmCba16X3LT9IMPqQaGOzq3+EewMLeCESbUm/uJaJLdqWrWRK4oNzxcMgmUkzav+s476HdA9CRo72am+g3Vdq+lAgMBAAECggEAcByKD6MZVoIjnlVo6qoVUA1+3kAuK/rLrz5/1wp4QYXGaW+eO+mVENm6v3D3UJESGnLbb+nL5Ymbunmn2EHvuBNkL1wOcJgfiPxM5ICmscaAeHu8N0plwpQp8m28yIheG8Qj0az2VmQmfhfCFVwMquuGHgC8hwdu/Uu6MLIObx1xjtaGbY9kk7nzAeXHeJ4RDeuNN0QrYuQVKwrIz1NtPNDR/cli298ZXJcm+HEhBCIHVIYpAq6BHSuiXVqPGEOYWYXo+yVhEtDJ8BmNqlN1Y1s6bnfu/tFkKUN6iQQ46vYnQEGTGR9lg7J/c6tqfRs9FcywWb9J1SX6HxPO8184zQKBgQD6vDYl20UT4ZtrzhFfMyV/1QUqFM/TdwNuiOsIewHBol9o7aOjrxrrbYVa1HOxETyBjmFsW+iIfOVl61SG2HcU4CG+O2s9WBo4JdRlOm4YQ8/83xO3YfbXzuTx8BMCyP/i1uPIZTKQFFAN0HiL96r4L60xHoWB7tQsbZiEbIO/2wKBgQDy7HnkgVeTld6o0+sT84FYRUotjDB00oUWiSeGtj0pFC4yIxhMhD8QjKiWoJyJItcoCsQ/EncuuwwRtuXi83793lJQR1DBYd+TSPg0M8J1pw97fUIPi/FU+jHtrsx7Vn/7Bk9voictsYVLAfbi68tYdsZpAaYOWYMY9NUfVuAmfwKBgCYZDwk1hgt9TkZVK2KRvPLthTldrC5veQAEoeHJ/vxTFbg105V9d9Op8odYnLOc8NqmrbrvRCfpAlo4JcHPhliPrdDf6m2Jw4IgjWNMO4pIU4QSyUYmBoHIGBWC6wCTVf47tKSwa7xkub0/nfF2km3foKtD/fk+NtMBXBlS+7ndAoGAJo6GIlCtN82X07AfJcGGjB4jUetoXYJ0gUkvruAKARUk5+xOFQcAg33v3EiNz+5pu/9JesFRjWc+2Sjwf/8p7t10ry1Ckg8Yz2XLj22PteDYQj91VsZdfaFgf1s5NXJbSdqMjSltkoEUqP0c1JOcaOQhRdVvJ+PpPPLPSPQfC70CgYBvJE1I06s7BEM1DOli3VyfNaJDI4k9W2dCJOU6Bh2MNmbdRjM3xnpOKH5SqRlCz/oI9pn4dxgbX6WPg331MD9CNYy2tt5KBQRrSuDj8p4jlzMIpX36hsyTTrzYU6WWSIPz6jXW8IexXKvXEmr8TVb78ZPiQfbG012cdUhAJniNgg==',
|
||||
pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDt7YgUeBQsoN/lrgo690mB7yEh8G9iXhZiDecgZCLRRSl3v2cH9w4WjhoW9erfnVbdoTqkCK+se8uK01ySi/ubQQDPcrjacXTa6wAuRTbCG/0bUR9RxKtxZZBS1HaY7L923ulgGDTiVaRQ3JQqhzmQkaU0ikNcluSGaw0kmhXP6JmcL+wndKgW5VD9etcp2Qlk8uUFC/GAO90cOAuER3wnI3ocHGm9on9zyb97g4TDzIfjSaTW4Wanmx2yVbURQxmCba16X3LT9IMPqQaGOzq3+EewMLeCESbUm/uJaJLdqWrWRK4oNzxcMgmUkzav+s476HdA9CRo72am+g3Vdq+lAgMBAAE='
|
||||
}
|
||||
|
||||
exports.node3 = {
|
||||
id: 'QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA',
|
||||
privKey: 'CAASpwkwggSjAgEAAoIBAQDdnGp0X7Pix5dIawfyuffVryRDRS5JXdyjayKUkgikJLYoiijB5TakrFKhx1SDKpmVLxxqAGz8m5iA2cHwetIQXTZvdYx7XXxv332En3ji8TiGRUiEFM8KQ5WCJ5G7yw8R2pv/pYdnMrPd04QbtSCn0cFVCiiA2Zkl5KnwBo/lf+sVI/TEeiwmVD9nxi13qWgBTmCysqH8Ppyu8fq+bQgqRZSlalVDswyIhgWlepPkD0uYakJJhhOxY+2RlbNhGY0qjRyMTYou2uR/hfd6j8uR++WdB0v3+DYWG2Kc3sWa4BLYb5r4trvQGO1Iagnwuk3AVoi7PldsaInekzWEVljDAgMBAAECggEAXx0jE49/xXWkmJBXePYYSL5C8hxfIV4HtJvm251R2CFpjTy/AXk/Wq4bSRQkUaeXA1CVAWntXP3rFmJfurb8McnP80agZNJa9ikV1jYbzEt71yUlWosT0XPwV0xkYBVnAmKxUafZ1ZENYcfGi53RxjVgpP8XIzZBZOIfjcVDPVw9NAOzQmq4i3DJEz5xZAkaeSM8mn5ZFl1JMBUOgyOHB7d4BWd3zuLyvnn0/08HlsaSUl0mZa3f2Lm2NlsjOiNfMCJTOIT+xDEP9THm5n2cqieSjvtpAZzV4kcoD0rB8OsyHQlFAEXzkgELDr5dVXji0rrIdVz8stYAKGfi996OAQKBgQDuviV1sc+ClJQA59vqbBiKxWqcuCKMzvmL4Yk1e/AkQeRt+JX9kALWzBx65fFmHTj4Lus8AIQoiruPxa0thtqh/m3SlucWnrdaW410xbz3KqQWS7bx+0sFWZIEi4N+PESrIYhtVbFuRiabYgliqdSU9shxtXXnvfhjl+9quZltiwKBgQDtoUCKqrZbm0bmzLvpnKdNodg1lUHaKGgEvWgza2N1t3b/GE07iha2KO3hBDta3bdfIEEOagY8o13217D0VIGsYNKpiEGLEeNIjfcXBEqAKiTfa/sXUfTprpWBZQ/7ZS+eZIYtQjq14EHa7ifAby1v3yDrMIuxphz5JfKdXFgYqQKBgHr47FikPwu2tkmFJCyqgzWvnEufOQSoc7eOc1tePIKggiX2/mM+M4gqWJ0hJeeAM+D6YeZlKa2sUBItMxeZN7JrWGw5mEx5cl4TfFhipgP2LdDiLRiVZL4bte+rYQ67wm8XdatDkYIIlkhBBi6Q5dPZDcQsQNAedPvvvb2OXi4jAoGBAKp06FpP+L2fle2LYSRDlhNvDCvrpDA8mdkEkRGJb/AKKdb09LnH5WDH3VNy+KzGrHoVJfWUAmNPAOFHeYzabaZcUeEAd5utui7afytIjbSABrEpwRTKWneiH2aROzSnMdBZ5ZHjlz/N3Q+RlHxKg/piwTdUPHCzasch/HX6vsr5AoGAGvhCNPKyCwpu8Gg5GQdx0yN6ZPar9wieD345cLanDZWKkLRQbo4SfkfoS+PDfOLzDbWFdPRnWQ0qhdPm3D/N1YD/nudHqbeDlx0dj/6lEHmmPKFFO2kiNFEhn8DycNGbvWyVBKksacuRXav21+LvW+TatUkRMhi8fgRoypnbJjg=',
|
||||
pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdnGp0X7Pix5dIawfyuffVryRDRS5JXdyjayKUkgikJLYoiijB5TakrFKhx1SDKpmVLxxqAGz8m5iA2cHwetIQXTZvdYx7XXxv332En3ji8TiGRUiEFM8KQ5WCJ5G7yw8R2pv/pYdnMrPd04QbtSCn0cFVCiiA2Zkl5KnwBo/lf+sVI/TEeiwmVD9nxi13qWgBTmCysqH8Ppyu8fq+bQgqRZSlalVDswyIhgWlepPkD0uYakJJhhOxY+2RlbNhGY0qjRyMTYou2uR/hfd6j8uR++WdB0v3+DYWG2Kc3sWa4BLYb5r4trvQGO1Iagnwuk3AVoi7PldsaInekzWEVljDAgMBAAE='
|
||||
}
|
||||
|
||||
exports.node4 = {
|
||||
id: 'QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy',
|
||||
privKey: 'CAASqAkwggSkAgEAAoIBAQC6pg6LYWbY+49SOYdYap6RPqKqZxg80IXeo3hiTUbiGtTruxVYZpnz3UbernL9J9mwlXJGRUQJUKmXmi1yePTQiyclpH0KyPefaWLbpxJQdCBI1TPZpDWo2hutWSPqhKBU1QyH2FLKQPWLdxuIX1cNFPtIlSl5gCxN6oiDIwh7++kxNM1G+d5XgJX6iHLlLoNv3Wn6XYX+VtYdyZRFk8gYyT2BrISbxmsrSjSOodwUUzF8TYTjsqW6ksL2x0mrRm2cMM9evULktqwU+I8l9ulASDbFWBXUToXaZSL9M+Oq5JvZO0WIjPeYVpAgWladtayhdxg5dBv8aTbDaM5DZvyRAgMBAAECggEAR65YbZz1k6Vg0HI5kXI4/YzxicHYJBrtHqjnJdGJxHILjZCmzPFydJ5phkG29ZRlXRS381bMn0s0Jn3WsFzVoHWgjitSvl6aAsXFapgKR42hjHcc15vh47wH3xYZ3gobTRkZG96vRO+XnX0bvM7orqR9MM3gRMI9wZqt3LcKnhpiqSlyEZ3Zehu7ZZ8B+XcUw42H6ZTXgmg5mCFEjS/1rVt+EsdZl7Ll7jHigahPA6qMjyRiZB6T20qQ0FFYfmaNuRuuC6cWUXf8DOgnEjMB/Mi/Feoip9bTqNBrVYn2XeDxdMv5pDznNKXpalsMkZwx5FpNOMKnIMdQFyAGtkeQ9QKBgQD3rjTiulitpbbQBzF8VXeymtMJAbR1TAqNv2yXoowhL3JZaWICM7nXHjjsJa3UzJygbi8bO0KWrw7tY0nUbPy5SmHtNYhmUsEjiTjqEnNRrYN68tEKr0HlgX+9rArsjOcwucl2svFSfk+rTYDHU5neZkDDhu1QmnZm/pQI92Lo4wKBgQDA6wpMd53fmX9DhWegs3xelRStcqBTw1ucWVRyPgY1hO1cJ0oReYIXKEw9CHNLW0RHvnVM26kRnqCl+dTcg7dhLuqrckuyQyY1KcRYG1ryJnz3euucaSF2UCsZCHvFNV7Vz8dszUMUVCogWmroVP6HE/BoazUCNh25s/dNwE+i+wKBgEfa1WL1luaBzgCaJaQhk4FQY2sYgIcLEYDACTwQn0C9aBpCdXmYEhEzpmX0JHM5DTOJ48atsYrPrK/3/yJOoB8NUk2kGzc8SOYLWGSoB6aphRx1N2o3IBH6ONoJAH5R/nxnWehCz7oUBP74lCS/v0MDPUS8bzrUJQeKUd4sDxjrAoGBAIRO7rJA+1qF+J1DWi4ByxNHJXZLfh/UhPj23w628SU1dGDWZVsUvZ7KOXdGW2RcRLj7q5E5uXtnEoCillViVJtnRPSun7Gzkfm2Gn3ezQH0WZKVkA+mnpd5JgW2JsS69L6pEPnS0OWZT4b+3AFZgXL8vs2ucR2CJeLdxYdilHuPAoGBAPLCzBkAboXZZtvEWqzqtVNqdMrjLHihFrpg4TXSsk8+ZQZCVN+sRyTGTvBX8+Jvx4at6ClaSgT3eJ/412fEH6CHvrFXjUE9W9y6X0axxaT63y1OXmFiB/hU3vjLWZKZWSDGNS7St02fYri4tWmGtJDjYG1maLRhMSzcoj4fP1xz',
|
||||
pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6pg6LYWbY+49SOYdYap6RPqKqZxg80IXeo3hiTUbiGtTruxVYZpnz3UbernL9J9mwlXJGRUQJUKmXmi1yePTQiyclpH0KyPefaWLbpxJQdCBI1TPZpDWo2hutWSPqhKBU1QyH2FLKQPWLdxuIX1cNFPtIlSl5gCxN6oiDIwh7++kxNM1G+d5XgJX6iHLlLoNv3Wn6XYX+VtYdyZRFk8gYyT2BrISbxmsrSjSOodwUUzF8TYTjsqW6ksL2x0mrRm2cMM9evULktqwU+I8l9ulASDbFWBXUToXaZSL9M+Oq5JvZO0WIjPeYVpAgWladtayhdxg5dBv8aTbDaM5DZvyRAgMBAAE='
|
||||
}
|
22
test/circuit/helpers/test-node.js
Normal file
22
test/circuit/helpers/test-node.js
Normal file
@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
|
||||
const Libp2p = require('../../../src')
|
||||
const secio = require('libp2p-secio')
|
||||
|
||||
class TestNode extends Libp2p {
|
||||
constructor (peerInfo, transports, muxer, options) {
|
||||
options = options || {}
|
||||
|
||||
const modules = {
|
||||
transport: transports,
|
||||
connection: {
|
||||
muxer: [muxer],
|
||||
crypto: options.isCrypto ? [secio] : null
|
||||
},
|
||||
discovery: []
|
||||
}
|
||||
super(modules, peerInfo, null, options)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TestNode
|
78
test/circuit/helpers/utils.js
Normal file
78
test/circuit/helpers/utils.js
Normal file
@ -0,0 +1,78 @@
|
||||
'use strict'
|
||||
|
||||
const TestNode = require('./test-node')
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerId = require('peer-id')
|
||||
const eachAsync = require('async/each')
|
||||
|
||||
exports.createNodes = function createNodes (configNodes, callback) {
|
||||
const nodes = {}
|
||||
eachAsync(Object.keys(configNodes), (key, cb1) => {
|
||||
const config = configNodes[key]
|
||||
|
||||
const setup = (err, peer) => {
|
||||
if (err) {
|
||||
callback(err)
|
||||
}
|
||||
|
||||
eachAsync(config.addrs, (addr, cb2) => {
|
||||
peer.multiaddrs.add(addr)
|
||||
cb2()
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
nodes[key] = new TestNode(peer, config.transports, config.muxer, config.config)
|
||||
cb1()
|
||||
})
|
||||
}
|
||||
|
||||
if (config.id) {
|
||||
PeerId.createFromJSON(config.id, (err, peerId) => {
|
||||
if (err) return callback(err)
|
||||
PeerInfo.create(peerId, setup)
|
||||
})
|
||||
} else {
|
||||
PeerInfo.create(setup)
|
||||
}
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
startNodes(nodes, (err) => {
|
||||
if (err) {
|
||||
callback(err)
|
||||
}
|
||||
|
||||
callback(null, nodes)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function startNodes (nodes, callback) {
|
||||
eachAsync(Object.keys(nodes),
|
||||
(key, cb) => {
|
||||
nodes[key].start(cb)
|
||||
},
|
||||
(err) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
callback(null)
|
||||
})
|
||||
}
|
||||
|
||||
exports.stopNodes = function stopNodes (nodes, callback) {
|
||||
eachAsync(Object.keys(nodes),
|
||||
(key, cb) => {
|
||||
nodes[key].stop(cb)
|
||||
},
|
||||
(err) => {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
callback()
|
||||
})
|
||||
}
|
433
test/circuit/hop.spec.js
Normal file
433
test/circuit/hop.spec.js
Normal file
@ -0,0 +1,433 @@
|
||||
/* eslint-env mocha */
|
||||
/* eslint max-nested-callbacks: ["error", 5] */
|
||||
'use strict'
|
||||
|
||||
const Hop = require('../../src/circuit/circuit/hop')
|
||||
const nodes = require('./fixtures/nodes')
|
||||
const Connection = require('interface-connection').Connection
|
||||
const handshake = require('pull-handshake')
|
||||
const waterfall = require('async/waterfall')
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerId = require('peer-id')
|
||||
const multiaddr = require('multiaddr')
|
||||
const pull = require('pull-stream/pull')
|
||||
const values = require('pull-stream/sources/values')
|
||||
const collect = require('pull-stream/sinks/collect')
|
||||
const lp = require('pull-length-prefixed')
|
||||
const proto = require('../../src/circuit/protocol')
|
||||
const StreamHandler = require('../../src/circuit/circuit/stream-handler')
|
||||
|
||||
const sinon = require('sinon')
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const expect = chai.expect
|
||||
chai.use(dirtyChai)
|
||||
|
||||
describe('relay', () => {
|
||||
describe(`.handle`, () => {
|
||||
let relay
|
||||
let swarm
|
||||
let fromConn
|
||||
let stream
|
||||
let shake
|
||||
|
||||
beforeEach((done) => {
|
||||
stream = handshake({ timeout: 1000 * 60 })
|
||||
shake = stream.handshake
|
||||
fromConn = new Connection(stream)
|
||||
const peerInfo = new PeerInfo(PeerId.createFromB58String('QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA'))
|
||||
fromConn.setPeerInfo(peerInfo)
|
||||
|
||||
const peers = {
|
||||
QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE:
|
||||
new PeerInfo(PeerId.createFromB58String(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`)),
|
||||
QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA:
|
||||
new PeerInfo(PeerId.createFromB58String(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`)),
|
||||
QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy:
|
||||
new PeerInfo(PeerId.createFromB58String(`QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`))
|
||||
}
|
||||
|
||||
Object.keys(peers).forEach((key) => { peers[key]._connectedMultiaddr = true }) // make it truthy
|
||||
|
||||
waterfall([
|
||||
(cb) => PeerId.createFromJSON(nodes.node4, cb),
|
||||
(peerId, cb) => PeerInfo.create(peerId, cb),
|
||||
(peer, cb) => {
|
||||
peer.multiaddrs.add('/p2p-circuit/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE')
|
||||
swarm = {
|
||||
_peerInfo: peer,
|
||||
conns: {
|
||||
QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE: new Connection(),
|
||||
QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA: new Connection(),
|
||||
QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy: new Connection()
|
||||
},
|
||||
_peerBook: {
|
||||
get: (peer) => {
|
||||
if (!peers[peer]) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
return peers[peer]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cb()
|
||||
}
|
||||
], () => {
|
||||
relay = new Hop(swarm, { enabled: true })
|
||||
relay._circuit = sinon.stub()
|
||||
relay._circuit.callsArgWith(2, null, new Connection())
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
relay._circuit.reset()
|
||||
})
|
||||
|
||||
it(`should handle a valid circuit request`, (done) => {
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: PeerId.createFromB58String(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).buffer]
|
||||
},
|
||||
dstPeer: {
|
||||
id: PeerId.createFromB58String(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).buffer]
|
||||
}
|
||||
}
|
||||
|
||||
relay.on('circuit:success', () => {
|
||||
expect(relay._circuit.calledWith(sinon.match.any, relayMsg)).to.be.ok()
|
||||
done()
|
||||
})
|
||||
|
||||
relay.handle(relayMsg, new StreamHandler(fromConn))
|
||||
})
|
||||
|
||||
it(`should handle a request to passive circuit`, (done) => {
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: PeerId.createFromB58String(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).buffer]
|
||||
},
|
||||
dstPeer: {
|
||||
id: PeerId.createFromB58String(`QmYJjAri5soV8RbeQcHaYYcTAYTET17QTvcoFMyKvRDTXe`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmYJjAri5soV8RbeQcHaYYcTAYTET17QTvcoFMyKvRDTXe`).buffer]
|
||||
}
|
||||
}
|
||||
|
||||
relay.active = false
|
||||
lp.decodeFromReader(
|
||||
shake,
|
||||
(err, msg) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
const response = proto.CircuitRelay.decode(msg)
|
||||
expect(response.code).to.equal(proto.CircuitRelay.Status.HOP_NO_CONN_TO_DST)
|
||||
expect(response.type).to.equal(proto.CircuitRelay.Type.STATUS)
|
||||
done()
|
||||
})
|
||||
|
||||
relay.handle(relayMsg, new StreamHandler(fromConn))
|
||||
})
|
||||
|
||||
it(`should handle a request to active circuit`, (done) => {
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: PeerId.createFromB58String(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).buffer]
|
||||
},
|
||||
dstPeer: {
|
||||
id: PeerId.createFromB58String(`QmYJjAri5soV8RbeQcHaYYcTAYTET17QTvcoFMyKvRDTXe`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmYJjAri5soV8RbeQcHaYYcTAYTET17QTvcoFMyKvRDTXe`).buffer]
|
||||
}
|
||||
}
|
||||
|
||||
relay.active = true
|
||||
relay.on('circuit:success', () => {
|
||||
expect(relay._circuit.calledWith(sinon.match.any, relayMsg)).to.be.ok()
|
||||
done()
|
||||
})
|
||||
|
||||
relay.on('circuit:error', (err) => {
|
||||
done(err)
|
||||
})
|
||||
|
||||
relay.handle(relayMsg, new StreamHandler(fromConn))
|
||||
})
|
||||
|
||||
it(`not dial to self`, (done) => {
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: PeerId.createFromB58String(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).buffer]
|
||||
},
|
||||
dstPeer: {
|
||||
id: PeerId.createFromB58String(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).buffer]
|
||||
}
|
||||
}
|
||||
|
||||
lp.decodeFromReader(
|
||||
shake,
|
||||
(err, msg) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
const response = proto.CircuitRelay.decode(msg)
|
||||
expect(response.code).to.equal(proto.CircuitRelay.Status.HOP_CANT_RELAY_TO_SELF)
|
||||
expect(response.type).to.equal(proto.CircuitRelay.Type.STATUS)
|
||||
done()
|
||||
})
|
||||
|
||||
relay.handle(relayMsg, new StreamHandler(fromConn))
|
||||
})
|
||||
|
||||
it(`fail on invalid src address`, (done) => {
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: `sdfkjsdnfkjdsb`,
|
||||
addrs: [`sdfkjsdnfkjdsb`]
|
||||
},
|
||||
dstPeer: {
|
||||
id: PeerId.createFromB58String(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).buffer]
|
||||
}
|
||||
}
|
||||
|
||||
lp.decodeFromReader(
|
||||
shake,
|
||||
(err, msg) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
const response = proto.CircuitRelay.decode(msg)
|
||||
expect(response.code).to.equal(proto.CircuitRelay.Status.HOP_SRC_MULTIADDR_INVALID)
|
||||
expect(response.type).to.equal(proto.CircuitRelay.Type.STATUS)
|
||||
done()
|
||||
})
|
||||
|
||||
relay.handle(relayMsg, new StreamHandler(fromConn))
|
||||
})
|
||||
|
||||
it(`fail on invalid dst address`, (done) => {
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: PeerId.createFromB58String(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).id,
|
||||
addrs: [multiaddr(`/ipfs/QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`).buffer]
|
||||
},
|
||||
dstPeer: {
|
||||
id: PeerId.createFromB58String(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).id,
|
||||
addrs: [`sdfkjsdnfkjdsb`]
|
||||
}
|
||||
}
|
||||
|
||||
lp.decodeFromReader(
|
||||
shake,
|
||||
(err, msg) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
const response = proto.CircuitRelay.decode(msg)
|
||||
expect(response.code).to.equal(proto.CircuitRelay.Status.HOP_DST_MULTIADDR_INVALID)
|
||||
expect(response.type).to.equal(proto.CircuitRelay.Type.STATUS)
|
||||
done()
|
||||
})
|
||||
|
||||
relay.handle(relayMsg, new StreamHandler(fromConn))
|
||||
})
|
||||
})
|
||||
|
||||
describe(`._circuit`, () => {
|
||||
let relay
|
||||
let swarm
|
||||
let srcConn
|
||||
let dstConn
|
||||
let srcStream
|
||||
let dstStream
|
||||
let srcShake
|
||||
let dstShake
|
||||
|
||||
before((done) => {
|
||||
srcStream = handshake({ timeout: 1000 * 60 })
|
||||
srcShake = srcStream.handshake
|
||||
srcConn = new Connection(srcStream)
|
||||
dstStream = handshake({ timeout: 1000 * 60 })
|
||||
dstShake = dstStream.handshake
|
||||
dstConn = new Connection(dstStream)
|
||||
const peerInfo = new PeerInfo(PeerId.createFromB58String('QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA'))
|
||||
srcConn.setPeerInfo(peerInfo)
|
||||
|
||||
const peers = {
|
||||
QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE:
|
||||
new PeerInfo(PeerId.createFromB58String(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`)),
|
||||
QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA:
|
||||
new PeerInfo(PeerId.createFromB58String(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`)),
|
||||
QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy:
|
||||
new PeerInfo(PeerId.createFromB58String(`QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`))
|
||||
}
|
||||
|
||||
Object.keys(peers).forEach((key) => { peers[key]._connectedMultiaddr = true }) // make it truthy
|
||||
|
||||
waterfall([
|
||||
(cb) => PeerId.createFromJSON(nodes.node4, cb),
|
||||
(peerId, cb) => PeerInfo.create(peerId, cb),
|
||||
(peer, cb) => {
|
||||
peer.multiaddrs.add('/p2p-circuit/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE')
|
||||
swarm = {
|
||||
_peerInfo: peer,
|
||||
conns: {
|
||||
QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE: new Connection(),
|
||||
QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA: new Connection(),
|
||||
QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy: new Connection()
|
||||
},
|
||||
_peerBook: {
|
||||
get: (peer) => {
|
||||
if (!peers[peer]) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
return peers[peer]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cb()
|
||||
}
|
||||
], () => {
|
||||
relay = new Hop(swarm, { enabled: true })
|
||||
relay._dialPeer = sinon.stub()
|
||||
relay._dialPeer.callsArgWith(1, null, dstConn)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
after(() => relay._dialPeer.reset())
|
||||
|
||||
describe('should correctly dial destination node', () => {
|
||||
const msg = {
|
||||
type: proto.CircuitRelay.Type.STOP,
|
||||
srcPeer: {
|
||||
id: Buffer.from(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`),
|
||||
addrs: [Buffer.from(`dsfsdfsdf`)]
|
||||
},
|
||||
dstPeer: {
|
||||
id: Buffer.from(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`),
|
||||
addrs: [Buffer.from(`sdflksdfndsklfnlkdf`)]
|
||||
}
|
||||
}
|
||||
|
||||
before(() => {
|
||||
relay._circuit(
|
||||
new StreamHandler(srcConn),
|
||||
msg,
|
||||
(err) => {
|
||||
expect(err).to.not.exist()
|
||||
})
|
||||
})
|
||||
|
||||
it('should respond with SUCCESS to source node', (done) => {
|
||||
lp.decodeFromReader(
|
||||
srcShake,
|
||||
(err, msg) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
const response = proto.CircuitRelay.decode(msg)
|
||||
expect(response.type).to.equal(proto.CircuitRelay.Type.STATUS)
|
||||
expect(response.code).to.equal(proto.CircuitRelay.Status.SUCCESS)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should send STOP message to destination node', (done) => {
|
||||
lp.decodeFromReader(
|
||||
dstShake,
|
||||
(err, _msg) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
const response = proto.CircuitRelay.decode(_msg)
|
||||
expect(response.type).to.deep.equal(msg.type)
|
||||
expect(response.srcPeer).to.deep.equal(msg.srcPeer)
|
||||
expect(response.dstPeer).to.deep.equal(msg.dstPeer)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should create circuit', (done) => {
|
||||
pull(
|
||||
values([proto.CircuitRelay.encode({
|
||||
type: proto.CircuitRelay.Type.STATUS,
|
||||
code: proto.CircuitRelay.Status.SUCCESS
|
||||
})]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
encoded.forEach((e) => dstShake.write(e))
|
||||
pull(
|
||||
values([Buffer.from('hello')]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
encoded.forEach((e) => srcShake.write(e))
|
||||
lp.decodeFromReader(
|
||||
dstShake,
|
||||
(err, _msg) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(_msg.toString()).to.equal('hello')
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('should fail creating circuit', () => {
|
||||
const msg = {
|
||||
type: proto.CircuitRelay.Type.STOP,
|
||||
srcPeer: {
|
||||
id: Buffer.from(`QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA`),
|
||||
addrs: [Buffer.from(`dsfsdfsdf`)]
|
||||
},
|
||||
dstPeer: {
|
||||
id: Buffer.from(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`),
|
||||
addrs: [Buffer.from(`sdflksdfndsklfnlkdf`)]
|
||||
}
|
||||
}
|
||||
|
||||
it('should not create circuit', (done) => {
|
||||
relay._circuit(
|
||||
new StreamHandler(srcConn),
|
||||
msg,
|
||||
(err) => {
|
||||
expect(err).to.exist()
|
||||
expect(err).to.match(/Unable to create circuit!/)
|
||||
done()
|
||||
})
|
||||
|
||||
pull(
|
||||
values([proto.CircuitRelay.encode({
|
||||
type: proto.CircuitRelay.Type.STATUS,
|
||||
code: proto.CircuitRelay.Status.STOP_RELAY_REFUSED
|
||||
})]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
|
||||
encoded.forEach((e) => dstShake.write(e))
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
292
test/circuit/listener.spec.js
Normal file
292
test/circuit/listener.spec.js
Normal file
@ -0,0 +1,292 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const Listener = require('../../src/circuit/listener')
|
||||
const nodes = require('./fixtures/nodes')
|
||||
const waterfall = require('async/waterfall')
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerId = require('peer-id')
|
||||
const multiaddr = require('multiaddr')
|
||||
const handshake = require('pull-handshake')
|
||||
const Connection = require('interface-connection').Connection
|
||||
const proto = require('../../src/circuit/protocol')
|
||||
const lp = require('pull-length-prefixed')
|
||||
const pull = require('pull-stream/pull')
|
||||
const values = require('pull-stream/sources/values')
|
||||
const collect = require('pull-stream/sinks/collect')
|
||||
const multicodec = require('../../src/circuit/multicodec')
|
||||
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const expect = chai.expect
|
||||
chai.use(dirtyChai)
|
||||
const sinon = require('sinon')
|
||||
|
||||
describe('listener', function () {
|
||||
describe(`listen`, function () {
|
||||
let swarm = null
|
||||
let handlerSpy = null
|
||||
let listener = null
|
||||
let stream = null
|
||||
let shake = null
|
||||
let conn = null
|
||||
|
||||
beforeEach(function (done) {
|
||||
stream = handshake({ timeout: 1000 * 60 })
|
||||
shake = stream.handshake
|
||||
conn = new Connection(stream)
|
||||
conn.setPeerInfo(new PeerInfo(PeerId
|
||||
.createFromB58String('QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE')))
|
||||
|
||||
waterfall([
|
||||
(cb) => PeerId.createFromJSON(nodes.node4, cb),
|
||||
(peerId, cb) => PeerInfo.create(peerId, cb),
|
||||
(peer, cb) => {
|
||||
swarm = {
|
||||
_peerInfo: peer,
|
||||
handle: sinon.spy((proto, h) => {
|
||||
handlerSpy = sinon.spy(h)
|
||||
}),
|
||||
conns: {
|
||||
QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE: new Connection()
|
||||
}
|
||||
}
|
||||
|
||||
listener = Listener(swarm, {}, () => {})
|
||||
listener.listen()
|
||||
cb()
|
||||
}
|
||||
], done)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
listener = null
|
||||
})
|
||||
|
||||
it(`should handle HOP`, function (done) {
|
||||
handlerSpy(multicodec.relay, conn)
|
||||
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: `QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`,
|
||||
addrs: [`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`]
|
||||
},
|
||||
dstPeer: {
|
||||
id: `QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`,
|
||||
addrs: [`/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`]
|
||||
}
|
||||
}
|
||||
|
||||
listener.hopHandler.handle = (message, conn) => {
|
||||
expect(message.type).to.equal(proto.CircuitRelay.Type.HOP)
|
||||
|
||||
expect(message.srcPeer.id.toString()).to.equal(relayMsg.srcPeer.id)
|
||||
expect(message.srcPeer.addrs[0].toString()).to.equal(relayMsg.srcPeer.addrs[0])
|
||||
|
||||
expect(message.dstPeer.id.toString()).to.equal(relayMsg.dstPeer.id)
|
||||
expect(message.dstPeer.addrs[0].toString()).to.equal(relayMsg.dstPeer.addrs[0])
|
||||
|
||||
done()
|
||||
}
|
||||
|
||||
pull(
|
||||
values([proto.CircuitRelay.encode(relayMsg)]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
encoded.forEach((e) => shake.write(e))
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it(`should handle STOP`, function (done) {
|
||||
handlerSpy(multicodec.relay, conn)
|
||||
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.STOP,
|
||||
srcPeer: {
|
||||
id: `QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`,
|
||||
addrs: [`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`]
|
||||
},
|
||||
dstPeer: {
|
||||
id: `QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`,
|
||||
addrs: [`/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`]
|
||||
}
|
||||
}
|
||||
|
||||
listener.stopHandler.handle = (message, conn) => {
|
||||
expect(message.type).to.equal(proto.CircuitRelay.Type.STOP)
|
||||
|
||||
expect(message.srcPeer.id.toString()).to.equal(relayMsg.srcPeer.id)
|
||||
expect(message.srcPeer.addrs[0].toString()).to.equal(relayMsg.srcPeer.addrs[0])
|
||||
|
||||
expect(message.dstPeer.id.toString()).to.equal(relayMsg.dstPeer.id)
|
||||
expect(message.dstPeer.addrs[0].toString()).to.equal(relayMsg.dstPeer.addrs[0])
|
||||
|
||||
done()
|
||||
}
|
||||
|
||||
pull(
|
||||
values([proto.CircuitRelay.encode(relayMsg)]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
encoded.forEach((e) => shake.write(e))
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it(`should emit 'connection'`, function (done) {
|
||||
handlerSpy(multicodec.relay, conn)
|
||||
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.STOP,
|
||||
srcPeer: {
|
||||
id: `QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`,
|
||||
addrs: [`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`]
|
||||
},
|
||||
dstPeer: {
|
||||
id: `QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`,
|
||||
addrs: [`/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`]
|
||||
}
|
||||
}
|
||||
|
||||
listener.stopHandler.handle = (message, sh) => {
|
||||
const newConn = new Connection(sh.rest())
|
||||
listener.stopHandler.emit('connection', newConn)
|
||||
}
|
||||
|
||||
listener.on('connection', (conn) => {
|
||||
expect(conn).to.be.instanceof(Connection)
|
||||
done()
|
||||
})
|
||||
|
||||
pull(
|
||||
values([proto.CircuitRelay.encode(relayMsg)]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
encoded.forEach((e) => shake.write(e))
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it(`should handle CAN_HOP`, function (done) {
|
||||
handlerSpy(multicodec.relay, conn)
|
||||
|
||||
const relayMsg = {
|
||||
type: proto.CircuitRelay.Type.CAN_HOP,
|
||||
srcPeer: {
|
||||
id: `QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`,
|
||||
addrs: [`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`]
|
||||
},
|
||||
dstPeer: {
|
||||
id: `QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`,
|
||||
addrs: [`/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`]
|
||||
}
|
||||
}
|
||||
|
||||
listener.hopHandler.handle = (message, conn) => {
|
||||
expect(message.type).to.equal(proto.CircuitRelay.Type.CAN_HOP)
|
||||
|
||||
expect(message.srcPeer.id.toString()).to.equal(relayMsg.srcPeer.id)
|
||||
expect(message.srcPeer.addrs[0].toString()).to.equal(relayMsg.srcPeer.addrs[0])
|
||||
|
||||
expect(message.dstPeer.id.toString()).to.equal(relayMsg.dstPeer.id)
|
||||
expect(message.dstPeer.addrs[0].toString()).to.equal(relayMsg.dstPeer.addrs[0])
|
||||
|
||||
done()
|
||||
}
|
||||
|
||||
pull(
|
||||
values([proto.CircuitRelay.encode(relayMsg)]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
encoded.forEach((e) => shake.write(e))
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it(`should handle invalid message correctly`, function (done) {
|
||||
handlerSpy(multicodec.relay, conn)
|
||||
|
||||
const relayMsg = {
|
||||
type: 100000,
|
||||
srcPeer: {
|
||||
id: Buffer.from(`QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`),
|
||||
addrs: [multiaddr(`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`).buffer]
|
||||
},
|
||||
dstPeer: {
|
||||
id: Buffer.from(`QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`),
|
||||
addrs: [multiaddr(`/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`).buffer]
|
||||
}
|
||||
}
|
||||
|
||||
pull(
|
||||
values([Buffer.from([relayMsg])]),
|
||||
lp.encode(),
|
||||
collect((err, encoded) => {
|
||||
expect(err).to.not.exist()
|
||||
encoded.forEach((e) => shake.write(e))
|
||||
}),
|
||||
lp.decodeFromReader(shake, { maxLength: this.maxLength }, (err, msg) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(proto.CircuitRelay.decode(msg).type).to.equal(proto.CircuitRelay.Type.STATUS)
|
||||
expect(proto.CircuitRelay.decode(msg).code).to.equal(proto.CircuitRelay.Status.MALFORMED_MESSAGE)
|
||||
done()
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe(`getAddrs`, function () {
|
||||
let swarm = null
|
||||
let listener = null
|
||||
let peerInfo = null
|
||||
|
||||
beforeEach(function (done) {
|
||||
waterfall([
|
||||
(cb) => PeerId.createFromJSON(nodes.node4, cb),
|
||||
(peerId, cb) => PeerInfo.create(peerId, cb),
|
||||
(peer, cb) => {
|
||||
swarm = {
|
||||
_peerInfo: peer
|
||||
}
|
||||
|
||||
peerInfo = peer
|
||||
listener = Listener(swarm, {}, () => {})
|
||||
cb()
|
||||
}
|
||||
], done)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
peerInfo = null
|
||||
})
|
||||
|
||||
it(`should return correct addrs`, function () {
|
||||
peerInfo.multiaddrs.add(`/ip4/0.0.0.0/tcp/4002`)
|
||||
peerInfo.multiaddrs.add(`/ip4/127.0.0.1/tcp/4003/ws`)
|
||||
|
||||
listener.getAddrs((err, addrs) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(addrs).to.deep.equal([
|
||||
multiaddr(`/p2p-circuit/ip4/0.0.0.0/tcp/4002/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`),
|
||||
multiaddr(`/p2p-circuit/ip4/127.0.0.1/tcp/4003/ws/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`)])
|
||||
})
|
||||
})
|
||||
|
||||
it(`don't return default addrs in an explicit p2p-circuit addres`, function () {
|
||||
peerInfo.multiaddrs.add(`/ip4/127.0.0.1/tcp/4003/ws`)
|
||||
peerInfo.multiaddrs.add(`/p2p-circuit/ip4/0.0.0.0/tcp/4002`)
|
||||
listener.getAddrs((err, addrs) => {
|
||||
expect(err).to.not.exist()
|
||||
expect(addrs[0]
|
||||
.toString())
|
||||
.to.equal(`/p2p-circuit/ip4/0.0.0.0/tcp/4002/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
50
test/circuit/proto.spec.js
Normal file
50
test/circuit/proto.spec.js
Normal file
@ -0,0 +1,50 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const expect = chai.expect
|
||||
chai.use(dirtyChai)
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
|
||||
const proto = require('../../src/circuit/protocol')
|
||||
|
||||
describe('protocol', function () {
|
||||
let msgObject = null
|
||||
let message = null
|
||||
|
||||
before(() => {
|
||||
msgObject = {
|
||||
type: proto.CircuitRelay.Type.HOP,
|
||||
srcPeer: {
|
||||
id: Buffer.from('QmSource'),
|
||||
addrs: [
|
||||
multiaddr('/p2p-circuit/ipfs/QmSource').buffer,
|
||||
multiaddr('/p2p-circuit/ip4/0.0.0.0/tcp/9000/ipfs/QmSource').buffer,
|
||||
multiaddr('/ip4/0.0.0.0/tcp/9000/ipfs/QmSource').buffer
|
||||
]
|
||||
},
|
||||
dstPeer: {
|
||||
id: Buffer.from('QmDest'),
|
||||
addrs: [
|
||||
multiaddr('/p2p-circuit/ipfs/QmDest').buffer,
|
||||
multiaddr('/p2p-circuit/ip4/1.1.1.1/tcp/9000/ipfs/QmDest').buffer,
|
||||
multiaddr('/ip4/1.1.1.1/tcp/9000/ipfs/QmDest').buffer
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
const buff = proto.CircuitRelay.encode(msgObject)
|
||||
message = proto.CircuitRelay.decode(buff)
|
||||
})
|
||||
|
||||
it(`should source and dest`, () => {
|
||||
expect(message.srcPeer).to.deep.equal(msgObject.srcPeer)
|
||||
expect(message.dstPeer).to.deep.equal(msgObject.dstPeer)
|
||||
})
|
||||
|
||||
it(`should encode message`, () => {
|
||||
expect(message.message).to.deep.equal(msgObject.message)
|
||||
})
|
||||
})
|
85
test/circuit/stop.spec.js
Normal file
85
test/circuit/stop.spec.js
Normal file
@ -0,0 +1,85 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const Stop = require('../../src/circuit/circuit/stop')
|
||||
const nodes = require('./fixtures/nodes')
|
||||
const Connection = require('interface-connection').Connection
|
||||
const handshake = require('pull-handshake')
|
||||
const waterfall = require('async/waterfall')
|
||||
const PeerInfo = require('peer-info')
|
||||
const PeerId = require('peer-id')
|
||||
const StreamHandler = require('../../src/circuit/circuit/stream-handler')
|
||||
const proto = require('../../src/circuit/protocol')
|
||||
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const expect = chai.expect
|
||||
chai.use(dirtyChai)
|
||||
|
||||
describe('stop', function () {
|
||||
describe(`handle relayed connections`, function () {
|
||||
let stopHandler
|
||||
|
||||
let swarm
|
||||
let conn
|
||||
let stream
|
||||
|
||||
beforeEach(function (done) {
|
||||
stream = handshake({ timeout: 1000 * 60 })
|
||||
conn = new Connection(stream)
|
||||
const peerId = PeerId.createFromB58String('QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE')
|
||||
conn.setPeerInfo(new PeerInfo(peerId))
|
||||
|
||||
waterfall([
|
||||
(cb) => PeerId.createFromJSON(nodes.node4, cb),
|
||||
(peerId, cb) => PeerInfo.create(peerId, cb),
|
||||
(peer, cb) => {
|
||||
peer.multiaddrs.add('/p2p-circuit/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE')
|
||||
swarm = {
|
||||
_peerInfo: peer,
|
||||
conns: {
|
||||
QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE: new Connection()
|
||||
}
|
||||
}
|
||||
|
||||
stopHandler = new Stop(swarm)
|
||||
cb()
|
||||
}
|
||||
], done)
|
||||
})
|
||||
|
||||
it(`handle request with a valid multiaddr`, function (done) {
|
||||
stopHandler.handle({
|
||||
type: proto.CircuitRelay.Type.STOP,
|
||||
srcPeer: {
|
||||
id: `QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`,
|
||||
addrs: [`/ipfs/QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`]
|
||||
},
|
||||
dstPeer: {
|
||||
id: `QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`,
|
||||
addrs: [`/ipfs/QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`]
|
||||
}
|
||||
}, new StreamHandler(conn), (conn) => { // multistream handler doesn't expect errors...
|
||||
expect(conn).to.be.instanceOf(Connection)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it(`handle request with invalid multiaddr`, function (done) {
|
||||
stopHandler.handle({
|
||||
type: proto.CircuitRelay.Type.STOP,
|
||||
srcPeer: {
|
||||
id: `QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE`,
|
||||
addrs: [`dsfsdfsdf`]
|
||||
},
|
||||
dstPeer: {
|
||||
id: `QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy`,
|
||||
addrs: [`sdflksdfndsklfnlkdf`]
|
||||
}
|
||||
}, new StreamHandler(conn), (conn) => {
|
||||
expect(conn).to.not.exist()
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user