Traducción de artículo oficial de Starkware (Builtins and Dynamic Layouts)
Resumen: Los Builtins optimizan el proceso de demostración. Sin embargo, cada demostración se calcula con respecto a un diseño (layout), y los diseños ineficientes para un trabajo de demostración en particular disminuyen los beneficios de los builtins. Actualmente, hay una pequeña lista estática de diseños, y cada demostración se calcula con respecto al diseño más adecuado de esa lista. El enfoque estático tiene dos principales inconvenientes. Primero, la limitada variedad de diseños es ineficiente para la mayoría de los trabajos de demostración, lo que genera costos innecesarios a los usuarios a través de un mecanismo de tarifas complicado. Segundo, el mantenimiento manual de la lista para adaptarse a nuevos builtins se vuelve mucho más difícil para un gran conjunto de builtins, dificultando prácticamente el proceso de demostración para admitir muchos builtins con cierto grado de eficiencia. Para resolver estos problemas, estamos trabajando en un sistema de Diseños Dinámicos (Dynamic Layout) en el que cada trabajo de demostración tiene un diseño adaptado a medida.
El stack de Cairo facilita la computación general demostrable mediante la compilación de código Cairo en instrucciones para una arquitectura de CPU compatible con STARK: la Máquina Virtual Cairo (en adelante, CVM). Las muchas ventajas de una CPU de propósito general conllevan un costo inherente: el CVM no está optimizado para muchas operaciones frecuentemente utilizadas. Ejemplos destacados de tales operaciones son funciones hash como Keccak, Pedersen y Poseidon, junto con otras operaciones como las de curvas elípticas y verificaciones de rango (es decir, verificar si un número específico se encuentra en un rango particular de valores).
Para resolver la relativa ineficiencia del CVM, el stack de Cairo introdujo el concepto de builtins para operaciones clave: plugins que optimizan la complejidad de demostración de esas operaciones. Los builtins son análogos a los ASIC: los ASIC son circuitos integrados específicos de aplicaciones, mientras que los builtins son restricciones algebraicas específicas de aplicaciones (AIRs, por sus siglas en inglés). Si no sabes o no recuerdas qué son los AIRs, los mencionaremos brevemente más adelante; más detalles aparecen en esta publicación introductoria en Medium.
En resumen, la complejidad de la demostración está correlacionada (aproximadamente de forma lineal) con un recurso llamado celdas de traza (trace cells), y los builtins simplifican las demostraciones de operaciones particulares utilizando muchas menos celdas de traza que la Cairo VM.
Después de haber explicado los beneficios de los builtins, parece natural desarrollarlos para muchas operaciones frecuentemente utilizadas. Sin embargo, esto es más fácil decirlo que hacerlo. El proceso actual de introducir nuevos builtins en Starknet involucra varios pasos:
Escribir el AIR.
Integrarlo en el probador mediante la creación de nuevos diseños (explicados a continuación).
Integrarlo en Starknet, es decir, modificar su base de código y herramientas para desarrolladores para usar el nuevo builtin.
Además del desafío de escribir un AIR, hay mucho espacio para mejorar en las dos etapas restantes. Esta publicación de alto nivel profundizará más en detalle sobre los builtins como AIRs específicos de aplicaciones, los problemas mencionados anteriormente y nuestros planes para el futuro próximo.
AIR es el acrónimo de Algebraic Intermediate Representation (Representación Algebraica Intermedia). En nuestro contexto, se trata de un sistema de polinomios que representa una máquina virtual. Por ejemplo, Cairo deriva su nombre de CPU AIR: un sistema de polinomios que representa una arquitectura de CPU específica. Una solución de este sistema de polinomios representa una transición de estado válida y se denomina traza de ejecución algebraica válida (AET, por sus siglas en inglés).
Los STARKs demuestran la operación correcta de una máquina virtual al demostrar que la traza de ejecución asociada es válida con respecto al AIR dado. En términos generales, las trazas de ejecución se organizan como tablas de números, y el protocolo STARK demuestra que estos números resuelven conjuntamente un sistema de polinomios.
Existen muchas formas de calcular lo mismo, y algunas computaciones son más eficientes que otras. En nuestro contexto, la complejidad de la demostración está determinada esencialmente por el tamaño de la traza, es decir, el número de celdas de traza en la tabla. Dado que las trazas se generan con respecto a un AIR, un AIR específico de aplicación puede reducir significativamente la traza de ejecución de una computación particular. Los builtins son AIRs específicos de aplicaciones que apuntan precisamente a esta optimización.
Aquí tienes una tabla que muestra las mejoras de eficiencia de "builtins" específicos (todos en producción).
Recordemos que una traza de ejecución algebraica (AET) es, en términos generales, una tabla de números que codifica una secuencia de pasos de la máquina virtual (es decir, una ejecución de un programa). Para calcular una prueba, el probador ejecuta el protocolo STARK en una traza de ejecución con respecto a un AIR.
Anteriormente, presentamos los builtins como AIRs específicos de aplicaciones que buscan minimizar la complejidad de la prueba al reducir el número de celdas de traza necesarias para codificar una computación. Sin embargo, la integración descuidada de los builtins en Starknet puede desperdiciar muchas celdas de traza, disminuyendo los beneficios previstos. Veamos más detalles al respecto.
En pocas palabras, un diseño de traza es una asignación de celdas de traza a diferentes “componentes". En nuestro contexto, estos componentes son el CVM y los builtins. Más específicamente, un diseño especifica la cantidad relativa de celdas de traza asignadas a cada componente. (Los diseños siempre se estructuran para agilizar la verificación de la prueba. Para obtener más información, consulta la sección "succinctness" en este artículo de Medium).
Aquí está el punto crucial: la complejidad de la prueba depende del número total de celdas de traza asignadas por el diseño, que puede ser mayor de lo necesario. Por ejemplo, para demostrar una secuencia de pasos del CVM, es aproximadamente el doble de eficiente utilizar un diseño que solo asigna celdas de traza al componente CVM en comparación con un diseño que asigna la mitad de las celdas de traza, por ejemplo, al builtin Poseidon. En resumen, la complejidad de demostrar una computación particular puede reducirse considerablemente con un diseño adecuado.
Actualmente, existe una lista mantenida manualmente de diseños, que crece gradualmente por dos razones principales:
Los builtins solo se pueden utilizar en diseños que les asignen celdas de traza. Por lo tanto, la adición de un builtin requiere al menos un nuevo diseño.
Adaptar un diseño a una ejecución de código Cairo puede mejorar la asignación de celdas. Por lo tanto, las optimizaciones de la utilización de celdas a menudo requieren nuevos diseños.
El código tanto para el probador como para el verificador (los verificadores de Solidity y Cairo) se configura según la lista de diseños.
Con la adición de los builtins Keccak y Poseidon, nos resultó cada vez más difícil generar una lista pequeña de diseños que incluyera muchos builtins y al mismo tiempo fuera eficiente para la ejecución de la mayoría de los bloques de Starknet. Además, se espera que esta eficiencia disminuya considerablemente con la introducción de más builtins, ya que los diseños tendrían que tener en cuenta las muchas posibles combinaciones y proporciones entre ellos.
Actualmente estamos trabajando para mejorar nuestro sistema y prescindir de una lista predefinida de diseños a favor de “Dynamic Layouts”: adaptados sobre la marcha para cada ejecución de código Cairo. Los Diseños Dinámicos siempre estarán proporcionalmente optimizados para el trabajo de demostración en curso. Desde una perspectiva de ingeniería, esto requiere un cambio considerable en la base de código para admitir entradas dinámicas. Sin embargo, esperamos que los Diseños Dinámicos agilicen la capa de demostración de Starknet al mejorar la utilización de las celdas de traza y, en consecuencia, aprovechar mejor la máquina del probador.
Los Diseños Dinámicos eliminarán los desafíos de mantener manualmente diseños eficientes para muchos builtins, lo que a su vez agilizará el proceso de integración de más builtins en Starknet.
Uno de los objetivos de las tarifas de transacción es cobrar a los usuarios por los costos marginales incurridos en el protocolo debido a sus transacciones. Dado que las unidades de las tarifas de transacción son moneda, el mecanismo de tarifas implica la conversión de recursos (por ejemplo, pasos de la VM, builtins, calldata, gas de Ethereum) a tokens (por ejemplo, STRK, ETH).
Actualmente, la utilización ineficiente de recursos por parte del probador afecta a los usuarios, ya que se les cobran tarifas según la traza total y no su parte utilizada. Los Diseños Dinámicos mejorarán la utilización de las celdas y, en consecuencia, reducirán la parte "innecesaria" de la tarifa de transacción (la parte que cubre el consumo de recursos no directamente incurrido por la transacción del usuario).
Actualmente, el último paso en la integración de los builtins implica modificar el código base de Starknet para utilizarlos efectivamente. Estas modificaciones son independientes de los diseños: se requieren para asegurar que el sistema operativo de Starknet invoque los builtins cuando sea posible. Por ejemplo, queremos que el sistema operativo de Starknet invoque el builtin Poseidon durante la ejecución de código Cairo que invoca la función hash Poseidon.
El soporte para builtins en Starknet se realiza de manera manual en la actualidad, de manera similar a los diseños. Sin embargo, a diferencia del caso de los diseños, este soporte manual seguirá siendo sencillo y directo incluso para muchos builtins. En otras palabras, el soporte para builtins en Starknet no impide la integración, y los Diseños Dinámicos allanarán el camino para la creación e integración de builtins adicionales.
En esta publicación explicamos qué son los builtins, sus beneficios, los desafíos involucrados en aprovechar estos beneficios y nuestros planes. Nuestro enfoque actual se centra en los Diseños Dinámicos, que mejorarán no solo la eficiencia del proceso de demostración, sino también la facilidad de integración de nuevos builtins.