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 }