paint-brush
Desembalaje de la actualización Starknet Boltpor@2077research
Nueva Historia

Desembalaje de la actualización Starknet Bolt

por 2077 Research17m2024/12/26
Read on Terminal Reader

Demasiado Largo; Para Leer

La actualización de Starknet Bolt introdujo dos características principales: ejecución paralela y rendimiento de bloques. Este artículo analiza cómo estas características recién introducidas mejoran el rendimiento de Starknet y la experiencia de transacción para los usuarios de la capa 2 (L2).
featured image - Desembalaje de la actualización Starknet Bolt
2077 Research HackerNoon profile picture


La última actualización de Starknet (v0.13.2) llamada Bolt trae dos cambios importantes: ejecución paralela y empaquetamiento de bloques . Aunque son independientes entre sí, ambas características respaldan el avance hacia el objetivo de un espacio de bloques rápido, barato y protegido criptográficamente por Ethereum.


La ejecución paralela permite que transacciones no conflictivas (es decir, transacciones que no tocan el mismo estado) se ejecuten simultáneamente. Al implementar la ejecución paralela, las capas 2 como Starknet pueden reducir el tiempo de ejecución sin aumentar el uso de recursos. Esto significa tarifas de transacción más bajas para los usuarios y tiempos de confirmación de transacciones significativamente mejorados.


El empaquetamiento de bloques optimiza el uso del espacio de blobs de Starknet en Ethereum L1: con el empaquetamiento de bloques, los secuenciadores pueden generar una prueba para verificar varios bloques L2 de Starknet simultáneamente. Esto desvincula el uso del espacio de blobs de la frecuencia de producción de bloques L2 y amortiza los costos de verificación de pruebas. Ambos reducen los costos operativos del secuenciador de Starknet, lo que significa que los usuarios pagan menos por transacción.


Como dijimos, Bolt hace que Starknet sea más barata y rápida. Este informe proporcionará un análisis detallado de la actualización de Bolt (centrándose en la ejecución paralela y el empaquetamiento de bloques) y explorará las implicaciones para el rendimiento de Starknet.

Un rápido repaso de los rollups

Los rollups son soluciones de escalado de capa dos (L2) que apuntan a escalar la cadena de bloques subyacente de capa uno (L1) moviendo la computación fuera de la cadena. Al mover la ejecución fuera de la cadena, los rollups pueden optimizar la escalabilidad (transacciones baratas y rápidas), mientras que la capa 1 brinda seguridad para las transacciones de capa 2.


A menudo se dice que los rollups “heredan la seguridad de la capa 1”. Esto significa, en esencia, que heredan las garantías de consenso y disponibilidad de datos que ofrece la capa 1. Además, la capa 1 también ofrece una garantía de seguridad en forma de puente seguro entre ella y el rollup.


Cuando los secuenciadores publican bloques L2 en L1, L1 ofrece garantías de la disponibilidad y el orden de esta información. A partir de aquí, los nodos L2 pueden calcular sin confianza la cadena L2 canónica con esta información junto con las reglas de la acumulación en torno a la derivación de la cadena y la transición de estado descritas por la implementación del nodo.


Para facilitar la conexión segura entre la L1 y la L2, la L1 requiere una prueba de que la cadena L2 que sigue actualmente es correcta y no incluye cambios de estado ilegales (por ejemplo, doble gasto). Esta necesidad de que los rollups demuestren la validez de los cambios de estado garantiza que la L1 no autorice retiros del rollup en función de un estado ilegal.


Los rollups difieren según cómo prueban la validez de los cambios de estado en la L1:

  • Los rollups de validez se basan en pruebas de validez para verificar objetivamente la corrección de la ejecución. Los proponentes pueden proponer un nuevo estado de rollup si envían una prueba de validez al contrato de rollup.
  • Los rollups optimistas se basan en la ausencia de pruebas de fraude para verificar subjetivamente la corrección de la ejecución. Los proponentes envían actualizaciones de estado sin pruebas, pero el contrato de rollup puede revertir cualquier actualización de estado cuya validez sea impugnada con éxito mediante una prueba de fraude.


Los rollups también proporcionan a la capa base datos suficientes para que las partes interesadas reconstruyan el estado de L2. Mientras que los rollups optimistas deben publicar datos completos de transacciones para permitir que los retadores calculen pruebas de fraude, los rollups de validez no tienen tales requisitos (las pruebas de validez garantizan la ejecución correcta). Pero publicar datos completos de transacciones en L1 sigue siendo útil desde una perspectiva de minimización de la confianza (reconstrucción del estado sin confianza y retiros sin permiso).


Starknet es un conjunto de validación que utiliza argumentos de conocimiento transparentes y escalables (STARK) para demostrar la validez de los cambios de estado. La última actualización de Starknet (con nombre en código Bolt) agrega ejecución paralela y empaquetamiento de bloques. En las secciones siguientes, explicaremos cómo funcionan las dos funciones y qué mejoras aportan a los usuarios de Starknet.

¿Qué cambió la mejora Starknet Bolt?

A un alto nivel, la actualización de Bolt cambió los mecanismos de ejecución, prueba y disponibilidad de datos de Starknet.

Optimización de la ejecución

Antes de la actualización de Bolt, las transacciones de Starknet se ejecutaban secuencialmente (una tras otra) mediante el secuenciador. La ejecución secuencial es sencilla, pero también muy ineficiente. Es ineficiente porque no aprovecha las múltiples unidades de procesamiento independientes que ofrecen las computadoras modernas y la posibilidad de paralelizar un conjunto de transacciones.


Ejecución secuencial


Ejecución paralela

La paralelización es una medida de cuán independientes son las transacciones en un conjunto determinado. Por ejemplo, considere el siguiente conjunto de tres transacciones:

  • Transacción 1: Alice quiere enviarle a Bob 1 STRK

  • Transacción 2: Caitlyn quiere enviarle a Danny 100 ETH

  • Transacción 3: Caitlyn quiere enviarle a Ella 100 ETH


La transacción 1 es completamente independiente de las transacciones 2 y 3 (porque accede a una parte diferente del estado, el saldo de Alice) y se puede ejecutar simultáneamente. Sin embargo, las transacciones 2 y 3 están en conflicto porque quieren acceder al mismo estado (el saldo de ETH de Caitlyn). Estas transacciones no se pueden ejecutar simultáneamente o terminaremos con resultados conflictivos.


Para ilustrarlo:

  • Digamos que el saldo de Caitlyn es de 300 ETH y las transacciones 2 y 3 comienzan al mismo tiempo. Ambas transacciones leerán el saldo inicial de la cuenta de Caitlyn como 300 ETH, deducirán el monto de la transferencia de este (300 - 100 = 200) y escribirán 200 ETH en la ubicación de la memoria donde se almacena el saldo de la cuenta de Caitlyn.
  • Las transacciones 2 y 3 leerán los saldos de Danny y Ella respectivamente y sumarán 100 ETH a los saldos de ambos usuarios. El saldo de Caitlyn se reduciría en 100 ETH, pero se acreditarían 200 ETH, lo que en realidad generaría 100 ETH de la nada.


Para evitar este tipo de conflictos (y la naturaleza compleja de los mecanismos de mitigación), Ethereum eligió la ejecución secuencial. Sin embargo, si bien la ejecución secuencial reduce la complejidad y mejora la seguridad, da como resultado un uso ineficiente del hardware. Peor aún, la tendencia del diseño de hardware sugiere que la ejecución secuencial se volverá cada vez más ineficiente en los próximos años.


La figura 4 muestra la tendencia del diseño de hardware en los últimos 50 años. ¿Cuál es la conclusión relevante? El rendimiento de un solo subproceso (círculos violeta) se ha estancado desde mediados de la década de 2000, mientras que la cantidad de núcleos lógicos ha aumentado aproximadamente al mismo tiempo. Podemos sacar dos conclusiones en función de estos datos:

  • Los diseñadores de hardware están escalando los chips de computadora agregando más unidades de procesamiento independientes en lugar de mejorar el rendimiento de una sola unidad.

  • Cualquier sistema que continúe dependiendo del aumento del rendimiento de una sola unidad de procesamiento experimentará un estancamiento en las ganancias de rendimiento incluso en hardware más nuevo.


Figura 4: Tendencias de los microprocesadores


En los últimos años han aparecido algoritmos sofisticados para gestionar los conflictos de transacciones y garantizar la corrección de la ejecución paralela. Block-STM (basado en un artículo de Fikunmi et al*) es uno de esos algoritmos y forma la parte central del nuevo motor de ejecución paralela de Starknet. Analizaremos el algoritmo Block-STM en secciones posteriores.

Optimización de las pruebas y la disponibilidad de datos

SHARP (abreviatura de Shared Prover) de Starknet siempre ha aprovechado las pruebas recursivas para reducir los costos de verificación tanto como sea posible. Una prueba recursiva es esencialmente una "prueba de prueba" en la que una prueba verifica que una o más pruebas son correctas. A continuación se muestra un esquema de cómo SHARP genera una prueba recursiva:

  • El sistema SHARP toma como entrada un conjunto de programas que se van a ejecutar (un “trabajo”) y genera una prueba de ejecución del trabajo. Estos “programas” son bloques L2 y la prueba da fe de la corrección de las transacciones.

  • La prueba se envía a otro programa que la verifica y convierte el programa de verificación de pruebas en un trabajo. SHARP toma el nuevo trabajo como entrada y genera otra prueba (esta prueba confirma la validez de la prueba anterior).

  • El proceso (prueba → trabajo → prueba) se reinicia y continúa hasta que se alcanza un objetivo, momento en el que la prueba final (que ahora es una versión altamente comprimida de la prueba original) se envía a L1.


Figura 5: Generación de pruebas recursivas


Este diseño amortiza en gran medida los costos por dos razones principales:

  • Los trabajos subsiguientes* no son programas o transacciones individuales y los costos de prueba crecen de manera sublineal. Esto significa que cuanto mayor sea el número de programas o transacciones dentro de un trabajo, mayor será el ahorro. Al crear pruebas por bloque en lugar de por transacción, las tarifas de transacción pueden ser mucho más económicas.
  • La recursión comprime en gran medida las pruebas, lo que da como resultado una “prueba de prueba” que es significativamente más barata de verificar en la L1 que la prueba inicial o cualquiera de las pruebas intermedias.


Si bien el sistema de pruebas era bueno, se desaprovecharon oportunidades de ahorrar costos. Por ejemplo, cada trabajo consistía en un solo bloque de Starknet y cada uno de estos bloques estaba diseñado para ocupar una gota en la L1. Esto generó ciertas ineficiencias, como se describe a continuación:

  • Antes de Bolt, Starknet no tenía (y aún no tiene) tiempos de bloque regulares; en su lugar, un bloque L2 se publicaba en L1 bajo dos condiciones: (1) Se ejecutaba el valor de un blob de datos (2) Habían transcurrido seis minutos desde el bloque anterior. Desafortunadamente, debido a la demanda, la mayoría de los bloques se enviaban a L1 debido al límite de seis minutos (no a los límites de DA).
  • Lo anterior significaba que los blobs (no los bloques) a menudo se subutilizaban (de forma grave), lo que generaba costos de gas innecesariamente altos. Los bloques de Starknet también tenían un costo fijo , que teóricamente se podía reducir aplicando las mismas técnicas de recursión que se analizaron anteriormente para producir pruebas de múltiples bloques.


El empaquetamiento de bloques resuelve estos problemas mediante el uso de un árbol binario de pruebas recursivas. Analizaremos el empaquetamiento de bloques en una sección posterior del artículo.

Bolt Parte 1: Ejecución paralela

Como se mencionó anteriormente, la ejecución secuencial es ineficiente (y lo será aún más a medida que pase el tiempo) y la ejecución paralela ingenua produce resultados no válidos. Sin embargo, los motores de ejecución paralela de producción se encargan de evitar resultados inconsistentes.


Existen dos enfoques para abordar la ejecución paralela: el control de concurrencia pesimista (PCC) y el control de concurrencia optimista (OCC) . El PCC y el OCC son unidades de procesamiento de transacciones (TPU). A continuación, se incluye una definición de unidad de procesamiento de transacciones de Block-STM frente a SVM: una comparación de motores de ejecución paralela:


La TPU suele estar acoplada a la máquina virtual (VM), pero es distinta de ella. Las VM de blockchain como EVM, SVM y MoveVM son VM de lenguaje de alto nivel... La TPU, que suele ser el tema de interés, subsume a la VM. Se encarga de la gestión de todo el proceso de ejecución de transacciones, incluida la creación y gestión de instancias de la VM.


El control de concurrencia pesimista está diseñado a partir del supuesto de que muchas de las transacciones dentro del conjunto de transacciones a ejecutar entrarán en conflicto, es decir, tocarán el mismo estado. El PCC evita estos conflictos.


Para evitar conflictos, PCC requiere que una transacción declare por adelantado a qué partes del estado accederá durante las operaciones de lectura/escritura. La unidad de procesamiento de transacciones puede usar esta información para programar transacciones de manera que se asegure que las transacciones conflictivas se ejecuten de manera secuencial (en lugar de hacerlo de manera simultánea). Algunas TPU también usan bloqueos para hacer cumplir este comportamiento (un bloqueo (también conocido como mutex) es un mecanismo que se usa para evitar el acceso simultáneo a una ubicación de memoria).


Dicho esto, la ejecución basada en PCC implica ciertas desventajas. En primer lugar, el requisito de proporcionar listas de acceso (que identifican la ranura de memoria que toca una transacción) degrada la experiencia del desarrollador y reduce la variedad de posibles aplicaciones. En segundo lugar, la programación de transacciones puede generar una sobrecarga innecesaria, especialmente cuando no hay conflictos.


El control de concurrencia optimista está diseñado con la suposición de que muchas de las transacciones dentro del conjunto dado no entrarán en conflicto, es decir, no escribirán en el mismo estado. Como tal, las TPU OCC ejecutan el conjunto de transacciones con todos los recursos disponibles y solo intentan detectar conflictos. Si se detecta un conflicto, las transacciones que entran en conflicto se ejecutan y se vuelven a verificar hasta que todo el conjunto pase y pueda confirmarse.


Las TPU de OCC no incurren en gastos generales por la programación, por lo que tienden a funcionar mejor cuando hay pocos conflictos. Las unidades de procesamiento de transacciones basadas en OCC también ofrecen una mejor experiencia para los desarrolladores y una gama más amplia de casos de uso porque no es necesario conocer las dependencias de estado de antemano.


Sin embargo, cuando el conjunto de transacciones es muy contencioso, la OCC tiene un peor desempeño que la PCC. Analizamos los diseños de TPU (con mucho más detalle) y comparamos los enfoques de OCC y PCC en nuestro artículo sobre ejecución paralela.


La nueva TPU de Starknet utiliza el enfoque OCC. Más específicamente, es una implementación del algoritmo Block-STM. Block-STM ejecuta transacciones de manera optimista con todos los recursos disponibles asumiendo que ninguno de ellos entrará en conflicto y verifica después de la ejecución que no se ejecuten transacciones conflictivas simultáneamente. Antes de profundizar en la nueva arquitectura de Starknet, es importante repasar algunas definiciones clave:

  1. Estado : el estado es la condición de un objeto en una instancia en el tiempo. En el contexto de la cadena de bloques, generalmente se refiere al valor de una porción de la memoria, por ejemplo, el saldo de una dirección es (parte de) su estado.
  2. Serializabilidad : se dice que la ejecución paralela ha conservado la propiedad de serializabilidad si la ejecución de un conjunto de transacciones en serie y simultáneamente produce los mismos resultados.
  3. Conflicto : se dice que dos transacciones entran en conflicto si, y solo si, al menos una de ellas desea escribir en una parte del estado a la que ambas desean acceder (puede ser de lectura o escritura). Si ambas transacciones solo leen una parte del estado, entonces no hay conflicto, pero si al menos una de ellas escribe en esa parte del estado, entonces las transacciones no se pueden ejecutar simultáneamente sin interrumpir la serialización. Hemos cubierto un caso de muestra anteriormente en el ejemplo de Caitlyn, Danny y Ella.
  4. Dependencia : Se dice que una transacción txj depende de (o es una dependencia de) una transacción txi si y solo si ambas transacciones escriben en la misma ubicación de memoria y txj viene después de txi en el orden serial. Si txi viniera después de txj , txi dependería de txj .
  5. Estructura de datos de múltiples versiones : una estructura de datos de múltiples versiones es aquella en la que se crea una nueva versión de la estructura de datos para cada escritura en la estructura de datos. En lugar de cambiar el valor existente, se crea una nueva versión específica de escritura de la ubicación que se va a cambiar. El valor de las estructuras de datos de múltiples versiones es que permiten lecturas y escrituras altamente concurrentes desde y hacia la misma región de la memoria. Más adelante exploraremos cómo esto resulta útil.

Con las definiciones fuera del camino, podemos pasar a cubrir cómo funciona Block-STM.

Cómo funciona Block-STM

La entrada a Block-STM es una cola (una lista ordenada) de transacciones, a esta lista a menudo se la llama BLOQUE. Esta lista se puede ordenar de cualquier manera; el único requisito es que exista un orden claramente definido. Por lo tanto, dado un conjunto de transacciones T que contiene transacciones {t0…tn} , las transacciones se ordenan de manera que {t0 > t1 > t2 … > tn} (léase: t0 tiene mayor prioridad que t1 , t1 tiene mayor prioridad que t2 etc.)


Al comienzo del proceso de ejecución, se crean dos conjuntos: un conjunto de ejecución E y un conjunto de validación V. E rastrea las transacciones que aún no se han ejecutado, mientras que V rastrea las transacciones que se han ejecutado pero aún no se han validado. Cada transacción también está asociada con un número de encarnación n para rastrear cuántas veces se ha ejecutado (y vuelto a ejecutar). El estado inicial de los conjuntos es que E contiene todas las transacciones y V está vacío, es decir, E = {t0,1 > t1,1 > t2,1 > … > tn,1} y V = {} .


Con estos conjuntos ordenados de transacciones, cada hilo utilizado para la ejecución recorre un bucle de tres etapas:

  1. Verificación realizada
  2. Buscar la siguiente tarea
  3. Realizar tarea

Verificación realizada

Durante este paso, el hilo verifica tanto V como E. Si ambos están vacíos y no se está ejecutando ninguna transacción, entonces el lote actual de transacciones se ha ejecutado completamente y los resultados se pueden confirmar en el almacenamiento.

Buscar siguiente tarea

Si V o E contienen transacciones, Block-STM selecciona la transacción con el índice más bajo (no el número de encarnación) de ambos conjuntos de transacciones, es decir, si E contiene {t1,3 , t3,1 and t5,2} y V contiene {t0,1, t2,4, t4,3} , la tarea de validación para la transacción t0 se seleccionaría como la siguiente tarea.

Realizar tarea

Una vez identificada y seleccionada la siguiente tarea, se ejecuta. Al final de este paso, el algoritmo vuelve a la etapa de verificación realizada. Este proceso continúa hasta que ambos conjuntos de transacciones estén vacíos.


Veamos qué sucede durante la ejecución y la validación:


Durante la ejecución de una transacción, el algoritmo Block-STM llena dos conjuntos (por transacción); un conjunto de lectura ( Ri,n ) y un conjunto de escritura ( Wn,i ). El conjunto de lectura contiene todas las ubicaciones de memoria desde las que una transacción leyó durante su ejecución, mientras que el conjunto de escritura contiene todas las ubicaciones de memoria en las que escribió. Durante la ejecución, las transacciones aplican sus escrituras a la estructura de datos de múltiples versiones, pero la lectura es un poco matizada.


En Block-STM, cuando una transacción desea leer de la estructura de datos, busca el valor escrito por la transacción de menor prioridad que tiene mayor prioridad. Por ejemplo, si tx1 , tx2 y tx7 han escrito en una ubicación de memoria y tx5 desea leer desde esta ubicación, lee la versión de la estructura de datos correspondiente a tx2 .


Esto se hace para reforzar la serialización; dado que tx5 se debe ejecutar después de tx2 y antes de tx7 , debe utilizar los valores escritos por tx2 y no tx7 . En este ejemplo, tx7 tendrá que volver a ejecutarse porque debería haber leído los valores escritos por tx5 , no tx2 ni ninguna transacción de mayor prioridad. Si se utilizó una estructura de datos de una sola versión, el valor escrito por tx2 no estaría disponible y seguramente se produciría un conflicto.


Para una tarea de validación, el conjunto de lectura de la transacción se compara con los valores actuales en las ubicaciones de memoria de las que leyó durante la ejecución. Por ejemplo, si tx2 lee la cuenta B durante la ejecución, durante la validación, se lee la ubicación de memoria de la cuenta B (teniendo en cuenta la definición de lectura que establecimos anteriormente). Si los dos valores son iguales, significa que ninguna transacción de mayor prioridad (por ejemplo, tx0 o tx1 ) ha escrito en esa ubicación durante la ejecución de tx2 . Esto da como resultado que tx2 se marque como validado, pero no sea seguro confirmarlo.


No se considera seguro confirmar la transacción porque, por diversos motivos, se podría ejecutar una transacción de menor prioridad después de que se haya validado la transacción. En nuestro ejemplo en ejecución, si tx1 toca la cuenta B y solo la toca después de que tx2 pase la validación, entonces tx2 debe volver a ejecutarse.


Para prever esto, cada vez que una transacción completa su ejecución, todas las transacciones de menor prioridad que habían pasado la validación se vuelven a validar para garantizar que no entren en conflicto con la transacción. Por ejemplo, si tx1 , tx3 y tx4 se han validado y tx2 completa su ejecución, tx3 y tx4 deben volver a validarse para garantizar que no entren en conflicto con tx2 (y que, por lo tanto, no sean dependencias de esta).


Si una transacción falla la validación, es decir, una transacción de mayor prioridad que escribe en el mismo estado se ejecutó simultáneamente con ella, entonces las escrituras que realizó la transacción son sucias (porque los valores son incorrectos). Pero en lugar de eliminar estos valores de la base de datos por completo, se marcan como ESTIMATE.


La bandera ESTIMATE le indica a cualquier transacción que lea esa ubicación de memoria que los valores allí no son correctos y las transacciones pausan su ejecución. Esto se hace en lugar de eliminar, ya que la reejecución de la transacción que no pasó la validación probablemente resultaría en la escritura en las mismas ubicaciones de memoria que la ejecución anterior.


Al marcar la ubicación de la memoria como una estimación en lugar de eliminarla, se pueden detectar las dependencias (de la transacción que no superó la validación) incluso antes de volver a ejecutarla, lo que evita ejecuciones innecesarias. Esta heurística reduce en gran medida el trabajo desperdiciado.

Poniéndolo todo junto

Una descripción completa de cómo Block-STM aborda la paralelización se puede resumir de la siguiente manera:

  • Un BLOCK de transacciones comienza como una lista ordenada con un orden de secuencia claramente definido. Estas transacciones se ejecutan en todos los recursos disponibles en orden de prioridad.
  • Durante la ejecución, se realiza un seguimiento de los conjuntos de lectura y escritura de las transacciones y se realizan lecturas y escrituras desde/hacia una estructura de datos con múltiples versiones. Cuando una transacción termina de ejecutarse, se la valida para garantizar que no se haya ejecutado simultáneamente con ninguna transacción conflictiva.
  • Si una transacción pasa la validación, se elimina de E y V. Y cuando se valida una transacción, todas las transacciones con menor prioridad que habían pasado la validación se reprograman para su validación.
  • Si una transacción no supera la validación, se reprograma para su ejecución. Cuando se ha ejecutado y validado todo el conjunto de transacciones, es seguro confirmar todo el BLOQUE y los resultados se pueden escribir en un almacenamiento permanente.


A continuación se muestra un ejemplo:


Figura 6: Ejemplo de Block-STM


Esta es una descripción general de cómo funciona Block-STM; puede encontrar más detalles en nuestro informe aquí y en el documento original de Block-STM aquí .

¿Cómo mejora Block-STM el rendimiento de Starknet?

Para cuantificar la importancia de agregar Block-STM, realizamos algunos puntos de referencia para evaluar las mejoras de rendimiento que proporciona en comparación con la ejecución secuencial y los resultados se muestran a continuación.


Figura 7: Rendimiento de Block-STM con un tamaño de bloque de 1k


Figura 8: Rendimiento de Block-STM con un tamaño de bloque de 10k


Los resultados muestran que a medida que aumenta el número de subprocesos (análogos a las unidades de procesamiento independientes) utilizados, también aumenta el rendimiento. Las mejoras son más pronunciadas con bloques más grandes, lo que da como resultado mejoras de rendimiento de hasta 9 veces en comparación con la ejecución secuencial con solo 16 subprocesos. Descubrimos que los resultados son más pronunciados con bloques más grandes.


Nuestras pruebas muestran que el rendimiento de Block-STM se degrada significativamente bajo cargas muy conflictivas, pero la práctica estándar de la industria es volver a la ejecución secuencial durante esos períodos. Recomendamos la misma mecánica a Starknet para preservar el rendimiento bajo cargas de trabajo muy conflictivas. Pero, en general, la incorporación de Block-STM mejorará significativamente y garantizará el futuro de Starknet.


El segundo cambio importante incluido en la actualización v0.13.2 es el empaquetado de bloques y lo abordaremos a continuación.

Parte 2 del perno: empaquetadura del bloque

Como se mencionó anteriormente, antes de Bolt, cada bloque de Starknet era su propio trabajo, lo que daba como resultado un costo fijo por bloque. Además, el sistema estaba diseñado de tal manera que cada bloque requería su propio blob independientemente de la cantidad de datos que consumiera realmente el bloque.


En un mundo en el que siempre hubiera una gran demanda, esto no sería un problema, pero Starknet actualmente ofrece más espacio de bloques del que hay demanda y, por lo tanto, hay una gran cantidad de recursos desperdiciados que podrían resultar en la pérdida de cientos de ETH en el transcurso de un mes. Para poner en contexto aún más la gravedad de la situación antes de Bolt, estos son los costos asociados con la publicación de un bloque en L1:


  1. 23K de gas por registro de hechos: parte de Verificar prueba y registrar
  2. Página de memoria SHARP de 56K de gas por registro
  3. 136K de gas por estado
  4. 50K de gas para que la precompilación de KZG muestree un blob,
  5. 86K de gas para ejecutar la función de actualización de estado.


Esto suma un total de 215 000 de gas por bloque y este costo es fijo, es decir, es el mismo independientemente de la cantidad de datos que contenga cada bloque y está relacionado con la cantidad de bloques mediante $Costo = num blocks * 215 000$. La solución ideal para este problema sería que los costos estuvieran relacionados con la cantidad de datos publicados en lugar de la cantidad de bloques. Y eso es exactamente lo que se logra con el empaquetamiento de bloques a través de árboles SNAR.

SNAR intenta

Los árboles recursivos aplicativos Starknet (SNAR) son un nuevo tipo de árbol binario introducido en Bolt para abordar los problemas destacados anteriormente. Un árbol SNAR tiene la siguiente estructura: cada hoja es un bloque Starknet y los nodos en todos los demás niveles son pruebas recursivas de sus hijos. El nodo raíz, que es una prueba recursiva de todas las demás pruebas, es el trabajo final que se envía al SHARed Prover (SHARP).


Figura 9: Árbol SNAR


Figura 10: Árbol SNAR en el flujo de trabajo de empaquetado de bloques

¿Qué hace el árbol SNAR?

El principal beneficio del árbol SNAR es que en lugar de publicar un bloque por prueba, se pueden amortizar muchos bloques de Starknet en la misma actualización L1. Las raíces del árbol SNAR ahora se publican en L1 solo cuando se alcanza uno de los dos límites configurables: el límite de DA (6 blobs de datos) o después de que se agregue una cierta cantidad de hojas al árbol (donde una hoja es un bloque).


Este diseño desvincula el costo de las transacciones de la cantidad de bloques. Ahora bien, todavía existe un costo fijo por cada bloque que surge de ejecutar el sistema operativo StarkNet (SNOS) en cada bloque, pero en general los costos están desvinculados. Estos son los números actuales:


  1. Registro de memoria SHARP por trabajo: 23K de gas (igual que antes)
  2. Página de memoria SHARP por trabajo: 36 000 páginas de gas (reducidas de 56 000 gracias a la optimización de SHARP),
  3. Actualización de estado por trabajo igual a:
  4. 86K gas (igual que antes) +
  5. 50K gas × número de blob utilizado. (Cuando se utilizó un blob por bloque, esto fue 50K x 1, lo que dio como resultado el número de gas 136K citado anteriormente).


El gráfico de la Figura 11 a continuación muestra cómo varían los costos del gas según el número de bloque en el diseño anterior y ahora (bajo Bolt):


Figura 11: Costos de verificación con y sin empaquetamiento de bloques


Es bastante obvio que el empaquetamiento de bloques reduce en gran medida los costos de verificación en la L1, lo que sin duda resultará en precios de gas más bajos para los usuarios de Starknet.

Conclusión

El efecto de los cambios realizados en Bolt: ejecución paralela optimista a través de Block-STM y empaquetamiento de bloques a través del SNAR propietario se puede resumir como: más rápido y más barato.


La ejecución paralela reduce el tiempo de ejecución y, por extensión, la congestión, lo que reducirá las tarifas de gas durante períodos de alto tráfico, mientras que los árboles SNAR abordan los costos asociados de DA y de prueba. Curiosamente, esta actualización convierte a Starknet en la primera L2 con ejecución paralela y la prepara para ser un contendiente importante en el espacio L2. Es importante señalar que es poco probable que el efecto de estos cambios sea evidente de inmediato, especialmente el de la ejecución paralela, pero son cruciales para proteger a Starknet y a todo el ecosistema Ethereum en su conjunto para el futuro.


Nota del autor: Una versión de este artículo fue publicada previamente aquí .