Rotate away from a connected server that stopped following the chain (B-86, ELC-21, ARC-26)

`server.ping` keeps succeeding on a server that is stalled, and nothing compared its tip
with the others', so it stayed the active server for ever.

- The listener records when the last header was accepted (monotonic clock, a module
  attribute so tests can move it).
- After every successful ping, ElectrumListener._check_not_stalled: once the last accepted
  header is older than 360s the other servers are asked for their tip
  (blockchain.headers.subscribe, ELC-14's timeouts); if any reports a higher height than
  ours the session ends with ServerStalledError and run() rotates to the next server. If
  none does the chain is just quiet and the session goes on.

No existing test changed. ELC-29 and /admin/electrum (the connection state and the age of
the last header, B-92) are untouched.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5.5 committed 2026-10-14 16:01:44 +02:00
1 parent 50b68d2957
commit 82d078e2d6
8 files changed
+185 -22

No files matched your search

+3 -3
View File
@@ -234,7 +234,7 @@ cifrava di nuovo il file sbagliato (vedi [operativita.md](operativita.md)).
| B-83 | Conferme e reintegri si basano solo sul server attivo | Alta | *da registrare* | `test_confirmation_proof.py`, `test_confirmation.py` | ELC, TX, DEP |
| B-84 | Il quorum può ridursi a un solo server o a nessuno senza avvisi; certificati TLS non verificati | Alta | *da registrare* | `test_electrum_client.py`, `test_electrum_listener.py` | ELC, SEC |
| B-85 | Le riorganizzazioni della catena non vengono né seguite né segnalate | Alta | *da registrare* | `test_electrum_listener.py` | ELC, RND |
| B-86 | Un server connesso ma fermo non viene mai sostituito | Alta | **aperto** | — | ELC, OPS |
| B-86 | Un server connesso ma fermo non viene mai sostituito | Alta | *da registrare* | `test_electrum_listener.py` | ELC, OPS |
| B-87 | L'RBF può lasciare un resto sotto la soglia di dust | Alta | **aperto** | — | TX |
| B-88 | Le transazioni SQLite non sono quelle che il codice presuppone; `synchronous=NORMAL` può perdere gli ultimi commit | Alta | *da registrare* | `test_sqlite_transactions.py`, `test_db_base.py` | DAT, ARC |
| B-89 | Problemi della chiave rilevati solo al primo uso; gli script accettano qualunque xprv e scrivono file leggibili da tutti | Alta | **aperto** | — | SEC, OPS |
@@ -252,9 +252,9 @@ cifrava di nuovo il file sbagliato (vedi [operativita.md](operativita.md)).
- **Corretti:** B-01 … B-70, tranne B-16, che è chiuso nella sostanza (il
crash è eliminato e `/guida` serve un segnaposto) ma lascia la guida vera
come limite accettato; dalla revisione del 2026-09-28: B-88, B-75, B-97, B-80, B-84, B-76, B-77, B-78, B-83, B-74, B-85.
come limite accettato; dalla revisione del 2026-09-28: B-88, B-75, B-97, B-80, B-84, B-76, B-77, B-78, B-83, B-74, B-85, B-86.
- **Aperti:** B-71, B-72 (gravità bassa, operativi o di documentazione) e
B-73 … B-98 dalla revisione del 2026-09-28 tranne i corretti (4 critici,
5 alti, 6 medi), da implementare nell'ordine di
4 alti, 6 medi), da implementare nell'ordine di
[piano-correzioni.md](piano-correzioni.md).
- **Prossimo numero libero:** `B-99`.