Skip to content

Commit

Permalink
feat: add update minCommissionRate to validators (#1379)
Browse files Browse the repository at this point in the history
## Description
This pull request contains the update staking minimum commission rate to all the validators whose validator commission rate below the minimum commission rate 
closes: #1082 

---

### Author Checklist

_All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues._

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] added appropriate labels to the PR
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/umee-network/umee/blob/main/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

_All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items._

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
  • Loading branch information
gsk967 committed Sep 15, 2022
1 parent 970184f commit d9c8367
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- [1319](https://github.com/umee-network/umee/pull/1319) Implemented MaxSupply.
- [1331](https://github.com/umee-network/umee/pull/1331) Implemented MinCollateralLiquidity.
- [1343](https://github.com/umee-network/umee/pull/1343) RepayBadDebt and Liquidate automatically clear blacklisted collateral.
- [1379](https://github.com/umee-network/umee/pull/1379) Add `mininumCommissionRate` update to all validators.

### Improvements

Expand Down
26 changes: 25 additions & 1 deletion app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

bech32ibckeeper "github.com/osmosis-labs/bech32-ibc/x/bech32ibc/keeper"
bech32ibctypes "github.com/osmosis-labs/bech32-ibc/x/bech32ibc/types"
v3upgrades "github.com/umee-network/umee/v3/app/upgrades/v3"
leveragetypes "github.com/umee-network/umee/v3/x/leverage/types"
oracletypes "github.com/umee-network/umee/v3/x/oracle/types"
)
Expand All @@ -30,7 +31,30 @@ func (app UmeeApp) RegisterUpgradeHandlers() {
}

ctx.Logger().Info("Upgrade handler execution finished, running migrations", "name", UpgradeV3_0Plan)
return app.mm.RunMigrations(ctx, app.configurator, fromVM)
vm, err := app.mm.RunMigrations(ctx, app.configurator, fromVM)
if err != nil {
return vm, err
}

ctx.Logger().Info("Upgrade handler execution finished, updating minimum commission rate param of staking module",
"name", UpgradeV3_0Plan)
minCommissionRate, err := v3upgrades.UpdateMinimumCommissionRateParam(ctx, app.StakingKeeper)
if err != nil {
return vm, sdkerrors.Wrapf(
err, "Calypso %q Upgrade: Unable to upgrade, failed to update minimum commission rate param of staking module",
UpgradeV3_0Plan)
}

ctx.Logger().Info("Upgrade handler execution finished, updating minimum commission rate of all validators",
"name", UpgradeV3_0Plan)
err = v3upgrades.SetMinimumCommissionRateToValidatros(ctx, app.StakingKeeper, minCommissionRate)
if err != nil {
return vm, sdkerrors.Wrapf(
err, "Calypso %q Upgrade: Unable to upgrade, failed to update minimum commission rate for validators",
UpgradeV3_0Plan)
}

return vm, err
})

upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
Expand Down
15 changes: 15 additions & 0 deletions app/upgrades/v3/expected_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package v3

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

type StakingKeeper interface {
GetParams(ctx sdk.Context) types.Params
SetParams(ctx sdk.Context, params types.Params)
GetAllValidators(ctx sdk.Context) (validators []types.Validator)
BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error
SetValidator(ctx sdk.Context, validator types.Validator)
GetValidator(ctx sdk.Context, addr sdk.ValAddress) (types.Validator, bool)
}
42 changes: 42 additions & 0 deletions app/upgrades/v3/min_commission.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package v3

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var (
minCommissionRate = sdk.MustNewDecFromStr("0.05")
)

// UpdateMinimumCommissionRateParam is update the minimum commission rate param of staking.
func UpdateMinimumCommissionRateParam(ctx sdk.Context, keeper StakingKeeper) (sdk.Dec, error) {
params := keeper.GetParams(ctx)
// update the minCommissionRate param
params.MinCommissionRate = minCommissionRate

keeper.SetParams(ctx, params)

return minCommissionRate, nil
}

// SetMinimumCommissionRateToValidatros is update the minimum commission rate to the validators rate
// whose commission rate is below the minimum commission rate.
func SetMinimumCommissionRateToValidatros(
ctx sdk.Context, keeper StakingKeeper, minCommissionRate sdk.Dec) error {
validators := keeper.GetAllValidators(ctx)

for _, validator := range validators {
if validator.Commission.Rate.IsNil() || validator.Commission.Rate.LT(minCommissionRate) {
if err := keeper.BeforeValidatorModified(ctx, validator.GetOperator()); err != nil {
return err
}

validator.Commission.Rate = minCommissionRate
validator.Commission.UpdateTime = ctx.BlockTime()

keeper.SetValidator(ctx, validator)
}
}

return nil
}
51 changes: 51 additions & 0 deletions app/upgrades/v3/min_commission_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package v3

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)

func TestUpdateMinimumCommissionRateParam(t *testing.T) {
ctx := sdk.NewContext(nil, tmproto.Header{}, false, nil)
_, sk := GenerateRandomTestCase()

// check default min commission rate
oldParams := sk.GetParams(ctx)
require.Equal(t, types.DefaultMinCommissionRate, oldParams.MinCommissionRate)

// update the min commission rate
_, err := UpdateMinimumCommissionRateParam(ctx, &sk)
require.NoError(t, err)

// get the updated params
updatedParams := sk.GetParams(ctx)
require.Equal(t, minCommissionRate, updatedParams.MinCommissionRate)
}

func TestSetMinimumCommissionRateToValidatros(t *testing.T) {
ctx := sdk.NewContext(nil, tmproto.Header{}, false, nil)
valAddrs, sk := GenerateRandomTestCase()

// update the min commission rate
minCommissionRate, err := UpdateMinimumCommissionRateParam(ctx, &sk)
require.NoError(t, err)
require.NotNil(t, minCommissionRate)

// update min commisson rate to all validators
err = SetMinimumCommissionRateToValidatros(ctx, &sk, minCommissionRate)
require.NoError(t, err)

// get the validator
validator, found := sk.GetValidator(ctx, valAddrs[0])
require.True(t, found)
require.True(t, minCommissionRate.Equal(validator.Commission.Rate))

validator2, found := sk.GetValidator(ctx, valAddrs[1])
require.True(t, found)
// validator2 commission rate should be greater than minCommissionRate
require.True(t, minCommissionRate.LT(validator2.Commission.Rate))
}
106 changes: 106 additions & 0 deletions app/upgrades/v3/staking_util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package v3

import (
"crypto/rand"
"math/big"

"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

var (
_ StakingKeeper = &MockStakingKeeper{}
)

// MockStakingKeeper imlements the StakingKeeper interface.
type MockStakingKeeper struct {
validators []types.Validator
params types.Params
}

// GetValidator implements StakingKeeper
func (m *MockStakingKeeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (types.Validator, bool) {
var (
validator types.Validator
found bool
)

for _, v := range m.validators {
if v.GetOperator().Equals(addr) {
found = true
validator = v
break
}
}

return validator, found
}

// BeforeValidatorModified implements StakingKeeper
func (*MockStakingKeeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error {
return nil
}

// GetAllValidators implements StakingKeeper
func (m *MockStakingKeeper) GetAllValidators(ctx sdk.Context) (validators []types.Validator) {
return m.validators
}

// GetParams implements StakingKeeper
func (m *MockStakingKeeper) GetParams(ctx sdk.Context) types.Params {
return m.params
}

// SetParams implements StakingKeeper
func (m *MockStakingKeeper) SetParams(ctx sdk.Context, params types.Params) {
m.params = params
}

// SetValidator implements StakingKeeper
func (m *MockStakingKeeper) SetValidator(ctx sdk.Context, validator types.Validator) {
for index, v := range m.validators {
if v.GetOperator().Equals(validator.GetOperator()) {
m.validators[index] = validator
break
}
}
}

// GenerateRandomTestCase
func GenerateRandomTestCase() ([]sdk.ValAddress, MockStakingKeeper) {
mockValidators := []types.Validator{}

var valAddrs []sdk.ValAddress
randNum, _ := rand.Int(rand.Reader, big.NewInt(10000))
numInputs := 10 + int((randNum.Int64() % 100))
for i := 0; i < numInputs; i++ {
pubKey := secp256k1.GenPrivKey().PubKey()
valValAddr := sdk.ValAddress(pubKey.Address())
mockValidator, _ := types.NewValidator(valValAddr, pubKey, types.Description{})
mockValidators = append(mockValidators, mockValidator)
}

// adding 0.01 to first validator
val := mockValidators[0]
val.Commission.Rate = sdk.MustNewDecFromStr("0.01")
mockValidators[0] = val

// adding more then minimumCommissionRate to validator 2
val = mockValidators[1]
val.Commission.Rate = types.DefaultMinCommissionRate.Add(sdk.MustNewDecFromStr("1"))
mockValidators[1] = val

valAddrs = []sdk.ValAddress{mockValidators[0].GetOperator(), mockValidators[1].GetOperator()}

stakingKeeper := NewMockStakingKeeper(mockValidators)

return valAddrs, stakingKeeper
}

func NewMockStakingKeeper(validatros []types.Validator) MockStakingKeeper {
return MockStakingKeeper{
validators: validatros,
params: types.DefaultParams(),
}
}

0 comments on commit d9c8367

Please sign in to comment.