Ethereum: de historia a labs

Artículo 34 de 48

71%

completado al llegar aquí

Sistemas distribuidosNota de investigación13 min de lectura

Optimistic rollups: optimismo con periodo de disputa

Cómo funciona un optimistic rollup: raíces afirmadas, ventana de impugnación, bisección hasta un paso de MIPS y retiros de OP Stack en dos fases.

Ruta Ethereum: 0/48

Un usuario mueve fondos de un optimistic rollup a Ethereum. El depósito en sentido contrario tardó minutos; el retiro, en cambio, le pide esperar del orden de una semana. No es un fallo de UX ni una política comercial. Es el precio exacto de una decisión de diseño: aceptar resultados sin comprobarlos, siempre que alguien tenga tiempo de demostrar que son falsos.

Un optimistic rollup publica en Ethereum los datos de sus transacciones y una raíz de estado que afirma el resultado, sin prueba de que sea correcto. Durante una ventana de impugnación (challenge period), cualquiera puede disputar esa afirmación con una prueba de fraude. Si nadie lo hace, la raíz se considera válida.

Brújula de lectura

Actor, evidencia y estado

Antes de avanzar, ubica quién actúa, qué prueba queda y qué parte del sistema cambia.

Actor

Proponente y retador

Uno afirma una raíz de salida; el otro la disputa moviendo el juego hasta un único paso.

Evidencia

Un paso de la VM en L1

El contrato ejecuta una instrucción con datos autenticados por el PreimageOracle.

Estado

Juego de disputa resuelto

Si la raíz gana, los retiros probados contra ella pueden finalizarse en L1.

Preguntas guía

  • ¿Por qué basta un solo verificador honesto para que un optimistic rollup sea seguro?
  • ¿Cómo reduce una disputa sobre millones de pasos a una única instrucción ejecutable en L1?
  • ¿Qué pasos sigue un retiro en OP Stack y de dónde sale la espera?
  • ¿Qué roles con permisos especiales siguen existiendo y por qué importan?

Conexiones dentro de la serie

Invariante optimista: un solo verificador honesto basta

En un sistema de votación necesitas una mayoría honesta. En un optimistic rollup necesitas mucho menos: un participante honesto que vigile y tenga los datos. ethereum.org lo formula así: la validez de la cadena depende de que exista un nodo honesto, que puede avanzarla publicando afirmaciones válidas o impugnando las inválidas.

El razonamiento es asimétrico. Mentir sobre una raíz es barato de intentar, pero una sola persona con los datos puede reejecutar el lote, encontrar la discrepancia y ganar la disputa. Para que el ataque compense, el atacante tendría que impedir que nadie impugne durante toda la ventana. De ahí salen las dos dependencias reales del modelo: los datos deben estar disponibles en L1 y la ventana debe ser lo bastante larga como para que un retador pueda reaccionar incluso bajo censura temporal en L1.

Las fianzas (bonds) completan el incentivo. Quien publica una afirmación deposita un valor que pierde si se demuestra falsa; ethereum.org describe que parte de la fianza del perdedor va al retador y parte se quema, para que dos cómplices no puedan simular disputas sin coste.

Historia: de la reejecución completa a la bisección

Las primeras pruebas de fraude eran de una ronda: el retador pedía a un contrato de L1 que reejecutara la transacción disputada y comparara la raíz. Funciona, pero obliga a publicar compromisos de estado por transacción y a pagar en L1 la ejecución completa, limitada además por el gas de un bloque. Por eso los diseños migraron a pruebas multironda, donde las partes dividen la disputa hasta que solo queda un paso.

OP Stack ilustra otra transición, de permisos a reglas. En su diseño anterior, un contrato L2OutputOracle recibía raíces de una clave PROPOSER con permiso, y otra clave CHALLENGER podía borrar raíces sin demostrar que eran incorrectas. La especificación lo describe como privilegios de "modo dios". Con las pruebas de fallo, las raíces pasan a ser juegos de disputa creados por un DisputeGameFactory: una raíz incorrecta ya no se borra, se demuestra incorrecta.

Traza de ejecución de una disputa en el Fault Dispute Game

La especificación de OP Stack separa la prueba de fallo en tres piezas: un programa que, dadas las entradas de L1, recalcula el estado de L2 sin estado propio; una VM capaz de probar en L1 cualquier instrucción de ese programa; y un juego de disputa interactivo que reduce el desacuerdo a una instrucción. Las implementaciones de VM listadas incluyen Cannon, una arquitectura MIPS64, y Asterisc, una RISC-V de 64 bits.

Figura 1

Bisección de una traza hasta un único paso verificable

Fuentes:

[4]
Bisección de una traza hasta un único paso verificable
Cómo leer esta figura

Cuatro barras horizontales representan la traza de ejecución desde S cero hasta S n entre dos raíces de salida. En el nivel 0 toda la traza está en disputa. En el nivel 1 las partes coinciden en el punto medio, la mitad izquierda queda en verde y la discrepancia se busca en la mitad derecha, en rojo. En el nivel 2 vuelven a coincidir en el nuevo punto medio y la búsqueda sigue a la derecha. En el nivel 3 no coinciden en el punto medio, así que la discrepancia está a la izquierda. Unos puntos suspensivos indican que el proceso continúa. Abajo, un contrato de L1 ejecuta un solo paso, S i más 1 igual a VM de S i y P i, alimentado por el PreimageOracle con datos de L1 y L2 autenticados; gana quien coincide con el resultado y los bonos van al ganador. Una nota indica que con n pasos bastan unos logaritmo en base 2 de n movimientos.

Visual original de TrautsLab. Esquema conceptual del juego de disputa: cada nivel compara el estado en el punto medio y descarta la mitad en la que las partes coinciden, hasta que solo queda un paso que el contrato de L1 ejecuta.

El juego empieza con una raíz afirmada para un número de bloque de L2. Cada jugada es un ataque (no estoy de acuerdo con tu afirmación) o una defensa (estoy de acuerdo, el error está después) y se coloca en una posición de un árbol binario de profundidad máxima MAX_GAME_DEPTH. Por encima de SPLIT_DEPTH, las afirmaciones son raíces de salida de bloques de L2; por debajo, son compromisos con el estado de la VM en una instrucción concreta.

Cuando la disputa llega a una sola instrucción, el contrato de L1 ejecuta ese paso. Si la instrucción necesita datos externos, como una cabecera de L1 o un nodo del estado de L2, los lee del PreimageOracle, un almacén donde cada dato se identifica por su hash. La VM no confía en nadie: solo acepta datos cuya preimagen coincide con un compromiso conocido.

El tiempo también es parte del protocolo. Cada equipo tiene un reloj de ajedrez: mover reanuda el reloj del rival y pausa el propio. Cuando el reloj acumulado supera MAX_CLOCK_DURATION, ya no se puede contestar esa afirmación, y el juego se resuelve de abajo arriba: una afirmación queda refutada si al menos uno de sus hijos queda sin refutar.

Traza de un retiro en OP Stack: iniciar, probar, finalizar

Un retiro de OP Stack son tres transacciones distintas. En L2, la cuenta llama al contrato predesplegado L2ToL1MessagePasser, que guarda el hash del mensaje. En L1, alguien envía una transacción de prueba al OptimismPortal con la prueba de inclusión de ese mensaje contra una raíz de salida. Más tarde, alguien envía la transacción de finalización, que comprueba que pasó el plazo y ejecuta el mensaje.

Línea de tiempo

Ciclo de vida de un retiro de L2 a L1

Nombres de la especificación de OP Stack; las duraciones son parámetros de despliegue.
  1. t0

    Inicio en L2

    La cuenta llama a L2ToL1MessagePasser; el hash del retiro queda en su storage.

  2. t0 + publicación

    Juego de disputa

    Un proponente crea un juego con la raíz de salida que incluye ese storage.

  3. t1

    Prueba en L1

    proveWithdrawalTransaction demuestra la inclusión contra la raíz del juego.

  4. PROOF_MATURITY_DELAY_SECONDS

    Espera

    Además, el juego debe resolverse a favor de la raíz y superar DISPUTE_GAME_FINALITY_DELAY_SECONDS.

  5. t2

    Finalización en L1

    finalizeWithdrawalTransaction ejecuta el mensaje o transfiere el ETH.

La especificación de retiros habla de una ventana de impugnación de 7 días tras la prueba, y ethereum.org usa la misma cifra aproximada para los optimistic rollups en general. Con las pruebas de fallo se añaden dos parámetros: PROOF_MATURITY_DELAY_SECONDS, el tiempo mínimo entre probar y finalizar, y DISPUTE_GAME_FINALITY_DELAY_SECONDS, un margen durante el cual el rol Guardian puede invalidar un juego ya resuelto si el sistema falló.

Para no esperar, existen proveedores de liquidez: compran el retiro pendiente y pagan en L1 al momento, a cambio de una comisión. Pueden hacerlo con poco riesgo porque, si ejecutan la cadena por su cuenta, saben que un retiro válido acabará confirmándose.

Riesgo operativo: quién vigila y quién puede pausar

El modelo asume que alguien vigila. Si tu aplicación custodia mucho valor en un optimistic rollup, considera ejecutar tú mismo un nodo y un retador, o al menos monitorizar los juegos de disputa que afectan a tus retiros. La especificación incluso advierte de afirmaciones "gorronas" (freeloader claims) que no cambian el resultado pero que el retador honesto debe contestar para cobrar los bonos que le corresponden.

Comparación

Qué garantiza la prueba de fallo y qué no

La prueba protege la corrección de la raíz; la operación del sistema depende de otros supuestos.

Lo que protege

Una raíz de salida falsa puede refutarse si un retador honesto actúa a tiempo.

Supuesto
un retador honesto
Coste en L1
un paso de la VM
  • bonos para quien gana
  • anclas de estado que avanzan tras cada juego resuelto

Lo que no protege

Censura del secuenciador, pausas del Guardian o actualizaciones de contratos.

Supuesto
gobernanza de los contratos L1
Mitigación
inclusión forzada y monitoreo
  • el Guardian puede pausar el portal
  • los retiros quedan atados al tipo de juego respetado

En diseño de producto, la ventana de impugnación es una restricción de negocio. Si tu flujo necesita liquidez en L1 de forma frecuente, presupuesta comisiones de proveedores de liquidez o planifica la tesorería con días de antelación. No prometas a usuarios "retiro inmediato" sin decir quién asume el riesgo de esa espera.

Laboratorio mínimo: bisección de juguete

Este fragmento ilustrativo reproduce la idea central: dos partes con trazas distintas encuentran el primer paso en el que divergen con un número logarítmico de comparaciones. No implementa el árbol de posiciones ni los relojes de OP Stack.

javascript
// Ilustrativo: encuentra el primer índice i tal que honest[i+1] !== claimed[i+1],
// asumiendo que coinciden al inicio, difieren al final y, una vez que divergen,
// ya no vuelven a coincidir (cada estado resume toda la historia anterior).
function bisect(honest, claimed) {
  let lo = 0;                    // índice donde ambos coinciden
  let hi = honest.length - 1;    // índice donde ambos difieren
  let rounds = 0;
  while (hi - lo > 1) {
    const mid = Math.floor((lo + hi) / 2);
    if (honest[mid] === claimed[mid]) lo = mid; else hi = mid;
    rounds += 1;
  }
  return { step: lo, rounds }; // L1 solo tendría que ejecutar el paso lo -> lo + 1
}

La validación observable es que, para trazas de un millón de estados, el bucle termina en unas 20 rondas, y que el paso devuelto es exactamente el primero alterado.

Quédate con esta frase: un optimistic rollup no prueba que tiene razón; da tiempo para demostrar que no la tiene. Ese tiempo es la ventana, y su coste aparece en cada retiro hacia L1.

Referencias

Bibliografía académica

Formato IEEENumerado para ingeniería, sistemas y protocolos.
  1. [1]

    ethereum.org, "Optimistic rollups."

    official docsID: ETH-OPTIMISTIC-DOCSAbrir fuente (abre en otra pestaña)

    Ventana de impugnación, pruebas de fraude de una ronda y multironda, retiros y proveedores de liquidez.

  2. [2]

    OP Stack specification, "Fault Proof: Bridge Integration."

    Semántica heredada de L2OutputOracle, rol Guardian, PROOF_MATURITY_DELAY_SECONDS y DISPUTE_GAME_FINALITY_DELAY_SECONDS.

  3. [3]

    OP Stack specification, "Fault Proof."

    Programa, VM y juego de disputa; PreimageOracle; Cannon (MIPS64) y Asterisc (RISC-V).

  4. [4]

    OP Stack specification, "Fault Dispute Game."

    Árbol de juego, SPLIT_DEPTH, MAX_GAME_DEPTH, ataque y defensa, reloj de ajedrez y resolución por subjuegos.

  5. [5]

    OP Stack specification, "Withdrawals."

    specID: OP-SPECS-WITHDRAWALSAbrir fuente (abre en otra pestaña)

    Transacciones de inicio, prueba y finalización; L2ToL1MessagePasser y OptimismPortal; ventana de 7 días.

Fuentes primarias, papers seminales y especificaciones técnicas citadas en esta investigación.

Rutas vecinas

Si este tema te abrió hambre, sigue por aquí.

Series y labs que comparten área o dependen de esta ruta. Pocas opciones, para no convertir la curiosidad en menú infinito.

Sigue leyendo

Ideas conectadas con este artículo

Una ruta corta para continuar sin abrir veinte pestañas y perder el hilo.

Los comentarios se cargan al final de la lectura para no meter peso antes de tiempo.