mukan-ibc/modules/apps/transfer/keeper/keeper_test.go
Mukan Erkin Törük 6852832fe8
Some checks failed
CodeQL / Analyze (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (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
Deploy to GitHub Pages / Deploy to GitHub Pages (push) Has been cancelled
Buf-Push / push (push) Has been cancelled
initial: sovereign Mukan Network fork
2026-05-11 03:18:28 +03:00

384 lines
10 KiB
Go

package keeper_test
import (
"errors"
"fmt"
"testing"
testifysuite "github.com/stretchr/testify/suite"
sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/ibc-go/v10/modules/apps/transfer/keeper"
"github.com/cosmos/ibc-go/v10/modules/apps/transfer/types"
channelkeeper "github.com/cosmos/ibc-go/v10/modules/core/04-channel/keeper"
ibctesting "github.com/cosmos/ibc-go/v10/testing"
)
type KeeperTestSuite struct {
testifysuite.Suite
coordinator *ibctesting.Coordinator
// testing chains used for convenience and readability
chainA *ibctesting.TestChain
chainB *ibctesting.TestChain
chainC *ibctesting.TestChain
}
func (suite *KeeperTestSuite) SetupTest() {
suite.coordinator = ibctesting.NewCoordinator(suite.T(), 3)
suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1))
suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2))
suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(3))
queryHelper := baseapp.NewQueryServerTestHelper(suite.chainA.GetContext(), suite.chainA.GetSimApp().InterfaceRegistry())
types.RegisterQueryServer(queryHelper, suite.chainA.GetSimApp().TransferKeeper)
}
func TestKeeperTestSuite(t *testing.T) {
testifysuite.Run(t, new(KeeperTestSuite))
}
func (suite *KeeperTestSuite) TestNewKeeper() {
testCases := []struct {
name string
instantiateFn func()
panicMsg string
}{
{"success", func() {
keeper.NewKeeper(
suite.chainA.GetSimApp().AppCodec(),
runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)),
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().MsgServiceRouter(),
suite.chainA.GetSimApp().AccountKeeper,
suite.chainA.GetSimApp().BankKeeper,
suite.chainA.GetSimApp().ICAControllerKeeper.GetAuthority(),
)
}, ""},
{"failure: transfer module account does not exist", func() {
keeper.NewKeeper(
suite.chainA.GetSimApp().AppCodec(),
runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)),
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().MsgServiceRouter(),
authkeeper.AccountKeeper{}, // empty account keeper
suite.chainA.GetSimApp().BankKeeper,
suite.chainA.GetSimApp().ICAControllerKeeper.GetAuthority(),
)
}, "the IBC transfer module account has not been set"},
{"failure: empty authority", func() {
keeper.NewKeeper(
suite.chainA.GetSimApp().AppCodec(),
runtime.NewKVStoreService(suite.chainA.GetSimApp().GetKey(types.StoreKey)),
suite.chainA.GetSimApp().GetSubspace(types.ModuleName),
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper,
suite.chainA.GetSimApp().MsgServiceRouter(),
suite.chainA.GetSimApp().AccountKeeper,
suite.chainA.GetSimApp().BankKeeper,
"", // authority
)
}, "authority must be non-empty"},
}
for _, tc := range testCases {
suite.SetupTest()
suite.Run(tc.name, func() {
if tc.panicMsg == "" {
suite.Require().NotPanics(
tc.instantiateFn,
)
} else {
suite.Require().PanicsWithError(
tc.panicMsg,
tc.instantiateFn,
)
}
})
}
}
func (suite *KeeperTestSuite) TestSetGetTotalEscrowForDenom() {
const denom = "atom"
var expAmount sdkmath.Int
testCases := []struct {
name string
malleate func()
expError error
}{
{
"success: with non-zero escrow amount",
func() {},
nil,
},
{
"success: with escrow amount > 2^63",
func() {
expAmount, _ = sdkmath.NewIntFromString("100000000000000000000")
},
nil,
},
{
"success: escrow amount 0 is not stored",
func() {
expAmount = sdkmath.ZeroInt()
},
nil,
},
{
"failure: setter panics with negative escrow amount",
func() {
expAmount = sdkmath.NewInt(-1)
},
errors.New("amount cannot be negative: -1"),
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest() // reset
expAmount = sdkmath.NewInt(100)
ctx := suite.chainA.GetContext()
tc.malleate()
coin := sdk.Coin{
Denom: denom,
Amount: expAmount,
}
if tc.expError == nil {
suite.chainA.GetSimApp().TransferKeeper.SetTotalEscrowForDenom(ctx, coin)
total := suite.chainA.GetSimApp().TransferKeeper.GetTotalEscrowForDenom(ctx, denom)
suite.Require().Equal(expAmount, total.Amount)
storeKey := suite.chainA.GetSimApp().GetKey(types.ModuleName)
store := ctx.KVStore(storeKey)
key := types.TotalEscrowForDenomKey(denom)
if expAmount.IsZero() {
suite.Require().False(store.Has(key))
} else {
suite.Require().True(store.Has(key))
}
} else {
suite.Require().PanicsWithError(tc.expError.Error(), func() {
suite.chainA.GetSimApp().TransferKeeper.SetTotalEscrowForDenom(ctx, coin)
})
total := suite.chainA.GetSimApp().TransferKeeper.GetTotalEscrowForDenom(ctx, denom)
suite.Require().Equal(sdkmath.ZeroInt(), total.Amount)
}
})
}
}
func (suite *KeeperTestSuite) TestGetAllDenomEscrows() {
var (
store storetypes.KVStore
cdc codec.Codec
expDenomEscrows sdk.Coins
)
testCases := []struct {
name string
malleate func()
expPass bool
}{
{
"success",
func() {
denom := "uatom" //nolint:goconst
amount := sdkmath.NewInt(100)
expDenomEscrows = append(expDenomEscrows, sdk.NewCoin(denom, amount))
bz := cdc.MustMarshal(&sdk.IntProto{Int: amount})
store.Set(types.TotalEscrowForDenomKey(denom), bz)
},
true,
},
{
"success: multiple denoms",
func() {
denom := "uatom"
amount := sdkmath.NewInt(100)
expDenomEscrows = append(expDenomEscrows, sdk.NewCoin(denom, amount))
bz := cdc.MustMarshal(&sdk.IntProto{Int: amount})
store.Set(types.TotalEscrowForDenomKey(denom), bz)
denom = "bar/foo"
amount = sdkmath.NewInt(50)
expDenomEscrows = append(expDenomEscrows, sdk.NewCoin(denom, amount))
bz = cdc.MustMarshal(&sdk.IntProto{Int: amount})
store.Set(types.TotalEscrowForDenomKey(denom), bz)
},
true,
},
{
"success: denom with non-alphanumeric characters",
func() {
denom := "ibc/123-456"
amount := sdkmath.NewInt(100)
expDenomEscrows = append(expDenomEscrows, sdk.NewCoin(denom, amount))
bz := cdc.MustMarshal(&sdk.IntProto{Int: amount})
store.Set(types.TotalEscrowForDenomKey(denom), bz)
},
true,
},
{
"failure: empty denom",
func() {
denom := ""
amount := sdkmath.ZeroInt()
bz := cdc.MustMarshal(&sdk.IntProto{Int: amount})
store.Set(types.TotalEscrowForDenomKey(denom), bz)
},
false,
},
{
"failure: wrong prefix key",
func() {
denom := "uatom"
amount := sdkmath.ZeroInt()
bz := cdc.MustMarshal(&sdk.IntProto{Int: amount})
store.Set(fmt.Appendf(nil, "wrong-prefix/%s", denom), bz)
},
false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest() // reset
expDenomEscrows = sdk.Coins{}
ctx := suite.chainA.GetContext()
storeKey := suite.chainA.GetSimApp().GetKey(types.ModuleName)
store = ctx.KVStore(storeKey)
cdc = suite.chainA.App.AppCodec()
tc.malleate()
denomEscrows := suite.chainA.GetSimApp().TransferKeeper.GetAllTotalEscrowed(ctx)
if tc.expPass {
suite.Require().Len(expDenomEscrows, len(denomEscrows))
suite.Require().ElementsMatch(expDenomEscrows, denomEscrows)
} else {
suite.Require().Empty(denomEscrows)
}
})
}
}
func (suite *KeeperTestSuite) TestParams() {
testCases := []struct {
name string
input types.Params
panicMsg string
}{
// it is not possible to set invalid booleans
{"success: set params false-false", types.NewParams(false, false), ""},
{"success: set params false-true", types.NewParams(false, true), ""},
{"success: set params true-false", types.NewParams(true, false), ""},
{"success: set params true-true", types.NewParams(true, true), ""},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest() // reset
ctx := suite.chainA.GetContext()
if tc.panicMsg == "" {
suite.chainA.GetSimApp().TransferKeeper.SetParams(ctx, tc.input)
expected := tc.input
p := suite.chainA.GetSimApp().TransferKeeper.GetParams(ctx)
suite.Require().Equal(expected, p)
} else {
suite.Require().PanicsWithError(tc.panicMsg, func() {
suite.chainA.GetSimApp().TransferKeeper.SetParams(ctx, tc.input)
})
}
})
}
}
func (suite *KeeperTestSuite) TestUnsetParams() {
suite.SetupTest()
ctx := suite.chainA.GetContext()
store := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetKey(types.ModuleName))
store.Delete([]byte(types.ParamsKey))
suite.Require().Panics(func() {
suite.chainA.GetSimApp().TransferKeeper.GetParams(ctx)
})
}
func (suite *KeeperTestSuite) TestWithICS4Wrapper() {
suite.SetupTest()
// test if the ics4 wrapper is the channel keeper initially
ics4Wrapper := suite.chainA.GetSimApp().TransferKeeper.GetICS4Wrapper()
_, isChannelKeeper := ics4Wrapper.(*channelkeeper.Keeper)
suite.Require().True(isChannelKeeper)
suite.Require().IsType((*channelkeeper.Keeper)(nil), ics4Wrapper)
// set the ics4 wrapper to the channel keeper
suite.chainA.GetSimApp().TransferKeeper.WithICS4Wrapper(nil)
ics4Wrapper = suite.chainA.GetSimApp().TransferKeeper.GetICS4Wrapper()
suite.Require().Nil(ics4Wrapper)
}
func (suite *KeeperTestSuite) TestIsBlockedAddr() {
suite.SetupTest()
testCases := []struct {
name string
addr sdk.AccAddress
expBlock bool
}{
{
"transfer module account address",
suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(types.ModuleName),
false,
},
{
"regular address",
suite.chainA.SenderAccount.GetAddress(),
false,
},
{
"blocked address",
suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(minttypes.ModuleName),
true,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.Require().Equal(tc.expBlock, suite.chainA.GetSimApp().TransferKeeper.IsBlockedAddr(tc.addr))
})
}
}