fix(mpc/backup): add accountSequence to backup share storage

- mpc-service: add accountSequence param to StoreBackupShareParams
- mpc-service: pass accountSequence when calling backup-service
- backup-service: add logging for store request success/failure

🤖 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 2025-12-10 15:06:00 -08:00
parent 300fe211c8
commit 41af5ef3a3
4 changed files with 37 additions and 21 deletions

View File

@ -9,7 +9,11 @@
"Bash(cat:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git push)"
"Bash(git push)",
"Bash(find:*)",
"Bash(npm run build:*)",
"Bash(npx prisma generate:*)",
"Bash(npx tsc:*)"
],
"deny": [],
"ask": []

View File

@ -6,6 +6,7 @@ import {
HttpCode,
HttpStatus,
Req,
Logger,
} from '@nestjs/common';
import { BackupShareApplicationService } from '../../application/services/backup-share-application.service';
import { StoreBackupShareCommand } from '../../application/commands/store-backup-share/store-backup-share.command';
@ -24,6 +25,8 @@ import {
@Controller('backup-share')
@UseGuards(ServiceAuthGuard)
export class BackupShareController {
private readonly logger = new Logger(BackupShareController.name);
constructor(
private readonly backupShareService: BackupShareApplicationService,
) {}
@ -34,24 +37,33 @@ export class BackupShareController {
@Body() dto: StoreShareDto,
@Req() request: any,
): Promise<StoreShareResponseDto> {
const command = new StoreBackupShareCommand(
dto.userId,
dto.accountSequence,
dto.publicKey,
dto.encryptedShareData,
request.sourceService,
request.sourceIp,
dto.threshold,
dto.totalParties,
);
this.logger.log(`[STORE] Received store request: userId=${dto.userId}, accountSequence=${dto.accountSequence}, publicKey=${dto.publicKey?.substring(0, 20)}...`);
const result = await this.backupShareService.storeBackupShare(command);
try {
const command = new StoreBackupShareCommand(
dto.userId,
dto.accountSequence,
dto.publicKey,
dto.encryptedShareData,
request.sourceService,
request.sourceIp,
dto.threshold,
dto.totalParties,
);
return {
success: true,
shareId: result.shareId,
message: 'Backup share stored successfully',
};
const result = await this.backupShareService.storeBackupShare(command);
this.logger.log(`[STORE] SUCCESS: shareId=${result.shareId}, userId=${dto.userId}, accountSequence=${dto.accountSequence}`);
return {
success: true,
shareId: result.shareId,
message: 'Backup share stored successfully',
};
} catch (error) {
this.logger.error(`[STORE] FAILED: userId=${dto.userId}, accountSequence=${dto.accountSequence}, error=${error.message}`);
throw error;
}
}
@Post('retrieve')

View File

@ -105,13 +105,14 @@ export class KeygenRequestedHandler implements OnModuleInit {
try {
await this.backupClient.storeBackupShare({
userId,
accountSequence,
username,
publicKey: result.publicKey,
partyId: result.delegateShare.partyId,
partyIndex: result.delegateShare.partyIndex,
encryptedShare: result.delegateShare.encryptedShare,
});
this.logger.log(`Delegate share stored to backup-service: userId=${userId}`);
this.logger.log(`Delegate share stored to backup-service: userId=${userId}, accountSequence=${accountSequence}`);
} catch (backupError) {
// 备份失败不阻塞主流程,但记录错误
this.logger.error(`Failed to store delegate share to backup-service: userId=${userId}`, backupError);

View File

@ -13,6 +13,7 @@ import * as jwt from 'jsonwebtoken';
export interface StoreBackupShareParams {
userId: string;
accountSequence: number;
username: string;
publicKey: string;
partyId: string;
@ -77,10 +78,8 @@ export class BackupClientService {
`${this.backupServiceUrl}/backup-share/store`,
{
userId: params.userId,
username: params.username,
accountSequence: params.accountSequence,
publicKey: params.publicKey,
partyId: params.partyId,
partyIndex: params.partyIndex,
encryptedShareData: params.encryptedShare,
},
{