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
384 lines
10 KiB
Go
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))
|
|
})
|
|
}
|
|
}
|