electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit fd8236538a955d51e0fd3268576f34fca2eaed51
parent 9c9ceb702a3a7bd0b535793db1c3478e4a402c01
Author: ThomasV <thomasv@electrum.org>
Date:   Sat, 23 Nov 2019 13:30:05 +0100

Open lightning channels with partially signed tx.
Fixes #5379.

Diffstat:
Melectrum/commands.py | 2+-
Melectrum/gui/kivy/uix/dialogs/lightning_open_channel.py | 6+++++-
Melectrum/gui/qt/main_window.py | 8+++++++-
Melectrum/lnpeer.py | 7+++----
Melectrum/lnworker.py | 11+++++++----
5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/electrum/commands.py b/electrum/commands.py @@ -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') diff --git a/electrum/gui/kivy/uix/dialogs/lightning_open_channel.py b/electrum/gui/kivy/uix/dialogs/lightning_open_channel.py @@ -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 @@ -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) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py @@ -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)) diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py @@ -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 @@ -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'] diff --git a/electrum/lnworker.py b/electrum/lnworker.py @@ -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, @@ -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: @@ -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): """