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