Flow Community Rewards are here. Earn points for engaging in the ecosystem, spend points on prizes. Learn more.
技术愿景

核心协议愿景

最后更新2023 年 9 月 14 日

动机+原则

在我们这个高科技的现代社会里,计算无处不在,但对于普通人来说,除了预定义的使用情况外,使用起来却出奇地麻烦。就我个人而言,我买了几台树莓派(Raspberry Pis)和其他迷你电脑,目的是创造性地将家里一些合理有用但并非必需的东西自动化。比如为我妻子的蜂鸟喂食器控制加热,防止它在冬天被冻坏。但最终,多个项目都没能成功,因为保持树莓派的更新和运行需要一些定期维护的时间。

我们缺少的是一个安全的计算和数据存储平台,在这个平台上,各种简单的软件应用程序可以轻松地进行交互,我可以添加定制的软件扩展或新组件,而无需设置和维护我的程序运行平台。 

通过互联网与邻居共享自己的照片或其他数据非常容易,无需安装网线。除了业余爱好者和专业人士外,大多数人都无法运行自己定制的计算,因为这需要对专用硬件进行艰难的设置。在未来,设备将越来越智能,并能适应其拥有者的个人生活模式,我们将需要一些计算平台,让个人可以轻松组成自己的协调和控制应用程序,并与其他人的应用程序对接。现在,想象一下互联网的延伸,增加适度的计算和数据存储能力。

全球分布

全球分布是必要的,因为互联网作为全球通信网络的效用主要取决于其覆盖范围。由不同地域的组织分散运作,是互联网不为特殊利益所左右的基础,因此也是其作为全球普遍使用的基础设施的基础。

由于互联网已经提供了交换数据的手段,附加的计算和数据存储服务可以在地理或业务上集中,云提供商就是这种情况。然而,在过去的几年里,我们已经认识到了多样性和复原力的价值:地理多样性能增强抵御自然灾害、战争、流行病和专制政府的复原力;运营多样性能增强抵御技术漏洞或错误以及狭隘的企业或政治利益的复原力。例如,由于对 StarLink 卫星网络集中化的担忧,欧盟刚刚决定开发自己的版本 IRIS²[0]。因此,我们认为,由全球分布的组织团体进行分散式操作,对 Flow 的弹性和公正性至关重要。尤其是后者,对于大规模采用而言至关重要,因为我们不必担心访问限制会被用于经济或政治权力斗争。

拜占庭容错

用技术术语来说,如果一个系统在某些组件恶意入侵的情况下仍能正常运行,那么这个系统就被称为 "拜占庭容错系统"[BFT][1,2]。就互联网而言,当你在大西洋彼岸发送信用卡信息进行网上购物时,你不必相信深海电缆的运营商。即使深海电缆运营商受到威胁并试图篡改您的数据,普通互联网协议也能保证数据的完整性(只要您的浏览器遵循最佳实践)。因此,我将互联网归类为 BFT 数据传输网络。然而,附加计算和数据存储服务通常不是 BFT,这限制了它们的弹性。

同样,"BFT "对 Flow 也至关重要,它允许不同业务部门在全球范围内开展协作,而不会产生单点故障。

可高效扩展的通用计算平台

作为 通用计算的高效可扩展平台是最后一组要求。你在 Flow 上拥有一个(或多个)用户账户,可以在其中安装程序和存储数据,这与 Linux、Windows 或 MacOS 用户账户非常相似。对数据的写入访问受到严格控制,因此默认情况下只有账户所有者才能修改数据,其他账户只能通过明确的权限修改数据。

全局分布、容错、可扩展操作系统的关键概念和术语

节点

节点是构成我们全球分布式、BFT、开放式操作系统的构件。非正式地讲,节点可以被描述为一个单独的行动者。它可以是单个服务器,也可以是由多个微服务组成的群组,具体取决于节点的职责。重要的一点是,节点是一个单独的实体,要么按规则行事,要么被视为恶意(正式说法是 "拜占庭")。节点由 "节点运营商 "运行,他们通常是公司、非营利组织、政府或拥有足够领域专业知识的个人。

规程

协议规定了节点应该如何交互。诚实 "的节点总是遵守规则,包括随时接受工作。

拜占庭节点

恶意节点拜占庭节点可以以任何方式偏离协议或离线[1]。一个拜占庭节点可能在很长一段时间内都表现得很诚实,只是在后来的某个时刻(或永远不会)才暴露其恶意意图,并有可能与其他拜占庭节点一起发动协同攻击。如果一个系统在有拜占庭节点参与的情况下仍能产生正确的输出,那么它就是拜占庭容错系统。

流动的动机

Flow应该能够在全球范围内被10亿用户采用,并且能够运行频繁交互、潜在的安全关键型应用,对计算和数据存储的要求适中。从算法上讲,Flow 属于区块链协议系列。尽管如此,我们认为将重点放在我们的最终目标上还是很有价值的:设计一个全球分布式、可高效扩展的 BFT 操作系统。因此,在 Flow 的整个设计和架构中,我们采用了以下指导原则,这些原则都是为了实现这一最终目标。

可用性:将复杂性吸收到平台中,而不是外包给开发人员

从我们的角度来看,以下最佳实践广泛地增强了可用性,Flow 目前已实施了这些最佳实践,但最后一项除外,这已列入我们的路线图。 

  • 我们相信,一致性会给软件开发人员带来巨大的好处。使用最终一致性数据库或实施并发算法会大大增加软件的复杂性、工程时间和维护成本[3]。从技术角度讲,我们希望事务符合 ACID 标准。
  • 用户账户的直观概念非常重要,一个账户可以有多个访问密钥,这些密钥可能具有不同的权限,密钥可以循环使用,等等。 
  • 我们希望有一种编程语言,在这种语言中,对象具有访问权限的原生概念。因此,我们可以表达这样的概念:"你给我一个对象,你作为创建者决定我可以用这个对象做什么(包括我是否可以复制它)"。Cadence 是 Flow 的编程语言,具有表达所有权和访问权限的本地语言特点。 
  • 最后,在系统中内置一个(加密安全的)伪随机数发生器 [PRNG] 是非常有用的。因此,Flow 实现了 DFinity 风格的随机信标[4](包括分布式密钥生成)。在其他底层协议功能中,Flow 虚拟机利用随机信标为智能合约的 PRNG 播种。由此产生的随机数是不可预测、可验证和防篡改的--所有这些都是在网络中存在一组相互勾结的敌对节点的情况下实现的[5]。 

通过在平台层面实现广泛使用的功能(如随机数生成),我们减少了开发开销。开发人员可以专注于他们的核心目标,而不必绕开平台的缺陷。 

效率是基本要求

据研究人员估计,2020 年,信息和通信技术造成的温室气体排放量约占全球温室气体排放量的 2% - 4%[6]。此外,钴、铜、锂和稀土元素等所需资源的提取和提炼也会对生态环境造成巨大影响。因此,高效的资源消耗是 Flow 的核心架构指标。 

2021 年,Flow 总共消耗了 0.18 千兆瓦时的能源[7],相当于大约 30 个人的耗电量[8]。目前,Flow 已经是效率最高的 BFT 计算平台之一[9]。随着 Flow 的成熟和交易负载的增加,我们预计 Flow 的扩展效率将产生更明显的优势。  

论点一: 大规模采用需要高吞吐量和大状态空间。

我们认为,大规模应用需要显著的可扩展性,特别是在吞吐量、计算资源和用户数据方面。目前大约有 50 亿互联网用户。10 亿个用户账户平均每个账户存储 1MB 的数据,单个快照的数据量就已经达到 1 PB。为了保持弹性,高度分布式容错系统通常会对最近的更改保留有限的历史记录,这进一步加剧了存储需求。此外,如果使用情况需要,我们希望支持账户存储远大于 1 MB 的数据。 

此外,我们认为全球操作系统每秒需要处理多达 100 万个事务。在 Flow 中,事务本质上是一个小小的通用程序。它可以只调用已在平台上运行的应用程序的某些功能。但一个事务也可以包含一个更复杂的程序,与 Flow 上的各种其他应用程序进行交互。在学术文献中,通常的做法是将平均事务大小设定为 512B[10],我们认为这对于通用计算平台来说已经是一个保守的估计。在这种情况下,Flow 每秒需要摄取 0.5GB 的数据。

论文二: 软件可组合性的高价值--从开放源代码到开放执行 

目前,我们在编译阶段大量使用了可组合性,在这一阶段,软件由各种独立的库组合而成。微服务系统是另一个例子,但这里的组合是在运行时进行的。可组合性、可重用性以及协同改进和演进是开源软件开发的核心优势。  

软件即服务的趋势非常明显,即客户与软件开发人员操作的软件实例进行交互。遗憾的是,目前普遍采用的软件即服务的部署方式是在封闭的基础设施上进行的。这给软件的可组合性造成了巨大障碍,因为用户定制的每一个方面都必须与软件提供商协调。你不可能轻易地将自己的插件或扩展功能引入作为服务运行的软件,因为这不仅需要实现指定的接口(简单的部分),一般还需要与软件提供商专有的、封闭的基础设施兼容。 

高度可组合和可定制的软件已被认为是未来企业应用的关键特性[11,12,13,14]。同样,作为个人,我们也会根据自己的喜好和需求,对软件应用程序进行组合;例如,在智能手机上对交互式应用程序进行个人组合。开放式软件执行将开源的优势扩展到运行环境。您可以根据自己的需要,使用自己的插件和软件扩展来定制运行软件,而不必担心部署问题。开放式执行的基本思想是,软件在运行时可根据个人用户的需求动态连接。从概念上讲,这就是 Windows 中动态链接库或 Linux 中共享对象背后的理念。

支持广泛的可组合性在技术层面上意味着,Flow 必须高效地运行一个由频繁交互、图灵完备的应用程序组成的网络。如下图所示,如果应用程序在多个服务器上横向扩展,那么大量利用可组合性就需要大量通信。

(a) 描述了频繁互动的应用程序网络,(b) 描述 互动稀少的应用程序 网络。圆圈表示应用程序,箭头表示它们之间的交互。橙色线表示应用程序分布在 3 台服务器上。穿过橙色线的箭头表示两个不同的服务器由于应用程序之间的交互而必须交换数据。大量使用可组合性的应用程序(图 a)会导致大量通信。相比之下,分配很少交互的应用程序(图 b)则比较容易,即使服务器之间的通信是资源密集型的,因为代价高昂的操作相对较少。

论点三: 可扩展性是可用性和效率面临的长期挑战。

我们在上一段中概述的可扩展性要求相当高。虽然我们已经实现了分布式数据库等专业任务,但目前还没有通用的 BFT 计算平台能够承担这样的工作负荷。有限的可扩展性从根本上限制了可用性,因为它使大量有趣的用例变得不切实际。 

此外,效率低下导致的资源消耗也会随着系统规模的扩大而增加。小型计算平台需要增加 20% 的硬件和能源通常是可以接受的,而在全球使用的基础设施中浪费 20% 的资源则是不可行的。更糟糕的是,当系统规模扩大时,开销往往会不成比例地增加,例如,小型系统中 20% 的低效在扩大系统中会增加到 30% 的损失。 

总之,我们坚信,高效扩展到超大计算负荷是一个基本前提。大多数有抱负的软件创建者和公司都希望能为数百万到数十亿人提供服务。因此,从面向未来的角度来看,在选择计算平台时,资源高效的可扩展性应该是一个重要标准。

与大众分享这些益处

以下几点是前几节中对 Flow 架构目标的总结:

  • 吞吐量至少为每秒 100 万笔交易 (TPS);
  • 每秒至少摄取 ½ GB 的交易和数据(实际为 1 GB 及以上); 
  • 1 Petabyte(单个区块的状态快照大小)及以上的超大状态;
  • 支持大规模软件可组合性,即运行频繁交互、图灵完备的应用程序
  • 通过一次性解决平台级的共同挑战,将复杂性吸收到平台中,让所有开发人员受益。这可以解放开发人员,让他们专注于更高层次的工作,激发创造力,降低成本,进而使用户受益,促进创新。

Flow 正在解决可扩展性难题

从平台开发者的角度来看,将可扩展性挑战委托给未来当然是很方便的。然而,可扩展性是所有分布式 BFT 操作系统(包括 Flow 和所有其他以智能合约为核心的区块链平台)面临的最基本、最持久的挑战。因此,我们坚信,高可扩展性要求应在开发过程的早期就被去风险化,在架构的每一步都要考虑到。否则,平台开发者就会将可扩展性有限的风险外包给开发者和用户。我们鼓励开发人员询问,如果他们正在考虑的区块链平台获得主流采用并遇到扩展限制(绝大多数可能的情况),他们需要做出哪些改变。 

对于 Flow,我们正在通过构建一个能够透明地扩展到高计算负荷的操作系统来解决当前的扩展挑战。我们将大量的工程资源投入到更加复杂但高度可扩展的架构中,将人们熟知的吞吐量和延迟优化推迟到未来。即使按照目前的容量水平,并容纳一些主要的主流体验(如 NBA TopShot),Flow 也能容纳 10𪂙 倍的负载增长。相比之下,许多其他平台尽管其平台利用率低了几个数量级,但出于营销目的,却只专注于吞吐量优化。我们相信,从长远来看,持续的可扩展性将是开发人员最大的赢家,而不是通过特殊用途的优化来获得短期收益。 

Youtube、NBA、Ticketmaster、美国航空、Doodle 2、LaLiga 等主流媒体的应用程序选择 Flow,就是看中了它的长期可扩展性。知名品牌往往在早期就要求可扩展性,而草根开发者和独立项目则会在更长的时间尺度上受到扩展限制的影响。尽管如此,由于平台转移的成本很高,选择一个具有长期可扩展性的计算平台对于处于早期阶段的小型项目来说也是一个重要的战略决策。

专业运营节点

经常引起争议的话题是节点的硬件和运行要求。为了实现弹性和去中心化,我们通常希望有大量独立运行的冗余节点。因此,去中心化最大化论者要求业余爱好者使用普通商品硬件就能操作节点。然而,从科学的角度来看,即使我们假设所有硬件都能正确工作,也没有实质性证据表明任意计算可以高效地分布在许多小型硬件设备上。事实上,数据中心的趋势是计算能力越来越集中,CPU 每个内核的吞吐量越来越大,尽管硬件成本增加,冷却方面的挑战也越来越大[15]。原因在于,纵向扩展(使用相同数量、性能逐渐增强的计算机)在能源和硬件消耗以及软件工程复杂性方面,通常比横向扩展(逐渐增加计算机数量,但不增加单台计算机的功率)要有效得多。 

总之,我们认为,对于一个高度可扩展的分布式操作系统来说,由专业人员运营的节点对于提高效率至关重要。一个由公司、非营利组织、政府和具有专业领域知识的个人等不同群体运营节点的网络已经足够分散。事实上,与业余爱好者的节点相比,当一个网络由专业运营的节点组成时,我们预计其抵御恶意软件攻击或网络战争行为的能力会更强。

流水线是可扩展性的关键

我们从 IT 安全和基础设施复原力的角度讨论了全球分布式、混沌容错操作系统的优势和潜在的大规模应用。我们将 Flow 介绍为此类操作系统的原型,并提出了以下突破性的可扩展性目标:

  • 吞吐量至少为每秒 100 万笔交易 (TPS)。我们预计,这样的交易量将要求平台每秒至少摄取 ½ GB 的数据;更实际的情况是摄取 1 GB 及以上的数据。 
  • 1 Petabyte(单个区块的状态快照大小)及以上的超大状态;
  • 支持大规模软件可组合性,即运行频繁交互、图灵完备的应用程序

现在,我们来分析冗余、弹性和可扩展性之间的权衡。我们将得出这样的结论:在事务的整个生命周期中,高冗余度的成本和收益会有很大的不同。因此,Flow 采用模块化流水线来处理事务,这样就可以独立调整每个步骤的冗余度。

我们强调,可扩展性是分布式 BFT 操作系统(包括 Flow 和所有其他以智能合约为核心的区块链平台)面临的最基本、最持久的挑战之一。因此,我们坚信,高可扩展性要求必须在开发过程中尽早消除风险,并在架构的每一个步骤中加以考虑。否则,人们就会将平台可扩展性有限的风险外包给开发人员和用户。

冗余对复原力的重要性及其对可扩展性的代价

拜占庭容错计算平台的一个决定性特征是,即使有相当一部分节点发生故障或遭到破坏,它仍能产生正确的结果。要量化拜占庭容错系统的 "弹性",我们可以看一下在不影响系统整体正确性保证的情况下,能够被破坏的节点数量。在区块链领域,这个数字也被称为中本系数(Nakamoto Coefficient)[16]。从概念上讲,我们希望这个数字很大。这样,基础设施就能抵御自然灾害、大规模恶意软件感染或网络战争行为。需要注意的是,提供正确的结果是一个基本要求,而在发生自然灾害或大规模网络攻击时,我们可以接受一定程度的性能下降。 

在计算机科学文献中,算法保证通常是这样的:"只要少于 x% 的节点处于混沌状态,算法就能继续产生正确的结果"。这说明了冗余与弹性之间的基本联系。系统内冗余越多,系统崩溃所需的节点(绝对数量)就越多。 

我们总是需要一定程度的冗余,这主要是指多个节点各自处理相同的工作,因为任何一个节点都可能出现故障。不幸的是,资源消耗(硬件和能源)会随着冗余度的增加而线性增加。因此,要实现高效的可扩展性,就必须密切关注冗余在哪些方面对于恢复能力确实不可或缺。

事务线性化和事务执行在效率和冗余之间有不同的取舍

图 1:比较冗余对事务线性化和事务执行的成本和好处。冗余对执行的有限好处在于,假设协议在接受结果之前就能断言执行的正确性。在这种情况下,恶意行为者很难通过发布错误的执行结果来破坏系统的正确性。因此,尽管冗余度较低,系统输出的正确性仍能得到保证。 

交易顺序会从根本上影响计算结果。想象一下,还有一张音乐会门票,爱丽丝和鲍勃都试图购买。交易先被处理的那个人得到了票,而另一个人的购买尝试失败了。显然,顺序在这里很重要。不过需要注意的是,"正确的顺序 "并没有一个恰当的概念。离鲍勃近的服务器可能会先收到他的交易,而爱丽丝所在城市的另一台服务器可能会先看到她的交易。换句话说,[transactionAlice,transactionBob]和[transactionBob,transactionAlice]这两种顺序都是合法的,福禄需要选择其中一种。从形式上看,解决就订单达成一致这一问题的算法属于共识算法系列。确定事务顺序的过程称为 "事务线性化"。

直观地说,控制交易排序的单个潜在恶意行为者可以施加不当影响,例如系统性地损害某些用户的交易或完全审查这些交易。 此外,由于不存在单个正确的交易顺序,其他诚实节点很难甚至不可能最终证明交易线性化过程受到了破坏。因此,为了提高恢复能力,我们希望有更多的节点参与共识,也就是有更大的冗余系数。 

从资源消耗的角度来看,共识只需要少量计算。通信延迟和数据交换量才是主要瓶颈,尤其是在有很多节点参与的情况下,而我们需要的是弹性。因此,如果我们能将单个共识参与者摄取的数据量保持在较小的范围内,那么冗余成本对于共识阶段来说实际上是非常适中的(我们很快就会解释如何实现这一点)。 

相比之下,事务执行需要大量资源。如上所述,我们预计 Flow 成熟时的系统状态很容易达到 PB 级。此外,每秒至少有半千兆字节的代码需要执行,数据需要处理,甚至可能更多。要承担这样的计算负荷,需要非常强大的硬件,占用大量资源并消耗大量能源。 

对于全球规模的计算平台来说,由数百甚至数千个节点冗余执行交易在经济上是不合理的,在生态学上也是令人望而却步的。此外,高冗余度带来的好处也很有限,原因如下。与共识不同的是,事务的执行是完全确定的。换句话说,对于给定的起始状态和计算指令序列,客观上只有一个正确的输出。如果流量协议接受结果之前就能断言事务执行的正确性,那么恶意行为者就很难通过发布错误的执行结果来破坏系统的正确性。因此,尽管冗余度较低,系统输出的正确性仍能得到保证。

将共识与交易执行分开

图 2:Flow 的事务处理流水线(简化版)。在流水线中,事务线性化与事务执行是分开的,以允许不同程度的冗余。共识具有较高的冗余度。在参与节点数量较多(数百个)的情况下,共识步骤本身就能保证交易线性化的弹性(假设恶意行为者只能入侵有限数量的节点)。相比之下,事务执行的冗余度较低(10 或更低)。因此,可以想象恶意行为者可能会入侵参与执行的大部分节点。不过,出站交易结果的正确性仍然由验证步骤来保证,验证步骤也需要相当高的冗余度来抵御入侵企图。

将事务线性化与执行分离是分布式数据库的一种既定方法。我们在 2019 年发表了一篇论文,将这种方法扩展到了计算平台[17],并从一开始就在 Flow 中实现了这种方法。自 2021 年以来,以太坊在提议者-生成器分离的背景下[18],以及截至 2022 年,Oasis 和 Infura[19]也在探索类似的想法。不过,这两个项目都尚未完成最终设计。

通过分级共识扩展事务线性化

在上一节中,我们已经看到流水线是提高平台效率的关键。本章重点介绍流水线的第一步:交易线性化。我们将解释 Flow 的共识系统如何超越单个服务器的联网能力,据我们所知,这在区块链领域是无与伦比的。

在单个节点上每秒持续摄取至少半个千兆字节的交易数据具有相当大的挑战性,需要非常强大的硬件。我们不想依赖 "少数几个强大节点 "来实现交易线性化,因为这会影响 BFT 和去中心化(如上一节所述)。从概念上讲,这个难题的答案很直观:单个节点只接收所有进入交易的子集。 

图 3:横向扩展事务线性化。收集器集群接收部分入站事务,并将其批量转化为集合。集群内的收集器节点签署收集哈希值,以表示它们承诺暂时存储完整的收集,直到交易处理完毕。只有签名的哈希值("集合保证")会被发送到共识节点,而完整的集合数据会被直接发送到执行节点。因此,只有少数几个执行节点拥有强大的硬件,它们必须摄取完整的交易数据。 

Flow 通过图 3 所示的分层流程实现了横向扩展的事务摄取。我们在此简要总结了这一流程,感兴趣的读者可参阅我们的论文[20]了解详情。简而言之,有一类节点称为 "收集器",其工作是创建线性化事务批次。庞大的收集器集合(在成熟、最大化的协议中可能有几千个)每周被划分为较小的组(50 - 100 个节点),称为集群。 每笔交易都会根据哈希值进入一个特定的群组。如果协议中有k 个群集,则每个群集只需接收1/k的全局交易数据。线性化事务的单个批次(称为集合)可能包含多达 1000 个事务。一旦各集群有足够多的收集者签署并承诺存储该集合,整个集合就会直接进入执行节点。不过,只有被称为 "集合保证 "的集合参考才会发送给共识委员会。共识节点将收集保证线性化,并将其放入区块中。由于单个收集保证只有约 128 字节,因此共识参与者只需少量硬件,就能每秒接收数千个收集保证。由此产生的处理管道如图 4 所示。 

图 4:分层事务线性化的 Flow 事务处理流水线(简化版)。

2020 年初,我们发表了一篇论文,描述了分层、可水平扩展的事务线性化方法[20],当时我们正在完成 Flow 中相应的收集器实现。自 2021 年年中以来,以太坊也在朝着概念上非常相似的方向思考,虽然没有具体的发布日期,但使用了 "数据可用性碎片"[21,22]或最近的 "danksharding"[23,24]等关键词。

横向扩展的并行执行

在介绍了如何将线性化扩展到每秒 100 万次事务处理(上一章)之后,我们现在将重点转移到事务执行上。本章将介绍 Flow 如何通过将执行集中在数量有限的专用强节点上,来实现巨大的效率和可扩展性优势。

我们相信,为软件高度可组合性量身定制的操作系统能为开发人员带来巨大的利益并激发创造力,而创造力反过来又能为用户带来利益并促进平台的采用。大量使用可组合性的开发人员要求计算平台能够高效运行频繁交互、图灵完备的应用程序网络。随着计算负荷接近预期水平(PB 级状态和每秒千兆字节的入站事务),任何一台服务器都无法完全存储状态或以可接受的速度计算所有事务。因此,事务执行需要横向扩展,即应用程序必须分布在不同的服务器上。 

图 5:(a) 互动频繁的应用程序网络(b) 互动稀少的应用程序 网络。圆圈表示应用程序,箭头表示它们之间的交互。橙色线条表示应用程序分布在 3 台服务器上。穿过橙色线的箭头表示两个不同的服务器由于应用程序之间的交互而必须交换数据。大量使用可组合性的应用程序(图 a)会导致大量通信。相比之下,分配很少交互的应用程序(图 b)则比较容易,即使服务器之间的通信是资源密集型的,因为代价高昂的操作相对较少。 

大量使用可组合性的应用(图 5a)会导致大量通信。在这种情况下,服务器之间的数据交换必须高效。否则,计算平台就无法在不消耗资源的情况下进行扩展。 

相比之下,很少交互的应用(图 5b)可以分布在多个服务器上,即使服务器之间的数据交换需要大量资源。对于平台开发者来说,将计算平台局限于很少交互的应用是一条便捷的捷径。然而,这也给开发人员带来了巨大的复杂性,因为许多开发人员现在不得不绕开平台的缺陷。对于仅支持稀疏交互应用的平台来说,可扩展性难题必须由许多开发团队分别反复解决,而不是在平台层面一次性解决。 

Flow 团队坚信应将复杂性吸收到平台中,而不是外包给开发人员。我们对 Flow 进行了架构设计,以支持大规模可组合性,并在下文中介绍 Flow 如何有效地横向扩展事务执行。

Flow 采用的专用执行节点数量非常有限(在成熟协议中最多为 8 到 10 个)。我们设想每个执行节点都是一个小型数据中心。执行节点之间是完全冗余的,这意味着每个执行节点都在本地保存整个状态执行所有事务。我们的方法具有以下突破性的效率优势(如图 6 所示):

  • 由于数据本地化程度高(即通信距离短),大规模数据交换所需的硬件和能源资源有限。此外,在数据中心内,可以使用专门的网络基础设施,而如果距离较远,则成本过高,从而进一步将资源消耗降至最低。
  • 空间密集计算意味着低延迟通信。因此,Flow 可以运行大量交互的应用程序。如果在服务器通过互联网进行通信的广泛分布式网络上执行相同的计算,则会在延迟方面遇到瓶颈。 
  • 由于执行节点由单个操作员操作,因此执行节点内的服务器可以相互信任。因此,服务器可以检索状态和交换应用数据,而无需依赖耗费大量 CPU 和能源的签名和密码正确性证明。 
  • Flow 协议不考虑执行节点如何其众多服务器之间分配工作负载的具体情况。唯一的要求是,执行结果必须与线性化事务的顺序执行结果相同。因此,只要结果保持不变,执行节点就可以在内部对事务进行重新排序并并行执行。与大多数其他协议相比,Flow 具有改变游戏规则的优势,原因如下:

    - 不同的执行节点可以采用不同的启发式方法来并行处理事务。最有可能的是,没有一种并行事务算法在所有情况下都是最佳的。在采用多种启发式算法的情况下,不同的执行节点暂时会比其他节点更快,这取决于当前普遍的负载模式。整个平台的速度由最快的执行节点决定。因此,多样化的执行启发式方法能使 Flow 协议更快。

    - 执行节点可在本地改进其启发式,而无需协调耗时的协议升级。执行节点会因速度而获得奖励(我们将在今后的文章中讨论这个话题),它们可以将自己的并行化执行启发式视为知识产权。因此,我们期待对速度和效率进行持续、快节奏的优化。

    - 作为执行节点的一个实施细节,事务执行的横向扩展也极大地简化了 Flow 协议。 

图 6 (a) 描述了区块链中常见的分片模式。每个节点(绿色椭圆形)维护一个分片或一小部分分片的本地副本。对于密集交互软件的组合(如图 5a 所示),相互调用的各种应用程序经常在不同的节点上运行,而这些节点之间并不共享信任关系。因此,大多数功能调用都需要在节点之间进行 BFT 数据交换,这就带来了大量开销,例如:需要传输有效载荷数据的额外正确性证明;互联网上的长距离通信会产生延迟;通常情况下,碎片间通信需要通过共识来调解,从而导致更大的延迟和严重的吞吐量限制。
图 (b) 展示了 Flow 在执行节点(绿色椭圆形)内的水平扩展方法。执行节点内部采用不同的启发式并行计算方法。例如,顶部执行节点以类似于图(a)中碎片的方式对计算进行内部分区。不过,由于数据交换完全在节点内部进行,因此没有开销。此外,不同的执行节点采用不同的启发式方法对计算进行水平扩展。多样化的扩展启发式方法组合提高了 Flow 的弹性,并缓解了单个事务并行化启发式方法的负载瓶颈。  


总之,将事务执行集中在数量有限的专用强节点上,可以带来巨大的效率和可扩展性优势。我们强调,Flow 可以在不影响安全性或去中心化的情况下实现这一点。这是因为,对于给定的起始状态和计算指令序列,客观上只有一个正确的结果。下一章描述的验证步骤保证了只有正确的结果才会被接受。因此,尽管冗余度较低,系统输出的正确性仍能得到保证。

分布式验证

我们认为,对于高效、可扩展的计算平台来说,必须谨慎控制冗余,以保持资源消耗的实用性。但是,如果冗余度较低,大多数(或所有)执行节点被破坏的情况就会发生。为了保证只接受正确的事务执行结果,我们利用了冗余。从本质上讲,我们要求一组节点(称为 "验证节点 "或 "验证器")重新运行计算。如果有更多的验证者同意计算结果,Flow 就会认为计算结果是正确的,否则就会认为计算结果有问题而拒绝接受。 

细心的读者会发现,我们正在减少执行节点的冗余度,以提高效率,但在验证步骤中又增加了冗余度,以防止错误结果漏掉。尽管如此,通过大幅减少执行冗余,我们可以显著降低能耗和硬件消耗。但是,我们只需要在验证状态下增加少量冗余,而硬件和能耗成本是有限的。在这样的架构下,整个平台的效率仍然大大高于执行状态下的高冗余度。 

为了说明这个基本概念,我们可以假设这样一个场景:邪恶的夏娃和迂腐的鲍勃是安装火灾报警器的承包商,他们试图以一个糟糕的、错误的工作来蒙混过关。按照既定流程,夏娃和鲍勃最后必须向有执照的检查员展示他们的工作,检查员必须签字认可。简而言之,我们有 3 个冗余,因为夏娃、鲍勃和检查员都在花费时间。夏娃和鲍勃试图贿赂检查员,让他签字认可他们的错误工作。根据检查员的不同,有些检查员可能很脆弱,会接受贿赂并变得迂腐,而另一些检查员则会经受住贿赂。假设全市有 1000 名持有执照的检查员,其中 ⅓ 的检查员容易受到贿赂。对于检查工作的一名检查员,夏娃和鲍勃有 33.3% 的统计变化率来摆脱他们的错误结果。为了增加挑战性,我们可以指派 α = 5 名检查员,并要求夏娃和鲍勃至少提交其中⅔名检查员的签名。在这种情况下,他们必须足够幸运,这样才会有 3 个脆弱的检查员,从而将接受错误工作的几率降低到 5% 以下。指派 50 名检查员已经将概率降低到百万分之一以下!

重要的启示是,我们并不需要所有 1000 名检查员来检查工作。我们仍然可以通过从一大批检查员中随机分配数量有限的检查员,来建立一个安全高效的协议。 

从概念上讲,我们采用同样的方法来拒绝 Flow 中的错误执行结果:

  • 每个执行节点都会公布自己的结果,实质上是为其结果的正确性抵押了一大笔安全保证金(用区块链术语来说就是 "赌注")。 
  • 共识节点将未经验证的结果记录在区块中,并随机分配 α 个验证节点来检查结果。通过复杂的加密过程(DFinity 式随机信标[4]),在执行节点公布其结果时,验证者的分配是不可知的。  
  • ⅔ 分配的验证者需要批准执行结果。如果验证者发现结果有问题,执行节点的利益就会受到惩罚(形式上是 "削减");同样,如果执行节点没有向验证节点披露计算细节,使其能够进行检查,也会受到惩罚。 

图 7 显示了接受错误执行结果的概率取决于分配的验证器数量 α。在 10 个执行节点和分配 α=100 个验证器的情况下,我们的冗余度为 110,相对较小。其他区块链系统的执行冗余度高达数百,甚至接近 2000[25]。相比之下,Flow 的交易执行冗余要少一个数量级。我们强调,Flow 仅限制了执行冗余,这不会破坏去中心化和弹性,因为执行节点仅按照网络中去中心化、高弹性部分确定的顺序计算交易。 

执行节点唯一可能的攻击向量就是完全停止运行。尽管如此,一个诚实的执行节点就足以维持 Flow 的运行。 

图 7:接受错误结果的概率取决于分配的验证者数量 α。 在成熟的协议中,我们会从大约 1000 名验证者中随机分配 α。 当 α=100 时,概率会降至 10-12左右。如果增加验证者总数,概率还会进一步降低。


本文对 Flow 验证阶段的描述进行了大量浓缩和简化。例如,在完整协议中,我们将执行结果分成许多小块。每个验证节点只处理一个区块中所有区块的 5 - 8% 左右。因此,检查一个区块的繁重工作将在整个验证节点群中进行分布式并行处理。 

更多详情,请读者参阅我们关于执行与验证的论文[26]。虽然该论文中描述的方法仍然适用,但一些微妙的技术细节已经过修改和完善。对于感兴趣的读者,我们将在未来发表最新论文。

摘要和结论

冗余是 Flow 等分布式计算平台的核心参数。虽然高冗余度通常有利于恢复能力和去中心化,但也会带来大量的硬件和能源消耗。例如,在数百到数千个节点上复制 1 PB 的状态,在经济和生态上都是不合理的。 

我们认为,高效的可扩展性 和对高度交互、可组合应用的支持,对于任何以大规模采用和广泛实用为目标的分布式操作系统来说都是必不可少的。高效的可扩展性是一个持续的挑战,也是一个积极研究和开发的领域。众所周知,任何通用计算平台,从多核 CPU 到云基础设施,都无法在不牺牲效率或软件可组合性的情况下进行扩展,除非从一开始就将可扩展性设计到平台中。这适用于传统的计算平台,它们可以容忍崩溃故障。如果将要求扩展到还能容忍复杂故障,可扩展性就更难实现了。因此,我坚决不同意区块链领域的主流做法,即设计可扩展性严重受限的系统,并寄希望于未来的扩展(分片、卷积、零知识证明)来解决这个问题。

对于 Flow 来说,可扩展性是架构的固有组成部分,在开发的每一步都要加以考虑。在技术层面,我们通过精心控制冗余实现了前所未有的可扩展性。Flow 的架构将处理步骤分离到不同的专业节点角色中,以单独优化冗余。因此,我们在不牺牲分散性或弹性的情况下实现了最高效率。交易执行是硬件和能源消耗的主要驱动因素,但在 Flow 中冗余度极低。例如,在 2021 年,Flow 总共消耗了 0.18 GWh 的能源[7],相当于大约 30 个人的耗电量[8]。如今,Flow 已成为最高效的 BFT 计算平台之一[9]。我们强调,Flow 和其他较新的区块链平台的交易吞吐量仍比其成熟水平低几个数量级。随着计算负荷的增加,能耗通常也会增加,但由于其独特的架构,我们预计 Flow 的扩展效率将远高于其他平台。 

最后,我们想简单讨论一下复杂性。与其他流行的区块链相比,Flow 协议有 5 种不同的节点角色,看起来可能比较复杂。但是,我们要强调的是,Flow 协议已经包含了将 Flow 推向全球的全部复杂性,而其他项目则将扩展复杂性委托给了未来。例如,我们同意以太坊1.0比Flow简单得多,但它不能扩展。为了应对其扩展挑战,以太坊 2.0 的复杂度要高出几个数量级。 

我们推测,在未来将 Flow 与其他解决了扩展难题(同时不影响可组合性)的协议进行比较时,Flow 将是最简单、最直观的协议之一。这是因为将执行集中在专用的高能执行节点上是 Flow 独有的创新。其他协议(包括以太坊 2.0、Near 等)试图在没有信任关系的情况下在不同节点上横向扩展交易执行。因此,它们必须在协议层面上规定横向扩展事务执行的详细机制。  

作者:亚历山大-亨策尔(Alexander Hentschel)博士,2023 年流量区块链首席协议架构师