Skip to content

fix(p2p): keep the established dht identity instead of replacing it at runtime - #1408

Merged
vipwzw merged 2 commits into
masterfrom
fix/dht-keep-established-identity
Oct 16, 2026
Merged

vipwzw merged 2 commits into
masterfrom
fix/dht-keep-established-identity

Conversation

@vipwzw

@vipwzw vipwzw commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

问题

v1.72.1 重新落地空投索引修复后,doGenAirDropKey 里「用钱包空投地址替换节点身份并 reStart()」这条路径开始真的执行:

  • waitPid=false(bityuan.toml / chain33.toml 默认)时,initP2P 先 Randkey() 生成并持久化一个身份,host 用它对外发布 peer id;
  • 钱包就绪后 doGenAirDropKey 取到钱包派生身份,与 addrbook 不同就 saveKey(钱包身份) + reStart() —— 节点在运行期换了 peer id。

索引演化的准确线索(review 更正):

时间 提交 说明
09-22 53d304ea8 把索引改成 airDropIndex(纳秒+pid);11 分钟后被 b890d1d38 回滚,回滚信息原文:"Reverts the airdrop index change so an existing node's peer ID stays the same" —— 当时就已知「改索引 = 改已有节点 peer id」
09-23 ec5476309 / 563e80d77 / d2a16d33b 以「索引必须落在钱包合法区间」为由重新落地(ec5476309 起 randIndex 恒落在 [1e8, 1.01e8]),没有再处理身份问题

因此:≤ v1.72.0 时索引约 99% 越界(isValidIndex 拒绝),替换路径事实上不可达,身份稳定;v1.72.1 起替换是确定性的 —— 每个新节点在钱包解锁后约 1 秒必换一次,一个钱包只换一次(空投索引 sticky)。

影响:任何按 peer id 配置了本节点的对端都会失效(peering 列表、TSS peers、白名单)。plugin ci_rgbx 即被此打断。

修复

节点身份一旦在 addrbook 里持久化(peer id 已对外发布),就不再在运行期用钱包空投地址替换;钱包派生身份只在节点还没有身份时采用。waitPid=true 且 addrbook 为空时,仍在 host 启动前用空投地址确定身份(原语义保留)。

// 节点身份一旦在 addrbook 里持久化, 就不再在运行期用钱包空投地址替换它 ...
if savePrivkey != "" {
    log.Info("genAirDropKey", "keep the established dht identity, skip the airdrop key replacement")
    return false
}
p.addrBook.saveKey(walletPrivkey, walletPubkey)
return true

同时按 review 收尾:

  • 钱包导入把 ErrPrivkeyExist(身份已在钱包里)当成功,名字冲突时不再 sleep 1s,其它错误打日志后放弃 —— 修复后「addrbook 身份 ≠ 钱包空投键」成为常态,避免每次重启多等 1 秒并刷出像失败的 Error;
  • 修正 initP2P 与导入块的过时注释,并按 review 更正守卫注释(真实条件是 waitPid=false 时 initP2P 已落盘身份 ⇒ 这类节点不会采用钱包身份)。

测试

system/p2p/dht/p2p_airdrop_identity_test.go:

用例 钉住什么
TestP2PHostIdentityStableAfterWalletReady 真 host 回归:真 queue + 真 host + 真 leveldb addrbook + 钱包 mock 返回另一把钥;钱包就绪后轮询 host.ID() 与 addrbook 身份不变。去掉守卫时 1.2s 内 FAIL(既有 Test_p2p 仍通过,这正是该缺陷能上线的原因)
TestGenAirDropKeyKeepsEstablishedIdentity 已有身份 + 钱包身份不同 → 不替换、不请求重启、addrbook 不变,且 WalletImportPrivkey 被调用(守卫必须在导入之后)
TestGenAirDropKeyKeepsEstablishedIdentityWithWaitPid waitPid=true + 已有另一把身份 → 同样不替换(收窄守卫会 FAIL)
TestGenAirDropKeyAdoptsWalletKeyWithoutIdentity 无身份 → 采用钱包身份,且不调用导入(导入块由 !WaitPid 门控)
TestGenAirDropKeySameKeyReturnsEarly 同密钥提前返回分支(并注明它不钉新守卫)

变异矩阵(review 指出原三个用例拦不住,现已全部拦下):

变异 结果
守卫整体去掉 ...KeepsEstablishedIdentity、...WithWaitPid、真 host 用例 FAIL
守卫收窄为 savePrivkey != "" && !WaitPid ...WithWaitPid FAIL
跳过钱包导入块(等价于守卫上提) ...KeepsEstablishedIdentity FAIL

go test ./system/p2p/... 全绿(dht 包连跑两遍稳定)。

验证(证据等级说明)

plugin 侧用临时诊断分支(重启前后各打印 peer 名,超时导出容器日志)指向本提交跑 ci_rgbx:

  • 修复前(v1.72.6):t=20s/60s 看到的 peer 名与写进 TSS peers 配置的零交集 → auto DKG commit timeout;
  • 修复后:重启前后同一批 ID,auto DKG done,ci_rgbx pass 5m29s;
  • 对照:同一 plugin 代码在 chain33 v1.72.0 上也通过(替换路径不执行);
  • 与本仓库已合入的创世分叉无关:把 ForkGenesisOnlyAtHeightZero 配成 -1 后仍复现。

证据等级:以上来自 CI job 日志与本提交上的可执行用例;ci_rgbx harness 另有若干已文档化的成因会产生同一条失败串,本 PR 未逐个排除其历史偶发(仓内 rgbx-e2e.log 不是现场日志,未作为依据)。

未覆盖

plugin/p2p/gossip/p2p.go 有一份同构的「 ResetPeerkey + ReStart」运行期换身份实现,未被本次修复覆盖;当前配置均为 types=["dht"],暂时不受影响,另案处理。

…t runtime

v1.72.1 修好空投索引取值范围后(53d304ea8 等),doGenAirDropKey 里“用钱包空投地址
替换节点身份并 reStart()”这条路径开始真的执行:

- waitPid=false 时 initP2P 先生成并持久化一个随机身份,host 用它对外发布 peer id;
- 钱包就绪后 doGenAirDropKey 取到钱包派生身份,与 addrbook 不同就 saveKey + reStart,
  于是节点在运行期换了 peer id。

任何按 peer id 配置了本节点的对端都会失效。plugin 的 ci_rgbx 就是这样被打断的:
它在重启前发现 4 个 para 节点的 peer 名写进 TSS peers 配置,钱包就绪后节点身份变化,
配置里的 peers 与实际运行身份零交集,DKG 无法形成,auto DKG commit 必然超时
(实测 t=20s/60s 看到的 peer 名与配置零交集;关掉本仓库的创世分叉仍复现,与本分叉无关)。

修复:节点身份一旦在 addrbook 里持久化就不再在运行期替换;钱包派生身份只在节点还没有
身份时采用(waitPid=true 时会在 host 启动前确定身份,原语义不变)。

测试:新增 system/p2p/dht/p2p_airdrop_identity_test.go
- 已有身份且钱包身份不同 → 不替换、不请求重启、addrbook 不变
- 无身份 → 采用钱包身份
- 两边身份相同 → 保持原状
变异验证:去掉该分支后 TestGenAirDropKeyKeepsEstablishedIdentity 失败。
go test ./system/p2p/... 全绿。
vipwzw pushed a commit to 33cn/plugin that referenced this pull request Oct 16, 2026
依赖从 v1.72.0 回移版换成 v1.72.7-0.20261016053907-a95e7f042582(chain33 分支
fix/dht-keep-established-identity,33cn/chain33#1408):

- v1.72.6 已经包含本 PR 需要的系统分叉 ForkGenesisOnlyAtHeightZero(33cn/chain33#1407),
  但仍带着 v1.72.1 引入的回归:钱包就绪后 dht 用钱包空投地址替换节点身份并 reStart(),
  运行期更换 peer id;
- plugin 的 ci_rgbx 正是被这条路径打断(重启前发现的 TSS peers 与运行身份零交集,
  auto DKG commit 超时),与创世分叉无关(把它配成 -1 仍复现);
- 切到该修复后 ci_rgbx 通过(5m29s,重启前后 peer 名保持不变),因此不再需要
  v1.72.0 回移分支,等 chain33 发布 v1.72.7 后可换成正式版本号
- go test ./plugin/dapp/ticket/... 全绿
@vipwzw

vipwzw commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

plugin 侧验证(修复前后对照,同一份 plugin 代码)

用带诊断分支(重启前后各打印一次 peer 名,超时导出容器日志)指向本提交跑 ci_rgbx:

修复前(chain33 v1.72.6)— 失败,且 peer 身份确实被换掉:

[04:13:38] discovered TSS_PEERS = ...EkvCZ1a, ...LCnQMU4, ...Q1kR4nwn, ...VifrVrMe   ← 写进 TSS peers 配置
[04:13:38] rewrite TSS peers + restart para1-4
[04:14:24] DIAG t=20s peer names(now) = ...6Ysw8jJB, ...H1vShBXK, ...HZQZQBek, ...MGYhiafK   ← 与配置零交集
[04:15:11] DIAG t=60s peer names(now) = 同上
[04:16:22] ERROR: auto DKG commit timeout

修复后(本提交)— 通过,身份保持不变:

[05:44:42] discovered TSS_PEERS = ...AnyzJEp, ...Df54LZht, ...TZuq7ujC, ...
[05:44:57] DIAG peer names(after restart) = 同一批 ID(不再是新身份)
[05:45:10] auto DKG done, tssAddress=bcrt1qk4p34rp4xejynln8edetul79gs62a7uqawwh8p

ci_rgbx pass 5m29s;作为对照,同一 plugin 代码在 chain33 v1.72.0 上也通过(因为那时空投索引越界,替换路径实际不执行)。

另外确认与本仓库已合入的创世分叉无关:把 ForkGenesisOnlyAtHeightZero 配成 -1(守卫完全不生效)后,ci_rgbx 在 v1.72.6 上仍复现该超时。

go test ./system/p2p/... 全绿;变异验证见 PR 描述。

@vipwzw
vipwzw requested review from bysomeone and libangzhu October 16, 2026 06:11
@bysomeone

Copy link
Copy Markdown
Collaborator

结论:可合

这 11 行守卫的必要性已被独立复现:去掉它,真 host 的 peer id 会在钱包解锁后约 1.1 秒变化(三次运行全部复现,16Uiu2HAm… → 16Uiu2HA…);保留则 peer id 不变。既有的 Test_p2p 在去掉守卫时照样通过(它不等异步路径就退出了)——这也是该缺陷能上线的原因。

建议在本 PR 内补的两处测试

  1. 真 host 的 peer id 稳定性回归:仓内现成的 NewP2p + testnode 助手就能搭起来(真 queue + 真 host + 真 leveldb addrbook + 钱包 mock 返回另一把钥),记下 host.ID() 后轮询即可,去掉守卫即 FAIL。比依赖 plugin 侧的 ci_rgbx 划算得多。
  2. "addrbook 身份与钱包空投键不同"那一支(约 10 行):目前三个新用例里只有 TestGenAirDropKeyKeepsEstablishedIdentity 真的钉住守卫——把守卫收窄成 savePrivkey != "" && !p.p2pCfg.WaitPid、或者把它上提到导入块之前,三个用例全绿。前者会让"运行期换身份"回归,后者会静默跳过身份密钥的钱包备份。在 test1/test2 里补 AssertExpectations 可以把导入顺序变成契约。

表述上的四处更正

  1. 注释末句"钱包派生身份只在节点还没有身份时使用":非 waitPid 路径上 initP2P 已经先 Randkey() 落盘一把钥,守卫读到非空即返回 ⇒ 这类节点不会采用钱包身份。这是本次修复的意图,但注释写的是另一回事。
  2. "waitPid=true 时…原语义不变"不成立,不过条件不是 waitPid:initP2P 只在 addrbook 为空时才读 WaitPid。真正的条件是"addrbook 身份 ≠ 钱包空投键"(需要钱包重置 / 换助记词 / addrbook 还原这类运维异常才会出现),此时旧代码换身份并重启、新代码保留;且该路径下保留下来的身份不会进入钱包(导入块被 !WaitPid 门控)。
  3. "约 99% 会被 isValidIndex 拒绝"对应的是 ≤v1.72.0 那代生成器([1e8,2e8),命中率 1,000,001/100,000,000)。在 v1.72.1–v1.72.6 这个修复目标区间里 airDropIndex 恒落在合法区间 ⇒ 换身份是确定性的:每个新节点在钱包解锁后约 1 秒必换一次,一个钱包一生只换一次(空投索引 sticky)。这其实加强了修这个问题的动机,只是现表述容易读成"间歇性"。
  4. 提交信息与正文引的 53d304ea8 在 11 分钟后被 b890d1d38 回滚(其 body 原文即 "Reverts the airdrop index change so an existing node's peer ID stays the same"),v1.72.1 里重新落地的是 ec5476309 / 563e80d77 / d2a16d33b。改引后者并带上这段回滚史,线索才完整——那次回滚本身说明"改空投索引 = 改已有节点的 peer id"当时就已被认识到,只是重新落地时没把守卫一起带回来。

两点说明(不要求改动)

  • TestGenAirDropKeySameIdentityNoRestart 在 :489 的同密钥提前返回处就退出了,对本次新守卫零拦截力,命名与注释容易让人以为它在钉守卫。
  • 守卫让 savePrivkey != walletPrivkey 成为常态,于是"把身份导入钱包"那块每次启动都会执行:真实钱包下会先撞 ErrLabelHasUsed(睡 1 秒)再撞 ErrPrivkeyExist,即每次启动多约 1 秒与一条 ERROR 日志(修复前这个导入只发生一次)。属既有代码被本次修复放大,未在真实钱包上实跑,仅供留意。

另外两点(供参考)

  • ci_rgbx 的因果链在代码层是通的(换 id ⇒ 配置的 TSS peers 与已连 peer 零交集 ⇒ waitPeersReady 不返回 ⇒ DKG commit 超时)。不过同一 harness 另有已文档化的成因(如 nodegroup approve 前重启 para、para 重启后钱包上锁、AUTH 未重新 import)会产生同一条失败串,而仓内那份 rgbx-e2e.log 实际只是 go build 的包路径列表,没有可复核的现场日志,所以这条的证据等级建议在正文里标注清楚。
  • plugin/p2p/gossip/p2p.go 有一份同构的"ResetPeerkey + ReStart"运行期换身份实现,未被本次修复覆盖(现所有配置都是 types=["dht"],暂不受影响)。

覆盖边界

审了 doGenAirDropKey 的全部路径与调用点、initP2P 的三条身份分支、reStart 链路、addrbook 的持久化与校验、ec5476309 前后的索引范围演化、新测试的变异矩阵与覆盖率;未跑 CI / E2E,未复核 ci_rgbx 现场日志,未实跑 TSS/DKG 协议层,未审 chain33 之外的其它 dht 实现(除上述 gossip 一条)。

@bysomeone bysomeone left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 详细结论与两处补测试的建议见评论:#1408 (comment)

@libangzhu libangzhu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议批准。这个改动是对的,没有必须改完才能合的问题。

这个 PR 在修什么

waitPid=false 时,节点先用一把随机私钥启动,这个 peer id 已经告诉别的节点了。等钱包准备好,旧代码会把 peer id 换成助记词推导出来的那把钥匙,然后重启。v1.72.1 把空投地址的索引修好之后,这条路才真的走到。peer id 换一次,之前按旧 id 配好的连接就全失效。评论里 ci_rgbx 的 TSS 超时就是这个原因。空投索引写入钱包后会一直返回同一把私钥,所以只换这一次。

这次改完,addrbook 里已经有私钥就保持不动,不再换、也不再重启。waitPid=true 并且 addrbook 还没有私钥时,仍会在 host 启动前把助记词私钥写进去。

两种节点升级后会怎样

已经换成助记词 peer id 的节点,升级后还是这把钥匙,不会退回原来的随机私钥。

addrbook 里只存一把私钥。当初替换的时候,助记词私钥已经把随机私钥盖掉了,然后节点才重启。现在对外用的是助记词 peer id,说明磁盘上存的就是这把。升级后读出来继续用。原来的随机私钥如果还在,只在钱包账户 dht node award 里,不会再写回 addrbook。

waitPid=false 时,随机私钥一旦写进 addrbook,这个 peer id 就固定了。后来钱包里有了助记词,也不会再换。

没有私钥时,节点先生成一把随机私钥并存下来,再用它启动。钱包就绪后,只是把这把随机私钥复制进钱包(账户名 dht node award),方便备份。助记词推导的空投地址也会在钱包里建出来,但它只是钱包里的另一个账户,不会变成节点的 peer id。

这把钥匙一直有效的前提是 addrbook 里这条记录还在、还能读出来。记录被删掉或者损坏时,下次启动会再生成一把新的随机私钥,仍然不会改用助记词。

建议改一下,不改也能合

每次重启会多一次多余的导入。 身份固定之后,addrbook 里是随机私钥,钱包空投账户是另一把钥匙,两把永远对不上,所以每次启动都会再去钱包里导入一次节点私钥。

// system/p2p/dht/p2p.go:509-528
if savePrivkey != "" && !p.p2pCfg.WaitPid {
    var parm types.ReqWalletImportPrivkey
    parm.Privkey = savePrivkey
    parm.Label = "dht node award"
    for {
        _, err = p.api.ExecWalletFunc("wallet", "WalletImportPrivkey", &parm)
        if err == types.ErrLabelHasUsed {
            parm.Label = fmt.Sprintf("node award %d", rand.Int31n(1024000))
            time.Sleep(time.Second)
            continue
        }
        break
    }
}

钱包先看账户名,再看这把私钥在不在:

// wallet/wallet_proc.go:516-549
if Account != nil && err == nil {
    walletlog.Error("ProcImportPrivKey Label is exist in wallet!")
    return nil, types.ErrLabelHasUsed
}
// ...
if existDec := wcom.CBCDecrypterPrivkey([]byte(wallet.Password), existPriv); len(existDec) == len(privkeybyte) && string(existDec) == string(privkeybyte) {
    walletlog.Error("ProcImportPrivKey Privkey is exist in wallet!")
    return nil, types.ErrPrivkeyExist
}

第一次启动,名字还没用过,导入成功。以后每次启动只再走两步就退出,不会一直循环,也不挡已经启动的 host:名字 dht node award 已占用,睡 1 秒再换一个新名字;私钥上次已经导入过,就结束。每次重启多等 1 秒,日志里多两条看起来像失败的 Error。其它导入错误在这里被直接丢掉,p2p 没有日志。这把随机私钥助记词推不出来,第一次导入如果真失败,钱包里就没有备份。

建议把「私钥已经在钱包里」当成成功,名字冲突时不要先睡 1 秒,其它错误打日志:

_, err = p.api.ExecWalletFunc("wallet", "WalletImportPrivkey", &parm)
if err == nil || err == types.ErrPrivkeyExist {
    break
}
if err == types.ErrLabelHasUsed {
    parm.Label = fmt.Sprintf("node award %d", rand.Int31n(1024000))
    continue
}
log.Error("genAirDropKey", "WalletImportPrivkey err", err)
break

测试还差一点点。 「两把私钥相同」那个用例在比较时就返回了,没走到这次新增的判断。「已有身份不替换」那个用例,如果创建空投账户失败,也会返回不替换,测试照样能过,而且没有检查钱包导入是否真的被调用。建议把这两个调用断言出来。再补一条:waitPid=true 但 addrbook 里已经有另一把私钥时,也不替换。

两处旧注释会误导人。 一处还写着「先用临时 peer id,等钱包建好再换」。另一处还写着「保证最后用空投地址」。按这次的行为,addrbook 里已经存下的身份不再换。注释改成这句话就行。

…ixture

处理 #1408 review(bysomeone / libangzhu):

测试补强(三位 reviewer 都点到现有三个用例拦不住收窄/移动守卫):
- 新增真 host 回归 TestP2PHostIdentityStableAfterWalletReady:真 queue + 真 host +
  真 leveldb addrbook + 钱包 mock 返回另一把钥,钱包就绪后轮询 host.ID() 与 addrbook
  身份。去掉守卫时 1.2s 内 FAIL(与 review 实测的 ~1.1s 一致),而既有 Test_p2p 仍通过。
- 新增 TestGenAirDropKeyKeepsEstablishedIdentityWithWaitPid:waitPid=true 且 addrbook
  已有另一把钥时同样不得替换 —— 收窄成 `savePrivkey != "" && !WaitPid` 时该用例 FAIL。
- 前两个用例分别断言 WalletImportPrivkey 被调用/未被调用,把“守卫必须在导入之后”变成
  契约:跳过导入块(等价于守卫上提)时 KeepsEstablishedIdentity FAIL。
- TestGenAirDropKeySameIdentityNoRestart 改名为 ...SameKeyReturnsEarly 并注明它钉的是
  同密钥提前返回,不是本次守卫。

代码(libangzhu 建议):
- 钱包导入把 ErrPrivkeyExist(身份已在钱包里)当成功,名字冲突时不再 sleep 1 秒,
  其它错误打日志后放弃;避免修复后每次重启多等 1 秒并刷出像失败的 Error。

注释(bysomeone 更正):
- initP2P 的“生成临时 pid,待创建钱包之后替换”已不成立,改为“身份一经发布不再更换,
  钱包就绪后只把它导入钱包备份”。
- 守卫注释去掉“waitPid=true 原语义不变”,写明真实条件:waitPid=false 时 initP2P 已
  Randkey() 落盘身份,这类节点不会采用钱包身份;只有 addrbook 无身份且 host 启动前
  拿到空投地址(waitPid=true)才用它作身份。

线索更正:v1.72.1 里重新落地空投索引的是 ec54763 / 563e80d / d2a16d3;
最早的 53d304e 在 11 分钟后被 b890d1d 回滚,回滚信息原文即
"Reverts the airdrop index change so an existing node's peer ID stays the same" ——
说明“改索引 = 改已有节点 peer id”当时已被认识到,重新落地时没把守卫带回来。

变异矩阵(三处变异全部被拦):
- 守卫去掉 → KeepsEstablishedIdentity / WithWaitPid / 真 host 用例 FAIL
- 守卫收窄为 && !WaitPid → WithWaitPid FAIL
- 跳过钱包导入块 → KeepsEstablishedIdentity FAIL
go test ./system/p2p/... 全绿(dht 包连跑两遍稳定)。
@vipwzw

vipwzw commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

感谢两位的详细 review。逐条处理如下(commit e1bde75e2,PR 正文已同步更正):

测试建议(bysomeone 1、2;libangzhu「测试还差一点点」)

  1. 真 host 回归已补 TestP2PHostIdentityStableAfterWalletReady:真 queue + 真 host + 真 leveldb addrbook + 钱包 mock 返回另一把钥,钱包就绪后轮询 host.ID() 与 addrbook 身份。
    • 去掉守卫后 1.2s 内 FAIL(与你实测的 ~1.1s 一致);既有 Test_p2p 在同样变异下仍通过 —— 正是这个盲区让缺陷上线。已写进用例注释。
  2. 「addrbook 身份 ≠ 钱包空投键」那一支已补 TestGenAirDropKeyKeepsEstablishedIdentityWithWaitPid(waitPid=true + 已有另一把身份 → 不替换)。
  3. 导入顺序已变成契约:KeepsEstablishedIdentity 断言 WalletImportPrivkey 被调用、...WithWaitPid 断言未被调用(导入块由 !WaitPid 门控)。
  4. 变异矩阵已能拦下你指出的两种收窄:
    变异 结果
    守卫去掉 KeepsEstablishedIdentity / WithWaitPid / 真 host 用例 FAIL
    守卫收窄为 savePrivkey != "" && !WaitPid WithWaitPid FAIL
    跳过导入块(等价守卫上提) KeepsEstablishedIdentity FAIL
  5. TestGenAirDropKeySameIdentityNoRestart 已改名 ...SameKeyReturnsEarly,注释写明它钉的是同密钥提前返回、对新守卫零拦截力。

表述更正(bysomeone 1–4)

  1. 守卫注释末句已改:写明 waitPid=false 时 initP2P 已 Randkey() 落盘身份 ⇒ 这类节点读到非空身份即返回、不会采用钱包身份;只有 addrbook 无身份且在 host 启动前拿到空投地址(waitPid=true)才用它作身份。
  2. 删掉「waitPid=true 原语义不变」,并按你的说法改成「条件是 addrbook 身份 ≠ 钱包空投键」;同时点明该路径下保留的身份不进钱包(导入块被 !WaitPid 门控)。
  3. 「约 99% 被拒」已限定为 ≤ v1.72.0;v1.72.1–v1.72.6 期间替换是确定性的(新节点钱包就绪后约 1 秒换一次、每钱包一次),已按此改写正文并说明这加强而非削弱修复动机。
  4. 线索已改为 ec5476309 / 563e80d77 / d2a16d33b,并补上 53d304ea8 被 b890d1d38 回滚(回滚信息原文即 "Reverts the airdrop index change so an existing node's peer ID stays the same")这段历史 —— 说明该影响当时已被认识到,重新落地时没把守卫带回来。

libangzhu 的其余建议

  • 每次重启多余导入:已按你的写法改成把 ErrPrivkeyExist 当成功、名字冲突不再 sleep 1s、其它错误打日志后 break。
  • 两处旧注释:initP2P 的「生成临时 pid,待创建钱包之后替换」与导入块的「保证最后用空投地址」都已按新行为改写。

两点说明的处理

  • TestGenAirDropKeySameIdentityNoRestart:已改名并注释其覆盖范围(同上)。
  • 每次重启多 1 秒 + 两条 Error 日志:已随导入块改造消除;真实钱包上未实跑,仅本地 mock 覆盖,已在正文标注。
  • plugin/p2p/gossip/p2p.go 的同构实现:确认未覆盖,已写进正文「未覆盖」一节,另案处理。
  • ci_rgbx 证据等级:正文已注明我的证据是 CI job 日志 + 本提交上的可执行用例;harness 另有已文档化成因会产生同一失败串,未逐个排除历史偶发;仓内 rgbx-e2e.log 不作为依据。

vipwzw pushed a commit to 33cn/plugin that referenced this pull request Oct 16, 2026
…commit

依赖从 a95e7f042 跟到 e1bde75e2(v1.72.7-0.20261016082959-e1bde75e25d0):
#1408 review 补了真 host 身份稳定性回归、收紧了用例(变异矩阵可拦下收窄/移动守卫),
并把钱包导入的 ErrPrivkeyExist 当成功、去掉名字冲突时多余的 1 秒 sleep。

chain33 依赖最终包含:ForkGenesisOnlyAtHeightZero(33cn/chain33#1407) +
dht 身份不再运行期替换(33cn/chain33#1408)。
go test ./plugin/dapp/ticket/... 全绿。
@vipwzw
vipwzw merged commit ef6b9f6 into master Oct 16, 2026
23 checks passed
@33cn

33cn commented Oct 16, 2026

Copy link
Copy Markdown
Owner

🎉 This PR is included in version 1.72.7 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@33cn 33cn added the released label Oct 16, 2026
33cn pushed a commit to 33cn/plugin that referenced this pull request Oct 16, 2026
依赖从 v1.72.0 回移版换成 v1.72.7-0.20261016053907-a95e7f042582(chain33 分支
fix/dht-keep-established-identity,33cn/chain33#1408):

- v1.72.6 已经包含本 PR 需要的系统分叉 ForkGenesisOnlyAtHeightZero(33cn/chain33#1407),
  但仍带着 v1.72.1 引入的回归:钱包就绪后 dht 用钱包空投地址替换节点身份并 reStart(),
  运行期更换 peer id;
- plugin 的 ci_rgbx 正是被这条路径打断(重启前发现的 TSS peers 与运行身份零交集,
  auto DKG commit 超时),与创世分叉无关(把它配成 -1 仍复现);
- 切到该修复后 ci_rgbx 通过(5m29s,重启前后 peer 名保持不变),因此不再需要
  v1.72.0 回移分支,等 chain33 发布 v1.72.7 后可换成正式版本号
- go test ./plugin/dapp/ticket/... 全绿
33cn pushed a commit to 33cn/plugin that referenced this pull request Oct 16, 2026
…commit

依赖从 a95e7f042 跟到 e1bde75e2(v1.72.7-0.20261016082959-e1bde75e25d0):
#1408 review 补了真 host 身份稳定性回归、收紧了用例(变异矩阵可拦下收窄/移动守卫),
并把钱包导入的 ErrPrivkeyExist 当成功、去掉名字冲突时多余的 1 秒 sleep。

chain33 依赖最终包含:ForkGenesisOnlyAtHeightZero(33cn/chain33#1407) +
dht 身份不再运行期替换(33cn/chain33#1408)。
go test ./plugin/dapp/ticket/... 全绿。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants