新消息:Helius 收购 Light Protocol
Solana 执行概览
博客/基础知识

Solana 执行概览

研究员X 上的 Lostin
阅读需 34 分钟

衷心感谢 0xIchigo、dubbelosix、Jacob Creech、Maël Bomane、Nagaprasad Vr 和 Rex St. John 阅读本报告的早期版本并提供宝贵反馈。

引言

我们比世界上任何人都更了解如何做到更小、更快、更便宜,现在我们正将这些理念应用于区块链。

Greg Fitzgerald
Greg Fitzgerald
Solana 联合创始人

Solana 是一个高性能、低延迟的区块链,以速度、效率和对用户体验的重视而著称。其独特的一体化架构让全球去中心化网络每秒能够处理数千笔交易。它的区块时间为 400 毫秒,交易费用仅为几美分的一小部分,兼具速度与成本效益。本报告将深入解析 Solana 的设计和运行机制,探讨成就其能力的关键机制与网络拓扑。

Solana 采用一体化的区块链开发方式,并充分利用创始团队数十年构建分布式系统的经验。Solana 的核心原则之一是,软件绝不能成为硬件的阻碍。这意味着软件会充分发挥运行它的硬件性能,并随硬件扩展。作为一个统一的生态系统,构建在这条区块链上的所有应用都天然具备可组合性,可以无缝交互并彼此构建。这种架构也确保了简单直观的用户体验,无需跨链桥、独立的链 ID 或碎片化的流动性。

Solana 正在快速演进,近期进展包括 SVM rollup 和作为重要扩容方案的 ZK Compression。这些项目或许有一天会塑造我们未来对 Solana 的认知,但目前仍处于开发或采用的极早期阶段,因此本报告不会展开讨论。

交易生命周期

在本报告中,我们将主要通过典型交易的生命周期来理解 Solana。为了建立一个理解 Solana 交易的基础模型,可以将流程概括如下: 

  • 用户发起交易,所有交易都会发送给当前的主要区块生产者(称为 leader)。leader 将这些交易编入区块并执行,从而更新其本地状态。
  • 随后,这个交易区块会传播至整个网络,供其他验证者执行和确认。‍

本报告后续章节将扩展这一模型,更深入地解析该流程。首先从关键参与者——用户——开始。

六个阶段

本报告将持续引用上方的六阶段示意图,因为它为理解 Solana 核心要素之间的关系提供了一套一致的框架。

前面的章节按照这六个阶段编排。最后几章——Gossip、归档、经济机制和 Jito——将补充其余内容。需要注意的是,有些章节会横跨多个阶段,有些阶段也会出现在多个章节中。

这种重叠无法避免,因为六阶段框架本身存在局限。实际上,Solana 是一个复杂的分布式系统,包含许多相互依赖的要素。

用户

Solana 有潜力成为加密领域的 Apple。

Raj Gokal
Raj Gokal
Solana 联合创始人

用户通常从设置钱包应用并为其充值开始。Solana 上有多款热门钱包应用,既有原生移动应用,也有浏览器扩展。

钱包通过密码学方式生成用户密钥对,其中包含公钥和私钥。公钥是账户的唯一标识符,网络中的所有参与者都可以获知它。用户在 Solana 上的账户可以视为一种数据结构,用于保存与其在 Solana 区块链上的交互相关的信息和状态。就此而言,公钥类似于文件名:文件名能唯一标识文件系统中的文件,而 Solana 公钥则能唯一标识 Solana 区块链上的账户。Solana 公钥以 32 字节、Base58 编码的字符串表示。

FDKJvWcJNe6wecbgDYDFPCfgs14aJnVsUfWQRYWLn4Tn

私钥——也称为秘密密钥——可以视为授予账户访问和修改权限的密码或访问密钥。区块链通过私钥签名来处理授权。掌握私钥就拥有对账户的绝对控制权。Solana 私钥的长度同样为 32 字节。密钥对是由公钥(前半部分)和私钥(后半部分)组成的 64 字节组合。

示例:

3j15jr41S9KmdfughusutvvqBjAeEDbU5sDQp8EbwQ3Hify2pfM1hiEsuFFAVq8bwGywnZpswrbDzPENbBZbd5nj

[63,107,47,255,141,135,58,142,191,245,78,18,90,162,107,197,8,33,211,15,228,235,250,30,185,122,105,23,147,115,115,86,8,155,67,155,110,51,117,0,19,150,143,217,132,205,122,91,167,61,6,246,107,39,51,110,185,81,13,81,16,182,30,71]

私钥也可以从助记词种子短语派生,通常由 12 或 24 个单词组成。钱包经常采用这种格式,以便备份和恢复。一个种子短语可以确定性地派生出多个密钥。

Solana 使用广泛应用的椭圆曲线数字签名算法 Ed25519 来满足其公钥密码学需求。Ed25519 因密钥小、签名小、计算快且能抵御多种常见攻击而受到青睐。每个 Solana 钱包地址都代表 Ed25519 椭圆曲线上的一个点。

用户使用私钥签署交易。该签名会包含在交易数据中,其他参与者可以使用发送者的公钥进行验证。这个过程可确保交易未被篡改,并且已由对应私钥的所有者授权。签名也会充当交易的唯一标识符。

Solana 交易‍

发送交易是更改 Solana 状态的唯一方式。任何写入操作都通过交易执行,而且交易具有原子性——交易尝试执行的所有操作要么全部发生,要么整笔交易失败。交易的正式名称是“交易消息”,由四个部分组成:标头、账户地址列表、近期区块哈希和指令。

标头

标头包含对账户地址列表的引用,用于指明哪些账户必须签署交易。

账户地址

该列表包含交易期间将被读取或写入的所有账户。为每笔交易构建这样的列表是 Solana 特有的要求,可能会给开发者带来挑战。不过,提前知道交易将与哪些状态交互,也能实现许多其他区块链无法做到的优化。

近期区块哈希

它用于防止重复交易和过期交易。近期区块哈希会在 150 个区块后过期(约 1 分钟)。默认情况下,RPC 会每 2 秒尝试转发一次交易,直到交易最终确定或近期区块哈希过期;后者发生时,交易会被丢弃。

指令

指令构成交易的核心部分。每条指令代表一项特定操作(例如转账、铸造、销毁、创建账户、关闭账户)。每条指令都会指定要执行的程序、所需账户以及执行指令所需的数据。

一笔交易中的指令数量首先受交易大小限制,最大为 1,232 字节。可引用的账户数量也有限制。最后,交易的复杂度也受到计算单元(CU)的限制。CU 用于量化处理交易时消耗的计算资源。

执行交易所需的 SOL 成本分为两部分:基础费用和优先费。无论交易复杂度如何,基础费用固定为每个签名 5000 lamport——通常每笔交易有 1 个签名。

从技术上讲,优先费是可选的,但在区块空间需求较高时不可或缺。该费用按每个计算单元多少微 lamport(百万分之一 lamport)计价。其目的是作为价格信号,提高验证者节点将交易纳入区块的经济吸引力。 ‍

total fee = prioritization fee + base fee

prioritization fee = compute unit price (micro-lamports) x compute unit limit

目前,所有交易相关费用的 50% 会被销毁,从而将这些 SOL 永久移出流通;剩余 50% 归区块生产者所有。一项新变更(SIMD 96)即将推出,届时 100% 的优先费都将归区块生产者所有。基础费用保持不变。

发送交易

用户将钱包连接到应用,使应用能够读取用户的公钥。私钥仍保持加密状态,并安全地隔离在与应用分开的环境中。

应用根据用户的交互构建交易消息参数。例如,如果用户想兑换两种代币,就需要指定要买入的代币数量、对应要卖出的代币,以及可接受的交易滑点。

交易消息准备好后,会发送到钱包,使用用户的私钥签名。此时会弹出窗口,请用户确认是否愿意进行交易。该窗口可能包含交易结果的模拟。签名完成后,交易消息和签名会返回应用,应用随后可以将交易转发给用户选择的 RPC 提供商,可以是用户自己的,也可以是钱包使用的提供商。

RPC(远程过程调用)提供商充当应用与构建区块的验证者之间的中介。它们是一项关键服务,让应用能够提交或模拟已签名交易,并高效获取链上数据。应用通过 JSON-RPC 或 WebSocket 端点与网络交互(文档)。

Gulf Stream

Solana 的目标就是让交易传播得和新闻传遍全球一样快——也就是光在光纤中的速度。我们的竞争对手是 NASDAQ 和纽约证券交易所。

Anatoly Yakovenko
Anatoly Yakovenko
Solana 联合创始人

RPC(远程过程调用)是指 RPC 节点。这些节点可以视为与网络交互和读取网络数据的网关。它们运行与完整验证者相同的软件,但设置不同,因此能够准确模拟交易,并维持对当前状态的最新视图。截至本文撰写时,Solana 网络上已有超过 4,000 个 RPC 节点。

与完整验证者节点不同,RPC 节点在网络中没有任何质押。没有质押,它们就无法投票或构建区块。这种设置不同于大多数其他区块链,后者的验证者节点和 RPC 节点通常是同一节点。由于 RPC 节点不会获得质押奖励,运行 RPC 节点的经济模式与验证者不同,许多 RPC 节点以付费服务的形式面向运行 Solana 应用的开发者。

Solana 的突出之处在于,它从设计之初就以无需内存池即可运行为目标。传统区块链通过 gossip 协议在网络中随机、广泛地传播交易,而 Solana 会将在每个时隙中把所有交易转发给预先确定的主要验证者,即 leader。

RPC 收到需要纳入区块的交易消息后,必须将其转发给 leader。每个 epoch(约两天)开始前都会生成 leader 排期。即将到来的 epoch 会被划分为多个时隙,每个时隙固定为 400 毫秒,并为每个时隙选出一名 leader。质押量较高的验证者在每个 epoch 中被选为 leader 的次数更多。在每个时隙内,交易消息会被转发给有机会生成区块的 leader。轮到某个验证者时,它会切换到“leader 模式”,开始主动处理交易,并向网络中的其他节点广播区块。

质押加权服务质量 - SWQoS

2024 年初,Solana 引入了一种旨在防止垃圾信息并增强女巫攻击抵抗力的新机制,称为质押加权服务质量(SWQoS)。该系统使 leader 能够优先处理由其他已质押验证者代理的交易消息。在这里,质押量较高的验证者会按比例获得更多向 leader 传输交易消息数据包的容量。这种方法有效缓解了网络中未质押节点发起的女巫攻击。

‍在这种模式下,验证者还可以通过协议将其质押加权容量出租给 RPC 节点。作为回报,RPC 节点可以获得更高带宽,从而提升交易被纳入区块的比例。值得注意的是,leader 80% 的容量(2,000 个连接)预留给 SWQoS。其余 20%(500 个连接)分配给来自未质押节点的交易消息。这种分配策略类似于高速公路上的优先车道,驾驶者支付通行费来避开拥堵。

SWQoS 提高了向 leader 转发交易的要求,并降低了垃圾信息攻击的有效性,因此对 Solana 生态系统产生了影响。这项变更激励高流量应用进行垂直整合。通过运行自己的验证者节点或访问质押连接,应用可以确保获得访问 leader 的特权,从而增强交易处理能力。

关于 QUIC

2022 年底,Solana 采用 QUIC 网络协议来管理向 leader 传输交易消息。这次转变源于机器人在链上 NFT 铸造期间发送大量垃圾信息,导致网络中断。QUIC 支持快速异步通信。

‍QUIC 最初由 Google 于 2012 年开发,试图兼得两者之长。它既能提供类似 UDP 的快速异步通信,又具备 TCP 的安全会话和高级流量控制策略。这样便能限制单个流量源,让网络专注处理真实交易。它还有独立流的概念,因此即使一笔交易被丢弃,也不必阻塞其他交易。简而言之,QUIC 试图结合 TCP 和 UDP 的最佳特性。

区块构建

我们认为,就目前的虚拟机技术而言,SVM(Solana Virtual Machine)是最优秀的。

Andre Cronje
Andre Cronje
Fantom Foundation 首席技术官

许多区块链网络会先构建完整区块再进行广播,这称为离散区块构建。相比之下,Solana 采用连续区块构建,在分配的时隙内随着区块的创建动态组装并传输,从而显著降低延迟。

每个时隙持续 400 毫秒,每位 leader 会连续获得四个时隙(1.6 秒),之后轮换至下一位 leader。要让一个区块被接受,其中的所有交易都必须有效,并能由其他节点复现。

验证者会在担任 leader 前两个时隙停止转发交易,为即将到来的工作负载做准备。在此期间,入站流量会激增至每秒超过 1 GB,因为整个网络都在将数据包发送给即将上任的 leader。

交易消息抵达后会进入交易处理单元(TPU),这是验证者负责区块生产的核心逻辑。交易处理流程从获取阶段开始,此时通过 QUIC 接收交易。随后,交易进入签名验证阶段,接受严格的有效性检查。验证者会在此验证签名的有效性、检查签名数量是否正确,并排除重复交易。

‍Banking 阶段

Banking 阶段可以描述为区块构建阶段。它是 TPU 最重要的阶段,其名称源自“bank”。bank 就是给定区块的状态。对于每个区块,Solana 都有一个 bank,用于访问该区块的状态。当足够多的验证者对区块投票,使其最终确定后,账户更新会从 bank 刷写到磁盘,成为永久记录。链的最终状态是所有已确认交易共同作用的结果。该状态始终可以根据区块链历史以确定性方式重建。‍

交易会并行处理,并打包为账本“条目”;每个条目是一批包含 64 笔互不冲突的交易。在 Solana 上,并行处理交易很容易,因为每笔交易都必须完整列出其将读取和写入的所有账户。这一设计选择增加了开发者的负担,但也让验证者能够轻松选择互不冲突的交易放入每个条目执行,从而避免竞态条件。如果两笔交易都尝试写入同一账户(两次写入),或者一笔尝试读取而另一笔尝试写入同一账户(读取 + 写入),它们就会发生冲突。因此,冲突交易会进入不同条目并按顺序执行,而非冲突交易则并行执行。

系统使用六个线程并行处理交易,其中四个处理普通交易,另外两个专门处理投票交易;投票交易是 Solana 共识机制不可或缺的一部分。所有并行处理都通过多个 CPU 核心实现,验证者不需要 GPU(文档)。‍

交易分组为条目后,就可以由 Solana Virtual Machine(SVM)执行。交易所需的账户会被锁定;系统随后执行检查,确认交易是近期交易且尚未被处理。接着加载账户并执行交易逻辑,更新账户状态。条目哈希会发送到历史证明服务进行记录(下一节将详细介绍)。如果记录过程成功,所有变更都会提交到 bank,并解除第一步中对各账户施加的锁。执行由 SVM 完成,它是一个使用 Solana 分叉版 rBPF 构建的虚拟机;rBPF 是用于处理 JIT 编译和 eBPF 程序虚拟机的库。请注意,Solana 并未规定验证者应如何选择区块内的交易顺序。这种灵活性非常关键,我们将在本报告后面的经济机制 + Jito 章节中再次讨论。‍

客户端

Solana 网络由数千个独立运营的节点组成,这些节点协同维护一份统一账本。每个节点都是一台高性能机器,运行着同一种称为“客户端”的开源软件。

Solana 上线时只有一种验证者客户端软件——最初称为 Solana Labs 客户端,如今称为 Agave 客户端——使用 Rust 编写。此后,扩大客户端多样性一直是优先事项,并将在 Firedancer 客户端发布后真正实现。Firedancer 使用 C 编程语言从零开始完整重写了原始客户端。它由高频交易公司 Jump 的资深团队构建,有望成为所有区块链中性能最强的验证者客户端。

历史证明

我喝了两杯咖啡和一杯啤酒,一直熬到凌晨 4 点。那一刻我突然顿悟:这个谜题 [原文如此] 类似于工作量证明,使用相同的 SHA-256 抗原像哈希函数……我意识到,我找到了时间之箭。

Anatoly Yakovenko
Anatoly Yakovenko
Solana 联合创始人

历史证明 (PoH) 是 Solana 的独门秘方。它就像每个验证者内部的一座特殊时钟,帮助整个网络保持同步。PoH 为事件顺序和时间流逝建立了可靠的事实来源。最关键的是,它能确保所有节点遵循领导者调度。尽管名称相似,但历史证明并非工作量证明那样的共识算法。

‍随着网络扩张,节点之间的通信开销通常会增加,协调也会变得更加复杂。Solana 通过用 PoH 本地计算取代节点间通信来缓解这一问题。这意味着验证者只需一轮投票即可承诺一个区块。消息中的可信时间戳可确保验证者不会相互抢跑,提前开始生成自己的区块。

PoH 的基础是哈希算法的独特属性,具体来说是 SHA256:

  • 确定性: 相同的输入始终会生成相同的哈希值。
  • 固定大小: 无论输入大小如何,输出哈希值始终为 256 位。
  • 高效: 对任何给定输入都能快速计算哈希值。
  • 抗原像性:从哈希输出中找出原始输入在计算上不可行。
  • 雪崩效应: 输入中的微小变化(即使只有一位)也会产生截然不同的哈希值,这种属性称为雪崩效应。
  • 抗碰撞性:找出两个产生相同哈希输出的不同输入在计算上不可行。

在每个验证者客户端中,一个专用的“历史证明服务”会持续运行 SHA256 哈希算法,生成一条哈希链。每个哈希的输入都是前一个哈希的输出。由于哈希计算必须按顺序进行,而且未来哈希的结果无法提前得知,因此这条链的作用与可验证延迟函数相同。如果 PoH 服务创建了一条包含一千个哈希的链,我们就知道它必然花费了一定时间来依次计算每个哈希——这可以视为一种“微型工作量证明”。然而,由于每个哈希的输入和输出都已广播到网络,其他验证者可以并行验证这一千个哈希的正确性,速度远快于它们的生成速度。因此,PoH 难以生成,却易于验证。

不同 CPU 计算 SHA-256 的性能差异小得令人惊讶,即使最快的机器之间也只有微小差别。尽管人们投入了大量时间和精力来优化这一函数,但其性能已经触及一个普遍的上限,这在很大程度上源于 Bitcoin 对它的依赖。

‍在领导者的 slot 期间,PoH 服务会接收来自银行阶段的新处理条目。当前 PoH 哈希与条目中所有交易的哈希会合并为下一个 PoH 哈希。它相当于一个时间戳,将条目插入哈希链,并证明交易的处理顺序。这个过程不仅确认了时间的流逝,还构成了交易的密码学记录。

单个区块中包含 800,000 个哈希。PoH stream 还包含“tick”,即表示领导者仍处于活跃状态和时间正在流逝的空条目,时间跨度约为一秒的一小部分。每 6.25 毫秒产生一个 tick,因此每个区块包含 64 个 tick,总区块时间为 400 毫秒。

即使不是领导者,验证者也会持续运行 PoH 时钟,因为它在节点间同步过程中发挥着关键作用。

账户模型

在 SVM 中分离代码与状态是最出色的设计决策。感谢那些虔诚地把这个概念灌输到我脑中的嵌入式系统开发者。

Anatoly Yakovenko
Anatoly Yakovenko
Solana 联合创始人

在 Solana 验证者中,全局状态保存在名为 AccountsDB 的账户数据库中。该数据库负责在内存和磁盘中存储所有账户。账户索引的主要数据结构是 hashmap,因此 AccountsDB 本质上是一个庞大的键值存储。其中,键是账户地址,值是账户数据。

随着时间推移,Solana 账户数量已激增至数亿。这么多账户的部分原因是,正如 Solana 开发者常说的:“Solana 上的一切都是账户!”

Solana 账户

账户是持久保存数据的容器,类似于计算机上的文件。账户有多种形式:

  • 用户账户:这类账户拥有私钥,通常由钱包软件为用户生成。
  • 数据账户:这类账户存储状态信息,例如用户持有的某种代币数量。
  • 程序账户:这是包含可执行字节码的较大账户,大致相当于 Windows 上的 .exe 文件或 Mac 上的 .app 文件。
  • 原生程序账户:这些是预先部署的特殊程序账户,负责执行网络的各种核心功能。示例包括 Vote Program 和 BPF Loader。

所有账户都有以下字段:

程序‍

Solana 程序账户只包含可执行逻辑。这意味着程序运行时会修改其他账户的状态,但程序本身保持不变。代码与状态的分离让 Solana 有别于其他区块链,也为其多项优化提供了支持。开发者主要使用 Rust 编写这些程序。Rust 是一种通用编程语言,以高度重视安全性和性能而闻名。此外,还有多个 TypeScript 和 Python SDK,可用于简化应用前端的创建,并支持以编程方式与网络交互。

原生程序开箱即用地提供了许多常见功能。例如,Solana 不要求开发者部署代码来创建代币。开发者只需向预先部署的原生程序发送指令,该程序就会设置一个账户来存储代币的元数据,从而创建新代币。

租金

租金是一种旨在激励用户关闭账户并减少状态膨胀的机制。要创建新账户,账户必须持有最低额度的 SOL,称为“免租”金额。你可以将其视为让账户持续保存在验证者内存中所需的存储成本。如果账户数据变大,最低租金余额要求也会按比例提高。当账户不再需要时,可以将其关闭,租金会返还给账户所有者。 

例如,如果用户持有一种以美元计价的稳定币,该状态会存储在代币账户中。目前,代币账户的免租金额为 0.002 SOL。如果用户将全部稳定币余额转给朋友,就可以关闭该代币账户,并收回 0.002 SOL。程序通常会自动为用户处理账户关闭操作。还有一些应用可以帮助用户清理旧的闲置账户,并取回其中存储的少量 SOL。

所有权

任何人都可以读取账户数据,但 Solana 的所有权模型通过严格限制谁能修改(写入)账户数据来增强安全性。这一概念对于在 Solana 区块链上执行规则和权限至关重要。每个账户都有一个程序“所有者”。账户所有者负责管理账户,确保只有获得授权的程序才能更改账户数据。这条规则有一个明显的例外:转移 lamports(SOL 的最小单位)。无论所有权归谁,任何人都可以增加账户的 lamports 余额。

状态存储

Solana 程序是只读的可执行文件,因此必须使用“程序派生地址”(PDA) 存储状态。PDA 是一种特殊账户,与某个程序关联并归该程序所有,而不是归特定用户所有。普通 Solana 用户地址由 Ed25519 密钥对的公钥派生,而 PDA 没有私钥。它的公钥由一组参数(通常是关键词或其他账户地址)与所属程序的程序 ID(地址)共同派生。

PDA 地址位于“曲线外”,这意味着它们不像普通地址那样位于 Ed25519 曲线上。只有拥有该 PDA 的程序才能以编程方式为其生成签名,确保只有该程序可以修改 PDA 的状态。

Turbine

Solana 最有趣的部分不是并行化、SVM,也不是 Toly 的推文,而是一个你可能从未听说过的东西:Turbine。

Mert Mumtaz
Mert Mumtaz
Helius 联合创始人兼 CEO

在银行阶段,交易会被组织成条目,并发送到历史证明 stream 进行时间戳标记。区块的 bank 随之更新,这些条目也准备好进入下一阶段——Turbine。

Turbine 是领导者向网络其余部分传播区块的流程。它的设计灵感来自 BitTorrent,旨在实现快速、高效的传播,同时降低通信开销,并尽量减少领导者需要发送的数据量。

‍Turbine 通过名为“shredding”的过程,将交易数据拆分为“shred”来实现这一目标。shred 是不超过 1280 字节的小型数据包,类似于视频 stream 中的单个帧。重新组装后,这些 shred 可让验证者重放整个区块。shred 通过 UDP 在验证者之间经由互联网传输,并使用纠删码处理数据包丢失或恶意丢包。纠删码是一种基于多项式的错误检测和纠正方案,可确保数据完整性。即使部分 shred 丢失,仍可重建区块。

shred 会组成称为前向纠错 (FEC) 批次的分组。默认情况下,每个批次包含 64 个 shred(32 个数据 shred + 32 个恢复 shred)。数据恢复按 FEC 批次进行,也就是说,即使一个批次中多达一半的数据包丢失或损坏,仍能恢复全部数据。每个包含 64 个 shred 的批次都会构建 Merkle 树,由领导者签署根,并与前一批次链接。Merkle 根链提供了可验证的真实性与完整性路径,因此可以从网络中任何持有这些 shred 的节点安全获取它们。

领导者最初会向单个根节点广播,该节点再将 shred 分发给所有其他验证者节点。每个 shred 对应的根节点都会变化。验证者按层组织,形成“Turbine 树”。质押量较大的验证者通常位于树的上层,质押量较低的验证者则位于下层。

‍根据活跃验证者数量,这棵树通常跨越两到三跳。为便于展示,上图采用了 3 的扇出值,但 Solana 当前的实际扇出值设为 200。出于安全考虑,每生成一批新的 shred,树的顺序都会轮换。

这种系统的主要目标是缓解领导者和根节点的出站数据传输压力。通过采用传输和重传机制,负载会分散到领导者和重传节点之间,从而减轻任何单一节点的压力。

共识

一些聪明人告诉我,Solana 有一个真诚且聪明的开发者社区……我希望这个社区能获得公平的发展机会。

Vitalik Buterin
Vitalik Buterin
Ethereum 联合创始人

验证者通过 Turbine 从领导者处收到新区块后,必须验证每个条目中的所有交易。这包括重放整个区块、并行验证 PoH 哈希、按照 PoH 规定的顺序重新执行交易,以及更新本地 bank。 

‍该过程由交易验证单元 (TVU) 处理。它与领导者的交易处理单元 (TPU) 类似,是负责处理 shred 和验证区块的核心逻辑。与 TPU 一样,TVU 流程分为多个阶段。首先是 Shred Fetch Stage,在此阶段通过 Turbine 接收 shred。接下来的 Shred Verify Leader Signature Stage 会对 shred 执行多项合理性检查,其中最重要的是验证领导者签名,以确保收到的 shred 确实来自领导者。 ‍

在 Retransmit Stage,验证者根据自己在 Turbine 树中的位置,将 shred 转发给适当的下游验证者。在 Replay Stage,验证者会以正确顺序精确地重新执行每笔交易,同时更新自己的本地 bank 版本。

Replay Stage 与 TPU 中的银行阶段类似。它是最重要的阶段,也可以更直接地称为区块验证阶段。Replay 是一个单线程处理循环,负责协调多项关键操作,包括投票、重置 PoH 时钟和切换 bank。 

共识

为达成共识,Solana 使用 Tower BFT (TBFT)。它是著名的实用拜占庭故障容错 (PBFT) 算法的定制实现,大多数区块链都使用该算法就链状态达成一致。与所有区块链一样,Solana 假设网络中存在恶意节点,因此系统不仅要能承受节点故障,还必须能抵御一定程度的攻击。

Tower BFT 与其他链的不同之处在于,它利用历史证明提供的同步时钟。传统 PBFT 需要经过多轮通信才能就交易顺序达成一致,而 Solana 节点利用预先确定的事件顺序,显著降低了消息传递开销。

投票

‍为了参与共识并获得奖励,验证者会为其认为有效(即不存在双花或签名错误等问题)且应被视为规范链组成部分的区块提交投票。验证者需要为这些投票支付交易费。投票由领导者处理,并与普通用户交易一起写入区块。这就是 Solana 交易通常分为投票交易和非投票交易的原因。验证者提交正确且成功的投票后会获得一个 credit。该机制激励验证者为其认为最有可能被纳入的分叉投票,也就是“最重”的分叉。

分叉

Solana 速度如此之快,部分原因在于网络不会等待所有验证者就新生成的区块达成一致,才开始生成下一个区块。因此,两个不同区块链接到同一个父区块并形成分叉的情况并不少见。

Solana 验证者必须对这些分叉投票,并使用共识算法确定采用哪一个。当存在竞争分叉时,网络最终只会敲定其中一个,其他被丢弃分叉中的区块则会被放弃。

每个 slot 都有预先指定的领导者,而且只接受该领导者生成的区块;单个 slot 不可能存在两个候选区块。因此,潜在分叉的数量仅限于一种“有/无”跳过列表,这类分叉可能出现在领导者轮换 slot 的边界。一旦验证者选择了某个分叉,就必须承诺支持该分叉,直到锁定期结束,也就是至少在一段时间内坚持自己的选择。

‍Solana 的“跳过率”是未生成区块的 slot 百分比,通常在 2% 到 10% 之间,分叉是 slot 被跳过的主要原因。其他可能原因包括新 epoch 开始、领导者离线或生成了无效区块。

请记住:

Solana 上的交易状态会随其在共识流程中所处的阶段而变化:

  • 已处理:交易已包含在某个区块中。
  • 已确认:交易所在区块已获得三分之二绝对多数的投票。
  • 已敲定:交易所在区块之上已构建超过 31 个区块。

迄今为止,Solana 历史上从未出现过(乐观)确认的区块最终未被敲定的情况。‍

对于每个区块,Solana 都使用 bank 访问该区块的状态。当某个 bank 被敲定时,来自该 bank 及其祖先 bank 的账户更新会写入磁盘。此外,所有来自更早、但并非已敲定 bank 祖先的账户更新都会被清除。这个过程让 Solana 能高效维护多个潜在状态。

Gossip + 归档

区块链需要巧妙结合密码学、分布式系统、操作系统和编程语言。Solana 的超能力,是愿意尖叫着逃离每个领域中最有趣的问题。

Greg Fitzgerald
Greg Fitzgerald
Solana 联合创始人

Gossip

gossip 网络可以视为 Solana 网络的控制平面。数据平面负责处理交易流,而控制平面则传播区块链状态的关键元数据,例如联系信息、账本高度和投票信息。如果没有 gossip,验证者和 RPC 就无法得知各项服务开放了哪些地址和端口用于通信。新节点也依赖 gossip 加入网络。

Solana 的 gossip 协议采用非正式的点对点通信,并使用受改进版 PlumTree 算法启发的树状广播方式。这种方法无需依赖任何中心化来源,就能高效传播信息。

Gossip 在一定程度上作为独立系统运行,与大多数其他验证者组件相互独立。验证者和 RPC 每 0.1 秒通过 UDP 使用 gossip 共享已签名的数据对象,确保整个网络都能获取信息。所有 gossip 消息都不得超过 1280 字节的最大传输单元 (MTU),代码库中将其称为“packet struct”。

Gossip 记录是节点之间共享的实际数据对象。记录大约有 10 种,每种都有不同用途。Gossip 记录经过签名、版本化并带有时间戳,以确保完整性和时效性。

Gossip 消息分为四种:‍

  1. Push:最常见的消息,与一部分“push 对等节点”共享信息。
  2. Pull & Pull Response:定期检查遗漏的消息,并通过 pull 响应返回节点尚未拥有的信息。
  3. Prune:允许节点有选择地减少其维护的连接数量。
  4. Ping & Pong:节点健康检查——发送 ping 后应收到 pong,表明对等节点仍处于活跃状态。

Gossip 数据存储在集群复制数据存储 (CrdsTable) 中。该数据结构可能变得非常庞大,因此需要定期清理。

归档

Solana 与其他区块链的不同之处在于,它不需要完整历史记录来确定账户当前状态。Solana 的账户模型确保任意给定 slot 的状态都是已知的,因此验证者无需处理所有历史区块即可存储每个账户的当前状态。按照设计,RPC 和验证者不会保留完整的历史账本。它们通常只存储 1 或 2 个 epoch(2–4 天)的交易数据,这已足以验证链的顶端。

目前,归档由“仓库节点”管理。这些节点由专业 RPC 服务提供商、Solana Foundation 以及其他希望确保交易历史可用的生态参与者运营。仓库节点通常维护以下一项或两项内容:

  1. 账本归档:上传原始账本和 AccountsDB 快照,适合从头开始重放。
  2. Google Bigtable 实例:存储从创世区块开始的区块数据,并将其格式化以响应 RPC 请求。

经济模型 + Jito

人们正在意识到,Solana 是目前唯一能够支持主流消费级应用的链。

Ted Livingston
Ted Livingston
Code 创始人

Solana 通过通胀机制在每个 epoch 生成新的 SOL 代币,并以此分配质押奖励。这个过程会使非质押者的网络份额相对于质押者下降,从而将财富从非质押者转移给质押者。通胀于 2021 年初开始,初始通胀率为 8%,此后每年下降 15%,直至稳定在 1.5% 的长期水平。

‍任何 SOL 代币持有者都可以将代币质押给一个或多个验证者,以获得奖励并帮助保护网络。将代币分配给验证者称为委托。将代币委托给验证者表示对该验证者的信任,但不会让验证者获得代币的所有权或控制权。所有质押、解除质押和委托操作都会在下一个新 epoch 开始时执行。

投票奖励

‍验证者提交投票后,如果投票准确且成功,就会获得一个 credit。投票交易的费用为 0.000005 SOL,且无需支付优先费。每个验证者每天的投票开支约为 1 SOL,是运行验证者的主要运营成本。在整个 epoch 中,验证者通过投票积累 credit,并可在 epoch 结束时用这些 credit 换取部分通胀奖励。

表现最好的验证者可以成功为大约 90% 的 slot 投票。请注意,没有区块的 slot 百分比(slot 跳过率)在 2% 到 10% 以上,这些 slot 无法投票。平均而言,验证者会成功为约 80% 的 slot 投票,并在包含 432,000 个 slot 的 epoch 中获得 345,600 个 credit。

通胀奖励池首先根据该 epoch 中获得的 credit 进行分配。验证者在全部 credit 中的份额(其 credit 除以所有验证者的 credit 总和)决定了其奖励比例。该比例还会进一步按质押量加权。

因此,如果验证者拥有总质押量的 1%,且其 credit 数量处于平均水平,那么它应获得大约 1% 的总通胀奖励。如果其 credit 数量高于或低于平均水平,奖励也会相应波动。‍

投票表现差异是验证者向质押者提供的回报率(以 APY 衡量)各不相同的原因之一。另一个因素是验证者收取的佣金率,即分配给该验证者的通胀奖励总额中的一定比例。此外,验证者离线或与区块链不同步(称为失职)也会显著影响回报。

区块奖励

被指定为某个区块领导者的验证者会获得额外的区块奖励。这些奖励包括区块中所有交易基础费的 50% 和优先费的 50%,其余费用会被销毁。只有生成该区块的验证者能获得这些奖励。质押奖励按 epoch 分配,而区块奖励会在区块生成时立即记入验证者的身份账户。

流动性质押

流动性质押已成为原生质押的热门替代方案。参与者质押 SOL 后会收到一种代币,称为流动性质押代币 (LST) 或流动性质押衍生品 (LSD)。SOL 通常会存入一个质押池,由该池将代币委托给多个验证者。新收到的 LST 代币代表用户在已质押 SOL 中的份额。这些代币可以交易、在应用中使用或转让给他人,同时仍能赚取质押奖励。该系统的主要优势是显著提高资本效率。

Price of LST = (total staked SOL in pool * price of SOL) / total LST minted

采用传统原生质押时,质押者会随时间直接积累更多 SOL。而在流动性质押中,奖励会重新投入池中,从而提高 LST 的公允价值。只要存在将 LST 赎回为底层已质押 SOL 的机制,套利交易者就会确保代币价格保持合理。

Jito

截至撰写本文时,Solana 上超过 80%(来源)的质押量使用 Jito 验证者客户端软件。该客户端是原始 Agave 客户端的一个分叉,引入了协议外区块空间拍卖,通过小费为验证者提供额外经济激励。这项额外激励是 Jito 客户端在验证者中得到广泛采用的主要原因。

领导者使用 Jito 验证者客户端时,其交易最初会被发送到 Jito-Relayer。这款开源软件充当交易代理路由器。网络中的其他节点并不知道 Jito-Relayer 的存在,因为它们只是将交易发送到领导者通过 gossip 网络公布为其 ingress_socket 的地址和端口配置,并认为该配置属于领导者。

‍中继器会保留所有交易 200 毫秒,然后再将其转发给领导者。这种“减速带”机制会延迟传入的交易消息,为拍卖提供短暂的时间窗口。200 毫秒后,无论拍卖结果如何,中继器都会以乐观方式放行交易。

区块空间拍卖通过 Jito Block Engine 在链下进行,允许搜索者和应用提交以原子方式执行的交易组,称为 bundle。这些 bundle 通常包含套利或清算等时间敏感型交易。Jito 对所有小费收取 5% 的费用,最低小费为 10,000 lamports。小费完全在协议外运作,与协议内的优先费和基础费相互独立。Jito 此前运营过一项规范的协议外内存池服务,但该服务现已弃用。

订阅 Helius

及时了解 Solana 开发的最新动态,并在我们发布新内容时收到更新

放大图片