Browse Source

qt SwapDialog: propagate errors from _create_tx

fixes https://github.com/spesmilo/electrum/issues/8430
master
SomberNight 3 years ago
parent
commit
fc7c5dde6e
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 8
      electrum/gui/qt/main_window.py
  2. 37
      electrum/gui/qt/swap_dialog.py

8
electrum/gui/qt/main_window.py

@ -99,7 +99,7 @@ from .channels_list import ChannelsList
from .confirm_tx_dialog import ConfirmTxDialog from .confirm_tx_dialog import ConfirmTxDialog
from .rbf_dialog import BumpFeeDialog, DSCancelDialog from .rbf_dialog import BumpFeeDialog, DSCancelDialog
from .qrreader import scan_qrcode from .qrreader import scan_qrcode
from .swap_dialog import SwapDialog from .swap_dialog import SwapDialog, InvalidSwapParameters
from .balance_dialog import BalanceToolButton, COLOR_FROZEN, COLOR_UNMATURED, COLOR_UNCONFIRMED, COLOR_CONFIRMED, COLOR_LIGHTNING, COLOR_FROZEN_LIGHTNING from .balance_dialog import BalanceToolButton, COLOR_FROZEN, COLOR_UNMATURED, COLOR_UNCONFIRMED, COLOR_CONFIRMED, COLOR_LIGHTNING, COLOR_FROZEN_LIGHTNING
if TYPE_CHECKING: if TYPE_CHECKING:
@ -1126,7 +1126,11 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
self.show_error(str(e)) self.show_error(str(e))
return return
d = SwapDialog(self, is_reverse=is_reverse, recv_amount_sat=recv_amount_sat, channels=channels) d = SwapDialog(self, is_reverse=is_reverse, recv_amount_sat=recv_amount_sat, channels=channels)
return d.run() try:
return d.run()
except InvalidSwapParameters as e:
self.show_error(str(e))
return
@qt_event_listener @qt_event_listener
def on_event_request_status(self, wallet, key, status): def on_event_request_status(self, wallet, key, status):

37
electrum/gui/qt/swap_dialog.py

@ -20,17 +20,18 @@ from .my_treeview import create_toolbar_with_menu
if TYPE_CHECKING: if TYPE_CHECKING:
from .main_window import ElectrumWindow from .main_window import ElectrumWindow
CANNOT_RECEIVE_WARNING = """ CANNOT_RECEIVE_WARNING = _(
The requested amount is higher than what you can receive in your currently open channels. """The requested amount is higher than what you can receive in your currently open channels.
If you continue, your funds will be locked until the remote server can find a path to pay you. If you continue, your funds will be locked until the remote server can find a path to pay you.
If the swap cannot be performed after 24h, you will be refunded. If the swap cannot be performed after 24h, you will be refunded.
Do you want to continue? Do you want to continue?"""
""" )
class SwapDialog(WindowModalDialog, QtEventListener): class InvalidSwapParameters(Exception): pass
tx: Optional[PartialTransaction] class SwapDialog(WindowModalDialog, QtEventListener):
def __init__(self, window: 'ElectrumWindow', is_reverse=None, recv_amount_sat=None, channels=None): def __init__(self, window: 'ElectrumWindow', is_reverse=None, recv_amount_sat=None, channels=None):
WindowModalDialog.__init__(self, window, _('Submarine Swap')) WindowModalDialog.__init__(self, window, _('Submarine Swap'))
@ -231,7 +232,7 @@ class SwapDialog(WindowModalDialog, QtEventListener):
self.server_fee_label.repaint() # macOS hack for #6269 self.server_fee_label.repaint() # macOS hack for #6269
self.needs_tx_update = True self.needs_tx_update = True
def update_fee(self, tx): def update_fee(self, tx: Optional[PartialTransaction]) -> None:
"""Updates self.fee_label. No other side-effects.""" """Updates self.fee_label. No other side-effects."""
if self.is_reverse: if self.is_reverse:
sm = self.swap_manager sm = self.swap_manager
@ -243,6 +244,7 @@ class SwapDialog(WindowModalDialog, QtEventListener):
self.fee_label.repaint() # macOS hack for #6269 self.fee_label.repaint() # macOS hack for #6269
def run(self): def run(self):
"""Can raise InvalidSwapParameters."""
if not self.exec_(): if not self.exec_():
return return
if self.is_reverse: if self.is_reverse:
@ -273,24 +275,23 @@ class SwapDialog(WindowModalDialog, QtEventListener):
return return
is_max = self.max_button.isChecked() is_max = self.max_button.isChecked()
if is_max: if is_max:
tx = self._create_tx('!') tx = self._create_tx_safe('!')
self._spend_max_forward_swap(tx) self._spend_max_forward_swap(tx)
else: else:
onchain_amount = self.send_amount_e.get_amount() onchain_amount = self.send_amount_e.get_amount()
tx = self._create_tx(onchain_amount) tx = self._create_tx_safe(onchain_amount)
self.update_fee(tx) self.update_fee(tx)
def _create_tx(self, onchain_amount: Union[int, str, None]) -> Optional[PartialTransaction]: def _create_tx(self, onchain_amount: Union[int, str, None]) -> PartialTransaction:
if self.is_reverse: assert not self.is_reverse
return
if onchain_amount is None: if onchain_amount is None:
return raise InvalidSwapParameters("onchain_amount is None")
coins = self.window.get_coins() coins = self.window.get_coins()
if onchain_amount == '!': if onchain_amount == '!':
max_amount = sum(c.value_sats() for c in coins) max_amount = sum(c.value_sats() for c in coins)
max_swap_amount = self.swap_manager.max_amount_forward_swap() max_swap_amount = self.swap_manager.max_amount_forward_swap()
if max_swap_amount is None: if max_swap_amount is None:
return None raise InvalidSwapParameters("swap_manager.max_amount_forward_swap() is None")
if max_amount > max_swap_amount: if max_amount > max_swap_amount:
onchain_amount = max_swap_amount onchain_amount = max_swap_amount
outputs = [PartialTxOutput.from_address_and_value(ln_dummy_address(), onchain_amount)] outputs = [PartialTxOutput.from_address_and_value(ln_dummy_address(), onchain_amount)]
@ -299,9 +300,15 @@ class SwapDialog(WindowModalDialog, QtEventListener):
coins=coins, coins=coins,
outputs=outputs) outputs=outputs)
except (NotEnoughFunds, NoDynamicFeeEstimates) as e: except (NotEnoughFunds, NoDynamicFeeEstimates) as e:
return raise InvalidSwapParameters(str(e)) from e
return tx return tx
def _create_tx_safe(self, onchain_amount: Union[int, str, None]) -> Optional[PartialTransaction]:
try:
return self._create_tx(onchain_amount=onchain_amount)
except InvalidSwapParameters:
return None
def update_ok_button(self): def update_ok_button(self):
"""Updates self.ok_button. No other side-effects.""" """Updates self.ok_button. No other side-effects."""
send_amount = self.send_amount_e.get_amount() send_amount = self.send_amount_e.get_amount()

Loading…
Cancel
Save