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:
| Module | Responsibility |
|---|---|
server_registry | Server registration, discovery, and status tracking |
verification | SHA-256 content-addressed asset verification |
handshake | Challenge-response mutual authentication |
health | Heartbeat-based availability monitoring |
routing | Cross-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:
| Status | Description |
|---|---|
Online | Accepting connections and processing normally |
Degraded | Running but experiencing issues |
Offline | Not responding to health checks |
Suspended | Administratively 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:
| State | Description |
|---|---|
Initiated | Challenge sent, waiting for response |
ChallengeReceived | Response received, completion sent |
Completed | Mutual trust established |
Failed | Timeout 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:
- The source server generates a
SessionTokensigned with its private key. - The token is included in the
SessionHandoffEnvelopealong with the player state. - The destination server verifies the token using the source server's public key (obtained during the handshake).
- 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:
- Registry -- Both servers are registered and discoverable.
- Handshake -- Mutual trust is established via challenge-response.
- Health -- The destination server is confirmed healthy.
- Routing -- The portal route is resolved to the destination server and world.
- Verification -- Destination world assets are downloaded and verified by content hash.
- The player's session is handed off, and they arrive in the new world.
Key Types
| Type | Description |
|---|---|
ServerRegistry | In-memory registry of federated servers |
FederatedServer | Server identity, endpoint, public key, and status |
ServerStatus | Enum: Online, Degraded, Offline, Suspended |
AssetVerification | SHA-256 hash and size for content-addressed asset verification |
HandshakeManager | Tracks challenge-response handshake lifecycle |
HandshakeChallenge | Initial challenge with server ID, nonce, and timestamp |
HealthMonitor | Heartbeat-based server health tracking with thresholds |
HealthStatus | Enum: Healthy, Degraded, Unreachable |
RoutingTable | Portal-to-destination route mapping |
PortalRoute | A single route from source server to destination server and world |