github.com/cosmos/cosmos-sdk@v0.50.10/x/slashing/keeper/msg_server_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"time"
     5  
     6  	sdkmath "cosmossdk.io/math"
     7  
     8  	"github.com/cosmos/cosmos-sdk/testutil/testdata"
     9  	sdk "github.com/cosmos/cosmos-sdk/types"
    10  	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
    11  	"github.com/cosmos/cosmos-sdk/x/staking/types"
    12  )
    13  
    14  func (s *KeeperTestSuite) TestUpdateParams() {
    15  	require := s.Require()
    16  
    17  	minSignedPerWindow, err := sdkmath.LegacyNewDecFromStr("0.60")
    18  	require.NoError(err)
    19  
    20  	slashFractionDoubleSign, err := sdkmath.LegacyNewDecFromStr("0.022")
    21  	require.NoError(err)
    22  
    23  	slashFractionDowntime, err := sdkmath.LegacyNewDecFromStr("0.0089")
    24  	require.NoError(err)
    25  
    26  	invalidVal, err := sdkmath.LegacyNewDecFromStr("-1")
    27  	require.NoError(err)
    28  
    29  	testCases := []struct {
    30  		name      string
    31  		request   *slashingtypes.MsgUpdateParams
    32  		expectErr bool
    33  		expErrMsg string
    34  	}{
    35  		{
    36  			name: "set invalid authority",
    37  			request: &slashingtypes.MsgUpdateParams{
    38  				Authority: "foo",
    39  			},
    40  			expectErr: true,
    41  			expErrMsg: "invalid authority",
    42  		},
    43  		{
    44  			name: "set invalid signed blocks window",
    45  			request: &slashingtypes.MsgUpdateParams{
    46  				Authority: s.slashingKeeper.GetAuthority(),
    47  				Params: slashingtypes.Params{
    48  					SignedBlocksWindow:      0,
    49  					MinSignedPerWindow:      minSignedPerWindow,
    50  					DowntimeJailDuration:    time.Duration(34800000000000),
    51  					SlashFractionDoubleSign: slashFractionDoubleSign,
    52  					SlashFractionDowntime:   slashFractionDowntime,
    53  				},
    54  			},
    55  			expectErr: true,
    56  			expErrMsg: "signed blocks window must be positive",
    57  		},
    58  		{
    59  			name: "set invalid min signed per window",
    60  			request: &slashingtypes.MsgUpdateParams{
    61  				Authority: s.slashingKeeper.GetAuthority(),
    62  				Params: slashingtypes.Params{
    63  					SignedBlocksWindow:      int64(750),
    64  					MinSignedPerWindow:      invalidVal,
    65  					DowntimeJailDuration:    time.Duration(34800000000000),
    66  					SlashFractionDoubleSign: slashFractionDoubleSign,
    67  					SlashFractionDowntime:   slashFractionDowntime,
    68  				},
    69  			},
    70  			expectErr: true,
    71  			expErrMsg: "min signed per window cannot be negative",
    72  		},
    73  		{
    74  			name: "set invalid downtime jail duration",
    75  			request: &slashingtypes.MsgUpdateParams{
    76  				Authority: s.slashingKeeper.GetAuthority(),
    77  				Params: slashingtypes.Params{
    78  					SignedBlocksWindow:      int64(750),
    79  					MinSignedPerWindow:      minSignedPerWindow,
    80  					DowntimeJailDuration:    time.Duration(0),
    81  					SlashFractionDoubleSign: slashFractionDoubleSign,
    82  					SlashFractionDowntime:   slashFractionDowntime,
    83  				},
    84  			},
    85  			expectErr: true,
    86  			expErrMsg: "downtime jail duration must be positive",
    87  		},
    88  		{
    89  			name: "set invalid slash fraction double sign",
    90  			request: &slashingtypes.MsgUpdateParams{
    91  				Authority: s.slashingKeeper.GetAuthority(),
    92  				Params: slashingtypes.Params{
    93  					SignedBlocksWindow:      int64(750),
    94  					MinSignedPerWindow:      minSignedPerWindow,
    95  					DowntimeJailDuration:    time.Duration(10),
    96  					SlashFractionDoubleSign: invalidVal,
    97  					SlashFractionDowntime:   slashFractionDowntime,
    98  				},
    99  			},
   100  			expectErr: true,
   101  			expErrMsg: "double sign slash fraction cannot be negative",
   102  		},
   103  		{
   104  			name: "set invalid slash fraction downtime",
   105  			request: &slashingtypes.MsgUpdateParams{
   106  				Authority: s.slashingKeeper.GetAuthority(),
   107  				Params: slashingtypes.Params{
   108  					SignedBlocksWindow:      int64(750),
   109  					MinSignedPerWindow:      minSignedPerWindow,
   110  					DowntimeJailDuration:    time.Duration(10),
   111  					SlashFractionDoubleSign: slashFractionDoubleSign,
   112  					SlashFractionDowntime:   invalidVal,
   113  				},
   114  			},
   115  			expectErr: true,
   116  			expErrMsg: "downtime slash fraction cannot be negative",
   117  		},
   118  		{
   119  			name: "set full valid params",
   120  			request: &slashingtypes.MsgUpdateParams{
   121  				Authority: s.slashingKeeper.GetAuthority(),
   122  				Params: slashingtypes.Params{
   123  					SignedBlocksWindow:      int64(750),
   124  					MinSignedPerWindow:      minSignedPerWindow,
   125  					DowntimeJailDuration:    time.Duration(34800000000000),
   126  					SlashFractionDoubleSign: slashFractionDoubleSign,
   127  					SlashFractionDowntime:   slashFractionDowntime,
   128  				},
   129  			},
   130  			expectErr: false,
   131  		},
   132  	}
   133  
   134  	for _, tc := range testCases {
   135  		tc := tc
   136  		s.Run(tc.name, func() {
   137  			_, err := s.msgServer.UpdateParams(s.ctx, tc.request)
   138  			if tc.expectErr {
   139  				require.Error(err)
   140  				require.Contains(err.Error(), tc.expErrMsg)
   141  			} else {
   142  				require.NoError(err)
   143  			}
   144  		})
   145  	}
   146  }
   147  
   148  func (s *KeeperTestSuite) TestUnjail() {
   149  	testCases := []struct {
   150  		name      string
   151  		malleate  func() *slashingtypes.MsgUnjail
   152  		expErr    bool
   153  		expErrMsg string
   154  	}{
   155  		{
   156  			name: "invalid validator address: invalid request",
   157  			malleate: func() *slashingtypes.MsgUnjail {
   158  				return &slashingtypes.MsgUnjail{
   159  					ValidatorAddr: "invalid",
   160  				}
   161  			},
   162  			expErr:    true,
   163  			expErrMsg: "decoding bech32 failed",
   164  		},
   165  		{
   166  			name: "no self delegation: invalid request",
   167  			malleate: func() *slashingtypes.MsgUnjail {
   168  				_, pubKey, addr := testdata.KeyTestPubAddr()
   169  				valAddr := sdk.ValAddress(addr)
   170  				val, err := types.NewValidator(valAddr.String(), pubKey, types.Description{Moniker: "test"})
   171  				s.Require().NoError(err)
   172  
   173  				s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
   174  				s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(nil, nil)
   175  
   176  				return &slashingtypes.MsgUnjail{
   177  					ValidatorAddr: sdk.ValAddress(addr).String(),
   178  				}
   179  			},
   180  			expErr:    true,
   181  			expErrMsg: "validator has no self-delegation",
   182  		},
   183  		{
   184  			name: "validator not in the state: invalid request",
   185  			malleate: func() *slashingtypes.MsgUnjail {
   186  				_, _, addr := testdata.KeyTestPubAddr()
   187  				valAddr := sdk.ValAddress(addr)
   188  
   189  				s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(nil, nil)
   190  
   191  				return &slashingtypes.MsgUnjail{
   192  					ValidatorAddr: valAddr.String(),
   193  				}
   194  			},
   195  			expErr:    true,
   196  			expErrMsg: "address is not associated with any known validator",
   197  		},
   198  		{
   199  			name: "validator not jailed: invalid request",
   200  			malleate: func() *slashingtypes.MsgUnjail {
   201  				_, pubKey, addr := testdata.KeyTestPubAddr()
   202  				valAddr := sdk.ValAddress(addr)
   203  
   204  				val, err := types.NewValidator(valAddr.String(), pubKey, types.Description{Moniker: "test"})
   205  				val.Tokens = sdkmath.NewInt(1000)
   206  				val.DelegatorShares = sdkmath.LegacyNewDec(1)
   207  				val.Jailed = false
   208  
   209  				s.Require().NoError(err)
   210  
   211  				info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
   212  					time.Unix(2, 0), false, int64(10))
   213  
   214  				s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
   215  
   216  				s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
   217  				del := types.NewDelegation(addr.String(), valAddr.String(), sdkmath.LegacyNewDec(100))
   218  
   219  				s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
   220  
   221  				return &slashingtypes.MsgUnjail{
   222  					ValidatorAddr: sdk.ValAddress(addr).String(),
   223  				}
   224  			},
   225  			expErr:    true,
   226  			expErrMsg: "validator not jailed",
   227  		},
   228  		{
   229  			name: "validator tombstoned: invalid request",
   230  			malleate: func() *slashingtypes.MsgUnjail {
   231  				_, pubKey, addr := testdata.KeyTestPubAddr()
   232  				valAddr := sdk.ValAddress(addr)
   233  
   234  				val, err := types.NewValidator(valAddr.String(), pubKey, types.Description{Moniker: "test"})
   235  				val.Tokens = sdkmath.NewInt(1000)
   236  				val.DelegatorShares = sdkmath.LegacyNewDec(1)
   237  				val.Jailed = true
   238  
   239  				s.Require().NoError(err)
   240  
   241  				info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
   242  					time.Unix(2, 0), true, int64(10))
   243  
   244  				s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
   245  
   246  				s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
   247  				del := types.NewDelegation(addr.String(), valAddr.String(), sdkmath.LegacyNewDec(100))
   248  
   249  				s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
   250  
   251  				return &slashingtypes.MsgUnjail{
   252  					ValidatorAddr: sdk.ValAddress(addr).String(),
   253  				}
   254  			},
   255  			expErr:    true,
   256  			expErrMsg: "validator still jailed; cannot be unjailed",
   257  		},
   258  		{
   259  			name: "unjailing before wait period: invalid request",
   260  			malleate: func() *slashingtypes.MsgUnjail {
   261  				_, pubKey, addr := testdata.KeyTestPubAddr()
   262  				valAddr := sdk.ValAddress(addr)
   263  
   264  				val, err := types.NewValidator(valAddr.String(), pubKey, types.Description{Moniker: "test"})
   265  				val.Tokens = sdkmath.NewInt(1000)
   266  				val.DelegatorShares = sdkmath.LegacyNewDec(1)
   267  				val.Jailed = true
   268  
   269  				s.Require().NoError(err)
   270  
   271  				info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
   272  					s.ctx.BlockTime().AddDate(0, 0, 1), false, int64(10))
   273  
   274  				s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
   275  
   276  				s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
   277  				del := types.NewDelegation(addr.String(), valAddr.String(), sdkmath.LegacyNewDec(10000))
   278  
   279  				s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
   280  
   281  				return &slashingtypes.MsgUnjail{
   282  					ValidatorAddr: sdk.ValAddress(addr).String(),
   283  				}
   284  			},
   285  			expErr:    true,
   286  			expErrMsg: "validator still jailed; cannot be unjailed",
   287  		},
   288  		{
   289  			name: "valid request",
   290  			malleate: func() *slashingtypes.MsgUnjail {
   291  				_, pubKey, addr := testdata.KeyTestPubAddr()
   292  				valAddr := sdk.ValAddress(addr)
   293  
   294  				val, err := types.NewValidator(valAddr.String(), pubKey, types.Description{Moniker: "test"})
   295  				val.Tokens = sdkmath.NewInt(1000)
   296  				val.DelegatorShares = sdkmath.LegacyNewDec(1)
   297  
   298  				val.Jailed = true
   299  				s.Require().NoError(err)
   300  
   301  				info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
   302  					time.Unix(2, 0), false, int64(10))
   303  
   304  				s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
   305  
   306  				s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val, nil)
   307  				del := types.NewDelegation(addr.String(), valAddr.String(), sdkmath.LegacyNewDec(100))
   308  
   309  				s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del, nil)
   310  				s.stakingKeeper.EXPECT().Unjail(s.ctx, sdk.ConsAddress(addr)).Return(nil)
   311  
   312  				return &slashingtypes.MsgUnjail{
   313  					ValidatorAddr: sdk.ValAddress(addr).String(),
   314  				}
   315  			},
   316  			expErr: false,
   317  		},
   318  	}
   319  
   320  	for _, tc := range testCases {
   321  		tc := tc
   322  		s.Run(tc.name, func() {
   323  			req := tc.malleate()
   324  			_, err := s.msgServer.Unjail(s.ctx, req)
   325  
   326  			if tc.expErr {
   327  				s.Require().Error(err)
   328  				s.Require().Contains(err.Error(), tc.expErrMsg)
   329  			} else {
   330  				s.Require().NoError(err)
   331  			}
   332  		})
   333  	}
   334  }