并行执行
Monad 以并行方式执行交易,乍看起来,这似乎有着与以太坊不同的执行原语。实际并非如此,Monad 区块与以太坊区块相同:是一组线性有序的交易集,区块中执行交易的结果在 Monad 和以太坊中是相同的。
乐观执行
在基础层面上,Monad 使用乐观执行,这意味着 Monad 会在区块中较早的交易完成之前开始执行当前交易。有时(但并不总是),这会导致执行错误。
思考两笔交易(在区块中按此顺序排列):
交易1
:读取并更新账户 A 的余额(例如,接收来自账户 B 的转账)。交易2
:仍会读取和更新账户 A 的余额(例如,向账户 C 转账)。
如果这些交易是并行执行的,而 交易2
在 交易1
完成之前就开始执行,那么它为账户 A 读取的余额可能与按顺序执行时的余额不同, 这可能导致执行错误。
乐观执行解决这个问题的方法是跟踪 交易2
执行时的输入,并将其与 交易1
的输出进行比较。如果两者不同,我们就检测到 交易2
在执行时使用了错误的数据,此时需要使用正确的数据再次执行。
在 Monad 并行执行交易的同时,每个交易的更新状态都是按顺序"合并”的,以便检查是否有上述问题出现。
于此相关的计算机科学研究有乐观并发控制(OCC)和软件事务内存(STM)。
乐观执行的影响
在乐观执行的朴素方式中,直到区块中的早期交易完成后,我们才会发现交易需要再次执行。此时,所有早期交易的状态更新都已合并,因此该交易不可能再次因乐观执行而失败。
在执行交易的过程中,有些步骤并不依赖于状态。例如,重复签名是一项昂贵的计算,再次执行交易时,这项工作无需重复。
此外,由于合并失败而再次执行交易时,访问的账户和存储往往不会改变,因为状态仍缓存在内存中,因此这项昂贵的工作不需要重复操作。
执行调度
乐观执行的朴素方式会在处理器有可用资源时尝试开始执行下一笔交易,区块中可能存在相互依赖的长"链“交易,并行执行这些交易会导致大量故障。
提前确定交易之间的依赖关系,可以让 Monad 只在前序交易完成后才调度交易执行,从而避免资源浪费。Monad 采用静态代码分析技术,可以尝试做出这样的预测。在良好状态下,Monad 可以提前预测出许多依赖关系;在极端情况下,Monad 会退回到朴素执行方式。
未来工作
探索更多避免重复执行交易的方法,并实现它们。
最后更新于