From 5584b5a97a509c2a504f345394bf2df6f4220bdd Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 7 Nov 2018 11:47:43 +0000 Subject: [PATCH 1/9] refactor: ipns routing logic moved to instantiation --- package.json | 1 + src/core/components/pre-start.js | 11 +++++++++++ src/core/ipns/routing/offline-datastore.js | 3 +++ 3 files changed, 15 insertions(+) diff --git a/package.json b/package.json index f7c4f5ef9d..9f7e710743 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "dependencies": { "@nodeutils/defaults-deep": "^1.1.0", "async": "^2.6.1", + "base32.js": "~0.1.0", "big.js": "^5.2.2", "binary-querystring": "~0.1.2", "bl": "^2.1.2", diff --git a/src/core/components/pre-start.js b/src/core/components/pre-start.js index 13d914acc4..9914a8167e 100644 --- a/src/core/components/pre-start.js +++ b/src/core/components/pre-start.js @@ -7,6 +7,10 @@ const waterfall = require('async/waterfall') const Keychain = require('libp2p-keychain') const defaultsDeep = require('@nodeutils/defaults-deep') const NoKeychain = require('./no-keychain') + +const IPNS = require('../ipns') +const OfflineDatastore = require('../ipns/routing/offline-datastore') + /* * Load stuff from Repo into memory */ @@ -95,6 +99,13 @@ module.exports = function preStart (self) { cb() }, + // Setup offline routing for IPNS. + (cb) => { + const offlineDatastore = new OfflineDatastore(self._repo) + + self._ipns = new IPNS(offlineDatastore, self) + cb() + }, (cb) => self.pin._load(cb) ], callback) } diff --git a/src/core/ipns/routing/offline-datastore.js b/src/core/ipns/routing/offline-datastore.js index d561a5665f..924c4d7e28 100644 --- a/src/core/ipns/routing/offline-datastore.js +++ b/src/core/ipns/routing/offline-datastore.js @@ -4,11 +4,14 @@ const { Key } = require('interface-datastore') const { Record } = require('libp2p-record') const { encodeBase32 } = require('./utils') +<<<<<<< HEAD const errcode = require('err-code') const debug = require('debug') const log = debug('jsipfs:ipns:offline-datastore') log.error = debug('jsipfs:ipns:offline-datastore:error') +======= +>>>>>>> refactor: ipns routing logic moved to instantiation // Offline datastore aims to mimic the same encoding as routing when storing records // to the local datastore class OfflineDatastore { From 013f527b0e213e66d52da8760e86a4d9abe8b4f1 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Fri, 16 Nov 2018 16:48:31 +0000 Subject: [PATCH 2/9] refactor: fix review --- package.json | 1 - src/core/components/pre-start.js | 11 ----------- src/core/ipns/routing/offline-datastore.js | 3 --- 3 files changed, 15 deletions(-) diff --git a/package.json b/package.json index 9f7e710743..f7c4f5ef9d 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "dependencies": { "@nodeutils/defaults-deep": "^1.1.0", "async": "^2.6.1", - "base32.js": "~0.1.0", "big.js": "^5.2.2", "binary-querystring": "~0.1.2", "bl": "^2.1.2", diff --git a/src/core/components/pre-start.js b/src/core/components/pre-start.js index 9914a8167e..13d914acc4 100644 --- a/src/core/components/pre-start.js +++ b/src/core/components/pre-start.js @@ -7,10 +7,6 @@ const waterfall = require('async/waterfall') const Keychain = require('libp2p-keychain') const defaultsDeep = require('@nodeutils/defaults-deep') const NoKeychain = require('./no-keychain') - -const IPNS = require('../ipns') -const OfflineDatastore = require('../ipns/routing/offline-datastore') - /* * Load stuff from Repo into memory */ @@ -99,13 +95,6 @@ module.exports = function preStart (self) { cb() }, - // Setup offline routing for IPNS. - (cb) => { - const offlineDatastore = new OfflineDatastore(self._repo) - - self._ipns = new IPNS(offlineDatastore, self) - cb() - }, (cb) => self.pin._load(cb) ], callback) } diff --git a/src/core/ipns/routing/offline-datastore.js b/src/core/ipns/routing/offline-datastore.js index 924c4d7e28..d561a5665f 100644 --- a/src/core/ipns/routing/offline-datastore.js +++ b/src/core/ipns/routing/offline-datastore.js @@ -4,14 +4,11 @@ const { Key } = require('interface-datastore') const { Record } = require('libp2p-record') const { encodeBase32 } = require('./utils') -<<<<<<< HEAD const errcode = require('err-code') const debug = require('debug') const log = debug('jsipfs:ipns:offline-datastore') log.error = debug('jsipfs:ipns:offline-datastore:error') -======= ->>>>>>> refactor: ipns routing logic moved to instantiation // Offline datastore aims to mimic the same encoding as routing when storing records // to the local datastore class OfflineDatastore { From 219c260f9fd401c07379fcf7d2cb36201d89e178 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 15 Nov 2018 11:00:14 +0000 Subject: [PATCH 3/9] feat: ipns over dht --- package.json | 4 +- src/core/components/libp2p.js | 11 ++ src/core/components/start.js | 12 +- src/core/ipns/publisher.js | 63 ++++--- src/core/ipns/resolver.js | 29 ++- src/core/ipns/routing/utils.js | 13 +- test/cli/name.js | 335 ++++++++++++++++++++++----------- test/core/libp2p.spec.js | 12 ++ test/core/name.js | 158 +++++++++++----- 9 files changed, 435 insertions(+), 202 deletions(-) diff --git a/package.json b/package.json index f7c4f5ef9d..3d96da79a1 100644 --- a/package.json +++ b/package.json @@ -127,10 +127,10 @@ "joi": "^13.4.0", "joi-browser": "^13.4.0", "joi-multiaddr": "^3.0.0", - "libp2p": "~0.24.0", + "libp2p": "~0.24.1", "libp2p-bootstrap": "~0.9.3", "libp2p-crypto": "~0.14.1", - "libp2p-kad-dht": "~0.11.1", + "libp2p-kad-dht": "~0.12.1", "libp2p-keychain": "~0.3.3", "libp2p-mdns": "~0.12.0", "libp2p-mplex": "~0.8.4", diff --git a/src/core/components/libp2p.js b/src/core/components/libp2p.js index 87838cb1e7..d195623467 100644 --- a/src/core/components/libp2p.js +++ b/src/core/components/libp2p.js @@ -3,6 +3,7 @@ const promisify = require('promisify-es6') const get = require('lodash/get') const defaultsDeep = require('@nodeutils/defaults-deep') +const ipnsUtils = require('../ipns/routing/utils') module.exports = function libp2p (self) { return { @@ -16,6 +17,7 @@ module.exports = function libp2p (self) { const defaultBundle = (opts) => { const libp2pDefaults = { + datastore: opts.datastore, peerInfo: opts.peerInfo, peerBook: opts.peerBook, config: { @@ -43,6 +45,14 @@ module.exports = function libp2p (self) { get(opts.config, 'relay.hop.active', false)) } }, + dht: { + validators: { + ipns: ipnsUtils.validator + }, + selectors: { + ipns: ipnsUtils.selector + } + }, EXPERIMENTAL: { dht: get(opts.options, 'EXPERIMENTAL.dht', false), pubsub: get(opts.options, 'EXPERIMENTAL.pubsub', false) @@ -72,6 +82,7 @@ module.exports = function libp2p (self) { self._libp2pNode = libp2pBundle({ options: self._options, config: config, + datastore: self._repo.datastore, peerInfo: self._peerInfo, peerBook: self._peerInfoBook }) diff --git a/src/core/components/start.js b/src/core/components/start.js index 8a8fe10a85..b0053e4150 100644 --- a/src/core/components/start.js +++ b/src/core/components/start.js @@ -54,10 +54,14 @@ module.exports = (self) => { ipnsStores.push(pubsubDs) } - // NOTE: IPNS routing is being replaced by the local repo datastore while the IPNS over DHT is not ready - // When DHT is added, if local option enabled, should receive offlineDatastore as well - const offlineDatastore = new OfflineDatastore(self._repo) - ipnsStores.push(offlineDatastore) + // DHT should be added as routing if we are not running with local flag + // TODO: Need to change this logic once DHT is enabled by default, for now fallback to Offline datastore + if (get(self._options, 'EXPERIMENTAL.dht', false) && !self._options.local) { + ipnsStores.push(self._libp2pNode.dht) + } else { + const offlineDatastore = new OfflineDatastore(self._repo) + ipnsStores.push(offlineDatastore) + } // Create ipns routing with a set of datastores const routing = new TieredDatastore(ipnsStores) diff --git a/src/core/ipns/publisher.js b/src/core/ipns/publisher.js index 4be4fc41bb..aa330ce053 100644 --- a/src/core/ipns/publisher.js +++ b/src/core/ipns/publisher.js @@ -56,7 +56,6 @@ class IpnsPublisher { log.error(errMsg) return callback(errcode(new Error(errMsg), 'ERR_INVALID_PEER_ID')) } - const publicKey = peerId._pubKey ipns.embedPublicKey(publicKey, record, (err, embedPublicKeyRecord) => { @@ -162,45 +161,55 @@ class IpnsPublisher { const checkRouting = !(options.checkRouting === false) this._repo.datastore.get(ipns.getLocalKey(peerId.id), (err, dsVal) => { - let result - if (err) { if (err.code !== 'ERR_NOT_FOUND') { const errMsg = `unexpected error getting the ipns record ${peerId.id} from datastore` log.error(errMsg) return callback(errcode(new Error(errMsg), 'ERR_UNEXPECTED_DATASTORE_RESPONSE')) - } else { - if (!checkRouting) { + } + + if (!checkRouting) { + return callback(null, null) + } + + // Try to get from routing + let keys + try { + keys = ipns.getIdKeys(peerId.toBytes()) + } catch (err) { + log.error(err) + return callback(err) + } + + this._routing.get(keys.routingKey, (err, res) => { + if (err) { + log(`error when determining the last published IPNS record for ${peerId.id}`) return callback(null, null) - } else { - // TODO ROUTING - get from DHT - return callback(new Error('not implemented yet')) } - } - } - if (Buffer.isBuffer(dsVal)) { - result = dsVal + // unmarshal data + this._unmarshalData(res, callback) + }) } else { - const errMsg = `found ipns record that we couldn't convert to a value` - - log.error(errMsg) - return callback(errcode(new Error(errMsg), 'ERR_INVALID_IPNS_RECORD')) + // unmarshal data + this._unmarshalData(dsVal, callback) } + }) + } - // unmarshal data - try { - result = ipns.unmarshal(dsVal) - } catch (err) { - const errMsg = `found ipns record that we couldn't convert to a value` + _unmarshalData (data, callback) { + let result + try { + result = ipns.unmarshal(data) + } catch (err) { + const errMsg = `found ipns record that we couldn't convert to a value` - log.error(errMsg) - return callback(null, null) - } + log.error(errMsg) + return callback(null, null) + } - callback(null, result) - }) + callback(null, result) } _updateOrCreateRecord (privKey, value, validity, peerId, callback) { @@ -212,7 +221,7 @@ class IpnsPublisher { } const getPublishedOptions = { - checkRouting: false // TODO ROUTING - change to true + checkRouting: true } this._getPublished(peerId, getPublishedOptions, (err, record) => { diff --git a/src/core/ipns/resolver.js b/src/core/ipns/resolver.js index 8ff9c38ab3..f1f1931fd6 100644 --- a/src/core/ipns/resolver.js +++ b/src/core/ipns/resolver.js @@ -1,8 +1,10 @@ 'use strict' const ipns = require('ipns') +const crypto = require('libp2p-crypto') const PeerId = require('peer-id') const errcode = require('err-code') +const parallel = require('async/parallel') const debug = require('debug') const log = debug('jsipfs:ipns:resolver') @@ -96,13 +98,14 @@ class IpnsResolver { return callback(err) } - const { routingKey } = ipns.getIdKeys(peerId.toBytes()) + const { routingKey, routingPubKey } = ipns.getIdKeys(peerId.toBytes()) - // TODO DHT - get public key from routing? - // https://github.com/ipfs/go-ipfs/blob/master/namesys/routing.go#L70 - // https://github.com/libp2p/go-libp2p-routing/blob/master/routing.go#L99 - - this._routing.get(routingKey.toBuffer(), (err, res) => { + parallel([ + // Name should be the hash of a public key retrievable from ipfs. + // We retrieve public key to add it to the PeerId, as the IPNS record may not have it. + (cb) => this._routing.get(routingPubKey.toBuffer(), cb), + (cb) => this._routing.get(routingKey.toBuffer(), cb) + ], (err, res) => { if (err) { if (err.code !== 'ERR_NOT_FOUND') { const errMsg = `unexpected error getting the ipns record ${peerId.id}` @@ -116,9 +119,21 @@ class IpnsResolver { return callback(errcode(new Error(errMsg), 'ERR_NO_RECORD_FOUND')) } + // Public key + try { + // Insert it into the peer id public key, to be validated by IPNS validator + peerId.pubKey = crypto.keys.unmarshalPublicKey(res[0]) + } catch (err) { + const errMsg = `found public key record that we couldn't convert to a value` + + log.error(errMsg) + return callback(errcode(new Error(errMsg), 'ERR_INVALID_PUB_KEY_RECEIVED')) + } + + // IPNS entry let ipnsEntry try { - ipnsEntry = ipns.unmarshal(res) + ipnsEntry = ipns.unmarshal(res[1]) } catch (err) { const errMsg = `found ipns record that we couldn't convert to a value` diff --git a/src/core/ipns/routing/utils.js b/src/core/ipns/routing/utils.js index 9dc8b8b992..0d960618ce 100644 --- a/src/core/ipns/routing/utils.js +++ b/src/core/ipns/routing/utils.js @@ -1,9 +1,16 @@ 'use strict' const multibase = require('multibase') +const ipns = require('ipns') -module.exports.encodeBase32 = (buf) => { - const m = multibase.encode('base32', buf).slice(1) // slice off multibase codec +module.exports = { + encodeBase32: (buf) => { + const m = multibase.encode('base32', buf).slice(1) // slice off multibase codec - return m.toString().toUpperCase() // should be uppercase for interop with go + return m.toString().toUpperCase() // should be uppercase for interop with go + }, + validator: { + func: (key, record, cb) => ipns.validator.validate(record, key, cb) + }, + selector: (k, records) => ipns.validator.select(records[0], records[1]) } diff --git a/test/cli/name.js b/test/cli/name.js index 3acfb7b089..20aaca8400 100644 --- a/test/cli/name.js +++ b/test/cli/name.js @@ -16,169 +16,282 @@ const df = DaemonFactory.create({ type: 'js' }) const checkAll = (bits) => string => bits.every(bit => string.includes(bit)) describe('name', () => { - const passPhrase = hat() - const pass = '--pass ' + passPhrase - const name = 'test-key-' + hat() + describe('working locally', () => { + const passPhrase = hat() + const pass = '--pass ' + passPhrase + const name = 'test-key-' + hat() + + let ipfs + let ipfsd + + let cidAdded + let nodeId + let keyId + + before(function (done) { + this.timeout(80 * 1000) + + df.spawn({ + exec: `./src/cli/bin.js`, + config: { + Bootstrap: [] + }, + args: ['--pass', passPhrase, '--local'], + initOptions: { bits: 512 } + }, (err, _ipfsd) => { + expect(err).to.not.exist() + + ipfsd = _ipfsd + ipfs = ipfsExec(_ipfsd.repoPath) + + ipfs(`${pass} key gen ${name} --type rsa --size 2048`) + .then((out) => { + expect(out).to.include(name) + keyId = out.split(' ')[1] + + return ipfs('id') + }) + .then((res) => { + const id = JSON.parse(res) + expect(id).to.have.property('id') + nodeId = id.id - let ipfs - let ipfsd + return ipfs('add src/init-files/init-docs/readme') + }) + .then((out) => { + cidAdded = out.split(' ')[1] + done() + }) + }) + }) - let cidAdded - let nodeId - let keyId + after(function (done) { + if (ipfsd) { + ipfsd.stop(() => done()) + } else { + done() + } + }) - before(function (done) { - this.timeout(80 * 1000) + it('should publish correctly when the file was already added', function () { + this.timeout(60 * 1000) - df.spawn({ - exec: `./src/cli/bin.js`, - config: { - Bootstrap: [] - }, - args: ['--pass', passPhrase, '--local'], - initOptions: { bits: 512 } - }, (err, _ipfsd) => { - expect(err).to.not.exist() + return ipfs(`name publish ${cidAdded}`).then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded, nodeId])) + }) + }) - ipfsd = _ipfsd - ipfs = ipfsExec(_ipfsd.repoPath) + it('should publish and resolve an entry with the default options', function () { + this.timeout(60 * 1000) - ipfs(`${pass} key gen ${name} --type rsa --size 2048`).then((out) => { - expect(out).to.include(name) + return ipfs(`name publish ${cidAdded}`) + .then((res) => { + expect(res).to.exist() - keyId = out.split(' ')[1] + return ipfs('name resolve') + }) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded])) + }) + }) - ipfs('id').then((res) => { - const id = JSON.parse(res) + it('should publish correctly when the file was not added but resolve is disabled', function () { + this.timeout(60 * 1000) - expect(id).to.have.property('id') - nodeId = id.id + const notAddedCid = 'QmPFVLPmp9zv5Z5KUqLhe2EivAGccQW2r7M7jhVJGLZoZU' - ipfs('add src/init-files/init-docs/readme').then((out) => { - cidAdded = out.split(' ')[1] - done() - }) - }) + return ipfs(`name publish ${notAddedCid} --resolve false`).then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([notAddedCid, nodeId])) }) }) - }) - after(function (done) { - if (ipfsd) { - ipfsd.stop(() => done()) - } else { - done() - } - }) + it('should not get the entry correctly if its validity time expired', function () { + this.timeout(60 * 1000) - it('should publish correctly when the file was already added', function (done) { - this.timeout(60 * 1000) + return ipfs(`name publish ${cidAdded} --lifetime 10ns`) + .then((res) => { + expect(res).to.exist() - ipfs(`name publish ${cidAdded}`).then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([cidAdded, nodeId])) + setTimeout(function () { + return ipfs('name resolve') + .then((res) => { + expect(res).to.not.exist() + }) + .catch((err) => { + expect(err).to.exist() + }) + }, 1) + }) + }) + + it('should publish correctly when a new key is used', function () { + this.timeout(60 * 1000) - done() + return ipfs(`name publish ${cidAdded} --key ${name}`).then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded, keyId])) + }) }) - }) - it('should publish and resolve an entry with the default options', function (done) { - this.timeout(60 * 1000) + it('should return the immediate pointing record, unless using the recursive parameter', function () { + this.timeout(60 * 1000) - ipfs(`name publish ${cidAdded}`).then((res) => { - expect(res).to.exist() + return ipfs(`name publish ${cidAdded}`) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded, nodeId])) - ipfs('name resolve').then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([cidAdded])) + return ipfs(`name publish /ipns/${nodeId} --key ${name}`) + }) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([nodeId, keyId])) - done() - }) + return ipfs(`name resolve ${keyId}`) + }) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([nodeId])) + }) }) - }) - it('should publish correctly when the file was not added but resolve is disabled', function (done) { - this.timeout(60 * 1000) + it('should go recursively until finding an ipfs hash', function () { + this.timeout(60 * 1000) - const notAddedCid = 'QmPFVLPmp9zv5Z5KUqLhe2EivAGccQW2r7M7jhVJGLZoZU' + return ipfs(`name publish ${cidAdded}`) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded, nodeId])) - ipfs(`name publish ${notAddedCid} --resolve false`).then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([notAddedCid, nodeId])) + return ipfs(`name publish /ipns/${nodeId} --key ${name}`) + }) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([nodeId, keyId])) - done() + return ipfs(`name resolve ${keyId} --recursive`) + }) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded])) + }) }) }) - it('should not get the entry correctly if its validity time expired', function (done) { - this.timeout(60 * 1000) + describe('using dht', () => { + const passPhrase = hat() + const pass = '--pass ' + passPhrase + const name = 'test-key-' + hat() + + let ipfs + let ipfsd + + let cidAdded + let nodeId + let keyId + + before(function (done) { + this.timeout(80 * 1000) - ipfs(`name publish ${cidAdded} --lifetime 10ns`).then((res) => { - expect(res).to.exist() + df.spawn({ + exec: `./src/cli/bin.js`, + config: { + Bootstrap: [] + }, + args: ['--pass', passPhrase, '--enable-dht-experiment'], + initOptions: { bits: 512 } + }, (err, _ipfsd) => { + expect(err).to.not.exist() - setTimeout(function () { - ipfs('name resolve') + ipfsd = _ipfsd + ipfs = ipfsExec(_ipfsd.repoPath) + + ipfs(`${pass} key gen ${name} --type rsa --size 2048`) + .then((out) => { + expect(out).to.include(name) + keyId = out.split(' ')[1] + + return ipfs('id') + }) .then((res) => { - expect(res).to.not.exist() + const id = JSON.parse(res) + expect(id).to.have.property('id') + nodeId = id.id + + return ipfs('add src/init-files/init-docs/readme') }) - .catch((err) => { - expect(err).to.exist() + .then((out) => { + cidAdded = out.split(' ')[1] done() }) - }, 1) + }) }) - }) - - it('should publish correctly when a new key is used', function (done) { - this.timeout(60 * 1000) - ipfs(`name publish ${cidAdded} --key ${name}`).then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([cidAdded, keyId])) - - done() + after(function (done) { + if (ipfsd) { + ipfsd.stop(() => done()) + } else { + done() + } }) - }) - it('should return the immediate pointing record, unless using the recursive parameter', function (done) { - this.timeout(60 * 1000) + it('should publish and resolve an entry with the default options', function () { + this.timeout(60 * 1000) - ipfs(`name publish ${cidAdded}`).then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([cidAdded, nodeId])) + return ipfs(`name publish ${cidAdded}`) + .then((res) => { + expect(res).to.exist() - ipfs(`name publish /ipns/${nodeId} --key ${name}`).then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([nodeId, keyId])) + return ipfs('name resolve') + }) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded])) + }) + }) + + it('should not get the entry correctly if its validity time expired', function () { + this.timeout(60 * 1000) - ipfs(`name resolve ${keyId}`).then((res) => { + return ipfs(`name publish ${cidAdded} --lifetime 10ns`) + .then((res) => { expect(res).to.exist() - expect(res).to.satisfy(checkAll([nodeId])) - done() + setTimeout(function () { + return ipfs('name resolve') + .then((res) => { + expect(res).to.not.exist() + }) + .catch((err) => { + expect(err).to.exist() + }) + }, 1) }) - }) }) - }) - - it('should go recursively until finding an ipfs hash', function (done) { - this.timeout(60 * 1000) - ipfs(`name publish ${cidAdded}`).then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([cidAdded, nodeId])) + it('should return the immediate pointing record, unless using the recursive parameter', function () { + this.timeout(60 * 1000) - ipfs(`name publish /ipns/${nodeId} --key ${name}`).then((res) => { - expect(res).to.exist() - expect(res).to.satisfy(checkAll([nodeId, keyId])) + return ipfs(`name publish ${cidAdded}`) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([cidAdded, nodeId])) - ipfs(`name resolve ${keyId} --recursive`).then((res) => { + return ipfs(`name publish /ipns/${nodeId} --key ${name}`) + }) + .then((res) => { expect(res).to.exist() - expect(res).to.satisfy(checkAll([cidAdded])) + expect(res).to.satisfy(checkAll([nodeId, keyId])) - done() + return ipfs(`name resolve ${keyId}`) + }) + .then((res) => { + expect(res).to.exist() + expect(res).to.satisfy(checkAll([nodeId])) }) - }) }) }) }) diff --git a/test/core/libp2p.spec.js b/test/core/libp2p.spec.js index 19248eb535..aacc4215a3 100644 --- a/test/core/libp2p.spec.js +++ b/test/core/libp2p.spec.js @@ -7,6 +7,7 @@ const dirtyChai = require('dirty-chai') const expect = chai.expect chai.use(dirtyChai) +const MemoryStore = require('interface-datastore').MemoryDatastore const PeerInfo = require('peer-info') const PeerBook = require('peer-book') const WebSocketStar = require('libp2p-websocket-star') @@ -20,6 +21,7 @@ describe('libp2p customization', function () { // Provide some extra time for ci since we're starting libp2p nodes in each test this.timeout(15 * 1000) + let datastore let peerInfo let peerBook let mockConfig @@ -49,6 +51,7 @@ describe('libp2p customization', function () { }) } } + datastore = new MemoryStore() peerBook = new PeerBook() PeerInfo.create((err, pi) => { peerInfo = pi @@ -68,6 +71,9 @@ describe('libp2p customization', function () { describe('bundle', () => { it('should allow for using a libp2p bundle', (done) => { const ipfs = { + _repo: { + datastore + }, _peerInfo: peerInfo, _peerBook: peerBook, config: mockConfig, @@ -111,6 +117,9 @@ describe('libp2p customization', function () { describe('options', () => { it('should use options by default', (done) => { const ipfs = { + _repo: { + datastore + }, _peerInfo: peerInfo, _peerBook: peerBook, config: mockConfig @@ -150,6 +159,9 @@ describe('libp2p customization', function () { const wsstar = new WebSocketStar({ id: peerInfo.id }) const ipfs = { + _repo: { + datastore + }, _peerInfo: peerInfo, _peerBook: peerBook, config: mockConfig, diff --git a/test/core/name.js b/test/core/name.js index 08bb9b06da..7aa11ecdfe 100644 --- a/test/core/name.js +++ b/test/core/name.js @@ -10,6 +10,8 @@ chai.use(dirtyChai) const sinon = require('sinon') const fs = require('fs') +const parallel = require('async/parallel') +const series = require('async/series') const isNode = require('detect-node') const IPFS = require('../../src') @@ -21,6 +23,19 @@ const df = DaemonFactory.create({ type: 'proc' }) const ipfsRef = '/ipfs/QmPFVLPmp9zv5Z5KUqLhe2EivAGccQW2r7M7jhVJGLZoZU' +const publishAndResolve = (publisher, resolver, ipfsRef, publishOpts, nodeId, resolveOpts, callback) => { + series([ + (cb) => publisher.name.publish(ipfsRef, publishOpts, cb), + (cb) => resolver.name.resolve(nodeId, resolveOpts, cb) + ], (err, res) => { + expect(err).to.not.exist() + expect(res[0]).to.exist() + expect(res[1]).to.exist() + expect(res[1].path).to.equal(ipfsRef) + callback() + }) +} + describe('name', function () { if (!isNode) { return @@ -54,31 +69,16 @@ describe('name', function () { after((done) => ipfsd.stop(done)) it('should publish and then resolve correctly with the default options', function (done) { - node.name.publish(ipfsRef, { resolve: false }, (err, res) => { - expect(err).to.not.exist() - expect(res).to.exist() - - node.name.resolve(nodeId, (err, res) => { - expect(err).to.not.exist() - expect(res).to.exist() - expect(res.path).to.equal(ipfsRef) - done() - }) - }) + publishAndResolve(node, node, ipfsRef, { resolve: false }, nodeId, {}, done) }) it('should publish correctly with the lifetime option and resolve', function (done) { - node.name.publish(ipfsRef, { resolve: false, lifetime: '2h' }, (err, res) => { - expect(err).to.not.exist() - expect(res).to.exist() + const publishOpts = { + resolve: false, + lifetime: '2h' + } - node.name.resolve(nodeId, (err, res) => { - expect(err).to.not.exist() - expect(res).to.exist() - expect(res.path).to.equal(ipfsRef) - done() - }) - }) + publishAndResolve(node, node, ipfsRef, publishOpts, nodeId, {}, done) }) it('should not get the entry correctly if its validity time expired', function (done) { @@ -101,20 +101,15 @@ describe('name', function () { node.key.gen(keyName, { type: 'rsa', size: 2048 }, function (err, key) { expect(err).to.not.exist() - - node.name.publish(ipfsRef, { resolve: false }, (err) => { + series([ + (cb) => node.name.publish(ipfsRef, { resolve: false }, cb), + (cb) => node.name.publish(`/ipns/${nodeId}`, { resolve: false, key: keyName }, cb), + (cb) => node.name.resolve(key.id, { recursive: true }, cb) + ], (err, res) => { expect(err).to.not.exist() - - node.name.publish(`/ipns/${nodeId}`, { resolve: false, key: keyName }, (err) => { - expect(err).to.not.exist() - - node.name.resolve(key.id, { recursive: true }, (err, res) => { - expect(err).to.not.exist() - expect(res).to.exist() - expect(res.path).to.equal(ipfsRef) - done() - }) - }) + expect(res[2]).to.exist() + expect(res[2].path).to.equal(ipfsRef) + done() }) }) }) @@ -125,20 +120,15 @@ describe('name', function () { node.key.gen(keyName, { type: 'rsa', size: 2048 }, function (err, key) { expect(err).to.not.exist() - - node.name.publish(ipfsRef, { resolve: false }, (err) => { + series([ + (cb) => node.name.publish(ipfsRef, { resolve: false }, cb), + (cb) => node.name.publish(`/ipns/${nodeId}`, { resolve: false, key: keyName }, cb), + (cb) => node.name.resolve(key.id, cb) + ], (err, res) => { expect(err).to.not.exist() - - node.name.publish(`/ipns/${nodeId}`, { resolve: false, key: keyName }, (err) => { - expect(err).to.not.exist() - - node.name.resolve(key.id, (err, res) => { - expect(err).to.not.exist() - expect(res).to.exist() - expect(res.path).to.equal(`/ipns/${nodeId}`) - done() - }) - }) + expect(res[2]).to.exist() + expect(res[2].path).to.equal(`/ipns/${nodeId}`) + done() }) }) }) @@ -197,6 +187,78 @@ describe('name', function () { }) }) + describe('work with dht', () => { + let nodes + let nodeA + let nodeB + let nodeC + let idA + + const createNode = (callback) => { + df.spawn({ + exec: IPFS, + args: [`--pass ${hat()}`, '--enable-dht-experiment'], + config: { Bootstrap: [] } + }, callback) + } + + before(function (done) { + this.timeout(40 * 1000) + + parallel([ + (cb) => createNode(cb), + (cb) => createNode(cb), + (cb) => createNode(cb) + ], (err, _nodes) => { + expect(err).to.not.exist() + + nodes = _nodes + nodeA = _nodes[0].api + nodeB = _nodes[1].api + nodeC = _nodes[2].api + + parallel([ + (cb) => nodeA.id(cb), + (cb) => nodeB.id(cb) + ], (err, ids) => { + expect(err).to.not.exist() + + idA = ids[0] + parallel([ + (cb) => nodeC.swarm.connect(ids[0].addresses[0], cb), // C => A + (cb) => nodeC.swarm.connect(ids[1].addresses[0], cb) // C => B + ], done) + }) + }) + }) + + after((done) => parallel(nodes.map((node) => (cb) => node.stop(cb)), done)) + + it('should publish and then resolve correctly with the default options', function (done) { + this.timeout(50 * 1000) + publishAndResolve(nodeA, nodeB, ipfsRef, { resolve: false }, idA.id, {}, done) + }) + + it('should recursively resolve to an IPFS hash', function (done) { + this.timeout(80 * 1000) + const keyName = hat() + + nodeA.key.gen(keyName, { type: 'rsa', size: 2048 }, function (err, key) { + expect(err).to.not.exist() + series([ + (cb) => nodeA.name.publish(ipfsRef, { resolve: false }, cb), + (cb) => nodeA.name.publish(`/ipns/${idA.id}`, { resolve: false, key: keyName }, cb), + (cb) => nodeB.name.resolve(key.id, { recursive: true }, cb) + ], (err, res) => { + expect(err).to.not.exist() + expect(res[2]).to.exist() + expect(res[2].path).to.equal(ipfsRef) + done() + }) + }) + }) + }) + describe('errors', function () { if (!isNode) { return @@ -354,7 +416,7 @@ describe('name', function () { node.name.resolve(nodeId, { nocache: true }, (err, res) => { expect(err).to.exist() - expect(err.code).to.equal('ERR_INVALID_RECORD_RECEIVED') + expect(err.code).to.equal('ERR_INVALID_PUB_KEY_RECEIVED') stub.restore() done() }) From 8e225d337d7a00ea1166f87c516327b794c0e7b6 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 3 Dec 2018 15:46:14 +0000 Subject: [PATCH 4/9] fix: code review --- src/core/ipns/publisher.js | 15 ++++++++++----- test/core/name.js | 2 +- test/fixtures/go-ipfs-repo/datastore/CURRENT | 2 +- .../{MANIFEST-000017 => MANIFEST-000021} | Bin 323 -> 323 bytes test/fixtures/go-ipfs-repo/datastore_spec | 1 + 5 files changed, 13 insertions(+), 7 deletions(-) rename test/fixtures/go-ipfs-repo/datastore/{MANIFEST-000017 => MANIFEST-000021} (91%) create mode 100644 test/fixtures/go-ipfs-repo/datastore_spec diff --git a/src/core/ipns/publisher.js b/src/core/ipns/publisher.js index aa330ce053..2220d28174 100644 --- a/src/core/ipns/publisher.js +++ b/src/core/ipns/publisher.js @@ -182,10 +182,9 @@ class IpnsPublisher { return callback(err) } - this._routing.get(keys.routingKey, (err, res) => { + this._routing.get(keys.routingKey.toBuffer(), (err, res) => { if (err) { - log(`error when determining the last published IPNS record for ${peerId.id}`) - return callback(null, null) + return callback(err) } // unmarshal data @@ -206,7 +205,7 @@ class IpnsPublisher { const errMsg = `found ipns record that we couldn't convert to a value` log.error(errMsg) - return callback(null, null) + return callback(errcode(new Error(errMsg), 'ERR_INVALID_RECORD_DATA')) } callback(null, result) @@ -226,11 +225,17 @@ class IpnsPublisher { this._getPublished(peerId, getPublishedOptions, (err, record) => { if (err) { - return callback(err) + if (err.code !== 'ERR_NOT_FOUND') { + const errMsg = `unexpected error when determining the last published IPNS record for ${peerId.id}` + + log.error(errMsg) + return callback(errcode(new Error(errMsg), 'ERR_DETERMINING_PUBLISHED_RECORD')) + } } // Determinate the record sequence number let seqNumber = 0 + if (record && record.sequence !== undefined) { seqNumber = record.value.toString() !== value ? record.sequence + 1 : record.sequence } diff --git a/test/core/name.js b/test/core/name.js index 7aa11ecdfe..e43627ea94 100644 --- a/test/core/name.js +++ b/test/core/name.js @@ -340,7 +340,7 @@ describe('name', function () { node.name.publish(ipfsRef, { resolve: false }, (err, res) => { expect(err).to.exist() - expect(err.code).to.equal('ERR_UNEXPECTED_DATASTORE_RESPONSE') + expect(err.code).to.equal('ERR_DETERMINING_PUBLISHED_RECORD') stub.restore() done() diff --git a/test/fixtures/go-ipfs-repo/datastore/CURRENT b/test/fixtures/go-ipfs-repo/datastore/CURRENT index 056df57bb7..e60e1543b3 100644 --- a/test/fixtures/go-ipfs-repo/datastore/CURRENT +++ b/test/fixtures/go-ipfs-repo/datastore/CURRENT @@ -1 +1 @@ -MANIFEST-000017 +MANIFEST-000021 diff --git a/test/fixtures/go-ipfs-repo/datastore/MANIFEST-000017 b/test/fixtures/go-ipfs-repo/datastore/MANIFEST-000021 similarity index 91% rename from test/fixtures/go-ipfs-repo/datastore/MANIFEST-000017 rename to test/fixtures/go-ipfs-repo/datastore/MANIFEST-000021 index fb6bc82f413acedd0bc88da0ecde34ce80ba3ea9..dd5db1fec077fde75c2553a79525612b9c7e5cbf 100644 GIT binary patch delta 23 ecmX@ibeL&_2_yemm!;Jl42(=-oD9t3EW7|yF9ihv delta 23 ecmX@ibeL&_2_t`^l=)r`21X_!P6lRS7G3~H=>$6f diff --git a/test/fixtures/go-ipfs-repo/datastore_spec b/test/fixtures/go-ipfs-repo/datastore_spec new file mode 100644 index 0000000000..7bf9626c24 --- /dev/null +++ b/test/fixtures/go-ipfs-repo/datastore_spec @@ -0,0 +1 @@ +{"mounts":[{"mountpoint":"/blocks","path":"blocks","shardFunc":"/repo/flatfs/shard/v1/next-to-last/2","type":"flatfs"},{"mountpoint":"/","path":"datastore","type":"levelds"}],"type":"mount"} \ No newline at end of file From 5f8fbd36b0a93c153a18d206af6e50dc371c5858 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 3 Dec 2018 23:13:08 +0000 Subject: [PATCH 5/9] chore: fix line --- src/core/ipns/publisher.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ipns/publisher.js b/src/core/ipns/publisher.js index 2220d28174..b6d047f0d5 100644 --- a/src/core/ipns/publisher.js +++ b/src/core/ipns/publisher.js @@ -235,7 +235,6 @@ class IpnsPublisher { // Determinate the record sequence number let seqNumber = 0 - if (record && record.sequence !== undefined) { seqNumber = record.value.toString() !== value ? record.sequence + 1 : record.sequence } From 21ba08419c87e0545493228f161af710f8c728d7 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 4 Dec 2018 11:15:22 +0000 Subject: [PATCH 6/9] fix: publick key from routing --- src/core/ipns/resolver.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/core/ipns/resolver.js b/src/core/ipns/resolver.js index f1f1931fd6..264b8862bb 100644 --- a/src/core/ipns/resolver.js +++ b/src/core/ipns/resolver.js @@ -4,7 +4,7 @@ const ipns = require('ipns') const crypto = require('libp2p-crypto') const PeerId = require('peer-id') const errcode = require('err-code') -const parallel = require('async/parallel') +const auto = require('async/auto') const debug = require('debug') const log = debug('jsipfs:ipns:resolver') @@ -100,13 +100,13 @@ class IpnsResolver { const { routingKey, routingPubKey } = ipns.getIdKeys(peerId.toBytes()) - parallel([ + auto({ // Name should be the hash of a public key retrievable from ipfs. // We retrieve public key to add it to the PeerId, as the IPNS record may not have it. - (cb) => this._routing.get(routingPubKey.toBuffer(), cb), - (cb) => this._routing.get(routingKey.toBuffer(), cb) - ], (err, res) => { - if (err) { + pubKey: (cb) => this._routing.get(routingPubKey.toBuffer(), cb), + record: (cb) => this._routing.get(routingKey.toBuffer(), cb) + }, (err, res) => { + if (err && !res.record) { if (err.code !== 'ERR_NOT_FOUND') { const errMsg = `unexpected error getting the ipns record ${peerId.id}` @@ -119,21 +119,24 @@ class IpnsResolver { return callback(errcode(new Error(errMsg), 'ERR_NO_RECORD_FOUND')) } - // Public key - try { - // Insert it into the peer id public key, to be validated by IPNS validator - peerId.pubKey = crypto.keys.unmarshalPublicKey(res[0]) - } catch (err) { - const errMsg = `found public key record that we couldn't convert to a value` + // If public key was found in the routing, add it to the peer id + // otherwise, wait to check if it is embedded in the record. + if (res.pubKey) { + try { + // Insert it into the peer id public key, to be validated by IPNS validator + peerId.pubKey = crypto.keys.unmarshalPublicKey(res.pubKey) + } catch (err) { + const errMsg = `found public key record that we couldn't convert to a value` - log.error(errMsg) - return callback(errcode(new Error(errMsg), 'ERR_INVALID_PUB_KEY_RECEIVED')) + log.error(errMsg) + return callback(errcode(new Error(errMsg), 'ERR_INVALID_PUB_KEY_RECEIVED')) + } } // IPNS entry let ipnsEntry try { - ipnsEntry = ipns.unmarshal(res[1]) + ipnsEntry = ipns.unmarshal(res.record) } catch (err) { const errMsg = `found ipns record that we couldn't convert to a value` From 0d4e18a4d1eab8578e0b99a85c4eb42b0277cf87 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 4 Dec 2018 14:46:19 +0000 Subject: [PATCH 7/9] fix: ci --- ...HSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data | 4 - ...B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data | Bin 101 -> 0 bytes ...XJQPHVD7YSPD5KS75DRO7Q55ADVNORRBXV75Y.data | Bin 0 -> 10765 bytes ...SIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data | 3 - ...YVY4BA22FPHUIODJEXS4LCTQDWA275XAJDAPI.data | Bin 309 -> 0 bytes ...LZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data | 4 - ...774EZOYCYNHPRVFD53ZSAU7237F67XDSQGCYQ.data | Bin 10807 -> 0 bytes ...RTG5JS3JCUJDQM2DRB5RVF33DCUUOFJNGVDUI.data | Bin 10849 -> 0 bytes ...YNRNMP2VDKWBWGAEDDEJDACM3SGG3VIANDDXI.data | Bin 10765 -> 0 bytes ...VPZNQ6C4TJVSVGFTWWOTHP7GWZYGDUP5HIEXY.data | 4 + ...LJNXLLHZOPGSL2PBC65D4UIVWM6TI5F5TAFNI.data | 24 ---- ...VXLWEU4FWPVGT24VJT7DUZPTNLF25N25IGGQA.data | 4 - ...WJNESD7XHQSXA5EGJVNTPVHD7444C2KLKXHDI.data | Bin 10765 -> 0 bytes ...2DCW7R77FRIVHQ3V5OIPPS3XQBX34KRPNOIRQ.data | 3 - ...ZU7XAJL2BMIHGVB5ZR2IOKOSTRMLIKPB6K5I.data} | Bin 309 -> 402 bytes ...33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data | 3 - ...UGKFK27IE33WKGJNDW2TY3LSBNQ34R6OVOOQ.data} | 8 +- ...WYQZTRR5QVLP7VBQYAYW2Y5BAPOOGTW5H2PJQ.data | 3 + ...ML4UD5A3R4QRAVBI7NVH3PL64D3IJCWR2SPUQ.data | 36 ++++++ ...HTQ7R247ZI7KJWP3QWPQYS43LFULQC5ANLQFI.data | Bin 10765 -> 0 bytes ...GPPLZNZOMHHZVIU76LCD5GF5DWFPEGEKODQPI.data | 4 + ...OV2GWVMLAJPVEUMDMFKJZE7CMZESO6TYFAS2I.data | 3 + ...LP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data | 3 - ...D6VA64TGWP67KYA3AIMBUMVWGZ5AQN2L2HSWQ.data | Bin 10765 -> 0 bytes ...ANT6IBNTFN7WR5RPD5F6GN6MBKUUO25DNOTWQ.data | Bin 10891 -> 0 bytes ...NH7VEGIQJRPL6J7FT2XYVKAXT4MQPXXPUYUNY.data | Bin 10765 -> 0 bytes ...XCX5XMZLMGTYVODWPEDIW7JYEG7YXBIA7IUWY.data | 3 - ...LOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data | 114 ------------------ ...MFARFMBIEICCIO6SVSAMQB7VUE6LW7QNX3WGQ.data | Bin 0 -> 10807 bytes ...2FSMG76VV256I4PXBULZZ5ASNLK4FL4EG7XOI.data | Bin 10849 -> 0 bytes ...5KVN6ALXC6QRHK2X4R6EUFRMBB5OSFO2FUYDQ.data | 3 - ...EBXFD5QN6MTI5YBYMCVQJDXPKCOVR6RMLHZFQ.data | Bin 10807 -> 0 bytes test/fixtures/go-ipfs-repo/config | 102 ++++++---------- .../go-ipfs-repo/datastore/000002.ldb | Bin 211 -> 0 bytes .../go-ipfs-repo/datastore/000005.ldb | Bin 1120 -> 1815 bytes .../go-ipfs-repo/datastore/000010.ldb | Bin 1143 -> 0 bytes test/fixtures/go-ipfs-repo/datastore/CURRENT | 2 +- test/fixtures/go-ipfs-repo/datastore/LOG | 6 +- test/fixtures/go-ipfs-repo/datastore/LOG.old | 2 +- .../go-ipfs-repo/datastore/MANIFEST-000004 | Bin 0 -> 149 bytes .../go-ipfs-repo/datastore/MANIFEST-000021 | Bin 323 -> 0 bytes test/http-api/config.js | 1 + test/http-api/id.js | 4 +- test/http-api/inject/files.js | 3 +- test/http-api/inject/id.js | 4 +- test/http-api/inject/pin.js | 12 +- 46 files changed, 112 insertions(+), 250 deletions(-) delete mode 100644 test/fixtures/go-ipfs-repo/blocks/2F/CIQEUWUVLBXVFYSYCHHSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/75/CIQMB7DLJFKD267QJ2B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data create mode 100644 test/fixtures/go-ipfs-repo/blocks/75/CIQMUSJFXRZX7ZRBICXJQPHVD7YSPD5KS75DRO7Q55ADVNORRBXV75Y.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/AE/CIQONICFQZH7QVU6IPSIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/AP/CIQHAKDLTL5GMIFGN5YVY4BA22FPHUIODJEXS4LCTQDWA275XAJDAPI.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/C4/CIQDDZ5EDQK5AP7LRTLZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/CY/CIQDMKFEUGKSLXMEXO774EZOYCYNHPRVFD53ZSAU7237F67XDSQGCYQ.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/DU/CIQLBK52T5EHVHZY5URTG5JS3JCUJDQM2DRB5RVF33DCUUOFJNGVDUI.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/DX/CIQPDQJBGYDZNMOAGGYNRNMP2VDKWBWGAEDDEJDACM3SGG3VIANDDXI.data create mode 100644 test/fixtures/go-ipfs-repo/blocks/EX/CIQKA7ZA5YM6KOJE3HVPZNQ6C4TJVSVGFTWWOTHP7GWZYGDUP5HIEXY.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/FN/CIQIXBZMUTXFC5QIGMLJNXLLHZOPGSL2PBC65D4UIVWM6TI5F5TAFNI.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/GQ/CIQH7OEYWXL34RWYL7VXLWEU4FWPVGT24VJT7DUZPTNLF25N25IGGQA.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/HD/CIQDDVW2EZIJF4NQH7WJNESD7XHQSXA5EGJVNTPVHD7444C2KLKXHDI.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/IR/CIQERMRAAFXUAUOX3V2DCW7R77FRIVHQ3V5OIPPS3XQBX34KRPNOIRQ.data rename test/fixtures/go-ipfs-repo/blocks/{5X/CIQJ23BL4UHXA2KTI6NLTXZM4PW4VEFWQBJ4ACZQAS37BLGL4HUO5XY.data => K5/CIQPW4MAGTUNEBGZCEFZU7XAJL2BMIHGVB5ZR2IOKOSTRMLIKPB6K5I.data} (50%) delete mode 100644 test/fixtures/go-ipfs-repo/blocks/O6/CIQOYW2THIZBRGI7IN33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data rename test/fixtures/go-ipfs-repo/blocks/{5V/CIQFFRR4O52TS2Z7QLDDTF32OIR4FWLKT5YLL7MLDVIT7DC3NHOK5VA.data => OO/CIQBT4N7PS5IZ5IG2ZOUGKFK27IE33WKGJNDW2TY3LSBNQ34R6OVOOQ.data} (82%) create mode 100644 test/fixtures/go-ipfs-repo/blocks/PJ/CIQB4F7VKKQDXHMXX6WYQZTRR5QVLP7VBQYAYW2Y5BAPOOGTW5H2PJQ.data create mode 100644 test/fixtures/go-ipfs-repo/blocks/PU/CIQJF2E6OPOEYYEVHYML4UD5A3R4QRAVBI7NVH3PL64D3IJCWR2SPUQ.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/QF/CIQGPALRQ24P6NS4OWHTQ7R247ZI7KJWP3QWPQYS43LFULQC5ANLQFI.data create mode 100644 test/fixtures/go-ipfs-repo/blocks/QP/CIQNLGENZXNRUMUHZYGPPLZNZOMHHZVIU76LCD5GF5DWFPEGEKODQPI.data create mode 100644 test/fixtures/go-ipfs-repo/blocks/S2/CIQPF3CHDB5GQ5ZBISOV2GWVMLAJPVEUMDMFKJZE7CMZESO6TYFAS2I.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/S5/CIQHBGZNZRPWVEFNMTLP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/SW/CIQHPUVCWD6JA6AFUVD6VA64TGWP67KYA3AIMBUMVWGZ5AQN2L2HSWQ.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/TW/CIQFEAGMNNXXTYKYQSANT6IBNTFN7WR5RPD5F6GN6MBKUUO25DNOTWQ.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/UN/CIQOMBKARLB7PAITVSNH7VEGIQJRPL6J7FT2XYVKAXT4MQPXXPUYUNY.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/UW/CIQDVKITASFS55MC2TXCX5XMZLMGTYVODWPEDIW7JYEG7YXBIA7IUWY.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/VO/CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data create mode 100644 test/fixtures/go-ipfs-repo/blocks/WG/CIQN2ZNT35EZ4XBIEYMFARFMBIEICCIO6SVSAMQB7VUE6LW7QNX3WGQ.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/XO/CIQJGO2B2N75IUEM372FSMG76VV256I4PXBULZZ5ASNLK4FL4EG7XOI.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/YD/CIQENVCICS44LLYUDQ5KVN6ALXC6QRHK2X4R6EUFRMBB5OSFO2FUYDQ.data delete mode 100644 test/fixtures/go-ipfs-repo/blocks/ZF/CIQLBS5HG4PRCRQ7O4EBXFD5QN6MTI5YBYMCVQJDXPKCOVR6RMLHZFQ.data delete mode 100644 test/fixtures/go-ipfs-repo/datastore/000002.ldb delete mode 100644 test/fixtures/go-ipfs-repo/datastore/000010.ldb create mode 100644 test/fixtures/go-ipfs-repo/datastore/MANIFEST-000004 delete mode 100644 test/fixtures/go-ipfs-repo/datastore/MANIFEST-000021 diff --git a/test/fixtures/go-ipfs-repo/blocks/2F/CIQEUWUVLBXVFYSYCHHSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data b/test/fixtures/go-ipfs-repo/blocks/2F/CIQEUWUVLBXVFYSYCHHSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data deleted file mode 100644 index 4145619655..0000000000 --- a/test/fixtures/go-ipfs-repo/blocks/2F/CIQEUWUVLBXVFYSYCHHSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data +++ /dev/null @@ -1,4 +0,0 @@ - -ys# js-ipfs-repo -Implementation of the IPFS repo spec (https://github.com/ipfs/specs/tree/master/repo) in JavaScript -s \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/75/CIQMB7DLJFKD267QJ2B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data b/test/fixtures/go-ipfs-repo/blocks/75/CIQMB7DLJFKD267QJ2B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data deleted file mode 100644 index c9885c45d7e7c10d02b98208d40cfd7b8bfaed21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101 zcmWgA=TZ_+Kwo-;;PadOz%uNME$6+{JHE$$U!OUW!sO)in> z4G}T|X$WFClbv7rFrua5=1<0)Q}=J#b|1g=-GiXI3(2#~S zq#+GyNJARZkcKp*Aq{CrLmJYMhBTxh4QWV28q$!4G^8O7X-GpF(vXIKpke5RZra~< HCdqHU=u7k0 literal 0 HcmV?d00001 diff --git a/test/fixtures/go-ipfs-repo/blocks/AE/CIQONICFQZH7QVU6IPSIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data b/test/fixtures/go-ipfs-repo/blocks/AE/CIQONICFQZH7QVU6IPSIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data deleted file mode 100644 index 6860441aa1..0000000000 --- a/test/fixtures/go-ipfs-repo/blocks/AE/CIQONICFQZH7QVU6IPSIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data +++ /dev/null @@ -1,3 +0,0 @@ -/ -" gq6\u8~:6~gZ.directT2 -" 6(%݄.Ӿ5(ab recursiveT \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/AP/CIQHAKDLTL5GMIFGN5YVY4BA22FPHUIODJEXS4LCTQDWA275XAJDAPI.data b/test/fixtures/go-ipfs-repo/blocks/AP/CIQHAKDLTL5GMIFGN5YVY4BA22FPHUIODJEXS4LCTQDWA275XAJDAPI.data deleted file mode 100644 index 74de75af616ff437b5c7a3a5272281eac2146b6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309 zcmWgA<5Ch*SgK>j#LTl(=mjz6J*Z#Z`mUeibke1%>*qt`A@ymo*6O-~wOC)CS z3K@XZPnu<5V|lBKJN>}4>2CTNRSd^0_H1qVw~ozKk4Ii%i@p$ha(-S(VseSZ2}U7Z zkd6rls>-Jxlr$AsHtpiyKm2l@?&p6zQA*^T_KfrP>FKF6gjh0Ca|$F5F$tM~lqa2& z*O|D`YWmh`FN(J=HpxnHW4)f}dn)*>RpfVzsIJ{Y+=Zo?$=SNaC5c5P5({~S^g+6W z__Mw-Uda>Kbm^hob(zph@di$ZR2iSh3b{RB`110NH$rShsfj7MsS@Wngv>!2f{xjg zms)1qHyyK_UR9)g=w{aZf~|kMWdrSdqBHNTyCTF_oSIx(lvz@#o0ngbS}f7b!NtVE F2moEFc%uLS diff --git a/test/fixtures/go-ipfs-repo/blocks/C4/CIQDDZ5EDQK5AP7LRTLZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data b/test/fixtures/go-ipfs-repo/blocks/C4/CIQDDZ5EDQK5AP7LRTLZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data deleted file mode 100644 index ecce1053f6..0000000000 --- a/test/fixtures/go-ipfs-repo/blocks/C4/CIQDDZ5EDQK5AP7LRTLZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data +++ /dev/null @@ -1,4 +0,0 @@ -5 -" ׾F_uؔlzS?|ڲPc@ js-ipfs-repo - - \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/CY/CIQDMKFEUGKSLXMEXO774EZOYCYNHPRVFD53ZSAU7237F67XDSQGCYQ.data b/test/fixtures/go-ipfs-repo/blocks/CY/CIQDMKFEUGKSLXMEXO774EZOYCYNHPRVFD53ZSAU7237F67XDSQGCYQ.data deleted file mode 100644 index bbe6bda78d0a52f6d87da578f452d43718b9aa9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10807 zcmeI&tqQ_m6vpvsQC>mhU=TmxWeCpZ4H&eDU=nNw5wR?6Yue0K5w>X*qZns5SS{Xw z-hn1RK)egXzn^qC&+{usEMpXsYYQnaL-~-$SEZaY\IzxEElM/fLICENSE1 -" JZXoRX!Fwd87U;SöWw README.md{ - \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/HD/CIQDDVW2EZIJF4NQH7WJNESD7XHQSXA5EGJVNTPVHD7444C2KLKXHDI.data b/test/fixtures/go-ipfs-repo/blocks/HD/CIQDDVW2EZIJF4NQH7WJNESD7XHQSXA5EGJVNTPVHD7444C2KLKXHDI.data deleted file mode 100644 index 5ea0edda6f82982c276a4a3813a50c0e35121c68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10765 zcmeIzF%AJy6a~;Rm3)!Nk3xb(CK9$mt(wFR^jf72s6=9D)srdd6*gc6EI~I4+fbbT zRX6Y66Q?1IqgQpGAHRd{ss22Q^=&*UXYbW{zqlNV{wBXJW712aODXvf?XV11kq9)T zAq{CrLmJYMhBTxh4QWV28q$!4G^8O7X-GpF(vXHUq#+GyNJARZkcKp*;U8!iTA|tK KY}4Vho$h|}9P~&4 diff --git a/test/fixtures/go-ipfs-repo/blocks/IR/CIQERMRAAFXUAUOX3V2DCW7R77FRIVHQ3V5OIPPS3XQBX34KRPNOIRQ.data b/test/fixtures/go-ipfs-repo/blocks/IR/CIQERMRAAFXUAUOX3V2DCW7R77FRIVHQ3V5OIPPS3XQBX34KRPNOIRQ.data deleted file mode 100644 index 4a26a4ac35..0000000000 --- a/test/fixtures/go-ipfs-repo/blocks/IR/CIQERMRAAFXUAUOX3V2DCW7R77FRIVHQ3V5OIPPS3XQBX34KRPNOIRQ.data +++ /dev/null @@ -1,3 +0,0 @@ -/ -" !61صF2$`7#u@1directT2 -" Hz8#3u2ED ƥ*QKMQ recursiveT \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/5X/CIQJ23BL4UHXA2KTI6NLTXZM4PW4VEFWQBJ4ACZQAS37BLGL4HUO5XY.data b/test/fixtures/go-ipfs-repo/blocks/K5/CIQPW4MAGTUNEBGZCEFZU7XAJL2BMIHGVB5ZR2IOKOSTRMLIKPB6K5I.data similarity index 50% rename from test/fixtures/go-ipfs-repo/blocks/5X/CIQJ23BL4UHXA2KTI6NLTXZM4PW4VEFWQBJ4ACZQAS37BLGL4HUO5XY.data rename to test/fixtures/go-ipfs-repo/blocks/K5/CIQPW4MAGTUNEBGZCEFZU7XAJL2BMIHGVB5ZR2IOKOSTRMLIKPB6K5I.data index b799cf6b2236c91f8224b9fefe43aca16c773490..e1cd3e3e21d1e86994739a1b26b18c77aa98f034 100644 GIT binary patch delta 158 zcmV;P0Ac^N0+IueV=XKSA`&3->_-@SXm=q*on0E$V!)TwlwjCZCnWfpl1bj43JGZv z1Y~bxa~MI9Vw`3f@xOe!jP(ZAT|+3U*U(Mw$}(CzYIxe@7Q=jxomV;%4s&H=b#iHR zc`a^lbY*iGl?f6p3L+99)tHUV+Zr;5&J6djEz6j5=BTIqu@9y%M`FB&BAhrq5(IQ_ Mb#fTr1_}ZQ0pS5cM*si- delta 65 zcmV-H0KWf{1GNH>W08@YH&VttcXc^yKZ3?NmwIv|!r5w{aJBu59Z^4wTWQ>`)DjMJ XWn*=6X>@rlZf|sDa~OjN3IYfLzSSDg diff --git a/test/fixtures/go-ipfs-repo/blocks/O6/CIQOYW2THIZBRGI7IN33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data b/test/fixtures/go-ipfs-repo/blocks/O6/CIQOYW2THIZBRGI7IN33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data deleted file mode 100644 index 7b58d6c857..0000000000 --- a/test/fixtures/go-ipfs-repo/blocks/O6/CIQOYW2THIZBRGI7IN33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data +++ /dev/null @@ -1,3 +0,0 @@ -/ -" @ԆDgA7directT2 -" ;APY0k}E=p  recursiveT \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/5V/CIQFFRR4O52TS2Z7QLDDTF32OIR4FWLKT5YLL7MLDVIT7DC3NHOK5VA.data b/test/fixtures/go-ipfs-repo/blocks/OO/CIQBT4N7PS5IZ5IG2ZOUGKFK27IE33WKGJNDW2TY3LSBNQ34R6OVOOQ.data similarity index 82% rename from test/fixtures/go-ipfs-repo/blocks/5V/CIQFFRR4O52TS2Z7QLDDTF32OIR4FWLKT5YLL7MLDVIT7DC3NHOK5VA.data rename to test/fixtures/go-ipfs-repo/blocks/OO/CIQBT4N7PS5IZ5IG2ZOUGKFK27IE33WKGJNDW2TY3LSBNQ34R6OVOOQ.data index 951bfe0400..770348274e 100644 --- a/test/fixtures/go-ipfs-repo/blocks/5V/CIQFFRR4O52TS2Z7QLDDTF32OIR4FWLKT5YLL7MLDVIT7DC3NHOK5VA.data +++ b/test/fixtures/go-ipfs-repo/blocks/OO/CIQBT4N7PS5IZ5IG2ZOUGKFK27IE33WKGJNDW2TY3LSBNQ34R6OVOOQ.data @@ -1,5 +1,5 @@ - IPFS Alpha Security Notes +  IPFS Alpha Security Notes We try hard to ensure our system is safe and robust, but all software has bugs, especially new software. This distribution is meant to be an @@ -15,9 +15,13 @@ Please note the following: user provided data. But please point any problems out to us in a github issue, or email security@ipfs.io privately. +- security@ipfs.io GPG key: + - 4B9665FB 92636D17 7C7A86D3 50AAE8A9 59B13AF3 + - https://pgp.mit.edu/pks/lookup?op=get&search=0x50AAE8A959B13AF3 + - ipfs uses encryption for all communication, but it's NOT PROVEN SECURE YET! It may be totally broken. For now, the code is included to make sure we benchmark our operations with encryption in mind. In the future, there will be an "unsafe" mode for high performance intranet apps. If this is a blocking feature for you, please contact us. - \ No newline at end of file + \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/PJ/CIQB4F7VKKQDXHMXX6WYQZTRR5QVLP7VBQYAYW2Y5BAPOOGTW5H2PJQ.data b/test/fixtures/go-ipfs-repo/blocks/PJ/CIQB4F7VKKQDXHMXX6WYQZTRR5QVLP7VBQYAYW2Y5BAPOOGTW5H2PJQ.data new file mode 100644 index 0000000000..0335563629 --- /dev/null +++ b/test/fixtures/go-ipfs-repo/blocks/PJ/CIQB4F7VKKQDXHMXX6WYQZTRR5QVLP7VBQYAYW2Y5BAPOOGTW5H2PJQ.data @@ -0,0 +1,3 @@ + + Index + \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/PU/CIQJF2E6OPOEYYEVHYML4UD5A3R4QRAVBI7NVH3PL64D3IJCWR2SPUQ.data b/test/fixtures/go-ipfs-repo/blocks/PU/CIQJF2E6OPOEYYEVHYML4UD5A3R4QRAVBI7NVH3PL64D3IJCWR2SPUQ.data new file mode 100644 index 0000000000..e6ef304bfd --- /dev/null +++ b/test/fixtures/go-ipfs-repo/blocks/PU/CIQJF2E6OPOEYYEVHYML4UD5A3R4QRAVBI7NVH3PL64D3IJCWR2SPUQ.data @@ -0,0 +1,36 @@ + +WIP + +# 0.0 - Introduction + +Welcome to IPFS! This tour will guide you through a few of the +features of this tool, and the most common commands. Then, it will +immerse you into the world of merkledags and the amazing things +you can do with them. + + +This tour has many parts, and can be taken in different sequences. +Different people learn different ways, so choose your own adventure: + + To start with the concepts, try: + - The Merkle DAG + - Data Structures on the Merkle DAG + - Representing Files with unixfs + - add, cat, ls, refs + ... + + + To start with the examples, try: + - add, cat, ls, refs + - Representing Files with unixfs + - Data Structures on the Merkle DAG + - The Merkle DAG + ... + + + To start with the network, try: + - IPFS Nodes + - Running the daemon + - The Swarm + - The Web + \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/QF/CIQGPALRQ24P6NS4OWHTQ7R247ZI7KJWP3QWPQYS43LFULQC5ANLQFI.data b/test/fixtures/go-ipfs-repo/blocks/QF/CIQGPALRQ24P6NS4OWHTQ7R247ZI7KJWP3QWPQYS43LFULQC5ANLQFI.data deleted file mode 100644 index a8f98693b7d4797d0a55704b16c15a6aa7d34bd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10765 zcmeIzF%AJy6a~Szz&}ww{ J&EYejEr0X~^v?hQ diff --git a/test/fixtures/go-ipfs-repo/blocks/QP/CIQNLGENZXNRUMUHZYGPPLZNZOMHHZVIU76LCD5GF5DWFPEGEKODQPI.data b/test/fixtures/go-ipfs-repo/blocks/QP/CIQNLGENZXNRUMUHZYGPPLZNZOMHHZVIU76LCD5GF5DWFPEGEKODQPI.data new file mode 100644 index 0000000000..6636930467 --- /dev/null +++ b/test/fixtures/go-ipfs-repo/blocks/QP/CIQNLGENZXNRUMUHZYGPPLZNZOMHHZVIU76LCD5GF5DWFPEGEKODQPI.data @@ -0,0 +1,4 @@ +2 +" sL`>P}D +>ڟo_="u' 0.0-intro + \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/S2/CIQPF3CHDB5GQ5ZBISOV2GWVMLAJPVEUMDMFKJZE7CMZESO6TYFAS2I.data b/test/fixtures/go-ipfs-repo/blocks/S2/CIQPF3CHDB5GQ5ZBISOV2GWVMLAJPVEUMDMFKJZE7CMZESO6TYFAS2I.data new file mode 100644 index 0000000000..b137a86405 --- /dev/null +++ b/test/fixtures/go-ipfs-repo/blocks/S2/CIQPF3CHDB5GQ5ZBISOV2GWVMLAJPVEUMDMFKJZE7CMZESO6TYFAS2I.data @@ -0,0 +1,3 @@ +- +" R;fqaU 0 [X@8ӷOindex + \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/S5/CIQHBGZNZRPWVEFNMTLP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data b/test/fixtures/go-ipfs-repo/blocks/S5/CIQHBGZNZRPWVEFNMTLP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data deleted file mode 100644 index 3a99c365f0..0000000000 --- a/test/fixtures/go-ipfs-repo/blocks/S5/CIQHBGZNZRPWVEFNMTLP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data +++ /dev/null @@ -1,3 +0,0 @@ -4 -" Y9_)a˹2RmŖke9 js-ipfs-repo - \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/SW/CIQHPUVCWD6JA6AFUVD6VA64TGWP67KYA3AIMBUMVWGZ5AQN2L2HSWQ.data b/test/fixtures/go-ipfs-repo/blocks/SW/CIQHPUVCWD6JA6AFUVD6VA64TGWP67KYA3AIMBUMVWGZ5AQN2L2HSWQ.data deleted file mode 100644 index 78421c81c29ed8c18921f686ea3292e3e7300668..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10765 zcmeIzAqoOf6a~;x48ym`#~`RM41#V$vuVH`*sVtQAcCXSECW-t8{CI3!R7?FVL1Jz z%e(i)S;%Adsve7DGwPqdpJ%zbPo~%Tdwt$7FNbotEpDrr43g+lN<931^R@s0 diff --git a/test/fixtures/go-ipfs-repo/blocks/TW/CIQFEAGMNNXXTYKYQSANT6IBNTFN7WR5RPD5F6GN6MBKUUO25DNOTWQ.data b/test/fixtures/go-ipfs-repo/blocks/TW/CIQFEAGMNNXXTYKYQSANT6IBNTFN7WR5RPD5F6GN6MBKUUO25DNOTWQ.data deleted file mode 100644 index 10aa2ae4f1291a62edd84980f1c05b09b95f78ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10891 zcmWgA;8GG&c)a0=(~LhdBC~#fIWaSTr;7SI$0sSXC;Kd!I#aqLXh*0Jg9L-nsLIh$ z8ciXixns0s7%de?YlP9-aI`iYtqn(O!_nGsv^E^A4M%Ik(b{mdHXN-DM{C2;+HkZs z9IXvUYs1mnaI`iYtqn(O!_nGsv^E^A4M%Ik(b{mdHXN-DM{C2;+HkZs9IXvUYs1mn zaI`iYG__&mlom_2c+JFlUxXS??=;#MbToJ7(P`PK4+MoQKg`(u9q~6w(px+ cb8FM| recursiveT \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/VO/CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data b/test/fixtures/go-ipfs-repo/blocks/VO/CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data deleted file mode 100644 index 2dd80560a2..0000000000 --- a/test/fixtures/go-ipfs-repo/blocks/VO/CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data +++ /dev/null @@ -1,114 +0,0 @@ - -  # 0.1 - Quick Start - -This is a set of short examples with minimal explanation. It is meant as -a "quick start". Soon, we'll write a longer tour :-) - - -Add a file to ipfs: - - echo "hello world" >hello - ipfs add hello - - -View it: - - ipfs cat - - -Try a directory: - - mkdir foo - mkdir foo/bar - echo "baz" > foo/baz - echo "baz" > foo/bar/baz - ipfs add -r foo - - -View things: - - ipfs ls - ipfs ls /bar - ipfs cat /baz - ipfs cat /bar/baz - ipfs cat /bar - ipfs ls /baz - - -References: - - ipfs refs - ipfs refs -r - ipfs refs --help - - -Get: - - ipfs get foo2 - diff foo foo2 - - -Objects: - - ipfs object get - ipfs object get /foo2 - ipfs object --help - - -Pin + GC: - - ipfs pin -r - ipfs gc - ipfs ls - ipfs unpin -r - ipfs gc - - -Daemon: - - ipfs daemon (in another terminal) - ipfs id - - -Network: - - (must be online) - ipfs swarm peers - ipfs id - ipfs cat - - -Mount: - - (warning: fuse is finicky!) - ipfs mount - cd /ipfs/< - - -Tool: - - ipfs version - ipfs update - ipfs commands - ipfs config --help - open http://localhost:5001/webui - - -Browse: - - webui: - - http://localhost:5001/webui - - video: - - http://localhost:8080/ipfs/QmVc6zuAneKJzicnJpfrqCH9gSy6bz54JhcypfJYhGUFQu/play#/ipfs/QmTKZgRNwDNZwHtJSjCp6r5FYefzpULfy37JvMt9DwvXse - - images: - - http://localhost:8080/ipfs/QmZpc3HvfjEXvLWGQPWbHk3AjD5j8NEN4gmFN8Jmrd5g83/cs - - markdown renderer app: - - http://localhost:8080/ipfs/QmX7M9CiYXjVeFnkfVGf3y5ixTZ2ACeSGyL1vBJY1HvQPp/mdown - \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/blocks/WG/CIQN2ZNT35EZ4XBIEYMFARFMBIEICCIO6SVSAMQB7VUE6LW7QNX3WGQ.data b/test/fixtures/go-ipfs-repo/blocks/WG/CIQN2ZNT35EZ4XBIEYMFARFMBIEICCIO6SVSAMQB7VUE6LW7QNX3WGQ.data new file mode 100644 index 0000000000000000000000000000000000000000..afeac9fff900985e656e0ffd12d063e05daa810f GIT binary patch literal 10807 zcmeI&uL{Co6o=tW4Dt;`KSTr_j3MX+7_1t_WL=ojxNVMY|5GW1adZlX`)Y07y7%YP?qU{{$Gx2`m69sy zWJ+uZ*FiFniim)QXo!Yrh=yp0hG>X}Xo!Yrh=yp0hG>X}Xo!Yrh=yp0hG>X}Xo!Yr zh=yp0hG>X}XqXrcW5;W}&gn~D3*BocDjLt##D8b4Wpg{Q4v*3Q|5IopqvpJnuKel? D6)*)k literal 0 HcmV?d00001 diff --git a/test/fixtures/go-ipfs-repo/blocks/XO/CIQJGO2B2N75IUEM372FSMG76VV256I4PXBULZZ5ASNLK4FL4EG7XOI.data b/test/fixtures/go-ipfs-repo/blocks/XO/CIQJGO2B2N75IUEM372FSMG76VV256I4PXBULZZ5ASNLK4FL4EG7XOI.data deleted file mode 100644 index d899663bf7a13bb0563304b1d96985a784c2d515..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10849 zcmWgA;8GG&c)a0=(~LhdBC~#fIWaSTr;7SI$0sSXC;Kd!I#aqLXh*0Jg9L-nsLIh$ z8ciXixns0s7%de?YlP9-aI`iYtqn(O!_nGsv^E^A4M%Ik(b{mdHXN-DM{C2;+HkZs z9IXvUYs1mnaI`iYtqn(O!_nGsv^E^A4M%Ik(b{mdHXN-DM{C2;+HkZs9IXvUYs1mn zaI`iYG__&mlom_2c+JFlUxXS??=;#MbToJ7(P`PK4+MoQKg`(u9-MiqUv4K}orj%_y00+YJV}#XGok z)Gc&_%?H(zbc;FK34aUrCGW}p=j0S(a*4bcz{(GU&M5Dn1~4bcz{(GU&M5Dn1~4bcz{(GU&M5Dn1~ z4bcz{(GU&M5Dn4rZ!}yDE04r@ptViQt$NSPbgyf+T8kZmjdSx~?(hFos3IOo>d{>N G+6cZA+z2}W diff --git a/test/fixtures/go-ipfs-repo/config b/test/fixtures/go-ipfs-repo/config index 162598cdfc..e42d061b2f 100644 --- a/test/fixtures/go-ipfs-repo/config +++ b/test/fixtures/go-ipfs-repo/config @@ -1,51 +1,21 @@ { - "Identity": { - "PeerID": "QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A", - "PrivKey": "CAASpgkwggSiAgEAAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAECggEAZtju/bcKvKFPz0mkHiaJcpycy9STKphorpCT83srBVQi59CdFU6Mj+aL/xt0kCPMVigJw8P3/YCEJ9J+rS8BsoWE+xWUEsJvtXoT7vzPHaAtM3ci1HZd302Mz1+GgS8Epdx+7F5p80XAFLDUnELzOzKftvWGZmWfSeDnslwVONkL/1VAzwKy7Ce6hk4SxRE7l2NE2OklSHOzCGU1f78ZzVYKSnS5Ag9YrGjOAmTOXDbKNKN/qIorAQ1bovzGoCwx3iGIatQKFOxyVCyO1PsJYT7JO+kZbhBWRRE+L7l+ppPER9bdLFxs1t5CrKc078h+wuUr05S1P1JjXk68pk3+kQKBgQDeK8AR11373Mzib6uzpjGzgNRMzdYNuExWjxyxAzz53NAR7zrPHvXvfIqjDScLJ4NcRO2TddhXAfZoOPVH5k4PJHKLBPKuXZpWlookCAyENY7+Pd55S8r+a+MusrMagYNljb5WbVTgN8cgdpim9lbbIFlpN6SZaVjLQL3J8TWH6wKBgQDSChzItkqWX11CNstJ9zJyUE20I7LrpyBJNgG1gtvz3ZMUQCn3PxxHtQzN9n1P0mSSYs+jBKPuoSyYLt1wwe10/lpgL4rkKWU3/m1Myt0tveJ9WcqHh6tzcAbb/fXpUFT/o4SWDimWkPkuCb+8j//2yiXk0a/T2f36zKMuZvujqQKBgC6B7BAQDG2H2B/ijofp12ejJU36nL98gAZyqOfpLJ+FeMz4TlBDQ+phIMhnHXA5UkdDapQ+zA3SrFk+6yGk9Vw4Hf46B+82SvOrSbmnMa+PYqKYIvUzR4gg34rL/7AhwnbEyD5hXq4dHwMNsIDq+l2elPjwm/U9V0gdAl2+r50HAoGALtsKqMvhv8HucAMBPrLikhXP/8um8mMKFMrzfqZ+otxfHzlhI0L08Bo3jQrb0Z7ByNY6M8epOmbCKADsbWcVre/AAY0ZkuSZK/CaOXNX/AhMKmKJh8qAOPRY02LIJRBCpfS4czEdnfUhYV/TYiFNnKRj57PPYZdTzUsxa/yVTmECgYBr7slQEjb5Onn5mZnGDh+72BxLNdgwBkhO0OCdpdISqk0F0Pxby22DFOKXZEpiyI9XYP1C8wPiJsShGm2yEwBPWXnrrZNWczaVuCbXHrZkWQogBDG3HGXNdU4MAWCyiYlyinIBpPpoAJZSzpGLmWbMWh28+RJS6AQX6KHrK1o2uw==" - }, - "Datastore": { - "Type": "", - "Path": "", - "StorageMax": "", - "StorageGCWatermark": 0, - "GCPeriod": "", - "Params": null, - "NoSync": false - }, "Addresses": { "Swarm": [ - "/ip4/127.0.0.1/tcp/0", - "/ip4/127.0.0.1/tcp/0/ws" + "/ip4/0.0.0.0/tcp/4002", + "/ip4/127.0.0.1/tcp/4003/ws" ], - "API": "/ip4/127.0.0.1/tcp/0", - "Gateway": "/ip4/127.0.0.1/tcp/0" - }, - "Mounts": { - "IPFS": "/ipfs", - "IPNS": "/ipns", - "FuseAllowOther": false - }, - "Version": { - "Current": "0.4.0-dev", - "Check": "error", - "CheckDate": "0001-01-01T00:00:00Z", - "CheckPeriod": "172800000000000", - "AutoUpdate": "minor" + "API": "/ip4/127.0.0.1/tcp/5002", + "Gateway": "/ip4/127.0.0.1/tcp/9090" }, "Discovery": { "MDNS": { - "Enabled": false, + "Enabled": true, "Interval": 10 }, "webRTCStar": { - "Enabled": false + "Enabled": true } }, - "Ipns": { - "RepublishPeriod": "", - "RecordLifetime": "", - "ResolveCacheSize": 128 - }, "Bootstrap": [ "/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", @@ -67,43 +37,47 @@ "/dns4/node0.preload.ipfs.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic", "/dns4/node1.preload.ipfs.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6" ], - "Tour": { - "Last": "" - }, - "Gateway": { - "HTTPHeaders": null, - "RootRedirect": "", - "Writable": false - }, - "SupernodeRouting": { - "Servers": [ - "/ip4/104.236.176.52/tcp/4002/ipfs/QmXdb7tWTxdFEQEFgWBqkuYSrZd3mXrC7HxkD4krGNYx2U", - "/ip4/104.236.179.241/tcp/4002/ipfs/QmVRqViDByUxjUMoPnjurjKvZhaEMFDtK35FJXHAM4Lkj6", - "/ip4/104.236.151.122/tcp/4002/ipfs/QmSZwGx8Tn8tmcM4PtDJaMeUQNRhNFdBLVGPzRiNaRJtFH", - "/ip4/162.243.248.213/tcp/4002/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP", - "/ip4/128.199.219.111/tcp/4002/ipfs/Qmb3brdCYmKG1ycwqCbo6LUwWxTuo3FisnJV2yir7oN92R", - "/ip4/104.236.76.40/tcp/4002/ipfs/QmdRBCV8Cz2dGhoKLkD3YjPwVFECmqADQkx5ZteF2c6Fy4", - "/ip4/178.62.158.247/tcp/4002/ipfs/QmUdiMPci7YoEUBkyFZAh2pAbjqcPr7LezyiPD2artLw3v", - "/ip4/178.62.61.185/tcp/4002/ipfs/QmVw6fGNqBixZE4bewRLT2VXX7fAHUHs8JyidDiJ1P7RUN" - ] + "Identity": { + "PeerID": "QmTuh8pVDCz5kbShrK8MJsJgTycCcGwZm8hQd8SxdbYmby", + "PrivKey": "CAASpwkwggSjAgEAAoIBAQCiyLgGRpuGiorm6FzvBbrTU60e6iPMmwXL9mXyGitepQyeN7XF8e6cooFeJI/NIyvbmpa7rHCDzTWP+6ebIMOXjUjQDAgaYdHywKbAXi2cgh96yuTN+cfPJ0IVA1/4Xsn/mnaMmSNDxqnK3fExEDxZizL9iI7KQCGOHociwjNj2cqaz+4ldTQ6QBbqa8nBMbulUNtSzwihQHTHNVwhuYFGPXIIK8UhM1VR20HcCbX+TZ9RpBWLIGZgjJl2ClW7wLW1OAb55I/9CK6AmfOriVYSBxZSFi2jiPCGQmuzfiqEke6/hSZtxe8DRo8ELOQ9K2P3L27H2az2atis2FoqVY2LAgMBAAECggEBAJBg9I9kaqb/FEnPSDYb3+N1sPPdeZkM2ixYQ31i5pqQS0u9X7TMavV0UMe+J+krS8gAKbcVL8pG5T3qV3MIsVIm1rDoKvuzTTJA2uV94niRFPilIiDqbOT4De1zS9iPwhu51XHIlXWUq54qEbWRj+Vfx/8E8pjCHsDdpMAYfNoOsZClr993Hopnf+hfnCypjHpgr5JQzblbN9jmInCOS//Gjcx5IIAPSubNsRaM2sUzqCVaND2QFqQR6+efiHwO8tznLtEJtQ2eSh1LZrLNapovPpMrRyD56Wyj6YlPRd3XOBDcsxxj4WdHobQYqbRV+tI2kyIZ8RP0pOFnLBK1NqECgYEA5nwj3dkXCYBLJ3c2HcUzvQUJmsv7dTM6vsKGCbov/BLPwuKx/X5QlUO6INvHxuVk6+Fj+WTzCFu1gxU1A3bIPgxs6TvYBh4p9Om4ZoW8p7rgF6M5l+TvmlUAisA9X96wYIQnQsW0N5hncFlBveLqEGPXKydxB4y4qwjX8G2Jg3ECgYEAtM315984Rylj8Mj5SdvTUnxe3glixbGRqkj+SEs7ngW5YnKwiEcAvP1OrnczX1h6Aol2b9r89dnsdfsrnaTSEWeKlVqMUfVeixnbssIZD3ZmgzceLdT3q/uZoE89Lw7D+SxQfNG5Q7KekXjI1WQeEhAgNOVppARn/JiHUH9yKrsCgYA1Pen/Hl3e+P7jX/tlRx+bg2Vjl8k/mpTwafkSmCrrfOD3cOyS1TICOQHvAzYT8PuuLYOtoa8ueBjm7egwI6lABBjIi+VsDF2+0JqjPDOHP3jynOb5+o2KxiX4502GLufpc72qBAeMbC1A261/EsLlBFs5AcRvbQdfowxW4sbIUQKBgFRg3kclFIWZWmvPzw9aCMgxBLEInlD2qq1WvV0NxzfbIgZA0gP3Zu/MI4EmXhI8H0y5zE0tXOp7lnAFFPjQJ705niJPjLbfFQ1DtxU4oitmLTdFbM8k2aUomSyIblxcvra1qKZn1dczL+9h+BAmViZF4lHtUpzZ9ZGbuWKm56frAoGASs3C/VhZDhYuJxJWrQrw3pdXWHKosowDbitG9kmeUTOjzTb/UYDhDnWNIH5sfzOkmufEkIAPTKu9SCX4PIXIuwrbWUK6GAnJnqE8uuzGoz7wgV4ZxKiYbPsrXIn9+mFNhjyZM5PG71Vu/wWds7lduUsuWAIvlysqNX64mU3nSB4=" }, "API": { "HTTPHeaders": null }, - "Swarm": { - "AddrFilters": null - }, - "Log": { - "MaxSizeMB": 250, - "MaxBackups": 1, - "MaxAgeDays": 0 + "datastore": { + "Spec": { + "type": "mount", + "mounts": [ + { + "mountpoint": "/blocks", + "type": "measure", + "prefix": "flatfs.datastore", + "child": { + "type": "flatfs", + "path": "blocks", + "sync": true, + "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2" + } + }, + { + "mountpoint": "/", + "type": "measure", + "prefix": "leveldb.datastore", + "child": { + "type": "levelds", + "path": "datastore", + "compression": "none" + } + } + ] + } }, "Keychain": { "dek": { "keyLength": 64, "iterationCount": 10000, - "salt": "co5EbMmrhFwmhHjedZU73zhL", + "salt": "WzAwtXD84YNt474jS7PLTiPw", "hash": "sha2-512" } } -} +} \ No newline at end of file diff --git a/test/fixtures/go-ipfs-repo/datastore/000002.ldb b/test/fixtures/go-ipfs-repo/datastore/000002.ldb deleted file mode 100644 index fc04d660e9ab26bb5d27b3b6b33d212bd1e34f0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 211 zcmZROP}0xIPfpCyPs_|nEiTH>FJWY200SX~$SEzBZ1I|j^S%f*oZe})FX(9Q%%jt? zQy&NlS$>$Y`#n34QbA^3F(V^P!?OjhZT>&P<~cuU%i;RLe(ysy@1_qD4Q&dq4R$uX zbPxoo11sKKRu>QF9Qd?w0|O_M0pouNU?_u2-8}VndNoG}qZmkp00{rx(5+JHej5PO CoIXSV diff --git a/test/fixtures/go-ipfs-repo/datastore/000005.ldb b/test/fixtures/go-ipfs-repo/datastore/000005.ldb index 63d9d260b936415ee42b5aeda6c79fb941664398..db91675fb105e7578576aaf7a2fda42af6cef19a 100644 GIT binary patch literal 1815 zcmZSZ+{CKyW*QpdXdDvaX5!`S7#i;6;~3>==ItIFgeHR66WpY?PqEn8fI)3 z?ik?h7;F?66dD>7YVI3oV(K2s$ix5!TpIeB1$o8#LJC0#BaHYpE}c^JYk2uIWUBe@ zrRA>~U$JcExHNJ3O}>&VLanS^dV#s2em*|M0glejRfc6g6@g*d5ru_55vDC)2=g|cZ5xsS8?Lc{PZVp<_o{O zENyOi{KVNm-&_Q2<{E2gem`(WOR4^AOz@j2&Z`eJ?z|XxmRs}NffKIVPR$YE`yr8c z@>l+hInVtwc7(d*R2+?r5isBJ!^=L`Z=?E=9`zNSD<7()GplOO5{hSPs}Xx6xqhY( z|B5*r_L_-%_HIzt;mJDv?-k1pQ+Ln3NqQAERU$jx4)b}gbN^GRzuaw8lJ)X4#}+bs z&fb-@=EwUT6Azx?UAX_Oq{f?8hQ)=JlWuw4mtatmGcqu=&^0vDH82S=GO{u-wK6r< zGch$a0D~wE2CLOf91KFsm<*a2l?-^m3yUpW;W~TZ>gW8wBwfY%roD5^y9lZiyGrp`p+tB-<~yX z_nLy{v!?yOm(Nx>JiXWB0uP5&;>Aw~mK})Gozo;=b?V94pU2OuJBc#K|A;&Je^yz~ zOl9X|D^K11XeeM4*=_W#` zSm;o4+%!gUXQP{K5r_6sMdQ%G+m3fQxBl~;AGk!cTOlo>XJ#2!=*Td}wpZ-dv~EGV$I1R<+!t@0s2DS#+M*YA1i!&pUo|&9|%@ zYi>koh4ywcF*7nSGCN;migXY6i41mi^73^KcM5hg3H5Ue4s!A`a`X?0@(v9SH8zg$ z0wzjdN3&2Tw=gFcFE1A_vnZ!1BR@|@W@y4!(=W&-CfSch4hfON=yIJ2T%I_42D-Tg zdPll@dISfBhI_lZd3ZV*1-N+!dxr%0o4Wa%hXuMA1-gcZy85}f`gs_;dU$w+IRXFbXN<TQ=oe(>6*ICx!dggSLA}B|$)}boH(&kPCMT{o>(nxxx9L9b zf3BS)QBv>M6c17dj+iw@6Qmzca%t#bn9#xo66FM9Zid(d$&U<5%xRf9C8j}S-~*epX=)71=|%m$4AA%Ni*4_uDLJpb@CUW3!T R;vgaXApCbjw@Rt|Z2+If&inuX literal 1120 zcmZQDSjViNS&&z(FQg!8*qs;0^V3RMWIveo0t|Brg#j3VRkisv@!=|IgJvNC_dNx9y@%e`@arzW`upR#0^RR3Lu1P3 zgny1+s9JOHtH$|N^V2^pIaU+*`j0Vdf^UEA=Y(L*NL7==e45ubJUDbI<}5@1nZ5i@ zU-f@onB_6=BHQa-tVc_VRZiT0AST5ib<){%%1r}PkJe@8+6(<3{`CFeMP?prC*c znwwdgM`+7O$B&?~72w>77RV zf{y0SJUT5q^?{&}<%b!&-?Q^56=dcWGqS)myonCBGLo1n?_9oP$D!cvsdqIm%dJT< zUeCYn&kfrf>=lfOBoQtW6k&$7W$0~c7gOL@IORq4N$7y_CFLmFs-1D4yKkEePa;Yx&V3}9e z6J;wFzbL(7XX!B6*Rdrw=+4dxeU2>!j1QaGe>~sK(>yOETD?v4ss5$s3VXC14~0|~ z@|s=JZrGS)y@`hY)f%XfBnQv@ZgL4too7C-W6;9@lKgp&)Y9xu#YGC zq+Q(oPkf)J&zo^7bJ>~t)Xqs~*IU@HQqP#^{d0FztkiZ*y~k%OjhiRCYiY>$1@7+Z zzc{J2k%`0O*2zuI)9>zn)wWdsh9cXQc|w1;OnM=;)%wQi`6UM;Jtuj8n*Q?qk;X3q zZaf<6!(B7;zLu#kRKLAQM`r(FbFXM+CT2zkqS6H@{24)n$QSJzIOo8pg&P<+nGG2K hLjXe)2VAZvSyQK-gJTMZI7kRT2>;#Cty1cK8vstu!bkuB diff --git a/test/fixtures/go-ipfs-repo/datastore/000010.ldb b/test/fixtures/go-ipfs-repo/datastore/000010.ldb deleted file mode 100644 index 92077582ca4c1094d81e1c35f8703550afefa5f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1143 zcmZQDV9?Jj$Sc+tQjj$4&Wq#uX{9W(pHXd=&LNx2cdi6ocRIV%d~TcDw2tFO0@nWL9`h-bL3Yk+%*afr8@TbPk^RJchgVHA9N_5eTxD41QxO=J9Z^{56JZ); z7-4K;T3DFokyM;!W}Z>zXzZ6K)WGC&@4ao?>Nz(8|F>suXs_zIpd7w&-MpLjzTew7 zw;bnNa{uX~ml~7*<|J4d{FVA*zBjGA&O}w!=F`N7tE3H@g#_I96y)_DdRxPzt0SfDVr1iIeMXL&AqQ0=U2^7|FGm(P2B50#;ggx{k5MHf;A&mO%C&EUfb~C z(50BO4E<;J@;iOi|8-%O$GnSduXnK?Eh$zxasPps6ob@BXVWP+4NN^+mzirX^ndu{ z#t*;Sx0dNGNfK9{8ZLg&Y3{=GymywrWge8Ax zb8_8$u}O-_UoIvnSEU^1zHqkmzk}Jo{lB**@XgG7Tp+=qBxht`XsT;yq-$sxVrXh* zVrgY+u4iCoXlQ9}W@#R!!6>CfIN}*~849wANg!O1*k!T*#RNJcTULFAv{=p%R0p5|p&LRGejGWK}qNY!jl|rkT zI2eSMF&Q*5DjD#yacZ@Bw0-AgWMpJzU~XdMX8?+GF*PwVGHml$WiN9uvO;p{6~^*7 zjnC_)?mL!yo-^-fogiH<)#V;6^U8XnY{lXir8n#>9VYuaw!{YA*;%2_v890VVH5k0 z=ev2D=Y>S8w`o4rzw}&TkCx-1kjg?{vrD=>%@*e)9$i}<^>(k?*#eGjDX!_SpO^_A zd~u&uKT_JeV$DC^DKqPN`vna4@g$$Li@X1c@ALF|GfrhLJ5!(9IqB?r3;R{-856yK z?v9F;+ODbh_-v(d^JI4|4f(#n-Cg|`C$%;*ad_N1xygC@-QBO+mg?V7WV_2So6|Ky~%*a4g zWP`$=5k#;l^#s5<2R<#_z`)6D!1x~m7-n+7<=&p3p90Zl<9Tj>aJ&ZYEyNj-laBK8{h2X5Q|>QJ#UJrj8z7CSl%Q-hQUWp<%{m t;f?{`j=@HOL7|~Rq2|7UCZ_J8j7$t*AgrI0pPZPZUyzws%*X-}0|3MmCh`CP literal 0 HcmV?d00001 diff --git a/test/fixtures/go-ipfs-repo/datastore/MANIFEST-000021 b/test/fixtures/go-ipfs-repo/datastore/MANIFEST-000021 deleted file mode 100644 index dd5db1fec077fde75c2553a79525612b9c7e5cbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 323 zcmZ4R{UEAVtpY6 zNyF~EIG&$Y$|Cz2)n@4&vblWcO3-zuvpdb_wz++KvXX&^0Suh=3$pc{Jpr~kx7h`fmxh|7XT&#V`%^Y diff --git a/test/http-api/config.js b/test/http-api/config.js index 0d14504d1a..0958b16a72 100644 --- a/test/http-api/config.js +++ b/test/http-api/config.js @@ -27,6 +27,7 @@ skipOnWindows('config endpoint', () => { let ipfs = null let ipfsd = null + before(function (done) { this.timeout(20 * 1000) diff --git a/test/http-api/id.js b/test/http-api/id.js index 95de5cf686..ea54e158ee 100644 --- a/test/http-api/id.js +++ b/test/http-api/id.js @@ -73,8 +73,8 @@ skipOnWindows('id endpoint', () => { }) const idResult = { - ID: 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A', - PublicKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAE=', + ID: 'QmTuh8pVDCz5kbShrK8MJsJgTycCcGwZm8hQd8SxdbYmby', + PublicKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCiyLgGRpuGiorm6FzvBbrTU60e6iPMmwXL9mXyGitepQyeN7XF8e6cooFeJI/NIyvbmpa7rHCDzTWP+6ebIMOXjUjQDAgaYdHywKbAXi2cgh96yuTN+cfPJ0IVA1/4Xsn/mnaMmSNDxqnK3fExEDxZizL9iI7KQCGOHociwjNj2cqaz+4ldTQ6QBbqa8nBMbulUNtSzwihQHTHNVwhuYFGPXIIK8UhM1VR20HcCbX+TZ9RpBWLIGZgjJl2ClW7wLW1OAb55I/9CK6AmfOriVYSBxZSFi2jiPCGQmuzfiqEke6/hSZtxe8DRo8ELOQ9K2P3L27H2az2atis2FoqVY2LAgMBAAE=', Addresses: ['/ip4/0.0.0.0/tcp/0'], AgentVersion: 'js-ipfs', ProtocolVersion: '9000' diff --git a/test/http-api/inject/files.js b/test/http-api/inject/files.js index 7e65f7651f..86c7f7dbcb 100644 --- a/test/http-api/inject/files.js +++ b/test/http-api/inject/files.js @@ -62,7 +62,8 @@ module.exports = (http) => { }) }) - it('valid hash', (done) => { + it('valid hash', function (done) { + this.timeout(30 * 1000) api.inject({ method: 'GET', url: '/api/v0/cat?arg=QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o' diff --git a/test/http-api/inject/id.js b/test/http-api/inject/id.js index 35dc443e4d..51716b2594 100644 --- a/test/http-api/inject/id.js +++ b/test/http-api/inject/id.js @@ -29,8 +29,8 @@ module.exports = (http) => { } const idResult = { - ID: 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A', - PublicKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAE=', + ID: 'QmTuh8pVDCz5kbShrK8MJsJgTycCcGwZm8hQd8SxdbYmby', + PublicKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCiyLgGRpuGiorm6FzvBbrTU60e6iPMmwXL9mXyGitepQyeN7XF8e6cooFeJI/NIyvbmpa7rHCDzTWP+6ebIMOXjUjQDAgaYdHywKbAXi2cgh96yuTN+cfPJ0IVA1/4Xsn/mnaMmSNDxqnK3fExEDxZizL9iI7KQCGOHociwjNj2cqaz+4ldTQ6QBbqa8nBMbulUNtSzwihQHTHNVwhuYFGPXIIK8UhM1VR20HcCbX+TZ9RpBWLIGZgjJl2ClW7wLW1OAb55I/9CK6AmfOriVYSBxZSFi2jiPCGQmuzfiqEke6/hSZtxe8DRo8ELOQ9K2P3L27H2az2atis2FoqVY2LAgMBAAE=', Addresses: [ '/ip4/0.0.0.0/tcp/0' ], AgentVersion: 'js-ipfs', ProtocolVersion: '9000' diff --git a/test/http-api/inject/pin.js b/test/http-api/inject/pin.js index f36821c0bc..e351e721a7 100644 --- a/test/http-api/inject/pin.js +++ b/test/http-api/inject/pin.js @@ -17,17 +17,15 @@ const expect = require('chai').expect // - c4 // - c5 // - c6 -// - root2 const pins = { - root1: 'QmVtU7ths96fMgZ8YSZAbKghyieq7AjxNdcqyVzxTt3qVe', + root1: 'QmfGBRT6BbWJd7yUc2uYdaUZJBbnEFvTqehPFoSMQ6wgdr', c1: 'QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V', c2: 'QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y', c3: 'QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7', - c4: 'QmUzLxaXnM8RYCPEqLDX5foToi5aNZHqfYr285w2BKhkft', + c4: 'QmQN88TEidd3RY2u3dpib49fERTDfKtDpvxnvczATNsfKT', c5: 'QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB', - c6: 'QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ', - root2: 'QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn' + c6: 'QmciSU8hfpAXKjvK5YLUSwApomGSWN5gFbP4EpDAEzu2Te' } module.exports = (http) => { @@ -158,9 +156,7 @@ module.exports = (http) => { url: `/api/v0/pin/ls?type=recursive` }, (res) => { expect(res.statusCode).to.equal(200) - expect(res.result.Keys['QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn']) - .to.deep.eql({ Type: 'recursive' }) - expect(res.result.Keys['QmVtU7ths96fMgZ8YSZAbKghyieq7AjxNdcqyVzxTt3qVe']) + expect(res.result.Keys['QmfGBRT6BbWJd7yUc2uYdaUZJBbnEFvTqehPFoSMQ6wgdr']) .to.deep.eql({ Type: 'recursive' }) done() }) From 59d6f7556bc0847b04cb1769dd4ad79b77636bbd Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Wed, 5 Dec 2018 16:53:16 +0000 Subject: [PATCH 8/9] fix: code review --- src/core/components/init.js | 2 +- src/core/components/start.js | 2 +- src/core/ipns/index.js | 6 +++--- src/core/ipns/publisher.js | 16 +++++++--------- src/core/ipns/republisher.js | 6 +++--- src/core/ipns/resolver.js | 4 ++-- test/core/name.js | 4 ++-- 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/core/components/init.js b/src/core/components/init.js index 51c197e977..29cac89402 100644 --- a/src/core/components/init.js +++ b/src/core/components/init.js @@ -117,7 +117,7 @@ module.exports = function init (self) { (_, cb) => { const offlineDatastore = new OfflineDatastore(self._repo) - self._ipns = new IPNS(offlineDatastore, self._repo, self._peerInfo, self._keychain, self._options) + self._ipns = new IPNS(offlineDatastore, self._repo.datastore, self._peerInfo, self._keychain, self._options) cb(null, true) }, // add empty unixfs dir object (go-ipfs assumes this exists) diff --git a/src/core/components/start.js b/src/core/components/start.js index b0053e4150..95befc849b 100644 --- a/src/core/components/start.js +++ b/src/core/components/start.js @@ -65,7 +65,7 @@ module.exports = (self) => { // Create ipns routing with a set of datastores const routing = new TieredDatastore(ipnsStores) - self._ipns = new IPNS(routing, self._repo, self._peerInfo, self._keychain, self._options) + self._ipns = new IPNS(routing, self._repo.datastore, self._peerInfo, self._keychain, self._options) self._bitswap = new Bitswap( self._libp2pNode, diff --git a/src/core/ipns/index.js b/src/core/ipns/index.js index 06b43ca330..03962ba03c 100644 --- a/src/core/ipns/index.js +++ b/src/core/ipns/index.js @@ -17,9 +17,9 @@ const path = require('./path') const defaultRecordTtl = 60 * 1000 class IPNS { - constructor (routing, repo, peerInfo, keychain, options) { - this.publisher = new IpnsPublisher(routing, repo) - this.republisher = new IpnsRepublisher(this.publisher, repo, peerInfo, keychain, options) + constructor (routing, datastore, peerInfo, keychain, options) { + this.publisher = new IpnsPublisher(routing, datastore) + this.republisher = new IpnsRepublisher(this.publisher, datastore, peerInfo, keychain, options) this.resolver = new IpnsResolver(routing) this.cache = new Receptacle({ max: 1000 }) // Create an LRU cache with max 1000 items this.routing = routing diff --git a/src/core/ipns/publisher.js b/src/core/ipns/publisher.js index b6d047f0d5..52b2a3683b 100644 --- a/src/core/ipns/publisher.js +++ b/src/core/ipns/publisher.js @@ -15,9 +15,9 @@ const defaultRecordTtl = 60 * 60 * 1000 // IpnsPublisher is capable of publishing and resolving names to the IPFS routing system. class IpnsPublisher { - constructor (routing, repo) { + constructor (routing, datastore) { this._routing = routing - this._repo = repo + this._datastore = datastore } // publish record with a eol @@ -160,7 +160,7 @@ class IpnsPublisher { options = options || {} const checkRouting = !(options.checkRouting === false) - this._repo.datastore.get(ipns.getLocalKey(peerId.id), (err, dsVal) => { + this._datastore.get(ipns.getLocalKey(peerId.id), (err, dsVal) => { if (err) { if (err.code !== 'ERR_NOT_FOUND') { const errMsg = `unexpected error getting the ipns record ${peerId.id} from datastore` @@ -170,7 +170,7 @@ class IpnsPublisher { } if (!checkRouting) { - return callback(null, null) + return callback((errcode(new Error('record was not found'), 'ERR_NOT_FOUND'))) } // Try to get from routing @@ -202,10 +202,8 @@ class IpnsPublisher { try { result = ipns.unmarshal(data) } catch (err) { - const errMsg = `found ipns record that we couldn't convert to a value` - - log.error(errMsg) - return callback(errcode(new Error(errMsg), 'ERR_INVALID_RECORD_DATA')) + log.error(err) + return callback(errcode(new Error(err), 'ERR_INVALID_RECORD_DATA')) } callback(null, result) @@ -254,7 +252,7 @@ class IpnsPublisher { const data = ipns.marshal(entryData) // Store the new record - this._repo.datastore.put(ipns.getLocalKey(peerId.id), data, (err, res) => { + this._datastore.put(ipns.getLocalKey(peerId.id), data, (err, res) => { if (err) { const errMsg = `ipns record for ${value} could not be stored in the datastore` diff --git a/src/core/ipns/republisher.js b/src/core/ipns/republisher.js index 150cb313d7..31dab0f253 100644 --- a/src/core/ipns/republisher.js +++ b/src/core/ipns/republisher.js @@ -18,9 +18,9 @@ const defaultBroadcastInterval = 4 * hour const defaultRecordLifetime = 24 * hour class IpnsRepublisher { - constructor (publisher, repo, peerInfo, keychain, options) { + constructor (publisher, datastore, peerInfo, keychain, options) { this._publisher = publisher - this._repo = repo + this._datastore = datastore this._peerInfo = peerInfo this._keychain = keychain this._options = options @@ -160,7 +160,7 @@ class IpnsRepublisher { return callback(errcode(new Error(errMsg), 'ERR_INVALID_PEER_ID')) } - this._repo.datastore.get(ipns.getLocalKey(peerId.id), (err, dsVal) => { + this._datastore.get(ipns.getLocalKey(peerId.id), (err, dsVal) => { // error handling // no need to republish if (err && err.notFound) { diff --git a/src/core/ipns/resolver.js b/src/core/ipns/resolver.js index 264b8862bb..c2777e9f33 100644 --- a/src/core/ipns/resolver.js +++ b/src/core/ipns/resolver.js @@ -4,7 +4,7 @@ const ipns = require('ipns') const crypto = require('libp2p-crypto') const PeerId = require('peer-id') const errcode = require('err-code') -const auto = require('async/auto') +const parallel = require('async/parallel') const debug = require('debug') const log = debug('jsipfs:ipns:resolver') @@ -100,7 +100,7 @@ class IpnsResolver { const { routingKey, routingPubKey } = ipns.getIdKeys(peerId.toBytes()) - auto({ + parallel({ // Name should be the hash of a public key retrievable from ipfs. // We retrieve public key to add it to the PeerId, as the IPNS record may not have it. pubKey: (cb) => this._routing.get(routingPubKey.toBuffer(), cb), diff --git a/test/core/name.js b/test/core/name.js index e43627ea94..fcf53cdcea 100644 --- a/test/core/name.js +++ b/test/core/name.js @@ -336,7 +336,7 @@ describe('name', function () { }) it('should error to publish if we receive a unexpected error getting from datastore', function (done) { - const stub = sinon.stub(node._ipns.publisher._repo.datastore, 'get').callsArgWith(1, 'error-unexpected') + const stub = sinon.stub(node._ipns.publisher._datastore, 'get').callsArgWith(1, 'error-unexpected') node.name.publish(ipfsRef, { resolve: false }, (err, res) => { expect(err).to.exist() @@ -348,7 +348,7 @@ describe('name', function () { }) it('should error to publish if we receive a unexpected error putting to datastore', function (done) { - const stub = sinon.stub(node._ipns.publisher._repo.datastore, 'put').callsArgWith(2, 'error-unexpected') + const stub = sinon.stub(node._ipns.publisher._datastore, 'put').callsArgWith(2, 'error-unexpected') node.name.publish(ipfsRef, { resolve: false }, (err, res) => { expect(err).to.exist() From 067de7b99ecfd5bb0760332d079aaa6627416d03 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Thu, 6 Dec 2018 12:32:02 +0000 Subject: [PATCH 9/9] fix: resolve public key logic --- src/core/ipns/publisher.js | 13 ++++--- src/core/ipns/resolver.js | 78 +++++++++++++++++++++++--------------- test/core/name.js | 16 ++++---- 3 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/core/ipns/publisher.js b/src/core/ipns/publisher.js index 52b2a3683b..8cc6cbb418 100644 --- a/src/core/ipns/publisher.js +++ b/src/core/ipns/publisher.js @@ -73,9 +73,10 @@ class IpnsPublisher { series([ (cb) => this._publishEntry(keys.routingKey, embedPublicKeyRecord || record, peerId, cb), - // Publish the public key if a public key cannot be extracted from the ID - // We will be able to deprecate this part in the future, since the public keys will be only in the peerId - (cb) => embedPublicKeyRecord ? this._publishPublicKey(keys.routingPubKey, publicKey, peerId, cb) : cb() + // Publish the public key to support old go-ipfs nodes that are looking for it in the routing + // We will be able to deprecate this part in the future, since the public keys will be only + // in IPNS record and the peerId. + (cb) => this._publishPublicKey(keys.routingPubKey, publicKey, peerId, cb) ], (err) => { if (err) { log.error(err) @@ -158,7 +159,7 @@ class IpnsPublisher { } options = options || {} - const checkRouting = !(options.checkRouting === false) + const checkRouting = options.checkRouting !== false this._datastore.get(ipns.getLocalKey(peerId.id), (err, dsVal) => { if (err) { @@ -170,7 +171,7 @@ class IpnsPublisher { } if (!checkRouting) { - return callback((errcode(new Error('record was not found'), 'ERR_NOT_FOUND'))) + return callback((errcode(err))) } // Try to get from routing @@ -203,7 +204,7 @@ class IpnsPublisher { result = ipns.unmarshal(data) } catch (err) { log.error(err) - return callback(errcode(new Error(err), 'ERR_INVALID_RECORD_DATA')) + return callback(errcode(err, 'ERR_INVALID_RECORD_DATA')) } callback(null, result) diff --git a/src/core/ipns/resolver.js b/src/core/ipns/resolver.js index c2777e9f33..e72aee090e 100644 --- a/src/core/ipns/resolver.js +++ b/src/core/ipns/resolver.js @@ -4,7 +4,6 @@ const ipns = require('ipns') const crypto = require('libp2p-crypto') const PeerId = require('peer-id') const errcode = require('err-code') -const parallel = require('async/parallel') const debug = require('debug') const log = debug('jsipfs:ipns:resolver') @@ -100,13 +99,8 @@ class IpnsResolver { const { routingKey, routingPubKey } = ipns.getIdKeys(peerId.toBytes()) - parallel({ - // Name should be the hash of a public key retrievable from ipfs. - // We retrieve public key to add it to the PeerId, as the IPNS record may not have it. - pubKey: (cb) => this._routing.get(routingPubKey.toBuffer(), cb), - record: (cb) => this._routing.get(routingKey.toBuffer(), cb) - }, (err, res) => { - if (err && !res.record) { + this._routing.get(routingKey.toBuffer(), (err, record) => { + if (err) { if (err.code !== 'ERR_NOT_FOUND') { const errMsg = `unexpected error getting the ipns record ${peerId.id}` @@ -119,44 +113,66 @@ class IpnsResolver { return callback(errcode(new Error(errMsg), 'ERR_NO_RECORD_FOUND')) } - // If public key was found in the routing, add it to the peer id - // otherwise, wait to check if it is embedded in the record. - if (res.pubKey) { + // IPNS entry + let ipnsEntry + try { + ipnsEntry = ipns.unmarshal(record) + } catch (err) { + const errMsg = `found ipns record that we couldn't convert to a value` + + log.error(errMsg) + return callback(errcode(new Error(errMsg), 'ERR_INVALID_RECORD_RECEIVED')) + } + + // if the record has a public key validate it + if (ipnsEntry.pubKey) { + return this._validateRecord(peerId, ipnsEntry, callback) + } + + // Otherwise, try to get the public key from routing + this._routing.get(routingKey.toBuffer(), (err, pubKey) => { + if (err) { + if (err.code !== 'ERR_NOT_FOUND') { + const errMsg = `unexpected error getting the public key for the ipns record ${peerId.id}` + + log.error(errMsg) + return callback(errcode(new Error(errMsg), 'ERR_UNEXPECTED_ERROR_GETTING_PUB_KEY')) + } + const errMsg = `public key requested was not found for ${name} (${routingPubKey}) in the network` + + log.error(errMsg) + return callback(errcode(new Error(errMsg), 'ERR_NO_RECORD_FOUND')) + } + try { - // Insert it into the peer id public key, to be validated by IPNS validator - peerId.pubKey = crypto.keys.unmarshalPublicKey(res.pubKey) + // Insert it into the peer id, in order to be validated by IPNS validator + peerId.pubKey = crypto.keys.unmarshalPublicKey(pubKey) } catch (err) { const errMsg = `found public key record that we couldn't convert to a value` log.error(errMsg) return callback(errcode(new Error(errMsg), 'ERR_INVALID_PUB_KEY_RECEIVED')) } - } - // IPNS entry - let ipnsEntry - try { - ipnsEntry = ipns.unmarshal(res.record) - } catch (err) { - const errMsg = `found ipns record that we couldn't convert to a value` + this._validateRecord(peerId, ipnsEntry, callback) + }) + }) + } - log.error(errMsg) - return callback(errcode(new Error(errMsg), 'ERR_INVALID_RECORD_RECEIVED')) + // validate a resolved record + _validateRecord (peerId, ipnsEntry, callback) { + ipns.extractPublicKey(peerId, ipnsEntry, (err, pubKey) => { + if (err) { + return callback(err) } - ipns.extractPublicKey(peerId, ipnsEntry, (err, pubKey) => { + // IPNS entry validation + ipns.validate(pubKey, ipnsEntry, (err) => { if (err) { return callback(err) } - // IPNS entry validation - ipns.validate(pubKey, ipnsEntry, (err) => { - if (err) { - return callback(err) - } - - callback(null, ipnsEntry.value.toString()) - }) + callback(null, ipnsEntry.value.toString()) }) }) } diff --git a/test/core/name.js b/test/core/name.js index fcf53cdcea..2bf0119f09 100644 --- a/test/core/name.js +++ b/test/core/name.js @@ -308,7 +308,7 @@ describe('name', function () { it('should error to publish if _updateOrCreateRecord fails', function (done) { const stub = sinon.stub(node._ipns.publisher, '_updateOrCreateRecord').callsArgWith(4, 'error') - node.name.publish(ipfsRef, { resolve: false }, (err, res) => { + node.name.publish(ipfsRef, { resolve: false }, (err) => { expect(err).to.exist() stub.restore() @@ -326,7 +326,7 @@ describe('name', function () { it('should error to publish if receives an invalid datastore key', function (done) { const stub = sinon.stub(Key, 'isKey').returns(false) - node.name.publish(ipfsRef, { resolve: false }, (err, res) => { + node.name.publish(ipfsRef, { resolve: false }, (err) => { expect(err).to.exist() expect(err.code).to.equal('ERR_INVALID_DATASTORE_KEY') @@ -338,7 +338,7 @@ describe('name', function () { it('should error to publish if we receive a unexpected error getting from datastore', function (done) { const stub = sinon.stub(node._ipns.publisher._datastore, 'get').callsArgWith(1, 'error-unexpected') - node.name.publish(ipfsRef, { resolve: false }, (err, res) => { + node.name.publish(ipfsRef, { resolve: false }, (err) => { expect(err).to.exist() expect(err.code).to.equal('ERR_DETERMINING_PUBLISHED_RECORD') @@ -350,7 +350,7 @@ describe('name', function () { it('should error to publish if we receive a unexpected error putting to datastore', function (done) { const stub = sinon.stub(node._ipns.publisher._datastore, 'put').callsArgWith(2, 'error-unexpected') - node.name.publish(ipfsRef, { resolve: false }, (err, res) => { + node.name.publish(ipfsRef, { resolve: false }, (err) => { expect(err).to.exist() expect(err.code).to.equal('ERR_STORING_IN_DATASTORE') @@ -382,7 +382,7 @@ describe('name', function () { expect(err).to.not.exist() expect(res).to.exist() - node.name.resolve(nodeId, { nocache: true }, (err, res) => { + node.name.resolve(nodeId, { nocache: true }, (err) => { expect(err).to.exist() expect(err.code).to.equal('ERR_UNEXPECTED_ERROR_GETTING_RECORD') stub.restore() @@ -398,7 +398,7 @@ describe('name', function () { expect(err).to.not.exist() expect(res).to.exist() - node.name.resolve(nodeId, { nocache: true }, (err, res) => { + node.name.resolve(nodeId, { nocache: true }, (err) => { expect(err).to.exist() expect(err.code).to.equal('ERR_NO_RECORD_FOUND') stub.restore() @@ -414,9 +414,9 @@ describe('name', function () { expect(err).to.not.exist() expect(res).to.exist() - node.name.resolve(nodeId, { nocache: true }, (err, res) => { + node.name.resolve(nodeId, { nocache: true }, (err) => { expect(err).to.exist() - expect(err.code).to.equal('ERR_INVALID_PUB_KEY_RECEIVED') + expect(err.code).to.equal('ERR_INVALID_RECORD_RECEIVED') stub.restore() done() })