cloud-sre

Polygon Erigon アーカイブノードが 87218600 ブロックで停止した問題を修正した記録

Polygon Erigon アーカイブノードが Chicago hardfork の有効化ブロックで deterministic な gas used mismatch を起こし、0xPolygon/erigon を v3.5.0 から v3.6.0 に上げて解消した調査メモ。

Jun 18, 2026
PolygonErigonarchive-nodehardforktroubleshooting

Polygon Mainnet の Erigon アーカイブノードが 87218600 ブロック付近で進まなくなった。 アーカイブノードの障害では、まずディスク、CPU、メモリ、peer 数、snapshot 破損を疑いがちだ。 しかし今回はそこに問題はなかった。

問題は、ノードが Polygon Chicago hardfork の有効化ブロックで deterministic に失敗していたことだった。 修正は、実行中の 0xPolygon/erigonv3.5.0 から v3.6.0 に上げ、同じ /data ディレクトリを使ってコンテナを起動し直すことだった。

背景

ブロックチェーンノードは、ファイルのダウンロードだけで動いているわけではない。 各ブロックを自分で再実行し、その結果がネットワーク上で受け入れられている block header と一致するかを検証している。 そのため、CPU、メモリ、ディスク I/O が足りていても、ある特定のブロックで止まることがある。 ハードウェアではなく、そのブロックから有効になる新しいルールをクライアントが知らない可能性がある。

Polygon も他の EVM チェーンと同じように、hardfork によって実行ルールを変更する。 hardfork は、指定されたブロック高で有効になるプロトコルアップグレードだ。 その時点から gas pricing、precompile の挙動、Polygon 固有の system transaction の扱いなどが変わることがある。 クライアント binary がその新ルールを含んでいない場合、ネットワークと異なる結果を計算し、そのブロックを invalid と判断する。

今回の 87218600 は Polygon Mainnet の Chicago hardfork activation block だった。 実際に動いていたノードは古い v3.5.0 build だった。 hardfork 前のブロックは replay できたが、新ルールの境界で失敗した。

用語の説明

用語意味
Archive node過去の state を保持するノード。古い block、receipt、trace、contract state を調べられる。通常の pruned node より大きなストレージが必要。
ErigonEthereum client の一つ。この記録の対象は Polygon ルールに対応した 0xPolygon/erigon
Bor mainnetPolygon PoS mainnet の execution chain。Erigon では --chain=bor-mainnet で指定する。
Hardfork特定のブロックから有効になるプロトコルルール変更。ノードはそのブロックに到達する前に対応バージョンへ上げる必要がある。
Chicago hardforkPolygon の hardfork の一つ。0xPolygon/erigon v3.6.0 release notes では Mainnet activation block が 87218600 とされている。
Gas usedブロック実行で消費された gas の合計。ノードはこれを再計算し、block header の値と比較する。
StateSyncPolygon 固有の状態同期イベント。Polygon fork 付近の execution validation に影響する場合がある。
HeimdallPolygon の consensus/checkpoint layer。Erigon は --bor.heimdall=... で remote Heimdall に接続できる。
Fork choiceどの chain head が有効かを決める処理。execution が block を invalid と判断すると、その block へ進めない。
DatadirErigon が DB や snapshot を置くディレクトリ。今回は /data

症状

ノードは最後の valid tip まで unwind し、同じ gas-used mismatch でクラッシュした。

gas used mismatch block=87218600 header=79467913 execution=62712118
Execution failed block=87218600
err="invalid block, txnIdx=186, gas used by execution: 62712118, in header: 79467913"
pos sync failed: unexpected bad block at finalized waypoint

このログでは、エラーメッセージとブロック番号をセットで見る。 ブロック番号 87218600 が手がかりだった。

この番号はランダムではない。 0xPolygon/erigonv3.6.0 release notes には、Polygon Mainnet の Chicago activation block が 87218600 と書かれており、validators、RPC providers、node operators、infrastructure partners に対して hardfork 前のアップグレードを求めている [1]

実務上の判断は次のようになる。

  • ランダムなブロックで一度だけ失敗するなら、データ、peer、リソース問題の可能性がある。
  • 同じ hardfork activation block で何度も失敗するなら、まず client version を疑う。
  • 実際に動いている binary version を確認する前に、datadir を削除して再同期すべきではない。

除外したもの

このノードはすでにアーカイブノード向けの基盤調整を済ませていた。

レイヤー状態
Storage15TB クラスのデータボリューム、高 IOPS EBS に変更済み
Memory128GB クラスのホストへ変更済み
P2P再起動後に peer は復帰
Heimdallremote Heimdall scraper は継続して進行
Snapshot data既存の /data は読めており、失敗ブロック直前まで replay 可能

再起動後、ノードはブロックを再取得して挿入できていた。

GoodPeers eth68=3
inserting fetched blocks start=87214502 end=87216293 blocks=1792

この状況は、ランダムなリソース不足や完全なネットワーク断とは違う。 毎回同じ hardfork 境界まで進み、同じ検証で失敗していた。

GitHub 上の類似 issue

0xPolygon/erigon には同系統の open issue があった。

  • Issue #143bor-mainnetv3.5.0-230b11a7 で同じ gas mismatch pattern を報告し、StateSync gas handling を疑っている [2]
  • Issue #133pos sync failed: unexpected bad block at finalized waypoint を報告している [3]
  • Issue #100 は古いバージョンで同じ gas used by execution ... in header ... pattern を報告している [4]

これらの issue だけで最終修正を証明できるわけではない。 ただし調査方針を変えるには十分だった。 これはディスクや peer の問題ではなく、client/fork rule mismatch に見えた。

決定的だったバージョン確認

実際に動いていたコンテナはまだ古い build だった。

Build info git_tag=v3.5.0-dirty git_commit=230b11a713...

v3.6.0 のソースを clone しても、実行中の binary は変わらない。 新しい Docker image を build し、その image でコンテナを起動していなければ、実行中の binary は変わらない。

確認に使ったコマンドは次の通り。

docker logs --tail 100 polygon-erigon | grep 'Build info'
docker images | grep polygon-erigon

修正前は local-v3.5.0 image しか存在していなかった。

修正

まず v3.6.0 image を build した。

docker stop polygon-erigon
rm -rf /opt/erigon-v3.6.0
git clone --branch v3.6.0 --single-branch https://github.com/0xPolygon/erigon.git /opt/erigon-v3.6.0
cd /opt/erigon-v3.6.0
DOCKER_BUILDKIT=1 docker build -t polygon-erigon:local-v3.6.0 .

次に古いコンテナを消し、同じ /data mount で新しいコンテナを起動した。

docker update --restart=no polygon-erigon
docker rm -f polygon-erigon
docker network create erigon-net 2>/dev/null || true

重要な変更は image だけだ。

polygon-erigon:local-v3.6.0

アーカイブデータは削除していない。 ノードは引き続き次の設定を使った。

--chain=bor-mainnet
--datadir=/data
--prune.mode=archive
--db.size.limit=12TB
--db.pagesize=16KB
--bor.heimdall=https://heimdall-api.polygon.technology

RPC を再び公開しないように、Docker の port publish は JSON-RPC と metrics を localhost に限定した。

-p 127.0.0.1:8545:8545
-p 127.0.0.1:6060:6060

これでローカル検証は維持しつつ、public RPC は閉じたままにできる。

検証

新しいコンテナでは期待通りの build が表示された。

Build info git_tag=v3.6.0-dirty git_commit=231d67e50b...
Initialised chain configuration ... Chicago: 87218600

起動直後には一時的な peer warning が出た。

can't use any peers to download blocks
No GoodPeers

これは一時的だった。 その後、peer が見つかり、block insertion が再開した。

GoodPeers eth68=3
inserting fetched blocks start=87214502 end=87216293 blocks=1792

検証ポイントは、以前失敗していたブロックを越えたかどうかだった。

blk=87218538
blk=87218647
blk=87218727
blk=87218801

これで v3.6.087218600 を越えたことを確認できた。 以前のエラーは再発していない。

gas used mismatch block=87218600
unexpected bad block
Execution failed

再利用できる runbook

Polygon Erigon で同種の障害に当たったら、次の順で見る。

  1. 失敗しているブロック番号を確認する。
  2. ソースディレクトリではなく、実行中 binary のバージョンを確認する。
  3. 失敗ブロックと Polygon hardfork activation block を照合する。
  4. 上流 issue で同じエラー文字列を検索する。
  5. hardfork rule を含む release へ上げる。
  6. 上流が DB format 変更を明示していない限り、既存 datadir は消さない。
  7. 失敗していた正確なブロックを越えたか確認する。

特に有用だったコマンドは次の 2 つ。

docker logs --tail 100 polygon-erigon | grep 'Build info'

そして:

docker logs --since 15m polygon-erigon | \
  grep -E 'gas used mismatch|unexpected bad block|Execution failed|polygon.sync.*crashed'

前者は実際の実行バージョンを確認する。 後者は旧エラーがまだ出ているか確認する。

学び

この障害は最初、性能問題に見えた。 すでにストレージやインスタンスサイズの調整を行っていたからだ。 しかし、性能調整では hardfork rule mismatch は直せない。

ブロックチェーンノードが同じブロックで deterministic に止まる場合、特にそれが既知の hardfork activation block であれば、client version を最初から確認対象に入れる。

References

  1. 0xPolygon/erigon v3.6.0 release notes
  2. 0xPolygon/erigon issue #143: Block 76879430 - same gas mismatch pattern
  3. 0xPolygon/erigon issue #133: pos sync failed: unexpected bad block at finalized waypoint
  4. 0xPolygon/erigon issue #100: gas used by execution mismatch
  5. Polygon documentation: Erigon archive node