Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit fa1d79c

Browse files
committed
refactor: fix review
1 parent 87d6e9a commit fa1d79c

File tree

12 files changed

+448
-166
lines changed

12 files changed

+448
-166
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@
7474
"ncp": "^2.0.0",
7575
"qs": "^6.5.2",
7676
"rimraf": "^2.6.2",
77+
"sinon": "^7.1.1",
7778
"stream-to-promise": "^2.2.0"
7879
},
7980
"dependencies": {
8081
"@nodeutils/defaults-deep": "^1.1.0",
8182
"async": "^2.6.1",
82-
"base32.js": "~0.1.0",
8383
"big.js": "^5.2.2",
8484
"binary-querystring": "~0.1.2",
8585
"bl": "^2.1.2",

src/core/components/init.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ module.exports = function init (self) {
113113
(_, cb) => {
114114
const offlineDatastore = new OfflineDatastore(self._repo)
115115

116-
self._ipns = new IPNS(offlineDatastore, self)
116+
self._ipns = new IPNS(offlineDatastore, self._repo, self._peerInfo, self._keychain, self._options)
117117
cb(null, true)
118118
},
119119
// add empty unixfs dir object (go-ipfs assumes this exists)

src/core/components/pre-start.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ const waterfall = require('async/waterfall')
77
const Keychain = require('libp2p-keychain')
88
const defaultsDeep = require('@nodeutils/defaults-deep')
99
const NoKeychain = require('./no-keychain')
10-
11-
const IPNS = require('../ipns')
12-
const OfflineDatastore = require('../ipns/routing/offline-datastore')
13-
1410
/*
1511
* Load stuff from Repo into memory
1612
*/
@@ -99,13 +95,6 @@ module.exports = function preStart (self) {
9995

10096
cb()
10197
},
102-
// Setup offline routing for IPNS.
103-
(cb) => {
104-
const offlineDatastore = new OfflineDatastore(self._repo)
105-
106-
self._ipns = new IPNS(offlineDatastore, self)
107-
cb()
108-
},
10998
(cb) => self.pin._load(cb)
11099
], callback)
111100
}

src/core/components/start.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ module.exports = (self) => {
4343

4444
// TODO Add IPNS pubsub if enabled
4545

46-
// NOTE: Until the IPNS over DHT is not ready, it is being replaced by the local repo datastore
47-
// When DHT is added, If local option enabled, should receive offlineDatastore as well
46+
// NOTE: IPNS routing is being replaced by the local repo datastore while the IPNS over DHT is not ready
47+
// When DHT is added, if local option enabled, should receive offlineDatastore as well
4848
const offlineDatastore = new OfflineDatastore(self._repo)
4949
ipnsStores.push(offlineDatastore)
5050

5151
// Create ipns routing with a set of datastores
5252
const routing = new TieredDatastore(ipnsStores)
53-
self._ipns = new IPNS(routing, self)
53+
self._ipns = new IPNS(routing, self._repo, self._peerInfo, self._keychain, self._options)
5454

5555
self._bitswap = new Bitswap(
5656
self._libp2pNode,

src/core/ipns/index.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const { createFromPrivKey } = require('peer-id')
44
const series = require('async/series')
55
const Receptacle = require('receptacle')
66

7+
const errcode = require('err-code')
78
const debug = require('debug')
89
const log = debug('jsipfs:ipns')
910
log.error = debug('jsipfs:ipns:error')
@@ -16,9 +17,9 @@ const path = require('./path')
1617
const defaultRecordTtl = 60 * 1000
1718

1819
class IPNS {
19-
constructor (routing, ipfs) {
20-
this.publisher = new IpnsPublisher(routing, ipfs._repo)
21-
this.republisher = new IpnsRepublisher(this.publisher, ipfs)
20+
constructor (routing, repo, peerInfo, keychain, options) {
21+
this.publisher = new IpnsPublisher(routing, repo)
22+
this.republisher = new IpnsRepublisher(this.publisher, repo, peerInfo, keychain, options)
2223
this.resolver = new IpnsResolver(routing)
2324
this.cache = new Receptacle({ max: 1000 }) // Create an LRU cache with max 1000 items
2425
this.routing = routing
@@ -55,11 +56,20 @@ class IPNS {
5556

5657
// Resolve
5758
resolve (name, options, callback) {
59+
if (typeof name !== 'string') {
60+
const errMsg = `name received is not valid`
61+
62+
log.error(errMsg)
63+
return callback(errcode(new Error(errMsg), 'ERR_INVALID_NAME'))
64+
}
65+
5866
if (typeof options === 'function') {
5967
callback = options
6068
options = {}
6169
}
6270

71+
options = options || {}
72+
6373
// If recursive, we should not try to get the cached value
6474
if (!options.nocache && !options.recursive) {
6575
// Try to get the record from cache

src/core/ipns/publisher.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class IpnsPublisher {
3232

3333
PeerId.createFromPrivKey(privKey.bytes, (err, peerId) => {
3434
if (err) {
35-
callback(err)
35+
return callback(err)
3636
}
3737

3838
this._updateOrCreateRecord(privKey, value, lifetime, peerId, (err, record) => {

src/core/ipns/republisher.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ const defaultBroadcastInterval = 4 * hour
1818
const defaultRecordLifetime = 24 * hour
1919

2020
class IpnsRepublisher {
21-
constructor (publisher, ipfs) {
21+
constructor (publisher, repo, peerInfo, keychain, options) {
2222
this._publisher = publisher
23-
this._ipfs = ipfs
24-
this._repo = ipfs._repo
23+
this._repo = repo
24+
this._peerInfo = peerInfo
25+
this._keychain = keychain
26+
this._options = options
2527
this._republishHandle = null
2628
}
2729

@@ -62,8 +64,8 @@ class IpnsRepublisher {
6264
}
6365
}
6466

65-
const { privKey } = this._ipfs._peerInfo.id
66-
const { pass } = this._ipfs._options
67+
const { privKey } = this._peerInfo.id
68+
const { pass } = this._options
6769

6870
republishHandle.runPeriodically((done) => {
6971
this._republishEntries(privKey, pass, () => done(defaultBroadcastInterval))
@@ -98,16 +100,16 @@ class IpnsRepublisher {
98100
}
99101

100102
// keychain needs pass to get the cryptographic keys
101-
if (this._ipfs._keychain && Boolean(pass)) {
102-
this._ipfs._keychain.listKeys((err, list) => {
103+
if (this._keychain && Boolean(pass)) {
104+
this._keychain.listKeys((err, list) => {
103105
if (err) {
104106
log.error(err)
105107
return
106108
}
107109

108110
each(list, (key, cb) => {
109111
waterfall([
110-
(cb) => this._ipfs._keychain.exportKey(key.name, pass, cb),
112+
(cb) => this._keychain.exportKey(key.name, pass, cb),
111113
(pem, cb) => crypto.keys.import(pem, pass, cb)
112114
], (err, privKey) => {
113115
if (err) {

src/core/ipns/resolver.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,33 @@ class IpnsResolver {
8989

9090
// resolve ipns entries from the provided routing
9191
_resolveName (name, callback) {
92-
const peerId = PeerId.createFromB58String(name)
92+
let peerId
93+
94+
try {
95+
peerId = PeerId.createFromB58String(name)
96+
} catch (err) {
97+
return callback(err)
98+
}
99+
93100
const { routingKey } = ipns.getIdKeys(peerId.toBytes())
94101

95102
// TODO DHT - get public key from routing?
96103
// https://github.com/ipfs/go-ipfs/blob/master/namesys/routing.go#L70
97104
// https://github.com/libp2p/go-libp2p-routing/blob/master/routing.go#L99
98105

99106
this._routing.get(routingKey.toBuffer(), (err, res) => {
100-
if (err || !res) {
107+
if (err) {
101108
const errMsg = `record requested was not found for ${name} (${routingKey}) in the network`
102109

103110
log.error(errMsg)
104-
return callback(errcode(new Error(errMsg), 'ERR_NO_NETWORK_RECORD_FOUND'))
111+
return callback(errcode(new Error(errMsg), 'ERR_NO_RECORD_FOUND'))
112+
}
113+
114+
if (!res) {
115+
const errMsg = `record requested was empty for ${name} (${routingKey}) in the network`
116+
117+
log.error(errMsg)
118+
return callback(errcode(new Error(errMsg), 'ERR_EMPTY_RECORD_FOUND'))
105119
}
106120

107121
if (!Buffer.isBuffer(res)) {
@@ -111,8 +125,15 @@ class IpnsResolver {
111125
return callback(errcode(new Error(errMsg), 'ERR_INVALID_RECORD_RECEIVED'))
112126
}
113127

114-
const record = Record.deserialize(res)
115-
const ipnsEntry = ipns.unmarshal(record.value)
128+
let ipnsEntry
129+
130+
try {
131+
const record = Record.deserialize(res)
132+
ipnsEntry = ipns.unmarshal(record.value)
133+
} catch (err) {
134+
log.error(err)
135+
return callback(err)
136+
}
116137

117138
ipns.extractPublicKey(peerId, ipnsEntry, (err, pubKey) => {
118139
if (err) {

src/core/ipns/routing/offline-datastore.js

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
const { Key } = require('interface-datastore')
44
const { encodeBase32 } = require('./utils')
55

6+
const errcode = require('err-code')
7+
const debug = require('debug')
8+
const log = debug('jsipfs:ipns:offline-datastore')
9+
log.error = debug('jsipfs:ipns:offline-datastore:error')
10+
611
// Offline datastore aims to mimic the same encoding as routing when storing records
712
// to the local datastore
813
class OfflineDatastore {
@@ -18,8 +23,30 @@ class OfflineDatastore {
1823
* @returns {void}
1924
*/
2025
put (key, value, callback) {
21-
// encode key properly - base32(/ipns/{cid})
22-
const routingKey = new Key('/' + encodeBase32(key), false)
26+
if (!Buffer.isBuffer(key)) {
27+
const errMsg = `Offline datastore key must be a buffer`
28+
29+
log.error(errMsg)
30+
return callback(errcode(new Error(errMsg), 'ERR_INVALID_KEY'))
31+
}
32+
33+
if (!Buffer.isBuffer(value)) {
34+
const errMsg = `Offline datastore value must be a buffer`
35+
36+
log.error(errMsg)
37+
return callback(errcode(new Error(errMsg), 'ERR_INVALID_VALUE'))
38+
}
39+
40+
let routingKey
41+
42+
try {
43+
routingKey = this._routingKey(key)
44+
} catch (err) {
45+
const errMsg = `Not possible to generate the routing key`
46+
47+
log.error(errMsg)
48+
return callback(errcode(new Error(errMsg), 'ERR_GENERATING_ROUTING_KEY'))
49+
}
2350

2451
this._repo.datastore.put(routingKey, value, callback)
2552
}
@@ -31,11 +58,31 @@ class OfflineDatastore {
3158
* @returns {void}
3259
*/
3360
get (key, callback) {
34-
// encode key properly - base32(/ipns/{cid})
35-
const routingKey = new Key('/' + encodeBase32(key), false)
61+
if (!Buffer.isBuffer(key)) {
62+
const errMsg = `Offline datastore key must be a buffer`
63+
64+
log.error(errMsg)
65+
return callback(errcode(new Error(errMsg), 'ERR_INVALID_KEY'))
66+
}
67+
68+
let routingKey
69+
70+
try {
71+
routingKey = this._routingKey(key)
72+
} catch (err) {
73+
const errMsg = `Not possible to generate the routing key`
74+
75+
log.error(errMsg)
76+
return callback(errcode(new Error(errMsg), 'ERR_GENERATING_ROUTING_KEY'))
77+
}
3678

3779
this._repo.datastore.get(routingKey, callback)
3880
}
81+
82+
// encode key properly - base32(/ipns/{cid})
83+
_routingKey (key) {
84+
return new Key('/' + encodeBase32(key), false)
85+
}
3986
}
4087

4188
exports = module.exports = OfflineDatastore

src/core/ipns/routing/utils.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
'use strict'
22

3-
const base32 = require('base32.js')
3+
const multibase = require('multibase')
44

55
module.exports.encodeBase32 = (buf) => {
6-
const enc = new base32.Encoder()
7-
return enc.write(buf).finalize()
6+
return multibase.encode('base32', buf)
87
}

0 commit comments

Comments
 (0)