mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-06-22 05:21:35 +00:00
feat: add token based dialer
This commit is contained in:
@ -7,6 +7,7 @@ chai.use(require('chai-as-promised'))
|
||||
const { expect } = chai
|
||||
const sinon = require('sinon')
|
||||
const pDefer = require('p-defer')
|
||||
const pWaitFor = require('p-wait-for')
|
||||
const delay = require('delay')
|
||||
const Transport = require('libp2p-websockets')
|
||||
const Muxer = require('libp2p-mplex')
|
||||
@ -14,6 +15,7 @@ const Crypto = require('libp2p-secio')
|
||||
const multiaddr = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
const PeerInfo = require('peer-info')
|
||||
const AggregateError = require('aggregate-error')
|
||||
|
||||
const { codes: ErrorCodes } = require('../../src/errors')
|
||||
const Constants = require('../../src/constants')
|
||||
@ -49,6 +51,22 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
expect(dialer.timeout).to.equal(Constants.DIAL_TIMEOUT)
|
||||
})
|
||||
|
||||
it('should limit the number of tokens it provides', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const maxPerPeer = Constants.PER_PEER_LIMIT
|
||||
expect(dialer.tokens).to.have.length(Constants.MAX_PARALLEL_DIALS)
|
||||
const tokens = dialer.getTokens(maxPerPeer + 1)
|
||||
expect(tokens).to.have.length(maxPerPeer)
|
||||
expect(dialer.tokens).to.have.length(Constants.MAX_PARALLEL_DIALS - maxPerPeer)
|
||||
})
|
||||
|
||||
it('should not return tokens if non are left', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
sinon.stub(dialer, 'tokens').value([])
|
||||
const tokens = dialer.getTokens(1)
|
||||
expect(tokens.length).to.equal(0)
|
||||
})
|
||||
|
||||
it('should be able to connect to a remote node via its multiaddr', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
|
||||
@ -69,30 +87,36 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
|
||||
await expect(dialer.connectToMultiaddr(unsupportedAddr))
|
||||
.to.eventually.be.rejected()
|
||||
.and.to.have.property('code', ErrorCodes.ERR_TRANSPORT_DIAL_FAILED)
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
.and.to.have.nested.property('._errors[0].code', ErrorCodes.ERR_TRANSPORT_DIAL_FAILED)
|
||||
})
|
||||
|
||||
it('should be able to connect to a given peer', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
peerStore: {
|
||||
multiaddrsForPeer: () => [remoteAddr]
|
||||
}
|
||||
})
|
||||
const peerId = await PeerId.createFromJSON(Peers[0])
|
||||
const peerInfo = new PeerInfo(peerId)
|
||||
peerInfo.multiaddrs.add(remoteAddr)
|
||||
|
||||
const connection = await dialer.connectToPeer(peerInfo)
|
||||
const connection = await dialer.connectToPeer(peerId)
|
||||
expect(connection).to.exist()
|
||||
await connection.close()
|
||||
})
|
||||
|
||||
it('should fail to connect to a given peer with unsupported addresses', async () => {
|
||||
const dialer = new Dialer({ transportManager: localTM })
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
peerStore: {
|
||||
multiaddrsForPeer: () => [unsupportedAddr]
|
||||
}
|
||||
})
|
||||
const peerId = await PeerId.createFromJSON(Peers[0])
|
||||
const peerInfo = new PeerInfo(peerId)
|
||||
peerInfo.multiaddrs.add(unsupportedAddr)
|
||||
|
||||
await expect(dialer.connectToPeer(peerInfo))
|
||||
.to.eventually.be.rejected()
|
||||
.and.to.have.property('code', ErrorCodes.ERR_CONNECTION_FAILED)
|
||||
await expect(dialer.connectToPeer(peerId))
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
.and.to.have.nested.property('._errors[0].code', ErrorCodes.ERR_TRANSPORT_DIAL_FAILED)
|
||||
})
|
||||
|
||||
it('should abort dials on queue task timeout', async () => {
|
||||
@ -119,25 +143,21 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
concurrency: 2
|
||||
})
|
||||
|
||||
expect(dialer.tokens).to.have.length(2)
|
||||
|
||||
const deferredDial = pDefer()
|
||||
sinon.stub(localTM, 'dial').callsFake(async () => {
|
||||
await deferredDial.promise
|
||||
})
|
||||
|
||||
// Add 3 dials
|
||||
Promise.all([
|
||||
dialer.connectToMultiaddr(remoteAddr),
|
||||
dialer.connectToMultiaddr(remoteAddr),
|
||||
dialer.connectToMultiaddr(remoteAddr)
|
||||
])
|
||||
// Perform 3 multiaddr dials
|
||||
dialer.connectToMultiaddrs([remoteAddr, remoteAddr, remoteAddr])
|
||||
|
||||
// Let the call stack run
|
||||
await delay(0)
|
||||
|
||||
// We should have 2 in progress, and 1 waiting
|
||||
expect(localTM.dial.callCount).to.equal(2)
|
||||
expect(dialer.queue.pending).to.equal(2)
|
||||
expect(dialer.queue.size).to.equal(1)
|
||||
expect(dialer.tokens).to.have.length(0)
|
||||
|
||||
deferredDial.resolve()
|
||||
|
||||
@ -145,8 +165,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
await delay(0)
|
||||
// All dials should have executed
|
||||
expect(localTM.dial.callCount).to.equal(3)
|
||||
expect(dialer.queue.pending).to.equal(0)
|
||||
expect(dialer.queue.size).to.equal(0)
|
||||
expect(dialer.tokens).to.have.length(2)
|
||||
})
|
||||
|
||||
describe('libp2p.dialer', () => {
|
||||
@ -215,16 +234,18 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
}
|
||||
})
|
||||
|
||||
sinon.spy(libp2p.dialer.identifyService, 'identify')
|
||||
sinon.spy(libp2p.identifyService, 'identify')
|
||||
sinon.spy(libp2p.peerStore, 'replace')
|
||||
sinon.spy(libp2p.upgrader, 'onConnection')
|
||||
|
||||
const connection = await libp2p.dialer.connectToMultiaddr(remoteAddr)
|
||||
expect(connection).to.exist()
|
||||
// Wait for setImmediate to trigger the identify call
|
||||
await delay(1)
|
||||
expect(libp2p.dialer.identifyService.identify.callCount).to.equal(1)
|
||||
await libp2p.dialer.identifyService.identify.firstCall.returnValue
|
||||
|
||||
// Wait for onConnection to be called
|
||||
await pWaitFor(() => libp2p.upgrader.onConnection.callCount === 1)
|
||||
|
||||
expect(libp2p.identifyService.identify.callCount).to.equal(1)
|
||||
await libp2p.identifyService.identify.firstCall.returnValue
|
||||
|
||||
expect(libp2p.peerStore.replace.callCount).to.equal(1)
|
||||
})
|
||||
|
Reference in New Issue
Block a user