Desarrolladores

Paralelizando Stellar Core: El Primer Paso Hacia 5000 TPS

Autor

Marta Lokhava

Fecha de publicación

TL;DR Este blog es parte de nuestra serie continua sobre el progreso realizado en el plan de ruta 2025 de SDF y las iniciativas clave que estamos impulsando para mejorar la usabilidad, expandir la adopción y fortalecer el Ecosistema Stellar. Esta publicación se basa en los planes introducidos en Escalando Stellar Core: Planes para 2025.

En Stellar Development Foundation, nuestro enfoque está en apoyar casos de uso del mundo real y satisfacer las demandas evolutivas del ecosistema Stellar. Históricamente, los validadores, quienes determinan las configuraciones de la red, acordaron límites de libro mayor basados en el uso observado, logrando un equilibrio entre la aceptación razonable del libro mayor y tarifas justas para los participantes de la red.

Con la introducción de Soroban, hemos visto nuevos usuarios y casos de uso emergentes. En los últimos meses, el uso de Soroban ha crecido significativamente, y es probable que los validadores decidan ajustar los límites de la red en respuesta. Sin embargo, aumentar estos límites no es tarea simple: debemos asegurar que la red se mantenga saludable bajo una carga aumentada. Mirando hacia adelante, nuestros objetivos a corto y mediano plazo son alcanzar teóricamente 5000 transacciones por segundo y reducir el tiempo de bloque de los actuales 5 segundos a 2.5 segundos.

Para apoyar esta evolución, SDF comenzó una serie de mejoras importantes en Stellar Core el año pasado destinadas a mejorar la escalabilidad y allanar el camino para un mayor rendimiento y tiempos de bloque más bajos. Diseñamos estos cambios para aprovechar la capacidad de CPU ya presente en la mayoría de las computadoras modernas. La mejor parte: no se necesitan mejoras de hardware, Stellar Core simplemente hace un uso más inteligente de los núcleos de CPU existentes.

En una serie de publicaciones de blog próximas, repasaremos las mejoras de rendimiento, algunas ya implementadas y otras planificadas, y cómo ayudan a preparar a Stellar para el futuro.

Primero, permítanos articular la visión para un Stellar Core escalable. ¿Cómo queremos que se vea Stellar Core una vez que todos los cambios planificados estén completos?

Conceptualmente, el trabajo de Stellar Core se puede agrupar en tres corrientes de trabajo:

  1. Diseminando nuevas transacciones: Puntos de entrada a la red como Horizon y Stellar RPC continúan enviando nuevas transacciones a la red Stellar. Cada Stellar Core que recibe una nueva transacción ayuda a diseminarla validándola y enviando la transacción a otros Stellar Cores que conoce. Eventualmente, todos los Stellar Cores en la red reciben la transacción.
  2. Acordando un conjunto de transacciones para confirmar: el Stellar Consensus Protocol (SCP) requiere que los validadores intercambien mensajes con otros validadores en quienes confían. Esta corriente de trabajo implica la votación del validador en sí, así como ayudar a diseminar los votos de otros validadores.
  3. Ejecutando el conjunto de transacciones confirmadas: cuando la red está de acuerdo en un bloque a través del Stellar Consensus Protocol, Stellar Core aplica el bloque a la base de datos, en este punto consideramos las transacciones confirmadas.

Si fuéramos a visualizar estas tres corrientes, se vería como la Figura 1a, siendo la flecha azul el hilo principal.

Figura 1a. Esta diagrama visualiza el flujo de trabajo de Stellar Core: los círculos amarillos indican la diseminación de transacciones, los rectángulos azules representan la votación SCP sobre un conjunto de transacciones, los rectángulos morados muestran la ejecución del conjunto de transacciones confirmadas, y la flecha azul marca el paso del tiempo en el hilo principal.

Antes de la v22.1.0, Stellar Core ejecutaba las tres corrientes de trabajo en el hilo principal. La Figura 1b da una idea de cómo este trabajo puede ser ejecutado en el hilo principal. ¡Puede estar ocupado!

Figura 1b. Colocando todo el trabajo de la Fig. 1a en el hilo principal.

Un par de observaciones importantes de estos diagramas:

  • Las transacciones (amarillo) y los votos (azul) compiten por el tiempo del hilo principal, introduciendo así retrasos innecesarios para ambas corrientes.
  • La ejecución de bloques (morado) típicamente toma una cantidad no trivial de tiempo (piense en cientos de milisegundos, incluso segundos, ¡mucho dado que nuestro objetivo es reducir la latencia de extremo a extremo a 2.5 segundos!). Detener el hilo principal por períodos tan largos introduce un retraso de latencia aún peor para las otras dos corrientes.

Para remediar esta situación, primero hicimos dos cambios importantes (ilustrados en la Figura 2):

  • Dedicar un hilo/piscina de hilos separada al procesamiento de transacciones, eliminando así la competencia de CPU entre el consenso y el procesamiento de transacciones.
  • Dedicar un hilo/piscina de hilos separada a la ejecución de bloques, permitiendo que el hilo principal se enfoque puramente en el flujo de consenso sin que la ejecución de bloques detenga el consenso.
Figura 2. El nuevo flujo: la diseminación de transacciones y la ejecución de bloques obtienen piscinas de hilos dedicadas.

Nota que todavía hay algunas dependencias con este nuevo flujo: específicamente, el consenso y la ejecución de bloques siguen siendo secuenciales. Para lograr altos rendimientos y tiempos de bloque bajos, esto no es ideal por dos razones:

  • Nuestro tiempo mínimo de bloque depende de la suma de las latencias de consenso y ejecución

Bajo condiciones normales, el hilo principal que realiza el Stellar Consensus Protocol está esencialmente inactivo mientras un hilo separado ejecuta el bloque más reciente. De manera similar, mientras los validadores ejecutan el Stellar Consensus Protocol para acordar en un bloque, sus CPUs están mayormente inactivas, no ejecutando ningún bloque nuevo. Por supuesto, los validadores aún realizan algo de trabajo de CPU mientras ejecutan SCP (como procesar votos, verificar firmas de votos, etc), pero la cantidad es mínima comparada con la ejecución que consume mucha CPU.

El Juego Final: Encadenamiento

Entra el juego final: verdadero encadenamiento de votación y ejecución de bloques, ver Figura 3.

Figura 3. Encadenamiento de consenso y ejecución: los validadores votan por el libro mayor N+1 durante el libro mayor N. Para cuando los validadores han aplicado el libro mayor N, ya han votado por el bloque N+1 y están listos para aplicarlo.

Inicialmente propuesto por el CTO de SDF, Nico Barry, este diseño presenta varias propiedades interesantes:

  • Consenso y ejecución encadenados:
    • Mientras la red está aplicando el bloque N, simultáneamente está votando por el bloque N+1. Para cuando la ejecución de N se completa, el bloque N+1 está listo para aplicarse.
    • Esta arquitectura mantiene cada componente mayor continuamente activo: la piscina de hilos de ejecución siempre está aplicando, el hilo de consenso siempre está votando, y la piscina de hilos de diseminación de transacciones siempre está transmitiendo.
    • Esto abre la puerta para tiempos de bloque más bajos, ya que ahora el tiempo mínimo de bloque es max(latencia de consenso, latencia de ejecución), una mejora significativa sobre la anterior suma(latencia de consenso, latencia de ejecución).
  • Hemos diseñado los bloques para los libros mayores N y N+1 para que estén libres de conflictos. Esto asegura que los bloques acordados a través del consenso puedan ser validados de forma segura. El diseño previene ataques de denegación de servicio (DoS) en los que actores maliciosos intentan introducir bloques donde las transacciones en un bloque anterior podrían invalidar aquellas en uno subsiguiente, potencialmente reduciendo el rendimiento a cero.

Entonces, ¿cómo logramos esta visión? El resto de esta publicación de blog detallará el primer conjunto de cambios que hicimos y habilitamos en Stellar Core v22.1.0 para apoyar la diseminación paralela de transacciones. Las publicaciones de blog subsiguientes se centrarán en la nueva característica experimental de ejecución paralela, y los cambios planificados para lograr la visión descrita anteriormente.

Parte I: Aislamiento de la Diseminación

La diseminación de transacciones es, lógicamente, un componente bastante aislado, por ejemplo, el consenso y la ejecución no dependen directamente de él. Durante la diseminación, Stellar Core realiza una cantidad significativa de trabajo criptográfico costoso, incluyendo verificación de firmas, hashing, autenticación personalizada y procesamiento de bytes entrantes y salientes. Este trabajo es intensivo en CPU pero desacoplado de la lógica de negocio de la aplicación.

Debido a que estas cargas de trabajo están tanto particionadas como independientes, son adecuadas para la paralelización. Por eso abordamos esta área primero. Conjuntos de datos particionados eliminan preocupaciones sobre carreras de datos y bloqueos, permitiéndonos escalar el rendimiento de manera más segura y eficiente.

Más allá de la carga de trabajo criptográfica, Stellar Core ahora también realiza deduplicación de tráfico en segundo plano, algo posible gracias a su nueva infraestructura paralela. Esto elimina la mayor parte de la carga del hilo principal y contribuye a un rendimiento general más suave, como se observa en la Figura 4.

¡Pruébalo!

Para habilitar el procesamiento paralelo en tu Stellar Core, necesitarás configurar una nueva bandera especial, `BACKGROUND_OVERLAY_PROCESSING`. A partir de Stellar Core v22.1.0, BACKGROUND_OVERLAY_PROCESSING ya está activado por defecto, lo que significa que puedes disfrutar automáticamente de los beneficios de la paralelización.

Desplegando v22.1.0 resultó en una notable disminución de la presión en el hilo principal – en otras palabras, la cantidad de trabajo que el hilo principal tiene en su cola en cualquier momento ha disminuido significativamente. La Figura 4 ilustra la caída, como se observó en los validadores de SDF así como en las instancias de Horizon.

Figura 4. Una disminución en la presión del hilo principal tras el lanzamiento de Stellar Core v22.1.0. El eje Y es tiempo, el eje X es el número de tareas programadas - o una cola de trabajo - que Stellar Core necesita ejecutar.

Comenzando con v22.3.0, Stellar Core aprovechará completamente el procesamiento de transacciones en segundo plano realizando la verificación de firmas en el fondo (para hacerlo, activa la nueva bandera EXPERIMENTAL_BACKGROUND_TX_SIG_VERIFICATION).

Parte II: Aislamiento de la Ejecución

Esto es solo el comienzo del viaje hacia un Stellar Core completamente paralelizado. En la próxima entrega de esta serie de blogs, nos adentraremos en la segunda mejora principal: aislamiento de la ejecución. ¡Mantente atento!