Browse Source

Merge pull request #633 from mrfelton/fix/grpc-disconnect-reconnect

refactor(neutrino): more consistent naming in Neutrino class
renovate/lint-staged-8.x
JimmyMow 7 years ago
committed by GitHub
parent
commit
9340a56140
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      app/containers/Root.js
  2. 78
      app/lnd/lib/neutrino.js
  3. 15
      app/reducers/ipc.js
  4. 14
      app/reducers/lnd.js
  5. 7
      app/reducers/onboarding.js
  6. 22
      app/zap.js

13
app/containers/Root.js

@ -206,22 +206,23 @@ const Root = ({
onboardingProps,
syncingProps
}) => {
// If we are syncing show the syncing screen
if (!onboardingProps.onboarding.onboarded) {
// If we are onboarding show the onboarding screen.
if (onboardingProps.onboarding.onboarding) {
return <Onboarding {...onboardingProps} />
}
// If we are syncing show the syncing screen
// If we are syncing show the syncing screen.
if (
onboardingProps.onboarding.onboarded &&
lnd.lightningGrpcActive &&
onboardingProps.onboarding.connectionType === 'local' &&
lnd.grpcStarted &&
lnd.syncStatus !== 'complete'
) {
return <Syncing {...syncingProps} />
}
// Don't launch the app without gRPC connection
if (!lnd.grpcStarted) {
// Don't launch the app without a connection to the lightning wallet gRPC interface.
if (!lnd.lightningGrpcActive) {
return <LoadingBolt />
}

78
app/lnd/lib/neutrino.js

@ -5,17 +5,19 @@ import config from '../config'
import { mainLog, lndLog, lndLogGetLevel } from '../../utils/log'
import { fetchBlockHeight } from './util'
// Sync status is currenty pending.
const NEUTRINO_SYNC_STATUS_PENDING = 'chain-sync-pending'
// Waiting for chain backend to finish synchronizing.
const NEUTRINO_SYNC_STATUS_WAITING = 'chain-sync-waiting'
// Initial sync is currently in progress.
const NEUTRINO_SYNC_STATUS_IN_PROGRESS = 'chain-sync-started'
// Initial sync has completed.
const NEUTRINO_SYNC_STATUS_COMPLETE = 'chain-sync-finished'
// Sync statuses
const CHAIN_SYNC_PENDING = 'chain-sync-pending'
const CHAIN_SYNC_WAITING = 'chain-sync-waiting'
const CHAIN_SYNC_IN_PROGRESS = 'chain-sync-started'
const CHAIN_SYNC_COMPLETE = 'chain-sync-finished'
// Events
const ERROR = 'error'
const CLOSE = 'close'
const WALLET_UNLOCKER_GRPC_ACTIVE = 'wallet-unlocker-grpc-active'
const LIGHTNING_GRPC_ACTIVE = 'lightning-grpc-active'
const GOT_CURRENT_BLOCK_HEIGHT = 'got-current-block-height'
const GOT_LND_BLOCK_HEIGHT = 'got-lnd-block-height'
/**
* Wrapper class for Lnd to run and monitor it in Neutrino mode.
@ -27,9 +29,9 @@ class Neutrino extends EventEmitter {
this.alias = alias
this.autopilot = autopilot
this.process = null
this.grpcProxyStarted = false
this.walletOpened = false
this.chainSyncStatus = NEUTRINO_SYNC_STATUS_PENDING
this.walletUnlockerGrpcActive = false
this.lightningGrpcActive = false
this.chainSyncStatus = CHAIN_SYNC_PENDING
}
/**
@ -56,9 +58,9 @@ class Neutrino extends EventEmitter {
]
this.process = spawn(lndConfig.lndPath, neutrinoArgs)
.on('error', error => this.emit('error', error))
.on('error', error => this.emit(ERROR, error))
.on('close', code => {
this.emit('close', code)
this.emit(CLOSE, code)
this.process = null
})
@ -75,55 +77,55 @@ class Neutrino extends EventEmitter {
lndLog[lndLogGetLevel(line)](line)
}
// gRPC started.
if (!this.grpcProxyStarted) {
if (line.includes('gRPC proxy started') && line.includes('password')) {
this.grpcProxyStarted = true
this.emit('grpc-proxy-started')
// password RPC server listening (wallet unlocker started).
if (!this.walletUnlockerGrpcActive && !this.lightningGrpcActive) {
if (line.includes('RPC server listening on') && line.includes('password')) {
this.walletUnlockerGrpcActive = true
this.emit(WALLET_UNLOCKER_GRPC_ACTIVE)
}
}
// Wallet opened.
if (!this.walletOpened) {
if (line.includes('gRPC proxy started') && !line.includes('password')) {
this.walletOpened = true
this.emit('wallet-opened')
// RPC server listening (wallet unlocked).
if (!this.lightningGrpcActive) {
if (line.includes('RPC server listening on') && !line.includes('password')) {
this.lightningGrpcActive = true
this.emit(LIGHTNING_GRPC_ACTIVE)
}
}
// If the sync has already completed then we don't need to do anythibng else.
if (this.is(NEUTRINO_SYNC_STATUS_COMPLETE)) {
// If the sync has already completed then we don't need to do anything else.
if (this.is(CHAIN_SYNC_COMPLETE)) {
return
}
// Lnd waiting for backend to finish syncing.
if (this.is(NEUTRINO_SYNC_STATUS_PENDING) || this.is(NEUTRINO_SYNC_STATUS_IN_PROGRESS)) {
if (this.is(CHAIN_SYNC_PENDING) || this.is(CHAIN_SYNC_IN_PROGRESS)) {
if (
line.includes('No sync peer candidates available') ||
line.includes('Unable to synchronize wallet to chain') ||
line.includes('Waiting for chain backend to finish sync')
) {
this.setState(NEUTRINO_SYNC_STATUS_WAITING)
this.setState(CHAIN_SYNC_WAITING)
}
}
// Lnd syncing has started or resumed.
if (this.is(NEUTRINO_SYNC_STATUS_PENDING) || this.is(NEUTRINO_SYNC_STATUS_WAITING)) {
if (this.is(CHAIN_SYNC_PENDING) || this.is(CHAIN_SYNC_WAITING)) {
const match = line.match(/Syncing to block height (\d+)/)
if (match) {
// Notify that chhain syncronisation has now started.
this.setState(NEUTRINO_SYNC_STATUS_IN_PROGRESS)
this.setState(CHAIN_SYNC_IN_PROGRESS)
// This is the latest block that BTCd is aware of.
const btcdHeight = Number(match[1])
this.emit('got-current-block-height', btcdHeight)
this.emit(GOT_CURRENT_BLOCK_HEIGHT, btcdHeight)
// The height returned from the LND log output may not be the actual current block height (this is the case
// when BTCD is still in the middle of syncing the blockchain) so try to fetch thhe current height from from
// some block explorers just incase.
fetchBlockHeight()
.then(
height => (height > btcdHeight ? this.emit('got-current-block-height', height) : null)
height => (height > btcdHeight ? this.emit(GOT_CURRENT_BLOCK_HEIGHT, height) : null)
)
// If we were unable to fetch from bock explorers at least we already have what BTCd gave us so just warn.
.catch(err => mainLog.warn(`Unable to fetch block height: ${err.message}`))
@ -131,7 +133,7 @@ class Neutrino extends EventEmitter {
}
// Lnd as received some updated block data.
if (this.is(NEUTRINO_SYNC_STATUS_WAITING) || this.is(NEUTRINO_SYNC_STATUS_IN_PROGRESS)) {
if (this.is(CHAIN_SYNC_WAITING) || this.is(CHAIN_SYNC_IN_PROGRESS)) {
let height
let match
@ -144,13 +146,13 @@ class Neutrino extends EventEmitter {
}
if (height) {
this.setState(NEUTRINO_SYNC_STATUS_IN_PROGRESS)
this.emit('got-lnd-block-height', height)
this.setState(CHAIN_SYNC_IN_PROGRESS)
this.emit(GOT_LND_BLOCK_HEIGHT, height)
}
// Lnd syncing has completed.
if (line.includes('Chain backend is fully synced')) {
this.setState(NEUTRINO_SYNC_STATUS_COMPLETE)
this.setState(CHAIN_SYNC_COMPLETE)
}
}
})

15
app/reducers/ipc.js

@ -1,11 +1,5 @@
import createIpc from 'redux-electron-ipc'
import {
lndSyncStatus,
currentBlockHeight,
lndBlockHeight,
grpcDisconnected,
grpcConnected
} from './lnd'
import { lndSyncStatus, currentBlockHeight, lndBlockHeight, lightningGrpcActive } from './lnd'
import { receiveInfo } from './info'
import { receiveAddress } from './address'
import { receiveCryptocurrency } from './ticker'
@ -47,7 +41,7 @@ import { receiveDescribeNetwork, receiveQueryRoutes, receiveInvoiceAndQueryRoute
import {
startOnboarding,
startLndError,
walletUnlockerStarted,
walletUnlockerGrpcActive,
receiveSeed,
receiveSeedError,
successfullyCreatedWallet,
@ -60,8 +54,7 @@ const ipc = createIpc({
lndSyncStatus,
currentBlockHeight,
lndBlockHeight,
grpcDisconnected,
grpcConnected,
lightningGrpcActive,
receiveInfo,
@ -115,7 +108,7 @@ const ipc = createIpc({
startOnboarding,
startLndError,
walletUnlockerStarted,
walletUnlockerGrpcActive,
receiveSeed,
receiveSeedError,
successfullyCreatedWallet,

14
app/reducers/lnd.js

@ -15,8 +15,7 @@ export const SET_SYNC_STATUS_COMPLETE = 'SET_SYNC_STATUS_COMPLETE'
export const RECEIVE_BLOCK_HEIGHT = 'RECEIVE_BLOCK_HEIGHT'
export const RECEIVE_BLOCK = 'RECEIVE_BLOCK'
export const GRPC_DISCONNECTED = 'GRPC_DISCONNECTED'
export const GRPC_CONNECTED = 'GRPC_CONNECTED'
export const SET_LIGHTNING_WALLET_ACTIVE = 'SET_LIGHTNING_WALLET_ACTIVE'
// ------------------------------------
// Actions
@ -60,11 +59,9 @@ export const lndSyncStatus = (event, status) => (dispatch, getState) => {
}
}
export const grpcDisconnected = () => dispatch => dispatch({ type: GRPC_DISCONNECTED })
export const grpcConnected = () => dispatch => {
export const lightningGrpcActive = () => dispatch => {
dispatch(fetchInfo())
dispatch({ type: GRPC_CONNECTED })
dispatch({ type: SET_LIGHTNING_WALLET_ACTIVE })
}
// Receive IPC event for LND streaming a line
@ -98,8 +95,7 @@ const ACTION_HANDLERS = {
}),
[RECEIVE_BLOCK]: (state, { lndBlockHeight }) => ({ ...state, lndBlockHeight }),
[GRPC_DISCONNECTED]: state => ({ ...state, grpcStarted: false }),
[GRPC_CONNECTED]: state => ({ ...state, grpcStarted: true })
[SET_LIGHTNING_WALLET_ACTIVE]: state => ({ ...state, lightningGrpcActive: true })
}
// ------------------------------------
@ -107,7 +103,7 @@ const ACTION_HANDLERS = {
// ------------------------------------
const initialState = {
syncStatus: 'pending',
grpcStarted: false,
lightningGrpcActive: false,
blockHeight: 0,
lndBlockHeight: 0
}

7
app/reducers/onboarding.js

@ -250,7 +250,7 @@ export const startLndError = (event, errors) => (dispatch, getState) => {
}
// Listener from after the LND walletUnlocker has started
export const walletUnlockerStarted = () => dispatch => {
export const walletUnlockerGrpcActive = () => dispatch => {
dispatch({ type: LND_STARTED })
ipcRenderer.send('walletUnlocker', { msg: 'genSeed' })
}
@ -333,8 +333,8 @@ const ACTION_HANDLERS = {
[CHANGE_STEP]: (state, { step }) => ({ ...state, step, previousStep: state.step }),
[ONBOARDING_STARTED]: state => ({ ...state, onboarded: false }),
[ONBOARDING_FINISHED]: state => ({ ...state, onboarded: true }),
[ONBOARDING_STARTED]: state => ({ ...state, onboarding: true, onboarded: false }),
[ONBOARDING_FINISHED]: state => ({ ...state, onboarding: false, onboarded: true }),
[STARTING_LND]: state => ({ ...state, startingLnd: true }),
[LND_STARTED]: state => ({ ...state, startingLnd: false }),
@ -448,6 +448,7 @@ export { onboardingSelectors }
// Reducer
// ------------------------------------
const initialState = {
onboarding: false,
onboarded: false,
step: 0.1,
connectionType: store.get('type', 'local'),

22
app/zap.js

@ -81,7 +81,7 @@ class ZapController {
return setTimeout(async () => {
if (mode === 'external') {
// If lnd is already running, create and subscribe to the Lightning grpc object.
await this.startGrpc()
await this.startLightningWallet()
this.sendMessage('successfullyCreatedWallet')
} else {
// Otherwise, start the onboarding process.
@ -114,8 +114,8 @@ class ZapController {
/**
* Create and subscribe to the Lightning grpc object.
*/
async startGrpc() {
mainLog.info('Starting gRPC...')
async startLightningWallet() {
mainLog.info('Starting lightning wallet...')
const { lndSubscribe, lndMethods } = await lnd.initLnd()
// Subscribe to bi-directional streams
@ -126,7 +126,7 @@ class ZapController {
lndMethods(event, msg, data)
})
this.sendMessage('grpcConnected')
this.sendMessage('lightningGrpcActive')
}
/**
@ -142,7 +142,7 @@ class ZapController {
walletUnlockerMethods(event, msg, data)
})
this.sendMessage('walletUnlockerStarted')
this.sendMessage('walletUnlockerGrpcActive')
} catch (error) {
dialog.showMessageBox({
type: 'error',
@ -174,14 +174,14 @@ class ZapController {
app.quit()
})
this.neutrino.on('grpc-proxy-started', () => {
mainLog.info('gRPC proxy started')
this.neutrino.on('wallet-unlocker-grpc-active', () => {
mainLog.info('Wallet unlocker gRPC active')
this.startWalletUnlocker()
})
this.neutrino.on('wallet-opened', () => {
mainLog.info('Wallet opened')
this.startGrpc()
this.neutrino.on('lightning-grpc-active', () => {
mainLog.info('Lightning gRPC active')
this.startLightningWallet()
})
this.neutrino.on('chain-sync-waiting', () => {
@ -243,7 +243,7 @@ class ZapController {
mainLog.info(' > host:', cleanOptions.host)
mainLog.info(' > cert:', cleanOptions.cert)
mainLog.info(' > macaroon:', cleanOptions.macaroon)
this.startGrpc()
this.startLightningWallet()
.then(() => this.sendMessage('successfullyCreatedWallet'))
.catch(e => {
const errors = {}

Loading…
Cancel
Save