cloud-sre
为什么把 Polygon Erigon 归档节点从 v3.6.0 升到 v3.6.1-beta
一次 Polygon Erigon 归档节点现场记录:v3.6.0 修复 Chicago hardfork 块后,节点仍有 peer 和同步可疑现象,于是灰度切到 v3.6.1-beta。
第一次升级解决了明确的问题。
v3.5.0 不能越过 Polygon Mainnet 87218600 区块,也就是 Chicago hardfork 激活块。
升级到 0xPolygon/erigon v3.6.0 后,节点认识了 Chicago 规则,并且跨过了这个区块。
第二个问题没有那么干净。
到了 v3.6.0 后,节点还能继续跑,但 peer 表现偏弱,hardfork 后的同步日志仍然有可疑信号。
这不是 security group 问题:公网 P2P 可达,JSON-RPC 仍然没有暴露到公网,本机 RPC 也能用。
所以更稳的下一步不是删 /data 重来,而是带回滚边界测试 v3.6.1-beta。
文中用语说明
| 用语 | 含义 |
|---|---|
| Archive node / 归档节点 | 保存历史状态的节点,可以查老区块的 receipt、trace、合约历史状态。它比普通裁剪节点需要更多磁盘。 |
| Hardfork | 从某个指定区块开始生效的协议规则升级。节点必须在到达这个区块前运行认识新规则的版本。 |
| Chicago hardfork | Polygon 的一次 hardfork。0xPolygon/erigon v3.6.0 release notes 里写明 Mainnet 激活块是 87218600。 |
| Peer | 通过 P2P 连接上的其他节点。Erigon 需要 peer 下载区块和交换网络数据。 |
| GoodPeers | Erigon 当前认为“能提供所需数据”的 peer。数量低可能是网络问题,也可能是版本、forkid 或校验行为问题。 |
| Fork choice | 节点决定哪个链头有效的过程。如果执行层认为某个区块无效,fork choice 就不能推进过去。 |
| Datadir | Erigon 存数据库和 snapshot 的目录。这里是 /data。 |
| Beta release | 预发布版本。它可能包含关键修复,但上线前要有明确回滚方式。 |
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 激活块是 87218600 [1]。
重新构建并启动 polygon-erigon:local-v3.6.0 后,日志里出现:
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 规则不匹配的正确版本。
但这不等于节点已经完全追上链头。
还有哪里不对劲
升级到 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 端口映射错了。 这次公网 P2P 端口从外部能连通:
nc -vz <node-public-ip> 30303
Docker 的端口映射也是预期状态:
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 保持公网开放。 JSON-RPC 和 metrics 只留给本机。
上游 issue #154 也记录了类似现象:升级到 v3.6.0 后出现 No GoodPeers,日志里有 can't use any peers to download blocks [2]。
这个 issue 不能直接绑定到每一台节点。
但它给了一个排查方向:如果 P2P 连通性检查通过,下一层就该看客户端版本、forkid 和 hardfork 后同步行为。
为什么没有删除 datadir
删除 chaindata、heimdall 或 polygon-bridge,对归档节点来说代价很高。
这会把一个版本判断问题,变成一次漫长的恢复问题。
当时本机证据不支持这么做:
- 节点能打开
/data/chaindata。 - 节点能下载 checkpoint 区间。
- 节点能插入下载到的区块。
- 节点能进入
Execution阶段。 - 节点已经跨过
87218600。
更干净的测试是:只换客户端 build,保留同一个 /data。
这样对比更明确:同一块盘、同一份 snapshot、同一台机器、同一个网络边界,只换 Erigon 版本。
为什么测试 v3.6.1-beta
v3.6.1-beta 是 pre-release,不是默认最保守选择。
这次愿意测试它,是因为 changelog 指向了我们正在看的区域。
release notes 说它是 maintenance release,包含 bug fixes,其中包括:
- execution 和 P2P 相关的
ssTxsencoding / hardfork block 修复 - post-
v3.6.0backport - deterministic state sync
- Polygon-specific fork 的 P2P forkid 调整
这些正好对应这次可疑区域:Chicago 后的执行、peer 兼容性、同步校验 [3]。
启动参数
运行形态不变。
唯一核心变化是镜像从 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} 不能随便写。
如果节点对外广播的是旧公网 IP,peer 可能连不回来。
切换后看什么
先确认实际运行版本:
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...
再确认端口:
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
最后看同步:
sudo docker logs -f polygon-erigon | \
egrep 'GoodPeers|No GoodPeers|bad block|fork choice|Execution|inserting fetched blocks|update fork choice'
升级后的有用日志是:
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 少,同时没有插入区块、没有执行推进、反复 bad-block,才是停止项。
回滚边界
回滚方式很简单:
sudo docker stop polygon-erigon
sudo docker rm polygon-erigon
然后用同一套参数,把镜像换回:
polygon-erigon:local-v3.6.0
如果 v3.6.1-beta 出现下面这些情况,我会回滚:
- 反复
fork choice update bad block - 反复
unexpected bad block - 多次采样都没有
Execution推进 - P2P 连通性已经确认,但仍然不插入区块
这次早期信号没有走到这些条件。 节点继续下载、插入、更新 fork choice,并且进入执行。
留下的判断
这次从 v3.6.0 到 v3.6.1-beta,不是盲目追新。
它是一次范围很窄的测试:stable 的 Chicago 版本解决了一个问题,但 post-hardfork 同步和 peer 表现仍然值得怀疑,于是测试维护 beta。
我会复用的规则是:
- 数据库能打开、执行还在推进时,先不要删
/data - 每次只改一个变量
- 公网 RPC 继续关闭
- 看实际运行中的 Docker image,不看磁盘上的源码目录
- beta 版本只能当可回滚的运维测试,不能当永久假设