github.com/Finschia/finschia-sdk@v0.49.1/client/grpc/tmservice/service.go (about) 1 package tmservice 2 3 import ( 4 "context" 5 6 octypes "github.com/Finschia/ostracon/proto/ostracon/types" 7 gogogrpc "github.com/gogo/protobuf/grpc" 8 "github.com/grpc-ecosystem/grpc-gateway/runtime" 9 tmtypes "github.com/tendermint/tendermint/proto/tendermint/types" 10 "google.golang.org/grpc/codes" 11 "google.golang.org/grpc/status" 12 13 "github.com/Finschia/finschia-sdk/client" 14 "github.com/Finschia/finschia-sdk/client/rpc" 15 codectypes "github.com/Finschia/finschia-sdk/codec/types" 16 cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" 17 qtypes "github.com/Finschia/finschia-sdk/types/query" 18 "github.com/Finschia/finschia-sdk/version" 19 ) 20 21 // This is the struct that we will implement all the handlers on. 22 type queryServer struct { 23 clientCtx client.Context 24 interfaceRegistry codectypes.InterfaceRegistry 25 } 26 27 var ( 28 _ ServiceServer = queryServer{} 29 _ codectypes.UnpackInterfacesMessage = &GetLatestValidatorSetResponse{} 30 ) 31 32 // NewQueryServer creates a new tendermint query server. 33 func NewQueryServer(clientCtx client.Context, interfaceRegistry codectypes.InterfaceRegistry) ServiceServer { 34 return queryServer{ 35 clientCtx: clientCtx, 36 interfaceRegistry: interfaceRegistry, 37 } 38 } 39 40 // GetSyncing implements ServiceServer.GetSyncing 41 func (s queryServer) GetSyncing(ctx context.Context, _ *GetSyncingRequest) (*GetSyncingResponse, error) { 42 status, err := GetNodeStatus(ctx, s.clientCtx) 43 if err != nil { 44 return nil, err 45 } 46 return &GetSyncingResponse{ 47 Syncing: status.SyncInfo.CatchingUp, 48 }, nil 49 } 50 51 // ConvertOcProtoBlockToTmProtoBlock convert from ostracon proto block to tendermint proto block. 52 func ConvertOcProtoBlockToTmProtoBlock(block *octypes.Block) *tmtypes.Block { 53 return &tmtypes.Block{ 54 Header: block.Header, 55 Data: block.Data, 56 Evidence: block.Evidence, 57 LastCommit: block.LastCommit, 58 } 59 } 60 61 // GetLatestBlock implements ServiceServer.GetLatestBlock 62 func (s queryServer) GetLatestBlock(ctx context.Context, _ *GetLatestBlockRequest) (*GetLatestBlockResponse, error) { 63 status, err := GetBlock(ctx, s.clientCtx, nil) 64 if err != nil { 65 return nil, err 66 } 67 68 protoBlockID := status.BlockID.ToProto() 69 protoBlock, err := status.Block.ToProto() 70 if err != nil { 71 return nil, err 72 } 73 74 return &GetLatestBlockResponse{ 75 BlockId: &protoBlockID, 76 Block: ConvertOcProtoBlockToTmProtoBlock(protoBlock), 77 }, nil 78 } 79 80 // GetBlockByHeight implements ServiceServer.GetBlockByHeight 81 func (s queryServer) GetBlockByHeight(ctx context.Context, req *GetBlockByHeightRequest) (*GetBlockByHeightResponse, error) { 82 chainHeight, err := rpc.GetChainHeight(s.clientCtx) 83 if err != nil { 84 return nil, err 85 } 86 87 if req.Height > chainHeight { 88 return nil, status.Error(codes.InvalidArgument, "requested block height is bigger then the chain length") 89 } 90 91 protoBlockID, protoBlock, err := GetProtoBlock(ctx, s.clientCtx, &req.Height) 92 if err != nil { 93 return nil, err 94 } 95 return &GetBlockByHeightResponse{ 96 BlockId: &protoBlockID, 97 Block: ConvertOcProtoBlockToTmProtoBlock(protoBlock), 98 }, nil 99 } 100 101 // GetLatestValidatorSet implements ServiceServer.GetLatestValidatorSet 102 func (s queryServer) GetLatestValidatorSet(ctx context.Context, req *GetLatestValidatorSetRequest) (*GetLatestValidatorSetResponse, error) { 103 page, limit, err := qtypes.ParsePagination(req.Pagination) 104 if err != nil { 105 return nil, err 106 } 107 return validatorsOutput(ctx, s.clientCtx, nil, page, limit) 108 } 109 110 func (m *GetLatestValidatorSetResponse) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { 111 var pubKey cryptotypes.PubKey 112 for _, val := range m.Validators { 113 err := unpacker.UnpackAny(val.PubKey, &pubKey) 114 if err != nil { 115 return err 116 } 117 } 118 return nil 119 } 120 121 // GetValidatorSetByHeight implements ServiceServer.GetValidatorSetByHeight 122 func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *GetValidatorSetByHeightRequest) (*GetValidatorSetByHeightResponse, error) { 123 page, limit, err := qtypes.ParsePagination(req.Pagination) 124 if err != nil { 125 return nil, err 126 } 127 128 chainHeight, err := rpc.GetChainHeight(s.clientCtx) 129 if err != nil { 130 return nil, status.Error(codes.Internal, "failed to parse chain height") 131 } 132 if req.Height > chainHeight { 133 return nil, status.Error(codes.InvalidArgument, "requested block height is bigger then the chain length") 134 } 135 r, err := validatorsOutput(ctx, s.clientCtx, &req.Height, page, limit) 136 if err != nil { 137 return nil, err 138 } 139 return &GetValidatorSetByHeightResponse{ 140 BlockHeight: r.BlockHeight, 141 Validators: r.Validators, 142 Pagination: r.Pagination, 143 }, nil 144 } 145 146 func validatorsOutput(ctx context.Context, cctx client.Context, height *int64, page, limit int) (*GetLatestValidatorSetResponse, error) { 147 vs, err := rpc.GetValidators(ctx, cctx, height, &page, &limit) 148 if err != nil { 149 return nil, err 150 } 151 resp := GetLatestValidatorSetResponse{ 152 BlockHeight: vs.BlockHeight, 153 Validators: make([]*Validator, len(vs.Validators)), 154 Pagination: &qtypes.PageResponse{ 155 Total: vs.Total, 156 }, 157 } 158 for i, v := range vs.Validators { 159 anyPub, err := codectypes.NewAnyWithValue(v.PubKey) 160 if err != nil { 161 return nil, err 162 } 163 resp.Validators[i] = &Validator{ 164 Address: v.Address.String(), 165 ProposerPriority: v.ProposerPriority, 166 PubKey: anyPub, 167 VotingPower: v.VotingPower, 168 } 169 } 170 return &resp, nil 171 } 172 173 // GetNodeInfo implements ServiceServer.GetNodeInfo 174 func (s queryServer) GetNodeInfo(ctx context.Context, req *GetNodeInfoRequest) (*GetNodeInfoResponse, error) { 175 status, err := GetNodeStatus(ctx, s.clientCtx) 176 if err != nil { 177 return nil, err 178 } 179 180 protoNodeInfo := status.NodeInfo.ToProto() 181 nodeInfo := version.NewInfo() 182 183 deps := make([]*Module, len(nodeInfo.BuildDeps)) 184 185 for i, dep := range nodeInfo.BuildDeps { 186 deps[i] = &Module{ 187 Path: dep.Path, 188 Sum: dep.Sum, 189 Version: dep.Version, 190 } 191 } 192 193 resp := GetNodeInfoResponse{ 194 DefaultNodeInfo: protoNodeInfo, 195 ApplicationVersion: &VersionInfo{ 196 AppName: nodeInfo.AppName, 197 Name: nodeInfo.Name, 198 GitCommit: nodeInfo.GitCommit, 199 GoVersion: nodeInfo.GoVersion, 200 Version: nodeInfo.Version, 201 BuildTags: nodeInfo.BuildTags, 202 BuildDeps: deps, 203 CosmosSdkVersion: nodeInfo.LbmSdkVersion, 204 }, 205 } 206 return &resp, nil 207 } 208 209 // RegisterTendermintService registers the tendermint queries on the gRPC router. 210 func RegisterTendermintService( 211 qrt gogogrpc.Server, 212 clientCtx client.Context, 213 interfaceRegistry codectypes.InterfaceRegistry, 214 ) { 215 RegisterServiceServer( 216 qrt, 217 NewQueryServer(clientCtx, interfaceRegistry), 218 ) 219 } 220 221 // RegisterGRPCGatewayRoutes mounts the tendermint service's GRPC-gateway routes on the 222 // given Mux. 223 func RegisterGRPCGatewayRoutes(clientConn gogogrpc.ClientConn, mux *runtime.ServeMux) { 224 err := RegisterServiceHandlerClient(context.Background(), mux, NewServiceClient(clientConn)) 225 if err != nil { 226 panic(err) 227 } 228 }