github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/relay_test.go (about)

     1  package wasm_test
     2  
     3  //import (
     4  //	"encoding/json"
     5  //	"errors"
     6  //	"testing"
     7  //	"time"
     8  //
     9  //	wasmvm "github.com/CosmWasm/wasmvm"
    10  //	wasmvmtypes "github.com/CosmWasm/wasmvm/types"
    11  //	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    12  //	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
    13  //	ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
    14  //	clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
    15  //	channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
    16  //	ibctesting "github.com/cosmos/ibc-go/v3/testing"
    17  //	"github.com/stretchr/testify/assert"
    18  //	"github.com/stretchr/testify/require"
    19  //
    20  //	wasmibctesting "github.com/fibonacci-chain/fbc/x/wasm/ibctesting"
    21  //	wasmkeeper "github.com/fibonacci-chain/fbc/x/wasm/keeper"
    22  //	wasmtesting "github.com/fibonacci-chain/fbc/x/wasm/keeper/wasmtesting"
    23  //	"github.com/fibonacci-chain/fbc/x/wasm/types"
    24  //)
    25  //
    26  //func TestFromIBCTransferToContract(t *testing.T) {
    27  //	// scenario: given two chains,
    28  //	//           with a contract on chain B
    29  //	//           then the contract can handle the receiving side of an ics20 transfer
    30  //	//           that was started on chain A via ibc transfer module
    31  //
    32  //	transferAmount := sdk.NewInt(1)
    33  //	specs := map[string]struct {
    34  //		contract             wasmtesting.IBCContractCallbacks
    35  //		setupContract        func(t *testing.T, contract wasmtesting.IBCContractCallbacks, chain *wasmibctesting.TestChain)
    36  //		expChainABalanceDiff sdk.Int
    37  //		expChainBBalanceDiff sdk.Int
    38  //	}{
    39  //		"ack": {
    40  //			contract: &ackReceiverContract{},
    41  //			setupContract: func(t *testing.T, contract wasmtesting.IBCContractCallbacks, chain *wasmibctesting.TestChain) {
    42  //				c := contract.(*ackReceiverContract)
    43  //				c.t = t
    44  //				c.chain = chain
    45  //			},
    46  //			expChainABalanceDiff: transferAmount.Neg(),
    47  //			expChainBBalanceDiff: transferAmount,
    48  //		},
    49  //		"nack": {
    50  //			contract: &nackReceiverContract{},
    51  //			setupContract: func(t *testing.T, contract wasmtesting.IBCContractCallbacks, chain *wasmibctesting.TestChain) {
    52  //				c := contract.(*nackReceiverContract)
    53  //				c.t = t
    54  //			},
    55  //			expChainABalanceDiff: sdk.ZeroInt(),
    56  //			expChainBBalanceDiff: sdk.ZeroInt(),
    57  //		},
    58  //		"error": {
    59  //			contract: &errorReceiverContract{},
    60  //			setupContract: func(t *testing.T, contract wasmtesting.IBCContractCallbacks, chain *wasmibctesting.TestChain) {
    61  //				c := contract.(*errorReceiverContract)
    62  //				c.t = t
    63  //			},
    64  //			expChainABalanceDiff: sdk.ZeroInt(),
    65  //			expChainBBalanceDiff: sdk.ZeroInt(),
    66  //		},
    67  //	}
    68  //	for name, spec := range specs {
    69  //		t.Run(name, func(t *testing.T) {
    70  //			var (
    71  //				chainAOpts = []wasmkeeper.Option{wasmkeeper.WithWasmEngine(
    72  //					wasmtesting.NewIBCContractMockWasmer(spec.contract),
    73  //				)}
    74  //				coordinator = wasmibctesting.NewCoordinator(t, 2, []wasmkeeper.Option{}, chainAOpts)
    75  //				chainA      = coordinator.GetChain(wasmibctesting.GetChainID(0))
    76  //				chainB      = coordinator.GetChain(wasmibctesting.GetChainID(1))
    77  //			)
    78  //			coordinator.CommitBlock(chainA, chainB)
    79  //			myContractAddr := chainB.SeedNewContractInstance()
    80  //			contractBPortID := chainB.ContractInfo(myContractAddr).IBCPortID
    81  //
    82  //			spec.setupContract(t, spec.contract, chainB)
    83  //
    84  //			path := wasmibctesting.NewPath(chainA, chainB)
    85  //			path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
    86  //				PortID:  "transfer",
    87  //				Version: ibctransfertypes.Version,
    88  //				Order:   channeltypes.UNORDERED,
    89  //			}
    90  //			path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
    91  //				PortID:  contractBPortID,
    92  //				Version: ibctransfertypes.Version,
    93  //				Order:   channeltypes.UNORDERED,
    94  //			}
    95  //
    96  //			coordinator.SetupConnections(path)
    97  //			coordinator.CreateChannels(path)
    98  //
    99  //			originalChainABalance := chainA.Balance(chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
   100  //			// when transfer via sdk transfer from A (module) -> B (contract)
   101  //			coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, transferAmount)
   102  //			timeoutHeight := clienttypes.NewHeight(1, 110)
   103  //			msg := ibctransfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coinToSendToB, chainA.SenderAccount.GetAddress().String(), chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0)
   104  //			_, err := chainA.SendMsgs(msg)
   105  //			require.NoError(t, err)
   106  //			require.NoError(t, path.EndpointB.UpdateClient())
   107  //
   108  //			// then
   109  //			require.Equal(t, 1, len(chainA.PendingSendPackets))
   110  //			require.Equal(t, 0, len(chainB.PendingSendPackets))
   111  //
   112  //			// and when relay to chain B and handle Ack on chain A
   113  //			err = coordinator.RelayAndAckPendingPackets(path)
   114  //			require.NoError(t, err)
   115  //
   116  //			// then
   117  //			require.Equal(t, 0, len(chainA.PendingSendPackets))
   118  //			require.Equal(t, 0, len(chainB.PendingSendPackets))
   119  //
   120  //			// and source chain balance was decreased
   121  //			newChainABalance := chainA.Balance(chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
   122  //			assert.Equal(t, originalChainABalance.Amount.Add(spec.expChainABalanceDiff), newChainABalance.Amount)
   123  //
   124  //			// and dest chain balance contains voucher
   125  //			expBalance := ibctransfertypes.GetTransferCoin(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinToSendToB.Denom, spec.expChainBBalanceDiff)
   126  //			gotBalance := chainB.Balance(chainB.SenderAccount.GetAddress(), expBalance.Denom)
   127  //			assert.Equal(t, expBalance, gotBalance, "got total balance: %s", chainB.AllBalances(chainB.SenderAccount.GetAddress()))
   128  //		})
   129  //	}
   130  //}
   131  //
   132  //func TestContractCanInitiateIBCTransferMsg(t *testing.T) {
   133  //	// scenario: given two chains,
   134  //	//           with a contract on chain A
   135  //	//           then the contract can start an ibc transfer via ibctransfertypes.NewMsgTransfer
   136  //	//           that is handled on chain A by the ibc transfer module and
   137  //	//           received on chain B via ibc transfer module as well
   138  //
   139  //	myContract := &sendViaIBCTransferContract{t: t}
   140  //	var (
   141  //		chainAOpts = []wasmkeeper.Option{
   142  //			wasmkeeper.WithWasmEngine(
   143  //				wasmtesting.NewIBCContractMockWasmer(myContract)),
   144  //		}
   145  //		coordinator = wasmibctesting.NewCoordinator(t, 2, chainAOpts)
   146  //		chainA      = coordinator.GetChain(wasmibctesting.GetChainID(0))
   147  //		chainB      = coordinator.GetChain(wasmibctesting.GetChainID(1))
   148  //	)
   149  //	myContractAddr := chainA.SeedNewContractInstance()
   150  //	coordinator.CommitBlock(chainA, chainB)
   151  //
   152  //	path := wasmibctesting.NewPath(chainA, chainB)
   153  //	path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
   154  //		PortID:  ibctransfertypes.PortID,
   155  //		Version: ibctransfertypes.Version,
   156  //		Order:   channeltypes.UNORDERED,
   157  //	}
   158  //	path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
   159  //		PortID:  ibctransfertypes.PortID,
   160  //		Version: ibctransfertypes.Version,
   161  //		Order:   channeltypes.UNORDERED,
   162  //	}
   163  //	coordinator.SetupConnections(path)
   164  //	coordinator.CreateChannels(path)
   165  //
   166  //	// when contract is triggered to send IBCTransferMsg
   167  //	receiverAddress := chainB.SenderAccount.GetAddress()
   168  //	coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
   169  //
   170  //	// start transfer from chainA to chainB
   171  //	startMsg := &types.MsgExecuteContract{
   172  //		Sender:   chainA.SenderAccount.GetAddress().String(),
   173  //		Contract: myContractAddr.String(),
   174  //		Msg: startTransfer{
   175  //			ChannelID:    path.EndpointA.ChannelID,
   176  //			CoinsToSend:  coinToSendToB,
   177  //			ReceiverAddr: receiverAddress.String(),
   178  //		}.GetBytes(),
   179  //	}
   180  //	_, err := chainA.SendMsgs(startMsg)
   181  //	require.NoError(t, err)
   182  //
   183  //	// then
   184  //	require.Equal(t, 1, len(chainA.PendingSendPackets))
   185  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
   186  //
   187  //	// and when relay to chain B and handle Ack on chain A
   188  //	err = coordinator.RelayAndAckPendingPackets(path)
   189  //	require.NoError(t, err)
   190  //
   191  //	// then
   192  //	require.Equal(t, 0, len(chainA.PendingSendPackets))
   193  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
   194  //
   195  //	// and dest chain balance contains voucher
   196  //	bankKeeperB := chainB.GetTestSupport().BankKeeper()
   197  //	expBalance := ibctransfertypes.GetTransferCoin(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinToSendToB.Denom, coinToSendToB.Amount)
   198  //	gotBalance := chainB.Balance(chainB.SenderAccount.GetAddress(), expBalance.Denom)
   199  //	assert.Equal(t, expBalance, gotBalance, "got total balance: %s", bankKeeperB.GetAllBalances(chainB.GetContext(), chainB.SenderAccount.GetAddress()))
   200  //}
   201  //
   202  //func TestContractCanEmulateIBCTransferMessage(t *testing.T) {
   203  //	// scenario: given two chains,
   204  //	//           with a contract on chain A
   205  //	//           then the contract can emulate the ibc transfer module in the contract to send an ibc packet
   206  //	//           which is received on chain B via ibc transfer module
   207  //
   208  //	myContract := &sendEmulatedIBCTransferContract{t: t}
   209  //
   210  //	var (
   211  //		chainAOpts = []wasmkeeper.Option{
   212  //			wasmkeeper.WithWasmEngine(
   213  //				wasmtesting.NewIBCContractMockWasmer(myContract)),
   214  //		}
   215  //		coordinator = wasmibctesting.NewCoordinator(t, 2, chainAOpts)
   216  //
   217  //		chainA = coordinator.GetChain(wasmibctesting.GetChainID(0))
   218  //		chainB = coordinator.GetChain(wasmibctesting.GetChainID(1))
   219  //	)
   220  //	myContractAddr := chainA.SeedNewContractInstance()
   221  //	myContract.contractAddr = myContractAddr.String()
   222  //
   223  //	path := wasmibctesting.NewPath(chainA, chainB)
   224  //	path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
   225  //		PortID:  chainA.ContractInfo(myContractAddr).IBCPortID,
   226  //		Version: ibctransfertypes.Version,
   227  //		Order:   channeltypes.UNORDERED,
   228  //	}
   229  //	path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
   230  //		PortID:  ibctransfertypes.PortID,
   231  //		Version: ibctransfertypes.Version,
   232  //		Order:   channeltypes.UNORDERED,
   233  //	}
   234  //	coordinator.SetupConnections(path)
   235  //	coordinator.CreateChannels(path)
   236  //
   237  //	// when contract is triggered to send the ibc package to chain B
   238  //	timeout := uint64(chainB.LastHeader.Header.Time.Add(time.Hour).UnixNano()) // enough time to not timeout
   239  //	receiverAddress := chainB.SenderAccount.GetAddress()
   240  //	coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
   241  //
   242  //	// start transfer from chainA to chainB
   243  //	startMsg := &types.MsgExecuteContract{
   244  //		Sender:   chainA.SenderAccount.GetAddress().String(),
   245  //		Contract: myContractAddr.String(),
   246  //		Msg: startTransfer{
   247  //			ChannelID:       path.EndpointA.ChannelID,
   248  //			CoinsToSend:     coinToSendToB,
   249  //			ReceiverAddr:    receiverAddress.String(),
   250  //			ContractIBCPort: chainA.ContractInfo(myContractAddr).IBCPortID,
   251  //			Timeout:         timeout,
   252  //		}.GetBytes(),
   253  //		Funds: sdk.NewCoins(coinToSendToB),
   254  //	}
   255  //	_, err := chainA.SendMsgs(startMsg)
   256  //	require.NoError(t, err)
   257  //
   258  //	// then
   259  //	require.Equal(t, 1, len(chainA.PendingSendPackets))
   260  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
   261  //
   262  //	// and when relay to chain B and handle Ack on chain A
   263  //	err = coordinator.RelayAndAckPendingPackets(path)
   264  //	require.NoError(t, err)
   265  //
   266  //	// then
   267  //	require.Equal(t, 0, len(chainA.PendingSendPackets))
   268  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
   269  //
   270  //	// and dest chain balance contains voucher
   271  //	bankKeeperB := chainB.GetTestSupport().BankKeeper()
   272  //	expBalance := ibctransfertypes.GetTransferCoin(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinToSendToB.Denom, coinToSendToB.Amount)
   273  //	gotBalance := chainB.Balance(chainB.SenderAccount.GetAddress(), expBalance.Denom)
   274  //	assert.Equal(t, expBalance, gotBalance, "got total balance: %s", bankKeeperB.GetAllBalances(chainB.GetContext(), chainB.SenderAccount.GetAddress()))
   275  //}
   276  //
   277  //func TestContractCanEmulateIBCTransferMessageWithTimeout(t *testing.T) {
   278  //	// scenario: given two chains,
   279  //	//           with a contract on chain A
   280  //	//           then the contract can emulate the ibc transfer module in the contract to send an ibc packet
   281  //	//           which is not received on chain B and times out
   282  //
   283  //	myContract := &sendEmulatedIBCTransferContract{t: t}
   284  //
   285  //	var (
   286  //		chainAOpts = []wasmkeeper.Option{
   287  //			wasmkeeper.WithWasmEngine(
   288  //				wasmtesting.NewIBCContractMockWasmer(myContract)),
   289  //		}
   290  //		coordinator = wasmibctesting.NewCoordinator(t, 2, chainAOpts)
   291  //
   292  //		chainA = coordinator.GetChain(wasmibctesting.GetChainID(0))
   293  //		chainB = coordinator.GetChain(wasmibctesting.GetChainID(1))
   294  //	)
   295  //	coordinator.CommitBlock(chainA, chainB)
   296  //	myContractAddr := chainA.SeedNewContractInstance()
   297  //	myContract.contractAddr = myContractAddr.String()
   298  //
   299  //	path := wasmibctesting.NewPath(chainA, chainB)
   300  //	path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
   301  //		PortID:  chainA.ContractInfo(myContractAddr).IBCPortID,
   302  //		Version: ibctransfertypes.Version,
   303  //		Order:   channeltypes.UNORDERED,
   304  //	}
   305  //	path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
   306  //		PortID:  ibctransfertypes.PortID,
   307  //		Version: ibctransfertypes.Version,
   308  //		Order:   channeltypes.UNORDERED,
   309  //	}
   310  //	coordinator.SetupConnections(path)
   311  //	coordinator.CreateChannels(path)
   312  //	coordinator.UpdateTime()
   313  //
   314  //	// when contract is triggered to send the ibc package to chain B
   315  //	timeout := uint64(chainB.LastHeader.Header.Time.Add(time.Nanosecond).UnixNano()) // will timeout
   316  //	receiverAddress := chainB.SenderAccount.GetAddress()
   317  //	coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
   318  //	initialContractBalance := chainA.Balance(myContractAddr, sdk.DefaultBondDenom)
   319  //	initialSenderBalance := chainA.Balance(chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
   320  //
   321  //	// custom payload data to be transferred into a proper ICS20 ibc packet
   322  //	startMsg := &types.MsgExecuteContract{
   323  //		Sender:   chainA.SenderAccount.GetAddress().String(),
   324  //		Contract: myContractAddr.String(),
   325  //		Msg: startTransfer{
   326  //			ChannelID:       path.EndpointA.ChannelID,
   327  //			CoinsToSend:     coinToSendToB,
   328  //			ReceiverAddr:    receiverAddress.String(),
   329  //			ContractIBCPort: chainA.ContractInfo(myContractAddr).IBCPortID,
   330  //			Timeout:         timeout,
   331  //		}.GetBytes(),
   332  //		Funds: sdk.NewCoins(coinToSendToB),
   333  //	}
   334  //	_, err := chainA.SendMsgs(startMsg)
   335  //	require.NoError(t, err)
   336  //	coordinator.CommitBlock(chainA, chainB)
   337  //	// then
   338  //	require.Equal(t, 1, len(chainA.PendingSendPackets))
   339  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
   340  //	newContractBalance := chainA.Balance(myContractAddr, sdk.DefaultBondDenom)
   341  //	assert.Equal(t, initialContractBalance.Add(coinToSendToB), newContractBalance) // hold in escrow
   342  //
   343  //	// when timeout packet send (by the relayer)
   344  //	err = coordinator.TimeoutPendingPackets(path)
   345  //	require.NoError(t, err)
   346  //	coordinator.CommitBlock(chainA)
   347  //
   348  //	// then
   349  //	require.Equal(t, 0, len(chainA.PendingSendPackets))
   350  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
   351  //
   352  //	// and then verify account balances restored
   353  //	newContractBalance = chainA.Balance(myContractAddr, sdk.DefaultBondDenom)
   354  //	assert.Equal(t, initialContractBalance.String(), newContractBalance.String())
   355  //	newSenderBalance := chainA.Balance(chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
   356  //	assert.Equal(t, initialSenderBalance.String(), newSenderBalance.String())
   357  //}
   358  //
   359  //func TestContractHandlesChannelClose(t *testing.T) {
   360  //	// scenario: a contract is the sending side of an ics20 transfer but the packet was not received
   361  //	// on the destination chain within the timeout boundaries
   362  //	myContractA := &captureCloseContract{}
   363  //	myContractB := &captureCloseContract{}
   364  //
   365  //	var (
   366  //		chainAOpts = []wasmkeeper.Option{
   367  //			wasmkeeper.WithWasmEngine(
   368  //				wasmtesting.NewIBCContractMockWasmer(myContractA)),
   369  //		}
   370  //		chainBOpts = []wasmkeeper.Option{
   371  //			wasmkeeper.WithWasmEngine(
   372  //				wasmtesting.NewIBCContractMockWasmer(myContractB)),
   373  //		}
   374  //		coordinator = wasmibctesting.NewCoordinator(t, 2, chainAOpts, chainBOpts)
   375  //
   376  //		chainA = coordinator.GetChain(wasmibctesting.GetChainID(0))
   377  //		chainB = coordinator.GetChain(wasmibctesting.GetChainID(1))
   378  //	)
   379  //
   380  //	coordinator.CommitBlock(chainA, chainB)
   381  //	myContractAddrA := chainA.SeedNewContractInstance()
   382  //	_ = chainB.SeedNewContractInstance() // skip one instance
   383  //	myContractAddrB := chainB.SeedNewContractInstance()
   384  //
   385  //	path := wasmibctesting.NewPath(chainA, chainB)
   386  //	path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
   387  //		PortID:  chainA.ContractInfo(myContractAddrA).IBCPortID,
   388  //		Version: ibctransfertypes.Version,
   389  //		Order:   channeltypes.UNORDERED,
   390  //	}
   391  //	path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
   392  //		PortID:  chainB.ContractInfo(myContractAddrB).IBCPortID,
   393  //		Version: ibctransfertypes.Version,
   394  //		Order:   channeltypes.UNORDERED,
   395  //	}
   396  //	coordinator.SetupConnections(path)
   397  //	coordinator.CreateChannels(path)
   398  //	coordinator.CloseChannel(path)
   399  //	assert.True(t, myContractB.closeCalled)
   400  //}
   401  //
   402  //var _ wasmtesting.IBCContractCallbacks = &captureCloseContract{}
   403  //
   404  //// contract that sets a flag on IBC channel close only.
   405  //type captureCloseContract struct {
   406  //	contractStub
   407  //	closeCalled bool
   408  //}
   409  //
   410  //func (c *captureCloseContract) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
   411  //	c.closeCalled = true
   412  //	return &wasmvmtypes.IBCBasicResponse{}, 1, nil
   413  //}
   414  //
   415  //var _ wasmtesting.IBCContractCallbacks = &sendViaIBCTransferContract{}
   416  //
   417  //// contract that initiates an ics-20 transfer on execute via sdk message
   418  //type sendViaIBCTransferContract struct {
   419  //	contractStub
   420  //	t *testing.T
   421  //}
   422  //
   423  //func (s *sendViaIBCTransferContract) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
   424  //	var in startTransfer
   425  //	if err := json.Unmarshal(executeMsg, &in); err != nil {
   426  //		return nil, 0, err
   427  //	}
   428  //	ibcMsg := &wasmvmtypes.IBCMsg{
   429  //		Transfer: &wasmvmtypes.TransferMsg{
   430  //			ToAddress: in.ReceiverAddr,
   431  //			Amount:    wasmvmtypes.NewCoin(in.CoinsToSend.Amount.Uint64(), in.CoinsToSend.Denom),
   432  //			ChannelID: in.ChannelID,
   433  //			Timeout: wasmvmtypes.IBCTimeout{Block: &wasmvmtypes.IBCTimeoutBlock{
   434  //				Revision: 0,
   435  //				Height:   110,
   436  //			}},
   437  //		},
   438  //	}
   439  //
   440  //	return &wasmvmtypes.Response{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{IBC: ibcMsg}}}}, 0, nil
   441  //}
   442  //
   443  //var _ wasmtesting.IBCContractCallbacks = &sendEmulatedIBCTransferContract{}
   444  //
   445  //// contract that interacts as an ics20 sending side via IBC packets
   446  //// It can also handle the timeout.
   447  //type sendEmulatedIBCTransferContract struct {
   448  //	contractStub
   449  //	t            *testing.T
   450  //	contractAddr string
   451  //}
   452  //
   453  //func (s *sendEmulatedIBCTransferContract) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
   454  //	var in startTransfer
   455  //	if err := json.Unmarshal(executeMsg, &in); err != nil {
   456  //		return nil, 0, err
   457  //	}
   458  //	require.Len(s.t, info.Funds, 1)
   459  //	require.Equal(s.t, in.CoinsToSend.Amount.String(), info.Funds[0].Amount)
   460  //	require.Equal(s.t, in.CoinsToSend.Denom, info.Funds[0].Denom)
   461  //	dataPacket := ibctransfertypes.NewFungibleTokenPacketData(
   462  //		in.CoinsToSend.Denom, in.CoinsToSend.Amount.String(), info.Sender, in.ReceiverAddr,
   463  //	)
   464  //	if err := dataPacket.ValidateBasic(); err != nil {
   465  //		return nil, 0, err
   466  //	}
   467  //
   468  //	ibcMsg := &wasmvmtypes.IBCMsg{
   469  //		SendPacket: &wasmvmtypes.SendPacketMsg{
   470  //			ChannelID: in.ChannelID,
   471  //			Data:      dataPacket.GetBytes(),
   472  //			Timeout:   wasmvmtypes.IBCTimeout{Timestamp: in.Timeout},
   473  //		},
   474  //	}
   475  //	return &wasmvmtypes.Response{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{IBC: ibcMsg}}}}, 0, nil
   476  //}
   477  //
   478  //func (c *sendEmulatedIBCTransferContract) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
   479  //	packet := msg.Packet
   480  //
   481  //	var data ibctransfertypes.FungibleTokenPacketData
   482  //	if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packet.Data, &data); err != nil {
   483  //		return nil, 0, err
   484  //	}
   485  //	if err := data.ValidateBasic(); err != nil {
   486  //		return nil, 0, err
   487  //	}
   488  //	amount, _ := sdk.NewIntFromString(data.Amount)
   489  //
   490  //	returnTokens := &wasmvmtypes.BankMsg{
   491  //		Send: &wasmvmtypes.SendMsg{
   492  //			ToAddress: data.Sender,
   493  //			Amount:    wasmvmtypes.Coins{wasmvmtypes.NewCoin(amount.Uint64(), data.Denom)},
   494  //		},
   495  //	}
   496  //
   497  //	return &wasmvmtypes.IBCBasicResponse{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: returnTokens}}}}, 0, nil
   498  //}
   499  //
   500  //// custom contract execute payload
   501  //type startTransfer struct {
   502  //	ChannelID       string
   503  //	CoinsToSend     sdk.Coin
   504  //	ReceiverAddr    string
   505  //	ContractIBCPort string
   506  //	Timeout         uint64
   507  //}
   508  //
   509  //func (g startTransfer) GetBytes() types.RawContractMessage {
   510  //	b, err := json.Marshal(g)
   511  //	if err != nil {
   512  //		panic(err)
   513  //	}
   514  //	return b
   515  //}
   516  //
   517  //var _ wasmtesting.IBCContractCallbacks = &ackReceiverContract{}
   518  //
   519  //// contract that acts as the receiving side for an ics-20 transfer.
   520  //type ackReceiverContract struct {
   521  //	contractStub
   522  //	t     *testing.T
   523  //	chain *wasmibctesting.TestChain
   524  //}
   525  //
   526  //func (c *ackReceiverContract) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) {
   527  //	packet := msg.Packet
   528  //
   529  //	var src ibctransfertypes.FungibleTokenPacketData
   530  //	if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packet.Data, &src); err != nil {
   531  //		return nil, 0, err
   532  //	}
   533  //	require.NoError(c.t, src.ValidateBasic())
   534  //
   535  //	// call original ibctransfer keeper to not copy all code into this
   536  //	ibcPacket := toIBCPacket(packet)
   537  //	ctx := c.chain.GetContext() // HACK: please note that this is not reverted after checkTX
   538  //	err := c.chain.GetTestSupport().TransferKeeper().OnRecvPacket(ctx, ibcPacket, src)
   539  //	if err != nil {
   540  //		return nil, 0, sdkerrors.Wrap(err, "within our smart contract")
   541  //	}
   542  //
   543  //	var log []wasmvmtypes.EventAttribute // note: all events are under `wasm` event type
   544  //	ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)}).Acknowledgement()
   545  //	return &wasmvmtypes.IBCReceiveResult{Ok: &wasmvmtypes.IBCReceiveResponse{Acknowledgement: ack, Attributes: log}}, 0, nil
   546  //}
   547  //
   548  //func (c *ackReceiverContract) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
   549  //	var data ibctransfertypes.FungibleTokenPacketData
   550  //	if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(msg.OriginalPacket.Data, &data); err != nil {
   551  //		return nil, 0, err
   552  //	}
   553  //	// call original ibctransfer keeper to not copy all code into this
   554  //
   555  //	var ack channeltypes.Acknowledgement
   556  //	if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(msg.Acknowledgement.Data, &ack); err != nil {
   557  //		return nil, 0, err
   558  //	}
   559  //
   560  //	// call original ibctransfer keeper to not copy all code into this
   561  //	ctx := c.chain.GetContext() // HACK: please note that this is not reverted after checkTX
   562  //	ibcPacket := toIBCPacket(msg.OriginalPacket)
   563  //	err := c.chain.GetTestSupport().TransferKeeper().OnAcknowledgementPacket(ctx, ibcPacket, data, ack)
   564  //	if err != nil {
   565  //		return nil, 0, sdkerrors.Wrap(err, "within our smart contract")
   566  //	}
   567  //
   568  //	return &wasmvmtypes.IBCBasicResponse{}, 0, nil
   569  //}
   570  //
   571  //// contract that acts as the receiving side for an ics-20 transfer and always returns a nack.
   572  //type nackReceiverContract struct {
   573  //	contractStub
   574  //	t *testing.T
   575  //}
   576  //
   577  //func (c *nackReceiverContract) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) {
   578  //	packet := msg.Packet
   579  //
   580  //	var src ibctransfertypes.FungibleTokenPacketData
   581  //	if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packet.Data, &src); err != nil {
   582  //		return nil, 0, err
   583  //	}
   584  //	require.NoError(c.t, src.ValidateBasic())
   585  //	return &wasmvmtypes.IBCReceiveResult{Err: "nack-testing"}, 0, nil
   586  //}
   587  //
   588  //// contract that acts as the receiving side for an ics-20 transfer and always returns an error.
   589  //type errorReceiverContract struct {
   590  //	contractStub
   591  //	t *testing.T
   592  //}
   593  //
   594  //func (c *errorReceiverContract) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) {
   595  //	packet := msg.Packet
   596  //
   597  //	var src ibctransfertypes.FungibleTokenPacketData
   598  //	if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packet.Data, &src); err != nil {
   599  //		return nil, 0, err
   600  //	}
   601  //	require.NoError(c.t, src.ValidateBasic())
   602  //	return nil, 0, errors.New("error-testing")
   603  //}
   604  //
   605  //// simple helper struct that implements connection setup methods.
   606  //type contractStub struct{}
   607  //
   608  //func (s *contractStub) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) {
   609  //	return &wasmvmtypes.IBC3ChannelOpenResponse{}, 0, nil
   610  //}
   611  //
   612  //func (s *contractStub) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
   613  //	return &wasmvmtypes.IBCBasicResponse{}, 0, nil
   614  //}
   615  //
   616  //func (s *contractStub) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
   617  //	panic("implement me")
   618  //}
   619  //
   620  //func (s *contractStub) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) {
   621  //	panic("implement me")
   622  //}
   623  //
   624  //func (s *contractStub) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
   625  //	return &wasmvmtypes.IBCBasicResponse{}, 0, nil
   626  //}
   627  //
   628  //func (s *contractStub) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
   629  //	panic("implement me")
   630  //}
   631  //
   632  //func toIBCPacket(p wasmvmtypes.IBCPacket) channeltypes.Packet {
   633  //	var height clienttypes.Height
   634  //	if p.Timeout.Block != nil {
   635  //		height = clienttypes.NewHeight(p.Timeout.Block.Revision, p.Timeout.Block.Height)
   636  //	}
   637  //	return channeltypes.Packet{
   638  //		Sequence:           p.Sequence,
   639  //		SourcePort:         p.Src.PortID,
   640  //		SourceChannel:      p.Src.ChannelID,
   641  //		DestinationPort:    p.Dest.PortID,
   642  //		DestinationChannel: p.Dest.ChannelID,
   643  //		Data:               p.Data,
   644  //		TimeoutHeight:      height,
   645  //		TimeoutTimestamp:   p.Timeout.Timestamp,
   646  //	}
   647  //}