diff --git a/package.json b/package.json index bae2a42324..dc380290ee 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "async": "^2.1.4", "bl": "^1.1.2", "boom": "^4.2.0", + "cids": "^0.3.4", "debug": "^2.3.3", "fs-pull-blob-store": "^0.3.0", "glob": "^7.1.1", @@ -102,6 +103,7 @@ "mafmt": "^2.1.2", "multiaddr": "^2.1.1", "multihashes": "^0.3.0", + "multihashing-async": "^0.3.0", "path-exists": "^3.0.0", "peer-book": "^0.3.0", "peer-id": "^0.8.0", diff --git a/src/cli/commands/block/get.js b/src/cli/commands/block/get.js index f042eb0632..ed0218f03b 100644 --- a/src/cli/commands/block/get.js +++ b/src/cli/commands/block/get.js @@ -1,7 +1,7 @@ 'use strict' const utils = require('../../utils') -const mh = require('multihashes') +const CID = require('cids') const debug = require('debug') const log = debug('cli:block') log.error = debug('cli:block:error') @@ -19,17 +19,17 @@ module.exports = { throw err } - const hash = utils.isDaemonOn() - ? argv.key - : mh.fromB58String(argv.key) + const cid = new CID(argv.key) - ipfs.block.get(hash, (err, block) => { + ipfs.block.get(cid, (err, block) => { if (err) { throw err } if (block.data) { - console.log(block.data.toString()) + // writing the buffer to stdout seems to be the only way + // to send out binary data correctly + process.stdout.write(block.data) return } diff --git a/src/cli/commands/block/put.js b/src/cli/commands/block/put.js index cdd47a7776..47210d5012 100644 --- a/src/cli/commands/block/put.js +++ b/src/cli/commands/block/put.js @@ -1,32 +1,50 @@ 'use strict' const utils = require('../../utils') -const mh = require('multihashes') const bl = require('bl') const fs = require('fs') const Block = require('ipfs-block') +const CID = require('cids') +const multihashing = require('multihashing-async') const waterfall = require('async/waterfall') const debug = require('debug') const log = debug('cli:block') log.error = debug('cli:block:error') -function addBlock (buf) { +function addBlock (buf, opts) { + let block = new Block(buf) + let cid + utils.getIPFS((err, ipfs) => { if (err) { throw err } waterfall([ - (cb) => ipfs.block.put(new Block(buf), cb), - (block, cb) => block.key(cb) - ], (err, key) => { + (cb) => generateHash(block, opts, cb), + (mhash, cb) => generateCid(mhash, block, opts, cb), + (cb) => ipfs.block.put(block, cid, cb) + ], (err) => { if (err) { throw err } - console.log(mh.toB58String(key)) + console.log(cid.toBaseEncodedString()) }) }) + + function generateHash (block, opts, cb) { + if (opts.mhlen === undefined) { + multihashing(buf, opts.mhtype, cb) + } else { + multihashing(buf, opts.mhtype, opts.mhlen, cb) + } + } + + function generateCid (mhash, block, opts, cb) { + cid = new CID(opts.verison, opts.format, mhash) + cb() + } } module.exports = { @@ -34,11 +52,34 @@ module.exports = { describe: 'Stores input as an IPFS block', - builder: {}, + builder: { + format: { + alias: 'f', + describe: 'cid format for blocks to be created with.', + default: 'v0' + }, + mhtype: { + describe: 'multihash hash function', + default: 'sha2-256' + }, + mhlen: { + describe: 'multihash hash length', + default: undefined + } + }, handler (argv) { + // parse options + if (argv.format === 'v0') { + argv.verison = 0 + argv.format = 'dag-pb' + argv.mhtype = 'sha2-256' + } else { + argv.verison = 1 + } + if (argv.data) { - return addBlock(fs.readFileSync(argv.data)) + return addBlock(fs.readFileSync(argv.data), argv) } process.stdin.pipe(bl((err, input) => { @@ -46,7 +87,7 @@ module.exports = { throw err } - addBlock(input) + addBlock(input, argv) })) } } diff --git a/src/cli/commands/block/stat.js b/src/cli/commands/block/stat.js index ab7887c75b..a3cefd2f70 100644 --- a/src/cli/commands/block/stat.js +++ b/src/cli/commands/block/stat.js @@ -1,6 +1,7 @@ 'use strict' const utils = require('../../utils') +const CID = require('cids') const debug = require('debug') const log = debug('cli:block') log.error = debug('cli:block:error') @@ -13,12 +14,14 @@ module.exports = { builder: {}, handler (argv) { + const cid = new CID(argv.key) + utils.getIPFS((err, ipfs) => { if (err) { throw err } - ipfs.block.stat(argv.key, (err, stats) => { + ipfs.block.stat(cid, (err, stats) => { if (err) { throw err } diff --git a/src/core/components/dag.js b/src/core/components/dag.js index 4e35972dae..f8d17626a5 100644 --- a/src/core/components/dag.js +++ b/src/core/components/dag.js @@ -1,44 +1,39 @@ 'use strict' const promisify = require('promisify-es6') -// const dagPB = require('ipld-dag-pb') -// const dagCBOR = require('ipld-dag-cbor') -// const CID = require('cids') -// const mh = require('multihashes') +const dagPB = require('ipld-dag-pb') +const dagCBOR = require('ipld-dag-cbor') module.exports = function dag (self) { return { put: promisify((dagNode, multicodec, hashAlg, callback) => { - // TODO - // serialize - // get right hash - // generate cid - // put in IPLD Resolver - - /* - self._ipldResolver.put({ - node: node, - cid: new CID(node.multihash) - } - */ switch (multicodec) { - case 'dag-pb': {} break - case 'dag-cbor': {} break - default: - callback(new Error('IPLD Format not supported')) + case 'dag-pb': dagPB.util.cid(dagNode, gotCid); break + case 'dag-cbor': dagCBOR.util.cid(dagNode, gotCid); break + default: callback(new Error('IPLD Format not supported')) + } + + function gotCid (err, cid) { + if (err) { + return callback(err) + } + self._ipldResolver.put({ + node: dagNode, + cid: cid + }, callback) } }), get: promisify((cid, callback) => { - self.ipldResolver.get(cid, callback) + self._ipldResolver.get(cid, callback) }), rm: promisify((cid, callback) => { // TODO once pinning is complete, this remove operation has to first // verify that some pinning chain is not broken with the operation - self.ipldResolver.remove(cid, callback) + self._ipldResolver.remove(cid, callback) }), resolve: promisify((cid, path, callback) => { - self.ipldResolver.resolve(cid, path, callback) + self._ipldResolver.resolve(cid, path, callback) }) } } diff --git a/src/core/index.js b/src/core/index.js index a58836c10c..115417449a 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -18,6 +18,7 @@ const bootstrap = require('./components/bootstrap') const config = require('./components/config') const block = require('./components/block') const object = require('./components/object') +const dag = require('./components/dag') const libp2p = require('./components/libp2p') const swarm = require('./components/swarm') const ping = require('./components/ping') @@ -62,6 +63,7 @@ function IPFS (repoInstance) { this.config = config(this) this.block = block(this) this.object = object(this) + this.dag = dag(this) this.libp2p = libp2p(this) this.swarm = swarm(this) this.files = files(this) diff --git a/test/cli/test-block.js b/test/cli/test-block.js index 6beb8b3076..308ad3ae9a 100644 --- a/test/cli/test-block.js +++ b/test/cli/test-block.js @@ -16,9 +16,17 @@ describe('block', () => { }) }) + it('put with flags, format and mhtype', () => { + return ipfs('block put --format eth-block --mhtype keccak-256 test/test-data/eth-block').then((out) => { + expect(out).to.be.eql( + 'z43AaGF23fmvRnDP56Ub9WcJCfzSfqtmzNCCvmz5eudT8dtdCDS' + ) + }) + }) + it('get', () => { return ipfs('block get QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp').then((out) => { - expect(out).to.be.eql('hello world\n') + expect(out).to.be.eql('hello world') }) }) diff --git a/test/core/both/index.js b/test/core/both/index.js index a6dc8e5621..5fa7491541 100644 --- a/test/core/both/index.js +++ b/test/core/both/index.js @@ -2,7 +2,6 @@ 'use strict' describe('--both', () => { - require('./test-bitswap') require('./test-block') require('./test-bootstrap') require('./test-config') @@ -10,4 +9,6 @@ describe('--both', () => { require('./test-generic') require('./test-init') require('./test-object') + require('./test-dag') + require('./test-bitswap') }) diff --git a/test/test-data/eth-block b/test/test-data/eth-block new file mode 100644 index 0000000000..f2b366dc93 Binary files /dev/null and b/test/test-data/eth-block differ