cloud-sre
Polygon Erigon アーカイブノードを v3.6.0 から v3.6.1-beta に上げた理由
Chicago hardfork 対応の v3.6.0 でブロック 87218600 は越えられたが、peer と post-hardfork sync の挙動がまだ不安定だったため v3.6.1-beta を試した記録。
最初のアップグレードで、分かりやすい失敗は直った。
v3.5.0 は Polygon Mainnet の 87218600 ブロックを越えられなかった。
ここは Chicago hardfork の activation block だった。
0xPolygon/erigon v3.6.0 に上げると Chicago ルールが入り、ノードはそのブロックを越えた。
ただし、次の問題はもっと曖昧だった。
v3.6.0 でもノードは進むが、peer が少なく、hardfork 後の sync ログにも気になる行が残った。
security group の問題ではなかった。
public P2P は外から到達でき、JSON-RPC は public に出しておらず、local RPC は使えていた。
そこで /data を消してやり直すのではなく、rollback 前提で v3.6.1-beta を試した。
用語の説明
| 用語 | 意味 |
|---|---|
| Archive node | 過去の state を保持するノード。古い receipt、trace、contract state を調べられる。pruned node より大きなディスクが必要。 |
| Hardfork | 特定のブロックから有効になるプロトコルルール変更。ノードはそのブロックに到達する前に対応バージョンを動かす必要がある。 |
| Chicago hardfork | Polygon の hardfork。0xPolygon/erigon v3.6.0 release notes では Mainnet activation block が 87218600 とされている。 |
| Peer | P2P で接続する他のノード。Erigon は peer から block や network data を受け取る。 |
| GoodPeers | Erigon が現在「必要なデータを提供できる」と見ている peer。少ない理由は network、version、forkid、validation のどれでもあり得る。 |
| Fork choice | どの chain head が有効かを決める処理。execution が block を invalid と判断すると、そこへ進めない。 |
| Datadir | Erigon が database と snapshot を置くディレクトリ。今回は /data。 |
| Beta release | pre-release build。重要な修正を含む場合があるが、rollback できる形で試す。 |
v3.6.0 で直ったこと
前回の失敗は同じ場所で再現していた。
gas used by execution: 62712118, in header: 79467913, headerNum=87218600
pos sync failed: unexpected bad block at finalized waypoint
手がかりはブロック番号だった。
v3.6.0 release notes には、Chicago hardfork に必要な変更が入っており、Polygon Mainnet の activation block が 87218600 と書かれている [1]。
polygon-erigon:local-v3.6.0 を build して起動すると、ログはこう変わった。
Build info git_tag=v3.6.0-dirty git_commit=231d67e50b...
Initialised chain configuration ... Chicago: 87218600
その後、ノードは失敗していたブロックを越えた。
blk=87218538
blk=87218647
blk=87218801
この時点で、v3.6.0 は Chicago ルール不一致を直す正しい upgrade だった。
ただし、それで chain tip まで完全に追いついたわけではない。
まだ気になったこと
v3.6.0 へ上げた後も、peer 周りのログは弱かった。
何度か次のような行が出た。
[sync] can't use any peers to download blocks, will try again in a bit
[p2p] No GoodPeers
このログは文字通りに受け取りすぎない。 EC2 security group や Docker port mapping が間違っているとは限らない。 今回は public P2P port へ外部から接続できた。
nc -vz <node-public-ip> 30303
Docker の port publish も想定通りだった。
30303/tcp -> 0.0.0.0:30303
30303/udp -> 0.0.0.0:30303
42069/udp -> 0.0.0.0:42069
8545/tcp -> 127.0.0.1:8545
6060/tcp -> 127.0.0.1:6060
この形にしている理由は明確だ。 P2P は public に出す。 JSON-RPC と metrics は local に閉じる。
upstream issue #154 でも、v3.6.0 へ上げた後に No GoodPeers と can't use any peers to download blocks が出る事例が報告されている [2]。
それだけで同じ故障だとは断定できない。
ただ、P2P 到達性が確認できているなら、次に見るべき場所は client version、forkid、hardfork 後の sync behavior になる。
datadir を消さなかった理由
chaindata、heimdall、polygon-bridge を消すと、archive node では大きな作業になる。
version の切り分けが、長時間の restore 作業に変わってしまう。
この時点の証拠では、そこまでする理由はなかった。
/data/chaindataは開けていた。- checkpoint range は download できていた。
- fetched blocks は insert できていた。
Executionstage に入っていた。87218600はすでに越えていた。
よりきれいな比較は、client build だけを変えて同じ /data を使うことだった。
同じ disk、同じ snapshot、同じ instance、同じ network boundary のまま、Erigon だけを変える。
v3.6.1-beta を試した理由
v3.6.1-beta は pre-release なので、最初から常用前提にはしない。
それでも試した理由は changelog にある。
release notes では maintenance release とされ、次のような修正が入っている。
- execution と P2P の
ssTxsencoding / hardfork block 修正 - post-
v3.6.0backport - deterministic state sync
- Polygon-specific fork に関する P2P forkid 調整
見ていた症状は、Chicago 後の execution、peer compatibility、sync validation 周辺だった。 changelog の範囲と重なっていた [3]。
起動パラメータ
runtime の形は変えない。
中心の変更は image を polygon-erigon:local-v3.6.0 から polygon-erigon:local-v3.6.1-beta にすることだった。
EXT_IP="$(curl -sS http://169.254.169.254/latest/meta-data/public-ipv4)"
sudo docker run -d \
--name polygon-erigon \
--restart unless-stopped \
--network erigon-net \
--log-driver=json-file \
--log-opt max-size=100m \
--log-opt max-file=5 \
-v /data:/data \
-p 127.0.0.1:8545:8545 \
-p 30303:30303 \
-p 30303:30303/udp \
-p 42069:42069/udp \
-p 127.0.0.1:6060:6060 \
polygon-erigon:local-v3.6.1-beta \
--chain=bor-mainnet \
--datadir=/data \
--prune.mode=archive \
--db.size.limit=12TB \
--db.pagesize=16KB \
--metrics \
--metrics.addr=0.0.0.0 \
--metrics.port=6060 \
--http \
--ws \
--http.addr=0.0.0.0 \
--http.vhosts='*' \
--http.port=8545 \
--http.api=web3,net,eth,trace \
--private.api.addr=127.0.0.1:9090 \
--torrent.port=42069 \
--bor.heimdall=https://heimdall-api.polygon.technology \
--rpc.batch.concurrency=16 \
--rpc.batch.limit=5000 \
--rpc.returndata.limit=5000000 \
--maxpeers=200 \
--log.dir.path=/data/logs \
--log.dir.prefix=erigon \
--log.dir.verbosity=info \
--verbosity=3 \
--nat=extip:${EXT_IP}
--nat=extip:${EXT_IP} は重要だ。
古い public IP を advertise すると、peer が正しく戻ってこられない場合がある。
切り替え後に見たもの
最初に、実際に動いている build を見る。
sudo docker logs --tail 100 polygon-erigon | egrep 'Build info|Public IP|Starting Erigon'
期待するログは次の形だ。
Build info git_tag=v3.6.1-beta-dirty
[torrent] Public IP ip=<node-public-ip>
Starting Erigon on Bor Mainnet...
次に port を確認する。
sudo docker port polygon-erigon
期待する形はこうなる。
8545/tcp -> 127.0.0.1:8545
6060/tcp -> 127.0.0.1:6060
30303/tcp -> 0.0.0.0:30303
30303/udp -> 0.0.0.0:30303
42069/udp -> 0.0.0.0:42069
最後に sync の進み方を見る。
sudo docker logs -f polygon-erigon | \
egrep 'GoodPeers|No GoodPeers|bad block|fork choice|Execution|inserting fetched blocks|update fork choice'
upgrade 後の有効なログはこうだった。
inserting fetched blocks start=87269286 end=87271077 blocks=1792
inserting fetched blocks start=87271078 end=87274917 blocks=3840
update fork choice block=87274917
GoodPeers eth69=3 eth68=3
[4/6 Execution] blk=87269385 blks=52 blk/s=2.6
peer 数はまだ多くない。 それでもノードは進んでいる。 ここを分けて見る。 peer が少ないだけなら観察を続ける。 peer が少なく、block insertion もなく、Execution も進まず、bad-block が繰り返されるなら止まっている。
rollback の境界
rollback は単純にしておいた。
sudo docker stop polygon-erigon
sudo docker rm polygon-erigon
その後、同じコマンドで image だけ戻す。
polygon-erigon:local-v3.6.0
次のどれかが出たら戻す判断にする。
fork choice update bad blockが繰り返されるunexpected bad blockが繰り返される- 複数回見ても
Executionが進まない - P2P 到達性を確認済みなのに block insertion がない
この切り替えでは、最初の信号はそこまで悪くなかった。 download、insert、fork choice update、execution が続いた。
残した判断
v3.6.0 から v3.6.1-beta への移行は、単に新しいものへ寄せたわけではない。
stable な Chicago 対応版で一つ目の問題は直った。
ただし post-hardfork sync と peer の挙動にまだ疑わしい点が残り、maintenance beta の修正範囲と重なった。
そのため、rollback できる形で試した。
同じ状況なら、次の順序にする。
- database が開けて execution が進むなら、まず
/dataは消さない - 一度に変えるものは一つにする
- public RPC は閉じたままにする
- disk 上の source directory ではなく、実際に動いている Docker image を見る
- beta build は戻せる運用テストとして扱う