Repository navigation
fix(sync,p2p): 键控主修 —— delegated→root 亲签事件永不落图(N1–N4 + 四方向矩阵) - #125
Merged
Merged
Conversation
- scripts/keying-repro.mjs:沙箱 daemon×daemon 复现/变体工具(B 委派主动拨 A)。 单连接=绿;第二键再拨(EXTRA_DIAL=hex/device)=确定性红:B 亲签事件零落 A。 - scripts/keying-preload.mjs:NODE_OPTIONS 注入的六层探针(auth/conn/channel/ frames/queue/session),钉死断点:连接键不对称(拨号键 3 形态 vs 被拨侧恒派生 hex)+ 被拨侧同键坍缩 + 全局会话队列饥饿 + nudge 静默丢弃。 - src/sync/KEYING-FIX-PROPOSAL.md:A2 提案(根因到行 / N1–N4 方案 / 红线对照 / 测试与回滚 / 身份不变量草案 v0)。 - package.json:新增 verify:keying:repro。 供检查点①;src/ 产品代码零改动。
缺陷(#122 前存,已钉死到行):join hints 双键 + mDNS 自动再拨使同一对端出现第二条 连接(拨号键 libp2p id/deviceId/派生 hex 多形态 vs 被拨侧恒派生 hex),被拨侧同键坍缩、 旧 entry 的帧读取者滞留;nudge 落旧 entry 静默丢弃 + 常驻响应方会话占住全局队列 → delegated→root 亲签事件永不落图。单连接场景不受影响(故集群脚本从未暴露)。 N1 规范对端键:握手认证成功即把 session.peerId 规范化为 sha256hex(证书设备公钥) (canonicalPeerIdFromCertificate);P2PNode.peerKeyAliases/通道/在线登记/getChannel 全走规范键;拨号键只作寻址提示。 N2 单活连接收敛:新连接**认证成功**后才退役旧连接(按连接对象关闭 + 身份守卫的清理); connection-closed 携带连接对象,信道/会话/登记清理按代际比对;握手失败恢复同键原有 已认证会话(第二次认证失败不影响旧连接——对抗不变式)。 N3 响亮失败:nudgeDroppedStaleEntry/staleEntrySignals/identityFailures 三类计数 + sync-frames-dropped 事件;attachToNode 缺权威身份=显式失败+告警(删静默兜底)。 N4 会话队列按连接粒度(SyncTransport.connection 暴露承载连接),空闲守候不再饿死 其他连接/对端的会话。 测试:keying-canonicalization / drop-counters / session-queue-isolation / keying-convergence(含异主同名证书对抗);矩阵 scripts/verify-keying-matrix.mjs 13 场景(四方向 × 再拨两形态 + 重连竞态 + 冒名 + #122 主网流程 + 混合版本抽查)。 不变量定稿 src/sync/IDENTITY-INVARIANTS.md。 线协议/策略/存储/事件格式零改动。
Owner
Author
证据(P1·B2/B3 · 原始输出摘录)1) 红→绿(A1 红样本同一命令,连跑 6 次恒定) 2) 四方向矩阵 × 第二连接 × 重连 × 冒名 × #122 × 混合版本(13/13) (命令: 3) 判别性抽查(变异 → 锚点红 → 还原绿) 4) 全量 CI 五项(本地同构) |
Owner
Author
|
表述更正(检查点②):此前多处「零改动」的简化表述不够准确—— |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
键控主修 P1:delegated 守护 → root 守护「亲签事件永不落图」修复
缺陷(#122 前存,会话级红样本已钉死到行)
表征:daemon×daemon 下,delegated 侧写亲签 membership/记忆 → root 侧永不落图(同一 LAN 必然触发;单连接沙箱不触发,故
verify:daemon:cluster从未暴露——它只断言 A→B 这个坏不了的方向)。真实触发链:join 上车把邀请方地址双键写入地址簿(
deviceId+derivePeerIdHex(公钥),F-C12-1)+ mDNS 通告恰为派生 hex 形态 →handleLanDiscovery命中并以 hex 键对同一对端再拨一次;拨号键因此多形态(libp2p id / deviceId / 派生 hex),被拨侧一律派生 hex。断点(精确到行):
src/p2p/transport/Libp2pProvider.ts:644(被拨侧派生 hex)vs:670-685(拨号键原样)、src/p2p/P2PNetwork.ts:548-590/:593-603(LAN 再拨);去重只按本地键src/p2p/connection/ConnectionManager.ts:134。src/p2p/P2PNetwork.ts:740-746、src/sync/syncmgr/SyncManager.ts:999(旧 entry 被替换,旧 PeerFrames 仍读旧信道)。src/sync/syncmgr/SyncManager.ts:475-478(onlinePeers.get(key)!==entry→ 无声 return)。SyncManager.ts:1507-1511+:925-945(常驻响应方无限等 hello 不归还队列)→ 第二条连接的会话体永不启动(帧已解密却无人读)。⇒ B 亲签事件永不落图(双向皆断;首连接上「恰好先完成」的 A→B 推送掩盖问题)。
红样本(沙箱 daemon×daemon,
EXTRA_DIAL=hex,连跑 6 次恒定;原始输出见 commit 前的 A1 回执):如实更正(计划 §1.4 记录,历史可溯)
计划原列的两个嫌疑断点均未触发:①角色仲裁(
SyncManager.ts:988/:996)——探针显示两侧证书 deviceId 正确、initiate双侧互补,静默兜底未执行;②信任快路径(:1386)——失败时事件根本未到达校验点(单连接阶段verifyEventTrust全 ok)。真实断点在连接/会话路由键控层(上述 1–4),已按红线 1 顺带删除静默兜底。此更正已在检查点①经主控独立复跑认可。修复(N1–N4;红线语义:无「线协议 / 策略 / 存储 / 事件格式」变更)
peerId规范化为sha256hex(证书设备公钥)(canonicalPeerIdFromCertificate);channels/onlinePeers/pushTimers/getChannel全走规范键;拨号键只作寻址提示(peerKeyAliases翻译)。convergePeerConnection/retireConnection;ConnectionManager.disconnect(peerId, connection)按对象关闭 + 身份守卫);connection-closed携带连接对象,信道/会话/登记清理按代际比对;握手失败恢复同键原有已认证会话(第二次认证失败 → 旧连接继续正常服务,对抗不变式)。nudgeDroppedStaleEntry/staleEntrySignals/identityFailures+sync-frames-dropped事件;attachToNode缺权威身份 = 显式失败 + 告警(删除静默兜底)。enqueue按连接粒度(SyncTransport.connection),空闲守候不再饿死其他连接/对端。验证
EXTRA_DIAL=hex|device npm run verify:keying:repro修复前确定性红、修复后 10/10 绿(单连接基线两态均绿)。tests/p2p/keying-canonicalization.test.ts(拨号键不得留在会话身份;删规范化行 → 锚点红)tests/sync/drop-counters.test.ts(三类计数逐一断言;屏蔽 nudge 计数 → 锚点红)tests/sync/session-queue-isolation.test.ts(多对端不互相饿死)tests/integration/keying-convergence.test.ts(第二键再拨收敛 + 异主同名证书对抗)npm run verify:keying:matrix,13 场景全绿):b2a / a2b / 委派↔委派 × {单连接, hex 再拨, deviceId 再拨} + 重连竞态(拨号侧/被拨侧重启 + 掉线事件回填自愈,missing=0)+ 冒名第二连接(认证失败旧连接不受影响)+ feat(sync): daemon-layer auto-grant on subscription (killswitch-gated) #122 主网流程(委派侧订阅 notes → 根侧自动签发触发 → 数据到位)+ 混合版本抽查(旧端↔新端,两向各跑:连接/数据面记录见矩阵输出;旧端双拨遗留形态如实记录、连接面不倒退)。
check:cleanliness0/0。src/sync/IDENTITY-INVARIANTS.md(I1–I7 与实现/测试锚点对照)。回滚与影响面
P2PNetwork.ts/ConnectionManager.ts/AuthenticationHandshake.ts/SyncManager.ts/protocol.ts(仅新增SyncTransport内部可选字段connection+ getter——非线协议变更)+ 测试/脚本/文档;策略、存储、事件与握手/同步帧格式零改动。证据索引
scripts/keying-repro.mjs、scripts/keying-preload.mjs(本 PR 作者自用;矩阵为其超集)scripts/verify-keying-matrix.mjs(npm run verify:keying:matrix;OLD_MCP=<旧构建入口>启用混合版本抽查)src/sync/KEYING-FIX-PROPOSAL.md;不变量:src/sync/IDENTITY-INVARIANTS.md