github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/testing/chain.go (about)

     1  package ibctesting
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    10  
    11  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    12  	types2 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
    13  	ibcmsg "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/ibc-adapter"
    14  	ibc_tx "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ibc-tx"
    15  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1"
    16  
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    18  	//cryptotypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/types"
    19  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    20  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    22  	authtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
    23  
    24  	//banktypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank/types"
    25  	capabilitykeeper "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/keeper"
    26  	capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types"
    27  
    28  	stakingtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types"
    29  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    30  	tmproto "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    31  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/tmhash"
    32  	tmprototypes "github.com/fibonacci-chain/fbc/libs/tendermint/proto/types"
    33  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    34  	tmprotoversion "github.com/fibonacci-chain/fbc/libs/tendermint/version"
    35  	tmversion "github.com/fibonacci-chain/fbc/libs/tendermint/version"
    36  	"github.com/stretchr/testify/require"
    37  
    38  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    39  	apptypes "github.com/fibonacci-chain/fbc/app/types"
    40  	okcapptypes "github.com/fibonacci-chain/fbc/app/types"
    41  	clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types"
    42  	commitmenttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/23-commitment/types"
    43  	host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
    44  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported"
    45  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/types"
    46  	ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types"
    47  	"github.com/fibonacci-chain/fbc/libs/ibc-go/testing/mock"
    48  	"github.com/fibonacci-chain/fbc/libs/ibc-go/testing/simapp"
    49  )
    50  
    51  type TestChainI interface {
    52  	TxConfig() client.TxConfig
    53  	T() *testing.T
    54  	App() TestingApp
    55  	GetContext() sdk.Context
    56  	GetContextPointer() *sdk.Context
    57  	GetClientState(clientID string) exported.ClientState
    58  	QueryProof(key []byte) ([]byte, clienttypes.Height)
    59  	QueryConsensusStateProof(clientID string) ([]byte, clienttypes.Height)
    60  	GetConsensusState(clientID string, height exported.Height) (exported.ConsensusState, bool)
    61  	GetPrefix() commitmenttypes.MerklePrefix
    62  	LastHeader() *ibctmtypes.Header
    63  	QueryServer() types.QueryService
    64  	ChainID() string
    65  	Codec() *codec.CodecProxy
    66  	SenderAccount() sdk.Account
    67  	SenderAccountPV() crypto.PrivKey
    68  	SenderAccountPVBZ() []byte
    69  	CurrentTMClientHeader() *ibctmtypes.Header
    70  	ExpireClient(amount time.Duration)
    71  	CurrentHeader() tmproto.Header
    72  	CurrentHeaderTime(time.Time)
    73  	NextBlock()
    74  	BeginBlock()
    75  	UpdateNextBlock()
    76  
    77  	CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *ibctmtypes.Header
    78  	Vals() *tmtypes.ValidatorSet
    79  	Signers() []tmtypes.PrivValidator
    80  	GetSimApp() *simapp.SimApp
    81  	GetChannelCapability(portID, channelID string) *capabilitytypes.Capability
    82  	CreateChannelCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID, channelID string)
    83  	SendMsgs(msgs ...ibcmsg.Msg) (*sdk.Result, error)
    84  	QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height)
    85  	Coordinator() *Coordinator
    86  	QueryProofAtHeight(key []byte, height int64) ([]byte, clienttypes.Height)
    87  	ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty TestChainI, clientID string, trustedHeight clienttypes.Height) (*ibctmtypes.Header, error)
    88  	ConstructUpdateTMClientHeader(counterparty TestChainI, clientID string) (*ibctmtypes.Header, error)
    89  	sendMsgs(msgs ...ibcmsg.Msg) error
    90  	GetValsAtHeight(height int64) (*tmtypes.ValidatorSet, bool)
    91  	CreatePortCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID string)
    92  	GetPortCapability(portID string) *capabilitytypes.Capability
    93  
    94  	SenderAccounts() []SenderAccount
    95  }
    96  
    97  // TestChain is a testing struct that wraps a simapp with the last TM Header, the current ABCI
    98  // header and the validators of the TestChain. It also contains a field called ChainID. This
    99  // is the clientID that *other* chains use to refer to this TestChain. The SenderAccount
   100  // is used for delivering transactions through the application state.
   101  // NOTE: the actual application uses an empty chain-id for ease of testing.
   102  type TestChain struct {
   103  	t         *testing.T
   104  	privKeyBz []byte
   105  	context   sdk.Context
   106  
   107  	coordinator   *Coordinator
   108  	TApp          TestingApp
   109  	chainID       string
   110  	lastHeader    *ibctmtypes.Header // header for last block height committed
   111  	currentHeader tmproto.Header     // header for current block height
   112  	// QueryServer   types.QueryServer
   113  	queryServer types.QueryService
   114  	txConfig    client.TxConfig
   115  	codec       *codec.CodecProxy
   116  
   117  	vals    *tmtypes.ValidatorSet
   118  	signers []tmtypes.PrivValidator
   119  
   120  	senderPrivKey crypto.PrivKey
   121  	senderAccount authtypes.Account
   122  
   123  	senderAccounts []SenderAccount
   124  }
   125  
   126  var MaxAccounts = 10
   127  
   128  type SenderAccount struct {
   129  	SenderPrivKey crypto.PrivKey
   130  	SenderAccount auth.Account
   131  }
   132  
   133  // NewTestChain initializes a new TestChain instance with a single validator set using a
   134  // generated private key. It also creates a sender account to be used for delivering transactions.
   135  //
   136  // The first block height is committed to state in order to allow for client creations on
   137  // counterparty chains. The TestChain will return with a block height starting at 2.
   138  //
   139  // Time management is handled by the Coordinator in order to ensure synchrony between chains.
   140  // Each update of any chain increments the block header time for all chains by 5 seconds.
   141  func NewTestChain(t *testing.T, coord *Coordinator, chainID string) TestChainI {
   142  	// generate validator private/public key
   143  	privVal := mock.NewPV()
   144  	pubKey, err := privVal.GetPubKey()
   145  	require.NoError(t, err)
   146  
   147  	senderAccs := []SenderAccount{}
   148  
   149  	// generate genesis accounts
   150  	for i := 0; i < MaxAccounts; i++ {
   151  		senderPrivKey := secp256k1.GenPrivKey()
   152  		i, ok := sdk.NewIntFromString("92233720368547758080")
   153  		require.True(t, ok)
   154  		balance := sdk.NewCoins(apptypes.NewPhotonCoin(i))
   155  
   156  		acc := auth.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), balance, senderPrivKey.PubKey(), 0, 0)
   157  		//amount, ok := sdk.NewIntFromString("10000000000000000000")
   158  		//require.True(t, ok)
   159  
   160  		// add sender account
   161  		//balance := banktypes.Balance{
   162  		//	Address: acc.GetAddress().String(),
   163  		//	Coins:   sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)),
   164  		//}
   165  
   166  		//genAccs = append(genAccs, acc)
   167  		//genBals = append(genBals, balance)
   168  
   169  		senderAcc := SenderAccount{
   170  			SenderAccount: acc,
   171  			SenderPrivKey: senderPrivKey,
   172  		}
   173  
   174  		senderAccs = append(senderAccs, senderAcc)
   175  	}
   176  
   177  	// create validator set with single validator
   178  	validator := tmtypes.NewValidator(pubKey, 1)
   179  	valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
   180  	signers := []tmtypes.PrivValidator{privVal}
   181  
   182  	// generate genesis account
   183  	senderPrivKey := secp256k1.GenPrivKey()
   184  	//var pubkeyBytes secp256k1.PubKeySecp256k1
   185  	//copy(pubkeyBytes[:], senderPrivKey.PubKey().Bytes())
   186  
   187  	i, ok := sdk.NewIntFromString("92233720368547758080")
   188  	require.True(t, ok)
   189  	balance := sdk.NewCoins(apptypes.NewPhotonCoin(i))
   190  	var genesisAcc authtypes.GenesisAccount
   191  	genesisAcc = auth.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), balance, senderPrivKey.PubKey(), 0, 0)
   192  
   193  	//amount, ok := sdk.NewIntFromString("10000000000000000000")
   194  	//require.True(t, ok)
   195  
   196  	//fromBalance := suite.App().AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   197  	//var account *apptypes.EthAccount
   198  	//balance = sdk.NewCoins(fbexchaintypes.NewPhotonCoin(amount))
   199  	//addr := sdk.AccAddress(pubKey.Address())
   200  	//baseAcc := auth.NewBaseAccount(addr, balance, pubKey, 10, 50)
   201  	//account = &apptypes.EthAccount{
   202  	//	BaseAccount: baseAcc,
   203  	//	CodeHash:    []byte{1, 2},
   204  	//}
   205  	//fmt.Println(account)
   206  	//// balance := banktypes.Balance{
   207  	//// 	Address: acc.GetAddress().String(),
   208  	//// 	Coins:   sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)),
   209  	//// }
   210  
   211  	app := SetupWithGenesisValSet(t, chainID, valSet, []authtypes.GenesisAccount{genesisAcc}, balance)
   212  
   213  	// create current header and call begin block
   214  	header := tmproto.Header{
   215  		ChainID: chainID,
   216  		Height:  1,
   217  		Time:    coord.CurrentTime.UTC(),
   218  	}
   219  
   220  	txConfig := app.TxConfig()
   221  
   222  	// create an account to send transactions from
   223  	tchain := &TestChain{
   224  		t:              t,
   225  		privKeyBz:      senderPrivKey[:],
   226  		coordinator:    coord,
   227  		chainID:        chainID,
   228  		TApp:           app,
   229  		currentHeader:  header,
   230  		queryServer:    app.GetIBCKeeper(),
   231  		txConfig:       txConfig,
   232  		codec:          app.AppCodec(),
   233  		vals:           valSet,
   234  		signers:        signers,
   235  		senderPrivKey:  &senderPrivKey,
   236  		senderAccount:  genesisAcc,
   237  		senderAccounts: senderAccs,
   238  	}
   239  
   240  	//coord.UpdateNextBlock(tchain)
   241  	coord.CommitBlock(tchain)
   242  	//
   243  	//coord.UpdateNextBlock(tchain)
   244  	mockModuleAcc := tchain.GetSimApp().SupplyKeeper.GetModuleAccount(tchain.GetContext(), mock.ModuleName)
   245  	require.NotNil(t, mockModuleAcc)
   246  
   247  	return tchain
   248  }
   249  
   250  func NewTestEthChain(t *testing.T, coord *Coordinator, chainID string) *TestChain {
   251  	// generate validator private/public key
   252  	privVal := mock.NewPV()
   253  	pubKey, err := privVal.GetPubKey()
   254  	require.NoError(t, err)
   255  
   256  	// create validator set with single validator
   257  	validator := tmtypes.NewValidator(pubKey, 1)
   258  	valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
   259  	signers := []tmtypes.PrivValidator{privVal}
   260  
   261  	//Kb := keys.NewInMemory(hd.EthSecp256k1Options()...)
   262  	// generate genesis account
   263  	//info, err = Kb.CreateAccount(name, mnemonic, "", passWd, hdPath, hd.EthSecp256k1)
   264  	senderPrivKey, _ := ethsecp256k1.GenerateKey() //secp256k1.GenPrivKey()
   265  
   266  	ethPubkey := senderPrivKey.PubKey() //ethsecp256k1.PrivKey(senderPrivKey.Bytes()).PubKey()
   267  
   268  	i, ok := sdk.NewIntFromString("92233720368547758080")
   269  	require.True(t, ok)
   270  	balance := sdk.NewCoins(apptypes.NewPhotonCoin(i))
   271  
   272  	genesisAcc := &okcapptypes.EthAccount{
   273  		BaseAccount: auth.NewBaseAccount(ethPubkey.Address().Bytes(), balance, ethPubkey, 0, 0),
   274  		CodeHash:    []byte{},
   275  	}
   276  	//
   277  	//senderPrivKey.PubKey().Address().Bytes()
   278  
   279  	app := SetupWithGenesisValSet(t, chainID, valSet, []authtypes.GenesisAccount{genesisAcc}, balance)
   280  
   281  	// create current header and call begin block
   282  	header := tmproto.Header{
   283  		ChainID: chainID,
   284  		Height:  1,
   285  		Time:    coord.CurrentTime.UTC(),
   286  	}
   287  
   288  	txConfig := app.TxConfig()
   289  
   290  	// create an account to send transactions from
   291  	return &TestChain{
   292  		t:             t,
   293  		coordinator:   coord,
   294  		chainID:       chainID,
   295  		TApp:          app,
   296  		currentHeader: header,
   297  		queryServer:   app.GetIBCKeeper(),
   298  		txConfig:      txConfig,
   299  		codec:         app.AppCodec(),
   300  		vals:          valSet,
   301  		signers:       signers,
   302  		senderPrivKey: &senderPrivKey,
   303  		senderAccount: genesisAcc,
   304  		privKeyBz:     senderPrivKey[:],
   305  	}
   306  
   307  	//coord.UpdateNextBlock(tchain)
   308  	//coord.CommitBlock(tchain)
   309  	//
   310  	//coord.UpdateNextBlock(tchain)
   311  
   312  }
   313  func (chain *TestChain) SenderAccounts() []SenderAccount {
   314  	return chain.senderAccounts
   315  }
   316  
   317  // GetContext returns the current context for the application.
   318  func (chain *TestChain) GetContext() sdk.Context {
   319  	return chain.App().GetBaseApp().NewContext(false, chain.CurrentHeader())
   320  }
   321  
   322  func (chain *TestChain) TxConfig() client.TxConfig {
   323  	interfaceRegistry := types2.NewInterfaceRegistry()
   324  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   325  	chain.txConfig = ibc_tx.NewTxConfig(marshaler, ibc_tx.DefaultSignModes)
   326  	return chain.txConfig
   327  }
   328  
   329  // GetSimApp returns the SimApp to allow usage ofnon-interface fields.
   330  // CONTRACT: This function should not be called by third parties implementing
   331  // their own SimApp.
   332  func (chain *TestChain) GetSimApp() *simapp.SimApp {
   333  	app, ok := chain.TApp.(*simapp.SimApp)
   334  	require.True(chain.t, ok)
   335  
   336  	return app
   337  }
   338  
   339  // QueryProof performs an abci query with the given key and returns the proto encoded merkle proof
   340  // for the query and the height at which the proof will succeed on a tendermint verifier.
   341  func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) {
   342  	return chain.QueryProofAtHeight(key, chain.App().LastBlockHeight())
   343  }
   344  
   345  // QueryProof performs an abci query with the given key and returns the proto encoded merkle proof
   346  // for the query and the height at which the proof will succeed on a tendermint verifier.
   347  func (chain *TestChain) QueryProofAtHeight(key []byte, height int64) ([]byte, clienttypes.Height) {
   348  	res := chain.App().Query(abci.RequestQuery{
   349  		Path:   fmt.Sprintf("store/%s/key", host.StoreKey),
   350  		Height: height - 1,
   351  		Data:   key,
   352  		Prove:  true,
   353  	})
   354  
   355  	merkleProof, err := commitmenttypes.ConvertProofs(res.GetProof())
   356  	require.NoError(chain.t, err)
   357  
   358  	proof, err := chain.App().AppCodec().GetProtocMarshal().MarshalBinaryBare(&merkleProof)
   359  	require.NoError(chain.t, err)
   360  
   361  	revision := clienttypes.ParseChainID(chain.ChainID())
   362  
   363  	// proof height + 1 is returned as the proof created corresponds to the height the proof
   364  	// was created in the IAVL tree. Tendermint and subsequently the clients that rely on it
   365  	// have heights 1 above the IAVL tree. Thus we return proof height + 1
   366  	return proof, clienttypes.NewHeight(revision, uint64(res.Height)+1)
   367  }
   368  
   369  // QueryUpgradeProof performs an abci query with the given key and returns the proto encoded merkle proof
   370  // for the query and the height at which the proof will succeed on a tendermint verifier.
   371  func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height) {
   372  	res := chain.App().Query(abci.RequestQuery{
   373  		Path:   "store/upgrade/key",
   374  		Height: int64(height - 1),
   375  		Data:   key,
   376  		Prove:  true,
   377  	})
   378  
   379  	//	merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
   380  	merkleProof, err := commitmenttypes.ConvertProofs(res.GetProof())
   381  	require.NoError(chain.t, err)
   382  
   383  	// proof, err := chain.App().AppCodec().Marshal(&merkleProof)
   384  	// require.NoError(chain.t, err)
   385  	proof, err := chain.App().AppCodec().GetProtocMarshal().MarshalBinaryBare(&merkleProof)
   386  	require.NoError(chain.t, err)
   387  
   388  	revision := clienttypes.ParseChainID(chain.ChainID())
   389  
   390  	// proof height + 1 is returned as the proof created corresponds to the height the proof
   391  	// was created in the IAVL tree. Tendermint and subsequently the clients that rely on it
   392  	// have heights 1 above the IAVL tree. Thus we return proof height + 1
   393  	return proof, clienttypes.NewHeight(revision, uint64(res.Height+1))
   394  }
   395  
   396  // QueryConsensusStateProof performs an abci query for a consensus state
   397  // stored on the given clientID. The proof and consensusHeight are returned.
   398  func (chain *TestChain) QueryConsensusStateProof(clientID string) ([]byte, clienttypes.Height) {
   399  	clientState := chain.GetClientState(clientID)
   400  
   401  	consensusHeight := clientState.GetLatestHeight().(clienttypes.Height)
   402  	consensusKey := host.FullConsensusStateKey(clientID, consensusHeight)
   403  	proofConsensus, _ := chain.QueryProof(consensusKey)
   404  
   405  	return proofConsensus, consensusHeight
   406  }
   407  
   408  // NextBlock sets the last header to the current header and increments the current header to be
   409  // at the next block height. It does not update the time as that is handled by the Coordinator.
   410  //
   411  // CONTRACT: this function must only be called after app.Commit() occurs
   412  func (chain *TestChain) NextBlock() {
   413  	// set the last header to the current header
   414  	// use nil trusted fields
   415  	chain.SetLastHeader(chain.CurrentTMClientHeader())
   416  
   417  	// increment the current header
   418  	chain.SetCurrentHeader(tmproto.Header{
   419  		ChainID: chain.ChainID(),
   420  		Height:  chain.App().LastBlockHeight() + 1,
   421  		AppHash: chain.App().LastCommitID().Hash,
   422  		// NOTE: the time is increased by the coordinator to maintain time synchrony amongst
   423  		// chains.
   424  		Time:               chain.CurrentHeader().Time,
   425  		ValidatorsHash:     chain.Vals().Hash(chain.App().LastBlockHeight() + 1),
   426  		NextValidatorsHash: chain.Vals().Hash(chain.App().LastBlockHeight() + 1),
   427  	})
   428  
   429  	chain.App().BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader()})
   430  }
   431  
   432  func (chain *TestChain) BeginBlock() {
   433  	chain.App().BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader()})
   434  }
   435  
   436  func (chain *TestChain) UpdateNextBlock() {
   437  	chain.SetLastHeader(chain.CurrentTMClientHeader())
   438  
   439  	// increment the current header
   440  	chain.SetCurrentHeader(tmproto.Header{
   441  		ChainID: chain.ChainID(),
   442  		Height:  chain.App().LastBlockHeight() + 1,
   443  		AppHash: chain.App().LastCommitID().Hash,
   444  		// NOTE: the time is increased by the coordinator to maintain time synchrony amongst
   445  		// chains.
   446  		Time:               chain.CurrentHeader().Time,
   447  		ValidatorsHash:     chain.Vals().Hash(chain.App().LastBlockHeight() + 1),
   448  		NextValidatorsHash: chain.Vals().Hash(chain.App().LastBlockHeight() + 1),
   449  	})
   450  	chain.App().BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader()})
   451  }
   452  
   453  // sendMsgs delivers a transaction through the application without returning the result.
   454  func (chain *TestChain) sendMsgs(msgs ...ibcmsg.Msg) error {
   455  	_, err := chain.SendMsgs(msgs...)
   456  	return err
   457  }
   458  
   459  // SendMsgs delivers a transaction through the application. It updates the senders sequence
   460  // number and updates the TestChain's headers. It returns the result and error if one
   461  // occurred.
   462  func (chain *TestChain) SendMsgs(msgs ...ibcmsg.Msg) (*sdk.Result, error) {
   463  
   464  	// ensure the chain has the latest time
   465  	chain.Coordinator().UpdateTimeForChain(chain)
   466  	_, r, err := simapp.SignAndDeliver(
   467  		chain.t,
   468  		chain.TxConfig(),
   469  		chain.App().GetBaseApp(),
   470  		//chain.GetContextPointer().BlockHeader(),
   471  		chain.CurrentHeader(),
   472  		msgs,
   473  		chain.ChainID(),
   474  		[]uint64{chain.SenderAccount().GetAccountNumber()},
   475  		[]uint64{chain.SenderAccount().GetSequence()},
   476  		true, true, chain.senderPrivKey,
   477  	)
   478  	if err != nil {
   479  		return nil, err
   480  	}
   481  
   482  	// SignAndDeliver calls app.Commit()
   483  	chain.NextBlock()
   484  
   485  	// increment sequence for successful transaction execution
   486  	chain.SenderAccount().SetSequence(chain.SenderAccount().GetSequence() + 1)
   487  
   488  	chain.Coordinator().IncrementTime()
   489  
   490  	return r, nil
   491  }
   492  
   493  // GetClientState retrieves the client state for the provided clientID. The client is
   494  // expected to exist otherwise testing will fail.
   495  func (chain *TestChain) GetClientState(clientID string) exported.ClientState {
   496  	clientState, found := chain.App().GetIBCKeeper().ClientKeeper.GetClientState(chain.GetContext(), clientID)
   497  	require.True(chain.t, found)
   498  
   499  	return clientState
   500  }
   501  
   502  // GetConsensusState retrieves the consensus state for the provided clientID and height.
   503  // It will return a success boolean depending on if consensus state exists or not.
   504  func (chain *TestChain) GetConsensusState(clientID string, height exported.Height) (exported.ConsensusState, bool) {
   505  	return chain.App().GetIBCKeeper().ClientKeeper.GetClientConsensusState(chain.GetContext(), clientID, height)
   506  }
   507  
   508  // GetValsAtHeight will return the validator set of the chain at a given height. It will return
   509  // a success boolean depending on if the validator set exists or not at that height.
   510  func (chain *TestChain) GetValsAtHeight(height int64) (*tmtypes.ValidatorSet, bool) {
   511  	histInfo, ok := chain.App().GetStakingKeeper().GetHistoricalInfo(chain.GetContext(), height)
   512  	if !ok {
   513  		return nil, false
   514  	}
   515  
   516  	valSet := stakingtypes.Validators(histInfo.ValSet)
   517  
   518  	validators := make([]*tmtypes.Validator, len(valSet))
   519  	for i, val := range valSet {
   520  		validators[i] = tmtypes.NewValidator(val.GetConsPubKey(), 1)
   521  	}
   522  
   523  	return tmtypes.NewValidatorSet(validators), true
   524  }
   525  
   526  // GetAcknowledgement retrieves an acknowledgement for the provided packet. If the
   527  // acknowledgement does not exist then testing will fail.
   528  func (chain *TestChain) GetAcknowledgement(packet exported.PacketI) []byte {
   529  	ack, found := chain.App().GetIBCKeeper().ChannelKeeper.GetPacketAcknowledgement(chain.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
   530  	require.True(chain.t, found)
   531  
   532  	return ack
   533  }
   534  
   535  // GetPrefix returns the prefix for used by a chain in connection creation
   536  func (chain *TestChain) GetPrefix() commitmenttypes.MerklePrefix {
   537  	return commitmenttypes.NewMerklePrefix(chain.App().GetIBCKeeper().ConnectionKeeper.GetCommitmentPrefix().Bytes())
   538  }
   539  
   540  // ConstructUpdateTMClientHeader will construct a valid 07-tendermint Header to update the
   541  // light client on the source chain.
   542  func (chain *TestChain) ConstructUpdateTMClientHeader(counterparty TestChainI, clientID string) (*ibctmtypes.Header, error) {
   543  	return chain.ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty, clientID, clienttypes.ZeroHeight())
   544  }
   545  
   546  // ConstructUpdateTMClientHeader will construct a valid 07-tendermint Header to update the
   547  // light client on the source chain.
   548  func (chain *TestChain) ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty TestChainI, clientID string, trustedHeight clienttypes.Height) (*ibctmtypes.Header, error) {
   549  	header := counterparty.LastHeader()
   550  	// Relayer must query for LatestHeight on client to get TrustedHeight if the trusted height is not set
   551  	if trustedHeight.IsZero() {
   552  		trustedHeight = chain.GetClientState(clientID).GetLatestHeight().(clienttypes.Height)
   553  	}
   554  	var (
   555  		tmTrustedVals *tmtypes.ValidatorSet
   556  		ok            bool
   557  	)
   558  	// Once we get TrustedHeight from client, we must query the validators from the counterparty chain
   559  	// If the LatestHeight == LastHeader.Height, then TrustedValidators are current validators
   560  	// If LatestHeight < LastHeader.Height, we can query the historical validator set from HistoricalInfo
   561  	if trustedHeight == counterparty.LastHeader().GetHeight() {
   562  		tmTrustedVals = counterparty.Vals()
   563  	} else {
   564  		// NOTE: We need to get validators from counterparty at height: trustedHeight+1
   565  		// since the last trusted validators for a header at height h
   566  		// is the NextValidators at h+1 committed to in header h by
   567  		// NextValidatorsHash
   568  		tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight.RevisionHeight + 1))
   569  		if !ok {
   570  			return nil, sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight)
   571  		}
   572  	}
   573  	// inject trusted fields into last header
   574  	// for now assume revision number is 0
   575  	header.TrustedHeight = trustedHeight
   576  
   577  	trustedVals, err := tmTrustedVals.ToProto()
   578  	if err != nil {
   579  		return nil, err
   580  	}
   581  	header.TrustedValidators = trustedVals
   582  
   583  	return header, nil
   584  
   585  }
   586  
   587  // ExpireClient fast forwards the chain's block time by the provided amount of time which will
   588  // expire any clients with a trusting period less than or equal to this amount of time.
   589  func (chain *TestChain) ExpireClient(amount time.Duration) {
   590  	chain.Coordinator().IncrementTimeBy(amount)
   591  }
   592  
   593  // CurrentTMClientHeader creates a TM header using the current header parameters
   594  // on the chain. The trusted fields in the header are set to nil.
   595  func (chain *TestChain) CurrentTMClientHeader() *ibctmtypes.Header {
   596  	return chain.CreateTMClientHeader(chain.chainID, chain.CurrentHeader().Height, clienttypes.Height{}, chain.CurrentHeader().Time, chain.Vals(), nil, chain.Signers())
   597  }
   598  
   599  // CreateTMClientHeader creates a TM header to update the TM client. Args are passed in to allow
   600  // caller flexibility to use params that differ from the chain.
   601  func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *ibctmtypes.Header {
   602  	var (
   603  		valSet      *tmprototypes.ValidatorSet
   604  		trustedVals *tmprototypes.ValidatorSet
   605  	)
   606  	require.NotNil(chain.t, tmValSet)
   607  
   608  	vsetHash := tmValSet.Hash(blockHeight)
   609  
   610  	tmHeader := tmtypes.Header{
   611  		Version:            tmprotoversion.Consensus{Block: tmversion.BlockProtocol, App: 2},
   612  		ChainID:            chainID,
   613  		Height:             blockHeight,
   614  		Time:               timestamp,
   615  		LastBlockID:        MakeBlockID(make([]byte, tmhash.Size), 10_000, make([]byte, tmhash.Size)),
   616  		LastCommitHash:     chain.App().LastCommitID().Hash,
   617  		DataHash:           tmhash.Sum([]byte("data_hash")),
   618  		ValidatorsHash:     vsetHash,
   619  		NextValidatorsHash: vsetHash,
   620  		ConsensusHash:      tmhash.Sum([]byte("consensus_hash")),
   621  		AppHash:            chain.CurrentHeader().AppHash,
   622  		LastResultsHash:    tmhash.Sum([]byte("last_results_hash")),
   623  		EvidenceHash:       tmhash.Sum([]byte("evidence_hash")),
   624  		ProposerAddress:    tmValSet.Proposer.Address, //nolint:staticcheck
   625  	}
   626  	hhash := tmHeader.Hash()
   627  	blockID := MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set")))
   628  	voteSet := tmtypes.NewVoteSet(chainID, blockHeight, 1, tmtypes.PrecommitType, tmValSet)
   629  
   630  	commit, err := tmtypes.MakeCommit(blockID, blockHeight, 1, voteSet, signers, timestamp)
   631  	require.NoError(chain.t, err)
   632  
   633  	signedHeader := &tmtypes.SignedHeader{
   634  		Header: &tmHeader,
   635  		Commit: commit,
   636  	}
   637  
   638  	if tmValSet != nil {
   639  		valSet, err = tmValSet.ToProto()
   640  		if err != nil {
   641  			panic(err)
   642  		}
   643  	}
   644  
   645  	if tmTrustedVals != nil {
   646  		trustedVals, err = tmTrustedVals.ToProto()
   647  		if err != nil {
   648  			panic(err)
   649  		}
   650  	}
   651  
   652  	// The trusted fields may be nil. They may be filled before relaying messages to a client.
   653  	// The relayer is responsible for querying client and injecting appropriate trusted fields.
   654  	return &ibctmtypes.Header{
   655  		SignedHeader:      signedHeader.ToProto(),
   656  		ValidatorSet:      valSet,
   657  		TrustedHeight:     trustedHeight,
   658  		TrustedValidators: trustedVals,
   659  	}
   660  }
   661  
   662  // MakeBlockID copied unimported test functions from tmtypes to use them here
   663  func MakeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) tmtypes.BlockID {
   664  	return tmtypes.BlockID{
   665  		Hash: hash,
   666  		PartsHeader: tmtypes.PartSetHeader{
   667  			Total: int(partSetSize),
   668  			Hash:  partSetHash,
   669  		},
   670  	}
   671  }
   672  
   673  // CreateSortedSignerArray takes two PrivValidators, and the corresponding Validator structs
   674  // (including voting power). It returns a signer array of PrivValidators that matches the
   675  // sorting of ValidatorSet.
   676  // The sorting is first by .VotingPower (descending), with secondary index of .Address (ascending).
   677  func CreateSortedSignerArray(altPrivVal, suitePrivVal tmtypes.PrivValidator,
   678  	altVal, suiteVal *tmtypes.Validator) []tmtypes.PrivValidator {
   679  
   680  	switch {
   681  	case altVal.VotingPower > suiteVal.VotingPower:
   682  		return []tmtypes.PrivValidator{altPrivVal, suitePrivVal}
   683  	case altVal.VotingPower < suiteVal.VotingPower:
   684  		return []tmtypes.PrivValidator{suitePrivVal, altPrivVal}
   685  	default:
   686  		if bytes.Compare(altVal.Address, suiteVal.Address) == -1 {
   687  			return []tmtypes.PrivValidator{altPrivVal, suitePrivVal}
   688  		}
   689  		return []tmtypes.PrivValidator{suitePrivVal, altPrivVal}
   690  	}
   691  }
   692  
   693  // CreatePortCapability binds and claims a capability for the given portID if it does not
   694  // already exist. This function will fail testing on any resulting error.
   695  // NOTE: only creation of a capbility for a transfer or mock port is supported
   696  // Other applications must bind to the port in InitGenesis or modify this code.
   697  func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID string) {
   698  	// check if the portId is already binded, if not bind it
   699  	_, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.PortPath(portID))
   700  	if !ok {
   701  		// create capability using the IBC capability keeper
   702  		cap, err := chain.App().GetScopedIBCKeeper().NewCapability(chain.GetContext(), host.PortPath(portID))
   703  		require.NoError(chain.t, err)
   704  
   705  		// claim capability using the scopedKeeper
   706  		err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, host.PortPath(portID))
   707  		require.NoError(chain.t, err)
   708  	}
   709  
   710  	chain.App().Commit(abci.RequestCommit{})
   711  
   712  	chain.NextBlock()
   713  }
   714  
   715  // GetPortCapability returns the port capability for the given portID. The capability must
   716  // exist, otherwise testing will fail.
   717  func (chain *TestChain) GetPortCapability(portID string) *capabilitytypes.Capability {
   718  	cap, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.PortPath(portID))
   719  	require.True(chain.t, ok)
   720  
   721  	return cap
   722  }
   723  
   724  // CreateChannelCapability binds and claims a capability for the given portID and channelID
   725  // if it does not already exist. This function will fail testing on any resulting error. The
   726  // scoped keeper passed in will claim the new capability.
   727  func (chain *TestChain) CreateChannelCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID, channelID string) {
   728  	capName := host.ChannelCapabilityPath(portID, channelID)
   729  	// check if the portId is already binded, if not bind it
   730  	_, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), capName)
   731  	if !ok {
   732  		cap, err := chain.App().GetScopedIBCKeeper().NewCapability(chain.GetContext(), capName)
   733  		require.NoError(chain.t, err)
   734  		err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, capName)
   735  		require.NoError(chain.t, err)
   736  	}
   737  
   738  	chain.App().Commit(abci.RequestCommit{})
   739  
   740  	chain.NextBlock()
   741  }
   742  
   743  // GetChannelCapability returns the channel capability for the given portID and channelID.
   744  // The capability must exist, otherwise testing will fail.
   745  func (chain *TestChain) GetChannelCapability(portID, channelID string) *capabilitytypes.Capability {
   746  	cap, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.ChannelCapabilityPath(portID, channelID))
   747  	require.True(chain.t, ok)
   748  
   749  	return cap
   750  }
   751  
   752  // implement
   753  func (chain *TestChain) T() *testing.T {
   754  	return chain.t
   755  }
   756  func (chain *TestChain) App() TestingApp {
   757  	return chain.GetSimApp()
   758  }
   759  
   760  func (chain *TestChain) GetContextPointer() *sdk.Context {
   761  	return &chain.context
   762  }
   763  
   764  // func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height)  {}
   765  // func (chain *TestChain) GetConsensusState(clientID string, height exported.Height) (exported.ConsensusState, bool) {
   766  // }
   767  // func (chain *TestChain) GetPrefix() commitmenttypes.MerklePrefix   {}
   768  func (chain *TestChain) LastHeader() *ibctmtypes.Header {
   769  	return chain.lastHeader
   770  }
   771  func (chain *TestChain) SetLastHeader(lh *ibctmtypes.Header) {
   772  	chain.lastHeader = lh
   773  }
   774  
   775  func (chain *TestChain) QueryServer() types.QueryService {
   776  	return chain.queryServer
   777  }
   778  func (chain *TestChain) ChainID() string {
   779  	return chain.chainID
   780  }
   781  
   782  func (chain *TestChain) Codec() *codec.CodecProxy {
   783  	return chain.codec
   784  }
   785  func (chain *TestChain) SenderAccount() sdk.Account {
   786  	return chain.senderAccount
   787  }
   788  func (chain *TestChain) SenderAccountPV() crypto.PrivKey {
   789  
   790  	return chain.senderPrivKey
   791  }
   792  
   793  func (chain *TestChain) SenderAccountPVBZ() []byte {
   794  	return chain.privKeyBz
   795  }
   796  
   797  // func (chain *TestChain) CurrentTMClientHeader() *ibctmtypes.Header {}
   798  func (chain *TestChain) CurrentHeader() tmproto.Header {
   799  	return chain.currentHeader
   800  }
   801  func (chain *TestChain) SetCurrentHeader(h tmproto.Header) {
   802  	chain.currentHeader = h
   803  }
   804  
   805  // func (chain *TestChain) NextBlock()                                {}
   806  //
   807  // func CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *ibctmtypes.Header {
   808  // }
   809  func (chain *TestChain) Vals() *tmtypes.ValidatorSet {
   810  	return chain.vals
   811  }
   812  
   813  func (chain *TestChain) Signers() []tmtypes.PrivValidator {
   814  	return chain.signers
   815  }
   816  
   817  // func GetSimApp() *simapp.SimApp                                                                    {}
   818  // func GetChannelCapability(portID, channelID string) *capabilitytypes.Capability                    {}
   819  // func CreateChannelCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID, channelID string) {}
   820  // func SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error)                                                {}
   821  // func QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height)                     {}
   822  func (chain *TestChain) Coordinator() *Coordinator {
   823  	return chain.coordinator
   824  }
   825  
   826  func (chain *TestChain) CurrentHeaderTime(t time.Time) {
   827  	chain.currentHeader.Time = t
   828  }
   829  
   830  //func QueryProofAtHeight(key []byte, height uint64) ([]byte, clienttypes.Height) {}