Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test: Add interchain test for ibc hooks #44

Merged
merged 5 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ test-system: install
ictest-basic:
cd tests/interchaintest && go test -race -v -run TestStartOrai .

# Executes basic chain tests via interchaintest
ictest-ibchooks:
cd tests/interchaintest && go test -race -v -run TestIbcHooks .

###############################################################################
### Linting ###
###############################################################################
Expand Down
Binary file added tests/interchaintest/bytecode/counter.wasm
Binary file not shown.
165 changes: 165 additions & 0 deletions tests/interchaintest/ibc_hooks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package interchaintest

import (
"context"
"fmt"
"testing"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"github.com/strangelove-ventures/interchaintest/v8/relayer"
"github.com/strangelove-ventures/interchaintest/v8/testreporter"
"github.com/strangelove-ventures/interchaintest/v8/testutil"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)

// TestStartOrai is a basic test to assert that spinning up a Orai network with 1 validator works properly.
func TestIbcHooks(t *testing.T) {
if testing.Short() {
t.Skip()
}

t.Parallel()

ctx := context.Background()

numVals := 1
numFullNodes := 1

cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{
{
Name: "orai",
ChainConfig: oraiConfig,
NumValidators: &numVals,
NumFullNodes: &numFullNodes,
},
{
Name: "gaia",
Version: GaiaImageVersion,
NumValidators: &numVals,
NumFullNodes: &numFullNodes,
},
})

// Get chains from the chain factory
chains, err := cf.Chains(t.Name())
require.NoError(t, err)

orai, gaia := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain)

// Create relayer factory to utilize the go-relayer
client, network := interchaintest.DockerSetup(t)
r := interchaintest.NewBuiltinRelayerFactory(
ibc.CosmosRly,
zaptest.NewLogger(t),
relayer.CustomDockerImage(IBCRelayerImage, IBCRelayerVersion, "100:1000"),
).Build(t, client, network)

ic := interchaintest.NewInterchain().
AddChain(orai).
AddChain(gaia).
AddRelayer(r, "rly").
AddLink(interchaintest.InterchainLink{
Chain1: orai,
Chain2: gaia,
Relayer: r,
Path: pathOraiGaia,
})

rep := testreporter.NewNopReporter()
eRep := rep.RelayerExecReporter(t)

err = ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{
TestName: t.Name(),
Client: client,
NetworkID: network,
SkipPathCreation: false,

// This can be used to write to the block database which will index all block data e.g. txs, msgs, events, etc.
// BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(),
})
require.NoError(t, err)

t.Cleanup(func() {
_ = ic.Close()
})

// Start the relayer
require.NoError(t, r.StartRelayer(ctx, eRep, pathOraiGaia))
t.Cleanup(
func() {
err := r.StopRelayer(ctx, eRep)
if err != nil {
panic(fmt.Errorf("an error occurred while stopping the relayer: %s", err))
}
},
)

channel, err := ibc.GetTransferChannel(ctx, r, eRep, orai.Config().ChainID, gaia.Config().ChainID)
require.NoError(t, err)

// Create some user accounts on both chains
users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), genesisWalletAmount, orai, gaia)

// Wait a few blocks for relayer to start and for user accounts to be created
err = testutil.WaitForBlocks(ctx, 5, orai, gaia)
require.NoError(t, err)

// Get our Bech32 encoded user addresses
oraiUser, gaiaUser := users[0], users[1]

oraiUserAddress := sdk.MustBech32ifyAddressBytes(orai.Config().Bech32Prefix, oraiUser.Address())
gaiaUserAddr := sdk.MustBech32ifyAddressBytes(gaia.Config().Bech32Prefix, gaiaUser.Address())

_ = oraiUserAddress
_ = gaiaUserAddr

// Store and instantiate contract on Orai chain
counterContractID, err := orai.StoreContract(ctx, oraiUser.KeyName(), "./bytecode/counter.wasm")
require.NoError(t, err)

initMsg := "{\"count\": 0}"
contractAddress, err := orai.InstantiateContract(ctx, oraiUser.KeyName(), counterContractID, initMsg, true)
require.NoError(t, err)

// Get stake denom on orai
gaiaDenom := transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, gaia.Config().Denom) //transfer/channel-0/uatom
gaiaIBCDenom := transfertypes.ParseDenomTrace(gaiaDenom).IBCDenom() // ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2

// check contract address balance
balances, err := orai.BankQueryBalance(ctx, contractAddress, gaiaIBCDenom)
require.NoError(t, err)
require.Equal(t, math.NewInt(0), balances)

// send ibc transaction to execite the contract
transfer := ibc.WalletAmount{
Address: contractAddress,
Denom: gaia.Config().Denom,
Amount: amountToSend,
}
memo := fmt.Sprintf("{\"wasm\":{\"contract\":\"%s\",\"msg\": {\"increment\": {}} }}", contractAddress)
transferTx, err := gaia.SendIBCTransfer(ctx, channel.Counterparty.ChannelID, gaiaUserAddr, transfer, ibc.TransferOptions{Memo: memo})
require.NoError(t, err)

// waiting for ACK -> transfer successfully
gaiaHeight, err := gaia.Height(ctx)
require.NoError(t, err)
_, err = testutil.PollForAck(ctx, gaia, gaiaHeight-5, gaiaHeight+25, transferTx.Packet)
require.NoError(t, err)

// check new balances
balances, err = orai.BankQueryBalance(ctx, contractAddress, gaiaIBCDenom)
require.NoError(t, err)
require.Equal(t, amountToSend, balances)

// check contract
var res GetCountResponse
err = orai.QueryContract(ctx, contractAddress, QueryMsg{GetCount: &GetCountQuery{}}, &res)
require.NoError(t, err)
require.Equal(t, uint64(1), res.Data.Count)
}
5 changes: 5 additions & 0 deletions tests/interchaintest/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ var (
}
genesisWalletAmount = math.NewInt(100_000_000_000)
amountToSend = math.NewInt(1_000_000_000)

pathOraiGaia = "orai-gaia"
)

// oraiEncoding registers the Orai specific module codecs so that the associated types and msgs
Expand Down Expand Up @@ -91,6 +93,9 @@ func modifyGenesisShortProposals(
if err := dyno.Set(g, votingPeriod, "app_state", "gov", "params", "voting_period"); err != nil {
return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err)
}
if err := dyno.Set(g, "1", "initial_height"); err != nil {
return nil, fmt.Errorf("failed to set initial height in genesis json: %w", err)
}
if err := dyno.Set(g, maxDepositPeriod, "app_state", "gov", "params", "max_deposit_period"); err != nil {
return nil, fmt.Errorf("failed to set voting period in genesis json: %w", err)
}
Expand Down
16 changes: 16 additions & 0 deletions tests/interchaintest/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package interchaintest

type QueryMsg struct {
// IBC Hooks
GetCount *GetCountQuery `json:"get_count,omitempty"`
}

type GetCountQuery struct{}

type GetCountResponse struct {
Data CountObj `json: "data"`
}

type CountObj struct {
Count uint64 `json:"count"`
}