Título original: "Introducción al mecanismo de inclusión de fuerza de Rollup"
Autor: NIC Lin, director de Taipei Ethereum Meetup
Ayer mismo sucedió algo que sorprendió a innumerables personas: Linea, la segunda capa de Ethereum lanzada por la empresa matriz de Metamask, Consensys, cerró proactivamente. Los funcionarios dijeron que el propósito de esto era reducir el impacto del incidente de piratería de Velocore. Y esto no puede evitar recordar a la gente el cierre anterior de BSC Chain (BNB Chain) bajo coordinación oficial para reducir las pérdidas por ataques de piratas informáticos. Siempre que la gente hable de este tipo de cosas, dudará del valor descentralizado que defiende Web3.
Por supuesto, la razón principal de los incidentes mencionados anteriormente radica más en la imperfección de la infraestructura misma, es decir, una descentralización insuficiente: si una cadena está lo suficientemente descentralizada, entonces no debería detenerse en un abrir y cerrar de ojos. Debido a la estructura única de la segunda capa de Ethereum, la mayor parte de la Capa 2 se basa en el secuenciador centralizado. Aunque en los últimos años ha habido cada vez más argumentos a favor de los secuenciadores descentralizados, considerando el propósito de la segunda capa y su estructura, probablemente lo hagamos. Se puede considerar que lo más probable es que el clasificador de Capa 2 no esté muy descentralizado y, al final, puede que no esté tan descentralizado como la cadena BSC. Si este es realmente el caso, ¿qué debemos hacer?
De hecho, para la segunda capa, el daño más directo causado por la no descentralización del clasificador reside en su resistencia y actividad a la censura. Si solo hay unas pocas entidades (Secuenciadores) que procesan transacciones, entonces tiene poder absoluto sobre si le debe servir: puede rechazarlo si así lo desea y es posible que usted no tenga otra opción. Cómo resolver el problema anticensura de la Capa 2 es obviamente un tema importante.
En los últimos años, las principales segundas capas de Ethereum han propuesto varias soluciones a los problemas anticensura, como Loopring y Degate, las funciones de retiro forzado y trampilla de escape de StarkEx, y Arbitrum y otras funciones de inclusión forzada de OP Rollup, estos métodos pueden crear controles. y saldos en el Sequencer bajo ciertas condiciones para evitar que rechace la solicitud de transacción de cualquier usuario sin ningún motivo.
En el artículo de hoy, NIC Lin de la Asociación Ethereum de Taipei da su propio relato, experimentó personalmente con las funciones de transacción anticensura de cuatro paquetes acumulativos principales y analizó en profundidad el diseño del mecanismo de Force Inclusion desde aspectos como el flujo de trabajo y los métodos de operación, que es muy importante para Ethereum. Es especialmente valioso para la comunidad y los grandes inversores con grandes activos.
Revisión de transacciones e inclusión forzada
La resistencia a la censura de transacciones (Resistencia a la censura) es muy importante para una cadena de bloques. Si la cadena de bloques puede revisar y rechazar arbitrariamente las transacciones iniciadas por los usuarios, no será diferente de un servidor Web2. La actual resistencia de las transacciones de Ethereum a la censura proviene de su gran cantidad de Validadores. Si alguien quiere revisar las transacciones de Bob y evitar que sus transacciones se carguen en la cadena, debe intentar sobornar a la mayoría de los Validadores de la red o enviar spam a toda la red. La red envía continuamente transacciones basura con tarifas de manejo más altas que Bob para aprovechar el espacio del bloque. De cualquier manera, el costo será muy alto.
Nota: En la estructura PBS actual de Ethereum, el costo de revisar las transacciones se reducirá mucho. Puede consultar la proporción de bloques que cooperan con la OFAC para revisar las transacciones de Tornado Cash. La resistencia actual a la censura se basa en verificadores independientes y retransmisores fuera de la OFAC y la jurisdicción gubernamental.
Pero ¿qué pasa con el resumen? Rollup no requiere una gran cantidad de validadores para garantizar la seguridad. Incluso si Rollup tiene solo una función centralizada (Secuenciador) para generar bloques, es tan seguro como L1. Pero la seguridad y la resistencia a la censura son dos cosas diferentes. Incluso si un Rollup es tan seguro como Ethereum, con un solo secuenciador centralizado, las transacciones de cualquier usuario pueden ser censuradas.
Sequencer puede negarse a procesar la transacción del usuario, lo que provoca que se retengan los fondos del usuario y no pueda salir del Rollup.
Mecanismo de inclusión de fuerza
En lugar de exigir que Rollup tenga una gran cantidad de secuenciadores descentralizados, es mejor utilizar directamente las capacidades anticensura de L1:
Originalmente, Sequencer empaqueta los datos de las transacciones y los envía al contrato acumulativo L1. Es mejor agregar un diseño al contrato para que los usuarios puedan insertar transacciones en el contrato acumulativo por sí mismos. Este mecanismo se llama "Forzar inclusión". Mientras Sequencer no pueda censurar a los usuarios en el nivel L1, no puede evitar que los usuarios inserten transacciones en L1 por la fuerza. De esta forma, Rollup puede heredar la resistencia a la censura de L1.
El secuenciador no puede revisar las transacciones L1 del usuario sin pagar un alto costo
¿Cómo deberían surtir efecto las transacciones forzosas?
Si se permite que las transacciones se escriban directamente en el contrato Rollup a través de Force Inclusion (es decir, con efecto inmediato), el estado de Rollup cambiará inmediatamente. Por ejemplo, Bob inserta una transacción de "transferir 1000 DAI a Carol" a través de Force Inclusion. Si la transacción entra en vigor inmediatamente, el saldo de Bob en el último estado será 1000 DAI menos y el saldo de Carol será 1000 DAI más.
Si Force Inclusion puede escribir directamente la transacción en el contrato acumulativo y entrar en vigor de inmediato, el estado cambiará de inmediato.
Si el secuenciador también está recopilando transacciones fuera de la cadena en este momento y envía el siguiente lote de transacciones al contrato acumulativo, puede verse afectado por las transacciones que Bob inserta a la fuerza y entrar en vigor de inmediato. Este tipo de problema debe evitarse tanto como sea posible, por lo que Rollup generalmente no hace que la transacción Forzar inclusión surta efecto de inmediato, sino que primero permite al usuario insertar la transacción en la cola de espera en L1 y entrar en el estado de "preparación". .
Cuando Sequencer empaqueta transacciones fuera de la cadena y las envía al contrato Rollup, elige si desea insertar las transacciones antes mencionadas en la secuencia de transacciones. Si Sequencer ha estado ignorando estas transacciones en el estado de "preparación", una vez finalizado el período de ventana, el usuario. puede forzar estas transacciones. Insertar en el contrato Rollup.
El secuenciador puede decidir cuándo "recibir incidentalmente" las transacciones que esperan en la cola
El secuenciador aún puede negarse a procesar transacciones en la cola de espera.
Si el secuenciador se niega durante mucho tiempo, después de un período de tiempo, cualquiera puede forzar la transacción en el contrato acumulativo a través de la función Forzar inclusión.
A continuación, presentaremos en orden la implementación del mecanismo Force Inclusion de cuatro Rollup conocidos, incluidos Optimism, Arbitrum, StarkNet y zkSync.
El mecanismo de inclusión de la fuerza del optimismo
Primero, presentaremos el proceso de depósito de Optimism. Este depósito no solo se refiere a depositar dinero en Optimism, sino que también incluye "enviar información enviada por los usuarios a L2". Después de recibir el mensaje recién depositado, el nodo L2 convertirá el mensaje en una transacción L2 para su ejecución y lo enviará al destinatario designado del mensaje.
Mensaje del usuario de Depósito L1 a L2
Contrato L1CrossDomainMessenger
Cuando un usuario desea depositar tokens ETH o ERC-20 en Optimism, interactuará con el contrato L1StandardBridge en L1 a través de la página web frontal, especificando cuánto depositar y qué dirección L2 recibirá estos activos.
El contrato L1StandardBridge pasará el mensaje al contrato L1CrossDomainMessenger del siguiente nivel. Este contrato se utiliza principalmente como un componente para la comunicación mutua entre L1 y L2 y L2StandardBridge en L2 a través de este componente de comunicación general para decidir quién puede emitir el token. en monedas L2, o quién puede desbloquear fichas de L1.
Si un desarrollador necesita desarrollar un contrato que comunique y sincronice el estado entre L1 y L2, entonces puede construirlo en el contrato L1CrossDomainMessenger.
El mensaje del usuario pasa de L1 a L2 a través del contrato CrossDomainMessenger
Nota: En algunas imágenes de este artículo, CrossDomainMessager está escrito como CrossChainMessager
Contrato Portal Optimismo
El contrato L1CrossDomainMessenger enviará el mensaje al contrato OptimismPortal de nivel inferior. Después del procesamiento, el contrato OptimismPortal generará un evento llamado TransactionDeposited. Los parámetros incluyen "la persona que envió el mensaje", "la persona que recibió el mensaje". y parámetros de ejecución relacionados.
Luego, el nodo Optimism L2 escuchará el evento Transacción depositada generado por el contrato OptimismPortal y convertirá los parámetros del evento en una transacción L2. El iniciador de esta transacción será el "remitente del mensaje" especificado en el parámetro del evento Transacción depositada. El receptor de la transacción es la "persona que recibe el mensaje" en los parámetros del evento, y otros parámetros de la transacción también se derivan de los parámetros de los eventos anteriores.
El nodo L2 convertirá el parámetro de evento Transacción depositada de OptimismPortalemit en una transacción L2
Por ejemplo, esta es una transacción en la que un usuario deposita 0.01ETH a través del contrato L1StandardBridge. Este mensaje y el ETH se transmiten hasta el contrato OptimismPortal (la dirección es 0xbEb5...06Ed) y luego se convierten en un L2. transacción unos minutos después:
El iniciador del mensaje es el contrato L1CrossDomainMessenger; el receptor es el contrato L2CrossDomainMessenger en L2; el contenido del mensaje es que L1StandardBridge recibió el depósito de 0,01 ETH. Después de esto, se activarán algunos procesos, como la emisión de 0,01 ETH adicionales a L2StandardBridge, que luego se transferirá a Bob.
Cómo activarlo específicamente
Cuando desee forzar una transacción en el contrato Rollup de Optimism, el efecto que desea lograr es permitir que una "transacción iniciada y ejecutada en L2 desde su dirección L2" se ejecute sin problemas. En este momento, debe usar su dirección L2. envía el mensaje directamente al contrato OptimismPortal (tenga en cuenta que el contrato OptimismPortal está en realidad en L1, pero el formato de dirección del OP es el mismo que el formato de dirección L1. Puede llamar directamente al contrato anterior utilizando la cuenta L1 con la misma dirección que el cuenta L2).
El "iniciador" de la transacción L2 convertida por el evento Transacción depositada generada por el contrato será su cuenta L2. En este momento, el formato de la transacción es el mismo que el de la transacción L2 normal.
En la transacción L2 convertida a partir del evento Transacción depositada, el iniciador será el propio Bob; el destinatario es el contrato Uniswap y irá acompañado del ETH especificado, al igual que el propio Bob inició la transacción L2.
Si desea llamar a la función Force Inclusion de Optimism, debe llamar directamente a la función depositTransaction del contrato OptimismPortal y completar los parámetros de la transacción que desea ejecutar en L2.
Hice un experimento simple de inclusión forzada. Esta transacción quería lograr una cosa: usar mi dirección para realizar autotransferencias en L2 (0xeDc1...6909) y adjunté un mensaje de texto de "forzar inclusión".
Esta es la transacción L1 en la que ejecuto la función depositTransaction a través del contrato OptimismPortal. Puede ver que en el evento Transaction Deposited arroja, tanto desde como hacia yo.
Los valores en la columna de Datos opaca restante codifican "cuánto ETH viene con la persona que llama a la función de transacción de depósito", "cuánto ETH el iniciador de la transacción L2 quiere enviar al destinatario", "GasLimit de transacción L2" y " a los datos del receptor L2" y otra información.
Después de decodificar la información anterior, obtendrá:
"Cuánto ETH adjuntó la persona que llamó a la Transacción de depósito": 0, porque no deposité ETH de L1 a L2;
"¿Cuánto ETH quiere enviar el iniciador de la transacción L2 al destinatario?": 5566 (wei)
"GasLimit para transacciones L2": 50000
"Datos para el receptor L2": 0x666f72636520696e636c7573696f6e, que es la codificación hexadecimal de la cadena "forzar inclusión"
No mucho después, apareció la transacción L2 convertida: una transacción L2 en la que me transfirí dinero a mí mismo, la cantidad era 5566 wei y los datos eran la cadena "forzar inclusión". Y puede notar que TxnType (tipo de transacción) en Otros atributos en la penúltima línea de la imagen muestra la transacción del sistema 126 (Sistema), lo que significa que esta transacción no fue iniciada por mí en L2, sino que fue depositada por la transacción L1. Los acontecimientos se transforman.
Transacción L2 convertida
Si desea llamar al contrato L2 y enviar datos diferentes a través de Force Inclusion, no es más que completar los parámetros uno por uno en la función de Transacción de depósito anterior. Solo recuerde usar la misma dirección L1 que su cuenta L2 para llamar. Función de transacción de depósito, de modo que cuando el evento depositado se convierta en una transacción L2, el iniciador sea su cuenta L2.
Ventana del secuenciador
El nodo Optimismo L2 mencionado anteriormente convierte el evento Transacción Depositada en una transacción L2. De hecho, este nodo Optimismo se refiere al Secuenciador. Después de todo, esto está relacionado con la secuenciación de transacciones, por lo que solo el Secuenciador puede decidir cuándo convertir el evento mencionado anteriormente. una transacción L2.
Al escuchar el evento TransactionDeposited, el secuenciador no necesariamente convierte el evento en una transacción L2 de inmediato. Puede haber un retraso. El valor máximo de este período se denomina SequencerWindow.
La ventana del secuenciador actual en la red principal de Optimism es de 24 horas, es decir, cuando un usuario deposita una suma de dinero de L1 o Force Incluye una transacción, el peor de los casos es que se incluirá en el historial de transacciones de L2 después de 24 horas.
Mecanismo de inclusión de fuerza de Arbitrum
En Optimism, la operación de Depósito de L1 arrojará un evento de Transacción Depositada, y el resto es esperar a que el Secuenciador recopile las operaciones anteriores pero en Arbitrum, las operaciones que ocurren en L1 (ahorrar dinero o enviar mensajes a L2, etc.) .) se almacenará en L1 en una cola, en lugar de simplemente generar un evento.
Al secuenciador se le dará un período de tiempo para incluir las transacciones en la cola anterior en el historial de transacciones L2. Si el secuenciador no hace nada cuando se acabe el tiempo, cualquiera puede completarlo para el secuenciador.
Arbitrum mantendrá una Cola en el contrato L1. Si el Secuenciador no procesa activamente las transacciones en la Cola, cuando se acabe el tiempo, cualquiera puede forzar que las transacciones en la Cola se incluyan en el historial de transacciones L2.
En el diseño de Arbitrum, las operaciones como los depósitos que ocurren en L1 deben pasar por el contrato de Bandeja de entrada retrasada. Como sugiere el nombre, las operaciones aquí se retrasarán para que entren en vigor. El otro contrato es la Bandeja de entrada del secuenciador, que es el lugar directo donde se realiza el depósito. El secuenciador carga transacciones L2 a L1. Cada vez que el secuenciador carga una transacción L2, puede sacar algunas transacciones pendientes de la bandeja de entrada retrasada y escribirlas en el historial de transacciones.
Cuando Sequencer escribe una nueva transacción, puede sacar la transacción de DelayedInbox y escribirla en conjunto.
Diseños complejos y amplios materiales de referencia.
Si los lectores consultan directamente el capítulo oficial de Arbitrum sobre Secuenciador e Inclusión de Fuerza, verán que menciona cómo funciona aproximadamente la Inclusión de Fuerza, así como algunos nombres de parámetros y nombres de funciones:
El usuario primero va al contrato DelayedInbox para llamar a la función sendUnsignedTransaction. Si el Sequencer no se incluye en aproximadamente 24 horas, el usuario puede llamar a la función forceInclusion del contrato SequencerInbox. Luego, el funcionario de Arbitrum no adjuntó el enlace de la función al documento del sitio web oficial, por lo que solo puede consultar la función correspondiente en el código del contrato usted mismo.
Cuando encuentra la función sendUnsignedTransaction, descubre que debe completar el valor nonce y el valor maxFeePerGas usted mismo. ¿Qué dirección es el nonce? ¿En qué red está maxFeePerGas? ¿Cuál es la mejor manera de completarlo? No hay ninguna referencia de archivo, ni siquiera Natpsec. Luego también encontrarás un montón de funciones de apariencia similar en el contrato Arbitrum:
SendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction, no hay ningún documento que indique la diferencia entre estas funciones, cómo usarlas, cómo completar los parámetros, ni siquiera Natpsec.
Intenta completar los parámetros y enviar la transacción con la mentalidad de intentarlo. Quiere usar prueba y error para ver si puede encontrar el uso correcto, pero descubre que todas estas funciones realizan AddressAliasing en su dirección L1. , lo que resulta en el error final en L2. El remitente al iniciar la transacción es simplemente una dirección diferente, por lo que su dirección L2 permanece inmóvil.
enviar mensaje L2
Más tarde, accidentalmente hice clic en la búsqueda de Google y descubrí que Arbitrum tiene una biblioteca de tutoriales, que contiene scripts que demuestran cómo enviar transacciones L2 desde L1 (que es lo que significa Force Inclusion), y las funciones enumeradas en ella no son ninguna de las funciones. mencionado anteriormente, pero ¿una función llamada sendL2Message y el parámetro del mensaje es en realidad una transacción firmada con la cuenta L2?
¿Quién hubiera sabido que el "mensaje enviado a L2 a través de Force Inclusion" sería en realidad una "transacción L2 firmada"? Y no hay documentación ni Natspec que explique cuándo y cómo utilizar esta función.
Conclusión: es problemático generar manualmente una transacción forzada de Arbitrum. Se recomienda seguir el tutorial oficial y ejecutar el SDK de Arbitrum. A diferencia de otros paquetes acumulativos, Arbitrum tiene documentación clara para desarrolladores y notas de código. El propósito y los parámetros de muchas funciones carecen de explicación, lo que hace que los desarrolladores dediquen más tiempo del esperado a acceder a ellos y utilizarlos. También le pregunté a la gente de Arbitrum sobre Arbitrum Discord pero no obtuve una respuesta satisfactoria.
Cuando pregunté en Discord, la otra parte solo me dijo que mirara sendL2Message. No quisieron explicar las funciones de otras funciones (incluso sendUnsignedTransaction mencionada en el documento Force Inclusion), para qué se usan y cómo usarlas. y cuándo usarlos.
Mecanismo ForceInclusion de StarkNet
Desafortunadamente, StarkNet actualmente no tiene un mecanismo ForceInclusion. Sólo hay dos artículos que tratan sobre la censura y la inclusión forzada en el foro oficial.
No se puede probar la transacción fallida
La razón anterior se debe en realidad a que el sistema de prueba de conocimiento cero de StarkNet no puede probar una transacción fallida, por lo que no se puede permitir la inclusión forzada. Porque si alguien incluye por la fuerza maliciosamente (o involuntariamente) una transacción fallida que no se puede probar, StarkNet se bloqueará directamente: porque después de que la transacción se incluye por la fuerza, el Prover debe probar la transacción fallida, pero no tiene forma de probarla.
StarkNet espera introducir la función de probar transacciones fallidas en la versión v0.15.0, y luego debería ser posible implementar aún más el mecanismo de inclusión forzada.
Mecanismo ForceInclusion de zkSync
La transmisión de mensajes L1->L2 de zkSync y el mecanismo de inclusión forzada se realizan a través de la función requestL2Transaction del contrato MailBox. El usuario especifica la dirección L2, los datos de llamada, la cantidad de ETH adicional, el valor L2GasLimit, etc. requestL2Transaction combinará estos parámetros en un L2. Luego, la transacción se coloca en la cola de prioridad (PriorityQueue). Cuando la transacción se empaqueta y se carga en L1 (a través de la función commitBatches), el secuenciador indicará cuántas transacciones sacar de la cola de prioridad y las incluirá en el registro de transacciones L2. .
zkSync es muy similar a Optimism en la forma de Force Inclusion. Utiliza la dirección L2 del iniciador (consistente con la dirección L1) para llamar a funciones relacionadas y completar los datos (llamado, datos de llamada, etc.), en lugar de como Arbitrum. en una transacción L2 firmada; pero el diseño es el mismo que Arbitrum, ambos mantienen una cola en L1, y el secuenciador extrae las transacciones pendientes enviadas directamente por el usuario de la cola y las escribe en el medio del historial de transacciones.
Si va a Deposit ETH a través del puente oficial de zkSync, como esta transacción, llamará a la función requestL2Transaction del contrato MailBox. Pondrá la transacción L2 de Deposit ETH en la cola de prioridad y generará un evento NewPriorityRequest. Debido a que el contrato codifica los datos de la transacción L2 en una cadena de bytes, es difícil de leer. Si observa los parámetros de esta transacción L1, verá que el destinatario de L2 en los parámetros también es el iniciador de la transacción (. porque se deposita en usted mismo), por lo que después de un tiempo, cuando Sequencer saca esta transacción L2 de la cola de prioridad y la incluye en el historial de transacciones, se convertirá en una transacción transferida a sí misma en L2, y la cantidad de la transferencia es el depósito del iniciador de la transacción en L1. La cantidad de ETH transportada en la transacción ETH.
En la transacción L1Deposit, el iniciador y el receptor de la transacción son 0xeDc1...6909, la cantidad es 0.03ETH y los datos de llamada están vacíos.
Habrá una transacción de 0xeDc1...6909 transfiriéndose dinero a usted mismo en L2. El tipo de transacción (TxnType) es 255, que es una transacción del sistema.
Luego llamé directamente a la función requestL2Transaction de zkSync y envié una autotransferencia tal como lo hice antes cuando experimenté con la función de transacción forzada del OP: sin ningún ETH, los datos de llamada trajeron la codificación HEX de la cadena de "inclusión forzada".
Luego se convierte en la última transacción de L2 hacia sí mismo. Los datos de llamada son la cadena hexadecimal de "forzar inclusión": 0x666f72636520696e636c7573696f6e.
Cuando el secuenciador saca la transacción de PriorityQueue y la escribe en el historial de transacciones, se convertirá en la transacción L2 correspondiente en L2.
A través de la función requestL2Transaction, los usuarios pueden usar la cuenta L1 con la misma dirección L2 para enviar información en L1, especificando el destinatario L2, el monto de ETH adjunto y los datos de la llamada. Si el usuario desea llamar a otros contratos con Datos diferentes, lo mismo se hace completando los parámetros en la función requestL2Transaction uno por uno.
No existe ninguna función que permita a los usuarios forzar la inclusión
Aunque después de que la transacción L2 se coloque en la cola de prioridad, el período de espera para que la transacción L2 se incluya en el secuenciador se calculará de manera incidental. Sin embargo, el diseño actual de zkSync no tiene una función de inclusión forzada que los usuarios puedan aplicar, que es. equivalente a sólo la mitad de un juego. Es decir, aunque hay un "período de espera para la inclusión", en realidad se trata de "ver si el secuenciador quiere recibir ingresos": el secuenciador puede esperar hasta la fecha de vencimiento antes de recibir la transacción, o nunca podrá recibir ninguna transacción. en la cola de prioridad.
En el futuro, zkSync debería agregar funciones relacionadas para que los usuarios puedan forzar la inclusión de la transacción en el historial de transacciones L2 cuando el período de validez de los ingresos haya pasado pero no se haya incluido en el secuenciador. Este es un mecanismo de inclusión forzada verdaderamente efectivo.
Resumir
L1 se basa en una gran cantidad de validadores para garantizar la "seguridad" y la "resistencia a la censura" de la red. Rollup utiliza una pequeña cantidad o incluso un solo secuenciador para escribir transacciones, y su resistencia a la censura es aún más débil. Por lo tanto, Rollup necesita un mecanismo de inclusión forzada que permita a los usuarios omitir el secuenciador y escribir transacciones en el historial para evitar que el secuenciador las revise y haga imposible usar y retirar fondos del rollup.
Force Inclusion permite a los usuarios forzar que las transacciones se escriban en el historial, pero en el diseño, deben elegir si la transacción se puede insertar inmediatamente en el historial y entrar en vigor de inmediato. Si se permite que las transacciones entren en vigor de inmediato, tendrá un impacto negativo en el secuenciador, porque las transacciones que esperan ser recibidas en L2 pueden verse afectadas por transacciones recibidas por la fuerza en L1.
Por lo tanto, el mecanismo actual de Force Inclusion de Rollup primero pondrá las transacciones insertadas en L1 en un estado de espera y le dará al secuenciador un período de tiempo para reaccionar y elegir si incluye estas transacciones pendientes.
Tanto zkSync como Arbitrum mantienen una cola en L1 para administrar las transacciones de L2 enviadas por los usuarios desde L1 o los mensajes a L2. Arbitrum se llama DelayedInbox; zkSync se llama PriorityQueue;
Sin embargo, la forma en que zkSync envía transacciones L2 es similar a la de Optimism. Utiliza la dirección L2 para enviar mensajes a L1. Después de convertir a una transacción L2, el iniciador será la dirección L2. La función de Optimism para enviar transacciones L2 se llama depositTransaction; zkSync se llama requestL2Transaction. Arbitrum genera y firma una transacción L2 completa y luego la envía a través de la función sendL2Message. Arbitrum restaurará al firmante a través de la firma en L2 como el iniciador de la transacción L2.
StarkNet actualmente no tiene un mecanismo de inclusión forzada; zkSync es como un medio conjunto de inclusión forzada: hay una cola prioritaria y cada transacción L2 en la cola tiene un período de validez de inclusión, pero este período de validez actualmente es solo para decoración. El secuenciador puede elegir no incluir ninguna transacción L2 en PriorityQueue