github.com/Finschia/finschia-sdk@v0.49.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 s.Run(tc.name, func() { 315 clientCtx := val.ClientCtx 316 out, err := ExecGrant( 317 val, 318 tc.args, 319 ) 320 if tc.expectErr { 321 s.Require().Error(err) 322 } else { 323 var txResp sdk.TxResponse 324 s.Require().NoError(err) 325 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) 326 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 327 } 328 }) 329 } 330 } 331 332 func execDelegate(val *network.Validator, args []string) (testutil.BufferWriter, error) { 333 cmd := stakingcli.NewDelegateCmd() 334 clientCtx := val.ClientCtx 335 return clitestutil.ExecTestCLICmd(clientCtx, cmd, args) 336 } 337 338 func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() { 339 val := s.network.Validators[0] 340 341 grantee := s.grantee[0] 342 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 343 344 // send-authorization 345 _, err := ExecGrant( 346 val, 347 []string{ 348 grantee.String(), 349 "send", 350 fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), 351 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 352 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), 353 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 354 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 355 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 356 }, 357 ) 358 s.Require().NoError(err) 359 360 // generic-authorization 361 _, err = ExecGrant( 362 val, 363 []string{ 364 grantee.String(), 365 "generic", 366 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 367 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 368 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), 369 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 370 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 371 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 372 }, 373 ) 374 s.Require().NoError(err) 375 376 // generic-authorization used for amino testing 377 _, err = ExecGrant( 378 val, 379 []string{ 380 grantee.String(), 381 "generic", 382 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgSubmitProposal), 383 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 384 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), 385 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 386 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 387 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 388 fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), 389 }, 390 ) 391 s.Require().NoError(err) 392 393 testCases := []struct { 394 name string 395 args []string 396 respType proto.Message 397 expectedCode uint32 398 expectErr bool 399 }{ 400 { 401 "invalid grantee address", 402 []string{ 403 "invalid grantee", 404 typeMsgSend, 405 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 406 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 407 }, 408 nil, 409 0, 410 true, 411 }, 412 { 413 "invalid granter address", 414 []string{ 415 grantee.String(), 416 typeMsgSend, 417 fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"), 418 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 419 }, 420 nil, 421 0, 422 true, 423 }, 424 { 425 "Valid tx send authorization", 426 []string{ 427 grantee.String(), 428 typeMsgSend, 429 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 430 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 431 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 432 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 433 }, 434 &sdk.TxResponse{}, 0, 435 false, 436 }, 437 { 438 "Valid tx generic authorization", 439 []string{ 440 grantee.String(), 441 typeMsgVote, 442 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 443 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 444 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 445 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 446 }, 447 &sdk.TxResponse{}, 0, 448 false, 449 }, 450 { 451 "Valid tx with amino", 452 []string{ 453 grantee.String(), 454 typeMsgSubmitProposal, 455 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 456 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 457 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 458 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 459 fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), 460 }, 461 &sdk.TxResponse{}, 0, 462 false, 463 }, 464 } 465 for _, tc := range testCases { 466 s.Run(tc.name, func() { 467 cmd := cli.NewCmdRevokeAuthorization() 468 clientCtx := val.ClientCtx 469 470 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 471 if tc.expectErr { 472 s.Require().Error(err) 473 } else { 474 s.Require().NoError(err) 475 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 476 477 txResp := tc.respType.(*sdk.TxResponse) 478 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 479 } 480 }) 481 } 482 } 483 484 func (s *IntegrationTestSuite) TestExecAuthorizationWithExpiration() { 485 val := s.network.Validators[0] 486 grantee := s.grantee[0] 487 tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix() 488 489 _, err := ExecGrant( 490 val, 491 []string{ 492 grantee.String(), 493 "generic", 494 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 495 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 496 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 497 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 498 fmt.Sprintf("--%s=%d", cli.FlagExpiration, tenSeconds), 499 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 500 }, 501 ) 502 s.Require().NoError(err) 503 // msg vote 504 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()) 505 execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) 506 507 // waiting for authorization to expires 508 time.Sleep(12 * time.Second) 509 510 cmd := cli.NewCmdExecAuthorization() 511 clientCtx := val.ClientCtx 512 513 res, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ 514 execMsg.Name(), 515 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 516 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 517 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 518 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 519 }) 520 s.Require().NoError(err) 521 s.Require().Contains(res.String(), "authorization not found") 522 } 523 524 func (s *IntegrationTestSuite) TestNewExecGenericAuthorized() { 525 val := s.network.Validators[0] 526 grantee := s.grantee[0] 527 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 528 529 _, err := ExecGrant( 530 val, 531 []string{ 532 grantee.String(), 533 "generic", 534 fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), 535 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 536 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 537 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 538 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 539 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 540 }, 541 ) 542 s.Require().NoError(err) 543 544 // msg vote 545 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()) 546 execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) 547 548 testCases := []struct { 549 name string 550 args []string 551 respType proto.Message 552 expectedCode uint32 553 expectErr bool 554 }{ 555 { 556 "fail invalid grantee", 557 []string{ 558 execMsg.Name(), 559 fmt.Sprintf("--%s=%s", flags.FlagFrom, "grantee"), 560 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 561 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 562 }, 563 nil, 564 0, 565 true, 566 }, 567 { 568 "fail invalid json path", 569 []string{ 570 "/invalid/file.txt", 571 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 572 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 573 }, 574 nil, 575 0, 576 true, 577 }, 578 { 579 "valid txn", 580 []string{ 581 execMsg.Name(), 582 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 583 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 584 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 585 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 586 }, 587 &sdk.TxResponse{}, 588 0, 589 false, 590 }, 591 { 592 "valid tx with amino", 593 []string{ 594 execMsg.Name(), 595 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 596 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 597 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 598 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 599 fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), 600 }, 601 &sdk.TxResponse{}, 0, 602 false, 603 }, 604 } 605 606 for _, tc := range testCases { 607 s.Run(tc.name, func() { 608 cmd := cli.NewCmdExecAuthorization() 609 clientCtx := val.ClientCtx 610 611 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 612 if tc.expectErr { 613 s.Require().Error(err) 614 } else { 615 s.Require().NoError(err) 616 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 617 txResp := tc.respType.(*sdk.TxResponse) 618 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 619 } 620 }) 621 } 622 } 623 624 func (s *IntegrationTestSuite) TestNewExecGrantAuthorized() { 625 val := s.network.Validators[0] 626 grantee := s.grantee[0] 627 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 628 629 _, err := ExecGrant( 630 val, 631 []string{ 632 grantee.String(), 633 "send", 634 fmt.Sprintf("--%s=12%stoken", cli.FlagSpendLimit, val.Moniker), 635 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 636 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 637 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 638 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 639 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 640 }, 641 ) 642 s.Require().NoError(err) 643 tokens := sdk.NewCoins( 644 sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), sdk.NewInt(12)), 645 ) 646 normalGeneratedTx, err := banktestutil.MsgSendExec( 647 val.ClientCtx, 648 val.Address, 649 grantee, 650 tokens, 651 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 652 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 653 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 654 fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), 655 ) 656 s.Require().NoError(err) 657 execMsg := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String()) 658 testCases := []struct { 659 name string 660 args []string 661 expectedCode uint32 662 expectErr bool 663 }{ 664 { 665 "valid txn", 666 []string{ 667 execMsg.Name(), 668 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 669 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 670 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 671 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 672 }, 673 0, 674 false, 675 }, 676 { 677 "error over spent", 678 []string{ 679 execMsg.Name(), 680 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 681 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 682 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 683 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 684 }, 685 4, 686 false, 687 }, 688 } 689 690 for _, tc := range testCases { 691 s.Run(tc.name, func() { 692 cmd := cli.NewCmdExecAuthorization() 693 clientCtx := val.ClientCtx 694 695 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 696 if tc.expectErr { 697 s.Require().Error(err) 698 } else { 699 var response sdk.TxResponse 700 s.Require().NoError(err) 701 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 702 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 703 } 704 }) 705 } 706 } 707 708 func (s *IntegrationTestSuite) TestExecDelegateAuthorization() { 709 val := s.network.Validators[0] 710 grantee := s.grantee[0] 711 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 712 713 _, err := ExecGrant( 714 val, 715 []string{ 716 grantee.String(), 717 "delegate", 718 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 719 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 720 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 721 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 722 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 723 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 724 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 725 }, 726 ) 727 s.Require().NoError(err) 728 729 tokens := sdk.NewCoins( 730 sdk.NewCoin("stake", sdk.NewInt(50)), 731 ) 732 733 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(), 734 tokens.GetDenomByIndex(0), tokens[0].Amount) 735 execMsg := testutil.WriteToNewTempFile(s.T(), delegateTx) 736 737 testCases := []struct { 738 name string 739 args []string 740 expectedCode uint32 741 expectErr bool 742 errMsg string 743 }{ 744 { 745 "valid txn: (delegate half tokens)", 746 []string{ 747 execMsg.Name(), 748 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 749 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 750 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 751 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 752 }, 753 0, 754 false, 755 "", 756 }, 757 { 758 "valid txn: (delegate remaining half tokens)", 759 []string{ 760 execMsg.Name(), 761 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 762 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 763 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 764 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 765 }, 766 0, 767 false, 768 "", 769 }, 770 { 771 "failed with error no authorization found", 772 []string{ 773 execMsg.Name(), 774 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 775 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 776 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 777 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 778 }, 779 4, 780 false, 781 "authorization not found", 782 }, 783 } 784 785 for _, tc := range testCases { 786 s.Run(tc.name, func() { 787 cmd := cli.NewCmdExecAuthorization() 788 clientCtx := val.ClientCtx 789 790 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 791 if tc.expectErr { 792 s.Require().Error(err) 793 s.Require().Contains(err.Error(), tc.errMsg) 794 } else { 795 var response sdk.TxResponse 796 s.Require().NoError(err) 797 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 798 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 799 } 800 }) 801 } 802 803 // test delegate no spend-limit 804 _, err = ExecGrant( 805 val, 806 []string{ 807 grantee.String(), 808 "delegate", 809 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 810 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 811 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 812 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 813 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 814 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 815 }, 816 ) 817 s.Require().NoError(err) 818 tokens = sdk.NewCoins( 819 sdk.NewCoin("stake", sdk.NewInt(50)), 820 ) 821 822 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(), 823 tokens.GetDenomByIndex(0), tokens[0].Amount) 824 execMsg = testutil.WriteToNewTempFile(s.T(), delegateTx) 825 826 testCases = []struct { 827 name string 828 args []string 829 expectedCode uint32 830 expectErr bool 831 errMsg string 832 }{ 833 { 834 "valid txn", 835 []string{ 836 execMsg.Name(), 837 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 838 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 839 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 840 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 841 }, 842 0, 843 false, 844 "", 845 }, 846 { 847 "valid txn", 848 []string{ 849 execMsg.Name(), 850 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 851 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 852 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 853 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 854 }, 855 0, 856 false, 857 "", 858 }, 859 } 860 861 for _, tc := range testCases { 862 s.Run(tc.name, func() { 863 cmd := cli.NewCmdExecAuthorization() 864 clientCtx := val.ClientCtx 865 866 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 867 if tc.expectErr { 868 s.Require().Error(err) 869 s.Require().Contains(err.Error(), tc.errMsg) 870 } else { 871 var response sdk.TxResponse 872 s.Require().NoError(err) 873 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 874 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 875 } 876 }) 877 } 878 879 // test delegating to denied validator 880 _, err = ExecGrant( 881 val, 882 []string{ 883 grantee.String(), 884 "delegate", 885 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 886 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 887 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 888 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 889 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 890 fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.ValAddress.String()), 891 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 892 }, 893 ) 894 s.Require().NoError(err) 895 896 args := []string{ 897 execMsg.Name(), 898 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 899 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 900 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 901 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 902 } 903 cmd := cli.NewCmdExecAuthorization() 904 out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) 905 s.Require().NoError(err) 906 s.Contains(out.String(), fmt.Sprintf("cannot delegate/undelegate to %s validator", val.ValAddress.String())) 907 } 908 909 func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() { 910 val := s.network.Validators[0] 911 grantee := s.grantee[0] 912 twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() 913 914 // granting undelegate msg authorization 915 _, err := ExecGrant( 916 val, 917 []string{ 918 grantee.String(), 919 "unbond", 920 fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), 921 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 922 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 923 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 924 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 925 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 926 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 927 }, 928 ) 929 s.Require().NoError(err) 930 931 // delegating stakes to validator 932 _, err = execDelegate( 933 val, 934 []string{ 935 val.ValAddress.String(), 936 "100stake", 937 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 938 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 939 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 940 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 941 }, 942 ) 943 s.Require().NoError(err) 944 945 tokens := sdk.NewCoins( 946 sdk.NewCoin("stake", sdk.NewInt(50)), 947 ) 948 949 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(), 950 tokens.GetDenomByIndex(0), tokens[0].Amount) 951 execMsg := testutil.WriteToNewTempFile(s.T(), undelegateTx) 952 953 testCases := []struct { 954 name string 955 args []string 956 expectedCode uint32 957 expectErr bool 958 errMsg string 959 }{ 960 { 961 "valid txn: (undelegate half tokens)", 962 []string{ 963 execMsg.Name(), 964 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 965 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 966 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 967 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 968 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 969 }, 970 0, 971 false, 972 "", 973 }, 974 { 975 "valid txn: (undelegate remaining half tokens)", 976 []string{ 977 execMsg.Name(), 978 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 979 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 980 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 981 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 982 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 983 }, 984 0, 985 false, 986 "", 987 }, 988 { 989 "failed with error no authorization found", 990 []string{ 991 execMsg.Name(), 992 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 993 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 994 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 995 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 996 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 997 }, 998 4, 999 false, 1000 "authorization not found", 1001 }, 1002 } 1003 1004 for _, tc := range testCases { 1005 s.Run(tc.name, func() { 1006 cmd := cli.NewCmdExecAuthorization() 1007 clientCtx := val.ClientCtx 1008 1009 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1010 if tc.expectErr { 1011 s.Require().Error(err) 1012 s.Require().Contains(err.Error(), tc.errMsg) 1013 } else { 1014 var response sdk.TxResponse 1015 s.Require().NoError(err) 1016 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 1017 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 1018 } 1019 }) 1020 } 1021 1022 // grant undelegate authorization without limit 1023 _, err = ExecGrant( 1024 val, 1025 []string{ 1026 grantee.String(), 1027 "unbond", 1028 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1029 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1030 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1031 fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), 1032 fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), 1033 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1034 }, 1035 ) 1036 s.Require().NoError(err) 1037 tokens = sdk.NewCoins( 1038 sdk.NewCoin("stake", sdk.NewInt(50)), 1039 ) 1040 1041 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(), 1042 tokens.GetDenomByIndex(0), tokens[0].Amount) 1043 execMsg = testutil.WriteToNewTempFile(s.T(), undelegateTx) 1044 1045 testCases = []struct { 1046 name string 1047 args []string 1048 expectedCode uint32 1049 expectErr bool 1050 errMsg string 1051 }{ 1052 { 1053 "valid txn", 1054 []string{ 1055 execMsg.Name(), 1056 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 1057 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 1058 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1059 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1060 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1061 }, 1062 0, 1063 false, 1064 "", 1065 }, 1066 { 1067 "valid txn", 1068 []string{ 1069 execMsg.Name(), 1070 fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), 1071 fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), 1072 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1073 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1074 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1075 }, 1076 0, 1077 false, 1078 "", 1079 }, 1080 } 1081 1082 for _, tc := range testCases { 1083 s.Run(tc.name, func() { 1084 cmd := cli.NewCmdExecAuthorization() 1085 clientCtx := val.ClientCtx 1086 1087 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1088 if tc.expectErr { 1089 s.Require().Error(err) 1090 s.Require().Contains(err.Error(), tc.errMsg) 1091 } else { 1092 var response sdk.TxResponse 1093 s.Require().NoError(err) 1094 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) 1095 s.Require().Equal(tc.expectedCode, response.Code, out.String()) 1096 } 1097 }) 1098 } 1099 }