Skip to content

Commit 5b1afc3

Browse files
committed
feat: support all type of records
BREAKING CHANGE: validators have to deserialize the data (if using libp2p-record)
1 parent bf1787c commit 5b1afc3

File tree

3 files changed

+52
-21
lines changed

3 files changed

+52
-21
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@
3434
"dependencies": {
3535
"assert": "^1.4.1",
3636
"base32.js": "~0.1.0",
37-
"debug": "^3.1.0",
37+
"debug": "^4.1.0",
3838
"err-code": "^1.1.2",
39-
"interface-datastore": "~0.4.2",
40-
"libp2p-record": "~0.6.0"
39+
"interface-datastore": "~0.6.0"
4140
},
4241
"devDependencies": {
4342
"aegir": "^17.1.0",
@@ -46,7 +45,8 @@
4645
"dirty-chai": "^2.0.1",
4746
"ipfs": "~0.33.1",
4847
"ipfsd-ctl": "~0.40.0",
49-
"sinon": "^7.0.0"
48+
"libp2p-record": "~0.6.1",
49+
"sinon": "^7.1.1"
5050
},
5151
"contributors": [
5252
"Vasco Santos <[email protected]>",

src/index.js

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use strict'
22

3-
const { Record } = require('libp2p-record')
43
const { Key } = require('interface-datastore')
54
const { encodeBase32 } = require('./utils')
65

@@ -21,7 +20,7 @@ class DatastorePubsub {
2120
* @param {Object} validator - validator functions.
2221
* @param {function(record, peerId, callback)} validator.validate - function to validate a record.
2322
* @param {function(received, current, callback)} validator.select - function to select the newest between two records.
24-
* @param {function(key, callback)} subscriptionKeyFn - function to manipulate the key topic received before processing it.
23+
* @param {function(key, callback)} subscriptionKeyFn - optional function to manipulate the key topic received before processing it.
2524
* @memberof DatastorePubsub
2625
*/
2726
constructor (pubsub, datastore, peerId, validator, subscriptionKeyFn) {
@@ -208,17 +207,8 @@ class DatastorePubsub {
208207

209208
// Verify if the record received through pubsub is valid and better than the one currently stored
210209
_isBetter (key, val, callback) {
211-
let receivedRecord
212-
213-
try {
214-
receivedRecord = Record.deserialize(val)
215-
} catch (err) {
216-
log.error(err)
217-
return callback(err)
218-
}
219-
220210
// validate received record
221-
this._validateRecord(receivedRecord.value, key, (err, valid) => {
211+
this._validateRecord(val, key, (err, valid) => {
222212
// If not valid, it is not better than the one currently available
223213
if (err || !valid) {
224214
const errMsg = 'record received through pubsub is not valid'
@@ -230,21 +220,19 @@ class DatastorePubsub {
230220
// Get Local record
231221
const dsKey = new Key(key)
232222

233-
this._getLocal(dsKey.toBuffer(), (err, res) => {
223+
this._getLocal(dsKey.toBuffer(), (err, currentRecord) => {
234224
// if the old one is invalid, the new one is *always* better
235225
if (err) {
236226
return callback(null, true)
237227
}
238228

239229
// if the same record, do not need to store
240-
if (res.equals(val)) {
230+
if (currentRecord.equals(val)) {
241231
return callback(null, false)
242232
}
243233

244-
const currentRecord = Record.deserialize(res)
245-
246234
// verify if the received record should replace the current one
247-
this._selectRecord(receivedRecord.value, currentRecord.value, callback)
235+
this._selectRecord(val, currentRecord, callback)
248236
})
249237
})
250238
}

test/index.spec.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,49 @@ describe('datastore-pubsub', function () {
155155
})
156156
})
157157

158+
it('should validate if record content is the same', function (done) {
159+
const customValidator = {
160+
validate: (data, peerId, callback) => {
161+
const receivedRecord = Record.deserialize(data)
162+
163+
expect(receivedRecord.value.toString()).to.equal(value) // validator should deserialize correctly
164+
callback(null, receivedRecord.value.toString() === value)
165+
},
166+
select: (receivedRecod, currentRecord, callback) => {
167+
callback(null, 0)
168+
}
169+
}
170+
const dsPubsubA = new DatastorePubsub(pubsubA, datastoreA, peerIdA, smoothValidator)
171+
const dsPubsubB = new DatastorePubsub(pubsubB, datastoreB, peerIdB, customValidator)
172+
const topic = `/${keyRef}`
173+
let receivedMessage = false
174+
175+
function messageHandler () {
176+
receivedMessage = true
177+
}
178+
179+
dsPubsubB.get(key, (err, res) => {
180+
expect(err).to.exist()
181+
expect(res).to.not.exist() // not value available, but subscribed now
182+
183+
series([
184+
(cb) => waitForPeerToSubscribe(topic, ipfsdBId, ipfsdA, cb),
185+
// subscribe in order to understand when the message arrive to the node
186+
(cb) => pubsubB.subscribe(topic, messageHandler, cb),
187+
(cb) => dsPubsubA.put(key, serializedRecord, cb),
188+
// wait until message arrives
189+
(cb) => waitFor(() => receivedMessage === true, cb),
190+
// get from datastore
191+
(cb) => dsPubsubB.get(key, cb)
192+
], (err, res) => {
193+
// No record received, in spite of message received
194+
expect(err).to.not.exist() // message was discarded as a result of failing the validation
195+
expect(res[4]).to.exist()
196+
done()
197+
})
198+
})
199+
})
200+
158201
it('should put correctly to daemon A and daemon B should receive it as it tried to get it first and subscribed it', function (done) {
159202
const dsPubsubA = new DatastorePubsub(pubsubA, datastoreA, peerIdA, smoothValidator)
160203
const dsPubsubB = new DatastorePubsub(pubsubB, datastoreB, peerIdB, smoothValidator)

0 commit comments

Comments
 (0)