cloud-sre

为什么把 Polygon Erigon 归档节点从 v3.6.0 升到 v3.6.1-beta

一次 Polygon Erigon 归档节点现场记录:v3.6.0 修复 Chicago hardfork 块后,节点仍有 peer 和同步可疑现象,于是灰度切到 v3.6.1-beta。

Jun 19, 2026
PolygonErigonarchive-nodehardforktroubleshooting

第一次升级解决了明确的问题。 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 hardforkPolygon 的一次 hardfork。0xPolygon/erigon v3.6.0 release notes 里写明 Mainnet 激活块是 87218600
Peer通过 P2P 连接上的其他节点。Erigon 需要 peer 下载区块和交换网络数据。
GoodPeersErigon 当前认为“能提供所需数据”的 peer。数量低可能是网络问题,也可能是版本、forkid 或校验行为问题。
Fork choice节点决定哪个链头有效的过程。如果执行层认为某个区块无效,fork choice 就不能推进过去。
DatadirErigon 存数据库和 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

删除 chaindataheimdallpolygon-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 相关的 ssTxs encoding / hardfork block 修复
  • post-v3.6.0 backport
  • 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.0v3.6.1-beta,不是盲目追新。 它是一次范围很窄的测试:stable 的 Chicago 版本解决了一个问题,但 post-hardfork 同步和 peer 表现仍然值得怀疑,于是测试维护 beta。

我会复用的规则是:

  • 数据库能打开、执行还在推进时,先不要删 /data
  • 每次只改一个变量
  • 公网 RPC 继续关闭
  • 看实际运行中的 Docker image,不看磁盘上的源码目录
  • beta 版本只能当可回滚的运维测试,不能当永久假设

参考

  1. 0xPolygon/erigon v3.6.0 release notes
  2. 0xPolygon/erigon issue #154: "No GoodPeers" after upgrading to v3.6.0
  3. 0xPolygon/erigon v3.6.1-beta release notes
  4. Polygon documentation: Erigon archive node