github.com/Finschia/finschia-sdk@v0.48.1/x/staking/client/testutil/suite.go (about) 1 package testutil 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 "testing" 8 9 "github.com/gogo/protobuf/proto" 10 "github.com/stretchr/testify/suite" 11 "github.com/tendermint/tendermint/proto/tendermint/crypto" 12 13 ostcli "github.com/Finschia/ostracon/libs/cli" 14 "github.com/Finschia/ostracon/rpc/client/http" 15 16 "github.com/Finschia/finschia-sdk/client/flags" 17 "github.com/Finschia/finschia-sdk/crypto/hd" 18 "github.com/Finschia/finschia-sdk/crypto/keyring" 19 "github.com/Finschia/finschia-sdk/crypto/keys/ed25519" 20 clitestutil "github.com/Finschia/finschia-sdk/testutil/cli" 21 "github.com/Finschia/finschia-sdk/testutil/network" 22 sdk "github.com/Finschia/finschia-sdk/types" 23 "github.com/Finschia/finschia-sdk/types/query" 24 banktestutil "github.com/Finschia/finschia-sdk/x/bank/client/testutil" 25 "github.com/Finschia/finschia-sdk/x/staking/client/cli" 26 "github.com/Finschia/finschia-sdk/x/staking/types" 27 ) 28 29 type IntegrationTestSuite struct { 30 suite.Suite 31 32 cfg network.Config 33 network *network.Network 34 } 35 36 func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite { 37 return &IntegrationTestSuite{cfg: cfg} 38 } 39 40 func (s *IntegrationTestSuite) SetupSuite() { 41 s.T().Log("setting up integration test suite") 42 43 if testing.Short() { 44 s.T().Skip("skipping test in unit-tests mode.") 45 } 46 47 s.network = network.New(s.T(), s.cfg) 48 49 _, err := s.network.WaitForHeight(1) 50 s.Require().NoError(err) 51 52 unbond, err := sdk.ParseCoinNormalized("10stake") 53 s.Require().NoError(err) 54 55 val := s.network.Validators[0] 56 val2 := s.network.Validators[1] 57 58 // redelegate 59 _, err = MsgRedelegateExec( 60 val.ClientCtx, 61 val.Address, 62 val.ValAddress, 63 val2.ValAddress, 64 unbond, 65 fmt.Sprintf("--%s=%d", flags.FlagGas, 300000), 66 ) 67 s.Require().NoError(err) 68 _, err = s.network.WaitForHeight(1) 69 s.Require().NoError(err) 70 // unbonding 71 _, err = MsgUnbondExec(val.ClientCtx, val.Address, val.ValAddress, unbond) 72 s.Require().NoError(err) 73 _, err = s.network.WaitForHeight(1) 74 s.Require().NoError(err) 75 } 76 77 func (s *IntegrationTestSuite) TearDownSuite() { 78 s.T().Log("tearing down integration test suite") 79 s.network.Cleanup() 80 } 81 82 func (s *IntegrationTestSuite) TestNewCreateValidatorCmd() { 83 require := s.Require() 84 val := s.network.Validators[0] 85 86 consPrivKey := ed25519.GenPrivKey() 87 consPubKeyBz, err := s.cfg.Codec.MarshalInterfaceJSON(consPrivKey.PubKey()) 88 require.NoError(err) 89 require.NotNil(consPubKeyBz) 90 91 info, _, err := val.ClientCtx.Keyring.NewMnemonic("NewValidator", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) 92 require.NoError(err) 93 94 newAddr := sdk.AccAddress(info.GetPubKey().Address()) 95 _, err = banktestutil.MsgSendExec( 96 val.ClientCtx, 97 val.Address, 98 newAddr, 99 sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 100 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 101 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 102 ) 103 require.NoError(err) 104 105 testCases := []struct { 106 name string 107 args []string 108 expectErr bool 109 expectedCode uint32 110 respType proto.Message 111 }{ 112 { 113 "invalid transaction (missing amount)", 114 []string{ 115 fmt.Sprintf("--%s=AFAF00C4", cli.FlagIdentity), 116 fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), 117 fmt.Sprintf("--%s=contact@newvalidator.io", cli.FlagSecurityContact), 118 fmt.Sprintf("--%s='Hey, I am a new validator. Please delegate!'", cli.FlagDetails), 119 fmt.Sprintf("--%s=0.5", cli.FlagCommissionRate), 120 fmt.Sprintf("--%s=1.0", cli.FlagCommissionMaxRate), 121 fmt.Sprintf("--%s=0.1", cli.FlagCommissionMaxChangeRate), 122 fmt.Sprintf("--%s=1", cli.FlagMinSelfDelegation), 123 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr), 124 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 125 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 126 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 127 }, 128 true, 0, nil, 129 }, 130 { 131 "invalid transaction (missing pubkey)", 132 []string{ 133 fmt.Sprintf("--%s=%dstake", cli.FlagAmount, 100), 134 fmt.Sprintf("--%s=AFAF00C4", cli.FlagIdentity), 135 fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), 136 fmt.Sprintf("--%s=contact@newvalidator.io", cli.FlagSecurityContact), 137 fmt.Sprintf("--%s='Hey, I am a new validator. Please delegate!'", cli.FlagDetails), 138 fmt.Sprintf("--%s=0.5", cli.FlagCommissionRate), 139 fmt.Sprintf("--%s=1.0", cli.FlagCommissionMaxRate), 140 fmt.Sprintf("--%s=0.1", cli.FlagCommissionMaxChangeRate), 141 fmt.Sprintf("--%s=1", cli.FlagMinSelfDelegation), 142 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr), 143 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 144 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 145 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 146 }, 147 true, 0, nil, 148 }, 149 { 150 "invalid transaction (missing moniker)", 151 []string{ 152 fmt.Sprintf("--%s=%s", cli.FlagPubKey, consPubKeyBz), 153 fmt.Sprintf("--%s=%dstake", cli.FlagAmount, 100), 154 fmt.Sprintf("--%s=AFAF00C4", cli.FlagIdentity), 155 fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), 156 fmt.Sprintf("--%s=contact@newvalidator.io", cli.FlagSecurityContact), 157 fmt.Sprintf("--%s='Hey, I am a new validator. Please delegate!'", cli.FlagDetails), 158 fmt.Sprintf("--%s=0.5", cli.FlagCommissionRate), 159 fmt.Sprintf("--%s=1.0", cli.FlagCommissionMaxRate), 160 fmt.Sprintf("--%s=0.1", cli.FlagCommissionMaxChangeRate), 161 fmt.Sprintf("--%s=1", cli.FlagMinSelfDelegation), 162 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr), 163 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 164 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 165 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 166 }, 167 true, 0, nil, 168 }, 169 { 170 "valid transaction", 171 []string{ 172 fmt.Sprintf("--%s=%s", cli.FlagPubKey, consPubKeyBz), 173 fmt.Sprintf("--%s=%dstake", cli.FlagAmount, 100), 174 fmt.Sprintf("--%s=NewValidator", cli.FlagMoniker), 175 fmt.Sprintf("--%s=AFAF00C4", cli.FlagIdentity), 176 fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), 177 fmt.Sprintf("--%s=contact@newvalidator.io", cli.FlagSecurityContact), 178 fmt.Sprintf("--%s='Hey, I am a new validator. Please delegate!'", cli.FlagDetails), 179 fmt.Sprintf("--%s=0.5", cli.FlagCommissionRate), 180 fmt.Sprintf("--%s=1.0", cli.FlagCommissionMaxRate), 181 fmt.Sprintf("--%s=0.1", cli.FlagCommissionMaxChangeRate), 182 fmt.Sprintf("--%s=1", cli.FlagMinSelfDelegation), 183 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr), 184 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 185 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 186 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 187 }, 188 false, 0, &sdk.TxResponse{}, 189 }, 190 } 191 192 for _, tc := range testCases { 193 tc := tc 194 195 s.Run(tc.name, func() { 196 cmd := cli.NewCreateValidatorCmd() 197 clientCtx := val.ClientCtx 198 199 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 200 if tc.expectErr { 201 require.Error(err) 202 } else { 203 require.NoError(err, "test: %s\noutput: %s", tc.name, out.String()) 204 err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType) 205 require.NoError(err, out.String(), "test: %s, output\n:", tc.name, out.String()) 206 207 txResp := tc.respType.(*sdk.TxResponse) 208 require.Equal(tc.expectedCode, txResp.Code, 209 "test: %s, output\n:", tc.name, out.String()) 210 211 events := txResp.Logs[0].GetEvents() 212 for i := 0; i < len(events); i++ { 213 if events[i].GetType() == "create_validator" { 214 attributes := events[i].GetAttributes() 215 require.Equal(attributes[1].Value, "100stake") 216 break 217 } 218 } 219 } 220 }) 221 } 222 } 223 224 func (s *IntegrationTestSuite) TestGetCmdQueryValidator() { 225 val := s.network.Validators[0] 226 testCases := []struct { 227 name string 228 args []string 229 expectErr bool 230 }{ 231 { 232 "with invalid address ", 233 []string{"somethinginvalidaddress", fmt.Sprintf("--%s=json", ostcli.OutputFlag)}, 234 true, 235 }, 236 { 237 "with valid and not existing address", 238 []string{"linkvaloper1mqn4snc20sxt6lrecjclmdglfdmtql4408kwvl", fmt.Sprintf("--%s=json", ostcli.OutputFlag)}, 239 true, 240 }, 241 { 242 "happy case", 243 []string{val.ValAddress.String(), fmt.Sprintf("--%s=json", ostcli.OutputFlag)}, 244 false, 245 }, 246 } 247 for _, tc := range testCases { 248 tc := tc 249 s.Run(tc.name, func() { 250 cmd := cli.GetCmdQueryValidator() 251 clientCtx := val.ClientCtx 252 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 253 if tc.expectErr { 254 s.Require().Error(err) 255 s.Require().NotEqual("internal", err.Error()) 256 } else { 257 var result types.Validator 258 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)) 259 s.Require().Equal(val.ValAddress.String(), result.OperatorAddress) 260 } 261 }) 262 } 263 } 264 265 func (s *IntegrationTestSuite) TestGetCmdQueryValidators() { 266 val := s.network.Validators[0] 267 268 testCases := []struct { 269 name string 270 args []string 271 minValidatorCount int 272 }{ 273 { 274 "one validator case", 275 []string{ 276 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 277 fmt.Sprintf("--%s=1", flags.FlagLimit), 278 }, 279 1, 280 }, 281 { 282 "multi validator case", 283 []string{fmt.Sprintf("--%s=json", ostcli.OutputFlag)}, 284 len(s.network.Validators), 285 }, 286 } 287 288 for _, tc := range testCases { 289 tc := tc 290 291 s.Run(tc.name, func() { 292 cmd := cli.GetCmdQueryValidators() 293 clientCtx := val.ClientCtx 294 295 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 296 s.Require().NoError(err) 297 298 var result types.QueryValidatorsResponse 299 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)) 300 s.Require().Equal(tc.minValidatorCount, len(result.Validators)) 301 }) 302 } 303 } 304 305 func (s *IntegrationTestSuite) TestGetCmdQueryDelegation() { 306 val := s.network.Validators[0] 307 val2 := s.network.Validators[1] 308 309 testCases := []struct { 310 name string 311 args []string 312 expErr bool 313 respType proto.Message 314 expected proto.Message 315 }{ 316 { 317 "with wrong delegator address", 318 []string{ 319 "wrongDelAddr", 320 val2.ValAddress.String(), 321 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 322 }, 323 true, nil, nil, 324 }, 325 { 326 "with wrong validator address", 327 []string{ 328 val.Address.String(), 329 "wrongValAddr", 330 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 331 }, 332 true, nil, nil, 333 }, 334 { 335 "with json output", 336 []string{ 337 val.Address.String(), 338 val2.ValAddress.String(), 339 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 340 }, 341 false, 342 &types.DelegationResponse{}, 343 &types.DelegationResponse{ 344 Delegation: types.Delegation{ 345 DelegatorAddress: val.Address.String(), 346 ValidatorAddress: val2.ValAddress.String(), 347 Shares: sdk.NewDec(10), 348 }, 349 Balance: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)), 350 }, 351 }, 352 } 353 354 for _, tc := range testCases { 355 tc := tc 356 s.Run(tc.name, func() { 357 cmd := cli.GetCmdQueryDelegation() 358 clientCtx := val.ClientCtx 359 360 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 361 if tc.expErr { 362 s.Require().Error(err) 363 } else { 364 s.Require().NoError(err) 365 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 366 s.Require().Equal(tc.expected.String(), tc.respType.String()) 367 } 368 }) 369 } 370 } 371 372 func (s *IntegrationTestSuite) TestGetCmdQueryDelegations() { 373 val := s.network.Validators[0] 374 375 testCases := []struct { 376 name string 377 args []string 378 expErr bool 379 respType proto.Message 380 expected proto.Message 381 }{ 382 { 383 "with no delegator address", 384 []string{}, 385 true, nil, nil, 386 }, 387 { 388 "with wrong delegator address", 389 []string{"wrongDelAddr"}, 390 true, nil, nil, 391 }, 392 { 393 "valid request (height specific)", 394 []string{ 395 val.Address.String(), 396 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 397 fmt.Sprintf("--%s=1", flags.FlagHeight), 398 }, 399 false, 400 &types.QueryDelegatorDelegationsResponse{}, 401 &types.QueryDelegatorDelegationsResponse{ 402 DelegationResponses: types.DelegationResponses{ 403 types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)), 404 }, 405 Pagination: &query.PageResponse{}, 406 }, 407 }, 408 } 409 410 for _, tc := range testCases { 411 tc := tc 412 s.Run(tc.name, func() { 413 cmd := cli.GetCmdQueryDelegations() 414 clientCtx := val.ClientCtx 415 416 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 417 if tc.expErr { 418 s.Require().Error(err) 419 } else { 420 s.Require().NoError(err) 421 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 422 s.Require().Equal(tc.expected.String(), tc.respType.String()) 423 } 424 }) 425 } 426 } 427 428 func (s *IntegrationTestSuite) TestGetCmdQueryValidatorDelegations() { 429 val := s.network.Validators[0] 430 431 testCases := []struct { 432 name string 433 args []string 434 expErr bool 435 respType proto.Message 436 expected proto.Message 437 }{ 438 { 439 "with no validator address", 440 []string{}, 441 true, nil, nil, 442 }, 443 { 444 "wrong validator address", 445 []string{"wrongValAddr"}, 446 true, nil, nil, 447 }, 448 { 449 "valid request(height specific)", 450 []string{ 451 val.Address.String(), 452 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 453 fmt.Sprintf("--%s=1", flags.FlagHeight), 454 }, 455 false, 456 &types.QueryValidatorDelegationsResponse{}, 457 &types.QueryValidatorDelegationsResponse{ 458 DelegationResponses: types.DelegationResponses{ 459 types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)), 460 }, 461 Pagination: &query.PageResponse{}, 462 }, 463 }, 464 } 465 466 for _, tc := range testCases { 467 tc := tc 468 s.Run(tc.name, func() { 469 cmd := cli.GetCmdQueryDelegations() 470 clientCtx := val.ClientCtx 471 472 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 473 if tc.expErr { 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 s.Require().Equal(tc.expected.String(), tc.respType.String()) 479 } 480 }) 481 } 482 } 483 484 func (s *IntegrationTestSuite) TestGetCmdQueryUnbondingDelegations() { 485 val := s.network.Validators[0] 486 487 testCases := []struct { 488 name string 489 args []string 490 expErr bool 491 }{ 492 { 493 "wrong delegator address", 494 []string{ 495 "wrongDelAddr", 496 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 497 }, 498 true, 499 }, 500 { 501 "valid request", 502 []string{ 503 val.Address.String(), 504 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 505 }, 506 false, 507 }, 508 } 509 510 for _, tc := range testCases { 511 tc := tc 512 s.Run(tc.name, func() { 513 cmd := cli.GetCmdQueryUnbondingDelegations() 514 clientCtx := val.ClientCtx 515 516 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 517 518 if tc.expErr { 519 s.Require().Error(err) 520 } else { 521 var ubds types.QueryDelegatorUnbondingDelegationsResponse 522 err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ubds) 523 524 s.Require().NoError(err) 525 s.Require().Len(ubds.UnbondingResponses, 1) 526 s.Require().Equal(ubds.UnbondingResponses[0].DelegatorAddress, val.Address.String()) 527 } 528 }) 529 } 530 } 531 532 func (s *IntegrationTestSuite) TestGetCmdQueryUnbondingDelegation() { 533 val := s.network.Validators[0] 534 535 testCases := []struct { 536 name string 537 args []string 538 expErr bool 539 }{ 540 { 541 "wrong delegator address", 542 []string{ 543 "wrongDelAddr", 544 val.ValAddress.String(), 545 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 546 }, 547 true, 548 }, 549 { 550 "wrong validator address", 551 []string{ 552 val.Address.String(), 553 "wrongValAddr", 554 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 555 }, 556 true, 557 }, 558 { 559 "valid request", 560 []string{ 561 val.Address.String(), 562 val.ValAddress.String(), 563 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 564 }, 565 false, 566 }, 567 } 568 569 for _, tc := range testCases { 570 tc := tc 571 s.Run(tc.name, func() { 572 cmd := cli.GetCmdQueryUnbondingDelegation() 573 clientCtx := val.ClientCtx 574 575 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 576 577 if tc.expErr { 578 s.Require().Error(err) 579 } else { 580 var ubd types.UnbondingDelegation 581 582 err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ubd) 583 s.Require().NoError(err) 584 s.Require().Equal(ubd.DelegatorAddress, val.Address.String()) 585 s.Require().Equal(ubd.ValidatorAddress, val.ValAddress.String()) 586 s.Require().Len(ubd.Entries, 1) 587 } 588 }) 589 } 590 } 591 592 func (s *IntegrationTestSuite) TestGetCmdQueryValidatorUnbondingDelegations() { 593 val := s.network.Validators[0] 594 595 testCases := []struct { 596 name string 597 args []string 598 expErr bool 599 }{ 600 { 601 "wrong validator address", 602 []string{ 603 "wrongValAddr", 604 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 605 }, 606 true, 607 }, 608 { 609 "valid request", 610 []string{ 611 val.ValAddress.String(), 612 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 613 }, 614 false, 615 }, 616 } 617 618 for _, tc := range testCases { 619 tc := tc 620 s.Run(tc.name, func() { 621 cmd := cli.GetCmdQueryValidatorUnbondingDelegations() 622 clientCtx := val.ClientCtx 623 624 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 625 626 if tc.expErr { 627 s.Require().Error(err) 628 } else { 629 var ubds types.QueryValidatorUnbondingDelegationsResponse 630 err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ubds) 631 632 s.Require().NoError(err) 633 s.Require().Len(ubds.UnbondingResponses, 1) 634 s.Require().Equal(ubds.UnbondingResponses[0].DelegatorAddress, val.Address.String()) 635 } 636 }) 637 } 638 } 639 640 func (s *IntegrationTestSuite) TestGetCmdQueryRedelegations() { 641 val := s.network.Validators[0] 642 val2 := s.network.Validators[1] 643 644 testCases := []struct { 645 name string 646 args []string 647 expErr bool 648 }{ 649 { 650 "wrong delegator address", 651 []string{ 652 "wrongdeladdr", 653 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 654 }, 655 true, 656 }, 657 { 658 "valid request", 659 []string{ 660 val.Address.String(), 661 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 662 }, 663 false, 664 }, 665 } 666 667 for _, tc := range testCases { 668 tc := tc 669 s.Run(tc.name, func() { 670 cmd := cli.GetCmdQueryRedelegations() 671 clientCtx := val.ClientCtx 672 673 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 674 675 if tc.expErr { 676 s.Require().Error(err) 677 } else { 678 var redelegations types.QueryRedelegationsResponse 679 err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &redelegations) 680 681 s.Require().NoError(err) 682 683 s.Require().Len(redelegations.RedelegationResponses, 1) 684 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.DelegatorAddress, val.Address.String()) 685 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorSrcAddress, val.ValAddress.String()) 686 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorDstAddress, val2.ValAddress.String()) 687 } 688 }) 689 } 690 } 691 692 func (s *IntegrationTestSuite) TestGetCmdQueryRedelegation() { 693 val := s.network.Validators[0] 694 val2 := s.network.Validators[1] 695 696 testCases := []struct { 697 name string 698 args []string 699 expErr bool 700 }{ 701 { 702 "wrong delegator address", 703 []string{ 704 "wrongdeladdr", 705 val.ValAddress.String(), 706 val2.ValAddress.String(), 707 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 708 }, 709 true, 710 }, 711 { 712 "wrong source validator address address", 713 []string{ 714 val.Address.String(), 715 "wrongSrcValAddress", 716 val2.ValAddress.String(), 717 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 718 }, 719 true, 720 }, 721 { 722 "wrong destination validator address address", 723 []string{ 724 val.Address.String(), 725 val.ValAddress.String(), 726 "wrongDestValAddress", 727 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 728 }, 729 true, 730 }, 731 { 732 "valid request", 733 []string{ 734 val.Address.String(), 735 val.ValAddress.String(), 736 val2.ValAddress.String(), 737 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 738 }, 739 false, 740 }, 741 } 742 743 for _, tc := range testCases { 744 tc := tc 745 s.Run(tc.name, func() { 746 cmd := cli.GetCmdQueryRedelegation() 747 clientCtx := val.ClientCtx 748 749 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 750 751 if tc.expErr { 752 s.Require().Error(err) 753 } else { 754 var redelegations types.QueryRedelegationsResponse 755 756 err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &redelegations) 757 s.Require().NoError(err) 758 759 s.Require().Len(redelegations.RedelegationResponses, 1) 760 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.DelegatorAddress, val.Address.String()) 761 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorSrcAddress, val.ValAddress.String()) 762 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorDstAddress, val2.ValAddress.String()) 763 } 764 }) 765 } 766 } 767 768 func (s *IntegrationTestSuite) TestGetCmdQueryValidatorRedelegations() { 769 val := s.network.Validators[0] 770 val2 := s.network.Validators[1] 771 772 testCases := []struct { 773 name string 774 args []string 775 expErr bool 776 }{ 777 { 778 "wrong validator address", 779 []string{ 780 "wrongValAddr", 781 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 782 }, 783 true, 784 }, 785 { 786 "valid request", 787 []string{ 788 val.ValAddress.String(), 789 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 790 }, 791 false, 792 }, 793 } 794 795 for _, tc := range testCases { 796 tc := tc 797 s.Run(tc.name, func() { 798 cmd := cli.GetCmdQueryValidatorRedelegations() 799 clientCtx := val.ClientCtx 800 801 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 802 803 if tc.expErr { 804 s.Require().Error(err) 805 } else { 806 var redelegations types.QueryRedelegationsResponse 807 err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &redelegations) 808 809 s.Require().NoError(err) 810 811 s.Require().Len(redelegations.RedelegationResponses, 1) 812 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.DelegatorAddress, val.Address.String()) 813 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorSrcAddress, val.ValAddress.String()) 814 s.Require().Equal(redelegations.RedelegationResponses[0].Redelegation.ValidatorDstAddress, val2.ValAddress.String()) 815 } 816 }) 817 } 818 } 819 820 func (s *IntegrationTestSuite) TestGetCmdQueryHistoricalInfo() { 821 val := s.network.Validators[0] 822 823 testCases := []struct { 824 name string 825 args []string 826 error bool 827 }{ 828 { 829 "wrong height", 830 []string{ 831 "-1", 832 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 833 }, 834 true, 835 }, 836 { 837 "valid request", 838 []string{ 839 "1", 840 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 841 }, 842 false, 843 }, 844 } 845 846 for _, tc := range testCases { 847 tc := tc 848 s.Run(tc.name, func() { 849 cmd := cli.GetCmdQueryHistoricalInfo() 850 clientCtx := val.ClientCtx 851 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 852 853 if tc.error { 854 s.Require().Error(err) 855 } else { 856 var historicalInfo types.HistoricalInfo 857 858 err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &historicalInfo) 859 s.Require().NoError(err) 860 s.Require().NotNil(historicalInfo) 861 } 862 }) 863 } 864 } 865 866 func (s *IntegrationTestSuite) TestGetCmdQueryParams() { 867 val := s.network.Validators[0] 868 testCases := []struct { 869 name string 870 args []string 871 expectedOutput string 872 }{ 873 { 874 "with text output", 875 []string{fmt.Sprintf("--%s=text", ostcli.OutputFlag)}, 876 `bond_denom: stake 877 historical_entries: 10000 878 max_entries: 7 879 max_validators: 100 880 unbonding_time: 1814400s`, 881 }, 882 { 883 "with json output", 884 []string{fmt.Sprintf("--%s=json", ostcli.OutputFlag)}, 885 `{"unbonding_time":"1814400s","max_validators":100,"max_entries":7,"historical_entries":10000,"bond_denom":"stake"}`, 886 }, 887 } 888 for _, tc := range testCases { 889 tc := tc 890 s.Run(tc.name, func() { 891 cmd := cli.GetCmdQueryParams() 892 clientCtx := val.ClientCtx 893 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 894 s.Require().NoError(err) 895 s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String())) 896 }) 897 } 898 } 899 900 func (s *IntegrationTestSuite) TestGetCmdQueryPool() { 901 val := s.network.Validators[0] 902 testCases := []struct { 903 name string 904 args []string 905 expectedOutput string 906 }{ 907 { 908 "with text", 909 []string{ 910 fmt.Sprintf("--%s=text", ostcli.OutputFlag), 911 fmt.Sprintf("--%s=1", flags.FlagHeight), 912 }, 913 fmt.Sprintf(`bonded_tokens: "%s" 914 not_bonded_tokens: "0"`, cli.DefaultTokens.Mul(sdk.NewInt(2)).String()), 915 }, 916 { 917 "with json", 918 []string{ 919 fmt.Sprintf("--%s=json", ostcli.OutputFlag), 920 fmt.Sprintf("--%s=1", flags.FlagHeight), 921 }, 922 fmt.Sprintf(`{"not_bonded_tokens":"0","bonded_tokens":"%s"}`, cli.DefaultTokens.Mul(sdk.NewInt(2)).String()), 923 }, 924 } 925 for _, tc := range testCases { 926 tc := tc 927 s.Run(tc.name, func() { 928 cmd := cli.GetCmdQueryPool() 929 clientCtx := val.ClientCtx 930 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 931 s.Require().NoError(err) 932 s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String())) 933 }) 934 } 935 } 936 937 func (s *IntegrationTestSuite) TestNewEditValidatorCmd() { 938 val := s.network.Validators[0] 939 940 details := "bio" 941 identity := "test identity" 942 securityContact := "test contact" 943 website := "https://test.com" 944 945 testCases := []struct { 946 name string 947 args []string 948 expectErr bool 949 expectedCode uint32 950 respType proto.Message 951 }{ 952 { 953 "with no edit flag (since all are optional)", 954 []string{ 955 fmt.Sprintf("--%s=%s", flags.FlagFrom, "with wrong from address"), 956 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 957 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 958 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 959 }, 960 true, 0, nil, 961 }, 962 { 963 "with no edit flag (since all are optional)", 964 []string{ 965 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 966 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 967 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 968 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 969 }, 970 false, 0, &sdk.TxResponse{}, 971 }, 972 { 973 "edit validator details", 974 []string{ 975 fmt.Sprintf("--details=%s", details), 976 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 977 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 978 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 979 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 980 }, 981 false, 0, &sdk.TxResponse{}, 982 }, 983 { 984 "edit validator identity", 985 []string{ 986 fmt.Sprintf("--identity=%s", identity), 987 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 988 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 989 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 990 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 991 }, 992 false, 0, &sdk.TxResponse{}, 993 }, 994 { 995 "edit validator security-contact", 996 []string{ 997 fmt.Sprintf("--security-contact=%s", securityContact), 998 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 999 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 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 }, 1003 false, 0, &sdk.TxResponse{}, 1004 }, 1005 { 1006 "edit validator website", 1007 []string{ 1008 fmt.Sprintf("--website=%s", website), 1009 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1010 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1011 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1012 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1013 }, 1014 false, 0, &sdk.TxResponse{}, 1015 }, 1016 { 1017 "with all edit flags", 1018 []string{ 1019 fmt.Sprintf("--details=%s", details), 1020 fmt.Sprintf("--identity=%s", identity), 1021 fmt.Sprintf("--security-contact=%s", securityContact), 1022 fmt.Sprintf("--website=%s", website), 1023 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1024 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1025 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1026 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1027 }, 1028 false, 0, &sdk.TxResponse{}, 1029 }, 1030 } 1031 1032 for _, tc := range testCases { 1033 tc := tc 1034 1035 s.Run(tc.name, func() { 1036 cmd := cli.NewEditValidatorCmd() 1037 clientCtx := val.ClientCtx 1038 1039 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1040 if tc.expectErr { 1041 s.Require().Error(err) 1042 } else { 1043 s.Require().NoError(err, out.String()) 1044 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 1045 1046 txResp := tc.respType.(*sdk.TxResponse) 1047 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 1048 } 1049 }) 1050 } 1051 } 1052 1053 func (s *IntegrationTestSuite) TestNewDelegateCmd() { 1054 val := s.network.Validators[0] 1055 1056 info, _, err := val.ClientCtx.Keyring.NewMnemonic("NewAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) 1057 s.Require().NoError(err) 1058 1059 newAddr := sdk.AccAddress(info.GetPubKey().Address()) 1060 1061 _, err = banktestutil.MsgSendExec( 1062 val.ClientCtx, 1063 val.Address, 1064 newAddr, 1065 sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1066 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1067 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1068 ) 1069 s.Require().NoError(err) 1070 1071 testCases := []struct { 1072 name string 1073 args []string 1074 expectErr bool 1075 expectedCode uint32 1076 respType proto.Message 1077 }{ 1078 { 1079 "without delegate amount", 1080 []string{ 1081 val.ValAddress.String(), 1082 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), 1083 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1084 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1085 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1086 }, 1087 true, 0, nil, 1088 }, 1089 { 1090 "without validator address", 1091 []string{ 1092 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), 1093 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), 1094 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1095 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1096 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1097 }, 1098 true, 0, nil, 1099 }, 1100 { 1101 "valid transaction of delegate", 1102 []string{ 1103 val.ValAddress.String(), 1104 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), 1105 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), 1106 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1107 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1108 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1109 }, 1110 false, 0, &sdk.TxResponse{}, 1111 }, 1112 } 1113 1114 for _, tc := range testCases { 1115 tc := tc 1116 1117 s.Run(tc.name, func() { 1118 cmd := cli.NewDelegateCmd() 1119 clientCtx := val.ClientCtx 1120 1121 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1122 if tc.expectErr { 1123 s.Require().Error(err) 1124 } else { 1125 s.Require().NoError(err, out.String()) 1126 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 1127 1128 txResp := tc.respType.(*sdk.TxResponse) 1129 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 1130 } 1131 }) 1132 } 1133 } 1134 1135 func (s *IntegrationTestSuite) TestNewRedelegateCmd() { 1136 val := s.network.Validators[0] 1137 val2 := s.network.Validators[1] 1138 1139 testCases := []struct { 1140 name string 1141 args []string 1142 expectErr bool 1143 expectedCode uint32 1144 respType proto.Message 1145 }{ 1146 { 1147 "without amount", 1148 []string{ 1149 val.ValAddress.String(), // src-validator-addr 1150 val2.ValAddress.String(), // dst-validator-addr 1151 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1152 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1153 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1154 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1155 }, 1156 true, 0, nil, 1157 }, 1158 { 1159 "with wrong source validator address", 1160 []string{ 1161 `linkvaloper120yvjfy7m2gnu9mvusrs40cxxhpt8nr3jr36d2`, // src-validator-addr 1162 val2.ValAddress.String(), // dst-validator-addr 1163 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), // amount 1164 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1165 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1166 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1167 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1168 }, 1169 false, 3, &sdk.TxResponse{}, 1170 }, 1171 { 1172 "with wrong destination validator address", 1173 []string{ 1174 val.ValAddress.String(), // dst-validator-addr 1175 `linkvaloper120yvjfy7m2gnu9mvusrs40cxxhpt8nr3jr36d2`, // src-validator-addr 1176 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), // amount 1177 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1178 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1179 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1180 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1181 }, 1182 false, 31, &sdk.TxResponse{}, 1183 }, 1184 { 1185 "valid transaction of delegate", 1186 []string{ 1187 val.ValAddress.String(), // src-validator-addr 1188 val2.ValAddress.String(), // dst-validator-addr 1189 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), // amount 1190 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1191 fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), 1192 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1193 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1194 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1195 }, 1196 false, 0, &sdk.TxResponse{}, 1197 }, 1198 } 1199 1200 for _, tc := range testCases { 1201 tc := tc 1202 1203 s.Run(tc.name, func() { 1204 cmd := cli.NewRedelegateCmd() 1205 clientCtx := val.ClientCtx 1206 1207 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1208 if tc.expectErr { 1209 s.Require().Error(err) 1210 } else { 1211 s.Require().NoError(err, out.String()) 1212 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 1213 1214 txResp := tc.respType.(*sdk.TxResponse) 1215 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 1216 } 1217 }) 1218 } 1219 } 1220 1221 func (s *IntegrationTestSuite) TestNewUnbondCmd() { 1222 val := s.network.Validators[0] 1223 1224 testCases := []struct { 1225 name string 1226 args []string 1227 expectErr bool 1228 expectedCode uint32 1229 respType proto.Message 1230 }{ 1231 { 1232 "Without unbond amount", 1233 []string{ 1234 val.ValAddress.String(), 1235 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1236 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1237 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1238 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1239 }, 1240 true, 0, nil, 1241 }, 1242 { 1243 "Without validator address", 1244 []string{ 1245 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), 1246 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1247 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1248 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1249 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1250 }, 1251 true, 0, nil, 1252 }, 1253 { 1254 "valid transaction of unbond", 1255 []string{ 1256 val.ValAddress.String(), 1257 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), 1258 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1259 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1260 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1261 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1262 }, 1263 false, 0, &sdk.TxResponse{}, 1264 }, 1265 } 1266 1267 for _, tc := range testCases { 1268 tc := tc 1269 1270 s.Run(tc.name, func() { 1271 cmd := cli.NewUnbondCmd() 1272 clientCtx := val.ClientCtx 1273 1274 out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) 1275 if tc.expectErr { 1276 s.Require().Error(err) 1277 } else { 1278 s.Require().NoError(err, out.String()) 1279 s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) 1280 1281 txResp := tc.respType.(*sdk.TxResponse) 1282 s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) 1283 } 1284 }) 1285 } 1286 } 1287 1288 // TestBlockResults tests that the validator updates correctly show when 1289 // calling the /block_results RPC endpoint. 1290 // ref: https://github.com/cosmos/cosmos-sdk/issues/7401. 1291 func (s *IntegrationTestSuite) TestBlockResults() { 1292 require := s.Require() 1293 val := s.network.Validators[0] 1294 1295 // Create new account in the keyring. 1296 info, _, err := val.ClientCtx.Keyring.NewMnemonic("NewDelegator", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) 1297 require.NoError(err) 1298 newAddr := sdk.AccAddress(info.GetPubKey().Address()) 1299 1300 // Send some funds to the new account. 1301 _, err = banktestutil.MsgSendExec( 1302 val.ClientCtx, 1303 val.Address, 1304 newAddr, 1305 sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1306 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1307 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1308 ) 1309 require.NoError(err) 1310 1311 // Use CLI to create a delegation from the new account to validator `val`. 1312 delHeight, err := s.network.LatestHeight() 1313 require.NoError(err) 1314 cmd := cli.NewDelegateCmd() 1315 _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, []string{ 1316 val.ValAddress.String(), 1317 sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), 1318 fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), 1319 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1320 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1321 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1322 }) 1323 require.NoError(err) 1324 1325 // Create a HTTP rpc client. 1326 rpcClient, err := http.New(val.RPCAddress, "/websocket") 1327 require.NoError(err) 1328 1329 // Loop until we find a block result with the correct validator updates. 1330 // By experience, it happens around 2 blocks after `delHeight`. 1331 for { 1332 latestHeight, err := s.network.LatestHeight() 1333 require.NoError(err) 1334 1335 // Wait maximum 10 blocks, or else fail test. 1336 if latestHeight > delHeight+10 { 1337 s.Fail("timeout reached") 1338 } 1339 1340 res, err := rpcClient.BlockResults(context.Background(), &latestHeight) 1341 require.NoError(err) 1342 1343 if len(res.ValidatorUpdates) > 0 { 1344 valUpdate := res.ValidatorUpdates[0] 1345 require.Equal( 1346 valUpdate.GetPubKey().Sum.(*crypto.PublicKey_Ed25519).Ed25519, 1347 val.PubKey.Bytes(), 1348 ) 1349 1350 // We got our validator update, test passed. 1351 break 1352 } 1353 1354 s.network.WaitForNextBlock() 1355 } 1356 } 1357 1358 // https://github.com/cosmos/cosmos-sdk/issues/10660 1359 func (s *IntegrationTestSuite) TestEditValidatorMoniker() { 1360 val := s.network.Validators[0] 1361 require := s.Require() 1362 1363 txCmd := cli.NewEditValidatorCmd() 1364 moniker := "testing" 1365 _, err := clitestutil.ExecTestCLICmd(val.ClientCtx, txCmd, []string{ 1366 val.ValAddress.String(), 1367 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1368 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1369 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1370 fmt.Sprintf("--%s=%s", cli.FlagEditMoniker, moniker), 1371 fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), 1372 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1373 }) 1374 require.NoError(err) 1375 1376 queryCmd := cli.GetCmdQueryValidator() 1377 res, err := clitestutil.ExecTestCLICmd( 1378 val.ClientCtx, queryCmd, 1379 []string{val.ValAddress.String(), fmt.Sprintf("--%s=json", ostcli.OutputFlag)}, 1380 ) 1381 require.NoError(err) 1382 var result types.Validator 1383 require.NoError(val.ClientCtx.Codec.UnmarshalJSON(res.Bytes(), &result)) 1384 require.Equal(result.GetMoniker(), moniker) 1385 1386 _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, txCmd, []string{ 1387 val.ValAddress.String(), 1388 fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), 1389 fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 1390 fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 1391 fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), 1392 fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), 1393 }) 1394 require.NoError(err) 1395 1396 res, err = clitestutil.ExecTestCLICmd( 1397 val.ClientCtx, queryCmd, 1398 []string{val.ValAddress.String(), fmt.Sprintf("--%s=json", ostcli.OutputFlag)}, 1399 ) 1400 require.NoError(err) 1401 1402 require.NoError(val.ClientCtx.Codec.UnmarshalJSON(res.Bytes(), &result)) 1403 require.Equal(result.GetMoniker(), moniker) 1404 }