mukan-ibc/e2e/tests/upgrades/genesis_test.go
Mukan Erkin Törük 88dd97a9f8
Some checks failed
CodeQL / Analyze (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Has been cancelled
refactor: replace all github.com upstream refs with git.cw.tr/mukan-network
2026-05-11 03:36:22 +03:00

267 lines
9.3 KiB
Go

//go:build !test_e2e
package upgrades
import (
"context"
"testing"
"time"
"github.com/cosmos/gogoproto/proto"
"github.com/cosmos/interchaintest/v10"
"github.com/cosmos/interchaintest/v10/chain/cosmos"
"github.com/cosmos/interchaintest/v10/ibc"
test "github.com/cosmos/interchaintest/v10/testutil"
"github.com/stretchr/testify/suite"
"go.uber.org/zap"
sdkmath "cosmossdk.io/math"
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
banktypes "git.cw.tr/mukan-network/mukan-sdk/x/bank/types"
"github.com/cosmos/ibc-go/e2e/testsuite"
"github.com/cosmos/ibc-go/e2e/testsuite/query"
"github.com/cosmos/ibc-go/e2e/testvalues"
controllertypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/controller/types"
icatypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/types"
channeltypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/04-channel/types"
ibctesting "git.cw.tr/mukan-network/mukan-ibc/testing"
)
// compatibility:from_version: v8.7.0
func TestGenesisTestSuite(t *testing.T) {
suite.Run(t, new(GenesisTestSuite))
}
type GenesisTestSuite struct {
testsuite.E2ETestSuite
}
// SetupSuite sets up chains for the current test suite
func (s *GenesisTestSuite) SetupSuite() {
s.SetupChains(context.TODO(), 2, nil)
}
// TODO: this configuration was originally being applied to `GetChains` in the test body, but it is not
// actually being propagated correctly. If we want to apply the configuration, we can uncomment this code
// however the test actually fails when this is done.
// func (s *GenesisTestSuite) SetupSuite() {
// configFileOverrides := make(map[string]any)
// appTomlOverrides := make(test.Toml)
//
// appTomlOverrides["halt-height"] = haltHeight
// configFileOverrides["config/app.toml"] = appTomlOverrides
//
// s.SetupChains(context.TODO(), nil, func(options *testsuite.ChainOptions) {
// // create chains with specified chain configuration options
// options.ChainSpecs[0].ConfigFileOverrides = configFileOverrides
// })
// }
func (s *GenesisTestSuite) TestIBCGenesis() {
t := s.T()
haltHeight := int64(100)
chainA, chainB := s.GetChains()
ctx := context.Background()
testName := t.Name()
relayer := s.CreateDefaultPaths(testName)
channelA := s.GetChainAChannelForTest(testName)
var (
chainADenom = chainA.Config().Denom
chainBIBCToken = testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) // IBC token sent to chainB
)
chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)
chainAAddress := chainAWallet.FormattedAddress()
chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount)
chainBAddress := chainBWallet.FormattedAddress()
s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")
t.Run("ics20: native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) {
transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "")
s.AssertTxSuccess(transferTxResp)
})
t.Run("ics20: tokens are escrowed", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)
expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance)
})
// setup 2 accounts: controller account on chain A, a second chain B account.
// host account will be created when the ICA is registered
controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)
controllerAddress := controllerAccount.FormattedAddress()
chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount)
var hostAccount string
t.Run("ics27: broadcast MsgRegisterInterchainAccount", func(t *testing.T) {
// explicitly set the version string because we don't want to use incentivized channels.
version := icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID)
msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAddress, version, channeltypes.ORDERED)
txResp := s.BroadcastMessages(ctx, chainA, controllerAccount, msgRegisterAccount)
s.AssertTxSuccess(txResp)
})
t.Run("start relayer", func(t *testing.T) {
s.StartRelayer(relayer, testName)
})
t.Run("ics20: packets are relayed", func(t *testing.T) {
s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1)
actualBalance, err := query.Balance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom())
s.Require().NoError(err)
expected := testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance.Int64())
})
s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks")
t.Run("ics27: verify interchain account", func(t *testing.T) {
res, err := query.GRPCQuery[controllertypes.QueryInterchainAccountResponse](ctx, chainA, &controllertypes.QueryInterchainAccountRequest{
Owner: controllerAddress,
ConnectionId: ibctesting.FirstConnectionID,
})
s.Require().NoError(err)
s.Require().NotZero(len(res.Address))
hostAccount = res.Address
s.Require().NotEmpty(hostAccount)
channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID)
s.Require().NoError(err)
s.Require().Equal(len(channels), 2)
})
s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks")
t.Run("Halt chain and export genesis", func(t *testing.T) {
s.HaltChainAndExportGenesis(ctx, chainA.(*cosmos.CosmosChain), haltHeight)
})
t.Run("ics20: native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) {
transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "")
s.AssertTxSuccess(transferTxResp)
})
t.Run("ics20: tokens are escrowed", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)
expected := testvalues.StartingTokenAmount - 2*testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance)
})
t.Run("ics27: interchain account executes a bank transfer on behalf of the corresponding owner account", func(t *testing.T) {
t.Run("fund interchain account wallet", func(t *testing.T) {
// fund the host account so it has some $$ to send
err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{
Address: hostAccount,
Amount: sdkmath.NewInt(testvalues.StartingTokenAmount),
Denom: chainB.Config().Denom,
})
s.Require().NoError(err)
})
t.Run("broadcast MsgSendTx", func(t *testing.T) {
// assemble bank transfer message from host account to user account on host chain
msgSend := &banktypes.MsgSend{
FromAddress: hostAccount,
ToAddress: chainBAccount.FormattedAddress(),
Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)),
}
cdc := testsuite.Codec()
bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}, icatypes.EncodingProtobuf)
s.Require().NoError(err)
packetData := icatypes.InterchainAccountPacketData{
Type: icatypes.EXECUTE_TX,
Data: bz,
Memo: "e2e",
}
msgSendTx := controllertypes.NewMsgSendTx(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData)
resp := s.BroadcastMessages(
ctx,
chainA,
controllerAccount,
msgSendTx,
)
s.AssertTxSuccess(resp)
s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB))
})
})
s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks")
}
func (s *GenesisTestSuite) HaltChainAndExportGenesis(ctx context.Context, chain *cosmos.CosmosChain, haltHeight int64) {
timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Minute*2)
defer timeoutCtxCancel()
err := test.WaitForBlocks(timeoutCtx, int(haltHeight), chain)
s.Require().Error(err, "chain did not halt at halt height")
err = chain.StopAllNodes(ctx)
s.Require().NoError(err, "error stopping node(s)")
state, err := chain.ExportState(ctx, haltHeight)
s.Require().NoError(err)
appTomlOverrides := make(test.Toml)
appTomlOverrides["halt-height"] = 0
for _, node := range chain.Nodes() {
err := node.OverwriteGenesisFile(ctx, []byte(state))
s.Require().NoError(err)
}
for _, node := range chain.Nodes() {
err := test.ModifyTomlConfigFile(
ctx,
zap.NewExample(),
node.DockerClient,
node.TestName,
node.VolumeName,
"config/app.toml",
appTomlOverrides,
)
s.Require().NoError(err)
_, _, err = node.ExecBin(ctx, "comet", "unsafe-reset-all")
s.Require().NoError(err)
}
err = chain.StartAllNodes(ctx)
s.Require().NoError(err)
timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Minute*2)
defer timeoutCtxCancel()
err = test.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), chain)
s.Require().NoError(err, "chain did not produce blocks after halt")
height, err := chain.Height(ctx)
s.Require().NoError(err, "error fetching height after halt")
s.Require().Greater(height, haltHeight, "height did not increment after halt")
}