URI: 
       tlnworker improvements: - enable option data_loss_protect - separate add_peer from open_channel - display exceptions raised in open_channel - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit b8d908d63edf2b36029ce5c46b435a45db1ddecf
   DIR parent d2dfa8c558d81835c801c36b3c655e5357a18f58
  HTML 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:
         M electrum/commands.py                |       8 ++++----
         M electrum/gui/qt/main_window.py      |       5 ++++-
         M electrum/lnworker.py                |      40 +++++++++++++++++++------------
       
       3 files changed, 33 insertions(+), 20 deletions(-)
       ---
   DIR diff --git a/electrum/commands.py b/electrum/commands.py
       t@@ -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)
        
   DIR diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
       t@@ -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
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -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)
       t@@ -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]:
       t@@ -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()
       t@@ -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)
       t@@ -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):
       t@@ -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)
       t@@ -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)