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

Commit f75eb35

Browse files
JonKronedaviddias
authored andcommitted
feat: jsipfs pin improvements (#1249)
* initial sweep through to understand how pin works. Did make some changes but mostly minor. * refactor pb schema to it's own file * fix: don't pin files during files.add if opts.pin === false * feat: add some http qs parsing, http route/resources cleanup, cleanup core/utils.parseIpfsPath * feat: expand pin tests. \nFirst draft. still needs some further work. * feat: Add logging for entry/exit of pins: add/rm/flush/load. Clean some documentation. * feat: add --pin to files.add, fix: improper pin option parsing in core. * feat: Use ipfs.files.add to add init-docs instead of directly using the unix-fs importer. * feat(tests): Add tests for cli --pin option. I know this should be more of an integration test. Should be written in /core. Maybe talk with Victor about testing different layers * feat: use isIPFS to valiate a multihash.
1 parent abb7731 commit f75eb35

File tree

19 files changed

+277
-200
lines changed

19 files changed

+277
-200
lines changed

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,8 @@
107107
"hapi": "^16.6.2",
108108
"hapi-set-header": "^1.0.2",
109109
"hoek": "^5.0.3",
110-
"interface-datastore": "^0.4.1",
111-
"ipfs-api": "^18.0.0",
112-
"ipfs-bitswap": "~0.19.0",
113110
"human-to-milliseconds": "^1.0.0",
111+
"interface-datastore": "^0.4.1",
114112
"ipfs-api": "^18.1.1",
115113
"ipfs-bitswap": "~0.19.0",
116114
"ipfs-block": "~0.6.1",

src/cli/commands/files/add.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ module.exports = {
172172
type: 'boolean',
173173
default: false,
174174
describe: 'Write no output'
175+
},
176+
pin: {
177+
type: 'boolean',
178+
default: true,
179+
describe: 'Pin this object when adding'
175180
}
176181
},
177182

@@ -182,7 +187,8 @@ module.exports = {
182187
strategy: argv.trickle ? 'trickle' : 'balanced',
183188
shardSplitThreshold: argv.enableShardingExperiment ? argv.shardSplitThreshold : Infinity,
184189
'cid-version': argv['cid-version'],
185-
'raw-leaves': argv['raw-leaves']
190+
'raw-leaves': argv['raw-leaves'],
191+
pin: argv.pin
186192
}
187193

188194
// Temporary restriction on raw-leaves:

src/cli/commands/pin/add.js

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

3+
const print = require('../../utils').print
4+
35
module.exports = {
46
command: 'add <ipfs-path>',
57

@@ -21,7 +23,7 @@ module.exports = {
2123
argv.ipfs.pin.add(paths[0], { recursive: recursive }, (err, results) => {
2224
if (err) { throw err }
2325
results.forEach((res) => {
24-
console.log(`pinned ${res.hash} ${type}ly`)
26+
print(`pinned ${res.hash} ${type}ly`)
2527
})
2628
})
2729
}

src/cli/commands/pin/ls.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
'use strict'
22

3+
const print = require('../../utils').print
4+
35
module.exports = {
4-
command: 'ls',
6+
// bracket syntax with '...' tells yargs to optionally accept a list
7+
command: 'ls [ipfs-path...]',
58

69
describe: 'List objects pinned to local storage.',
710

811
builder: {
9-
path: {
10-
type: 'string',
11-
describe: 'List pinned state of specific <ipfs-path>.'
12-
},
1312
type: {
1413
type: 'string',
1514
alias: 't',
1615
default: 'all',
17-
describe: ('The type of pinned keys to list. ' +
18-
'Can be "direct", "indirect", "recursive", or "all".')
16+
choices: ['direct', 'indirect', 'recursive', 'all'],
17+
describe: 'The type of pinned keys to list.'
1918
},
2019
quiet: {
2120
type: 'boolean',
@@ -26,7 +25,7 @@ module.exports = {
2625
},
2726

2827
handler: (argv) => {
29-
const paths = argv.path && argv.path.split(' ')
28+
const paths = argv.ipfsPath || ''
3029
const type = argv.type
3130
const quiet = argv.quiet
3231
argv.ipfs.pin.ls(paths, { type: type }, (err, results) => {
@@ -36,7 +35,7 @@ module.exports = {
3635
if (!quiet) {
3736
line += ` ${res.type}`
3837
}
39-
console.log(line)
38+
print(line)
4039
})
4140
})
4241
}

src/cli/commands/pin/rm.js

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

3+
const print = require('../../utils').print
4+
35
module.exports = {
46
command: 'rm <ipfs-path>',
57

@@ -20,7 +22,7 @@ module.exports = {
2022
argv.ipfs.pin.rm(paths, { recursive: recursive }, (err, results) => {
2123
if (err) { throw err }
2224
results.forEach((res) => {
23-
console.log(`unpinned ${res.hash}`)
25+
print(`unpinned ${res.hash}`)
2426
})
2527
})
2628
}

src/core/components/files.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const CID = require('cids')
1818
const toB58String = require('multihashes').toB58String
1919

2020
function noop () {}
21+
function identity (x) { return x }
2122

2223
function prepareFile (self, opts, file, callback) {
2324
opts = opts || {}
@@ -125,7 +126,8 @@ module.exports = function files (self) {
125126
}, options)
126127

127128
let total = 0
128-
let prog = opts.progress || (() => {})
129+
const shouldPin = 'pin' in opts ? opts.pin : true
130+
const prog = opts.progress || noop
129131
const progress = (bytes) => {
130132
total += bytes
131133
prog(total)
@@ -137,7 +139,7 @@ module.exports = function files (self) {
137139
pull.flatten(),
138140
importer(self._ipld, opts),
139141
pull.asyncMap(prepareFile.bind(null, self, opts)),
140-
pull.asyncMap(pinFile.bind(null, self))
142+
shouldPin ? pull.asyncMap(pinFile.bind(null, self)) : identity
141143
)
142144
}
143145

src/core/components/init-assets.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,20 @@ module.exports = function addDefaultAssets (self, log, callback) {
1515

1616
pull(
1717
pull.values([initDocsPath]),
18-
pull.asyncMap((val, cb) => glob(path.join(val, '/**/*'), cb)),
18+
pull.asyncMap((val, cb) =>
19+
glob(path.join(val, '/**/*'), { nodir: true }, cb)
20+
),
1921
pull.flatten(),
20-
pull.map((element) => {
22+
pull.map(element => {
2123
const addPath = element.substring(index + 1)
22-
23-
if (fs.statSync(element).isDirectory()) { return }
24-
2524
return { path: addPath, content: file(element) }
2625
}),
27-
// Filter out directories, which are undefined from above
28-
pull.filter(Boolean),
29-
importer(self._ipld),
30-
pull.through((el) => {
31-
if (el.path === 'init-docs') {
32-
const cid = new CID(el.multihash)
26+
self.files.addPullStream(),
27+
pull.through(file => {
28+
if (file.path === 'init-docs') {
29+
const cid = new CID(file.hash)
3330
log('to get started, enter:\n')
34-
log(`\t jsipfs files cat /ipfs/${cid.toBaseEncodedString()}/readme\n`)
31+
log(`\tjsipfs files cat /ipfs/${cid.toBaseEncodedString()}/readme\n`)
3532
}
3633
}),
3734
pull.collect((err) => {

src/core/components/init.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,11 @@ module.exports = function init (self) {
8585
}
8686

8787
self.log('adding assets')
88-
const tasks = [
88+
parallel([
8989
// add empty unixfs dir object (go-ipfs assumes this exists)
90-
(cb) => self.object.new('unixfs-dir', cb)
91-
]
92-
93-
if (typeof addDefaultAssets === 'function') {
94-
tasks.push((cb) => addDefaultAssets(self, opts.log, cb))
95-
}
96-
97-
parallel(tasks, (err) => {
90+
(cb) => self.object.new('unixfs-dir', cb),
91+
(cb) => addDefaultAssets(self, opts.log, cb)
92+
], (err) => {
9893
if (err) {
9994
cb(err)
10095
} else {

src/core/components/pin-set.js

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,14 @@ const DAGLink = dagPB.DAGLink
1111
const varint = require('varint')
1212
const once = require('once')
1313

14+
const pbSchema = require('./pin.proto')
15+
1416
const emptyKeyHash = 'QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n'
1517
const emptyKey = multihashes.fromB58String(emptyKeyHash)
1618
const defaultFanout = 256
1719
const maxItems = 8192
18-
19-
// Protobuf interface
20-
// from go-ipfs/pin/internal/pb/header.proto
21-
const pbSchema = `
22-
syntax = "proto2";
23-
24-
package ipfs.pin;
25-
26-
option go_package = "pb";
27-
28-
message Set {
29-
optional uint32 version = 1;
30-
optional uint32 fanout = 2;
31-
optional fixed32 seed = 3;
32-
}
33-
`
34-
3520
const pb = protobuf(pbSchema)
21+
3622
function readHeader (rootNode) {
3723
// rootNode.data should be a buffer of the format:
3824
// < varint(headerLength) | header | itemData... >
@@ -63,7 +49,6 @@ exports = module.exports = function (dag) {
6349
const pinSet = {
6450
// should this be part of `object` API?
6551
hasChild: (root, childhash, callback, _links, _checked, _seen) => {
66-
// callback (err, has)
6752
callback = once(callback)
6853
if (typeof childhash === 'object') {
6954
childhash = toB58String(childhash)
@@ -81,11 +66,13 @@ exports = module.exports = function (dag) {
8166
if (bs58link === childhash) {
8267
return callback(null, true)
8368
}
69+
70+
// don't check the same links twice
71+
if (bs58link in _seen) { return }
72+
_seen[bs58link] = true
73+
8474
dag.get(new CID(link.multihash), (err, res) => {
8575
if (err) { return callback(err) }
86-
// don't check the same links twice
87-
if (bs58link in _seen) { return }
88-
_seen[bs58link] = true
8976

9077
_checked++
9178
_links += res.value.links.length
@@ -95,7 +82,6 @@ exports = module.exports = function (dag) {
9582
},
9683

9784
storeSet: (keys, logInternalKey, callback) => {
98-
// callback (err, rootNode)
9985
callback = once(callback)
10086
const items = keys.map((key) => {
10187
return {
@@ -115,10 +101,8 @@ exports = module.exports = function (dag) {
115101
},
116102

117103
storeItems: (items, logInternalKey, callback, _depth, _subcalls, _done) => {
118-
// callback (err, rootNode)
119104
callback = once(callback)
120-
// const seed = crypto.randomBytes(4).readUInt32LE(0, true) // old nondeterministic behavior
121-
const seed = _depth // new deterministic behavior
105+
const seed = _depth
122106
const pbHeader = pb.Set.encode({
123107
version: 1,
124108
fanout: defaultFanout,
@@ -210,9 +194,8 @@ exports = module.exports = function (dag) {
210194
},
211195

212196
loadSet: (rootNode, name, logInternalKey, callback) => {
213-
// callback (err, keys)
214197
callback = once(callback)
215-
const link = rootNode.links.filter(l => l.name === name).pop()
198+
const link = rootNode.links.find(l => l.name === name)
216199
if (!link) { return callback(new Error('No link found with name ' + name)) }
217200
logInternalKey(link.multihash)
218201
dag.get(new CID(link.multihash), (err, res) => {
@@ -229,7 +212,6 @@ exports = module.exports = function (dag) {
229212
},
230213

231214
walkItems: (node, walkerFn, logInternalKey, callback) => {
232-
// callback (err)
233215
callback = once(callback)
234216
const h = readHeader(node)
235217
if (h.err) { return callback(h.err) }

0 commit comments

Comments
 (0)