Qt swaps_dialog: do not use side effects to update tx.
Use the app timer instead, so that the tx is not recomputed on every slider move (like in ConfirmTxDialog). A similar modification is needed for QML. I started with Qt in order to get a sense of how it should be done.
This commit is contained in:
@@ -38,7 +38,6 @@ class SwapDialog(WindowModalDialog):
|
|||||||
self.lnworker = self.window.wallet.lnworker
|
self.lnworker = self.window.wallet.lnworker
|
||||||
self.swap_manager = self.lnworker.swap_manager
|
self.swap_manager = self.lnworker.swap_manager
|
||||||
self.network = window.network
|
self.network = window.network
|
||||||
self.tx = None # for the forward-swap only
|
|
||||||
self.channels = channels
|
self.channels = channels
|
||||||
self.is_reverse = is_reverse if is_reverse is not None else True
|
self.is_reverse = is_reverse if is_reverse is not None else True
|
||||||
vbox = QVBoxLayout(self)
|
vbox = QVBoxLayout(self)
|
||||||
@@ -102,6 +101,14 @@ class SwapDialog(WindowModalDialog):
|
|||||||
if recv_amount_sat:
|
if recv_amount_sat:
|
||||||
self.init_recv_amount(recv_amount_sat)
|
self.init_recv_amount(recv_amount_sat)
|
||||||
self.update()
|
self.update()
|
||||||
|
self.needs_tx_update = True
|
||||||
|
self.window.gui_object.timer.timeout.connect(self.timer_actions)
|
||||||
|
|
||||||
|
def timer_actions(self):
|
||||||
|
if self.needs_tx_update:
|
||||||
|
self.update_tx()
|
||||||
|
self.update_ok_button()
|
||||||
|
self.needs_tx_update = False
|
||||||
|
|
||||||
def init_recv_amount(self, recv_amount_sat):
|
def init_recv_amount(self, recv_amount_sat):
|
||||||
if recv_amount_sat == '!':
|
if recv_amount_sat == '!':
|
||||||
@@ -137,32 +144,23 @@ class SwapDialog(WindowModalDialog):
|
|||||||
if self.is_reverse:
|
if self.is_reverse:
|
||||||
self._spend_max_reverse_swap()
|
self._spend_max_reverse_swap()
|
||||||
else:
|
else:
|
||||||
self._spend_max_forward_swap()
|
# spend_max_forward_swap will be called in update_tx
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
self.send_amount_e.setAmount(None)
|
self.send_amount_e.setAmount(None)
|
||||||
self.update_fee()
|
self.needs_tx_update = True
|
||||||
self.update_ok_button()
|
|
||||||
|
|
||||||
def uncheck_max(self):
|
def uncheck_max(self):
|
||||||
self.max_button.setChecked(False)
|
self.max_button.setChecked(False)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def _spend_max_forward_swap(self):
|
def _spend_max_forward_swap(self, tx):
|
||||||
self._update_tx('!')
|
if tx:
|
||||||
if self.tx:
|
amount = tx.output_value_for_address(ln_dummy_address())
|
||||||
amount = self.tx.output_value_for_address(ln_dummy_address())
|
self.send_amount_e.setAmount(amount)
|
||||||
max_amt = self.swap_manager.max_amount_forward_swap()
|
else:
|
||||||
if max_amt is None:
|
self.send_amount_e.setAmount(None)
|
||||||
self.send_amount_e.setAmount(None)
|
self.max_button.setChecked(False)
|
||||||
self.max_button.setChecked(False)
|
|
||||||
return
|
|
||||||
if amount > max_amt:
|
|
||||||
amount = max_amt
|
|
||||||
self._update_tx(amount)
|
|
||||||
if self.tx:
|
|
||||||
amount = self.tx.output_value_for_address(ln_dummy_address())
|
|
||||||
assert amount <= max_amt
|
|
||||||
self.send_amount_e.setAmount(amount)
|
|
||||||
|
|
||||||
def _spend_max_reverse_swap(self):
|
def _spend_max_reverse_swap(self):
|
||||||
amount = min(self.lnworker.num_sats_can_send(), self.swap_manager.get_max_amount())
|
amount = min(self.lnworker.num_sats_can_send(), self.swap_manager.get_max_amount())
|
||||||
@@ -185,9 +183,7 @@ class SwapDialog(WindowModalDialog):
|
|||||||
self.recv_amount_e.setStyleSheet(ColorScheme.BLUE.as_stylesheet())
|
self.recv_amount_e.setStyleSheet(ColorScheme.BLUE.as_stylesheet())
|
||||||
self.recv_amount_e.follows = False
|
self.recv_amount_e.follows = False
|
||||||
self.send_follows = False
|
self.send_follows = False
|
||||||
self._update_tx(send_amount)
|
self.needs_tx_update = True
|
||||||
self.update_fee()
|
|
||||||
self.update_ok_button()
|
|
||||||
|
|
||||||
def on_recv_edited(self):
|
def on_recv_edited(self):
|
||||||
if self.recv_amount_e.follows:
|
if self.recv_amount_e.follows:
|
||||||
@@ -202,9 +198,7 @@ class SwapDialog(WindowModalDialog):
|
|||||||
self.send_amount_e.setStyleSheet(ColorScheme.BLUE.as_stylesheet())
|
self.send_amount_e.setStyleSheet(ColorScheme.BLUE.as_stylesheet())
|
||||||
self.send_amount_e.follows = False
|
self.send_amount_e.follows = False
|
||||||
self.send_follows = True
|
self.send_follows = True
|
||||||
self._update_tx(send_amount)
|
self.needs_tx_update = True
|
||||||
self.update_fee()
|
|
||||||
self.update_ok_button()
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
from .util import IconLabel
|
from .util import IconLabel
|
||||||
@@ -219,17 +213,15 @@ class SwapDialog(WindowModalDialog):
|
|||||||
server_fee_str = '%.2f'%sm.percentage + '% + ' + self.window.format_amount(server_mining_fee) + ' ' + self.window.base_unit()
|
server_fee_str = '%.2f'%sm.percentage + '% + ' + self.window.format_amount(server_mining_fee) + ' ' + self.window.base_unit()
|
||||||
self.server_fee_label.setText(server_fee_str)
|
self.server_fee_label.setText(server_fee_str)
|
||||||
self.server_fee_label.repaint() # macOS hack for #6269
|
self.server_fee_label.repaint() # macOS hack for #6269
|
||||||
self.update_tx()
|
self.needs_tx_update = True
|
||||||
self.update_fee()
|
|
||||||
self.update_ok_button()
|
|
||||||
|
|
||||||
def update_fee(self):
|
def update_fee(self, tx):
|
||||||
"""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
|
||||||
fee = sm.get_claim_fee()
|
fee = sm.get_claim_fee()
|
||||||
else:
|
else:
|
||||||
fee = self.tx.get_fee() if self.tx else None
|
fee = tx.get_fee() if tx else None
|
||||||
fee_text = self.window.format_amount(fee) + ' ' + self.window.base_unit() if fee else ''
|
fee_text = self.window.format_amount(fee) + ' ' + self.window.base_unit() if fee else ''
|
||||||
self.fee_label.setText(fee_text)
|
self.fee_label.setText(fee_text)
|
||||||
self.fee_label.repaint() # macOS hack for #6269
|
self.fee_label.repaint() # macOS hack for #6269
|
||||||
@@ -261,42 +253,45 @@ class SwapDialog(WindowModalDialog):
|
|||||||
|
|
||||||
def update_tx(self):
|
def update_tx(self):
|
||||||
if self.is_reverse:
|
if self.is_reverse:
|
||||||
|
self.update_fee(None)
|
||||||
return
|
return
|
||||||
is_max = self.max_button.isChecked()
|
is_max = self.max_button.isChecked()
|
||||||
if is_max:
|
if is_max:
|
||||||
self._spend_max_forward_swap()
|
tx = self._create_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()
|
||||||
self._update_tx(onchain_amount)
|
tx = self._create_tx(onchain_amount)
|
||||||
|
self.update_fee(tx)
|
||||||
|
|
||||||
def _update_tx(self, onchain_amount):
|
def _create_tx(self, onchain_amount):
|
||||||
"""Updates self.tx. No other side-effects."""
|
|
||||||
if self.is_reverse:
|
if self.is_reverse:
|
||||||
return
|
return
|
||||||
if onchain_amount is None:
|
if onchain_amount is None:
|
||||||
self.tx = None
|
|
||||||
return
|
return
|
||||||
outputs = [PartialTxOutput.from_address_and_value(ln_dummy_address(), onchain_amount)]
|
|
||||||
coins = self.window.get_coins()
|
coins = self.window.get_coins()
|
||||||
|
if onchain_amount == '!':
|
||||||
|
max_amount = sum(c.value_sats() for c in coins)
|
||||||
|
max_swap_amount = self.swap_manager.max_amount_forward_swap()
|
||||||
|
if max_amount > max_swap_amount:
|
||||||
|
onchain_amount = max_swap_amount
|
||||||
|
outputs = [PartialTxOutput.from_address_and_value(ln_dummy_address(), onchain_amount)]
|
||||||
try:
|
try:
|
||||||
self.tx = self.window.wallet.make_unsigned_transaction(
|
tx = self.window.wallet.make_unsigned_transaction(
|
||||||
coins=coins,
|
coins=coins,
|
||||||
outputs=outputs)
|
outputs=outputs)
|
||||||
except (NotEnoughFunds, NoDynamicFeeEstimates) as e:
|
except (NotEnoughFunds, NoDynamicFeeEstimates) as e:
|
||||||
self.tx = None
|
return
|
||||||
|
return tx
|
||||||
|
|
||||||
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()
|
||||||
recv_amount = self.recv_amount_e.get_amount()
|
recv_amount = self.recv_amount_e.get_amount()
|
||||||
self.ok_button.setEnabled(
|
self.ok_button.setEnabled(bool(send_amount) and bool(recv_amount))
|
||||||
(send_amount is not None)
|
|
||||||
and (recv_amount is not None)
|
|
||||||
and (self.tx is not None or self.is_reverse)
|
|
||||||
)
|
|
||||||
|
|
||||||
def do_normal_swap(self, lightning_amount, onchain_amount, password):
|
def do_normal_swap(self, lightning_amount, onchain_amount, password):
|
||||||
tx = self.tx
|
tx = self._create_tx(onchain_amount)
|
||||||
assert tx
|
assert tx
|
||||||
coro = self.swap_manager.normal_swap(
|
coro = self.swap_manager.normal_swap(
|
||||||
lightning_amount_sat=lightning_amount,
|
lightning_amount_sat=lightning_amount,
|
||||||
|
|||||||
Reference in New Issue
Block a user