-
-
Notifications
You must be signed in to change notification settings - Fork 132
Description
Problem
Peers with full same-version connections never perform new transport handshakes, so the handshake-based version discovery mechanism never fires. These peers form stale sub-networks that never discover newer versions (reported by Ivvor: node stuck on 0.2.13 overnight with all peers on 0.2.13).
This is the same root problem as #3664, but this issue proposes a decentralized solution rather than polling GitHub.
Proposed Solution: Layered Version Discovery
Layer 1: Periodic gateway handshake (primary)
Every ~4 hours (with jitter), initiate a transport-level handshake with a configured gateway, purely for version exchange. This works because:
- Version exchange already happens during the transport handshake (
report_peer_version()is called on every handshake, even incompatible ones) - The gateway is almost always on the latest version
- Gateway addresses are hardcoded in config, so this works even when the network is degraded or broken (e.g., after a bad release)
- No new protocol messages needed — reuses existing handshake infrastructure
- The connection doesn't need to complete a full CONNECT — just the transport handshake is enough
If the gateway reports a newer version, the existing update check task verifies against GitHub (to prevent malicious version claims) and triggers the update.
Layer 2: Version contract (future, separate issue)
A well-known Freenet contract containing signed version info that all peers subscribe to. Updates propagate through the subscription tree. This is the most "Freenet-native" approach but:
- Requires a reasonably healthy network to propagate updates
- Can't be the sole mechanism — a bad release that breaks the network would also break the version contract
- Needs a signed contract with release key verification
- Larger implementation scope (new contract, release process integration, startup subscription)
Layer 1 should be implemented first as the reliable fallback. Layer 2 can be added later as an optimization.
Design Details
Where the probe lives
connection_maintenance in ring.rs is the natural home — it already manages connections and has access to gateway addresses. Add a ~4h timer (with ±20% jitter and staggered initial start) that initiates a transport handshake with a configured gateway.
What happens after version discovery
The existing machinery handles everything:
- Transport handshake calls
report_peer_version()orsignal_urgent_update() - The 60s update check task sees the signal
- Verifies against GitHub (prevents spoofed version claims)
- If confirmed, exits with code 42 → service manager runs
freenet update
Anti-thundering-herd
- Initial delay: random 0-4h after startup
- Subsequent probes: 4h ± 20% jitter
- Same pattern used by the existing staggered update mechanism
Edge cases
- Gateway unreachable: Handshake fails silently, retry on next 4h cycle
- Gateway on same version:
report_peer_versionsees no newer version, no action - Network completely down: Transport handshake fails, falls back to next cycle. No worse than current behavior.
- Dirty/dev builds: Gated by the existing
auto_update_disabledcheck
Relationship to #3664
This replaces the GitHub-polling approach proposed in #3664 with a decentralized mechanism. #3664's current PR (#3665) polls GitHub directly every 4h — this issue proposes polling the gateway via transport handshake instead, using GitHub only for verification of peer-reported version claims.
Not in scope
- Windows auto-update support (tracked in fix: peers with sufficient connections never discover version updates #3664 Gap 2)
- Version contract implementation (future work, separate issue)
[AI-assisted - Claude]