Repository: spesmilo/electrum

Issue:
Display problem: Stuck in Synchronizing after changing network socks settings and connecting to another server
2.7.18 on windows appears to have a display problem, regardless it is fully synced it will print Synchronizing forever. The console command network.unanswered_requests will return nothing.

To reproduce, just connect to a server (on TCP or SSL, doesn't matter) directly, and wait until fully synced so that it shows green ball. Then, change at network settings to use a socks5 address (in my case I entered socks5:localhost:9150 and tried to connect to the same server, but on the onion Tor hostname). It will only show Synchronizing in this case. The same happens if you try to connect to the regular server name (not .onion) but after changing the socks5 network settings. Closing and reopening the wallet fixes it, and it will show green while connected via socks5 proxy.

Another thing is that if you open the network settings after it is in Synchronizing mode and change the server after the 2nd change it won't connect any more and show red (didn't wait for more than 5 minutes to see if it actually will remain like this but even 5 minutes seams very much for this). Does it make sense to add a button to connect/disconnect on demand, or call connect every time the network settings wizard closes?


Discussion:
Can you run it from a command line to see if it prints a traceback?
I was able to reproduce in git-head version.
Turning on SOCKS proxy throws this backtrace:
```
[Network] stopping network
pipe: socket error [Errno 9] Bad file descriptor
[Network] starting network
[electrum.0x0000.de] connection closed remotely
[Network] setting proxy {'user': '', 'host': '127.0.0.1', 'password': '', 'mode': 'socks5', 'port': '9050'}
[Network] connecting to Electrum.hsmiths.com:8080:t as new interface
[Network] connecting to Electrum.hsmiths.com:8080:t as new interface
[helicarrier.bauerj.eu] connected
[btc.vpirate.org] connected
[ndnd.selfhost.eu] connected
[electrum.mindspot.org] connected
[Electrum.hsmiths.com] connected
[Electrum.hsmiths.com] connected
[Network] switching to Electrum.hsmiths.com:8080:t
[Network] sending subscriptions to Electrum.hsmiths.com:8080:t 0 27
Exception in thread Thread-3:
Traceback (most recent call last):
  File "python\lib\threading.py", line 801, in __bootstrap_inner
    self.run()
  File "electrum\lib\network.py", line 820, in run
    self.maintain_sockets()
  File "electrum\lib\network.py", line 672, in maintain_sockets
    self.connecting.remove(server)
KeyError: 'Electrum.hsmiths.com:8080:t'

```
Possibly related, I get a similar backtrace when I toggle SSL. 
```
[Network] stopping network
pipe: socket error [Errno 9] Bad file descriptor
[Electrum.hsmiths.com] connection closed remotely
[Network] starting network
[Network] connecting to Electrum.hsmiths.com:8080:t as new interface
[Network] connecting to Electrum.hsmiths.com:8080:t as new interface
[Electrum.hsmiths.com] connected
[Electrum.hsmiths.com] connected
[Network] switching to Electrum.hsmiths.com:8080:t
[Network] sending subscriptions to Electrum.hsmiths.com:8080:t 0 27
Exception in thread Thread-3:
Traceback (most recent call last):
  File "pythonlib\threading.py", line 801, in __bootstrap_inner
    self.run()
  File "electrum\lib\network.py", line 820, in run
    self.maintain_sockets()
  File "electrum\lib\network.py", line 672, in maintain_sockets
    self.connecting.remove(server)
KeyError: 'Electrum.hsmiths.com:8080:t'


```
And while in this state (Synchornizing...) if you open the network pop-up more times to make changes to socks address / server it stops and doesn't re-connect at all to any server, you need to close the app and open again.

Resolving patch:
diff --git a/lib/network.py b/lib/network.py
--- a/lib/network.py
+++ b/lib/network.py
@@ -325,14 +325,14 @@ def send_subscriptions(self):
         for request in requests:
             message_id = self.queue_request(request[0], request[1])
             self.unanswered_requests[message_id] = request
-        for addr in self.subscribed_addresses:
-            self.queue_request('blockchain.address.subscribe', [addr])
         self.queue_request('server.banner', [])
         self.queue_request('server.donation_address', [])
         self.queue_request('server.peers.subscribe', [])
         for i in bitcoin.FEE_TARGETS:
             self.queue_request('blockchain.estimatefee', [i])
         self.queue_request('blockchain.relayfee', [])
+        for addr in self.subscribed_addresses:
+            self.queue_request('blockchain.address.subscribe', [addr])
 
     def get_status_value(self, key):
         if key == 'status':
@@ -432,6 +432,8 @@ def stop_network(self):
         self.print_error("stopping network")
         for interface in self.interfaces.values():
             self.close_interface(interface)
+        if self.interface:
+            self.close_interface(self.interface)
         assert self.interface is None
         assert not self.interfaces
         self.connecting = set()
@@ -669,7 +671,8 @@ def maintain_sockets(self):
         # Responses to connection attempts?
         while not self.socket_queue.empty():
             server, socket = self.socket_queue.get()
-            self.connecting.remove(server)
+            if server in self.connecting:
+                self.connecting.remove(server)
             if socket:
                 self.new_interface(server, socket)
             else:


Test patch: