diff --git a/app/ante.go b/app/ante.go index b44892b..625e68e 100644 --- a/app/ante.go +++ b/app/ante.go @@ -53,6 +53,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), passageante.NewBlockAccountDecorator(), + passageante.NewValidateMinCommissionDecorator(), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewSetPubKeyDecorator(options.AccountKeeper), ante.NewValidateSigCountDecorator(options.AccountKeeper), diff --git a/app/ante/min_commission.go b/app/ante/min_commission.go new file mode 100644 index 0000000..31f55ce --- /dev/null +++ b/app/ante/min_commission.go @@ -0,0 +1,70 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authztypes "github.com/cosmos/cosmos-sdk/x/authz" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +var MinCommissionRate = sdk.MustNewDecFromStr("0.05") + +// ValidateMinCommissionDecorator validates the minimum commission rate of validator +// to be not less than minimum commission rate when creating or editing validator. +type ValidateMinCommissionDecorator struct{} + +func NewValidateMinCommissionDecorator() ValidateMinCommissionDecorator { + return ValidateMinCommissionDecorator{} +} + +func (mcd ValidateMinCommissionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, + next sdk.AnteHandler, +) (sdk.Context, error) { + msgs := tx.GetMsgs() + + // handle msg based on type + if err := mcd.handleMsgs(msgs); err != nil { + return ctx, err + } + + return next(ctx, tx, simulate) +} + +func (mcd ValidateMinCommissionDecorator) handleMsgs(msgs []sdk.Msg) error { + for _, msg := range msgs { + switch m := msg.(type) { + case *stakingtypes.MsgCreateValidator: + if err := validateMinCommissionRate(m.Commission.Rate); err != nil { + return err + } + + case *stakingtypes.MsgEditValidator: + if m.CommissionRate != nil { + if err := validateMinCommissionRate(*m.CommissionRate); err != nil { + return err + } + } + + case *authztypes.MsgExec: + execMsgs, err := m.GetMessages() + if err != nil { + return err + } + + if err := mcd.handleMsgs(execMsgs); err != nil { + return err + } + + } + } + return nil +} + +func validateMinCommissionRate(rate sdk.Dec) error { + if rate.IsNil() || rate.LT(MinCommissionRate) { + return sdkerrors.ErrInvalidRequest.Wrapf( + "cannot set validator commission to less than minimum rate of %s", MinCommissionRate) + } + + return nil +} diff --git a/app/app.go b/app/app.go index a0a3337..6cc4f49 100644 --- a/app/app.go +++ b/app/app.go @@ -665,6 +665,7 @@ func (app *PassageApp) setupUpgradeHandlers() { app.DistrKeeper, app.BankKeeper, app.AccountKeeper, + app.StakingKeeper, app.ClaimKeeper, ), ) diff --git a/app/upgrades/types.go b/app/upgrades/types.go index 7143399..001de63 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -6,6 +6,7 @@ import ( auth "github.com/cosmos/cosmos-sdk/x/auth/keeper" bank "github.com/cosmos/cosmos-sdk/x/bank/keeper" distribution "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + staking "github.com/cosmos/cosmos-sdk/x/staking/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" claim "github.com/envadiv/Passage3D/x/claim/keeper" ) @@ -19,7 +20,7 @@ type Upgrade struct { UpgradeName string // CreateUpgradeHandler defines the function that creates an upgrade handler - CreateUpgradeHandler func(*module.Manager, module.Configurator, distribution.Keeper, bank.Keeper, auth.AccountKeeper, claim.Keeper) upgradetypes.UpgradeHandler + CreateUpgradeHandler func(*module.Manager, module.Configurator, distribution.Keeper, bank.Keeper, auth.AccountKeeper, staking.Keeper, claim.Keeper) upgradetypes.UpgradeHandler // Store upgrades, should be used for any new modules introduced, new modules deleted, or store names renamed. StoreUpgrades store.StoreUpgrades diff --git a/app/upgrades/v2.2.0/upgrade.go b/app/upgrades/v2.2.0/upgrade.go index 90964b8..0612eb5 100644 --- a/app/upgrades/v2.2.0/upgrade.go +++ b/app/upgrades/v2.2.0/upgrade.go @@ -12,14 +12,17 @@ import ( vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" bank "github.com/cosmos/cosmos-sdk/x/bank/keeper" distribution "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + staking "github.com/cosmos/cosmos-sdk/x/staking/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/envadiv/Passage3D/app/upgrades" claim "github.com/envadiv/Passage3D/x/claim/keeper" claimtypes "github.com/envadiv/Passage3D/x/claim/types" ) -const Name = "v2.2.0" -const upasgDenom = "upasg" +const ( + Name = "v2.2.0" + upasgDenom = "upasg" +) // 150,000,000 $PASG tokens var amount = sdk.NewCoins(sdk.NewCoin(upasgDenom, sdk.NewInt(150000000000000))) @@ -36,9 +39,9 @@ func CreateUpgradeHandler( dk distribution.Keeper, bk bank.Keeper, ak auth.AccountKeeper, + _ staking.Keeper, ck claim.Keeper, ) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { if err := ExecuteProposal(ctx, ak, bk, ck, dk); err != nil { return nil, err @@ -49,7 +52,7 @@ func CreateUpgradeHandler( } func ExecuteProposal(ctx sdk.Context, ak auth.AccountKeeper, bk bank.Keeper, ck claim.Keeper, dk distribution.Keeper) error { - var sixMonths = time.Hour * 24 * 180 + sixMonths := time.Hour * 24 * 180 vestingAcc, err := sdk.AccAddressFromBech32("pasg105488mw9t3qtp62jhllde28v40xqxpjksjqmvx") if err != nil { diff --git a/app/upgrades/v2.4.0/upgrade.go b/app/upgrades/v2.4.0/upgrade.go index a4350e2..bcdcab0 100644 --- a/app/upgrades/v2.4.0/upgrade.go +++ b/app/upgrades/v2.4.0/upgrade.go @@ -8,6 +8,7 @@ import ( bank "github.com/cosmos/cosmos-sdk/x/bank/keeper" distribution "github.com/cosmos/cosmos-sdk/x/distribution/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + staking "github.com/cosmos/cosmos-sdk/x/staking/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/envadiv/Passage3D/app/upgrades" claim "github.com/envadiv/Passage3D/x/claim/keeper" @@ -28,9 +29,9 @@ func CreateUpgradeHandler( _ distribution.Keeper, bk bank.Keeper, ak auth.AccountKeeper, + _ staking.Keeper, _ claim.Keeper, ) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { if err := ExecuteProposal(ctx, ak, bk); err != nil { return nil, err diff --git a/app/upgrades/v2.5.0/min_commission.go b/app/upgrades/v2.5.0/min_commission.go new file mode 100644 index 0000000..8c85c24 --- /dev/null +++ b/app/upgrades/v2.5.0/min_commission.go @@ -0,0 +1,24 @@ +package v2_5 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + staking "github.com/cosmos/cosmos-sdk/x/staking/keeper" +) + +// SetValidatorsMinCommissionRate update the minimum commission rate of the validator +// whose commission rate is below the minimum commission rate. +func SetValidatorsMinCommissionRate(ctx sdk.Context, sk staking.Keeper, minCommissionRate sdk.Dec) error { + validators := sk.GetAllValidators(ctx) + + for _, validator := range validators { + if validator.Commission.Rate.IsNil() || validator.Commission.Rate.LT(minCommissionRate) { + // call before validator modified hooks in staking keeper + sk.BeforeValidatorModified(ctx, validator.GetOperator()) + validator.Commission.Rate = minCommissionRate + validator.Commission.UpdateTime = ctx.BlockTime() + sk.SetValidator(ctx, validator) + } + } + + return nil +} diff --git a/app/upgrades/v2.5.0/upgrade.go b/app/upgrades/v2.5.0/upgrade.go index 4a587aa..b56f560 100644 --- a/app/upgrades/v2.5.0/upgrade.go +++ b/app/upgrades/v2.5.0/upgrade.go @@ -10,7 +10,9 @@ import ( auth "github.com/cosmos/cosmos-sdk/x/auth/keeper" bank "github.com/cosmos/cosmos-sdk/x/bank/keeper" distribution "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + staking "github.com/cosmos/cosmos-sdk/x/staking/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + passageante "github.com/envadiv/Passage3D/app/ante" "github.com/envadiv/Passage3D/app/upgrades" claim "github.com/envadiv/Passage3D/x/claim/keeper" claimtypes "github.com/envadiv/Passage3D/x/claim/types" @@ -32,10 +34,11 @@ func CreateUpgradeHandler( _ distribution.Keeper, bk bank.Keeper, ak auth.AccountKeeper, + sk staking.Keeper, ck claim.Keeper, ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - if err := ExecuteProposal(ctx, ak, bk, ck); err != nil { + if err := ExecuteProposal(ctx, ak, bk, sk, ck); err != nil { return nil, err } @@ -43,7 +46,7 @@ func CreateUpgradeHandler( } } -func ExecuteProposal(ctx sdk.Context, ak auth.AccountKeeper, bk bank.Keeper, ck claim.Keeper) error { +func ExecuteProposal(ctx sdk.Context, ak auth.AccountKeeper, bk bank.Keeper, sk staking.Keeper, ck claim.Keeper) error { oneMonth := time.Hour * 24 * 30 // clear old claim records @@ -80,5 +83,7 @@ func ExecuteProposal(ctx sdk.Context, ak auth.AccountKeeper, bk bank.Keeper, ck params.DurationUntilDecay = oneMonth ck.SetParams(ctx, params) - return nil + + // set minimum commission rate to validators + return SetValidatorsMinCommissionRate(ctx, sk, passageante.MinCommissionRate) }