mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-04-25 18:42:15 +00:00
chore: add certified peer records to persisted peer store
This commit is contained in:
parent
8f2e69048f
commit
74d414c21f
@ -82,9 +82,6 @@ class IdentifyService {
|
|||||||
this._protocols = protocols
|
this._protocols = protocols
|
||||||
|
|
||||||
this.handleMessage = this.handleMessage.bind(this)
|
this.handleMessage = this.handleMessage.bind(this)
|
||||||
|
|
||||||
// TODO: this should be stored in the certified AddressBook in follow up PR
|
|
||||||
this._selfRecord = undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,22 +181,18 @@ class IdentifyService {
|
|||||||
// Get the observedAddr if there is one
|
// Get the observedAddr if there is one
|
||||||
observedAddr = IdentifyService.getCleanMultiaddr(observedAddr)
|
observedAddr = IdentifyService.getCleanMultiaddr(observedAddr)
|
||||||
|
|
||||||
let addresses
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const envelope = await Envelope.openAndCertify(signedPeerRecord, PeerRecord.DOMAIN)
|
const envelope = await Envelope.openAndCertify(signedPeerRecord, PeerRecord.DOMAIN)
|
||||||
const peerRecord = await PeerRecord.createFromProtobuf(envelope.payload)
|
if (this.peerStore.addressBook.consumePeerRecord(envelope)) {
|
||||||
|
return
|
||||||
addresses = peerRecord.multiaddrs
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
|
log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
|
||||||
// Try Legacy
|
|
||||||
addresses = listenAddrs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update peers data in PeerStore
|
// Update peers data in PeerStore
|
||||||
try {
|
try {
|
||||||
this.peerStore.addressBook.set(id, addresses.map((addr) => multiaddr(addr)))
|
this.peerStore.addressBook.set(id, listenAddrs.map((addr) => multiaddr(addr)))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('received invalid addrs', err)
|
log.error('received invalid addrs', err)
|
||||||
}
|
}
|
||||||
@ -294,21 +287,24 @@ class IdentifyService {
|
|||||||
|
|
||||||
const id = connection.remotePeer
|
const id = connection.remotePeer
|
||||||
|
|
||||||
let addresses
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const envelope = await Envelope.openAndCertify(message.signedPeerRecord, PeerRecord.DOMAIN)
|
const envelope = await Envelope.openAndCertify(message.signedPeerRecord, PeerRecord.DOMAIN)
|
||||||
const peerRecord = await PeerRecord.createFromProtobuf(envelope.payload)
|
if (this.peerStore.addressBook.consumePeerRecord(envelope)) {
|
||||||
|
return
|
||||||
addresses = peerRecord.multiaddrs
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
<<<<<<< HEAD
|
||||||
log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
|
log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
|
||||||
// Try Legacy
|
// Try Legacy
|
||||||
addresses = message.listenAddrs
|
addresses = message.listenAddrs
|
||||||
|
=======
|
||||||
|
log('received invalid envelope, discard it and fallback to listenAddrs is available')
|
||||||
|
>>>>>>> chore: add certified peer records to persisted peer store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update peers data in PeerStore
|
||||||
try {
|
try {
|
||||||
this.peerStore.addressBook.set(id, addresses.map((addr) => multiaddr(addr)))
|
this.peerStore.addressBook.set(id, message.listenAddrs.map((addr) => multiaddr(addr)))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('received invalid addrs', err)
|
log.error('received invalid addrs', err)
|
||||||
}
|
}
|
||||||
@ -321,10 +317,12 @@ class IdentifyService {
|
|||||||
* Get self signed peer record raw envelope.
|
* Get self signed peer record raw envelope.
|
||||||
* @return {Buffer}
|
* @return {Buffer}
|
||||||
*/
|
*/
|
||||||
async _getSelfPeerRecord () {
|
async _getSelfPeerRecord() {
|
||||||
|
const selfSignedPeerRecord = this.peerStore.addressBook.getRawEnvelope(this.peerId)
|
||||||
|
|
||||||
// TODO: support invalidation when dynamic multiaddrs are supported
|
// TODO: support invalidation when dynamic multiaddrs are supported
|
||||||
if (this._selfRecord) {
|
if (selfSignedPeerRecord) {
|
||||||
return this._selfRecord
|
return selfSignedPeerRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -333,10 +331,9 @@ class IdentifyService {
|
|||||||
multiaddrs: this._libp2p.multiaddrs
|
multiaddrs: this._libp2p.multiaddrs
|
||||||
})
|
})
|
||||||
const envelope = await Envelope.seal(peerRecord, this.peerId)
|
const envelope = await Envelope.seal(peerRecord, this.peerId)
|
||||||
|
this.peerStore.addressBook.consumePeerRecord(envelope)
|
||||||
|
|
||||||
this._selfRecord = envelope.marshal()
|
return this.peerStore.addressBook.getRawEnvelope(this.peerId)
|
||||||
|
|
||||||
return this._selfRecord
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('failed to get self peer record')
|
log.error('failed to get self peer record')
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,8 @@ class AddressBook extends Book {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConsumePeerRecord adds addresses from a signed peer.PeerRecord contained in a record envelope.
|
* ConsumePeerRecord adds addresses from a signed peer record contained in a record envelope.
|
||||||
* This will return a boolean that indicates if the record was successfully processed and integrated
|
* This will return a boolean that indicates if the record was successfully processed and added
|
||||||
* into the AddressBook.
|
* into the AddressBook.
|
||||||
* @param {Envelope} envelope
|
* @param {Envelope} envelope
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
@ -93,31 +93,25 @@ class AddressBook extends Book {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensure the record has multiaddrs
|
||||||
|
if (!peerRecord.multiaddrs || !peerRecord.multiaddrs.length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const peerId = peerRecord.peerId
|
const peerId = peerRecord.peerId
|
||||||
const id = peerId.toB58String()
|
const id = peerId.toB58String()
|
||||||
const entry = this.data.get(id) || {}
|
const entry = this.data.get(id) || {}
|
||||||
const storedRecord = entry.record
|
const storedRecord = entry.record
|
||||||
|
|
||||||
// ensure seq is greater than, or equal to, the last received
|
// ensure seq is greater than, or equal to, the last received
|
||||||
if (storedRecord &&
|
if (storedRecord && storedRecord.seqNumber >= peerRecord.seqNumber) {
|
||||||
storedRecord.seqNumber >= peerRecord.seqNumber) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the record has multiaddrs
|
|
||||||
if (!peerRecord.multiaddrs || !peerRecord.multiaddrs.length) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const addresses = this._toAddresses(peerRecord.multiaddrs, true)
|
const addresses = this._toAddresses(peerRecord.multiaddrs, true)
|
||||||
|
|
||||||
// TODO: new record with different addresses from stored record
|
// Replace unsigned addresses by the new ones from the record
|
||||||
// - Remove the older ones?
|
// TODO: Once we have ttls for the addresses, we should merge these in.
|
||||||
// - Change to uncertified?
|
|
||||||
|
|
||||||
// TODO: events
|
|
||||||
// Should a multiaddr only modified to certified trigger an event?
|
|
||||||
// - Needed for persistent peer store
|
|
||||||
this._setData(peerId, {
|
this._setData(peerId, {
|
||||||
addresses,
|
addresses,
|
||||||
record: {
|
record: {
|
||||||
@ -130,19 +124,34 @@ class AddressBook extends Book {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a peer raw envelope.
|
||||||
|
* @param {PeerId} peerId
|
||||||
|
* @return {Buffer}
|
||||||
|
*/
|
||||||
|
getRawEnvelope (peerId) {
|
||||||
|
const entry = this.data.get(peerId.toB58String())
|
||||||
|
|
||||||
|
if (!entry || !entry.record || !entry.record.raw) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry.record.raw
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an Envelope containing a PeerRecord for the given peer.
|
* Get an Envelope containing a PeerRecord for the given peer.
|
||||||
* @param {PeerId} peerId
|
* @param {PeerId} peerId
|
||||||
* @return {Promise<Envelope>}
|
* @return {Promise<Envelope>}
|
||||||
*/
|
*/
|
||||||
getPeerRecord (peerId) {
|
getPeerRecord (peerId) {
|
||||||
const entry = this.data.get(peerId.toB58String())
|
const raw = this.getRawEnvelope(peerId)
|
||||||
|
|
||||||
if (!entry || !entry.record || !entry.record.raw) {
|
if (!raw) {
|
||||||
return
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
return Envelope.createFromProtobuf(entry.record.raw)
|
return Envelope.createFromProtobuf(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,7 +179,7 @@ class AddressBook extends Book {
|
|||||||
|
|
||||||
// Already knows the peer
|
// Already knows the peer
|
||||||
if (rec && rec.length === addresses.length) {
|
if (rec && rec.length === addresses.length) {
|
||||||
const intersection = rec.filter((mi) => addresses.some((newMi) => mi.multiaddr.equals(newMi.multiaddr)))
|
const intersection = rec.filter((addr) => addresses.some((newAddr) => addr.multiaddr.equals(newAddr.multiaddr)))
|
||||||
|
|
||||||
// Are new addresses equal to the old ones?
|
// Are new addresses equal to the old ones?
|
||||||
// If yes, no changes needed!
|
// If yes, no changes needed!
|
||||||
@ -214,9 +223,9 @@ class AddressBook extends Book {
|
|||||||
const rec = entry.addresses
|
const rec = entry.addresses
|
||||||
|
|
||||||
// Add recorded uniquely to the new array (Union)
|
// Add recorded uniquely to the new array (Union)
|
||||||
rec && rec.forEach((mi) => {
|
rec && rec.forEach((addr) => {
|
||||||
if (!addresses.find(r => r.multiaddr.equals(mi.multiaddr))) {
|
if (!addresses.find(r => r.multiaddr.equals(addr.multiaddr))) {
|
||||||
addresses.push(mi)
|
addresses.push(addr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -249,7 +258,6 @@ class AddressBook extends Book {
|
|||||||
* @returns {Array<data>}
|
* @returns {Array<data>}
|
||||||
*/
|
*/
|
||||||
get (peerId) {
|
get (peerId) {
|
||||||
// TODO: should we return Entry instead??
|
|
||||||
if (!PeerId.isPeerId(peerId)) {
|
if (!PeerId.isPeerId(peerId)) {
|
||||||
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
|
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
|
||||||
}
|
}
|
||||||
|
@ -177,21 +177,24 @@ class PersistentPeerStore extends PeerStore {
|
|||||||
const b32key = peerId.toString()
|
const b32key = peerId.toString()
|
||||||
const key = new Key(`${NAMESPACE_ADDRESS}${b32key}`)
|
const key = new Key(`${NAMESPACE_ADDRESS}${b32key}`)
|
||||||
|
|
||||||
const addresses = this.addressBook.get(peerId)
|
const entry = this.addressBook.data.get(peerId.toB58String())
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Deleted from the book
|
// Deleted from the book
|
||||||
if (!addresses) {
|
if (!entry) {
|
||||||
batch.delete(key)
|
batch.delete(key)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const encodedData = Addresses.encode({
|
const encodedData = Addresses.encode({
|
||||||
addrs: addresses.map((address) => ({
|
addrs: entry.addresses.map((address) => ({
|
||||||
multiaddr: address.multiaddr.buffer
|
multiaddr: address.multiaddr.buffer
|
||||||
}))
|
})),
|
||||||
|
certified_record: entry.record ? {
|
||||||
|
seq: entry.record.seqNumber,
|
||||||
|
raw: entry.record.raw
|
||||||
|
} : undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
batch.put(key, encodedData)
|
batch.put(key, encodedData)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(err)
|
log.error(err)
|
||||||
@ -299,7 +302,11 @@ class PersistentPeerStore extends PeerStore {
|
|||||||
{
|
{
|
||||||
addresses: decoded.addrs.map((address) => ({
|
addresses: decoded.addrs.map((address) => ({
|
||||||
multiaddr: multiaddr(address.multiaddr)
|
multiaddr: multiaddr(address.multiaddr)
|
||||||
}))
|
})),
|
||||||
|
record: decoded.certified_record ? {
|
||||||
|
raw: decoded.certified_record.raw,
|
||||||
|
seqNumber: decoded.certified_record.seq
|
||||||
|
} : undefined
|
||||||
},
|
},
|
||||||
{ emit: false })
|
{ emit: false })
|
||||||
break
|
break
|
||||||
|
@ -363,7 +363,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
|||||||
const connection = await libp2p.dial(remoteAddr)
|
const connection = await libp2p.dial(remoteAddr)
|
||||||
expect(connection).to.exist()
|
expect(connection).to.exist()
|
||||||
|
|
||||||
sinon.spy(libp2p.peerStore.addressBook, 'set')
|
sinon.spy(libp2p.peerStore.addressBook, 'consumePeerRecord')
|
||||||
sinon.spy(libp2p.peerStore.protoBook, 'set')
|
sinon.spy(libp2p.peerStore.protoBook, 'set')
|
||||||
|
|
||||||
// Wait for onConnection to be called
|
// Wait for onConnection to be called
|
||||||
@ -372,7 +372,8 @@ describe('Dialing (direct, WebSockets)', () => {
|
|||||||
expect(libp2p.identifyService.identify.callCount).to.equal(1)
|
expect(libp2p.identifyService.identify.callCount).to.equal(1)
|
||||||
await libp2p.identifyService.identify.firstCall.returnValue
|
await libp2p.identifyService.identify.firstCall.returnValue
|
||||||
|
|
||||||
expect(libp2p.peerStore.addressBook.set.callCount).to.equal(1)
|
// Self + New peer
|
||||||
|
expect(libp2p.peerStore.addressBook.consumePeerRecord.callCount).to.equal(2)
|
||||||
expect(libp2p.peerStore.protoBook.set.callCount).to.equal(1)
|
expect(libp2p.peerStore.protoBook.set.callCount).to.equal(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const { IdentifyService, multicodecs } = require('../../src/identify')
|
|||||||
const Peers = require('../fixtures/peers')
|
const Peers = require('../fixtures/peers')
|
||||||
const Libp2p = require('../../src')
|
const Libp2p = require('../../src')
|
||||||
const Envelope = require('../../src/record/envelope')
|
const Envelope = require('../../src/record/envelope')
|
||||||
|
const PeerStore = require('../../src/peer-store')
|
||||||
const baseOptions = require('../utils/base-options.browser')
|
const baseOptions = require('../utils/base-options.browser')
|
||||||
const pkg = require('../../package.json')
|
const pkg = require('../../package.json')
|
||||||
|
|
||||||
@ -50,14 +51,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: localPeer,
|
peerId: localPeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
peerStore: {
|
peerStore: new PeerStore(),
|
||||||
addressBook: {
|
|
||||||
set: () => { }
|
|
||||||
},
|
|
||||||
protoBook: {
|
|
||||||
set: () => { }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
multiaddrs: listenMaddrs
|
multiaddrs: listenMaddrs
|
||||||
},
|
},
|
||||||
protocols
|
protocols
|
||||||
@ -67,6 +61,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: remotePeer,
|
peerId: remotePeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
|
peerStore: new PeerStore(),
|
||||||
multiaddrs: listenMaddrs
|
multiaddrs: listenMaddrs
|
||||||
},
|
},
|
||||||
protocols
|
protocols
|
||||||
@ -109,17 +104,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: localPeer,
|
peerId: localPeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
peerStore: {
|
peerStore: new PeerStore(),
|
||||||
addressBook: {
|
|
||||||
set: () => {}
|
|
||||||
},
|
|
||||||
protoBook: {
|
|
||||||
set: () => { }
|
|
||||||
},
|
|
||||||
metadataBook: {
|
|
||||||
set: () => { }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
multiaddrs: listenMaddrs
|
multiaddrs: listenMaddrs
|
||||||
},
|
},
|
||||||
protocols
|
protocols
|
||||||
@ -129,6 +114,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: remotePeer,
|
peerId: remotePeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
|
peerStore: new PeerStore(),
|
||||||
multiaddrs: listenMaddrs
|
multiaddrs: listenMaddrs
|
||||||
},
|
},
|
||||||
protocols
|
protocols
|
||||||
@ -142,7 +128,7 @@ describe('Identify', () => {
|
|||||||
sinon.stub(localConnectionMock, 'newStream').returns({ stream: local, protocol: multicodecs.IDENTIFY })
|
sinon.stub(localConnectionMock, 'newStream').returns({ stream: local, protocol: multicodecs.IDENTIFY })
|
||||||
sinon.stub(Envelope, 'openAndCertify').throws()
|
sinon.stub(Envelope, 'openAndCertify').throws()
|
||||||
|
|
||||||
sinon.spy(localIdentify.peerStore.addressBook, 'set')
|
sinon.spy(localIdentify.peerStore.addressBook, 'consumePeerRecord')
|
||||||
sinon.spy(localIdentify.peerStore.protoBook, 'set')
|
sinon.spy(localIdentify.peerStore.protoBook, 'set')
|
||||||
sinon.spy(localIdentify.peerStore.metadataBook, 'set')
|
sinon.spy(localIdentify.peerStore.metadataBook, 'set')
|
||||||
|
|
||||||
@ -156,7 +142,7 @@ describe('Identify', () => {
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(localIdentify.peerStore.addressBook.set.callCount).to.equal(1)
|
expect(localIdentify.peerStore.addressBook.consumePeerRecord.callCount).to.equal(1)
|
||||||
expect(localIdentify.peerStore.protoBook.set.callCount).to.equal(1)
|
expect(localIdentify.peerStore.protoBook.set.callCount).to.equal(1)
|
||||||
|
|
||||||
const metadataArgs = localIdentify.peerStore.metadataBook.set.firstCall.args
|
const metadataArgs = localIdentify.peerStore.metadataBook.set.firstCall.args
|
||||||
@ -165,11 +151,11 @@ describe('Identify', () => {
|
|||||||
expect(metadataArgs[2].toString()).to.equal(`js-libp2p/${pkg.version}`)
|
expect(metadataArgs[2].toString()).to.equal(`js-libp2p/${pkg.version}`)
|
||||||
|
|
||||||
// Validate the remote peer gets updated in the peer store
|
// Validate the remote peer gets updated in the peer store
|
||||||
const call = localIdentify.peerStore.addressBook.set.firstCall
|
const addresses = localIdentify.peerStore.addressBook.get(remotePeer)
|
||||||
expect(call.args[0].id.bytes).to.equal(remotePeer.bytes)
|
expect(addresses).to.exist()
|
||||||
expect(call.args[1]).to.exist()
|
expect(addresses).have.lengthOf(listenMaddrs.length)
|
||||||
expect(call.args[1]).have.lengthOf(listenMaddrs.length)
|
expect(addresses.map((a) => a.multiaddr)[0].equals(listenMaddrs[0]))
|
||||||
expect(call.args[1][0].equals(listenMaddrs[0]))
|
expect(addresses.map((a) => a.isCertified)[0]).to.eql(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw if identified peer is the wrong peer', async () => {
|
it('should throw if identified peer is the wrong peer', async () => {
|
||||||
@ -177,14 +163,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: localPeer,
|
peerId: localPeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
peerStore: {
|
peerStore: new PeerStore(),
|
||||||
addressBook: {
|
|
||||||
set: () => { }
|
|
||||||
},
|
|
||||||
protoBook: {
|
|
||||||
set: () => { }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
multiaddrs: []
|
multiaddrs: []
|
||||||
},
|
},
|
||||||
protocols
|
protocols
|
||||||
@ -193,6 +172,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: remotePeer,
|
peerId: remotePeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
|
peerStore: new PeerStore(),
|
||||||
multiaddrs: []
|
multiaddrs: []
|
||||||
},
|
},
|
||||||
protocols
|
protocols
|
||||||
@ -229,6 +209,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: localPeer,
|
peerId: localPeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
|
peerStore: new PeerStore(),
|
||||||
multiaddrs: listenMaddrs
|
multiaddrs: listenMaddrs
|
||||||
},
|
},
|
||||||
protocols: new Map([
|
protocols: new Map([
|
||||||
@ -241,14 +222,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: remotePeer,
|
peerId: remotePeer,
|
||||||
connectionManager,
|
connectionManager,
|
||||||
peerStore: {
|
peerStore: new PeerStore(),
|
||||||
addressBook: {
|
|
||||||
set: () => { }
|
|
||||||
},
|
|
||||||
protoBook: {
|
|
||||||
set: () => { }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
multiaddrs: []
|
multiaddrs: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -261,7 +235,7 @@ describe('Identify', () => {
|
|||||||
const [local, remote] = duplexPair()
|
const [local, remote] = duplexPair()
|
||||||
sinon.stub(localConnectionMock, 'newStream').returns({ stream: local, protocol: multicodecs.IDENTIFY_PUSH })
|
sinon.stub(localConnectionMock, 'newStream').returns({ stream: local, protocol: multicodecs.IDENTIFY_PUSH })
|
||||||
|
|
||||||
sinon.spy(remoteIdentify.peerStore.addressBook, 'set')
|
sinon.spy(remoteIdentify.peerStore.addressBook, 'consumePeerRecord')
|
||||||
sinon.spy(remoteIdentify.peerStore.protoBook, 'set')
|
sinon.spy(remoteIdentify.peerStore.protoBook, 'set')
|
||||||
|
|
||||||
// Run identify
|
// Run identify
|
||||||
@ -274,11 +248,14 @@ describe('Identify', () => {
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(remoteIdentify.peerStore.addressBook.set.callCount).to.equal(1)
|
expect(remoteIdentify.peerStore.addressBook.consumePeerRecord.callCount).to.equal(1)
|
||||||
expect(remoteIdentify.peerStore.protoBook.set.callCount).to.equal(1)
|
expect(remoteIdentify.peerStore.protoBook.set.callCount).to.equal(1)
|
||||||
const [peerId, multiaddrs] = remoteIdentify.peerStore.addressBook.set.firstCall.args
|
|
||||||
expect(peerId.bytes).to.eql(localPeer.bytes)
|
const addresses = localIdentify.peerStore.addressBook.get(localPeer)
|
||||||
expect(multiaddrs).to.eql(listenMaddrs)
|
expect(addresses).to.exist()
|
||||||
|
expect(addresses).have.lengthOf(listenMaddrs.length)
|
||||||
|
expect(addresses.map((a) => a.multiaddr)).to.eql(listenMaddrs)
|
||||||
|
|
||||||
const [peerId2, protocols] = remoteIdentify.peerStore.protoBook.set.firstCall.args
|
const [peerId2, protocols] = remoteIdentify.peerStore.protoBook.set.firstCall.args
|
||||||
expect(peerId2.bytes).to.eql(localPeer.bytes)
|
expect(peerId2.bytes).to.eql(localPeer.bytes)
|
||||||
expect(protocols).to.eql(Array.from(localProtocols))
|
expect(protocols).to.eql(Array.from(localProtocols))
|
||||||
@ -293,6 +270,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: localPeer,
|
peerId: localPeer,
|
||||||
connectionManager: new EventEmitter(),
|
connectionManager: new EventEmitter(),
|
||||||
|
peerStore: new PeerStore(),
|
||||||
multiaddrs: listenMaddrs
|
multiaddrs: listenMaddrs
|
||||||
},
|
},
|
||||||
protocols: new Map([
|
protocols: new Map([
|
||||||
@ -305,14 +283,7 @@ describe('Identify', () => {
|
|||||||
libp2p: {
|
libp2p: {
|
||||||
peerId: remotePeer,
|
peerId: remotePeer,
|
||||||
connectionManager,
|
connectionManager,
|
||||||
peerStore: {
|
peerStore: new PeerStore(),
|
||||||
addressBook: {
|
|
||||||
set: () => { }
|
|
||||||
},
|
|
||||||
protoBook: {
|
|
||||||
set: () => { }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
multiaddrs: []
|
multiaddrs: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -326,7 +297,7 @@ describe('Identify', () => {
|
|||||||
sinon.stub(localConnectionMock, 'newStream').returns({ stream: local, protocol: multicodecs.IDENTIFY_PUSH })
|
sinon.stub(localConnectionMock, 'newStream').returns({ stream: local, protocol: multicodecs.IDENTIFY_PUSH })
|
||||||
sinon.stub(Envelope, 'openAndCertify').throws()
|
sinon.stub(Envelope, 'openAndCertify').throws()
|
||||||
|
|
||||||
sinon.spy(remoteIdentify.peerStore.addressBook, 'set')
|
sinon.spy(remoteIdentify.peerStore.addressBook, 'consumePeerRecord')
|
||||||
sinon.spy(remoteIdentify.peerStore.protoBook, 'set')
|
sinon.spy(remoteIdentify.peerStore.protoBook, 'set')
|
||||||
|
|
||||||
// Run identify
|
// Run identify
|
||||||
@ -339,11 +310,14 @@ describe('Identify', () => {
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(remoteIdentify.peerStore.addressBook.set.callCount).to.equal(1)
|
expect(remoteIdentify.peerStore.addressBook.consumePeerRecord.callCount).to.equal(1)
|
||||||
expect(remoteIdentify.peerStore.protoBook.set.callCount).to.equal(1)
|
expect(remoteIdentify.peerStore.protoBook.set.callCount).to.equal(1)
|
||||||
const [peerId, multiaddrs] = remoteIdentify.peerStore.addressBook.set.firstCall.args
|
|
||||||
expect(peerId.bytes).to.eql(localPeer.bytes)
|
const addresses = localIdentify.peerStore.addressBook.get(localPeer)
|
||||||
expect(multiaddrs).to.eql(listenMaddrs)
|
expect(addresses).to.exist()
|
||||||
|
expect(addresses).have.lengthOf(listenMaddrs.length)
|
||||||
|
expect(addresses.map((a) => a.multiaddr)).to.eql(listenMaddrs)
|
||||||
|
|
||||||
const [peerId2, protocols] = remoteIdentify.peerStore.protoBook.set.firstCall.args
|
const [peerId2, protocols] = remoteIdentify.peerStore.protoBook.set.firstCall.args
|
||||||
expect(peerId2.bytes).to.eql(localPeer.bytes)
|
expect(peerId2.bytes).to.eql(localPeer.bytes)
|
||||||
expect(protocols).to.eql(Array.from(localProtocols))
|
expect(protocols).to.eql(Array.from(localProtocols))
|
||||||
@ -378,15 +352,15 @@ describe('Identify', () => {
|
|||||||
await libp2p.start()
|
await libp2p.start()
|
||||||
|
|
||||||
sinon.spy(libp2p.identifyService, 'identify')
|
sinon.spy(libp2p.identifyService, 'identify')
|
||||||
const peerStoreSpySet = sinon.spy(libp2p.peerStore.addressBook, 'set')
|
const peerStoreSpyConsumeRecord = sinon.spy(libp2p.peerStore.addressBook, 'consumePeerRecord')
|
||||||
const peerStoreSpyAdd = sinon.spy(libp2p.peerStore.addressBook, 'add')
|
const peerStoreSpyAdd = sinon.spy(libp2p.peerStore.addressBook, 'add')
|
||||||
|
|
||||||
const connection = await libp2p.dialer.connectToPeer(remoteAddr)
|
const connection = await libp2p.dialer.connectToPeer(remoteAddr)
|
||||||
expect(connection).to.exist()
|
expect(connection).to.exist()
|
||||||
|
|
||||||
// Wait for peer store to be updated
|
// Wait for peer store to be updated
|
||||||
// Dialer._createDialTarget (add), Identify (replace)
|
// Dialer._createDialTarget (add), Identify (consume), Create self (consume)
|
||||||
await pWaitFor(() => peerStoreSpySet.callCount === 1 && peerStoreSpyAdd.callCount === 1)
|
await pWaitFor(() => peerStoreSpyConsumeRecord.callCount === 2 && peerStoreSpyAdd.callCount === 1)
|
||||||
expect(libp2p.identifyService.identify.callCount).to.equal(1)
|
expect(libp2p.identifyService.identify.callCount).to.equal(1)
|
||||||
|
|
||||||
// The connection should have no open streams
|
// The connection should have no open streams
|
||||||
|
@ -459,7 +459,8 @@ describe('addressBook', () => {
|
|||||||
return defer.promise
|
return defer.promise
|
||||||
})
|
})
|
||||||
|
|
||||||
it('with same data currently in AddressBook (not certified)', async () => {
|
it('emits change:multiaddrs event with same data currently in AddressBook (not certified)', async () => {
|
||||||
|
const defer = pDefer()
|
||||||
const multiaddrs = [addr1, addr2]
|
const multiaddrs = [addr1, addr2]
|
||||||
|
|
||||||
// Set addressBook data
|
// Set addressBook data
|
||||||
@ -482,10 +483,19 @@ describe('addressBook', () => {
|
|||||||
})
|
})
|
||||||
const envelope = await Envelope.seal(peerRecord, peerId)
|
const envelope = await Envelope.seal(peerRecord, peerId)
|
||||||
|
|
||||||
|
peerStore.once('change:multiaddrs', ({ peerId, multiaddrs }) => {
|
||||||
|
expect(peerId).to.exist()
|
||||||
|
expect(multiaddrs).to.eql(multiaddrs)
|
||||||
|
defer.resolve()
|
||||||
|
})
|
||||||
|
|
||||||
// consume peer record
|
// consume peer record
|
||||||
const consumed = ab.consumePeerRecord(envelope)
|
const consumed = ab.consumePeerRecord(envelope)
|
||||||
expect(consumed).to.eql(true)
|
expect(consumed).to.eql(true)
|
||||||
|
|
||||||
|
// Wait event
|
||||||
|
await defer.promise
|
||||||
|
|
||||||
// Validate data exists and certified
|
// Validate data exists and certified
|
||||||
addrs = ab.get(peerId)
|
addrs = ab.get(peerId)
|
||||||
expect(addrs).to.exist()
|
expect(addrs).to.exist()
|
||||||
@ -496,7 +506,8 @@ describe('addressBook', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('with previous partial data in AddressBook (not certified)', async () => {
|
it('emits change:multiaddrs event with previous partial data in AddressBook (not certified)', async () => {
|
||||||
|
const defer = pDefer()
|
||||||
const multiaddrs = [addr1, addr2]
|
const multiaddrs = [addr1, addr2]
|
||||||
|
|
||||||
// Set addressBook data
|
// Set addressBook data
|
||||||
@ -516,10 +527,19 @@ describe('addressBook', () => {
|
|||||||
})
|
})
|
||||||
const envelope = await Envelope.seal(peerRecord, peerId)
|
const envelope = await Envelope.seal(peerRecord, peerId)
|
||||||
|
|
||||||
|
peerStore.once('change:multiaddrs', ({ peerId, multiaddrs }) => {
|
||||||
|
expect(peerId).to.exist()
|
||||||
|
expect(multiaddrs).to.eql(multiaddrs)
|
||||||
|
defer.resolve()
|
||||||
|
})
|
||||||
|
|
||||||
// consume peer record
|
// consume peer record
|
||||||
const consumed = ab.consumePeerRecord(envelope)
|
const consumed = ab.consumePeerRecord(envelope)
|
||||||
expect(consumed).to.eql(true)
|
expect(consumed).to.eql(true)
|
||||||
|
|
||||||
|
// Wait event
|
||||||
|
await defer.promise
|
||||||
|
|
||||||
// Validate data exists and certified
|
// Validate data exists and certified
|
||||||
addrs = ab.get(peerId)
|
addrs = ab.get(peerId)
|
||||||
expect(addrs).to.exist()
|
expect(addrs).to.exist()
|
||||||
@ -531,6 +551,7 @@ describe('addressBook', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('with previous different data in AddressBook (not certified)', async () => {
|
it('with previous different data in AddressBook (not certified)', async () => {
|
||||||
|
const defer = pDefer()
|
||||||
const multiaddrsUncertified = [addr3]
|
const multiaddrsUncertified = [addr3]
|
||||||
const multiaddrsCertified = [addr1, addr2]
|
const multiaddrsCertified = [addr1, addr2]
|
||||||
|
|
||||||
@ -553,10 +574,19 @@ describe('addressBook', () => {
|
|||||||
})
|
})
|
||||||
const envelope = await Envelope.seal(peerRecord, peerId)
|
const envelope = await Envelope.seal(peerRecord, peerId)
|
||||||
|
|
||||||
|
peerStore.once('change:multiaddrs', ({ peerId, multiaddrs }) => {
|
||||||
|
expect(peerId).to.exist()
|
||||||
|
expect(multiaddrs).to.eql(multiaddrs)
|
||||||
|
defer.resolve()
|
||||||
|
})
|
||||||
|
|
||||||
// consume peer record
|
// consume peer record
|
||||||
const consumed = ab.consumePeerRecord(envelope)
|
const consumed = ab.consumePeerRecord(envelope)
|
||||||
expect(consumed).to.eql(true)
|
expect(consumed).to.eql(true)
|
||||||
|
|
||||||
|
// Wait event
|
||||||
|
await defer.promise
|
||||||
|
|
||||||
// Validate data exists and certified
|
// Validate data exists and certified
|
||||||
addrs = ab.get(peerId)
|
addrs = ab.get(peerId)
|
||||||
expect(addrs).to.exist()
|
expect(addrs).to.exist()
|
||||||
@ -565,7 +595,6 @@ describe('addressBook', () => {
|
|||||||
expect(addr.isCertified).to.eql(true)
|
expect(addr.isCertified).to.eql(true)
|
||||||
expect(multiaddrsCertified[index].equals(addr.multiaddr)).to.eql(true)
|
expect(multiaddrsCertified[index].equals(addr.multiaddr)).to.eql(true)
|
||||||
})
|
})
|
||||||
// TODO: should it has the older one?
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -5,7 +5,11 @@ const chai = require('chai')
|
|||||||
chai.use(require('dirty-chai'))
|
chai.use(require('dirty-chai'))
|
||||||
const { expect } = chai
|
const { expect } = chai
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
|
|
||||||
|
const Envelope = require('../../src/record/envelope')
|
||||||
|
const PeerRecord = require('../../src/record/peer-record')
|
||||||
const PeerStore = require('../../src/peer-store/persistent')
|
const PeerStore = require('../../src/peer-store/persistent')
|
||||||
|
|
||||||
const multiaddr = require('multiaddr')
|
const multiaddr = require('multiaddr')
|
||||||
const { MemoryDatastore } = require('interface-datastore')
|
const { MemoryDatastore } = require('interface-datastore')
|
||||||
|
|
||||||
@ -99,6 +103,7 @@ describe('Persisted PeerStore', () => {
|
|||||||
expect(storedPeer.id.toB58String()).to.eql(peer.toB58String())
|
expect(storedPeer.id.toB58String()).to.eql(peer.toB58String())
|
||||||
expect(storedPeer.protocols).to.have.members(protocols)
|
expect(storedPeer.protocols).to.have.members(protocols)
|
||||||
expect(storedPeer.addresses.map((a) => a.multiaddr.toString())).to.have.members([multiaddrs[0].toString()])
|
expect(storedPeer.addresses.map((a) => a.multiaddr.toString())).to.have.members([multiaddrs[0].toString()])
|
||||||
|
expect(storedPeer.addresses.map((a) => a.isCertified)).to.have.members([false])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should load content to the peerStore when restart but not put in datastore again', async () => {
|
it('should load content to the peerStore when restart but not put in datastore again', async () => {
|
||||||
@ -211,7 +216,162 @@ describe('Persisted PeerStore', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: certified?
|
it('should store certified peer records after peer marked as dirty (threshold 1)', async () => {
|
||||||
|
const [peerId] = await peerUtils.createPeerId()
|
||||||
|
const multiaddrs = [multiaddr('/ip4/156.10.1.22/tcp/1000')]
|
||||||
|
const spyDirty = sinon.spy(peerStore, '_addDirtyPeer')
|
||||||
|
const spyDs = sinon.spy(datastore, 'batch')
|
||||||
|
const commitSpy = sinon.spy(peerStore, '_commitData')
|
||||||
|
|
||||||
|
await peerStore.start()
|
||||||
|
|
||||||
|
const peerRecord = new PeerRecord({
|
||||||
|
peerId,
|
||||||
|
multiaddrs
|
||||||
|
})
|
||||||
|
const envelope = await Envelope.seal(peerRecord, peerId)
|
||||||
|
|
||||||
|
// consume peer record
|
||||||
|
const consumed = peerStore.addressBook.consumePeerRecord(envelope)
|
||||||
|
expect(consumed).to.eql(true)
|
||||||
|
expect(spyDirty).to.have.property('callCount', 1) // Address
|
||||||
|
expect(spyDs).to.have.property('callCount', 1)
|
||||||
|
|
||||||
|
// let batch commit complete
|
||||||
|
await Promise.all(commitSpy.returnValues)
|
||||||
|
|
||||||
|
// Should have three peer records stored in the datastore
|
||||||
|
const queryParams = {
|
||||||
|
prefix: '/peers/'
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0
|
||||||
|
for await (const _ of datastore.query(queryParams)) { // eslint-disable-line
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
expect(count).to.equal(1)
|
||||||
|
|
||||||
|
// Validate data
|
||||||
|
const storedPeer = peerStore.get(peerId)
|
||||||
|
expect(storedPeer.id.toB58String()).to.eql(peerId.toB58String())
|
||||||
|
expect(storedPeer.addresses.map((a) => a.multiaddr.toString())).to.have.members([multiaddrs[0].toString()])
|
||||||
|
expect(storedPeer.addresses.map((a) => a.isCertified)).to.have.members([true])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should load certified peer records to the peerStore when restart but not put in datastore again', async () => {
|
||||||
|
const spyDs = sinon.spy(datastore, 'batch')
|
||||||
|
const peers = await peerUtils.createPeerId({ number: 2 })
|
||||||
|
const commitSpy = sinon.spy(peerStore, '_commitData')
|
||||||
|
const multiaddrs = [
|
||||||
|
multiaddr('/ip4/156.10.1.22/tcp/1000'),
|
||||||
|
multiaddr('/ip4/156.10.1.23/tcp/1000')
|
||||||
|
]
|
||||||
|
const peerRecord0 = new PeerRecord({
|
||||||
|
peerId: peers[0],
|
||||||
|
multiaddrs: [multiaddrs[0]]
|
||||||
|
})
|
||||||
|
const envelope0 = await Envelope.seal(peerRecord0, peers[0])
|
||||||
|
const peerRecord1 = new PeerRecord({
|
||||||
|
peerId: peers[1],
|
||||||
|
multiaddrs: [multiaddrs[1]]
|
||||||
|
})
|
||||||
|
const envelope1 = await Envelope.seal(peerRecord1, peers[1])
|
||||||
|
|
||||||
|
await peerStore.start()
|
||||||
|
|
||||||
|
// AddressBook
|
||||||
|
let consumed = peerStore.addressBook.consumePeerRecord(envelope0)
|
||||||
|
expect(consumed).to.eql(true)
|
||||||
|
consumed = peerStore.addressBook.consumePeerRecord(envelope1)
|
||||||
|
expect(consumed).to.eql(true)
|
||||||
|
|
||||||
|
// let batch commit complete
|
||||||
|
await Promise.all(commitSpy.returnValues)
|
||||||
|
|
||||||
|
expect(spyDs).to.have.property('callCount', 2) // 2 Address + 2 Key + 2 Proto + 1 Metadata
|
||||||
|
expect(peerStore.peers.size).to.equal(2)
|
||||||
|
|
||||||
|
await peerStore.stop()
|
||||||
|
peerStore.addressBook.data.clear()
|
||||||
|
|
||||||
|
// Load on restart
|
||||||
|
const spy = sinon.spy(peerStore, '_processDatastoreEntry')
|
||||||
|
|
||||||
|
await peerStore.start()
|
||||||
|
|
||||||
|
expect(spy).to.have.property('callCount', 2)
|
||||||
|
expect(spyDs).to.have.property('callCount', 2)
|
||||||
|
|
||||||
|
expect(peerStore.peers.size).to.equal(2)
|
||||||
|
expect(peerStore.addressBook.data.size).to.equal(2)
|
||||||
|
|
||||||
|
expect(peerStore.addressBook.getRawEnvelope(peers[0])).to.exist()
|
||||||
|
expect(peerStore.addressBook.getRawEnvelope(peers[1])).to.exist()
|
||||||
|
|
||||||
|
// Validate stored envelopes
|
||||||
|
const storedEnvelope0 = await peerStore.addressBook.getPeerRecord(peers[0])
|
||||||
|
expect(envelope0.isEqual(storedEnvelope0)).to.eql(true)
|
||||||
|
|
||||||
|
const storedEnvelope1 = await peerStore.addressBook.getPeerRecord(peers[1])
|
||||||
|
expect(envelope1.isEqual(storedEnvelope1)).to.eql(true)
|
||||||
|
|
||||||
|
// Validate multiaddrs
|
||||||
|
const storedPeer0 = peerStore.get(peers[0])
|
||||||
|
expect(storedPeer0.id.toB58String()).to.eql(peers[0].toB58String())
|
||||||
|
expect(storedPeer0.addresses.map((a) => a.multiaddr.toString())).to.have.members([multiaddrs[0].toString()])
|
||||||
|
|
||||||
|
const storedPeer1 = peerStore.get(peers[1])
|
||||||
|
expect(storedPeer1.id.toB58String()).to.eql(peers[1].toB58String())
|
||||||
|
expect(storedPeer1.addresses.map((a) => a.multiaddr.toString())).to.have.members([multiaddrs[1].toString()])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should delete certified peer records from the datastore on delete', async () => {
|
||||||
|
const [peer] = await peerUtils.createPeerId()
|
||||||
|
const multiaddrs = [multiaddr('/ip4/156.10.1.22/tcp/1000')]
|
||||||
|
const commitSpy = sinon.spy(peerStore, '_commitData')
|
||||||
|
|
||||||
|
await peerStore.start()
|
||||||
|
|
||||||
|
// AddressBook
|
||||||
|
const peerRecord = new PeerRecord({
|
||||||
|
peerId: peer,
|
||||||
|
multiaddrs
|
||||||
|
})
|
||||||
|
const envelope = await Envelope.seal(peerRecord, peer)
|
||||||
|
|
||||||
|
// consume peer record
|
||||||
|
const consumed = peerStore.addressBook.consumePeerRecord(envelope)
|
||||||
|
expect(consumed).to.eql(true)
|
||||||
|
|
||||||
|
// let batch commit complete
|
||||||
|
await Promise.all(commitSpy.returnValues)
|
||||||
|
expect(peerStore.addressBook.getRawEnvelope(peer)).to.exist()
|
||||||
|
|
||||||
|
const spyDs = sinon.spy(datastore, 'batch')
|
||||||
|
const spyAddressBook = sinon.spy(peerStore.addressBook, 'delete')
|
||||||
|
|
||||||
|
// Delete from PeerStore
|
||||||
|
peerStore.delete(peer)
|
||||||
|
|
||||||
|
// let batch commit complete
|
||||||
|
await Promise.all(commitSpy.returnValues)
|
||||||
|
|
||||||
|
await peerStore.stop()
|
||||||
|
|
||||||
|
expect(spyAddressBook).to.have.property('callCount', 1)
|
||||||
|
expect(spyDs).to.have.property('callCount', 1)
|
||||||
|
|
||||||
|
// Should have zero peer records stored in the datastore
|
||||||
|
const queryParams = {
|
||||||
|
prefix: '/peers/'
|
||||||
|
}
|
||||||
|
|
||||||
|
for await (const _ of datastore.query(queryParams)) { // eslint-disable-line
|
||||||
|
throw new Error('Datastore should be empty')
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(peerStore.addressBook.getRawEnvelope(peer)).to.not.exist()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('setup with content not stored per change (threshold 2)', () => {
|
describe('setup with content not stored per change (threshold 2)', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user