ビープ、ビープ、ビープ。ビープ、ビープ、ビープ。
スティーブンの眠りは、厳しい携帯の音で崩れ、彼を夢から突然引きずり出す。暗闇の中、画面が明るく光り、ベッドサイドテーブルで激しく振動する。ビープ、ビープ、ビープ。彼はうめき声をあげ、ぼんやりと目をこすり、デバイスに手を伸ばす。メッセージを見て、彼の心は沈む―ノードがダウンしている。ためらうことなく、彼はベッドから飛び出し、半分服を着たまま、電話のロックを解除しようと手探りすると、さらにメッセージが殺到する。そして彼に気付かされる―クラスタ全体がダウンしている。
まさにこの瞬間、世界中の都市やタイムゾーンに散らばった場所で、何百人ものノードオペレーターが、恐怖の瞬間が到来したという同じ認識を持って携帯電話を見つめています。
ソラナは、すべての分散システムと同様に、単一の実装の欠陥や曖昧なエッジケースがネットワーク全体の障害につながる可能性があるという現実の下で運営されています。障害は、破壊的である一方、複雑な分散インフラを維持する過程で避けられない部分です。これは、分散型ブロックチェーン、中央集権取引所、またはAmazonやMicrosoftなどの主要なクラウドサービスプロバイダーでも同様です。
問題は、障害が発生するかどうかではなく、いつ、そしてネットワークがどのように進化し、将来のインシデントに適応し、強化するかです。厳密なシミュレーションテスト、インセンティブ付きのテストネット、アクティブなバグバウンティプログラムにもかかわらず、どんなに適切に設計されていても、考えられるすべての障害モードを予測できるシステムはありません。最も貴重な教訓は、実際の運用から得られます。
過去5年間、Solanaは7つの別々の障害事象を経験しました。そのうち5つはクライアントのバグによるもので、2つはネットワークが取引スパムの洪水に対処できなかったことが原因でした。初期のSolanaバージョンには、後にネットワークストレスの緩和に欠かせない優先手数料やローカル手数料市場などの重要な過積載管理メカニズムが欠けていました。そのようなメカニズムの欠如は、基本的にスパムをインセンティブとして利用したことにより、2022年全体を通じて低下したパフォーマンスと混雑が継続することにつながりました。
Solanaの停止とパフォーマンス低下の過去の事例
この記事では、各Solanaの障害について詳しく分析し、その原因、トリガーとなるイベント、および解決策について検討します。さらに、ネットワークの再起動、バグレポート、ライブネスとセーフティの基本的な概念についても議論します。これらのセクションは順番に読むのがベストですが、それぞれが単独で成立しており、読者が最も興味を持つトピックや障害事象に飛ぶことができるように設計されています。
CAP定理(Brewerの定理とも呼ばれる)によれば、分散システムは、3つの特性のうち2つしか達成できません:
ブロックチェーンにとって、分割耐性は不可欠です。ネットワークの断続は避けられません。これにより、AP(可用性 + 分割耐性)とCP(整合性 + 分割耐性)の選択を迫られます。ほとんどの高速確定PoSチェーンと同様に、Solanaは可用性よりも整合性を優先し、CPシステムとなっています。致命的な障害が発生すると、古いデータを提供するか、安全でない書き込みを許可するのではなく、システムを停止させます。これにより、ノードソフトウェアが手動での介入を必要とする回復不能な状態に入る可能性がありますが、ユーザー資金の安全性を確保します。
CAP定理のトレードオフ内でのSolanaの位置
Liveness Failure: ブロックチェーンが進行を停止し、バリデータのダウンタイム、ネットワークの分割、またはコンセンサスの停滞によってトランザクションの確認およびブロックの生成が阻害される場合に発生します。CAP定理の文脈では、これは可用性の損失に対応します。
セーフティフェイル:ブロックチェーンの確定状態が不適切に変更またはフォークされたときに発生します。これにより、しばしばコンセンサスのバグや悪意のある攻撃によって引き起こされる、相反する履歴や二重支出が生じる可能性があります。CAP定理の文脈では、これは一貫性の喪失に対応します。
Solanaは生存よりも安全を優先します。そのため、極端なネットワークストレスや合意の失敗の場合、ネットワークは停止しますが、状態の破損のリスクを冒すことはありません。停止は中断を引き起こす可能性があり、アプリケーション、ユーザー、および検証者に影響を与えるかもしれませんが、不整合または破損した元帳の致命的な結果よりも望ましいです。
Solanaネットワークを再起動するには、最後に楽観的に確認されたブロックスロットを特定し、そのスロットの信頼できるローカル状態のスナップショットからノードを再起動する必要があります。再起動スロットはオンチェーンで決定されないため、バリデーターのオペレーターは、安全なロールバックポイントに同意するためにオフチェーンのコンセンサスに達する必要があります。この調整は、Solana Tech Discordの #mb-validatorsチャンネルで公開され、プロのバリデーターオペレーターがリアルタイムでコミュニケーションを取ります。ほとんどのオペレーターは、ブロック生産が停止した瞬間に通知する自動アラートシステムを使用しており、迅速な対応を保証します。
正しい再起動スロットについてコンセンサスが得られたら、オペレーターは台帳ツールを使用して新しいローカルスナップショットを生成し、バリデーターを再起動し、総ステークの少なくとも80%がオンラインに戻るのを待ちます。そうして初めて、ネットワークはブロックの生成と検証を再開します。クラスターの再起動時に最大 20% のオフライン ステークがあることを確認することで、再起動直後にノードがフォークしたりオフラインに戻ったりした場合に、オンラインを維持するための十分な安全マージンを確保できます。
バグ報奨金プログラムは、ソフトウェアの脆弱性を特定して報告したセキュリティ研究者に報酬を与えます。これは、積極的にインセンティブを与えるため、重要な防衛線です悪用される前にバグを捕捉する.Agaveクライアントの潜在的な脆弱性を特定したセキュリティ研究者や開発者は、適切なセキュリティチャネルを通じて報告することをお勧めします。詳細な開示ガイドラインは、Agave GitHubリポジトリにあります.
重大な脆弱性の有効な報告に対して報酬が提供され、支払いは深刻度に基づいています:
かつFireDancerクライアントには独自のバグバウンティプログラムがありますImmunefiを通じてホストされ、重要な調査結果に対して最大500,000USDCの報酬を提供します。
以下のセクションでは、2020年3月16日にMainnet Betaを立ち上げから始まり、ソラナの障害と性能低下期間について詳細で年代順の分析を提供します。この調査は、主要なインシデント、その原因、およびネットワークのその後の改善を強調し、ソラナが時間とともに安定性と耐久性を向上させるためにどのように進化したかについての洞察を提供します。
ダウンタイム:約6時間
ルートの問題: ブロック伝播バグ
修正:
この停止はによって引き起こされました以前に知られていたブロック修復およびコード処理の問題の未確認のバグによってトリガーされますタービン、ソラナのブロック伝播メカニズム. バリデータが同じスロットの2つの異なるブロックを送信し、それらを2つの異なるパーティション(AとB)に伝播させたときに障害が発生しましたが、第三のパーティションは独自に矛盾を検出しました。
各パーティションが少数派の持分しか保持していなかったため、どれも超過半数のコンセンサスを達成することができず、チェーンを進展させることができませんでした。根本的な問題は、Solanaの内部データ構造がブロックとそれらの計算された状態を追跡する方法に由来しています。システムは、履歴の証明(PoH)スロット番号(u64識別子)を使用して状態を参照し、そのスロットのブロックを参照していました。ネットワークがパーティションに分割されると、ノードはブロックAとBを同一と誤解し、適切な修復とブロックの同期を阻害しました。
各パーティションは、他方が同じブロックを持っていると想定し、基本的な衝突が発生しました:
パーティション間の状態遷移が異なるため、バリデーターはフォークを修復または調整することができず、最終性を防いでいました。
この問題の解決策は、ハッシュではなくスロット番号でブロックを追跡するサービスを許可する同じスロットの任意の数のブロックが分割を作成した場合、それらは異なるスロットを占有するブロックと同じように扱われます。ノードはすべての可能なフォークを修復でき、コンセンサスは分割を解決することができます。
バグが停止の最初の原因でしたが、Solanaがブロック生成を再開するには少なくとも80%のステーク参加が必要なため、ダウンタイムのほとんどは、十分なステークウェイトがオンラインに戻るのを待ったことに起因しています。
ダウンタイム:十七時間
ルート問題:ボット取引によるメモリオーバーフロー
修正:
2021年9月14日、Solanaは、グレーププロトコルがクラウドファンディングプラットフォームRaydium AcceleRaytorでのオンチェーン初のDEXオファリング(IDO)の開始に続いて、大規模なネットワークの停止を経験しました。IDOの12分以内に、ネットワークは前例のないボットによる取引の洪水に圧倒され、ルーテッドスロットの生成を停止しました。これらのボットは、分散型サービス拒否(DDoS)攻撃を効果的に実行し、ネットワークの容量を超える取引負荷を押し付けました。
ピーク時の混雑時:
2021年9月14日のGrape IDOの障害中のSolanaスロット数(データソース:Jump Crypto)
ボットの1つは、グローバルSPLトークンプログラムや今は亡きSerum DEXプログラムを含む18の主要アカウントを書き込みロックするようにトランザクションを構築しました。これにより、これらのアカウントとやり取りするすべてのトランザクションがブロックされ、Solanaの並列処理能力が大幅に低下しました。トランザクションを独立して実行する代わりに、ネットワークがボトルネックになり、トランザクションを順番に処理し、輻輳を悪化させました。
プログラムの書き込みロックを無視する修正プログラムが既に開発され、リリースが予定されています。その後、ネットワークを再起動すると、このアップグレードが有効になり、この攻撃ベクトルが完全に削除されました。
IDOイベント中、バリデーターはボット主導のトランザクションを大量に受け取り、過剰なトランザクションを次のリーダーに転送し、混雑を増幅させました。ネットワークの再起動により、トランザクション転送にレート制限が導入され、将来のトランザクションの嵐がリーダーを圧倒するのを防ぎます。
ソラナのRPCノードは、失敗したトランザクションを自動的に再試行します。これは信頼性を向上させるための機能です。しかし、この再試行機構は極端な混雑状態下でトランザクションの洪水を悪化させ、ネットワークが回復する代わりに古いトランザクションを循環させていました。Solana 1.8では、設定可能なRPC再試行動作が導入され、アプリケーションが短い有効期限時間や指数バックオフ戦略で再試行を最適化できるようになりました。
過度の混雑の中、Solanaのリーダーたちはコンセンサスを維持するために重要な投票トランザクションを含めることに失敗しました。その結果、確認されていない投票の欠如がコンセンサスの停滞につながり、新しいルートブロックの生成が停止しました。後のSolanaクライアントのバージョンでは、投票トランザクションを優先するメカニズムが導入され、将来のイベントで通常のトランザクションに埋もれることなく防止されました。
ネットワークの再起動中に、2 つ目の問題が発生しました。バリデーターは、アクティブなステーク量が激しく変動していることを報告しました。この問題は、賭け金の割合が誤って100倍され、可能な最大値を超えてしまうバグに起因していました。インフレーションメカニズムは、非常に多くの新しいSOLトークンを作成したため、64ビットの符号なし整数がオーバーフローしました。このバグはすぐに特定され、2回目の再起動前にパッチが適用されました。
ダウンタイム:なし
原因: 過剰な重複取引
一部修正:
2022年1月6日から1月12日の間、Solanaメインネットは深刻なネットワーク混雑を経験し、パフォーマンスが低下し、一部の停止が発生しました。この混乱は、ボットが過剰な重複取引をスパムし、ネットワーク容量を大幅に減少させたことにより引き起こされました。ブロックの処理に予想以上の時間がかかり、次のリーダーがフォークしてスループットをさらに低下させることがありました。ピーク時には、取引の成功率が最大で70%まで低下しました。クライアントは、ネットワークのますます複雑で高い計算取引を処理するのに苦労し、需要に対応する能力の限界が露呈しました。
1月21日から23日にかけて追加の不安定性が発生し、混雑が続いていました。1月22日には、公共のRPCエンドポイント(https://api.mainnet-beta.solana.com) went offline due to abuse, as spammed batched RPC calls overwhelmed the system.
これらの問題に対処するために、Solana 1.8.12リリースは特にプログラムキャッシュの枯渇を対象としています、 一方でバージョン1.8.14では、Sysvarキャッシュ、SigVerify破棄、およびSigVerify重複の改善が導入されました.
ダウンタイム:8時間
ルートの問題: ボットアカウントからのトランザクションスパム
修正:
2022年4月30日、Solanaは前例のないトランザクションリクエストの急増を経験しました。一部のノードは、ノードあたり秒間600万リクエストに達し、トラフィックはノードあたり100 Gbpsを生成しました。この急増は、Metaplex Candy Machineプログラムを通じて新しく発行されたNFTを確保しようとするボットによって引き起こされました。このミンティングメカニズムは、先着順で動作し、ネットワークにトランザクションを殺到させ、ミントを獲得する強力な経済的インセンティブを生み出しました。
2022年4月30日/5月1日、キャンディーマシンの停止、パケット毎秒のイングレス(データソース:Jump Crypto)
取引量が急増するにつれ、バリデーターはメモリーを使い果たし、最終的にコンセンサスが停滞しました。不十分な投票スループットにより、以前のブロックの最終化が阻害され、放棄されたフォークのクリーンアップが妨げられました。その結果、バリデーターは評価するフォークの数が多過ぎて圧倒され、再起動後でも容量を超過し、ネットワークを復旧するために手動で介入する必要がありました。
この障害は2021年9月のインシデントと類似点を持っていましたが、ソラナは向上した耐久性を示しました。前回の障害よりも取引リクエストが10,000%増加しましたが、ネットワークははるかに長い間運用され続け、検証者コミュニティが以前のスケーリングの課題に対応して行った改善を反映しています。
2022年4月30日/5月1日、キャンディーマシンの停止、アクティブなバリデーター(データソース:Jump Crypto)
正規スナップショットが合意された後、ネットワークの再起動は1.5時間未満で完了しました。Solana v1.10には、ノードが遅いまたは停滞したコンセンサスに耐える時間を延ばすためのメモリ使用の改善が含まれています。
しかし、根本的な問題は未解決のままでした。リーダーは引き続き、効果的なスパム防止を行わずに同じアカウントデータを競合して処理し、ユーザーは自分の取引の緊急性を優先することができませんでした。この問題を解決するために、3つの長期的なメカニズムが実用的な解決策として提案されました。
QUICの採用: 以前、Solanaは、Gulf Streamを介してRPCノードから現在のリーダーへトランザクションを送信するためにUDP(User Datagram Protocol)ネットワーキングプロトコルに依存していました。速く効率的ですが、UDPは接続がなく、フロー制御や受信確認が不足しています。したがって、悪用行為を防止したり緩和する有効な方法がありません。ネットワークトラフィックを制御するために、検証者のトランザクション取り込みプロトコル(つまり、TPUのFetchステージ)はQUICで再実装されました。
QUICはTCPとUDPの両方の利点を提供しようとします。これにより、UDPと同様の高速非同期通信が可能になりますが、TCPのセキュアセッションと高度なフローコントロール戦略も利用できます。これにより、個々のトラフィックソースに制限を設けることができ、ネットワークは本物のトランザクションの処理に集中できます。QUICには、個々のトランザクションがドロップされても、残りのトランザクションをブロックしないという概念もあります。QUICは最終的に、Solana Labsのクライアントに1.13.4リリースで統合されました。
ステークウェイト付きサービス品質(SWQoS): バリデータが保有するステークに基づいてネットワークトラフィックの優先順位を付ける新しいシステムが導入され、より高いステークを持つ者がより効率的にトランザクションを送信できるようになりました。このメカニズムでは、合計ステークの3%を持つバリデータはリーダーに合計パケットの3%まで送信できます。SWQoSはシビル抵抗対策として機能し、低品質のトランザクションでネットワークを氾濫させる悪意のある行為者にとってより困難になります。このアプローチは、以前の先着順モデルを置き換えています。このモデルは、ソースを考慮せずにトランザクションを無差別に受け入れていました。
優先手数料の紹介:トランザクションが取り込まれると、それらは引き続き共有口座データへのアクセスを競い合います。以前は、この競合は単純な先着順で解決され、ユーザーはトランザクションの緊急性を示す方法がありませんでした。誰でもトランザクションを送信できるため、ステークウェイトはこの段階で優先順位付けには適していません。これを解決するために、Compute Budgetプログラムに新しい命令が追加され、実行とブロックの含まれる追加料金を指定することができるようになりました。料金と計算単位の比率は、トランザクションの実行優先度を決定し、取引の注文に対するより動的で市場主導のアプローチを確実にします。
Metaplexは、ミント取引に0.01 SOLのボット税を迅速に導入しましたbot-driven spamと戦うためにCandy Machineプログラムとやり取りしています。このスパム対策メカニズムは、意図しない間違いをした正当なユーザーを罰することなく、悪意のある活動を阻止するために最小料金を課しました。この税金は、特定のシナリオで適用されました。
この経済的な抑止力は非常に効果的であることが証明されました。ミント・スナイパーはすぐに枯渇し、スパム活動も止まりました。最初の数日で、ボッターたちは合わせて426 SOL以上の損失を被りました。
ダウンタイム:4時間半
ルートの問題: コンセンサスの失敗につながる耐久性のあるナンスのバグ
修正:
ランタイムバグにより、特定の耐久性のあるナンストランザクションが、最近のブロックハッシュの代わりに耐久性のあるナンスを使用した場合、通常のトランザクションとして1回、再度ナンストランザクションとして2回処理されることがありました。 これにより、一部のノードが2回目の実行を拒否する一方、他のノードがそれを受け入れるという非決定論的な動作が生じました。 重要なのは、バリデーターの3分の1以上がブロックを受け入れたため、必要な2分の1の多数決に到達することが阻まれました。
標準トランザクションとは異なり、永続ノンストランザクションは期限切れにならず、二重実行を防ぐために独自のメカニズムが必要です。これらは、各アカウントに関連付けられたオンチェーンのノンス値を使用して逐次処理され、永続的なノンストランザクションが処理されるたびにローテーションされます。いったんローテーションすると、同じ nonce トランザクションが再び有効になることはありません。
問題を軽減するために、耐久性のあるノンス取引が一時的に無効にされました。修正は後にSolana 1.10.23で実装されましたこれにより、ノンスとブロックハッシュのドメインを分離することで、重複した実行を防止しました。このアップデートにより、ノンスアカウントを進める際にブロックハッシュが固定された文字列でハッシュ化されるため、ブロックハッシュはノンス値として無効になります。その結果、通常のトランザクションとして1度実行された取引を、耐久性のあるトランザクションとして再実行したり、その逆も行ったりすることはできません。さらに、新しいDurableNonceタイプが、将来の類似した問題を防ぐために、ノンスアカウントの状態で以前のブロックハッシュ値を置き換えました。
以前のHeliusブログ記事を読んでください耐久性のあるナンスとその用途についてもっと理解する.
ダウンタイム:8時間半
ルートの問題:フォーク選択ルールのバグがコンセンサスの失敗につながりました
修正:
この停止は、バリデータが同じブロック高さで誤って重複ブロックを生成したことによって引き起こされました。これは、バリデータのプライマリノードとフォールバックスペアノードの両方が同時にアクティブになり、同じノードIDを使用して異なるブロックを提案したために発生しました。この状況は、停止の前に少なくとも24時間持続しました。その間、ネットワークはバリデータの重複したリーダースロットを正しく処理しました。
ネットワークがフォーク選択ロジックのバグによって回復不能なフォークに遭遇したとき、クラスターは最終的に停止しました。このバグにより、ブロックプロデューサーは前のブロック上での構築を妨げられ、コンセンサスの失敗につながりました。
ソラナでは、フォークは日常的に発生し、通常、バリデータは投票の過半数に合わせてフォークを解決します(最も重いフォーク)。 バリデータが間違ったフォークを選択した場合、ネットワークと同期するために最も重いフォークに切り替える必要があります。 ただし、この場合、バリデータは、スロットが最後に投票されたスロットと一致した場合、最も重いブロックに戻ることができませんでした。 この欠陥により、バリデータは立ち往生し続け、コンセンサスが進展せず、最終的にネットワークが停止することにつながりました。
重複ブロックバグの停止と分岐選択、2022年9月(出典:Laine、Michael Hubbard)
上記の例では、不良バリデータCは、リーダースロット5から8の間に重複したブロックを生成します。次のリーダーであるバリデータGが引き継ぐと、重複のうち1つしか検知せず、その分岐を拡張します。しかし、続くリーダーであるバリデータDは、バリデータCからの両方の重複ブロックを検知し、それらを破棄して代わりにスロット4の上にその分岐を構築することを決定します。
ネットワークが進展するにつれ、バリデーターGによって構築されたフォークが大部分のステークからの票を獲得し、正準チェーンとして確立されます。自分のフォークが負けていることに気づいたバリデーターDは、バリデーターGのフォークに切り替えようと試みます。しかし、フォーク選択ロジックのバグにより、この移行は失敗に終わります。この問題は、2つのフォークの共通の祖先であるスロット5の重複ブロックが正しく処理されなかったために発生し、バリデーターDが過半数のフォークを認識できなくなりました。その結果、バリデーターDは自分のフォークで立ち往生し、メインチェーンに戻ることができません。
この問題は、コア チームによるレビュー後に解決されました。パッチがマスターブランチにマージされ、すべてのリリースブランチにバックポートされました.
ダウンタイム:ほぼ19時間
ルートの問題: シュレッド転送サービスにおける重複排除ロジックの失敗
修正:
バリデーターのカスタムシュレッド転送サービスが誤作動し、標準ブロックよりも桁違いに大きなブロック(ほぼ150,000シュレッド)をリーダースロット中に送信しました。これにより、バリデーターデデュプリケーションフィルターが過負荷となり、データが連続して再転送されることになりました。新しいブロックが生成されるたびに問題が複合し、ついにプロトコルが飽和状態になりました。
大規模なブロックの停止、ブロックあたりの細断数、2023 年 2 月(出典: レイン、マイケル・ハバード)
異常なネットワークトラフィックの急増により、タービンは圧倒され、ブロックデータを大幅に遅いフォールバックブロック修復プロトコルを介して送信することを余儀なくされました。タービンは大きなブロックを除外することで耐えるように設計されていますが、このフィルタリングロジックの上流にはシュレッド転送サービスがあり、その効果が低下しています。劣化期間中、ブロックリーダーは自動的に投票のみモードに切り替わり、経済的な非投票取引を除外する安全装置となりました。
問題の根本原因は、シュレッド転送サービス内の重複排除ロジックの障害であり、シュレッドの冗長な再送信を防いでいました。さらに、再送信パイプライン内の重複排除フィルタは元々、タービンツリー内でのループを防ぐように設計されていなかったため、問題が悪化しました。
ネットワークは、最後に確認された安定したバリデータソフトウェアバージョンにダウングレードして、手動で再起動されました。これらの問題を緩和するために、Solana v1.13.7 と v1.14.17 では、重複排除ロジックが強化されましたこれにより、フィルターの飽和を防ぐ能力が向上し、より堅牢なネットワークパフォーマンスが保証されます。
ダウンタイム:ほぼ5時間
ルートの問題: JITキャッシュで無限の再コンパイルループを引き起こすバグ
修正:
Agave バリデーターのジャストインタイム (JIT) は、すべてのプログラムを参照するトランザクションを実行する前にコンパイルします。パフォーマンスを最適化するために、頻繁に使用されるプログラムのJIT出力がキャッシュされ、不要な再コンパイルが削減されます。Agave v1.16の一部として、既存のキャッシュメカニズムであるLoadedProgramsは、ExecutorsCacheと呼ばれる新しい実装に置き換えられ、いくつかの効率性が導入されました。
LoadedProgramsは、キャッシュされたプログラムのグローバルでフォークを認識したビューを提供し、会計データの重複を減らし、トランザクション実行スレッドが新しいプログラムを協調的に読み込むことで、コンパイルの競合を防ぎました。このシステムの特徴の1つは、プログラムがアクティブになるスロットを追跡すること(有効スロット高さとして知られる)であり、オンチェーンのプログラムデータが更新されるときにキャッシュの無効化を検出することでした。
ほとんどのプログラムの有効スロットの高さは、オンチェーンアカウントに保存されているデプロイスロットから導き出されました。ただし、レガシーローダーを使用してデプロイされたプログラムは、このデプロイスロットをアカウントに保持しませんでした。LoadedPrograms は、回避策として、これらのプログラムに有効なスロットの高さ 0 を割り当てました。
デプロイ命令が検出されたときに例外が発生し、プログラムのバイトコードが置き換えられたことが通知されました。この場合、LoadedPrograms は、正しい有効スロット高さのエントリを一時的に挿入します。ただし、トランザクションはこのエントリを参照しないため、削除の影響を非常に受けやすくなっていました。削除されると、JIT 出力は破棄され、プログラムはアンロードのマークが付けられましたが、有効なスロットの高さは保持されました。
もし取引が後でこのロードされていないプログラムを参照した場合、LoadedProgramsはそれを再コンパイルして、その有効なスロットの高さにエントリを再挿入しました。通常、これにより、プログラムは次の反復で実行可能になります。ただし、旧バージョンのローダープログラムの場合、新しいJIT出力にはセンチネルスロットの高さであるゼロが割り当てられ、それにより以前のロードされていないエントリの後ろに配置されました。その結果、LoadedProgramsはプログラムをロードされたと認識せず、反復ごとに連続的な再コンパイルループがトリガーされました。
Agave v1.16では、LoadedProgramsは協力的なローディングをサポートしておらず、トリガーとなるトランザクションがブロックにパックされることを許可していました。このブロックはその後ネットワーク全体に伝播され、すべての検証ノードがそれを再生して同じ無限の再コンパイルループに入りました。停止期間中、クラスタのステークの95%以上がAgave v1.17を実行していたため、ほとんどの検証ノードがこのブロックで停止し、ネットワークが停止しました。
このバグは、Devnetクラスターの停止に関する調査中に先週特定され、パッチの展開が予定されていました。@jeff.washington/2024-02-06-ソラナ-mainnet-beta-outage-report-619bd75b3ce0">選択された緩和策は、Agave v1.17 に変更をバックポートし、ネットワーク再起動時に機能ゲートをすぐに削除することでした。これにより、バグを誘発する責任があるレガシーローダーが無効化され、さらなる発生を防ぎました。
ダウンタイム:なし
ルートの問題:正しくないELFアドレスのアラインメントの仮定
修正:
8月5日、Anzaの主要エンジニアは、外部の研究者によって報告されたAgaveクライアントの脆弱性に警告されました.攻撃者はこの欠陥を悪用して、リーダーバリデーターをクラッシュさせ、ネットワーク全体の停止につながる可能性があります。これを受けて、Anzaのエンジニアは迅速にパッチを開発し、複数のサードパーティのセキュリティ会社が監査を行いました。
SolanaプログラムはLLVMを使用してコンパイルされます実行可能可及びリンク可能形式(ELF)この脆弱性は、これらの生成されたELFファイル内の誤ったアドレスアライメントの仮定から生じました。 ELFのサニタイズは通常、さまざまな整合性チェックを施しますが、.textセクションのアライメントを検証しませんでした。この見落としにより、悪意のある作成されたELFファイルが誤った.textセクションを定義し、仮想マシンが無効なアドレスにジャンプする可能性がありました。これにより、ホストのセグメンテーション違反が発生し、検証プログラムがクラッシュする可能性がありました。
攻撃者は次の方法でこの脆弱性を不正利用する可能性があります。
公開されているパッチアップデートは、脆弱性を直ちに明らかにします。これにより、攻撃者は脆弱性をリバースエンジニアリングし、十分な量のステークがアップグレードされる前にネットワークを停止するのに十分な時間を与えることができます。クリティカルマスのバリデーターは、このようなシナリオを回避するために、できるだけ早くパッチリリースを採用する必要があります。
8月7日までに、Solana Foundationは、さまざまなコミュニケーションプラットフォーム上のプライベートメッセージを通じてバリデーターに連絡を取りました、今後の重要なパッチを通知し、インシデントの日付と一意の識別子を確認するハッシュ化されたメッセージを共有します。複数の著名なAnza、Jito、Solana Foundationのメンバーが、このハッシュをX、GitHub、LinkedInで共有し、メッセージの正確性を検証しました。共有されたハッシュの例:
翌日、コアメンバーはバリデーターに連絡を取り続け、緊急性と機密性の重要性を強調しました。あらかじめ決められた時刻、8月8日午後2時(UTC)に、バリデーターのオペレーターは、パッチのダウンロード、検証、適用の手順を含む追加のメッセージを受け取りました。このパッチは、Agave のメインリポジトリではなく、既知の Anza エンジニアの Github リポジトリでホストされていました。手順には、ダウンロードしたパッチファイルを提供されたシャサムと照合することが含まれていました。
8月8日午後8時(UTC)までに、ステークの圧倒的多数にパッチが適用され、ネットワークセキュリティが確保されました。これに続いて、脆弱性とそれに対応するパッチが公開され、残りのすべてのバリデーターにアップグレードが呼びかけられました。
パッチの静かな配布とバリデータの舞台裏での調整は、Solanaの分散化に対する懸念を引き起こしました。事件の直後、ソラナ財団のエグゼクティブディレクターであるダン・アルバートは、メディアのインタビューでこれらの批判に対処しました。
「中央集権と調整能力を混同しないことが重要だと思います。世界中に1,500以上のブロック生成ノードがあり、ほぼ同数の個人が運営しています... 彼らと自発的にコミュニケーションを取る能力は、中央集権とは混同すべきではありません。」
韓国ブロックチェーンウィーク(KBW)2024
集中化と調整能力を混同しないことが重要だと思います。世界中に1,500のブロック生成ノードがあり、ほぼ同じ数の個人によって運営されています。彼ら、または彼らの一部と自発的にコミュニケーションをとる能力は、中央集権化と混同されるべきではありません。
この執筆時点では、ソラナは1年以上の間、停止時間なしで運用されており、mainnet-betaから“ベータ”タグを削除するための重要なマイルストーンを達成しました。停止時間の頻度はネットワークが成熟するにつれて減少しており、Firedancerの導入によりクライアントの多様性が向上し、未発見のバグやエッジケースによる完全なクラスタ全体のシャットダウンのリスクが低減すると期待されています。ただし、Heliusの創設者であるMert Mumtazを含む一部のコミュニティリーダーは、停止時間が続くと予測しています。時が解決するでしょう。
この作品の以前のバージョンをレビューしてくれたZantetsu(Shinobi Systems)とOxIchigoに多くの感謝を申し上げます。
ビープ、ビープ、ビープ。ビープ、ビープ、ビープ。
スティーブンの眠りは、厳しい携帯の音で崩れ、彼を夢から突然引きずり出す。暗闇の中、画面が明るく光り、ベッドサイドテーブルで激しく振動する。ビープ、ビープ、ビープ。彼はうめき声をあげ、ぼんやりと目をこすり、デバイスに手を伸ばす。メッセージを見て、彼の心は沈む―ノードがダウンしている。ためらうことなく、彼はベッドから飛び出し、半分服を着たまま、電話のロックを解除しようと手探りすると、さらにメッセージが殺到する。そして彼に気付かされる―クラスタ全体がダウンしている。
まさにこの瞬間、世界中の都市やタイムゾーンに散らばった場所で、何百人ものノードオペレーターが、恐怖の瞬間が到来したという同じ認識を持って携帯電話を見つめています。
ソラナは、すべての分散システムと同様に、単一の実装の欠陥や曖昧なエッジケースがネットワーク全体の障害につながる可能性があるという現実の下で運営されています。障害は、破壊的である一方、複雑な分散インフラを維持する過程で避けられない部分です。これは、分散型ブロックチェーン、中央集権取引所、またはAmazonやMicrosoftなどの主要なクラウドサービスプロバイダーでも同様です。
問題は、障害が発生するかどうかではなく、いつ、そしてネットワークがどのように進化し、将来のインシデントに適応し、強化するかです。厳密なシミュレーションテスト、インセンティブ付きのテストネット、アクティブなバグバウンティプログラムにもかかわらず、どんなに適切に設計されていても、考えられるすべての障害モードを予測できるシステムはありません。最も貴重な教訓は、実際の運用から得られます。
過去5年間、Solanaは7つの別々の障害事象を経験しました。そのうち5つはクライアントのバグによるもので、2つはネットワークが取引スパムの洪水に対処できなかったことが原因でした。初期のSolanaバージョンには、後にネットワークストレスの緩和に欠かせない優先手数料やローカル手数料市場などの重要な過積載管理メカニズムが欠けていました。そのようなメカニズムの欠如は、基本的にスパムをインセンティブとして利用したことにより、2022年全体を通じて低下したパフォーマンスと混雑が継続することにつながりました。
Solanaの停止とパフォーマンス低下の過去の事例
この記事では、各Solanaの障害について詳しく分析し、その原因、トリガーとなるイベント、および解決策について検討します。さらに、ネットワークの再起動、バグレポート、ライブネスとセーフティの基本的な概念についても議論します。これらのセクションは順番に読むのがベストですが、それぞれが単独で成立しており、読者が最も興味を持つトピックや障害事象に飛ぶことができるように設計されています。
CAP定理(Brewerの定理とも呼ばれる)によれば、分散システムは、3つの特性のうち2つしか達成できません:
ブロックチェーンにとって、分割耐性は不可欠です。ネットワークの断続は避けられません。これにより、AP(可用性 + 分割耐性)とCP(整合性 + 分割耐性)の選択を迫られます。ほとんどの高速確定PoSチェーンと同様に、Solanaは可用性よりも整合性を優先し、CPシステムとなっています。致命的な障害が発生すると、古いデータを提供するか、安全でない書き込みを許可するのではなく、システムを停止させます。これにより、ノードソフトウェアが手動での介入を必要とする回復不能な状態に入る可能性がありますが、ユーザー資金の安全性を確保します。
CAP定理のトレードオフ内でのSolanaの位置
Liveness Failure: ブロックチェーンが進行を停止し、バリデータのダウンタイム、ネットワークの分割、またはコンセンサスの停滞によってトランザクションの確認およびブロックの生成が阻害される場合に発生します。CAP定理の文脈では、これは可用性の損失に対応します。
セーフティフェイル:ブロックチェーンの確定状態が不適切に変更またはフォークされたときに発生します。これにより、しばしばコンセンサスのバグや悪意のある攻撃によって引き起こされる、相反する履歴や二重支出が生じる可能性があります。CAP定理の文脈では、これは一貫性の喪失に対応します。
Solanaは生存よりも安全を優先します。そのため、極端なネットワークストレスや合意の失敗の場合、ネットワークは停止しますが、状態の破損のリスクを冒すことはありません。停止は中断を引き起こす可能性があり、アプリケーション、ユーザー、および検証者に影響を与えるかもしれませんが、不整合または破損した元帳の致命的な結果よりも望ましいです。
Solanaネットワークを再起動するには、最後に楽観的に確認されたブロックスロットを特定し、そのスロットの信頼できるローカル状態のスナップショットからノードを再起動する必要があります。再起動スロットはオンチェーンで決定されないため、バリデーターのオペレーターは、安全なロールバックポイントに同意するためにオフチェーンのコンセンサスに達する必要があります。この調整は、Solana Tech Discordの #mb-validatorsチャンネルで公開され、プロのバリデーターオペレーターがリアルタイムでコミュニケーションを取ります。ほとんどのオペレーターは、ブロック生産が停止した瞬間に通知する自動アラートシステムを使用しており、迅速な対応を保証します。
正しい再起動スロットについてコンセンサスが得られたら、オペレーターは台帳ツールを使用して新しいローカルスナップショットを生成し、バリデーターを再起動し、総ステークの少なくとも80%がオンラインに戻るのを待ちます。そうして初めて、ネットワークはブロックの生成と検証を再開します。クラスターの再起動時に最大 20% のオフライン ステークがあることを確認することで、再起動直後にノードがフォークしたりオフラインに戻ったりした場合に、オンラインを維持するための十分な安全マージンを確保できます。
バグ報奨金プログラムは、ソフトウェアの脆弱性を特定して報告したセキュリティ研究者に報酬を与えます。これは、積極的にインセンティブを与えるため、重要な防衛線です悪用される前にバグを捕捉する.Agaveクライアントの潜在的な脆弱性を特定したセキュリティ研究者や開発者は、適切なセキュリティチャネルを通じて報告することをお勧めします。詳細な開示ガイドラインは、Agave GitHubリポジトリにあります.
重大な脆弱性の有効な報告に対して報酬が提供され、支払いは深刻度に基づいています:
かつFireDancerクライアントには独自のバグバウンティプログラムがありますImmunefiを通じてホストされ、重要な調査結果に対して最大500,000USDCの報酬を提供します。
以下のセクションでは、2020年3月16日にMainnet Betaを立ち上げから始まり、ソラナの障害と性能低下期間について詳細で年代順の分析を提供します。この調査は、主要なインシデント、その原因、およびネットワークのその後の改善を強調し、ソラナが時間とともに安定性と耐久性を向上させるためにどのように進化したかについての洞察を提供します。
ダウンタイム:約6時間
ルートの問題: ブロック伝播バグ
修正:
この停止はによって引き起こされました以前に知られていたブロック修復およびコード処理の問題の未確認のバグによってトリガーされますタービン、ソラナのブロック伝播メカニズム. バリデータが同じスロットの2つの異なるブロックを送信し、それらを2つの異なるパーティション(AとB)に伝播させたときに障害が発生しましたが、第三のパーティションは独自に矛盾を検出しました。
各パーティションが少数派の持分しか保持していなかったため、どれも超過半数のコンセンサスを達成することができず、チェーンを進展させることができませんでした。根本的な問題は、Solanaの内部データ構造がブロックとそれらの計算された状態を追跡する方法に由来しています。システムは、履歴の証明(PoH)スロット番号(u64識別子)を使用して状態を参照し、そのスロットのブロックを参照していました。ネットワークがパーティションに分割されると、ノードはブロックAとBを同一と誤解し、適切な修復とブロックの同期を阻害しました。
各パーティションは、他方が同じブロックを持っていると想定し、基本的な衝突が発生しました:
パーティション間の状態遷移が異なるため、バリデーターはフォークを修復または調整することができず、最終性を防いでいました。
この問題の解決策は、ハッシュではなくスロット番号でブロックを追跡するサービスを許可する同じスロットの任意の数のブロックが分割を作成した場合、それらは異なるスロットを占有するブロックと同じように扱われます。ノードはすべての可能なフォークを修復でき、コンセンサスは分割を解決することができます。
バグが停止の最初の原因でしたが、Solanaがブロック生成を再開するには少なくとも80%のステーク参加が必要なため、ダウンタイムのほとんどは、十分なステークウェイトがオンラインに戻るのを待ったことに起因しています。
ダウンタイム:十七時間
ルート問題:ボット取引によるメモリオーバーフロー
修正:
2021年9月14日、Solanaは、グレーププロトコルがクラウドファンディングプラットフォームRaydium AcceleRaytorでのオンチェーン初のDEXオファリング(IDO)の開始に続いて、大規模なネットワークの停止を経験しました。IDOの12分以内に、ネットワークは前例のないボットによる取引の洪水に圧倒され、ルーテッドスロットの生成を停止しました。これらのボットは、分散型サービス拒否(DDoS)攻撃を効果的に実行し、ネットワークの容量を超える取引負荷を押し付けました。
ピーク時の混雑時:
2021年9月14日のGrape IDOの障害中のSolanaスロット数(データソース:Jump Crypto)
ボットの1つは、グローバルSPLトークンプログラムや今は亡きSerum DEXプログラムを含む18の主要アカウントを書き込みロックするようにトランザクションを構築しました。これにより、これらのアカウントとやり取りするすべてのトランザクションがブロックされ、Solanaの並列処理能力が大幅に低下しました。トランザクションを独立して実行する代わりに、ネットワークがボトルネックになり、トランザクションを順番に処理し、輻輳を悪化させました。
プログラムの書き込みロックを無視する修正プログラムが既に開発され、リリースが予定されています。その後、ネットワークを再起動すると、このアップグレードが有効になり、この攻撃ベクトルが完全に削除されました。
IDOイベント中、バリデーターはボット主導のトランザクションを大量に受け取り、過剰なトランザクションを次のリーダーに転送し、混雑を増幅させました。ネットワークの再起動により、トランザクション転送にレート制限が導入され、将来のトランザクションの嵐がリーダーを圧倒するのを防ぎます。
ソラナのRPCノードは、失敗したトランザクションを自動的に再試行します。これは信頼性を向上させるための機能です。しかし、この再試行機構は極端な混雑状態下でトランザクションの洪水を悪化させ、ネットワークが回復する代わりに古いトランザクションを循環させていました。Solana 1.8では、設定可能なRPC再試行動作が導入され、アプリケーションが短い有効期限時間や指数バックオフ戦略で再試行を最適化できるようになりました。
過度の混雑の中、Solanaのリーダーたちはコンセンサスを維持するために重要な投票トランザクションを含めることに失敗しました。その結果、確認されていない投票の欠如がコンセンサスの停滞につながり、新しいルートブロックの生成が停止しました。後のSolanaクライアントのバージョンでは、投票トランザクションを優先するメカニズムが導入され、将来のイベントで通常のトランザクションに埋もれることなく防止されました。
ネットワークの再起動中に、2 つ目の問題が発生しました。バリデーターは、アクティブなステーク量が激しく変動していることを報告しました。この問題は、賭け金の割合が誤って100倍され、可能な最大値を超えてしまうバグに起因していました。インフレーションメカニズムは、非常に多くの新しいSOLトークンを作成したため、64ビットの符号なし整数がオーバーフローしました。このバグはすぐに特定され、2回目の再起動前にパッチが適用されました。
ダウンタイム:なし
原因: 過剰な重複取引
一部修正:
2022年1月6日から1月12日の間、Solanaメインネットは深刻なネットワーク混雑を経験し、パフォーマンスが低下し、一部の停止が発生しました。この混乱は、ボットが過剰な重複取引をスパムし、ネットワーク容量を大幅に減少させたことにより引き起こされました。ブロックの処理に予想以上の時間がかかり、次のリーダーがフォークしてスループットをさらに低下させることがありました。ピーク時には、取引の成功率が最大で70%まで低下しました。クライアントは、ネットワークのますます複雑で高い計算取引を処理するのに苦労し、需要に対応する能力の限界が露呈しました。
1月21日から23日にかけて追加の不安定性が発生し、混雑が続いていました。1月22日には、公共のRPCエンドポイント(https://api.mainnet-beta.solana.com) went offline due to abuse, as spammed batched RPC calls overwhelmed the system.
これらの問題に対処するために、Solana 1.8.12リリースは特にプログラムキャッシュの枯渇を対象としています、 一方でバージョン1.8.14では、Sysvarキャッシュ、SigVerify破棄、およびSigVerify重複の改善が導入されました.
ダウンタイム:8時間
ルートの問題: ボットアカウントからのトランザクションスパム
修正:
2022年4月30日、Solanaは前例のないトランザクションリクエストの急増を経験しました。一部のノードは、ノードあたり秒間600万リクエストに達し、トラフィックはノードあたり100 Gbpsを生成しました。この急増は、Metaplex Candy Machineプログラムを通じて新しく発行されたNFTを確保しようとするボットによって引き起こされました。このミンティングメカニズムは、先着順で動作し、ネットワークにトランザクションを殺到させ、ミントを獲得する強力な経済的インセンティブを生み出しました。
2022年4月30日/5月1日、キャンディーマシンの停止、パケット毎秒のイングレス(データソース:Jump Crypto)
取引量が急増するにつれ、バリデーターはメモリーを使い果たし、最終的にコンセンサスが停滞しました。不十分な投票スループットにより、以前のブロックの最終化が阻害され、放棄されたフォークのクリーンアップが妨げられました。その結果、バリデーターは評価するフォークの数が多過ぎて圧倒され、再起動後でも容量を超過し、ネットワークを復旧するために手動で介入する必要がありました。
この障害は2021年9月のインシデントと類似点を持っていましたが、ソラナは向上した耐久性を示しました。前回の障害よりも取引リクエストが10,000%増加しましたが、ネットワークははるかに長い間運用され続け、検証者コミュニティが以前のスケーリングの課題に対応して行った改善を反映しています。
2022年4月30日/5月1日、キャンディーマシンの停止、アクティブなバリデーター(データソース:Jump Crypto)
正規スナップショットが合意された後、ネットワークの再起動は1.5時間未満で完了しました。Solana v1.10には、ノードが遅いまたは停滞したコンセンサスに耐える時間を延ばすためのメモリ使用の改善が含まれています。
しかし、根本的な問題は未解決のままでした。リーダーは引き続き、効果的なスパム防止を行わずに同じアカウントデータを競合して処理し、ユーザーは自分の取引の緊急性を優先することができませんでした。この問題を解決するために、3つの長期的なメカニズムが実用的な解決策として提案されました。
QUICの採用: 以前、Solanaは、Gulf Streamを介してRPCノードから現在のリーダーへトランザクションを送信するためにUDP(User Datagram Protocol)ネットワーキングプロトコルに依存していました。速く効率的ですが、UDPは接続がなく、フロー制御や受信確認が不足しています。したがって、悪用行為を防止したり緩和する有効な方法がありません。ネットワークトラフィックを制御するために、検証者のトランザクション取り込みプロトコル(つまり、TPUのFetchステージ)はQUICで再実装されました。
QUICはTCPとUDPの両方の利点を提供しようとします。これにより、UDPと同様の高速非同期通信が可能になりますが、TCPのセキュアセッションと高度なフローコントロール戦略も利用できます。これにより、個々のトラフィックソースに制限を設けることができ、ネットワークは本物のトランザクションの処理に集中できます。QUICには、個々のトランザクションがドロップされても、残りのトランザクションをブロックしないという概念もあります。QUICは最終的に、Solana Labsのクライアントに1.13.4リリースで統合されました。
ステークウェイト付きサービス品質(SWQoS): バリデータが保有するステークに基づいてネットワークトラフィックの優先順位を付ける新しいシステムが導入され、より高いステークを持つ者がより効率的にトランザクションを送信できるようになりました。このメカニズムでは、合計ステークの3%を持つバリデータはリーダーに合計パケットの3%まで送信できます。SWQoSはシビル抵抗対策として機能し、低品質のトランザクションでネットワークを氾濫させる悪意のある行為者にとってより困難になります。このアプローチは、以前の先着順モデルを置き換えています。このモデルは、ソースを考慮せずにトランザクションを無差別に受け入れていました。
優先手数料の紹介:トランザクションが取り込まれると、それらは引き続き共有口座データへのアクセスを競い合います。以前は、この競合は単純な先着順で解決され、ユーザーはトランザクションの緊急性を示す方法がありませんでした。誰でもトランザクションを送信できるため、ステークウェイトはこの段階で優先順位付けには適していません。これを解決するために、Compute Budgetプログラムに新しい命令が追加され、実行とブロックの含まれる追加料金を指定することができるようになりました。料金と計算単位の比率は、トランザクションの実行優先度を決定し、取引の注文に対するより動的で市場主導のアプローチを確実にします。
Metaplexは、ミント取引に0.01 SOLのボット税を迅速に導入しましたbot-driven spamと戦うためにCandy Machineプログラムとやり取りしています。このスパム対策メカニズムは、意図しない間違いをした正当なユーザーを罰することなく、悪意のある活動を阻止するために最小料金を課しました。この税金は、特定のシナリオで適用されました。
この経済的な抑止力は非常に効果的であることが証明されました。ミント・スナイパーはすぐに枯渇し、スパム活動も止まりました。最初の数日で、ボッターたちは合わせて426 SOL以上の損失を被りました。
ダウンタイム:4時間半
ルートの問題: コンセンサスの失敗につながる耐久性のあるナンスのバグ
修正:
ランタイムバグにより、特定の耐久性のあるナンストランザクションが、最近のブロックハッシュの代わりに耐久性のあるナンスを使用した場合、通常のトランザクションとして1回、再度ナンストランザクションとして2回処理されることがありました。 これにより、一部のノードが2回目の実行を拒否する一方、他のノードがそれを受け入れるという非決定論的な動作が生じました。 重要なのは、バリデーターの3分の1以上がブロックを受け入れたため、必要な2分の1の多数決に到達することが阻まれました。
標準トランザクションとは異なり、永続ノンストランザクションは期限切れにならず、二重実行を防ぐために独自のメカニズムが必要です。これらは、各アカウントに関連付けられたオンチェーンのノンス値を使用して逐次処理され、永続的なノンストランザクションが処理されるたびにローテーションされます。いったんローテーションすると、同じ nonce トランザクションが再び有効になることはありません。
問題を軽減するために、耐久性のあるノンス取引が一時的に無効にされました。修正は後にSolana 1.10.23で実装されましたこれにより、ノンスとブロックハッシュのドメインを分離することで、重複した実行を防止しました。このアップデートにより、ノンスアカウントを進める際にブロックハッシュが固定された文字列でハッシュ化されるため、ブロックハッシュはノンス値として無効になります。その結果、通常のトランザクションとして1度実行された取引を、耐久性のあるトランザクションとして再実行したり、その逆も行ったりすることはできません。さらに、新しいDurableNonceタイプが、将来の類似した問題を防ぐために、ノンスアカウントの状態で以前のブロックハッシュ値を置き換えました。
以前のHeliusブログ記事を読んでください耐久性のあるナンスとその用途についてもっと理解する.
ダウンタイム:8時間半
ルートの問題:フォーク選択ルールのバグがコンセンサスの失敗につながりました
修正:
この停止は、バリデータが同じブロック高さで誤って重複ブロックを生成したことによって引き起こされました。これは、バリデータのプライマリノードとフォールバックスペアノードの両方が同時にアクティブになり、同じノードIDを使用して異なるブロックを提案したために発生しました。この状況は、停止の前に少なくとも24時間持続しました。その間、ネットワークはバリデータの重複したリーダースロットを正しく処理しました。
ネットワークがフォーク選択ロジックのバグによって回復不能なフォークに遭遇したとき、クラスターは最終的に停止しました。このバグにより、ブロックプロデューサーは前のブロック上での構築を妨げられ、コンセンサスの失敗につながりました。
ソラナでは、フォークは日常的に発生し、通常、バリデータは投票の過半数に合わせてフォークを解決します(最も重いフォーク)。 バリデータが間違ったフォークを選択した場合、ネットワークと同期するために最も重いフォークに切り替える必要があります。 ただし、この場合、バリデータは、スロットが最後に投票されたスロットと一致した場合、最も重いブロックに戻ることができませんでした。 この欠陥により、バリデータは立ち往生し続け、コンセンサスが進展せず、最終的にネットワークが停止することにつながりました。
重複ブロックバグの停止と分岐選択、2022年9月(出典:Laine、Michael Hubbard)
上記の例では、不良バリデータCは、リーダースロット5から8の間に重複したブロックを生成します。次のリーダーであるバリデータGが引き継ぐと、重複のうち1つしか検知せず、その分岐を拡張します。しかし、続くリーダーであるバリデータDは、バリデータCからの両方の重複ブロックを検知し、それらを破棄して代わりにスロット4の上にその分岐を構築することを決定します。
ネットワークが進展するにつれ、バリデーターGによって構築されたフォークが大部分のステークからの票を獲得し、正準チェーンとして確立されます。自分のフォークが負けていることに気づいたバリデーターDは、バリデーターGのフォークに切り替えようと試みます。しかし、フォーク選択ロジックのバグにより、この移行は失敗に終わります。この問題は、2つのフォークの共通の祖先であるスロット5の重複ブロックが正しく処理されなかったために発生し、バリデーターDが過半数のフォークを認識できなくなりました。その結果、バリデーターDは自分のフォークで立ち往生し、メインチェーンに戻ることができません。
この問題は、コア チームによるレビュー後に解決されました。パッチがマスターブランチにマージされ、すべてのリリースブランチにバックポートされました.
ダウンタイム:ほぼ19時間
ルートの問題: シュレッド転送サービスにおける重複排除ロジックの失敗
修正:
バリデーターのカスタムシュレッド転送サービスが誤作動し、標準ブロックよりも桁違いに大きなブロック(ほぼ150,000シュレッド)をリーダースロット中に送信しました。これにより、バリデーターデデュプリケーションフィルターが過負荷となり、データが連続して再転送されることになりました。新しいブロックが生成されるたびに問題が複合し、ついにプロトコルが飽和状態になりました。
大規模なブロックの停止、ブロックあたりの細断数、2023 年 2 月(出典: レイン、マイケル・ハバード)
異常なネットワークトラフィックの急増により、タービンは圧倒され、ブロックデータを大幅に遅いフォールバックブロック修復プロトコルを介して送信することを余儀なくされました。タービンは大きなブロックを除外することで耐えるように設計されていますが、このフィルタリングロジックの上流にはシュレッド転送サービスがあり、その効果が低下しています。劣化期間中、ブロックリーダーは自動的に投票のみモードに切り替わり、経済的な非投票取引を除外する安全装置となりました。
問題の根本原因は、シュレッド転送サービス内の重複排除ロジックの障害であり、シュレッドの冗長な再送信を防いでいました。さらに、再送信パイプライン内の重複排除フィルタは元々、タービンツリー内でのループを防ぐように設計されていなかったため、問題が悪化しました。
ネットワークは、最後に確認された安定したバリデータソフトウェアバージョンにダウングレードして、手動で再起動されました。これらの問題を緩和するために、Solana v1.13.7 と v1.14.17 では、重複排除ロジックが強化されましたこれにより、フィルターの飽和を防ぐ能力が向上し、より堅牢なネットワークパフォーマンスが保証されます。
ダウンタイム:ほぼ5時間
ルートの問題: JITキャッシュで無限の再コンパイルループを引き起こすバグ
修正:
Agave バリデーターのジャストインタイム (JIT) は、すべてのプログラムを参照するトランザクションを実行する前にコンパイルします。パフォーマンスを最適化するために、頻繁に使用されるプログラムのJIT出力がキャッシュされ、不要な再コンパイルが削減されます。Agave v1.16の一部として、既存のキャッシュメカニズムであるLoadedProgramsは、ExecutorsCacheと呼ばれる新しい実装に置き換えられ、いくつかの効率性が導入されました。
LoadedProgramsは、キャッシュされたプログラムのグローバルでフォークを認識したビューを提供し、会計データの重複を減らし、トランザクション実行スレッドが新しいプログラムを協調的に読み込むことで、コンパイルの競合を防ぎました。このシステムの特徴の1つは、プログラムがアクティブになるスロットを追跡すること(有効スロット高さとして知られる)であり、オンチェーンのプログラムデータが更新されるときにキャッシュの無効化を検出することでした。
ほとんどのプログラムの有効スロットの高さは、オンチェーンアカウントに保存されているデプロイスロットから導き出されました。ただし、レガシーローダーを使用してデプロイされたプログラムは、このデプロイスロットをアカウントに保持しませんでした。LoadedPrograms は、回避策として、これらのプログラムに有効なスロットの高さ 0 を割り当てました。
デプロイ命令が検出されたときに例外が発生し、プログラムのバイトコードが置き換えられたことが通知されました。この場合、LoadedPrograms は、正しい有効スロット高さのエントリを一時的に挿入します。ただし、トランザクションはこのエントリを参照しないため、削除の影響を非常に受けやすくなっていました。削除されると、JIT 出力は破棄され、プログラムはアンロードのマークが付けられましたが、有効なスロットの高さは保持されました。
もし取引が後でこのロードされていないプログラムを参照した場合、LoadedProgramsはそれを再コンパイルして、その有効なスロットの高さにエントリを再挿入しました。通常、これにより、プログラムは次の反復で実行可能になります。ただし、旧バージョンのローダープログラムの場合、新しいJIT出力にはセンチネルスロットの高さであるゼロが割り当てられ、それにより以前のロードされていないエントリの後ろに配置されました。その結果、LoadedProgramsはプログラムをロードされたと認識せず、反復ごとに連続的な再コンパイルループがトリガーされました。
Agave v1.16では、LoadedProgramsは協力的なローディングをサポートしておらず、トリガーとなるトランザクションがブロックにパックされることを許可していました。このブロックはその後ネットワーク全体に伝播され、すべての検証ノードがそれを再生して同じ無限の再コンパイルループに入りました。停止期間中、クラスタのステークの95%以上がAgave v1.17を実行していたため、ほとんどの検証ノードがこのブロックで停止し、ネットワークが停止しました。
このバグは、Devnetクラスターの停止に関する調査中に先週特定され、パッチの展開が予定されていました。@jeff.washington/2024-02-06-ソラナ-mainnet-beta-outage-report-619bd75b3ce0">選択された緩和策は、Agave v1.17 に変更をバックポートし、ネットワーク再起動時に機能ゲートをすぐに削除することでした。これにより、バグを誘発する責任があるレガシーローダーが無効化され、さらなる発生を防ぎました。
ダウンタイム:なし
ルートの問題:正しくないELFアドレスのアラインメントの仮定
修正:
8月5日、Anzaの主要エンジニアは、外部の研究者によって報告されたAgaveクライアントの脆弱性に警告されました.攻撃者はこの欠陥を悪用して、リーダーバリデーターをクラッシュさせ、ネットワーク全体の停止につながる可能性があります。これを受けて、Anzaのエンジニアは迅速にパッチを開発し、複数のサードパーティのセキュリティ会社が監査を行いました。
SolanaプログラムはLLVMを使用してコンパイルされます実行可能可及びリンク可能形式(ELF)この脆弱性は、これらの生成されたELFファイル内の誤ったアドレスアライメントの仮定から生じました。 ELFのサニタイズは通常、さまざまな整合性チェックを施しますが、.textセクションのアライメントを検証しませんでした。この見落としにより、悪意のある作成されたELFファイルが誤った.textセクションを定義し、仮想マシンが無効なアドレスにジャンプする可能性がありました。これにより、ホストのセグメンテーション違反が発生し、検証プログラムがクラッシュする可能性がありました。
攻撃者は次の方法でこの脆弱性を不正利用する可能性があります。
公開されているパッチアップデートは、脆弱性を直ちに明らかにします。これにより、攻撃者は脆弱性をリバースエンジニアリングし、十分な量のステークがアップグレードされる前にネットワークを停止するのに十分な時間を与えることができます。クリティカルマスのバリデーターは、このようなシナリオを回避するために、できるだけ早くパッチリリースを採用する必要があります。
8月7日までに、Solana Foundationは、さまざまなコミュニケーションプラットフォーム上のプライベートメッセージを通じてバリデーターに連絡を取りました、今後の重要なパッチを通知し、インシデントの日付と一意の識別子を確認するハッシュ化されたメッセージを共有します。複数の著名なAnza、Jito、Solana Foundationのメンバーが、このハッシュをX、GitHub、LinkedInで共有し、メッセージの正確性を検証しました。共有されたハッシュの例:
翌日、コアメンバーはバリデーターに連絡を取り続け、緊急性と機密性の重要性を強調しました。あらかじめ決められた時刻、8月8日午後2時(UTC)に、バリデーターのオペレーターは、パッチのダウンロード、検証、適用の手順を含む追加のメッセージを受け取りました。このパッチは、Agave のメインリポジトリではなく、既知の Anza エンジニアの Github リポジトリでホストされていました。手順には、ダウンロードしたパッチファイルを提供されたシャサムと照合することが含まれていました。
8月8日午後8時(UTC)までに、ステークの圧倒的多数にパッチが適用され、ネットワークセキュリティが確保されました。これに続いて、脆弱性とそれに対応するパッチが公開され、残りのすべてのバリデーターにアップグレードが呼びかけられました。
パッチの静かな配布とバリデータの舞台裏での調整は、Solanaの分散化に対する懸念を引き起こしました。事件の直後、ソラナ財団のエグゼクティブディレクターであるダン・アルバートは、メディアのインタビューでこれらの批判に対処しました。
「中央集権と調整能力を混同しないことが重要だと思います。世界中に1,500以上のブロック生成ノードがあり、ほぼ同数の個人が運営しています... 彼らと自発的にコミュニケーションを取る能力は、中央集権とは混同すべきではありません。」
韓国ブロックチェーンウィーク(KBW)2024
集中化と調整能力を混同しないことが重要だと思います。世界中に1,500のブロック生成ノードがあり、ほぼ同じ数の個人によって運営されています。彼ら、または彼らの一部と自発的にコミュニケーションをとる能力は、中央集権化と混同されるべきではありません。
この執筆時点では、ソラナは1年以上の間、停止時間なしで運用されており、mainnet-betaから“ベータ”タグを削除するための重要なマイルストーンを達成しました。停止時間の頻度はネットワークが成熟するにつれて減少しており、Firedancerの導入によりクライアントの多様性が向上し、未発見のバグやエッジケースによる完全なクラスタ全体のシャットダウンのリスクが低減すると期待されています。ただし、Heliusの創設者であるMert Mumtazを含む一部のコミュニティリーダーは、停止時間が続くと予測しています。時が解決するでしょう。
この作品の以前のバージョンをレビューしてくれたZantetsu(Shinobi Systems)とOxIchigoに多くの感謝を申し上げます。