diff --git a/app/ante/msg_ante.go b/app/ante/msg_ante.go index 3fdbab18a..fdd6f203c 100644 --- a/app/ante/msg_ante.go +++ b/app/ante/msg_ante.go @@ -6,12 +6,15 @@ 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/auth/legacy/legacytx" "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" claimtypes "github.com/crescent-network/crescent/v5/x/claim/types" + exchangetypes "github.com/crescent-network/crescent/v5/x/exchange/types" farmingtypes "github.com/crescent-network/crescent/v5/x/farming/types" + liquiditytypes "github.com/crescent-network/crescent/v5/x/liquidity/types" ) // initial deposit must be greater than or equal to 50% of the minimum deposit @@ -38,8 +41,7 @@ func (d MsgFilterDecorator) AnteHandle( if !d.enabled { return next(ctx, tx, simulate) } - msgs := tx.GetMsgs() - if err = d.ValidateMsgs(ctx, msgs); err != nil { + if err = d.ValidateMsgs(ctx, tx.GetMsgs()); err != nil { return ctx, err } @@ -47,13 +49,15 @@ func (d MsgFilterDecorator) AnteHandle( } func (d MsgFilterDecorator) ValidateMsgs(ctx sdk.Context, msgs []sdk.Msg) error { + numMsg, numBatchMsg := 0, 0 var minInitialDeposit sdk.Coins validateMsg := func(msg sdk.Msg, nested bool) error { - // mempool(check tx) level msg filter - if ctx.IsCheckTx() { - switch msg := msg.(type) { - // prevent messages with insufficient initial deposit amount - case *govtypes.MsgSubmitProposal: + numMsg++ + switch msg := msg.(type) { + // prevent gov messages with insufficient initial deposit amount + case *govtypes.MsgSubmitProposal: + // mempool(check tx) level msg filter + if ctx.IsCheckTx() { if minInitialDeposit.Empty() { depositParams := d.govKeeper.GetDepositParams(ctx) minInitialDeposit = CalcMinInitialDeposit(depositParams.MinDeposit, minInitialDepositFraction) @@ -63,32 +67,31 @@ func (d MsgFilterDecorator) ValidateMsgs(ctx sdk.Context, msgs []sdk.Msg) error return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "insufficient initial deposit amount - required: %v", minInitialDeposit) } } - } - // deliver tx level msg filter - switch msg := msg.(type) { - // deprecated msgs - case *claimtypes.MsgClaim, - *farmingtypes.MsgCreateFixedAmountPlan, - *farmingtypes.MsgCreateRatioPlan, - *farmingtypes.MsgStake, - *farmingtypes.MsgUnstake, - *farmingtypes.MsgHarvest, - *farmingtypes.MsgRemovePlan, - *farmingtypes.MsgAdvanceEpoch: - return fmt.Errorf("%s is deprecated msg type", sdk.MsgTypeURL(msg)) + // tracking mixed batch msg with regular msg + case *exchangetypes.MsgPlaceBatchLimitOrder, + *exchangetypes.MsgPlaceMMBatchLimitOrder, + *exchangetypes.MsgCancelOrder: + numMsg-- + numBatchMsg++ + // block double nested MsgExec case *authz.MsgExec: if nested { return fmt.Errorf("double nested %s is not allowed", sdk.MsgTypeURL(msg)) } + default: + // block deprecated module's msgs + if legacyMsg, ok := msg.(legacytx.LegacyMsg); ok { + switch legacyMsg.Route() { + case liquiditytypes.RouterKey, + farmingtypes.RouterKey, + claimtypes.RouterKey: + return fmt.Errorf("%s is deprecated msg type", sdk.MsgTypeURL(msg)) + } + } } - // TODO: on next PR - // - add other deprecated msg types - // - prevent authz nested midblock, batch msgs - // - prevent multi msgs midblock, batch msgs with normal msg - return nil } @@ -107,6 +110,7 @@ func (d MsgFilterDecorator) ValidateMsgs(ctx sdk.Context, msgs []sdk.Msg) error } for _, m := range msgs { + // validate authz nested msgs if authzMsg, ok := m.(*authz.MsgExec); ok { if err := validateAuthz(authzMsg); err != nil { return err @@ -119,6 +123,12 @@ func (d MsgFilterDecorator) ValidateMsgs(ctx sdk.Context, msgs []sdk.Msg) error return err } } + + // block mixed batch msg with regular msg + if numBatchMsg > 0 && numMsg > 0 { + return fmt.Errorf("cannot mix batch msg and regular msg in one tx") + } + return nil } diff --git a/app/ante/msg_ante_test.go b/app/ante/msg_ante_test.go index 200a62b4f..5c10f8d54 100644 --- a/app/ante/msg_ante_test.go +++ b/app/ante/msg_ante_test.go @@ -11,6 +11,9 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" claimtypes "github.com/crescent-network/crescent/v5/x/claim/types" + exchangetypes "github.com/crescent-network/crescent/v5/x/exchange/types" + farmingtypes "github.com/crescent-network/crescent/v5/x/farming/types" + liquiditytypes "github.com/crescent-network/crescent/v5/x/liquidity/types" ) type runTxMode uint8 @@ -30,7 +33,6 @@ func (suite *AnteTestSuite) TestAnteHandlerSubmitProposalMsg() { feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() acc := accounts[0].acc.GetAddress() - //accStr := acc.String() // Variable data per test case var ( @@ -322,6 +324,53 @@ func (suite *AnteTestSuite) TestAnteHandlerDeprecatedMsg() { false, fmt.Errorf("/crescent.claim.v1beta1.MsgClaim is deprecated msg type"), }, + { + "deprecated msg - farming", + func() { + msg := &farmingtypes.MsgStake{ + Farmer: accStr, + StakingCoins: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1))), + } + msgs = []sdk.Msg{msg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + }, + runTxModeDeliver, + false, + fmt.Errorf("/crescent.farming.v1beta1.MsgStake is deprecated msg type"), + }, + { + "deprecated msg - liquidity", + func() { + msg := &liquiditytypes.MsgCreatePair{ + Creator: accStr, + BaseCoinDenom: "abc", + QuoteCoinDenom: "stake", + } + msgs = []sdk.Msg{msg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + }, + runTxModeDeliver, + false, + fmt.Errorf("/crescent.liquidity.v1beta1.MsgCreatePair is deprecated msg type"), + }, + { + "not deprecated msg", + func() { + msg := &exchangetypes.MsgCreateMarket{ + Sender: accStr, + BaseDenom: "abc", + QuoteDenom: "stake", + } + msgs = []sdk.Msg{msg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{1} + }, + runTxModeDeliver, + true, + nil, + }, } for _, tc := range testCases { @@ -342,7 +391,6 @@ func (suite *AnteTestSuite) TestDoubleNestedAuthzMsg() { feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() acc := accounts[0].acc.GetAddress() - //accStr := acc.String() // Variable data per test case var ( @@ -404,3 +452,172 @@ func (suite *AnteTestSuite) TestDoubleNestedAuthzMsg() { }) } } + +func (suite *AnteTestSuite) TestMixedBatchMsg() { + suite.SetupTest(false) // reset + + // Same data for every test cases + accounts := suite.CreateTestAccounts(2) + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + acc := accounts[0].acc.GetAddress() + + // Variable data per test case + var ( + accNums []uint64 + msgs []sdk.Msg + privs []cryptotypes.PrivKey + accSeqs []uint64 + ) + + msg := testdata.NewTestMsg(acc) + batchMsg := exchangetypes.NewMsgPlaceBatchLimitOrder(acc, 1, true, sdk.ZeroDec(), sdk.ZeroInt(), 0) + authzMsg := authz.NewMsgExec(acc, []sdk.Msg{batchMsg, msg}) + authzMsg2 := authz.NewMsgExec(acc, []sdk.Msg{batchMsg}) + authzMsg3 := authz.NewMsgExec(acc, []sdk.Msg{batchMsg, batchMsg}) + //authzMsgNested := authz.NewMsgExec(acc, []sdk.Msg{&authzMsg}) + + testCases := []TestCase{ + { + "only batch msg", + func() { + + msgs = []sdk.Msg{batchMsg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} + }, + runTxModeDeliver, + true, + nil, + }, + { + "only batch msgs", + func() { + + msgs = []sdk.Msg{batchMsg, batchMsg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{1} + }, + runTxModeDeliver, + true, + nil, + }, + { + "mixed batch msg with multi msg", + func() { + + msgs = []sdk.Msg{batchMsg, msg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{2} + }, + runTxModeDeliver, + false, + fmt.Errorf("cannot mix batch msg and regular msg in one tx"), + }, + { + "mixed batch msg with multi msg - check tx", + func() { + + msgs = []sdk.Msg{batchMsg, msg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{2} + }, + runTxModeCheck, + false, + fmt.Errorf("cannot mix batch msg and regular msg in one tx"), + }, + { + "mixed batch msg with multi msg", + func() { + + msgs = []sdk.Msg{msg, batchMsg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{2} + }, + runTxModeDeliver, + false, + fmt.Errorf("cannot mix batch msg and regular msg in one tx"), + }, + { + "mixed batch msg with authz msg", + func() { + + msgs = []sdk.Msg{msg, &authzMsg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{2} + }, + runTxModeDeliver, + false, + fmt.Errorf("cannot mix batch msg and regular msg in one tx"), + }, + { + "mixed batch msg with authz msg - 2", + func() { + + msgs = []sdk.Msg{&authzMsg, msg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{2} + }, + runTxModeDeliver, + false, + fmt.Errorf("cannot mix batch msg and regular msg in one tx"), + }, + { + "mixed batch msg with authz msg - 3", + func() { + + msgs = []sdk.Msg{msg, &authzMsg2} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{2} + }, + runTxModeDeliver, + false, + fmt.Errorf("cannot mix batch msg and regular msg in one tx"), + }, + { + "authz only batch msg", + func() { + + msgs = []sdk.Msg{&authzMsg2} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{2} + }, + runTxModeDeliver, + true, + nil, + }, + { + "authz only batch msg - 2", + func() { + + msgs = []sdk.Msg{&authzMsg3} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{3} + }, + runTxModeDeliver, + true, + nil, + }, + { + "authz only batch msg - 3", + func() { + + msgs = []sdk.Msg{&authzMsg3, batchMsg} + + privs, accNums, accSeqs = []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{4} + }, + runTxModeDeliver, + true, + nil, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + tc.malleate() + + suite.RunTestCase(privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), tc) + }) + } +} diff --git a/app/params/weights.go b/app/params/weights.go index 7828d2c1c..e88a4a26e 100644 --- a/app/params/weights.go +++ b/app/params/weights.go @@ -2,6 +2,7 @@ package params // Default simulation operation weights for messages and gov proposals. const ( + // deprecated farming module DefaultWeightMsgCreateFixedAmountPlan int = 0 DefaultWeightMsgCreateRatioPlan int = 0 DefaultWeightMsgStake int = 0 @@ -9,17 +10,21 @@ const ( DefaultWeightMsgHarvest int = 0 DefaultWeightMsgRemovePlan int = 0 - DefaultWeightMsgCreatePair int = 10 - DefaultWeightMsgCreatePool int = 10 - DefaultWeightMsgCreateRangedPool int = 15 - DefaultWeightMsgDeposit int = 20 - DefaultWeightMsgWithdraw int = 20 - DefaultWeightMsgLimitOrder int = 80 - DefaultWeightMsgMarketOrder int = 60 - DefaultWeightMsgMMOrder int = 40 - DefaultWeightMsgCancelOrder int = 20 - DefaultWeightMsgCancelAllOrders int = 20 - DefaultWeightMsgCancelMMOrder int = 20 + // deprecated liquidity module + DefaultWeightMsgCreatePair int = 0 + DefaultWeightMsgCreatePool int = 0 + DefaultWeightMsgCreateRangedPool int = 0 + DefaultWeightMsgDeposit int = 0 + DefaultWeightMsgWithdraw int = 0 + DefaultWeightMsgLimitOrder int = 0 + DefaultWeightMsgMarketOrder int = 0 + DefaultWeightMsgMMOrder int = 0 + DefaultWeightMsgCancelOrder int = 0 + DefaultWeightMsgCancelAllOrders int = 0 + DefaultWeightMsgCancelMMOrder int = 0 + + // Deprecated claim module + DefaultWeightMsgClaim int = 0 DefaultWeightAddPublicPlanProposal int = 5 DefaultWeightUpdatePublicPlanProposal int = 5 @@ -34,8 +39,6 @@ const ( DefaultWeightCompleteRedelegationUnbonding int = 30 DefaultWeightTallyWithLiquidStaking int = 30 - DefaultWeightMsgClaim int = 0 - DefaultWeightMsgLiquidFarm int = 50 DefaultWeightMsgLiquidUnfarm int = 10 DefaultWeightMsgPlaceBid int = 20 diff --git a/x/liquidity/simulation/operations_test.go b/x/liquidity/simulation/operations_test.go index 3dec7e065..ed5494b69 100644 --- a/x/liquidity/simulation/operations_test.go +++ b/x/liquidity/simulation/operations_test.go @@ -28,7 +28,7 @@ type SimTestSuite struct { } func (s *SimTestSuite) SetupTest() { - s.app = chain.Setup(false) + s.app = chain.SetupWithNoMsgFilter(false) s.ctx = s.app.BaseApp.NewContext(false, tmproto.Header{}) s.keeper = s.app.LiquidityKeeper }