commit 49284f716b90a266b4664b364d7c0303ac4ba123
parent fec96775089a1831a49bbd1a0e7d06d29b2d4021
Author: SomberNight <somber.night@protonmail.com>
Date: Wed, 20 Nov 2019 18:43:05 +0100
wallet: bump fee now supports coin selection
related: #5719
Diffstat:
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
@@ -1471,7 +1471,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
else:
raise Exception('unknown invoice type')
- def get_coins(self, nonlocal_only=False):
+ def get_coins(self, *, nonlocal_only=False):
coins = self.get_manually_selected_coins()
return coins or self.wallet.get_spendable_coins(None, nonlocal_only=nonlocal_only)
@@ -2949,7 +2949,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
is_final = cb.isChecked()
new_fee_rate = feerate_e.get_amount()
try:
- new_tx = self.wallet.bump_fee(tx=tx, new_fee_rate=new_fee_rate)
+ new_tx = self.wallet.bump_fee(tx=tx, new_fee_rate=new_fee_rate, coins=self.get_coins())
except CannotBumpFee as e:
self.show_error(str(e))
return
diff --git a/electrum/wallet.py b/electrum/wallet.py
@@ -1097,9 +1097,11 @@ class Abstract_Wallet(AddressSynchronizer):
max_conf = max(max_conf, tx_age)
return max_conf >= req_conf
- def bump_fee(self, *, tx: Transaction, new_fee_rate) -> PartialTransaction:
+ def bump_fee(self, *, tx: Transaction, new_fee_rate: Union[int, float, Decimal],
+ coins: Sequence[PartialTxInput] = None) -> PartialTransaction:
"""Increase the miner fee of 'tx'.
'new_fee_rate' is the target min rate in sat/vbyte
+ 'coins' is a list of UTXOs we can choose from as potential new inputs to be added
"""
if tx.is_final():
raise CannotBumpFee(_('Cannot bump fee') + ': ' + _('transaction is final'))
@@ -1118,7 +1120,7 @@ class Abstract_Wallet(AddressSynchronizer):
# method 1: keep all inputs, keep all not is_mine outputs,
# allow adding new inputs
tx_new = self._bump_fee_through_coinchooser(
- tx=tx, new_fee_rate=new_fee_rate)
+ tx=tx, new_fee_rate=new_fee_rate, coins=coins)
method_used = 1
except CannotBumpFee:
# method 2: keep all inputs, no new inputs are added,
@@ -1139,7 +1141,8 @@ class Abstract_Wallet(AddressSynchronizer):
tx_new.locktime = get_locktime_for_new_transaction(self.network)
return tx_new
- def _bump_fee_through_coinchooser(self, *, tx: Transaction, new_fee_rate) -> PartialTransaction:
+ def _bump_fee_through_coinchooser(self, *, tx: Transaction, new_fee_rate: Union[int, Decimal],
+ coins: Sequence[PartialTxInput] = None) -> PartialTransaction:
tx = PartialTransaction.from_tx(tx)
tx.add_info_from_wallet(self)
old_inputs = list(tx.inputs())
@@ -1164,7 +1167,10 @@ class Abstract_Wallet(AddressSynchronizer):
if not fixed_outputs:
raise CannotBumpFee(_('Cannot bump fee') + ': could not figure out which outputs to keep')
- coins = self.get_spendable_coins(None)
+ if coins is None:
+ coins = self.get_spendable_coins(None)
+ # make sure we don't try to spend output from the tx-to-be-replaced:
+ coins = [c for c in coins if c.prevout.txid.hex() != tx.txid()]
for item in coins:
self.add_input_info(item)
def fee_estimator(size):
@@ -1180,7 +1186,8 @@ class Abstract_Wallet(AddressSynchronizer):
except NotEnoughFunds as e:
raise CannotBumpFee(e)
- def _bump_fee_through_decreasing_outputs(self, *, tx: Transaction, new_fee_rate) -> PartialTransaction:
+ def _bump_fee_through_decreasing_outputs(self, *, tx: Transaction,
+ new_fee_rate: Union[int, Decimal]) -> PartialTransaction:
tx = PartialTransaction.from_tx(tx)
tx.add_info_from_wallet(self)
inputs = tx.inputs()