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: ¶ms, 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 }