diff --git a/electrum/gui/qt/confirm_tx_dialog.py b/electrum/gui/qt/confirm_tx_dialog.py index 8a9297b28..1f7a5aa4d 100644 --- a/electrum/gui/qt/confirm_tx_dialog.py +++ b/electrum/gui/qt/confirm_tx_dialog.py @@ -421,6 +421,8 @@ class TxEditor(WindowModalDialog): _('This may result in higher transactions fees.') ])) self.use_multi_change_menu.setEnabled(self.wallet.use_change) + # fixme: some of these options (WALLET_SEND_CHANGE_TO_LIGHTNING, WALLET_MERGE_DUPLICATE_OUTPUTS) + # only make sense when we create a new tx, and should not be visible/enabled in rbf dialog add_cv_action(self.config.cv.WALLET_MERGE_DUPLICATE_OUTPUTS, self.toggle_merge_duplicate_outputs) add_cv_action(self.config.cv.WALLET_SPEND_CONFIRMED_ONLY, self.toggle_confirmed_only) add_cv_action(self.config.cv.WALLET_COIN_CHOOSER_OUTPUT_ROUNDING, self.toggle_output_rounding) diff --git a/electrum/gui/qt/send_tab.py b/electrum/gui/qt/send_tab.py index 7fc6833b1..4b6064ffc 100644 --- a/electrum/gui/qt/send_tab.py +++ b/electrum/gui/qt/send_tab.py @@ -322,6 +322,7 @@ class SendTab(QWidget, MessageBoxMixin, Logger): base_tx=base_tx, is_sweep=is_sweep, send_change_to_lightning=self.config.WALLET_SEND_CHANGE_TO_LIGHTNING, + merge_duplicate_outputs=self.config.WALLET_MERGE_DUPLICATE_OUTPUTS, ) output_values = [x.value for x in outputs] is_max = any(parse_max_spend(outval) for outval in output_values) diff --git a/electrum/wallet.py b/electrum/wallet.py index 46758ea8d..e1875bb05 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -1828,6 +1828,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): BIP69_sort: Optional[bool] = True, base_tx: Optional[PartialTransaction] = None, send_change_to_lightning: bool = False, + merge_duplicate_outputs: bool = False, ) -> PartialTransaction: """Can raise NotEnoughFunds or NoDynamicFeeEstimates.""" @@ -1900,7 +1901,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): old_change_addrs = [] # change address. if empty, coin_chooser will set it change_addrs = self.get_change_addresses_for_new_transaction(change_addr or old_change_addrs) - if self.config.WALLET_MERGE_DUPLICATE_OUTPUTS: + if merge_duplicate_outputs: txo = transaction.merge_duplicate_tx_outputs(txo) tx = coin_chooser.make_tx( coins=coins, @@ -3083,6 +3084,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): base_tx: Optional[PartialTransaction] = None, inputs: Optional[List[PartialTxInput]] = None, send_change_to_lightning: Optional[bool] = None, + merge_duplicate_outputs: Optional[bool] = None, nonlocal_only: bool = False, BIP69_sort: bool = True, ) -> PartialTransaction: @@ -3098,6 +3100,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): change_addr=change_addr, base_tx=base_tx, send_change_to_lightning=send_change_to_lightning, + merge_duplicate_outputs=merge_duplicate_outputs, rbf=rbf, BIP69_sort=BIP69_sort, ) diff --git a/tests/test_wallet_vertical.py b/tests/test_wallet_vertical.py index f3b1d9a36..028b7525c 100644 --- a/tests/test_wallet_vertical.py +++ b/tests/test_wallet_vertical.py @@ -2062,11 +2062,10 @@ class TestWalletSending(ElectrumTestCase): wallet.adb.receive_tx_callback(tx1, TX_HEIGHT_UNCONFIRMED) self.assertEqual((0, 298_000, 0), wallet.get_balance()) - wallet.config.WALLET_MERGE_DUPLICATE_OUTPUTS = True # second payment to dest_addr (merged) outputs2 = [PartialTxOutput.from_address_and_value(dest_addr, 100_000)] coins = wallet.get_spendable_coins(domain=None) - tx2 = wallet.make_unsigned_transaction(coins=coins, outputs=outputs2, fee_policy=FixedFeePolicy(3000), base_tx=tx1) + tx2 = wallet.make_unsigned_transaction(coins=coins, outputs=outputs2, fee_policy=FixedFeePolicy(3000), base_tx=tx1, merge_duplicate_outputs=True) tx2.set_rbf(True) tx2.locktime = 2534850 tx2.version = 2 @@ -2081,7 +2080,6 @@ class TestWalletSending(ElectrumTestCase): wallet.adb.receive_tx_callback(tx1, TX_HEIGHT_UNCONFIRMED) self.assertEqual((0, 298_000, 0), wallet.get_balance()) - wallet.config.WALLET_MERGE_DUPLICATE_OUTPUTS = False # second payment to dest_addr (not merged, just duplicate outputs) outputs2 = [PartialTxOutput.from_address_and_value(dest_addr, 100_000)] coins = wallet.get_spendable_coins(domain=None)