Merge pull request #1600: Friend can create validator and delegate on behalf of genesis validator
* Added msg and handling for surrogate create validator * changelog and error fix * fix changelog * Remove unnecessary msg by combining into CreateValidator * Refactor * Appease linter * Added onbehalfof functionality in client * fmt * Added gaia onbehalfof test * Update test for onbehalfof validator creation * fix test * Fix flag error * Add app test * fmt * Fixed signer for onbehalfof createvalidator * Fix error msg * Simplify test * fmt
This commit is contained in:
parent
9afb89491c
commit
b195c556e2
|
@ -89,6 +89,7 @@ FEATURES
|
|||
* [tests] created a randomized testing framework.
|
||||
- Currently bank has limited functionality in the framework
|
||||
- Auth has its invariants checked within the framework
|
||||
* [x/stake] Allow validator to be created with starting delegation by a third-party delegator on behalf of validator.
|
||||
* [tests] Add WaitForNextNBlocksTM helper method
|
||||
* [keys] New keys now have 24 word recovery keys, for heightened security
|
||||
|
||||
|
|
|
@ -729,7 +729,7 @@ func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr,
|
|||
{
|
||||
"delegator_addr": "%s",
|
||||
"validator_addr": "%s",
|
||||
"bond": { "denom": "%s", "amount": "60" }
|
||||
"delegation": { "denom": "%s", "amount": "60" }
|
||||
}
|
||||
],
|
||||
"begin_unbondings": [],
|
||||
|
|
|
@ -94,9 +94,10 @@ func testAddr(addr string) sdk.AccAddress {
|
|||
|
||||
func newTestMsgCreateValidator(address sdk.AccAddress, pubKey crypto.PubKey, amt sdk.Int) stake.MsgCreateValidator {
|
||||
return stake.MsgCreateValidator{
|
||||
Description: stake.Description{},
|
||||
ValidatorAddr: address,
|
||||
PubKey: pubKey,
|
||||
SelfDelegation: sdk.Coin{"steak", amt},
|
||||
Description: stake.Description{},
|
||||
DelegatorAddr: address,
|
||||
ValidatorAddr: address,
|
||||
PubKey: pubKey,
|
||||
Delegation: sdk.Coin{"steak", amt},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ func checkValidator(t *testing.T, mapp *mock.App, keeper Keeper,
|
|||
addr sdk.AccAddress, expFound bool) Validator {
|
||||
|
||||
ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{})
|
||||
validator, found := keeper.GetValidator(ctxCheck, addr1)
|
||||
validator, found := keeper.GetValidator(ctxCheck, addr)
|
||||
|
||||
require.Equal(t, expFound, found)
|
||||
return validator
|
||||
|
@ -138,6 +138,18 @@ func TestStakeMsgs(t *testing.T) {
|
|||
require.Equal(t, sdk.Bonded, validator.Status())
|
||||
require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded()))
|
||||
|
||||
// addr1 create validator on behalf of addr2
|
||||
createValidatorMsgOnBehalfOf := NewMsgCreateValidatorOnBehalfOf(addr1, addr2, priv2.PubKey(), bondCoin, description)
|
||||
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{createValidatorMsgOnBehalfOf}, []int64{0, 1}, []int64{1, 0}, true, priv1, priv2)
|
||||
mock.CheckBalance(t, mApp, addr1, sdk.Coins{genCoin.Minus(bondCoin).Minus(bondCoin)})
|
||||
mApp.BeginBlock(abci.RequestBeginBlock{})
|
||||
|
||||
validator = checkValidator(t, mApp, keeper, addr2, true)
|
||||
require.Equal(t, addr2, validator.Owner)
|
||||
require.Equal(t, sdk.Bonded, validator.Status())
|
||||
require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded()))
|
||||
|
||||
// check the bond that should have been created as well
|
||||
checkDelegation(t, mApp, keeper, addr1, addr1, true, sdk.NewRat(10))
|
||||
|
||||
|
@ -145,7 +157,7 @@ func TestStakeMsgs(t *testing.T) {
|
|||
description = NewDescription("bar_moniker", "", "", "")
|
||||
editValidatorMsg := NewMsgEditValidator(addr1, description)
|
||||
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{editValidatorMsg}, []int64{0}, []int64{1}, true, priv1)
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{editValidatorMsg}, []int64{0}, []int64{2}, true, priv1)
|
||||
validator = checkValidator(t, mApp, keeper, addr1, true)
|
||||
require.Equal(t, description, validator.Description)
|
||||
|
||||
|
@ -153,13 +165,13 @@ func TestStakeMsgs(t *testing.T) {
|
|||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin})
|
||||
delegateMsg := NewMsgDelegate(addr2, addr1, bondCoin)
|
||||
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{delegateMsg}, []int64{1}, []int64{0}, true, priv2)
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{delegateMsg}, []int64{1}, []int64{1}, true, priv2)
|
||||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin.Minus(bondCoin)})
|
||||
checkDelegation(t, mApp, keeper, addr2, addr1, true, sdk.NewRat(10))
|
||||
|
||||
// begin unbonding
|
||||
beginUnbondingMsg := NewMsgBeginUnbonding(addr2, addr1, sdk.NewRat(10))
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{beginUnbondingMsg}, []int64{1}, []int64{1}, true, priv2)
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{beginUnbondingMsg}, []int64{1}, []int64{2}, true, priv2)
|
||||
|
||||
// delegation should exist anymore
|
||||
checkDelegation(t, mApp, keeper, addr2, addr1, false, sdk.Rat{})
|
||||
|
|
|
@ -50,7 +50,17 @@ func GetCmdCreateValidator(cdc *wire.Codec) *cobra.Command {
|
|||
Website: viper.GetString(FlagWebsite),
|
||||
Details: viper.GetString(FlagDetails),
|
||||
}
|
||||
msg := stake.NewMsgCreateValidator(validatorAddr, pk, amount, description)
|
||||
|
||||
var msg sdk.Msg
|
||||
if viper.GetString(FlagAddressDelegator) != "" {
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg = stake.NewMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr, pk, amount, description)
|
||||
} else {
|
||||
msg = stake.NewMsgCreateValidator(validatorAddr, pk, amount, description)
|
||||
}
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc)
|
||||
|
@ -65,6 +75,7 @@ func GetCmdCreateValidator(cdc *wire.Codec) *cobra.Command {
|
|||
cmd.Flags().AddFlagSet(fsAmount)
|
||||
cmd.Flags().AddFlagSet(fsDescription)
|
||||
cmd.Flags().AddFlagSet(fsValidator)
|
||||
cmd.Flags().AddFlagSet(fsDelegator)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ func registerTxRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, k
|
|||
type msgDelegationsInput struct {
|
||||
DelegatorAddr string `json:"delegator_addr"` // in bech32
|
||||
ValidatorAddr string `json:"validator_addr"` // in bech32
|
||||
Bond sdk.Coin `json:"bond"`
|
||||
Delegation sdk.Coin `json:"delegation"`
|
||||
}
|
||||
type msgBeginRedelegateInput struct {
|
||||
DelegatorAddr string `json:"delegator_addr"` // in bech32
|
||||
|
@ -119,7 +119,7 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx conte
|
|||
messages[i] = stake.MsgDelegate{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
Bond: msg.Bond,
|
||||
Delegation: msg.Delegation,
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k
|
|||
if found {
|
||||
return ErrValidatorPubKeyExists(k.Codespace()).Result()
|
||||
}
|
||||
if msg.SelfDelegation.Denom != k.GetParams(ctx).BondDenom {
|
||||
if msg.Delegation.Denom != k.GetParams(ctx).BondDenom {
|
||||
return ErrBadDenom(k.Codespace()).Result()
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k
|
|||
|
||||
// move coins from the msg.Address account to a (self-delegation) delegator account
|
||||
// the validator account and global shares are updated within here
|
||||
_, err := k.Delegate(ctx, msg.ValidatorAddr, msg.SelfDelegation, validator)
|
||||
_, err := k.Delegate(ctx, msg.DelegatorAddr, msg.Delegation, validator)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
@ -130,13 +130,13 @@ func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper)
|
|||
if !found {
|
||||
return ErrNoValidatorFound(k.Codespace()).Result()
|
||||
}
|
||||
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
|
||||
if msg.Delegation.Denom != k.GetParams(ctx).BondDenom {
|
||||
return ErrBadDenom(k.Codespace()).Result()
|
||||
}
|
||||
if validator.Revoked == true {
|
||||
return ErrValidatorRevoked(k.Codespace()).Result()
|
||||
}
|
||||
_, err := k.Delegate(ctx, msg.DelegatorAddr, msg.Bond, validator)
|
||||
_, err := k.Delegate(ctx, msg.DelegatorAddr, msg.Delegation, validator)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
|
|
@ -16,19 +16,24 @@ import (
|
|||
//______________________________________________________________________
|
||||
|
||||
func newTestMsgCreateValidator(address sdk.AccAddress, pubKey crypto.PubKey, amt int64) MsgCreateValidator {
|
||||
return MsgCreateValidator{
|
||||
Description: Description{},
|
||||
ValidatorAddr: address,
|
||||
PubKey: pubKey,
|
||||
SelfDelegation: sdk.Coin{"steak", sdk.NewInt(amt)},
|
||||
}
|
||||
return types.NewMsgCreateValidator(address, pubKey, sdk.Coin{"steak", sdk.NewInt(amt)}, Description{})
|
||||
}
|
||||
|
||||
func newTestMsgDelegate(delegatorAddr, validatorAddr sdk.AccAddress, amt int64) MsgDelegate {
|
||||
return MsgDelegate{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
Bond: sdk.Coin{"steak", sdk.NewInt(amt)},
|
||||
Delegation: sdk.Coin{"steak", sdk.NewInt(amt)},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr sdk.AccAddress, valPubKey crypto.PubKey, amt int64) MsgCreateValidator {
|
||||
return MsgCreateValidator{
|
||||
Description: Description{},
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
PubKey: valPubKey,
|
||||
Delegation: sdk.Coin{"steak", sdk.NewInt(amt)},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +165,32 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) {
|
|||
assert.Equal(t, Description{}, validator.Description)
|
||||
}
|
||||
|
||||
func TestDuplicatesMsgCreateValidatorOnBehalfOf(t *testing.T) {
|
||||
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
|
||||
|
||||
validatorAddr := keep.Addrs[0]
|
||||
delegatorAddr := keep.Addrs[1]
|
||||
pk := keep.PKs[0]
|
||||
msgCreateValidatorOnBehalfOf := newTestMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr, pk, 10)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper)
|
||||
require.True(t, got.IsOK(), "%v", got)
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
|
||||
require.True(t, found)
|
||||
require.Equal(t, sdk.Bonded, validator.Status())
|
||||
require.Equal(t, validatorAddr, validator.Owner)
|
||||
require.Equal(t, pk, validator.PubKey)
|
||||
require.Equal(t, sdk.NewRat(10), validator.PoolShares.Bonded())
|
||||
require.Equal(t, sdk.NewRat(10), validator.DelegatorShares)
|
||||
require.Equal(t, Description{}, validator.Description)
|
||||
|
||||
// one validator cannot be created twice even from different delegator
|
||||
msgCreateValidatorOnBehalfOf.DelegatorAddr = keep.Addrs[2]
|
||||
msgCreateValidatorOnBehalfOf.PubKey = keep.PKs[1]
|
||||
got = handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper)
|
||||
require.False(t, got.IsOK(), "%v", got)
|
||||
}
|
||||
|
||||
func TestIncrementsMsgDelegate(t *testing.T) {
|
||||
initBond := int64(1000)
|
||||
ctx, accMapper, keeper := keep.CreateTestInput(t, false, initBond)
|
||||
|
@ -329,11 +360,12 @@ func TestMultipleMsgCreateValidator(t *testing.T) {
|
|||
params := setInstantUnbondPeriod(keeper, ctx)
|
||||
|
||||
validatorAddrs := []sdk.AccAddress{keep.Addrs[0], keep.Addrs[1], keep.Addrs[2]}
|
||||
delegatorAddrs := []sdk.AccAddress{keep.Addrs[3], keep.Addrs[4], keep.Addrs[5]}
|
||||
|
||||
// bond them all
|
||||
for i, validatorAddr := range validatorAddrs {
|
||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[i], 10)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
msgCreateValidatorOnBehalfOf := newTestMsgCreateValidatorOnBehalfOf(delegatorAddrs[i], validatorAddr, keep.PKs[i], 10)
|
||||
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
|
||||
|
@ -341,18 +373,18 @@ func TestMultipleMsgCreateValidator(t *testing.T) {
|
|||
require.Equal(t, (i + 1), len(validators))
|
||||
val := validators[i]
|
||||
balanceExpd := sdk.NewInt(initBond - 10)
|
||||
balanceGot := accMapper.GetAccount(ctx, val.Owner).GetCoins().AmountOf(params.BondDenom)
|
||||
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, 10, int(val.DelegatorShares.RoundInt64()), "expected %d shares, got %d", 10, val.DelegatorShares)
|
||||
require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot)
|
||||
}
|
||||
|
||||
// unbond them all
|
||||
// unbond them all by revoking delegation
|
||||
for i, validatorAddr := range validatorAddrs {
|
||||
validatorPre, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
_, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
msgBeginUnbonding := NewMsgBeginUnbonding(validatorAddr, validatorAddr, sdk.NewRat(10)) // self-delegation
|
||||
msgCompleteUnbonding := NewMsgCompleteUnbonding(validatorAddr, validatorAddr)
|
||||
msgBeginUnbonding := NewMsgBeginUnbonding(delegatorAddrs[i], validatorAddr, sdk.NewRat(10)) // remove delegation
|
||||
msgCompleteUnbonding := NewMsgCompleteUnbonding(delegatorAddrs[i], validatorAddr)
|
||||
got := handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbonding, keeper)
|
||||
|
@ -367,7 +399,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) {
|
|||
require.False(t, found)
|
||||
|
||||
expBalance := sdk.NewInt(initBond)
|
||||
gotBalance := accMapper.GetAccount(ctx, validatorPre.Owner).GetCoins().AmountOf(params.BondDenom)
|
||||
gotBalance := accMapper.GetAccount(ctx, delegatorAddrs[i]).GetCoins().AmountOf(params.BondDenom)
|
||||
require.Equal(t, expBalance, gotBalance, "expected account to have %d, got %d", expBalance, gotBalance)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,13 +71,14 @@ var (
|
|||
DefaultGenesisState = types.DefaultGenesisState
|
||||
RegisterWire = types.RegisterWire
|
||||
|
||||
NewMsgCreateValidator = types.NewMsgCreateValidator
|
||||
NewMsgEditValidator = types.NewMsgEditValidator
|
||||
NewMsgDelegate = types.NewMsgDelegate
|
||||
NewMsgBeginUnbonding = types.NewMsgBeginUnbonding
|
||||
NewMsgCompleteUnbonding = types.NewMsgCompleteUnbonding
|
||||
NewMsgBeginRedelegate = types.NewMsgBeginRedelegate
|
||||
NewMsgCompleteRedelegate = types.NewMsgCompleteRedelegate
|
||||
NewMsgCreateValidator = types.NewMsgCreateValidator
|
||||
NewMsgCreateValidatorOnBehalfOf = types.NewMsgCreateValidatorOnBehalfOf
|
||||
NewMsgEditValidator = types.NewMsgEditValidator
|
||||
NewMsgDelegate = types.NewMsgDelegate
|
||||
NewMsgBeginUnbonding = types.NewMsgBeginUnbonding
|
||||
NewMsgCompleteUnbonding = types.NewMsgCompleteUnbonding
|
||||
NewMsgBeginRedelegate = types.NewMsgBeginRedelegate
|
||||
NewMsgCompleteRedelegate = types.NewMsgCompleteRedelegate
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -2,6 +2,7 @@ package types
|
|||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
@ -27,38 +28,63 @@ var maximumBondingRationalDenominator sdk.Int = sdk.NewInt(int64(math.Pow10(MaxB
|
|||
// MsgCreateValidator - struct for unbonding transactions
|
||||
type MsgCreateValidator struct {
|
||||
Description
|
||||
ValidatorAddr sdk.AccAddress `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pubkey"`
|
||||
SelfDelegation sdk.Coin `json:"self_delegation"`
|
||||
DelegatorAddr sdk.AccAddress `json:"delegator_address"`
|
||||
ValidatorAddr sdk.AccAddress `json:"validator_address"`
|
||||
PubKey crypto.PubKey `json:"pubkey"`
|
||||
Delegation sdk.Coin `json:"delegation"`
|
||||
}
|
||||
|
||||
// Default way to create validator. Delegator address and validator address are the same
|
||||
func NewMsgCreateValidator(validatorAddr sdk.AccAddress, pubkey crypto.PubKey,
|
||||
selfDelegation sdk.Coin, description Description) MsgCreateValidator {
|
||||
return MsgCreateValidator{
|
||||
Description: description,
|
||||
ValidatorAddr: validatorAddr,
|
||||
PubKey: pubkey,
|
||||
SelfDelegation: selfDelegation,
|
||||
Description: description,
|
||||
DelegatorAddr: validatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
PubKey: pubkey,
|
||||
Delegation: selfDelegation,
|
||||
}
|
||||
}
|
||||
|
||||
// Creates validator msg by delegator address on behalf of validator address
|
||||
func NewMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr sdk.AccAddress, pubkey crypto.PubKey,
|
||||
delegation sdk.Coin, description Description) MsgCreateValidator {
|
||||
return MsgCreateValidator{
|
||||
Description: description,
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
PubKey: pubkey,
|
||||
Delegation: delegation,
|
||||
}
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgCreateValidator) Type() string { return MsgType }
|
||||
|
||||
// Return address(es) that must sign over msg.GetSignBytes()
|
||||
func (msg MsgCreateValidator) GetSigners() []sdk.AccAddress {
|
||||
return []sdk.AccAddress{msg.ValidatorAddr}
|
||||
// delegator is first signer so delegator pays fees
|
||||
addrs := []sdk.AccAddress{msg.DelegatorAddr}
|
||||
if !reflect.DeepEqual(msg.DelegatorAddr, msg.ValidatorAddr) {
|
||||
// if validator addr is not same as delegator addr, validator must sign msg as well
|
||||
addrs = append(addrs, msg.ValidatorAddr)
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
// get the bytes for the message signer to sign on
|
||||
func (msg MsgCreateValidator) GetSignBytes() []byte {
|
||||
b, err := MsgCdc.MarshalJSON(struct {
|
||||
Description
|
||||
ValidatorAddr sdk.AccAddress `json:"address"`
|
||||
DelegatorAddr sdk.AccAddress `json:"delegator_address"`
|
||||
ValidatorAddr sdk.AccAddress `json:"validator_address"`
|
||||
PubKey string `json:"pubkey"`
|
||||
Bond sdk.Coin `json:"bond"`
|
||||
Delegation sdk.Coin `json:"delegation"`
|
||||
}{
|
||||
Description: msg.Description,
|
||||
ValidatorAddr: msg.ValidatorAddr,
|
||||
PubKey: sdk.MustBech32ifyValPub(msg.PubKey),
|
||||
Delegation: msg.Delegation,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -68,10 +94,13 @@ func (msg MsgCreateValidator) GetSignBytes() []byte {
|
|||
|
||||
// quick validity check
|
||||
func (msg MsgCreateValidator) ValidateBasic() sdk.Error {
|
||||
if msg.DelegatorAddr == nil {
|
||||
return ErrNilDelegatorAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.ValidatorAddr == nil {
|
||||
return ErrNilValidatorAddr(DefaultCodespace)
|
||||
}
|
||||
if !(msg.SelfDelegation.Amount.GT(sdk.ZeroInt())) {
|
||||
if !(msg.Delegation.Amount.GT(sdk.ZeroInt())) {
|
||||
return ErrBadDelegationAmount(DefaultCodespace)
|
||||
}
|
||||
empty := Description{}
|
||||
|
@ -135,14 +164,14 @@ func (msg MsgEditValidator) ValidateBasic() sdk.Error {
|
|||
type MsgDelegate struct {
|
||||
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
||||
ValidatorAddr sdk.AccAddress `json:"validator_addr"`
|
||||
Bond sdk.Coin `json:"bond"`
|
||||
Delegation sdk.Coin `json:"delegation"`
|
||||
}
|
||||
|
||||
func NewMsgDelegate(delegatorAddr, validatorAddr sdk.AccAddress, bond sdk.Coin) MsgDelegate {
|
||||
func NewMsgDelegate(delegatorAddr, validatorAddr sdk.AccAddress, delegation sdk.Coin) MsgDelegate {
|
||||
return MsgDelegate{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
Bond: bond,
|
||||
Delegation: delegation,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +198,7 @@ func (msg MsgDelegate) ValidateBasic() sdk.Error {
|
|||
if msg.ValidatorAddr == nil {
|
||||
return ErrNilValidatorAddr(DefaultCodespace)
|
||||
}
|
||||
if !(msg.Bond.Amount.GT(sdk.ZeroInt())) {
|
||||
if !(msg.Delegation.Amount.GT(sdk.ZeroInt())) {
|
||||
return ErrBadDelegationAmount(DefaultCodespace)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -69,6 +69,46 @@ func TestMsgEditValidator(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// test ValidateBasic and GetSigners for MsgCreateValidatorOnBehalfOf
|
||||
func TestMsgCreateValidatorOnBehalfOf(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, moniker, identity, website, details string
|
||||
delegatorAddr sdk.AccAddress
|
||||
validatorAddr sdk.AccAddress
|
||||
validatorPubKey crypto.PubKey
|
||||
bond sdk.Coin
|
||||
expectPass bool
|
||||
}{
|
||||
{"basic good", "a", "b", "c", "d", addr1, addr2, pk2, coinPos, true},
|
||||
{"partial description", "", "", "c", "", addr1, addr2, pk2, coinPos, true},
|
||||
{"empty description", "", "", "", "", addr1, addr2, pk2, coinPos, false},
|
||||
{"empty delegator address", "a", "b", "c", "d", emptyAddr, addr2, pk2, coinPos, false},
|
||||
{"empty validator address", "a", "b", "c", "d", addr1, emptyAddr, pk2, coinPos, false},
|
||||
{"empty pubkey", "a", "b", "c", "d", addr1, addr2, emptyPubkey, coinPos, true},
|
||||
{"empty bond", "a", "b", "c", "d", addr1, addr2, pk2, coinZero, false},
|
||||
{"negative bond", "a", "b", "c", "d", addr1, addr2, pk2, coinNeg, false},
|
||||
{"negative bond", "a", "b", "c", "d", addr1, addr2, pk2, coinNeg, 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)
|
||||
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{})
|
||||
addrs := msg.GetSigners()
|
||||
require.Equal(t, []sdk.AccAddress{addr1}, addrs, "Signers on default msg is wrong")
|
||||
|
||||
msg = NewMsgCreateValidatorOnBehalfOf(addr2, addr1, pk1, coinPos, Description{})
|
||||
addrs = msg.GetSigners()
|
||||
require.Equal(t, []sdk.AccAddress{addr2, addr1}, addrs, "Signers for onbehalfof msg is wrong")
|
||||
}
|
||||
|
||||
// test ValidateBasic for MsgDelegate
|
||||
func TestMsgDelegate(t *testing.T) {
|
||||
tests := []struct {
|
||||
|
|
Loading…
Reference in New Issue