Esta es una introducción a la ejecución asíncrona: cómo la hicimos funcionar en Monad, por qué EIP-7702 la rompió y cómo solucionarla Para contextualizar, la ejecución asincrónica ha estado en Monad desde que los clientes de consenso y ejecución se conectaron entre sí. La ejecución asíncrona permite que la ejecución retrase el consenso en un número fijo de bloques desde una perspectiva de interacción. La mayoría de las cadenas de bloques tienen consenso intercalado. Es decir, la ejecución ocurre antes del consenso, lo que significa meter la ejecución en un presupuesto de tiempo que es una pequeña fracción del tiempo de bloque (el resto está ocupado por mensajes de todo el mundo, también conocido como consenso). Esto limita inherentemente el gas por segundo del sistema. Los L2 evitan esto al no tener consenso en absoluto. Pero queremos el comportamiento de una L1 distribuida y descentralizada que mantenga un alto rendimiento. La ejecución asíncrona nos permite evadir este problema moviendo la ejecución fuera de la ruta de acceso activa del consenso. En cambio, el consenso y la ejecución ocurren en carriles paralelos. El consenso sobre el bloque 2 se produce mientras la ejecución del bloque 1 se ejecuta en paralelo. Sin embargo, todavía debe haber un acuerdo entre el consenso y la ejecución. Específicamente, ese acuerdo es: la ejecución solo puede retrasar el consenso hasta en k bloques, porque las propuestas de bloques contienen una raíz de Merkle retrasada. Además, el consenso es bloques de construcción con una visión retrasada del estado (retrasada por k bloques). Esto significa que existe el peligro de que el consenso incluya una transacción de un remitente que, en el momento en que ejecutamos, resulta tener un saldo vacío. Sería malo si el protocolo permitiera que esto sucediera, porque abriría un vector de denegación de servicio (DOS). Por lo tanto, para abordar este problema y habilitar de forma segura la ejecución asíncrona, el cliente de consenso de Monad calcula el débito MON máximo de cada transacción como MON_spent = gas_bid * gas_limit + valor. El cliente de consenso mantiene una lista actualizada de los saldos de cuenta disponibles para cada remitente después de deducir MON_spent por cada transacción que enviaron. A partir de ese saldo corriente, el cliente de consenso solo incluye transacciones si puede estar seguro de que la transacción se puede pagar. Este es un enfoque pesimista para la construcción de bloques, ya que no tiene en cuenta la posibilidad de que las cuentas ganen saldo de una transferencia. Permítanme explicar lo que quiero decir con un ejemplo. Supongamos que la cuenta de Alice tiene 100 MON. Luego, las siguientes 3 transacciones se incluyen en el bloque 1000: Tx 1: Alice envía 20 MON a Bob, lo que cuesta 1 MON en tarifas Tx 2: Alice gasta 70 MON comprando una memecoin, con un costo de 1 MON en tarifas...