commit b8d908d63edf2b36029ce5c46b435a45db1ddecf
parent d2dfa8c558d81835c801c36b3c655e5357a18f58
Author: ThomasV <thomasv@electrum.org>
Date: Wed, 5 Jun 2019 11:08:16 +0200
lnworker improvements:
- enable option data_loss_protect
- separate add_peer from open_channel
- display exceptions raised in open_channel
Diffstat:
3 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/electrum/commands.py b/electrum/commands.py
@@ -771,15 +771,15 @@ class Commands:
return sorted(known_commands.keys())
# lightning network commands
+ @command('wn')
+ def add_peer(self, connection_string, timeout=20):
+ return self.lnworker.add_peer(connection_string)
+
@command('wpn')
def open_channel(self, connection_string, amount, channel_push=0, password=None):
return self.lnworker.open_channel(connection_string, satoshis(amount), satoshis(channel_push), password)
@command('wn')
- def reestablish_channel(self):
- self.lnworker.reestablish_channel()
-
- @command('wn')
def lnpay(self, invoice, attempts=1, timeout=10):
return self.lnworker.pay(invoice, attempts=attempts, timeout=timeout)
diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
@@ -1860,7 +1860,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
_('Remote peer ID') + ':' + node_id,
_('This channel will be usable after 3 confirmations')
]))
- WaitingDialog(self, _('Opening channel...'), task, on_success, self.on_error)
+ def on_failure(exc_info):
+ type_, e, traceback = exc_info
+ self.show_error(_('Could not open channel: {}').format(e))
+ WaitingDialog(self, _('Opening channel...'), task, on_success, on_failure)
def query_choice(self, msg, choices):
# Needed by QtHandler for hardware wallets
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
@@ -114,9 +114,9 @@ class LNWorker(Logger):
for peer in peers:
last_tried = self._last_tried_peer.get(peer, 0)
if last_tried + PEER_RETRY_INTERVAL < now:
- await self.add_peer(peer.host, peer.port, peer.pubkey)
+ await self._add_peer(peer.host, peer.port, peer.pubkey)
- async def add_peer(self, host, port, node_id):
+ async def _add_peer(self, host, port, node_id):
if node_id in self.peers:
return self.peers[node_id]
port = int(port)
@@ -142,7 +142,7 @@ class LNWorker(Logger):
peer_list = self.config.get('lightning_peers', [])
for host, port, pubkey in peer_list:
asyncio.run_coroutine_threadsafe(
- self.add_peer(host, int(port), bfh(pubkey)),
+ self._add_peer(host, int(port), bfh(pubkey)),
self.network.asyncio_loop)
def _get_next_peers_to_try(self) -> Sequence[LNPeerAddr]:
@@ -302,7 +302,7 @@ class LNWallet(LNWorker):
super().__init__(xprv)
self.ln_keystore = keystore.from_xprv(xprv)
#self.localfeatures |= LnLocalFeatures.OPTION_DATA_LOSS_PROTECT_REQ
- #self.localfeatures |= LnLocalFeatures.OPTION_DATA_LOSS_PROTECT_OPT
+ self.localfeatures |= LnLocalFeatures.OPTION_DATA_LOSS_PROTECT_OPT
self.invoices = self.storage.get('lightning_invoices', {}) # RHASH -> (invoice, direction, is_paid)
self.preimages = self.storage.get('lightning_preimages', {}) # RHASH -> preimage
self.sweep_address = wallet.get_receiving_address()
@@ -618,15 +618,14 @@ class LNWallet(LNWorker):
def on_channels_updated(self):
self.network.trigger_callback('channels')
- def open_channel(self, connect_contents, local_amt_sat, push_amt_sat, password=None, timeout=20):
- node_id, rest = extract_nodeid(connect_contents)
+ def add_peer(self, connect_str, timeout=20):
+ node_id, rest = extract_nodeid(connect_str)
peer = self.peers.get(node_id)
if not peer:
- nodes_get = self.network.channel_db.nodes_get
- node_info = nodes_get(node_id)
if rest is not None:
host, port = split_host_port(rest)
else:
+ node_info = self.network.channel_db.nodes_get(node_id)
if not node_info:
raise ConnStringFormatError(_('Unknown node:') + ' ' + bh2u(node_id))
addrs = self.channel_db.get_node_addresses(node_info)
@@ -637,12 +636,23 @@ class LNWallet(LNWorker):
socket.getaddrinfo(host, int(port))
except socket.gaierror:
raise ConnStringFormatError(_('Hostname does not resolve (getaddrinfo failed)'))
- peer_future = asyncio.run_coroutine_threadsafe(self.add_peer(host, port, node_id),
- self.network.asyncio_loop)
- peer = peer_future.result(timeout)
+ peer_future = asyncio.run_coroutine_threadsafe(
+ self._add_peer(host, port, node_id),
+ self.network.asyncio_loop)
+ try:
+ peer = peer_future.result(timeout)
+ except concurrent.futures.TimeoutError:
+ raise Exception(_("add_peer timed out"))
+ return peer
+
+ def open_channel(self, connect_str, local_amt_sat, push_amt_sat, password=None, timeout=20):
+ peer = self.add_peer(connect_str, timeout)
coro = self._open_channel_coroutine(peer, local_amt_sat, push_amt_sat, password)
- f = asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
- chan = f.result(timeout)
+ fut = asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
+ try:
+ chan = fut.result(timeout=timeout)
+ except concurrent.futures.TimeoutError:
+ raise Exception(_("open_channel timed out"))
return chan.funding_outpoint.to_str()
def pay(self, invoice, attempts=1, amount_sat=None, timeout=10):
@@ -908,7 +918,7 @@ class LNWallet(LNWorker):
if peer:
last_tried = self._last_tried_peer.get(peer, 0)
if last_tried + PEER_RETRY_INTERVAL_FOR_CHANNELS < now:
- await self.add_peer(peer.host, peer.port, peer.pubkey)
+ await self._add_peer(peer.host, peer.port, peer.pubkey)
return
# try random address for node_id
node_info = self.channel_db.nodes_get(chan.node_id)
@@ -920,7 +930,7 @@ class LNWallet(LNWorker):
peer = LNPeerAddr(host, port, chan.node_id)
last_tried = self._last_tried_peer.get(peer, 0)
if last_tried + PEER_RETRY_INTERVAL_FOR_CHANNELS < now:
- await self.add_peer(host, port, chan.node_id)
+ await self._add_peer(host, port, chan.node_id)
while True:
await asyncio.sleep(1)