move synchronous_get to network.py, fix get_balance script
[electrum-nvc.git] / lib / network.py
index 81b476e..02cf727 100644 (file)
@@ -9,7 +9,7 @@ DEFAULT_PORTS = {'t':'50001', 's':'50002', 'h':'8081', 'g':'8082'}
 DEFAULT_SERVERS = {
     'the9ull.homelinux.org': {'h': '8082', 't': '50001'},
     'electrum.coinwallet.me': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
-    'electrum.dynaloop.net': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
+    'electrum.hachre.de': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
     'electrum.koh.ms': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
     'electrum.novit.ro': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
     'electrum.stepkrav.pw': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
@@ -33,6 +33,9 @@ def filter_protocol(servers, p):
     return l
     
 
+def pick_random_server():
+    return random.choice( filter_protocol(DEFAULT_SERVERS,'s') )
+
 
 class Network(threading.Thread):
 
@@ -50,8 +53,36 @@ class Network(threading.Thread):
         self.servers = []
         self.banner = ''
         self.interface = None
+        self.proxy = self.config.get('proxy')
         self.heights = {}
 
+        dir_path = os.path.join( self.config.path, 'certs')
+        if not os.path.exists(dir_path):
+            os.mkdir(dir_path)
+
+
+        # default subscriptions
+        self.subscriptions = {}
+        self.subscriptions[self.on_banner] = [('server.banner',[])]
+        self.subscriptions[self.on_peers] = [('server.peers.subscribe',[])]
+
+
+    def send_subscriptions(self):
+        for cb, sub in self.subscriptions.items():
+            self.interface.send(sub, cb)
+
+
+    def subscribe(self, messages, callback):
+        with self.lock:
+            if self.subscriptions.get(callback) is None: 
+                self.subscriptions[callback] = []
+            for message in messages:
+                if message not in self.subscriptions[callback]:
+                    self.subscriptions[callback].append(message)
+
+        if self.interface and self.interface.is_connected:
+            self.interface.send( messages, callback )
+
 
     def register_callback(self, event, callback):
         with self.lock:
@@ -92,7 +123,7 @@ class Network(threading.Thread):
     def start_interface(self, server):
         if server in self.interfaces.keys():
             return
-        i = interface.Interface({'server':server})
+        i = interface.Interface({'server':server, 'path':self.config.path, 'proxy':self.proxy})
         self.interfaces[server] = i
         i.start(self.queue)
 
@@ -121,13 +152,30 @@ class Network(threading.Thread):
             return self.interface.is_connected
 
 
-    def set_server(self, server, proxy):
-        i = self.interface
+    def set_proxy(self, proxy):
+        self.proxy = proxy
+
+
+    def set_server(self, server):
+        if self.default_server == server:
+            return
+
+        # stop the interface in order to terminate subscriptions
+        self.interface.stop() 
+        # notify gui
+        self.trigger_callback('disconnecting')
+        # start interface
         self.default_server = server
-        self.start_interface(server)
-        self.interface = self.interfaces[server]
-        i.stop_subscriptions() # fixme: it should not stop all subscriptions, and send 'unsubscribe'
-        self.trigger_callback('disconnecting') # for actively disconnecting
+
+        if server in self.interfaces.keys():
+            self.interface = self.interfaces[server]
+            self.send_subscriptions()
+        else:
+            self.start_interface(server)
+            self.interface = self.interfaces[server]
+        
+
+
 
 
     def run(self):
@@ -142,8 +190,7 @@ class Network(threading.Thread):
             if i.is_connected:
                 i.send([ ('blockchain.headers.subscribe',[])], self.on_header)
                 if i == self.interface:
-                    i.send([('server.banner',[])], self.on_banner)
-                    i.send([('server.peers.subscribe',[])], self.on_peers)
+                    self.send_subscriptions()
                     self.trigger_callback('connected')
             else:
                 self.disconnected_servers.append(i.server)
@@ -179,10 +226,28 @@ class Network(threading.Thread):
         with self.lock: return self.running
 
     
+    def synchronous_get(self, requests, timeout=100000000):
+        queue = Queue.Queue()
+        ids = self.interface.send(requests, lambda i,r: queue.put(r))
+        id2 = ids[:]
+        res = {}
+        while ids:
+            r = queue.get(True, timeout)
+            _id = r.get('id')
+            if _id in ids:
+                ids.remove(_id)
+                res[_id] = r.get('result')
+        out = []
+        for _id in id2:
+            out.append(res[_id])
+        return out
+
+
     def retrieve_transaction(self, tx_hash, tx_height=0):
         import transaction
-        r = self.interface.synchronous_get([ ('blockchain.transaction.get',[tx_hash, tx_height]) ])[0]
-        return transaction.Transaction(r)
+        r = self.synchronous_get([ ('blockchain.transaction.get',[tx_hash, tx_height]) ])[0]
+        if r:
+            return transaction.Transaction(r)
 
 
     def parse_servers(self, result):