diff --git a/PENDING.md b/PENDING.md index 8a5b088b95..6289f1d2e3 100644 --- a/PENDING.md +++ b/PENDING.md @@ -19,6 +19,11 @@ ### Gaia +* [\#3789] Update validator creation flow: + * Remove `NewMsgCreateValidatorOnBehalfOf` and corresponding business logic + * Ensure the validator address equals the delegator address during + `MsgCreateValidator#ValidateBasic` + ### SDK * [\#3669] Ensure consistency in message naming, codec registration, and JSON diff --git a/docs/gaia/validators/validator-setup.md b/docs/gaia/validators/validator-setup.md index cac1508d04..7c5e7d03bd 100644 --- a/docs/gaia/validators/validator-setup.md +++ b/docs/gaia/validators/validator-setup.md @@ -53,20 +53,19 @@ __Note__: If unspecified, `consensus_pubkey` will default to the output of `gaia ## Participate in genesis as a validator -__Note__: This section only concerns validators that want to be in the genesis file. If the chain you want to validate is already live, skip this section. +__Note__: This section only concerns validators that want to be in the genesis +file. If the chain you want to validate is already live, skip this section. -__Note__: `Gaia-9002` and `Game of stakes` will not use this process. They will be bootsrapped using Tendermint seed validators. You will just need to use the [create-validator](#create-your-validator) command in order to join as a validator for these networks. +__Note__: `Gaia-9002` and `Game of stakes` will not use this process. They will +be bootstrapped using validators operated by Tendermint. You will just need to use the +[create-validator](#create-your-validator) command in order to join as a validator +for these networks. -If you want to participate in genesis as a validator, you need to justify that you (or a delegator) have some stake at genesis, create one (or multiple) transaction to bond this stake to your validator address, and include this transaction in the genesis file. +If you want to participate in genesis as a validator, you need to justify that +you have some stake at genesis, create one (or multiple) transactions to bond this +stake to your validator address, and include this transaction in the genesis file. -We thus need to distinguish two cases: - -- Case 1: You want to bond the initial stake from your validator's address. -- Case 2: You want to bond the initial stake from a delegator's address. - -### Case 1: The initial stake comes from your validator's address - -In this case, you will create a `gentx`: +You will need create a `gentx`: ```bash gaiad gentx \ @@ -78,46 +77,17 @@ gaiad gentx \ --name ``` -__Note__: This command automatically store your `gentx` in `~/.gaiad/config/gentx` for it to be processed at genesis. +__Note__: This command automatically store your `gentx` in `~/.gaiad/config/gentx` +for it to be processed at genesis. ::: tip Consult `gaiad gentx --help` for more information on the flags defaults. ::: -A `gentx` is a JSON file carrying a self-delegation. All genesis transactions are collected by a `genesis coordinator` and validated against an initial `genesis.json`. Such initial `genesis.json` contains only a list of accounts and their coins. Once the transactions are processed, they are merged in the `genesis.json`'s `gentxs` field. - -### Case 2: The initial stake comes from a delegator's address - -In this case, you need both the signature of the validator and the delegator. Start by creating an unsigned `create-validator` transaction, and save it in a file called `unsignedValTx`: - -```bash -gaiacli tx staking create-validator \ - --amount=5STAKE \ - --pubkey=$(gaiad tendermint show-validator) \ - --moniker="choose a moniker" \ - --chain-id= \ - --from= \ - --commission-rate="0.10" \ - --commission-max-rate="0.20" \ - --commission-max-change-rate="0.01" \ - --address-delegator="address of the delegator" \ - --generate-only \ - > unsignedValTx.json -``` - -Then, sign this `unsignedValTx` with your validator's private key, and save the output in a new file `signedValTx.json`: - -```bash -gaiacli tx sign unsignedValTx.json --from= > signedValTx.json -``` - -Then, pass this file to the delegator, who needs to run the following command: - -```bash -gaiacli tx sign signedValTx.json --from= > gentx.json -``` - -This `gentx.json` needs to be included in the `~/.gaiad/config/gentx` folder on the validator's machine to be processed at genesis, just like in case 1 (except here it needs to be copied manually into the folder). +A `gentx` is a JSON file carrying a self-delegation. All genesis transactions are +collected by a `genesis coordinator` and validated against an initial `genesis.json`. +Such initial `genesis.json` contains only a list of accounts and their coins. +Once the transactions are processed, they are merged in the `genesis.json`'s `gentxs` field. ### Copy the Initial Genesis File and Process Genesis Transactions diff --git a/docs/translations/kr/gaia/validators/validator-setup.md b/docs/translations/kr/gaia/validators/validator-setup.md index aeaff5ff35..aa105bfc50 100755 --- a/docs/translations/kr/gaia/validators/validator-setup.md +++ b/docs/translations/kr/gaia/validators/validator-setup.md @@ -57,13 +57,6 @@ __참고__: 이 문항은 제네시스 파일에 참가하려는 밸리데이터 밸리데이터로써 제네시스에 참가하고 싶으시다면 우선 본인(또는 위임자)가 stake를 보유하고 있다는 것을 증명해야 합니다. 스테이크를 검증인에게 본딩하는 하나 이상의 트랜잭션을 발생하신 후, 해당 트랜잭션을 제네시스 파일에 추가하시기 바랍니다. -우선 두가지의 케이스가 존재합니다: - -- 경우 1: 본인 밸리데이터의 stake를 본딩(위임)한다. -- 경우 2: 타인(위임자)의 stake를 본딩한다. - -### Case 1: 최초 위임이 밸리데이터 본인 주소에서 발생하는 경우 - 이런 경우에는 `gentx`를 생성하셔야 합니다: ```bash @@ -84,40 +77,6 @@ __참고__: 이 명령어는 제네시스에서의 처리를 위해 `gentx`를 ` `gentx`는 자체위임 정보가 포함된 JSON 파일입니다. 모든 제네시스 트랜잭셕은 `genesis coordinator`에 의하여 모아진 후 최초 `genesis.json`파일과 대치하여 검증합니다. 최초 `genesis.json`에는 계정 리스트와 각 계정이 보유하고 있는 코인 정보가 포함되어있습니다. 트랜잭션이 처리되었다면 해당 정보는 `genesis.json`의 `gentx` 항목에 머지(merge)됩니다. -### Case 2: 최초 위임이 위임자(delegator) 주소에서 발생하는 경우 - -이런 경우에는 위임자와 검증인의 서명이 둘다 필요합니다. 우선 서명이 되지 않은 `create-validator` 트랜잭션을 생성하신 후 `unsignedValTx`라는 파일에 저장하십시오: - -```bash -gaiacli tx staking create-validator \ - --amount=5STAKE \ - --pubkey=$(gaiad tendermint show-validator) \ - --moniker="choose a moniker" \ - --chain-id= \ - --from= \ - --commission-rate="0.10" \ - --commission-max-rate="0.20" \ - --commission-max-change-rate="0.01" \ - --address-delegator="address of the delegator" \ - --generate-only \ - > unsignedValTx.json -``` - -이제 해당 `unsignedValTx`를 밸리데이터의 프라이빗 키를 이용해 서명합니다. 서명이된 아웃풋을 `signedValTx.json`이라는 파일에 저장합니다: - -```bash -gaiacli tx sign unsignedValTx.json --from= > signedValTx.json -``` - -이제 이 파일을 위임자에게 전달하세요. 위임인은 다음 명령어를 실행하면 됩니다: - -```bash -gaiacli tx sign signedValTx.json --from= > gentx.json -``` - -이 파일은 제네시스 절차에서 필요하기 때문에 Case 1과 동일하게 `gentx.json`은 밸리데이터 머신의 `~/.gaiad/config/gentx` 폴더에 포함되어야 합니다 (Case 2 에서는 직접 해당 파을을 이동해야 합니다). - - ### 제네시스 파일 복사, 제네시스 트랜잭션 처리하기 우선 `genesis.json`파일을 `gaiad`의 config 디렉토리로 가져옵니다. diff --git a/x/staking/alias.go b/x/staking/alias.go index 5e9ddaccd0..999814b6d2 100644 --- a/x/staking/alias.go +++ b/x/staking/alias.go @@ -85,12 +85,11 @@ var ( DefaultGenesisState = types.DefaultGenesisState RegisterCodec = types.RegisterCodec - NewMsgCreateValidator = types.NewMsgCreateValidator - NewMsgCreateValidatorOnBehalfOf = types.NewMsgCreateValidatorOnBehalfOf - NewMsgEditValidator = types.NewMsgEditValidator - NewMsgDelegate = types.NewMsgDelegate - NewMsgUndelegate = types.NewMsgUndelegate - NewMsgBeginRedelegate = types.NewMsgBeginRedelegate + NewMsgCreateValidator = types.NewMsgCreateValidator + NewMsgEditValidator = types.NewMsgEditValidator + NewMsgDelegate = types.NewMsgDelegate + NewMsgUndelegate = types.NewMsgUndelegate + NewMsgBeginRedelegate = types.NewMsgBeginRedelegate NewQuerier = querier.NewQuerier NewQueryDelegatorParams = querier.NewQueryDelegatorParams diff --git a/x/staking/app_test.go b/x/staking/app_test.go index 65fc2292ee..d4481cef73 100644 --- a/x/staking/app_test.go +++ b/x/staking/app_test.go @@ -131,28 +131,13 @@ func TestStakingMsgs(t *testing.T) { require.Equal(t, sdk.Bonded, validator.Status) require.True(sdk.IntEq(t, bondTokens, validator.BondedTokens())) - // addr1 create validator on behalf of addr2 - createValidatorMsgOnBehalfOf := NewMsgCreateValidatorOnBehalfOf( - addr1, sdk.ValAddress(addr2), priv2.PubKey(), bondCoin, description, commissionMsg, sdk.OneInt(), - ) - - mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{createValidatorMsgOnBehalfOf}, []uint64{0, 0}, []uint64{1, 0}, true, true, priv1, priv2) - mock.CheckBalance(t, mApp, addr1, sdk.Coins{genCoin.Sub(bondCoin).Sub(bondCoin)}) mApp.BeginBlock(abci.RequestBeginBlock{}) - validator = checkValidator(t, mApp, keeper, sdk.ValAddress(addr2), true) - require.Equal(t, sdk.ValAddress(addr2), validator.OperatorAddress) - require.Equal(t, sdk.Bonded, validator.Status) - require.True(sdk.IntEq(t, bondTokens, validator.Tokens)) - - // check the bond that should have been created as well - checkDelegation(t, mApp, keeper, addr1, sdk.ValAddress(addr1), true, bondTokens.ToDec()) - // edit the validator description = NewDescription("bar_moniker", "", "", "") editValidatorMsg := NewMsgEditValidator(sdk.ValAddress(addr1), description, nil, nil) - mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{editValidatorMsg}, []uint64{0}, []uint64{2}, true, true, priv1) + mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{editValidatorMsg}, []uint64{0}, []uint64{1}, true, true, priv1) validator = checkValidator(t, mApp, keeper, sdk.ValAddress(addr1), true) require.Equal(t, description, validator.Description) @@ -160,13 +145,13 @@ func TestStakingMsgs(t *testing.T) { mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin}) delegateMsg := NewMsgDelegate(addr2, sdk.ValAddress(addr1), bondCoin) - mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{delegateMsg}, []uint64{0}, []uint64{1}, true, true, priv2) + mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{delegateMsg}, []uint64{0}, []uint64{0}, true, true, priv2) mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin.Sub(bondCoin)}) checkDelegation(t, mApp, keeper, addr2, sdk.ValAddress(addr1), true, bondTokens.ToDec()) // begin unbonding beginUnbondingMsg := NewMsgUndelegate(addr2, sdk.ValAddress(addr1), bondTokens.ToDec()) - mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{beginUnbondingMsg}, []uint64{0}, []uint64{2}, true, true, priv2) + mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{beginUnbondingMsg}, []uint64{0}, []uint64{1}, true, true, priv2) // delegation should exist anymore checkDelegation(t, mApp, keeper, addr2, sdk.ValAddress(addr1), false, sdk.Dec{}) diff --git a/x/staking/client/cli/flags.go b/x/staking/client/cli/flags.go index 14cac4c073..761d533ee1 100644 --- a/x/staking/client/cli/flags.go +++ b/x/staking/client/cli/flags.go @@ -8,7 +8,6 @@ import ( // nolint const ( - FlagAddressDelegator = "address-delegator" FlagAddressValidator = "validator" FlagAddressValidatorSrc = "addr-validator-source" FlagAddressValidatorDst = "addr-validator-dest" @@ -67,7 +66,6 @@ func init() { fsDescriptionEdit.String(FlagWebsite, types.DoNotModifyDesc, "The validator's (optional) website") fsDescriptionEdit.String(FlagDetails, types.DoNotModifyDesc, "The validator's (optional) details") fsValidator.String(FlagAddressValidator, "", "The Bech32 address of the validator") - fsDelegator.String(FlagAddressDelegator, "", "The Bech32 address of the delegator") fsRedelegation.String(FlagAddressValidatorSrc, "", "The Bech32 address of the source validator") fsRedelegation.String(FlagAddressValidatorDst, "", "The Bech32 address of the destination validator") } diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 74f4a76f48..b5eb8defa1 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -44,7 +44,7 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command { cmd.Flags().AddFlagSet(fsDescriptionCreate) cmd.Flags().AddFlagSet(FsCommissionCreate) cmd.Flags().AddFlagSet(FsMinSelfDelegation) - cmd.Flags().AddFlagSet(fsDelegator) + cmd.Flags().String(FlagIP, "", fmt.Sprintf("The node's public IP. It takes effect only when used in combination with --%s", client.FlagGenerateOnly)) cmd.Flags().String(FlagNodeID, "", "The node's ID") @@ -259,23 +259,9 @@ func BuildCreateValidatorMsg(cliCtx context.CLIContext, txBldr authtxb.TxBuilder return txBldr, nil, fmt.Errorf(staking.ErrMinSelfDelegationInvalid(staking.DefaultCodespace).Error()) } - delAddr := viper.GetString(FlagAddressDelegator) - - var msg sdk.Msg - if delAddr != "" { - delAddr, err := sdk.AccAddressFromBech32(delAddr) - if err != nil { - return txBldr, nil, err - } - - msg = staking.NewMsgCreateValidatorOnBehalfOf( - delAddr, sdk.ValAddress(valAddr), pk, amount, description, commissionMsg, minSelfDelegation, - ) - } else { - msg = staking.NewMsgCreateValidator( - sdk.ValAddress(valAddr), pk, amount, description, commissionMsg, minSelfDelegation, - ) - } + msg := staking.NewMsgCreateValidator( + sdk.ValAddress(valAddr), pk, amount, description, commissionMsg, minSelfDelegation, + ) if viper.GetBool(client.FlagGenerateOnly) { ip := viper.GetString(FlagIP) @@ -284,5 +270,6 @@ func BuildCreateValidatorMsg(cliCtx context.CLIContext, txBldr authtxb.TxBuilder txBldr = txBldr.WithMemo(fmt.Sprintf("%s@%s:26656", nodeID, ip)) } } + return txBldr, msg, nil } diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 348d07935b..97d306f6e1 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -178,38 +178,6 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { require.True(t, got.IsOK(), "%v", got) } -func TestDuplicatesMsgCreateValidatorOnBehalfOf(t *testing.T) { - ctx, _, keeper := keep.CreateTestInput(t, false, 1000) - - validatorAddr := sdk.ValAddress(keep.Addrs[0]) - delegatorAddr := keep.Addrs[1] - pk := keep.PKs[0] - valTokens := sdk.TokensFromTendermintPower(10) - msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr, pk, valTokens) - got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper) - require.True(t, got.IsOK(), "%v", got) - - // must end-block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, validatorAddr) - - require.True(t, found) - assert.Equal(t, sdk.Bonded, validator.Status) - assert.Equal(t, validatorAddr, validator.OperatorAddress) - assert.Equal(t, pk, validator.ConsPubKey) - assert.True(sdk.IntEq(t, valTokens, validator.Tokens)) - assert.True(sdk.DecEq(t, valTokens.ToDec(), validator.DelegatorShares)) - assert.Equal(t, Description{}, validator.Description) - - // one validator cannot be created twice even from different delegator - msgCreateValidatorOnBehalfOf.DelegatorAddress = keep.Addrs[2] - msgCreateValidatorOnBehalfOf.PubKey = keep.PKs[1] - got = handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper) - require.False(t, got.IsOK(), "%v", got) -} - func TestLegacyValidatorDelegations(t *testing.T) { ctx, _, keeper := keep.CreateTestInput(t, false, int64(1000)) setInstantUnbondPeriod(keeper, ctx) @@ -555,25 +523,27 @@ func TestMultipleMsgCreateValidator(t *testing.T) { sdk.ValAddress(keep.Addrs[2]), } delegatorAddrs := []sdk.AccAddress{ - keep.Addrs[3], - keep.Addrs[4], - keep.Addrs[5], + keep.Addrs[0], + keep.Addrs[1], + keep.Addrs[2], } // bond them all for i, validatorAddr := range validatorAddrs { valTokens := sdk.TokensFromTendermintPower(10) - msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidatorOnBehalfOf( - delegatorAddrs[i], validatorAddr, keep.PKs[i], valTokens) + msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidator(validatorAddr, keep.PKs[i], valTokens) + got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper) require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) - //Check that the account is bonded + // verify that the account is bonded validators := keeper.GetValidators(ctx, 100) require.Equal(t, (i + 1), len(validators)) + val := validators[i] balanceExpd := initTokens.Sub(valTokens) balanceGot := accMapper.GetAccount(ctx, delegatorAddrs[i]).GetCoins().AmountOf(params.BondDenom) + require.Equal(t, i+1, len(validators), "expected %d validators got %d, validators: %v", i+1, len(validators), validators) require.Equal(t, valTokens, val.DelegatorShares.RoundInt(), "expected %d shares, got %d", 10, val.DelegatorShares) require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) diff --git a/x/staking/test_common.go b/x/staking/test_common.go index 62cee84db2..634d924ac5 100644 --- a/x/staking/test_common.go +++ b/x/staking/test_common.go @@ -54,10 +54,3 @@ func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk. amount := sdk.NewCoin(sdk.DefaultBondDenom, amt) return NewMsgDelegate(delAddr, valAddr, amount) } - -func NewTestMsgCreateValidatorOnBehalfOf(delAddr sdk.AccAddress, valAddr sdk.ValAddress, - valPubKey crypto.PubKey, amt sdk.Int) MsgCreateValidator { - - amount := sdk.NewCoin(sdk.DefaultBondDenom, amt) - return NewMsgCreateValidatorOnBehalfOf(delAddr, valAddr, valPubKey, amount, Description{}, commissionMsg, sdk.OneInt()) -} diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index 620ea1e9f7..f9c2eea77f 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -42,23 +42,17 @@ type msgCreateValidatorJSON struct { } // Default way to create validator. Delegator address and validator address are the same -func NewMsgCreateValidator(valAddr sdk.ValAddress, pubkey crypto.PubKey, - selfDelegation sdk.Coin, description Description, commission CommissionMsg, minSelfDelegation sdk.Int) MsgCreateValidator { +func NewMsgCreateValidator( + valAddr sdk.ValAddress, pubKey crypto.PubKey, selfDelegation sdk.Coin, + description Description, commission CommissionMsg, minSelfDelegation sdk.Int, +) MsgCreateValidator { - return NewMsgCreateValidatorOnBehalfOf( - sdk.AccAddress(valAddr), valAddr, pubkey, selfDelegation, description, commission, minSelfDelegation, - ) -} - -// Creates validator msg by delegator address on behalf of validator address -func NewMsgCreateValidatorOnBehalfOf(delAddr sdk.AccAddress, valAddr sdk.ValAddress, - pubkey crypto.PubKey, value sdk.Coin, description Description, commission CommissionMsg, minSelfDelegation sdk.Int) MsgCreateValidator { return MsgCreateValidator{ Description: description, - DelegatorAddress: delAddr, + DelegatorAddress: sdk.AccAddress(valAddr), ValidatorAddress: valAddr, - PubKey: pubkey, - Value: value, + PubKey: pubKey, + Value: selfDelegation, Commission: commission, MinSelfDelegation: minSelfDelegation, } @@ -133,6 +127,9 @@ func (msg MsgCreateValidator) ValidateBasic() sdk.Error { if msg.ValidatorAddress.Empty() { return ErrNilValidatorAddr(DefaultCodespace) } + if !sdk.AccAddress(msg.ValidatorAddress).Equals(msg.DelegatorAddress) { + return ErrBadValidatorAddr(DefaultCodespace) + } if msg.Value.Amount.LTE(sdk.ZeroInt()) { return ErrBadDelegationAmount(DefaultCodespace) } diff --git a/x/staking/types/msg_test.go b/x/staking/types/msg_test.go index 1e124e20ed..a2a60a44e7 100644 --- a/x/staking/types/msg_test.go +++ b/x/staking/types/msg_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" @@ -78,55 +77,6 @@ func TestMsgEditValidator(t *testing.T) { } } -// test ValidateBasic and GetSigners for MsgCreateValidatorOnBehalfOf -func TestMsgCreateValidatorOnBehalfOf(t *testing.T) { - commission1 := NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) - commission2 := NewCommissionMsg(sdk.NewDec(5), sdk.NewDec(5), sdk.NewDec(5)) - - tests := []struct { - name, moniker, identity, website, details string - commissionMsg CommissionMsg - minSelfDelegation sdk.Int - delegatorAddr sdk.AccAddress - validatorAddr sdk.ValAddress - validatorPubKey crypto.PubKey - bond sdk.Coin - expectPass bool - }{ - {"basic good", "a", "b", "c", "d", commission2, sdk.OneInt(), sdk.AccAddress(addr1), addr2, pk2, coinPos, true}, - {"partial description", "", "", "c", "", commission2, sdk.OneInt(), sdk.AccAddress(addr1), addr2, pk2, coinPos, true}, - {"empty description", "", "", "", "", commission1, sdk.OneInt(), sdk.AccAddress(addr1), addr2, pk2, coinPos, false}, - {"empty delegator address", "a", "b", "c", "d", commission1, sdk.OneInt(), sdk.AccAddress(emptyAddr), addr2, pk2, coinPos, false}, - {"empty validator address", "a", "b", "c", "d", commission2, sdk.OneInt(), sdk.AccAddress(addr1), emptyAddr, pk2, coinPos, false}, - {"empty pubkey", "a", "b", "c", "d", commission1, sdk.OneInt(), sdk.AccAddress(addr1), addr2, emptyPubkey, coinPos, true}, - {"empty bond", "a", "b", "c", "d", commission2, sdk.OneInt(), sdk.AccAddress(addr1), addr2, pk2, coinZero, false}, - {"zero min self delegation", "a", "b", "c", "d", commission2, sdk.ZeroInt(), sdk.AccAddress(addr1), addr2, pk2, coinPos, false}, - {"negative min self delegation", "", "", "c", "", commission2, sdk.NewInt(-1), sdk.AccAddress(addr1), addr2, pk2, coinPos, false}, - {"delegation less than min self delegation", "a", "b", "c", "d", commission2, coinPos.Amount.Add(sdk.OneInt()), sdk.AccAddress(addr1), addr2, pk2, coinPos, false}, - } - - for _, tc := range tests { - description := NewDescription(tc.moniker, tc.identity, tc.website, tc.details) - msg := NewMsgCreateValidatorOnBehalfOf( - tc.delegatorAddr, tc.validatorAddr, tc.validatorPubKey, tc.bond, description, tc.commissionMsg, tc.minSelfDelegation, - ) - - if tc.expectPass { - require.Nil(t, msg.ValidateBasic(), "test: %v", tc.name) - } else { - require.NotNil(t, msg.ValidateBasic(), "test: %v", tc.name) - } - } - - msg := NewMsgCreateValidator(addr1, pk1, coinPos, Description{}, CommissionMsg{}, sdk.OneInt()) - addrs := msg.GetSigners() - require.Equal(t, []sdk.AccAddress{sdk.AccAddress(addr1)}, addrs, "Signers on default msg is wrong") - - msg = NewMsgCreateValidatorOnBehalfOf(sdk.AccAddress(addr2), addr1, pk1, coinPos, Description{}, CommissionMsg{}, sdk.OneInt()) - addrs = msg.GetSigners() - require.Equal(t, []sdk.AccAddress{sdk.AccAddress(addr2), sdk.AccAddress(addr1)}, addrs, "Signers for onbehalfof msg is wrong") -} - // test ValidateBasic for MsgDelegate func TestMsgDelegate(t *testing.T) { tests := []struct {