diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index df324beab4..add16fb52c 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -162,9 +163,7 @@ func TestUnbondDelegation(t *testing.T) { } keeper.SetDelegation(ctx, delegation) - var err error - var amount sdk.Dec - amount, err = keeper.unbond(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) + amount, err := keeper.unbond(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) require.NoError(t, err) require.Equal(t, int64(6), amount.RoundInt64()) // shares to be added to an unbonding delegation / redelegation @@ -180,12 +179,187 @@ func TestUnbondDelegation(t *testing.T) { require.Equal(t, int64(4), pool.BondedTokens.RoundInt64()) } +// test removing all self delegation from a validator which should +// shift it from the bonded to unbonded state +func TestUndelegateSelfDelegation(t *testing.T) { + + ctx, _, keeper := CreateTestInput(t, false, 0) + pool := keeper.GetPool(ctx) + pool.LooseTokens = sdk.NewDec(20) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) + require.Equal(t, int64(10), issuedShares.RoundInt64()) + keeper.SetPool(ctx, pool) + validator = keeper.UpdateValidator(ctx, validator) + pool = keeper.GetPool(ctx) + selfDelegation := types.Delegation{ + DelegatorAddr: addrVals[0], + ValidatorAddr: addrVals[0], + Shares: issuedShares, + } + keeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) + require.Equal(t, int64(10), issuedShares.RoundInt64()) + keeper.SetPool(ctx, pool) + validator = keeper.UpdateValidator(ctx, validator) + pool = keeper.GetPool(ctx) + delegation := types.Delegation{ + DelegatorAddr: addrDels[0], + ValidatorAddr: addrVals[0], + Shares: issuedShares, + } + keeper.SetDelegation(ctx, delegation) + + err := keeper.BeginUnbonding(ctx, addrVals[0], addrVals[0], sdk.NewDec(10)) + require.NoError(t, err) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + pool = keeper.GetPool(ctx) + + require.Equal(t, int64(10), validator.Tokens.RoundInt64()) + require.Equal(t, sdk.Unbonding, validator.Status) +} + func TestUndelegateFromUnbondingValidator(t *testing.T) { - require.Fail(t) + ctx, _, keeper := CreateTestInput(t, false, 0) + pool := keeper.GetPool(ctx) + pool.LooseTokens = sdk.NewDec(20) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) + require.Equal(t, int64(10), issuedShares.RoundInt64()) + keeper.SetPool(ctx, pool) + validator = keeper.UpdateValidator(ctx, validator) + pool = keeper.GetPool(ctx) + selfDelegation := types.Delegation{ + DelegatorAddr: addrVals[0], + ValidatorAddr: addrVals[0], + Shares: issuedShares, + } + keeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) + require.Equal(t, int64(10), issuedShares.RoundInt64()) + keeper.SetPool(ctx, pool) + validator = keeper.UpdateValidator(ctx, validator) + pool = keeper.GetPool(ctx) + delegation := types.Delegation{ + DelegatorAddr: addrDels[0], + ValidatorAddr: addrVals[0], + Shares: issuedShares, + } + keeper.SetDelegation(ctx, delegation) + + header := ctx.BlockHeader() + blockHeight := int64(10) + header.Height = blockHeight + blockTime := time.Unix(333, 0) + header.Time = blockTime + ctx = ctx.WithBlockHeader(header) + + // unbond the all self-delegation to put validator in unbonding state + err := keeper.BeginUnbonding(ctx, addrVals[0], addrVals[0], sdk.NewDec(10)) + require.NoError(t, err) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, blockHeight, validator.UnbondingHeight) + params := keeper.GetParams(ctx) + require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingMinTime)) + + //change the context + header = ctx.BlockHeader() + blockHeight2 := int64(20) + header.Height = blockHeight2 + blockTime2 := time.Unix(444, 0) + header.Time = blockTime2 + ctx = ctx.WithBlockHeader(header) + + // unbond some of the other delegation's shares + err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) + require.NoError(t, err) + + // retrieve the unbonding delegation + ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.True(t, ubd.Balance.IsEqual(sdk.NewInt64Coin(params.BondDenom, 6))) + assert.Equal(t, blockHeight, ubd.CreationHeight) + assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.MinTime)) } func TestUndelegateFromUnbondedValidator(t *testing.T) { - require.Fail(t) + ctx, _, keeper := CreateTestInput(t, false, 0) + pool := keeper.GetPool(ctx) + pool.LooseTokens = sdk.NewDec(20) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) + require.Equal(t, int64(10), issuedShares.RoundInt64()) + keeper.SetPool(ctx, pool) + validator = keeper.UpdateValidator(ctx, validator) + pool = keeper.GetPool(ctx) + selfDelegation := types.Delegation{ + DelegatorAddr: addrVals[0], + ValidatorAddr: addrVals[0], + Shares: issuedShares, + } + keeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) + require.Equal(t, int64(10), issuedShares.RoundInt64()) + keeper.SetPool(ctx, pool) + validator = keeper.UpdateValidator(ctx, validator) + pool = keeper.GetPool(ctx) + delegation := types.Delegation{ + DelegatorAddr: addrDels[0], + ValidatorAddr: addrVals[0], + Shares: issuedShares, + } + keeper.SetDelegation(ctx, delegation) + + header := ctx.BlockHeader() + blockHeight := int64(10) + header.Height = blockHeight + blockTime := time.Unix(333, 0) + header.Time = blockTime + ctx = ctx.WithBlockHeader(header) + + // unbond the all self-delegation to put validator in unbonding state + err := keeper.BeginUnbonding(ctx, addrVals[0], addrVals[0], sdk.NewDec(10)) + require.NoError(t, err) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, blockHeight, validator.UnbondingHeight) + params := keeper.GetParams(ctx) + require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingMinTime)) + + // change the context to one which makes the validator considered unbonded + header = ctx.BlockHeader() + blockHeight2 := int64(20) + header.Height = blockHeight2 + blockTime2 := time.Unix(444, 0).Add(params.UnbondingTime) + header.Time = blockTime2 + ctx = ctx.WithBlockHeader(header) + + // unbond some of the other delegation's shares + err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) + require.NoError(t, err) + + // no ubd should have been found, coins should have been returned direcly to account + _, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.False(t, found) } // Make sure that that the retrieving the delegations doesn't affect the state @@ -269,9 +443,9 @@ func TestRedelegation(t *testing.T) { } func TestRedelegationFromUnbondingValidator(t *testing.T) { - require.Fail(t) + require.Fail(t, "") } func TestRedelegationFromUnbondedValidator(t *testing.T) { - require.Fail(t) + require.Fail(t, "") } diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index c53d4e1ec2..65bac2d808 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -206,16 +206,6 @@ func TestSlashValidatorAtCurrentHeight(t *testing.T) { require.Equal(t, sdk.NewDec(5).RoundInt64(), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64()) } -// slash an unbonding validator -func TestSlashUnbondingValidator(t *testing.T) { - require.Fail(t) -} - -// fail an attept to slash an unbonded validator -func TestSlashUnbondedValidator(t *testing.T) { - require.Fail(t) -} - // tests Slash at a previous height with an unbonding delegation func TestSlashWithUnbondingDelegation(t *testing.T) { ctx, keeper, params := setupHelper(t, 10)