diff --git a/tests/e2e/ibc_fees_test.go b/tests/e2e/ibc_fees_test.go index 9df428dcf..851af33bf 100644 --- a/tests/e2e/ibc_fees_test.go +++ b/tests/e2e/ibc_fees_test.go @@ -50,17 +50,17 @@ func TestIBCFeesTransfer(t *testing.T) { // when an ics-29 fee is attached to an ibc package // then the relayer's payee is receiving the fee(s) on success marshaler := app.MakeEncodingConfig(t).Codec - coord := wasmibctesting.NewCoordinator(t, 2) - chainA := coord.GetChain(wasmibctesting.GetChainID(1)) - chainB := coord.GetChain(wasmibctesting.GetChainID(2)) + coord := wasmibctesting.NewCoordinator2(t, 2) + chainA := wasmibctesting.NewWasmTestChain(coord.GetChain(wasmibctesting.GetChainID(1))) + chainB := wasmibctesting.NewWasmTestChain(coord.GetChain(wasmibctesting.GetChainID(2))) - actorChainA := sdk.AccAddress(chainA.SenderPrivKey.PubKey().Address()) - actorChainB := sdk.AccAddress(chainB.SenderPrivKey.PubKey().Address()) + actorChainA := sdk.AccAddress(chainA.IbcChain.SenderPrivKey.PubKey().Address()) + actorChainB := sdk.AccAddress(chainB.IbcChain.SenderPrivKey.PubKey().Address()) receiver := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len)) payee := sdk.AccAddress(bytes.Repeat([]byte{2}, address.Len)) oneToken := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(1))) - path := wasmibctesting.NewPath(chainA, chainB) + path := ibctesting.NewPath(chainA.IbcChain, chainB.IbcChain) path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ PortID: ibctransfertypes.PortID, Version: string(marshaler.MustMarshalJSON(&ibcfee.Metadata{FeeVersion: ibcfee.Version, AppVersion: ibctransfertypes.V2})), @@ -73,7 +73,7 @@ func TestIBCFeesTransfer(t *testing.T) { } // with an ics-20 transfer channel setup between both chains coord.Setup(path) - appA := chainA.App.(*app.WasmApp) + appA := chainA.GetWasmApp() require.True(t, appA.IBCFeeKeeper.IsFeeEnabled(chainA.GetContext(), ibctransfertypes.PortID, path.EndpointA.ChannelID)) // and with a payee registered on both chains _, err := chainA.SendMsgs(ibcfee.NewMsgRegisterPayee(ibctransfertypes.PortID, path.EndpointA.ChannelID, actorChainA.String(), payee.String())) @@ -86,14 +86,14 @@ func TestIBCFeesTransfer(t *testing.T) { ibcPayloadMsg := ibctransfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, []sdk.Coin{transferCoin}, actorChainA.String(), receiver.String(), clienttypes.Height{}, uint64(time.Now().Add(time.Minute).UnixNano()), "testing", &ibctransfertypes.Forwarding{Unwind: false, Hops: []ibctransfertypes.Hop{}}) ibcPackageFee := ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) feeMsg := ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibctransfertypes.PortID, path.EndpointA.ChannelID, actorChainA.String(), nil) - _, err = chainA.SendMsgs(feeMsg, ibcPayloadMsg) + result, err := chainA.SendMsgs(feeMsg, ibcPayloadMsg) require.NoError(t, err) pendingIncentivisedPackages := appA.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainA.GetContext(), ibctransfertypes.PortID, path.EndpointA.ChannelID) assert.Len(t, pendingIncentivisedPackages, 1) require.NoError(t, err) // message committed - require.NoError(t, coord.RelayAndAckPendingPackets(path)) + wasmibctesting.RelayAndAckPacket(t, path, result) // then expBalance := GetTransferCoin(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, transferCoin.Denom, transferCoin.Amount) @@ -112,14 +112,14 @@ func TestIBCFeesTransfer(t *testing.T) { ibcPayloadMsg = ibctransfertypes.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, []sdk.Coin{transferCoin}, actorChainB.String(), receiver.String(), clienttypes.Height{}, uint64(time.Now().Add(time.Minute).UnixNano()), "more testing", &ibctransfertypes.Forwarding{Unwind: false, Hops: []ibctransfertypes.Hop{}}) ibcPackageFee = ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) feeMsg = ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), nil) - _, err = chainB.SendMsgs(feeMsg, ibcPayloadMsg) + result, err = chainB.SendMsgs(feeMsg, ibcPayloadMsg) require.NoError(t, err) - appB := chainB.App.(*app.WasmApp) + appB := chainB.GetWasmApp() pendingIncentivisedPackages = appB.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainB.GetContext(), ibctransfertypes.PortID, path.EndpointB.ChannelID) assert.Len(t, pendingIncentivisedPackages, 1) // when packages relayed - require.NoError(t, coord.RelayAndAckPendingPackets(path)) + wasmibctesting.RelayAndAckPacket(t, path, result) // then expBalance = GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, transferCoin.Denom, transferCoin.Amount) @@ -136,11 +136,11 @@ func TestIBCFeesWasm(t *testing.T) { // when an ics-29 fee is attached to an ibc package // then the relayer's payee is receiving the fee(s) on success marshaler := app.MakeEncodingConfig(t).Codec - coord := wasmibctesting.NewCoordinator(t, 2) - chainA := coord.GetChain(ibctesting.GetChainID(1)) - chainB := coord.GetChain(ibctesting.GetChainID(2)) - actorChainA := sdk.AccAddress(chainA.SenderPrivKey.PubKey().Address()) - actorChainB := sdk.AccAddress(chainB.SenderPrivKey.PubKey().Address()) + coord := wasmibctesting.NewCoordinator2(t, 2) + chainA := wasmibctesting.NewWasmTestChain(coord.GetChain(ibctesting.GetChainID(1))) + chainB := wasmibctesting.NewWasmTestChain(coord.GetChain(ibctesting.GetChainID(2))) + actorChainA := sdk.AccAddress(chainA.IbcChain.SenderPrivKey.PubKey().Address()) + actorChainB := sdk.AccAddress(chainB.IbcChain.SenderPrivKey.PubKey().Address()) // setup chain A codeID := chainA.StoreCodeFile("./testdata/cw20_base.wasm.gz").CodeID @@ -156,7 +156,7 @@ func TestIBCFeesWasm(t *testing.T) { payee := sdk.AccAddress(bytes.Repeat([]byte{2}, address.Len)) oneToken := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(1))) - path := wasmibctesting.NewPath(chainA, chainB) + path := ibctesting.NewPath(chainA.IbcChain, chainB.IbcChain) path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ PortID: ibcContractPortID, Version: string(marshaler.MustMarshalJSON(&ibcfee.Metadata{FeeVersion: ibcfee.Version, AppVersion: ibctransfertypes.V1})), @@ -169,8 +169,8 @@ func TestIBCFeesWasm(t *testing.T) { } // with an ics-29 fee enabled channel setup between both chains coord.Setup(path) - appA := chainA.App.(*app.WasmApp) - appB := chainB.App.(*app.WasmApp) + appA := chainA.GetWasmApp() + appB := chainB.GetWasmApp() require.True(t, appA.IBCFeeKeeper.IsFeeEnabled(chainA.GetContext(), ibcContractPortID, path.EndpointA.ChannelID)) require.True(t, appB.IBCFeeKeeper.IsFeeEnabled(chainB.GetContext(), ibctransfertypes.PortID, path.EndpointB.ChannelID)) // and with a payee registered for A -> B @@ -189,13 +189,13 @@ func TestIBCFeesWasm(t *testing.T) { } ibcPackageFee := ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) feeMsg := ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibcContractPortID, path.EndpointA.ChannelID, actorChainA.String(), nil) - _, err = chainA.SendMsgs(feeMsg, &execMsg) + result, err := chainA.SendMsgs(feeMsg, &execMsg) require.NoError(t, err) pendingIncentivisedPackages := appA.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainA.GetContext(), ibcContractPortID, path.EndpointA.ChannelID) assert.Len(t, pendingIncentivisedPackages, 1) // and packages relayed - require.NoError(t, coord.RelayAndAckPendingPackets(path)) + wasmibctesting.RelayAndAckPacket(t, path, result) // then // on chain A @@ -221,13 +221,13 @@ func TestIBCFeesWasm(t *testing.T) { ibcPayloadMsg := ibctransfertypes.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, []sdk.Coin{gotBalance}, actorChainB.String(), actorChainA.String(), clienttypes.Height{}, uint64(time.Now().Add(time.Minute).UnixNano()), "even more tests", &ibctransfertypes.Forwarding{Unwind: false, Hops: []ibctransfertypes.Hop{}}) ibcPackageFee = ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) feeMsg = ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), nil) - _, err = chainB.SendMsgs(feeMsg, ibcPayloadMsg) + result, err = chainB.SendMsgs(feeMsg, ibcPayloadMsg) require.NoError(t, err) pendingIncentivisedPackages = appB.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainB.GetContext(), ibctransfertypes.PortID, path.EndpointB.ChannelID) assert.Len(t, pendingIncentivisedPackages, 1) // when packages relayed - require.NoError(t, coord.RelayAndAckPendingPackets(path)) + wasmibctesting.RelayAndAckPacket(t, path, result) // then // on chain A diff --git a/tests/ibctesting/chain2.go b/tests/ibctesting/chain2.go new file mode 100644 index 000000000..02b4d23c2 --- /dev/null +++ b/tests/ibctesting/chain2.go @@ -0,0 +1,394 @@ +package ibctesting + +import ( + "bytes" + "compress/gzip" + "context" + "os" + "strings" + "testing" + + "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmttypes "github.com/cometbft/cometbft/types" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/gogoproto/proto" + ibcfeekeeper "github.com/cosmos/ibc-go/v9/modules/apps/29-fee/keeper" + + "github.com/CosmWasm/wasmd/app" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/types" + abci "github.com/cometbft/cometbft/abci/types" + capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" + clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" + ibckeeper "github.com/cosmos/ibc-go/v9/modules/core/keeper" + ibctesting "github.com/cosmos/ibc-go/v9/testing" + ibctestingtypes "github.com/cosmos/ibc-go/v9/testing/types" +) + +type WasmTestApp struct { + App *app.WasmApp +} + +// ibc-go additions +func (app WasmTestApp) GetBaseApp() *baseapp.BaseApp { + return app.App.BaseApp +} + +func (app WasmTestApp) GetStakingKeeper() ibctestingtypes.StakingKeeper { + return app.App.GetStakingKeeper() +} + +func (app WasmTestApp) GetIBCKeeper() *ibckeeper.Keeper { + return app.App.GetIBCKeeper() +} + +func (app WasmTestApp) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper { + return app.App.GetScopedIBCKeeper() +} + +func (app WasmTestApp) GetTxConfig() client.TxConfig { + return app.App.TxConfig() +} + +func (app WasmTestApp) AppCodec() codec.Codec { + return app.App.AppCodec() +} + +func (app WasmTestApp) LastCommitID() storetypes.CommitID { + return app.App.LastCommitID() +} + +func (app WasmTestApp) LastBlockHeight() int64 { + return app.App.LastBlockHeight() +} + +func (app WasmTestApp) Info(a *abci.RequestInfo) (*abci.ResponseInfo, error) { + return app.App.Info(a) +} + +func (app WasmTestApp) Query(c context.Context, a *abci.RequestQuery) (*abci.ResponseQuery, error) { + return app.App.Query(c, a) +} + +func (app WasmTestApp) CheckTx(a *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { + return app.App.CheckTx(a) +} + +func (app WasmTestApp) InitChain(a *abci.RequestInitChain) (*abci.ResponseInitChain, error) { + return app.App.InitChain(a) +} + +func (app WasmTestApp) PrepareProposal(a *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { + return app.App.PrepareProposal(a) +} + +func (app WasmTestApp) ProcessProposal(a *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { + return app.App.ProcessProposal(a) +} + +func (app WasmTestApp) FinalizeBlock(a *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { + return app.App.FinalizeBlock(a) +} + +func (app WasmTestApp) ExtendVote(c context.Context, a *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + return app.App.ExtendVote(c, a) +} + +func (app WasmTestApp) VerifyVoteExtension(a *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + return app.App.VerifyVoteExtension(a) +} + +func (app WasmTestApp) Commit() (*abci.ResponseCommit, error) { + return app.App.Commit() +} + +func (app WasmTestApp) ListSnapshots(a *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { + return app.App.ListSnapshots(a) +} + +func (app WasmTestApp) OfferSnapshot(a *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { + return app.App.OfferSnapshot(a) +} + +func (app WasmTestApp) LoadSnapshotChunk(a *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { + return app.App.LoadSnapshotChunk(a) +} + +func (app WasmTestApp) ApplySnapshotChunk(a *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { + return app.App.ApplySnapshotChunk(a) +} + +func (app WasmTestApp) GetIBCFeeKeeper() ibcfeekeeper.Keeper { + return app.App.IBCFeeKeeper +} + +func (app WasmTestApp) GetBankKeeper() bankkeeper.Keeper { + return app.App.GetBankKeeper() +} + +func (app WasmTestApp) GetWasmKeeper() wasmkeeper.Keeper { + return app.App.GetWasmKeeper() +} + +type WasmTestChain struct { + IbcChain *ibctesting.TestChain +} + +func NewWasmTestChain(chain *ibctesting.TestChain) WasmTestChain { + return WasmTestChain{IbcChain: chain} +} + +func (chain WasmTestChain) GetContext() sdk.Context { + return chain.IbcChain.GetContext() +} + +func (chain WasmTestChain) GetWasmApp() *app.WasmApp { + return chain.IbcChain.App.(WasmTestApp).App +} + +func (chain WasmTestChain) StoreCodeFile(filename string) types.MsgStoreCodeResponse { + wasmCode, err := os.ReadFile(filename) + require.NoError(chain.IbcChain.TB, err) + if strings.HasSuffix(filename, "wasm") { // compress for gas limit + var buf bytes.Buffer + gz := gzip.NewWriter(&buf) + _, err := gz.Write(wasmCode) + require.NoError(chain.IbcChain.TB, err) + err = gz.Close() + require.NoError(chain.IbcChain.TB, err) + wasmCode = buf.Bytes() + } + return chain.StoreCode(wasmCode) +} + +func (chain WasmTestChain) StoreCode(byteCode []byte) types.MsgStoreCodeResponse { + storeMsg := &types.MsgStoreCode{ + Sender: chain.IbcChain.SenderAccount.GetAddress().String(), + WASMByteCode: byteCode, + } + r, err := chain.IbcChain.SendMsgs(storeMsg) + require.NoError(chain.IbcChain.TB, err) + + var pInstResp types.MsgStoreCodeResponse + chain.UnwrapExecTXResult(r, &pInstResp) + + require.NotEmpty(chain.IbcChain.TB, pInstResp.CodeID) + require.NotEmpty(chain.IbcChain.TB, pInstResp.Checksum) + return pInstResp +} + +// UnwrapExecTXResult is a helper to unpack execution result from proto any type +func (chain WasmTestChain) UnwrapExecTXResult(r *abci.ExecTxResult, target proto.Message) { + var wrappedRsp sdk.TxMsgData + require.NoError(chain.IbcChain.TB, chain.IbcChain.App.AppCodec().Unmarshal(r.Data, &wrappedRsp)) + + // unmarshal protobuf response from data + require.Len(chain.IbcChain.TB, wrappedRsp.MsgResponses, 1) + require.NoError(chain.IbcChain.TB, proto.Unmarshal(wrappedRsp.MsgResponses[0].Value, target)) +} + +func (chain WasmTestChain) InstantiateContract(codeID uint64, initMsg []byte) sdk.AccAddress { + instantiateMsg := &types.MsgInstantiateContract{ + Sender: chain.IbcChain.SenderAccount.GetAddress().String(), + Admin: chain.IbcChain.SenderAccount.GetAddress().String(), + CodeID: codeID, + Label: "ibc-test", + Msg: initMsg, + Funds: sdk.Coins{ibctesting.TestCoin}, + } + + r, err := chain.IbcChain.SendMsgs(instantiateMsg) + require.NoError(chain.IbcChain.TB, err) + + var pExecResp types.MsgInstantiateContractResponse + chain.UnwrapExecTXResult(r, &pExecResp) + + a, err := sdk.AccAddressFromBech32(pExecResp.Address) + require.NoError(chain.IbcChain.TB, err) + return a +} + +func (chain WasmTestChain) ContractInfo(contractAddr sdk.AccAddress) *types.ContractInfo { + return chain.IbcChain.App.(WasmTestApp).GetWasmKeeper().GetContractInfo(chain.IbcChain.GetContext(), contractAddr) +} + +// Fund an address with the given amount in default denom +func (chain WasmTestChain) Fund(addr sdk.AccAddress, amount math.Int) { + _, err := chain.IbcChain.SendMsgs(&banktypes.MsgSend{ + FromAddress: chain.IbcChain.SenderAccount.GetAddress().String(), + ToAddress: addr.String(), + Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), + }) + require.NoError(chain.IbcChain.TB, err) +} + +// GetTimeoutHeight is a convenience function which returns a IBC packet timeout height +// to be used for testing. It returns the current IBC height + 100 blocks +func (chain WasmTestChain) GetTimeoutHeight() clienttypes.Height { + return clienttypes.NewHeight(clienttypes.ParseChainID(chain.IbcChain.ChainID), uint64(chain.IbcChain.GetContext().BlockHeight())+100) +} + +func (chain WasmTestChain) Balance(acc sdk.AccAddress, denom string) sdk.Coin { + return chain.IbcChain.App.(WasmTestApp).GetBankKeeper().GetBalance(chain.IbcChain.GetContext(), acc, denom) +} + +func (chain WasmTestChain) AllBalances(acc sdk.AccAddress) sdk.Coins { + return chain.IbcChain.App.(WasmTestApp).GetBankKeeper().GetAllBalances(chain.IbcChain.GetContext(), acc) +} + +func (chain WasmTestChain) SendMsgs(msgs ...sdk.Msg) (*abci.ExecTxResult, error) { + return chain.IbcChain.SendMsgs(msgs...) +} + +func RelayAndAckPacket(t *testing.T, path *ibctesting.Path, result *abci.ExecTxResult) { + packet, err := ibctesting.ParsePacketFromEvents(result.Events) + require.NoError(t, err) + err = path.RelayPacket(packet) + require.NoError(t, err) +} + +// ChainAppFactory abstract factory method that usually implemented by app.SetupWithGenesisValSet +type ChainAppFactory2 func(t *testing.T, valSet *cmttypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasmkeeper.Option, balances ...banktypes.Balance) WasmTestApp + +// DefaultWasmAppFactory instantiates and sets up the default wasmd app +func DefaultWasmAppFactory2(t *testing.T, valSet *cmttypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasmkeeper.Option, balances ...banktypes.Balance) WasmTestApp { + return WasmTestApp{App: app.SetupWithGenesisValSet(t, valSet, genAccs, chainID, opts, balances...)} +} + +// NewDefaultTestChain initializes a new test chain with a default of 4 validators +// Use this function if the tests do not need custom control over the validator set +func NewDefaultTestChain2(t *testing.T, coord *ibctesting.Coordinator, chainID string, opts ...wasmkeeper.Option) *ibctesting.TestChain { + return NewTestChain2(t, coord, DefaultWasmAppFactory2, chainID, opts...) +} + +// NewTestChain initializes a new test chain with a default of 4 validators +// Use this function if the tests do not need custom control over the validator set +func NewTestChain2(t *testing.T, coord *ibctesting.Coordinator, appFactory ChainAppFactory2, chainID string, opts ...wasmkeeper.Option) *ibctesting.TestChain { + // generate validators private/public key + var ( + validatorsPerChain = 4 + validators = make([]*cmttypes.Validator, 0, validatorsPerChain) + signersByAddress = make(map[string]cmttypes.PrivValidator, validatorsPerChain) + ) + + for i := 0; i < validatorsPerChain; i++ { + _, privVal := cmttypes.RandValidator(false, 100) + pubKey, err := privVal.GetPubKey() + require.NoError(t, err) + validators = append(validators, cmttypes.NewValidator(pubKey, 1)) + signersByAddress[pubKey.Address().String()] = privVal + } + + // construct validator set; + // Note that the validators are sorted by voting power + // or, if equal, by address lexical order + valSet := cmttypes.NewValidatorSet(validators) + + return NewTestChainWithValSet2(t, coord, appFactory, chainID, valSet, signersByAddress, opts...) +} + +// NewTestChainWithValSet initializes a new TestChain instance with the given validator set +// and signer array. It also initializes 10 Sender accounts with a balance of 10000000000000000000 coins of +// bond denom to use for tests. +// +// The first block height is committed to state in order to allow for client creations on +// counterparty chains. The TestChain will return with a block height starting at 2. +// +// Time management is handled by the Coordinator in order to ensure synchrony between chains. +// Each update of any chain increments the block header time for all chains by 5 seconds. +// +// NOTE: to use a custom sender privkey and account for testing purposes, replace and modify this +// constructor function. +// +// CONTRACT: Validator array must be provided in the order expected by Tendermint. +// i.e. sorted first by power and then lexicographically by address. +func NewTestChainWithValSet2(t *testing.T, coord *ibctesting.Coordinator, appFactory ChainAppFactory2, chainID string, valSet *cmttypes.ValidatorSet, signers map[string]cmttypes.PrivValidator, opts ...wasmkeeper.Option) *ibctesting.TestChain { + genAccs := []authtypes.GenesisAccount{} + genBals := []banktypes.Balance{} + senderAccs := []ibctesting.SenderAccount{} + + // generate genesis accounts + for i := 0; i < MaxAccounts; i++ { + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), uint64(i), 0) + amount, ok := math.NewIntFromString("10000000000000000000") + require.True(t, ok) + + // add sender account + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), + } + + genAccs = append(genAccs, acc) + genBals = append(genBals, balance) + + senderAcc := ibctesting.SenderAccount{ + SenderAccount: acc, + SenderPrivKey: senderPrivKey, + } + + senderAccs = append(senderAccs, senderAcc) + } + + wasmApp := appFactory(t, valSet, genAccs, chainID, opts, genBals...) + + // create current header and call begin block + header := cmtproto.Header{ + ChainID: chainID, + Height: 1, + Time: coord.CurrentTime.UTC(), + } + + txConfig := wasmApp.GetTxConfig() + + // create an account to send transactions from + chain := &ibctesting.TestChain{ + TB: t, + Coordinator: coord, + ChainID: chainID, + App: wasmApp, + ProposedHeader: header, + TxConfig: txConfig, + Codec: wasmApp.AppCodec(), + Vals: valSet, + NextVals: valSet, + Signers: signers, + SenderPrivKey: senderAccs[0].SenderPrivKey, + SenderAccount: senderAccs[0].SenderAccount, + SenderAccounts: senderAccs, + } + + coord.CommitBlock(chain) + + return chain +} + +// NewCoordinator initializes Coordinator with N TestChain's +func NewCoordinator2(t *testing.T, n int) *ibctesting.Coordinator { + t.Helper() + chains := make(map[string]*ibctesting.TestChain) + coord := &ibctesting.Coordinator{ + T: t, + CurrentTime: globalStartTime, + } + + for i := 1; i <= n; i++ { + chainID := ibctesting.GetChainID(i) + chains[chainID] = NewDefaultTestChain2(t, coord, chainID) + } + coord.Chains = chains + + return coord +}