github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/distribution/handler_test.go (about)

     1  package distribution
     2  
     3  import (
     4  	"testing"
     5  
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
     8  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
     9  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    10  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    11  	"github.com/fibonacci-chain/fbc/x/distribution/keeper"
    12  	"github.com/fibonacci-chain/fbc/x/distribution/types"
    13  	"github.com/fibonacci-chain/fbc/x/staking"
    14  	stakingtypes "github.com/fibonacci-chain/fbc/x/staking/types"
    15  	"github.com/stretchr/testify/require"
    16  	"github.com/stretchr/testify/suite"
    17  )
    18  
    19  type HandlerSuite struct {
    20  	suite.Suite
    21  }
    22  
    23  func TestHandlerSuite(t *testing.T) {
    24  	suite.Run(t, new(HandlerSuite))
    25  }
    26  
    27  func (suite *HandlerSuite) TestHandlerWithdrawDelegatorReward() {
    28  	testCases := []struct {
    29  		title    string
    30  		dochange func(ctx sdk.Context, dk Keeper)
    31  		errors   [4]sdk.Error
    32  	}{
    33  		{
    34  			"change distribution type",
    35  			func(ctx sdk.Context, dk Keeper) {
    36  				tmtypes.UnittestOnlySetMilestoneVenus2Height(-1)
    37  				proposal := types.NewChangeDistributionTypeProposal("change distri type", "", types.DistributionTypeOnChain)
    38  				keeper.HandleChangeDistributionTypeProposal(ctx, dk, proposal)
    39  				require.Equal(suite.T(), dk.GetDistributionType(ctx), types.DistributionTypeOnChain)
    40  			},
    41  			[4]sdk.Error{types.ErrUnknownDistributionMsgType(), types.ErrCodeEmptyDelegationDistInfo(), nil, nil},
    42  		},
    43  		{
    44  			"set withdraw reward disable",
    45  			func(ctx sdk.Context, dk Keeper) {
    46  				tmtypes.UnittestOnlySetMilestoneVenus2Height(-1)
    47  				proposal := types.NewChangeDistributionTypeProposal("change distri type", "", types.DistributionTypeOnChain)
    48  				keeper.HandleChangeDistributionTypeProposal(ctx, dk, proposal)
    49  				require.Equal(suite.T(), dk.GetDistributionType(ctx), types.DistributionTypeOnChain)
    50  
    51  				proposalWithdrawReward := types.NewWithdrawRewardEnabledProposal("title", "description", false)
    52  				keeper.HandleWithdrawRewardEnabledProposal(ctx, dk, proposalWithdrawReward)
    53  				require.Equal(suite.T(), false, dk.GetWithdrawRewardEnabled(ctx))
    54  			},
    55  			[4]sdk.Error{types.ErrUnknownDistributionMsgType(), types.ErrCodeDisabledWithdrawRewards(),
    56  				stakingtypes.ErrCodeDisabledOperate(), types.ErrCodeDisabledWithdrawRewards()},
    57  		},
    58  		{
    59  			"no change distribution type",
    60  			func(ctx sdk.Context, dk Keeper) {
    61  
    62  			},
    63  			[4]sdk.Error{types.ErrUnknownDistributionMsgType(), types.ErrUnknownDistributionMsgType(), nil, types.ErrUnknownDistributionMsgType()},
    64  		},
    65  	}
    66  
    67  	for _, tc := range testCases {
    68  		suite.Run(tc.title, func() {
    69  			ctx, _, dk, sk, _ := keeper.CreateTestInputDefault(suite.T(), false, 10)
    70  			handler := NewHandler(dk)
    71  			delAddr1 := keeper.TestDelAddrs[0]
    72  			valAddr1 := keeper.TestValAddrs[0]
    73  
    74  			valOpAddrs := []sdk.ValAddress{valAddr1}
    75  
    76  			msg := NewMsgWithdrawDelegatorReward(delAddr1, valAddr1)
    77  			_, err := handler(ctx, msg)
    78  			require.Equal(suite.T(), tc.errors[0], err)
    79  
    80  			msg2 := NewMsgWithdrawDelegatorAllRewards(delAddr1)
    81  			_, err = handler(ctx, msg2)
    82  			require.Equal(suite.T(), tc.errors[0], err)
    83  
    84  			tc.dochange(ctx, dk)
    85  
    86  			// no deposit and add shares
    87  			_, err = handler(ctx, msg)
    88  			require.Equal(suite.T(), tc.errors[1], err)
    89  
    90  			// deposit and add shares
    91  			keeper.DoDepositWithError(suite.T(), ctx, sk, delAddr1, sdk.NewCoin(sk.BondDenom(ctx), sdk.NewInt(100)), tc.errors[2])
    92  			keeper.DoAddSharesWithError(suite.T(), ctx, sk, delAddr1, valOpAddrs, tc.errors[2])
    93  
    94  			_, err = handler(ctx, msg)
    95  			require.Equal(suite.T(), tc.errors[3], err)
    96  		})
    97  	}
    98  }
    99  
   100  type allocationParam struct {
   101  	totalPower int64
   102  	isVote     []bool
   103  	isJailed   []bool
   104  	fee        sdk.SysCoins
   105  }
   106  
   107  func createVotes(ctx sdk.Context, sk staking.Keeper, test allocationParam) []abci.VoteInfo {
   108  	var votes []abci.VoteInfo
   109  	for i := int64(0); i < int64(len(test.isVote)); i++ {
   110  		if test.isJailed[i] {
   111  			sk.Jail(ctx, keeper.TestConsAddrs[i])
   112  		}
   113  		abciVal := abci.Validator{Address: keeper.TestConsAddrs[i], Power: i + 1}
   114  		if test.isVote[i] {
   115  			votes = append(votes, abci.VoteInfo{Validator: abciVal, SignedLastBlock: true})
   116  		}
   117  	}
   118  	return votes
   119  }
   120  
   121  func (suite *HandlerSuite) TestHandlerWithdrawValidatorCommission() {
   122  	testCases := []struct {
   123  		title            string
   124  		doAllocateTokens func(ctx sdk.Context, ak auth.AccountKeeper, dk Keeper, sk staking.Keeper, supplyKeeper types.SupplyKeeper)
   125  		dochange         func(ctx sdk.Context, dk Keeper)
   126  		errors           [2]sdk.Error
   127  	}{
   128  		{
   129  			"normal, no change distribution type",
   130  			func(ctx sdk.Context, ak auth.AccountKeeper, dk Keeper, sk staking.Keeper, supplyKeeper types.SupplyKeeper) {
   131  				feeCollector := supplyKeeper.GetModuleAccount(ctx, auth.FeeCollectorName)
   132  				require.NotNil(suite.T(), feeCollector)
   133  				err := feeCollector.SetCoins(sdk.SysCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(int64(100))}})
   134  				require.NoError(suite.T(), err)
   135  				ak.SetAccount(ctx, feeCollector)
   136  				allocationParam := allocationParam{
   137  					10,
   138  					[]bool{true, true, true, true}, []bool{false, false, false, false},
   139  					nil,
   140  				}
   141  				votes := createVotes(ctx, sk, allocationParam)
   142  				dk.AllocateTokens(ctx, 1, keeper.TestConsAddrs[0], votes)
   143  				require.Nil(suite.T(), err)
   144  			},
   145  			func(ctx sdk.Context, dk Keeper) {},
   146  			[2]sdk.Error{types.ErrNoValidatorCommission(), nil},
   147  		},
   148  		{
   149  			"no allocate tokens, no change distribution type",
   150  			func(ctx sdk.Context, ak auth.AccountKeeper, dk Keeper, sk staking.Keeper, supplyKeeper types.SupplyKeeper) {
   151  
   152  			},
   153  			func(ctx sdk.Context, dk Keeper) {},
   154  			[2]sdk.Error{types.ErrNoValidatorCommission(), types.ErrNoValidatorCommission()},
   155  		},
   156  		{
   157  			"normal, change distribution type",
   158  			func(ctx sdk.Context, ak auth.AccountKeeper, dk Keeper, sk staking.Keeper, supplyKeeper types.SupplyKeeper) {
   159  				feeCollector := supplyKeeper.GetModuleAccount(ctx, auth.FeeCollectorName)
   160  				require.NotNil(suite.T(), feeCollector)
   161  				err := feeCollector.SetCoins(sdk.SysCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(int64(100))}})
   162  				require.NoError(suite.T(), err)
   163  				ak.SetAccount(ctx, feeCollector)
   164  				allocationParam := allocationParam{
   165  					10,
   166  					[]bool{true, true, true, true}, []bool{false, false, false, false},
   167  					nil,
   168  				}
   169  				votes := createVotes(ctx, sk, allocationParam)
   170  				dk.AllocateTokens(ctx, 1, keeper.TestConsAddrs[0], votes)
   171  				require.Nil(suite.T(), err)
   172  			},
   173  			func(ctx sdk.Context, dk Keeper) {
   174  				tmtypes.UnittestOnlySetMilestoneVenus2Height(-1)
   175  				proposal := types.NewChangeDistributionTypeProposal("change distri type", "", types.DistributionTypeOnChain)
   176  				keeper.HandleChangeDistributionTypeProposal(ctx, dk, proposal)
   177  				require.Equal(suite.T(), dk.GetDistributionType(ctx), types.DistributionTypeOnChain)
   178  			},
   179  			[2]sdk.Error{types.ErrNoValidatorCommission(), nil},
   180  		},
   181  		{
   182  			"no allocate tokens, change distribution type",
   183  			func(ctx sdk.Context, ak auth.AccountKeeper, dk Keeper, sk staking.Keeper, supplyKeeper types.SupplyKeeper) {
   184  				tmtypes.UnittestOnlySetMilestoneVenus2Height(-1)
   185  				proposal := types.NewChangeDistributionTypeProposal("change distri type", "", types.DistributionTypeOnChain)
   186  				keeper.HandleChangeDistributionTypeProposal(ctx, dk, proposal)
   187  				require.Equal(suite.T(), dk.GetDistributionType(ctx), types.DistributionTypeOnChain)
   188  			},
   189  			func(ctx sdk.Context, dk Keeper) {},
   190  			[2]sdk.Error{types.ErrNoValidatorCommission(), types.ErrNoValidatorCommission()},
   191  		},
   192  		{
   193  			"normal, no impact when set withdraw reward disable",
   194  			func(ctx sdk.Context, ak auth.AccountKeeper, dk Keeper, sk staking.Keeper, supplyKeeper types.SupplyKeeper) {
   195  				feeCollector := supplyKeeper.GetModuleAccount(ctx, auth.FeeCollectorName)
   196  				require.NotNil(suite.T(), feeCollector)
   197  				err := feeCollector.SetCoins(sdk.SysCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(int64(100))}})
   198  				require.NoError(suite.T(), err)
   199  				ak.SetAccount(ctx, feeCollector)
   200  				allocationParam := allocationParam{
   201  					10,
   202  					[]bool{true, true, true, true}, []bool{false, false, false, false},
   203  					nil,
   204  				}
   205  				votes := createVotes(ctx, sk, allocationParam)
   206  				dk.AllocateTokens(ctx, 1, keeper.TestConsAddrs[0], votes)
   207  				require.Nil(suite.T(), err)
   208  			},
   209  			func(ctx sdk.Context, dk Keeper) {
   210  				tmtypes.UnittestOnlySetMilestoneVenus2Height(-1)
   211  				proposal := types.NewChangeDistributionTypeProposal("change distri type", "", types.DistributionTypeOnChain)
   212  				keeper.HandleChangeDistributionTypeProposal(ctx, dk, proposal)
   213  				require.Equal(suite.T(), dk.GetDistributionType(ctx), types.DistributionTypeOnChain)
   214  
   215  				proposalWithdrawReward := types.NewWithdrawRewardEnabledProposal("title", "description", false)
   216  				keeper.HandleWithdrawRewardEnabledProposal(ctx, dk, proposalWithdrawReward)
   217  				require.Equal(suite.T(), false, dk.GetWithdrawRewardEnabled(ctx))
   218  			},
   219  			[2]sdk.Error{types.ErrNoValidatorCommission(), types.ErrCodeDisabledWithdrawRewards()},
   220  		},
   221  	}
   222  
   223  	for _, tc := range testCases {
   224  		suite.Run(tc.title, func() {
   225  			ctx, ak, dk, sk, supplyKeeper := keeper.CreateTestInputDefault(suite.T(), false, 10)
   226  			handler := NewHandler(dk)
   227  			valAddr1 := keeper.TestValAddrs[0]
   228  
   229  			msg := NewMsgWithdrawValidatorCommission(valAddr1)
   230  
   231  			_, err := handler(ctx, msg)
   232  			require.Equal(suite.T(), tc.errors[0], err)
   233  
   234  			staking.EndBlocker(ctx, sk)
   235  			tc.dochange(ctx, dk)
   236  			tc.doAllocateTokens(ctx, ak, dk, sk, supplyKeeper)
   237  			_, err = handler(ctx, msg)
   238  			require.Equal(suite.T(), tc.errors[1], err)
   239  		})
   240  	}
   241  }
   242  
   243  func (suite *HandlerSuite) TestWithdrawDisabled() {
   244  	type param struct {
   245  		blockVersion int64
   246  		enable       bool
   247  		expectError  error
   248  	}
   249  
   250  	testCases := []struct {
   251  		title   string
   252  		execute func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int)
   253  		params  []param
   254  	}{
   255  		{
   256  			"create val",
   257  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   258  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   259  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   260  				DoCreateValidatorWithError(suite.T(), *ctx, sk, keeper.TestValAddrs[0], nil, p.expectError)
   261  			},
   262  			[]param{
   263  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   264  				{-1, true, stakingtypes.ErrValidatorOwnerExists()},
   265  				{0, false, stakingtypes.ErrValidatorOwnerExists()},
   266  				{0, true, stakingtypes.ErrValidatorOwnerExists()},
   267  			},
   268  		},
   269  		{
   270  			"disable edit val",
   271  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   272  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   273  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   274  				DoEditValidatorWithError(suite.T(), *ctx, sk, keeper.TestValAddrs[0], sdk.NewDec(0), p.expectError)
   275  			},
   276  			[]param{
   277  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   278  				{-1, true, stakingtypes.ErrCommissionUpdateTime()},
   279  			},
   280  		},
   281  		{
   282  			"disable destroy val",
   283  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   284  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   285  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   286  				DoDestroyValidatorWithError(suite.T(), *ctx, sk, keeper.TestValAccAddrs[i], p.expectError)
   287  			},
   288  			[]param{
   289  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   290  				{-1, true, nil},
   291  				{0, false, nil},
   292  				{0, true, nil},
   293  			},
   294  		},
   295  		{
   296  			"disable withdraw DoAddShares",
   297  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   298  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   299  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   300  				DoAddSharesWithError(suite.T(), *ctx, sk, keeper.TestDelAddrs[0], valOpAddrs, p.expectError)
   301  			},
   302  			[]param{
   303  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   304  				{-1, true, nil},
   305  				{0, false, nil},
   306  				{0, true, nil},
   307  			},
   308  		},
   309  		{
   310  			"disable withdraw DoRegProxy",
   311  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   312  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   313  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   314  				DoRegProxyWithError(suite.T(), *ctx, sk, keeper.TestDelAddrs[i], true, p.expectError)
   315  			},
   316  			[]param{
   317  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   318  				{-1, true, nil},
   319  				{0, false, nil},
   320  				{0, true, nil},
   321  			},
   322  		},
   323  		{
   324  			"disable withdraw DoWithdraw",
   325  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   326  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   327  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   328  				DoWithdrawWithError(suite.T(), *ctx, sk, keeper.TestDelAddrs[i], sdk.NewCoin(sk.BondDenom(*ctx),
   329  					sdk.NewInt(100)), p.expectError)
   330  			},
   331  			[]param{
   332  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   333  				{-1, true, nil},
   334  				{0, false, nil},
   335  				{0, true, nil},
   336  			},
   337  		},
   338  		{
   339  			"disable withdraw DoBindProxy",
   340  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   341  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   342  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   343  				DoBindProxyWithError(suite.T(), *ctx, sk, keeper.TestDelAddrs[i+1], keeper.TestDelAddrs[0], p.expectError)
   344  				tmtypes.UnittestOnlySetMilestoneVenus2Height(-1)
   345  				dk.SetWithdrawRewardEnabled(*ctx, true)
   346  			},
   347  			[]param{
   348  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   349  				{-1, true, nil},
   350  				{0, false, nil},
   351  			},
   352  		},
   353  		{
   354  			"disable withdraw DoUnBindProxy",
   355  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   356  				DoBindProxyWithError(suite.T(), *ctx, sk, keeper.TestDelAddrs[i+1], keeper.TestDelAddrs[0], nil)
   357  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   358  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   359  				DoUnBindProxyWithError(suite.T(), *ctx, sk, keeper.TestDelAddrs[i+1], p.expectError)
   360  				tmtypes.UnittestOnlySetMilestoneVenus2Height(-1)
   361  				dk.SetWithdrawRewardEnabled(*ctx, true)
   362  			},
   363  			[]param{
   364  				{-1, false, stakingtypes.ErrCodeDisabledOperate()},
   365  				{-1, true, nil},
   366  				{0, false, nil},
   367  			},
   368  		},
   369  		{
   370  			"disable withdraw address",
   371  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   372  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   373  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   374  				DoSetWithdrawAddressWithError(suite.T(), *ctx, dk, keeper.TestDelAddrs[i], p.expectError)
   375  			},
   376  			[]param{
   377  				{-1, false, types.ErrCodeDisabledWithdrawRewards()},
   378  				{-1, true, nil},
   379  				{0, false, nil},
   380  				{0, true, nil},
   381  			},
   382  		},
   383  		{
   384  			"disable withdraw validator commission",
   385  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   386  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   387  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   388  				DoWithdrawValidatorCommissionWithError(suite.T(), *ctx, dk, keeper.TestValAddrs[0], p.expectError)
   389  			},
   390  			[]param{
   391  				{-1, false, types.ErrCodeDisabledWithdrawRewards()},
   392  				{-1, true, types.ErrNoValidatorCommission()},
   393  				{0, false, types.ErrNoValidatorCommission()},
   394  				{0, true, types.ErrNoValidatorCommission()},
   395  			},
   396  		},
   397  		{
   398  			"disable set withdraw address",
   399  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   400  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   401  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   402  				DoSetWithdrawAddressWithError(suite.T(), *ctx, dk, keeper.TestDelAddrs[i], p.expectError)
   403  			},
   404  			[]param{
   405  				{-1, false, types.ErrCodeDisabledWithdrawRewards()},
   406  				{-1, true, nil},
   407  				{0, false, nil},
   408  				{0, true, nil},
   409  			},
   410  		},
   411  		{
   412  			"disable set withdraw delegator reward",
   413  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   414  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   415  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   416  				DoWithdrawDelegatorRewardWithError(suite.T(), *ctx, dk, keeper.TestDelAddrs[0], keeper.TestValAddrs[0], p.expectError)
   417  			},
   418  			[]param{
   419  				{-1, false, types.ErrCodeDisabledWithdrawRewards()},
   420  				{-1, true, types.ErrUnknownDistributionMsgType()},
   421  				{0, false, types.ErrUnknownDistributionMsgType()},
   422  				{0, true, types.ErrUnknownDistributionMsgType()},
   423  			},
   424  		},
   425  		{
   426  			"disable set withdraw delegator all reward",
   427  			func(ctx *sdk.Context, dk Keeper, sk staking.Keeper, valOpAddrs []sdk.ValAddress, p param, i int) {
   428  				tmtypes.UnittestOnlySetMilestoneVenus2Height(p.blockVersion)
   429  				dk.SetWithdrawRewardEnabled(*ctx, p.enable)
   430  				DoWithdrawDelegatorAllRewardWithError(suite.T(), *ctx, dk, keeper.TestDelAddrs[0], p.expectError)
   431  			},
   432  			[]param{
   433  				{-1, false, types.ErrCodeDisabledWithdrawRewards()},
   434  				{-1, true, types.ErrUnknownDistributionMsgType()},
   435  				{0, false, types.ErrUnknownDistributionMsgType()},
   436  				{0, true, types.ErrUnknownDistributionMsgType()},
   437  			},
   438  		},
   439  	}
   440  
   441  	for _, tc := range testCases {
   442  		suite.Run(tc.title, func() {
   443  			communityTax := sdk.NewDecWithPrec(2, 2)
   444  			ctx, _, _, dk, sk, _, _ := keeper.CreateTestInputAdvanced(suite.T(), false, 1000, communityTax)
   445  			valOpAddrs, valConsPks, _ := keeper.GetTestAddrs()
   446  			for i, _ := range valOpAddrs {
   447  				keeper.DoCreateValidator(suite.T(), ctx, sk, valOpAddrs[i], valConsPks[i])
   448  			}
   449  			// end block to bond validator
   450  			staking.EndBlocker(ctx, sk)
   451  			//delegation
   452  			for _, v := range keeper.TestDelAddrs {
   453  				keeper.DoDeposit(suite.T(), ctx, sk, v, sdk.NewCoin(sk.BondDenom(ctx), sdk.NewInt(100)))
   454  				keeper.DoAddShares(suite.T(), ctx, sk, v, valOpAddrs)
   455  			}
   456  
   457  			DoRegProxyWithError(suite.T(), ctx, sk, keeper.TestDelAddrs[0], true, nil)
   458  			DoDepositWithError(suite.T(), ctx, sk, keeper.TestDelAddrs[0], sdk.NewCoin(sk.BondDenom(ctx), sdk.NewInt(100)), nil)
   459  
   460  			for i, p := range tc.params {
   461  				tc.execute(&ctx, dk, sk, valOpAddrs, p, i)
   462  			}
   463  
   464  			proposal := types.NewChangeDistributionTypeProposal("change distri type", "", types.DistributionTypeOnChain)
   465  			keeper.HandleChangeDistributionTypeProposal(ctx, dk, proposal)
   466  		})
   467  	}
   468  }
   469  
   470  func DoCreateValidatorWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, valAddr sdk.ValAddress, valConsPk crypto.PubKey, expectError error) {
   471  	s := staking.NewHandler(sk)
   472  	msg := staking.NewMsgCreateValidator(valAddr, valConsPk, staking.Description{}, keeper.NewTestSysCoin(1, 0))
   473  	_, e := s(ctx, msg)
   474  	require.Equal(t, expectError, e)
   475  }
   476  
   477  func DoEditValidatorWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, valAddr sdk.ValAddress, newRate sdk.Dec, expectError error) {
   478  	h := staking.NewHandler(sk)
   479  	msg := staking.NewMsgEditValidatorCommissionRate(valAddr, newRate)
   480  	_, e := h(ctx, msg)
   481  	require.Equal(t, expectError, e)
   482  }
   483  
   484  func DoWithdrawWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, delAddr sdk.AccAddress, amount sdk.SysCoin, expectError error) {
   485  	h := staking.NewHandler(sk)
   486  	msg := staking.NewMsgWithdraw(delAddr, amount)
   487  	_, e := h(ctx, msg)
   488  	require.Equal(t, expectError, e)
   489  }
   490  
   491  func DoDestroyValidatorWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, delAddr sdk.AccAddress, expectError error) {
   492  	h := staking.NewHandler(sk)
   493  	msg := staking.NewMsgDestroyValidator(delAddr)
   494  	_, e := h(ctx, msg)
   495  	require.Equal(t, expectError, e)
   496  }
   497  
   498  func DoDepositWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, delAddr sdk.AccAddress, amount sdk.SysCoin, expectError error) {
   499  	h := staking.NewHandler(sk)
   500  	msg := staking.NewMsgDeposit(delAddr, amount)
   501  	_, e := h(ctx, msg)
   502  	require.Equal(t, expectError, e)
   503  }
   504  
   505  func DoAddSharesWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, delAddr sdk.AccAddress, valAddrs []sdk.ValAddress, expectError error) {
   506  	h := staking.NewHandler(sk)
   507  	msg := staking.NewMsgAddShares(delAddr, valAddrs)
   508  	_, e := h(ctx, msg)
   509  	require.Equal(t, expectError, e)
   510  }
   511  
   512  func DoRegProxyWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, delAddr sdk.AccAddress, reg bool, expectError error) {
   513  	h := staking.NewHandler(sk)
   514  	msg := staking.NewMsgRegProxy(delAddr, reg)
   515  	_, e := h(ctx, msg)
   516  	require.Equal(t, expectError, e)
   517  }
   518  
   519  func DoBindProxyWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, delAddr sdk.AccAddress, proxyAddr sdk.AccAddress, expectError error) {
   520  	h := staking.NewHandler(sk)
   521  	msg := staking.NewMsgBindProxy(delAddr, proxyAddr)
   522  	_, e := h(ctx, msg)
   523  	require.Equal(t, expectError, e)
   524  }
   525  
   526  func DoUnBindProxyWithError(t *testing.T, ctx sdk.Context, sk staking.Keeper, delAddr sdk.AccAddress, expectError error) {
   527  	h := staking.NewHandler(sk)
   528  	msg := staking.NewMsgUnbindProxy(delAddr)
   529  	_, e := h(ctx, msg)
   530  	require.Equal(t, expectError, e)
   531  }
   532  
   533  func DoSetWithdrawAddressWithError(t *testing.T, ctx sdk.Context, dk Keeper, delAddr sdk.AccAddress, expectError error) {
   534  	h := NewHandler(dk)
   535  	msg := NewMsgSetWithdrawAddress(delAddr, delAddr)
   536  	_, e := h(ctx, msg)
   537  	require.Equal(t, expectError, e)
   538  }
   539  
   540  func DoWithdrawValidatorCommissionWithError(t *testing.T, ctx sdk.Context, dk Keeper, valAddr sdk.ValAddress, expectError error) {
   541  	h := NewHandler(dk)
   542  	msg := NewMsgWithdrawValidatorCommission(valAddr)
   543  	_, e := h(ctx, msg)
   544  	require.Equal(t, expectError, e)
   545  }
   546  
   547  func DoWithdrawDelegatorRewardWithError(t *testing.T, ctx sdk.Context, dk Keeper, delAddr sdk.AccAddress,
   548  	valAddr sdk.ValAddress, expectError error) {
   549  	h := NewHandler(dk)
   550  	msg := NewMsgWithdrawDelegatorReward(delAddr, valAddr)
   551  	_, e := h(ctx, msg)
   552  	require.Equal(t, expectError, e)
   553  }
   554  
   555  func DoWithdrawDelegatorAllRewardWithError(t *testing.T, ctx sdk.Context, dk Keeper, delAddr sdk.AccAddress, expectError error) {
   556  	h := NewHandler(dk)
   557  	msg := NewMsgWithdrawDelegatorAllRewards(delAddr)
   558  	_, e := h(ctx, msg)
   559  	require.Equal(t, expectError, e)
   560  }