electrum

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

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:
Melectrum/gui/qt/main_window.py | 4++--
Melectrum/wallet.py | 17++++++++++++-----
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()