Browse Source

wallet: try to plug gap limit for change addresses (#4530)

master
ghost43 7 years ago committed by GitHub
parent
commit
941df4153b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 40
      electrum/wallet.py

40
electrum/wallet.py

@ -179,6 +179,8 @@ class Abstract_Wallet(AddressSynchronizer):
self.fiat_value = storage.get('fiat_value', {}) self.fiat_value = storage.get('fiat_value', {})
self.receive_requests = storage.get('payment_requests', {}) self.receive_requests = storage.get('payment_requests', {})
self.calc_unused_change_addresses()
# save wallet type the first time # save wallet type the first time
if self.storage.get('wallet_type') is None: if self.storage.get('wallet_type') is None:
self.storage.put('wallet_type', self.wallet_type) self.storage.put('wallet_type', self.wallet_type)
@ -225,6 +227,16 @@ class Abstract_Wallet(AddressSynchronizer):
def synchronize(self): def synchronize(self):
pass pass
def calc_unused_change_addresses(self):
with self.lock:
if hasattr(self, '_unused_change_addresses'):
addrs = self._unused_change_addresses
else:
addrs = self.get_change_addresses()
self._unused_change_addresses = [addr for addr in addrs if
self.get_address_history_len(addr) == 0]
return list(self._unused_change_addresses)
def is_deterministic(self): def is_deterministic(self):
return self.keystore.is_deterministic() return self.keystore.is_deterministic()
@ -554,21 +566,22 @@ class Abstract_Wallet(AddressSynchronizer):
self.add_input_info(item) self.add_input_info(item)
# change address # change address
# if we leave it empty, coin_chooser will set it
change_addrs = []
if change_addr: if change_addr:
change_addrs = [change_addr] change_addrs = [change_addr]
else: elif self.use_change:
addrs = self.get_change_addresses()[-self.gap_limit_for_change:] # Recalc and get unused change addresses
if self.use_change and addrs: addrs = self.calc_unused_change_addresses()
# New change addresses are created only after a few # New change addresses are created only after a few
# confirmations. Select the unused addresses within the # confirmations.
# gap limit; if none take one at random if addrs:
change_addrs = [addr for addr in addrs if # if there are any unused, select all
self.get_address_history_len(addr) == 0] change_addrs = addrs
if not change_addrs:
change_addrs = [random.choice(addrs)]
else: else:
# coin_chooser will set change address # if there are none, take one randomly from the last few
change_addrs = [] addrs = self.get_change_addresses()[-self.gap_limit_for_change:]
change_addrs = [random.choice(addrs)] if addrs else []
# Fee estimator # Fee estimator
if fixed_fee is None: if fixed_fee is None:
@ -1420,6 +1433,9 @@ class Deterministic_Wallet(Abstract_Wallet):
self._addr_to_addr_index[address] = (for_change, n) self._addr_to_addr_index[address] = (for_change, n)
self.save_addresses() self.save_addresses()
self.add_address(address) self.add_address(address)
if for_change:
# note: if it's actually used, it will get filtered later
self._unused_change_addresses.append(address)
return address return address
def synchronize_sequence(self, for_change): def synchronize_sequence(self, for_change):

Loading…
Cancel
Save