Título original: "Bedrock Explicador"

Escrito por: Oficial de Optimismo

Compilado por: Frank, Foresight News

Bedrock es el nombre de la primera versión oficial de OP Stack, un conjunto de componentes modulares gratuitos y de código abierto diseñados para impulsar el crecimiento de Optimism.

Resumen de mejora

Bedrock mejora a su predecesor, incluyendo:

  • Reduzca las tarifas de transacción utilizando la compresión optimizada de transacciones por lotes y Ethereum como capa de disponibilidad de datos;

  • Reducción de la latencia al empaquetar transacciones L1 en acumulaciones mediante un mejor manejo de las reorganizaciones L1;

  • Habilitar sistemas de prueba modulares mediante la reutilización de códigos;

  • Mejore el rendimiento del nodo eliminando la deuda de diseño.

tarifas más bajas

Bedrock utiliza una estrategia de compresión de datos optimizada para minimizar los costos de datos. Actualmente estamos evaluando el impacto de este cambio, pero esperamos que reduzca significativamente las tarifas.

Bedrock también elimina todos los costos de gas asociados con la ejecución de EVM al enviar datos a L1, lo que reducirá los costos en un 10 % adicional en comparación con las versiones anteriores del protocolo.

Tiempo de crédito de depósito más corto

Bedrock ha introducido soporte para reorganizaciones L1 en el software del nodo, lo que reduce significativamente el tiempo que los usuarios tienen que esperar para que se acrediten los depósitos.

Las versiones anteriores del protocolo podían tardar hasta 10 minutos en confirmar los depósitos, mientras que con Bedrock esperamos que los depósitos se confirmen en 3 minutos.

Prueba modular mejorada

Bedrock abstrae el sistema de prueba de OP Stack para que el paquete acumulativo pueda usar pruebas de falla o pruebas de validez (como zk-SNARK) para demostrar la ejecución correcta después de la entrada en el paquete acumulativo. Esta abstracción también permitirá el uso de Cannon para probar la fallo de sistema.

Rendimiento de nodo mejorado

El rendimiento del software del nodo mejora significativamente al ejecutar múltiples transacciones en un único "bloque" acumulativo en lugar del modelo de "una transacción por bloque" de versiones anteriores.

Esto permite que el costo de las actualizaciones de Merkle Trie se distribuya entre múltiples transacciones, lo que con los volúmenes de transacciones actuales reduce el crecimiento de los datos estatales en aproximadamente 15 GB por año.

El rendimiento del nodo también se ha mejorado aún más al eliminar la deuda técnica de versiones anteriores del protocolo, incluida la eliminación de la necesidad de un nodo de "capa de transporte de datos" separado para indexar L1 y la actualización del software del nodo para consultar de manera eficiente las transacciones a partir de datos L1.

Equivalencia de Ethereum mejorada

Bedrock fue diseñado desde el principio para ser lo más "consistente" con Ethereum posible, y se han eliminado muchas desviaciones de Ethereum en versiones anteriores del protocolo, incluyendo:

  • Modelo “una transacción por bloque”;

  • Personalice el código de operación para obtener información del bloque L1;

  • Separe los campos de costo L1/L2 en la API JSON-RPC;

  • Representación ERC20 personalizada de saldos ETH.

Bedrock también agregó soporte para EIP-1559, reorganización de blockchain y otras características de Ethereum presentes en L1.

Criterios de diseño

Bedrock está diseñado para ser modular y escalable al mismo tiempo que reutiliza el código existente de Ethereum y apunta a lograr una equivalencia del 100% de Ethereum siempre que sea posible.

Modular

Al utilizar interfaces y esquemas de control de versiones bien definidos, Bedrock puede reemplazar fácilmente diferentes componentes en la pila OP y agregar nuevas funciones.

Esto le permite adaptarse al desarrollo futuro del ecosistema Ethereum con una arquitectura flexible, como por ejemplo:

  • El nodo acumulativo está separado del cliente de ejecución;

  • Diseño modular a prueba de fallos.

reutilización de código

Bedrock utiliza la arquitectura e infraestructura existente de Ethereum siempre que sea posible. Este enfoque permite a OP Stack heredar las ventajas de seguridad y efecto Lindy del código base probado en batalla utilizado por la red principal de Ethereum.

Encontrará ejemplos de esto en todo el diseño, que incluyen:

  • cliente de ejecución mínimamente modificado;

  • Contratos EVM en lugar de código de cliente precompilado.

Equivalencia de Ethereum

Bedrock está diseñado para ser máximamente compatible con las experiencias existentes de los desarrolladores de Ethereum, pero existen algunas excepciones debido a diferencias fundamentales entre L1 y rollup: diferentes modelos de tarifas, tiempos de bloqueo más rápidos (2 segundos frente a 12 segundos) y tipos de transacciones especiales que incluyen transacciones de depósito L1.

Estas excepciones incluyen:

  • Prueba de fallas de clientes de ejecución de Ethereum diseñada para probar modificaciones mínimas;

  • Ethereum realiza la reutilización del código del lado del cliente para que lo utilicen los nodos y ordenadores en la red L2.

protocolo

Los rollups se basan en la disponibilidad de datos (generalmente una cadena de bloques L1 como Ethereum). En la configuración más común, el protocolo rollup deriva una "cadena L2 canónica" de dos fuentes principales de información:

  • El secuenciador publica los datos de la transacción en L1;

  • Las transacciones de depósito se envían mediante cuentas y contratos inteligentes al contrato puente en L1.

Los siguientes son los componentes básicos del acuerdo:

  • Al interactuar directamente con el contrato inteligente en L1, el depósito se escribe en la "cadena L2 estándar";

  • Los retiros se escriben en la "cadena canónica L2" e implícitamente desencadenan interacciones con contratos inteligentes y cuentas en L1;

  • Los lotes son escrituras de datos correspondientes a lotes en el resumen;

  • La derivación de bloques es cómo interpretar las lecturas de datos en L1 para comprender la "cadena canónica L2";

  • El sistema de prueba define la finalidad de las raíces de salida publicadas en L1 para que puedan ejecutarse (por ejemplo, realizar retiros).

depósito

El depósito es una transacción en L1 y se incluirá en el resumen. Por definición, se garantiza que los depósitos se incluirán en la "cadena canónica L2" como medio para evitar la censura o el control de la L2.

Cualquier mensaje entregado desde L1

Las transacciones de depósito son transacciones acumuladas realizadas como parte de un depósito. Con Bedrock, los depósitos son transacciones de Ethereum totalmente universales, como cuentas en Ethereum o contratos inteligentes que pueden crear contratos de "depósito".

Bedrock define un contrato de depósito disponible en L1: es un contrato inteligente con el que las cuentas L1 y los contratos inteligentes pueden interactuar para escribir en L2. Las transacciones de depósito en L2 se derivan de transacciones emitidas por este contrato de depósito e incluyen parámetros esperados como desde, hacia y datos.

Consulte la sección Especificaciones del acuerdo de contrato de depósito para obtener más detalles.

Compre gas L2 garantizado en L1

Bedrock también aclaró el mecanismo de quema de gas y el mercado de tarifas de depósito: el gas gastado en L2 mediante transacciones de depósito se compra en L1 mediante la quema de gas.

Este gas se compra específicamente en el mercado de tarifas y existe un límite estricto en la cantidad total de gas proporcionado a todas las transacciones de depósito en un único bloque L1. Este mecanismo se utiliza para evitar ataques de denegación de servicio (DoS) que podrían ocurrir. Al escribir transacciones de L1 a L2, porque estas transacciones consumen mucho gas en L2, pero son muy baratas en L1.

El gas proporcionado para las transacciones de depósito a veces se denomina "gas garantizado". El Gas Garantizado es único porque se paga quemando Gas en L1 y, por lo tanto, no es reembolsable.

Y la cantidad total de gas L1 que debe quemarse por unidad de gas L2 garantizado depende del precio del gas L2 informado por el mecanismo de carga estilo EIP-1559. Además, los usuarios reciben una asignación de gas dinámica basada en la cantidad de gas L1 gastada en el cálculo de las actualizaciones del mecanismo de tarifas.

Para obtener una explicación más detallada, lea las especificaciones del protocolo en la sección de depósito.

Retirar dinero

Los retiros son transacciones entre capas iniciadas en L2 y completadas por transacciones ejecutadas en L1. Vale la pena señalar que las cuentas L2 pueden usar retiros para llamar a contratos L1 o transferir ETH de cuentas L2 a cuentas L1.

El retiro se inicia llamando al contrato preimplementado Message Passer en L2, que registra las propiedades importantes del mensaje en su almacenamiento, y luego el retiro se completa en L1 llamando al contrato OptimismPortal para demostrar la inclusión de este mensaje de retiro.

De esta manera, los retiros y los depósitos son diferentes: las transacciones de retiro deben completarse mediante contratos inteligentes en L1, en lugar de depender de información derivada de bloques.

Proceso de retiro de dos pasos

Los errores de validación de la prueba de retiro han sido la causa principal de muchos hacks de puentes entre cadenas en los últimos años. La versión Bedrock introduce un paso adicional en el proceso de retirada de versiones anteriores diseñado para proporcionar una defensa adicional contra este tipo de errores.

En el proceso de retiro de dos pasos, cada retiro debe presentar la prueba Merkle correspondiente al retiro 7 días antes de la salida final. Este nuevo mecanismo de seguridad brinda a las herramientas de monitoreo 7 días completos para encontrar y detectar la invalidez de la prueba de retiro.

Si se descubre que el certificado de retiro no es válido durante este período, se pueden implementar reparaciones de contratos inteligentes antes de que se pierdan los fondos, lo que reduce en gran medida el riesgo de compromiso del puente entre cadenas.

Consulte la sección Especificaciones del acuerdo de retirada para obtener más detalles.

Lotes

En Bedrock, se define un formato cableado para el paso de mensajes entre L1 y L2 (es decir, L2 deriva bloques de L1, L2 escribe transacciones en L1), este formato cableado está diseñado para reducir al mínimo el costo de escritura en L1 y la complejidad del software.

Optimizar la compresión de datos

Para optimizar la compresión de datos, las listas de transacciones L2 (llamadas lotes de secuenciador) se organizan en grupos de objetos (llamados canales). El tamaño máximo de cada canal se puede definir en un parámetro configurable, que inicialmente se establecerá en 9,5 M. Estos canales Se espera que se comprima utilizando la función de compresión y se envíe a L1.

envío paralelo por lotes

Para paralelizar mensajes de secuenciadores que envían datos de canal comprimidos a L1, los canales se descomponen aún más en "marcos de canal", que son fragmentos de datos de canal comprimidos que pueden caber en una única transacción L1.

Suponiendo que los "marcos de canal" son independientes entre sí y se conoce el orden, las transacciones de Ethereum enviadas a L1 por el secuenciador se pueden enviar en paralelo, minimizando así la complejidad del software del secuenciador y permitiendo rellenar todo el espacio de datos disponible en L1.

Minimizando el gas Ethereum

Bedrock elimina todo el gas de ejecución utilizado por el sistema L1 para enviar datos del canal a L1 en transacciones denominadas "transacciones por lotes". Toda la lógica de verificación que ocurría anteriormente en los contratos inteligentes L1 se ha movido a la lógica de derivación de bloques. En cambio, las "transacciones por lotes" se envían a una única dirección EOA en Ethereum, denominada "dirección de bandeja de entrada por lotes".

Los lotes todavía están sujetos a controles de validez (es decir, deben estar codificados correctamente), al igual que las transacciones individuales dentro del lote (por ejemplo, las firmas deben ser válidas), los lotes no válidos y las transacciones individuales no válidas dentro de lotes válidos se consideran descartados y irrelevantes para el sistema.

Nota: Ethereum pronto se actualizará a una nueva versión que incluye EIP-4844, que introduce un mercado de tarifas de escritura de datos separado y aumenta el límite superior en la cantidad de datos que el protocolo Ethereum está dispuesto a almacenar. Se espera que este cambio reduzca aún más el número de costos asociados con la publicación en L1.

Para obtener una explicación más detallada, lea la Especificación de formato de cable.

Horquilla de bloque

En Bedrock, el protocolo está diseñado para garantizar que el momento de los depósitos en L1 esté relacionado con la derivación de bloques de la "cadena L2 canónica". Lo que esto hace es una función pura de escribir datos en L1 a través de las propiedades del secuenciador, depósito y bloque L1.

Para lograr esto, el protocolo define estrategias para garantizar depósitos, manejar marcas de tiempo L1 y L2 y manejar ventanas de pedidos en el canal para garantizar pedidos correctos.

Depósito garantizado en cuenta

Los objetivos del protocolo de derivación de bloques se definen de la siguiente manera:

Después de que haya transcurrido cada "intervalo de bloque L2", debe haber un bloque L2 y la marca de tiempo del bloque L2 se sincroniza con la marca de tiempo de L1 (es decir, garantizar que los depósitos se incluyan en el orden cronológico lógico).

En Bedrock, se introduce el concepto de "época de secuenciación": es el rango de bloques L2 derivados de una serie de bloques L1. Cada época se identifica mediante un "número de época", que es igual al número en la ventana de clasificación. El número de secuencia del bloque del primer bloque L1. El tamaño de las épocas puede variar, sujeto a algunas restricciones.

El canal derivado por lotes trata la marca de tiempo del bloque L1 asociado con el "número de época" como ancla para determinar el orden de las transacciones en L2. El protocolo garantiza que el primer bloque L2 de una época nunca quedará por detrás de la marca de tiempo del bloque L1 de la época coincidente. El primer bloque de una época debe contener depósitos en L1 para garantizar que el depósito será procesado.

Tenga en cuenta que en la versión Bedrock, el objetivo de intervalo de bloqueo en L2 está configurado en 2 segundos.

Manejo de marcas de tiempo L1 y L2

Bedrock intenta resolver el problema de conciliar las marcas de tiempo en L2 con las marcas de tiempo en L1 que existen en las transacciones de depósito.

Para ello, permite una breve ventana de tiempo para que la clasificación aplique libremente marcas de tiempo en transacciones L2 entre épocas.

La ventana de secuenciación es la secuencia de bloques L1 a partir de los cuales se pueden derivar épocas. En una ventana de clasificación, el primer bloque L1 número N contiene las "transacciones por lotes" de la época.​

La ventana de clasificación contiene bloques, que depende del tamaño de la ventana de clasificación: un parámetro de configuración de nivel de resumen fijo debe ser al menos 2; aumentarlo le dará al secuenciador más oportunidades para clasificar transacciones L2 en depósitos, reducirlo para secuenciar el tiempo más estricto ventana introducida por el servidor para enviar "transacciones por lotes". Se trata de un equilibrio entre la creación de oportunidades MEV y el aumento de la complejidad del software.

Una constante de protocolo llamada "deriva máxima del secuenciador" controla la marca de tiempo máxima que un bloque puede tener dentro de su época. Con esta deriva, el secuenciador puede tener problemas temporales para conectarse a L1. Permanezca activo.

Tubería de bifurcación de bloque

La "cadena L2 canónica" se puede procesar desde cero comenzando desde el estado de génesis L2, configurando el inicio de la cadena L2 en la primera época y luego procesando todas las ventanas de clasificación para determinar los lotes del secuenciador de acuerdo con el siguiente orden simplificado y secuencia correcta para tuberías de depósito:

prueba de fracaso

Después de que el secuenciador procese uno o más bloques L2, las salidas de los cálculos de transacciones ejecutados en estos bloques deberán escribirse en L1 para permitir la ejecución sin confianza de mensajes L2 a L1, como retiros, etc.

En Bedrock, la salida se procesa en forma de estructura de árbol, lo que minimiza el costo de probar cualquier dato capturado por la salida. Los proponentes envían periódicamente raíces de salida a L1 que sirven como raíces de Merkle para toda la "cadena canónica L2".

Las futuras actualizaciones de OP Stack deberían incluir una especificación de una variante a prueba de fallas con enlaces para incentivar a los proponentes a proponer raíces de salida correctas.

Para obtener detalles completos, lea la especificación del protocolo en la sección Propuesta de raíz de salida L2.

implementar

En Bedrock, OP Stack tiene que depender en gran medida de la separación de preocupaciones técnicas especificada de Ethereum al reflejar la separación entre la capa de ejecución y la capa de consenso de Ethereum.

Entonces Bedrock introdujo la separación de clientes de ejecución y nodos acumulativos de la misma manera.

Ejecutar cliente

Los clientes de ejecución son sistemas que ejecutan secuenciadores y otros tipos de operadores de nodos para determinar el estado de la cadena L2 canónica. También realiza otras funciones, como manejar transacciones entrantes y comunicaciones entre pares, así como procesar el estado del sistema para manejar consultas dirigidas a él.

Con Bedrock, OP Stack tiene como objetivo reutilizar la propia especificación del cliente de ejecución de Ethereum y muchas de sus operaciones de ejecución. En esta versión, Bedrock demostró una modificación extremadamente limitada del cliente Ethereum go-ethereum, con una diferencia de menos de 2000 líneas de código.

Hay dos razones fundamentales para la diferencia: procesar transacciones de depósito y cobrar tarifas de transacción.

Procesar transacciones de depósito

Para representar las transacciones depositadas en un resumen, se introduce un tipo de transacción adicional. La implementación de clientes que implementan este nuevo tipo de transacción se basa en el estándar de transacción de tipo EIP-2718.

Cobrar tarifas de transacción

Los rollups también tienen esencialmente dos tipos de tarifas relacionadas con las transacciones:

Uno es la tarifa del secuenciador. El costo de operar el secuenciador se calcula utilizando la misma tabla de gas y el mismo algoritmo EIP-1559 que Ethereum. Estas tarifas se utilizan en el protocolo para operar el secuenciador y fluctúan con el tiempo según la congestión de la red.

Otra tarifa por disponibilidad de datos. Los costos de disponibilidad de datos están asociados con la escritura de transacciones por lotes en L1 y están destinados a cubrir las tarifas del secuenciador por enviar transacciones por lotes a L1.

En Bedrock, la parte de disponibilidad de datos de la tarifa se determina en función de la información del contrato inteligente del sistema acumulativo llamado GasPriceOracle, que se basa en los atributos del bloque L1 insertados al comienzo de cada época durante el proceso de derivación del bloque. está actualizado.

Bedrock especifica que ambos costos se agregan en un campo cuando se usa JSON-RPC.

nodo acumulativo

A diferencia de Ethereum, Bedrock no tiene consenso de PoS. Por el contrario, el consenso de una "cadena L2 canónica" se define mediante derivación de bloques. El cliente de ejecución de OP Stack se comunica con un nuevo componente que implementa la bifurcación de bloques llamado nodo acumulativo, que se comunica con el cliente de ejecución utilizando exactamente la misma API del motor que Ethereum.

El nodo acumulativo es un componente sin estado responsable de derivar el estado del sistema leyendo datos y depósitos en L1. En Bedrock, los nodos acumulativos se pueden utilizar para secuenciar transacciones entrantes de usuarios u otros nodos acumulativos, o para validar transacciones confirmadas publicadas en L1 confiando únicamente en L1.

Los diversos usos de los nodos acumulativos se resumen a continuación:

Verificar la "cadena L2 canónica"

El modo más simple de ejecutar nodos acumulativos es simplemente seguir la "cadena L2 canónica". En este modo, el nodo acumulativo no tiene pares y se usa estrictamente para leer datos de L1 e interpretar los datos de acuerdo con las reglas del protocolo de derivación de bloques.

Uno de los propósitos de dicho nodo es verificar que las raíces de salida compartidas por otros nodos o publicadas en L1 sean correctas de acuerdo con la definición del protocolo. Además, los proponentes que tengan la intención de enviar raíces de salida a L1 pueden usar optimism_outputAtBlock para generar las raíces de salida que necesitan y devolver el hash de 32 bytes correspondiente a la raíz de salida L2.

Para hacer esto, los nodos solo deberían necesitar seguir el encabezado del bloque "finalizado". El término "finalizado" se refiere al consenso de Ethereum PoS (es decir, canónico y casi irreversible), y el encabezado del bloque L2 "finalizado" es el área de la "cadena L2 canónica" derivada únicamente del bloque L1 "finalizado". cabeza.

Participar en la red L2

La forma más común de utilizar un nodo acumulativo es participar en una red de otros nodos acumulativos, rastreando los procesos y el estado de L2. En este modo, el nodo acumulativo lee simultáneamente los datos y los depósitos que observa desde L1, los interpreta en bloques y acepta transacciones entrantes de usuarios y pares en la red de otros nodos acumulativos.

Los nodos que participan en la red pueden utilizar los encabezados de bloque seguros e inseguros de la L2 con la que se están sincronizando.

  • Los encabezados de bloque L2 seguros representan acumulaciones que se pueden construir en las que cada bloque (incluidos los encabezados) se puede derivar completamente de la cadena L1 de referencia antes de que L1 deba "finalizarse" (es decir, la reorganización aún puede ocurrir en L1);

  • Los encabezados de bloques L2 inseguros incluyen bloques inseguros que no se han derivado de L1. Estos bloques provienen del funcionamiento del nodo acumulativo como secuenciador o de una sincronización insegura con el secuenciador. Esto también se denomina encabezado de bloque "más reciente". En caso de desacuerdo, elija siempre el encabezado del bloque L2 seguro en lugar del encabezado del bloque L2 inseguro. Cuando ocurre un desacuerdo, la porción insegura de la cadena se reorganizará;

En la mayoría de los casos, para aplicaciones de usuario final, los nodos acumulativos en la red L2 harán referencia a encabezados de bloques L2 inseguros.

Clasificación de transacciones

La tercera forma de utilizar nodos acumulativos es ordenar transacciones. En este modo, los nodos acumulativos crearán nuevos bloques encima de encabezados de bloques L2 inseguros. Actualmente, sólo hay un secuenciador por red OP Stack.

El secuenciador también es responsable de publicar lotes de transacciones en L1 para que otros nodos de la red puedan sincronizarse desde allí.

dosificador

La función de un secuenciador es producir lotes de transacciones; para este propósito, los secuenciadores pueden ejecutar nodos acumulativos y tener procesos separados que ejecutan lotes leyendo desde el nodo acumulativo confiable en el que se ejecutan.

Esto garantiza que un componente complementario de OP Stack llamado controlador de transacciones por lotes lea los datos de la transacción del nodo acumulativo y los interprete como una transacción por lotes que se escribirá en L1; el componente del lote es responsable de leer y ejecutar mediante el secuenciador. El nodo acumula el encabezado del bloque L2 inseguro, crea transacciones por lotes y las escribe en L1.

Contrato puente estándar

Bedrock también incluye un par de contratos puente para los tipos de depósitos más comunes, llamado Contrato Puente Estándar. Estos contratos encapsulan contratos de depósito y retiro, proporcionando una interfaz simple para depósitos y retiros de tokens ETH y ERC-20.

Estos contratos puente están diseñados para que un lado del puente entre cadenas tenga el token nativo y el otro lado contenga un token envuelto que pueda gestionar la acuñación y la quema. Unir el token nativo implica bloquear el token nativo en el contrato y luego bloquear el token nativo en el puente entre cadenas. El otro lado acuña una cantidad igual de tokens encapsulados.

Para obtener más información, consulte la sección Especificación del protocolo estándar de puente entre cadenas.

Cañón

Si bien la construcción y la verificación a prueba de fallas se implementan en Cannon, la especificación del juego a prueba de fallas y la integración del desafío raíz de salida en el nodo acumulativo son parte de los hitos de especificación posteriores.

Otras lecturas

Especificación del protocolo

La especificación del protocolo define los detalles técnicos de OP Stack y es la fuente de información más actualizada sobre el funcionamiento interno del protocolo.

Diferencia de lecho de roca

Para conocer en profundidad las diferencias entre Bedrock y las versiones anteriores, consulte En qué se diferencia Bedrock.