electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 941df4153bebb97834ddb12dc5e5f8367e691d74
parent f3f5b8a5d69040cc7203bff7a210fd85a18c8951
Author: ghost43 <somber.night@protonmail.com>
Date:   Wed, 15 Aug 2018 14:33:12 +0200

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


Diffstat:
Melectrum/wallet.py | 40++++++++++++++++++++++++++++------------
1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/electrum/wallet.py b/electrum/wallet.py @@ -179,6 +179,8 @@ class Abstract_Wallet(AddressSynchronizer): self.fiat_value = storage.get('fiat_value', {}) self.receive_requests = storage.get('payment_requests', {}) + self.calc_unused_change_addresses() + # save wallet type the first time if self.storage.get('wallet_type') is None: self.storage.put('wallet_type', self.wallet_type) @@ -225,6 +227,16 @@ class Abstract_Wallet(AddressSynchronizer): def synchronize(self): 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): return self.keystore.is_deterministic() @@ -554,21 +566,22 @@ 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] - else: - addrs = self.get_change_addresses()[-self.gap_limit_for_change:] - if self.use_change and addrs: - # New change addresses are created only after a few - # confirmations. Select the unused addresses within the - # gap limit; if none take one at random - change_addrs = [addr for addr in addrs if - self.get_address_history_len(addr) == 0] - if not change_addrs: - change_addrs = [random.choice(addrs)] + 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: - # coin_chooser will set change address - change_addrs = [] + # 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 [] # Fee estimator if fixed_fee is None: @@ -1420,6 +1433,9 @@ class Deterministic_Wallet(Abstract_Wallet): self._addr_to_addr_index[address] = (for_change, n) self.save_addresses() 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 def synchronize_sequence(self, for_change):