feat: add durable Kuknos settlement coordination
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package grpcadapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
|
||||
"gl/domain/ledger"
|
||||
ledgerv1 "gl/gen/ledger/v1"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func (h *Handler) EnqueueSettlement(ctx context.Context, request *ledgerv1.EnqueueSettlementRequest) (*ledgerv1.EnqueueSettlementResponse, error) {
|
||||
if h.settlement == nil {
|
||||
return nil, status.Error(codes.Unimplemented, "settlement is not configured")
|
||||
}
|
||||
record, already, err := h.settlement.Enqueue(ctx, request.GetSourceService(), request.GetSourceTransactionId(), request.GetIdempotencyKey(), request.GetNetwork(), request.GetSignedTransactionXdr())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
return &ledgerv1.EnqueueSettlementResponse{SettlementId: record.ID, Status: string(record.Status), AlreadyExisted: already}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) RetrySettlement(ctx context.Context, request *ledgerv1.RetrySettlementRequest) (*ledgerv1.RetrySettlementResponse, error) {
|
||||
if h.settlement == nil {
|
||||
return nil, status.Error(codes.Unimplemented, "settlement is not configured")
|
||||
}
|
||||
values := metadata.ValueFromIncomingContext(ctx, "x-admin-token")
|
||||
if h.adminToken == "" || len(values) != 1 || subtle.ConstantTimeCompare([]byte(values[0]), []byte(h.adminToken)) != 1 {
|
||||
return nil, status.Error(codes.PermissionDenied, "invalid administrative token")
|
||||
}
|
||||
record, err := h.settlement.RetryByOperator(ctx, request.GetSettlementId(), request.GetActorId(), request.GetReason())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.FailedPrecondition, err.Error())
|
||||
}
|
||||
return &ledgerv1.RetrySettlementResponse{Settlement: settlementMessage(record)}, nil
|
||||
}
|
||||
|
||||
func settlementMessage(record ledger.Settlement) *ledgerv1.Settlement {
|
||||
return &ledgerv1.Settlement{SettlementId: record.ID, SourceService: record.SourceService, SourceTransactionId: record.SourceTxID, IdempotencyKey: record.IdempotencyKey, Status: string(record.Status), Network: record.Network, TransactionHash: record.TransactionHash, Attempts: uint32(record.Attempts), LastError: record.LastError}
|
||||
}
|
||||
|
||||
func (h *Handler) GetSettlement(ctx context.Context, request *ledgerv1.GetSettlementRequest) (*ledgerv1.Settlement, error) {
|
||||
if h.settlement == nil {
|
||||
return nil, status.Error(codes.Unimplemented, "settlement is not configured")
|
||||
}
|
||||
var id, key string
|
||||
switch lookup := request.GetLookup().(type) {
|
||||
case *ledgerv1.GetSettlementRequest_SettlementId:
|
||||
id = lookup.SettlementId
|
||||
case *ledgerv1.GetSettlementRequest_IdempotencyKey:
|
||||
key = lookup.IdempotencyKey
|
||||
}
|
||||
record, err := h.settlement.Get(ctx, id, key)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.NotFound, err.Error())
|
||||
}
|
||||
return settlementMessage(record), nil
|
||||
}
|
||||
Reference in New Issue
Block a user