URI: 
       tOpen lightning channels with partially signed tx. Fixes #5379. - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit fd8236538a955d51e0fd3268576f34fca2eaed51
   DIR parent 9c9ceb702a3a7bd0b535793db1c3478e4a402c01
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Sat, 23 Nov 2019 13:30:05 +0100
       
       Open lightning channels with partially signed tx.
       Fixes #5379.
       
       Diffstat:
         M electrum/commands.py                |       2 +-
         M electrum/gui/kivy/uix/dialogs/ligh… |       6 +++++-
         M electrum/gui/qt/main_window.py      |       8 +++++++-
         M electrum/lnpeer.py                  |       7 +++----
         M electrum/lnworker.py                |      11 +++++++----
       
       5 files changed, 23 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/electrum/commands.py b/electrum/commands.py
       t@@ -929,7 +929,7 @@ class Commands:
                push_sat = satoshis(push_amount)
                dummy_output = PartialTxOutput.from_address_and_value(ln_dummy_address(), funding_sat)
                funding_tx = wallet.mktx(outputs = [dummy_output], rbf=False, sign=False, nonlocal_only=True)
       -        chan = await wallet.lnworker._open_channel_coroutine(connection_string, funding_tx, funding_sat, push_sat, password)
       +        chan, funding_tx = await wallet.lnworker._open_channel_coroutine(connection_string, funding_tx, funding_sat, push_sat, password)
                return chan.funding_outpoint.to_str()
        
            @command('wn')
   DIR diff --git a/electrum/gui/kivy/uix/dialogs/lightning_open_channel.py b/electrum/gui/kivy/uix/dialogs/lightning_open_channel.py
       t@@ -138,7 +138,7 @@ class LightningOpenChannelDialog(Factory.Popup):
        
            def do_open_channel(self, conn_str, amount, password):
                try:
       -            chan = self.app.wallet.lnworker.open_channel(conn_str, amount, 0, password=password)
       +            chan, funding_tx = self.app.wallet.lnworker.open_channel(conn_str, amount, 0, password=password)
                except Exception as e:
                    self.app.show_error(_('Problem opening channel: ') + '\n' + repr(e))
                    return
       t@@ -148,4 +148,8 @@ class LightningOpenChannelDialog(Factory.Popup):
                    _('Remote peer ID') + ':' + chan.node_id.hex(),
                    _('This channel will be usable after {} confirmations').format(n)
                ])
       +        if not funding_tx.is_complete():
       +            message += '\n\n' + _('Please sign and broadcast the funding transaction')
                self.app.show_info(message)
       +        if not funding_tx.is_complete():
       +            self.app.tx_dialog(funding_tx)
   DIR diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
       t@@ -1636,14 +1636,20 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
                funding_sat = funding_tx.output_value_for_address(ln_dummy_address())
                def task():
                    return self.wallet.lnworker.open_channel(connect_str, funding_tx, funding_sat, push_amt, password)
       -        def on_success(chan):
       +        def on_success(args):
       +            chan, funding_tx = args
                    n = chan.constraints.funding_txn_minimum_depth
                    message = '\n'.join([
                        _('Channel established.'),
                        _('Remote peer ID') + ':' + chan.node_id.hex(),
                        _('This channel will be usable after {} confirmations').format(n)
                    ])
       +            if not funding_tx.is_complete():
       +                message += '\n\n' + _('Please sign and broadcast the funding transaction')
                    self.show_message(message)
       +            if not funding_tx.is_complete():
       +                self.show_transaction(funding_tx)
       +
                def on_failure(exc_info):
                    type_, e, traceback = exc_info
                    self.show_error(_('Could not open channel: {}').format(e))
   DIR diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
       t@@ -575,6 +575,8 @@ class Peer(Logger):
                funding_tx.add_outputs([funding_output])
                funding_tx.set_rbf(False)
                self.lnworker.wallet.sign_transaction(funding_tx, password)
       +        if not funding_tx.is_complete() and not funding_tx.is_segwit():
       +            raise Exception(_('Funding transaction is not complete'))
                funding_txid = funding_tx.txid()
                funding_index = funding_tx.outputs().index(funding_output)
                # remote commitment transaction
       t@@ -605,10 +607,7 @@ class Peer(Logger):
                remote_sig = payload['signature']
                chan.receive_new_commitment(remote_sig, [])
                chan.open_with_first_pcp(remote_per_commitment_point, remote_sig)
       -        # broadcast funding tx
       -        # TODO make more robust (timeout low? server returns error?)
       -        await asyncio.wait_for(self.network.broadcast_transaction(funding_tx), LN_P2P_NETWORK_TIMEOUT)
       -        return chan
       +        return chan, funding_tx
        
            async def on_open_channel(self, payload):
                # payload['channel_flags']
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -812,7 +812,7 @@ class LNWallet(LNWorker):
                peer = await self.add_peer(connect_str)
                # peer might just have been connected to
                await asyncio.wait_for(peer.initialized.wait(), LN_P2P_NETWORK_TIMEOUT)
       -        chan = await peer.channel_establishment_flow(
       +        chan, funding_tx = await peer.channel_establishment_flow(
                    password,
                    funding_tx=funding_tx,
                    funding_sat=funding_sat,
       t@@ -821,7 +821,10 @@ class LNWallet(LNWorker):
                self.save_channel(chan)
                self.lnwatcher.add_channel(chan.funding_outpoint.to_str(), chan.get_funding_address())
                self.network.trigger_callback('channels_updated', self.wallet)
       -        return chan
       +        if funding_tx.is_complete():
       +            # TODO make more robust (timeout low? server returns error?)
       +            await asyncio.wait_for(self.network.broadcast_transaction(funding_tx), LN_P2P_NETWORK_TIMEOUT)
       +        return chan, funding_tx
        
            @log_exceptions
            async def add_peer(self, connect_str: str) -> Peer:
       t@@ -858,10 +861,10 @@ class LNWallet(LNWorker):
                coro = self._open_channel_coroutine(connect_str, funding_tx, funding_sat, push_amt_sat, password)
                fut = asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
                try:
       -            chan = fut.result(timeout=timeout)
       +            chan, funding_tx = fut.result(timeout=timeout)
                except concurrent.futures.TimeoutError:
                    raise Exception(_("open_channel timed out"))
       -        return chan
       +        return chan, funding_tx
        
            def pay(self, invoice, amount_sat=None, attempts=1):
                """