Merge #2500: Block conflicting redelegations
* Block conflicting redelegations * Update PENDING.md * Add conflicting redelegation testcase
This commit is contained in:
parent
6164640ffd
commit
c0ce451003
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue