diff --git a/electrum/wallet.py b/electrum/wallet.py index 70648ec0e..060de9025 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -1850,6 +1850,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): def get_change_addresses_for_new_transaction( self, preferred_change_addr=None, *, allow_reusing_used_change_addrs: bool = True, ) -> List[str]: + """note: might return an empty list! (e.g. if use_change is disabled, or allow_reuse is False)""" change_addrs = [] if preferred_change_addr: if isinstance(preferred_change_addr, (list, tuple)): @@ -2111,7 +2112,8 @@ class Abstract_Wallet(ABC, Logger, EventListener): to_distribute -= reserve_sized_input.value_sats() else: self.logger.info(f'Adding change output to meet utxo reserve requirements') - change_addr = self.get_change_addresses_for_new_transaction(change_addr)[0] + change_addrs = self.get_change_addresses_for_new_transaction(change_addr) + change_addr = change_addrs[0] if change_addrs else tx_inputs[0].address change = PartialTxOutput.from_address_and_value(change_addr, self.config.LN_UTXO_RESERVE) change.is_utxo_reserve = True # for GUI outputs.append(change) diff --git a/tests/test_wallet_vertical.py b/tests/test_wallet_vertical.py index c1c73dcfa..2578362d0 100644 --- a/tests/test_wallet_vertical.py +++ b/tests/test_wallet_vertical.py @@ -2107,6 +2107,27 @@ class TestWalletSending(ElectrumTestCase): tx = make_tx(to_self_address) self.assertEqual(1, len(tx.outputs())) + async def test_ln_reserve__usechange_off(self): + """Send all the coins using 'max', with wallet.use_change being off. + This will create a reserve UTXO, reusing an input address. + """ + wallet, outgoing_address, to_self_address = self._create_cause_carbon_wallet() + wallet.use_change = False + def make_tx(): + outputs = [PartialTxOutput.from_address_and_value(outgoing_address, '!')] + wallet.lnworker = mock.Mock() + wallet.lnworker.has_anchor_channels.return_value = True + return wallet.make_unsigned_transaction( + outputs = outputs, + fee_policy = FixedFeePolicy(100), + ) + tx = make_tx() + self.assertEqual(1, len(tx.inputs())) + self.assertEqual(2, len(tx.outputs())) + outputs = {txout.address: txout.value for txout in tx.outputs()} + assert outgoing_address in outputs + assert outputs[tx.inputs()[0].address] == self.config.LN_UTXO_RESERVE # address-reuse + async def test_ln_reserve_keep_existing_reserve(self): """ tests if make_unsigned_transaction keeps the existing reserve utxo