From 2e5f08a365e1537b2d47d235d384e067322087e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Federico=20Kunze=20K=C3=BCllmer?=
 <31522760+fedekunze@users.noreply.github.com>
Date: Tue, 31 Jan 2023 14:02:31 +0100
Subject: [PATCH] chore: Add `HasConnection` and `HasChannel` methods. (#3082)

(cherry picked from commit b2fb1192245134607e0e7a294d09d2aa1145f017)

# Conflicts:
#	CHANGELOG.md
#	modules/core/02-client/migrations/v7/store.go
#	modules/light-clients/07-tendermint/types/store.go
---
 CHANGELOG.md                                  |  30 +++
 modules/apps/29-fee/keeper/keeper.go          |   2 +-
 modules/apps/transfer/keeper/keeper.go        |   2 +-
 modules/core/02-client/keeper/keeper.go       |   6 +-
 modules/core/02-client/migrations/v7/store.go | 205 ++++++++++++++++++
 modules/core/03-connection/keeper/keeper.go   |  13 +-
 modules/core/04-channel/keeper/keeper.go      |  20 +-
 modules/core/04-channel/keeper/keeper_test.go |   2 +-
 .../07-tendermint/types/store.go              |  11 +-
 9 files changed, 272 insertions(+), 19 deletions(-)
 create mode 100644 modules/core/02-client/migrations/v7/store.go

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76bf29d3f88..4179efbe60a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,6 +46,36 @@ Ref: https://keepachangelog.com/en/1.0.0/
 
 ### Improvements
 
+<<<<<<< HEAD
+=======
+* (core) [\#3082](https://github.com/cosmos/ibc-go/pull/3082) Add `HasConnection` and `HasChannel` methods.
+* (tests) [\#2926](https://github.com/cosmos/ibc-go/pull/2926) Lint tests
+* (apps/transfer) [\#2643](https://github.com/cosmos/ibc-go/pull/2643) Add amount, denom, and memo to transfer event emission.
+* (core) [\#2746](https://github.com/cosmos/ibc-go/pull/2746) Allow proof height to be zero for all core IBC `sdk.Msg` types that contain proofs.
+* (light-clients/06-solomachine) [\#2746](https://github.com/cosmos/ibc-go/pull/2746) Discard proofHeight for solo machines and use the solo machine sequence instead.
+* (modules/light-clients/07-tendermint) [\#1713](https://github.com/cosmos/ibc-go/pull/1713) Allow client upgrade proposals to update `TrustingPeriod`. See ADR-026 for context.
+* (modules/core/02-client) [\#1188](https://github.com/cosmos/ibc-go/pull/1188/files) Routing `MsgSubmitMisbehaviour` to `UpdateClient` keeper function. Deprecating `SubmitMisbehaviour` endpoint.
+* (modules/core/02-client) [\#1208](https://github.com/cosmos/ibc-go/pull/1208) Replace `CheckHeaderAndUpdateState` usage in 02-client with calls to `VerifyClientMessage`, `CheckForMisbehaviour`, `UpdateStateOnMisbehaviour` and `UpdateState`.
+* (modules/light-clients/09-localhost) [\#1187](https://github.com/cosmos/ibc-go/pull/1187/) Removing localhost light client implementation as it is not functional. An upgrade handler is provided in `modules/migrations/v5` to prune `09-localhost` clients and consensus states from the store.
+* [\#1186](https://github.com/cosmos/ibc-go/pull/1186/files) Removing `GetRoot` function from ConsensusState interface in `02-client`. `GetRoot` is unused by core IBC.
+* (modules/core/02-client) [\#1196](https://github.com/cosmos/ibc-go/pull/1196) Adding VerifyClientMessage to ClientState interface.
+* (modules/core/02-client) [\#1198](https://github.com/cosmos/ibc-go/pull/1198) Adding UpdateStateOnMisbehaviour to ClientState interface.
+* (modules/core/02-client) [\#1170](https://github.com/cosmos/ibc-go/pull/1170) Updating `ClientUpdateProposal` to set client state in lightclient implementations `CheckSubstituteAndUpdateState` methods.
+* (modules/core/02-client) [\#1197](https://github.com/cosmos/ibc-go/pull/1197) Adding `CheckForMisbehaviour` to `ClientState` interface.
+* (modules/core/02-client) [\#1195](https://github.com/cosmos/ibc-go/pull/1210) Removing `CheckHeaderAndUpdateState` from `ClientState` interface & associated light client implementations.
+* (modules/core/02-client) [\#1189](https://github.com/cosmos/ibc-go/pull/1212) Removing `CheckMisbehaviourAndUpdateState` from `ClientState` interface & associated light client implementations.
+* (modules/core/exported) [\#1206](https://github.com/cosmos/ibc-go/pull/1206) Adding new method `UpdateState` to `ClientState` interface.
+* (modules/core/02-client) [\#1741](https://github.com/cosmos/ibc-go/pull/1741) Emitting a new `upgrade_chain` event upon setting upgrade consensus state.
+* (client) [\#724](https://github.com/cosmos/ibc-go/pull/724) `IsRevisionFormat` and `IsClientIDFormat` have been updated to disallow newlines before the dash used to separate the chainID and revision number, and the client type and client sequence.
+* (02-client/cli) [\#897](https://github.com/cosmos/ibc-go/pull/897) Remove `GetClientID()` from `Misbehaviour` interface. Submit client misbehaviour cli command requires an explicit client id now.
+* (06-solomachine) [\#1972](https://github.com/cosmos/ibc-go/pull/1972) Solo machine implementation of `ZeroCustomFields` fn now panics as the fn is only used for upgrades which solo machine does not support.    
+* (light-clients/06-solomachine) Moving `verifyMisbehaviour` function from update.go to misbehaviour_handle.go.
+* [\#2434](https://github.com/cosmos/ibc-go/pull/2478) Removed all `TypeMsg` constants
+* (modules/core/exported) [#1689] (https://github.com/cosmos/ibc-go/pull/2539) Removing `GetVersions` from `ConnectionI` interface.
+* (core/02-connection) [#2419](https://github.com/cosmos/ibc-go/pull/2419) Add optional proof data to proto definitions of `MsgConnectionOpenTry` and `MsgConnectionOpenAck` for host state machines that are unable to introspect their own consensus state.
+* (modules/light-clients/07-tendermint) [#2007](https://github.com/cosmos/ibc-go/pull/3046) Moved non-verification misbehaviour checks to `CheckForMisbehaviour`
+
+>>>>>>> b2fb1192 (chore: Add `HasConnection` and `HasChannel` methods. (#3082))
 ### Features
 
 ### Bug Fixes
diff --git a/modules/apps/29-fee/keeper/keeper.go b/modules/apps/29-fee/keeper/keeper.go
index e506ef8118f..5d0ef4b3811 100644
--- a/modules/apps/29-fee/keeper/keeper.go
+++ b/modules/apps/29-fee/keeper/keeper.go
@@ -291,7 +291,7 @@ func (k Keeper) GetFeesInEscrow(ctx sdk.Context, packetID channeltypes.PacketId)
 	store := ctx.KVStore(k.storeKey)
 	key := types.KeyFeesInEscrow(packetID)
 	bz := store.Get(key)
-	if bz == nil {
+	if len(bz) == 0 {
 		return types.PacketFees{}, false
 	}
 
diff --git a/modules/apps/transfer/keeper/keeper.go b/modules/apps/transfer/keeper/keeper.go
index 9688d57aff2..4d57d95b28b 100644
--- a/modules/apps/transfer/keeper/keeper.go
+++ b/modules/apps/transfer/keeper/keeper.go
@@ -93,7 +93,7 @@ func (k Keeper) SetPort(ctx sdk.Context, portID string) {
 func (k Keeper) GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes) (types.DenomTrace, bool) {
 	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey)
 	bz := store.Get(denomTraceHash)
-	if bz == nil {
+	if len(bz) == 0 {
 		return types.DenomTrace{}, false
 	}
 
diff --git a/modules/core/02-client/keeper/keeper.go b/modules/core/02-client/keeper/keeper.go
index 634c70494fc..fba24dd5147 100644
--- a/modules/core/02-client/keeper/keeper.go
+++ b/modules/core/02-client/keeper/keeper.go
@@ -67,7 +67,7 @@ func (k Keeper) GenerateClientIdentifier(ctx sdk.Context, clientType string) str
 func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (exported.ClientState, bool) {
 	store := k.ClientStore(ctx, clientID)
 	bz := store.Get(host.ClientStateKey())
-	if bz == nil {
+	if len(bz) == 0 {
 		return nil, false
 	}
 
@@ -85,7 +85,7 @@ func (k Keeper) SetClientState(ctx sdk.Context, clientID string, clientState exp
 func (k Keeper) GetClientConsensusState(ctx sdk.Context, clientID string, height exported.Height) (exported.ConsensusState, bool) {
 	store := k.ClientStore(ctx, clientID)
 	bz := store.Get(host.ConsensusStateKey(height))
-	if bz == nil {
+	if len(bz) == 0 {
 		return nil, false
 	}
 
@@ -104,7 +104,7 @@ func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height
 func (k Keeper) GetNextClientSequence(ctx sdk.Context) uint64 {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get([]byte(types.KeyNextClientSequence))
-	if bz == nil {
+	if len(bz) == 0 {
 		panic("next client sequence is nil")
 	}
 
diff --git a/modules/core/02-client/migrations/v7/store.go b/modules/core/02-client/migrations/v7/store.go
new file mode 100644
index 00000000000..b70e541e671
--- /dev/null
+++ b/modules/core/02-client/migrations/v7/store.go
@@ -0,0 +1,205 @@
+package v7
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/cosmos/cosmos-sdk/codec"
+	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
+	storetypes "github.com/cosmos/cosmos-sdk/store/types"
+	sdk "github.com/cosmos/cosmos-sdk/types"
+	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+
+	clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
+	host "github.com/cosmos/ibc-go/v7/modules/core/24-host"
+	"github.com/cosmos/ibc-go/v7/modules/core/exported"
+	solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine"
+	ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint"
+)
+
+// Localhost is the client type for a localhost client. It is also used as the clientID
+// for the localhost client.
+const Localhost string = "09-localhost"
+
+// MigrateStore performs in-place store migrations from ibc-go v6 to ibc-go v7.
+// The migration includes:
+//
+// - Migrating solo machine client states from v2 to v3 protobuf definition
+// - Pruning all solo machine consensus states
+// - Removing the localhost client
+// - Asserting existing tendermint clients are properly registered on the chain codec
+func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error {
+	store := ctx.KVStore(storeKey)
+
+	if err := handleSolomachineMigration(ctx, store, cdc, clientKeeper); err != nil {
+		return err
+	}
+
+	if err := handleTendermintMigration(ctx, store, cdc, clientKeeper); err != nil {
+		return err
+	}
+
+	if err := handleLocalhostMigration(ctx, store, cdc, clientKeeper); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// handleSolomachineMigration iterates over the solo machine clients and migrates client state from
+// protobuf definition v2 to v3. All consensus states stored outside of the client state are pruned.
+func handleSolomachineMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error {
+	clients, err := collectClients(ctx, store, exported.Solomachine)
+	if err != nil {
+		return err
+	}
+
+	for _, clientID := range clients {
+		clientStore := clientKeeper.ClientStore(ctx, clientID)
+
+		bz := clientStore.Get(host.ClientStateKey())
+		if len(bz) == 0 {
+			return sdkerrors.Wrapf(clienttypes.ErrClientNotFound, "clientID %s", clientID)
+		}
+
+		var any codectypes.Any
+		if err := cdc.Unmarshal(bz, &any); err != nil {
+			return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state")
+		}
+
+		var clientState ClientState
+		if err := cdc.Unmarshal(any.Value, &clientState); err != nil {
+			return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state")
+		}
+
+		updatedClientState := migrateSolomachine(clientState)
+
+		// update solomachine in store
+		clientKeeper.SetClientState(ctx, clientID, &updatedClientState)
+
+		removeAllClientConsensusStates(clientStore)
+	}
+
+	return nil
+}
+
+// handlerTendermintMigration asserts that the tendermint client in state can be decoded properly.
+// This ensures the upgrading chain properly registered the tendermint client types on the chain codec.
+func handleTendermintMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error {
+	clients, err := collectClients(ctx, store, exported.Tendermint)
+	if err != nil {
+		return err
+	}
+
+	if len(clients) == 0 {
+		return nil // no-op if no tm clients exist
+	}
+
+	if len(clients) > 1 {
+		return sdkerrors.Wrap(sdkerrors.ErrLogic, "more than one Tendermint client collected")
+	}
+
+	clientID := clients[0]
+
+	// unregistered tendermint client types will panic when unmarshaling the client state
+	// in GetClientState
+	clientState, ok := clientKeeper.GetClientState(ctx, clientID)
+	if !ok {
+		return sdkerrors.Wrapf(clienttypes.ErrClientNotFound, "clientID %s", clientID)
+	}
+
+	_, ok = clientState.(*ibctm.ClientState)
+	if !ok {
+		return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "client state is not tendermint even though client id contains 07-tendermint")
+	}
+
+	return nil
+}
+
+// handleLocalhostMigration removes all client and consensus states associated with the localhost client type.
+func handleLocalhostMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error {
+	clients, err := collectClients(ctx, store, Localhost)
+	if err != nil {
+		return err
+	}
+
+	for _, clientID := range clients {
+		clientStore := clientKeeper.ClientStore(ctx, clientID)
+
+		// delete the client state
+		clientStore.Delete(host.ClientStateKey())
+
+		removeAllClientConsensusStates(clientStore)
+	}
+
+	return nil
+}
+
+// collectClients will iterate over the provided client type prefix in the client store
+// and return a list of clientIDs associated with the client type. This is necessary to
+// avoid state corruption as modifying state during iteration is unsafe. A special case
+// for tendermint clients is included as only one tendermint clientID is required for
+// v7 migrations.
+func collectClients(ctx sdk.Context, store sdk.KVStore, clientType string) (clients []string, err error) {
+	clientPrefix := []byte(fmt.Sprintf("%s/%s", host.KeyClientStorePrefix, clientType))
+	iterator := sdk.KVStorePrefixIterator(store, clientPrefix)
+
+	defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() })
+	for ; iterator.Valid(); iterator.Next() {
+		path := string(iterator.Key())
+		if !strings.Contains(path, host.KeyClientState) {
+			// skip non client state keys
+			continue
+		}
+
+		clientID := host.MustParseClientStatePath(path)
+		clients = append(clients, clientID)
+
+		// optimization: exit after a single tendermint client iteration
+		if strings.Contains(clientID, exported.Tendermint) {
+			return clients, nil
+		}
+	}
+
+	return clients, nil
+}
+
+// removeAllClientConsensusStates removes all client consensus states from the associated
+// client store.
+func removeAllClientConsensusStates(clientStore sdk.KVStore) {
+	iterator := sdk.KVStorePrefixIterator(clientStore, []byte(host.KeyConsensusStatePrefix))
+	var heights []exported.Height
+
+	defer iterator.Close()
+	for ; iterator.Valid(); iterator.Next() {
+		keySplit := strings.Split(string(iterator.Key()), "/")
+		// key is in the format "consensusStates/<height>"
+		if len(keySplit) != 2 || keySplit[0] != string(host.KeyConsensusStatePrefix) {
+			continue
+		}
+
+		// collect consensus states to be pruned
+		heights = append(heights, clienttypes.MustParseHeight(keySplit[1]))
+	}
+
+	// delete all consensus states
+	for _, height := range heights {
+		clientStore.Delete(host.ConsensusStateKey(height))
+	}
+}
+
+// migrateSolomachine migrates the solomachine from v2 to v3 solo machine protobuf definition.
+// Notably it drops the AllowUpdateAfterProposal field.
+func migrateSolomachine(clientState ClientState) solomachine.ClientState {
+	consensusState := &solomachine.ConsensusState{
+		PublicKey:   clientState.ConsensusState.PublicKey,
+		Diversifier: clientState.ConsensusState.Diversifier,
+		Timestamp:   clientState.ConsensusState.Timestamp,
+	}
+
+	return solomachine.ClientState{
+		Sequence:       clientState.Sequence,
+		IsFrozen:       clientState.IsFrozen,
+		ConsensusState: consensusState,
+	}
+}
diff --git a/modules/core/03-connection/keeper/keeper.go b/modules/core/03-connection/keeper/keeper.go
index 6620673ab24..ddff53f5224 100644
--- a/modules/core/03-connection/keeper/keeper.go
+++ b/modules/core/03-connection/keeper/keeper.go
@@ -66,7 +66,7 @@ func (k Keeper) GenerateConnectionIdentifier(ctx sdk.Context) string {
 func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.ConnectionKey(connectionID))
-	if bz == nil {
+	if len(bz) == 0 {
 		return types.ConnectionEnd{}, false
 	}
 
@@ -76,6 +76,13 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.Conne
 	return connection, true
 }
 
+// HasConnection returns a true if the connection with the given identifier
+// exists in the store.
+func (k Keeper) HasConnection(ctx sdk.Context, connectionID string) bool {
+	store := ctx.KVStore(k.storeKey)
+	return store.Has(host.ConnectionKey(connectionID))
+}
+
 // SetConnection sets a connection to the store
 func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) {
 	store := ctx.KVStore(k.storeKey)
@@ -105,7 +112,7 @@ func (k Keeper) GetTimestampAtHeight(ctx sdk.Context, connection types.Connectio
 func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.ClientConnectionsKey(clientID))
-	if bz == nil {
+	if len(bz) == 0 {
 		return nil, false
 	}
 
@@ -126,7 +133,7 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths
 func (k Keeper) GetNextConnectionSequence(ctx sdk.Context) uint64 {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get([]byte(types.KeyNextConnectionSequence))
-	if bz == nil {
+	if len(bz) == 0 {
 		panic("next connection sequence is nil")
 	}
 
diff --git a/modules/core/04-channel/keeper/keeper.go b/modules/core/04-channel/keeper/keeper.go
index db05a8457a5..a6d5c4bf967 100644
--- a/modules/core/04-channel/keeper/keeper.go
+++ b/modules/core/04-channel/keeper/keeper.go
@@ -66,11 +66,17 @@ func (k Keeper) GenerateChannelIdentifier(ctx sdk.Context) string {
 	return channelID
 }
 
+// HasChannel true if the channel with the given identifiers exists in state.
+func (k Keeper) HasChannel(ctx sdk.Context, portID, channelID string) bool {
+	store := ctx.KVStore(k.storeKey)
+	return store.Has(host.ChannelKey(portID, channelID))
+}
+
 // GetChannel returns a channel with a particular identifier binded to a specific port
 func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.ChannelKey(portID, channelID))
-	if bz == nil {
+	if len(bz) == 0 {
 		return types.Channel{}, false
 	}
 
@@ -100,7 +106,7 @@ func (k Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string
 func (k Keeper) GetNextChannelSequence(ctx sdk.Context) uint64 {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get([]byte(types.KeyNextChannelSequence))
-	if bz == nil {
+	if len(bz) == 0 {
 		panic("next channel sequence is nil")
 	}
 
@@ -118,7 +124,7 @@ func (k Keeper) SetNextChannelSequence(ctx sdk.Context, sequence uint64) {
 func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.NextSequenceSendKey(portID, channelID))
-	if bz == nil {
+	if len(bz) == 0 {
 		return 0, false
 	}
 
@@ -136,7 +142,7 @@ func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, s
 func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.NextSequenceRecvKey(portID, channelID))
-	if bz == nil {
+	if len(bz) == 0 {
 		return 0, false
 	}
 
@@ -154,7 +160,7 @@ func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, s
 func (k Keeper) GetNextSequenceAck(ctx sdk.Context, portID, channelID string) (uint64, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.NextSequenceAckKey(portID, channelID))
-	if bz == nil {
+	if len(bz) == 0 {
 		return 0, false
 	}
 
@@ -172,7 +178,7 @@ func (k Keeper) SetNextSequenceAck(ctx sdk.Context, portID, channelID string, se
 func (k Keeper) GetPacketReceipt(ctx sdk.Context, portID, channelID string, sequence uint64) (string, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.PacketReceiptKey(portID, channelID, sequence))
-	if bz == nil {
+	if len(bz) == 0 {
 		return "", false
 	}
 
@@ -219,7 +225,7 @@ func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID stri
 func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) {
 	store := ctx.KVStore(k.storeKey)
 	bz := store.Get(host.PacketAcknowledgementKey(portID, channelID, sequence))
-	if bz == nil {
+	if len(bz) == 0 {
 		return nil, false
 	}
 	return bz, true
diff --git a/modules/core/04-channel/keeper/keeper_test.go b/modules/core/04-channel/keeper/keeper_test.go
index ac97d72e7c3..2fcf10e4fb0 100644
--- a/modules/core/04-channel/keeper/keeper_test.go
+++ b/modules/core/04-channel/keeper/keeper_test.go
@@ -46,7 +46,7 @@ func (suite *KeeperTestSuite) TestSetChannel() {
 	suite.coordinator.SetupConnections(path)
 
 	// check for channel to be created on chainA
-	_, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
+	found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.HasChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
 	suite.False(found)
 
 	path.SetChannelOrdered()
diff --git a/modules/light-clients/07-tendermint/types/store.go b/modules/light-clients/07-tendermint/types/store.go
index 2a8eacee2e6..f7e58e44c3f 100644
--- a/modules/light-clients/07-tendermint/types/store.go
+++ b/modules/light-clients/07-tendermint/types/store.go
@@ -54,11 +54,16 @@ func SetConsensusState(clientStore sdk.KVStore, cdc codec.BinaryCodec, consensus
 // store. An error is returned if the consensus state does not exist.
 func GetConsensusState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height) (*ConsensusState, error) {
 	bz := store.Get(host.ConsensusStateKey(height))
+<<<<<<< HEAD:modules/light-clients/07-tendermint/types/store.go
 	if bz == nil {
 		return nil, sdkerrors.Wrapf(
 			clienttypes.ErrConsensusStateNotFound,
 			"consensus state does not exist for height %s", height,
 		)
+=======
+	if len(bz) == 0 {
+		return nil, false
+>>>>>>> b2fb1192 (chore: Add `HasConnection` and `HasChannel` methods. (#3082)):modules/light-clients/07-tendermint/store.go
 	}
 
 	consensusStateI, err := clienttypes.UnmarshalConsensusState(cdc, bz)
@@ -138,7 +143,7 @@ func SetProcessedTime(clientStore sdk.KVStore, height exported.Height, timeNs ui
 func GetProcessedTime(clientStore sdk.KVStore, height exported.Height) (uint64, bool) {
 	key := ProcessedTimeKey(height)
 	bz := clientStore.Get(key)
-	if bz == nil {
+	if len(bz) == 0 {
 		return 0, false
 	}
 	return sdk.BigEndianToUint64(bz), true
@@ -169,7 +174,7 @@ func SetProcessedHeight(clientStore sdk.KVStore, consHeight, processedHeight exp
 func GetProcessedHeight(clientStore sdk.KVStore, height exported.Height) (exported.Height, bool) {
 	key := ProcessedHeightKey(height)
 	bz := clientStore.Get(key)
-	if bz == nil {
+	if len(bz) == 0 {
 		return nil, false
 	}
 	processedHeight, err := clienttypes.ParseHeight(string(bz))
@@ -320,7 +325,7 @@ func PruneAllExpiredConsensusStates(
 // Helper function for GetNextConsensusState and GetPreviousConsensusState
 func getTmConsensusState(clientStore sdk.KVStore, cdc codec.BinaryCodec, key []byte) (*ConsensusState, bool) {
 	bz := clientStore.Get(key)
-	if bz == nil {
+	if len(bz) == 0 {
 		return nil, false
 	}