complete tests
This commit is contained in:
@@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@@ -256,44 +257,56 @@ func (k Keeper) Delegate(ctx sdk.Context, delegatorAddr sdk.AccAddress, bondAmt
|
||||
// unbond the the delegation return
|
||||
func (k Keeper) unbond(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddress,
|
||||
shares sdk.Dec) (amount sdk.Dec, err sdk.Error) {
|
||||
fmt.Println("wackydebugoutput unbond 0")
|
||||
|
||||
// check if delegation has any shares in it unbond
|
||||
delegation, found := k.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
if !found {
|
||||
fmt.Println("wackydebugoutput unbond 1")
|
||||
err = types.ErrNoDelegatorForAddress(k.Codespace())
|
||||
return
|
||||
}
|
||||
fmt.Println("wackydebugoutput unbond 2")
|
||||
|
||||
// retrieve the amount to remove
|
||||
if delegation.Shares.LT(shares) {
|
||||
fmt.Println("wackydebugoutput unbond 3")
|
||||
err = types.ErrNotEnoughDelegationShares(k.Codespace(), delegation.Shares.String())
|
||||
return
|
||||
}
|
||||
fmt.Println("wackydebugoutput unbond 4")
|
||||
|
||||
// get validator
|
||||
validator, found := k.GetValidator(ctx, validatorAddr)
|
||||
if !found {
|
||||
fmt.Println("wackydebugoutput unbond 5")
|
||||
err = types.ErrNoValidatorFound(k.Codespace())
|
||||
return
|
||||
}
|
||||
fmt.Println("wackydebugoutput unbond 6")
|
||||
|
||||
// subtract shares from delegator
|
||||
delegation.Shares = delegation.Shares.Sub(shares)
|
||||
|
||||
// remove the delegation
|
||||
if delegation.Shares.IsZero() {
|
||||
fmt.Println("wackydebugoutput unbond 7")
|
||||
|
||||
// if the delegation is the operator of the validator then
|
||||
// trigger a jail validator
|
||||
if bytes.Equal(delegation.DelegatorAddr, validator.Operator) && validator.Jailed == false {
|
||||
fmt.Println("wackydebugoutput unbond 8")
|
||||
validator.Jailed = true
|
||||
}
|
||||
fmt.Println("wackydebugoutput unbond 9")
|
||||
k.RemoveDelegation(ctx, delegation)
|
||||
} else {
|
||||
fmt.Println("wackydebugoutput unbond 10")
|
||||
// Update height
|
||||
delegation.Height = ctx.BlockHeight()
|
||||
k.SetDelegation(ctx, delegation)
|
||||
}
|
||||
fmt.Println("wackydebugoutput unbond 11")
|
||||
|
||||
// remove the coins from the validator
|
||||
pool := k.GetPool(ctx)
|
||||
@@ -303,9 +316,12 @@ func (k Keeper) unbond(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddr
|
||||
|
||||
// update then remove validator if necessary
|
||||
validator = k.UpdateValidator(ctx, validator)
|
||||
fmt.Printf("debug validator: %v\n", validator)
|
||||
if validator.DelegatorShares.IsZero() {
|
||||
fmt.Println("wackydebugoutput unbond 12")
|
||||
k.RemoveValidator(ctx, validator.Operator)
|
||||
}
|
||||
fmt.Println("wackydebugoutput unbond 13")
|
||||
|
||||
return
|
||||
}
|
||||
@@ -315,24 +331,25 @@ func (k Keeper) unbond(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddr
|
||||
// get info for begin functions: MinTime and CreationHeight
|
||||
func (k Keeper) getBeginInfo(ctx sdk.Context, params types.Params, validatorSrcAddr sdk.AccAddress) (
|
||||
minTime time.Time, height int64, completeNow bool) {
|
||||
fmt.Println("wackydebugoutput getBeginInfo 0")
|
||||
|
||||
validator, found := k.GetValidator(ctx, validatorSrcAddr)
|
||||
switch {
|
||||
case !found || validator.Status == sdk.Bonded:
|
||||
|
||||
// longest wait - just unbonding period from now
|
||||
// the longest wait - just unbonding period from now
|
||||
minTime = ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||
height = ctx.BlockHeader().Height
|
||||
return minTime, height, false
|
||||
|
||||
case validator.IsUnbonded(ctx):
|
||||
return minTime, height, true
|
||||
|
||||
case validator.Status == sdk.Unbonding:
|
||||
minTime = validator.UnbondingMinTime
|
||||
height = validator.UnbondingHeight
|
||||
return minTime, height, false
|
||||
|
||||
case validator.Status == sdk.Unbonded:
|
||||
return minTime, height, true
|
||||
|
||||
default:
|
||||
panic("unknown validator status")
|
||||
}
|
||||
@@ -403,27 +420,38 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delegatorAddr, validatorAddr
|
||||
// complete unbonding an unbonding record
|
||||
func (k Keeper) BeginRedelegation(ctx sdk.Context, delegatorAddr, validatorSrcAddr,
|
||||
validatorDstAddr sdk.AccAddress, sharesAmount sdk.Dec) sdk.Error {
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 0")
|
||||
|
||||
// check if this is a transitive redelegation
|
||||
if k.HasReceivingRedelegation(ctx, delegatorAddr, validatorSrcAddr) {
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 1")
|
||||
return types.ErrTransitiveRedelegation(k.Codespace())
|
||||
}
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 2")
|
||||
|
||||
returnAmount, err := k.unbond(ctx, delegatorAddr, validatorSrcAddr, sharesAmount)
|
||||
if err != nil {
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 3")
|
||||
return err
|
||||
}
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 4")
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
returnCoin := sdk.Coin{params.BondDenom, returnAmount.RoundInt()}
|
||||
fmt.Printf("debug returnCoin: %v\n", returnCoin)
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 5")
|
||||
dstValidator, found := k.GetValidator(ctx, validatorDstAddr)
|
||||
if !found {
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 6")
|
||||
return types.ErrBadRedelegationDst(k.Codespace())
|
||||
}
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 7")
|
||||
sharesCreated, err := k.Delegate(ctx, delegatorAddr, returnCoin, dstValidator, false)
|
||||
if err != nil {
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 8")
|
||||
return err
|
||||
}
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 9")
|
||||
|
||||
// create the unbonding delegation
|
||||
minTime := ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||
@@ -432,8 +460,10 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delegatorAddr, validatorSrcAd
|
||||
minTime, height, completeNow := k.getBeginInfo(ctx, params, validatorSrcAddr)
|
||||
|
||||
if completeNow { // no need to create the redelegation object
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 10")
|
||||
return nil
|
||||
}
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 11")
|
||||
|
||||
red := types.Redelegation{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
@@ -446,6 +476,7 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delegatorAddr, validatorSrcAd
|
||||
Balance: returnCoin,
|
||||
InitialBalance: returnCoin,
|
||||
}
|
||||
fmt.Println("wackydebugoutput BeginRedelegation 13")
|
||||
k.SetRedelegation(ctx, red)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -219,8 +219,6 @@ func TestUndelegateSelfDelegation(t *testing.T) {
|
||||
|
||||
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)
|
||||
}
|
||||
@@ -358,8 +356,8 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
||||
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)
|
||||
ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
||||
require.False(t, found, "%v", ubd)
|
||||
}
|
||||
|
||||
// Make sure that that the retrieving the delegations doesn't affect the state
|
||||
@@ -442,10 +440,203 @@ func TestRedelegation(t *testing.T) {
|
||||
require.False(t, found)
|
||||
}
|
||||
|
||||
func TestRedelegationFromUnbondingValidator(t *testing.T) {
|
||||
require.Fail(t, "")
|
||||
func TestRedelegateSelfDelegation(t *testing.T) {
|
||||
|
||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||
pool := keeper.GetPool(ctx)
|
||||
pool.LooseTokens = sdk.NewDec(30)
|
||||
|
||||
//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 validator
|
||||
validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{})
|
||||
validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||
keeper.SetPool(ctx, pool)
|
||||
validator2 = keeper.UpdateValidator(ctx, validator2)
|
||||
|
||||
// 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.BeginRedelegation(ctx, addrVals[0], addrVals[0], addrVals[1], sdk.NewDec(10))
|
||||
require.NoError(t, err)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(t, found)
|
||||
require.Equal(t, int64(10), validator.Tokens.RoundInt64())
|
||||
require.Equal(t, sdk.Unbonding, validator.Status)
|
||||
}
|
||||
|
||||
func TestRedelegationFromUnbondedValidator(t *testing.T) {
|
||||
func TestRedelegateFromUnbondingValidator(t *testing.T) {
|
||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||
pool := keeper.GetPool(ctx)
|
||||
pool.LooseTokens = sdk.NewDec(30)
|
||||
|
||||
//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)
|
||||
|
||||
// create a second validator
|
||||
validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{})
|
||||
validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||
keeper.SetPool(ctx, pool)
|
||||
validator2 = keeper.UpdateValidator(ctx, validator2)
|
||||
|
||||
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.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], sdk.NewDec(6))
|
||||
require.NoError(t, err)
|
||||
|
||||
// retrieve the unbonding delegation
|
||||
ubd, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
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 TestRedelegateFromUnbondedValidator(t *testing.T) {
|
||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||
pool := keeper.GetPool(ctx)
|
||||
pool.LooseTokens = sdk.NewDec(30)
|
||||
|
||||
//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)
|
||||
|
||||
// create a second validator
|
||||
validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{})
|
||||
validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||
keeper.SetPool(ctx, pool)
|
||||
validator2 = keeper.UpdateValidator(ctx, validator2)
|
||||
|
||||
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.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], sdk.NewDec(6))
|
||||
require.NoError(t, err)
|
||||
|
||||
// no ubd should have been found, coins should have been returned direcly to account
|
||||
ubd, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||
require.False(t, found, "%v", ubd)
|
||||
require.Fail(t, "")
|
||||
}
|
||||
|
||||
@@ -46,14 +46,9 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in
|
||||
return
|
||||
}
|
||||
|
||||
// slashing should not be slashing unbonded
|
||||
if validator.Status == sdk.Unbonded {
|
||||
// should not be slashing unbonded
|
||||
if validator.IsUnbonded(ctx) {
|
||||
panic(fmt.Sprintf("should not be slashing unbonded validator: %v", validator))
|
||||
} else if validator.Status == sdk.Unbonding {
|
||||
ctxTime := ctx.BlockHeader().Time
|
||||
if ctxTime.After(validator.UnbondingMinTime) {
|
||||
panic(fmt.Sprintf("should not be slashing unbonded validator: %v", validator))
|
||||
}
|
||||
}
|
||||
|
||||
operatorAddress := validator.GetOperator()
|
||||
|
||||
@@ -418,6 +418,19 @@ func (v Validator) BondedTokens() sdk.Dec {
|
||||
return sdk.ZeroDec()
|
||||
}
|
||||
|
||||
// Returns if the validator should be considered unbonded
|
||||
func (v Validator) IsUnbonded(ctx sdk.Context) bool {
|
||||
if v.Status == sdk.Unbonded {
|
||||
return true
|
||||
} else if v.Status == sdk.Unbonding {
|
||||
ctxTime := ctx.BlockHeader().Time
|
||||
if ctxTime.After(v.UnbondingMinTime) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//______________________________________________________________________
|
||||
|
||||
// ensure fulfills the sdk validator types
|
||||
|
||||
Reference in New Issue
Block a user