Traducción del artículo original en inglés.
Desarrolladores
Hacia un GenLayer 100 % seguro. Parte 1: la arquitectura
Cómo los contratos de consenso, los nodos validadores y la GenVM de GenLayer forman una arquitectura de defensa en profundidad para que los Intelligent Contracts sean seguros.
Edgars Nemše8 min de lectura
Empezamos una serie sobre cómo conseguimos que GenLayer esté lo más cerca posible de ser 100 % seguro. El motivo es sencillo: GenLayer es un sistema crítico que guarda fondos y emite juicios, y aquí un bug no es solo una caída del servicio. Puede suponer que mucha gente pierda mucho dinero. Nos lo tomamos muy en serio.
Nos inspiramos en sistemas con un perfil de fallos parecido, en los que cualquier error es crítico: los controladores de vuelo o el software de control industrial. El enfoque es la defensa en profundidad, es decir, muchas capas independientes de pruebas y validación. Pruebas basadas en ejemplos y ejecuciones de extremo a extremo de todo el sistema antes de cada merge. Pruebas de conformidad generativas contrastadas con un modelo de referencia. Una CI que rompe el código a propósito para demostrar que las pruebas lo detectarían. Un modelo formal en TLA+ del protocolo de consenso, con demostraciones verificadas por máquina de sus propiedades clave. Y más.
Pero la primera capa de defensa es la propia arquitectura: un sistema bien diseñado elimina clases enteras de bugs antes de que se escriba una sola prueba. Por eso, además, las pruebas no se entienden sin ella: todas se derivan directamente de cómo está construido el sistema. Así que este primer artículo repasa las piezas clave y las interfaces entre ellas. Doy por hecho que ya sabes qué es GenLayer y qué problema resuelve; si no, empieza por nuestro artículo sobre Optimistic Democracy, el consenso nativo de IA que está cambiando el comercio, y por nuestra documentación. Aquí nos vamos a centrar en la ingeniería que hay entre bastidores.
GenLayer se divide en tres componentes principales que se comunican entre sí: los contratos de consenso de la GenLayer Chain, el nodo validador y la GenVM. El diagrama de abajo muestra cómo encajan, y el resto del artículo los recorre uno por uno.
Los contratos de consenso
Cada transacción de GenLayer avanza por una máquina de estados implementada como contratos de Solidity en la GenLayer Chain, un rollup EVM. Los contratos siguen todo el ciclo de vida: la transacción entra en cola, un líder la propone, los validadores la votan, se acepta y, tras el plazo de apelación, pasa a ser definitiva. Las apelaciones llevan la misma transacción a conjuntos de validadores cada vez mayores, hasta llegar al conjunto completo. El propio conjunto de validadores también vive aquí: los validadores hacen staking para entrar en él, y para cada transacción los contratos eligen del conjunto un líder y un comité.
La cadena es la única fuente de verdad. Nada más guarda el estado oficial: si quieres saber en qué punto de su ciclo de vida está una transacción, la respuesta está en los contratos. Cada cambio de estado emite un evento, y esos eventos son la forma en que el resto del sistema sabe qué hacer a continuación.
La cadena es también la capa de comunicación. Los nodos nunca hablan directamente entre sí: no hay comunicación peer-to-peer ni gossip. Una propuesta es una transacción, un voto es una transacción, y la cadena las ordena todas. Eso elimina toda una clase de problemas de consenso antes de que existan. No hay bifurcaciones, porque todos leen la misma secuencia canónica de eventos. No hay compromisos dobles ni votos contradictorios, porque el contrato rechaza estructuralmente un segundo voto en lugar de detectarlo a posteriori. No hay gestión de particiones ni lógica de cambio de vista en nuestro protocolo, porque la entrega y el orden de los mensajes son tarea de la cadena subyacente. Hasta los tiempos de espera son objetivos: «el líder no respondió a tiempo» es un hecho que el contrato puede verificar a partir del tiempo de bloque, no la opinión local de un nodo. La cadena zanja qué pasó; a Optimistic Democracy solo le queda decidir qué significa.
El precio es que cada paso del protocolo es una transacción on-chain, así que el tiempo de bloque marca el mínimo de la latencia del consenso. Es una concesión deliberada: latencia a cambio de eliminar categorías enteras de fallos propios de los sistemas distribuidos. También significa que el historial completo de cada decisión de consenso es un registro ordenado que se puede reproducir, algo que será importante más adelante en esta serie.
El nodo validador
El nodo validador es lo que ejecutan los operadores. Lo primero que hay que dejar claro es lo que no es: no es un nodo de la GenLayer Chain. La cadena es una cadena EVM normal, con sus propios nodos completos y su propio RPC, y ahí es donde se establece el orden. El nodo validador es un cliente de esa cadena: se conecta al RPC de un nodo de la cadena, se suscribe a eventos y envía transacciones. Sí, son dos capas de nodos y dos capas de RPC. Aun así, el reparto del trabajo es limpio: los nodos de la cadena se ponen de acuerdo en el orden de los eventos; los nodos validadores actúan en consecuencia.
Por dentro, son tres cosas en un solo binario:
- Un worker de consenso. Es su trabajo principal: el nodo vigila los eventos de la cadena y, cuando lo eligen como líder o validador de una transacción, la ejecuta a través de la GenVM (con los modelos que haya configurado el operador) y envía los votos y las revelaciones. Para la cadena, es una cuenta más que envía transacciones firmadas.
- Un nodo completo. Sigue la cadena y mantiene el estado de GenLayer. La cadena guarda el registro ordenado y el estado del consenso; el estado de los propios Intelligent Contracts es derivado: el nodo vuelve a ejecutar las transacciones aceptadas a través de la GenVM y guarda el estado resultante en su propia base de datos local.
- El RPC. La interfaz de GenLayer con la que hablan los usuarios, los SDK y las herramientas. Las lecturas propias de GenLayer se responden a partir del estado derivado; los métodos estándar
eth_pasan directamente a un nodo de la cadena. Las transacciones siempre van a la cadena: ese paso directo solo significa que te basta con una conexión.
Así que el nodo consume un RPC por debajo y sirve otro distinto por encima. Puedes ejecutar el mismo binario sin validar (sigue sincronizándose y sirviendo el RPC), pero el trabajo principal, y el que interesa en esta serie, es validar. Esa es la parte por la que haces staking.
GenVM
La GenVM es donde realmente se ejecutan los contratos, y su diseño es lo que permite que Optimistic Democracy funcione: combina el determinismo con un no determinismo controlado, con llamadas a LLM y acceso a la web exactamente donde el desarrollador los pide, y en ningún otro sitio.
El nivel superior de todo contrato se ejecuta en modo determinista. La GenVM es un entorno aislado WASM (conjunto de instrucciones determinista, memoria aislada y ninguna forma de tocar el mundo exterior salvo a través de las funciones del host que expone la máquina virtual: almacenamiento, calldata, mensajes entre contratos), así que todos los validadores que ejecutan la misma transacción obtienen exactamente el mismo resultado, hasta el hash.
Dentro de esa ejecución, el contrato puede abrir bloques no deterministas. Cada bloque se ejecuta en su propia instancia aislada de la GenVM, y esa instancia recibe funciones del host adicionales para leer la web y llamar a LLM. Es el único lugar donde existen esas capacidades: el código determinista no puede alcanzarlas, porque las importaciones sencillamente no están ahí.
El consenso se corresponde directamente con esta división. La ejecución determinista tiene que coincidir exactamente en todos los nodos, como en cualquier blockchain normal. Los bloques no deterministas son donde los resultados pueden diferir legítimamente entre validadores, y ahí es donde toman el relevo la votación de Optimistic Democracy y el Principio de Equivalencia.
Esto es también lo que nos permite poner on-chain un intérprete completo de CPython y usar Python normal y corriente como lenguaje de contratos. No inventamos un dialecto determinista de Python: la GenVM compila el intérprete real a WASM y lo ejecuta dentro del entorno aislado. El código de los contratos se ejecuta sin cambios; cualquier no determinismo que Python lleve dentro queda fijado por el entorno determinista.
Un intérprete real on-chain significa toda la potencia del lenguaje, incluidas cosas como eval. Un contrato puede ejecutar código que no existía cuando se desplegó (un LLM puede escribir código en plena ejecución y el contrato puede ejecutarlo en la misma llamada) y sigue siendo seguro y determinista, porque todo lo que se ejecuta vive dentro del mismo entorno aislado, con las mismas funciones del host y nada más.
El intérprete se distribuye como un runner, un entorno de ejecución direccionado por contenido y fijado por hash en la cabecera del contrato. Así, todos los validadores que ejecutan tu contrato usan un entorno idéntico byte a byte, hasta la compilación concreta del intérprete.
Aun así, Python es la opción por defecto, no el límite. La interfaz de contratos de la GenVM es WASM: cualquier cosa que compile a WASM puede ser un contrato. Si quieres, escribe uno directamente en Rust o en C; el runner de Python no es más que el entorno estándar que hace cómodo el caso habitual.
Una transacción, de principio a fin
- Un usuario envía una transacción a la cadena, directamente a un nodo de la cadena o a través del paso directo de un nodo validador. La transacción llega a los contratos de consenso y queda en cola.
- Los contratos eligen un líder y un comité de validadores, y lo anuncian en un evento.
- El nodo del líder recoge el evento y ejecuta la transacción en su GenVM: el código determinista, en el entorno aislado; los bloques no deterministas, a través de las funciones del host habilitadas para ello. El resultado vuelve on-chain como propuesta del líder.
- El nodo de cada validador vuelve a ejecutar la transacción en su propia GenVM y compara su resultado con la propuesta. La comparación no pregunta si el resultado del líder es idéntico, sino si es aceptable: eso es el Principio de Equivalencia, y el desarrollador del contrato define los criterios en cada llamada. Los votos se envían primero ocultos (compromiso) y después se revelan.
- Si hay una mayoría de acuerdo, la transacción se acepta y su decisión surte efecto. Si en cambio la mayoría la rechaza, la red rota a un nuevo líder y lo vuelve a intentar; y si aun así no se alcanza el consenso, la transacción termina indeterminada y el estado del contrato queda intacto. Tampoco un resultado aceptado es definitivo todavía: durante el plazo de apelación, cualquiera puede apelar y enviar la transacción a un conjunto de validadores mayor.
- El plazo se cierra y la transacción pasa a ser definitiva. A partir de ahí es permanente.
Cada flecha de ese recorrido cruza uno de dos puntos de unión: entre los contratos y el nodo, eventos hacia abajo y transacciones hacia arriba; entre el nodo y la GenVM, ejecución y resultado.
La primera capa de defensa
Todo lo que ha descrito este artículo comparte un hilo conductor: en un enfoque de defensa en profundidad, la propia arquitectura es la primera capa. Elimina de raíz clases enteras de bugs: como toda la comunicación pasa por la cadena, las bifurcaciones, los votos dobles y la gestión de particiones no son problemas que tengamos que resolver. Nos da propiedades que se cumplen por construcción, no porque una prueba lo compruebe: el determinismo viene del entorno aislado WASM, y la reproducibilidad, de los runners fijados por hash. Y traza los límites que hacen que el sistema se pueda probar: cada punto de unión del diagrama es un lugar donde una capa puede contrastarse con una interfaz bien definida.
Las capas siguientes se ocupan de todo lo que la arquitectura no puede garantizar por construcción. Cada componente falla de maneras distintas, así que el enfoque de pruebas es distinto para cada uno: los contratos de consenso se prueban como una máquina de estados; el nodo validador, con el comportamiento real de los contratos como referencia; la GenVM, para verificar que el determinismo que heredamos se cumple de verdad. Y como los componentes tienen que funcionar juntos, las pruebas no se detienen en sus bordes: atraviesan los límites y las combinaciones de estas capas, hasta llegar a las ejecuciones de extremo a extremo de todo el sistema. De eso tratará el resto de esta serie.



