package keeper import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // QuerierChannels defines the sdk.Querier to query all the channels. func QuerierChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryAllChannelsParams if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } channels := k.GetAllChannels(ctx) start, end := client.Paginate(len(channels), params.Page, params.Limit, 100) if start < 0 || end < 0 { channels = []types.IdentifiedChannel{} } else { channels = channels[start:end] } res, err := codec.MarshalJSONIndent(k.cdc, channels) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } // QuerierConnectionChannels defines the sdk.Querier to query all the channels for a connection. func QuerierConnectionChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryConnectionChannelsParams if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } channels := k.GetAllChannels(ctx) connectionChannels := []types.IdentifiedChannel{} for _, channel := range channels { if channel.ConnectionHops[0] == params.Connection { connectionChannels = append(connectionChannels, channel) } } start, end := client.Paginate(len(connectionChannels), params.Page, params.Limit, 100) if start < 0 || end < 0 { connectionChannels = []types.IdentifiedChannel{} } else { connectionChannels = channels[start:end] } res, err := codec.MarshalJSONIndent(k.cdc, connectionChannels) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } // QuerierChannelClientState defines the sdk.Querier to query all the ClientState // associated with a given Channel. func QuerierChannelClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryChannelClientStateParams if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) if !found { return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, params.PortID, params.ChannelID) } connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { return nil, sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) if !found { return nil, sdkerrors.Wrapf(clienttypes.ErrClientNotFound, connection.ClientID) } res, err := codec.MarshalJSONIndent(k.cdc, clientState) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } // QuerierPacketCommitments defines the sdk.Querier to query all packet commitments on a // specified channel. func QuerierPacketCommitments(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { var params types.QueryPacketCommitmentsParams if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } packetCommitments := k.GetAllPacketCommitmentsAtChannel(ctx, params.PortID, params.ChannelID) sequences := make([]uint64, 0, len(packetCommitments)) for _, pc := range packetCommitments { sequences = append(sequences, pc.Sequence) } start, end := client.Paginate(len(sequences), params.Page, params.Limit, 100) if start < 0 || end < 0 { sequences = []uint64{} } else { sequences = sequences[start:end] } res, err := codec.MarshalJSONIndent(k.cdc, sequences) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil } // QuerierUnrelayedAcknowledgements defines the sdk.Querier to query all unrelayed // acknowledgements for a specified channel end. func QuerierUnrelayedAcknowledgements(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { return queryUnrelayedPackets(ctx, req, k, true) } // QuerierUnrelayedPacketSends defines the sdk.Querier to query all unrelayed packets for a // specified channel end. func QuerierUnrelayedPacketSends(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { return queryUnrelayedPackets(ctx, req, k, false) } // helper function to query for unrelayed packets as specified by the isForAcks boolean. If // set to true it will return unrelayed acknowledgements otherwise it will return unrelayed // packet sends. func queryUnrelayedPackets(ctx sdk.Context, req abci.RequestQuery, k Keeper, isForAcks bool) ([]byte, error) { var params types.QueryUnrelayedPacketsParams if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } var unrelayedPackets []uint64 for _, seq := range params.Sequences { if _, found := k.GetPacketAcknowledgement(ctx, params.PortID, params.ChannelID, seq); found == isForAcks { unrelayedPackets = append(unrelayedPackets, seq) } } start, end := client.Paginate(len(unrelayedPackets), params.Page, params.Limit, 100) if start < 0 || end < 0 { unrelayedPackets = []uint64{} } else { unrelayedPackets = unrelayedPackets[start:end] } res, err := codec.MarshalJSONIndent(k.cdc, unrelayedPackets) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return res, nil }