Skip to content

feat: decentralized version discovery via periodic gateway handshake #3677

@sanity

Description

@sanity

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:

  1. Transport handshake calls report_peer_version() or signal_urgent_update()
  2. The 60s update check task sees the signal
  3. Verifies against GitHub (prevents spoofed version claims)
  4. 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_version sees 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_disabled check

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

[AI-assisted - Claude]

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-networkingArea: Networking, ring protocol, peer discoveryE-mediumExperience needed to fix/implement: Medium / intermediateP-highHigh priorityS-needs-designStatus: Needs architectural design or RFCT-featureType: New functionality request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions