本文深入探讨了Solana区块链中的承诺级别(Commitment Levels),包括Processed、Confirmed和Finalized三种主要级别。文章详细解释了每种承诺级别的技术定义、内部机制、开发者用例以及对可靠性、性能和安全性的影响。通过了解这些承诺级别,开发者可以根据应用的需求,在速度和确定性之间做出最佳选择。
Solana 是一个高性能的区块链,可以每秒处理数千笔交易。为了同时确保速度和安全,Solana 为交易确认提供了 Commitment Levels(承诺级别)。承诺级别表明给定的区块或交易的“最终”程度,从而平衡了响应速度和确定性之间的权衡。
简单来说,更强的承诺级别(例如 finalized)提供更可靠的保证,即交易已得到网络确认(即回滚的可能性较小),而较弱的承诺级别(例如 processed)提供反馈的速度更快,但提供的确认不太确定。
本博客介绍了 Solana 的所有承诺级别——Processed、Confirmed、Finalized 以及其他(包括已弃用的术语)——包括技术定义、差异、内部机制、开发者用例,以及对可靠性、性能和安全性的影响。
Solana 承诺级别是一种标准化的方式来衡量网络对给定区块或交易的共识。当你向 Solana RPC 节点查询交易状态或帐户数据(例如,getTransaction)时,你可以指定承诺级别,以表明你希望数据达到何种最终状态。Solana 使用此承诺级别让客户端可以平衡延迟与确定性:较低的承诺级别提供更快的反馈,而较高的承诺级别为开发者提供更强的保证,即状态不会恢复。
Solana 定义了三个主要的承诺级别(按最终性降序排列):
最高确定性级别,表示该区块已获得绝大多数权益(≥66%)的确认,并且至少在其之上构建了 31 个进一步确认的区块,从而使该插槽获得最大的 32 票锁定。一个 finalized 的交易实际上是不可逆转的。
一个中间级别,其中区块已获得绝大多数权益(≥66%)的投票,但尚未通过更长时间的持续投票进行 finalized,这使得反转更加困难。这通常被称为乐观确认,它提供了一个强有力的保证,即交易位于“主分叉”或规范链上。
Processed 意味着该交易刚刚被一个 leader 处理,并包含在该节点所知的最新区块中。但是,该区块可能尚未获得任何集群范围内的投票。如果该区块最终没有进入多数分叉,则该交易仍然可能被丢弃。
这些级别代表了交易生命周期中的各个阶段。
一个新提交的交易将从 Processed → Confirmed → Finalized 移动,因为更多的网络观察并投票支持包含它的区块,并且后续区块构建在该区块之上。更高的承诺意味着更多的节点已经同意该交易的包含,从而降低了分叉或回滚的风险。
让我们详细探讨每个级别。
一旦验证者节点(即当前的 leader)将交易包含在一个区块中,该交易就被认为是 Processed。这是最早的确认:该交易已被接收并 本地 纳入账本状态。
Processed 级别的关键特征包括:
假设 Alice 在 Solana 上提交了一笔转账。只要当前的 leader 将其添加到区块(插槽 N)中,该交易就会被标记为 Processed。Alice 的钱包可能会立即将该交易显示为 待处理/已处理。
但是,如果该 leader 的区块未被大多数验证者接受(例如,leader 速度慢或离线,并且另一个分叉接管),则 Alice 的交易可能会消失(即被丢弃),因为已处理的区块未成为主链的一部分。
Confirmed 承诺级别表示该交易的区块已被集群的绝大多数接受,并且很可能位于规范链上。从技术上讲,“confirmed”意味着 ≥66% 的权益加权验证者已直接投票支持该区块。
主要特征:
在多数分叉上: 包含该交易的区块被认为是账本的多数分叉的一部分。这意味着网络认为该区块是一个规范区块。
绝大多数投票: 至少三分之二的总权益已投票确认该区块。这些投票是通过 Solana 的 gossip 机制 收集的,这意味着验证者已在网络上广播并观察了对该区块的投票。此阶段利用了 Solana v1.3 中引入的 乐观确认,该功能允许节点一旦获得绝大多数投票(即使在 finalized 之前),就将区块视为已确认。
回滚风险低: 凭借 66%+ 的共识,冲突分叉替换此区块的 可能性极低,但并非不可能。除非发生重大重组,否则所有诚实的验证者都已有效地提交到此区块。在 Solana 的五年历史中,没有 confirmed 的区块被回滚过。
比 Finalized 快: confirmed 状态通常在给定的区块或交易被标记为 processed 后不久(在一两秒内)发生,因为验证者会立即投票支持新区块。它不会等待许多后续区块。因此,confirmed 在正常情况下提供了速度和信心之间的良好平衡。
乐观最终性: 通常,由于 Solana 的快速共识,开发者将一个 confirmed 的交易视为 本质上 是最终的,用于大多数实际目的。但是,在 finalization 之前,仍然存在很小的回滚机会。
一旦集群的验证者投票支持区块 N,来自上面的 Alice 的交易就会变为 Confirmed。在实践中,如果接下来的几个验证者(通过插槽 N+1、N+2 等)投票并看到区块 N,达到 66% 的阈值,则网络会将区块 N 标记为 confirmed。Alice 的钱包现在可以安全地向用户显示该交易为 confirmed。
此时 Alice 的转账被回滚的概率非常低(仅当发生罕见的分叉或网络问题时)。这类似于其他链中的“N 个确认”,但在 Solana 上,它是基于权益投票而不是固定数量的区块确认。
当一个交易的区块被绝大多数投票 并且 其上构建了足够的额外区块时,该交易就被认为是 Finalized。关于 Solana 的共识,这对应于区块达到最大锁定,通常在 32 个连续投票(插槽)确认后。Finalized 是最强的承诺级别,提供最高的确定性,即交易不会被撤销。
Finalized 的特征包括:
不可逆转的区块: 集群已将此区块识别为 finalized,这意味着它已 扎根 在账本状态中。验证者不会回滚它,并且它实际上是永久性的。
绝大多数 + 锁定: 与 Confirmed 类似,至少 66% 的权益认可了该区块。此外,31+ 个后续 confirmed 的区块 已在其后添加。换句话说,网络已在此区块之上构建了一条深链,达到了重组不可行的锁定深度。
最大锁定(32 票): Solana 的 Tower BFT 机制以指数方式加倍投票的锁定周期。一旦一个区块在 tower 中累积了 32 票(意味着它通过 32 个更多插槽仍然是分叉的头部),它就达到了最大锁定并被 finalized。此时,任何试图投票支持备用分叉的验证者都将违反共识规则。
最安全,最慢的确认: Finalization 通常比 processed 和 confirmed 级别落后一段时间(在正常情况下约为 ~10-20 秒,因为每个 32 个插槽约为 400 毫秒 ≈ 13 秒)。这是 Finalized 确定性的权衡。通过等待 finalization,客户端可以消除交易被丢弃或撤销的所有风险,但代价是额外的延迟。
Confirmed + 构建在其上: 查看 finalization 的另一种方式:它是一个 confirmed 的 区块,埋在许多更多区块之下。所有诚实的节点都已可验证地将此区块锁定为永久账本的一部分。
在网络继续生成超出插槽 N 的区块后,Alice 的交易达到 Finalized 状态。假设到插槽 N+32,绝大多数验证者已投票支持直到 N+32 的每个连续区块(没有分叉接管)。区块 N(带有 Alice 的交易)现在已 finalized。
此时,就 Solana 的账本而言,Alice 的交易是绝对永久的 - 即使她等待一段时间,包括她的转账在内的状态也不会改变。
任何需要强最终性的应用程序(如释放资金的交易所)现在都可以安全地对此交易采取行动。值得注意的是,如果攻击者试图撤销此操作,他们需要控制超过 1/3 的权益并违反共识。
早期版本的 Solana(2021 年之前)公开了额外的承诺级别,这些级别此后已被 弃用,取而代之的是上述三个级别。
为了完整起见,以下是旧术语以及它们如何映射到当前级别:
recent – 已弃用;相当于 Processed。在较旧的文档中,“recent”仅指节点知道的最新状态。
single 和 singleGossip – 已弃用;相当于 Confirmed。这些指的是涉及单个验证者或通过 gossip 进行确认,这与 confirmed 定义一致。
root 和 max – 已弃用;相当于 Finalized。“Root”指的是集群中已 finalized 的 rooted 状态,而“max”指的是最大锁定——两者实际上都意味着 finalized。
如今,开发者在指定承诺级别时应仅使用 processed、confirmed 或 finalized。Solana JSON-RPC API 自 v1.5.5 起默认为这些术语,并将已弃用的术语视为其映射级别的别名。
此外,如果在 RPC 请求中未指定任何承诺,则默认为 Finalized(即,节点默认返回大多数 finalized 的状态)。
Processed、Confirmed 和 Finalized 之间的差异可以理解为有多少网络已确认该交易,以及它被撤销的可能性有多大。下表(改编自官方 Solana 文档)总结了关键区别:
属性 | Processed | Confirmed | Finalized |
包含的区块(已被 leader 接收) | ✔️ 是 | ✔️ 是 | ✔️ 是 |
区块位于多数分叉上 | ◑ 不确定(可能位于少数分叉上) | ✔️ 是 | ✔️ 是 |
该区块中存在交易 | ✔️ 是 | ✔️ 是 | ✔️ 是 |
66%+ 的权益投票支持此区块 | 否 | ✔️ 是 | ✔️ 是 |
构建在顶部的后续区块 | N/A | 少数 | ✔️ 构建了 31+ 个区块 |
总之,Processed 仅表示交易在一个区块中(仅此而已)。Confirmed 表示集群已同意该区块(绝大多数投票),但它仍然靠近链的顶端。Finalized 表示该区块位于链的深处,有许多确认 - 如此之深以至于它实际上是不可变的。
查看差异的另一种方式是交易随着时间的推移保留在规范账本中的概率。
立即处理时,概率不是 100%(存在分叉或失败的可能)。一旦获得 >66% 权益的 confirmed,包含概率会急剧上升。到它被 finalized 并且顶部有多个区块时,包含概率约为 100%。
下图说明了这一点,该图显示了随着更多插槽的过去和承诺级别的提高,交易被 finalized 的可能性如何增加:
交易被包含在最终规范链中的可能性随着时间的推移而增加。最初在插槽 n(已处理的交易)时,存在一些交易可能被“跳过”或分叉出去的风险。通过乐观确认(已确认),包含可能性随着验证者的投票而急剧上升。在构建足够的连续分叉(已完成)之后,逆转的可能性实际上达到零。这表明随着承诺级别的提高,回滚的风险降低。
了解 Solana 的共识如何“在底层”工作可以阐明为什么存在这些承诺级别:
Solana 的 leader 以快速连续的方式生成区块(每个插槽一个 leader,插槽约为 400 毫秒)。交易被流式传输到 历史证明(PoH) 哈希链中,形成区块中的条目。区块通过 Turbine(Solana 的区块传播协议)在网络中快速传播。当 leader 生成一个包含你的交易的区块时,该区块会立即传播但尚未 confirm — 对应于 Processed 阶段。
Solana 使用一种名为 Tower BFT 的 BFT 共识算法。验证者(每个验证者控制一些权益)投票支持他们认为应该成为账本下一部分的区块。投票本身就是 Solana 交易,它们包括 锁定 的概念。每次验证者在插槽 N 处投票支持一个区块时,它都会产生一个锁定,这样如果它稍后投票支持一个冲突的分叉,它可能会失去在一段时间内投票的能力。
这些锁定会随着对同一分叉的每次连续投票呈指数级增长(锁定插槽 1、2、4、8...),并上限为 32 票。如果验证者连续 32 次投票支持一个分叉(意味着 32 个插槽前的区块仍然是最重分叉的一部分),则该区块处于 最大锁定 状态。这种机制激励验证者坚持多数分叉并finalize区块。
当生成一个区块时,验证者会广播对其的投票。一旦绝大多数(≥66%)的权益投票支持一个区块,Solana 节点就会认为该区块已被 乐观地确认。这是 Confirmed 承诺级别。它发生得很快,通常在区块之后的一个或两个插槽内,因为投票通过 gossip 传播。
重要的是,Solana 的实现不需要等待区块在账本中扎根;它相信绝大多数投票是一个乐观的信号,表明该区块最终会被 finalized(除非 <33% 的权益行为不端)。
这就是为什么它被称为 乐观确认:在正常的拜占庭容错假设(最多 1/3 不诚实)下,绝大多数投票意味着该区块不会被推翻。如果一个分叉要覆盖它,则 >33% 的验证者必须投票支持一个备用链,这打破了假设。
随着新区块继续生成并被投票支持,每个 confirmed 的区块都会在分叉中更深地移动。一旦一个区块在它之后的连续 32 个插槽中累积了投票,它就会达到最大锁定。此时,网络会 将该区块扎根,将其标记为 finalized 且不可逆转。Finalization 意味着该区块至少比头部晚 31 个区块,并且从未被放弃以支持另一个分叉。现在,所有节点都认为该区块是不可变历史记录的一部分(该插槽之前的账本状态已冻结)。
实际上,Finalized 承诺对应于 PoW 链 类比中的“区块具有 ≥32 个确认”,但 Solana 通过时间锁定的投票而不是工作量证明确认来实现此目的。32 个插槽规则是 Tower BFT 设计的结果(锁定加倍直到 2^32),并在 1/3 容错假设下提供最终性的数学保证。
Solana 的共识不断评估分叉。验证者使用最重分叉选择算法(基于权益投票权重)来决定构建哪个分叉。如果一个区块仅由一部分验证者处理并且未能获得投票,则另一个分叉可以覆盖它。这就是为什么 Processed 交易可以被丢弃。
一旦一个区块被 2/3 确认,一个备用分叉必须有超过 1/3 的权益支持才能获胜,这非常不可能并且意味着恶意行为。
Finalization 后,如果没有灾难性的共识失败,回滚该区块的分叉基本上是不可能的。即使网络停止或受到攻击,撤销 finalized 的插槽也需要协议规则之外的协调。
为了总结这些机制:Processed = 生成的区块(PoH)但尚未被广泛投票;Confirmed = 集群投票(Tower BFT)达到了该区块上的绝大多数(乐观共识);Finalized = 该区块在许多更多投票后作为链的“根”持续存在(绝对共识最终性)。Solana 的设计确保了 confirmed 的区块在短暂延迟后被 finalized,从而提供快速确认和最终绝对最终性。
在 Solana 上构建时,选择适当的承诺级别至关重要。不同的应用程序对速度与确定性有不同的要求。
以下是每个级别的典型用例和最佳实践:
在速度至关重要且可以接受一些回滚风险的情况下,开发者可能会使用 Processed 承诺。例如,在开发和测试期间,你可能需要立即确认验证者_已收到_交易。
UI 应用程序(如钱包或游戏)可以在处理完交易后乐观地显示交易,以改善用户体验(例如,显示“待处理”状态)。
但是,由于不能保证处理过的交易会保留,因此不建议将此级别用于生产关键流程。如果使用,它应该用于低价值或非关键交易,其中潜在的回滚不会造成严重问题。
通常建议将 Confirmed 级别作为 Solana 上许多用例的默认设置。它以最小的延迟影响提供了强大的成功保证。
例如,进行代币交换的 DeFi 应用程序或转移资金的用户通常会依赖于 confirmed 状态:一旦交易被 confirmed,该应用程序就可以在正常情况下将其视为已完成。与 Processed 相比,此级别大大降低了交易被丢弃的几率。最佳实践是使用承诺级别 Confirmed,尤其是在查询最近的区块哈希和发送交易时,因为它在延迟和安全性之间提供了更好的平衡。
当需要绝对确定性时,例如高价值资产转移、跨链桥或交易所存款确认,开发者应使用 Finalized 承诺级别。这对于即使是极小的回滚风险也是不可接受的情况很常见。
例如,交易所可能会等待交易被 finalize 后再将存款记入用户的帐户,以避免以后可能撤销存款的任何重组机会。
另一个用途是在一系列交易之后:在考虑复杂的交易完成之前,可以确保最终状态已 finalize (例如,在需要最终账本状态的审计或结算过程中)。
开发者应该意识到,要求 Finalized 承诺会增加延迟,并且在网络负载较重的情况下,会增加交易过期的可能性,因为你实际上是在等待较旧区块的哈希被 finalize 。Finalized 应该谨慎地用于只有额外安全性值得延迟权衡的最关键交易。
总之,Processed 主要用于快速反馈和非生产用途,Confirmed 是大多数操作的首选,可提供安全性能平衡,而 Finalized 则保留给你真正需要保证最终性的情况,尽管需要等待。
许多应用程序将使用混合:在 Processed 上显示 UI 更新,在 Confirmed 上考虑完成的事情,并在 Finalized 上记录。
承诺级别的选择直接影响可靠性(交易会保留吗?)、性能(延迟)和安全性(双重支出或分叉问题的风险):
更高的承诺级别提高了交易被永久记录的可靠性。就存在于账本中而言,一个 finalized 的交易基本上具有 100% 的可靠性(除非发生特殊事件),而 confirmed 的交易具有非常高的可靠性,但不是 100%,而 processed 的交易的可靠性较低。
如前所述,如果仅计算 processed 的交易,大约 ~5% 的交易最终可能会被丢弃(由于分叉变动),而 confirmed 的交易会将风险降低到接近 0%。
在关键应用程序中,使用 finalized 承诺消除了你的交易位于稍后被丢弃的分叉中的风险。
在你获得确认的速度与承诺级别之间存在明显的权衡。
Processed 确认几乎是即时的(在区块时间内,通常为亚秒级)。
Confirmed 增加了一个小的延迟(大约一两个插槽,可能额外 ~0.5-1 秒)以收集验证者投票 - 它仍然非常快,并且在实践中通常对用户来说不明显。
Finalized 增加了最大的延迟,因为只有在生成大约 30 多个后续区块后,该交易才会被报告为 finalized 。通常,大约 ~10-20 秒才能达到最终状态。
在 网络拥塞 或区块生产缓慢期间,此延迟可能会更长。因此,如果过度使用,要求 Finalized 承诺可能会减慢用户体验和吞吐量。如果应用程序等待 finalization,则必须考虑额外的等待时间。但是,这并不意味着交易本身需要更长的时间才能在链上执行;这意味着客户端正在等待更长时间以确保它已 finalized 。Solana 同时仍在处理新交易。
一个重要的微妙影响是交易过期和区块哈希的使用。Solana 交易包括一个最近的区块哈希,并且仅在该区块哈希之后的 ~150 个插槽内有效。
如果你请求一个 finalized 的区块哈希来签署你的交易,则该区块哈希较旧(因为 finalized 滞后于头部),并且在交易过期之前你剩余的插槽将更少。如果网络拥塞并且你的交易没有快速处理,这会增加过期的几率。
使用更新的(Confirmed 的)区块哈希会提供更长的窗口。官方建议是使用 Confirmed 用于 getLatestBlockhash 以降低过期风险。
因此,对预检或区块哈希使用 Finalized 可能会略微减少你的交易被提取的时间,从而影响负载下的可靠性。
简而言之,在负载较重时, Finalized 承诺可能会牺牲一些活跃性 - 你可以获得确定性,但可能会以更多的交易超时为代价,如果网络接近容量。
从安全角度来看(例如,防止双重支出、分叉安全),Finalized 是最安全的。
一旦 finalized,撤销交易将需要超过三分之一的总权益采取恶意行为,这很可能会被注意到并受到惩罚。
在正常情况下,Confirmed 非常安全(攻击者必须创建一个冲突的分叉并说服 >33% 的验证者在绝大多数已经投票_之后_支持它,如果没有重大的协调攻击,这是极不可能的)。
然而,Confirmed 确实存在一个理论上的情况,即如果一些验证者(略低于 33%)搁置投票或一个分叉仅仅在边缘,那么一个 confirmed 的区块可能会被孤立。然而,Solana 的设计(乐观确认)假定有一个诚实的多数来阻止这种情况。
Processed 提供最少的安全性:在投票结束之前,不能保证任何其他验证者甚至都知道该交易。一个恶意的 leader 甚至可能包含一个交易,然后未能正确传输区块,等等。
因此,Processed 不应依赖于任何安全关键的确认(它更像是流程已启动的“通知器”)。
总之:在防止分叉和双重支出的安全性方面,Finalized > Confirmed > Processed。
当从 Solana 读取状态时(例如,通过 RPC 检查帐户余额),你还需要指定承诺级别。如果你为读取使用 Processed 承诺级别,你可能会看到非常新的数据,但它可能来自未 finalized 的分叉。对于读取使用 Finalized 可以为你提供绝对一致性(每个人都同意的状态),但它可能会滞后几个插槽。对于大多数情况,与交易一样,为状态查询使用 Confirmed 是一种很好的平衡。这确保了你不会根据可能恢复的分叉做出决策。
对于写入查询(即发送交易),承诺主要对客户端库等待确认的方式很重要。一种常见的模式是使用特定的 preflightCommitment (可能会根据最新状态模拟 TX)发送交易,然后使用具有相同承诺级别的 confirmTransaction 。如果需要,开发者可以选择等待 finalized 的确认。
为了用实际数字来说明这一点:根据最近的测量,Solana 在 ~ 0.4 秒 内 处理 了一笔交易,在 ~ 0.6 秒 内达到了 confirmed 状态,并在 ~ 13 秒 内实现了 finalization。
如果你的应用程序(例如支付应用程序)每笔交易无法等待 ~13 秒,你应该使用 confirmed,它仍然提供强大的安全性。
如果你在链之间转移大量资金,你可以选择等待完整的 ~13 秒以完全确定。另一方面,如果你正在构建一些速度至关重要且可以接受一点风险的东西,例如乐观地更新 UI,你可以依靠 processed 状态来提供快速的用户体验。
Solana 的承诺级别—— Processed、Confirmed 和 Finalized ——是一个核心功能,使开发者可以为每笔交易定制速度和确定性之间的平衡。
Processed 提供即时但不确定的结果,Confirmed 在一两秒内提供接近于最终的保证(足以满足大多数应用程序),而 Finalized 在额外时间后提供绝对的最终性。
在底层,这些级别对应于 Solana 的共识进展:从生成一个区块,到被绝大多数投票,再到在具有最大锁定的账本中扎根。
在 Solana 上构建时,为任务选择正确的承诺级别至关重要:
每个级别都会影响交易包含的可靠性以及你等待的时间。
通过理解技术含义(66% 投票、32 个区块、分叉、锁定)并遵循最新的最佳实践,开发者可以确保他们在不牺牲应用程序的一致性和安全性的前提下获得 Solana 承诺的性能。
- 原文链接: helius.dev/blog/solana-c...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!