Das DHT-Netzwerk
Wie finden hunderte unabhängiger Server ohne zentrales Verzeichnis einander, einigen sich darauf, wo Daten leben, und routen Anfragen effizient? Hashiverse nutzt eine Kademlia-Distributed-Hash-Table — dieselbe Algorithmenfamilie, die BitTorrent, IPFS und Ethereums Peer-Discovery verwenden — angepasst an die Zugriffsmuster eines sozialen Netzwerks.
Der Ring
Jede Entität in Hashiverse — Server, Nutzer, Beiträge, Hashtags — hat eine 256-Bit-Kennung, die aus ihrem Blake3-Hash abgeleitet wird. Diese IDs liegen auf einem Ring: Der Adressraum schließt sich bei 2256. Die „Distanz" zwischen zwei IDs ist das XOR ihrer Bitmuster, eine Metrik, die dem Ring nützliche Routing-Eigenschaften verleiht.
Jeder Server hält Verbindungen zu anderen Servern, deren IDs im XOR-Abstand nah an seiner eigenen liegen, plus Verbindungen in exponentiell wachsenden Distanzen (die Kademlia-k-Buckets). Diese Struktur bedeutet, dass jeder Server eine Anfrage in O(log n) Sprüngen zum Server routen kann, der einer Ziel-ID am nächsten ist, wobei n die Anzahl der Server im Netzwerk ist.
Quelle: kademlia.rs
Wo Daten leben
Ein Bucket von Beiträgen wird auf den Servern gespeichert, deren IDs der
location_id des Buckets am nächsten sind — ein Hash, der aus Bucket-Typ,
Basis-ID (Nutzer, Hashtag oder Beitrag) und Zeitfenster abgeleitet ist. Das bedeutet:
- Die Beiträge eines Nutzers werden auf den Servern gespeichert, die der ID dieses Nutzers im Ring am nächsten sind.
- Die Beiträge eines Hashtags werden in der Nähe der Hash-ID des Hashtags gespeichert.
- Während neue Server beitreten und gehen, verschiebt sich die Menge der nächsten Nachbarn, und die Heilung verbreitet die Daten zu den neuen nächsten Servern.
Es gibt keinen Master-Index. Kein Server weiß, wo alles ist. Jeder Server weiß, wo Dinge in seiner Nähe sind, und wie zu Dingen zu routen ist, die weiter weg sind.
Lastverteilung
Beliebte Hashtags wären ein Engpass, wenn alle Beiträge zu einem Hashtag dauerhaft auf derselben Handvoll Server landeten. Hashiverse verteilt diese Last über zeitepochenbasierte Schlüsselrotation: Die Standort-ID eines Hashtag-Buckets verschiebt sich über die Zeit, sodass verschiedene Epochen auf verschiedenen Teilen des Rings landen — verschiedene Server. Alle Timeline-Standort-IDs rotieren monatlich; aber geschäftigere Timelines laufen automatisch in Buckets zunehmender Granularität über.
Das Bucket-System ist hierarchisch: 1-Monats-Buckets unterteilen sich in wöchentliche, dann tägliche, dann 6-Stunden-, stündliche, 15-Minuten-, 5-Minuten- und 1-Minuten- Buckets. Das Laden der Timeline durchläuft diese Hierarchie rekursiv — beginnt grob und steigt nur dort in feinere Buckets ab, wo Inhalte existieren. Eine Timeline mit spärlicher Aktivität lädt günstig; eine dichte Timeline lädt effizient, weil jedes Bucket parallel abgerufen werden kann.
Quelle: buckets.rs,
recursive_bucket_visitor.rs
Transport-Abstraktion
Das Protokoll ist transport-agnostisch. Die Traits TransportFactory,
TransportServer und TransportServerHandler in
hashiverse-lib/src/transport/
definieren die Schnittstelle; Implementierungen werden ausgetauscht, ohne die
Protokolllogik zu berühren:
- mem_transport: In-Memory-Kanäle, in Tests verwendet. Erlaubt es, vollständige Multi-Server-Topologien in einem einzigen Prozess ohne Netzwerk-Overhead hochzufahren.
- HttpsTransport / TcpTransport: Produktionsimplementierungen in
hashiverse-server/src/network/transport/, mit HTTPS via auto-bereitgestellter Zertifikate über rcgen und instant-acme (Let's Encrypt). - WasmTransport: Browser-HTTP-Transport via gloo-net, in
wasm_transport.rs.
Die Integrationstests nutzen das ausgiebig: Ein Test, der Heilungsverhalten, DHT-Routing oder Beitragsverbreitung prüft, kann komplett im Speicher mit deterministischem Timing, ohne Ports und ohne Aufräumarbeit laufen.
Test-Harness-Orchestrierung
Das test-harness-Binary startet einen Primärserver (für Bootstrap) plus eine
konfigurierbare Anzahl Sekundärserver in einem einzigen Prozess unter Verwendung von
Tokios JoinSet, alle teilen sich denselben Cancellation-Token für sauberes
Herunterfahren. Der Orchestrator HashiverseServer initialisiert Kademlia,
startet Transport-Handler und verwaltet die Peer-Entdeckung.
Quelle: hashiverse-integration-tests/src/bin/test_harness.rs