Skip to content

Commit

Permalink
Merge pull request #157 from decentrio/fix-min-commission
Browse files Browse the repository at this point in the history
!chore: write upgrade handler for new minimum commission rate
  • Loading branch information
jiujiteiro authored Jun 26, 2024
2 parents 7fd9755 + 385aa91 commit c1454d9
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 11 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ Ref: https://keepachangelog.com/en/1.0.0/

# Changelog

## [Unreleased]

### Improvements

- (chore) [#157](https://github.com/realiotech/realio-network/pull/157): update the validators' commissions if their commissions are less than 5%

## [v0.9.0] - 2024-03-27

Expand Down
2 changes: 1 addition & 1 deletion app/ante/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (suite *AnteTestSuite) SetupTest() {
consAddress := sdk.ConsAddress(privCons.PubKey().Address())

isCheckTx := false
suite.app = app.Setup(isCheckTx, feemarkettypes.DefaultGenesisState())
suite.app = app.Setup(isCheckTx, feemarkettypes.DefaultGenesisState(), 1)
suite.Require().NotNil(suite.app.AppCodec())

suite.ctx = suite.app.BaseApp.NewContext(isCheckTx, tmproto.Header{
Expand Down
2 changes: 1 addition & 1 deletion app/fork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func TestFork(t *testing.T) {
realio := Setup(false, nil)
realio := Setup(false, nil, 1)

ctx := realio.BaseApp.NewContext(false, tmproto.Header{Height: ForkHeight})
stakingKeeper := realio.StakingKeeper
Expand Down
20 changes: 15 additions & 5 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,11 @@ func init() {
func Setup(
isCheckTx bool,
feemarketGenesis *feemarkettypes.GenesisState,
numberVals int,
) *RealioNetwork {
privVal := mock.NewPV()
pubKey, _ := privVal.GetPubKey()
encCdc := MakeEncodingConfig()

// create validator set with single validator
validator := tmtypes.NewValidator(pubKey, 1)
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
valSet := GenValSet(numberVals)

// generate genesis account
senderPrivKey := secp256k1.GenPrivKey()
Expand Down Expand Up @@ -242,3 +239,16 @@ func SetupTestingApp() (ibctesting.TestingApp, map[string]json.RawMessage) {
app := New(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, cfg, simapp.EmptyAppOptions{})
return app, simapp.NewDefaultGenesisState(cfg.Codec)
}

func GenValSet(nums int) *tmtypes.ValidatorSet {
vals := []*tmtypes.Validator{}

for i := 0; i < nums; i++ {
privVal := mock.NewPV()
pubKey, _ := privVal.GetPubKey()
vals = append(vals, tmtypes.NewValidator(pubKey, 1))
}
valSet := tmtypes.NewValidatorSet(vals)

return valSet
}
10 changes: 10 additions & 0 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
servertypes "github.com/cosmos/cosmos-sdk/server/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
multistakingtypes "github.com/realio-tech/multi-staking-module/x/multi-staking/types"
"github.com/realiotech/realio-network/app/upgrades/commission"
multistaking "github.com/realiotech/realio-network/app/upgrades/multi-staking"

upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
Expand All @@ -24,6 +25,15 @@ func (app *RealioNetwork) setupUpgradeHandlers(appOpts servertypes.AppOptions) {
),
)

app.UpgradeKeeper.SetUpgradeHandler(
commission.UpgradeName,
commission.CreateUpgradeHandler(
app.mm,
app.configurator,
&app.StakingKeeper,
),
)

upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(fmt.Errorf("failed to read upgrade info from disk: %w", err))
Expand Down
7 changes: 7 additions & 0 deletions app/upgrades/commission/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package commission

const (
// UpgradeName defines the on-chain upgrade name.
UpgradeName = "Commission"
NewMinCommisionRate = "0.05"
)
64 changes: 64 additions & 0 deletions app/upgrades/commission/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package commission

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
sk *stakingkeeper.Keeper,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
ctx.Logger().Info("Starting upgrade for multi staking...")
fixMinCommisionRate(ctx, sk)
return mm.RunMigrations(ctx, configurator, vm)
}
}

func fixMinCommisionRate(ctx sdk.Context, staking *stakingkeeper.Keeper) {
// Upgrade every validators min-commission rate
validators := staking.GetAllValidators(ctx)
minComm := sdk.MustNewDecFromStr(NewMinCommisionRate)

for _, v := range validators {
//nolint
if v.Commission.Rate.LT(minComm) {
comm, err := updateValidatorCommission(ctx, staking, v, minComm)
if err != nil {
panic(err)
}

// call the before-modification hook since we're about to update the commission
staking.BeforeValidatorModified(ctx, v.GetOperator())
v.Commission = comm
staking.SetValidator(ctx, v)
}
}
}

func updateValidatorCommission(ctx sdk.Context, staking *stakingkeeper.Keeper,
validator stakingtypes.Validator, newRate sdk.Dec,
) (stakingtypes.Commission, error) {
commission := validator.Commission
blockTime := ctx.BlockHeader().Time

if newRate.LT(staking.MinCommissionRate(ctx)) {
return commission, fmt.Errorf("cannot set validator commission to less than minimum rate of %s", staking.MinCommissionRate(ctx))
}

commission.Rate = newRate
if commission.MaxRate.LT(newRate) {
commission.MaxRate = newRate
}

commission.UpdateTime = blockTime

return commission, nil
}
70 changes: 70 additions & 0 deletions app/upgrades_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package app

import (
"testing"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/realiotech/realio-network/app/upgrades/commission"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)

func TestCommissionUpgrade(t *testing.T) {
app := Setup(false, nil, 4)
ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: app.LastBlockHeight() + 1})
validators := app.StakingKeeper.GetAllValidators(ctx)

comm0 := stakingtypes.CommissionRates{
Rate: sdk.MustNewDecFromStr("0.01"),
MaxRate: sdk.MustNewDecFromStr("0.01"),
MaxChangeRate: sdk.MustNewDecFromStr("0.02"),
}
comm1 := stakingtypes.CommissionRates{
Rate: sdk.MustNewDecFromStr("0.02"),
MaxRate: sdk.MustNewDecFromStr("0.03"),
MaxChangeRate: sdk.MustNewDecFromStr("0.02"),
}
comm2 := stakingtypes.CommissionRates{
Rate: sdk.MustNewDecFromStr("0.06"),
MaxRate: sdk.MustNewDecFromStr("0.07"),
MaxChangeRate: sdk.MustNewDecFromStr("0.02"),
}
comm3 := stakingtypes.CommissionRates{
Rate: sdk.MustNewDecFromStr("0.1"),
MaxRate: sdk.MustNewDecFromStr("0.2"),
MaxChangeRate: sdk.MustNewDecFromStr("0.1"),
}

validators[0].Commission.CommissionRates = comm0
validators[1].Commission.CommissionRates = comm1
validators[2].Commission.CommissionRates = comm2
validators[3].Commission.CommissionRates = comm3

app.StakingKeeper.SetValidator(ctx, validators[0])
app.StakingKeeper.SetValidator(ctx, validators[1])
app.StakingKeeper.SetValidator(ctx, validators[2])
app.StakingKeeper.SetValidator(ctx, validators[3])

upgradePlan := upgradetypes.Plan{
Name: commission.UpgradeName,
Height: ctx.BlockHeight(),
}
err := app.UpgradeKeeper.ScheduleUpgrade(ctx, upgradePlan)

require.NoError(t, err)
ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Now()})
app.UpgradeKeeper.ApplyUpgrade(ctx, upgradePlan)

validatorsAfter := app.StakingKeeper.GetAllValidators(ctx)

upgradeMinCommRate := sdk.MustNewDecFromStr(commission.NewMinCommisionRate)
require.Equal(t, validatorsAfter[0].Commission.CommissionRates.Rate, upgradeMinCommRate)
require.Equal(t, validatorsAfter[1].Commission.CommissionRates.Rate, upgradeMinCommRate)
require.Equal(t, validatorsAfter[0].Commission.CommissionRates.MaxRate, upgradeMinCommRate)
require.Equal(t, validatorsAfter[1].Commission.CommissionRates.MaxRate, upgradeMinCommRate)
require.Equal(t, validatorsAfter[2].Commission.CommissionRates.Rate, validators[2].Commission.CommissionRates.Rate)
require.Equal(t, validatorsAfter[3].Commission.CommissionRates.Rate, validators[3].Commission.CommissionRates.Rate)
}
2 changes: 1 addition & 1 deletion x/asset/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (suite *GenesisTestSuite) SetupTest() {
// consensus key
consAddress := sdk.ConsAddress(testutil.GenAddress().Bytes())

suite.app = app.Setup(false, feemarkettypes.DefaultGenesisState())
suite.app = app.Setup(false, feemarkettypes.DefaultGenesisState(), 1)
suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{
Height: 1,
ChainID: realiotypes.MainnetChainID,
Expand Down
2 changes: 1 addition & 1 deletion x/asset/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (suite *KeeperTestSuite) DoSetupTest(t *testing.T) {
consAddress := sdk.ConsAddress(priv.PubKey().Address())

// init app
suite.app = app.Setup(checkTx, nil)
suite.app = app.Setup(checkTx, nil, 1)

// Set Context
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{
Expand Down
2 changes: 1 addition & 1 deletion x/mint/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (suite *KeeperTestSuite) DoSetupTest(t *testing.T) {
consAddress := sdk.ConsAddress(priv.PubKey().Address())

// init app
suite.app = app.Setup(checkTx, nil)
suite.app = app.Setup(checkTx, nil, 1)

// Set Context
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{
Expand Down
2 changes: 1 addition & 1 deletion x/mint/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

func TestItCreatesModuleAccountOnInitBlock(t *testing.T) {
realio := app.Setup(false, nil)
realio := app.Setup(false, nil, 1)
ctx := realio.BaseApp.NewContext(false, tmproto.Header{})
acc := realio.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName))
require.NotNil(t, acc)
Expand Down

0 comments on commit c1454d9

Please sign in to comment.