URI: 
       tMerge pull request #3782 from SomberNight/opt_wallet_get_address_index - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 64127a8beee4af6f73280e6ab918aa4d1fce6195
   DIR parent 2343894e0f9b33641f43a4670949851ac59f1dd0
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Tue, 30 Jan 2018 01:06:44 +0100
       
       Merge pull request #3782 from SomberNight/opt_wallet_get_address_index
       
       Optimisations in wallet.py
       Diffstat:
         M gui/qt/main_window.py               |       2 ++
         M lib/wallet.py                       |      37 ++++++++++++++++++++++---------
       
       2 files changed, 28 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -62,6 +62,7 @@ from .fee_slider import FeeSlider
        
        from .util import *
        
       +from electrum.util import profiler
        
        class StatusBarButton(QPushButton):
            def __init__(self, icon, tooltip, func):
       t@@ -325,6 +326,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
                    self.print_error('close_wallet', self.wallet.storage.path)
                run_hook('close_wallet', self.wallet)
        
       +    @profiler
            def load_wallet(self, wallet):
                wallet.thread = TaskThread(self, self.on_error)
                self.wallet = wallet
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -346,14 +346,10 @@ class Abstract_Wallet(PrintError):
            def is_change(self, address):
                if not self.is_mine(address):
                    return False
       -        return address in self.change_addresses
       +        return self.get_address_index(address)[0]
        
            def get_address_index(self, address):
       -        if address in self.receiving_addresses:
       -            return False, self.receiving_addresses.index(address)
       -        if address in self.change_addresses:
       -            return True, self.change_addresses.index(address)
       -        raise Exception("Address not found", address)
       +        raise NotImplementedError()
        
            def export_private_key(self, address, password):
                """ extended WIF format """
       t@@ -1050,8 +1046,10 @@ class Abstract_Wallet(PrintError):
        
            def is_used(self, address):
                h = self.history.get(address,[])
       +        if len(h) == 0:
       +            return False
                c, u, x = self.get_addr_balance(address)
       -        return len(h) > 0 and c + u + x == 0
       +        return c + u + x == 0
        
            def is_empty(self, address):
                c, u, x = self.get_addr_balance(address)
       t@@ -1489,6 +1487,9 @@ class Imported_Wallet(Simple_Wallet):
            def is_beyond_limit(self, address, is_change):
                return False
        
       +    def is_mine(self, address):
       +        return address in self.addresses
       +
            def get_fingerprint(self):
                return ''
        
       t@@ -1678,6 +1679,14 @@ class Deterministic_Wallet(Abstract_Wallet):
                        if n > nmax: nmax = n
                return nmax + 1
        
       +    def load_addresses(self):
       +        super().load_addresses()
       +        self._addr_to_addr_index = {}  # key: address, value: (is_change, index)
       +        for i, addr in enumerate(self.receiving_addresses):
       +            self._addr_to_addr_index[addr] = (False, i)
       +        for i, addr in enumerate(self.change_addresses):
       +            self._addr_to_addr_index[addr] = (True, i)
       +
            def create_new_address(self, for_change=False):
                assert type(for_change) is bool
                addr_list = self.change_addresses if for_change else self.receiving_addresses
       t@@ -1685,6 +1694,7 @@ class Deterministic_Wallet(Abstract_Wallet):
                x = self.derive_pubkeys(for_change, n)
                address = self.pubkeys_to_address(x)
                addr_list.append(address)
       +        self._addr_to_addr_index[address] = (for_change, n)
                self.save_addresses()
                self.add_address(address)
                return address
       t@@ -1716,17 +1726,22 @@ class Deterministic_Wallet(Abstract_Wallet):
        
            def is_beyond_limit(self, address, is_change):
                addr_list = self.get_change_addresses() if is_change else self.get_receiving_addresses()
       -        i = addr_list.index(address)
       -        prev_addresses = addr_list[:max(0, i)]
       +        i = self.get_address_index(address)[1]
                limit = self.gap_limit_for_change if is_change else self.gap_limit
       -        if len(prev_addresses) < limit:
       +        if i < limit:
                    return False
       -        prev_addresses = prev_addresses[max(0, i - limit):]
       +        prev_addresses = addr_list[max(0, i - limit):max(0, i)]
                for addr in prev_addresses:
                    if self.history.get(addr):
                        return False
                return True
        
       +    def is_mine(self, address):
       +        return address in self._addr_to_addr_index
       +
       +    def get_address_index(self, address):
       +        return self._addr_to_addr_index[address]
       +
            def get_master_public_keys(self):
                return [self.get_master_public_key()]