From d6b31a9fd2700ca4c9a6a764d765d390e6820f8d Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 9 Jul 2018 14:41:11 +0200 Subject: [PATCH 01/10] fix: double pre start call License: MIT Signed-off-by: Alan Shaw --- src/core/boot.js | 108 ++++++++++++++++------------------- src/core/components/start.js | 3 +- 2 files changed, 52 insertions(+), 59 deletions(-) diff --git a/src/core/boot.js b/src/core/boot.js index a8cb79d179..4b3a4c10fd 100644 --- a/src/core/boot.js +++ b/src/core/boot.js @@ -1,7 +1,7 @@ 'use strict' const waterfall = require('async/waterfall') -const series = require('async/series') +const auto = require('async/auto') const extend = require('deep-extend') const RepoErrors = require('ipfs-repo').errors @@ -27,16 +27,7 @@ module.exports = (self) => { return cb(null, true) } - series([ - (cb) => self._repo.open(cb), - (cb) => self.pin._load(cb), - (cb) => self.preStart(cb), - (cb) => { - self.log('initialized') - self.state.initialized() - cb(null, true) - } - ], (err, res) => { + self._repo.open((err, res) => { if (err) { // If the error is that no repo exists, // which happens when the version file is not found @@ -62,59 +53,60 @@ module.exports = (self) => { }) } - const done = (err) => { - if (err) { - return self.emit('error', err) - } - self.log('boot:done') - self.emit('ready') - } - - const tasks = [] - - // check if there as a repo and if so open it - maybeOpenRepo((err, hasRepo) => { - if (err) { - return done(err) - } - - // No repo, but need should init one - if (doInit && !hasRepo) { - tasks.push((cb) => self.init(initOptions, cb)) - // we know we will have a repo for all follwing tasks - // if the above succeeds - hasRepo = true - } + const tasks = { + repoExists: (cb) => maybeOpenRepo(cb), + repoCreated: ['repoExists', (res, cb) => { + if (!doInit || res.repoExists) return cb(null, false) + // No repo, but need should init one + self.init(initOptions, (err) => { + if (err) return cb(err) + cb(null, true) + }) + }], + loadPinset: ['repoExists', (res, cb) => { + if (!res.repoExists) return cb() + self.pin._load(cb) + }], + setConfig: ['repoExists', 'repoCreated', (res, cb) => { + if (!setConfig) return cb() - // Need to set config - if (setConfig) { - if (!hasRepo) { + if (!res.repoExists && !res.repoCreated) { console.log('WARNING, trying to set config on uninitialized repo, maybe forgot to set "init: true"') - } else { - tasks.push((cb) => { - waterfall([ - (cb) => self.config.get(cb), - (config, cb) => { - extend(config, options.config) - - self.config.replace(config, cb) - } - ], cb) - }) + return cb() } - } - // Need to start up the node - if (doStart) { - if (!hasRepo) { + waterfall([ + (cb) => self.config.get(cb), + (config, cb) => { + extend(config, options.config) + self.config.replace(config, cb) + } + ], cb) + }], + initialize: ['repoExists', 'loadPinset', 'repoCreated', 'setConfig', (res, cb) => { + self.log('initialized') + self.state.initialized() + cb(null, true) + }], + start: ['repoExists', 'repoCreated', 'initialize', (res, cb) => { + if (!doStart) return cb() + + // If the repo didn't already exists and wasn't just created then can't start + if (!res.repoExists && !res.repoCreated) { console.log('WARNING, trying to start ipfs node on uninitialized repo, maybe forgot to set "init: true"') - return done(new Error('Uninitalized repo')) - } else { - tasks.push((cb) => self.start(cb)) + return cb(new Error('Uninitalized repo')) } - } - // Do the actual boot sequence - series(tasks, done) + self.start(cb) + }] + } + + // Do the actual boot sequence + auto(tasks, (err) => { + if (err) { + return self.emit('error', err) + } + self.log('booted') + self.emit('ready') }) } diff --git a/src/core/components/start.js b/src/core/components/start.js index f0517b1ed9..1a8a9e2371 100644 --- a/src/core/components/start.js +++ b/src/core/components/start.js @@ -7,7 +7,7 @@ const promisify = require('promisify-es6') module.exports = (self) => { return promisify((callback) => { - callback = callback || function noop () {} + self.log('starting') const done = (err) => { if (err) { @@ -16,6 +16,7 @@ module.exports = (self) => { } self.state.started() + self.log('started') setImmediate(() => self.emit('start')) callback() } From 87f043e110862d43819151ad20820c8cc5da0618 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 12 Jul 2018 16:41:41 +0100 Subject: [PATCH 02/10] fix: initialize event only after repo initializes License: MIT Signed-off-by: Alan Shaw --- src/core/boot.js | 67 +++++++++++--------------------- src/core/components/pre-start.js | 31 ++++++++++++++- src/core/components/start.js | 59 +++++++++++++--------------- src/core/state.js | 18 ++++++++- 4 files changed, 94 insertions(+), 81 deletions(-) diff --git a/src/core/boot.js b/src/core/boot.js index 4b3a4c10fd..9015e276bf 100644 --- a/src/core/boot.js +++ b/src/core/boot.js @@ -1,8 +1,6 @@ 'use strict' const waterfall = require('async/waterfall') -const auto = require('async/auto') -const extend = require('deep-extend') const RepoErrors = require('ipfs-repo').errors // Boot an IPFS node depending on the options set @@ -11,8 +9,6 @@ module.exports = (self) => { const options = self._options const doInit = options.init const doStart = options.start - const config = options.config - const setConfig = config && typeof config === 'object' const repoOpen = !self._repo.closed const customInitOptions = typeof options.init === 'object' ? options.init : {} @@ -49,60 +45,41 @@ module.exports = (self) => { } return cb(err) } - cb(null, res) + cb(null, true) }) } - const tasks = { - repoExists: (cb) => maybeOpenRepo(cb), - repoCreated: ['repoExists', (res, cb) => { - if (!doInit || res.repoExists) return cb(null, false) + const tasks = [ + (cb) => maybeOpenRepo(cb), + (repoOpened, cb) => { + if (!doInit || repoOpened) return cb(null, repoOpened) // No repo, but need should init one self.init(initOptions, (err) => { if (err) return cb(err) cb(null, true) }) - }], - loadPinset: ['repoExists', (res, cb) => { - if (!res.repoExists) return cb() - self.pin._load(cb) - }], - setConfig: ['repoExists', 'repoCreated', (res, cb) => { - if (!setConfig) return cb() - - if (!res.repoExists && !res.repoCreated) { - console.log('WARNING, trying to set config on uninitialized repo, maybe forgot to set "init: true"') - return cb() + }, + (initialized, cb) => { + if (initialized) { + self.log('initialized') + self.state.initialized() } - - waterfall([ - (cb) => self.config.get(cb), - (config, cb) => { - extend(config, options.config) - self.config.replace(config, cb) - } - ], cb) - }], - initialize: ['repoExists', 'loadPinset', 'repoCreated', 'setConfig', (res, cb) => { - self.log('initialized') - self.state.initialized() - cb(null, true) - }], - start: ['repoExists', 'repoCreated', 'initialize', (res, cb) => { + cb(null, initialized) + }, + (initialized, cb) => { + // No problem, we can't preStart until we're initialized + if (!initialized) return cb() + self.preStart(cb) + }, + (cb) => { + // No problem, we don't have to start the node if (!doStart) return cb() - - // If the repo didn't already exists and wasn't just created then can't start - if (!res.repoExists && !res.repoCreated) { - console.log('WARNING, trying to start ipfs node on uninitialized repo, maybe forgot to set "init: true"') - return cb(new Error('Uninitalized repo')) - } - self.start(cb) - }] - } + } + ] // Do the actual boot sequence - auto(tasks, (err) => { + waterfall(tasks, (err) => { if (err) { return self.emit('error', err) } diff --git a/src/core/components/pre-start.js b/src/core/components/pre-start.js index 2121ff6e22..7882488c8b 100644 --- a/src/core/components/pre-start.js +++ b/src/core/components/pre-start.js @@ -5,17 +5,38 @@ const PeerInfo = require('peer-info') const multiaddr = require('multiaddr') const waterfall = require('async/waterfall') const Keychain = require('libp2p-keychain') +const extend = require('deep-extend') const NoKeychain = require('./no-keychain') /* * Load stuff from Repo into memory */ module.exports = function preStart (self) { return (callback) => { + if (self.state.state() !== 'initialized') { + return callback(new Error('Not able to pre-start from state: ' + self.state.state())) + } + self.log('pre-start') + self.state.preStart() const pass = self._options.pass waterfall([ (cb) => self._repo.config.get(cb), + (config, cb) => { + if (!self._options.config) { + return cb(null, config) + } + + extend(config, self._options.config) + + self.config.replace(config, (err) => { + if (err) { + return cb(err) + } + + cb(null, config) + }) + }, (config, cb) => { // Create keychain configuration, if needed. if (config.Keychain) { @@ -78,7 +99,15 @@ module.exports = function preStart (self) { } cb() + }, + (cb) => self.pin._load(cb) + ], (err) => { + if (err) { + return callback(err) } - ], callback) + self.log('pre-started') + self.state.preStarted() + callback() + }) } } diff --git a/src/core/components/start.js b/src/core/components/start.js index 1a8a9e2371..e94482d809 100644 --- a/src/core/components/start.js +++ b/src/core/components/start.js @@ -7,47 +7,40 @@ const promisify = require('promisify-es6') module.exports = (self) => { return promisify((callback) => { - self.log('starting') - - const done = (err) => { + series([ + (cb) => { + switch (self.state.state()) { + case 'initialized': return self.preStart(cb) + case 'stopped': return cb() + default: cb(new Error(`Not able to start from state: ${self.state.state()}`)) + } + }, + (cb) => { + self.log('starting') + self.state.start() + cb() + }, + (cb) => self.libp2p.start(cb), + (cb) => { + self._bitswap = new Bitswap( + self._libp2pNode, + self._repo.blocks, + { statsEnabled: true } + ) + + self._bitswap.start() + self._blockService.setExchange(self._bitswap) + } + ], (err) => { if (err) { setImmediate(() => self.emit('error', err)) return callback(err) } - self.state.started() self.log('started') + self.state.started() setImmediate(() => self.emit('start')) callback() - } - - if (self.state.state() !== 'stopped') { - return done(new Error('Not able to start from state: ' + self.state.state())) - } - - self.log('starting') - self.state.start() - - series([ - (cb) => { - self._repo.closed - ? self._repo.open(cb) - : cb() - }, - (cb) => self.preStart(cb), - (cb) => self.libp2p.start(cb) - ], (err) => { - if (err) { return done(err) } - - self._bitswap = new Bitswap( - self._libp2pNode, - self._repo.blocks, - { statsEnabled: true } - ) - - self._bitswap.start() - self._blockService.setExchange(self._bitswap) - done() }) }) } diff --git a/src/core/state.js b/src/core/state.js index c86a2539de..b9804eb51b 100644 --- a/src/core/state.js +++ b/src/core/state.js @@ -10,10 +10,16 @@ module.exports = (self) => { const s = fsm('uninitalized', { uninitalized: { init: 'initializing', - initialized: 'stopped' + initialized: 'initialized' }, initializing: { - initialized: 'stopped' + initialized: 'initialized' + }, + initialized: { + preStart: 'preStarting' + }, + preStarting: { + preStarted: 'stopped' }, stopped: { start: 'starting' @@ -43,6 +49,14 @@ module.exports = (self) => { s('initialized') } + s.preStart = () => { + s('preStart') + } + + s.preStarted = () => { + s('preStarted') + } + s.stop = () => { s('stop') } From c1b366d587f00c44fd2045490003b73d88f0cb09 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 12 Jul 2018 16:59:46 +0100 Subject: [PATCH 03/10] fix: call callback License: MIT Signed-off-by: Alan Shaw --- src/core/boot.js | 7 ++----- src/core/components/start.js | 10 +++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/boot.js b/src/core/boot.js index 9015e276bf..fe7db601f7 100644 --- a/src/core/boot.js +++ b/src/core/boot.js @@ -53,11 +53,8 @@ module.exports = (self) => { (cb) => maybeOpenRepo(cb), (repoOpened, cb) => { if (!doInit || repoOpened) return cb(null, repoOpened) - // No repo, but need should init one - self.init(initOptions, (err) => { - if (err) return cb(err) - cb(null, true) - }) + // No repo, but should init one + self.init(initOptions, (err) => cb(err, true)) }, (initialized, cb) => { if (initialized) { diff --git a/src/core/components/start.js b/src/core/components/start.js index e94482d809..2dee6153c9 100644 --- a/src/core/components/start.js +++ b/src/core/components/start.js @@ -10,9 +10,12 @@ module.exports = (self) => { series([ (cb) => { switch (self.state.state()) { - case 'initialized': return self.preStart(cb) - case 'stopped': return cb() - default: cb(new Error(`Not able to start from state: ${self.state.state()}`)) + case 'initialized': + return self.preStart(cb) + case 'stopped': + return cb() + default: + cb(new Error(`Not able to start from state: ${self.state.state()}`)) } }, (cb) => { @@ -30,6 +33,7 @@ module.exports = (self) => { self._bitswap.start() self._blockService.setExchange(self._bitswap) + cb() } ], (err) => { if (err) { From 786dd6cb73672b06dd03ffa8ca3598774c25c13b Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 12 Jul 2018 17:10:06 +0100 Subject: [PATCH 04/10] fix: error message regex License: MIT Signed-off-by: Alan Shaw --- src/cli/commands/daemon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index 6c6e4d9d30..98877abe7b 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -35,7 +35,7 @@ module.exports = { httpAPI = new HttpAPI(process.env.IPFS_PATH, null, argv) httpAPI.start((err) => { - if (err && err.code === 'ENOENT' && err.message.match(/Uninitalized repo/i)) { + if (err && err.code === 'ENOENT' && err.message.match(/uninitalized/i)) { print('Error: no initialized ipfs repo found in ' + repoPath) print('please run: jsipfs init') process.exit(1) From 420a8f38ae57a3bb190089efb07512b5c83a81bb Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 13 Jul 2018 15:02:45 +0100 Subject: [PATCH 05/10] fix: typo on intial state name and other fixes License: MIT Signed-off-by: Alan Shaw --- src/cli/commands/daemon.js | 2 +- src/core/boot.js | 110 +++++++++++++++++-------------- src/core/components/init.js | 2 +- src/core/components/pre-start.js | 7 ++ src/core/components/start.js | 7 ++ src/core/state.js | 4 +- 6 files changed, 78 insertions(+), 54 deletions(-) diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index 98877abe7b..254f3f9c13 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -35,7 +35,7 @@ module.exports = { httpAPI = new HttpAPI(process.env.IPFS_PATH, null, argv) httpAPI.start((err) => { - if (err && err.code === 'ENOENT' && err.message.match(/uninitalized/i)) { + if (err && err.code === 'ENOENT' && err.message.match(/not initialized/i)) { print('Error: no initialized ipfs repo found in ' + repoPath) print('please run: jsipfs init') process.exit(1) diff --git a/src/core/boot.js b/src/core/boot.js index fe7db601f7..af500937c0 100644 --- a/src/core/boot.js +++ b/src/core/boot.js @@ -9,74 +9,57 @@ module.exports = (self) => { const options = self._options const doInit = options.init const doStart = options.start - const repoOpen = !self._repo.closed const customInitOptions = typeof options.init === 'object' ? options.init : {} const initOptions = Object.assign({ bits: 2048, pass: self._options.pass }, customInitOptions) - // Checks if a repo exists, and if so opens it - // Will return callback with a bool indicating the existence - // of the repo - const maybeOpenRepo = (cb) => { - // nothing to do - if (repoOpen) { - return cb(null, true) - } - - self._repo.open((err, res) => { - if (err) { - // If the error is that no repo exists, - // which happens when the version file is not found - // we just want to signal that no repo exist, not - // fail the whole process. - - // Use standardized errors as much as possible - if (err.code === RepoErrors.ERR_REPO_NOT_INITIALIZED) { - return cb(null, false) - } - - // TODO: As error codes continue to be standardized, this logic can be phase out; - // it is here to maintain compatability - if (err.message.match(/not found/) || // indexeddb - err.message.match(/ENOENT/) || // fs - err.message.match(/No value/) // memory - ) { - return cb(null, false) - } - return cb(err) + // Do the actual boot sequence + waterfall([ + // Checks if a repo exists, and if so opens it + // Will return callback with a bool indicating the existence + // of the repo + (cb) => { + // nothing to do + if (!self._repo.closed) { + return cb(null, true) } - cb(null, true) - }) - } - const tasks = [ - (cb) => maybeOpenRepo(cb), - (repoOpened, cb) => { - if (!doInit || repoOpened) return cb(null, repoOpened) - // No repo, but should init one - self.init(initOptions, (err) => cb(err, true)) + self._repo.open((err, res) => { + if (isRepoUninitializedError(err)) return cb(null, false) + if (err) return cb(err) + cb(null, true) + }) }, - (initialized, cb) => { - if (initialized) { + // Initialize the repo if it was not opened + (repoOpened, cb) => { + if (repoOpened) { self.log('initialized') self.state.initialized() + return cb() } - cb(null, initialized) + + if (!doInit) { + return cb() + } + + // No repo, but should init one + self.init(initOptions, (err) => cb(err)) }, - (initialized, cb) => { + (cb) => { // No problem, we can't preStart until we're initialized - if (!initialized) return cb() + if (!self.state.state() !== 'initialized') { + return cb() + } self.preStart(cb) }, (cb) => { // No problem, we don't have to start the node - if (!doStart) return cb() + if (!doStart) { + return cb() + } self.start(cb) } - ] - - // Do the actual boot sequence - waterfall(tasks, (err) => { + ], (err) => { if (err) { return self.emit('error', err) } @@ -84,3 +67,30 @@ module.exports = (self) => { self.emit('ready') }) } + +function isRepoUninitializedError (err) { + if (!err) { + return false + } + + // If the error is that no repo exists, + // which happens when the version file is not found + // we just want to signal that no repo exist, not + // fail the whole process. + + // Use standardized errors as much as possible + if (err.code === RepoErrors.ERR_REPO_NOT_INITIALIZED) { + return true + } + + // TODO: As error codes continue to be standardized, this logic can be phase out; + // it is here to maintain compatability + if (err.message.match(/not found/) || // indexeddb + err.message.match(/ENOENT/) || // fs + err.message.match(/No value/) // memory + ) { + return true + } + + return false +} diff --git a/src/core/components/init.js b/src/core/components/init.js index 5b5f77d8e7..cb9d02721f 100644 --- a/src/core/components/init.js +++ b/src/core/components/init.js @@ -27,7 +27,7 @@ module.exports = function init (self) { callback(null, res) } - if (self.state.state() !== 'uninitalized') { + if (self.state.state() !== 'uninitialized') { return done(new Error('Not able to init from state: ' + self.state.state())) } diff --git a/src/core/components/pre-start.js b/src/core/components/pre-start.js index 7882488c8b..d8cfb182ed 100644 --- a/src/core/components/pre-start.js +++ b/src/core/components/pre-start.js @@ -21,6 +21,13 @@ module.exports = function preStart (self) { const pass = self._options.pass waterfall([ + (cb) => { + // The repo may be closed if previously stopped + if (self._repo.closed) { + return self._repo.open(cb) + } + cb() + }, (cb) => self._repo.config.get(cb), (config, cb) => { if (!self._options.config) { diff --git a/src/core/components/start.js b/src/core/components/start.js index 2dee6153c9..c404616d45 100644 --- a/src/core/components/start.js +++ b/src/core/components/start.js @@ -18,6 +18,13 @@ module.exports = (self) => { cb(new Error(`Not able to start from state: ${self.state.state()}`)) } }, + (cb) => { + // The repo may be closed if previously stopped + if (self._repo.closed) { + return self._repo.open(cb) + } + cb() + }, (cb) => { self.log('starting') self.state.start() diff --git a/src/core/state.js b/src/core/state.js index b9804eb51b..3c68eb217a 100644 --- a/src/core/state.js +++ b/src/core/state.js @@ -7,8 +7,8 @@ log.error = debug('jsipfs:state:error') const fsm = require('fsm-event') module.exports = (self) => { - const s = fsm('uninitalized', { - uninitalized: { + const s = fsm('uninitialized', { + uninitialized: { init: 'initializing', initialized: 'initialized' }, From 03f5547bc7a8b9cd6e1385ac2fe3fe03c7d18c93 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 13 Jul 2018 16:27:03 +0100 Subject: [PATCH 06/10] fix: simplify License: MIT Signed-off-by: Alan Shaw --- src/core/boot.js | 27 ++++++----------- src/core/components/init.js | 19 ++++++++++-- src/core/components/pre-start.js | 21 +------------ src/core/components/start.js | 52 ++++++++++++++------------------ src/core/state.js | 10 ++---- 5 files changed, 50 insertions(+), 79 deletions(-) diff --git a/src/core/boot.js b/src/core/boot.js index af500937c0..0602cb90a0 100644 --- a/src/core/boot.js +++ b/src/core/boot.js @@ -10,9 +10,6 @@ module.exports = (self) => { const doInit = options.init const doStart = options.start - const customInitOptions = typeof options.init === 'object' ? options.init : {} - const initOptions = Object.assign({ bits: 2048, pass: self._options.pass }, customInitOptions) - // Do the actual boot sequence waterfall([ // Checks if a repo exists, and if so opens it @@ -30,27 +27,21 @@ module.exports = (self) => { cb(null, true) }) }, - // Initialize the repo if it was not opened (repoOpened, cb) => { + // Init with existing initialized, opened, repo if (repoOpened) { - self.log('initialized') - self.state.initialized() - return cb() + return self.init({ repo: self._repo }, (err) => cb(err)) } - if (!doInit) { - return cb() + if (doInit) { + const initOptions = Object.assign( + { bits: 2048, pass: self._options.pass }, + typeof options.init === 'object' ? options.init : {} + ) + return self.init(initOptions, (err) => cb(err)) } - // No repo, but should init one - self.init(initOptions, (err) => cb(err)) - }, - (cb) => { - // No problem, we can't preStart until we're initialized - if (!self.state.state() !== 'initialized') { - return cb() - } - self.preStart(cb) + cb() }, (cb) => { // No problem, we don't have to start the node diff --git a/src/core/components/init.js b/src/core/components/init.js index cb9d02721f..c8ef37c882 100644 --- a/src/core/components/init.js +++ b/src/core/components/init.js @@ -22,9 +22,16 @@ module.exports = function init (self) { return callback(err) } - self.state.initialized() - self.emit('init') - callback(null, res) + self.preStart((err) => { + if (err) { + self.emit('error', err) + return callback(err) + } + + self.state.initialized() + self.emit('init') + callback(null, res) + }) } if (self.state.state() !== 'uninitialized') { @@ -34,6 +41,12 @@ module.exports = function init (self) { self.state.init() self.log('init') + // An initialized, open repo was passed, use this one! + if (opts.repo) { + self._repo = opts.repo + return done(null, true) + } + opts.emptyRepo = opts.emptyRepo || false opts.bits = Number(opts.bits) || 2048 opts.log = opts.log || function () {} diff --git a/src/core/components/pre-start.js b/src/core/components/pre-start.js index d8cfb182ed..ed30190a0a 100644 --- a/src/core/components/pre-start.js +++ b/src/core/components/pre-start.js @@ -12,22 +12,10 @@ const NoKeychain = require('./no-keychain') */ module.exports = function preStart (self) { return (callback) => { - if (self.state.state() !== 'initialized') { - return callback(new Error('Not able to pre-start from state: ' + self.state.state())) - } - self.log('pre-start') - self.state.preStart() const pass = self._options.pass waterfall([ - (cb) => { - // The repo may be closed if previously stopped - if (self._repo.closed) { - return self._repo.open(cb) - } - cb() - }, (cb) => self._repo.config.get(cb), (config, cb) => { if (!self._options.config) { @@ -108,13 +96,6 @@ module.exports = function preStart (self) { cb() }, (cb) => self.pin._load(cb) - ], (err) => { - if (err) { - return callback(err) - } - self.log('pre-started') - self.state.preStarted() - callback() - }) + ], callback) } } diff --git a/src/core/components/start.js b/src/core/components/start.js index c404616d45..fd4832e35a 100644 --- a/src/core/components/start.js +++ b/src/core/components/start.js @@ -7,28 +7,30 @@ const promisify = require('promisify-es6') module.exports = (self) => { return promisify((callback) => { + const done = (err) => { + if (err) { + setImmediate(() => self.emit('error', err)) + return callback(err) + } + + self.state.started() + setImmediate(() => self.emit('start')) + callback() + } + + if (self.state.state() !== 'stopped') { + return done(new Error(`Not able to start from state: ${self.state.state()}`)) + } + + self.log('starting') + self.state.start() + series([ - (cb) => { - switch (self.state.state()) { - case 'initialized': - return self.preStart(cb) - case 'stopped': - return cb() - default: - cb(new Error(`Not able to start from state: ${self.state.state()}`)) - } - }, (cb) => { // The repo may be closed if previously stopped - if (self._repo.closed) { - return self._repo.open(cb) - } - cb() - }, - (cb) => { - self.log('starting') - self.state.start() - cb() + self._repo.closed + ? self._repo.open(cb) + : cb() }, (cb) => self.libp2p.start(cb), (cb) => { @@ -42,16 +44,6 @@ module.exports = (self) => { self._blockService.setExchange(self._bitswap) cb() } - ], (err) => { - if (err) { - setImmediate(() => self.emit('error', err)) - return callback(err) - } - - self.log('started') - self.state.started() - setImmediate(() => self.emit('start')) - callback() - }) + ], done) }) } diff --git a/src/core/state.js b/src/core/state.js index 3c68eb217a..a99a18a886 100644 --- a/src/core/state.js +++ b/src/core/state.js @@ -10,16 +10,10 @@ module.exports = (self) => { const s = fsm('uninitialized', { uninitialized: { init: 'initializing', - initialized: 'initialized' + initialized: 'stopped' }, initializing: { - initialized: 'initialized' - }, - initialized: { - preStart: 'preStarting' - }, - preStarting: { - preStarted: 'stopped' + initialized: 'stopped' }, stopped: { start: 'starting' From f9a22dd8d8d6b6e72b761927a1288063210966d3 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 13 Jul 2018 16:30:48 +0100 Subject: [PATCH 07/10] fix: remove unused preStart and preStarted state changers License: MIT Signed-off-by: Alan Shaw --- src/core/state.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/core/state.js b/src/core/state.js index a99a18a886..eaae92b8e3 100644 --- a/src/core/state.js +++ b/src/core/state.js @@ -43,14 +43,6 @@ module.exports = (self) => { s('initialized') } - s.preStart = () => { - s('preStart') - } - - s.preStarted = () => { - s('preStarted') - } - s.stop = () => { s('stop') } From 3da92dc818f8eacc6b41b1bbb44493037a6a3458 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 13 Jul 2018 16:42:58 +0100 Subject: [PATCH 08/10] fix: error message regex License: MIT Signed-off-by: Alan Shaw --- src/cli/commands/daemon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index 254f3f9c13..acce564227 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -35,7 +35,7 @@ module.exports = { httpAPI = new HttpAPI(process.env.IPFS_PATH, null, argv) httpAPI.start((err) => { - if (err && err.code === 'ENOENT' && err.message.match(/not initialized/i)) { + if (err && err.code === 'ENOENT' && err.message.match(/uninitialized/i)) { print('Error: no initialized ipfs repo found in ' + repoPath) print('please run: jsipfs init') process.exit(1) From 90524aa89a948fae796cb2449bc1846130a50cd3 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Sat, 14 Jul 2018 14:24:44 +0100 Subject: [PATCH 09/10] feat: import with CID base option License: MIT Signed-off-by: Alan Shaw --- src/core/components/files.js | 16 +++++++++++++--- src/core/utils.js | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/core/components/files.js b/src/core/components/files.js index f69868bd77..8fed819a93 100644 --- a/src/core/components/files.js +++ b/src/core/components/files.js @@ -36,11 +36,13 @@ function prepareFile (self, opts, file, callback) { ? cb(null, file) : self.object.get(file.multihash, opts, cb), (node, cb) => { - const b58Hash = cid.toBaseEncodedString() + const hash = cid.toBaseEncodedString(opts.cidBase) cb(null, { - path: opts.wrapWithDirectory ? file.path.substring(WRAPPER.length) : (file.path || b58Hash), - hash: b58Hash, + path: opts.wrapWithDirectory + ? file.path.substring(WRAPPER.length) + : (file.path || hash), + hash: hash, size: node.size }) } @@ -144,6 +146,10 @@ module.exports = function files (self) { opts.cidVersion = 1 } + if (opts.cidBase && opts.cidVersion !== 1) { + opts.cidVersion = 1 + } + let total = 0 const prog = opts.progress || noop @@ -246,6 +252,10 @@ module.exports = function files (self) { options.cidVersion = 1 } + if (options.cidBase && options.cidVersion !== 1) { + options.cidVersion = 1 + } + pull( pull.values([data]), _addPullStream(options), diff --git a/src/core/utils.js b/src/core/utils.js index a0d67e449a..167b4e675a 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -4,6 +4,7 @@ const multihashes = require('multihashes') const promisify = require('promisify-es6') const map = require('async/map') const isIpfs = require('is-ipfs') +const CID = require('cids') exports.OFFLINE_ERROR = 'This command must be run in online mode. Try running \'ipfs daemon\' first.' @@ -76,7 +77,7 @@ const resolvePath = promisify(function (objectAPI, ipfsPaths, callback) { return cb(err) } - const rootHash = multihashes.fromB58String(parsedPath.hash) + const rootHash = new CID(parsedPath.hash) const rootLinks = parsedPath.links if (!rootLinks.length) { return cb(null, rootHash) From 8e34b3518b8f50bd7e277468d3ca0fb2a03ae04c Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 17 Jul 2018 11:03:29 +0100 Subject: [PATCH 10/10] feat: add --cid-base arg to CLI License: MIT Signed-off-by: Alan Shaw --- src/cli/commands/files/add.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/cli/commands/files/add.js b/src/cli/commands/files/add.js index fe2a602a41..253d1047e0 100644 --- a/src/cli/commands/files/add.js +++ b/src/cli/commands/files/add.js @@ -152,6 +152,10 @@ module.exports = { type: 'integer', describe: 'Cid version. Non-zero value will change default of \'raw-leaves\' to true. (experimental)' }, + 'cid-base': { + type: 'string', + describe: 'The multibase of the printed CID for added files. (experimental)' + }, hash: { type: 'string', choices: Object.keys(mh.names), @@ -190,6 +194,7 @@ module.exports = { ? argv.shardSplitThreshold : Infinity, cidVersion: argv.cidVersion, + cidBase: argv.cidBase, rawLeaves: argv.rawLeaves, onlyHash: argv.onlyHash, hashAlg: argv.hash, @@ -209,6 +214,10 @@ module.exports = { throw new Error('Implied argument raw-leaves must be passed and set to false when cid-version is > 0') } + if (options.cidBase && options.cidVersion !== 1) { + options.cidVersion = 1 + } + // Temporary restriction on raw-leaves: // When hash != undefined then raw-leaves MUST be present and false. //