Skip to content

Commit

Permalink
add create validator test suit
Browse files Browse the repository at this point in the history
  • Loading branch information
randyahx authored and Keefe Liu committed Dec 21, 2022
1 parent daadf7e commit 0ca1497
Show file tree
Hide file tree
Showing 8 changed files with 906 additions and 14 deletions.
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.12.2
github.com/prometheus/common v0.34.0
github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b
github.com/rakyll/statik v0.1.7
github.com/regen-network/cosmos-proto v0.3.1
github.com/rs/zerolog v1.27.0
Expand Down Expand Up @@ -84,6 +85,7 @@ require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/ledger-go v0.9.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/creachadair/taskgroup v0.3.2 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand All @@ -95,6 +97,7 @@ require (
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-kit/kit v0.12.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
Expand All @@ -118,36 +121,46 @@ require (
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/lib/pq v1.10.6 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rs/cors v1.8.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ulikunitz/xz v0.5.8 // indirect
github.com/urfave/cli/v2 v2.3.0 // indirect
github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.opencensus.io v0.23.0 // indirect
Expand Down
645 changes: 639 additions & 6 deletions go.sum

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions testutil/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package network
import (
"bufio"
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
Expand All @@ -17,6 +18,7 @@ import (

"cosmossdk.io/math"
ethHd "github.com/evmos/ethermint/crypto/hd"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
tmrand "github.com/tendermint/tendermint/libs/rand"
Expand Down Expand Up @@ -400,15 +402,20 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) {
return nil, err
}

blsSecretKey, err := bls.RandKey()
if err != nil {
return nil, err
}
blsPubKey := hex.EncodeToString(blsSecretKey.PublicKey().Marshal())

createValMsg, err := stakingtypes.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(commission, sdk.OneDec(), sdk.OneDec()),
sdk.OneInt(),
// FIXME: should set proper value to pass testcases.
addr, addr, addr, "",
addr, addr, addr, blsPubKey,
)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion x/gov/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

Expand Down
15 changes: 15 additions & 0 deletions x/staking/client/testutil/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,28 @@ package testutil

import (
"testing"
"time"

"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)

func TestIntegrationTestSuite(t *testing.T) {
cfg := network.DefaultConfig()
cfg.NumValidators = 2
suite.Run(t, NewIntegrationTestSuite(cfg))

dp := v1.NewDepositParams(sdk.NewCoins(sdk.NewCoin(cfg.BondDenom, v1.DefaultMinDepositTokens)), time.Duration(15)*time.Second)
vp := v1.NewVotingParams(time.Duration(5) * time.Second)
genesisState := v1.DefaultGenesisState()
genesisState.DepositParams = &dp
genesisState.VotingParams = &vp
bz, err := cfg.Codec.MarshalJSON(genesisState)
require.NoError(t, err)
cfg.GenesisState["gov"] = bz
cfg.NumValidators = 1
suite.Run(t, NewCreateValidatorTestSuite(cfg))
}
225 changes: 225 additions & 0 deletions x/staking/client/testutil/create_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package testutil

import (
"encoding/base64"
"encoding/hex"
"fmt"
"os"
"time"

"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/stretchr/testify/suite"
tmcli "github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authztestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

type CreateValidatorTestSuite struct {
suite.Suite

cfg network.Config
network *network.Network
proposalIDs []string
validators []sdk.AccAddress
}

func NewCreateValidatorTestSuite(cfg network.Config) *CreateValidatorTestSuite {
return &CreateValidatorTestSuite{cfg: cfg}
}

func (s *CreateValidatorTestSuite) SetupSuite() {
s.T().Log("setting up test suite")

var err error
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
s.Require().NoError(err)

_, err = s.network.WaitForHeight(1)
s.Require().NoError(err)

newVal := s.submitProposal()
s.validators = append(s.validators, newVal)
proposalID := fmt.Sprintf("%d", 1)
s.proposalIDs = append(s.proposalIDs, proposalID)
s.voteProposal(proposalID)
}

func (s *CreateValidatorTestSuite) SetupNewSuite() {
s.T().Log("setting up new test suite")

var err error
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
s.Require().NoError(err)

_, err = s.network.WaitForHeight(1)
s.Require().NoError(err)
}

func (s *CreateValidatorTestSuite) submitProposal() sdk.AccAddress {
val := s.network.Validators[0]
clientCtx := val.ClientCtx

// Get coin from current validator
k, _, err := val.ClientCtx.Keyring.NewMnemonic("NewAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
s.Require().NoError(err)

pub, err := k.GetPubKey()
s.Require().NoError(err)

newVal := sdk.AccAddress(pub.Address())
_, err = banktestutil.MsgSendExec(
val.ClientCtx,
val.Address,
newVal,
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200000000))),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
)
s.Require().NoError(err)

// Grant delegate authorization
_, err = authztestutil.CreateGrant(val, []string{
authtypes.NewModuleAddress(gov.ModuleName).String(),
"delegate",
fmt.Sprintf("--spend-limit=100000000%s", s.cfg.BondDenom),
fmt.Sprintf("--allowed-validators=%s", newVal.String()),
fmt.Sprintf("--%s=%s", flags.FlagFrom, newVal.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
})
s.Require().NoError(err)

//nolint:staticcheck
args := append([]string{
s.createValidatorProposal(newVal).Name(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, newVal.String()),
fmt.Sprintf("--gas=%s", fmt.Sprintf("%d", flags.DefaultGasLimit+100000)),
}, commonArgs...)

_, err = clitestutil.ExecTestCLICmd(clientCtx, govcli.NewCmdSubmitProposal(), args)
s.Require().NoError(err)

return newVal
}

func (s *CreateValidatorTestSuite) voteProposal(proposalID string) {
val := s.network.Validators[0]
clientCtx := val.ClientCtx

//nolint:staticcheck
args := append([]string{
proposalID,
"yes",
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
}, commonArgs...)
_, err := clitestutil.ExecTestCLICmd(clientCtx, govcli.NewCmdVote(), args)
s.Require().NoError(err)
}

func (s *CreateValidatorTestSuite) TearDownSuite() {
s.T().Log("tearing down test suite")
s.network.Cleanup()
}

func (s *CreateValidatorTestSuite) TestQuerySuccessfulCreatedValidator() {
val := s.network.Validators[0]
clientCtx := val.ClientCtx
proposalID := s.proposalIDs[0]
newVal := s.validators[0]

// waiting for voting period to end
time.Sleep(10 * time.Second)

// query proposal
args := []string{proposalID, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
out, err := clitestutil.ExecTestCLICmd(clientCtx, govcli.GetCmdQueryProposal(), args)
s.Require().NoError(err)
var proposal v1.Proposal
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &proposal), out.String())
s.Require().Equal(v1.ProposalStatus_PROPOSAL_STATUS_PASSED, proposal.Status, out.String())

// query validator
queryCmd := cli.GetCmdQueryValidator()
res, err := clitestutil.ExecTestCLICmd(
val.ClientCtx, queryCmd,
[]string{newVal.String(), fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
)
s.Require().NoError(err)
var result types.Validator
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(res.Bytes(), &result))
s.Require().Equal(result.GetStatus(), types.Bonded, fmt.Sprintf("validator %s not in bonded status", newVal.String()))
}

func (s *CreateValidatorTestSuite) createValidatorProposal(valAddr sdk.AccAddress) *os.File {
pubKey := base64.StdEncoding.EncodeToString(ed25519.GenPrivKey().PubKey().Bytes())

blsSecretKey, _ := bls.RandKey()
blsPubKey := hex.EncodeToString(blsSecretKey.PublicKey().Marshal())

propMetadata := []byte{42}
proposal := fmt.Sprintf(`
{
"messages": [
{
"@type": "/cosmos.staking.v1beta1.MsgCreateValidator",
"description":{
"moniker":"testnode",
"identity":"",
"website":"",
"security_contact":"",
"details":""
},
"commission":{
"rate":"0.100000000000000000",
"max_rate":"0.200000000000000000",
"max_change_rate":"0.010000000000000000"
},
"min_self_delegation":"10000000",
"delegator_address":"%s",
"validator_address":"%s",
"pubkey":{
"@type":"/cosmos.crypto.ed25519.PubKey",
"key":"%s"
},
"value":{
"denom":"stake",
"amount":"10000000"
},
"from":"%s",
"relayer_address":"%s",
"relayer_blskey":"%s"
}
],
"metadata": "%s",
"deposit": "%s"
}`,
valAddr.String(),
valAddr.String(),
pubKey,
authtypes.NewModuleAddress(gov.ModuleName),
valAddr.String(),
blsPubKey,
base64.StdEncoding.EncodeToString(propMetadata),
sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens),
)

proposalFile := testutil.WriteToNewTempFile(s.T(), proposal)
return proposalFile
}
Loading

0 comments on commit 0ca1497

Please sign in to comment.