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

!chore: write upgrade handler for new minimum commission rate #8

Merged
merged 12 commits into from
May 14, 2024
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
3 changes: 0 additions & 3 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ import (
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"

// staking
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
Expand Down Expand Up @@ -107,13 +106,11 @@ import (
feemarkettypes "github.com/evmos/evmos/v18/x/feemarket/types"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"

// multi-staking
multistaking "github.com/realio-tech/multi-staking-module/x/multi-staking"
multistakingkeeper "github.com/realio-tech/multi-staking-module/x/multi-staking/keeper"
multistakingtypes "github.com/realio-tech/multi-staking-module/x/multi-staking/types"
"github.com/realiotech/realio-network/app/ante"

// unnamed import of statik for swagger UI support
_ "github.com/realiotech/realio-network/client/docs/statik"
realionetworktypes "github.com/realiotech/realio-network/types"
Expand Down
2 changes: 1 addition & 1 deletion app/fork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,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
21 changes: 15 additions & 6 deletions app/test_helpers.go
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,9 @@ func init() {
func Setup(
isCheckTx bool,
feemarketGenesis *feemarkettypes.GenesisState,
numberVals int,
) *RealioNetwork {
privVal := mock.NewPV()
pubKey, _ := privVal.GetPubKey()

// 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 @@ -240,3 +236,16 @@ func SetupTestingApp() (ibctesting.TestingApp, map[string]json.RawMessage) {
app := New(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, cfg, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome))
return app, app.DefaultGenesis()
}

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
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
multistakingtypes "github.com/realio-tech/multi-staking-module/x/multi-staking/types"
multistaking "github.com/realiotech/realio-network/app/upgrades/multi-staking"
v4 "github.com/realiotech/realio-network/app/upgrades/v4"
)

func (app *RealioNetwork) setupUpgradeHandlers(appOpts servertypes.AppOptions) {
Expand All @@ -23,6 +24,15 @@ func (app *RealioNetwork) setupUpgradeHandlers(appOpts servertypes.AppOptions) {
),
)

app.UpgradeKeeper.SetUpgradeHandler(
v4.UpgradeName,
v4.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/v4/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package v4

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

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)
params := staking.GetParams(ctx)
params.MinCommissionRate = minComm

err := staking.SetParams(ctx, params)
if err != nil {
panic(err)
}

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

v.Commission = comm

// call the before-modification hook since we're about to update the commission
staking.Hooks().BeforeValidatorModified(ctx, v.GetOperator())
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"

tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
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"
v4 "github.com/realiotech/realio-network/app/upgrades/v4"
"github.com/stretchr/testify/require"
)

func TestV4Upgrade(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: v4.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(v4.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 @@ -31,7 +31,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 @@ -58,7 +58,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 @@ -11,7 +11,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
Loading