所有非投票交易,都可以异步计算。
撰文:Anatoly Yakovenko,Solana 首席执行官 ( 联合创始人兼 CEO)
编译:1912212.eth,Foresight News
Solana 目标是在符合物理法则下,尽快同步单一、无需许可的全球状态机。我相信能够实现这一目标的架构将如下所示:
- 大量全节点,超过 10,000 个(N > 10,000)
为了使网络作为全球状态机运行,它需要支持众多全节点。Turbine 已经证明在现代硬件和网络上,向非常庞大的网络进行快速复制是可扩展的。
- 大量区块生成领导者,超过 10,000 个(N > 10,000)
- 并发领导者同时产生区块,随机选择在 4 到 16 的范围内。
并发领导者使网络能够在全球范围内拥有多个位置来排序用户交易。可以减少用户与网络之间的距离,消除了在交易被添加到链上之前,需要全节点验证的需求。
- 区块时间为 120 毫秒
短区块时间创建了快速的最终性点,增强了抗审查能力,提高了用户体验,减少了重新排序交易的窗口,并整体加速了网络。
- 在核准分委员会中的一些投票共识节点,数量在 200 到 400 之间,随机选择领导者,每个 epoch 4 到 8 个小时轮换一次。
共识对于选择分叉至关重要,而分叉是由于网络分区而发生的。200 个或更多节点的样本将在统计上代表网络中的所有主要分区,并紧密匹配它们的实际分布。因此,不需要所有全节点投票,200 个已经足够了。将核准限制为分委员会减少支持 120 毫秒区块所需的内存和网络带宽。减少区块时间自然增加了每秒发送的投票数,对为共识分配的资源造成了一定的压力。
120 毫秒区块中的真正挑战是回放所有用户交易。由于网络是无需许可的,保证具有可靠时间执行任意用户代码的同质化执行环境是极其困难的。虽然存在可能性,但只能通过限制用户交易的可用计算资源,并确保每个节点都超配到最坏情况的情况。
不过,对于投票支持分叉或在分叉上构建的领导者的共识节点,没有理由执行完整状态。为了保持共识节点和领导者的核准同步,状态只需要在每个期间计算一次。
异步执行
动机
同步执行要求所有投票和创建区块的节点在任何区块中都要超高配置,以确定最坏情况的执行时间。异步执行是极少数几乎没有权衡的情况之一。共识节点在投票之前可以执行较少的工作。工作可以聚合和批处理,使其在执行时高效,没有任何缓存丢失。它甚至可以在与共识节点或领导者完全不同的机器上执行。希望进行同步执行的用户可以分配足够的硬件资源,以便实时执行每个状态转换,而无需等待整个网络。
鉴于应用程序和核心开发者的多样性,值得计划每年进行一次主要协议更改。如果必须选择一个,我的选择将是异步执行。
概述
目前验证器迅速在每个区块上重复所有交易,并仅在为区块计算完整状态后才进行投票。此提案的目标是将对分叉的投票决策与计算区块的完整状态转换分开。
在核准中进行投票的验证器只需要选择分叉;他们根本不需要执行任何状态。只有在每个 epoch,他们才需要状态来计算下一个核准。
投票程序进行了调整,以便可以独立执行。节点仅在投票之前执行投票程序。由于验证器不占用太多空间,内存要求应该相对较小。由于投票具有非常可预测的执行时间,投票程序的执行应该几乎没有任何抖动。
所有非投票交易都可以异步计算。这允许重播批量执行所有非投票交易,预取并提前对所有程序进行 JIT,几乎消除了所有缓存丢失。长期目标是只有需要实时低延迟完整状态计算的机器会为此任务进行配置。据推测,用户将为额外的硬件支付费用。
一旦分离了分叉选择和状态执行,加快进度就变得更加容易:
- 异步执行
- 每个 epoch 轮换固定数量的投票委员会
- 200 毫秒的区块时间
由于用户交易重播不能阻塞分叉选择,减小区块时间时,波动性不再是一个问题。唯一需要考虑的是,在 200 毫秒时验证器的投票速率加倍。对核准如何计算配额进行相当直接的更改,将使我们能够将核准的大小固定为 200 或 400,或者任何看起来合适的数字。
将执行与共识完全分开也是自然而然的。重新启动只需要检查固定大小核准中投票程序账户的共识节点,将会更加快速。
实际上,我相信确认时间将会提高,因为核准的绝大多数会尽可能快地进行投票,而在这些投票传播的同时,向用户提供完整状态执行结果的节点可以同时执行交易。因此,我们今天看到的任何重播抖动都应该与投票网络传播同时发生。
投票
- 投票账户必须拥有足够数量的 SOL,以覆盖 2 个 epoch 的投票。
- 投票交易必须是简单。非简单的投票必定执行失败。区块生成者应该放弃复杂的投票。
- 从投票账户中提取 SOL 被允许,只要余额不降到低于 1 个 epoch 的投票。
- 为了清零所有的 lamports,Vote CLOSE 指令必须要求完整的时代经过。投票账户在时代 1 被标记为 CLOSE,但只能在时代 2 时进行 CLOSE。CLOSE 允许提取所有的 SOL,并删除投票账户。一旦一个账户被标记为 CLOSE,它只能被完全删除,不能重新打开。
- 投票包含一个 VoteBankHash,而不是常规的 BankHash。
领导者调控和核准
只有验证器满足以下条件:
- 质押量 > X
- 以及 SOL > 2 个时代的投票
- 且没有标记为 CLOSE
才能进入领导者调度并计入核准。对于版本 2,我们可以将 LeaderSchedule 与 Quorum 分开,它们各自的要求不必相同。
VoteBankHash 计算
与计算所有交易的 Bankhash 不同,验证器仅为与 LeaderScheduler 中的验证器相关的简单投票交易计算 VoteBankHash。所有其他交易都被忽略。在重播所有投票后,VoteBankHash 以与当前 BankHash 相同的格式计算。
VoteBankHash 应该累积先前的 VoteBankHash,而不是完整的 BankHash。
BankHash 计算
对于所有 optimistic 确认的区块(可配置为所有区块),验证器开始计算 UserBankHash,其中包括所有状态转换,但不包括 VoteBankHash 计算中已考虑的交易。
然后,BankHash 是从(VoteBankHash,UserBankHash)的累积中派生出来的。前 99.5% 的验证器每 100 个时隙将 BankHash 作为其投票的一部分提交。虽然每 100 个时隙提交一次,但它在每个时隙都进行计算。值得注意的是,对于一小部分节点始终在 gossip 中提交 BankHash 作为没有观察到非确定性的软信号可能是值得的。
如果少于 67% 的验证器提交完整的 BankHash 计算,领导者应将可用的用户交易和可写账户的区块空间减少 50%。这个措施是为了保护链免受可能过度增加重播时间的滥用。
BankHash 应该累积先前的 BankHash。
去银行领导者
在区块创建期间,领导者很可能无法获取用于创建区块的状态,并且在区块创建期间执行所有交易并不理想。
- 领导者维护付费账户余额的缓存。
- 如果一个付费账户被用作系统转账的源,或者作为可写账户与系统程序一起传递给另一个程序,那么该付费账户余额被设置为 0。
- 根据声明的计算单元(CUs)将区块按本地费用优先级排序打包,直到区块被填满。
- 从付费账户余额缓存中扣除费用。
- 付费账户余额缓存由 BankHash 计算进行补充。
网络因交易垃圾邮件失败而产生的成本相对较小,仅包括存储在存档中的字节和传播区块中的交易所需的带宽。
鉴于验证者已经寻求最大化自己的收益,他们有充分的激励来维护一个准确的付费账户缓存。此外,如果没有设置惩罚机制,长期来看,任何网络中的任何人都可以轻松地为缓存提供服务。在服务器损坏的情况下,无银行领导者操作者应该能够轻松切换或从多个来源进行采样。
这意味着由于验证者追求最大化收益的动机,他们将努力维护准确的付费账户缓存。在没有惩罚机制的情况下,这个缓存可能会长期由网络中的任何节点提供服务。此外,如果服务器发生故障,无银行领导者的操作者应该能够轻松地进行切换或从多个来源进行采样。
权衡
主要权衡在于为用户状态提供服务的全节点缺乏确认的签名,以确认其提供状态与核准的其余部分完全一致。状态的唯一权威解释应该保持不变,即使每个交易在分类帐中按顺序重播。任何性能优化都不应改变结果。因此,一旦分叉被最终确定,就只剩下正确的状态可以计算,只要运行时实现没有错误。
旨在可靠提供状态的节点应该运行多台机器和客户端,如果状态执行中出现差异,它们应该停止操作。这本质上是运营商今天应该做的事情,因为仅仅依赖于网络的其余部分引入了正直的大多数假设。
用户还可以签署断言 BankHash 或触发中止的交易。只有在计算的确切 BankHash 与由 RPC 提供者提供给用户的 BankHash 完全相同时,网络的其余部分才会执行这些交易。
长期无状态共识节点路线图
具有固定大小核准的网络只需要非常小的状态量来启动。核准本身及其质押权重以及所有投票账户余额。这是一个非常小的内存量和一个可以快速分发并在重新启动时快速初始化的微小快照文件。
如果核准与全节点不一致,正在同时跟踪核准和状态的全节点将停止运行。这意味着,如果核准与状态发生分歧,交易所、法币通道、RPC、桥接等都将停止运行。这只需要极小比例的有缺陷的无状态共识节点。
无银行领导者可以依赖于多个全节点的样本来提供付费账户的初始余额缓存。即使有缺陷,结果将是区块中的垃圾邮件而不是共识失败。操作者应该能够监控他们的领导者健康状况以及他们注入到区块中的垃圾邮件的百分比,并迅速响应故障。