※この記事は、Terra Classic L1開発チーム「L1 Task Force」のメンバーであるLuncBurnArmy氏(@luncburnarmy)が2023年3月9日に公開した記事『After-Action Review v1.1.0』の内容を日本語訳した記事となります。
記事の要点
- エラーが起きた際に「ノードを再起動させる」という行為が短期的にアップグレードを破綻させる原因
- 必要な投票権を超えたことが完全に確認されるまで待つことが重要
- 今回のv1.1.0アップグレードから学んだ教訓は今後にしっかり活かす
v1.1.0アップグレードで発生したエラーについて
この記事は、v1.1.0 アップグレード時にL1 Task Forceで実施した作業の概要と、主な事象の概要を説明するものです。
L2の問題やバグ修正に関してはL1チームの範囲外であるため、このレビューには織り込まれていません。すべてのウォレットプロバイダーとL2アプリは、自身の製品がClassicコアの新しいアップグレードバージョンで正しく機能することを確認し、ユーザーコミュニティにタイムリーなアップデートとパッチを提供するために、独自の調査を実施する必要があります。
Terra Classic(LUNC)ブロックチェーンは2023年3月1日 2:18 UTC(日本時間:2023年3月1日 11:18)にバージョンv1.1.0への定期アップグレードを実施しました。「Cosmos SDK」で標準となったソフトウェアアップグレード提案ガバナンス方式で進行したのはTerra Classicチェーンの歴史上初めてのことでした。
3月1日 2:34 UTC(日本時間:2023年3月1日 11:34)時点、14分以内に投票合意67%の境目に達し、チェーンは必要な投票力をクリアしてブロック「11734001」を生成しました。しかし、その後のブロックではチェーンが合意に達することができませんでした。
合意ラウンドで指摘されたように、3名の バリデータ(画像左側の列の肩をすくめている絵文字の部分)がブロック11734002で他のバリデータセットと異なるハッシュを提案していました。このエラーは次のようなものでした。
投票前のステップ:
Proposalブロックが無効 = "wrong Block.Header.LastResultsHash. Expected AFE97BD368F0D6B92206B83EB89A1CBC8DED4B9EE1596F4A819C6817F53F47C9, got 658EC57B453249685F1074BC1F6CE5C56C04730BD850F0F05DFAAD41BF02B3B1" height=11734002 module=consensus round=55
この時点で私たちはその後8時間の間合意ラウンドに留まることになり、いくつかの方法でこの問題のデバッグを試みました。
1つ目の問題:異なるGo言語のバージョン
まずはじめに、非決定性がプログラミング言語「go」のバージョンの違いによって引き起こされた可能性があると考えました。アップグレードの数日前から公式にサポートされているgolangのバージョンは"go 1.18.x"だけだったので、異なるバージョンの go言語を使用しているすべての人にサポートされているバージョンをインストールするように依頼しました。今にして考えるとこの点は問題ではありませんでしたが、私たちが同じバージョンを使っていることは良いことであると言えるでしょう。
2つ目の問題:ノード再起動で多くの接続を失う
次に問題となったのは、ノード が再起動のためにオフラインになり始めると多くのノードが接続を失い始めたことです。必要な投票力が67%のしきい値から、オンラインの30 ~ 40%の投票力まで低下する段階に入りました。
この問題に対処するため、開発者のフルノードの1つを永続的に接続される通信機器として変更し、誰しもが他の全員を発見できるようにしました。この発見期間中に、私たちのネットワークには、osmosisやphoenixというチェーンIDを持つノードなど、奇妙な通信機器がいくつか接続されていることに気づきました。このとき、addrbook.jsonを切り離し、更新したものを提供しました。
3つ目の問題:合意形成モジュールのフリーズ
3つ目の問題となったのは「addrbookの更新」「接続する通信機器の追加」「terradの再起動」など、様々なことを試すためにノードが切断されると、これらのノードに接続されていた合意形成モジュールがフリーズしたことです。いくつかのマシンでは"curl localhost:26657/consensus_state"が応答しなくなったのでこれが原因だと判断しました。
terradを停止・起動しても、合意された状態をオンラインに戻すことはできませんでした。合意形成モジュールの凍結を解除するにはスナップショットからの再同期が唯一の解決策でした。AutoStakeバリデータは、アップグレードの高さでスナップショットと再同期の指示を共有し、凍結したバリデータに対して迅速な再同期対応を可能にしました。
これらの対応を行うことで最終的に3月1日 10:00 UTC(日本時間:3月1日 19:00)頃に投票力が67%に達することができました。
エラーに対する疑問とその答え
ブロック11734002で合意に達しなかったのはなぜ?
Q. ブロック11734001では合意に達してブロック11734002では合意に達しなかったのはなぜなのか?
その答えは、LordInateurがアップグレードの過程で発見し、ユーザーのA.E氏によって明らかにされました。
私が犯してしまった愚かなミスですが、もし同じようなことをする場合は他の人が学べるように説明します。もしsystemdを使っており、chain-specificなフォルダにwasmライブラリを置いている場合、そして別のマシンでterradをビルドする場合は、wasm libを実際にコピーしてLD_LIBRARY_PATHを設定することを確認してください。そうしないとアプリケーションのハッシュエラーが発生する可能性があります。
間違ったバージョンのlibwasmvm.soを使用した場合、ブロック11734001のアプリハッシュで問題は発生しませんでしたが、11734002のアプリハッシュで問題が起きることが確認されました。
この点については、terradを必要なv0.16.7ではなくv0.16.6でコンパイルして以下のように手動で確認しました。
ldd ~/go/bin/terrad linux-vdso.so.1 (0x00007ffc39bad000) libwasmvm.so => /home/luna/go/pkg/mod/github.com/!cosm!wasm/wasmvm@v0.16.6/api/libwasmvm.so (0x00007fbdc5200000)
ここでは、不正なlibwasmvmの出力が、確かにハッシュ「658EC57B453249685F1074BC1F6CE5C56C04730BD850F0F05DFAAD41BF02B3B1」を期待していることが分かり、アップグレード中に見られたエラーと一致しています。
タグの不一致・異なるterrad使用が原因?
Q. タグの不一致や、コミットハッシュが異なるterradを使用することでこの問題が発生したのか?
答えは「いいえ」で、間違ったコミットハッシュでterradを実行してもブロック11734001の正しいブロックハッシュは生成されないことが確認されており、チェーン停止の理由にはなりませんでした。
もっと上手く対処する方法があった?
Q. もっと上手くエラーに対処できたのだろうか?
この点に関しては残念ながら、この問題は事前に予測することはできませんでした。今にして思えば「解決策を見出す前に、全員がもっと長く待つこと」が最良のアプローチだったのでしょう。誤動作に対してノードを再起動させるという行為が、短期的にアップグレードを破綻させる原因となってしまいました。もし待っていれば、より多くのバリデータがオンラインになり、libwasmvmの問題を抱える投票者はごく少数だったため、最終的に再びコンセンサスを得られたでしょう。
今後のアップグレードでの改善点
理想的なシナリオでは、バリデータノードを実行しているすべてのバリデータが私たちのテストネット上でもバリデータノードを実行し、columbus-5メインネットの完全なステージング環境を提供することができるようになります。
これにより、L1チームとすべてのバリデーターはアップグレードプロセスにサポートされていない要素(Go言語のバージョンが正しくないなど)を意図的に導入することも含めて、アップグレードプロセス全体をエンドツーエンドでシミュレートすることができます。
しかし、バリデータセット全体を含むバリデータテストネットは、次回のアップグレードでは利用できなくなる予定です。チームはこれがTendermintやCosmos SDKのアップグレードを遅らせる理由にはならないことを確認しています。
当面の間、チームは以下の教訓を次回のアップグレードに生かします。
- チェーン停止時に67%以上の投票力を持つ相当数のバリデータから直ちにアップグレードすることを確約してもらい、他のバリデータにも同じことを強く勧める
- 必要な投票権を超えたことが完全に確認されるまで何もせず待つ
- いくつかの異なるバリデータ構成でアップグレードのテストを継続する
- 次回のアップグレードに先立ちテストネットを強化し、いくつかのバリデーターを追加する(L1 Task ForceはlinodeとAWSのリソースを使用し、追加のテストネットバリデータをプロビジョニングする予定)
Terra Classicチェーンは2023年3月1日にv1.1.0へのアップグレードに成功しました。今回のv1.1.0アップグレードから学んだ教訓は残りのQ1内に予定されているアップグレードに適用され、すべて当初の予定通りのタイムライン内で計画通りに進められます。
v1.1.0アップグレードの概要を説明してくれた Edward Kim氏、そして教訓に貢献してくれた他のL1チームメンバー全員に感謝します。
『After-Action Review v1.1.0』の原文はこちら