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

     1  package wasm_test
     2  
     3  //import (
     4  //	"testing"
     5  //
     6  //	"github.com/stretchr/testify/assert"
     7  //
     8  //	channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
     9  //	ibctesting "github.com/cosmos/ibc-go/v3/testing"
    10  //
    11  //	wasmvmtypes "github.com/CosmWasm/wasmvm/types"
    12  //	"github.com/stretchr/testify/require"
    13  //
    14  //	wasmibctesting "github.com/fibonacci-chain/fbc/x/wasm/ibctesting"
    15  //	wasmkeeper "github.com/fibonacci-chain/fbc/x/wasm/keeper"
    16  //)
    17  //
    18  //func TestIBCReflectContract(t *testing.T) {
    19  //	// scenario:
    20  //	//  chain A: ibc_reflect_send.wasm
    21  //	//  chain B: reflect.wasm + ibc_reflect.wasm
    22  //	//
    23  //	//  Chain A "ibc_reflect_send" sends a IBC packet "on channel connect" event to chain B "ibc_reflect"
    24  //	//  "ibc_reflect" sends a submessage to "reflect" which is returned as submessage.
    25  //
    26  //	var (
    27  //		coordinator = wasmibctesting.NewCoordinator(t, 2)
    28  //		chainA      = coordinator.GetChain(wasmibctesting.GetChainID(0))
    29  //		chainB      = coordinator.GetChain(wasmibctesting.GetChainID(1))
    30  //	)
    31  //	coordinator.CommitBlock(chainA, chainB)
    32  //
    33  //	initMsg := []byte(`{}`)
    34  //	codeID := chainA.StoreCodeFile("./keeper/testdata/ibc_reflect_send.wasm").CodeID
    35  //	sendContractAddr := chainA.InstantiateContract(codeID, initMsg)
    36  //
    37  //	reflectID := chainB.StoreCodeFile("./keeper/testdata/reflect.wasm").CodeID
    38  //	initMsg = wasmkeeper.IBCReflectInitMsg{
    39  //		ReflectCodeID: reflectID,
    40  //	}.GetBytes(t)
    41  //	codeID = chainB.StoreCodeFile("./keeper/testdata/ibc_reflect.wasm").CodeID
    42  //
    43  //	reflectContractAddr := chainB.InstantiateContract(codeID, initMsg)
    44  //	var (
    45  //		sourcePortID      = chainA.ContractInfo(sendContractAddr).IBCPortID
    46  //		counterpartPortID = chainB.ContractInfo(reflectContractAddr).IBCPortID
    47  //	)
    48  //	coordinator.CommitBlock(chainA, chainB)
    49  //	coordinator.UpdateTime()
    50  //
    51  //	require.Equal(t, chainA.CurrentHeader.Time, chainB.CurrentHeader.Time)
    52  //	path := wasmibctesting.NewPath(chainA, chainB)
    53  //	path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
    54  //		PortID:  sourcePortID,
    55  //		Version: "ibc-reflect-v1",
    56  //		Order:   channeltypes.ORDERED,
    57  //	}
    58  //	path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
    59  //		PortID:  counterpartPortID,
    60  //		Version: "ibc-reflect-v1",
    61  //		Order:   channeltypes.ORDERED,
    62  //	}
    63  //
    64  //	coordinator.SetupConnections(path)
    65  //	coordinator.CreateChannels(path)
    66  //
    67  //	// TODO: query both contracts directly to ensure they have registered the proper connection
    68  //	// (and the chainB has created a reflect contract)
    69  //
    70  //	// there should be one packet to relay back and forth (whoami)
    71  //	// TODO: how do I find the packet that was previously sent by the smart contract?
    72  //	// Coordinator.RecvPacket requires channeltypes.Packet as input?
    73  //	// Given the source (portID, channelID), we should be able to count how many packets are pending, query the data
    74  //	// and submit them to the other side (same with acks). This is what the real relayer does. I guess the test framework doesn't?
    75  //
    76  //	// Update: I dug through the code, especially channel.Keeper.SendPacket, and it only writes a commitment
    77  //	// only writes I see: https://github.com/fibonacci-chain/fbc/libs/cosmos-sdk/blob/31fdee0228bd6f3e787489c8e4434aabc8facb7d/x/ibc/core/04-channel/keeper/packet.go#L115-L116
    78  //	// commitment is hashed packet: https://github.com/fibonacci-chain/fbc/libs/cosmos-sdk/blob/31fdee0228bd6f3e787489c8e4434aabc8facb7d/x/ibc/core/04-channel/types/packet.go#L14-L34
    79  //	// how is the relayer supposed to get the original packet data??
    80  //	// eg. ibctransfer doesn't store the packet either: https://github.com/fibonacci-chain/fbc/libs/cosmos-sdk/blob/master/x/ibc/applications/transfer/keeper/relay.go#L145-L162
    81  //	// ... or I guess the original packet data is only available in the event logs????
    82  //	// https://github.com/fibonacci-chain/fbc/libs/cosmos-sdk/blob/31fdee0228bd6f3e787489c8e4434aabc8facb7d/x/ibc/core/04-channel/keeper/packet.go#L121-L132
    83  //
    84  //	// ensure the expected packet was prepared, and relay it
    85  //	require.Equal(t, 1, len(chainA.PendingSendPackets))
    86  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
    87  //	err := coordinator.RelayAndAckPendingPackets(path)
    88  //	require.NoError(t, err)
    89  //	require.Equal(t, 0, len(chainA.PendingSendPackets))
    90  //	require.Equal(t, 0, len(chainB.PendingSendPackets))
    91  //
    92  //	// let's query the source contract and make sure it registered an address
    93  //	query := ReflectSendQueryMsg{Account: &AccountQuery{ChannelID: path.EndpointA.ChannelID}}
    94  //	var account AccountResponse
    95  //	err = chainA.SmartQuery(sendContractAddr.String(), query, &account)
    96  //	require.NoError(t, err)
    97  //	require.NotEmpty(t, account.RemoteAddr)
    98  //	require.Empty(t, account.RemoteBalance)
    99  //
   100  //	// close channel
   101  //	coordinator.CloseChannel(path)
   102  //
   103  //	// let's query the source contract and make sure it registered an address
   104  //	account = AccountResponse{}
   105  //	err = chainA.SmartQuery(sendContractAddr.String(), query, &account)
   106  //	require.Error(t, err)
   107  //	assert.Contains(t, err.Error(), "not found")
   108  //}
   109  //
   110  //type ReflectSendQueryMsg struct {
   111  //	Admin        *struct{}     `json:"admin,omitempty"`
   112  //	ListAccounts *struct{}     `json:"list_accounts,omitempty"`
   113  //	Account      *AccountQuery `json:"account,omitempty"`
   114  //}
   115  //
   116  //type AccountQuery struct {
   117  //	ChannelID string `json:"channel_id"`
   118  //}
   119  //
   120  //type AccountResponse struct {
   121  //	LastUpdateTime uint64            `json:"last_update_time,string"`
   122  //	RemoteAddr     string            `json:"remote_addr"`
   123  //	RemoteBalance  wasmvmtypes.Coins `json:"remote_balance"`
   124  //}