Artículo del Blog
Autor
Stellar Development Foundation
Fecha de publicación
Horizonte
Ingestión
API
Hace más de un año, el equipo de StellarX añadió un GitHub problema sobre un extraño 500 Internal Server Error devuelto por Horizon de vez en cuando. Después de revisarlo, nos dimos cuenta de la causa: Horizon estaba obteniendo ofertas de la base de datos de Stellar-Core y algunas de esas ofertas venían de libros contables aún no ingeridos por Horizon. Para obtener un tiempo de creación para las ofertas, Horizon verifica el tiempo de cierre del libro contable, y si un libro contable aún no ha sido ingerido, esa verificación resulta vacía. De ahí el error del servidor.
Mientras tanto, recibíamos informes sobre tiempos de respuesta muy largos para el endpoint /paths
. Stellar tiene un libro de órdenes descentralizado que permite a los usuarios intercambiar un activo por otro, y el endpoint /paths
te ayuda a encontrar el mejor conjunto de intercambios intermedios para que puedas cambiar la cantidad mínima posible del activo fuente por la cantidad máxima posible del activo destino. Horizon dependía de la base de datos de Stellar-Core, que simplemente no está optimizada para consultas de búsqueda de caminos.
Esos problemas (principalmente menores) no eran exactamente nuevos — habíamos sido conscientes de problemas similares durante años — pero se estaban volviendo cada vez más comunes. Para abordarlos, tuvimos que hacer un cambio fundamental en la arquitectura de Horizon, y construir un sistema completamente nuevo para la ingestión de datos. En los últimos meses, eso es exactamente lo que hemos hecho.
El nuevo sistema de ingestión, que está incluido en la versión Horizon v0.20.1, está listo para pruebas, y en este breve blog explicaré el razonamiento detrás de ello y describiré dos características experimentales en Horizon que no habrían sido posibles en el antiguo sistema. Tiene algunas grandes ventajas sobre el antiguo sistema de ingestión — es más consistente y amigable para los desarrolladores, permite la configuración por parte del usuario, y no sobrecarga a Stellar-Core — y eventualmente planeamos pasarnos completamente a él. En este momento, ambos sistemas están trabajando concurrentemente, y si habilitas una bandera de característica especial en Horizon puedes probar el nuevo sistema y sus nuevas características ¡ahora mismo!
El nuevo paquete de ingestión Golang también puede ser utilizado fuera de Horizon para construir aplicaciones y servicios personalizados. En los próximos meses, publicaremos documentación, ejemplos y una nueva entrada de blog explicando cómo usarlo.
Comencemos con una explicación extremadamente breve y simplificada de cómo funciona Stellar-Core. En resumen: Stellar-Core es una máquina de estado replicada. Cada libro contable representa un estado que es cambiado por un conjunto de transacciones. Stellar-Core luego propaga la información sobre el nuevo estado/libro contable a la red y publica un punto de control en los archivos de historia cada 64 libros contables.
Podemos ver que hay dos tipos de datos conectados a cada libro contable:
Antes del nuevo sistema de ingestión, Horizon no tenía su propia vista del estado (o entradas de libro contable). Los usuarios podían solicitar los datos históricos (transacciones, operaciones, pagos, intercambios, etc.), y Horizon los serviría desde su DB directamente, pero todas las solicitudes conectadas al estado actual del libro contable se reenviaban a Stellar-Core.
Esta única decisión arquitectónica causó muchos problemas, entre ellos:
Para solucionar estos problemas, el nuevo sistema de ingestión tiene una copia completa del estado del libro contable construida usando archivos de historia. Usar archivos de historia no genera carga en Stellar-Core, y permite construir el estado no solo para el último libro contable sino también para cualquier otro libro de control en el pasado. Tener acceso al estado permite la creación de nuevas características, como los dos ejemplos que se encuentran a continuación.
“Cuentas para Firmantes” fue una solicitud de característica muy popular en nuestro GitHub. Puedes usarlo para buscar todas las cuentas que coinciden con un firmante dado, lo que facilita a los clientes de Stellar implementar multi-firma de manera amigable para el usuario. Si, por ejemplo, tienes una cuenta principal que también co-firma varias cuentas multi-firma — una cuenta de negocios, una cuenta que compartes con tu pareja, una cuenta de confianza familiar — tu billetera Stellar puede encontrarlas todas usando tu cuenta principal, sin esfuerzo adicional de tu parte. Con una sola llave, puedes gestionar fácilmente múltiples cuentas multi-firma.
Antes del nuevo sistema de ingestión, no podíamos construir la vista “Cuentas para Firmantes” porque Stellar-Core no tiene un índice en el campo firmante
en la tabla de firmantes
, y la consulta no era lo suficientemente rápida para un uso en tiempo real, en producción. Para complicar más las cosas, una versión posterior de Stellar-Core añadió una actualización de rendimiento que eliminó completamente la tabla de firmantes y movió el array codificado en XDR de firmantes a la tabla de cuentas
.
Debido a que el nuevo sistema puede recrear el estado, pudimos crear una tabla en la base de datos de Horizon con todos los firmantes e índices adecuados. Esta característica ha estado disponible desde 0.19.0, pero está oculta detrás de una bandera de característica. También puedes probarlo en nuestros clusters públicos de Horizon.
Otra característica que lanzamos como parte de 0.20.0 es un algoritmo de búsqueda de caminos más rápido. Hubo muchos experimentos pasados que intentaron mejorar el rendimiento de la búsqueda de caminos a través de Horizon. El nuevo sistema de ingestión finalmente añade estas mejoras a Horizon.
La versión anterior del algoritmo de búsqueda de caminos era lenta por dos razones:
Para mejorar la búsqueda de caminos, usamos el nuevo sistema de ingestión para construir un grafo de libro de órdenes en memoria de todas las ofertas en la red. Como mantenemos todo en memoria, el acceso a los datos es extremadamente rápido. Esto disminuyó el tiempo de respuesta del endpoint /paths
para algunas consultas ¡en 10 veces! Para probarlo, inicia Horizon con la bandera de característica ENABLE_EXPERIMENTAL_INGESTION=true
bandera de función o usa nuestros clústeres públicos de Horizon. Para más información, consulta el notas de lanzamiento.
En el tercer trimestre de 2019 trabajaremos en trasladar todas las características de Horizon al nuevo sistema. También publicaremos documentación para el nuevo paquete de ingestión que se puede utilizar para construir aplicaciones y servicios personalizados y avanzados sin Horizon.