Solana 停機完整歷史:原因、修復與經驗教訓

進階2/26/2025, 9:07:22 AM
本文將詳細分析每次 Solana 停機事件,探討根本原因、觸發事件以及為解決問題所採取的措施。

嘟,嘟,嘟。嘟,嘟,嘟。

史蒂文的睡眠被手機刺耳的鈴聲打斷,將他從夢境中猛然拉回現實。黑暗中,手機屏幕亮得刺眼,在床頭櫃上劇烈震動。嘟,嘟,嘟。

他呻吟一聲,迷迷糊糊地揉了揉眼睛,伸手拿起手機。眯著眼看向消息,心中一沉——節點宕機了。

他毫不猶豫地跳下床,衣衫不整地摸索著解鎖手機,而更多的消息不斷湧入。就在這時,他猛然意識到——整個集群都宕機了。

就在此刻,地球另一端的不同城市和時區,數百名節點運營者也正盯著手機,意識到他們最害怕的時刻已經到來——一次停機。

引言

與所有分佈式系統一樣,Solana 也面臨著這樣一個現實:單個實現缺陷或模糊的邊緣情況都可能導致全網故障。儘管停機會帶來干擾,但這是維護複雜分佈式基礎設施的必然過程——無論是在去中心化區塊鏈、中心化交易所,還是亞馬遜或微軟等大型雲服務提供商中。

問題不在於故障是否會發生,而在於何時發生,以及網絡將如何演變以適應並增強其應對未來事件的能力。儘管進行了嚴格的模擬測試、激勵性測試網以及活躍的漏洞賞金計劃,但即使是設計再完善的系統也無法預見每一種可能的故障模式。最寶貴的經驗往往來自實際運行中的事件。

在過去五年裡,Solana 共經歷了七次獨立的停機事件,其中五次由客戶端漏洞引發,另外兩次則是由於網絡無法應對大規模交易垃圾郵件。Solana 的早期版本缺乏關鍵的擁堵管理機制,例如優先費用和本地費用市場,而這些機制後來被證明在緩解網絡壓力方面至關重要。由於缺乏這些機制,2022 年期間網絡頻繁出現性能下降和擁堵現象,因為其機制實際上激勵了垃圾交易的產生。

Solana 停機與性能下降的歷史實例

本文將詳細分析每次 Solana 停機事件,探討根本原因、觸發事件以及為解決問題所採取的措施。此外,我們還將討論網絡重啟、漏洞報告以及活性與安全性故障等核心概念。儘管這些部分按順序閱讀效果最佳,但每一部分都可以獨立閱讀,方便讀者直接跳轉到感興趣的主題或具體的停機事件。

活性與安全性

根據 CAP 定理(亦稱 Brewer 定理),分佈式系統只能在以下三個特性中實現兩個:

  • 一致性 - 每次讀取都能看到之前的所有寫入。
  • 可用性 - 每個請求都會收到響應。
  • 分區容錯性 - 系統在網絡分區的情況下仍能繼續運行。

對於區塊鏈而言,分區容錯性至關重要,因為網絡中斷是不可避免的。這迫使系統在 AP(可用性 + 分區容錯性)和 CP(一致性 + 分區容錯性)之間做出選擇。與大多數快速最終性 PoS 鏈一樣,Solana 優先考慮一致性而非可用性,因此屬於 CP 系統。在關鍵故障期間,Solana 會選擇暫停運行,而不是提供過期數據或允許不安全的寫入。雖然這意味著節點軟件可能會進入需要人工干預的不可恢復狀態,但它確保了用戶資金的安全。

Solana 在 CAP 定理權衡中的定位

活性故障:指區塊鏈停止推進,導致由於驗證者宕機、網絡分區或共識停滯而無法確認交易或生產區塊。在 CAP 定理中,這對應於可用性的喪失。

安全性故障:指區塊鏈的最終狀態被篡改或出現不正確的分叉,可能導致歷史記錄衝突或雙花,通常由共識漏洞或惡意攻擊引發。在 CAP 定理中,這對應於一致性的喪失。

Solana 優先考慮安全性而非活性。因此,在網絡壓力過大或共識故障的情況下,Solana 會選擇暫停運行,而不是冒著狀態被破壞的風險。儘管停機會對應用程序、用戶和驗證者造成干擾,但相比賬本出現不一致或被篡改帶來的災難性後果,這種權衡更為可取。

網絡重啟

重啟 Solana 網絡涉及識別最後一個經過樂觀確認的區塊槽位,並從該槽位的受信本地狀態快照重新啟動節點。由於重啟槽位並非通過鏈上確定,驗證者運營者必須在鏈下達成共識,以確定安全的回滾點。這一協調過程公開進行,地點是在 Solana Tech Discord 的 #mb-validators 頻道,專業驗證者運營者會在此進行實時溝通。大多數運營者都配備了自動警報系統,可在區塊生產停止的瞬間發出通知,確保快速響應。

一旦就正確的重啟槽位達成共識,運營者會使用 ledger 工具生成新的本地快照,重新啟動驗證者,並等待至少 80% 的總質押重新上線。只有在達到這一比例後,網絡才會恢復區塊生產與驗證。在集群重啟時,確保離線質押不超過 20%,可為節點在重啟後因分叉或再次下線時提供足夠的安全餘量。

漏洞報告

漏洞賞金計劃通過獎勵安全研究人員來鼓勵他們識別並報告軟件漏洞。這是一道關鍵的防線,可主動激勵在漏洞被利用之前將其發現。發現 Agave 客戶端潛在漏洞的安全研究人員和開發者應通過適當的安全渠道進行報告。詳細的披露指南可在 Agave 的 GitHub 倉庫中找到

針對有效的關鍵漏洞報告,將根據嚴重程度提供獎勵:

  • 資金損失:最高 25,000 SOL
  • 共識或安全性違規:最高 12,500 SOL
  • 活性或可用性喪失:最高 5,000 SOL

此外,FireDancer 客戶端在 Immunefi 平臺上設有單獨的漏洞賞金計劃,對於關鍵發現,最高獎勵為 500,000 USDC。

停機實例

以下部分將提供一個詳細的時間順序分析,涵蓋自 2020 年 3 月 16 日 Mainnet Beta 啟動以來 Solana 的停機事件和性能下降期。此分析將突出關鍵事件、根本原因以及網絡隨後的改進,洞察 Solana 如何隨著時間的推移不斷增強穩定性和韌性。

Turbine 漏洞:2020 年 12 月

停機時間:大約六小時

根本問題:區塊傳播漏洞

修復措施:

  • 通過哈希跟蹤區塊,而非槽位號
  • 修復 Turbine 中可更早進行故障檢測的地方
  • 通過 gossip 將首次檢測到的故障傳播給所有驗證者

這次停機由一個之前已知的區塊修復和代碼處理問題引發,該問題是由 Turbine 中未被識別的漏洞觸發的。Turbine 是 Solana 的區塊傳播機制。故障發生時,一個驗證者為同一槽位傳播了兩個不同的區塊,並將它們分別傳播到兩個獨立的分區(A 和 B),而第三個分區獨立檢測到了不一致性。

由於每個分區只持有少數股份,因此沒有任何分區能達成超大多數共識來推進鏈。根本問題源於 Solana 內部數據結構如何跟蹤區塊及其計算狀態。系統使用歷史證明(PoH)槽位號(一個 u64 標識符)來引用該槽位的狀態和區塊。一旦網絡分裂為多個分區,節點誤將區塊 A 和 B 視為相同,從而阻止了區塊的正確修復和同步。

每個分區都認為另一個分區持有相同的區塊,從而導致了一個根本性的衝突:

  • 持有區塊 A 的節點拒絕從區塊 B 派生的分叉
  • 持有區塊 B 的節點拒絕從區塊 A 派生的分叉

由於各分區之間的狀態轉變不同,驗證者無法修復或調和這些分叉,進而阻止了最終確定。

解決該問題的修復方案是允許服務通過哈希跟蹤區塊,而非通過槽位號。如果同一槽位的多個區塊創建了分區,它們將與佔據不同槽位的區塊分區一樣處理。這樣,節點將能夠修復所有可能的分叉,並且共識可以解決這些分區問題。

儘管漏洞是停機的初始原因,但大部分停機時間來自於等待足夠的質押權重重新上線,因為 Solana 需要至少 80% 的質押參與才能恢復區塊生產。

Grape 協議 IDO:2021 年 9 月

停機時間:十七小時

根本問題:由機器人交易引起的內存溢出

修復措施:

  • 忽略程序上的寫鎖
  • 對交易轉發進行速率限制
  • 可配置的 RPC 重試行為
  • TPU 投票交易優先級

2021 年 9 月 14 日,Solana 在 Grape 協議在眾籌平臺 Raydium AcceleRaytor 上啟動其鏈上首次 DEX 發行(IDO)後,遭遇了嚴重的網絡停滯。在 IDO 開始後的 12 分鐘內,網絡被前所未有的機器人驅動交易洪流壓垮,導致無法生產根槽。這些機器人有效地發起了分佈式拒絕服務(DDoS)攻擊,將交易負載推超出網絡的承載能力。

在高峰擁堵時:

  • 部分驗證者接收到了超過 300,000 筆交易每秒。
  • 原始交易數據超過了 1 Gbps,且每秒 120,000 個數據包。
  • 流量有時超過了網絡接口的物理限制,導致在數據包甚至到達驗證者之前,交換機端口就發生了數據包丟失。

2021 年 9 月 14 日 Grape 協議 IDO 停機期間的 Solana 每秒槽數(數據來源:Jump Crypto)

其中一個機器人將其交易結構化為寫鎖定 18 個關鍵賬戶,包括全球 SPL 代幣協議和現已停用的 Serum DEX 協議。這導致所有與這些賬戶交互的交易被阻塞,嚴重降低了 Solana 的並行處理能力。網絡無法獨立執行交易,而是必須按順序處理交易,從而加劇了擁堵。

一種忽略程序寫鎖的修復方法已開發完成並計劃發佈。網絡重啟後,該升級被啟用,從而永久消除了這一攻擊向量。

在 IDO 期間,驗證者接收了大量由機器人驅動的交易,並將多餘的交易轉發給下一任領導者,進一步加劇了擁堵。網絡重啟後,引入了交易轉發速率限制,以防止未來的交易風暴壓垮領導者。

Solana 的 RPC 節點會自動重試失敗的交易,這一功能旨在提高可靠性。然而,在極端擁堵情況下,這一重試機制加劇了交易洪流,使舊交易持續循環,阻礙網絡恢復。Solana 1.8 版本引入了可配置的 RPC 重試行為,使應用程序能夠通過縮短交易過期時間和採用指數退避策略來優化重試。

在嚴重擁堵情況下,Solana 的領導者未能包含投票交易,而投票交易對維持共識至關重要。由於缺乏已確認的投票,導致共識停滯,阻止了新根塊的生成。Solana 客戶端的後續版本引入了一種機制,優先處理投票交易,防止其在未來事件中被常規交易淹沒。

第二個錯誤:整數溢出

在網絡重啟過程中,出現了第二個問題。驗證者報告活躍質押數量大幅波動。問題源於一個錯誤:質押百分比被錯誤地乘以 100,導致數值超出最大允許值。通脹機制生成了過多的 SOL 代幣,導致 64 位無符號整數溢出。該錯誤被迅速識別並在第二次重啟前修復。

高擁堵:2022 年 1 月

停機時間:無

根本原因:過多重複交易

部分修復措施:

  • Solana 1.8.12 和 1.8.14 版本發佈
  • 優化 SigVerify 重複數據消除
  • 提升執行器緩存性能

2022 年 1 月 6 日至 1 月 12 日,Solana 主網經歷了嚴重的網絡擁堵,導致性能下降和部分故障。此次中斷由機器人大量發送重複交易引發,顯著降低了網絡容量。區塊處理時間延長,導致下一個領導者分叉,進一步降低吞吐量。高峰時,交易成功率下降多達 70%。客戶端難以處理複雜且高計算量的交易,暴露出其在高需求情況下的性能瓶頸。

1 月 21 日至 23 日,網絡出現額外的不穩定性,擁堵持續存在。1 月 22 日,由於被濫用的批量 RPC 調用導致系統過載,公共 RPC 端點 (https://api.mainnet-beta.solana.com) 下線。

為解決這些問題,Solana 1.8.12 版本針對程序緩存耗盡進行了優化,而 1.8.14 版本則提升了 Sysvar 緩存、SigVerify 丟棄機制和 SigVerify 重複數據消除功能

Candy Machine 垃圾交易:2022 年 4 月/5 月

停機時間:8 小時

根本原因:機器人賬戶發送的垃圾交易

修復措施:

  • Candy Machine 程序引入機器人稅
  • Solana v1.10 內存性能優化

2022 年 4 月 30 日,Solana 遭遇前所未有的交易請求激增。部分節點報告其請求量高達每秒 600 萬次,生成的網絡流量超過每個節點 100 Gbps。這一激增是由機器人試圖通過 Metaplex Candy Machine 程序搶購新鑄造的 NFT 導致的。該鑄造機制採用先到先得的方式,促使機器人大量發送交易以提高搶購成功率。

2022 年 4 月 30 日/5 月 1 日 Candy Machine 停機事件,每秒數據包輸入量(數據來源:Jump Crypto)

隨著交易量飆升,驗證者內存耗盡並崩潰,最終導致共識停滯。由於投票吞吐量不足,早期區塊無法最終確定,導致廢棄的分叉無法被清理。因此,驗證者因需評估的大量分叉而不堪重負,即使重新啟動後仍無法恢復,最終需要人工干預才能恢復網絡。

儘管此次停機與 2021 年 9 月的事件有相似之處,但 Solana 展現出更強的抗壓能力。儘管交易請求量比上次激增了 10,000%,網絡仍能運行更長時間,體現了驗證者社區在應對過去擴容挑戰後取得的改進成果。

2022 年 4 月 30 日/5 月 1 日 Candy Machine 停機事件,活躍驗證者數量(數據來源:Jump Crypto)

在確定規範快照後,網絡重啟耗時不到 1.5 小時。Solana v1.10 提供了內存使用優化,使節點在共識緩慢或停滯時能維持更長時間。

然而,根本問題仍未解決。Leader 依舊按照“先到先得”原則處理爭奪相同賬戶數據的交易,且缺乏有效的垃圾交易防護,導致用戶無法根據交易緊急程度進行優先處理。為此,提出了三種長期機制作為解決方案。

QUIC 協議的採用:Solana 先前使用 UDP(用戶數據報協議)通過 Gulf Stream 將 RPC 節點的交易發送至當前 Leader。儘管 UDP 速度快、效率高,但它是無連接協議,缺乏流量控制和接收確認,無法有效防範或減輕濫用行為。為此,驗證者的交易接收協議(即 TPU 的 Fetch Stage)被重新設計,採用 QUIC 協議。

QUIC 結合了 TCP 和 UDP 的優點,既能實現類似 UDP 的快速異步通信,又具備 TCP 的安全會話和高級流量控制策略,從而限制單一流量來源,使網絡更專注於處理真實交易。此外,QUIC 支持獨立的數據流概念,即使一個交易丟失,也不會阻塞其他交易。QUIC 最終集成至 Solana Labs 客戶端,並在 1.13.4 版本中發佈。

Stake-Weighted Quality of Service (SWQoS):引入了基於驗證者質押權重的網絡流量優先機制,確保質押比例更高的驗證者能更高效地發送交易。在此機制下,持有總質押量 3% 的驗證者可向 Leader 發送最多佔總數據包量 3% 的交易。SWQoS 作為一種 Sybil 攻擊防護措施,使惡意攻擊者更難用低質量交易淹沒網絡。這一方法取代了此前“先到先得”的模式,後者在接收交易時不區分來源。

引入優先費用:在交易被接收後,仍需競爭訪問共享賬戶數據。此前,這一爭奪通過“先到先得”機制解決,用戶無法表達交易的緊急性。由於任何人都可提交交易,質押權重並不適用於此階段的優先排序。為此,Compute Budget 程序新增了一條指令,允許用戶指定在交易執行和區塊包含時收取的額外費用。交易的執行優先級取決於“費用與計算單位的比率”,從而實現更具動態性和市場驅動的交易排序方式。

Candy Machine 機器人稅

Metaplex 迅速在 Candy Machine 程序的鑄造交易中引入了 0.01 SOL 的硬編碼機器人稅,以打擊由機器人驅動的垃圾交易。這一反垃圾機制通過收取最低費用來阻止惡意活動,同時不會懲罰因操作失誤而產生的正常用戶。該稅收適用於以下特定情況:

  • 嘗試在 Candy Machine 尚未開放時進行鑄造
  • 嘗試在庫存為空時進行鑄造
  • 交易中鑄造或設置集合指令未作為最終指令
  • 使用了錯誤的集合 ID
  • 設置集合指令不匹配
  • 集合設置與鑄造指令之間的簽名者支付者不匹配
  • 涉及禁止程序的可疑交易
  • 嘗試從受 AllowList 保護的 Candy Machine 進行鑄造,但未持有所需的 AllowList 代幣

這一經濟性威懾措施非常有效。Mint 機器人迅速被耗盡,垃圾交易活動停止。在最初幾天內,機器人操作者共損失超過 426 SOL。

Durable Nonce 錯誤:2022年6月

停機時間:四個半小時

根本原因:Durable nonce 錯誤導致共識失敗

修復措施:

  • 暫時禁用 durable nonce 交易
  • Solana 1.10.23 更新

一個運行時錯誤導致某些 durable nonce 交易被處理了兩次——一次作為常規交易,另一次作為 nonce 交易——如果它們在 recent_blockhash 字段中使用的是最近的區塊哈希,而不是 durable nonce。這導致驗證者之間出現非確定性行為,因為有些節點拒絕了第二次執行,而其他節點接受了它。關鍵的是,由於超過三分之一的驗證者接受了該區塊,它阻止了所需的三分之二多數達成共識。

與標準交易不同,durable nonce 交易不會過期,需要一個獨特的機制來防止雙重執行。它們是串行處理的,使用與每個賬戶綁定的鏈上 nonce 值,每次處理 durable nonce 交易時都會旋轉。一旦旋轉,相同的 nonce 交易不應再次有效。

為了解決這一問題,durable nonce 交易被暫時禁用。之後,Solana 1.10.23 更新實施了修復,防止了重複執行,通過將 nonce 和區塊哈希域分開來解決此問題。該更新確保在推進 nonce 賬戶時,區塊哈希與固定字符串一起進行哈希,使得區塊哈希不能作為 nonce 值。因此,作為常規交易執行的交易不能作為 durable 交易重新執行,反之亦然。此外,新的 DurableNonce 類型替代了 nonce 賬戶狀態中的先前區塊哈希值,增加了類型安全性,並防止了類似問題的發生。

閱讀我們之前的 Helius 博客文章,瞭解更多關於 durable nonce 的內容及其用途。

重複區塊錯誤:2022年9月

停機時間:八個半小時

根本原因:分叉選擇規則中的錯誤導致共識失敗

修復措施:

  • 客戶端補丁

此次故障是由於某個驗證者錯誤地在相同區塊高度生成了重複區塊。原因是該驗證者的主節點和備用節點同時激活,使用相同的節點身份但提議了不同的區塊。這種情況持續了至少24小時,在此期間,網絡能夠正確處理驗證者的重複領導者槽位。

當網絡因分叉選擇邏輯中的錯誤而遇到不可恢復的分叉時,集群最終停止運行。此錯誤導致區塊生產者無法在前一個區塊的基礎上構建,從而導致共識失敗。

在 Solana 網絡中,分叉是常見現象,驗證者通常通過選擇獲得大多數投票的分叉(即最重分叉)來解決分叉問題。當驗證者選擇了錯誤的分叉時,它必須切換到最重分叉以與網絡保持同步。然而,在此次事件中,如果驗證者的最後投票槽位與最重銀行的槽位一致,則無法恢復到最重銀行。此缺陷導致驗證者陷入死循環,阻止了共識的推進,並最終導致網絡停機。

重複區塊錯誤導致的分叉選擇,2022年9月(來源:Laine,Michael Hubbard)

在上述示例中,故障驗證者 C 在其領導槽位 5 至 8 生成了重複區塊。當驗證者 G 接任為下一個領導者時,它僅觀察到其中一個重複區塊,並相應地擴展其分叉。然而,接下來的領導者驗證者 D 檢測到來自驗證者 C 的兩個重複區塊,並決定將其丟棄,而是在槽位 4 之上構建自己的分叉。

隨著網絡運行,驗證者 G 構建的分叉獲得了大多數質押的投票,確立了其作為規範鏈的地位。由於意識到自己的分叉正在失敗,驗證者 D 嘗試切換到驗證者 G 的分叉。然而,由於分叉選擇邏輯中的錯誤,該切換未能成功。問題的根源在於兩個分叉的共同祖先——槽位 5 的重複區塊——未被正確處理,導致驗證者 D 無法識別大多數分叉。結果,驗證者 D 被困在自己的分叉上,無法重新加入主鏈。

該問題在核心團隊的審查後得到解決。修復補丁已合併至主分支,並回溯應用於所有發佈分支。

大型區塊導致 Turbine 超載,2023年2月

停機時間:近19小時

根本原因:分片轉發服務中的去重邏輯失效

修復措施:

  • 改進 Turbine 的去重邏輯與過濾機制
  • 添加客戶端補丁,強制區塊生產者在生成大區塊時中止

某驗證者的自定義分片轉發服務發生故障,在其領導槽位期間傳輸了一個異常龐大的區塊(接近15萬片分片),其規模遠超標準區塊。這導致驗證者的去重過濾器超載,數據被持續重複轉發。隨著新區塊不斷生成,問題進一步加劇,最終導致協議飽和。

大型區塊故障,每個區塊的分片數量,2023年2月(來源:Laine,Michael Hubbard)

異常的網絡流量激增導致 Turbine 超載,被迫通過速度明顯較慢的備用 Block Repair 協議傳輸區塊數據。儘管 Turbine 設計用於通過過濾大區塊來承受其影響,但分片轉發服務位於此過濾邏輯的上游,削弱了其效果。在性能受損期間,區塊領導者自動切換至僅投票模式,這是一種安全機制,要求領導者排除經濟類的非投票交易。

問題的根本原因是分片轉發服務中的去重邏輯失效,未能阻止分片的冗餘重傳。此外,重傳流水線中的去重過濾器最初並未設計用於防止 Turbine 樹內部的循環,進一步加劇了問題。

網絡通過手動重啟並降級至最後已知的穩定驗證者軟件版本恢復運行。為解決這些問題,Solana v1.13.7 和 v1.14.17 引入了去重邏輯增強,提升了防止過濾器飽和的能力,從而確保網絡性能更加穩健。

無限重新編譯循環,2024年2月

停機時間:近 5 小時

根本原因:JIT 緩存中的錯誤導致無限重新編譯循環

修復措施:

  • 禁用傳統加載器 v1.17.20

Agave 驗證者在執行引用程序的交易前,會對所有程序進行即時編譯 (JIT)。為了優化性能,JIT 會將常用程序的輸出緩存,減少不必要的重複編譯。作為 Agave v1.16 的一部分,原有的 LoadedPrograms 緩存機制被替換為新的 ExecutorsCache,實現了多項效率提升。

LoadedPrograms 提供了一個全局、支持分叉的程序緩存視圖,減少了賬務數據的重複,並允許交易執行線程協同加載新程序,防止編譯衝突。其關鍵功能是跟蹤程序生效的插槽高度(即有效插槽高度),以便在鏈上程序數據更新時檢測緩存失效。

大多數程序的有效插槽高度來自其部署插槽,並存儲在鏈上賬戶中。然而,使用傳統加載器部署的程序未在其賬戶中保留部署插槽。為此,LoadedPrograms 將這些程序的有效插槽高度設置為零。

當檢測到部署指令,表明程序字節碼已被替換時,會觸發一個例外情況。此時,LoadedPrograms 會臨時插入一個具有正確有效插槽高度的條目。然而,由於交易從未引用過此條目,導致其很容易被驅逐。當條目被驅逐時,JIT 輸出被丟棄,程序被標記為卸載,但有效插槽高度仍被保留。

如果隨後有交易引用此已卸載程序,LoadedPrograms 會重新編譯它並在其有效插槽高度下重新插入條目。通常,這會使程序在下次迭代時可供執行。然而,對於傳統加載器程序,新的 JIT 輸出會被分配為零這一哨兵插槽高度,導致其排列在先前已卸載條目的後面。結果是,LoadedPrograms 無法識別該程序已被加載,從而在每次迭代時觸發持續的重新編譯循環。

在 Agave v1.16 中,LoadedPrograms 不支持協作加載,因此觸發交易會被打包到一個區塊中。此區塊隨後在整個網絡上傳播,導致所有驗證者重放該區塊並陷入相同的無限重新編譯循環。由於在故障期間,超過 95% 的網絡質押節點運行的是 Agave v1.17,大多數驗證者在此區塊上陷入停滯,導致網絡中斷。

該錯誤在前一週的一次 Devnet 集群故障調查中已被發現,並計劃進行修復。@jeff.washington/2024-02-06-solana-mainnet-beta-outage-report-619bd75b3ce0”>最終的緩解措施是將更改回溯至 Agave v1.17,並在網絡重啟時立即移除功能門控,從而禁用導致該錯誤的傳統加載器,防止問題再次發生。

協調漏洞補丁,2024年8月

停機時間:無

根本問題:ELF 地址對齊假設不正確

修復:

  • 補丁更新

8 月 5 日,Anza 核心工程師收到一名外部研究人員報告的 Agave 客戶端漏洞。攻擊者可能利用此漏洞導致領導驗證者崩潰,從而引發全網停機。對此,Anza 工程師迅速開發了補丁,並經多家第三方安全公司審計。

Solana 程序使用 LLVM 編譯為可執行與可鏈接格式 (ELF)。漏洞源於這些 ELF 文件中地址對齊假設的錯誤。儘管 ELF 檢查通常會強制執行各種完整性驗證,但未對 .text 段的對齊進行驗證。這一疏忽可能允許惡意構造的 ELF 文件定義錯位的 .text 段,導致虛擬機跳轉至無效地址,從而引發主機段錯誤並使驗證者崩潰。

攻擊者可通過以下方式利用該漏洞:

  • 創建使用 CALL_REG 操作碼的惡意 Solana 程序。
  • 操縱 ELF 文件使其 .text 段錯位。
  • 將程序部署並調用於網絡上,從而觸發驗證者崩潰。

補丁更新流程

任何公開發布的補丁更新都會立即暴露漏洞,從而可能讓攻擊者有時間對漏洞進行逆向工程,並在足夠數量的驗證者完成升級之前導致網絡停機。為了避免這種情況,必須儘快讓大多數驗證者採用補丁版本。

截至 8 月 7 日,Solana 基金會的多名成員已通過各種通信平臺的私信聯繫驗證者,告知即將發佈的重要補丁,並分享了一條經過哈希處理的信息,以確認事件的日期和唯一標識符。Anza、Jito 和 Solana 基金會的多位知名成員隨後在 X、GitHub 和 LinkedIn 上發佈了此哈希值,以驗證信息的準確性。示例哈希值共享如下:

在接下來的一天裡,核心成員繼續聯繫驗證者,強調緊迫性和保密性的重要性。按照預定時間,即 8 月 8 日 14:00 UTC,驗證者運營商收到了進一步的通知,包含了下載、驗證和應用補丁的指令。該補丁託管在一位知名 Anza 工程師的 GitHub 倉庫中,而非主 Agave 倉庫。指令中還包括了將下載的補丁文件與提供的 shasum 哈希值進行驗證的要求。

截至 8 月 8 日 20:00 UTC,持有超級多數權益的驗證者已完成補丁更新,確保了網絡安全。隨後,漏洞及其相關補丁被公開披露,並呼籲所有剩餘驗證者儘快進行升級。

此次補丁的私下分發以及驗證者之間的幕後協調引發了關於 Solana 去中心化性質的擔憂。事件發生後不久,Solana 基金會執行董事 Dan Albert 在一次媒體採訪中迴應了這些批評。

“我認為不能將協調能力與中心化混為一談。全球有大約 1,500 個區塊生產節點,由幾乎同樣多的個人運營……能夠與他們,或部分驗證者,自願地進行溝通,並不等同於中心化。”

2024 年韓國區塊鏈周 (KBW)

“我認為不能將協調能力與中心化混為一談。全球有大約 1,500 個區塊生產節點,由幾乎同樣多的個人運營……能夠與他們,或部分驗證者,自願地進行溝通,並不等同於中心化。”

結論

截至目前,Solana 已經超過一年沒有發生停機事件,達成了移除“beta”標籤並正式從 mainnet-beta 中移除的重要里程碑。隨著網絡的成熟,停機事件的頻率似乎有所下降,而 Firedancer 的引入預計將提升客戶端多樣性,減少尚未發現的漏洞或邊緣情況導致整個集群停機的風險。然而,包括 Helius 創始人 Mert Mumtaz 在內的一些社區領袖預測,停機事件仍將繼續發生,時間將證明一切。

感謝 Zantetsu(Shinobi Systems)和 OxIchigo 對本文早期版本的審閱。

聲明:

  1. 本文轉載自[Helius]。所有版權歸原作者所有[Lostin]。若對本次轉載有異議,請聯繫 Gate Learn 團隊,他們會及時處理。
  2. 免責聲明:本文所表達的觀點和意見僅代表作者個人觀點,不構成任何投資建議。
  3. Gate Learn 團隊將文章翻譯成其他語言。除非另有說明,否則禁止複製、分發或抄襲翻譯文章。

Solana 停機完整歷史:原因、修復與經驗教訓

進階2/26/2025, 9:07:22 AM
本文將詳細分析每次 Solana 停機事件,探討根本原因、觸發事件以及為解決問題所採取的措施。

嘟,嘟,嘟。嘟,嘟,嘟。

史蒂文的睡眠被手機刺耳的鈴聲打斷,將他從夢境中猛然拉回現實。黑暗中,手機屏幕亮得刺眼,在床頭櫃上劇烈震動。嘟,嘟,嘟。

他呻吟一聲,迷迷糊糊地揉了揉眼睛,伸手拿起手機。眯著眼看向消息,心中一沉——節點宕機了。

他毫不猶豫地跳下床,衣衫不整地摸索著解鎖手機,而更多的消息不斷湧入。就在這時,他猛然意識到——整個集群都宕機了。

就在此刻,地球另一端的不同城市和時區,數百名節點運營者也正盯著手機,意識到他們最害怕的時刻已經到來——一次停機。

引言

與所有分佈式系統一樣,Solana 也面臨著這樣一個現實:單個實現缺陷或模糊的邊緣情況都可能導致全網故障。儘管停機會帶來干擾,但這是維護複雜分佈式基礎設施的必然過程——無論是在去中心化區塊鏈、中心化交易所,還是亞馬遜或微軟等大型雲服務提供商中。

問題不在於故障是否會發生,而在於何時發生,以及網絡將如何演變以適應並增強其應對未來事件的能力。儘管進行了嚴格的模擬測試、激勵性測試網以及活躍的漏洞賞金計劃,但即使是設計再完善的系統也無法預見每一種可能的故障模式。最寶貴的經驗往往來自實際運行中的事件。

在過去五年裡,Solana 共經歷了七次獨立的停機事件,其中五次由客戶端漏洞引發,另外兩次則是由於網絡無法應對大規模交易垃圾郵件。Solana 的早期版本缺乏關鍵的擁堵管理機制,例如優先費用和本地費用市場,而這些機制後來被證明在緩解網絡壓力方面至關重要。由於缺乏這些機制,2022 年期間網絡頻繁出現性能下降和擁堵現象,因為其機制實際上激勵了垃圾交易的產生。

Solana 停機與性能下降的歷史實例

本文將詳細分析每次 Solana 停機事件,探討根本原因、觸發事件以及為解決問題所採取的措施。此外,我們還將討論網絡重啟、漏洞報告以及活性與安全性故障等核心概念。儘管這些部分按順序閱讀效果最佳,但每一部分都可以獨立閱讀,方便讀者直接跳轉到感興趣的主題或具體的停機事件。

活性與安全性

根據 CAP 定理(亦稱 Brewer 定理),分佈式系統只能在以下三個特性中實現兩個:

  • 一致性 - 每次讀取都能看到之前的所有寫入。
  • 可用性 - 每個請求都會收到響應。
  • 分區容錯性 - 系統在網絡分區的情況下仍能繼續運行。

對於區塊鏈而言,分區容錯性至關重要,因為網絡中斷是不可避免的。這迫使系統在 AP(可用性 + 分區容錯性)和 CP(一致性 + 分區容錯性)之間做出選擇。與大多數快速最終性 PoS 鏈一樣,Solana 優先考慮一致性而非可用性,因此屬於 CP 系統。在關鍵故障期間,Solana 會選擇暫停運行,而不是提供過期數據或允許不安全的寫入。雖然這意味著節點軟件可能會進入需要人工干預的不可恢復狀態,但它確保了用戶資金的安全。

Solana 在 CAP 定理權衡中的定位

活性故障:指區塊鏈停止推進,導致由於驗證者宕機、網絡分區或共識停滯而無法確認交易或生產區塊。在 CAP 定理中,這對應於可用性的喪失。

安全性故障:指區塊鏈的最終狀態被篡改或出現不正確的分叉,可能導致歷史記錄衝突或雙花,通常由共識漏洞或惡意攻擊引發。在 CAP 定理中,這對應於一致性的喪失。

Solana 優先考慮安全性而非活性。因此,在網絡壓力過大或共識故障的情況下,Solana 會選擇暫停運行,而不是冒著狀態被破壞的風險。儘管停機會對應用程序、用戶和驗證者造成干擾,但相比賬本出現不一致或被篡改帶來的災難性後果,這種權衡更為可取。

網絡重啟

重啟 Solana 網絡涉及識別最後一個經過樂觀確認的區塊槽位,並從該槽位的受信本地狀態快照重新啟動節點。由於重啟槽位並非通過鏈上確定,驗證者運營者必須在鏈下達成共識,以確定安全的回滾點。這一協調過程公開進行,地點是在 Solana Tech Discord 的 #mb-validators 頻道,專業驗證者運營者會在此進行實時溝通。大多數運營者都配備了自動警報系統,可在區塊生產停止的瞬間發出通知,確保快速響應。

一旦就正確的重啟槽位達成共識,運營者會使用 ledger 工具生成新的本地快照,重新啟動驗證者,並等待至少 80% 的總質押重新上線。只有在達到這一比例後,網絡才會恢復區塊生產與驗證。在集群重啟時,確保離線質押不超過 20%,可為節點在重啟後因分叉或再次下線時提供足夠的安全餘量。

漏洞報告

漏洞賞金計劃通過獎勵安全研究人員來鼓勵他們識別並報告軟件漏洞。這是一道關鍵的防線,可主動激勵在漏洞被利用之前將其發現。發現 Agave 客戶端潛在漏洞的安全研究人員和開發者應通過適當的安全渠道進行報告。詳細的披露指南可在 Agave 的 GitHub 倉庫中找到

針對有效的關鍵漏洞報告,將根據嚴重程度提供獎勵:

  • 資金損失:最高 25,000 SOL
  • 共識或安全性違規:最高 12,500 SOL
  • 活性或可用性喪失:最高 5,000 SOL

此外,FireDancer 客戶端在 Immunefi 平臺上設有單獨的漏洞賞金計劃,對於關鍵發現,最高獎勵為 500,000 USDC。

停機實例

以下部分將提供一個詳細的時間順序分析,涵蓋自 2020 年 3 月 16 日 Mainnet Beta 啟動以來 Solana 的停機事件和性能下降期。此分析將突出關鍵事件、根本原因以及網絡隨後的改進,洞察 Solana 如何隨著時間的推移不斷增強穩定性和韌性。

Turbine 漏洞:2020 年 12 月

停機時間:大約六小時

根本問題:區塊傳播漏洞

修復措施:

  • 通過哈希跟蹤區塊,而非槽位號
  • 修復 Turbine 中可更早進行故障檢測的地方
  • 通過 gossip 將首次檢測到的故障傳播給所有驗證者

這次停機由一個之前已知的區塊修復和代碼處理問題引發,該問題是由 Turbine 中未被識別的漏洞觸發的。Turbine 是 Solana 的區塊傳播機制。故障發生時,一個驗證者為同一槽位傳播了兩個不同的區塊,並將它們分別傳播到兩個獨立的分區(A 和 B),而第三個分區獨立檢測到了不一致性。

由於每個分區只持有少數股份,因此沒有任何分區能達成超大多數共識來推進鏈。根本問題源於 Solana 內部數據結構如何跟蹤區塊及其計算狀態。系統使用歷史證明(PoH)槽位號(一個 u64 標識符)來引用該槽位的狀態和區塊。一旦網絡分裂為多個分區,節點誤將區塊 A 和 B 視為相同,從而阻止了區塊的正確修復和同步。

每個分區都認為另一個分區持有相同的區塊,從而導致了一個根本性的衝突:

  • 持有區塊 A 的節點拒絕從區塊 B 派生的分叉
  • 持有區塊 B 的節點拒絕從區塊 A 派生的分叉

由於各分區之間的狀態轉變不同,驗證者無法修復或調和這些分叉,進而阻止了最終確定。

解決該問題的修復方案是允許服務通過哈希跟蹤區塊,而非通過槽位號。如果同一槽位的多個區塊創建了分區,它們將與佔據不同槽位的區塊分區一樣處理。這樣,節點將能夠修復所有可能的分叉,並且共識可以解決這些分區問題。

儘管漏洞是停機的初始原因,但大部分停機時間來自於等待足夠的質押權重重新上線,因為 Solana 需要至少 80% 的質押參與才能恢復區塊生產。

Grape 協議 IDO:2021 年 9 月

停機時間:十七小時

根本問題:由機器人交易引起的內存溢出

修復措施:

  • 忽略程序上的寫鎖
  • 對交易轉發進行速率限制
  • 可配置的 RPC 重試行為
  • TPU 投票交易優先級

2021 年 9 月 14 日,Solana 在 Grape 協議在眾籌平臺 Raydium AcceleRaytor 上啟動其鏈上首次 DEX 發行(IDO)後,遭遇了嚴重的網絡停滯。在 IDO 開始後的 12 分鐘內,網絡被前所未有的機器人驅動交易洪流壓垮,導致無法生產根槽。這些機器人有效地發起了分佈式拒絕服務(DDoS)攻擊,將交易負載推超出網絡的承載能力。

在高峰擁堵時:

  • 部分驗證者接收到了超過 300,000 筆交易每秒。
  • 原始交易數據超過了 1 Gbps,且每秒 120,000 個數據包。
  • 流量有時超過了網絡接口的物理限制,導致在數據包甚至到達驗證者之前,交換機端口就發生了數據包丟失。

2021 年 9 月 14 日 Grape 協議 IDO 停機期間的 Solana 每秒槽數(數據來源:Jump Crypto)

其中一個機器人將其交易結構化為寫鎖定 18 個關鍵賬戶,包括全球 SPL 代幣協議和現已停用的 Serum DEX 協議。這導致所有與這些賬戶交互的交易被阻塞,嚴重降低了 Solana 的並行處理能力。網絡無法獨立執行交易,而是必須按順序處理交易,從而加劇了擁堵。

一種忽略程序寫鎖的修復方法已開發完成並計劃發佈。網絡重啟後,該升級被啟用,從而永久消除了這一攻擊向量。

在 IDO 期間,驗證者接收了大量由機器人驅動的交易,並將多餘的交易轉發給下一任領導者,進一步加劇了擁堵。網絡重啟後,引入了交易轉發速率限制,以防止未來的交易風暴壓垮領導者。

Solana 的 RPC 節點會自動重試失敗的交易,這一功能旨在提高可靠性。然而,在極端擁堵情況下,這一重試機制加劇了交易洪流,使舊交易持續循環,阻礙網絡恢復。Solana 1.8 版本引入了可配置的 RPC 重試行為,使應用程序能夠通過縮短交易過期時間和採用指數退避策略來優化重試。

在嚴重擁堵情況下,Solana 的領導者未能包含投票交易,而投票交易對維持共識至關重要。由於缺乏已確認的投票,導致共識停滯,阻止了新根塊的生成。Solana 客戶端的後續版本引入了一種機制,優先處理投票交易,防止其在未來事件中被常規交易淹沒。

第二個錯誤:整數溢出

在網絡重啟過程中,出現了第二個問題。驗證者報告活躍質押數量大幅波動。問題源於一個錯誤:質押百分比被錯誤地乘以 100,導致數值超出最大允許值。通脹機制生成了過多的 SOL 代幣,導致 64 位無符號整數溢出。該錯誤被迅速識別並在第二次重啟前修復。

高擁堵:2022 年 1 月

停機時間:無

根本原因:過多重複交易

部分修復措施:

  • Solana 1.8.12 和 1.8.14 版本發佈
  • 優化 SigVerify 重複數據消除
  • 提升執行器緩存性能

2022 年 1 月 6 日至 1 月 12 日,Solana 主網經歷了嚴重的網絡擁堵,導致性能下降和部分故障。此次中斷由機器人大量發送重複交易引發,顯著降低了網絡容量。區塊處理時間延長,導致下一個領導者分叉,進一步降低吞吐量。高峰時,交易成功率下降多達 70%。客戶端難以處理複雜且高計算量的交易,暴露出其在高需求情況下的性能瓶頸。

1 月 21 日至 23 日,網絡出現額外的不穩定性,擁堵持續存在。1 月 22 日,由於被濫用的批量 RPC 調用導致系統過載,公共 RPC 端點 (https://api.mainnet-beta.solana.com) 下線。

為解決這些問題,Solana 1.8.12 版本針對程序緩存耗盡進行了優化,而 1.8.14 版本則提升了 Sysvar 緩存、SigVerify 丟棄機制和 SigVerify 重複數據消除功能

Candy Machine 垃圾交易:2022 年 4 月/5 月

停機時間:8 小時

根本原因:機器人賬戶發送的垃圾交易

修復措施:

  • Candy Machine 程序引入機器人稅
  • Solana v1.10 內存性能優化

2022 年 4 月 30 日,Solana 遭遇前所未有的交易請求激增。部分節點報告其請求量高達每秒 600 萬次,生成的網絡流量超過每個節點 100 Gbps。這一激增是由機器人試圖通過 Metaplex Candy Machine 程序搶購新鑄造的 NFT 導致的。該鑄造機制採用先到先得的方式,促使機器人大量發送交易以提高搶購成功率。

2022 年 4 月 30 日/5 月 1 日 Candy Machine 停機事件,每秒數據包輸入量(數據來源:Jump Crypto)

隨著交易量飆升,驗證者內存耗盡並崩潰,最終導致共識停滯。由於投票吞吐量不足,早期區塊無法最終確定,導致廢棄的分叉無法被清理。因此,驗證者因需評估的大量分叉而不堪重負,即使重新啟動後仍無法恢復,最終需要人工干預才能恢復網絡。

儘管此次停機與 2021 年 9 月的事件有相似之處,但 Solana 展現出更強的抗壓能力。儘管交易請求量比上次激增了 10,000%,網絡仍能運行更長時間,體現了驗證者社區在應對過去擴容挑戰後取得的改進成果。

2022 年 4 月 30 日/5 月 1 日 Candy Machine 停機事件,活躍驗證者數量(數據來源:Jump Crypto)

在確定規範快照後,網絡重啟耗時不到 1.5 小時。Solana v1.10 提供了內存使用優化,使節點在共識緩慢或停滯時能維持更長時間。

然而,根本問題仍未解決。Leader 依舊按照“先到先得”原則處理爭奪相同賬戶數據的交易,且缺乏有效的垃圾交易防護,導致用戶無法根據交易緊急程度進行優先處理。為此,提出了三種長期機制作為解決方案。

QUIC 協議的採用:Solana 先前使用 UDP(用戶數據報協議)通過 Gulf Stream 將 RPC 節點的交易發送至當前 Leader。儘管 UDP 速度快、效率高,但它是無連接協議,缺乏流量控制和接收確認,無法有效防範或減輕濫用行為。為此,驗證者的交易接收協議(即 TPU 的 Fetch Stage)被重新設計,採用 QUIC 協議。

QUIC 結合了 TCP 和 UDP 的優點,既能實現類似 UDP 的快速異步通信,又具備 TCP 的安全會話和高級流量控制策略,從而限制單一流量來源,使網絡更專注於處理真實交易。此外,QUIC 支持獨立的數據流概念,即使一個交易丟失,也不會阻塞其他交易。QUIC 最終集成至 Solana Labs 客戶端,並在 1.13.4 版本中發佈。

Stake-Weighted Quality of Service (SWQoS):引入了基於驗證者質押權重的網絡流量優先機制,確保質押比例更高的驗證者能更高效地發送交易。在此機制下,持有總質押量 3% 的驗證者可向 Leader 發送最多佔總數據包量 3% 的交易。SWQoS 作為一種 Sybil 攻擊防護措施,使惡意攻擊者更難用低質量交易淹沒網絡。這一方法取代了此前“先到先得”的模式,後者在接收交易時不區分來源。

引入優先費用:在交易被接收後,仍需競爭訪問共享賬戶數據。此前,這一爭奪通過“先到先得”機制解決,用戶無法表達交易的緊急性。由於任何人都可提交交易,質押權重並不適用於此階段的優先排序。為此,Compute Budget 程序新增了一條指令,允許用戶指定在交易執行和區塊包含時收取的額外費用。交易的執行優先級取決於“費用與計算單位的比率”,從而實現更具動態性和市場驅動的交易排序方式。

Candy Machine 機器人稅

Metaplex 迅速在 Candy Machine 程序的鑄造交易中引入了 0.01 SOL 的硬編碼機器人稅,以打擊由機器人驅動的垃圾交易。這一反垃圾機制通過收取最低費用來阻止惡意活動,同時不會懲罰因操作失誤而產生的正常用戶。該稅收適用於以下特定情況:

  • 嘗試在 Candy Machine 尚未開放時進行鑄造
  • 嘗試在庫存為空時進行鑄造
  • 交易中鑄造或設置集合指令未作為最終指令
  • 使用了錯誤的集合 ID
  • 設置集合指令不匹配
  • 集合設置與鑄造指令之間的簽名者支付者不匹配
  • 涉及禁止程序的可疑交易
  • 嘗試從受 AllowList 保護的 Candy Machine 進行鑄造,但未持有所需的 AllowList 代幣

這一經濟性威懾措施非常有效。Mint 機器人迅速被耗盡,垃圾交易活動停止。在最初幾天內,機器人操作者共損失超過 426 SOL。

Durable Nonce 錯誤:2022年6月

停機時間:四個半小時

根本原因:Durable nonce 錯誤導致共識失敗

修復措施:

  • 暫時禁用 durable nonce 交易
  • Solana 1.10.23 更新

一個運行時錯誤導致某些 durable nonce 交易被處理了兩次——一次作為常規交易,另一次作為 nonce 交易——如果它們在 recent_blockhash 字段中使用的是最近的區塊哈希,而不是 durable nonce。這導致驗證者之間出現非確定性行為,因為有些節點拒絕了第二次執行,而其他節點接受了它。關鍵的是,由於超過三分之一的驗證者接受了該區塊,它阻止了所需的三分之二多數達成共識。

與標準交易不同,durable nonce 交易不會過期,需要一個獨特的機制來防止雙重執行。它們是串行處理的,使用與每個賬戶綁定的鏈上 nonce 值,每次處理 durable nonce 交易時都會旋轉。一旦旋轉,相同的 nonce 交易不應再次有效。

為了解決這一問題,durable nonce 交易被暫時禁用。之後,Solana 1.10.23 更新實施了修復,防止了重複執行,通過將 nonce 和區塊哈希域分開來解決此問題。該更新確保在推進 nonce 賬戶時,區塊哈希與固定字符串一起進行哈希,使得區塊哈希不能作為 nonce 值。因此,作為常規交易執行的交易不能作為 durable 交易重新執行,反之亦然。此外,新的 DurableNonce 類型替代了 nonce 賬戶狀態中的先前區塊哈希值,增加了類型安全性,並防止了類似問題的發生。

閱讀我們之前的 Helius 博客文章,瞭解更多關於 durable nonce 的內容及其用途。

重複區塊錯誤:2022年9月

停機時間:八個半小時

根本原因:分叉選擇規則中的錯誤導致共識失敗

修復措施:

  • 客戶端補丁

此次故障是由於某個驗證者錯誤地在相同區塊高度生成了重複區塊。原因是該驗證者的主節點和備用節點同時激活,使用相同的節點身份但提議了不同的區塊。這種情況持續了至少24小時,在此期間,網絡能夠正確處理驗證者的重複領導者槽位。

當網絡因分叉選擇邏輯中的錯誤而遇到不可恢復的分叉時,集群最終停止運行。此錯誤導致區塊生產者無法在前一個區塊的基礎上構建,從而導致共識失敗。

在 Solana 網絡中,分叉是常見現象,驗證者通常通過選擇獲得大多數投票的分叉(即最重分叉)來解決分叉問題。當驗證者選擇了錯誤的分叉時,它必須切換到最重分叉以與網絡保持同步。然而,在此次事件中,如果驗證者的最後投票槽位與最重銀行的槽位一致,則無法恢復到最重銀行。此缺陷導致驗證者陷入死循環,阻止了共識的推進,並最終導致網絡停機。

重複區塊錯誤導致的分叉選擇,2022年9月(來源:Laine,Michael Hubbard)

在上述示例中,故障驗證者 C 在其領導槽位 5 至 8 生成了重複區塊。當驗證者 G 接任為下一個領導者時,它僅觀察到其中一個重複區塊,並相應地擴展其分叉。然而,接下來的領導者驗證者 D 檢測到來自驗證者 C 的兩個重複區塊,並決定將其丟棄,而是在槽位 4 之上構建自己的分叉。

隨著網絡運行,驗證者 G 構建的分叉獲得了大多數質押的投票,確立了其作為規範鏈的地位。由於意識到自己的分叉正在失敗,驗證者 D 嘗試切換到驗證者 G 的分叉。然而,由於分叉選擇邏輯中的錯誤,該切換未能成功。問題的根源在於兩個分叉的共同祖先——槽位 5 的重複區塊——未被正確處理,導致驗證者 D 無法識別大多數分叉。結果,驗證者 D 被困在自己的分叉上,無法重新加入主鏈。

該問題在核心團隊的審查後得到解決。修復補丁已合併至主分支,並回溯應用於所有發佈分支。

大型區塊導致 Turbine 超載,2023年2月

停機時間:近19小時

根本原因:分片轉發服務中的去重邏輯失效

修復措施:

  • 改進 Turbine 的去重邏輯與過濾機制
  • 添加客戶端補丁,強制區塊生產者在生成大區塊時中止

某驗證者的自定義分片轉發服務發生故障,在其領導槽位期間傳輸了一個異常龐大的區塊(接近15萬片分片),其規模遠超標準區塊。這導致驗證者的去重過濾器超載,數據被持續重複轉發。隨著新區塊不斷生成,問題進一步加劇,最終導致協議飽和。

大型區塊故障,每個區塊的分片數量,2023年2月(來源:Laine,Michael Hubbard)

異常的網絡流量激增導致 Turbine 超載,被迫通過速度明顯較慢的備用 Block Repair 協議傳輸區塊數據。儘管 Turbine 設計用於通過過濾大區塊來承受其影響,但分片轉發服務位於此過濾邏輯的上游,削弱了其效果。在性能受損期間,區塊領導者自動切換至僅投票模式,這是一種安全機制,要求領導者排除經濟類的非投票交易。

問題的根本原因是分片轉發服務中的去重邏輯失效,未能阻止分片的冗餘重傳。此外,重傳流水線中的去重過濾器最初並未設計用於防止 Turbine 樹內部的循環,進一步加劇了問題。

網絡通過手動重啟並降級至最後已知的穩定驗證者軟件版本恢復運行。為解決這些問題,Solana v1.13.7 和 v1.14.17 引入了去重邏輯增強,提升了防止過濾器飽和的能力,從而確保網絡性能更加穩健。

無限重新編譯循環,2024年2月

停機時間:近 5 小時

根本原因:JIT 緩存中的錯誤導致無限重新編譯循環

修復措施:

  • 禁用傳統加載器 v1.17.20

Agave 驗證者在執行引用程序的交易前,會對所有程序進行即時編譯 (JIT)。為了優化性能,JIT 會將常用程序的輸出緩存,減少不必要的重複編譯。作為 Agave v1.16 的一部分,原有的 LoadedPrograms 緩存機制被替換為新的 ExecutorsCache,實現了多項效率提升。

LoadedPrograms 提供了一個全局、支持分叉的程序緩存視圖,減少了賬務數據的重複,並允許交易執行線程協同加載新程序,防止編譯衝突。其關鍵功能是跟蹤程序生效的插槽高度(即有效插槽高度),以便在鏈上程序數據更新時檢測緩存失效。

大多數程序的有效插槽高度來自其部署插槽,並存儲在鏈上賬戶中。然而,使用傳統加載器部署的程序未在其賬戶中保留部署插槽。為此,LoadedPrograms 將這些程序的有效插槽高度設置為零。

當檢測到部署指令,表明程序字節碼已被替換時,會觸發一個例外情況。此時,LoadedPrograms 會臨時插入一個具有正確有效插槽高度的條目。然而,由於交易從未引用過此條目,導致其很容易被驅逐。當條目被驅逐時,JIT 輸出被丟棄,程序被標記為卸載,但有效插槽高度仍被保留。

如果隨後有交易引用此已卸載程序,LoadedPrograms 會重新編譯它並在其有效插槽高度下重新插入條目。通常,這會使程序在下次迭代時可供執行。然而,對於傳統加載器程序,新的 JIT 輸出會被分配為零這一哨兵插槽高度,導致其排列在先前已卸載條目的後面。結果是,LoadedPrograms 無法識別該程序已被加載,從而在每次迭代時觸發持續的重新編譯循環。

在 Agave v1.16 中,LoadedPrograms 不支持協作加載,因此觸發交易會被打包到一個區塊中。此區塊隨後在整個網絡上傳播,導致所有驗證者重放該區塊並陷入相同的無限重新編譯循環。由於在故障期間,超過 95% 的網絡質押節點運行的是 Agave v1.17,大多數驗證者在此區塊上陷入停滯,導致網絡中斷。

該錯誤在前一週的一次 Devnet 集群故障調查中已被發現,並計劃進行修復。@jeff.washington/2024-02-06-solana-mainnet-beta-outage-report-619bd75b3ce0”>最終的緩解措施是將更改回溯至 Agave v1.17,並在網絡重啟時立即移除功能門控,從而禁用導致該錯誤的傳統加載器,防止問題再次發生。

協調漏洞補丁,2024年8月

停機時間:無

根本問題:ELF 地址對齊假設不正確

修復:

  • 補丁更新

8 月 5 日,Anza 核心工程師收到一名外部研究人員報告的 Agave 客戶端漏洞。攻擊者可能利用此漏洞導致領導驗證者崩潰,從而引發全網停機。對此,Anza 工程師迅速開發了補丁,並經多家第三方安全公司審計。

Solana 程序使用 LLVM 編譯為可執行與可鏈接格式 (ELF)。漏洞源於這些 ELF 文件中地址對齊假設的錯誤。儘管 ELF 檢查通常會強制執行各種完整性驗證,但未對 .text 段的對齊進行驗證。這一疏忽可能允許惡意構造的 ELF 文件定義錯位的 .text 段,導致虛擬機跳轉至無效地址,從而引發主機段錯誤並使驗證者崩潰。

攻擊者可通過以下方式利用該漏洞:

  • 創建使用 CALL_REG 操作碼的惡意 Solana 程序。
  • 操縱 ELF 文件使其 .text 段錯位。
  • 將程序部署並調用於網絡上,從而觸發驗證者崩潰。

補丁更新流程

任何公開發布的補丁更新都會立即暴露漏洞,從而可能讓攻擊者有時間對漏洞進行逆向工程,並在足夠數量的驗證者完成升級之前導致網絡停機。為了避免這種情況,必須儘快讓大多數驗證者採用補丁版本。

截至 8 月 7 日,Solana 基金會的多名成員已通過各種通信平臺的私信聯繫驗證者,告知即將發佈的重要補丁,並分享了一條經過哈希處理的信息,以確認事件的日期和唯一標識符。Anza、Jito 和 Solana 基金會的多位知名成員隨後在 X、GitHub 和 LinkedIn 上發佈了此哈希值,以驗證信息的準確性。示例哈希值共享如下:

在接下來的一天裡,核心成員繼續聯繫驗證者,強調緊迫性和保密性的重要性。按照預定時間,即 8 月 8 日 14:00 UTC,驗證者運營商收到了進一步的通知,包含了下載、驗證和應用補丁的指令。該補丁託管在一位知名 Anza 工程師的 GitHub 倉庫中,而非主 Agave 倉庫。指令中還包括了將下載的補丁文件與提供的 shasum 哈希值進行驗證的要求。

截至 8 月 8 日 20:00 UTC,持有超級多數權益的驗證者已完成補丁更新,確保了網絡安全。隨後,漏洞及其相關補丁被公開披露,並呼籲所有剩餘驗證者儘快進行升級。

此次補丁的私下分發以及驗證者之間的幕後協調引發了關於 Solana 去中心化性質的擔憂。事件發生後不久,Solana 基金會執行董事 Dan Albert 在一次媒體採訪中迴應了這些批評。

“我認為不能將協調能力與中心化混為一談。全球有大約 1,500 個區塊生產節點,由幾乎同樣多的個人運營……能夠與他們,或部分驗證者,自願地進行溝通,並不等同於中心化。”

2024 年韓國區塊鏈周 (KBW)

“我認為不能將協調能力與中心化混為一談。全球有大約 1,500 個區塊生產節點,由幾乎同樣多的個人運營……能夠與他們,或部分驗證者,自願地進行溝通,並不等同於中心化。”

結論

截至目前,Solana 已經超過一年沒有發生停機事件,達成了移除“beta”標籤並正式從 mainnet-beta 中移除的重要里程碑。隨著網絡的成熟,停機事件的頻率似乎有所下降,而 Firedancer 的引入預計將提升客戶端多樣性,減少尚未發現的漏洞或邊緣情況導致整個集群停機的風險。然而,包括 Helius 創始人 Mert Mumtaz 在內的一些社區領袖預測,停機事件仍將繼續發生,時間將證明一切。

感謝 Zantetsu(Shinobi Systems)和 OxIchigo 對本文早期版本的審閱。

聲明:

  1. 本文轉載自[Helius]。所有版權歸原作者所有[Lostin]。若對本次轉載有異議,請聯繫 Gate Learn 團隊,他們會及時處理。
  2. 免責聲明:本文所表達的觀點和意見僅代表作者個人觀點,不構成任何投資建議。
  3. Gate Learn 團隊將文章翻譯成其他語言。除非另有說明,否則禁止複製、分發或抄襲翻譯文章。
即刻開始交易
註冊並交易即可獲得
$100
和價值
$5500
理財體驗金獎勵!