You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a057c55
Browse filesBrowse the repository at this point in the historyBrowse files
* Add Electrum protocol version negotiation
Moves server.version handling out of _ping_loop into a dedicated
`handshaking` state in the monitor loop state machine.
The handshake runs synchronously after recv/write/notify threads
are started but before the ping thread is launched, ensuring the
protocol ordering constraint (server.version before server.ping,
required since protocol 1.2) is enforced by the architecture, not
just by call order within a thread.
Changes:
- New `handshaking` state between `creating_threads` and
`execute_recreation_callback`; ping thread only starts after a
successful handshake
- Protocol range raised from ["1.2", "1.4"] to ["1.3", "1.4"];
blockchain.block.header, used throughout spectrum.py, was added
in 1.3
- Negotiated server software version and protocol version stored
as `server_software_version` and `negotiated_protocol` on the
socket instance and logged at INFO level
- All failure paths (RPCError, timeout, unexpected response format,
sub-minimum negotiated version) trigger reconnect via
`broken_killing_threads`
- Fix logger.exception() missing argument in _create_threads
Tested against libbitcoin, ElectrumX, Fulcrum and electrs-esplora.
* test: update Electrum socket state expectations
---------
Co-authored-by: al-munazzim <al-munazzim@users.noreply.github.com>
The states are stored in the `ElectrumSocket.state` property. The Constructor of the `ElectrumSocket` is hardly doing more than just setting up the `_monitor_thread` which is an endless loop going through these states:
263
276
* `creating_sockets` will create the sockets and pass to `creating_threads` or to `broken_creating_sockets` if that fails
264
277
* `broken_creating_sockets` will try to create the socket and sleep for some time if that fails (and endlessly try to do that)
265
-
* `creating_threads` will create the write/recv/ping/notify threads and start them
278
+
* `creating_threads` will create the write/recv/notify threads (not ping yet) and start them
279
+
* `handshaking` calls server.version synchronously. On success it stores the negotiated protocol version and starts the ping thread. On failure it transitions to `broken_killing_threads`.
266
280
* `execute_recreation_callback` will call that callback after setting the status to `ok`
267
-
* the `ok` state will now simply check the other thready and if one of them is no longer alive (probably the ping-thread as he will exit if ping fails for 4 times) it will transition to `broken_killing_threads`
281
+
* the `ok` state will now simply check the other threads and if one of them is no longer alive (probably the ping-thread as he will exit if ping fails for 4 times) it will transition to `broken_killing_threads`
268
282
* `broken_killing_threads` will set `self.running` to false and wait for the threads to terminate. Especially the `recv` thread might not terminate until he get internet connection (again). This might take forever. If all threads are terminated, it will transition to `creating_socket`
0 commit comments