Require a real Electrum quorum and allow certificate pinning (B-84, ELC-01, ELC-03, ELC-14, ELC-19, ARC-20, OPS-12)
An empty ELECTRUM_FALLBACK_SERVERS (the .env.example default) silently made every corroboration pass, and with fallbacks the majority was taken over whoever answered, so one reachable fallback decided alone. TLS certificates were never checked. - _corroborate_majority passes only with at least 2 answers (MIN_QUORUM_RESPONSES) and a strict majority of the answers; no other server configured, or fewer than 2 answering, fails. ALLOW_NO_QUORUM=true keeps the old reduced rule. - config.validate_quorum_servers, called from the lifespan after parse_endpoints, refuses to start with fewer than 2 fallback servers unless ALLOW_NO_QUORUM=true (which logs a warning at every start). - Optional pinning: `host:port[:mode]:pin=<sha256>` per fallback and ELECTRUM_CERT_PIN for the primary; ElectrumClient compares the SHA-256 of the DER certificate after the TLS handshake and a mismatch fails like an unreachable server. A pin on a plaintext entry is a startup error. - .env.example now ships the four bootstrap servers and documents both new variables; docs/setup.md, spec, storico and BUGS.md updated. - Tests changed because the spec changed: the two "no other servers configured -> True" corroboration tests now assert that outcome only under allow_no_quorum. Note: a dev .env with fewer than 2 fallback servers will now refuse to start. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fd6a91e93d
commit
13cb66cc06
18 files changed
+451
-125
No files matched your search
+20
-5
@@ -3,17 +3,32 @@ ELECTRUM_PORT=50002
|
||||
ELECTRUM_USE_SSL=true
|
||||
|
||||
# Additional Electrum servers to fall back to, comma-separated. Each entry is
|
||||
# `host:port` (TLS, the normal case) or `host:port:notls`. The listener rotates
|
||||
# over the primary above plus these, so one unreachable server costs a single
|
||||
# reconnect attempt instead of an outage — every deposit credit, broadcast and
|
||||
# `host:port` (TLS, the normal case), `host:port:notls`, or `host:port:pin=<sha256>`
|
||||
# (TLS, and the server's DER certificate must hash to that SHA-256, in hex). The
|
||||
# listener rotates over the primary above plus these, so one unreachable server costs
|
||||
# a single reconnect attempt instead of an outage — every deposit credit, broadcast and
|
||||
# confirmation goes through this one connection, which makes a single server the
|
||||
# platform's biggest single point of failure. A typo here fails at startup rather
|
||||
# than during the outage when the fallback is what you need.
|
||||
#
|
||||
# AT LEAST 2 are required (B-84): every decision that moves money is corroborated by
|
||||
# the *other* servers and needs two independent answers, so with fewer than two
|
||||
# fallbacks the server refuses to start (override: ALLOW_NO_QUORUM, development only).
|
||||
# Configure three or more in production, so one being down does not stop the lottery.
|
||||
#
|
||||
# These are the mainnet bootstrap servers from the PalladiumWallet repo
|
||||
# (src/Core/Chain/ChainProfiles.cs, ChainProfiles.Mainnet.BootstrapServers) — the
|
||||
# same ones the reference wallet falls back to:
|
||||
# Example: ELECTRUM_FALLBACK_SERVERS=173.212.224.67:50002,144.91.120.225:50002,66.94.115.80:50002,89.117.149.130:50002
|
||||
ELECTRUM_FALLBACK_SERVERS=
|
||||
ELECTRUM_FALLBACK_SERVERS=173.212.224.67:50002,144.91.120.225:50002,66.94.115.80:50002,89.117.149.130:50002
|
||||
|
||||
# Optional: SHA-256 (hex) of the primary server's DER certificate. A connection that
|
||||
# presents another certificate fails like an unreachable server. Empty = not pinned.
|
||||
ELECTRUM_CERT_PIN=
|
||||
|
||||
# Development only: start with fewer than 2 fallback servers (corroboration then falls
|
||||
# back to the weak rule: a single answer decides, or nothing is checked at all).
|
||||
# NEVER true in production.
|
||||
ALLOW_NO_QUORUM=false
|
||||
|
||||
# Fernet key protecting the master xprv at rest. Generate with:
|
||||
# python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
||||
|
||||
Reference in new issue
Block a user