URI: 
       twallet: split "change address logic" from make_unsigned_transaction - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 8bfe12e047a4be2f534b5c066f0698d9273ff391
   DIR parent e864fa50882db90df50e6e0240f55197b28097ed
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Thu, 20 Jun 2019 17:54:37 +0200
       
       wallet: split "change address logic" from make_unsigned_transaction
       
       Diffstat:
         M electrum/wallet.py                  |      52 ++++++++++++++++++-------------
       
       1 file changed, 30 insertions(+), 22 deletions(-)
       ---
   DIR diff --git a/electrum/wallet.py b/electrum/wallet.py
       t@@ -674,6 +674,33 @@ class Abstract_Wallet(AddressSynchronizer):
                    return tx
                return candidate
        
       +    def get_change_addresses_for_new_transaction(self, preferred_change_addr=None) -> List[str]:
       +        change_addrs = []
       +        if preferred_change_addr:
       +            if isinstance(preferred_change_addr, (list, tuple)):
       +                change_addrs = list(preferred_change_addr)
       +            else:
       +                change_addrs = [preferred_change_addr]
       +        elif self.use_change:
       +            # Recalc and get unused change addresses
       +            addrs = self.calc_unused_change_addresses()
       +            # New change addresses are created only after a few
       +            # confirmations.
       +            if addrs:
       +                # if there are any unused, select all
       +                change_addrs = addrs
       +            else:
       +                # if there are none, take one randomly from the last few
       +                addrs = self.get_change_addresses()[-self.gap_limit_for_change:]
       +                change_addrs = [random.choice(addrs)] if addrs else []
       +        for addr in change_addrs:
       +            assert is_address(addr), f"not valid bitcoin address: {addr}"
       +            # note that change addresses are not necessarily ismine
       +            # in which case this is a no-op
       +            self.check_address(addr)
       +        max_change = self.max_change_outputs if self.multiple_change else 1
       +        return change_addrs[:max_change]
       +
            def make_unsigned_transaction(self, coins, outputs, config, fixed_fee=None,
                                          change_addr=None, is_sweep=False):
                # check outputs
       t@@ -694,26 +721,8 @@ class Abstract_Wallet(AddressSynchronizer):
                    self.add_input_info(item)
        
                # change address
       -        # if we leave it empty, coin_chooser will set it
       -        change_addrs = []
       -        if change_addr:
       -            change_addrs = [change_addr]
       -        elif self.use_change:
       -            # Recalc and get unused change addresses
       -            addrs = self.calc_unused_change_addresses()
       -            # New change addresses are created only after a few
       -            # confirmations.
       -            if addrs:
       -                # if there are any unused, select all
       -                change_addrs = addrs
       -            else:
       -                # if there are none, take one randomly from the last few
       -                addrs = self.get_change_addresses()[-self.gap_limit_for_change:]
       -                change_addrs = [random.choice(addrs)] if addrs else []
       -        for addr in change_addrs:
       -            # note that change addresses are not necessarily ismine
       -            # in which case this is a no-op
       -            self.check_address(addr)
       +        # if empty, coin_chooser will set it
       +        change_addrs = self.get_change_addresses_for_new_transaction(change_addr)
        
                # Fee estimator
                if fixed_fee is None:
       t@@ -727,7 +736,6 @@ class Abstract_Wallet(AddressSynchronizer):
        
                if i_max is None:
                    # Let the coin chooser select the coins to spend
       -            max_change = self.max_change_outputs if self.multiple_change else 1
                    coin_chooser = coinchooser.get_coin_chooser(config)
                    # If there is an unconfirmed RBF tx, merge with it
                    base_tx = self.get_unconfirmed_base_tx_for_batching()
       t@@ -751,7 +759,7 @@ class Abstract_Wallet(AddressSynchronizer):
                    else:
                        txi = []
                        txo = []
       -            tx = coin_chooser.make_tx(coins, txi, outputs[:] + txo, change_addrs[:max_change],
       +            tx = coin_chooser.make_tx(coins, txi, outputs[:] + txo, change_addrs,
                                              fee_estimator, self.dust_threshold())
                else:
                    # FIXME?? this might spend inputs with negative effective value...