From ff7c7e569ce0749f76bd282b5d16edadbc7e2201 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 13 Aug 2018 07:29:45 -0700 Subject: [PATCH] fix: dag.get return error on missing multicodec (#831) Before this change it just failed silently for 'raw' DAGs such as `bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy` License: MIT Signed-off-by: Marcin Rataj --- src/dag/get.js | 17 +++++++--- test/dag.spec.js | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 test/dag.spec.js diff --git a/src/dag/get.js b/src/dag/get.js index ead6a732c..f3b7027e2 100644 --- a/src/dag/get.js +++ b/src/dag/get.js @@ -7,6 +7,11 @@ const CID = require('cids') const waterfall = require('async/waterfall') const block = require('../block') +const resolvers = { + 'dag-cbor': dagCBOR.resolver, + 'dag-pb': dagPB.resolver +} + module.exports = (send) => { return promisify((cid, path, options, callback) => { if (typeof path === 'function') { @@ -40,12 +45,14 @@ module.exports = (send) => { }) }, (ipfsBlock, path, cb) => { - if (ipfsBlock.cid.codec === 'dag-cbor') { - dagCBOR.resolver.resolve(ipfsBlock.data, path, cb) - } - if (ipfsBlock.cid.codec === 'dag-pb') { - dagPB.resolver.resolve(ipfsBlock.data, path, cb) + const dagResolver = resolvers[ipfsBlock.cid.codec] + if (!dagResolver) { + const error = new Error('ipfs-api is missing DAG resolver for "' + ipfsBlock.cid.codec + '" multicodec') + error.missingMulticodec = ipfsBlock.cid.codec + cb(error) + return } + dagResolver.resolve(ipfsBlock.data, path, cb) } ], callback) }) diff --git a/test/dag.spec.js b/test/dag.spec.js new file mode 100644 index 000000000..8224fc863 --- /dev/null +++ b/test/dag.spec.js @@ -0,0 +1,82 @@ +/* eslint-env mocha */ +/* eslint max-nested-callbacks: ["error", 8] */ + +'use strict' + +const chai = require('chai') +const dirtyChai = require('dirty-chai') +const expect = chai.expect +chai.use(dirtyChai) +const series = require('async/series') +const dagPB = require('ipld-dag-pb') +const DAGNode = dagPB.DAGNode + +const IPFSApi = require('../src') +const f = require('./utils/factory') + +let ipfsd +let ipfs + +describe('.dag', function () { + this.timeout(20 * 1000) + before(function (done) { + series([ + (cb) => f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { + expect(err).to.not.exist() + ipfsd = _ipfsd + ipfs = IPFSApi(_ipfsd.apiAddr) + cb() + }) + ], done) + }) + + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) + + it('should be able to put and get a DAG node with format dag-pb', (done) => { + const data = Buffer.from('some data') + DAGNode.create(data, (err, node) => { + expect(err).to.not.exist() + ipfs.dag.put(node, {format: 'dag-pb', hashAlg: 'sha2-256'}, (err, cid) => { + expect(err).to.not.exist() + cid = cid.toV0() + expect(cid.codec).to.equal('dag-pb') + cid = cid.toBaseEncodedString('base58btc') + // expect(cid).to.equal('bafybeig3t3eugdchignsgkou3ly2mmy4ic4gtfor7inftnqn3yq4ws3a5u') + expect(cid).to.equal('Qmd7xRhW5f29QuBFtqu3oSD27iVy35NRB91XFjmKFhtgMr') + ipfs.dag.get(cid, (err, result) => { + expect(err).to.not.exist() + expect(result.value.data).to.deep.equal(data) + done() + }) + }) + }) + }) + + it('should be able to put and get a DAG node with format dag-cbor', (done) => { + const cbor = {foo: 'dag-cbor-bar'} + ipfs.dag.put(cbor, {format: 'dag-cbor', hashAlg: 'sha2-256'}, (err, cid) => { + expect(err).to.not.exist() + expect(cid.codec).to.equal('dag-cbor') + cid = cid.toBaseEncodedString('base32') + expect(cid).to.equal('bafyreic6f672hnponukaacmk2mmt7vs324zkagvu4hcww6yba6kby25zce') + ipfs.dag.get(cid, (err, result) => { + expect(err).to.not.exist() + expect(result.value).to.deep.equal(cbor) + done() + }) + }) + }) + + it('should callback with error when missing DAG resolver for raw multicodec', (done) => { + // CIDv1 with multicodec = raw + const cid = 'bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy' + ipfs.dag.get(cid, (err, result) => { + expect(result).to.not.exist() + expect(err.message).to.equal('ipfs-api is missing DAG resolver for "raw" multicodec') + done() + }) + }) +})