fix(android): ensure session event subscription active before creating sign session

Add ensureSessionEventSubscriptionActive() call at the start of createSignSession()
to prevent race condition where session_started event arrives before subscription
is ready. Also add debug logging for _signSessionId and pendingSignInitiatorInfo
in event callback to help diagnose sign initiator event matching issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-01 21:45:18 -08:00
parent ecd7a2a2dc
commit 0bd764e1d1
2 changed files with 28 additions and 0 deletions

View File

@ -1936,6 +1936,11 @@ class TssRepository @Inject constructor(
): Result<SignSessionResult> {
return withContext(Dispatchers.IO) {
try {
// CRITICAL: Ensure session event subscription is active BEFORE creating sign session
// This prevents race condition where session_started event arrives before subscription is ready
android.util.Log.d("TssRepository", "[CO-SIGN] Ensuring session event subscription is active before creating sign session")
ensureSessionEventSubscriptionActive()
// Get share record
val shareEntity = shareRecordDao.getShareById(shareId)
?: return@withContext Result.failure(Exception("Share not found"))
@ -2145,8 +2150,15 @@ class TssRepository @Inject constructor(
?: return@withContext Result.failure(Exception("Share not found"))
android.util.Log.d("TssRepository", "[CO-SIGN] startSigning: participants=${session.participants.size}")
android.util.Log.d("TssRepository", "[CO-SIGN] startSigning: sessionId=$sessionId, partyId=$partyId, partyIndex=${shareEntity.partyIndex}")
android.util.Log.d("TssRepository", "[CO-SIGN] startSigning: thresholdT=${session.thresholdT}, thresholdN=${shareEntity.thresholdN}")
android.util.Log.d("TssRepository", "[CO-SIGN] startSigning: messageHash=${session.messageHash?.take(20)}...")
session.participants.forEachIndexed { idx, p ->
android.util.Log.d("TssRepository", "[CO-SIGN] startSigning: participant[$idx] = ${p.partyId.take(12)}..., index=${p.partyIndex}")
}
// Start TSS sign
android.util.Log.d("TssRepository", "[CO-SIGN] Calling tssNativeBridge.startSign...")
val startResult = tssNativeBridge.startSign(
sessionId = sessionId,
partyId = partyId,
@ -2158,10 +2170,13 @@ class TssRepository @Inject constructor(
shareData = shareEntity.encryptedShare,
password = password
)
android.util.Log.d("TssRepository", "[CO-SIGN] tssNativeBridge.startSign returned: isSuccess=${startResult.isSuccess}")
if (startResult.isFailure) {
android.util.Log.e("TssRepository", "[CO-SIGN] startSign FAILED: ${startResult.exceptionOrNull()?.message}")
return@withContext Result.failure(startResult.exceptionOrNull()!!)
}
android.util.Log.d("TssRepository", "[CO-SIGN] startSign succeeded, starting progress collection...")
// Start collecting progress from native bridge
startProgressCollection()

View File

@ -329,6 +329,8 @@ class MainViewModel @Inject constructor(
android.util.Log.d("MainViewModel", " _currentSessionId: ${_currentSessionId.value}")
android.util.Log.d("MainViewModel", " pendingJoinKeygenInfo?.sessionId: ${pendingJoinKeygenInfo?.sessionId}")
android.util.Log.d("MainViewModel", " pendingJoinSignInfo?.sessionId: ${pendingJoinSignInfo?.sessionId}")
android.util.Log.d("MainViewModel", " _signSessionId: ${_signSessionId.value}")
android.util.Log.d("MainViewModel", " pendingSignInitiatorInfo?.sessionId: ${pendingSignInitiatorInfo?.sessionId}")
when (event.eventType) {
"session_started" -> {
@ -362,9 +364,12 @@ class MainViewModel @Inject constructor(
// Check if this is for sign initiator (TransferScreen - 发起签名)
val signSessionId = _signSessionId.value
android.util.Log.d("MainViewModel", "Checking for sign initiator: signSessionId=$signSessionId, eventSessionId=${event.sessionId}")
if (signSessionId != null && event.sessionId == signSessionId) {
android.util.Log.d("MainViewModel", "Session started event for sign initiator, triggering sign")
startSignAsInitiator(event.selectedParties)
} else {
android.util.Log.d("MainViewModel", "NOT triggering sign initiator: signSessionId=$signSessionId, pendingSignInitiatorInfo=${pendingSignInitiatorInfo?.sessionId}")
}
}
"party_joined", "participant_joined" -> {
@ -1218,22 +1223,30 @@ class MainViewModel @Inject constructor(
* Start the TSS signing process
*/
private fun startSigningProcess(sessionId: String, shareId: Long, password: String) {
android.util.Log.d("MainViewModel", "[SIGN] startSigningProcess called: sessionId=$sessionId, shareId=$shareId")
viewModelScope.launch {
android.util.Log.d("MainViewModel", "[SIGN] Calling repository.startSigning...")
val startResult = repository.startSigning(sessionId, shareId, password)
android.util.Log.d("MainViewModel", "[SIGN] repository.startSigning returned: isSuccess=${startResult.isSuccess}")
if (startResult.isFailure) {
android.util.Log.e("MainViewModel", "[SIGN] startSigning FAILED: ${startResult.exceptionOrNull()?.message}")
_uiState.update { it.copy(error = startResult.exceptionOrNull()?.message) }
return@launch
}
// Wait for signature
android.util.Log.d("MainViewModel", "[SIGN] startSigning succeeded, calling waitForSignature...")
val signResult = repository.waitForSignature()
android.util.Log.d("MainViewModel", "[SIGN] waitForSignature returned: isSuccess=${signResult.isSuccess}")
signResult.fold(
onSuccess = { result ->
android.util.Log.d("MainViewModel", "[SIGN] Signature received: ${result.signature.take(20)}...")
_signature.value = result.signature
},
onFailure = { e ->
android.util.Log.e("MainViewModel", "[SIGN] waitForSignature FAILED: ${e.message}")
_uiState.update { it.copy(error = e.message) }
}
)