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

Commit a2954cb

Browse files
vasco-santosdaviddias
authored andcommitted
feat: Add support for specifying hash algorithms in files.add
1 parent c307eb9 commit a2954cb

File tree

5 files changed

+72
-11
lines changed

5 files changed

+72
-11
lines changed

src/cli/commands/files/add.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const zip = require('pull-zip')
1010
const getFolderSize = require('get-folder-size')
1111
const byteman = require('byteman')
1212
const waterfall = require('async/waterfall')
13+
const mh = require('multihashes')
1314
const utils = require('../../utils')
1415
const print = require('../../utils').print
1516
const createProgressBar = require('../../utils').createProgressBar
@@ -162,6 +163,11 @@ module.exports = {
162163
type: 'integer',
163164
describe: 'Cid version. Non-zero value will change default of \'raw-leaves\' to true. (experimental)'
164165
},
166+
hash: {
167+
type: 'string',
168+
choices: Object.keys(mh.names),
169+
describe: 'Hash function to use. Will set Cid version to 1 if used. (experimental)'
170+
},
165171
quiet: {
166172
alias: 'q',
167173
type: 'boolean',
@@ -191,7 +197,8 @@ module.exports = {
191197
: Infinity,
192198
cidVersion: argv.cidVersion,
193199
rawLeaves: argv.rawLeaves,
194-
onlyHash: argv.onlyHash
200+
onlyHash: argv.onlyHash,
201+
hashAlg: argv.hash
195202
}
196203

197204
// Temporary restriction on raw-leaves:
@@ -206,6 +213,18 @@ module.exports = {
206213
throw new Error('Implied argument raw-leaves must be passed and set to false when cid-version is > 0')
207214
}
208215

216+
// Temporary restriction on raw-leaves:
217+
// When hash != undefined then raw-leaves MUST be present and false.
218+
//
219+
// This is because raw-leaves is not yet implemented in js-ipfs,
220+
// and go-ipfs changes the value of raw-leaves to true when
221+
// hash != undefined unless explicitly set to false.
222+
//
223+
// This retains feature parity without having to implement raw-leaves.
224+
if (options.hash && options.rawLeaves !== false) {
225+
throw new Error('Implied argument raw-leaves must be passed and set to false when hash argument is specified')
226+
}
227+
209228
if (options.rawLeaves) {
210229
throw new Error('Not implemented: raw-leaves')
211230
}

src/core/components/files.js

+17-8
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ function noop () {}
2222
function prepareFile (self, opts, file, callback) {
2323
opts = opts || {}
2424

25-
waterfall([
26-
(cb) => opts.onlyHash ? cb(null, file) : self.object.get(file.multihash, cb),
27-
(node, cb) => {
28-
let cid = new CID(node.multihash)
25+
let cid = new CID(file.multihash)
2926

30-
if (opts['cid-version'] === 1) {
31-
cid = cid.toV1()
32-
}
27+
if (opts.cidVersion === 1) {
28+
cid = cid.toV1()
29+
}
3330

31+
waterfall([
32+
(cb) => opts.onlyHash ? cb(null, file) : self.object.get(file.multihash, opts, cb),
33+
(node, cb) => {
3434
const b58Hash = cid.toBaseEncodedString()
3535

3636
cb(null, {
@@ -110,6 +110,10 @@ module.exports = function files (self) {
110110
: Infinity
111111
}, options)
112112

113+
if (opts.hashAlg && opts.cidVersion !== 1) {
114+
opts.cidVersion = 1
115+
}
116+
113117
let total = 0
114118
let prog = opts.progress || (() => {})
115119
const progress = (bytes) => {
@@ -182,7 +186,7 @@ module.exports = function files (self) {
182186
}
183187

184188
return {
185-
add: promisify((data, options, callback) => {
189+
add: promisify((data, options = {}, callback) => {
186190
if (typeof options === 'function') {
187191
callback = options
188192
options = {}
@@ -200,6 +204,11 @@ module.exports = function files (self) {
200204
return callback(new Error('first arg must be a buffer, readable stream, an object or array of objects'))
201205
}
202206

207+
// CID v0 is for multihashes encoded with sha2-256
208+
if (options.hashAlg && options.cidVersion !== 1) {
209+
options.cidVersion = 1
210+
}
211+
203212
pull(
204213
pull.values([data]),
205214
_addPullStream(options),

src/core/components/object.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,11 @@ module.exports = function object (self) {
191191
} catch (err) {
192192
return callback(err)
193193
}
194-
const cid = new CID(mh)
194+
let cid = new CID(mh)
195+
196+
if (options.cidVersion === 1) {
197+
cid = cid.toV1()
198+
}
195199

196200
self._ipld.get(cid, (err, result) => {
197201
if (err) {
@@ -214,6 +218,7 @@ module.exports = function object (self) {
214218
if (err) {
215219
return callback(err)
216220
}
221+
217222
callback(null, node.data)
218223
})
219224
}),

src/http/api/resources/files.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ exports.add = {
207207
cidVersion: request.query['cid-version'],
208208
rawLeaves: request.query['raw-leaves'],
209209
progress: request.query.progress ? progressHandler : null,
210-
onlyHash: request.query['only-hash']
210+
onlyHash: request.query['only-hash'],
211+
hashAlg: request.query['hash']
211212
}
212213

213214
const aborter = abortable()

test/cli/files.js

+27
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,22 @@ const expect = require('chai').expect
77
const path = require('path')
88
const compareDir = require('dir-compare').compareSync
99
const rimraf = require('rimraf').sync
10+
const CID = require('cids')
11+
const mh = require('multihashes')
1012
const runOnAndOff = require('../utils/on-and-off')
1113

14+
// TODO: Test against all algorithms Object.keys(mh.names)
15+
// This subset is known to work with both go-ipfs and js-ipfs as of 2017-09-05
16+
const HASH_ALGS = [
17+
'sha1',
18+
'sha2-256',
19+
'sha2-512',
20+
'keccak-224',
21+
'keccak-256',
22+
'keccak-384',
23+
'keccak-512'
24+
]
25+
1226
describe('files', () => runOnAndOff((thing) => {
1327
let ipfs
1428
const readme = fs.readFileSync(path.join(process.cwd(), '/src/init-files/init-docs/readme'))
@@ -300,6 +314,19 @@ describe('files', () => runOnAndOff((thing) => {
300314
})
301315
})
302316

317+
HASH_ALGS.forEach((name) => {
318+
it(`add with hash=${name} and raw-leaves=false`, function () {
319+
this.timeout(30 * 1000)
320+
321+
return ipfs(`add src/init-files/init-docs/readme --hash=${name} --raw-leaves=false`)
322+
.then((out) => {
323+
const hash = out.split(' ')[1]
324+
const cid = new CID(hash)
325+
expect(mh.decode(cid.multihash).name).to.equal(name)
326+
})
327+
})
328+
})
329+
303330
it('cat', function () {
304331
this.timeout(30 * 1000)
305332

0 commit comments

Comments
 (0)