はじめに:重要な安全ルール
絶対にしてはいけないこと
- 同じ
priv_validator_key.jsonを持つ2つのノードを同時に実行しないでください。 二重署名が発生し、スラッシュは0%ですが、恒久的なトゥームストーン(tombstone)につながります。そのバリデーターは二度とアクティブセットに復帰できません。 - 結果を完全に理解していない限り、バリデーターノードで
unsafe-reset-allを使用しないでください。 コンセンサスstateが消去され、トゥームストーンにつながる矛盾した投票を生成する可能性があります。 - ノードが稼働中の状態で
priv_validator_state.jsonをバックアップしないでください。 このファイルはコンセンサス中に絶えず変化します。まずノードを完全に停止してからコピーしてください。 - バックアップした
priv_validator_state.jsonを復元せずに、スナップショット復旧後のノードを起動しないでください。 スナップショットにはこのファイルが含まれません。復元せずに起動すると署名stateがブロック高0にリセットされ、二重署名を引き起こします。 - アーカイブノードや大きな履歴を持つノードは、事前にテストせずにロールバックしないでください。 大規模なデータベースでのロールバックは数時間かかるか、ノードを完全に使用不能にする可能性があります。特にPebbleDBでは注意が必要です。
- ロールバック、スナップショット復元、バイナリアップグレードなどの復旧作業の前には、必ずノードを完全に停止してから
priv_validator_state.jsonをバックアップしてください。 - ロールバックやスナップショット復旧の後、ノードを起動する前に、必ず
priv_validator_state.jsonを元の場所に復元してください。 - ノードを起動する前に、必ず
priv_validator_state.jsonが破損していないことを確認してください。 height、round、stepの値が妥当かどうかをチェックしてください。 - 協調アップグレードでは必ず
--halt-heightを設定してください。 halt-heightフラグを設定しなかったノードは、より困難な復旧手順が必要になります。 - アップグレード後の起動前に、必ず
injectived versionでバイナリのバージョンを確認してください。 - チェーンが安定したら、一時的なコンセンサスの上書き設定(
--unsafe-consensus-timeout-precommit-delta=1msなど)を必ず元に戻してください。
復旧用のスナップショットが必要ですか? プルーニングされたスナップショットとコミュニティプロバイダーについては、このページの下部にあるスナップショットリソースを参照してください。アーカイブセグメントのスナップショットについては、アーカイブセットアップページを参照してください。
よくある問題と解決策
アップグレード高でノードが停止したまま進まない
症状:- ノードログに、想定されたアップグレード高でチェーンが停止したことが表示される
latest_block_heightが停止高を超えて進まない
- ノードを停止する
~/.injectived/data/priv_validator_state.jsonをバックアップする- 新しいバイナリをインストールする
- 確認する:
injectived version - ノードを起動する
アップグレード後のブロックヘッダーハッシュの不一致
症状:- ノードを停止する
priv_validator_state.jsonをバックアップする- 1ブロックロールバックする:
priv_validator_state.jsonを復元する- 新しいバイナリでノードを起動する
矛盾した投票(conflicting vote)の警告
症状:priv_validator_state.json がリセットまたは破損したため、すでに署名済みのラウンドに再度署名し、矛盾した投票を生成しています。
よくある引き金:
- バリデーターで
unsafe-reset-allを実行した - 古い、または誤った
priv_validator_state.jsonを復元した - ノードが稼働中の状態で
priv_validator_state.jsonをバックアップした(古いコピー) - rollbackコマンドがバリデーターstateをリセットした
- (ノードを完全に停止した後に取得した)正しい
priv_validator_state.jsonのバックアップがある場合:それを復元して再起動してください。 - 正しいバックアップがない場合:直ちにノードを停止し、ブロック生成が再開されるのを待ってから再起動してください。 誤ったstateで起動すると二重署名のリスクがあります。
- 署名情報を確認する:
バリデーターがトゥームストーンされた(二重署名)
症状:- 同じ署名キーでノードの2つのインスタンスを実行した
- 古い
priv_validator_state.jsonを復元したことで、すでに署名済みのブロック高で再署名が発生した - ロールバックによって署名stateがリセットされ、その後ノードが矛盾したブロックに署名した
- 影響を受けたバリデーターのトゥームストーンを明示的に解除するガバナンスプロポーザルまたはアップグレードハンドラー
- 新しいオペレーターキーで新しいバリデーターを作成する(既存のデリゲーションは失われます)
- ハードウェアで強制されるシングルサイナーのセマンティクスのために、TMKMSまたはHorcruxを使用する
- ノードを停止した後に必ず
priv_validator_state.jsonをバックアップする - 同じ署名キーで2つのノードを同時に実行しない
スナップショットからの復旧
使用すべきタイミング: ロールバックが失敗する、時間がかかりすぎる、またはノードのstateが修復不可能なほど破損している場合(AppHashの不一致)。 手順:- ノードを完全に停止する
~/.injectived/data/priv_validator_state.jsonをバックアップする- 他の場所にバックアップしていない場合は
~/.injectived/config/priv_validator_key.jsonもバックアップする - 信頼できるプロバイダーからスナップショットをダウンロードする:
- Injectiveチームがセキュリティアップグレードの前や最中に緊急スナップショットを共有する場合もあります
- Polkachu Injective Snapshots(通常goleveldb)
- コミュニティのバリデーターがインシデント時に緊急スナップショットを共有することがあります
- 古いデータを削除する:
- スナップショットを
~/.injectived/data/に展開する - バックアップしておいた
priv_validator_state.jsonを~/.injectived/data/に復元する priv_validator_state.jsonが存在し、内容が正しいことを確認する- ノードを起動する
自分の priv_validator_state.json を必ず保持しなければならない理由
スナップショットにはブロックチェーンデータ(ブロック、アプリケーションstate)が含まれますが、バリデーターの署名stateは決して含まれません。署名stateは、バリデーターが最後に署名したheight、round、stepを記録しています。これを失ったり空のファイルで置き換えたりすると、ノードは自分がすでに何に署名したかを認識できず、矛盾したブロックに署名する可能性があります。その結果、二重署名と恒久的なトゥームストーンが発生します。
署名stateが常にスナップショットのブロック高以上でなければならない理由を示す、実践的な例を挙げます。
前提: ブロック125をhalt-heightとする協調チェーンアップグレード。
priv_validator_state.json は次のようになっています:
--halt-height フラグはブロック126がコミット(ファイナライズ)されるのを防ぎますが、CometBFTコンセンサスエンジンはそれでもブロック高126に入り、アプリケーション層がブロックの処理を拒否してノードがシャットダウンするまで、そのラウンド(プロポーズ、prevote、precommit)を開始します。高いラウンド番号(42)は、バリデーターが徐々に停止していく中でコンセンサスに到達できず、ネットワークがラウンドを重ねたことを反映しています。これは正常な動作です:ブロック126は一度もファイナライズされなかったにもかかわらず、あなたのバリデーターはブロック高126で実際に投票を行ったのです。
つまり、あなたのバリデーターはすでにブロック高126、ラウンド42で投票を行っています。利用可能なスナップショットはブロック高115のものです。
署名stateなしでスナップショットを復元するとどうなるか:
スナップショットには priv_validator_state.json が含まれないか、空のもの(height 0)が付属します。この状態でノードを起動すると:
- ノードはブロック高115からブロックチェーンデータをロードする
- ブロック116〜125をリプレイしてブロック高126まで追いつく
- ブロック高126でコンセンサスに入り、ラウンド0から署名を開始する
- しかし、ネットワークにはこのブロック高でのラウンド42のあなたの投票がすでに存在する
- あなたのノードはブロック高126で別のブロック提案に署名する(新しいバイナリでリプレイしたため、異なる結果を生成する可能性がある)
- ネットワークが、あなたのバリデーターキーからの2つの矛盾した署名を検出する
- あなたのバリデーターは二重署名となり、トゥームストーンされます。恒久的に。
- ノードを停止する
priv_validator_state.jsonをバックアップする(height 126、round 42と記録されている)- データディレクトリを削除する
- スナップショット(ブロック高115からのブロックチェーンデータ)を展開する
- バックアップした
priv_validator_state.jsonをデータディレクトリに書き戻す - ノードを起動する
- ブロック高115からブロックチェーンデータをロードする
- ブロック116〜125をリプレイしてブロック高126まで追いつく
- ブロック高126で署名stateを読み取る:「ラウンド42まではすでに署名済み」
- ラウンド0〜42をスキップし、新たに署名する前にラウンド43を待つ
- 矛盾した投票は発生しません。あなたのバリデーターは安全です。
データベースバックエンドの互換性: スナップショットはバックエンド固有です。goleveldbのスナップショットはpebbledb向けに設定されたノードでは動作せず、その逆も同様です。設定を確認してください:
ロールバックがハングまたは失敗する
症状:injectived rollback は実行されるが完了しない、またはエラーを出力する。
原因:
- PebbleDBバックエンド: pebbleでのロールバックには既知の問題があり、無期限にハングする可能性があります
- 非常に大きなデータベース: ロールバック時間はデータベースのサイズに比例します
- 破損したWAL(Write-Ahead Log)
- PebbleDBノードの場合:代わりにスナップショットから復旧してください
- 大規模ノードの場合:ロールバックが30分以上経っても完了しない場合は中断し、スナップショットを使用してください
- goleveldbへの切り替えを検討してください。PebbleDBはスペース効率に優れていますが、ロールバックに関するテストは十分ではありません
キャッチアップ中のラウンド後退エラー
症状:AppHashの不一致
症状:- ロールバックを試す:
injectived rollback - ロールバックが失敗するかエラーが続く場合:スナップショットから復旧する
- 復旧後は必ず
priv_validator_state.jsonを復元する
アップグレード後にセントリーノードが停止したまま
症状: バリデーターノードはアップグレード済みで署名しているが、セントリーノードは古いブロック高で停止したままになっている。 原因: セントリーノードも、アップグレード高を超えてブロックを処理するために新しいバイナリを必要とします。 解決策: セントリーノードをバリデーターと同じバージョンのバイナリにアップグレードしてください。セントリーはpriv_validator_state.json を持ちません(署名を行わないため)が、正しいバイナリは必要です。
アップグレード後にチェーンが停滞する(投票パワー不足)
症状:- アップグレード高の後、チェーンが新しいブロックを生成しない
- コンセンサスのラウンド番号が継続的に増加する(ラウンド50、100、200以上)
- ノードはprevoteとprecommitをログに記録しているが、ブロックはコミットされない
latest_block_heightが停止高で止まったまま
- チェーンがアップグレード高で停止する(例:ブロック125)
- アップグレード済みのバリデーターがブロック高126でコンセンサスへの参加を開始する
- 各ラウンドでネットワークはブロック126のファイナライズを試みるが、投票パワーの2/3未満しか投票していないため失敗する
- ラウンド番号が増加し、サイクルが繰り返される。ラウンド1、2、3、…50、…100以上
- 十分な数のバリデーターがアップグレードを完了してオンラインになるまで、これが続く
- すでにアップグレード済みの場合: 対応は不要です。あなたのノードは参加しており、クォーラムに達すると自動的に次のブロックをファイナライズします。ノードがラウンドを追いかける間、ログにラウンド後退エラーが表示されますが、これは想定内です(キャッチアップ中のラウンド後退エラーを参照)。
- まだアップグレードしていない場合: あなたは不足している投票パワーの一部です。チェーンの再開を助けるため、できるだけ早くアップグレードを完了してください。
- 進捗を監視する: オンラインで参加しているバリデーターの数を確認する:
- バリデーターチャンネルで連携する: 大規模なアップグレードの際、バリデーターは通常、認証済みバリデーターチャンネルで連携し、アップグレードの進捗と投票パワーの割合を追跡します。
この時間帯が長引くほど、ラウンド番号は高くなります。後からオンラインになるバリデーターは、それらすべてのラウンドを追いかける必要があります。
--unsafe-consensus-timeout-precommit-delta=1ms フラグが存在するのはこのためですが、チェーンが安定したら削除することを忘れないでください。ダウンタイムによるジェイル(トゥームストーンではない)
症状:- バリデーターが非アクティブまたはジェイル状態と表示される
- 署名情報で
tombstoned: falseになっている - ブロックミスのカウンターが高い
- ノードが稼働しており、最新のブロックまで完全に追いついていることを確認する
- unjailを実行する:
- バリデーターが再びアクティブになったことを確認する:
協調アップグレードチェックリスト
アップグレード高の前
- ガバナンスプロポーザルまたはチェーンチームから、目標のhalt-heightを確認する
- 新しいバイナリをダウンロードして検証する(sha256チェックサムを確認)
- ノード設定またはCLIフラグで
--halt-height=<target_height>を設定する - Cosmovisorを使用している場合:正しいアップグレードディレクトリに新しいバイナリを配置する
-
priv_validator_state.jsonをバックアップする - ロールバックが必要になった場合に備えて、スナップショットプロバイダーを把握しておく
- チェーンが停止高に向かって進行するのを監視する
アップグレード高の時点
- ノードが想定した高さで停止したことを確認する
- ノードを完全に停止する(プロセスが終了していることを確認する)
-
priv_validator_state.jsonをバックアップする - 新しいバイナリをインストールする
- バージョンを確認する:
アップグレード後
- 新しいバイナリでノードを起動する
- コンセンサスへの参加状況をログで監視する
- prevoteが正しいことを確認する(すべてのラウンドでnilに投票していないこと)
- エクスプローラー(Mintscan)で投票パワーを監視する
-
wrong Block.Header.LastResultsHashが表示された場合:停止し、1ブロックロールバックし、priv_validator_state.jsonを復元して再起動する - ラウンドキャッチアップの上書き設定(
--unsafe-consensus-timeout-precommit-delta)を使用している場合:安定したら削除する - バリデーターが署名していることを確認する:
モニタリングリファレンス
コンセンサスと同期のステータス
バリデーターの健全性
ノード設定
プルーニングされたノードとアーカイブノードの比較
その他のリソース
スナップショットリソース
Injective提供のスナップショット
Injectiveは、2つのリージョンでプルーニングされたメインネットスナップショットを維持しています。最新の利用可能なブロック高とダウンロードURLについては、ステータスエンドポイントを確認してください:
最新のスナップショットをダウンロードするには、ステータスエンドポイントで現在のファイル名を確認してください:
コミュニティのスナップショットプロバイダー
- Polkachu Injective Snapshots(通常goleveldb、プルーニング済み)
- HighStakes Injective Snapshots
- コミュニティのバリデーターがインシデント時にバリデーターチャンネルで緊急スナップショットを共有することがあります
