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

Commit 6d46e2e

Browse files
author
Alan Shaw
authored
feat: cid base option (#1552)
Implements an option for the CLI, HTTP API and core (where appropriate) that will allow the user to pick the multibase encoding for any CIDs that are returned as strings. **NOTE** Using the CID base option in `bitswap`, `dag` and `object` APIs **WILL NOT** auto upgrade your CID to v1 if it is a v0 CID and **WILL NOT** apply the encoding you specified. This is because these APIs return IPLD objects with links and changing the version of the links would result in a different hash for the node if you were to re-add it. Also, the CID you used to retrieve the node wouldn't actually refer to the node you got back any longer. [Read this](ipfs/kubo#5349 (comment)) for further context. This PR adds a `--cid-base` option to the following **CLI commands**: * `jsipfs bitswap stat` * `jsipfs bitswap unwant` * `jsipfs bitswap wantlist` * `jsipfs block put` * `jsipfs block stat` * `jsipfs add` * `jsipfs ls` * `jsipfs object get` * `jsipfs object links` * `jsipfs object new` * `jsipfs object patch add-link` * `jsipfs object patch append-data` * `jsipfs object patch rm-link` * `jsipfs object patch set-data` * `jsipfs object put` * `jsipfs object stat` * `jsipfs pin add` * `jsipfs pin ls` * `jsipfs pin rm` * `jsipfs resolve` Note: these two MFS commands _already_ implement the `--cid-base` option: * `jsipfs files ls` * `jsipfs files stat` It also adds `?cid-base=` query option to the following **HTTP endpoints**: * `/api/v0/bitswap/wantlist` * `/api/v0/bitswap/stat` * `/api/v0/bitswap/unwant` * `/api/v0/block/put` * `/api/v0/block/stat` * `/api/v0/add` * `/api/v0/ls` * `/api/v0/object/new` * `/api/v0/object/get` * `/api/v0/object/put` * `/api/v0/object/stat` * `/api/v0/object/links` * `/api/v0/object/patch/append-data` * `/api/v0/object/patch/set-data` * `/api/v0/object/patch/add-link` * `/api/v0/object/patch/rm-link` * `/api/v0/pin/ls` * `/api/v0/pin/add` * `/api/v0/pin/rm` * `/api/v0/resolve` It adds a `cidBase` option to the following **core functions**: * `resolve` License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent 3659d7e commit 6d46e2e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1784
-347
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
"ipfs-bitswap": "~0.21.0",
109109
"ipfs-block": "~0.8.0",
110110
"ipfs-block-service": "~0.15.1",
111-
"ipfs-http-client": "^28.0.1",
111+
"ipfs-http-client": "^28.1.0",
112112
"ipfs-http-response": "~0.2.1",
113113
"ipfs-mfs": "~0.8.0",
114114
"ipfs-multipart": "~0.1.0",
@@ -122,7 +122,7 @@
122122
"ipld-git": "~0.2.2",
123123
"ipld-zcash": "~0.1.6",
124124
"ipns": "~0.4.3",
125-
"is-ipfs": "~0.4.7",
125+
"is-ipfs": "~0.4.8",
126126
"is-pull-stream": "~0.0.0",
127127
"is-stream": "^1.1.0",
128128
"joi": "^14.3.0",

src/cli/commands/add.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ const getFolderSize = require('get-folder-size')
1111
const byteman = require('byteman')
1212
const waterfall = require('async/waterfall')
1313
const mh = require('multihashes')
14-
const utils = require('../utils')
15-
const print = require('../utils').print
16-
const createProgressBar = require('../utils').createProgressBar
14+
const multibase = require('multibase')
15+
const { print, isDaemonOn, createProgressBar } = require('../utils')
16+
const { cidToString } = require('../../utils/cid')
1717

1818
function checkPath (inPath, recursive) {
1919
// This function is to check for the following possible inputs
@@ -90,7 +90,7 @@ function addPipeline (index, addStream, list, argv) {
9090
sortBy(added, 'path')
9191
.reverse()
9292
.map((file) => {
93-
const log = [ 'added', file.hash ]
93+
const log = [ 'added', cidToString(file.hash, { base: argv.cidBase }) ]
9494

9595
if (!quiet && file.path.length > 0) log.push(file.path)
9696

@@ -156,10 +156,15 @@ module.exports = {
156156
describe: 'CID version. Defaults to 0 unless an option that depends on CIDv1 is passed. (experimental)',
157157
default: 0
158158
},
159+
'cid-base': {
160+
describe: 'Number base to display CIDs in.',
161+
type: 'string',
162+
choices: multibase.names
163+
},
159164
hash: {
160165
type: 'string',
161166
choices: Object.keys(mh.names),
162-
describe: 'Hash function to use. Will set Cid version to 1 if used. (experimental)'
167+
describe: 'Hash function to use. Will set CID version to 1 if used. (experimental)'
163168
},
164169
quiet: {
165170
alias: 'q',
@@ -202,7 +207,7 @@ module.exports = {
202207
chunker: argv.chunker
203208
}
204209

205-
if (options.enableShardingExperiment && utils.isDaemonOn()) {
210+
if (options.enableShardingExperiment && isDaemonOn()) {
206211
throw new Error('Error: Enabling the sharding experiment should be done on the daemon')
207212
}
208213
const ipfs = argv.ipfs

src/cli/commands/bitswap/stat.js

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

3-
const print = require('../../utils').print
3+
const multibase = require('multibase')
4+
const { print } = require('../../utils')
5+
const { cidToString } = require('../../../utils/cid')
46

57
module.exports = {
68
command: 'stat',
79

810
describe: 'Show some diagnostic information on the bitswap agent.',
911

10-
builder: {},
12+
builder: {
13+
'cid-base': {
14+
describe: 'Number base to display CIDs in. Note: specifying a CID base for v0 CIDs will have no effect.',
15+
type: 'string',
16+
choices: multibase.names
17+
}
18+
},
1119

12-
handler (argv) {
13-
argv.ipfs.bitswap.stat((err, stats) => {
20+
handler ({ ipfs, cidBase }) {
21+
ipfs.bitswap.stat((err, stats) => {
1422
if (err) {
1523
throw err
1624
}
1725

18-
stats.wantlist = stats.wantlist || []
19-
stats.wantlist = stats.wantlist.map(entry => entry['/'])
26+
stats.wantlist = stats.wantlist.map(k => cidToString(k['/'], { base: cidBase, upgrade: false }))
2027
stats.peers = stats.peers || []
2128

2229
print(`bitswap status

src/cli/commands/bitswap/unwant.js

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

3-
const print = require('../../utils').print
3+
const multibase = require('multibase')
4+
const { print } = require('../../utils')
5+
const { cidToString } = require('../../../utils/cid')
46

57
module.exports = {
68
command: 'unwant <key>',
@@ -12,14 +14,19 @@ module.exports = {
1214
alias: 'k',
1315
describe: 'Key to remove from your wantlist',
1416
type: 'string'
17+
},
18+
'cid-base': {
19+
describe: 'Number base to display CIDs in. Note: specifying a CID base for v0 CIDs will have no effect.',
20+
type: 'string',
21+
choices: multibase.names
1522
}
1623
},
17-
handler (argv) {
18-
argv.ipfs.bitswap.unwant(argv.key, (err) => {
24+
handler ({ ipfs, key, cidBase }) {
25+
ipfs.bitswap.unwant(key, (err) => {
1926
if (err) {
2027
throw err
2128
}
22-
print(`Key ${argv.key} removed from wantlist`)
29+
print(`Key ${cidToString(key, { base: cidBase, upgrade: false })} removed from wantlist`)
2330
})
2431
}
2532
}

src/cli/commands/bitswap/wantlist.js

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

3-
const print = require('../../utils').print
3+
const multibase = require('multibase')
4+
const { print } = require('../../utils')
5+
const { cidToString } = require('../../../utils/cid')
46

57
module.exports = {
68
command: 'wantlist [peer]',
@@ -12,17 +14,20 @@ module.exports = {
1214
alias: 'p',
1315
describe: 'Specify which peer to show wantlist for.',
1416
type: 'string'
17+
},
18+
'cid-base': {
19+
describe: 'Number base to display CIDs in. Note: specifying a CID base for v0 CIDs will have no effect.',
20+
type: 'string',
21+
choices: multibase.names
1522
}
1623
},
1724

18-
handler (argv) {
19-
argv.ipfs.bitswap.wantlist(argv.peer, (err, res) => {
25+
handler ({ ipfs, peer, cidBase }) {
26+
ipfs.bitswap.wantlist(peer, (err, list) => {
2027
if (err) {
2128
throw err
2229
}
23-
res.Keys.forEach((cid) => {
24-
print(cid['/'])
25-
})
30+
list.Keys.forEach(k => print(cidToString(k['/'], { base: cidBase, upgrade: false })))
2631
})
2732
}
2833
}

src/cli/commands/block/get.js

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

3-
const CID = require('cids')
43
const print = require('../../utils').print
54

65
module.exports = {
@@ -10,10 +9,8 @@ module.exports = {
109

1110
builder: {},
1211

13-
handler (argv) {
14-
const cid = new CID(argv.key)
15-
16-
argv.ipfs.block.get(cid, (err, block) => {
12+
handler ({ ipfs, key }) {
13+
ipfs.block.get(key, (err, block) => {
1714
if (err) {
1815
throw err
1916
}

src/cli/commands/block/put.js

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

3-
const CID = require('cids')
4-
const multihashing = require('multihashing-async')
53
const bl = require('bl')
64
const fs = require('fs')
7-
const Block = require('ipfs-block')
8-
const waterfall = require('async/waterfall')
9-
const print = require('../../utils').print
5+
const multibase = require('multibase')
6+
const { print } = require('../../utils')
7+
const { cidToString } = require('../../../utils/cid')
108

119
function addBlock (data, opts) {
1210
const ipfs = opts.ipfs
13-
let cid
1411

15-
waterfall([
16-
(cb) => multihashing(data, opts.mhtype || 'sha2-256', cb),
17-
(multihash, cb) => {
18-
if (opts.format !== 'dag-pb' || opts.version !== 0) {
19-
cid = new CID(1, opts.format || 'dag-pb', multihash)
20-
} else {
21-
cid = new CID(0, 'dag-pb', multihash)
22-
}
23-
24-
ipfs.block.put(new Block(data, cid), cb)
25-
}
26-
], (err) => {
12+
ipfs.block.put(data, opts, (err, block) => {
2713
if (err) {
2814
throw err
2915
}
30-
print(cid.toBaseEncodedString())
16+
print(cidToString(block.cid, { base: opts.cidBase }))
3117
})
3218
}
3319

@@ -52,8 +38,12 @@ module.exports = {
5238
},
5339
version: {
5440
describe: 'cid version',
55-
type: 'number',
56-
default: 0
41+
type: 'number'
42+
},
43+
'cid-base': {
44+
describe: 'Number base to display CIDs in.',
45+
type: 'string',
46+
choices: multibase.names
5747
}
5848
},
5949

src/cli/commands/block/rm.js

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

3-
const utils = require('../../utils')
4-
const mh = require('multihashes')
5-
const print = utils.print
3+
const { print, isDaemonOn } = require('../../utils')
64

75
module.exports = {
86
command: 'rm <key>',
@@ -11,18 +9,18 @@ module.exports = {
119

1210
builder: {},
1311

14-
handler (argv) {
15-
if (utils.isDaemonOn()) {
12+
handler ({ ipfs, key }) {
13+
if (isDaemonOn()) {
1614
// TODO implement this once `js-ipfs-http-client` supports it
1715
throw new Error('rm block with daemon running is not yet implemented')
1816
}
1917

20-
argv.ipfs.block.rm(mh.fromB58String(argv.key), (err) => {
18+
ipfs.block.rm(key, (err) => {
2119
if (err) {
2220
throw err
2321
}
2422

25-
print('removed ' + argv.key)
23+
print('removed ' + key)
2624
})
2725
}
2826
}

src/cli/commands/block/stat.js

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

3-
const CID = require('cids')
4-
const print = require('../../utils').print
3+
const multibase = require('multibase')
4+
const { print } = require('../../utils')
5+
const { cidToString } = require('../../../utils/cid')
56

67
module.exports = {
78
command: 'stat <key>',
89

910
describe: 'Print information of a raw IPFS block',
1011

11-
builder: {},
12+
builder: {
13+
'cid-base': {
14+
describe: 'Number base to display CIDs in.',
15+
type: 'string',
16+
choices: multibase.names
17+
}
18+
},
1219

13-
handler (argv) {
14-
argv.ipfs.block.stat(new CID(argv.key), (err, stats) => {
20+
handler ({ ipfs, key, cidBase }) {
21+
ipfs.block.stat(key, (err, stats) => {
1522
if (err) {
1623
throw err
1724
}
1825

19-
print('Key: ' + stats.key)
26+
print('Key: ' + cidToString(stats.key, { base: cidBase }))
2027
print('Size: ' + stats.size)
2128
})
2229
}

src/cli/commands/ls.js

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

3-
const utils = require('../utils')
3+
const multibase = require('multibase')
4+
const { print, rightpad } = require('../utils')
5+
const { cidToString } = require('../../utils/cid')
46

57
module.exports = {
68
command: 'ls <key>',
@@ -24,33 +26,41 @@ module.exports = {
2426
desc: 'Resolve linked objects to find out their types. (not implemented yet)',
2527
type: 'boolean',
2628
default: false // should be true when implemented
29+
},
30+
'cid-base': {
31+
describe: 'Number base to display CIDs in.',
32+
type: 'string',
33+
choices: multibase.names
2734
}
2835
},
2936

30-
handler (argv) {
31-
let path = argv.key
32-
if (path.startsWith('/ipfs/')) {
33-
path = path.replace('/ipfs/', '')
34-
}
35-
36-
argv.ipfs.ls(path, { recursive: argv.recursive }, (err, links) => {
37+
handler ({ ipfs, key, recursive, headers, cidBase }) {
38+
ipfs.ls(key, { recursive }, (err, links) => {
3739
if (err) {
3840
throw err
3941
}
4042

41-
if (argv.headers) {
43+
links = links.map(file => Object.assign(file, { hash: cidToString(file.hash, { base: cidBase }) }))
44+
45+
if (headers) {
4246
links = [{ hash: 'Hash', size: 'Size', name: 'Name' }].concat(links)
4347
}
4448

4549
const multihashWidth = Math.max.apply(null, links.map((file) => file.hash.length))
4650
const sizeWidth = Math.max.apply(null, links.map((file) => String(file.size).length))
4751

52+
let pathParts = key.split('/')
53+
54+
if (key.startsWith('/ipfs/')) {
55+
pathParts = pathParts.slice(2)
56+
}
57+
4858
links.forEach(link => {
4959
const fileName = link.type === 'dir' ? `${link.name || ''}/` : link.name
50-
const padding = link.depth - path.split('/').length
51-
utils.print(
52-
utils.rightpad(link.hash, multihashWidth + 1) +
53-
utils.rightpad(link.size || '', sizeWidth + 1) +
60+
const padding = link.depth - pathParts.length
61+
print(
62+
rightpad(link.hash, multihashWidth + 1) +
63+
rightpad(link.size || '', sizeWidth + 1) +
5464
' '.repeat(padding) + fileName
5565
)
5666
})

0 commit comments

Comments
 (0)