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