Skip to content

Commit

Permalink
fix(lnd): relax unhandled openchannel timeout
Browse files Browse the repository at this point in the history
This removes the hard timeout placed on each attempt to connect to a
peer's lnd node when attempting to open a channel with that peer. This
timeout was causing xud to crash because it threw an error that was not
being handled in the encapsulating catch block, which did not catch the
error because it was thrown from a callback.

Rather than attempt to correct the asynchronous exception handling,
this lifts the timeout limit set within xud and instead will wait on
each connect attempt until it succeeds, times out, or fails according to
the logic within lnd.

Fixes #1405.
  • Loading branch information
sangaman committed Apr 9, 2020
1 parent bd1711d commit b072391
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 39 deletions.
16 changes: 4 additions & 12 deletions lib/lndclient/LndClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,14 +725,13 @@ class LndClient extends SwapClient {
if (connectionEstablished) {
await this.openChannelSync(peerPubKey, units);
} else {
throw new Error('connectPeerAddreses failed');
throw new Error(`could not connect to lnd uris for ${peerPubKey}`);
}
}

/**
* Tries to connect to a given list of peer's node addresses
* in a sequential order.
* Returns true when successful, otherwise false.
* Tries to connect to a given list of a peer's uris in sequential order.
* @returns `true` when successful, otherwise `false`.
*/
private connectPeerAddreses = async (
peerListeningUris: string[],
Expand All @@ -745,23 +744,16 @@ class LndClient extends SwapClient {
address: splitUri[1],
};
});
const CONNECT_TIMEOUT = 4000;
for (const uri of splitListeningUris) {
const { peerPubKey, address } = uri;
let timeout: NodeJS.Timeout | undefined;
try {
timeout = setTimeout(() => {
throw new Error('connectPeer has timed out');
}, CONNECT_TIMEOUT);
await this.connectPeer(peerPubKey, address);
return true;
} catch (e) {
if (e.message && e.message.includes('already connected')) {
return true;
}
this.logger.trace(`connectPeer failed: ${e}`);
} finally {
timeout && clearTimeout(timeout);
this.logger.trace(`connectPeer to ${uri} failed: ${e}`);
}
}
return false;
Expand Down
24 changes: 0 additions & 24 deletions test/jest/LndClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,30 +126,6 @@ describe('LndClient', () => {
.toHaveBeenCalledWith(peerPubKey, units);
});

test('it throws when timeout reached', async () => {
expect.assertions(3);
jest.useFakeTimers();
lnd['openChannelSync'] = jest.fn().mockReturnValue(Promise.resolve());
const timeOut = () => {
jest.runAllTimers();
return new Promise(() => {});
};
lnd['connectPeer'] = jest.fn()
.mockImplementation(timeOut);
try {
await lnd.openChannel({
units,
peerIdentifier: peerPubKey,
lndUris: lndListeningUris,
});
} catch (e) {
expect(e).toMatchSnapshot();
}
expect(lnd['connectPeer']).toHaveBeenCalledTimes(2);
expect(lnd['openChannelSync']).not.toHaveBeenCalled();
jest.clearAllTimers();
});

test('it stops trying to connect to lnd uris when first once succeeds', async () => {
expect.assertions(3);
lnd['openChannelSync'] = jest.fn().mockReturnValue(Promise.resolve());
Expand Down
4 changes: 1 addition & 3 deletions test/jest/__snapshots__/LndClient.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`LndClient openChannel it throws when connectPeer fails 1`] = `[Error: connectPeerAddreses failed]`;
exports[`LndClient openChannel it throws when connectPeer fails 1`] = `[Error: could not connect to lnd uris for 02f8895eb03c37b2665415be4d83b20228acc0abc55ebf6728565141c66cfc164a]`;

exports[`LndClient openChannel it throws when openchannel fails 1`] = `[Error: openChannelSync error]`;

exports[`LndClient openChannel it throws when timeout reached 1`] = `[Error: connectPeerAddreses failed]`;

exports[`LndClient sendPayment it rejects upon sendPaymentSync error 1`] = `
Object {
"code": "7.4",
Expand Down

0 comments on commit b072391

Please sign in to comment.