switch_to_random_interface used to do is_connected()
checks and remove interfaces when switching. This
is redundant: interfaces are only added to self.interfaces
once in is_connected() state from process_if_notification().
When they are disconnected, a notification is also received
and process_if_notification() performs the removal. Furthermore,
two other callers of switch_to_interface do not do explicit
is_connected() checks before calling it.
Traceback (most recent call last):
File "src/electrum/lib/network.py", line 411, in process_request
out['result'] = f(*params)
UnboundLocalError: local variable 'f' referenced before assignment
[Network] network error local variable 'f' referenced before assignment
switch_to_interface() becomes the common place where
self.interface is set; therefore self.interface is not None
precisely when self.default_server is connected. Previously some
places required it to be connected and some didn't. Also an
interface change now sends the 'updated' notification
consistently - previously some did and some didn't.
Have network_start() call start_interfaces() - this also means
network restarts now do this.
Fix apparent off-by-one in start_interfaces()
Prefer to use safer self.is_connected() as it checks interface
is not None.
Using common code gives small observable changes in behaviour:
- slightly different print_error() messages
- network restarts now enter status 'connecting' which they
didn't before, which seems correct
- status 'connecting' is done with set_status() rather than
simply assigning the status, which seems more correct. Now
that the response_queue is available in the constructor this
works; it used to fail with 'response_queue is not defined'
This is somewhat cleaner as the proxy's pipe and network setup
was awkwardly interleaved. It also means network's constructor
is free to use both; currently some code is working around the
fact that the response queue doesn't exist in the constructor.
Found these issues while trying to create, sign, and broadcast a raw transaction.
* createrawtransaction was using old signature for Transaction constructor
* Signwithwallet and decoderawtransaction need to call deserialize on tx before they can access inputs and outputs. (Maybe adding getInputs() and getOutputs() which deserializes if needed might be nicer)
A couple of changes
1) Old electrum wallets seemed to save labels in latin1, when you call json.dumps on line 83/84 it fails silently, which causes the label import to fail. Whenever electrum saves, it then overwrites your default wallet with no labels - essentially deleting all your labels. The solution to this is iterating over all the labels for old wallets decoding anything that fails to unicode() as latin1, and then unicoding it :)
2) Failing to import data and then deleting it is bad. So I'm raising an exception to avoid data being lost.
First, close the socket from the thread itself rather than from
the stop() function. This prevents another thread closing the
socket that the interface thread is simultaneously using.
Second, it occasionally would happen that the parent thread such as
network.py start() an interface, do a send_request() and timeout
waiting for a response (timeouts are 0.1s). It would check
is_connected(), get False, and assume the connection has failed.
In fact the thread hadn't even been scheduled or gotten around to
completing the socket connection. Fix by having self.connected
start out True. If the connection fails or times out, we set
connected to False soon enough.
Finally for correctness we need to deepcopy a send_request() rather
than take a reference to it.
The verifier will retain responsibility for verification, but will no longer
hold the transaction sets itself.
Change requires_fee to take a wallet.
Add new function add_unverified_tx()
Move get_confirmations() to the wallet from the verifier.
Currently requests are sent from the requestor's thread. The lock is
not properly held where necessary so this is not thread-safe. For example
it can race with the thread stopping and closing the socket the
requestor is trying to use to send with.
Resolve such races by having send_request() simply queue the requests,
which are asynchronously sent from the interface thread itself.
First step in cleaning up the run() function.
Calls stop() rather than setting is_connected to False on
case of timeout, which cleanly closes the socket.