mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-04-25 10:32:14 +00:00
chore: persist delete with test
This commit is contained in:
parent
5123a8357b
commit
9ea9287bea
@ -113,9 +113,9 @@ All the knownw peer protocols are stored with a key pattern as follows:
|
|||||||
|
|
||||||
_NOT_YET_IMPLEMENTED_
|
_NOT_YET_IMPLEMENTED_
|
||||||
|
|
||||||
All public and private keys are stored under the following pattern:
|
All public keys are stored under the following pattern:
|
||||||
|
|
||||||
` /peers/keys/<b32 peer id no padding>/{pub, priv}`
|
` /peers/keys/<b32 peer id no padding>`
|
||||||
|
|
||||||
**MetadataBook**
|
**MetadataBook**
|
||||||
|
|
||||||
|
@ -40,17 +40,24 @@ class AddressBook extends Book {
|
|||||||
*/
|
*/
|
||||||
super({
|
super({
|
||||||
peerStore,
|
peerStore,
|
||||||
eventName: 'change:multiaddrs',
|
event: {
|
||||||
eventProperty: 'multiaddrs',
|
name: 'change:multiaddrs',
|
||||||
protoBuf: Protobuf,
|
property: 'multiaddrs',
|
||||||
dsPrefix: '/peers/addrs/',
|
transformer: (data) => data.map((address) => address.multiaddr)
|
||||||
eventTransformer: (data) => data.map((address) => address.multiaddr),
|
},
|
||||||
dsSetTransformer: (data) => ({
|
ds: {
|
||||||
addrs: data.map((address) => address.multiaddr.buffer)
|
prefix: '/peers/addrs/',
|
||||||
}),
|
setTransformer: (data) => Protobuf.encode({
|
||||||
dsGetTransformer: (data) => data.addrs.map((a) => ({
|
addrs: data.map((address) => address.multiaddr.buffer)
|
||||||
multiaddr: multiaddr(a)
|
}),
|
||||||
}))
|
getTransformer: (encData) => {
|
||||||
|
const data = Protobuf.decode(encData)
|
||||||
|
|
||||||
|
return data.addrs.map((a) => ({
|
||||||
|
multiaddr: multiaddr(a)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,35 +23,24 @@ class Book {
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @param {Object} properties
|
* @param {Object} properties
|
||||||
* @param {PeerStore} properties.peerStore PeerStore instance.
|
* @param {PeerStore} properties.peerStore PeerStore instance.
|
||||||
* @param {string} properties.eventName Name of the event to emit by the PeerStore.
|
* @param {Object} [properties.event] Event properties. If not provided, no events will be emitted.
|
||||||
* @param {string} properties.eventProperty Name of the property to emit by the PeerStore.
|
* @param {string} [properties.event.name] Name of the event to emit by the PeerStore.
|
||||||
* @param {Object} properties.protoBuf Suffix of the Datastore Key
|
* @param {string} [properties.event.property] Name of the property to emit by the PeerStore.
|
||||||
* @param {String} properties.dsPrefix Prefix of the Datastore Key
|
* @param {function} [properties.events.transformer] Transformer function of the provided data for being emitted.
|
||||||
* @param {String} [properties.dsSuffix] Suffix of the Datastore Key
|
* @param {Object} [properties.ds] Datastore properties. If not provided, no data will be persisted.
|
||||||
* @param {function} [properties.eventTransformer] Transformer function of the provided data for being emitted.
|
* @param {String} [properties.ds.prefix] Prefix of the Datastore Key
|
||||||
* @param {function} [properties.dsSetTransformer] Transformer function of the provided data for being persisted.
|
* @param {String} [properties.ds.suffix = ''] Suffix of the Datastore Key
|
||||||
* @param {function} [properties.dsGetTransformer] Transformer function of the persisted data to be loaded.
|
* @param {function} [properties.ds.setTransformer] Transformer function of the provided data for being persisted.
|
||||||
|
* @param {function} [properties.ds.getTransformer] Transformer function of the persisted data to be loaded.
|
||||||
*/
|
*/
|
||||||
constructor ({
|
constructor ({
|
||||||
peerStore,
|
peerStore,
|
||||||
eventName,
|
event,
|
||||||
eventProperty,
|
ds
|
||||||
protoBuf,
|
|
||||||
dsPrefix,
|
|
||||||
dsSuffix = '',
|
|
||||||
eventTransformer = passthrough,
|
|
||||||
dsSetTransformer = passthrough,
|
|
||||||
dsGetTransformer = passthrough
|
|
||||||
}) {
|
}) {
|
||||||
this._ps = peerStore
|
this._ps = peerStore
|
||||||
this.eventName = eventName
|
this.event = event
|
||||||
this.eventProperty = eventProperty
|
this.ds = ds
|
||||||
this.protoBuf = protoBuf
|
|
||||||
this.dsPrefix = dsPrefix
|
|
||||||
this.dsSuffix = dsSuffix
|
|
||||||
this.eventTransformer = eventTransformer
|
|
||||||
this.dsSetTransformer = dsSetTransformer
|
|
||||||
this.dsGetTransformer = dsGetTransformer
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map known peers to their data.
|
* Map known peers to their data.
|
||||||
@ -67,23 +56,23 @@ class Book {
|
|||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async _loadData () {
|
async _loadData () {
|
||||||
if (!this._ps._datastore || !this._ps._enabledPersistance) {
|
if (!this._ps._datastore || !this._ps._enabledPersistance || !this.ds) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const persistenceQuery = {
|
const prefix = this.ds.prefix || ''
|
||||||
prefix: this.dsPrefix
|
const suffix = this.ds.suffix || ''
|
||||||
}
|
const transformer = this.ds.getTransformer || passthrough
|
||||||
|
|
||||||
for await (const { key, value } of this._ps._datastore.query(persistenceQuery)) {
|
for await (const { key, value } of this._ps._datastore.query({ prefix })) {
|
||||||
try {
|
try {
|
||||||
// PeerId to add to the book
|
// PeerId to add to the book
|
||||||
const b32key = key.toString()
|
const b32key = key.toString()
|
||||||
.replace(this.dsPrefix, '') // remove prefix from key
|
.replace(prefix, '') // remove prefix from key
|
||||||
.replace(this.dsSuffix, '') // remove suffix from key
|
.replace(suffix, '') // remove suffix from key
|
||||||
const peerId = PeerId.createFromCID(b32key)
|
const peerId = PeerId.createFromCID(b32key)
|
||||||
// Data in the format to add to the book
|
// Data in the format to add to the book
|
||||||
const data = this.dsGetTransformer(this.protoBuf.decode(value))
|
const data = transformer(value)
|
||||||
// Add the book without persist the replicated data and emit modify
|
// Add the book without persist the replicated data and emit modify
|
||||||
this._setData(peerId, data, {
|
this._setData(peerId, data, {
|
||||||
persist: false,
|
persist: false,
|
||||||
@ -113,10 +102,14 @@ class Book {
|
|||||||
this._setPeerId(peerId)
|
this._setPeerId(peerId)
|
||||||
|
|
||||||
// Emit event
|
// Emit event
|
||||||
emit && this._ps.emit(this.eventName, {
|
if (this.event && emit) {
|
||||||
peerId,
|
const transformer = this.event.transformer || passthrough
|
||||||
[this.eventProperty]: this.eventTransformer(data)
|
|
||||||
})
|
this._ps.emit(this.event.name, {
|
||||||
|
peerId,
|
||||||
|
[this.event.property]: transformer(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Add to Persistence datastore
|
// Add to Persistence datastore
|
||||||
persist && await this._persistData(peerId, data)
|
persist && await this._persistData(peerId, data)
|
||||||
@ -130,14 +123,18 @@ class Book {
|
|||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async _persistData (peerId, data) {
|
async _persistData (peerId, data) {
|
||||||
if (!this._ps._datastore || !this._ps._enabledPersistance) {
|
if (!this._ps._datastore || !this._ps._enabledPersistance || !this.ds) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const prefix = this.ds.prefix || ''
|
||||||
|
const suffix = this.ds.suffix || ''
|
||||||
|
const transformer = this.ds.setTransformer || passthrough
|
||||||
|
|
||||||
const b32key = peerId.toString()
|
const b32key = peerId.toString()
|
||||||
const k = `${this.dsPrefix}${b32key}${this.dsSuffix}`
|
const k = `${prefix}${b32key}${suffix}`
|
||||||
try {
|
try {
|
||||||
const value = this.protoBuf.encode(this.dsSetTransformer(data))
|
const value = transformer(data)
|
||||||
|
|
||||||
await this._ps._datastore.put(new Key(k), value)
|
await this._ps._datastore.put(new Key(k), value)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -192,13 +189,21 @@ class Book {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
this._ps.emit(this.eventName, {
|
// Emit event
|
||||||
|
this.event && this._ps.emit(this.event.name, {
|
||||||
peerId,
|
peerId,
|
||||||
[this.eventProperty]: []
|
[this.event.property]: []
|
||||||
})
|
})
|
||||||
|
|
||||||
// Update Persistence datastore
|
// Update Persistence datastore
|
||||||
this._persistData(peerId, [])
|
if (this._ps._datastore && this._ps._enabledPersistance && this.ds) {
|
||||||
|
const prefix = this.ds.prefix || ''
|
||||||
|
const suffix = this.ds.suffix || ''
|
||||||
|
const b32key = peerId.toString()
|
||||||
|
|
||||||
|
const k = `${prefix}${b32key}${suffix}`
|
||||||
|
this._ps._datastore.delete(new Key(k))
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,22 @@ class ProtoBook extends Book {
|
|||||||
*/
|
*/
|
||||||
super({
|
super({
|
||||||
peerStore,
|
peerStore,
|
||||||
eventName: 'change:protocols',
|
event: {
|
||||||
eventProperty: 'protocols',
|
name: 'change:protocols',
|
||||||
protoBuf: Protobuf,
|
property: 'protocols',
|
||||||
dsPrefix: '/peers/protos/',
|
transformer: (data) => Array.from(data)
|
||||||
eventTransformer: (data) => Array.from(data),
|
},
|
||||||
dsSetTransformer: (data) => ({
|
ds: {
|
||||||
protocols: Array.from(data)
|
prefix: '/peers/protos/',
|
||||||
}),
|
setTransformer: (data) => Protobuf.encode({
|
||||||
dsGetTransformer: (data) => new Set(data.protocols)
|
protocols: Array.from(data)
|
||||||
|
}),
|
||||||
|
getTransformer: (encData) => {
|
||||||
|
const data = Protobuf.decode(encData)
|
||||||
|
|
||||||
|
return new Set(data.protocols)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -305,4 +305,39 @@ describe('libp2p.peerStore', () => {
|
|||||||
|
|
||||||
await newNode.stop()
|
await newNode.stop()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should delete content from the datastore on delete', async () => {
|
||||||
|
const [peer] = await peerUtils.createPeerId({ number: 2 })
|
||||||
|
const multiaddrs = [multiaddr('/ip4/156.10.1.22/tcp/1000')]
|
||||||
|
const protocols = ['/ping/1.0.0']
|
||||||
|
const spyDs = sinon.spy(memoryDatastore, 'delete')
|
||||||
|
const spyAddressBook = sinon.spy(libp2p.peerStore.addressBook, 'delete')
|
||||||
|
const spyProtoBook = sinon.spy(libp2p.peerStore.protoBook, 'delete')
|
||||||
|
|
||||||
|
await libp2p.start()
|
||||||
|
|
||||||
|
// AddressBook
|
||||||
|
await libp2p.peerStore.addressBook.set(peer, multiaddrs)
|
||||||
|
// ProtoBook
|
||||||
|
await libp2p.peerStore.protoBook.set(peer, protocols)
|
||||||
|
|
||||||
|
expect(spyDs).to.have.property('callCount', 0)
|
||||||
|
|
||||||
|
// Delete from PeerStore
|
||||||
|
libp2p.peerStore.delete(peer)
|
||||||
|
await libp2p.stop()
|
||||||
|
|
||||||
|
expect(spyAddressBook).to.have.property('callCount', 1)
|
||||||
|
expect(spyProtoBook).to.have.property('callCount', 1)
|
||||||
|
expect(spyDs).to.have.property('callCount', 2)
|
||||||
|
|
||||||
|
// Should have zero peer records stored in the datastore
|
||||||
|
const queryParams = {
|
||||||
|
prefix: '/peers/'
|
||||||
|
}
|
||||||
|
|
||||||
|
for await (const _ of memoryDatastore.query(queryParams)) { // eslint-disable-line
|
||||||
|
throw new Error('Datastore should be empty')
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user