URI: 
       tlnbase: propagate error messages received in on_error to their relevant coroutines - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 6f3c2b30edab034c7d0cb93c6ce4d8e124f55a17
   DIR parent 11c3ca281c30c7830c705c8d1295e4cd7d9d567f
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Sun,  7 Oct 2018 12:19:34 +0200
       
       lnbase: propagate error messages received in on_error to their relevant coroutines
       
       Diffstat:
         M electrum/commands.py                |       3 +--
         M electrum/gui/qt/channels_list.py    |      13 +++++++------
         M electrum/lnbase.py                  |      11 +++++++++--
         M electrum/lnworker.py                |      23 ++++++++++-------------
       
       4 files changed, 27 insertions(+), 23 deletions(-)
       ---
   DIR diff --git a/electrum/commands.py b/electrum/commands.py
       t@@ -766,8 +766,7 @@ class Commands:
            # lightning network commands
            @command('wpn')
            def open_channel(self, connection_string, amount, channel_push=0, password=None):
       -        f = self.wallet.lnworker.open_channel(connection_string, satoshis(amount), satoshis(channel_push), password)
       -        return f.result(5)
       +        return self.wallet.lnworker.open_channel(connection_string, satoshis(amount), satoshis(channel_push), password)
        
            @command('wn')
            def reestablish_channel(self):
   DIR diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py
       t@@ -110,11 +110,12 @@ class ChannelsList(MyTreeWidget):
                local_amt = local_amt_inp.get_amount()
                push_amt = push_amt_inp.get_amount()
                connect_contents = str(remote_nodeid.text()).strip()
       -
       -        try:
       -            self.main_window.protect(self.open_channel, (connect_contents, local_amt, push_amt))
       -        except ConnStringFormatError as e:
       -            self.parent.show_error(str(e))
       +        self.main_window.protect(self.open_channel, (connect_contents, local_amt, push_amt))
        
            def open_channel(self, *args, **kwargs):
       -        self.parent.wallet.lnworker.open_channel(*args, **kwargs)
       +        import traceback, sys
       +        try:
       +            self.parent.wallet.lnworker.open_channel(*args, **kwargs)
       +        except Exception as e:
       +            traceback.print_exc(file=sys.stderr)
       +            self.parent.show_error('Cannot open channel: %s' % str(e))
   DIR diff --git a/electrum/lnbase.py b/electrum/lnbase.py
       t@@ -406,6 +406,12 @@ class Peer(PrintError):
        
            def on_error(self, payload):
                self.print_error("error", payload["data"].decode("ascii"))
       +        chan_id = payload.get("channel_id")
       +        for d in [ self.channel_accepted, self.channel_reestablished, self.funding_signed,
       +                   self.funding_created, self.revoke_and_ack, self.commitment_signed,
       +                   self.announcement_signatures, self.closing_signed ]:
       +            if chan_id in d:
       +                self.channel_accepted[chan_id].put_nowait({'error':payload['data']})
        
            def on_ping(self, payload):
                l = int.from_bytes(payload['num_pong_bytes'], 'big')
       t@@ -518,7 +524,6 @@ class Peer(PrintError):
                per_commitment_secret_seed = keypair_generator(LnKeyFamily.REVOCATION_ROOT).privkey
                return local_config, per_commitment_secret_seed
        
       -    @aiosafe
            async def channel_establishment_flow(self, password, funding_sat, push_msat, temp_channel_id):
                await self.initialized
                local_config, per_commitment_secret_seed = self.make_local_config(funding_sat, push_msat, LOCAL)
       t@@ -549,6 +554,8 @@ class Peer(PrintError):
                )
                self.send_message(msg)
                payload = await self.channel_accepted[temp_channel_id].get()
       +        if payload.get('error'):
       +            raise Exception(payload.get('error'))
                remote_per_commitment_point = payload['first_per_commitment_point']
                remote_config=ChannelConfig(
                    payment_basepoint=OnlyPubkeyKeypair(payload['payment_basepoint']),
       t@@ -1094,7 +1101,7 @@ class Peer(PrintError):
                self.payment_preimages[sha256(preimage)].put_nowait(preimage)
        
            def on_update_fail_malformed_htlc(self, payload):
       -        self.on_error(payload)
       +        self.print_error("error", payload["data"].decode("ascii"))
        
            def on_update_add_htlc(self, payload):
                # no onion routing for the moment: we assume we are the end node
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -181,16 +181,13 @@ class LNWorker(PrintError):
            async def _open_channel_coroutine(self, peer, local_amount_sat, push_sat, password):
                # peer might just have been connected to
                await asyncio.wait_for(peer.initialized, 5)
       -
       -        openingchannel = await peer.channel_establishment_flow(password,
       -                                                               funding_sat=local_amount_sat + push_sat,
       -                                                               push_msat=push_sat * 1000,
       -                                                               temp_channel_id=os.urandom(32))
       -        if not openingchannel:
       -            self.print_error("Channel_establishment_flow returned None")
       -            return
       -        self.save_channel(openingchannel)
       -        self.network.lnwatcher.watch_channel(openingchannel, partial(self.on_channel_utxos, openingchannel))
       +        chan = await peer.channel_establishment_flow(
       +            password,
       +            funding_sat=local_amount_sat + push_sat,
       +            push_msat=push_sat * 1000,
       +            temp_channel_id=os.urandom(32))
       +        self.save_channel(chan)
       +        self.network.lnwatcher.watch_channel(chan, partial(self.on_channel_utxos, chan))
                self.on_channels_updated()
        
            def on_channels_updated(self):
       t@@ -206,9 +203,8 @@ class LNWorker(PrintError):
                # TODO maybe filter out onion if not on tor?
                return random.choice(addr_list)
        
       -    def open_channel(self, connect_contents, local_amt_sat, push_amt_sat, pw):
       +    def open_channel(self, connect_contents, local_amt_sat, push_amt_sat, pw, timeout=5):
                node_id, rest = extract_nodeid(connect_contents)
       -
                peer = self.peers.get(node_id)
                if not peer:
                    all_nodes = self.network.channel_db.nodes
       t@@ -225,7 +221,8 @@ class LNWorker(PrintError):
                        raise ConnStringFormatError(_('Hostname does not resolve (getaddrinfo failed)'))
                    peer = self.add_peer(host, port, node_id)
                coro = self._open_channel_coroutine(peer, local_amt_sat, push_amt_sat, None if pw == "" else pw)
       -        return asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
       +        f = asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
       +        return f.result(timeout)
        
            def pay(self, invoice, amount_sat=None):
                addr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)