并行区块构建
- 原文链接:writings.flashbots.net/parallel-bui...
- 译者:AI翻译官,校对:翻译小组
- 本文链接:learnblockchain.cn/article…
在这篇博客文章中,我们介绍了一种新的区块构建方法:并行区块构建。与传统的顺序构建算法将所有交易视为潜在冲突不同, 并行区块构建认识到区块中的大多数交易实际上是独立的。当用户用 ETH 兑换 USDC 时,这并不影响某人铸造 NFT——那么为什么要顺序处理它们呢?
并行构建不会这样做。它提前识别出哪些交易组确实存在冲突,然后并行处理这些冲突。并行处理为我们带来了几个关键好处:
这篇文章描述了我们的开源实现并分享了测试的早期结果:在生产环境中,它已经能够在 19% 的时间内构建出更有价值的区块,而在回测中显示出高达 50% 的潜力。
让我们深入了解它是如何工作的。
感谢 Robert Anessi 提供的许多启发性想法,以及 Daniel 和 Vitaly 的贡献。
上图是我们的高层架构
下面我们将详细介绍每个组件。
第一步,冲突识别,隔离可能基于共享存储读取和写入而冲突的交易组。我们的实现使用 ConflictFinder
快速通过维护存储槽和交易组之间的映射来分组交易。对于每个交易,它识别潜在冲突,并根据冲突的数量采取三条路径之一:
结果是一组 ConflictGroup
结构,每个结构包含其成员交易以供解决。
/// ConflictGroups 描述了一组冲突的订单.
pub struct ConflictGroup {
pub id: usize,
pub orders: Arc<Vec<SimulatedOrder>>,
pub conflicting_group_ids: Arc<HashSet<usize>>,
}
一旦定义了冲突组,ConflictTaskGenerator
生成优先级任务以解决它们。我们并不是采用单一策略,而是同时探索多种方法,这带来了几个好处:
这是我们用来定义每个任务的结构
/// ConflictTask 提供一个用于解决特定 [ConflictGroup] 的任务,使用特定的 [Algorithm].
pub struct ConflictTask
{
pub group_idx: usize,
pub algorithm: Algorithm,
pub priority: TaskPriority,
pub group: ConflictGroup,
pub created_at: Instant,
}
/// 定义任务的优先级
pub enum TaskPriority {
Low = 0,
Medium = 1,
High = 2,
}
/// Algorithm 提供用于解决 [ConflictGroup] 的算法.
pub enum Algorithm {
Greedy, // 最大 gas 价格,最大利润
ReverseGreedy,
Length,
AllPermutations,
Random { seed: u64, count: usize },
}
这种灵活的方法使我们能够尝试多种算法并有效地处理它们的优先级,在快速和全面结果之间取得平衡。
冲突解决利用一组工作线程,每个线程从共享任务队列中提取任务。每个线程并行执行其任务的指定算法,然后将结果写入共享的“最佳结果”存储。这里的一个关键优化是 模拟缓存:在评估相同交易的不同排序时,我们重用先前计算的结果以减少冗余。
/// 这不是实际代码,但它展示了核心过程
self.thread_pool.spawn(move || {
while !cancellation_token.is_cancelled() {
if let Some(task) = task_queue.pop() {
// 处理任务并找到最佳排序
let result = process_task(task);
result_sender.send(result);
}
}
});
...
/// 在并发环境中收集和管理每组的最佳结果.
pub struct ResultsAggregator {
result_receiver: std_mpsc::Receiver<(GroupId, (ResolutionResult, ConflictGroup))>,
best_results: Arc<BestResults>,
}
/// 共享最佳结果实例
pub struct BestResults {
pub data: DashMap<GroupId, (ResolutionResult, ConflictGroup)>,
pub version: AtomicU64,
}
ResultsAggregator
监控工作线程发送的结果,并仅保留每个冲突的最高价值解决方案。
在冲突解决后,BlockBuildingResultAssembler
将每个冲突组的最佳解决方案与独立交易结合起来,创建最终区块。这个步骤很简单:由于冲突已经解决,组装过程涉及的排序约束最小,我们可以简单地将组合并在一起。
对并行构建器的测试产生了令人鼓舞的结果。
在高 MEV 环境中的回测
在高 MEV 日(复杂有序区块更可能出现)中,对 2000 个区块进行回测,发现并行构建器构建出比仅使用贪婪算法更好的区块的概率为 50%,产生了 40 个额外的 ETH 价值。有趣的是,这些额外价值大多集中在少数几个区块中:前 20 个区块产生了 25 个额外的 ETH,前 75 个区块产生了 35 个 ETH。
如果我们查看按区块价值百分比增长的前几个区块,可以观察到类似的分布,少量区块中有大量集中,而价值急剧下降。
这种模式表明,少量区块从更复杂的排序中显著受益,而大多数区块则获得很少或适度的收益。
最后,我们观察到我们的实现还有改进的空间:一些交易被贪婪算法包含,而并未被并行构建器包含。理论上这不应该发生,因此这明显表明某处存在 bug。
在低 MEV 环境中的回测
在低 MEV 环境中对 2000 个区块进行回测,60% 的区块中并行构建器的结果优于任何贪婪算法。然而,这些改进带来的额外价值非常有限。最多每个区块有 0.05 个额外的 ETH,但具有额外价值的中位数区块的盈利能力低于 0.005 ETH。这些结果表明,当活动较少时,贪婪算法是足够的,这在直觉上是合理的。
来自实时生产(低 MEV)环境的结果
在生产部署的第一周——一个相对低 MEV 的时间段——并行构建器构建更好区块的频率为 19%。对于一小部分区块,它的盈利能力更高:在 3% 的区块中,并行构建器的价值比下一个最佳算法高出 100%!这大致与我们在回测中看到的结果相匹配,其中更好的合并不成比例地影响少量区块。
然而,并行构建器仅在 20% 的时间内生成更好区块而不是 50-60% 的事实表明,实时版本还有改进的空间。直觉上这可能是由于寻找冲突和异步通信的延迟开销,但需要更多分析。
总体而言,我们认为这些结果显示了这种区块构建模型的巨大潜力,特别是随着更复杂和专门构建的合并算法的实施。
在这个架构上有许多令人兴奋的未来工作方向:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!