URI: 
       treplace wallet.interface everywhere - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 6b6c508976039782835c4f77ac4ae1a6afd8b73a
   DIR parent 907dca6eb9c6e012ac0cb6de32f66f364e43f443
  HTML Author: thomasv <thomasv@gitorious>
       Date:   Thu, 12 Sep 2013 14:58:42 +0200
       
       replace wallet.interface everywhere
       
       Diffstat:
         M gui/gui_classic/installwizard.py    |       8 +++-----
         M gui/gui_classic/lite_window.py      |       5 +++--
         M gui/gui_classic/main_window.py      |      24 +++++++++++-------------
         M gui/gui_classic/network_dialog.py   |       1 +
         M gui/gui_gtk.py                      |      12 ++++++------
         M gui/gui_text.py                     |       8 ++++----
         M lib/blockchain.py                   |       2 ++
         M lib/interface.py                    |      23 ++++++-----------------
         M lib/network.py                      |      34 ++++++++++++++++----------------
         M lib/wallet.py                       |      56 +++++++++++++++++++------------
       
       10 files changed, 87 insertions(+), 86 deletions(-)
       ---
   DIR diff --git a/gui/gui_classic/installwizard.py b/gui/gui_classic/installwizard.py
       t@@ -242,17 +242,16 @@ class InstallWizard(QDialog):
            def restore_wallet(self, wallet):
        
                # wait until we are connected, because the user might have selected another server
       -        if not wallet.interface.is_connected:
       -            waiting = lambda: False if wallet.interface.is_connected else "%s \n" % (_("Connecting..."))
       +        if not self.network.interface.is_connected:
       +            waiting = lambda: False if self.network.interface.is_connected else "%s \n" % (_("Connecting..."))
                    waiting_dialog(waiting)
        
                waiting = lambda: False if wallet.is_up_to_date() else "%s\n%s %d\n%s %.1f"\
       -            %(_("Please wait..."),_("Addresses generated:"),len(wallet.addresses(True)),_("Kilobytes received:"), wallet.interface.bytes_received/1024.)
       +            %(_("Please wait..."),_("Addresses generated:"),len(wallet.addresses(True)),_("Kilobytes received:"), self.network.interface.bytes_received/1024.)
        
                # try to restore old account
                wallet.create_old_account()
                wallet.set_up_to_date(False)
       -        wallet.interface.poke('synchronizer')
                waiting_dialog(waiting)
        
                if wallet.is_found():
       t@@ -262,7 +261,6 @@ class InstallWizard(QDialog):
                    wallet.accounts.pop(0)
                    wallet.create_accounts()
                    wallet.set_up_to_date(False)
       -            wallet.interface.poke('synchronizer')
                    waiting_dialog(waiting)
        
                if wallet.is_found():
   DIR diff --git a/gui/gui_classic/lite_window.py b/gui/gui_classic/lite_window.py
       t@@ -832,6 +832,7 @@ class MiniDriver(QObject):
                super(QObject, self).__init__()
        
                self.wallet = wallet
       +        self.network = wallet.network
                self.window = window
        
                self.wallet.network.register_callback('updated',self.update_callback)
       t@@ -851,9 +852,9 @@ class MiniDriver(QObject):
                self.emit(SIGNAL("updatesignal()"))
        
            def update(self):
       -        if not self.wallet.interface:
       +        if not self.network.interface:
                    self.initializing()
       -        elif not self.wallet.interface.is_connected:
       +        elif not self.network.interface.is_connected:
                    self.connecting()
                elif not self.wallet.up_to_date:
                    self.synchronizing()
   DIR diff --git a/gui/gui_classic/main_window.py b/gui/gui_classic/main_window.py
       t@@ -281,13 +281,11 @@ class ElectrumWindow(QMainWindow):
                    self.show_message("file not found "+ filename)
                    return
        
       -        interface = self.wallet.interface
       -        blockchain = self.wallet.verifier.blockchain
                self.wallet.stop_threads()
                
                # create new wallet 
                wallet = Wallet(storage)
       -        wallet.start_threads(interface, blockchain)
       +        wallet.start_threads(network)
        
                self.load_wallet(wallet)
        
       t@@ -302,7 +300,7 @@ class ElectrumWindow(QMainWindow):
                storage = WalletStorage({'wallet_path': filename})
                assert not storage.file_exists
        
       -        wizard = installwizard.InstallWizard(self.config, self.wallet.interface, self.wallet.verifier.blockchain, storage)
       +        wizard = installwizard.InstallWizard(self.config, self.network, storage)
                wallet = wizard.run()
                if wallet: 
                    self.load_wallet(wallet)
       t@@ -410,12 +408,12 @@ class ElectrumWindow(QMainWindow):
        
            def notify_transactions(self):
                print_error("Notifying GUI")
       -        if len(self.wallet.interface.pending_transactions_for_notifications) > 0:
       +        if len(self.network.interface.pending_transactions_for_notifications) > 0:
                    # Combine the transactions if there are more then three
       -            tx_amount = len(self.wallet.interface.pending_transactions_for_notifications)
       +            tx_amount = len(self.network.interface.pending_transactions_for_notifications)
                    if(tx_amount >= 3):
                        total_amount = 0
       -                for tx in self.wallet.interface.pending_transactions_for_notifications:
       +                for tx in self.network.interface.pending_transactions_for_notifications:
                            is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
                            if(v > 0):
                                total_amount += v
       t@@ -423,11 +421,11 @@ class ElectrumWindow(QMainWindow):
                        self.notify("%s new transactions received. Total amount received in the new transactions %s %s" \
                                        % (tx_amount, self.format_amount(total_amount), self.base_unit()))
        
       -                self.wallet.interface.pending_transactions_for_notifications = []
       +                self.network.interface.pending_transactions_for_notifications = []
                    else:
       -              for tx in self.wallet.interface.pending_transactions_for_notifications:
       +              for tx in self.network.interface.pending_transactions_for_notifications:
                          if tx:
       -                      self.wallet.interface.pending_transactions_for_notifications.remove(tx)
       +                      self.network.interface.pending_transactions_for_notifications.remove(tx)
                              is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
                              if(v > 0):
                                  self.notify("New transaction received. %s %s" % (self.format_amount(v), self.base_unit()))
       t@@ -535,7 +533,7 @@ class ElectrumWindow(QMainWindow):
                return "BTC" if self.decimal_point == 8 else "mBTC"
        
            def update_status(self):
       -        if self.wallet.interface and self.wallet.interface.is_connected:
       +        if self.network.interface and self.network.interface.is_connected:
                    if not self.wallet.up_to_date:
                        text = _("Synchronizing...")
                        icon = QIcon(":icons/status_waiting.png")
       t@@ -555,7 +553,7 @@ class ElectrumWindow(QMainWindow):
        
            def update_wallet(self):
                self.update_status()
       -        if self.wallet.up_to_date or not self.wallet.interface.is_connected:
       +        if self.wallet.up_to_date or not self.network.interface.is_connected:
                    self.update_history_tab()
                    self.update_receive_tab()
                    self.update_contacts_tab()
       t@@ -1308,7 +1306,7 @@ class ElectrumWindow(QMainWindow):
                console.updateNamespace({'wallet' : self.wallet, 'network' : self.network, 'gui':self})
                console.updateNamespace({'util' : util, 'bitcoin':bitcoin})
        
       -        c = commands.Commands(self.wallet, self.wallet.interface, lambda: self.console.set_json(True))
       +        c = commands.Commands(self.wallet, self.network.interface, lambda: self.console.set_json(True))
                methods = {}
                def mkfunc(f, method):
                    return lambda *args: apply( f, (method, args, self.password_dialog ))
   DIR diff --git a/gui/gui_classic/network_dialog.py b/gui/gui_classic/network_dialog.py
       t@@ -239,5 +239,6 @@ class NetworkDialog(QDialog):
                self.config.set_key("proxy", proxy, True)
                self.config.set_key("server", server, True)
                self.network.set_server(server, proxy)
       +
                self.config.set_key('auto_cycle', self.autocycle_cb.isChecked(), True)
                return True
   DIR diff --git a/gui/gui_gtk.py b/gui/gui_gtk.py
       t@@ -33,7 +33,7 @@ import platform
        MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monospace'
        
        from electrum.util import format_satoshis
       -from electrum.interface import DEFAULT_SERVERS
       +from electrum.network import DEFAULT_SERVERS
        from electrum.bitcoin import MIN_RELAY_TX_FEE
        
        def numbify(entry, is_int = False):
       t@@ -268,7 +268,7 @@ def run_settings_dialog(wallet, parent):
        def run_network_dialog( wallet, parent ):
            image = gtk.Image()
            image.set_from_stock(gtk.STOCK_NETWORK, gtk.ICON_SIZE_DIALOG)
       -    interface = wallet.interface
       +    interface = wallet.network.interface
            if parent:
                if interface.is_connected:
                    status = "Connected to %s:%d\n%d blocks"%(interface.host, interface.port, wallet.network.blockchain.height)
       t@@ -279,7 +279,7 @@ def run_network_dialog( wallet, parent ):
                status = "Please choose a server.\nSelect cancel if you are offline."
        
            server = interface.server
       -    servers = interface.get_servers()
       +    servers = wallet.network.get_servers()
        
            dialog = gtk.MessageDialog( parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                                            gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, status)
       t@@ -345,7 +345,7 @@ def run_network_dialog( wallet, parent ):
            treeview = gtk.TreeView(model=server_list)
            treeview.show()
        
       -    if wallet.interface.servers:
       +    if interface.servers:
                label = 'Active Servers'
            else:
                label = 'Default Servers'
       t@@ -1107,7 +1107,7 @@ class ElectrumWindow:
                return vbox
        
            def update_status_bar(self):
       -        interface = self.wallet.interface
       +        interface = self.wallet.network.interface
                if self.funds_error:
                    text = "Not enough funds"
                elif interface and interface.is_connected:
       t@@ -1133,7 +1133,7 @@ class ElectrumWindow:
                    self.update_history_tab()
                    self.update_receiving_tab()
                    # addressbook too...
       -            self.info.set_text( self.wallet.interface.banner )
       +            self.info.set_text( self.wallet.network.banner )
                    self.wallet_updated = False
        
            def update_receiving_tab(self):
   DIR diff --git a/gui/gui_text.py b/gui/gui_text.py
       t@@ -102,7 +102,7 @@ class ElectrumGui:
        
        
            def print_balance(self):
       -        if self.wallet.interface and self.wallet.interface.is_connected:
       +        if self.network.interface and self.network.interface.is_connected:
                    if not self.wallet.up_to_date:
                        msg = _( "Synchronizing..." )
                    else: 
       t@@ -143,7 +143,7 @@ class ElectrumGui:
                self.stdscr.addstr( 12, 25, _("[Clear]"), curses.A_REVERSE if self.pos%6==5 else curses.color_pair(2))
        
            def print_banner(self):
       -        for i, x in enumerate( self.wallet.interface.banner.split('\n') ):
       +        for i, x in enumerate( self.network.banner.split('\n') ):
                    self.stdscr.addstr( 1+i, 1, x )
        
            def print_list(self, list, firstline):
       t@@ -318,7 +318,7 @@ class ElectrumGui:
        
            def network_dialog(self):
                out = self.run_dialog('Network', [
       -            {'label':'server', 'type':'str', 'value':self.wallet.interface.server},
       +            {'label':'server', 'type':'str', 'value':self.network.interface.server},
                    {'label':'proxy', 'type':'str', 'value':self.config.get('proxy', '')},
                    ], buttons = 1)
                if out:
       t@@ -331,7 +331,7 @@ class ElectrumGui:
        
                        self.wallet.config.set_key("proxy", proxy, True)
                        self.wallet.config.set_key("server", server, True)
       -                self.wallet.interface.set_server(server, proxy)
       +                self.network.interface.set_server(server, proxy)
                        
        
        
   DIR diff --git a/lib/blockchain.py b/lib/blockchain.py
       t@@ -65,6 +65,8 @@ class Blockchain(threading.Thread):
                    if not result: continue
        
                    i, result = result
       +            if not result: continue
       +            
                    header = result.get('result')
                    height = header.get('block_height')
                    self.servers_height[i.server] = height
   DIR diff --git a/lib/interface.py b/lib/interface.py
       t@@ -381,6 +381,12 @@ class Interface(threading.Thread):
                    raise BaseException('Unknown protocol: %s'%protocol)
        
        
       +    def stop_subscriptions(self):
       +        for callback in self.subscriptions.keys():
       +            callback(self, None)
       +        self.subscriptions = {}
       +
       +
            def send(self, messages, callback):
        
                sub = []
       t@@ -430,23 +436,6 @@ class Interface(threading.Thread):
                return proxy
        
        
       -    def set_server(self, server, proxy=None):
       -        "todo: remove this"
       -        # raise an error if the format isnt correct
       -        a,b,c = server.split(':')
       -        b = int(b)
       -        assert c in 'stgh'
       -        # set the server
       -        if server != self.server or proxy != self.proxy:
       -            print "changing server:", server, proxy
       -            self.server = server
       -            self.proxy = proxy
       -            if self.is_connected and self.protocol in 'st' and self.s:
       -                self.s.shutdown(socket.SHUT_RDWR)
       -                self.s.close()
       -            self.is_connected = False  # this exits the polling loop
       -            self.trigger_callback('disconnecting') # for actively disconnecting
       -
        
            def stop(self):
                if self.is_connected and self.protocol in 'st' and self.s:
   DIR diff --git a/lib/network.py b/lib/network.py
       t@@ -45,9 +45,9 @@ class Network(threading.Thread):
                self.interfaces = {}
                self.queue = Queue.Queue()
                self.default_server = self.config.get('server')
       -        self.servers_list = filter_protocol(DEFAULT_SERVERS,'s')
       +        self.disconnected_servers = []
                self.callbacks = {}
       -        #banner
       +        self.servers = []
                self.banner = ''
        
        
       t@@ -66,13 +66,17 @@ class Network(threading.Thread):
        
        
            def random_server(self):
       -        if len(self.servers_list) <= len(self.interfaces.keys()):
       -            return
       +        choice_list = []
       +        l = filter_protocol(self.get_servers(), 's')
       +        for s in l:
       +            if s in self.disconnected_servers or s in self.interfaces.keys():
       +                continue
       +            else:
       +                choice_list.append(s)
                
       -        while True:
       -            server = random.choice( self.servers_list )
       -            if server not in self.interfaces.keys(): break
       -
       +        if not choice_list: return
       +        
       +        server = random.choice( choice_list )
                return server
        
        
       t@@ -116,11 +120,11 @@ class Network(threading.Thread):
        
        
            def set_server(self, server, proxy):
       -        subscriptions = self.interface.subscriptions
       +        i = self.interface
                self.default_server = server
                self.start_interface(server)
                self.interface = self.interfaces[server]
       -        self.resend_subscriptions(subscriptions)
       +        i.stop_subscriptions() # fixme: it should not stop all subscriptions, and send 'unsubscribe'
                self.trigger_callback('disconnecting') # for actively disconnecting
        
        
       t@@ -138,8 +142,9 @@ class Network(threading.Thread):
                        if i == self.interface:
                            i.send([('server.banner',[])], self.on_banner)
                            i.send([('server.peers.subscribe',[])], self.on_peers)
       +                    self.trigger_callback('connected')
                    else:
       -                self.servers_list.remove(i.server)
       +                self.disconnected_servers.append(i.server)
                        self.interfaces.pop(i.server)
                        self.start_random_interface()
                        
       t@@ -154,6 +159,7 @@ class Network(threading.Thread):
                self.blockchain.queue.put((i,result))
        
            def on_peers(self, i, r):
       +        if not r: return
                self.servers = self.parse_servers(r.get('result'))
                self.trigger_callback('peers')
        
       t@@ -200,12 +206,6 @@ class Network(threading.Thread):
                return servers
        
        
       -    def resend_subscriptions(self, subscriptions):
       -        for channel, messages in subscriptions.items():
       -            if messages:
       -                self.interface.send(messages, channel)
       -
       -
        
        
        if __name__ == "__main__":
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -224,7 +224,6 @@ class Wallet:
        
            def update(self):
                self.up_to_date = False
       -        #self.interface.poke('synchronizer')
                while not self.is_up_to_date(): 
                    time.sleep(0.1)
        
       t@@ -1039,7 +1038,7 @@ class Wallet:
                        print_error("received transaction that is no longer referenced in history", tx_hash)
                        return
                    self.transactions[tx_hash] = tx
       -            self.interface.pending_transactions_for_notifications.append(tx)
       +            self.network.interface.pending_transactions_for_notifications.append(tx)
                    self.save_transactions()
                    if self.verifier and tx_height>0: 
                        self.verifier.add(tx_hash, tx_height)
       t@@ -1188,7 +1187,7 @@ class Wallet:
            def send_tx(self, tx):
                # asynchronous
                self.tx_event.clear()
       -        self.interface.send([('blockchain.transaction.broadcast', [str(tx)])], self.on_broadcast)
       +        self.network.interface.send([('blockchain.transaction.broadcast', [str(tx)])], self.on_broadcast)
                return tx.hash()
        
            def on_broadcast(self, i, result):
       t@@ -1320,7 +1319,7 @@ class Wallet:
                            # assert not self.is_mine(_addr)
                            ext_requests.append( ('blockchain.address.get_history', [_addr]) )
        
       -                ext_h = self.interface.synchronous_get(ext_requests)
       +                ext_h = self.network.interface.synchronous_get(ext_requests)
                        print_error("sync:", ext_requests, ext_h)
                        height = None
                        for h in ext_h:
       t@@ -1362,7 +1361,6 @@ class Wallet:
            def start_threads(self, network):
                from verifier import TxVerifier
                self.network = network
       -        self.interface = network.interface
                self.verifier = TxVerifier(self.network, self.storage)
                self.verifier.start()
                self.set_verifier(self.verifier)
       t@@ -1385,7 +1383,7 @@ class WalletSynchronizer(threading.Thread):
                self.daemon = True
                self.wallet = wallet
                wallet.synchronizer = self
       -        self.interface = self.wallet.interface
       +        self.network = self.wallet.network
                #self.wallet.network.register_callback('connected', lambda: self.wallet.set_up_to_date(False))
                self.was_updated = True
                self.running = False
       t@@ -1403,15 +1401,25 @@ class WalletSynchronizer(threading.Thread):
                messages = []
                for addr in addresses:
                    messages.append(('blockchain.address.subscribe', [addr]))
       -        self.interface.send( messages, lambda i,r: self.queue.put(r))
       +        self.network.interface.send( messages, lambda i,r: self.queue.put(r))
        
        
            def run(self):
       -        if not self.interface.is_connected:
       -            print_error( "synchronizer: waiting for interface")
       -            self.interface.connect_event.wait()
       +        with self.lock:
       +            self.running = True
       +
       +        while self.is_running():
       +            interface = self.network.interface
       +            if not interface.is_connected:
       +                print_error("synchronizer: waiting for interface")
       +                interface.connect_event.wait()
       +                
       +            self.run_interface(interface)
        
       -        with self.lock: self.running = True
       +
       +    def run_interface(self, interface):
       +
       +        print_error("synchronizer: connected to", interface.server)
        
                requested_tx = []
                missing_tx = []
       t@@ -1423,12 +1431,10 @@ class WalletSynchronizer(threading.Thread):
                    for tx_hash, tx_height in history:
                        if self.wallet.transactions.get(tx_hash) is None and (tx_hash, tx_height) not in missing_tx:
                            missing_tx.append( (tx_hash, tx_height) )
       -        print_error("missing tx", missing_tx)
        
       -        # wait until we are connected, in case the user is not connected
       -        while not self.interface.is_connected:
       -            time.sleep(1)
       -        
       +        if missing_tx:
       +            print_error("missing tx", missing_tx)
       +
                # subscriptions
                self.subscribe_to_addresses(self.wallet.addresses(True, next=True))
        
       t@@ -1443,12 +1449,12 @@ class WalletSynchronizer(threading.Thread):
                    # request missing transactions
                    for tx_hash, tx_height in missing_tx:
                        if (tx_hash, tx_height) not in requested_tx:
       -                    self.interface.send([ ('blockchain.transaction.get',[tx_hash, tx_height]) ], lambda i,r: self.queue.put(r))
       +                    interface.send([ ('blockchain.transaction.get',[tx_hash, tx_height]) ], lambda i,r: self.queue.put(r))
                            requested_tx.append( (tx_hash, tx_height) )
                    missing_tx = []
        
                    # detect if situation has changed
       -            if self.interface.is_up_to_date() and self.queue.empty():
       +            if interface.is_up_to_date() and self.queue.empty():
                        if not self.wallet.is_up_to_date():
                            self.wallet.set_up_to_date(True)
                            self.was_updated = True
       t@@ -1462,10 +1468,16 @@ class WalletSynchronizer(threading.Thread):
                        self.was_updated = False
        
                    # 2. get a response
       -            r = self.queue.get(block=True, timeout=10000000000)
       +            try:
       +                r = self.queue.get(block=True, timeout=1)
       +            except Queue.Empty:
       +                continue
        
       -            # poke sends None. (needed during stop)
       -            if not r: continue
       +            if interface != self.network.interface:
       +                break
       +            
       +            if not r:
       +                continue
        
                    # 3. handle response
                    method = r['method']
       t@@ -1480,7 +1492,7 @@ class WalletSynchronizer(threading.Thread):
                        addr = params[0]
                        if self.wallet.get_status(self.wallet.get_history(addr)) != result:
                            if requested_histories.get(addr) is None:
       -                        self.interface.send([('blockchain.address.get_history', [addr])], lambda i,r:self.queue.put(r))
       +                        interface.send([('blockchain.address.get_history', [addr])], lambda i,r:self.queue.put(r))
                                requested_histories[addr] = result
        
                    elif method == 'blockchain.address.get_history':