github.com/Finschia/finschia-sdk@v0.48.1/x/authz/client/testutil/tx.go (about) 1 package testutil 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/gogo/protobuf/proto" 8 "github.com/stretchr/testify/suite" 9 10 "github.com/Finschia/finschia-sdk/client/flags" 11 "github.com/Finschia/finschia-sdk/crypto/hd" 12 "github.com/Finschia/finschia-sdk/crypto/keyring" 13 "github.com/Finschia/finschia-sdk/testutil" 14 clitestutil "github.com/Finschia/finschia-sdk/testutil/cli" 15 "github.com/Finschia/finschia-sdk/testutil/network" 16 sdk "github.com/Finschia/finschia-sdk/types" 17 "github.com/Finschia/finschia-sdk/x/authz/client/cli" 18 banktestutil "github.com/Finschia/finschia-sdk/x/bank/client/testutil" 19 bank "github.com/Finschia/finschia-sdk/x/bank/types" 20 govcli "github.com/Finschia/finschia-sdk/x/gov/client/cli" 21 govtestutil "github.com/Finschia/finschia-sdk/x/gov/client/testutil" 22 govtypes "github.com/Finschia/finschia-sdk/x/gov/types" 23 stakingcli "github.com/Finschia/finschia-sdk/x/staking/client/cli" 24 ) 25 26 type IntegrationTestSuite struct { 27 suite.Suite 28 29 cfg network.Config 30 network *network.Network 31 grantee []sdk.AccAddress 32 } 33 34 func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite { 35 return &IntegrationTestSuite{cfg: cfg} 36 } 37 38 func (s *IntegrationTestSuite) SetupSuite() { 39 s.T().Log("setting up integration test suite") 40 41 s.network = network.New(s.T(), s.cfg) 42 43 val := s.network.Validators[0] 44 s.grantee = make([]sdk.AccAddress, 2) 45 46 // Create new account in the keyring. 47 s.grantee[0] = s.createAccount("grantee1") 48 // Send some funds to the new account. 49 s.msgSendExec(s.grantee[0]) 50 51 _, err := s.network.WaitForHeight(1) 52 s.Require().NoError(err) 53 54 // create a proposal with deposit 55 _, err = govtestutil.MsgSubmitProposal(val.ClientCtx, val.Address.String(), 56 "Text Proposal 1", "Where is the title!?", govtypes.ProposalTypeText, 57 fmt.Sprintf("--%s=%s", govcli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, govtypes.DefaultMinDepositTokens).String())) 58 s.Require().NoError(err) 59 60 // Create new account in the keyring. 61 s.grantee[1] = s.createAccount("grantee2") 62 // Send some funds to the new account. 63 s.msgSendExec(s.grantee[1]) 64 65 // grant send authorization to grantee2 66 out, err := ExecGrant(val, []string{ 67 s.grantee[1].String(), 68 "send", 69 fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), 70 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 71 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 72 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 73 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()), 74 fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), 75 }) 76 s.Require().NoError(err) 77 s.Require().Contains(out.String(), `"code":0`) 78 79 _, err = s.network.WaitForHeight(1) 80 s.Require().NoError(err) 81 } 82 83 func (s *IntegrationTestSuite) createAccount(uid string) sdk.AccAddress { 84 val := s.network.Validators[0] 85 // Create new account in the keyring. 86 info, _, err := val.ClientCtx.Keyring.NewMnemonic(uid, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) 87 s.Require().NoError(err) 88 return sdk.AccAddress(info.GetPubKey().Address()) 89 } 90 91 func (s *IntegrationTestSuite) msgSendExec(grantee sdk.AccAddress) { 92 val := s.network.Validators[0] 93 // Send some funds to the new account. 94 out, err := banktestutil.MsgSendExec( 95 val.ClientCtx, 96 val.Address, 97 grantee, 98 sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 99 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 100 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 101 ) 102 s.Require().NoError(err) 103 s.Require().Contains(out.String(), `"code":0`) 104 } 105 106 func (s *IntegrationTestSuite) TearDownSuite() { 107 s.T().Log("tearing down integration test suite") 108 s.network.Cleanup() 109 } 110 111 var ( 112 typeMsgSend = bank.SendAuthorization{}.MsgTypeURL() 113 typeMsgVote = sdk.MsgTypeURL(&govtypes.MsgVote{}) 114 typeMsgSubmitProposal = sdk.MsgTypeURL(&govtypes.MsgSubmitProposal{}) 115 ) 116 117 func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { 118 val := s.network.Validators[0] 119 grantee := s.grantee[0] 120 121 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 122 pastHour := time.Now().Add(time.Minute * time.Duration(-60)).Unix() 123 124 testCases := []struct { 125 name string 126 args []string 127 expectedCode uint32 128 expectErr bool 129 }{ 130 { 131 "Invalid granter Address", 132 []string{ 133 "grantee_addr", 134 "send", 135 fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), 136 fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"), 137 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 138 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 139 }, 140 0, 141 true, 142 }, 143 { 144 "Invalid grantee Address", 145 []string{ 146 "grantee_addr", 147 "send", 148 fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), 149 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 150 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 151 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 152 }, 153 0, 154 true, 155 }, 156 { 157 "Invalid expiration time", 158 []string{ 159 grantee.String(), 160 "send", 161 fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), 162 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 163 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 164 fmt.Sprintf("--%s=%d", cli.FlagExpiration, pastHour), 165 }, 166 0xd, 167 false, // TODO: enable in v0.45 168 }, 169 { 170 "fail with error invalid msg-type", 171 []string{ 172 grantee.String(), 173 "generic", 174 fmt.Sprintf("--%s=invalid-msg-type", cli.FlagMsgType), 175 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 176 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 177 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 178 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 179 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 180 }, 181 0x1d, 182 false, 183 }, 184 { 185 "failed with error both validators not allowed", 186 []string{ 187 grantee.String(), 188 "delegate", 189 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 190 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 191 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 192 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 193 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 194 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 195 fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.ValAddress.String()), 196 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 197 }, 198 0, 199 true, 200 }, 201 { 202 "valid tx delegate authorization allowed validators", 203 []string{ 204 grantee.String(), 205 "delegate", 206 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 207 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 208 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 209 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 210 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 211 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 212 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 213 }, 214 0, 215 false, 216 }, 217 { 218 "valid tx delegate authorization deny validators", 219 []string{ 220 grantee.String(), 221 "delegate", 222 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 223 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 224 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 225 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 226 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 227 fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.ValAddress.String()), 228 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 229 }, 230 0, 231 false, 232 }, 233 { 234 "valid tx undelegate authorization", 235 []string{ 236 grantee.String(), 237 "unbond", 238 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 239 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 240 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 241 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 242 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 243 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 244 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 245 }, 246 0, 247 false, 248 }, 249 { 250 "valid tx redelegate authorization", 251 []string{ 252 grantee.String(), 253 "redelegate", 254 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 255 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 256 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 257 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 258 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 259 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 260 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 261 }, 262 0, 263 false, 264 }, 265 { 266 "Valid tx send authorization", 267 []string{ 268 grantee.String(), 269 "send", 270 fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), 271 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 272 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 273 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 274 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 275 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 276 }, 277 0, 278 false, 279 }, 280 { 281 "Valid tx generic authorization", 282 []string{ 283 grantee.String(), 284 "generic", 285 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 286 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 287 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 288 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 289 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 290 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 291 }, 292 0, 293 false, 294 }, 295 { 296 "Valid tx with amino", 297 []string{ 298 grantee.String(), 299 "generic", 300 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 301 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 302 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 303 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 304 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 305 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 306 fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), 307 }, 308 0, 309 false, 310 }, 311 } 312 313 for _, tc := range testCases { 314 tc := tc 315 s.Run(tc.name, func() { 316 clientCtx := val.ClientCtx 317 out, err := ExecGrant( 318 val, 319 tc.args, 320 ) 321 if tc.expectErr { 322 s.Require().Error(err) 323 } else { 324 var txResp sdk.TxResponse 325 s.Require().NoError(err) 326 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) 327 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 328 } 329 }) 330 } 331 } 332 333 func execDelegate(val *network.Validator, args []string) (testutil.BufferWriter, error) { 334 cmd := stakingcli.NewDelegateCmd() 335 clientCtx := val.ClientCtx 336 return clitestutil.ExecTestCLICmd(clientCtx, cmd, args) 337 } 338 339 func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() { 340 val := s.network.Validators[0] 341 342 grantee := s.grantee[0] 343 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 344 345 // send-authorization 346 _, err := ExecGrant( 347 val, 348 []string{ 349 grantee.String(), 350 "send", 351 fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), 352 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 353 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), 354 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 355 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 356 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 357 }, 358 ) 359 s.Require().NoError(err) 360 361 // generic-authorization 362 _, err = ExecGrant( 363 val, 364 []string{ 365 grantee.String(), 366 "generic", 367 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 368 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 369 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), 370 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 371 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 372 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 373 }, 374 ) 375 s.Require().NoError(err) 376 377 // generic-authorization used for amino testing 378 _, err = ExecGrant( 379 val, 380 []string{ 381 grantee.String(), 382 "generic", 383 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgSubmitProposal), 384 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 385 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), 386 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 387 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 388 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 389 fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), 390 }, 391 ) 392 s.Require().NoError(err) 393 394 testCases := []struct { 395 name string 396 args []string 397 respType proto.Message 398 expectedCode uint32 399 expectErr bool 400 }{ 401 { 402 "invalid grantee address", 403 []string{ 404 "invalid grantee", 405 typeMsgSend, 406 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 407 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 408 }, 409 nil, 410 0, 411 true, 412 }, 413 { 414 "invalid granter address", 415 []string{ 416 grantee.String(), 417 typeMsgSend, 418 fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"), 419 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 420 }, 421 nil, 422 0, 423 true, 424 }, 425 { 426 "Valid tx send authorization", 427 []string{ 428 grantee.String(), 429 typeMsgSend, 430 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 431 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 432 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 433 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 434 }, 435 &sdk.TxResponse{}, 0, 436 false, 437 }, 438 { 439 "Valid tx generic authorization", 440 []string{ 441 grantee.String(), 442 typeMsgVote, 443 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 444 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 445 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 446 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 447 }, 448 &sdk.TxResponse{}, 0, 449 false, 450 }, 451 { 452 "Valid tx with amino", 453 []string{ 454 grantee.String(), 455 typeMsgSubmitProposal, 456 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 457 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 458 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 459 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 460 fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), 461 }, 462 &sdk.TxResponse{}, 0, 463 false, 464 }, 465 } 466 for _, tc := range testCases { 467 tc := tc 468 s.Run(tc.name, func() { 469 cmd := cli.NewCmdRevokeAuthorization() 470 clientCtx := val.ClientCtx 471 472 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 473 if tc.expectErr { 474 s.Require().Error(err) 475 } else { 476 s.Require().NoError(err) 477 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 478 479 txResp := tc.respType.(*sdk.TxResponse) 480 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 481 } 482 }) 483 } 484 } 485 486 func (s *IntegrationTestSuite) TestExecAuthorizationWithExpiration() { 487 val := s.network.Validators[0] 488 grantee := s.grantee[0] 489 tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix() 490 491 _, err := ExecGrant( 492 val, 493 []string{ 494 grantee.String(), 495 "generic", 496 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 497 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 498 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 499 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 500 fmt.Sprintf("--%s=%d", cli.FlagExpiration, tenSeconds), 501 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 502 }, 503 ) 504 s.Require().NoError(err) 505 // msg vote 506 voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String()) 507 execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) 508 509 // waiting for authorization to expires 510 time.Sleep(12 * time.Second) 511 512 cmd := cli.NewCmdExecAuthorization() 513 clientCtx := val.ClientCtx 514 515 res, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ 516 execMsg.Name(), 517 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 518 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 519 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 520 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 521 }) 522 s.Require().NoError(err) 523 s.Require().Contains(res.String(), "authorization not found") 524 } 525 526 func (s *IntegrationTestSuite) TestNewExecGenericAuthorized() { 527 val := s.network.Validators[0] 528 grantee := s.grantee[0] 529 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 530 531 _, err := ExecGrant( 532 val, 533 []string{ 534 grantee.String(), 535 "generic", 536 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 537 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 538 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 539 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 540 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 541 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 542 }, 543 ) 544 s.Require().NoError(err) 545 546 // msg vote 547 voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String()) 548 execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) 549 550 testCases := []struct { 551 name string 552 args []string 553 respType proto.Message 554 expectedCode uint32 555 expectErr bool 556 }{ 557 { 558 "fail invalid grantee", 559 []string{ 560 execMsg.Name(), 561 fmt.Sprintf("--%s=%s", flags.FlagFrom, "grantee"), 562 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 563 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 564 }, 565 nil, 566 0, 567 true, 568 }, 569 { 570 "fail invalid json path", 571 []string{ 572 "/invalid/file.txt", 573 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 574 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 575 }, 576 nil, 577 0, 578 true, 579 }, 580 { 581 "valid txn", 582 []string{ 583 execMsg.Name(), 584 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 585 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 586 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 587 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 588 }, 589 &sdk.TxResponse{}, 590 0, 591 false, 592 }, 593 { 594 "valid tx with amino", 595 []string{ 596 execMsg.Name(), 597 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 598 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 599 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 600 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 601 fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), 602 }, 603 &sdk.TxResponse{}, 0, 604 false, 605 }, 606 } 607 608 for _, tc := range testCases { 609 tc := tc 610 s.Run(tc.name, func() { 611 cmd := cli.NewCmdExecAuthorization() 612 clientCtx := val.ClientCtx 613 614 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 615 if tc.expectErr { 616 s.Require().Error(err) 617 } else { 618 s.Require().NoError(err) 619 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 620 txResp := tc.respType.(*sdk.TxResponse) 621 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 622 } 623 }) 624 } 625 } 626 627 func (s *IntegrationTestSuite) TestNewExecGrantAuthorized() { 628 val := s.network.Validators[0] 629 grantee := s.grantee[0] 630 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 631 632 _, err := ExecGrant( 633 val, 634 []string{ 635 grantee.String(), 636 "send", 637 fmt.Sprintf("--%s=12%stoken", cli.FlagSpendLimit, val.Moniker), 638 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 639 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 640 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 641 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 642 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 643 }, 644 ) 645 s.Require().NoError(err) 646 tokens := sdk.NewCoins( 647 sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), sdk.NewInt(12)), 648 ) 649 normalGeneratedTx, err := banktestutil.MsgSendExec( 650 val.ClientCtx, 651 val.Address, 652 grantee, 653 tokens, 654 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 655 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 656 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 657 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 658 ) 659 s.Require().NoError(err) 660 execMsg := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String()) 661 testCases := []struct { 662 name string 663 args []string 664 expectedCode uint32 665 expectErr bool 666 }{ 667 { 668 "valid txn", 669 []string{ 670 execMsg.Name(), 671 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 672 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 673 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 674 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 675 }, 676 0, 677 false, 678 }, 679 { 680 "error over spent", 681 []string{ 682 execMsg.Name(), 683 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 684 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 685 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 686 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 687 }, 688 4, 689 false, 690 }, 691 } 692 693 for _, tc := range testCases { 694 tc := tc 695 s.Run(tc.name, func() { 696 cmd := cli.NewCmdExecAuthorization() 697 clientCtx := val.ClientCtx 698 699 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 700 if tc.expectErr { 701 s.Require().Error(err) 702 } else { 703 var response sdk.TxResponse 704 s.Require().NoError(err) 705 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 706 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 707 } 708 }) 709 } 710 } 711 712 func (s *IntegrationTestSuite) TestExecDelegateAuthorization() { 713 val := s.network.Validators[0] 714 grantee := s.grantee[0] 715 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 716 717 _, err := ExecGrant( 718 val, 719 []string{ 720 grantee.String(), 721 "delegate", 722 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 723 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 724 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 725 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 726 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 727 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 728 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 729 }, 730 ) 731 s.Require().NoError(err) 732 733 tokens := sdk.NewCoins( 734 sdk.NewCoin("stake", sdk.NewInt(50)), 735 ) 736 737 delegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), 738 tokens.GetDenomByIndex(0), tokens[0].Amount) 739 execMsg := testutil.WriteToNewTempFile(s.T(), delegateTx) 740 741 testCases := []struct { 742 name string 743 args []string 744 expectedCode uint32 745 expectErr bool 746 errMsg string 747 }{ 748 { 749 "valid txn: (delegate half tokens)", 750 []string{ 751 execMsg.Name(), 752 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 753 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 754 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 755 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 756 }, 757 0, 758 false, 759 "", 760 }, 761 { 762 "valid txn: (delegate remaining half tokens)", 763 []string{ 764 execMsg.Name(), 765 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 766 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 767 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 768 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 769 }, 770 0, 771 false, 772 "", 773 }, 774 { 775 "failed with error no authorization found", 776 []string{ 777 execMsg.Name(), 778 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 779 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 780 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 781 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 782 }, 783 4, 784 false, 785 "authorization not found", 786 }, 787 } 788 789 for _, tc := range testCases { 790 tc := tc 791 s.Run(tc.name, func() { 792 cmd := cli.NewCmdExecAuthorization() 793 clientCtx := val.ClientCtx 794 795 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 796 if tc.expectErr { 797 s.Require().Error(err) 798 s.Require().Contains(err.Error(), tc.errMsg) 799 } else { 800 var response sdk.TxResponse 801 s.Require().NoError(err) 802 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 803 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 804 } 805 }) 806 } 807 808 // test delegate no spend-limit 809 _, err = ExecGrant( 810 val, 811 []string{ 812 grantee.String(), 813 "delegate", 814 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 815 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 816 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 817 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 818 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 819 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 820 }, 821 ) 822 s.Require().NoError(err) 823 tokens = sdk.NewCoins( 824 sdk.NewCoin("stake", sdk.NewInt(50)), 825 ) 826 827 delegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), 828 tokens.GetDenomByIndex(0), tokens[0].Amount) 829 execMsg = testutil.WriteToNewTempFile(s.T(), delegateTx) 830 831 testCases = []struct { 832 name string 833 args []string 834 expectedCode uint32 835 expectErr bool 836 errMsg string 837 }{ 838 { 839 "valid txn", 840 []string{ 841 execMsg.Name(), 842 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 843 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 844 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 845 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 846 }, 847 0, 848 false, 849 "", 850 }, 851 { 852 "valid txn", 853 []string{ 854 execMsg.Name(), 855 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 856 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 857 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 858 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 859 }, 860 0, 861 false, 862 "", 863 }, 864 } 865 866 for _, tc := range testCases { 867 tc := tc 868 s.Run(tc.name, func() { 869 cmd := cli.NewCmdExecAuthorization() 870 clientCtx := val.ClientCtx 871 872 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 873 if tc.expectErr { 874 s.Require().Error(err) 875 s.Require().Contains(err.Error(), tc.errMsg) 876 } else { 877 var response sdk.TxResponse 878 s.Require().NoError(err) 879 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 880 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 881 } 882 }) 883 } 884 885 // test delegating to denied validator 886 _, err = ExecGrant( 887 val, 888 []string{ 889 grantee.String(), 890 "delegate", 891 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 892 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 893 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 894 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 895 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 896 fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.ValAddress.String()), 897 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 898 }, 899 ) 900 s.Require().NoError(err) 901 902 args := []string{ 903 execMsg.Name(), 904 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 905 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 906 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 907 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 908 } 909 cmd := cli.NewCmdExecAuthorization() 910 out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) 911 s.Require().NoError(err) 912 s.Contains(out.String(), fmt.Sprintf("cannot delegate/undelegate to %s validator", val.ValAddress.String())) 913 } 914 915 func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() { 916 val := s.network.Validators[0] 917 grantee := s.grantee[0] 918 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 919 920 // granting undelegate msg authorization 921 _, err := ExecGrant( 922 val, 923 []string{ 924 grantee.String(), 925 "unbond", 926 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 927 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 928 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 929 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 930 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 931 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 932 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 933 }, 934 ) 935 s.Require().NoError(err) 936 937 // delegating stakes to validator 938 _, err = execDelegate( 939 val, 940 []string{ 941 val.ValAddress.String(), 942 "100stake", 943 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 944 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 945 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 946 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 947 }, 948 ) 949 s.Require().NoError(err) 950 951 tokens := sdk.NewCoins( 952 sdk.NewCoin("stake", sdk.NewInt(50)), 953 ) 954 955 undelegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), 956 tokens.GetDenomByIndex(0), tokens[0].Amount) 957 execMsg := testutil.WriteToNewTempFile(s.T(), undelegateTx) 958 959 testCases := []struct { 960 name string 961 args []string 962 expectedCode uint32 963 expectErr bool 964 errMsg string 965 }{ 966 { 967 "valid txn: (undelegate half tokens)", 968 []string{ 969 execMsg.Name(), 970 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 971 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 972 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 973 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 974 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 975 }, 976 0, 977 false, 978 "", 979 }, 980 { 981 "valid txn: (undelegate remaining half tokens)", 982 []string{ 983 execMsg.Name(), 984 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 985 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 986 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 987 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 988 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 989 }, 990 0, 991 false, 992 "", 993 }, 994 { 995 "failed with error no authorization found", 996 []string{ 997 execMsg.Name(), 998 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 999 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 1000 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1001 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1002 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1003 }, 1004 4, 1005 false, 1006 "authorization not found", 1007 }, 1008 } 1009 1010 for _, tc := range testCases { 1011 tc := tc 1012 s.Run(tc.name, func() { 1013 cmd := cli.NewCmdExecAuthorization() 1014 clientCtx := val.ClientCtx 1015 1016 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1017 if tc.expectErr { 1018 s.Require().Error(err) 1019 s.Require().Contains(err.Error(), tc.errMsg) 1020 } else { 1021 var response sdk.TxResponse 1022 s.Require().NoError(err) 1023 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 1024 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 1025 } 1026 }) 1027 } 1028 1029 // grant undelegate authorization without limit 1030 _, err = ExecGrant( 1031 val, 1032 []string{ 1033 grantee.String(), 1034 "unbond", 1035 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1036 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1037 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1038 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 1039 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 1040 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1041 }, 1042 ) 1043 s.Require().NoError(err) 1044 tokens = sdk.NewCoins( 1045 sdk.NewCoin("stake", sdk.NewInt(50)), 1046 ) 1047 1048 undelegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), 1049 tokens.GetDenomByIndex(0), tokens[0].Amount) 1050 execMsg = testutil.WriteToNewTempFile(s.T(), undelegateTx) 1051 1052 testCases = []struct { 1053 name string 1054 args []string 1055 expectedCode uint32 1056 expectErr bool 1057 errMsg string 1058 }{ 1059 { 1060 "valid txn", 1061 []string{ 1062 execMsg.Name(), 1063 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 1064 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 1065 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1066 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1067 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1068 }, 1069 0, 1070 false, 1071 "", 1072 }, 1073 { 1074 "valid txn", 1075 []string{ 1076 execMsg.Name(), 1077 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 1078 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 1079 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1080 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1081 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1082 }, 1083 0, 1084 false, 1085 "", 1086 }, 1087 } 1088 1089 for _, tc := range testCases { 1090 tc := tc 1091 s.Run(tc.name, func() { 1092 cmd := cli.NewCmdExecAuthorization() 1093 clientCtx := val.ClientCtx 1094 1095 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1096 if tc.expectErr { 1097 s.Require().Error(err) 1098 s.Require().Contains(err.Error(), tc.errMsg) 1099 } else { 1100 var response sdk.TxResponse 1101 s.Require().NoError(err) 1102 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 1103 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 1104 } 1105 }) 1106 } 1107 }