diff --git a/x/tx-boundary/ante/antetest/ante_test.go b/x/tx-boundary/ante/antetest/ante_test.go index 0b135a2dd..1e52f0a60 100644 --- a/x/tx-boundary/ante/antetest/ante_test.go +++ b/x/tx-boundary/ante/antetest/ante_test.go @@ -19,13 +19,14 @@ func TestAnteTestSuite(t *testing.T) { suite.Run(t, new(AnteTestSuite)) } -func (s *AnteTestSuite) TestStakingAnte() { +func (s *AnteTestSuite) TestStakingAnteBasic() { _, _, addr1 := testdata.KeyTestPubAddr() delegateMsg := stakingtypes.NewMsgDelegate(s.delegator, s.validators[0].GetOperator(), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10000000))) msgDelegateAny, err := cdctypes.NewAnyWithValue(delegateMsg) + require.NoError(s.T(), err) + addr2 := s.delegator - require.NoError(s.T(), err) for _, tc := range []struct { desc string txMsg sdk.Msg @@ -118,3 +119,128 @@ func (s *AnteTestSuite) TestStakingAnte() { } } } + +func (s *AnteTestSuite) TestStakingAnteUpdateLimit() { + _, _, addr1 := testdata.KeyTestPubAddr() + delegateMsg := stakingtypes.NewMsgDelegate(s.delegator, s.validators[0].GetOperator(), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10000000))) + + msgDelegateAny, err := cdctypes.NewAnyWithValue(delegateMsg) + require.NoError(s.T(), err) + + addr2 := s.delegator + + for _, tc := range []struct { + desc string + txMsg sdk.Msg + malleate func() error + blocksAdded int64 + expErr bool + expErrStr string + }{ + { + desc: "Case delegate success update limit", + txMsg: stakingtypes.NewMsgDelegate(s.delegator, s.validators[0].GetOperator(), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10000000))), + malleate: func() error { + s.app.TxBoundaryKeepper.SetLimitPerAddr(s.ctx, addr2, types.LimitPerAddr{ + DelegateCount: 5, + ReledegateCount: 5, + LatestUpdateBlock: s.ctx.BlockHeight(), + }) + return nil + }, + blocksAdded: 5, + expErr: false, + }, + { + desc: "Case redelegate success update limit", + txMsg: stakingtypes.NewMsgBeginRedelegate(s.delegator, s.validators[0].GetOperator(), s.newvalidators[0].GetOperator(), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10000000))), + malleate: func() error { + s.app.TxBoundaryKeepper.SetLimitPerAddr(s.ctx, addr2, types.LimitPerAddr{ + DelegateCount: 5, + ReledegateCount: 5, + LatestUpdateBlock: s.ctx.BlockHeight(), + }) + return nil + }, + blocksAdded: 5, + expErr: false, + }, + { + desc: "Case authz success update limit", + txMsg: &authz.MsgExec{Grantee: addr1.String(), Msgs: []*cdctypes.Any{msgDelegateAny}}, + malleate: func() error { + s.app.TxBoundaryKeepper.SetLimitPerAddr(s.ctx, addr2, types.LimitPerAddr{ + DelegateCount: 5, + ReledegateCount: 5, + LatestUpdateBlock: s.ctx.BlockHeight(), + }) + return nil + }, + blocksAdded: 5, + expErr: false, + }, + { + desc: "Case delegate fail update limit", + txMsg: stakingtypes.NewMsgDelegate(s.delegator, s.validators[0].GetOperator(), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10000000))), + malleate: func() error { + s.app.TxBoundaryKeepper.SetLimitPerAddr(s.ctx, addr2, types.LimitPerAddr{ + DelegateCount: 5, + ReledegateCount: 5, + LatestUpdateBlock: s.ctx.BlockHeight(), + }) + return nil + }, + blocksAdded: 4, + expErr: true, + }, + { + desc: "Case redelegate fail update limit", + txMsg: stakingtypes.NewMsgBeginRedelegate(s.delegator, s.validators[0].GetOperator(), s.newvalidators[0].GetOperator(), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10000000))), + malleate: func() error { + s.app.TxBoundaryKeepper.SetLimitPerAddr(s.ctx, addr2, types.LimitPerAddr{ + DelegateCount: 5, + ReledegateCount: 5, + LatestUpdateBlock: s.ctx.BlockHeight(), + }) + return nil + }, + blocksAdded: 4, + expErr: true, + }, + { + desc: "Case authz success update limit", + txMsg: &authz.MsgExec{Grantee: addr1.String(), Msgs: []*cdctypes.Any{msgDelegateAny}}, + malleate: func() error { + s.app.TxBoundaryKeepper.SetLimitPerAddr(s.ctx, addr2, types.LimitPerAddr{ + DelegateCount: 5, + ReledegateCount: 5, + LatestUpdateBlock: s.ctx.BlockHeight(), + }) + return nil + }, + blocksAdded: 4, + expErr: true, + }, + } { + tc := tc + s.SetupTest() + tc.malleate() + s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() + priv1, _, _ := testdata.KeyTestPubAddr() + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + + mfd := txboundaryAnte.NewStakingPermissionDecorator(s.app.AppCodec(), s.app.TxBoundaryKeepper) + antehandler := sdk.ChainAnteDecorators(mfd) + s.Require().NoError(s.txBuilder.SetMsgs(tc.txMsg)) + + tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) + s.Require().NoError(err) + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + tc.blocksAdded) + _, err = antehandler(s.ctx, tx, false) + if !tc.expErr { + s.Require().NoError(err) + } else { + s.Require().Error(err) + } + } +} diff --git a/x/tx-boundary/keeper/keeper.go b/x/tx-boundary/keeper/keeper.go index f02942f94..989ae7f83 100644 --- a/x/tx-boundary/keeper/keeper.go +++ b/x/tx-boundary/keeper/keeper.go @@ -149,10 +149,11 @@ func (k Keeper) UpdateLimitPerAddr(ctx sdk.Context, addr sdk.AccAddress) { return } boundary := k.GetDelegateBoundary(ctx) - if limitPerAddr.LatestUpdateBlock+int64(boundary.BlocksPerGeneration) >= ctx.BlockHeight() { + if limitPerAddr.LatestUpdateBlock+int64(boundary.BlocksPerGeneration) <= ctx.BlockHeight() { // Calculate the generated tx number from the duration between latest update block and current block height var generatedTx uint64 - duration := uint64(limitPerAddr.LatestUpdateBlock) + boundary.BlocksPerGeneration - uint64(ctx.BlockHeight()) + + duration := uint64(ctx.BlockHeight()) - uint64(limitPerAddr.LatestUpdateBlock) if duration/boundary.BlocksPerGeneration > 5 { generatedTx = 5 } else { @@ -173,6 +174,9 @@ func (k Keeper) UpdateLimitPerAddr(ctx sdk.Context, addr sdk.AccAddress) { } // Update LatestUpdateBlock limitPerAddr.LatestUpdateBlock = ctx.BlockHeight() + + // Set to store + k.SetLimitPerAddr(ctx, addr, limitPerAddr) return } }