Skip to content

Commit

Permalink
Merge #2500: Block conflicting redelegations
Browse files Browse the repository at this point in the history
* Block conflicting redelegations

* Update PENDING.md

* Add conflicting redelegation testcase
  • Loading branch information
cwgoes authored and rigelrozanski committed Oct 16, 2018
1 parent 6164640 commit c0ce451
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ BREAKING CHANGES
* [x/staking] \#2236 more distribution hooks for distribution
* [x/stake] \#2394 Split up UpdateValidator into distinct state transitions applied only in EndBlock
* [x/stake] \#2412 Added an unbonding validator queue to EndBlock to automatically update validator.Status when finished Unbonding
* [x/stake] \#2500 Block conflicting redelegations until we add an index
* [x/params] Global Paramstore refactored

* Tendermint
Expand Down
42 changes: 42 additions & 0 deletions x/stake/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,48 @@ func TestTransitiveRedelegation(t *testing.T) {
require.True(t, got.IsOK(), "expected no error")
}

func TestConflictingRedelegation(t *testing.T) {
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
validatorAddr := sdk.ValAddress(keep.Addrs[0])
validatorAddr2 := sdk.ValAddress(keep.Addrs[1])

// set the unbonding time
params := keeper.GetParams(ctx)
params.UnbondingTime = 1
keeper.SetParams(ctx, params)

// create the validators
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")

msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 10)
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")

// end block to bond them
EndBlocker(ctx, keeper)

// begin redelegate
msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, sdk.NewDec(5))
got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
require.True(t, got.IsOK(), "expected no error, %v", got)

// cannot redelegate again while first redelegation still exists
got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
require.True(t, !got.IsOK(), "expected an error, msg: %v", msgBeginRedelegate)

// progress forward in time
ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(10 * time.Second))

// complete first redelegation
EndBlocker(ctx, keeper)

// now should be able to redelegate again
got = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
require.True(t, got.IsOK(), "expected no error")
}

func TestUnbondingWhenExcessValidators(t *testing.T) {
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
validatorAddr1 := sdk.ValAddress(keep.Addrs[0])
Expand Down
7 changes: 7 additions & 0 deletions x/stake/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,13 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd
func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress,
valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec) (types.Redelegation, sdk.Error) {

// check if there is already a redelgation in progress from src to dst
// TODO quick fix, instead we should use an index, see https://github.com/cosmos/cosmos-sdk/issues/1402
_, found := k.GetRedelegation(ctx, delAddr, valSrcAddr, valDstAddr)
if found {
return types.Redelegation{}, types.ErrConflictingRedelegation(k.Codespace())
}

// check if this is a transitive redelegation
if k.HasReceivingRedelegation(ctx, delAddr, valSrcAddr) {
return types.Redelegation{}, types.ErrTransitiveRedelegation(k.Codespace())
Expand Down
5 changes: 5 additions & 0 deletions x/stake/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ func ErrTransitiveRedelegation(codespace sdk.CodespaceType) sdk.Error {
"redelegation to this validator already in progress, first redelegation to this validator must complete before next redelegation")
}

func ErrConflictingRedelegation(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidDelegation,
"conflicting redelegation from this source validator to this dest validator already exists, you must wait for it to finish")
}

func ErrBothShareMsgsGiven(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidInput, "both shares amount and shares percent provided")
}
Expand Down

0 comments on commit c0ce451

Please sign in to comment.