gui: detect if reserve inputs have been removed from tx
Adapts the gui(s) to detect if an existing reserve input has not been used as input for the transaction even though the user tried to spend max. This allows to show the lightning reserve warning not only for reserve change outputs but also for existing reserve inputs that have been ignored for this max spend transaction. Still keeps the `is_utxo_reserve` flag on `PartialTxOutput` as it is used in the qml gui.
This commit is contained in:
@@ -434,7 +434,10 @@ class QETxFinalizer(TxFeeSlider):
|
||||
self.update_fee_warning_from_tx(tx=tx, invoice_amt=amount)
|
||||
|
||||
if self._amount.isMax and not self.warning:
|
||||
if reserve_sats := sum(txo.value for txo in tx.outputs() if txo.is_utxo_reserve):
|
||||
if reserve_sats := self._wallet.wallet.tx_keeps_ln_utxo_reserve(
|
||||
tx,
|
||||
gui_spend_max=self._amount.isMax
|
||||
):
|
||||
reserve_str = self._config.format_amount_and_units(reserve_sats)
|
||||
self.warning = ' '.join([
|
||||
_('Warning') + ':',
|
||||
|
||||
@@ -544,7 +544,7 @@ class TxEditor(WindowModalDialog):
|
||||
if any((txin.block_height is not None and txin.block_height<=0) for txin in self.tx.inputs()):
|
||||
messages.append(_('This transaction will spend unconfirmed coins.'))
|
||||
# warn if a reserve utxo was added
|
||||
if reserve_sats := sum(txo.value for txo in self.tx.outputs() if txo.is_utxo_reserve):
|
||||
if reserve_sats := self.wallet.tx_keeps_ln_utxo_reserve(self.tx, gui_spend_max=bool(self.output_value == '!')):
|
||||
reserve_str = self.main_window.config.format_amount_and_units(reserve_sats)
|
||||
messages.append(_('Could not spend max: a security reserve of {} was kept for your Lightning channels.').format(reserve_str))
|
||||
# warn if we merge from mempool
|
||||
|
||||
@@ -1911,6 +1911,19 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
def is_low_reserve(self) -> bool:
|
||||
return self.should_keep_reserve_utxo([], [], False)
|
||||
|
||||
def tx_keeps_ln_utxo_reserve(self, tx, *, gui_spend_max: bool) -> Optional[int]:
|
||||
if reserve_output_amount := sum(txo.value for txo in tx.outputs() if txo.is_utxo_reserve):
|
||||
# tx has a reserve change output
|
||||
return reserve_output_amount
|
||||
if gui_spend_max: # user tried to spend max amount
|
||||
coins_in_wallet = self.get_spendable_coins(nonlocal_only=False, confirmed_only=False)
|
||||
amount_in_wallet = sum(c.value_sats() for c in coins_in_wallet)
|
||||
tx_spend_amount = tx.output_value() + tx.get_fee()
|
||||
if amount_in_wallet - tx_spend_amount == self.config.LN_UTXO_RESERVE:
|
||||
# tx keeps exactly LN_UTXO_RESERVE amount sats in the wallet
|
||||
return self.config.LN_UTXO_RESERVE
|
||||
return None
|
||||
|
||||
@profiler(min_threshold=0.1)
|
||||
def make_unsigned_transaction(
|
||||
self, *,
|
||||
|
||||
Reference in New Issue
Block a user