La red DHT

¿Cómo encuentran cientos de servidores independientes, sin directorio central, unos a otros, se ponen de acuerdo sobre dónde viven los datos y enrutan peticiones de forma eficiente? Hashiverse usa una tabla de hash distribuida Kademlia — la misma familia de algoritmos que utilizan BitTorrent, IPFS y la capa de descubrimiento de pares de Ethereum — adaptada a los patrones de acceso de una red social.

El anillo

Cada entidad en Hashiverse — servidores, usuarios, publicaciones, hashtags — tiene un identificador de 256 bits derivado de su hash Blake3. Estos IDs viven en un anillo: el espacio de direcciones se cierra en 2256. La «distancia» entre dos IDs es el XOR de sus patrones de bits, una métrica que da al anillo propiedades útiles de enrutamiento.

Cada servidor mantiene conexiones con otros servidores cuyos IDs estén próximos al suyo en distancia XOR, más conexiones a distancias exponencialmente crecientes (los k-buckets de Kademlia). Esta estructura significa que cualquier servidor puede enrutar una consulta al servidor más cercano a cualquier ID objetivo en O(log n) saltos, donde n es el número de servidores de la red.

Fuente: kademlia.rs

Dónde viven los datos

Un bucket de publicaciones se almacena en los servidores cuyos IDs están más próximos al location_id del bucket — un hash derivado del tipo de bucket, el ID base (usuario, hashtag o publicación) y la ventana de tiempo. Esto significa:

No hay un índice maestro. Ningún servidor sabe dónde está todo. Cada servidor sabe dónde están las cosas cercanas a él, y cómo enrutar hacia las que están lejos.

Distribución de carga

Los hashtags populares serían un cuello de botella si todas las publicaciones de un hashtag aterrizaran indefinidamente en el mismo puñado de servidores. Hashiverse distribuye esa carga mediante rotación de claves basada en épocas temporales: el ID de ubicación de un bucket de hashtag se desplaza con el tiempo, así que distintas épocas caen en distintas zonas del anillo — distintos servidores. Todos los IDs de ubicación de cronología rotan con cadencia mensual; pero las cronologías más cargadas se desbordan automáticamente a buckets de granularidad creciente.

El sistema de buckets es jerárquico: los buckets de 1 mes se subdividen en semanales, luego diarios, luego de 6 horas, horarios, de 15 minutos, de 5 minutos y de 1 minuto. La carga de la cronología recorre esta jerarquía recursivamente — empieza grueso y solo profundiza en buckets más finos donde existe contenido. Una cronología con poca actividad se carga barato; una densa se carga eficientemente porque cada bucket puede recuperarse en paralelo.

Fuente: buckets.rs, recursive_bucket_visitor.rs

Abstracción del transporte

El protocolo es agnóstico al transporte. Los traits TransportFactory, TransportServer y TransportServerHandler en hashiverse-lib/src/transport/ definen la interfaz; las implementaciones se intercambian sin tocar la lógica del protocolo:

Las pruebas de integración explotan esto a fondo: una prueba que verifica comportamiento de reparación, enrutamiento DHT o propagación de publicaciones puede ejecutarse enteramente en memoria con timing determinista, sin puertos y sin limpieza.

Orquestación del test-harness

El binario test-harness arranca un servidor primario (para bootstrap) más un número configurable de servidores secundarios en un solo proceso usando el JoinSet de Tokio, todos compartiendo el mismo token de cancelación para apagado limpio. El orquestador HashiverseServer inicializa Kademlia, lanza los manejadores de transporte y gestiona el descubrimiento de pares.

Fuente: hashiverse-integration-tests/src/bin/test_harness.rs