rwadurian/backend/mpc-system/services/service-party-android/LOG_ANALYSIS_PARTY1.md

10 KiB
Raw Blame History

Party 1 日志分析报告

📋 基本信息

  • Party ID: 7c72c28f-082d-4ba4-a213-5b906abeb5cc
  • Party Index: 1
  • Session ID: f01810e9-4b0f-4933-a06a-0382124e0d25
  • Invite Code: 6C72-753E-9C17
  • Threshold: 2-of-3

成功的步骤

1. 应用启动和初始化

15:57:57.690 Setting up session event callback
15:57:58.140 Party registered: 7c72c28f...
15:57:58.186 Connected successfully

2. 会话创建

15:58:50.215 Creating keygen session
15:58:50.364 Create session response received
15:58:50.365 Session created: sessionId=f01810e9..., inviteCode=6C72-753E-9C17

关键配置:

  • persistent_count: 1 (server-party-co-managed)
  • external_count: 2 (两台手机)
  • selected_server_parties: ["co-managed-party-3"]

3. 参与者加入

第一次 participant_joined (15:58:50.385):

  • selectedParties: [co-managed-party-3, 7c72c28f...] (2个)
  • Party 1 自己加入成功

第二次 participant_joined (15:58:58.210):

  • selectedParties: [co-managed-party-3, 7c72c28f..., ca64e2b1...] (3个)
  • Party 2 加入成功

4. session_started 事件触发

15:58:58.207 Session event: session_started
15:58:58.208 Session started event for keygen initiator, triggering keygen
15:58:58.210 Starting keygen as initiator: sessionId=..., t=2, n=3

5. 获取会话状态

15:58:58.271 Session status response:
  status=in_progress
  participants=3
  - co-managed-party-3 (index=0, status=joined)
  - 7c72c28f... (index=1, status=joined)  ← 我
  - ca64e2b1... (index=2, status=joined)

6. 启动 TSS keygen

15:58:58.272 Starting keygen as initiator: sessionId=...
15:58:58.272 My party index: 1
15:58:58.301 [PROGRESS] Starting progress collection from native bridge
15:58:58.301 [JobManager] Launched job: progress_collection (active jobs: 3)

🚨 发现的问题

问题 1: Mark Party Ready 失败 🔴

15:58:58.318 E/GrpcClient: Mark party ready failed:
INTERNAL: optimistic lock conflict: session was modified by another transaction

分析:

  • 乐观锁冲突Optimistic Lock Conflict
  • 说明多个参与者同时尝试更新会话状态
  • 这个错误导致 Party 1 没有成功标记为 ready

影响:

  • 服务器可能认为 Party 1 还没有准备好
  • 可能影响 TSS 协议的启动

根本原因:

  • TssRepository.startKeygenAsInitiator line 2138: grpcClient.markPartyReady(sessionId, partyId)
  • 这个调用失败了,但没有错误处理
  • 代码继续执行到 line 2141: waitForKeygenResult()

代码片段:

// Line 2138
grpcClient.markPartyReady(sessionId, partyId)  // ← 失败但没有检查

// Line 2141
val keygenResult = tssNativeBridge.waitForKeygenResult(password)  // ← 继续等待

问题 2: 534 个待处理消息堆积(最严重)🚨🚨🚨

15:58:58.345 W/GrpcClient: Has 534 pending messages - may have missed events
15:59:28.440 W/GrpcClient: Has 534 pending messages - may have missed events  ← 30秒后还是534

分析:

  • 消息队列堆积了534个未处理消息
  • 30秒后还是534个,说明消息完全没有被消费
  • TSS 协议需要消息路由才能工作

影响:

  • TSS 协议无法进行
  • 参与者之间无法交换密钥生成的中间值
  • 导致 keygen 卡死

可能原因:

  1. message_collection job 没有真正工作

    • 虽然日志显示启动了,但可能内部失败了
    • 没有错误日志,可能被静默吞掉
  2. 消息路由没有正确初始化

    • line 15:58:50.387: "Starting message routing: sessionId=..., routingPartyId=..."
    • 但之后没有任何消息发送/接收日志
  3. markPartyReady 失败导致消息路由失效

    • 服务器可能只向 "ready" 的参与者发送消息
    • 如果 Party 1 没有标记为 ready可能收不到消息

问题 3: TssNativeBridge 完全没有日志 🔴

预期应该有的日志:

TssNativeBridge: keygenAsInitiator called with sessionId=...
TssNativeBridge: Keygen round 1/9
TssNativeBridge: Keygen round 2/9
...
TssNativeBridge: Keygen completed successfully

实际: 完全没有任何 TssNativeBridge 的输出!

分析:

  • TssNativeBridge.startKeygen (line 63-88) 没有任何日志
  • 无法判断:
    1. 是否成功调用了 native library
    2. 是否立即失败
    3. 是否在等待消息

代码问题:

// TssNativeBridge.kt:63-88
suspend fun startKeygen(...): Result<Unit> = withContext(Dispatchers.IO) {
    try {
        val participantsJson = gson.toJson(participants)
        Tsslib.startKeygen(...)  // ← 没有日志!
        Result.success(Unit)     // ← 立即返回
    } catch (e: Exception) {
        Result.failure(e)        // ← 如果这里失败,也没有日志!
    }
}

建议添加日志:

suspend fun startKeygen(...): Result<Unit> = withContext(Dispatchers.IO) {
    try {
        android.util.Log.d("TssNativeBridge", "startKeygen called: sessionId=$sessionId, partyIndex=$partyIndex")
        val participantsJson = gson.toJson(participants)
        android.util.Log.d("TssNativeBridge", "Calling native Tsslib.startKeygen...")
        Tsslib.startKeygen(...)
        android.util.Log.d("TssNativeBridge", "Tsslib.startKeygen returned successfully")
        Result.success(Unit)
    } catch (e: Exception) {
        android.util.Log.e("TssNativeBridge", "startKeygen failed", e)
        Result.failure(e)
    }
}

问题 4: 没有进度更新 🔴

预期应该有的日志:

MainViewModel: Progress update: 1 / 9
MainViewModel: Progress update: 2 / 9
...

实际: 完全没有!

分析:

  • progress_collection job 启动了15:58:58.301
  • 但没有收集到任何进度
  • 说明:
    1. TssNativeBridge 没有报告进度
    2. 或者 keygen 根本没有启动

🎯 根本原因推断

最可能的原因(按概率排序)

1. markPartyReady 失败导致消息路由失效 (70%)

链条:

markPartyReady 失败
    ↓
服务器认为 Party 1 未准备好
    ↓
不向 Party 1 发送 TSS 消息
    ↓
Party 1 的 message_collection 收不到消息
    ↓
534 个消息堆积(可能是其他 party 发给自己的)
    ↓
TSS 协议无法进行
    ↓
keygen 卡死

验证方法:

  • 检查服务器日志,看 Party 1 的状态是否为 ready
  • 检查 Party 2 和 co-managed-party 的日志,看他们是否收到消息

2. TssNativeBridge.startKeygen 静默失败 (20%)

链条:

Tsslib.startKeygen() 调用失败
    ↓
没有抛出异常(或被吞掉)
    ↓
返回 Result.success(Unit)
    ↓
代码继续执行到 waitForKeygenResult()
    ↓
永久等待(因为 keygen 没有真正启动)

验证方法:

  • 添加 TssNativeBridge 日志
  • 检查 native library 的日志输出

3. 消息路由初始化失败 (10%)

链条:

Starting message routing (15:58:50.387)
    ↓
subscribeToTssMessages 失败(没有日志)
    ↓
无法接收 TSS 消息
    ↓
keygen 卡死

🔍 需要进一步调查

1. 其他 Party 的日志

需要收集:

  • Party 2 (ca64e2b1-8a7c-4cc9-a8c7-5667a206e674) 的日志
  • co-managed-party-3 的服务器日志

重点看:

  • 他们是否成功 markPartyReady
  • 他们是否收到/发送了 TSS 消息?
  • 他们的 pending messages 数量?
  • 他们的进度更新?

2. 服务器端状态

需要检查:

# 查询会话状态
curl -X GET https://mpc-grpc.szaiai.com/api/sessions/f01810e9-4b0f-4933-a06a-0382124e0d25

# 查询参与者状态
# 看 Party 1 (7c72c28f...) 的 status 是否为 "ready"

3. 添加更详细的日志

需要在以下位置添加日志:

TssNativeBridge.kt

suspend fun startKeygen(...): Result<Unit> {
    android.util.Log.d("TssNativeBridge", "startKeygen: sessionId=$sessionId, partyIndex=$partyIndex, t=$thresholdT, n=$thresholdN")
    android.util.Log.d("TssNativeBridge", "participants: $participants")

    try {
        val participantsJson = gson.toJson(participants)
        android.util.Log.d("TssNativeBridge", "Calling native Tsslib.startKeygen...")

        Tsslib.startKeygen(...)

        android.util.Log.d("TssNativeBridge", "Tsslib.startKeygen returned (async)")
        Result.success(Unit)
    } catch (e: Exception) {
        android.util.Log.e("TssNativeBridge", "startKeygen FAILED", e)
        Result.failure(e)
    }
}

TssRepository.kt

// Line 2138 - 检查 markPartyReady 结果
val markReadyResult = grpcClient.markPartyReady(sessionId, partyId)
if (markReadyResult.isFailure) {
    android.util.Log.e("TssRepository", "Failed to mark party ready: ${markReadyResult.exceptionOrNull()?.message}")
    // 考虑重试或返回错误
}

🛠️ 临时解决方案

方案 1: 重试 markPartyReady

修改 TssRepository.kt line 2138:

// 重试机制
repeat(3) { attempt ->
    try {
        grpcClient.markPartyReady(sessionId, partyId)
        android.util.Log.d("TssRepository", "Successfully marked party ready on attempt ${attempt + 1}")
        break
    } catch (e: Exception) {
        android.util.Log.w("TssRepository", "markPartyReady attempt ${attempt + 1} failed: ${e.message}")
        if (attempt == 2) {
            // 最后一次尝试失败,抛出错误
            return@coroutineScope Result.failure(Exception("Failed to mark party ready after 3 attempts"))
        }
        delay(1000)  // 等待1秒后重试
    }
}

方案 2: 添加完整的日志

在所有关键位置添加日志,特别是:

  • TssNativeBridge.startKeygen
  • markPartyReady
  • message_collection job

📊 总结

确定的问题

  1. markPartyReady 失败optimistic lock conflict
  2. 534个消息堆积未处理
  3. TssNativeBridge 没有任何日志
  4. 没有进度更新

最可能的根本原因

markPartyReady 失败 → 服务器不发送消息给 Party 1 → 消息路由失效 → keygen 卡死

下一步行动

  1. 立即: 收集 Party 2 和 co-managed-party 的日志
  2. 短期: 添加 TssNativeBridge 日志
  3. 中期: 添加 markPartyReady 重试机制
  4. 长期: 改进错误处理和日志记录

请提供 Party 2 的日志,我可以进行对比分析!