ChainCatcher 链捕手

Posted on Jun 14, 2022Read on Mirror.xyz

Solana扩容机制分析:牺牲可用性换取高效率的极端尝试 | CatcherVC Research

作者:eternal1997,CatcherVC 技术顾问 :刘洋,《嵌入式系统安全》作者

Solana以系统可用性为代价,将Layer1扩容的叙事推向了极端,基本触及无分片公链的TPS瓶颈。但多次宕机似乎预示了牺牲可用性换取效率的结局。

摘要

  • Solana扩容主要基于:高效利用网络带宽、减少节点间通讯次数、加快节点运算速度 三大方面,这些措施直接缩短了出块和共识通讯的时间,但也降低了系统可用性(安全)。
  • Solana提前公开出块者Leader名单,揭示了单一可信的数据来源,缩减了共识通讯开销。但又会带来贿赂、针对性攻击等安全隐患。
  • Solana将共识通讯(投票信息)作为交易事件来处理,TPS成分中超过70%都是共识讯息,与用户交易相关的TPS约为500—1000
  • Solana的Gulf Stream机制取缔了全局性交易池,这提高了交易处理速度,但降低了过滤垃圾交易的效率,Leader容易宕机
  • Solana的Leader节点发布的是交易序列,而非真实的区块。结合Turbine传输协议,交易序列可以切碎后分发给不同节点,数据同步速度极快。
  • POH(Proof Of History)实质为一种计时和计数方式,它给不同的交易事件盖上序号,生成交易序列。Leader实质上在交易序列中发布了全网一致的计时器(时钟)。在很短的窗口期内,不同节点的账本推进、时间推移都是一致的;
  • Solana有132个节点占据67%的质押份额,其中的25个节点占据33%的质押份额,基本构成了“寡头政治”或“元老院”。如果这25个节点串谋,足以导致网络陷入混乱;
  • Solana对节点硬件水准要求很高,它以设备成本为代价,实现了纵向扩容。运行Solana节点的个体多为鲸鱼或机构、企业,不利于真正意义的去中心化。
  • 综上,Solana以高级节点设备、颠覆性的共识机制与数据传输协议,将Layer1扩容推向了极端,基本触及无分片公链可维持的TPS瓶颈。但多次宕机已经预示了牺牲可用性/安全性来换取效率的结局。

导语

2021年是区块链和Crypto的转折之年。随着Web3等概念成为显学,公链界迎来了有史以来最强劲的流量增长。在这样的外部环境下,以太坊凭借充分的去中心化和安全性,成为Web3世界的泰山北斗,但效率问题却成了它的“阿喀琉斯之踵”。相比于TPS轻松破千的VISA,每秒10几笔交易的以太坊宛若怀中襁褓,与其“世界级去中心化应用平台”的宏大愿景相差甚远。

对此,Solana、Avalanche、Fantom、Near等以扩容为核心的新公链一度成为Web3叙事的主要角色,获得了巨量资本的垂青。仅以Solana为例,这个号称“以太坊杀手”的头部公链在2021年市值飙涨170倍,如日中天,甚至一度超越老牌公链Polkadot和Cardano,大有和以太坊争雄的势头。

但这种来势汹汹的态势没有持续太久。2021年9月14日,Solana因为性能上的问题,首次迎来宕机事故,时间长达17小时,SOL代币价格随之快速下跌15%;2022年1月,Solana再次出现宕机,时长足有30小时,引发了极为广泛的讨论;之后的5月,Solana先后宕机2次,6月初又宕机1次。根据Solana官方的说法,其主网至少经历了8次性能下降或是宕机事故。

(链闻联创刘锋对Solana的评论)

伴随着诸多问题的出现,以太坊支持者为首的批评者轮番对Solana提出质疑,有人甚至给Solana冠以“SQLana”的称号(SQL是管理中心化数据库的系统),并先后产生了大量的评论与分析。时至今日,关于Solana真实可用性的讨论似乎从未停止,吸引着无数好奇心浓重的观察者。出于对主流公链的兴趣与关注,CatcherVC将从自身视角出发,在本文对Solana扩容机制及其宕机的部分原因展开简单解读。

Solana系统架构、共识机制、区块传输流程

公链的效率主要指其处理交易的能力,也就是吞吐量TPS(每秒处理的交易笔数),这个指标受到出块速度和区块容量的影响,同时也影响着交易手续费和用户活跃度。从2018年甚嚣尘上的EOS,到近期发币的Optimism,所有扩容方案几乎都绕不开“加速出块”这个最关键的要素。

要提升出块速度,往往要在出块流程上“做手脚”,Solana也不出其右。其扩容方式主要立足于 高效利用网络带宽、减少节点间通讯的次数、提高节点处理事务的速度 三大方面,这些措施直接缩短了出块和共识通讯的时间。Solana的创始人Anatoly Yakovenko及其队友对每一个细节都进行了精心雕琢,以系统的可用性(安全)为代价,尽可能在效率上作出提升,基本达到了无分片公链的实际TPS极限,最终作出了“有代价”的创新。

相比于其他采用POS的公链,Solana最大的创新点在于其独特的共识协议网络节点通信方式,该共识协议基于POSPBFT(实用拜占庭容错),引入独创的POH(Proof of History)作为推进区块链账本的机制,独树一帜的创建了自己的共识体系。

单从表现形式的角度看,Solana的共识协议与Cardano最早的Ouroboros(衔尾蛇)算法类似,都包含Epoch(纪元)Slot(间隔)两大时间单位。每个Slot约为0.4~0.8秒,相当于一个区块的时间间隔。而每个Epoch周期包含43.2万个Slot(区块),长达2~4天。

在Solana的系统架构中,最重要的角色分为两类:Leader(出块者)和Validator(验证者)。两者实际上都是质押了SOL代币的全节点,只是在不同的Slot(出块周期)内,Leader会由不同的全节点来充当,而没有当选Leader的全节点会成为Validator。

在每个新的Epoch周期开始时,Solana网络会按照各节点的质押权重进行抽选,组成一个出块者Leader轮换名单,“钦定”了未来不同时刻的出块者。在整个Epoch(2~4天)内,出块者会按照名单指定的次序进行轮换,每过4个Slot(出块周期),Leader节点就会进行一次变更。

(Solana第313个Epoch出块节点轮换名单的一部分)

由于提前公开了未来的出块节点,Solana网络实质获得了确定而可信的新区块数据源,为共识过程提供了巨大便利。

Solana出块流程简述

为了更清晰的理解Solana的扩容机制,我们不妨从出块逻辑开始,对Solana的大致结构进行解析:

1.用户发起交易后,会被客户端直接转发给Leader节点,或者先被普通节点接收,再立刻转发给Leader;

2.出块者Leader接收网络内全部的待处理交易,一边执行,一边给交易指令排序,制成交易序列(类似区块)。每隔一段时间,Leader会把排好的交易序列发送给Validator验证节点;

3.Validator按照交易序列(区块)给定的顺序执行交易,产生相应的状态信息State(执行交易会改变节点的状态,比如改变某些账户的余额);

4.每发送N个交易序列,Leader会定期公开本地的状态State,Validator会将其与自己的State作对比,给出 肯定/否定 的投票。这一步就类似于以太坊2.0或其他POS公链里的“检查点”。

5.如果在规定时间内,Leader收集到占全网 2/3质押权重 的节点们给出的肯定票,则此前发布的交易序列和状态State就被敲定,“检查点”通过,相当于区块完成最终确认Finality

6.一般而言,给出肯定票的Validator节点与出块者Leader所执行的交易、执行后的状态都是相同的,数据会同步。

7.每过4个Slot周期,Leader会进行一次切换,这意味着Leader每次大概有1.6秒~3.2秒时间掌握网络的“最高话语权”。

Solana扩容机制细解

表面看来,Solana的出块逻辑与其他采用POS机制的公链大体一致,都有一个发布区块、对区块投票的过程。但如果我们对每一个步骤都展开观察,不难发现Solana与其他公链之间有着天壤之别,而这正是其高TPS、低可用性的根源所在

1.最重要的一点:Solana提前公开每个周期Slot的出块者Leader,大幅减少了共识过程的工作量。在其他POS公链中,由于缺乏单一的、可信的出块节点,网络的共识通讯效率极低,产生的时间复杂度往往比Solana高出几个数量级,这成为了多数公链在TPS上的瓶颈。

以主流的POS共识协议或PBFT算法为例,这些算法大多采用了和Solana相同的时间单位与角色划分,也有类似于Epoch纪元、Slot区块周期、Leader出块者、Validator验证者、Vote投票 的设定,只是参数设置和叫法不同而已。最大的不同在于,此类算法大多以安全性(可用性)为前提,不会提前公开Leader名单。

(比如Cardano也会事先生成一个Leader轮换列表,但列表不公开。每个选中的Leader只知道自己该在何时出块,不知道其他时刻的出块者是谁。这使得出块节点不可被外界预测。)

由于没有公开的出块者,节点间会“互不信任”并“各自为政”。此时,若某个节点自称为合法出块者,大家并不敢信任他,必须要其出示相关的Proof证明才行。但此类Proof证明的生成、传播、验证会浪费带宽资源,并产生额外的工作量(甚至会和ZK零知识证明扯上关系)。Solana公开每个时段的Leader,可以避免此类麻烦。

更为重要的是,在绝大多数POS共识协议或PBFT类算法中,针对新区块的投票Vote(一个区块要得到网络内2/3节点的肯定票才能敲定),往往由各个节点通过“流言协议”,以类似1对1交流的方式发送或收集,有点类似于病毒式随机扩散,实质等价于 每两个节点间都要通讯一次,其复杂度和耗时远高于Solana的共识协议。

在Tendermint等PBFT算法中,单个Validator节点至少要收集网络内2/3的节点发出的单张投票。如果全网节点数量为N,则每个节点至少接收2/3×N个投票,整个网络产生的通讯次数至少为2/3×N²,显然这个数量级太大了(和N的平方成正比)。如果节点数量很多,其共识过程的耗时往往会陡增。

(普通公链里单个节点投票的传播方式,类似过程每个节点都会做1次,每次出块要进行N次类似的传播)

(相关科普:《雪崩DEX开发者为你详解Avalanche共识机制》)

对此,Solana和Avalanche以不同的方式改良了节点收集投票的通讯过程,降低了时间复杂度。通俗的讲,Leader集中汇总所有Validator发出的投票,再把这些投票打包在一起(写进交易序列里),一次性推送到网络中

这样一来,节点们无需再通过“流言协议”频繁的、1个1个的互换投票信息,通讯次数降低到了常数N甚至是logN的数量级,这在很大程度上缩短了出块时间,大幅提高了TPS

目前Solana出块周期基本和单个Slot的时长一致,为0.4~0.8秒,甚至比Avalanche还快出3倍。(Solana浏览器显示的区块,实质是每个Slot内Leader发布的交易序列)。

但这也带来了另一个问题:由Leader在交易序列(区块)内发布节点们的投票信息,会占用区块空间。在Solana的设定中,Leader实质将共识投票作为一种交易事件来处理,其发布的交易序列包含节点投票Vote,而这些投票正是Solana TPS的主要成分(一般占70%以上)。

按照Solana浏览器里的数据统计,其实际TPS维持在2000~3000左右,其中70%以上是与普通用户无关的共识投票讯息,与用户交易相关的实际TPS维持在500~1000,虽然比BSC和Polygon、EOS等高性能公链还高出1个量级,但仍无法达到官方所鼓吹的上万级别。

同时,如果Solana未来不断的提升去中心化程度,允许更多的节点参与共识投票(目前有近2000个Validator),则Leader发布的交易序列中必将包含更多的投票讯息,会持续压缩与用户交易相关的TPS空间。这标志着Solana在不分片的前提下,基本难以取得更高的TPS。

某种程度来看,Solana每秒500~1000笔的交易处理能力已达到无分片公链的巅峰,在节点数量较多、不分片且支持智能合约的前提下,新公链基本难以超越Solana的TPS量级,除非它们采用“委员会”模式,只允许少量节点参与共识,或者退化为中心化服务器。只要参与共识的节点数量很多,就难以取得比Solana更高的“可证实的TPS”。

格外值得注意的是,由于每个Epoch内(2~4天)的出块者名单是提前公开的,Solana的共识协议与原始的Tendermint算法并无本质区别,实际都没有赋予出块者以不可预测性,所有人都能预知未来某个时间点由谁来出块,这就会在 可用性/安全性 上产生诸多隐患。 (Leader易遭遇有预谋的DDOS攻击,提高了故障率,若连续几个Leader出现故障,则网络容易宕机;且用户可提前贿赂Leader等)

2.Gulf Stream与网络宕机:Solana公开出块者Leader名单还有一个更重要的目的:配合其独创的Gulf Stream(海湾流)机制,提高网络处理交易的速度。

用户发起交易后,往往被客户端程序直接转发给指定的Leader,或者先被某个普通节点接收,再被该节点快速发送给Leader。这种方式可以让Leader尽快接收交易请求,提高响应速度。(称为Gulf Stream机制,是Solana宕机的主因之一)

Solana的这种设定,是与其他公链截然不同的交易提交方式。Gulf Stream取缔了比特币和以太坊的“全局交易池”设定,普通节点不运行大容量的交易池。一个节点收到用户的待处理交易后,只需交给Leader,不必再发给其他节点,这种做法大幅提高了效率,但由于取缔了交易池,普通节点无法高效拦截垃圾交易,容易导致Leader节点宕机。

为了深刻理解这一点,我们可以对比ETH: ·以太坊的每个全节点都有名为交易池(内存池)的存储区域,用于存放未上链、待处理的交易指令。

·当节点接收到新的交易请求后,会先进行过滤,判断交易指令是否合规(是否为重复/垃圾交易),之后将其存入交易池,再转发给其他节点(病毒式扩散)。

·最终,一笔合法的待处理交易会传遍网络,放入所有节点的交易池里,这就让不同节点都获取到相同的数据,表现出“一致性”。

以太坊和比特币采取这种机制,理由很明确:不知道未来的出块者是谁,所有人都有概率打包新区块。所以,必须让不同节点接收到相同的待处理交易,为打包区块做准备。

如果有矿池节点发布新区块,接收区块的节点会解析其中的交易序列,按次序执行,再把这部分交易指令从交易池中清掉。至此,一批待处理的交易就可以上链。

Solana取缔了以太坊的那种交易池,待处理的交易无需在网络内随机扩散,而被快速提交给指定的Leader,再打包成交易序列一次性分发出去(类似于前文的分发投票的方式)。最终,一笔交易只需要夹在交易序列里,在网络内传播1圈(以太坊实际是2圈)。在交易数量很大的情况下,这个细微差别可以大幅提高传播效率。

但根据交易池TxPool的相关技术说明,交易池/内存池实质发挥了数据缓冲区和过滤器的作用,能提升公链可用性。所有节点都运行交易池,收录网络内全部待处理交易,不同节点就可以独立过滤垃圾请求,第一时间拦截重复交易,分担流量压力。虽然采用交易池会放慢出块速度,但如果有用户发起重复交易(交易池里有记录的请求),或其他类型的垃圾请求,接收到交易的节点可在本地将其过滤,不会再转发出去,这就让过滤工作被全网节点分担开。

(在以太坊网络,恶意用户发起的重复交易更容易被各个节点直接拦截)

Solana采取了背道而驰的做法。在Gulf Stream机制下,普通节点们不运营全网一致的交易池,无法高效拦截 重复/垃圾交易。普通节点真正能做的,只是检查交易数据包是否符合正确格式,无力辨别恶意重复请求。同时,由于普通节点“一股脑”的把交易指令推给Leader,相当于把过滤交易的“重担”甩给了Leader自己,在流量极大、重复交易数量极多的情况下,Leader节点会因压力过大而无法顺利出块,共识投票将无法顺利传播,网络容易崩溃。

对此,Solana创始人Anatoly Yakovenko于今年1月27日表示,某些热门项目的公售时段,每秒最多有近200万笔交易请求到达同一个Leader节点,其中90%以上是完全相同的重复交易,最终导致Solana宕机。

(参考资料:《深度调查:新公链们为何频现宕机事故?》)

综上所述,以太坊实质是牺牲效率换安全,Solana则是牺牲安全换效率,它所面临的问题可归纳为: 由于Leader轮换顺序是给定的,必须按照这个轮换链条不断的走下去。但由于流量分担机制不完善,Leader节点故障几率较高,如果某段时间内用户流量过大(如某些火热NFT开启公售),可能使多个Leader先后出现故障(比如未来40个Slot的Leader都不能顺利出块),这样一来,共识过程受阻,网络会分叉、Leader轮换链条会彻底断裂,最终会彻底崩溃。

3.类似BT种子的Turbine传输协议:在上文的Gulf Stream机制配合下,Leader迅速接收一段时间内的全部交易请求,检查其合法性,之后会执行交易。同时,Leader采用称为POH(Proof of History)的机制,为每笔交易都盖上一个序列号,为交易事件排序。(细节将于后文阐述)

Leader把交易事件排好序后,会把交易序列切成X个不同的碎片,分别发送给质押资产最多的X个Validator,再由他们传播给其他Validator。Validator群体会自行交换收到的碎片,在本地拼凑完整的交易序列(区块)。

为了便于理解,我们可以将每个不同的碎片视作数据量缩减的小区块。Leader一次对外分发X个碎片,相当于发出X个不同的小区块,让不同的节点接收并进一步扩散。

Solana的这种消息分发方式很特别,灵感来自于BT种子。(原理不易用文字表述,主旨在于同时利用多个节点的闲置带宽,并行式的传输数据)。一般而言,交易序列被切分的碎片数越多,节点群体扩散碎片、拼凑交易序列的速度越快,数据同步效率也会显著提升。

而在其他公链中,出块者会向X个邻居节点发送相同的区块,相当于把一个区块复制X份发出去,而非分发X个不同的碎片(小区块),这种做法产生的数据冗余和带宽浪费很严重。究其根源,传统的区块Block式结构不可切分,根本无法灵活传输,而Solana干脆以交易序列Sequence替代区块式结构,结合类似BT种子的Turbine协议,可以实现高速的数据分发,极大提升了吞吐量TPS。

Solana官方曾表示,在Turbine传输协议下,网络有4万个节点时,可以在0.5秒内把一个交易序列同步给所有节点。

同时,在Turbine协议下,节点按照其质押资产的权重,被划分为不同的层级(优先级),质押资产多的Validator率先收到Leader发出的数据,之后由这些节点传递给下一层。在这种机制下,占全网质押资产2/3权重的节点群体,会最先收录Leader发出的交易序列,加快账本(区块)的确认速度。

根据Solana浏览器披露的数据,目前2/3的质押权重被132个节点瓜分,再结合前文所说的传播机制,这些节点最先收到Leader发出的交易序列,也会率先给出投票。而只要得到这132个节点的投票,Leader发布的交易序列便可敲定。从某种角度看,这些节点抢跑在其他节点之前,如果他们串谋,便可产生某些作恶场景。

更值得注意的是,目前Solana有25个节点占据了1/3的质押权重,按照拜占庭容错理论,只要这25个节点集体串谋(比如故意不向某个Leader发出投票),足以让Solana网络陷入混乱。某种程度来讲,Solana面临的“寡头政治”问题是所有采用POS投票制的公链都应该去重视的。

4.POH(Proof Of History):前文提到,Turbine协议允许Leader将交易序列切碎,把不同的碎片发布出去。这种做法要有一个保障:交易序列被切碎后,要容易被拼凑复原。为了解决这个问题,Solana特意在数据包中掺杂纠删码(可防止数据丢失),并且引入独创的POH(Proof Of History)机制为交易事件排序。

在Solana白皮书中,Yakovenko以哈希函数SHA256为案例,展示了POH的原理。为了便于理解,本文将以下面的例子解释POH机制:

(由于POH及对应的时间演进逻辑较难用语言描述,建议先阅读Solana中文白皮书对POH的解读, 再将本文以下桥段作为辅助阅读)

·SHA256函数的输入值和输出值是唯一映射的(1对1),输入参数X后,仅有唯一的输出结果SHA256(X)=?;不同的X会得到不同的 ?=SHA256(X);

·如果循环、递归的计算SHA256,比如: 定义X2 = SHA256 ( X1 ), 再用X2计算X3 = SHA256 (X2),再算X4 = SHA256 (X3),如此重复迭代下去,Xn = SHA256 ( X[n-1] );

·反复执行这个过程,最终我们会得到一个X1,X2,X3......Xn的序列,该序列有个特点:Xn = SHA256 ( X[n-1] ),排在后面的Xn是前面X[n-1]的“后代”。

·将该序列公开发布后,如果有外人想验证序列的正确性,比如他想判断Xn是否真的是X[n-1]的“合法后代”,可以直接将X[n-1]代入SHA256函数去算,看结果和Xn是否相同。

·在这种模式下,没有X1就得不到X2,没有X2得不到X3......没有Xn得不到后面的X[n+1]。这样一来,序列就具有了连续性和唯一性。

·最关键的一点:交易事件可以被插进序列里。比如: 在x3出生后、x4未出现时,交易事件T1可作为外部输入,和X3迭加在一起,得到x4 = SHA256(X3+T1)。其中,X3的出现略早于T1,X4则为(T1+X3)孕育的后代,T1实质被夹在X3和X4的“生日”之间。

以此类推,T2可以在X8产生后,作为外界的输入参数,计算X9=SHA256(T2+X8),这样T2的出现时间就被夹在x8和x9的“生日”之间;

•在上面的场景中,实际的POH序列为以下形式

其中,交易事件T1和T2是外界插入序列里的数据,在POH序列的时间记录上,他晚于X3早于X4。 只要给出T1在POH序列里的次序号,可得知它之前发生了多少次SHA256计算(T1前面有X1、X2、X3,发生了3次SHA256计算)。 同样的道理,T2前面有X1~X8八个X,发生了8次计算。

以上过程的白话解释如下:有个人拿着秒表在那里数秒,每当他收到一封信,他就按照秒表的读数,在信封上记下时间。收到十封信后,这十封信上记录的秒数肯定不同,有先后区分,这就给不同的信件排了序,根据信件上的记录还可以知道两封信之间隔多久。

·Leader在对外发布交易序列时,只要在T1的数据包里给出X3的数值,并告知X3的序号(第3个),接收数据包的Validator便可解析出T1之前的完整POH序列; 只要在T2的数据包里,提供X8的数值,及其序号8,Validator便可解析出T2之前的完整POH序列;

·按照POH的设定,只要标记出每笔交易在POH序列里的序号(Counter),并给出紧挨着它的X值(Last Valid Hash),就可以披露出每笔交易的次序。由于SHA256函数本身的特性,这种通过哈希计算来敲定的次序,难以被篡改。

同时,Validator知道Leader得出POH序列的方式,他们可以执行相同的操作,还原出完整的POH序列,验证Leader发布的数据的正确性。

For example,如果Leader发布的交易序列数据包为: T1,序号3,紧邻X3; T2,序号5,紧邻X5; T3,序号8,紧邻X8; T4,序号10,紧邻X10; POH序列初始值X1;

Validator接收到以上数据包后,便可把X1作为初始参数,循环代入SHA256函数自行计算,解析出完整的POH序列为:

这样一来,只要知道序列里总共包含多少个X,就可得知计算者做了几次SHA256计算。事先估计好每次哈希计算的耗时,就可以知道不同交易的时间间隔(比如T1和T2之间隔了2个x,就隔着2次SHA256计算,约为??毫秒)。得知了不同交易之间相隔的秒数后,可以更方便的确定每笔交易发生的时间点,省去了很多麻烦的工作。

·一般而言,Leader会时刻不停的执行SHA256函数,得到新的X,把序列不断向前推进。如果有交易事件,就将其作为外部输入,插进序列里;

·如果有节点尝试在网络中发布掺水的序列,替换Leader发布的版本,比如把上文中的X2替换为X2’ ,序列变为X1,X2’,X3......Xn,显然其他人只要对比X3和SHA256(X2’),就可以发现两者对不上号,序列造假了。 所以,造假者必须把X2’之后的X全部替换才行,但这样做成本很高,尤其在X的个数很庞大的情况下,造假将非常浪费时间。此情此景,最好的办法就是不去造假,收到了Leader发出的序列后原方不动的转发给别的节点。 再考虑到Leader会在发布的每个数据包里加上自己的数字签名,在网络内传播的序列其实是“唯一的”“难以被篡改的”;

5.全网一致的时间推进:Solana的创始人Yakovenko曾强调,POH最大的作用是提供了一个“全局一致的单一时钟”(其实应该转译为:全网一致的时间推进) 。这句话其实可以这样理解: Leader节点在网络内发布了一个唯一的、难以篡改的交易序列。根据该交易序列的数据包,节点可以解析出完整的POH序列,而POH序列是Solana独创的计时方式,可以作为时间参照物。

如前文所述,由于Leader会时刻不停的执行SHA256哈希计算,把POH序列不断向前推进,这个序列记录了N次哈希计算的结果,对应着N次计算过程,包含了时间推移。而Solana把计算的次数当做独特的计时方式。

在原始的参数设定中,默认200万次哈希计算对应现实中1秒,每个Slot出块周期为400 ms,也就是说每个Slot产生的POH序列包含80万次哈希计算。Solana还创造了一个名为Tick(滴答)的名词,类比钟表指针前进时的滴答声。按照设定,每个Tick应该包含1.25万次哈希计算,1个Slot周期包含64次Tick,每160次Tick对应现实中1秒。

以上只是理想状态下的设定,在实际的运行过程中,每秒可产生的哈希计算次数往往不固定,所以实际的参数应该是动态调整的。但以上说明可以解释POH机制的大致逻辑,这种设计让Solana节点在收到POH序列后,根据其中包含的哈希计算次数,判断1个Slot是否结束,以及是否到了下一个Leader该出现的时候(4个Slot一轮换)。

由于可以判断每个Slot的 起始点,Validator会把 起始点 中间夹着的交易序列划分为一个区块。一旦得到敲定,就相当于把账本向前推进了一个区块,系统则向前推移了一个Slot。

这就可以用一句话概括: “时钟的指针不会回头,但我们可以用自己的手把它向前推”。—碇源渡《新世纪福音战士EVA》

换言之,只要节点都收到相同的交易序列,那么他们解析出的POH序列,及对应的时间推进都是一致的。这就创造了一个“全局一致的单一时钟”(全网一致的时间推进)。

(在原始的Tendermint算法中,每个节点在本地的账本上添加的是相同的区块,区块高度一致,几乎从不分叉,所以按照Solana对“时间推移”的解释,在Tendermint中,不同节点的时间推移应该也是一致的)

此外,由于交易事件在POH序列中的序号是给定的,节点仅凭自己计算就可获知,不同的交易之间隔了多少次哈希计算(隔着几个X),也就能大致估算出不同交易之间的时间差△T。

有了大致的△T和某个初始的时间戳TimeStamp 0后,就可以像多米诺骨牌一样,粗略估算每起事件的发生时刻(时间戳)。 For example: T1发生于01:27:01,T2与T1之间隔着1万次哈希计算(1万个X),如果1万次哈希计算耗时约为1秒,则T2大概发生在T1的1秒后,也就是01:27:02。以此类推,所有交易事件发生的时间(时间戳)都可以粗略推算出来,这带来了巨大便利,允许节点独立确认某些数据的送达时间。

同时,POH机制也方便统计各节点给出投票的时间点。Solana白皮书中提出,Validator应该在Leader每次发布State状态信息后的0.5秒内提供投票。

如果0.5秒对应着100万次哈希计算(前文的100万个X),而Leader发布State后,后面的序列里连续100万次哈希计算都没有收录进某节点的投票,大家就可以得知这个节点在偷懒,没有在规定时间内履行投票的义务,届时系统可以执行相应的惩罚措施(Tower BFT)。

6.与Optimism的相似性:以上即为Solana独创的POH(Proof Of History),类似于Optimism和Arbitrum的交易排序形式,都通过与哈希函数有关的计算,来确立一个“不可篡改、唯一确定”的交易事件序列,之后由Leader/Sequencer将这个序列发布给验证节点Validator/Verifier。

在Optimism中也有类似Leader的角色,叫Sequencer(排序器),它在数据传输中也取缔了区块式结构,定期在以太坊某合约地址中发布交易序列,叫Validator自己去读取并执行。不同的Validator收到的交易序列都是相同的,那么他们执行下来后得到的状态State也必定相同。这个时候再去对比Sequencer的状态State,各个Validator自己就能验证其正确性,几乎不需要和其他节点沟通。

在Optimism的共识机制中,并没有要求不同Validator之间进行互动,也没有收集投票的步骤,“共识”其实是隐式的。如果有Validator执行完交易序列后,发现Sequencer/Leader提供的状态信息State不对,就可以发起“挑战”,质疑Sequencer/Leader。但在这种模式下,Optimism为交易事件提供了7天的敲定窗口期,Sequencer发布交易序列后,需要7天无人质疑,才能最终确认,这显然是Soalna无法接受的。

Solana要求Validator尽快给出投票,目的在于让网络快速达成共识,快速敲定交易序列,这样可以比Optimism具备更高的效率。

此外,Solana分发和验证交易序列的方式更灵活,允许将一个序列切碎,以碎片的形式分发,这为Turbine协议的实行创造了完美的土壤;

同时,Solana允许节点同时运行多个计算部件,并行式的验证不同碎片的正确性,把验证工作分担开,大幅节约时间。在OP和Arbitrum中则不允许这种做法,Optimism直接以1笔交易对应1个执行后状态State的方式,通过Transcation—State映射的形式给出交易序列,只能由一个CPU核心从头到尾一步一步的去计算一遍,才能验证整个序列的正确性,相对而言笨重低效很多。Solana的POH序列可以从任意一个位置开始验证,多个计算单元可以同时验证不同的POH片段,这就为多线程并行式的验证模式提供了基础。

7.针对节点本身的纵向扩容:以上是Solana在出块流程、共识机制和数据传输协议上的改良,除此之外,Solana还创建了名为Sealevel和Pipeline、 Cloudbreak的机制,支持多线程、并行、并发的执行模式,并支持以GPU来作为执行计算的部件,大幅提高了节点处理指令的速度,优化了硬件资源的利用效率,属于纵向扩容的范畴。由于相关技术细节较为复杂,且与本文的侧重点并无关联,在此不展开赘述。

虽然Solana的纵向扩容大幅提升了节点设备处理交易指令的速度,但也抬高了对硬件配置的要求。目前Solana的节点配置要求很高,被许多人评为“企业级硬件水平”,并被斥责为“节点设备最昂贵的公链”。

以下为Solana的Validator节点硬件要求: Cpu 12或24核,内存至少128 GB,硬盘2T SSD,网络带宽至少达到300 MB/s,一般为1GB/s。 再对比当前以太坊节点的硬件要求(转型POS前): CPU 4核以上,内存至少16 GB,硬盘0.5 T SSD,网络带宽至少25 MB/s。

考虑到以太坊转型POS后节点硬件配置要求会调低,Solana对节点硬件的要求远远高于前者。根据部分说法,一个Solana节点的硬件成本,相当于几百个转型POS后的以太坊节点。由于节点运行成本过高,Solana网络的运行工作很大程度上成为了鲸鱼和专业机构、企业的专利。

对此,以太坊前CTO、Polkadot创始人Gavin Wood曾在去年Solana首次宕机后评论称:真正的去中心化和安全性比高效率更有价值。如果用户不能自己运行网络的全节点,那么这样的项目将和传统银行毫无区别。

全文总结

  • Solana扩容主要基于:高效利用网络带宽、减少节点间通讯次数、加快节点处理事务的速度 三大方面,这些措施直接缩短了出块和共识通讯的时间,但也降低了系统可用性(安全)。
  • Solana提前公开每个出块周期Slot内的出块者Leader名单,实质揭示了单一可信的数据来源,借此大幅精简了共识通讯的流程。但公开Leader信息会带来贿赂、针对性攻击等潜在安全隐患。
  • Solana将共识通讯(投票信息)作为一种交易事件来处理,TPS成分中往往超过70%都是共识讯息,真实与用户交易相关的TPS约为500—1000;
  • Solana的Gulf Stream机制实质取缔了全局性交易池,虽然这提高了交易处理速度,但普通节点无法高效拦截垃圾交易,Leader会面临巨大压力,容易致使其宕机。若Leader宕机,则共识讯息无法正常发布,网络容易分叉甚至崩溃;
  • Solana的Leader节点发布的是交易序列,而非真实的区块。结合Turbine传输协议,交易序列可以被切碎后分发给不同节点,最终的数据同步速度极快。
  • POH(Proof Of History)实质为一种计时和计数方式,它可以给不同的交易事件盖上不可篡改的序号,生成交易序列。同时,由于同一时间只有单一的Leader发布交易序列,其中蕴含POH计时序列,Leader实质上发布了全网一致的计时器(时钟)。在一个很短的窗口期内,不同节点的账本推进、时间推移都是一致的;
  • Solana有132个节点占据67%的质押份额,其中的25个节点占据33%的质押份额,基本构成了“寡头政治”或“元老院”。如果这25个节点串谋,足以导致网络陷入混乱;
  • Solana对节点硬件水准要求较高,它在抬高设备成本的基础上,实现了纵向扩容。但这也致使运行Solana节点的个体多为鲸鱼或机构、企业,不利于真正意义的去中心化。

从某种角度来看,Solana实际成为了公链中最特立独行的存在,它以高级的节点硬件水准、颠覆性的共识机制与网络传输协议,将Layer1扩容的叙事推向了极端,基本触及了无分片公链可长期维持的TPS瓶颈,但Solana的多次宕机,似乎已经说明了牺牲 可用性/安全性 来换取效率的最终结局。

从长远看,去中心化和安全性始终是公链领域的核心叙事,虽然Solana靠着一时的TPS数值与SBF等金融大鳄的推波助澜,一度成为资本簇拥下的瑰宝,但EOS的结局已经昭示,Web3世界不需要单纯的营销和高效率,只有真正具备可用性的事物,能够在历史洪流的冲刷中屹立不倒,永世长存。

(在此特别感谢 《嵌入式系统安全》的作者 刘洋 先生、Rebase社区 及 W3.Hitchhiker团队 对本文作者的帮助)

参考文献

1.Solana白皮书中文版

2.Gulf Stream: Solana’s Mempool-less Transaction Forwarding Protocol

3.Turbine Block Propagation

4.Solana调研报告

5.Solana之旅

6.与币安钱包合作的高性能公链Solana是如何提速的?

7.Overclock blockchain to 710,000 transactions per second: a review of the Proof of History algorithm

8.Solana 的逆袭之路 - SQLANA

9.PoS和Tendermint共识讲解

10.以太坊源码分析:交易缓冲池txpool

11.以太坊交易池架构设计

12.PBFT基础流程

13.Tendermint-2-共识算法:Tendermint-BFT详解

14.Cardano(ADA)的共识算法Ouroboros

15.深度调查:新公链们为何频现宕机事故?

16.深度解读Optimism:基本架构、Gas机制与挑战 | CatcherVC Research

17.剖析新版Metis:Gas最低Layer2的去中心化进行时 |CatcherVC Research

Solana