Federation Protocol

How independent Aether servers discover each other, verify assets, establish trust, and route players across server boundaries.

Aether is designed for a decentralized metaverse where anyone can host their own world server. The federation protocol, implemented in the aether-federation crate, defines how independent servers discover each other, prove asset integrity, establish mutual trust, monitor availability, and route players through cross-server portals.

Overview

Federation enables cross-instance interoperability. A player on Server A can travel to a world hosted on Server B without creating a new account or re-downloading assets they already have. The protocol is composed of five modules:

ModuleResponsibility
server_registryServer registration, discovery, and status tracking
verificationSHA-256 content-addressed asset verification
handshakeChallenge-response mutual authentication
healthHeartbeat-based availability monitoring
routingCross-server portal routing table

All modules are synchronous, in-memory data structures with no external dependencies beyond sha2 for hashing. They can be embedded in any async runtime without coupling.

Server Registry

Every federated server registers with a shared registry that tracks its identity, endpoint, and status:

use aether_federation::server_registry::{ServerRegistry, FederatedServer, ServerStatus};

let mut registry = ServerRegistry::new();

registry.register(FederatedServer {
    id: "server-alpha".into(),
    name: "Alpha World Hub".into(),
    endpoint: "https://alpha.example.com:4433".into(),
    public_key: server_public_key.to_vec(),
    registered_at_ms: now_ms(),
    last_heartbeat_ms: now_ms(),
    status: ServerStatus::Online,
})?;

// Look up a server by ID
let server = registry.get("server-alpha")?;

// List all online servers
let online = registry.list_by_status(ServerStatus::Online);

Servers transition through four status states:

StatusDescription
OnlineAccepting connections and processing normally
DegradedRunning but experiencing issues
OfflineNot responding to health checks
SuspendedAdministratively disabled

The registry rejects duplicate registrations. To update a server's information, the server must first deregister and re-register, or use the update_status method.

Asset Verification

When a player travels to a new server, they may need to download assets for that world. The verification module ensures asset integrity through SHA-256 content-addressed hashing:

use aether_federation::verification::{compute_hash, verify_asset, AssetVerification};

// Server publishes asset metadata
let verification = AssetVerification {
    content_hash: compute_hash(&asset_bytes),
    size_bytes: asset_bytes.len() as u64,
    verified: false,
};

// Client downloads the asset and verifies it
let result = verify_asset(&downloaded_bytes, &verification);
match result {
    VerificationResult::Valid => {
        // Asset matches, safe to use
    }
    VerificationResult::HashMismatch { expected, actual } => {
        // Asset was tampered with or corrupted
    }
    VerificationResult::SizeMismatch { expected, actual } => {
        // Download was incomplete
    }
}

Handshake Protocol

Before two servers can exchange player data or route portal traversals, they must establish mutual trust through a challenge-response handshake:

Server A -> Server B: HandshakeChallenge { server_id, nonce, timestamp }
Server B -> Server A: HandshakeResponse { server_id, nonce_signed, challenge_back }
Server A -> Server B: HandshakeComplete { nonce_signed_back }

The HandshakeManager tracks in-progress and completed handshakes:

use aether_federation::handshake::{HandshakeManager, HandshakeChallenge};

let mut manager = HandshakeManager::new();

// Initiate a handshake with another server
let challenge = manager.initiate("server-beta", generate_nonce())?;
send_to_server("server-beta", challenge);

// When the response arrives
let complete = manager.process_response("server-beta", response)?;
send_to_server("server-beta", complete);

// Check if the handshake succeeded
assert!(manager.is_trusted("server-beta"));

Handshakes progress through four states:

StateDescription
InitiatedChallenge sent, waiting for response
ChallengeReceivedResponse received, completion sent
CompletedMutual trust established
FailedTimeout or invalid response

A completed handshake is required before any player routing or asset transfer occurs between two servers.

Health Monitoring

The health module tracks server availability through periodic heartbeats:

use aether_federation::health::{HealthMonitor, HealthStatus};

let mut monitor = HealthMonitor::new(
    3,  // degraded after 3 consecutive failures
    10, // unreachable after 10 consecutive failures
);

// Record heartbeat results
monitor.record_success("server-beta");
monitor.record_failure("server-gamma");

// Check current status
let status = monitor.get_status("server-gamma");

The health state machine transitions based on consecutive failure counts:

Healthy -> Degraded (failures >= degraded_threshold)
Degraded -> Unreachable (failures >= failure_threshold)
Unreachable -> Healthy (success recorded)
Degraded -> Healthy (success recorded)

Any successful heartbeat resets the failure counter and returns the server to Healthy status. The routing table uses health status to avoid sending players to unreachable servers.

Portal Routing

The routing table maps portal IDs to cross-server routes:

use aether_federation::routing::{RoutingTable, PortalRoute};

let mut routing = RoutingTable::new();

routing.add_route(PortalRoute {
    portal_id: "portal-alpha-to-beta".into(),
    source_server: "server-alpha".into(),
    destination_server: "server-beta".into(),
    destination_world: "beta-main-world".into(),
    active: true,
})?;

// Look up where a portal leads
let route = routing.lookup("portal-alpha-to-beta")?;

// List all routes originating from a server
let routes = routing.list_by_server("server-alpha");

// Resolve the full destination (checks health, active status)
let destination = routing.resolve_destination("portal-alpha-to-beta")?;

Routes can be activated and deactivated dynamically. The resolve_destination method checks that the destination server is healthy and the route is active before returning the destination.

Federated Authentication

When a player traverses a cross-server portal, their identity must be verified on the destination server without requiring a separate login. The federation protocol supports this through the session handoff envelope (from aether-zoning) combined with the handshake trust chain:

  1. The source server generates a SessionToken signed with its private key.
  2. The token is included in the SessionHandoffEnvelope along with the player state.
  3. The destination server verifies the token using the source server's public key (obtained during the handshake).
  4. If valid, the player is admitted with their transferred state.

This chain of trust means players can move freely between any servers that have completed mutual handshakes.

Putting It All Together

A typical cross-server portal traversal involves all five modules working together:

  1. Registry -- Both servers are registered and discoverable.
  2. Handshake -- Mutual trust is established via challenge-response.
  3. Health -- The destination server is confirmed healthy.
  4. Routing -- The portal route is resolved to the destination server and world.
  5. Verification -- Destination world assets are downloaded and verified by content hash.
  6. The player's session is handed off, and they arrive in the new world.

Key Types

TypeDescription
ServerRegistryIn-memory registry of federated servers
FederatedServerServer identity, endpoint, public key, and status
ServerStatusEnum: Online, Degraded, Offline, Suspended
AssetVerificationSHA-256 hash and size for content-addressed asset verification
HandshakeManagerTracks challenge-response handshake lifecycle
HandshakeChallengeInitial challenge with server ID, nonce, and timestamp
HealthMonitorHeartbeat-based server health tracking with thresholds
HealthStatusEnum: Healthy, Degraded, Unreachable
RoutingTablePortal-to-destination route mapping
PortalRouteA single route from source server to destination server and world