From 489f115e774d43caa6678c7ff87f6af0c69bc9f1 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Wed, 15 Aug 2018 12:14:48 +0200 Subject: [PATCH 1/2] feat(wallet): restart onboarding on app refresh If a full refresh is done from within the app (`cmd + r`) restart the onboarding process from the beginning, including stopping lnd and disconnecting any active connections. Fix #641 --- app/lib/zap/controller.js | 42 ++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/app/lib/zap/controller.js b/app/lib/zap/controller.js index 9c1cee80..891f88c2 100644 --- a/app/lib/zap/controller.js +++ b/app/lib/zap/controller.js @@ -105,9 +105,6 @@ class ZapController { this.mainWindow.loadURL(`file://${__dirname}/dist/index.html`) } - // Register IPC listeners so that we can react to instructions coming from the app. - this._registerIpcListeners() - // Show the window as soon as the application has finished loading. this.mainWindow.webContents.on('did-finish-load', () => { this.mainWindow.show() @@ -130,8 +127,31 @@ class ZapController { // FSM Callbacks // ------------------------------------ + onOnboarding() { + mainLog.debug('[FSM] onOnboarding...') + + // Deregister IPC listeners so that we can start fresh. + this._removeIpcListeners() + + // Ensure wallet is disconnected. + this.disconnectLightningWallet() + + // If Neutrino is running, kill it. + if (this.neutrino) { + this.neutrino.stop() + } + + // Give the grpc connections a chance to be properly closed out. + return new Promise(resolve => setTimeout(resolve, 200)) + } + onStartOnboarding() { mainLog.debug('[FSM] onStartOnboarding...') + + // Register IPC listeners so that we can react to instructions coming from the app. + this._registerIpcListeners() + + // Notify the app to start the onboarding process. this.sendMessage('startOnboarding', this.lndConfig) } @@ -258,6 +278,9 @@ class ZapController { * Create and subscribe to the Lightning service. */ async startLightningWallet() { + if (this.lightningGrpcConnected) { + return + } mainLog.info('Starting lightning wallet...') this.lightning = new Lightning() @@ -287,7 +310,7 @@ class ZapController { mainLog.info('Disconnecting lightning Wallet...') // Disconnect streams. - this.lightning.unsubscribe() + this.lightning.disconnect() // Update our internal state. this.lightningGrpcConnected = false @@ -400,11 +423,20 @@ class ZapController { _registerIpcListeners() { ipcMain.on('startLnd', (event, options: onboardingOptions) => this.finishOnboarding(options)) } + + /** + * Add IPC event listeners... + */ + _removeIpcListeners() { + ipcMain.removeAllListeners('startLnd') + ipcMain.removeAllListeners('walletUnlocker') + ipcMain.removeAllListeners('lnd') + } } StateMachine.factory(ZapController, { transitions: [ - { name: 'startOnboarding', from: 'none', to: 'onboarding' }, + { name: 'startOnboarding', from: '*', to: 'onboarding' }, { name: 'startLnd', from: 'onboarding', to: 'running' }, { name: 'connectLnd', from: 'onboarding', to: 'connected' }, { name: 'terminate', from: '*', to: 'terminated' } From 2ab60892d0fb7c36e118a94993ac06b9ab3add1c Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Wed, 15 Aug 2018 12:52:37 +0200 Subject: [PATCH 2/2] test(neutrino): tests for start and stop methods --- test/unit/lnd/neutrino.spec.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/unit/lnd/neutrino.spec.js b/test/unit/lnd/neutrino.spec.js index c89c3489..34077076 100644 --- a/test/unit/lnd/neutrino.spec.js +++ b/test/unit/lnd/neutrino.spec.js @@ -168,4 +168,33 @@ describe('Neutrino', function() { }) }) }) + + describe('.start', () => { + describe('called when neutrino is already running', () => { + beforeEach(() => { + this.neutrino = new Neutrino() + this.neutrino.process = 123 + }) + it('should throw an error', () => { + expect(() => { + this.neutrino.start() + }).toThrow() + }) + }) + }) + + describe('.stop', () => { + describe('called when neutrino is already running', () => { + beforeEach(() => { + this.neutrino = new Neutrino() + this.neutrino.process = { + kill: jest.fn() + } + this.neutrino.stop() + }) + it('should kill the neutrino process', () => { + expect(this.neutrino.process).toBeNull() + }) + }) + }) })