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

Commit 73d3686

Browse files
committed
chore: ipns routing logic moved to instantiation
1 parent 06262b5 commit 73d3686

File tree

13 files changed

+136
-60
lines changed

13 files changed

+136
-60
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"dependencies": {
7979
"@nodeutils/defaults-deep": "^1.1.0",
8080
"async": "^2.6.1",
81+
"base32.js": "~0.1.0",
8182
"big.js": "^5.2.2",
8283
"binary-querystring": "~0.1.2",
8384
"bl": "^2.1.2",
@@ -86,6 +87,7 @@
8687
"byteman": "^1.3.5",
8788
"cid-tool": "~0.1.0",
8889
"cids": "~0.5.5",
90+
"datastore-core": "~0.6.0",
8991
"debug": "^4.1.0",
9092
"err-code": "^1.1.2",
9193
"file-type": "^10.2.0",

src/core/components/init.js

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ const defaultsDeep = require('@nodeutils/defaults-deep')
88
const defaultConfig = require('../runtime/config-nodejs.js')
99
const Keychain = require('libp2p-keychain')
1010

11+
const IPNS = require('../ipns')
12+
const OfflineDatastore = require('../ipns/routing/offline-datastore')
13+
1114
const addDefaultAssets = require('./init-assets')
1215

1316
module.exports = function init (self) {
@@ -105,6 +108,13 @@ module.exports = function init (self) {
105108
cb(null, true)
106109
}
107110
},
111+
// Setup offline routing for IPNS. This is primarily used for offline ipns modifications, such as the initializeKeyspace feature.
112+
(_, cb) => {
113+
const offlineDatastore = new OfflineDatastore(self._repo)
114+
115+
self._ipns = new IPNS(offlineDatastore, self)
116+
cb(null, true)
117+
},
108118
// add empty unixfs dir object (go-ipfs assumes this exists)
109119
(_, cb) => {
110120
if (opts.emptyRepo) {

src/core/components/name.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ module.exports = function name (self) {
128128
const nocache = options.nocache && options.nocache.toString() === 'true'
129129
const recursive = options.recursive && options.recursive.toString() === 'true'
130130

131-
const local = true // TODO ROUTING - use self._options.local
131+
const local = self._options.local
132132

133133
if (!self.isOnline() && !local) {
134134
const errMsg = utils.OFFLINE_ERROR
@@ -157,11 +157,10 @@ module.exports = function name (self) {
157157

158158
const resolveOptions = {
159159
nocache,
160-
recursive,
161-
local
160+
recursive
162161
}
163162

164-
self._ipns.resolve(name, self._peerInfo.id, resolveOptions, callback)
163+
self._ipns.resolve(name, resolveOptions, callback)
165164
})
166165
}
167166
}

src/core/components/pre-start.js

+11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ const waterfall = require('async/waterfall')
77
const Keychain = require('libp2p-keychain')
88
const extend = require('deep-extend')
99
const NoKeychain = require('./no-keychain')
10+
11+
const IPNS = require('../ipns')
12+
const OfflineDatastore = require('../ipns/routing/offline-datastore')
13+
1014
/*
1115
* Load stuff from Repo into memory
1216
*/
@@ -95,6 +99,13 @@ module.exports = function preStart (self) {
9599

96100
cb()
97101
},
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+
},
98109
(cb) => self.pin._load(cb)
99110
], callback)
100111
}

src/core/components/start.js

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ const series = require('async/series')
44
const Bitswap = require('ipfs-bitswap')
55
const setImmediate = require('async/setImmediate')
66
const promisify = require('promisify-es6')
7+
const { TieredDatastore } = require('datastore-core')
8+
9+
const IPNS = require('../ipns')
10+
const OfflineDatastore = require('../ipns/routing/offline-datastore')
711

812
module.exports = (self) => {
913
return promisify((callback) => {
@@ -34,6 +38,20 @@ module.exports = (self) => {
3438
},
3539
(cb) => self.libp2p.start(cb),
3640
(cb) => {
41+
// Setup online routing for IPNS with a tiered routing composed by a DHT and a Pubsub router (if properly enabled)
42+
const ipnsStores = []
43+
44+
// TODO Add IPNS pubsub if enabled
45+
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
48+
const offlineDatastore = new OfflineDatastore(self._repo)
49+
ipnsStores.push(offlineDatastore)
50+
51+
// Create ipns routing with a set of datastores
52+
const routing = new TieredDatastore(ipnsStores)
53+
self._ipns = new IPNS(routing, self)
54+
3755
self._bitswap = new Bitswap(
3856
self._libp2pNode,
3957
self._repo.blocks,

src/core/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const ipldZcash = require('ipld-zcash')
3333
const config = require('./config')
3434
const boot = require('./boot')
3535
const components = require('./components')
36-
const IPNS = require('./ipns')
36+
3737
// replaced by repo-browser when running in the browser
3838
const defaultRepo = require('./runtime/repo-nodejs')
3939
const preload = require('./preload')
@@ -107,7 +107,7 @@ class IPFS extends EventEmitter {
107107
})
108108
this._preload = preload(this)
109109
this._mfsPreload = mfsPreload(this)
110-
this._ipns = new IPNS(null, this)
110+
this._ipns = undefined
111111

112112
// IPFS Core exposed components
113113
// - for booting up a node

src/core/ipns/index.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ class IPNS {
1919
constructor (routing, ipfs) {
2020
this.publisher = new IpnsPublisher(routing, ipfs._repo)
2121
this.republisher = new IpnsRepublisher(this.publisher, ipfs)
22-
this.resolver = new IpnsResolver(routing, ipfs._repo)
22+
this.resolver = new IpnsResolver(routing)
2323
this.cache = new Receptacle({ max: 1000 }) // Create an LRU cache with max 1000 items
24+
this.routing = routing
2425
}
2526

2627
// Publish
@@ -53,7 +54,12 @@ class IPNS {
5354
}
5455

5556
// Resolve
56-
resolve (name, peerId, options, callback) {
57+
resolve (name, options, callback) {
58+
if (typeof options === 'function') {
59+
callback = options
60+
options = {}
61+
}
62+
5763
// If recursive, we should not try to get the cached value
5864
if (!options.nocache && !options.recursive) {
5965
// Try to get the record from cache
@@ -67,7 +73,7 @@ class IPNS {
6773
}
6874
}
6975

70-
this.resolver.resolve(name, peerId, options, (err, result) => {
76+
this.resolver.resolve(name, options, (err, result) => {
7177
if (err) {
7278
log.error(err)
7379
return callback(err)

src/core/ipns/path.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,7 @@ const resolvePath = (ipfsNode, name, callback) => {
1313
if (isIPFS.ipnsPath(name)) {
1414
log(`resolve ipns path ${name}`)
1515

16-
const local = true // TODO ROUTING - use self._options.local
17-
18-
const options = {
19-
local: local
20-
}
21-
22-
return ipfsNode._ipns.resolve(name, ipfsNode._peerInfo.id, options, callback)
16+
return ipfsNode._ipns.resolve(name, callback)
2317
}
2418

2519
// ipfs path

src/core/ipns/publisher.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ class IpnsPublisher {
6767

6868
let keys
6969
try {
70-
keys = ipns.getIdKeys(peerId.id)
70+
keys = ipns.getIdKeys(peerId.toBytes())
7171
} catch (err) {
7272
log.error(err)
7373
return callback(err)
7474
}
7575

7676
series([
77-
(cb) => this._publishEntry(keys.ipnsKey, embedPublicKeyRecord || record, peerId, cb),
77+
(cb) => this._publishEntry(keys.routingKey, embedPublicKeyRecord || record, peerId, cb),
7878
// Publish the public key if a public key cannot be extracted from the ID
7979
// We will be able to deprecate this part in the future, since the public keys will be only in the peerId
80-
(cb) => embedPublicKeyRecord ? this._publishPublicKey(keys.pkKey, publicKey, peerId, cb) : cb()
80+
(cb) => embedPublicKeyRecord ? this._publishPublicKey(keys.routingPubKey, publicKey, peerId, cb) : cb()
8181
], (err) => {
8282
if (err) {
8383
log.error(err)
@@ -108,13 +108,13 @@ class IpnsPublisher {
108108
return callback(err)
109109
}
110110

111-
// TODO Routing - this should be replaced by a put to the DHT
112-
this._repo.datastore.put(key, rec.serialize(), (err, res) => {
111+
// Add record to routing (buffer key)
112+
this._routing.put(key.toBuffer(), rec.serialize(), (err, res) => {
113113
if (err) {
114114
const errMsg = `ipns record for ${key.toString()} could not be stored in the routing`
115115

116116
log.error(errMsg)
117-
return callback(errcode(new Error(errMsg), 'ERR_STORING_IN_DATASTORE'))
117+
return callback(errcode(new Error(errMsg), 'ERR_PUTTING_TO_ROUTING'))
118118
}
119119

120120
log(`ipns record for ${key.toString()} was stored in the routing`)
@@ -146,13 +146,13 @@ class IpnsPublisher {
146146
return callback(err)
147147
}
148148

149-
// TODO Routing - this should be replaced by a put to the DHT
150-
this._repo.datastore.put(key, rec.serialize(), (err, res) => {
149+
// Add public key to routing (buffer key)
150+
this._routing.put(key.toBuffer(), rec.serialize(), (err, res) => {
151151
if (err) {
152152
const errMsg = `public key for ${key.toString()} could not be stored in the routing`
153153

154154
log.error(errMsg)
155-
return callback(errcode(new Error(errMsg), 'ERR_STORING_IN_DATASTORE'))
155+
return callback(errcode(new Error(errMsg), 'ERR_PUTTING_TO_ROUTING'))
156156
}
157157

158158
log(`public key for ${key.toString()} was stored in the routing`)

src/core/ipns/resolver.js

+21-34
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const ipns = require('ipns')
44
const { fromB58String } = require('multihashes')
55
const Record = require('libp2p-record').Record
6+
const PeerId = require('peer-id')
67
const errcode = require('err-code')
78

89
const debug = require('debug')
@@ -12,13 +13,11 @@ log.error = debug('jsipfs:ipns:resolver:error')
1213
const defaultMaximumRecursiveDepth = 32
1314

1415
class IpnsResolver {
15-
constructor (routing, repo) {
16+
constructor (routing) {
1617
this._routing = routing
17-
this._repo = repo
18-
this._resolver = undefined // TODO Routing - add Router resolver
1918
}
2019

21-
resolve (name, peerId, options, callback) {
20+
resolve (name, options, callback) {
2221
if (typeof options === 'function') {
2322
callback = options
2423
options = {}
@@ -33,7 +32,6 @@ class IpnsResolver {
3332

3433
options = options || {}
3534
const recursive = options.recursive && options.recursive.toString() === 'true'
36-
const local = !(options.local === false)
3735

3836
const nameSegments = name.split('/')
3937

@@ -53,20 +51,7 @@ class IpnsResolver {
5351
depth = defaultMaximumRecursiveDepth
5452
}
5553

56-
// Get the intended resoulver function
57-
// TODO Routing - set default resolverFn
58-
59-
let resolverFn
60-
61-
if (local) {
62-
resolverFn = this._resolveLocal
63-
}
64-
65-
if (!resolverFn) {
66-
return callback(new Error('not implemented yet'))
67-
}
68-
69-
this.resolver(key, depth, peerId, resolverFn, (err, res) => {
54+
this.resolver(key, depth, (err, res) => {
7055
if (err) {
7156
return callback(err)
7257
}
@@ -77,10 +62,7 @@ class IpnsResolver {
7762
}
7863

7964
// Recursive resolver according to the specified depth
80-
resolver (name, depth, peerId, resolverFn, callback) {
81-
// bind resolver function
82-
this._resolver = resolverFn
83-
65+
resolver (name, depth, callback) {
8466
// Exceeded recursive maximum depth
8567
if (depth === 0) {
8668
const errMsg = `could not resolve name (recursion limit of ${defaultMaximumRecursiveDepth} exceeded)`
@@ -89,7 +71,7 @@ class IpnsResolver {
8971
return callback(errcode(new Error(errMsg), 'ERR_RESOLVE_RECURSION_LIMIT'))
9072
}
9173

92-
this._resolver(name, peerId, (err, res) => {
74+
this._resolveName(name, (err, res) => {
9375
if (err) {
9476
return callback(err)
9577
}
@@ -102,30 +84,35 @@ class IpnsResolver {
10284
}
10385

10486
// continue recursively until depth equals 0
105-
this.resolver(nameSegments[2], depth - 1, peerId, resolverFn, callback)
87+
this.resolver(nameSegments[2], depth - 1, callback)
10688
})
10789
}
10890

109-
// resolve ipns entries locally using the datastore
110-
_resolveLocal (name, peerId, callback) {
111-
const { ipnsKey } = ipns.getIdKeys(fromB58String(name))
91+
// resolve ipns entries from the provided routing
92+
_resolveName (name, callback) {
93+
const peerId = PeerId.createFromB58String(name)
94+
const { routingKey } = ipns.getIdKeys(fromB58String(name))
11295

113-
this._repo.datastore.get(ipnsKey, (err, dsVal) => {
114-
if (err) {
115-
const errMsg = `local record requested was not found for ${name} (${ipnsKey})`
96+
// TODO DHT - get public key from routing?
97+
// https://github.com/ipfs/go-ipfs/blob/master/namesys/routing.go#L70
98+
// https://github.com/libp2p/go-libp2p-routing/blob/master/routing.go#L99
99+
100+
this._routing.get(routingKey.toBuffer(), (err, res) => {
101+
if (err || !res) {
102+
const errMsg = `record requested was not found for ${name} (${routingKey}) in the network`
116103

117104
log.error(errMsg)
118-
return callback(errcode(new Error(errMsg), 'ERR_NO_LOCAL_RECORD_FOUND'))
105+
return callback(errcode(new Error(errMsg), 'ERR_NO_NETWORK_RECORD_FOUND'))
119106
}
120107

121-
if (!Buffer.isBuffer(dsVal)) {
108+
if (!Buffer.isBuffer(res)) {
122109
const errMsg = `found ipns record that we couldn't convert to a value`
123110

124111
log.error(errMsg)
125112
return callback(errcode(new Error(errMsg), 'ERR_INVALID_RECORD_RECEIVED'))
126113
}
127114

128-
const record = Record.deserialize(dsVal)
115+
const record = Record.deserialize(res)
129116
const ipnsEntry = ipns.unmarshal(record.value)
130117

131118
ipns.extractPublicKey(peerId, ipnsEntry, (err, pubKey) => {

0 commit comments

Comments
 (0)