From 0c78f0efd2a45fd87a1bf34de52741ca12154f7a Mon Sep 17 00:00:00 2001 From: achingbrain Date: Wed, 31 Oct 2018 14:52:04 +0000 Subject: [PATCH] feat: adds onlyHash option to ipld.put IPLD and it's resolvers are the gatekeepers of creating CIDs from nodes. IPFS has variations on `onlyHash` parameters that can be passed to CLI commands, the intention of which is to return a CID for a given node and not write it to a block store. Since IPLD guards the block store and the generation of CIDs, we have to reach deep into it's heart to peform this. It makes sense that this should occur further down the stack so this PR adds an `onlyHash` option to `ipld.put` to accomplish this. --- README.md | 6 +++++- src/index.js | 8 ++++++++ test/ipld-all.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e53484..3624e0e 100644 --- a/README.md +++ b/README.md @@ -136,9 +136,13 @@ const ipld = new Ipld({ `options` is an object that must contain one of the following combinations: - `cid` - the CID of the node -- `[hashAlg]`, `[version]` and `format` - the hashAlg, version and the format that should be used to create the CID of the node. The +- `[hashAlg]`, `[version]` and `format` - the hashAlg, version and the format that should be used to create the CID of the node. The `hashAlg` and `version` defaults to the default values for the `format`. +It may contain any of the following: + +- `onlyHash` - If true the serialized form of the node will not be passed to the underlying block store but the passed callback will be invoked as if it had been + `callback` is a function that should have the signature as following: `function (err, cid) {}`, where `err` is an Error object in case of error and `cid` is the cid of the stored object. ### `.get(cid [, path] [, options], callback)` diff --git a/src/index.js b/src/index.js index dc3a4f3..58be233 100644 --- a/src/index.js +++ b/src/index.js @@ -174,6 +174,10 @@ class IPLDResolver { callback = callback || noop if (options.cid && CID.isCID(options.cid)) { + if (options.onlyHash) { + return setImmediate(() => callback(null, options.cid)) + } + return this._put(options.cid, node, callback) } @@ -186,6 +190,10 @@ class IPLDResolver { return callback(err) } + if (options.onlyHash) { + return callback(null, cid) + } + this._put(cid, node, callback) }) } diff --git a/test/ipld-all.js b/test/ipld-all.js index 1896c67..a75a9c4 100644 --- a/test/ipld-all.js +++ b/test/ipld-all.js @@ -15,6 +15,7 @@ const dagPB = require('ipld-dag-pb') const dagCBOR = require('ipld-dag-cbor') const each = require('async/each') const waterfall = require('async/waterfall') +const CID = require('cids') const IPLDResolver = require('../src') @@ -66,4 +67,48 @@ describe('IPLD Resolver for dag-cbor + dag-pb', () => { done() }) }) + + it('does not store nodes when onlyHash is passed', (done) => { + waterfall([ + (cb) => dagPB.DAGNode.create(Buffer.from('Some data here'), cb), + (node, cb) => resolver.put(nodePb, { + onlyHash: true, + version: 1, + hashAlg: 'sha2-256', + format: 'dag-pb' + }, cb), + (cid, cb) => resolver.bs._repo.blocks.has(cid, cb) + ], (error, result) => { + if (error) { + return done(error) + } + + expect(result).to.be.false() + done() + }) + }) + + it('does not store nodes when onlyHash is passed and a CID is passed', (done) => { + const cid = new CID('QmTmxQfEHbQzntsXPTU4ae2ZgBGwseBmS12AkZnKCkuf2G') + + waterfall([ + (cb) => dagPB.DAGNode.create(Buffer.from('Some data here'), cb), + (node, cb) => resolver.put(nodePb, { + onlyHash: true, + cid + }, cb), + (cid2, cb) => { + expect(cid2).to.equal(cid) + + resolver.bs._repo.blocks.has(cid2, cb) + } + ], (error, result) => { + if (error) { + return done(error) + } + + expect(result).to.be.false() + done() + }) + }) })