From c2aa971c72afcac13fa09e622db40853f5c86f24 Mon Sep 17 00:00:00 2001 From: Reece Williams <31943163+Reecepbcups@users.noreply.github.com> Date: Mon, 6 Feb 2023 17:44:08 -0600 Subject: [PATCH] adds gov deposit handler to v12, tested manually (#550) --- app/ante.go | 6 +++ app/app.go | 1 + app/decorators/constant.go | 3 ++ app/decorators/gov_filter.go | 91 ++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 app/decorators/constant.go create mode 100644 app/decorators/gov_filter.go diff --git a/app/ante.go b/app/ante.go index b3ca97a0a..ebac5384a 100644 --- a/app/ante.go +++ b/app/ante.go @@ -10,6 +10,10 @@ import ( ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + + decorators "github.com/CosmosContracts/juno/v12/app/decorators" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -19,6 +23,7 @@ import ( type HandlerOptions struct { ante.HandlerOptions + GovKeeper govkeeper.Keeper IBCKeeper *ibckeeper.Keeper TxCounterStoreKey sdk.StoreKey WasmConfig wasmTypes.WasmConfig @@ -125,6 +130,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit), wasmkeeper.NewCountTXDecorator(options.TxCounterStoreKey), ante.NewRejectExtensionOptionsDecorator(), + decorators.NewGovPreventSpamDecorator(options.Cdc, options.GovKeeper), ante.NewMempoolFeeDecorator(), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), diff --git a/app/app.go b/app/app.go index 898045fdd..81a3f0b6f 100644 --- a/app/app.go +++ b/app/app.go @@ -633,6 +633,7 @@ func New( SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, + GovKeeper: app.GovKeeper, IBCKeeper: app.IBCKeeper, TxCounterStoreKey: keys[wasm.StoreKey], WasmConfig: wasmConfig, diff --git a/app/decorators/constant.go b/app/decorators/constant.go new file mode 100644 index 000000000..d8df2f057 --- /dev/null +++ b/app/decorators/constant.go @@ -0,0 +1,3 @@ +package decorators + +var DefaultIsAppSimulation = false diff --git a/app/decorators/gov_filter.go b/app/decorators/gov_filter.go new file mode 100644 index 000000000..e6f981482 --- /dev/null +++ b/app/decorators/gov_filter.go @@ -0,0 +1,91 @@ +package decorators + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/authz" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +var MiniumInitialDepositRate = sdk.NewDecWithPrec(20, 2) + +type GovPreventSpamDecorator struct { + govKeeper govkeeper.Keeper + cdc codec.BinaryCodec +} + +func NewGovPreventSpamDecorator(cdc codec.BinaryCodec, govKeeper govkeeper.Keeper) GovPreventSpamDecorator { + return GovPreventSpamDecorator{ + govKeeper: govKeeper, + cdc: cdc, + } +} + +func (gpsd GovPreventSpamDecorator) AnteHandle( + ctx sdk.Context, tx sdk.Tx, + simulate bool, next sdk.AnteHandler, +) (newCtx sdk.Context, err error) { + if DefaultIsAppSimulation { + return next(ctx, tx, simulate) + } + msgs := tx.GetMsgs() + + err = gpsd.checkSpamSubmitProposalMsg(ctx, msgs) + + if err != nil { + return ctx, err + } + + return next(ctx, tx, simulate) +} + +func (gpsd GovPreventSpamDecorator) checkSpamSubmitProposalMsg(ctx sdk.Context, msgs []sdk.Msg) error { + validMsg := func(m sdk.Msg) error { + if msg, ok := m.(*govtypes.MsgSubmitProposal); ok { + // prevent spam gov msg + depositParams := gpsd.govKeeper.GetDepositParams(ctx) + miniumInitialDeposit := gpsd.calcMiniumInitialDeposit(depositParams.MinDeposit) + if msg.InitialDeposit.IsAllLT(miniumInitialDeposit) { + return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "not enough initial deposit. required: %v", miniumInitialDeposit) + } + } + return nil + } + + // Check every msg in the tx, if it's a MsgExec, check the inner msgs. + // If it's a MsgSubmitProposal, check the initial deposit is enough. + for _, m := range msgs { + var innerMsg sdk.Msg + if msg, ok := m.(*authz.MsgExec); ok { + for _, v := range msg.Msgs { + err := gpsd.cdc.UnpackAny(v, &innerMsg) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") + } + + err = validMsg(innerMsg) + if err != nil { + return err + } + } + } else { + err := validMsg(m) + if err != nil { + return err + } + } + } + + return nil +} + +func (gpsd GovPreventSpamDecorator) calcMiniumInitialDeposit(minDeposit sdk.Coins) (miniumInitialDeposit sdk.Coins) { + for _, coin := range minDeposit { + miniumInitialCoin := MiniumInitialDepositRate.MulInt(coin.Amount).RoundInt() + miniumInitialDeposit = miniumInitialDeposit.Add(sdk.NewCoin(coin.Denom, miniumInitialCoin)) + } + + return +}