NUEVO: Helius adquiere Light Protocol
comparación del ciclo de vida de las transacciones de Solana y Sui
Blog/Fundamentos

Al límite del determinismo: ciclo de vida de las transacciones en Solana Sealevel y el runtime de objetos de Sui

Investigador y desarrollador full stack.Prince Israel en XPrince Israel en LinkedIn
29 min de lectura

Solana y Sui son destacadas blockchains de capa 1 y alto rendimiento capaces de procesar grandes volúmenes de transacciones a un costo muy bajo sin sacrificar escalabilidad, velocidad ni descentralización.

Ambos protocolos han obtenido reconocimiento en la industria como blockchains de vanguardia que resuelven muchas de las limitaciones de blockchains anteriores como Ethereum y Bitcoin.

Estos protocolos están diseñados para procesar decenas de miles de transacciones en paralelo, lo que permite un rendimiento excepcionalmente alto tanto en teoría como en la práctica. Por ejemplo, Solana puede alcanzar hasta 65,000 transacciones por segundo (TPS) en condiciones ideales y mantiene cerca de 4,000 TPS en situaciones reales.

Por otro lado, Sui ha demostrado un máximo teórico de 297,000 TPS, pero desde su lanzamiento ha procesado un máximo de 3,500 TPS, con un promedio diario cercano a 400 TPS de transacciones de usuarios y 600 TPS de transacciones del sistema para construir checkpoints.

Actualmente, Solana logra la confirmación optimista en 400 ms y la finalidad completa en ~12.8 segundos. Se espera que alcance la finalidad completa en 100-130 ms con la próxima actualización de consenso Alpenglow. Sui logra finalidad en menos de un segundo en el percentil 90 (P90) de latencia gracias a su sólido diseño optimista.

En este artículo de investigación, examinamos los mecanismos subyacentes que impulsan el alto rendimiento de las transacciones mediante el análisis del ciclo de vida de las transacciones de ambas cadenas. También ofrecemos una comparación integral para mostrar cómo sus distintos modelos de ejecución les permiten lograr un alto rendimiento con poco tiempo hasta la finalidad.

¿Cuál es el ciclo de vida de una transacción de blockchain?

Las blockchains procesan transacciones. Las transacciones afectan el estado (es decir, la vista actualizada de las cuentas en una blockchain). Comprender el ciclo de vida de una transacción puede ser la expresión más clara de la filosofía de diseño de una blockchain. Ofrece a las partes interesadas técnicas información importante sobre cómo se optimiza la cadena para obtener rendimiento y seguridad, sus garantías de determinismo, los costos relativos de ingeniería y los posibles puntos problemáticos en condiciones reales.

En las siguientes secciones, examinaremos las distintas etapas por las que pasan las transacciones desde su envío hasta su finalización y cómo este proceso afecta la ejecución en distintos niveles dentro de estas cadenas.

Ciclo de vida de las transacciones de Solana

La blockchain Solana se basa en un diseño único que utiliza Proof-of-Stake (PoS) como mecanismo de consenso y Proof-of-History (PoH) como mecanismo de medición del tiempo para ordenar las transacciones de forma eficiente.

El modelo de diseño de Solana se centra en las cuentas, lo que también puede expresarse así: "todo en Solana es una cuenta".

Las cuentas almacenan datos, incluidos el estado y los binarios ejecutables (es decir, el código de los programas). Las transacciones contienen instrucciones que modifican el estado de las cuentas. Los nodos que participan en el consenso de la red y procesan transacciones se denominan validadores. El proceso mediante el cual se procesan transacciones para modificar una cuenta se denomina procesamiento segmentado, y los puntos donde una transacción se encuentra en distintas fases de su ciclo de vida se denominan etapas.

Una transacción de Solana

En Solana, una transacción es un conjunto de firmas de mensajes serializados firmados por la primera clave de la clave de cuenta de Message.

El mensaje de una transacción es una estructura de datos que contiene un encabezado, claves de cuentas, un blockhash reciente e instrucciones. El encabezado contiene MessageHeader, que describe la organización de las claves de cuentas de Message.

Cada instrucción define de forma explícita a qué cuentas puede acceder y qué permisos requiere para cada una. Estos permisos indican si una cuenta es de solo lectura o de lectura y escritura, y si debe haber firmado la transacción que incluye la instrucción.

Código
pub struct Message {
pub header: MessageHeader,
pub account_keys: Vec<Pubkey>,
pub recent_blockhash: Hash,
pub instructions: Vec<CompiledInstruction>,
}

Cada instrucción contiene una lista de todas las cuentas a las que puede acceder, junto con los permisos requeridos para cada cuenta.

Un Message contiene una única lista plana compartida de todas las cuentas que requieren todas las instrucciones de la transacción. Esta lista plana se crea al construir un Message, y las instrucciones se convierten en un conjunto de CompiledInstructions. Luego, estos CompiledInstructions hacen referencia por índice a las cuentas que necesitan de la lista compartida única.

La lista de cuentas compartida se ordena según los permisos requeridos por las cuentas:

  • Cuentas que permiten escritura y son firmantes.
  • Cuentas que son de solo lectura y firmantes.
  • Cuentas que permiten escritura y no son firmantes.
  • Cuentas que son de solo lectura y no son firmantes.

Dado este orden, los campos de MessageHeader describen qué permisos requiere cada cuenta de una transacción.

Código
pub struct MessageHeader { 
pub num_required_signatures: u8,
pub num_readonly_signed_accounts: u8,
pub num_readonly_unsigned_accounts: u8,
}

Cuando varias transacciones acceden a las mismas cuentas de solo lectura, el runtime puede procesarlas en paralelo dentro de una única entrada de PoH. Las transacciones que acceden a las mismas cuentas de lectura y escritura se procesan de forma secuencial.

Las transacciones se envían al cliente mediante Gulf Stream, el protocolo de reenvío de transacciones de Solana, y se procesan mediante dos procesos segmentados y de varias etapas en el validador: la Transaction Processing Unit (TPU) y la Transaction Validation Unit (TVU).

Estos procesos trabajan junto con el runtime para garantizar que las transacciones que modifican estados de cuentas diferentes se procesen en paralelo, mientras que las que modifican el mismo estado de cuenta se procesen secuencialmente.

La TPU se ejecuta cuando el validador está en modo líder (es decir, produce bloques), y la TVU se ejecuta cuando está en modo validador (es decir, valida bloques). En ambos casos, el hardware segmentado es similar: entrada de red, escrituras en disco, salida de red, etc. Sin embargo, el uso de ese hardware es distinto. En pocas palabras, la TPU crea entradas del ledger, mientras que la TVU valida esas entradas.

A grandes rasgos, las transacciones se envían mediante un cliente y se procesan a través de Gulf Stream usando QUIC hasta la TPU de un líder. La transacción se somete a verificaciones y luego la etapa bancaria la programa para su ejecución. Las actualizaciones de estado se escriben en el estado en memoria del banco. Los validadores votan por los bloques mediante gossip, y los bloques se finalizan con Tower BFT, una variante de PBFT con mecanismos de bloqueo ponderados por stake.

Gulf Stream

En la mayoría de las blockchains, las transacciones que envían los usuarios se colocan en la “cola” de un mempool (literalmente, un “grupo de memoria”) para esperar a que la red las procese. Las transacciones firmadas pueden permanecer en el mempool durante un periodo prolongado o incluso indefinido mientras esperan su ejecución si la red no está en un estado óptimo o no se cumplen las condiciones de ejecución. Como resultado, es posible que nunca se incluyan en un bloque.

Solana elimina la necesidad de un mempool global mediante un calendario de líderes determinista influido por un algoritmo ponderado por stake, conocido como Stake-Weighted Quality of Service (SWQoS), que prioriza los mensajes de transacciones enrutados a través de validadores con stake.

Como todos los nodos activos conocen de antemano el calendario de líderes, los mensajes de transacciones pueden distribuirse eficientemente. Esto garantiza que los próximos líderes ya tengan suficientes transacciones para procesar antes de su turno de producción de bloques. Este mecanismo permite a los validadores preprocesar las transacciones, verificar firmas y eliminar con antelación las transacciones duplicadas o malformadas.

Otra ventaja de Gulf Stream es que, en las cadenas tradicionales que usan un mempool, los productores de bloques también deben retransmitir las mismas transacciones dentro de un bloque. Esto significa que cada transacción se propaga al menos dos veces por la red. Solana no necesita sobrecargar gossip para sincronizar transacciones pendientes, y las transacciones no tienen que competir por espacio en los bloques mediante subastas de gas. En su lugar, se distribuyen según la programación.

Transaction Processing Unit (TPU)

La TPU es la lógica central del validador responsable de producir bloques. Las transacciones se obtienen del cliente y se reenvían en paquetes de datos mediante un componente llamado QUIC streamer, que asigna la memoria de los paquetes y lee los datos del endpoint QUIC (esto se conoce como “Fetch Stage”). Cada stream transmite un paquete dentro de una restricción de transmisión QUIC identificada por el cliente (dirección IP, clave pública del nodo) y el servidor.

Después, los paquetes se transmiten a la Sigverify Stage, donde se deduplican mediante un mecanismo especial de reducción de carga para eliminar el exceso de paquetes. Los paquetes deduplicados se filtran para eliminar los que tienen firmas no válidas y se reenvían a la etapa bancaria.

La etapa bancaria es un componente clave de la ejecución del runtime de Solana. Programa los paquetes entrantes, vuelve a filtrarlos para detectar conflictos y evalúa si pueden procesarse, retenerse o reenviarse en lotes. Si detecta que el nodo es el productor del bloque, procesa los paquetes retenidos y los recién recibidos mediante el componente Bank. Este componente es una representación en memoria del estado completo del ledger en un slot determinado.

Dentro de la etapa bancaria y del componente de programación, la transacción se registra en dos estados:

  • Un estado sin procesar, en el que la transacción está disponible para programarse
  • Un estado pendiente, en el que la transacción se está programando o procesando

Cuando una transacción termina de procesarse, puede ser reintentable. Si lo es, vuelve al estado sin procesar; de lo contrario, debe descartarse. Las transacciones procesadas válidas se convierten en una “Entry” mediante ticks de PoH, se agrupan en bloques y se transmiten como shreds a los pares de la red mediante Turbine, el protocolo de propagación de bloques de Solana. Este genera códigos de borrado para “regenerar” los paquetes de datos perdidos antes de transmitirlos al par de red correspondiente en la Broadcast Stage.

Transaction Validation Unit (TVU)

La TVU es la lógica de los nodos validadores que no son líderes y se encarga de validar y propagar los bloques. En la TVU, los paquetes de datos se procesan en etapas multihilo antes de finalizarse. Esto incluye las etapas de obtención de shreds, verificación de firmas, retransmisión y repetición.

En la Shred Fetch Stage y la etapa de verificación de la firma del líder de los shreds, los nodos que no son líderes reciben los shreds de otros nodos mediante UDP y verifican las firmas por lotes. Los shreds válidos se retransmiten a los nodos pares en la Retransmit Stage, y cada transacción se reproduce en orden en la Replay Stage.

En la etapa de repetición, se invoca el runtime para volver a ejecutar todas las transacciones de forma determinista. Así se garantiza que todos los cambios de estado, atributos de programas y hashes del banco coincidan exactamente con la salida del líder.

Si un bloque se considera válido, el validador firma una transacción de voto y envía ese voto al líder para incluirlo en bloques posteriores.

Runtime

El runtime es el procesador simultáneo de transacciones de Solana que comparten la TPU y la TVU. Las transacciones especifican por adelantado sus dependencias de datos (es decir, las cuentas que desean leer o escribir) para permitir la ejecución explícita con memoria dinámica. Como resultado, la lectura del estado puede aislarse bien de la ejecución de programas, lo que permite al runtime coordinar el acceso simultáneo.

El runtime de Solana usa un motor de ejecución llamado Sealevel para garantizar que las transacciones que acceden a cuentas de solo lectura se ejecuten en paralelo. Por el contrario, las transacciones que acceden a cuentas con escritura superpuesta se serializan y ejecutan secuencialmente.

Dentro del runtime, las transacciones se ejecutan atómicamente. Todas las instrucciones de una transacción deben ejecutarse correctamente para que esta se confirme en el banco; de lo contrario, la transacción falla.

El runtime interactúa con un programa determinado mediante un punto de entrada con una interfaz bien definida. Este punto de entrada es simplemente una función de Rust que todos los programas onchain exponen de forma clara como punto inicial de ejecución y sirve como interfaz entre el runtime de Solana y los programas. Su motor de ejecución asigna claves públicas a cuentas y las dirige a este punto de entrada. Sin embargo, aplica algunas restricciones esenciales para guiar su lógica de ejecución, definidas por la arquitectura del conjunto de instrucciones de la máquina virtual:

  • Solo el programa propietario puede modificar el contenido de una cuenta.
  • Los saldos totales de todas las cuentas son iguales antes y después de ejecutar una transacción, pero esto solo se aplica de forma agregada. Los lamports no se conservan en transferencias y quemas del sistema.
  • Después de ejecutar la transacción, los saldos de las cuentas de solo lectura deben ser iguales a los saldos anteriores.
  • Todas las instrucciones de la transacción se ejecutan atómicamente. Si una falla, se descartan todas las modificaciones de las cuentas.

Los pipelines de la TPU y la TVU siguen rutas ligeramente distintas al interactuar con el runtime. El runtime de la TPU garantiza que las “entries” se registren mediante ticks de PoH antes de confirmar la memoria, mientras que el runtime de la TVU garantiza que las “entries” se verifiquen antes de que el runtime procese cualquier transacción.

Consenso

El consenso es uno de los mecanismos más fundamentales de los sistemas complejos de computación distribuida. En el ciclo de vida de las transacciones de Solana, el consenso ocurre después de que la TVU ejecuta y valida el bloque, pero antes de su finalización. La idea central del consenso es alcanzar un acuerdo uniforme que garantice que los participantes de la red acepten el mismo resultado y que, una vez decidido, no puedan cambiar su decisión.

En términos formales, un mecanismo de consenso tolerante a fallas debe satisfacer las siguientes propiedades:

  • Acuerdo uniforme: No hay dos nodos que decidan de forma diferente.
  • Integridad: Ningún nodo decide más de una vez.
  • Validez: Si un nodo decide un valor, ese valor fue propuesto por otro nodo.
  • Terminación: Cada nodo que no falla termina decidiendo algún valor.

A primera vista, el objetivo del consenso es lograr que los nodos se pongan de acuerdo sobre algo. En Solana, existen varias situaciones en las que los nodos deben ponerse de acuerdo. Esto predomina en tres escenarios:

Rotación de líderes

Todos los nodos deben acordar quién es el líder porque las fallas de red pueden interrumpir la comunicación y provocar un escenario de cerebro dividido, en el que varios nodos creen erróneamente que son el líder al mismo tiempo.

El calendario de líderes se genera con una semilla predefinida y el siguiente algoritmo: la altura de ticks de PoH (es decir, un contador que aumenta de forma monótona) se usa periódicamente como semilla de un algoritmo pseudoaleatorio estable.

En esa altura, se obtiene del banco una muestra de todas las cuentas con stake cuyas identidades de líder hayan votado dentro de una cantidad de ticks configurada por el clúster. La muestra se denomina conjunto activo y se ordena por peso de stake. Luego, la semilla aleatoria se usa para seleccionar nodos ponderados por stake y crear un orden ponderado por stake, que se vuelve válido después de una cantidad de ticks configurada por el clúster.

Sincronización

Sin marcas de tiempo confiables, un validador no puede determinar el orden de los bloques entrantes. Solana usa un mecanismo llamado Proof-of-History como reloj criptográfico para ordenar las transacciones antes de que pasen por consenso. Según la documentación de Anza sobre sincronización:

“Los nodos líderes asignan una "marca de tiempo" a los bloques mediante pruebas criptográficas de que ha transcurrido cierto tiempo desde la última prueba. Todos los datos incluidos mediante hash en la prueba ocurrieron con certeza antes de que esta se generara. Después, el nodo comparte el nuevo bloque con los nodos validadores, que pueden verificar esas pruebas. Los bloques pueden llegar a los validadores en cualquier orden o incluso reproducirse años después. Con garantías de sincronización tan confiables, Solana puede dividir los bloques en lotes más pequeños de transacciones denominados entries. Luego, las entries se transmiten a los validadores en tiempo real, antes de que exista cualquier noción de consenso del bloque”.

Es importante recordar que, aunque Proof-of-History no es un mecanismo de consenso, tiene un impacto significativo en el rendimiento del consenso Proof-of-Stake de Solana.

Confirmación atómica

Otro proceso necesario sobre el que los nodos deben ponerse de acuerdo es la confirmación atómica. En un sistema de alto rendimiento como Solana, una transacción puede fallar en algunos nodos y completarse correctamente en otros.

Para evitar la ejecución parcial, Solana garantiza la atomicidad dentro del runtime en el sentido de ACID. También garantiza que todos los nodos estén de acuerdo sobre el resultado de una transacción: revierten los cambios si algo sale mal o los confirman si todo sale bien.

El compromiso en Solana mide la finalidad de un bloque (slot) según la cantidad de validadores que votaron por él y la profundidad de sus votos en el mecanismo de bloqueo Tower BFT. Refleja la solidez del acuerdo de la red sobre el slot dado según los votos emitidos por los validadores. Cada validador vota por slots, específicamente por alturas de bloque, y se compromete a no votar por bifurcaciones en conflicto. Los bloqueos de Tower BFT garantizan la aplicación de este mecanismo.

Solana tiene tres estados de compromiso: procesado, confirmado y finalizado. Un bloque se considera confirmado cuando una supermayoría de validadores con stake (≥66 %) vota por él, y se finaliza cuando se construyen al menos 32 bloques confirmados encima.

Como consecuencia directa de su ejecución paralela optimista y su calendario asíncrono de líderes, Solana sigue un modelo de “ejecutar primero y votar después”: el protocolo no espera a que todos los validadores acepten un bloque recién producido antes de producir el siguiente. Esto también puede provocar bifurcaciones, es decir, un escenario donde existen simultáneamente dos o más cadenas competidoras. Una vez que un slot se finaliza, se abandonan todas las bifurcaciones competidoras y esa bifurcación se convierte en la cadena canónica.

Alpenglow

Al momento de publicar este artículo, Solana usa Tower BFT y el ledger de PoH para garantizar que la red alcance un estado de consenso incluso cuando algunos participantes fallan.

Recientemente, el equipo de investigación de Anza propuso un nuevo diseño para un protocolo de consenso más simple y eficiente llamado Alpenglow. Alpenglow busca renovar los componentes heredados del diseño de consenso actual, incluidos Proof of History, Tower BFT y el uso de gossip para propagar votos.

En esencia, Alpenglow usa Votor y Rotor para acelerar el consenso de Solana:

Votor es un mecanismo de votación de dos niveles diseñado para lograr la finalidad de un bloque en una sola ronda si responde el 80 % del stake, y en dos rondas si responde al menos el 60 % del stake.

Rotor perfecciona el protocolo Turbine actual mediante una única capa de nodos de retransmisión que gestiona la distribución de shreds. Rotor también aprovecha el ancho de banda de los nodos participantes en proporción a su stake para reducir los saltos y optimizar el rendimiento de Solana. 

Sui

A diferencia de Solana, que usa un modelo centrado en cuentas, la blockchain Sui utiliza un modelo de datos orientado a objetos que representa los datos de estado como objetos con identificadores, propiedades y métodos únicos.

En Sui, un contrato inteligente también es un objeto denominado paquete Sui Move, con un identificador único que manipula objetos. Estos paquetes Sui Move incluyen un conjunto de módulos de bytecode de Move . Cada módulo es único por su nombre y por la combinación del ID onchain de un paquete y el nombre del módulo, que lo identifican de forma única.

Aunque los detalles del diseño y los metadatos de los objetos están fuera del alcance de este artículo, es fundamental recordar que cada objeto tiene un propietario que determina cómo puede usarse en las transacciones.

Los objetos pueden tener los siguientes modelos de propiedad:

  • Objetos propiedad de una dirección: Un objeto propiedad de una dirección pertenece a una dirección específica de 32 bytes, ya sea una dirección de cuenta o un ID de objeto. Solo su propietario puede acceder a él.
  • Objetos inmutables: Un objeto inmutable no puede modificarse, transferirse ni eliminarse. No tiene propietario y está disponible globalmente para que cualquiera lo use.
  • Objetos compartidos: Un objeto compartido se comparte y también está disponible para todos.
  • Objetos encapsulados: Esto implica encapsular un objeto dentro de otro. Los objetos encapsulados no son independientes y solo puede accederse a ellos mediante el objeto que los contiene.

Una transacción de Sui

En Sui, las transacciones se componen de un grupo de comandos que se ejecutan sobre entradas para definir el resultado de la transacción. Estos grupos de comandos se denominan bloques de transacciones programables (PTB) y definen todas las transacciones de usuarios en Sui. Los PTB permiten a un usuario llamar varias funciones de Move, administrar sus objetos y gestionar sus “monedas” en una sola transacción sin tener que publicar un nuevo paquete de Move.

La estructura de un PTB se define así:

Código
{
    inputs: [Input],
    commands: [Command],
}

inputs es un vector de argumentos que pueden ser objetos o valores puros. Estos objetos pueden pertenecer al remitente, ser compartidos o ser inmutables. El campo commands es un vector de instrucciones de transacción de alto nivel.

Durante la ejecución de los PTB, el vector de entrada se completa con los objetos de entrada o los bytes de valores puros. Luego, los comandos de la transacción se ejecutan en orden y los resultados se almacenan en un vector de resultados. Este es un arreglo de valores donde cada valor puede ser cualquier tipo arbitrario de Move específico de cada comando. A diferencia de las entradas, los valores no se limitan a objetos o valores puros. Por último, los efectos de la transacción se aplican atómicamente. 

No analizaremos los detalles internos de los PTB de Sui, pues es otro tema complejo. Sin embargo, debes tener en cuenta que, al comenzar la ejecución, el runtime del PTB toma los objetos de entrada ya cargados y los incorpora al arreglo de entrada. La red ya verificó los objetos mediante reglas como su existencia y la validez de su propiedad. Los bytes de valores puros también se cargan en el arreglo, pero no se validan hasta que se usan.

En esta etapa, los efectos sobre la moneda de gas son de suma importancia. Aquí se retira de la moneda el presupuesto máximo de gas. Por lo general, el remitente de la transacción especifica ese presupuesto al enviarla, y este representa la cantidad máxima de gas que puede consumir. El gas sin usar se devuelve a la moneda al terminar la ejecución, incluso si cambió de propietario. Después, cada comando de la transacción se ejecuta en orden.

Después del envío, el nodo completo certifica todos los metadatos proporcionados al enviar la transacción a un nodo validador, en la etapa de certificación. El nodo validador realiza todas las verificaciones de validez necesarias y, si se superan, firma la transacción para confirmar su validez. Para que un nodo validador considere válida una transacción, esta debe:

  • Tener una firma de usuario válida.
  • Garantizar que el iniciador de la transacción tenga acceso a todos los objetos de entrada de su propiedad que usa la transacción.
  • Garantizar que existan los objetos de entrada compartidos que usa la transacción.
  • Contener al menos la cantidad de gas especificada en el presupuesto de gas de la transacción.

Si se superan todas las verificaciones, el validador intenta bloquear todos los objetos inputs que tienen propietario para el “resumen de transacción” determinado. Así garantiza que cada entrada con propietario solo pueda usarse una vez a la vez.

Si el proceso de bloqueo se completa correctamente, el validador firma la transacción y devuelve la firma al nodo completo.

Un nodo completo de Sui es, en esencia, una vista de solo lectura del estado de la red. A diferencia de los nodos validadores, los nodos completos no pueden firmar transacciones, aunque sí pueden validar la integridad de la cadena al volver a ejecutar transacciones confirmadas previamente por un cuórum de validadores. El nodo completo no recopila una sola firma de validador, sino tantas firmas como sea posible en paralelo. Sin embargo, solo se necesita una supermayoría (⅔+ del stake) para formar un certificado de transacción.

Ejecución y checkpoints

Una vez que las transacciones reciben un certificado, se envían para su ejecución a un comité de validadores, es decir, un conjunto de validadores independientes establecido para cada época. El validador no necesita volver a verificar las transacciones: solo debe verificar las firmas del certificado. Si la firma del certificado es válida, el validador puede estar seguro de que la transacción es válida.

Durante la ejecución, las transacciones se dividen en dos categorías: transacciones de objetos con propietario y transacciones de objetos compartidos:

Transacciones de objetos con propietario

Las transacciones de objetos con propietario no acceden a ningún objeto de entrada compartido y se ejecutan de inmediato. También se conocen como transacciones de ruta rápida; es decir, se ejecutan después de la validación y se confirman en la cadena canónica. Estas transacciones no “pasan” por el consenso. Con el tiempo sí pasan por él, pero solo para generar un orden canónico que permita incluirlas en checkpoints. Esto es técnicamente posible porque no existe riesgo de escrituras en conflicto: solo el propietario puede modificar el objeto. 

Transacciones de objetos compartidos

Las transacciones de objetos compartidos acceden a objetos compartidos y, por lo tanto, deben ordenarse mediante consenso respecto de otras transacciones que usen y ejecuten los mismos objetos. También se conocen como transacciones de ruta lenta. Deben pasar por todo el proceso de consenso para garantizar la coherencia, ya que varios usuarios pueden acceder a los objetos involucrados y modificarlos. 

Anteriormente, Narwhal, el mempool de Sui, evitaba la congestión típica al separar la distribución y el orden de las transacciones. Mantenía las transacciones certificadas y firmadas en un grafo acíclico dirigido (DAG) sin ordenarlas por sí mismo. Bullshark proporcionaba después el orden de consenso.

Para mejorar aún más el rendimiento y la resiliencia, se presentó el protocolo HammerHead como una mejora de Bullshark que implementaba una selección dinámica de líderes basada en puntuaciones. Esto redujo significativamente la latencia y mejoró el rendimiento, especialmente cuando había líderes defectuosos o caídos.

A partir de estos avances, Mysticeti ahora sustituye tanto a Narwhal como a Bullshark y unifica la distribución y el orden de las transacciones en un solo protocolo. Mysticeti ordena las transacciones en una secuencia total, lo que agiliza aún más el proceso y logra menor latencia y mayor rendimiento. Además, debido al modelo de propiedad centrado en objetos de Sui, la mayoría de las transacciones siguen siendo independientes y no necesitan competir por un slot de orden global.

Después de ejecutar las transacciones, el validador firma sus efectos y los devuelve al nodo completo. Los efectos de una transacción son, en esencia, una lista de todas las acciones que realizó, como todos los objetos modificados, el gas consumido y el estado de ejecución de la transacción.

Las firmas de efectos constituyen una colección de certificados de efectos que el nodo completo obtiene de una supermayoría de validadores, lo que garantiza que una transacción se finalizó.

Cuando una transacción se incluye en un checkpoint, lo que indica la etapa final de su ciclo de vida, los cambios de estado resultantes ya se finalizaron y aplicaron a la red.

En las transacciones que solo incluyen objetos de entrada con propietario, los validadores las ejecutan y finalizan antes de enviarlas a la capa de consenso para ordenarlas.

En cambio, las transacciones que incluyen objetos de entrada compartidos se envían al consenso para ordenarlas antes de ejecutarlas y no vuelven a enviarse para su inclusión en checkpoints.

El validador recopila fragmentos completos de transacciones ordenados causalmente desde la capa de consenso y construye un checkpoint. Este contiene tanto la lista de resúmenes de transacciones como los resúmenes correspondientes de los efectos de cada transacción. Por ello, los checkpoints sirven como un registro inmutable de todas las transiciones de estado finalizadas en la red.

Finalidad

Una transacción de Sui alcanza la finalidad en cuanto una supermayoría (2𝑓 + 1) de validadores acepta y contrafirma un certificado de transacción, incluso antes de que el consenso ordene o ejecute el certificado. En ese momento, no puede producirse ninguna transacción en conflicto y la transacción no puede revocarse. En las transacciones que solo incluyen objetos con propietario, el resultado de la ejecución se conoce inmediatamente al alcanzar la finalidad. En las transacciones de objetos compartidos, el resultado solo se determina después de que el consenso ordena el certificado. La finalidad de la transacción se alcanza en dos recorridos de ida y vuelta por la red.

La liquidación ocurre cuando una supermayoría de validadores ejecuta la transacción y se forma un certificado de efectos. En las transacciones de objetos con propietario, esta ejecución sucede de inmediato, sin esperar el consenso. En las transacciones de objetos compartidos, la ejecución y la liquidación ocurren justo después de que el consenso ordena el certificado. En ambos casos, la creación del checkpoint no retrasa la liquidación, por lo que la latencia es menor que la del proceso de checkpoints.

Aunque un certificado de transacción es un fuerte indicador de finalidad, solo un certificado de efectos o la inclusión en un checkpoint certificado ofrece una garantía absoluta. Esto se debe a que requieren que una supermayoría de validadores ejecute la transacción y confirme sus efectos.

A grandes rasgos, el ciclo de vida de las transacciones de Sui aprovecha un modelo centrado en objetos para maximizar el paralelismo y la eficiencia. Cuando se envía una transacción para certificarla, los validadores intentan bloquear las versiones específicas de los objetos de entrada a los que hace referencia.

En los objetos con propietario, estos bloqueos se adquieren de inmediato durante la certificación, lo que garantiza acceso exclusivo y evita el doble gasto. En los objetos compartidos, los bloqueos solo se establecen después de que el protocolo de consenso de Sui ordena la transacción.

Una vez obtenidos todos los bloqueos necesarios, se programa la transacción para ejecutarla. Este diseño permite ejecutar de forma independiente y en paralelo las transacciones que operan sobre conjuntos separados de objetos, lo que reduce significativamente la contención y la congestión en partes no relacionadas del estado.

Después de una ejecución correcta, los validadores firman los efectos de la transacción. Cuando se recopila una supermayoría de firmas, se forma un certificado de efectos. Este certificado garantiza la finalidad de la liquidación e indica que la transacción ya es irreversible y sus efectos son permanentes.

Los checkpoints no forman parte de la ruta crítica de ejecución ni de finalidad de las transacciones. En su lugar, se construyen después de la ejecución para proporcionar un orden canónico de las transacciones y facilitar la sincronización del estado de los nodos que no participaron directamente en la ejecución.

El modelo de objetos de Sui permite rastrear con precisión las dependencias a nivel de objeto, lo que elimina la necesidad de sincronizar el estado global. Esta arquitectura admite una ejecución distribuida y escalable en hardware estándar, en lugar de depender de avances en el rendimiento del hardware para lograr un mayor rendimiento.

Hallazgos sobre ejecución, escalabilidad y compromisos de diseño

Como indicamos antes, comprender el ciclo de vida de una transacción puede ser la expresión más clara de la filosofía de diseño de una blockchain. Las diferencias entre los ciclos de vida de las transacciones de Solana y Sui revelan profundas filosofías sobre el modelo de ejecución en tres dimensiones esenciales: eficiencia de ejecución, límites de escalabilidad y compromisos de diseño.

Ejecución

Como cadena centrada en cuentas, Solana detecta dinámicamente los conflictos entre cuentas mediante el bloqueo de cuentas durante la Banking Stage. Así garantiza que las transacciones que no modifican la misma cuenta se procesen en paralelo, mientras que las transacciones en conflicto se procesen secuencialmente.

Aunque este tipo de mecanismo de detección de cuentas puede generar costos adicionales del runtime en situaciones de alta actividad DeFi, especialmente cuando los programas necesitan ejecutar lógica de otros programas mediante un mecanismo llamado Cross-Program Invocation, el motor de ejecución de Solana sigue logrando un paralelismo masivo gracias a su detección dinámica de conflictos. Esto permite que la cadena ejecute transacciones casi al instante y con tarifas increíblemente bajas.

Por otro lado, Sui no necesita preocuparse por las transacciones en conflicto, pues el paralelismo se deduce durante la compilación gracias a su modelo de propiedad centrado en objetos. El modelo de objetos compartidos y con propietario permite deducir los conflictos de forma estática y lograr un costo del runtime cercano a cero para las transacciones de objetos con propietario.

Límites de escalabilidad

En términos de escalabilidad, Sui logra escalabilidad horizontal y puede escalar linealmente con las particiones de objetos al procesar transacciones de objetos con propietario sin consenso global. Esto permite una finalidad casi instantánea, inferior a un segundo, y un rendimiento limitado únicamente por el hardware disponible. Las transacciones de objetos compartidos requieren consenso, pero con la actualización Mysticeti ahora también logran finalidad en menos de un segundo y un alto rendimiento. La arquitectura de Sui permite que tanto la distribución como la ejecución de bloques escalen de forma elástica al agregar más recursos. Esto permite que el sistema gestione eficientemente cargas de trabajo mayores, aunque la ruta de consenso no es tan ilimitada como la ruta rápida de los objetos con propietario.

Solana, por su enfoque de líder único y su distribución de la ejecución limitada por la contención entre cuentas, parece alcanzar cierto límite de escalabilidad horizontal debido al modelo de estado global con un solo shard y la incorporación de transacciones por slot centrada en el líder. Sin embargo, se optimiza agresivamente dentro de este límite mediante su procesamiento segmentado bien definido, complementado por PoH. Las transacciones pueden ordenarse con precisión, procesarse en menos de 400 ms y lograr confirmación optimista en menos de un segundo. En términos de escalabilidad vertical, Solana escala enormemente con el hardware de los validadores, especialmente los núcleos de CPU y la RAM, pues esto se ajusta perfectamente a su diseño inherente.

Es importante aclarar que Solana elige la escalabilidad vertical por encima de la horizontal y alcanza un límite debido a compromisos de diseño, no a una falla arquitectónica. Actualmente se desarrollan algunos enfoques horizontales, como mercados de tarifas locales, subredes virtuales y minimización del estado mediante CMT.

Compromisos de diseño

Solana garantiza el determinismo mediante restricciones estrictas del runtime, aislamiento de cuentas y programación determinista de líderes. Su resolución dinámica de la contención entre cuentas y su procesamiento segmentado bien definido favorecen una interacción profunda entre programas, lo que permite una gran componibilidad.

Sui ofrece garantías de determinismo mediante rutas de ejecución integradas que determina el análisis de la propiedad de los objetos. Al mismo tiempo, su modelo centrado en objetos permite la componibilidad mediante objetos compartidos y bloques de transacciones programables (PTB), lo que permite interacciones complejas y operaciones atómicas entre varios contratos y usuarios. Esto es posible porque el propietario de un objeto puede ser otro objeto, lo que permite la interoperabilidad a nivel de objeto y la organización de objetos en árboles de propiedad. Estas estructuras son especialmente útiles cuando los objetos se usan juntos con frecuencia o cuando se necesitan búsquedas en el runtime para determinar sobre qué objeto operar durante la ejecución.

Resumen

El mecanismo que procesa las transacciones desde su envío hasta la finalidad sustenta el increíble rendimiento de Solana y Sui. Al examinar el ciclo de vida de las transacciones, podemos comprender los pipelines cuidadosamente diseñados que garantizan una latencia baja y un alto rendimiento en ambas cadenas.

Solana se diseñó con un modelo centrado en cuentas, y las transacciones pasan por una serie de procesos y pipelines multihilo para garantizar su validez. Las transacciones se envían al líder, que ejecuta el pipeline de la TPU para verificar y programar las transacciones según corresponda: en paralelo si no entran en conflicto y secuencialmente si lo hacen. Cuando un validador no produce bloques, ejecuta el pipeline de la TVU para replicar y validar transacciones. Tanto la TPU como la TVU usan el runtime. Como resultado, Solana procesa miles de transacciones en periodos muy breves porque el runtime puede identificar por adelantado y de forma determinista las cuentas que no se superponen y ejecutar en paralelo las transacciones sin conflictos. Esto hace que Solana sea ideal para casos reales como trading de alta frecuencia, DeFi con una gran componibilidad, dApps que requieren mucha infraestructura y dApps de consumo con baja latencia.

Por otro lado, Sui usa un modelo centrado en objetos donde un identificador único rastrea cada objeto. Al deducir la propiedad de los objetos, puede determinar estáticamente si una transacción puede ejecutarse en paralelo cuando afecta conjuntos separados de objetos. Gracias a su modelo de doble ruta de ejecución, que separa las transacciones en transacciones de objetos con propietario y transacciones de objetos compartidos, y usa checkpoints firmados para mantener sincronizados los nodos completos, puede procesar transacciones ligeras sin sobrecargar la capa de consenso. Al mismo tiempo, logra una finalidad rápida y confiable, además de una sincronización eficiente para los nodos nuevos. Esto le permite escalar horizontalmente al aumentar la carga y resulta muy útil para aplicaciones con interacciones masivas entre objetos, como DeFi, videojuegos, exchanges centrados en activos y activos programables.

Referencias

Suscríbete a Helius

Mantente al día con las novedades del desarrollo en Solana y recibe actualizaciones cuando publiquemos

Imagen ampliada