异步执行是Monad提升性能的关键技术之一,目前大部分公链都是同步执行机制,Solana虽然提出并持续更新了相关方案,但由于复杂度较高、影响面较大而尚没有实现。什么是异步执行同步执行以以太坊为例,出块节点需要先执行打包进入区块的所有交易,更新本地状态树、交易树和回执树,这3棵MPT树的根需要包
异步执行是Monad提升性能的关键技术之一,目前大部分公链都是同步执行机制,Solana虽然提出并持续更新了相关方案,但由于复杂度较高、影响面较大而尚没有实现。
以以太坊为例,出块节点需要先执行打包进入区块的所有交易,更新本地状态树、交易树和回执树,这3棵MPT树的根需要包含在区块头中,验证节点接收到出块节点广播的区块,同样需要先执行该区块中的所有交易,更新3棵树,验证树根和区块头是否一致,如果一致,验证通过并进行共识投票,否则拒绝该区块。可以看到共识和执行是耦合的,需要先执行才能共识,换一个角度理解就是,节点共识的不仅是区块中的交易排序,还有执行结果和最终状态。
异步执行就是把共识和执行解耦,先对区块交易排序进行共识,然后异步执行交易。这样做的好处主要有:
异步执行方案可行的主要依据是:
对比以太坊,出块节点将选择的交易排序打包成区块广播给其他验证节点,验证节点收到区块后进行一些基础验证,例如交易签名是否有效、区块gas是否超过限制等,然后进行投票共识,当这个区块最终确认后才会开始执行。 如果Monad节点共识的只是交易排序,那么怎么保证账户状态的一致性呢?Monad采用了延迟默克尔根,出块节点出块时包含的不是当前区块交易执行后生成的状态树根,而是往前D个区块对应区块的状态树根,如图:
这个D是一个系统级参数,testnet设置为3。如下图,不难理解,这个D的最小值应该取所有交易能够最快被执行的延迟slot个数,这个值为3,因为MonadBFT共识需要3轮出块周期才能确认。更进一步,如果D设置越大,交易还没被执行的概率越小,延迟默克尔根准确的概率越高,节点状态不一致的风险也越小,但是交易确认更慢,影响用户体验;反之如果D设置越小,交易确认越快,但节点状态不一致风险越高,最终影响性能。
这个延迟默克尔根是要被共识的,如果出块节点作恶,篡改执行结果,诚实节点会拒绝区块,如果是诚实节点执行错误(理论上应该不存在,但不排除节点可能受到攻击或者其他干扰,如果出现不一致,可能会因为拒绝最终确认的区块脱离共识才察觉,需要等项目开源后确认),需要回滚到N-D-1区块尝试重新执行,直到状态一致,否则会脱离共识,受到slash或者被踢出验证网络。
不难看出,和用户和开发者早已习惯的确认机制不同,区块的最终确认不代表交易已经被执行,状态已经更新,因此不能根据区块是否确认进行状态确认。按Monad官方文档所说的通过牺牲一部分严密性来提升吞吐量。这给一些应用场景带来了复杂性,例如轻节点,需要使用延迟默克尔证明,对于MEV,因为当前状态不是最新,而且因为出块周期很短,导致构建者没有充足时间和最新状态来进行模拟。另外一个可能不稳定的因素就是没有经过长时间的公网检验,共识执行分离可能会引入新的攻击向量。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!