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
267 lines
9.3 KiB
Go
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")
|
|
}
|