chore: store self protocols in protobook (#760)

This commit is contained in:
Vasco Santos
2020-10-27 13:50:14 +00:00
parent 558bcf9541
commit 8456d0e051
6 changed files with 264 additions and 96 deletions

View File

@ -29,18 +29,21 @@ const remoteAddr = MULTIADDRS_WEBSOCKETS[0]
const listenMaddrs = [multiaddr('/ip4/127.0.0.1/tcp/15002/ws')]
describe('Identify', () => {
let localPeer
let remotePeer
const protocols = new Map([
[multicodecs.IDENTIFY, () => {}],
[multicodecs.IDENTIFY_PUSH, () => {}]
])
let localPeer, localPeerStore
let remotePeer, remotePeerStore
const protocols = [multicodecs.IDENTIFY, multicodecs.IDENTIFY_PUSH]
before(async () => {
[localPeer, remotePeer] = (await Promise.all([
PeerId.createFromJSON(Peers[0]),
PeerId.createFromJSON(Peers[1])
]))
localPeerStore = new PeerStore({ peerId: localPeer })
localPeerStore.protoBook.set(localPeer, protocols)
remotePeerStore = new PeerStore({ peerId: remotePeer })
remotePeerStore.protoBook.set(remotePeer, protocols)
})
afterEach(() => {
@ -52,20 +55,19 @@ describe('Identify', () => {
libp2p: {
peerId: localPeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: localPeer }),
multiaddrs: listenMaddrs
},
protocols
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true
}
})
const remoteIdentify = new IdentifyService({
libp2p: {
peerId: remotePeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: remotePeer }),
multiaddrs: listenMaddrs
},
protocols
peerStore: remotePeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true
}
})
const observedAddr = multiaddr('/ip4/127.0.0.1/tcp/1234')
@ -108,20 +110,20 @@ describe('Identify', () => {
libp2p: {
peerId: localPeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: localPeer }),
multiaddrs: listenMaddrs
},
protocols
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true
}
})
const remoteIdentify = new IdentifyService({
libp2p: {
peerId: remotePeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: remotePeer }),
multiaddrs: listenMaddrs
},
protocols
peerStore: remotePeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true
}
})
const observedAddr = multiaddr('/ip4/127.0.0.1/tcp/1234')
@ -167,19 +169,17 @@ describe('Identify', () => {
libp2p: {
peerId: localPeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: localPeer }),
peerStore: localPeerStore,
multiaddrs: []
},
protocols
}
})
const remoteIdentify = new IdentifyService({
libp2p: {
peerId: remotePeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: remotePeer }),
peerStore: remotePeerStore,
multiaddrs: []
},
protocols
}
})
const observedAddr = multiaddr('/ip4/127.0.0.1/tcp/1234')
@ -206,33 +206,38 @@ describe('Identify', () => {
describe('push', () => {
it('should be able to push identify updates to another peer', async () => {
const storedProtocols = [multicodecs.IDENTIFY, multicodecs.IDENTIFY_PUSH, '/echo/1.0.0']
const connectionManager = new EventEmitter()
connectionManager.getConnection = () => { }
const localPeerStore = new PeerStore({ peerId: localPeer })
localPeerStore.protoBook.set(localPeer, storedProtocols)
const localIdentify = new IdentifyService({
libp2p: {
peerId: localPeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: localPeer }),
multiaddrs: listenMaddrs
},
protocols: new Map([
[multicodecs.IDENTIFY],
[multicodecs.IDENTIFY_PUSH],
['/echo/1.0.0']
])
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true
}
})
const remotePeerStore = new PeerStore({ peerId: remotePeer })
remotePeerStore.protoBook.set(remotePeer, storedProtocols)
const remoteIdentify = new IdentifyService({
libp2p: {
peerId: remotePeer,
connectionManager,
peerStore: new PeerStore({ peerId: remotePeer }),
multiaddrs: []
peerStore: remotePeerStore,
multiaddrs: [],
isStarted: () => true
}
})
// Setup peer protocols and multiaddrs
const localProtocols = new Set([multicodecs.IDENTIFY, multicodecs.IDENTIFY_PUSH, '/echo/1.0.0'])
const localProtocols = new Set(storedProtocols)
const localConnectionMock = { newStream: () => { } }
const remoteConnectionMock = { remotePeer: localPeer }
@ -271,33 +276,38 @@ describe('Identify', () => {
// LEGACY
it('should be able to push identify updates to another peer with no certified peer records support', async () => {
const storedProtocols = [multicodecs.IDENTIFY, multicodecs.IDENTIFY_PUSH, '/echo/1.0.0']
const connectionManager = new EventEmitter()
connectionManager.getConnection = () => { }
const localPeerStore = new PeerStore({ peerId: localPeer })
localPeerStore.protoBook.set(localPeer, storedProtocols)
const localIdentify = new IdentifyService({
libp2p: {
peerId: localPeer,
connectionManager: new EventEmitter(),
peerStore: new PeerStore({ peerId: localPeer }),
multiaddrs: listenMaddrs
},
protocols: new Map([
[multicodecs.IDENTIFY],
[multicodecs.IDENTIFY_PUSH],
['/echo/1.0.0']
])
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true
}
})
const remotePeerStore = new PeerStore({ peerId: remotePeer })
remotePeerStore.protoBook.set(remotePeer, storedProtocols)
const remoteIdentify = new IdentifyService({
libp2p: {
peerId: remotePeer,
connectionManager,
peerStore: new PeerStore({ peerId: remotePeer }),
multiaddrs: []
multiaddrs: [],
isStarted: () => true
}
})
// Setup peer protocols and multiaddrs
const localProtocols = new Set([multicodecs.IDENTIFY, multicodecs.IDENTIFY_PUSH, '/echo/1.0.0'])
const localProtocols = new Set(storedProtocols)
const localConnectionMock = { newStream: () => {} }
const remoteConnectionMock = { remotePeer: localPeer }

View File

@ -5,7 +5,9 @@ const chai = require('chai')
chai.use(require('dirty-chai'))
const { expect } = chai
const sinon = require('sinon')
const pDefer = require('p-defer')
const pWaitFor = require('p-wait-for')
const PeerStore = require('../../src/peer-store')
@ -224,6 +226,96 @@ describe('protoBook', () => {
})
})
describe('protoBook.remove', () => {
let peerStore, pb
beforeEach(() => {
peerStore = new PeerStore({ peerId })
pb = peerStore.protoBook
})
afterEach(() => {
peerStore.removeAllListeners()
})
it('throws invalid parameters error if invalid PeerId is provided', () => {
expect(() => {
pb.remove('invalid peerId')
}).to.throw(ERR_INVALID_PARAMETERS)
})
it('throws invalid parameters error if no protocols provided', () => {
expect(() => {
pb.remove(peerId)
}).to.throw(ERR_INVALID_PARAMETERS)
})
it('removes the given protocol and emits change event', async () => {
const spy = sinon.spy()
const supportedProtocols = ['protocol1', 'protocol2']
const removedProtocols = ['protocol1']
const finalProtocols = supportedProtocols.filter(p => !removedProtocols.includes(p))
peerStore.on('change:protocols', spy)
// Replace
pb.set(peerId, supportedProtocols)
let protocols = pb.get(peerId)
expect(protocols).to.have.deep.members(supportedProtocols)
// Remove
pb.remove(peerId, removedProtocols)
protocols = pb.get(peerId)
expect(protocols).to.have.deep.members(finalProtocols)
await pWaitFor(() => spy.callCount === 2)
const [firstCallArgs] = spy.firstCall.args
const [secondCallArgs] = spy.secondCall.args
expect(arraysAreEqual(firstCallArgs.protocols, supportedProtocols))
expect(arraysAreEqual(secondCallArgs.protocols, finalProtocols))
})
it('emits on remove if the content changes', () => {
const spy = sinon.spy()
const supportedProtocols = ['protocol1', 'protocol2']
const removedProtocols = ['protocol2']
const finalProtocols = supportedProtocols.filter(p => !removedProtocols.includes(p))
peerStore.on('change:protocols', spy)
// set
pb.set(peerId, supportedProtocols)
// remove (content already existing)
pb.remove(peerId, removedProtocols)
const protocols = pb.get(peerId)
expect(protocols).to.have.deep.members(finalProtocols)
return pWaitFor(() => spy.callCount === 2)
})
it('does not emit on remove if the content does not change', () => {
const spy = sinon.spy()
const supportedProtocols = ['protocol1', 'protocol2']
const removedProtocols = ['protocol3']
peerStore.on('change:protocols', spy)
// set
pb.set(peerId, supportedProtocols)
// remove
pb.remove(peerId, removedProtocols)
// Only one event
expect(spy.callCount).to.eql(1)
})
})
describe('protoBook.get', () => {
let peerStore, pb