Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Commit

Permalink
fix(onboarding): handle host/cert errors on boot
Browse files Browse the repository at this point in the history
When the app starts it tries to automatically log into the last active
wallet. If there is a problem with the cert or macaroon files, the user
is left hanging on the loading screen.

Consolidate errors from startLnd into a single object, and ensure that
we handle all lnd start errors.

Fix #1215
  • Loading branch information
mrfelton committed Jan 6, 2019
1 parent 99fa15f commit b41caa9
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 51 deletions.
6 changes: 3 additions & 3 deletions app/components/Home/Home.js
Expand Up @@ -23,7 +23,7 @@ class Home extends React.Component {
activeWalletSettings: PropTypes.object,
deleteWallet: PropTypes.func.isRequired,
lndConnect: PropTypes.object,
startLndHostError: PropTypes.string,
startLndError: PropTypes.object,
lightningGrpcActive: PropTypes.bool.isRequired,
walletUnlockerGrpcActive: PropTypes.bool.isRequired,
wallets: PropTypes.array.isRequired,
Expand Down Expand Up @@ -61,7 +61,7 @@ class Home extends React.Component {
activeWallet,
deleteWallet,
startLnd,
startLndHostError,
startLndError,
unlockWallet,
wallets,
setActiveWallet,
Expand Down Expand Up @@ -117,7 +117,7 @@ class Home extends React.Component {
stopLnd={stopLnd}
lightningGrpcActive={lightningGrpcActive}
walletUnlockerGrpcActive={walletUnlockerGrpcActive}
startLndHostError={startLndHostError}
startLndError={startLndError}
setError={setError}
setStartLndError={setStartLndError}
deleteWallet={deleteWallet}
Expand Down
18 changes: 9 additions & 9 deletions app/components/Home/WalletLauncher.js
Expand Up @@ -14,7 +14,7 @@ class WalletLauncher extends React.Component {
startLnd: PropTypes.func.isRequired,
lightningGrpcActive: PropTypes.bool.isRequired,
walletUnlockerGrpcActive: PropTypes.bool.isRequired,
startLndHostError: PropTypes.string,
startLndError: PropTypes.object,
setStartLndError: PropTypes.func.isRequired,
setError: PropTypes.func.isRequired,
stopLnd: PropTypes.func.isRequired,
Expand All @@ -24,12 +24,12 @@ class WalletLauncher extends React.Component {
}

componentDidMount() {
const { stopLnd, startLndHostError, setError, setStartLndError } = this.props
const { stopLnd, startLndError, setError, setStartLndError } = this.props
stopLnd()

// If the wallet unlocker became active, switch to the login screen
if (startLndHostError) {
setError(startLndHostError)
// If there are lnd start errors, show as a global error.
if (startLndError) {
setError(startLndError)
setStartLndError(null)
}
}
Expand All @@ -42,15 +42,15 @@ class WalletLauncher extends React.Component {
history,
lightningGrpcActive,
walletUnlockerGrpcActive,
startLndHostError,
startLndError,
setError,
setStartLndError,
wallet
} = this.props

// If the wallet unlocker became active, switch to the login screen
if (startLndHostError && !prevProps.startLndHostError) {
setError(startLndHostError)
// If we got lnd start errors, show as a global error.
if (startLndError && !prevProps.startLndError) {
setError(startLndError)
setStartLndError(null)
}

Expand Down
9 changes: 1 addition & 8 deletions app/components/Onboarding/Steps/ConnectionConfirm.js
Expand Up @@ -40,14 +40,7 @@ class ConnectionConfirm extends React.Component {

static defaultProps = {
wizardApi: {},
wizardState: {},
connectionHost: '',
connectionCert: '',
connectionMacaroon: '',
connectionString: '',
startLndHostError: '',
startLndCertError: '',
startLndMacaroonError: ''
wizardState: {}
}

handleSubmit = async () => {
Expand Down
8 changes: 1 addition & 7 deletions app/components/Onboarding/Steps/ConnectionDetails.js
Expand Up @@ -28,13 +28,7 @@ class ConnectionDetails extends React.Component {

static defaultProps = {
wizardApi: {},
wizardState: {},
connectionHost: '',
connectionCert: '',
connectionMacaroon: '',
startLndHostError: '',
startLndCertError: '',
startLndMacaroonError: ''
wizardState: {}
}

componentDidMount() {
Expand Down
2 changes: 1 addition & 1 deletion app/containers/Home.js
Expand Up @@ -17,7 +17,7 @@ const mapStateToProps = state => ({
activeWalletSettings: walletSelectors.activeWalletSettings(state),
lightningGrpcActive: state.lnd.lightningGrpcActive,
walletUnlockerGrpcActive: state.lnd.walletUnlockerGrpcActive,
startLndHostError: state.lnd.startLndHostError,
startLndError: state.lnd.startLndError,
unlockingWallet: state.lnd.unlockingWallet,
unlockWalletError: state.lnd.unlockWalletError
})
Expand Down
14 changes: 8 additions & 6 deletions app/containers/Initializer.js
Expand Up @@ -22,7 +22,7 @@ class Initializer extends React.Component {
isReady: PropTypes.bool.isRequired,
lightningGrpcActive: PropTypes.bool.isRequired,
walletUnlockerGrpcActive: PropTypes.bool.isRequired,
startLndHostError: PropTypes.string.isRequired,
startLndError: PropTypes.object,
startActiveWallet: PropTypes.func.isRequired,
fetchSuggestedNodes: PropTypes.func.isRequired,
fetchTicker: PropTypes.func.isRequired,
Expand Down Expand Up @@ -55,7 +55,7 @@ class Initializer extends React.Component {
hasWallets,
history,
lightningGrpcActive,
startLndHostError,
startLndError,
walletUnlockerGrpcActive,
startActiveWallet
} = this.props
Expand All @@ -64,7 +64,9 @@ class Initializer extends React.Component {
if (isReady && !prevProps.isReady) {
if (activeWalletSettings) {
if (isWalletOpen) {
return startActiveWallet()
// Catch the error and swallow it with a noop.
// Errors are handled below by listening for updates to the startLndError prop.
return startActiveWallet().catch(() => {})
} else {
return history.push(`/home/wallet/${activeWallet}`)
}
Expand All @@ -75,8 +77,8 @@ class Initializer extends React.Component {
return hasWallets ? history.push('/home') : history.push('/onboarding')
}

// If there wad a problem starting lnd, swich to the wallet launcher.
if (startLndHostError && !prevProps.startLndHostError) {
// If there was a problem starting lnd, swich to the wallet launcher.
if (startLndError && !prevProps.startLndError) {
return history.push(`/home/wallet/${activeWallet}`)
}

Expand Down Expand Up @@ -107,7 +109,7 @@ const mapStateToProps = state => ({
hasWallets: walletSelectors.hasWallets(state),
lightningGrpcActive: state.lnd.lightningGrpcActive,
walletUnlockerGrpcActive: state.lnd.walletUnlockerGrpcActive,
startLndHostError: state.lnd.startLndHostError,
startLndError: state.lnd.startLndError,
isWalletOpen: state.wallet.isWalletOpen,
isReady: appSelectors.isReady(state)
})
Expand Down
9 changes: 5 additions & 4 deletions app/containers/Onboarding.js
Expand Up @@ -24,7 +24,8 @@ import {
fetchSeed,
createNewWallet,
recoverOldWallet,
unlockWallet
unlockWallet,
lndSelectors
} from 'reducers/lnd'

const mapStateToProps = state => ({
Expand All @@ -39,9 +40,9 @@ const mapStateToProps = state => ({
lndConnect: state.onboarding.lndConnect,
lightningGrpcActive: state.lnd.lightningGrpcActive,
walletUnlockerGrpcActive: state.lnd.walletUnlockerGrpcActive,
startLndHostError: state.lnd.startLndHostError,
startLndCertError: state.lnd.startLndCertError,
startLndMacaroonError: state.lnd.startLndMacaroonError,
startLndHostError: lndSelectors.startLndHostError(state),
startLndCertError: lndSelectors.startLndCertError(state),
startLndMacaroonError: lndSelectors.startLndMacaroonError(state),
seed: state.onboarding.seed,
unlockWalletError: state.lnd.unlockWalletError,
onboarded: state.onboarding.onboarded,
Expand Down
2 changes: 1 addition & 1 deletion app/containers/Root.js
Expand Up @@ -34,7 +34,7 @@ class Root extends React.Component {
hasWallets: PropTypes.bool,
clearError: PropTypes.func.isRequired,
theme: PropTypes.object,
error: PropTypes.string,
error: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.object]),
history: PropTypes.object.isRequired,
isLoading: PropTypes.bool.isRequired,

Expand Down
36 changes: 24 additions & 12 deletions app/reducers/lnd.js
Expand Up @@ -145,14 +145,14 @@ export const startLnd = options => async (dispatch, getState) => {
dispatch({ type: STARTING_LND })
dispatch(send('startLnd', options))

window.ipcRenderer.once('startLndError', error => {
window.ipcRenderer.once('startLndError', (event, error) => {
window.ipcRenderer.removeListener('startLndSuccess', resolve)
reject(error)
})

window.ipcRenderer.once('startLndSuccess', res => {
window.ipcRenderer.once('startLndSuccess', () => {
window.ipcRenderer.removeListener('startLndError', reject)
resolve(res)
resolve()
})
})
}
Expand Down Expand Up @@ -332,7 +332,7 @@ export const startActiveWallet = () => async (dispatch, getState) => {
if (!state.lnd.lndStarted && !state.lnd.startingLnd) {
const activeWalletSettings = walletSelectors.activeWalletSettings(state)
if (activeWalletSettings) {
dispatch(startLnd(activeWalletSettings))
await dispatch(startLnd(activeWalletSettings))
}
}
}
Expand Down Expand Up @@ -386,9 +386,7 @@ const ACTION_HANDLERS = {
[SET_START_LND_ERROR]: (state, { errors }) => ({
...state,
startingLnd: false,
startLndHostError: errors ? errors.host : '',
startLndCertError: errors ? errors.cert : '',
startLndMacaroonError: errors ? errors.macaroon : ''
startLndError: errors
}),

[SET_WALLET_UNLOCKER_ACTIVE]: state => ({
Expand Down Expand Up @@ -441,11 +439,9 @@ const initialState = {
unlockingWallet: false,
walletUnlockerGrpcActive: false,
lightningGrpcActive: false,
unlockWalletError: '',
startLndHostError: '',
startLndCertError: '',
startLndMacaroonError: '',
fetchSeedError: '',
unlockWalletError: null,
startLndError: null,
fetchSeedError: null,
syncStatus: 'pending',
blockHeight: 0,
lndBlockHeight: 0,
Expand All @@ -463,6 +459,22 @@ const lndBlockHeightSelector = state => state.lnd.lndBlockHeight
const lndFirstBlockHeightSelector = state => state.lnd.lndFirstBlockHeight
const lndCfilterHeightSelector = state => state.lnd.lndCfilterHeight
const lndFirstCfilterHeightSelector = state => state.lnd.lndFirstCfilterHeight
const startLndErrorSelector = state => state.lnd.startLndError

lndSelectors.startLndHostError = createSelector(
startLndErrorSelector,
startLndError => (startLndError ? startLndError.host : null)
)

lndSelectors.startLndCertError = createSelector(
startLndErrorSelector,
startLndError => (startLndError ? startLndError.cert : null)
)

lndSelectors.startLndMacaroonError = createSelector(
startLndErrorSelector,
startLndError => (startLndError ? startLndError.macaroon : null)
)

lndSelectors.syncPercentage = createSelector(
blockHeightSelector,
Expand Down
8 changes: 8 additions & 0 deletions stories/containers/home.stories.js
Expand Up @@ -62,6 +62,12 @@ const store = new Store({
]
})

const setError = async error => {
console.log('setError', error)
}
const setStartLndError = async error => {
console.log('setStartLndError', error)
}
const startLnd = async wallet => {
console.log('startLnd', wallet)
await delay(500)
Expand Down Expand Up @@ -114,6 +120,8 @@ storiesOf('Containers.Home', module)
stopLnd={stopLnd}
unlockWallet={unlockWallet}
deleteWallet={deleteWallet}
setError={setError}
setStartLndError={setStartLndError}
setUnlockWalletError={setUnlockWalletError}
setActiveWallet={setActiveWallet}
/>
Expand Down

0 comments on commit b41caa9

Please sign in to comment.