fix(register-node): #19 popSigner 读 KMS /pop camelCase (真 TEE 逮到的 bug) - #186
Conversation
…/popPoint/popSig) 真 TEE 上逮到的 bug:KMS /pop 响应是 camelCase(publicKey/popPoint/popSig,api_server.rs PopSignResp serde rename),但 popSigner 读的是 snake_case(public_key/pop_point/pop_signature) → 对真 KMS /pop 必失败(字段 undefined → 抛"缺字段")。之前 mock-TEE 无 /pop、板A 掉线, 测不出来;这次坚持在板B(真 TEE)测,register bundle→popSigner→真 /pop 全链路跑通逮到并修。 已在板B真TEE验证:修复后 register-node.bundle.mjs → popSigner → 真 /pop → 拿到 PoP、 算出 nodeId(publicKey 匹配 TEE key)+ Sepolia 计划。#19 popSigner 缺口终极闭合。 Claude-Session: https://claude.ai/code/session_015cWRdv3oPjoQ21PEjwo9m5
clestons
left a comment
There was a problem hiding this comment.
✅ APPROVE — 真 bug,修得对,已对 KMS 服务端结构逐字核实
register-node.mjs 的 popSigner 读 KMS /pop 响应时用了 snake_case(public_key/pop_point/pop_signature),但服务端发的是 camelCase。老代码里那句校验
if (!d.public_key || !d.pop_point || !d.pop_signature) throw 'KMS /pop 响应缺字段'在服务端返 camelCase 的现实下 每次必抛 —— key-less TEE 节点的整条 popSigner 链上注册路径 100% 走不通。正是「真 TEE 逮到」的那类字段名 bug。
对着服务端源码核过(不是靠 PR 自述):
kms/host/src/api_server.rs的/pophandler,响应结构PopSignResp显式 serde rename:
#[serde(rename = "publicKey")]/"popPoint"/"popSig"→ 上线 JSON 就是{ publicKey, popPoint, popSig }。- 结构体上方注释白纸黑字:「camelCase JSON keys — register-node.mjs reads
{ popPoint, popSig }… cross-repo contract (CC-37)」。 - 本 PR 改成读
d.publicKey/d.popPoint/d.popSig,与服务端 rename、CC-37 契约、SDKDvtPop三者一致。 - 校验/三处赋值/错误文案/
keccak256(d.publicKey)(nodeId 绑定)全同步改,内部自洽;register-node 输出键(publicKey/popPoint/popSig)本就 camelCase,未动,下游 SDK/合约契约不受影响。
一个 heads-up(非本 PR 问题,不阻塞)
code search 发现 YetAnotherAA-Validator/scripts/register-node.mjs 也有个 register-node,但它的 /pop 是另一套形状(POST /pop {node_id, pop_point} → {pop_sig},自己算 popPoint、只问签名),和 KMS-TEE 这条返 {publicKey,popPoint,popSig} 的是不同契约。两处刻意分叉、不是同一个 bug —— 但两个 repo 各有一份 register-node.mjs、/pop 语义还不同,属于跨仓一致性的味道,建议哪天在 CC-37 契约文档里把「谁用哪套 /pop」标清,免得以后再踩字段名。
安全相关路径(链上节点注册 + PoP),但修复是纯字段名对齐、已对权威服务端结构核实,结论确定,无需 Codex PK。合并交作者。
Reviewed by clestons (local-model tier, PR-Daemon)。已拉 api_server.rs PopSignResp 逐字核实 camelCase 契约。
Security Audit ReportDate: Sat Jul 18 16:24:14 UTC 2026 Cargo Audit Results |
真 TEE 逮到的 bug(板 B 验证时发现)
KMS
/pop响应是 camelCase ——{ publicKey, popPoint, popSig }(api_server.rsPopSignResp 的 serde rename),但register-node.mjs的 popSigner 读的是 snake_case{ public_key, pop_point, pop_signature }→ 对真 KMS/pop必然失败(字段 undefined → 抛"缺字段")。为什么之前没发现:mock-TEE 无
/pop、板 A 掉线 → popSigner 路径从没对真 TEE 测过(只测过blsSecretKey本地路径)。这次坚持在板 B 真 TEE 上测,register bundle → popSigner → 真 /pop全链路跑通时逮到。修复
popSigner 改读 camelCase(
d.publicKey/d.popPoint/d.popSig)+ nodeId 从d.publicKey派生。已在真 TEE 验证 ✅
板 B 上 provision 一把 BLS key → 修复后的
register-node.bundle.mjs→ popSigner → 真 KMS/pop→ 拿到 PoP、算出 nodeId(publicKey 匹配 TEE key)+ Sepolia 计划(minStake 30 GToken)。这闭合了 #19 那条"待板 A"的 popSigner 缺口,也顺带验证了 combined-tee 的 KMS-TEE 签名机制。测完板 B 已 restore 还原。https://claude.ai/code/session_015cWRdv3oPjoQ21PEjwo9m5