tMerge pull request #1260 from kyuupichan/avoid_addr_reuse - electrum - Electrum Bitcoin wallet
 (HTM) git clone https://git.parazyd.org/electrum
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
       ---
 (DIR) commit ed5747fbcf5b1f9f9053c8af4c7c18dad92e22df
 (DIR) parent 48f98f75dbf4b043949f08f3a84e8a8e1adbdc62
 (HTM) Author: ThomasV <electrumdev@gmail.com>
       Date:   Sat, 30 May 2015 10:20:47 +0200
       
       Merge pull request #1260 from kyuupichan/avoid_addr_reuse
       
       Avoid change address reuse if possible
       Diffstat:
         M lib/wallet.py                       |      21 ++++++++++++++-------
       
       1 file changed, 14 insertions(+), 7 deletions(-)
       ---
 (DIR) diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -142,7 +142,7 @@ class Abstract_Wallet(object):
            def __init__(self, storage):
                self.storage = storage
                self.electrum_version = ELECTRUM_VERSION
       -        self.gap_limit_for_change = 3 # constant
       +        self.gap_limit_for_change = 6 # constant
                # saved fields
                self.seed_version          = storage.get('seed_version', NEW_SEED_VERSION)
                self.use_change            = storage.get('use_change',True)
       t@@ -170,7 +170,7 @@ class Abstract_Wallet(object):
                self.unverified_tx = {}
                # Verified transactions.  Each value is a (height, timestamp, block_pos) tuple.  Access with self.lock.
                self.verified_tx   = storage.get('verified_tx3',{})
       -        
       +
                # there is a difference between wallet.up_to_date and interface.is_up_to_date()
                # interface.is_up_to_date() returns true when all requests have been answered and processed
                # wallet.up_to_date is true when the wallet is synchronized (stronger requirement)
       t@@ -398,7 +398,7 @@ class Abstract_Wallet(object):
                        if tx_hash not in self.verified_tx and tx_height <= self.get_local_height():
                            txs.append((tx_hash, tx_height))
                return txs
       -    
       +
            def undo_verifications(self, height):
                '''Used by the verifier when a reorg has happened'''
                txs = []
       t@@ -690,7 +690,7 @@ class Abstract_Wallet(object):
                        _type, x, v = txo
                        if _type == 'address':
                            addr = x
       -                elif _type == 'pubkey': 
       +                elif _type == 'pubkey':
                            addr = public_key_to_bc_address(x.decode('hex'))
                        else:
                            addr = None
       t@@ -887,10 +887,17 @@ class Abstract_Wallet(object):
                    # send change to one of the accounts involved in the tx
                    address = inputs[0].get('address')
                    account, _ = self.get_address_index(address)
       -            if not self.use_change or not self.accounts[account].has_change():
       -                change_addr = address
       +            if self.use_change and self.accounts[account].has_change():
       +                # New change addresses are created only after a few confirmations.
       +                # Choose an unused change address if any, otherwise take one at random
       +                change_addrs = self.accounts[account].get_addresses(1)[-self.gap_limit_for_change:]
       +                for change_addr in change_addrs:
       +                    if self.get_num_tx(change_addr) == 0:
       +                        break
       +                else:
       +                    change_addr = random.choice(change_addrs)
                    else:
       -                change_addr = self.accounts[account].get_addresses(1)[-self.gap_limit_for_change]
       +                change_addr = address
        
                # if change is above dust threshold, add a change output.
                change_amount = total - ( amount + fee )