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