diff --git a/example.js b/example.js index 73f56bc6..8239c353 100644 --- a/example.js +++ b/example.js @@ -3,7 +3,7 @@ const Repo = require('ipfs-repo') const repo = new Repo('/Users/awesome/.jsipfs') -repo.init({my: 'config'}, (err) => { +repo.init({ my: 'config' }, (err) => { if (err) { throw err } diff --git a/package.json b/package.json index a2ba847e..91543806 100644 --- a/package.json +++ b/package.json @@ -38,11 +38,11 @@ "npm": ">=3.0.0" }, "devDependencies": { - "aegir": "^15.3.1", + "aegir": "^17.1.1", "chai": "^4.2.0", "dirty-chai": "^2.0.1", "lodash": "^4.17.11", - "memdown": "^1.4.1", + "memdown": "^3.0.0", "multihashes": "~0.4.14", "multihashing-async": "~0.5.1", "ncp": "^2.0.0", @@ -52,17 +52,17 @@ "async": "^2.6.1", "base32.js": "~0.1.0", "big.js": "^5.2.2", - "cids": "~0.5.5", + "cids": "~0.5.7", "datastore-core": "~0.6.0", "datastore-fs": "~0.7.0", "datastore-level": "~0.10.0", "debug": "^4.1.0", "interface-datastore": "~0.6.0", - "ipfs-block": "~0.7.1", + "ipfs-block": "~0.8.0", "lodash.get": "^4.4.2", "lodash.has": "^4.5.2", "lodash.set": "^4.3.2", - "multiaddr": "^5.0.0", + "multiaddr": "^6.0.0", "proper-lockfile": "^3.2.0", "pull-stream": "^3.6.9", "sort-keys": "^2.0.0" diff --git a/src/blockstore.js b/src/blockstore.js index 46a04b91..e38c386c 100644 --- a/src/blockstore.js +++ b/src/blockstore.js @@ -77,9 +77,29 @@ function createBaseStore (store) { }) } - const k = cidToDsKey(cid) - store.get(k, (err, blockData) => { - if (err) { return callback(err) } + const key = cidToDsKey(cid) + store.get(key, (err, blockData) => { + if (err) { + // If not found, we try with the other CID version. + // If exists, then store that block under the CID that was requested. + // Some duplication occurs. + if (err.code === 'ERR_NOT_FOUND') { + const otherCid = cidToOtherVersion(cid) + if (!otherCid) return callback(err) + + const otherKey = cidToDsKey(otherCid) + return store.get(otherKey, (err, blockData) => { + if (err) return callback(err) + + store.put(key, blockData, (err) => { + if (err) return callback(err) + callback(null, new Block(blockData, cid)) + }) + }) + } + + return callback(err) + } callback(null, new Block(blockData, cid)) }) @@ -140,7 +160,16 @@ function createBaseStore (store) { }) } - store.has(cidToDsKey(cid), callback) + store.has(cidToDsKey(cid), (err, exists) => { + if (err) return callback(err) + if (exists) return callback(null, true) + + // If not found, we try with the other CID version. + const otherCid = cidToOtherVersion(cid) + if (!otherCid) return callback(null, false) + + store.has(cidToDsKey(otherCid), callback) + }) }, /** * Delete a block from the store @@ -164,3 +193,11 @@ function createBaseStore (store) { } } } + +function cidToOtherVersion (cid) { + try { + return cid.version === 0 ? cid.toV1() : cid.toV0() + } catch (err) { + return null + } +} diff --git a/src/index.js b/src/index.js index 610506d1..d02446db 100644 --- a/src/index.js +++ b/src/index.js @@ -42,7 +42,7 @@ class IpfsRepo { * @param {object} options - Configuration */ constructor (repoPath, options) { - assert.equal(typeof repoPath, 'string', 'missing repoPath') + assert.strictEqual(typeof repoPath, 'string', 'missing repoPath') this.options = buildOptions(options) this.closed = true @@ -170,7 +170,7 @@ class IpfsRepo { return callback(err, null) } - assert.equal(typeof lockfile.close, 'function', 'Locks must have a close method') + assert.strictEqual(typeof lockfile.close, 'function', 'Locks must have a close method') callback(null, lockfile) }) } @@ -273,7 +273,7 @@ class IpfsRepo { options = {} } - options = Object.assign({}, {human: false}, options) + options = Object.assign({}, { human: false }, options) parallel({ storageMax: (cb) => this.config.get('Datastore.StorageMax', (err, max) => { diff --git a/src/lock.js b/src/lock.js index 38c932ba..60038344 100644 --- a/src/lock.js +++ b/src/lock.js @@ -29,13 +29,15 @@ exports.lock = (dir, callback) => { const file = path.join(dir, lockFile) log('locking %s', file) - lock(dir, {lockfilePath: file, stale: STALE_TIME}) + lock(dir, { lockfilePath: file, stale: STALE_TIME }) .then(release => { - callback(null, {close: (cb) => { - release() - .then(() => cb()) - .catch(err => cb(err)) - }}) + callback(null, { + close: (cb) => { + release() + .then(() => cb()) + .catch(err => cb(err)) + } + }) }) .catch(err => callback(err)) } diff --git a/test/blockstore-test.js b/test/blockstore-test.js index 4813e642..45ae748a 100644 --- a/test/blockstore-test.js +++ b/test/blockstore-test.js @@ -45,7 +45,7 @@ module.exports = (repo) => { }) it('empty value', (done) => { - const d = new Buffer(0) + const d = Buffer.alloc(0) multihashing(d, 'sha2-256', (err, multihash) => { expect(err).to.not.exist() const empty = new Block(d, new CID(multihash)) @@ -70,7 +70,7 @@ module.exports = (repo) => { this.timeout(15000) // add time for ci waterfall([ (cb) => map(_.range(50), (i, cb) => { - const d = new Buffer('many' + Math.random()) + const d = Buffer.from('many' + Math.random()) multihashing(d, 'sha2-256', (err, hash) => { if (err) { return cb(err) @@ -135,6 +135,46 @@ module.exports = (repo) => { done() }) }) + + it('should get block stored under v0 CID with a v1 CID', done => { + const data = Buffer.from(`TEST${Date.now()}`) + + multihashing(data, 'sha2-256', (err, hash) => { + if (err) return done(err) + + const cid = new CID(hash) + + repo.blocks.put(new Block(data, cid), err => { + if (err) return done(err) + + repo.blocks.get(cid.toV1(), (err, block) => { + expect(err).to.not.exist() + expect(block.data).to.eql(data) + done() + }) + }) + }) + }) + + it('should get block stored under v1 CID with a v0 CID', done => { + const data = Buffer.from(`TEST${Date.now()}`) + + multihashing(data, 'sha2-256', (err, hash) => { + if (err) return done(err) + + const cid = new CID(1, 'dag-pb', hash) + + repo.blocks.put(new Block(data, cid), err => { + if (err) return done(err) + + repo.blocks.get(cid.toV0(), (err, block) => { + expect(err).to.not.exist() + expect(block.data).to.eql(data) + done() + }) + }) + }) + }) }) describe('.has', () => { @@ -153,6 +193,46 @@ module.exports = (repo) => { done() }) }) + + it('should have block stored under v0 CID with a v1 CID', done => { + const data = Buffer.from(`TEST${Date.now()}`) + + multihashing(data, 'sha2-256', (err, hash) => { + if (err) return done(err) + + const cid = new CID(hash) + + repo.blocks.put(new Block(data, cid), err => { + if (err) return done(err) + + repo.blocks.has(cid.toV1(), (err, exists) => { + expect(err).to.not.exist() + expect(exists).to.eql(true) + done() + }) + }) + }) + }) + + it('should have block stored under v1 CID with a v0 CID', done => { + const data = Buffer.from(`TEST${Date.now()}`) + + multihashing(data, 'sha2-256', (err, hash) => { + if (err) return done(err) + + const cid = new CID(1, 'dag-pb', hash) + + repo.blocks.put(new Block(data, cid), err => { + if (err) return done(err) + + repo.blocks.has(cid.toV0(), (err, exists) => { + expect(err).to.not.exist() + expect(exists).to.eql(true) + done() + }) + }) + }) + }) }) describe('.delete', () => { diff --git a/test/repo-test.js b/test/repo-test.js index 2287cc00..83c625d3 100644 --- a/test/repo-test.js +++ b/test/repo-test.js @@ -32,10 +32,10 @@ module.exports = (repo) => { it('set config', (done) => { series([ - (cb) => repo.config.set({a: 'b'}, cb), + (cb) => repo.config.set({ a: 'b' }, cb), (cb) => repo.config.get((err, config) => { if (err) return cb(err) - expect(config).to.deep.equal({a: 'b'}) + expect(config).to.deep.equal({ a: 'b' }) cb() }) ], done) @@ -54,7 +54,7 @@ module.exports = (repo) => { (cb) => repo.config.set('c.x', 'd', cb), (cb) => repo.config.get((err, config) => { if (err) return cb(err) - expect(config).to.deep.equal({a: 'b', c: { x: 'd' }}) + expect(config).to.deep.equal({ a: 'b', c: { x: 'd' } }) cb() }) ], done) diff --git a/test/stat-test.js b/test/stat-test.js index c8ae84fb..b263c368 100644 --- a/test/stat-test.js +++ b/test/stat-test.js @@ -26,7 +26,7 @@ module.exports = (repo) => { }) it('get human stats', (done) => { - repo.stat({human: true}, (err, stats) => { + repo.stat({ human: true }, (err, stats) => { expect(err).to.not.exist() expect(stats).to.exist() expect(stats).to.have.property('numObjects')