func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height) {
	res := chain.App.Query(abci.RequestQuery{
		Path:   "store/upgrade/key",
		Height: int64(height - 1),
		Data:   key,
		Prove:  true,
	})
	merkleProof := commitmenttypes.MerkleProof{
		Proof: res.ProofOps,
	}
	proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof)
	require.NoError(chain.t, err)
	version := clienttypes.ParseChainID(chain.ChainID)
	return proof, clienttypes.NewHeight(version, uint64(res.Height+1))
}
QueryUpgradeProof performs an abci query with the given key and returns the proto encoded merkle proof
for the query and the height at which the proof will succeed on a tendermint verifier.
package ibctesting
import (
	"fmt"
	"strconv"
	"testing"
	"time"
	"github.com/stretchr/testify/require"
	abci "github.com/tendermint/tendermint/abci/types"
	"github.com/tendermint/tendermint/crypto"
	"github.com/tendermint/tendermint/crypto/tmhash"
	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
	tmprotoversion "github.com/tendermint/tendermint/proto/tendermint/version"
	tmtypes "github.com/tendermint/tendermint/types"
	tmversion "github.com/tendermint/tendermint/version"
	"github.com/chainapsis/cosmos-sdk-interchain-account/simapp"
	"github.com/chainapsis/cosmos-sdk-interchain-account/x/ibc-account/testing/mock"
	ibcaccounttypes "github.com/chainapsis/cosmos-sdk-interchain-account/x/ibc-account/types"
	"github.com/cosmos/cosmos-sdk/client"
	"github.com/cosmos/cosmos-sdk/codec"
	"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
	clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
	connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types"
	channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
	commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types"
	host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
	"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
	"github.com/cosmos/cosmos-sdk/x/ibc/core/types"
	solomachinetypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/types"
	ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types"
	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
const (
	Tendermint  = ibctmtypes.Tendermint
	SoloMachine = solomachinetypes.SoloMachine
	TrustingPeriod  time.Duration = time.Hour * 24 * 7 * 2
	UnbondingPeriod time.Duration = time.Hour * 24 * 7 * 3
	MaxClockDrift   time.Duration = time.Second * 10
	DefaultChannelVersion = ibcaccounttypes.Version
	InvalidID             = "IDisInvalid"
	ConnectionIDPrefix = "conn"
	ChannelIDPrefix    = "chan"
	IBCAccountPort = ibcaccounttypes.ModuleName
	Title       = "title"
	Description = "description"
)
var (
	DefaultConsensusParams = simapp.DefaultConsensusParams
	DefaultOpenInitVersion *connectiontypes.Version
	DefaultTrustLevel ibctmtypes.Fraction = ibctmtypes.DefaultTrustLevel
	TestHash                              = tmhash.Sum([]byte("TESTING HASH"))
	TestCoin                              = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
	UpgradePath = fmt.Sprintf("%s/%s", "upgrade", "upgradedClient")
	ConnectionVersion = connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions())[0]
	ExpSimPassSend = true
	ExpPassSend    = true
)
type TestChain struct {
	t *testing.T
	App           *simapp.SimApp
	ChainID       string
	LastHeader    *ibctmtypes.Header  
	CurrentHeader tmproto.Header      
	QueryServer   types.QueryServer
	TxConfig      client.TxConfig
	Codec         codec.BinaryMarshaler
	Vals    *tmtypes.ValidatorSet
	Signers []tmtypes.PrivValidator
	senderPrivKey crypto.PrivKey
	SenderAccount authtypes.AccountI
	ClientIDs   []string           
	Connections []*TestConnection  
}
func NewTestChain(t *testing.T, chainID string) *TestChain {
	privVal := mock.NewPV()
	pubKey, err := privVal.GetPubKey()
	require.NoError(t, err)
	validator := tmtypes.NewValidator(pubKey.(cryptotypes.IntoTmPubKey).AsTmPubKey(), 1)
	valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
	signers := []tmtypes.PrivValidator{privVal}
	senderPrivKey := secp256k1.GenPrivKey()
	acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
	balance := banktypes.Balance{
		Address: acc.GetAddress().String(),
		Coins:   sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
	}
	app := simapp.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance)
	header := tmproto.Header{
		ChainID: chainID,
		Height:  1,
		Time:    globalStartTime,
	}
	txConfig := simapp.MakeTestEncodingConfig().TxConfig
	chain := &TestChain{
		t:             t,
		ChainID:       chainID,
		App:           app,
		CurrentHeader: header,
		QueryServer:   app.IBCKeeper,
		TxConfig:      txConfig,
		Codec:         app.AppCodec(),
		Vals:          valSet,
		Signers:       signers,
		senderPrivKey: senderPrivKey,
		SenderAccount: acc,
		ClientIDs:     make([]string, 0),
		Connections:   make([]*TestConnection, 0),
	}
	chain.NextBlock()
	return chain
}
func (chain *TestChain) GetContext() sdk.Context {
	ctx := chain.App.BaseApp.NewContext(false, chain.CurrentHeader)
	return ctx.WithConsensusParams(DefaultConsensusParams)
}
func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) {
	res := chain.App.Query(abci.RequestQuery{
		Path:   fmt.Sprintf("store/%s/key", host.StoreKey),
		Height: chain.App.LastBlockHeight() - 1,
		Data:   key,
		Prove:  true,
	})
	merkleProof := commitmenttypes.MerkleProof{
		Proof: res.ProofOps,
	}
	proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof)
	require.NoError(chain.t, err)
	version := clienttypes.ParseChainID(chain.ChainID)
	return proof, clienttypes.NewHeight(version, uint64(res.Height)+1)
}