# MPC Party Service 架构文档

## 概述

MPC Party Service 是 RWA Durian 系统中的多方计算（Multi-Party Computation）服务端组件。该服务负责参与分布式密钥生成、签名和密钥轮换协议，安全地管理服务端的密钥分片。

## 架构设计原则

### 1. 六边形架构 (Hexagonal Architecture)

本服务采用六边形架构（又称端口与适配器架构），实现业务逻辑与外部依赖的解耦：

```
┌─────────────────────────────────────────────────────────────┐
│                      API Layer (Driving Adapters)            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │ REST API    │  │ gRPC API    │  │ WebSocket   │          │
│  │ Controllers │  │ (Future)    │  │ Handlers    │          │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘          │
└─────────┼────────────────┼────────────────┼─────────────────┘
          │                │                │
          ▼                ▼                ▼
┌─────────────────────────────────────────────────────────────┐
│                    Application Layer                         │
│  ┌─────────────────┐  ┌─────────────────┐                   │
│  │ Command Handlers│  │ Query Handlers  │                   │
│  │ - Keygen        │  │ - GetShareInfo  │                   │
│  │ - Signing       │  │ - ListShares    │                   │
│  │ - Rotate        │  │                 │                   │
│  └────────┬────────┘  └────────┬────────┘                   │
│           │                    │                             │
│  ┌────────▼────────────────────▼────────┐                   │
│  │     Application Services              │                   │
│  │     - MPCPartyApplicationService      │                   │
│  └────────────────┬─────────────────────┘                   │
└───────────────────┼─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────────────────────────┐
│                      Domain Layer                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  Entities   │  │   Value     │  │  Domain     │          │
│  │ - PartyShare│  │   Objects   │  │  Services   │          │
│  │ - Session   │  │ - ShareId   │  │ - TSS       │          │
│  │   State     │  │ - PartyId   │  │ - Encryption│          │
│  │             │  │ - Threshold │  │             │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
│                                                              │
│  ┌─────────────────────────────────────────────────┐        │
│  │              Domain Events                       │        │
│  │  - ShareCreatedEvent                            │        │
│  │  - ShareRotatedEvent                            │        │
│  │  - ShareRevokedEvent                            │        │
│  └─────────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────────────────────────┐
│                Infrastructure Layer (Driven Adapters)        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  Prisma     │  │   Redis     │  │   Kafka     │          │
│  │  Repository │  │   Cache     │  │   Events    │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
│                                                              │
│  ┌─────────────┐  ┌─────────────┐                           │
│  │ Coordinator │  │  Message    │                           │
│  │   Client    │  │  Router     │                           │
│  └─────────────┘  └─────────────┘                           │
└─────────────────────────────────────────────────────────────┘
```

### 2. CQRS 模式 (Command Query Responsibility Segregation)

命令和查询分离，提高系统的可扩展性和可维护性：

- **Commands**: 改变系统状态的操作
  - `ParticipateInKeygenCommand`
  - `ParticipateInSigningCommand`
  - `RotateShareCommand`

- **Queries**: 只读操作
  - `GetShareInfoQuery`
  - `ListSharesQuery`

### 3. 领域驱动设计 (DDD)

- **聚合根 (Aggregate Root)**: `PartyShare`
- **值对象 (Value Objects)**: `ShareId`, `PartyId`, `SessionId`, `Threshold`, `ShareData`, `PublicKey`, `Signature`, `MessageHash`
- **领域事件 (Domain Events)**: 用于解耦和异步处理
- **仓储接口 (Repository Interfaces)**: 定义在领域层，实现在基础设施层

## 目录结构

```
src/
├── api/                          # API 层 (Driving Adapters)
│   ├── controllers/              # REST 控制器
│   │   └── mpc-party.controller.ts
│   ├── dto/                      # 数据传输对象
│   │   ├── request/              # 请求 DTO
│   │   └── response/             # 响应 DTO
│   └── api.module.ts
│
├── application/                  # 应用层
│   ├── commands/                 # 命令处理器
│   │   ├── participate-keygen/
│   │   ├── participate-signing/
│   │   └── rotate-share/
│   ├── queries/                  # 查询处理器
│   │   ├── get-share-info/
│   │   └── list-shares/
│   ├── services/                 # 应用服务
│   │   └── mpc-party-application.service.ts
│   └── application.module.ts
│
├── domain/                       # 领域层
│   ├── entities/                 # 实体
│   │   ├── party-share.entity.ts
│   │   └── session-state.entity.ts
│   ├── value-objects/            # 值对象
│   │   └── index.ts
│   ├── enums/                    # 枚举
│   │   └── index.ts
│   ├── events/                   # 领域事件
│   │   └── index.ts
│   ├── repositories/             # 仓储接口
│   │   ├── party-share.repository.interface.ts
│   │   └── session-state.repository.interface.ts
│   ├── services/                 # 领域服务
│   │   ├── share-encryption.domain-service.ts
│   │   └── tss-protocol.domain-service.ts
│   └── domain.module.ts
│
├── infrastructure/               # 基础设施层 (Driven Adapters)
│   ├── persistence/              # 持久化
│   │   ├── prisma/               # Prisma ORM
│   │   ├── repositories/         # 仓储实现
│   │   └── mappers/              # 数据映射器
│   ├── redis/                    # Redis 缓存与锁
│   │   ├── cache/
│   │   └── lock/
│   ├── messaging/                # 消息传递
│   │   └── kafka/
│   ├── external/                 # 外部服务客户端
│   │   └── mpc-system/
│   └── infrastructure.module.ts
│
├── shared/                       # 共享模块
│   ├── decorators/               # 装饰器
│   ├── filters/                  # 异常过滤器
│   ├── guards/                   # 守卫
│   └── interceptors/             # 拦截器
│
├── config/                       # 配置
│   └── index.ts
│
├── app.module.ts                 # 根模块
└── main.ts                       # 入口文件
```

## 核心组件详解

### 1. Domain Layer (领域层)

#### PartyShare 实体

```typescript
// src/domain/entities/party-share.entity.ts
export class PartyShare {
  private readonly _id: ShareId;
  private readonly _partyId: PartyId;
  private readonly _sessionId: SessionId;
  private readonly _shareType: PartyShareType;
  private readonly _shareData: ShareData;
  private readonly _publicKey: PublicKey;
  private readonly _threshold: Threshold;
  private _status: PartyShareStatus;
  private _lastUsedAt?: Date;
  private readonly _domainEvents: DomainEvent[] = [];

  // 工厂方法 - 创建新分片
  static create(props: CreatePartyShareProps): PartyShare;

  // 工厂方法 - 从持久化数据重建
  static reconstruct(props: ReconstructPartyShareProps): PartyShare;

  // 业务方法
  markAsUsed(): void;
  rotate(newShareData: ShareData, newSessionId: SessionId): PartyShare;
  revoke(reason: string): void;
}
```

#### Value Objects (值对象)

值对象是不可变的，通过值来识别：

```typescript
// ShareId - 分片唯一标识
export class ShareId {
  static create(value: string): ShareId;
  static generate(): ShareId;
  get value(): string;
  equals(other: ShareId): boolean;
}

// Threshold - 门限配置
export class Threshold {
  static create(n: number, t: number): Threshold;
  get n(): number;  // 总分片数
  get t(): number;  // 签名门限
  canSign(availableParties: number): boolean;
}

// ShareData - 加密的分片数据
export class ShareData {
  static create(encryptedData: Buffer, iv: Buffer, authTag: Buffer): ShareData;
  toJSON(): ShareDataJson;
  static fromJSON(json: ShareDataJson): ShareData;
}
```

#### Domain Services (领域服务)

```typescript
// 分片加密服务
export class ShareEncryptionDomainService {
  encrypt(plaintext: Buffer, masterKey: Buffer): EncryptedData;
  decrypt(encryptedData: EncryptedData, masterKey: Buffer): Buffer;
  generateMasterKey(): Buffer;
  deriveKeyFromPassword(password: string, salt: Buffer): Promise<Buffer>;
}

// TSS 协议服务接口
export interface TssProtocolDomainService {
  runKeygen(params: KeygenParams): Promise<KeygenResult>;
  runSigning(params: SigningParams): Promise<SigningResult>;
  runRefresh(params: RefreshParams): Promise<RefreshResult>;
}
```

### 2. Application Layer (应用层)

#### Command Handlers

```typescript
// ParticipateInKeygenHandler
@CommandHandler(ParticipateInKeygenCommand)
export class ParticipateInKeygenHandler {
  async execute(command: ParticipateInKeygenCommand): Promise<KeygenResultDto> {
    // 1. 加入会话
    const sessionInfo = await this.coordinatorClient.joinSession(/*...*/);

    // 2. 运行 TSS Keygen 协议
    const keygenResult = await this.tssProtocolService.runKeygen(/*...*/);

    // 3. 加密并保存分片
    const encryptedShare = this.encryptionService.encrypt(/*...*/);
    const partyShare = PartyShare.create(/*...*/);
    await this.partyShareRepository.save(partyShare);

    // 4. 发布领域事件
    await this.eventPublisher.publishAll(partyShare.domainEvents);

    return result;
  }
}
```

#### Application Service

应用服务协调命令和查询处理器：

```typescript
@Injectable()
export class MPCPartyApplicationService {
  async participateInKeygen(params: ParticipateKeygenParams): Promise<KeygenResultDto>;
  async participateInSigning(params: ParticipateSigningParams): Promise<SigningResultDto>;
  async rotateShare(params: RotateShareParams): Promise<RotateResultDto>;
  async getShareInfo(shareId: string): Promise<ShareInfoDto>;
  async listShares(params: ListSharesParams): Promise<ListSharesResultDto>;
}
```

### 3. Infrastructure Layer (基础设施层)

#### Repository Implementation

```typescript
@Injectable()
export class PartyShareRepositoryImpl implements PartyShareRepository {
  constructor(
    private readonly prisma: PrismaService,
    private readonly mapper: PartyShareMapper,
  ) {}

  async save(share: PartyShare): Promise<void> {
    const entity = this.mapper.toPersistence(share);
    await this.prisma.partyShare.create({ data: entity });
  }

  async findById(id: ShareId): Promise<PartyShare | null> {
    const entity = await this.prisma.partyShare.findUnique({
      where: { id: id.value },
    });
    return entity ? this.mapper.toDomain(entity) : null;
  }
}
```

#### External Service Clients

```typescript
// MPC Coordinator Client - 与协调器通信
@Injectable()
export class MPCCoordinatorClient {
  async joinSession(params: JoinSessionParams): Promise<SessionInfo>;
  async reportCompletion(sessionId: string, status: string): Promise<void>;
}

// Message Router Client - P2P 消息传递
@Injectable()
export class MPCMessageRouterClient {
  async subscribeMessages(sessionId: string): Promise<AsyncIterator<Message>>;
  async sendMessage(message: Message): Promise<void>;
}
```

### 4. API Layer (API 层)

#### Controller

```typescript
@Controller('mpc-party')
@UseGuards(JwtAuthGuard)
export class MPCPartyController {
  // 异步端点 - 立即返回 202
  @Post('keygen/participate')
  @HttpCode(HttpStatus.ACCEPTED)
  async participateInKeygen(@Body() dto: ParticipateKeygenDto): Promise<KeygenAcceptedDto>;

  // 同步端点 - 等待完成
  @Post('keygen/participate-sync')
  async participateInKeygenSync(@Body() dto: ParticipateKeygenDto): Promise<KeygenResultDto>;

  // 查询端点
  @Get('shares')
  async listShares(@Query() query: ListSharesDto): Promise<ListSharesResponseDto>;

  @Get('shares/:shareId')
  async getShareInfo(@Param('shareId') shareId: string): Promise<ShareInfoResponseDto>;

  // 公开端点
  @Public()
  @Get('health')
  health(): HealthStatus;
}
```

## 数据流

### Keygen 流程

```
┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│  Client  │     │Controller│     │ Handler  │     │TSS Service│
└────┬─────┘     └────┬─────┘     └────┬─────┘     └────┬─────┘
     │                │                │                │
     │ POST /keygen   │                │                │
     │ /participate   │                │                │
     │───────────────>│                │                │
     │                │ execute()      │                │
     │                │───────────────>│                │
     │                │                │ joinSession()  │
     │                │                │───────────────>│ Coordinator
     │                │                │<───────────────│
     │                │                │                │
     │                │                │ runKeygen()    │
     │                │                │───────────────>│
     │                │                │    ...MPC...   │
     │                │                │<───────────────│
     │                │                │                │
     │                │                │ save(share)    │
     │                │                │───────────────>│ Repository
     │                │                │<───────────────│
     │                │                │                │
     │                │                │ publish(event) │
     │                │                │───────────────>│ Kafka
     │  202 Accepted  │<───────────────│                │
     │<───────────────│                │                │
     │                │                │                │
```

### Signing 流程

```
┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│  Client  │     │Controller│     │ Handler  │     │TSS Service│
└────┬─────┘     └────┬─────┘     └────┬─────┘     └────┬─────┘
     │                │                │                │
     │ POST /signing  │                │                │
     │ /participate   │                │                │
     │───────────────>│                │                │
     │                │ execute()      │                │
     │                │───────────────>│                │
     │                │                │ findShare()    │
     │                │                │───────────────>│ Repository
     │                │                │<───────────────│
     │                │                │                │
     │                │                │ decrypt()      │
     │                │                │───────────────>│ Encryption
     │                │                │<───────────────│
     │                │                │                │
     │                │                │ runSigning()   │
     │                │                │───────────────>│
     │                │                │    ...MPC...   │
     │                │                │<───────────────│
     │                │                │                │
     │  202 Accepted  │<───────────────│ signature      │
     │<───────────────│                │                │
```

## 安全设计

### 1. 分片加密

所有密钥分片在存储前使用 AES-256-GCM 加密：

```typescript
// 加密流程
const { encryptedData, iv, authTag } = encryptionService.encrypt(
  shareData,
  masterKey
);

// 存储加密后的数据
const shareData = ShareData.create(encryptedData, iv, authTag);
```

### 2. 访问控制

- JWT Token 验证
- Party ID 绑定
- 操作审计日志

### 3. 安全通信

- TLS 加密传输
- 消息签名验证
- 会话令牌认证

## 扩展性设计

### 1. 水平扩展

- 无状态服务设计
- Redis 分布式锁
- Kafka 事件驱动

### 2. 多协议支持

通过领域服务接口抽象，支持不同的 TSS 实现：

```typescript
// 接口定义
export interface TssProtocolDomainService {
  runKeygen(params: KeygenParams): Promise<KeygenResult>;
  runSigning(params: SigningParams): Promise<SigningResult>;
  runRefresh(params: RefreshParams): Promise<RefreshResult>;
}

// 可替换实现
// - GG20 实现
// - FROST 实现
// - 其他 TSS 协议
```

### 3. 插件化设计

基础设施层的实现可以轻松替换：

- 数据库：Prisma 支持多种数据库
- 缓存：可替换为其他缓存方案
- 消息队列：可替换为 RabbitMQ 等

## 配置管理

```typescript
// src/config/index.ts
export const configurations = [
  () => ({
    port: parseInt(process.env.APP_PORT, 10) || 3006,
    env: process.env.NODE_ENV || 'development',
    apiPrefix: process.env.API_PREFIX || 'api/v1',

    database: {
      url: process.env.DATABASE_URL,
    },

    redis: {
      host: process.env.REDIS_HOST,
      port: parseInt(process.env.REDIS_PORT, 10) || 6379,
    },

    mpc: {
      coordinatorUrl: process.env.MPC_COORDINATOR_URL,
      messageRouterWsUrl: process.env.MPC_MESSAGE_ROUTER_WS_URL,
      partyId: process.env.MPC_PARTY_ID,
    },

    security: {
      jwtSecret: process.env.JWT_SECRET,
      shareMasterKey: process.env.SHARE_MASTER_KEY,
    },
  }),
];
```

## 监控与可观测性

### 1. 日志

使用 NestJS Logger，支持结构化日志：

```typescript
private readonly logger = new Logger(MPCPartyController.name);

this.logger.log(`Keygen request: session=${sessionId}, party=${partyId}`);
this.logger.error(`Keygen failed: ${error.message}`, error.stack);
```

### 2. 健康检查

```typescript
@Get('health')
health() {
  return {
    status: 'ok',
    timestamp: new Date().toISOString(),
    service: 'mpc-party-service',
  };
}
```

### 3. 指标（待实现）

- 请求延迟
- 错误率
- MPC 协议执行时间
- 分片操作统计

## 依赖关系图

```
┌─────────────────────────────────────────────────────────────┐
│                         AppModule                            │
├─────────────────────────────────────────────────────────────┤
│  imports:                                                    │
│    ├── ConfigModule (global)                                │
│    ├── JwtModule (global)                                   │
│    ├── DomainModule                                         │
│    ├── InfrastructureModule                                 │
│    ├── ApplicationModule                                    │
│    └── ApiModule                                            │
│                                                              │
│  providers:                                                  │
│    ├── GlobalExceptionFilter                                │
│    ├── TransformInterceptor                                 │
│    └── JwtAuthGuard                                         │
└─────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│  DomainModule   │  │Infrastructure   │  │ApplicationModule│
│                 │  │    Module       │  │                 │
│ - Encryption    │◄─┤ - Prisma        │◄─┤ - Handlers      │
│   Service       │  │ - Redis         │  │ - AppService    │
│ - TSS Service   │  │ - Kafka         │  │                 │
│   (interface)   │  │ - Clients       │  │                 │
└─────────────────┘  └─────────────────┘  └─────────────────┘
                              │
                              ▼
                     ┌─────────────────┐
                     │    ApiModule    │
                     │                 │
                     │ - Controllers   │
                     │ - DTOs          │
                     └─────────────────┘
```

## 总结

MPC Party Service 采用清晰的分层架构，遵循 DDD 和 CQRS 原则，实现了：

1. **高内聚低耦合**：各层职责明确，依赖于抽象
2. **可测试性**：依赖注入使得单元测试和集成测试易于实现
3. **可扩展性**：插件化设计支持不同的 TSS 协议和基础设施
4. **安全性**：多层安全措施保护敏感的密钥分片
5. **可观测性**：完善的日志和健康检查支持运维监控
