Skip to content

Commit

Permalink
Add TestMsgCancelUnlocking, minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
iverc committed Dec 15, 2024
1 parent 2fad51c commit 6dfe0e5
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 7 deletions.
1 change: 1 addition & 0 deletions x/tier/keeper/lockup.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func (k Keeper) SetLockup(ctx context.Context, unlocking bool, delAddr sdk.AccAd
epochDuration := *params.EpochDuration

unlockTime := sdkCtx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs))
// use unbondTime from stakingKeeper.Undelegate() if present, set it to match unlockTime otherwise
var unbTime *time.Time
if unbondTime != nil {
utcTime := unbondTime.UTC()
Expand Down
181 changes: 181 additions & 0 deletions x/tier/keeper/msg_cancel_unlocking_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package keeper_test

import (
"testing"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/stretchr/testify/require"

appparams "github.com/sourcenetwork/sourcehub/app/params"
"github.com/sourcenetwork/sourcehub/x/tier/keeper"
"github.com/sourcenetwork/sourcehub/x/tier/types"
)

type TestCase struct {
name string
input *types.MsgCancelUnlocking
expErr bool
expErrMsg string
expectedAmount math.Int
}

func runMsgTestCase(t *testing.T, tc TestCase, k keeper.Keeper, ms types.MsgServer, initState func() sdk.Context, delAddress sdk.AccAddress, valAddress sdk.ValAddress) {
ctx := initState()

err := tc.input.ValidateBasic()
if err != nil {
if tc.expErr {
require.Contains(t, err.Error(), tc.expErrMsg)
return
}
t.Fatalf("unexpected error in ValidateBasic: %v", err)
}

resp, err := ms.CancelUnlocking(ctx, tc.input)

if tc.expErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expErrMsg)
} else {
require.NoError(t, err)
require.NotNil(t, resp, "Response should not be nil for valid cancel unlocking")

lockup := k.GetLockup(ctx, delAddress, valAddress)
require.NotNil(t, lockup, "Lockup should not be nil after cancel unlocking")
require.Equal(t, tc.expectedAmount, lockup.Amount, "Lockup amount should match expected after cancel unlocking")
}
}

func TestMsgCancelUnlocking(t *testing.T) {
k, ms, ctx := setupMsgServer(t)
sdkCtx := sdk.UnwrapSDKContext(ctx)

validCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100))
partialCancelCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(50))
excessCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(500))
zeroCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.ZeroInt())
negativeAmount := math.NewInt(-100)
initialDelegatorBalance := math.NewInt(2000)
initialValidatorBalance := math.NewInt(1000)

delAddr := "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9"
valAddr := "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm"

delAddress, err := sdk.AccAddressFromBech32(delAddr)
require.NoError(t, err)
valAddress, err := sdk.ValAddressFromBech32(valAddr)
require.NoError(t, err)

initState := func() sdk.Context {
ctx, _ := sdkCtx.CacheContext()
initializeDelegator(t, &k, ctx, delAddress, initialDelegatorBalance)
initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, valAddress, initialValidatorBalance)
err = k.Lock(ctx, delAddress, valAddress, validCoin.Amount)
require.NoError(t, err)
_, _, _, err = k.Unlock(ctx, delAddress, valAddress, validCoin.Amount)
require.NoError(t, err)
return ctx
}

testCases := []TestCase{
{
name: "invalid stake amount (zero)",
input: &types.MsgCancelUnlocking{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
CreationHeight: 1,
Stake: zeroCoin,
},
expErr: true,
expErrMsg: "invalid amount",
},
{
name: "invalid stake amount (negative)",
input: &types.MsgCancelUnlocking{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
CreationHeight: 1,
Stake: sdk.Coin{
Denom: appparams.DefaultBondDenom,
Amount: negativeAmount,
},
},
expErr: true,
expErrMsg: "invalid amount",
},
{
name: "non-existent unlocking",
input: &types.MsgCancelUnlocking{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
CreationHeight: 100,
Stake: validCoin,
},
expErr: true,
expErrMsg: "no unbonding delegation found",
},
{
name: "invalid delegator address",
input: &types.MsgCancelUnlocking{
DelegatorAddress: "invalid-address",
ValidatorAddress: valAddr,
CreationHeight: 1,
Stake: validCoin,
},
expErr: true,
expErrMsg: "delegator address",
},
{
name: "invalid validator address",
input: &types.MsgCancelUnlocking{
DelegatorAddress: delAddr,
ValidatorAddress: "invalid-validator-address",
CreationHeight: 1,
Stake: validCoin,
},
expErr: true,
expErrMsg: "validator address",
},
{
name: "valid cancel unlocking (partial)",
input: &types.MsgCancelUnlocking{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
CreationHeight: 1,
Stake: partialCancelCoin,
},
expErr: false,
expectedAmount: validCoin.Amount.Sub(partialCancelCoin.Amount),
},
{
name: "valid cancel unlocking (full)",
input: &types.MsgCancelUnlocking{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
CreationHeight: 1,
Stake: validCoin,
},
expErr: false,
expectedAmount: validCoin.Amount.Sub(math.OneInt()),
},
{
name: "excess unlocking amount",
input: &types.MsgCancelUnlocking{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
CreationHeight: 1,
Stake: excessCoin,
},
expErr: false,
expectedAmount: validCoin.Amount.Sub(math.OneInt()),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
runMsgTestCase(t, tc, k, ms, initState, delAddress, valAddress)
})
}
}
4 changes: 2 additions & 2 deletions x/tier/keeper/msg_lock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func TestMsgLock(t *testing.T) {
validCoin2 := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(3000))
zeroCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.ZeroInt())
negativeAmount := math.NewInt(-1000)
initialDelegatorBalance := math.NewInt(2000)
initialValidatorBalance := math.NewInt(1000)

delAddr := "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9"
valAddr := "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm"
Expand All @@ -29,9 +31,7 @@ func TestMsgLock(t *testing.T) {
valAddress, err := sdk.ValAddressFromBech32(valAddr)
require.NoError(t, err)

initialDelegatorBalance := math.NewInt(2000)
initializeDelegator(t, &k, sdkCtx, delAddress, initialDelegatorBalance)
initialValidatorBalance := math.NewInt(1000)
initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), sdkCtx, valAddress, initialValidatorBalance)

testCases := []struct {
Expand Down
6 changes: 3 additions & 3 deletions x/tier/keeper/msg_redelegate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ func TestMsgRedelegate(t *testing.T) {
validCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100))
zeroCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.ZeroInt())
negativeAmount := math.NewInt(-100)
initialDelegatorBalance := math.NewInt(2000)
initialSrcValidatorBalance := math.NewInt(1000)
initialDstValidatorBalance := math.NewInt(500)

delAddr := "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9"
srcValAddr := "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm"
Expand All @@ -32,10 +35,7 @@ func TestMsgRedelegate(t *testing.T) {
dstValAddress, err := sdk.ValAddressFromBech32(dstValAddr)
require.NoError(t, err)

initialDelegatorBalance := math.NewInt(2000)
initializeDelegator(t, &k, sdkCtx, delAddress, initialDelegatorBalance)
initialSrcValidatorBalance := math.NewInt(1000)
initialDstValidatorBalance := math.NewInt(500)
initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), sdkCtx, srcValAddress, initialSrcValidatorBalance)
initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), sdkCtx, dstValAddress, initialDstValidatorBalance)

Expand Down
4 changes: 2 additions & 2 deletions x/tier/keeper/msg_unlock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func TestMsgUnlock(t *testing.T) {
validCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100))
zeroCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.ZeroInt())
negativeAmount := math.NewInt(-100)
initialDelegatorBalance := math.NewInt(2000)
initialValidatorBalance := math.NewInt(1000)

delAddr := "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9"
valAddr := "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm"
Expand All @@ -29,9 +31,7 @@ func TestMsgUnlock(t *testing.T) {
valAddress, err := sdk.ValAddressFromBech32(valAddr)
require.NoError(t, err)

initialDelegatorBalance := math.NewInt(2000)
initializeDelegator(t, &k, sdkCtx, delAddress, initialDelegatorBalance)
initialValidatorBalance := math.NewInt(1000)
initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), sdkCtx, valAddress, initialValidatorBalance)

// lock some tokens to test the unlock logic
Expand Down

0 comments on commit 6dfe0e5

Please sign in to comment.