2025-12-22 13:37:57 +08:00
|
|
|
|
package model
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"errors"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
|
|
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
|
|
|
|
|
2025-12-26 14:35:39 +08:00
|
|
|
|
"go.yandata.net/wangsiyuan/go-trustlog/api/grpc/pb"
|
2025-12-22 13:37:57 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// FromProtobuf 将protobuf的OperationData转换为model.Operation.
|
|
|
|
|
|
func FromProtobuf(pbOp *pb.OperationData) (*Operation, error) {
|
|
|
|
|
|
if pbOp == nil {
|
|
|
|
|
|
return nil, errors.New("protobuf operation data is nil")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 转换时间戳
|
|
|
|
|
|
if pbOp.GetTimestamp() == nil {
|
|
|
|
|
|
return nil, errors.New("timestamp is required")
|
|
|
|
|
|
}
|
|
|
|
|
|
timestamp := pbOp.GetTimestamp().AsTime()
|
|
|
|
|
|
|
|
|
|
|
|
// 构建Operation
|
|
|
|
|
|
operation := &Operation{
|
|
|
|
|
|
OpID: pbOp.GetOpId(),
|
|
|
|
|
|
Timestamp: timestamp,
|
|
|
|
|
|
OpSource: Source(pbOp.GetOpSource()),
|
2025-12-26 13:47:55 +08:00
|
|
|
|
OpCode: OpCode(pbOp.GetOpCode()),
|
2025-12-22 13:37:57 +08:00
|
|
|
|
DoPrefix: pbOp.GetDoPrefix(),
|
|
|
|
|
|
DoRepository: pbOp.GetDoRepository(),
|
|
|
|
|
|
Doid: pbOp.GetDoid(),
|
|
|
|
|
|
ProducerID: pbOp.GetProducerId(),
|
|
|
|
|
|
OpActor: pbOp.GetOpActor(),
|
|
|
|
|
|
// OpAlgorithm和OpMetaHash字段已移除,固定使用Sha256Simd,哈希值由Envelope的OriginalHash提供
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理可选的哈希字段
|
|
|
|
|
|
if reqHash := pbOp.GetRequestBodyHash(); reqHash != "" {
|
|
|
|
|
|
operation.RequestBodyHash = &reqHash
|
|
|
|
|
|
}
|
|
|
|
|
|
if respHash := pbOp.GetResponseBodyHash(); respHash != "" {
|
|
|
|
|
|
operation.ResponseBodyHash = &respHash
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return operation, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ToProtobuf 将model.Operation转换为protobuf的OperationData.
|
|
|
|
|
|
func ToProtobuf(op *Operation) (*pb.OperationData, error) {
|
|
|
|
|
|
if op == nil {
|
|
|
|
|
|
return nil, errors.New("operation is nil")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 转换时间戳
|
|
|
|
|
|
timestamp := timestamppb.New(op.Timestamp)
|
|
|
|
|
|
|
|
|
|
|
|
pbOp := &pb.OperationData{
|
|
|
|
|
|
OpId: op.OpID,
|
|
|
|
|
|
Timestamp: timestamp,
|
|
|
|
|
|
OpSource: string(op.OpSource),
|
2025-12-26 13:47:55 +08:00
|
|
|
|
OpCode: int32(op.OpCode),
|
2025-12-22 13:37:57 +08:00
|
|
|
|
DoPrefix: op.DoPrefix,
|
|
|
|
|
|
DoRepository: op.DoRepository,
|
|
|
|
|
|
Doid: op.Doid,
|
|
|
|
|
|
ProducerId: op.ProducerID,
|
|
|
|
|
|
OpActor: op.OpActor,
|
|
|
|
|
|
// OpAlgorithm、OpMetaHash和OpHash字段已移除,固定使用Sha256Simd,哈希值由Envelope的OriginalHash提供
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理可选的哈希字段
|
|
|
|
|
|
if op.RequestBodyHash != nil {
|
|
|
|
|
|
pbOp.RequestBodyHash = *op.RequestBodyHash
|
|
|
|
|
|
}
|
|
|
|
|
|
if op.ResponseBodyHash != nil {
|
|
|
|
|
|
pbOp.ResponseBodyHash = *op.ResponseBodyHash
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return pbOp, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FromProtobufValidationResult 将protobuf的ValidationStreamRes转换为model.ValidationResult.
|
|
|
|
|
|
func FromProtobufValidationResult(pbRes *pb.ValidationStreamRes) (*ValidationResult, error) {
|
|
|
|
|
|
if pbRes == nil {
|
|
|
|
|
|
return nil, errors.New("protobuf validation result is nil")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result := &ValidationResult{
|
|
|
|
|
|
Code: pbRes.GetCode(),
|
|
|
|
|
|
Msg: pbRes.GetMsg(),
|
|
|
|
|
|
Progress: pbRes.GetProgress(),
|
|
|
|
|
|
Proof: ProofFromProtobuf(pbRes.GetProof()), // 取证证明
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果有操作数据,则转换
|
|
|
|
|
|
if pbRes.GetData() != nil {
|
|
|
|
|
|
op, err := FromProtobuf(pbRes.GetData())
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("failed to convert operation data: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
result.Data = op
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RecordFromProtobuf 将protobuf的RecordData转换为model.Record.
|
|
|
|
|
|
func RecordFromProtobuf(pbRec *pb.RecordData) (*Record, error) {
|
|
|
|
|
|
if pbRec == nil {
|
|
|
|
|
|
return nil, errors.New("protobuf record data is nil")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 构建Record
|
|
|
|
|
|
record := &Record{
|
|
|
|
|
|
ID: pbRec.GetId(),
|
|
|
|
|
|
DoPrefix: pbRec.GetDoPrefix(),
|
|
|
|
|
|
ProducerID: pbRec.GetProducerId(),
|
|
|
|
|
|
Operator: pbRec.GetOperator(),
|
|
|
|
|
|
Extra: pbRec.GetExtra(),
|
|
|
|
|
|
RCType: pbRec.GetRcType(),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 转换时间戳
|
|
|
|
|
|
if pbRec.GetTimestamp() != nil {
|
|
|
|
|
|
record.Timestamp = pbRec.GetTimestamp().AsTime()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return record, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RecordToProtobuf 将model.Record转换为protobuf的RecordData.
|
|
|
|
|
|
func RecordToProtobuf(rec *Record) (*pb.RecordData, error) {
|
|
|
|
|
|
if rec == nil {
|
|
|
|
|
|
return nil, errors.New("record is nil")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 转换时间戳
|
|
|
|
|
|
timestamp := timestamppb.New(rec.Timestamp)
|
|
|
|
|
|
|
|
|
|
|
|
pbRec := &pb.RecordData{
|
|
|
|
|
|
Id: rec.ID,
|
|
|
|
|
|
DoPrefix: rec.DoPrefix,
|
|
|
|
|
|
ProducerId: rec.ProducerID,
|
|
|
|
|
|
Timestamp: timestamp,
|
|
|
|
|
|
Operator: rec.Operator,
|
|
|
|
|
|
Extra: rec.Extra,
|
|
|
|
|
|
RcType: rec.RCType,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return pbRec, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RecordValidationResult 包装记录验证的流式响应结果.
|
|
|
|
|
|
type RecordValidationResult struct {
|
|
|
|
|
|
Code int32 // 状态码(100处理中,200完成,500失败)
|
|
|
|
|
|
Msg string // 消息描述
|
|
|
|
|
|
Progress string // 当前进度(比如 "50%")
|
|
|
|
|
|
Data *Record // 最终完成时返回的记录数据,过程中可为空
|
|
|
|
|
|
Proof *Proof // 取证证明(仅在完成时返回)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsProcessing 判断是否正在处理中.
|
|
|
|
|
|
func (r *RecordValidationResult) IsProcessing() bool {
|
|
|
|
|
|
return r.Code == ValidationCodeProcessing
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsCompleted 判断是否已完成.
|
|
|
|
|
|
func (r *RecordValidationResult) IsCompleted() bool {
|
|
|
|
|
|
return r.Code == ValidationCodeCompleted
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsFailed 判断是否失败.
|
|
|
|
|
|
func (r *RecordValidationResult) IsFailed() bool {
|
|
|
|
|
|
return r.Code >= ValidationCodeFailed
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RecordFromProtobufValidationResult 将protobuf的RecordValidationStreamRes转换为model.RecordValidationResult.
|
|
|
|
|
|
func RecordFromProtobufValidationResult(pbRes *pb.RecordValidationStreamRes) (*RecordValidationResult, error) {
|
|
|
|
|
|
if pbRes == nil {
|
|
|
|
|
|
return nil, errors.New("protobuf record validation result is nil")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result := &RecordValidationResult{
|
|
|
|
|
|
Code: pbRes.GetCode(),
|
|
|
|
|
|
Msg: pbRes.GetMsg(),
|
|
|
|
|
|
Progress: pbRes.GetProgress(),
|
|
|
|
|
|
Proof: ProofFromProtobuf(pbRes.GetProof()), // 取证证明
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果有记录数据,则转换
|
|
|
|
|
|
if pbRes.GetResult() != nil {
|
|
|
|
|
|
rec, err := RecordFromProtobuf(pbRes.GetResult())
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("failed to convert record data: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
result.Data = rec
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
|
|
}
|