衷心感谢 0xIchigo、dubbelosix、Jacob Creech、Maël Bomane、Nagaprasad Vr 和 Rex St. John 阅读本报告的早期版本并提供了宝贵的反馈。
本报告的 PDF 版本可在此下载 。
“我们比世界上任何人都更了解更小、更快、更便宜的概念,现在我们将这些概念应用于区块链。” — Greg Fitzgerald,Solana 联合创始人
Solana 是一个高性能、低延迟的区块链,以其速度、效率和用户体验为重点而闻名。其独特的集成架构使其能够在全球分布式网络中每秒处理数千笔交易。其区块时间为 400 毫秒,交易费用仅为几分钱的一部分,既实现了速度又实现了成本效益。本报告深入探讨了 Solana 的设计和操作的复杂性,探索了其能力的关键机制和网络拓扑。
Solana 采用集成的方法进行区块链开发,利用创始团队在构建分布式系统方面的数十年经验。Solana 的核心原则之一是软件永远不应妨碍硬件。这意味着软件会充分利用其运行的硬件并随之扩展。作为一个统一的生态系统,所有构建在这条单一区块链上的应用程序都继承了可组合性,使它们能够无缝地相互交互和构建。这种架构还确保了简单直观的用户体验,无需桥接、单独的链 ID 或流动性碎片化。
Solana 正在迅速发展,最近的发展包括 SVM rollups 和 ZK Compression 作为重要的扩展解决方案。虽然这些项目可能有一天会塑造我们对 Solana 的未来看法,但它们目前处于非常早期的发展或采用阶段,因此不会在本报告中涵盖。
在本报告中,我们理解 Solana 的主要视角将是典型交易的生命周期。为了构建理解 Solana 交易的基本模型,我们可以概述如下过程:
本报告的后续部分将扩展此模型,并更详细地探讨此过程,从关键参与者——用户开始。
记住
对 Solana 核心协议的重大更改通过提交 Solana 改进文档 (SIMD) 的正式透明流程进行,社区成员和核心工程师将公开评论。然后由网络对 SIMD 进行投票。
我们将在本报告中引用上图所示的六阶段视觉图,因为它为我们提供了一个一致的框架来理解 Solana 核心元素之间的关系。
前几章是根据这六个阶段安排的。最后几章——Gossip、Archive、Economics 和 Jito——将解决任何未解决的问题。需要注意的是,有些章节会跨越多个阶段,有些阶段会出现在多个章节中。
这种重叠是不可避免的,因为六阶段框架有其局限性。实际上,Solana 是一个复杂的分布式系统,具有许多相互依赖的元素。
“Solana 有潜力成为加密货币界的苹果” — 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 上,发送交易是唯一改变状态的方式。任何写操作都是通过交易执行的,并且交易是原子的——要么交易尝试做的一切都发生,要么交易失败。交易,更正式地称为“交易消息”,包含四个部分:头部、账户地址列表、最近的区块哈希和指令。
交易中的指令数量首先受其大小限制,最大可达 1,232 字节。还有对可引用账户数量的限制。最后,交易的复杂性也受到计算单元(CUs)的限制。CUs 量化了处理交易时消耗的计算资源。
记住
SOL 的最小单位称为“lamport”,相当于十亿分之一的 SOL,类似于比特币中的聪。lamport 以计算机科学家和数学家 Leslie Lamport的名字命名,他的研究奠定了现代分布式系统的许多理论基础。
执行交易的 SOL 成本分为两部分——基础费用和优先费用。基础费用是固定的,每个签名成本为 5000 lamports,与交易的复杂性无关——通常每笔交易有 1 个签名。
优先费用在技术上是可选的,但在区块空间需求高的时期变得必要。这些费用以每计算单元的微 lamports(百万分之一 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 端点进行交互( 文档 )。
记住
Solana 上的“交易失败”一词具有误导性,并引起了相当大的混淆。这些交易会产生费用,并且由运行时按照签名者的意图成功执行。它们由于交易自身的逻辑要求而“失败”。超过 80% 的“失败”交易来自错误代码 0x1771,即超过滑点金额的代码(数据)。值得注意的是,这些交易中有 95% 是由仅 0.1% 的活跃 Solana 地址提交的,主要是试图利用时间敏感价格套利机会的自动化机器人。
“Solana 的目标是让交易像新闻一样快速传播到世界各地——通过光纤以光速传播。我们竞争的对象是 NASDAQ 和纽约证券交易所。” — Anatoly Yakovenko,Solana 联合创始人
RPC(远程过程调用)指的是 RPC 节点。这些节点可以被视为与网络交互和读取数据的网关。它们运行与完整验证节点相同的软件,但设置不同,使它们能够准确模拟交易并保持当前状态的最新视图。截至撰写本文时,Solana 网络上有超过 4,000 个 RPC 节点。
与完整验证节点不同,RPC 节点在网络中没有任何权益。没有权益,它们不能投票或构建区块。这种设置与大多数其他区块链不同,在其他区块链中,验证节点和 RPC 节点通常是相同的。由于 RPC 节点不接收质押奖励,运行 RPC 节点的经济性与验证节点不同,许多作为开发人员运行 Solana 应用程序的付费服务运营。
Solana 脱颖而出,因为它从一开始就设计为无需内存池运行。与使用八卦协议随机且广泛地在网络上传播交易的传统区块链不同,Solana 将所有交易转发给每个插槽的预定主验证者,称为领导者。
提示
Solana 运行四个集群:Localnet、Testnet、Devnet 和 Mainnet-Beta。当人们提到 Solana 或 Solana 网络时,他们几乎总是指 Mainnet-Beta。Mainnet-Beta 是唯一一个代币具有实际价值的集群,而其他集群仅用于测试目的。
一旦 RPC 接收到要包含在区块中的交易消息,它必须转发给领导者。每个纪元(大约每两天)之前会生成一个领导者计划。即将到来的纪元被划分为插槽,每个插槽固定为 400 毫秒,并为每个插槽选择一个领导者。拥有更高权益的验证者将在每个纪元中更频繁地被选为领导者。在每个插槽期间,交易消息被转发给领导者,领导者有机会生成一个区块。当轮到某个验证者时,他们会切换到“领导者模式”,开始积极处理交易并将区块广播到网络的其余部分。
2024 年初,Solana 引入了一种新的机制,旨在防止垃圾邮件并增强 Sybil 抵抗力,称为“基于权益的服务质量”(SWQoS)。该系统使领导者能够优先处理通过其他有权益的验证者代理的交易消息。在这里,拥有更高权益的验证者被授予按比例更高的容量,以将交易消息包传输给领导者。这种方法有效地减轻了来自网络中无权益节点的 Sybil 攻击。
在这种模式下,验证者还可以与 RPC 节点达成协议,将其基于权益的容量租赁给 RPC 节点。作为回报,RPC 节点获得增加的带宽,使其能够在区块中实现更高的交易包含率。值得注意的是,领导者的 80% 容量(2000 个连接)保留给 SWQoS。剩余的 20%(500 个连接)分配给来自无权益节点的交易消息。这种分配策略类似于高速公路上的优先车道,司机支付通行费以避免交通堵塞。
SWQoS 通过提高将交易转发给领导者的要求并减少垃圾邮件攻击的有效性,对 Solana 生态系统产生了影响。这一变化激励了高流量应用程序垂直整合其操作。通过运行自己的验证者节点或访问有权益的连接,应用程序可以确保对领导者的特权访问,从而增强其交易处理能力。
2022 年底,Solana 采用了 QUIC 网络协议来管理交易消息传输给领导者。这一转变是由于机器人在链上 NFT 铸造时造成的网络中断而引发的。QUIC 促进了快速、异步通信。
QUIC 最初由 Google 于 2012 年开发,试图提供两全其美的解决方案。它促进了类似于 UDP 的快速、异步通信,但具有 TCP 的安全会话和高级流量控制策略。这允许对单个流量源进行限制,以便网络可以专注于处理真实交易。它还具有独立流的概念;因此,如果一个交易被丢弃,不需要阻塞其余的交易。简而言之,QUIC 可以被认为是试图结合 TCP 和 UDP 的最佳特性。
提示框
基于权益的原则在 Solana 的系统中反复出现,包括投票奖励、涡轮树、领导者计划、Gulf Stream 和八卦网络。拥有更高权益的验证者在网络中被赋予更高的信任和优先角色。
“我们认为 SVM(Solana 虚拟机)是目前虚拟机技术中最好的。” — Andre Cronje,Fantom Foundation
许多区块链网络在广播之前构建整个区块,这被称为离散区块构建。相比之下,Solana 采用连续区块构建,这涉及在分配的时间插槽内动态组装和流式传输区块,从而显著减少延迟。
每个插槽持续 400 毫秒,每个领导者被分配四个连续插槽(1.6 秒),然后轮换到下一个领导者。要使区块获得接受,区块中的所有交易必须有效并且可以被其他节点重现。
在成为领导者的两个插槽之前,验证者停止交易转发,以准备即将到来的工作负载。在此期间,入站流量激增,达到每秒超过一千兆字节,因为整个网络将数据包指向即将到来的领导者。
收到后,交易消息进入交易处理单元(TPU),这是验证者负责区块生成的核心逻辑。在这里,交易处理序列从获取阶段开始,交易通过 QUIC 接收。随后,交易进入 SigVerify 阶段,进行严格的验证检查。在这里,验证者验证签名的有效性,检查签名数量是否正确,并消除重复交易。
银行阶段可以描述为区块构建阶段。它是 TPU 最重要的阶段,其名称来源于“银行”。银行只是给定区块的状态。对于每个区块,Solana 都有一个用于访问该区块状态的银行。当一个区块在足够多的验证者投票后变得最终确定时,他们会将账户更新从银行刷新到磁盘,使其永久化。链的最终状态是所有确认交易的结果。这个状态可以始终从区块链历史中确定性地重建。
交易以并行方式处理并打包成分类账“条目”,即 64 个不冲突交易的批次。在 Solana 上进行并行交易处理很容易,因为每个交易必须包含它将读取和写入的所有账户的完整列表。这个设计选择给开发者带来了负担,但允许验证者通过轻松选择仅不冲突的交易进行执行来避免竞争条件。交易如果都尝试写入同一个账户(两个写入)或一个尝试读取而另一个写入同一个账户(读取 + 写入),则会冲突。因此,冲突交易进入不同的条目并按顺序执行,而不冲突的交易则并行执行。
有六个线程并行处理交易,其中四个专用于普通交易,两个专门处理投票交易,这对于 Solana 的共识机制至关重要。所有处理的并行化都是通过多个 CPU 核心实现的;验证者没有 GPU 要求( 文档 )。
一旦交易被分组到条目中,它们就准备由 Solana 虚拟机(SVM)执行。交易所需的账户被锁定;运行检查以确认交易是最近的但尚未被处理。账户被加载,交易逻辑被执行,更新账户状态。条目的哈希将被发送到历史证明服务进行记录(更多内容将在下一节中介绍)。如果记录过程成功,所有更改将提交到银行,并且在第一步中对每个账户施加的锁将被解除。执行由 SVM 完成,这是一个使用 Solana 分支的 rBPF 构建的虚拟机,这是一个用于处理 JIT 编译和 eBPF 程序虚拟机的库。请注意,Solana 不强制规定验证者如何选择在区块内排序交易。这种灵活性是一个关键点,我们将在本报告的经济学+Jito 部分中回到这一点。
记住
SVM 这个术语可能是模糊的,因为它可能指的是“Solana 虚拟机”或“Sealevel 虚拟机”。这两个术语描述的是相同的概念,Sealevel 是 Solana 运行环境的名称。尽管最近努力精确定义其边界,SVM 这个术语仍然被松散地使用。
Solana 是一个由数千个独立操作的节点组成的网络,这些节点协作维护一个统一的账本。每个节点都是运行相同开源软件的高性能机器,被称为“客户端”。
Solana 最初推出时只有一个验证者客户端软件——最初是 Solana Labs 客户端,现在被称为 Agave 客户端 ——用 Rust 编写。自那时起,扩展客户端多样性一直是一个优先事项,并将在 Firedancer 客户端推出时真正实现。Firedancer 是对原始客户端的完全从头重写,使用 C 编程语言编写。由高频交易公司 Jump 的经验丰富团队构建,它承诺成为任何区块链上性能最好的验证者客户端。
“我喝了两杯咖啡和一杯啤酒,熬到凌晨 4 点。我有了一个灵光一现的时刻,这个谜题 [原文如此] 类似于使用相同 SHA-256 抗预映像哈希函数的工作量证明……我知道我有了这个时间之箭。” — Anatoly Yakovenko,Solana 联合创始人
历史证明(PoH)是 Solana 的秘密武器,像每个验证者中的一个特殊时钟,促进了网络的同步。PoH 为事件的顺序和时间的流逝建立了可靠的真相来源。最关键的是,它确保遵守领导者时间表。尽管名称相似,历史证明不是一种共识算法,如工作量证明。
随着网络的扩展,节点之间的通信开销通常会增加,协调变得越来越复杂。Solana 通过用 PoH 本地计算替代节点间通信来缓解这一问题。这意味着验证者只需一轮投票即可承诺一个区块。消息中的可信时间戳确保验证者不能互相踩踏并提前开始他们的区块。
PoH 的基础是哈希算法的独特属性,特别是 SHA256:
在每个验证者客户端中,一个专门的“历史证明服务”不断运行 SHA256 哈希算法,创建一个哈希链。每个哈希的输入是前一个哈希的输出。由于哈希工作必须按顺序完成,未来哈希的结果不能提前知道,这条链的作用与可验证延迟函数相同。如果 PoH 服务创建了一千个哈希的链,我们知道它必须按顺序计算每个哈希——这可以被认为是“微型工作量证明”。然而,其他验证者可以以比生成速度快得多的速度并行验证这千个哈希的正确性,因为每个哈希的输入和输出都已广播到网络。因此,PoH 难以生成但易于验证。
在不同 CPU 上计算 SHA-256 的性能范围出奇地窄,在最快的机器之间只有很小的差异。尽管在优化这个函数上投入了大量时间和精力,但由于比特币对它的依赖,已经达到了一个常见的上限。
在领导者的时段内,PoH 服务将从银行阶段接收新处理的条目。当前的 PoH 哈希加上条目中所有交易的哈希被组合成下一个 PoH 哈希。这作为一个时间戳,将条目插入到哈希链中,证明交易处理的顺序。这个过程不仅确认了时间的流逝,还作为交易的加密记录。
在一个区块中,有 800,000 个哈希。PoH 流还包括“滴答”,这是空条目,表示领导者的活跃性和时间的流逝,近似于一小部分秒。每 6.25 毫秒发生一次滴答,导致每个区块有 64 次滴答,总区块时间为 400 毫秒。
验证者即使在不是领导者时也会不断运行 PoH 时钟,因为它在节点之间的同步过程中起着关键作用。
记住
PoH 的主要好处是,即使区块生产者离线(称为“失职”状态),它也能确保正确的领导者计划必须得到遵守。PoH 防止恶意验证者在轮到他们之前生成区块。
“在 SVM 中分离代码和状态是最好的设计决策。那些虔诚地将这个概念灌输到我脑海中的嵌入式系统开发者是有福的。” — Anatoly Yakovenko,Solana 联合创始人
在 Solana 验证者中,全局状态保存在称为 AccountsDB 的账户数据库中。该数据库负责存储所有账户,无论是在内存中还是在磁盘上。账户索引中的主要数据结构是哈希图,使得 AccountsDB 本质上是一个庞大的键值存储 。在这里,键是账户地址,值是账户数据。
随着时间的推移,Solana 账户的数量激增至数亿。这一大数量部分是因为,正如 Solana 开发者喜欢说的那样,“Solana 上的一切都是一个账户!”
账户是一个持久保存数据的容器,类似于计算机上的文件。它们有多种形式:
所有账户都有以下字段:
Solana 程序账户仅包含可执行逻辑。这意味着当程序运行时,它会改变其他账户的状态,但自身保持不变。这种代码和状态的分离使 Solana 与其他区块链不同,并支持其许多优化。开发者主要使用 Rust 编写合约,这是一种以安全性和性能著称的通用编程语言。此外,还有多个 TypeScript 和 Python 的 SDK 可用,以便创建应用程序前端并实现与网络的程序化交互。
许多常见功能由原生程序提供,开箱即用。例如,Solana 不需要开发者部署代码来创建代币。相反,指令被发送到一个预部署的原生程序,该程序将设置一个账户来存储代币的元数据,从而有效地创建一个新代币。
租金是一种旨在激励用户关闭账户并减少状态膨胀的机制。要创建一个新账户,该账户必须持有 SOL 的最低余额,即“免租金”金额。这可以被视为在验证者内存中保持账户存活的存储成本。如果账户数据的大小增加,需要的最低余额租金也会成比例增加。当账户不再需要时,可以关闭账户,租金将返还给账户所有者。
例如,如果用户持有美元计价的稳定币,这种状态存储在一个代币账户中。目前,代币账户的免租金金额为 0.002 SOL。如果用户将其全部稳定币余额转移给朋友,则可以关闭代币账户,用户将收回其 0.002 SOL。程序通常会自动为用户处理账户关闭。几种应用程序可帮助用户清理旧的、未使用的账户并收回存储在其中的小额 SOL。
虽然读取账户数据是普遍允许的,但 Solana 的所有权模型通过严格限制谁可以修改(写入)账户数据来增强安全性。这一概念对于在 Solana 区块链上执行规则和权限至关重要。每个账户都有一个程序“所有者”。账户的所有者负责管理它,确保只有授权的程序可以更改账户的数据。此规则的一个显著例外是 lamports(SOL 的最小单位)的转移——增加账户的 lamports 余额是普遍允许的,无论所有权如何。
Solana 程序作为只读可执行文件,必须使用“程序派生地址”(PDAs)存储状态。PDAs 是与程序关联并由程序拥有的特殊类型账户,而不是特定用户。虽然普通的 Solana 用户地址是从 Ed25519 密钥对的公钥派生的,但 PDAs 没有私钥。相反,它们的公钥是从一组参数(通常是关键字或其他账户地址)以及拥有程序的程序 ID(地址)组合派生的。
PDA 地址存在于“曲线外”,这意味着它们不像普通地址那样在 Ed25519 曲线上。只有拥有 PDA 的程序可以程序化地为其生成签名,确保只有它可以修改 PDA 的状态。
上图:Solana 代币账户是程序派生地址(PDAs)的具体示例。它们用于持有代币并存在于“曲线外”。关联代币账户(ATA)程序确保每个钱包只能有一个关联的代币账户用于每种代币类型,提供了一种标准化的代币账户管理方式。
“Solana 最有趣的部分不是并行化、SVM 或 Toly 的推文。而是你可能没听说过的东西:Turbine。” — Mert Mumtaz,Helius
在银行阶段,交易被组织成条目并发送到历史证明流进行时间戳记。区块的银行被更新,条目现在准备进入下一个阶段——Turbine。
Turbine 是领导者将其区块传播到网络其余部分的过程。受 BitTorrent 启发,它设计得快速高效,减少通信开销并最小化领导者需要发送的数据量。
Turbine 通过一个称为“分片”的过程将交易数据分解为“碎片”来实现这一目标。碎片是小的数据包,最多 1280 字节,类似于视频流中的单个帧。当重新组装时,这些碎片允许验证者重播整个区块。这些碎片通过互联网使用 UDP 在验证者之间传输,并利用纠删码来处理数据包丢失或恶意丢包。 纠删码 ,一种基于多项式的错误检测和纠正方案,确保数据完整性。即使一些碎片丢失,区块仍然可以重建。
碎片被分组为称为前向纠错(FEC)批次的批次。默认情况下,这些批次由 64 个碎片(32 个数据碎片 +32 个恢复碎片)组成。数据恢复在每个 FEC 批次内进行,这意味着一个批次中最多一半的数据包可以丢失或损坏,所有数据仍然可以恢复。每 64 个碎片的批次都会进行默克尔树处理,根由领导者签名,并与前一个批次链接。这个过程确保了碎片可以从网络中拥有它们的任何节点安全地获取,因为默克尔树根的链条提供了一个可验证的真实性和完整性路径。
领导者最初向一个根节点广播,根节点将碎片传播给所有其他验证节点。每个碎片的根节点都会变化。验证者被组织成层,形成“Turbine 树”。拥有较大权益的验证者通常位于树的顶部,而那些拥有较少权益的验证者则位于底部。
树通常跨越两到三跳,具体取决于活跃验证者的数量。为了视觉简洁,上图显示了一个 3 的扇出(fanout),但 Solana 的实际扇出值目前设置为 200。出于安全原因,每个新批次的碎片树的顺序都会旋转。
这种系统的主要目标是减轻领导者和根节点的出站数据出口压力。通过利用传输和重传系统,负载在领导者和重传者之间分配,减少了任何单个节点的压力。
“一些聪明的人告诉我,Solana 有一个真诚的聪明的开发者社区……我希望这个社区能有公平的机会茁壮成长” — Vitalik Buterin,以太坊联合创始人
一旦验证者通过 Turbine 从领导者那里接收到一个新区块,它必须验证每个条目中的所有交易。这涉及重播整个区块,平行验证 PoH 哈希,按照 PoH 规定的顺序重新创建交易,并更新其本地银行。
这个过程由交易验证单元(TVU)处理,类似于领导者的交易处理单元(TPU),作为处理碎片和区块验证的核心逻辑。与 TPU 一样,TVU 流程分为几个阶段,首先是碎片获取阶段,在该阶段通过 Turbine 接收碎片。在随后的碎片验证领导者签名阶段,碎片经过多次完整性检查,最显著的是验证领导者的签名,以确保 xxx 收到的碎片来自领导者。
在重传阶段,验证者根据其在 Turbine 树中的位置,将碎片转发给适当的下游验证者。在重播阶段,验证者按正确顺序精确地重新创建每个交易,同时更新其本地版本的银行。
重播阶段类似于 TPU 中的银行阶段;这是最重要的阶段,可以更直接地描述为区块验证阶段。重播是一个单线程的过程循环,协调许多关键操作,包括投票、重置 PoH 时钟和切换银行。
上图:重播阶段负责将验证者切换到领导者模式并开始区块生产。原始视觉:Justin Starry,Anza
为了实现共识,Solana 使用了 Tower BFT(TBFT),这是著名的实用拜占庭容错 (PBFT)算法的自定义实现,大多数区块链使用 PBFT 算法来就链的状态达成一致。像所有区块链一样,Solana 假设网络中存在恶意节点,因此系统不仅必须承受节点故障,还必须承受一定程度的攻击。
Tower BFT 通过利用历史证明提供的同步时钟与其他链区分开来。虽然传统的 PBFT 需要多轮通信来就交易顺序达成一致,但 Solana 节点利用预先建立的事件顺序,显著减少了消息传递的开销。
为了参与共识并获得奖励,验证者提交他们认为有效(即没有双花或错误签名等问题)并被视为规范的区块的投票。验证者为这些投票支付交易费,这些投票由领导者处理并与普通用户交易一起包含在区块中。这就是为什么 Solana 交易通常分为投票和非投票交易。当验证者提交正确且成功的投票时,它们会获得一个信用。这一机制激励验证者投票给他们认为最有可能被包含的分叉,即“最重”的分叉。
Solana 之所以如此之快,部分原因在于网络在生成下一个区块之前,不会等待所有验证者就新生成的区块达成一致。因此,两个不同的区块链接到同一个父区块,从而产生分叉的情况并不少见。
Solana 验证者必须对这些分叉进行投票,并使用共识算法决定采用哪个分叉。当存在相互竞争的分叉时,网络最终只会确定一个分叉,而被丢弃的分叉中的区块则会被废弃。
每个插槽都有一个预先确定的领导者,只有该领导者的区块才会被接受;一个插槽不可能有两个提议的区块。因此,潜在分叉的数量被限制在一个“there/not-there”的分叉跳转列表中,这些分叉可能出现在领导者节点轮换插槽边界上。一旦验证者选择了一个分支,它就会被提交到这个分支,直到锁定时间到期,这意味着它必须在最短的时间内坚持自己的选择。
Solana 的“跳过率”——没有产生区块的槽的百分比——在 2% 到 10% 之间波动,分叉是这些跳过插槽的主要原因。其他可能的跳过槽的原因包括:新 epoch 的开始、领导者节点离线或生成无效区块。
记住
交易在 Solana 上的状态因其在共识过程中的当前阶段而不同:
- 已处理:交易已包含在区块中。
- 已确认:交易的区块已获得 2/3 的超级多数投票。
- 已最终确定:交易的区块上已构建了超过 31 个区块。
迄今为止,Solana 的历史上从未出现过(乐观地)确认的区块未能最终确定的情况。
对于每个区块,Solana 使用一个银行来访问该区块的状态。当一个银行被最终确定时,该银行及其祖先的账户更新会被刷新到磁盘。此外,任何来自早期银行且不是最终确定银行祖先的账户更新都会被修剪。这个过程允许 Solana 高效地维护多个潜在状态。
“区块链需要巧妙地结合密码学、分布式系统、操作系统和编程语言。Solana 的超能力在于愿意逃避每个学科中最有趣的问题。” — Greg Fitzgerald,Solana 联合创始人
Gossip 网络可以被视为 Solana 网络的控制平面 。与处理交易流的数据平面不同,控制平面传播关于区块链状态的重要元数据,例如联系信息、分布式账本高度和投票信息。没有 Gossip,验证者和 RPC 就不知道哪些地址和端口开放供各种服务进行通信。新节点也依赖 Gossip 加入网络。
Solana 的 Gossip 协议使用非正式的点对点通信,采用树状广播方式,其灵感来源于改进的 PlumTree 算法。这种方法高效地传播信息,而不依赖任何中心来源。
Gossip 在某种程度上作为一个独立的系统运行,与大多数其他验证者组件无关。验证者和 RPC 每 0.1 秒通过 UDP 以 Gossip 方式共享签名数据对象,确保信息在网络中的可用性。所有 Gossip 消息必须小于或等于 1280 字节的最大传输单元(MTU),在代码库中称为“数据包结构”。
Gossip 记录是节点之间共享的实际数据对象。大约有 10 种不同类型的记录,每种记录都有不同的用途。Gossip 记录有签名、版本和时间戳,以确保完整性和时效性。
Gossip 消息有四种类型:
Push:最常见的消息,与一部分“push peers”共享信息。
Pull & Pull Response::定期检查是否有遗漏的消息,拉取响应会发送节点没有的信息。
Prune:允许节点选择性地减少它们维护的连接数量。
Ping 和 Pong:节点的健康检查——如果发送了 ping,则期望返回 pong,表示节点仍然活跃。
Gossip 数据存储在集群复制数据存储(CrdsTable)中。这个数据结构可以变得非常大,需要定期修剪。
Solana 与其他区块链的不同之处在于,它不需要整个历史记录来确定账户的当前状态。Solana 的帐户模型确保任何给定插槽的状态是已知的,允许验证者在不处理所有历史区块的情况下存储每个账户的当前状态。RPC 和验证者在设计上不保留整个历史账本。相反,它们通常只存储 1 或 2 个 epoch(2-4 天)的交易数据,这足以验证链的最新插槽。
档案目前由“仓库节点”管理,由专业的 RPC 服务提供商、Solana 基金会和其他有兴趣确保交易历史可用的生态系统参与者运营。 仓库节点通常维护以下一个或两个节点:
分布式账本档案:上传原始的分布式账本和 AccountsDB 快照,适合从头开始重播。
Google Bigtable 实例:存储从创世区块开始的区块数据,格式化后可满足 RPC 请求。
“人们正在意识到 Solana 是今天唯一可用的支持主流消费应用的链。” — Ted Livingston,创始人 Code
Solana 通过在每个 epoch 发行新的 SOL 代币来分配质押奖励,从而实现通货膨胀。这一过程导致非质押者的网络份额相对于质押者减少,从而导致财富从非质押者转移到质押者。通货膨胀机制于 2021 年初启动,初始年通胀率为 8%,每年减少 15%,直到长期稳定在 1.5%。
任何 SOL 代币持有者都可以获得奖励,并通过将代币质押给一个或多个验证者来帮助保护网络。将代币分配给验证者称为委托。将代币委托给验证者表示对验证者的信任。然而,这并不赋予验证者对代币的所有权或控制权。所有质押、取消质押和委托操作都在下一个新 epoch 开始时执行。
投票奖励
当验证者提交投票时,如果投票准确且成功,他们会获得一个信用点。投票交易费用为 0.000005 SOL,免收优先权费用。每个验证者每天的投票费用约为 1 SOL,这也是验证者的主要运营成本。在整个 epoch 中,验证者通过投票积累信用点,在 epoch 结束时可兑换通胀份额。
表现最出色的验证者成功地对大约 90% 的插槽进行了投票。需要注意的是,没有区块的插槽百分比 (跳过的插槽率) 范围从 2% 到 10% 以上,这些插槽不能投票。验证者平均在大约 80% 的插槽上成功投票,在 432,000 个插槽中获得 345,600 个信用点。
通货膨胀总额首先是根据该时期获得的信用点来划分的。验证者在总信用点数中的份额(其信用点数除以所有验证者的信用点数总和)决定了其奖励比例。这是进一步加权的赌注。
因此,如果验证者的信用点数处于平均水平,那么他所获得的奖励大约为总质押的 1%。如果他们的信用点数高于或低于平均值,他们的奖励也会相应波动。
投票表现的差异是验证者向质押者提供的回报(以年收益率衡量)不同的原因之一。另一个因素是验证者收取的佣金率,这是针对验证者的通胀奖励总额的一个百分比。此外,验证者离线或与区块链不同步(称为延迟)也会对回报产生重大影响。
区块奖励
被指定为特定区块领导者的验证者将获得额外的区块奖励。这些奖励包括区块内所有交易的 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,套利交易者将确保代币价格保持合理。
截至撰写本文时,超过 80% 的 Solana 质押使用了 Jito 客户端验证软件( 来源 )。这个客户端是原始 Agave 客户端的一个分支,通过协议外的区块空间拍卖为验证者提供额外的经济激励。这种额外的激励是 Jito 客户端在验证者中广泛采用的主要因素。
当领导者使用 Jito 验证客户端时,他们的交易最初会被定向到 Jito-Relayer。这款开源软件充当交易代理路由器。其他网络节点不知道 Jito-Relayer 的存在,因为它们只是将交易发送到领导者节点在 gossip 网络上公布的地址和端口配置,认为这是领导者节点的 ingress_socket。
中继器将所有交易保留 200 毫秒,然后再转发给领导者节点。这种“减速带”机制会延迟传入的交易消息,为进行拍卖提供了一个简短的窗口。在 200 毫秒后,中继器乐观地释放交易,而不管拍卖结果如何。
区块空间拍卖通过 Jito 区块引擎在链下进行,允许搜索者和应用程序提交一组原子执行的交易,称为捆绑(bundles)。这些捆绑通常包含时间敏感的交易,如套利或清算。Jito 对所有小费收取 5% 的费用,最低小费为 10,000 lamports。小费完全在协议外操作,与协议内的优先费和基础费用分开。之前,Jito 运营了一个规范的协议外内存池服务,现已废弃。