Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add update minCommissionRate to validators #1379

Merged
merged 12 commits into from
Sep 15, 2022
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"
"github.com/umee-network/umee/v3/app/upgrades"
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, updatiing minimum commission rate param of staking module",
toteki marked this conversation as resolved.
Show resolved Hide resolved
"name", UpgradeV3_0Plan)
minCommissionRate, err := upgrades.UpdateMinimumCommissionRateParam(ctx, app.StakingKeeper)
if err != nil {
return vm, sdkerrors.Wrapf(
err, "Calypso %q Upgrade: Unable to upgrade, failied to update minimum commission rate param of staking module",
toteki marked this conversation as resolved.
Show resolved Hide resolved
UpgradeV3_0Plan)
}

ctx.Logger().Info("Upgrade handler execution finished, updatiing minimum commission rate of all validators",
toteki marked this conversation as resolved.
Show resolved Hide resolved
"name", UpgradeV3_0Plan)
err = upgrades.SetMinimumCommissionRateToValidatros(ctx, app.StakingKeeper, minCommissionRate)
if err != nil {
return vm, sdkerrors.Wrapf(
err, "Calypso %q Upgrade: Unable to upgrade, failied to update minimum commission rate to validatos",
toteki marked this conversation as resolved.
Show resolved Hide resolved
UpgradeV3_0Plan)
}

return vm, err
})

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

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/min_commission.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package upgrades

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/min_commission_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package upgrades

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/test_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package upgrades
gsk967 marked this conversation as resolved.
Show resolved Hide resolved

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(),
}
}