code.vegaprotocol.io/vega@v0.79.0/datanode/api/utils.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package api 17 18 import ( 19 "context" 20 "fmt" 21 22 "code.vegaprotocol.io/vega/datanode/entities" 23 24 "golang.org/x/sync/errgroup" 25 "google.golang.org/grpc/codes" 26 "google.golang.org/protobuf/proto" 27 ) 28 29 func toProtos[T proto.Message, V entities.ProtoEntity[T]](inputs []V) []T { 30 protos := make([]T, 0, len(inputs)) 31 for _, input := range inputs { 32 proto := input.ToProto() 33 protos = append(protos, proto) 34 } 35 return protos 36 } 37 38 func mapSlice[T proto.Message, V any](inputs []V, toProto func(V) (T, error)) ([]T, error) { 39 protos := make([]T, 0, len(inputs)) 40 for _, input := range inputs { 41 proto, err := toProto(input) 42 if err != nil { 43 return nil, fmt.Errorf("failed to convert to proto: %w", err) 44 } 45 protos = append(protos, proto) 46 } 47 return protos, nil 48 } 49 50 // queryProtoEntities invokes queryFunc and converts the entity to protos. 51 func queryProtoEntities[T proto.Message, E entities.ProtoEntity[T]]( 52 ctx context.Context, eg *errgroup.Group, txHash entities.TxHash, 53 queryFunc func(ctx context.Context, txHash entities.TxHash) ([]E, error), 54 apiErr error, 55 ) chan []T { 56 outChan := make(chan []T, 1) 57 58 eg.Go(func() error { 59 items, err := queryFunc(ctx, txHash) 60 if err != nil { 61 return apiError(codes.Internal, apiErr, err) 62 } 63 64 outChan <- toProtos[T](items) 65 return nil 66 }) 67 68 return outChan 69 } 70 71 type mapableEntities interface { 72 entities.Entities | entities.LedgerEntry | entities.Transfer | entities.MarginLevels 73 } 74 75 // queryAndMapEntities invokes queryFunc and maps every single entity with mapFunc. 76 func queryAndMapEntities[T proto.Message, E mapableEntities]( 77 ctx context.Context, eg *errgroup.Group, txHash entities.TxHash, 78 queryFunc func(context.Context, entities.TxHash) ([]E, error), 79 mapFunc func(E) (T, error), 80 apiErr error, 81 ) chan []T { 82 outChan := make(chan []T, 1) 83 84 eg.Go(func() error { 85 items, err := queryFunc(ctx, txHash) 86 if err != nil { 87 return apiError(codes.Internal, apiErr, err) 88 } 89 90 mapped, err := mapSlice(items, mapFunc) 91 if err != nil { 92 return apiError(codes.Internal, apiErr, err) 93 } 94 95 outChan <- mapped 96 return nil 97 }) 98 99 return outChan 100 }