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  }