github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/02-client/keeper/grpc_query.go (about)

     1  package keeper
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"sort"
     8  	"strings"
     9  
    10  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/prefix"
    11  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    12  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
    13  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/query"
    14  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types"
    15  	host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
    16  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported"
    17  	"google.golang.org/grpc/codes"
    18  	"google.golang.org/grpc/status"
    19  )
    20  
    21  var _ types.QueryServer = Keeper{}
    22  
    23  // ClientState implements the Query/ClientState gRPC method
    24  func (q Keeper) ClientState(c context.Context, req *types.QueryClientStateRequest) (*types.QueryClientStateResponse, error) {
    25  	if req == nil {
    26  		return nil, status.Error(codes.InvalidArgument, "empty request")
    27  	}
    28  
    29  	if err := host.ClientIdentifierValidator(req.ClientId); err != nil {
    30  		return nil, status.Error(codes.InvalidArgument, err.Error())
    31  	}
    32  
    33  	ctx := sdk.UnwrapSDKContext(c)
    34  	clientState, found := q.GetClientState(ctx, req.ClientId)
    35  	if !found {
    36  		return nil, status.Error(
    37  			codes.NotFound,
    38  			sdkerrors.Wrap(types.ErrClientNotFound, req.ClientId).Error(),
    39  		)
    40  	}
    41  
    42  	any, err := types.PackClientState(clientState)
    43  	if err != nil {
    44  		return nil, status.Error(codes.Internal, err.Error())
    45  	}
    46  
    47  	proofHeight := types.GetSelfHeight(ctx)
    48  	return &types.QueryClientStateResponse{
    49  		ClientState: any,
    50  		ProofHeight: proofHeight,
    51  	}, nil
    52  }
    53  
    54  // ClientStates implements the Query/ClientStates gRPC method
    55  func (q Keeper) ClientStates(c context.Context, req *types.QueryClientStatesRequest) (*types.QueryClientStatesResponse, error) {
    56  	if req == nil {
    57  		return nil, status.Error(codes.InvalidArgument, "empty request")
    58  	}
    59  
    60  	ctx := sdk.UnwrapSDKContext(c)
    61  
    62  	clientStates := types.IdentifiedClientStates{}
    63  	store := prefix.NewStore(ctx.KVStore(q.storeKey), host.KeyClientStorePrefix)
    64  
    65  	pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error {
    66  		keySplit := strings.Split(string(key), "/")
    67  		if keySplit[len(keySplit)-1] != "clientState" {
    68  			return nil
    69  		}
    70  
    71  		clientState, err := q.UnmarshalClientState(value)
    72  		if err != nil {
    73  			return err
    74  		}
    75  
    76  		clientID := keySplit[1]
    77  		if err := host.ClientIdentifierValidator(clientID); err != nil {
    78  			return err
    79  		}
    80  
    81  		identifiedClient := types.NewIdentifiedClientState(clientID, clientState)
    82  		clientStates = append(clientStates, identifiedClient)
    83  		return nil
    84  	})
    85  
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	sort.Sort(clientStates)
    91  
    92  	return &types.QueryClientStatesResponse{
    93  		ClientStates: clientStates,
    94  		Pagination:   pageRes,
    95  	}, nil
    96  }
    97  
    98  // ConsensusState implements the Query/ConsensusState gRPC method
    99  func (q Keeper) ConsensusState(c context.Context, req *types.QueryConsensusStateRequest) (*types.QueryConsensusStateResponse, error) {
   100  	if req == nil {
   101  		return nil, status.Error(codes.InvalidArgument, "empty request")
   102  	}
   103  
   104  	if err := host.ClientIdentifierValidator(req.ClientId); err != nil {
   105  		return nil, status.Error(codes.InvalidArgument, err.Error())
   106  	}
   107  
   108  	ctx := sdk.UnwrapSDKContext(c)
   109  
   110  	var (
   111  		consensusState exported.ConsensusState
   112  		found          bool
   113  	)
   114  
   115  	height := types.NewHeight(req.RevisionNumber, req.RevisionHeight)
   116  	if req.LatestHeight {
   117  		consensusState, found = q.GetLatestClientConsensusState(ctx, req.ClientId)
   118  	} else {
   119  		if req.RevisionHeight == 0 {
   120  			return nil, status.Error(codes.InvalidArgument, "consensus state height cannot be 0")
   121  		}
   122  
   123  		consensusState, found = q.GetClientConsensusState(ctx, req.ClientId, height)
   124  	}
   125  
   126  	if !found {
   127  		return nil, status.Error(
   128  			codes.NotFound,
   129  			sdkerrors.Wrapf(types.ErrConsensusStateNotFound, "client-id: %s, height: %s", req.ClientId, height).Error(),
   130  		)
   131  	}
   132  
   133  	any, err := types.PackConsensusState(consensusState)
   134  	if err != nil {
   135  		return nil, status.Error(codes.Internal, err.Error())
   136  	}
   137  
   138  	proofHeight := types.GetSelfHeight(ctx)
   139  	return &types.QueryConsensusStateResponse{
   140  		ConsensusState: any,
   141  		ProofHeight:    proofHeight,
   142  	}, nil
   143  }
   144  
   145  // ConsensusStates implements the Query/ConsensusStates gRPC method
   146  func (q Keeper) ConsensusStates(c context.Context, req *types.QueryConsensusStatesRequest) (*types.QueryConsensusStatesResponse, error) {
   147  	if req == nil {
   148  		return nil, status.Error(codes.InvalidArgument, "empty request")
   149  	}
   150  
   151  	if err := host.ClientIdentifierValidator(req.ClientId); err != nil {
   152  		return nil, status.Error(codes.InvalidArgument, err.Error())
   153  	}
   154  
   155  	ctx := sdk.UnwrapSDKContext(c)
   156  
   157  	consensusStates := []types.ConsensusStateWithHeight{}
   158  	store := prefix.NewStore(ctx.KVStore(q.storeKey), host.FullClientKey(req.ClientId, []byte(fmt.Sprintf("%s/", host.KeyConsensusStatePrefix))))
   159  
   160  	pageRes, err := query.FilteredPaginate(store, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) {
   161  		// filter any metadata stored under consensus state key
   162  		if strings.Contains(string(key), "/") {
   163  			return false, nil
   164  		}
   165  
   166  		height, err := types.ParseHeight(string(key))
   167  		if err != nil {
   168  			return false, err
   169  		}
   170  
   171  		consensusState, err := q.UnmarshalConsensusState(value)
   172  		if err != nil {
   173  			return false, err
   174  		}
   175  
   176  		consensusStates = append(consensusStates, types.NewConsensusStateWithHeight(height, consensusState))
   177  		return true, nil
   178  	})
   179  
   180  	if err != nil {
   181  		return nil, err
   182  	}
   183  
   184  	return &types.QueryConsensusStatesResponse{
   185  		ConsensusStates: consensusStates,
   186  		Pagination:      pageRes,
   187  	}, nil
   188  }
   189  
   190  // ConsensusStateHeights implements the Query/ConsensusStateHeights gRPC method
   191  func (q Keeper) ConsensusStateHeights(c context.Context, req *types.QueryConsensusStateHeightsRequest) (*types.QueryConsensusStateHeightsResponse, error) {
   192  	if req == nil {
   193  		return nil, status.Error(codes.InvalidArgument, "empty request")
   194  	}
   195  
   196  	if err := host.ClientIdentifierValidator(req.ClientId); err != nil {
   197  		return nil, status.Error(codes.InvalidArgument, err.Error())
   198  	}
   199  
   200  	ctx := sdk.UnwrapSDKContext(c)
   201  
   202  	var consensusStateHeights []types.Height
   203  	store := prefix.NewStore(ctx.KVStore(q.storeKey), host.FullClientKey(req.ClientId, []byte(fmt.Sprintf("%s/", host.KeyConsensusStatePrefix))))
   204  
   205  	pageRes, err := query.FilteredPaginate(store, req.Pagination, func(key, _ []byte, accumulate bool) (bool, error) {
   206  		// filter any metadata stored under consensus state key
   207  		if bytes.Contains(key, []byte("/")) {
   208  			return false, nil
   209  		}
   210  
   211  		height, err := types.ParseHeight(string(key))
   212  		if err != nil {
   213  			return false, err
   214  		}
   215  
   216  		consensusStateHeights = append(consensusStateHeights, height)
   217  		return true, nil
   218  	})
   219  
   220  	if err != nil {
   221  		return nil, err
   222  	}
   223  
   224  	return &types.QueryConsensusStateHeightsResponse{
   225  		ConsensusStateHeights: consensusStateHeights,
   226  		Pagination:            pageRes,
   227  	}, nil
   228  }
   229  
   230  // ClientStatus implements the Query/ClientStatus gRPC method
   231  func (q Keeper) ClientStatus(c context.Context, req *types.QueryClientStatusRequest) (*types.QueryClientStatusResponse, error) {
   232  	if req == nil {
   233  		return nil, status.Error(codes.InvalidArgument, "empty request")
   234  	}
   235  
   236  	if err := host.ClientIdentifierValidator(req.ClientId); err != nil {
   237  		return nil, status.Error(codes.InvalidArgument, err.Error())
   238  	}
   239  
   240  	ctx := sdk.UnwrapSDKContext(c)
   241  	clientState, found := q.GetClientState(ctx, req.ClientId)
   242  	if !found {
   243  		return nil, status.Error(
   244  			codes.NotFound,
   245  			sdkerrors.Wrap(types.ErrClientNotFound, req.ClientId).Error(),
   246  		)
   247  	}
   248  
   249  	clientStore := q.ClientStore(ctx, req.ClientId)
   250  	status := clientState.Status(ctx, clientStore, q.cdc)
   251  
   252  	return &types.QueryClientStatusResponse{
   253  		Status: string(status),
   254  	}, nil
   255  }
   256  
   257  // ClientParams implements the Query/ClientParams gRPC method
   258  func (q Keeper) ClientParams(c context.Context, _ *types.QueryClientParamsRequest) (*types.QueryClientParamsResponse, error) {
   259  	ctx := sdk.UnwrapSDKContext(c)
   260  	params := q.GetParams(ctx)
   261  
   262  	return &types.QueryClientParamsResponse{
   263  		Params: &params,
   264  	}, nil
   265  }
   266  
   267  func (q Keeper) UpgradedClientState(c context.Context, req *types.QueryUpgradedClientStateRequest) (*types.QueryUpgradedClientStateResponse, error) {
   268  	if req == nil {
   269  		return nil, status.Error(codes.InvalidArgument, "empty request")
   270  	}
   271  
   272  	ctx := sdk.UnwrapSDKContext(c)
   273  
   274  	plan, found := q.GetUpgradePlan(ctx)
   275  	if !found {
   276  		return nil, status.Error(
   277  			codes.NotFound, "upgrade plan not found",
   278  		)
   279  	}
   280  
   281  	bz, found := q.GetUpgradedClient(ctx, plan.Height)
   282  	if !found {
   283  		return nil, status.Error(codes.NotFound, types.ErrClientNotFound.Error())
   284  	}
   285  
   286  	clientState, err := types.UnmarshalClientState(q.cdc, bz)
   287  	if err != nil {
   288  		return nil, status.Error(
   289  			codes.Internal, err.Error(),
   290  		)
   291  	}
   292  
   293  	any, err := types.PackClientState(clientState)
   294  	if err != nil {
   295  		return nil, status.Error(codes.Internal, err.Error())
   296  	}
   297  
   298  	return &types.QueryUpgradedClientStateResponse{
   299  		UpgradedClientState: any,
   300  	}, nil
   301  }
   302  
   303  func (q Keeper) UpgradedConsensusState(c context.Context, req *types.QueryUpgradedConsensusStateRequest) (*types.QueryUpgradedConsensusStateResponse, error) {
   304  	if req == nil {
   305  		return nil, status.Error(codes.InvalidArgument, "empty request")
   306  	}
   307  
   308  	ctx := sdk.UnwrapSDKContext(c)
   309  
   310  	bz, found := q.GetUpgradedConsensusState(ctx, ctx.BlockHeight())
   311  	if !found {
   312  		return nil, status.Errorf(codes.NotFound, "%s, height %d", types.ErrConsensusStateNotFound.Error(), ctx.BlockHeight())
   313  	}
   314  
   315  	consensusState, err := types.UnmarshalConsensusState(q.cdc, bz)
   316  	if err != nil {
   317  		return nil, status.Error(
   318  			codes.Internal, err.Error(),
   319  		)
   320  	}
   321  
   322  	any, err := types.PackConsensusState(consensusState)
   323  	if err != nil {
   324  		return nil, status.Error(codes.Internal, err.Error())
   325  	}
   326  
   327  	return &types.QueryUpgradedConsensusStateResponse{
   328  		UpgradedConsensusState: any,
   329  	}, nil
   330  }