diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d7328ca8f50..cfad9ecfd0ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 0.35.0 + +### Bug Fixes + +#### SDK + +* Fix for the `x/staking` module security advisory for downstream consumers of the +SDK. This fix was introduced in v0.34.6 for the Cosmos Hub. + +## 0.34.7 + +### Bug Fixes + +#### SDK + +* Fix gas consumption bug in `Undelegate` preventing the ability to sync from +genesis. + ## 0.34.6 ### Bug Fixes diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 61b69d3ee5f2..14759e5828de 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -804,67 +804,6 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { require.False(t, found, "unbonding object should not exist") } -func TestUnbondingFork(t *testing.T) { - ctx, _, keeper := keep.CreateTestInput(t, false, 1000) - validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] - - // create the validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // bond a delegator - msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected ok, got %v", got) - - // unbond the delegator from the validator - unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) - msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) - require.True(t, got.IsOK(), "expected no error") - - EndBlocker(ctx, keeper) - - // validate the unbonding object does not exist as it was never created - _, found := keeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) - require.False(t, found, "unbonding object should not exist") - - // reproduce same sequence except past fork height - ctx, _, keeper = keep.CreateTestInput(t, false, 1000) - validatorAddr, delegatorAddr = sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] - ctx = ctx.WithBlockHeight(keep.UndelegatePatchHeight) - - // create the validator - msgCreateValidator = NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // bond a delegator - msgDelegate = NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) - got = handleMsgDelegate(ctx, msgDelegate, keeper) - require.True(t, got.IsOK(), "expected ok, got %v", got) - - // unbond the delegator from the validator - msgUndelegateDelegator = NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) - got = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper) - require.True(t, got.IsOK(), "expected no error") - - EndBlocker(ctx, keeper) - - // validate the unbonding object exists prior to the unbonding period expiring - _, found = keeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) - require.True(t, found, "unbonding object should exist") - - // move to past unbonding period - ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(keeper.UnbondingTime(ctx))) - EndBlocker(ctx, keeper) - - // validate the unbonding object no longer exists as the unbonding period has expired - _, found = keeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) - require.False(t, found, "unbonding object should not exist") -} - func TestRedelegationPeriod(t *testing.T) { ctx, AccMapper, keeper := keep.CreateTestInput(t, false, 1000) validatorAddr, validatorAddr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 9559398923db..5ef10f6f45b8 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -9,10 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// UndelegatePatchHeight reflects the height at which to switch to the -// undelegating patch. -const UndelegatePatchHeight = 482100 - // return a specific delegation func (k Keeper) GetDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) ( @@ -586,41 +582,6 @@ func (k Keeper) Undelegate( ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec, ) (time.Time, sdk.Error) { - // Undelegating must obey the unbonding period regardless of the validator's - // status for safety. Block heights prior to undelegatePatchHeight allowed - // delegates to unbond from an unbonded validator immediately. - if ctx.BlockHeight() < UndelegatePatchHeight { - completionTime, height, completeNow := k.getBeginInfo(ctx, valAddr) - - returnAmount, err := k.unbond(ctx, delAddr, valAddr, sharesAmount) - if err != nil { - return completionTime, err - } - - // no need to create the ubd object just complete now - if completeNow { - balance := sdk.NewCoin(k.BondDenom(ctx), returnAmount) - - // track undelegation only when remaining or truncated shares are non-zero - if !balance.IsZero() { - if _, err := k.bankKeeper.UndelegateCoins(ctx, delAddr, sdk.Coins{balance}); err != nil { - return completionTime, err - } - } - - return completionTime, nil - } - - if k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) { - return time.Time{}, types.ErrMaxUnbondingDelegationEntries(k.Codespace()) - } - - ubd := k.SetUnbondingDelegationEntry(ctx, delAddr, valAddr, height, completionTime, returnAmount) - k.InsertUBDQueue(ctx, ubd, completionTime) - - return completionTime, nil - } - returnAmount, err := k.unbond(ctx, delAddr, valAddr, sharesAmount) if err != nil { return time.Time{}, err