commit ed5747fbcf5b1f9f9053c8af4c7c18dad92e22df
parent 48f98f75dbf4b043949f08f3a84e8a8e1adbdc62
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:
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/lib/wallet.py b/lib/wallet.py
@@ -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)
@@ -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)
@@ -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 = []
@@ -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
@@ -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 )