Merge pull request #1609: prevent create-validator with duplicate pubkey

This commit is contained in:
rigelrozanski 2018-07-09 20:42:57 -04:00
parent 777d7bee5a
commit f8b625b391
5 changed files with 56 additions and 25 deletions

View File

@ -124,6 +124,7 @@ BUG FIXES
* [x/stake] fix revoke bytes ordering (was putting revoked candidates at the top of the list)
* [x/stake] bond count was counting revoked validators as bonded, fixed
* \#1565 - fix cliff validator persisting when validator set shrinks from max
* \#1010 - two validators can't bond with the same pubkey anymore
## 0.19.0

View File

@ -65,7 +65,11 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k
// check to see if the pubkey or sender has been registered before
_, found := k.GetValidator(ctx, msg.ValidatorAddr)
if found {
return ErrValidatorAlreadyExists(k.Codespace()).Result()
return ErrValidatorOwnerExists(k.Codespace()).Result()
}
_, found = k.GetValidatorByPubKey(ctx, msg.PubKey)
if found {
return ErrValidatorPubKeyExists(k.Codespace()).Result()
}
if msg.SelfDelegation.Denom != k.GetParams(ctx).BondDenom {
return ErrBadDenom(k.Codespace()).Result()

View File

@ -3,6 +3,7 @@ package stake
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
@ -118,25 +119,45 @@ func TestValidatorByPowerIndex(t *testing.T) {
func TestDuplicatesMsgCreateValidator(t *testing.T) {
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
validatorAddr := keep.Addrs[0]
pk := keep.PKs[0]
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pk, 10)
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
addr1, addr2 := keep.Addrs[0], keep.Addrs[1]
pk1, pk2 := keep.PKs[0], keep.PKs[1]
msgCreateValidator1 := newTestMsgCreateValidator(addr1, pk1, 10)
got := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper)
require.True(t, got.IsOK(), "%v", got)
validator, found := keeper.GetValidator(ctx, validatorAddr)
validator, found := keeper.GetValidator(ctx, addr1)
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)
assert.Equal(t, sdk.Bonded, validator.Status())
assert.Equal(t, addr1, validator.Owner)
assert.Equal(t, pk1, validator.PubKey)
assert.Equal(t, sdk.NewRat(10), validator.PoolShares.Bonded())
assert.Equal(t, sdk.NewRat(10), validator.DelegatorShares)
assert.Equal(t, Description{}, validator.Description)
// one validator cannot bond twice
msgCreateValidator.PubKey = keep.PKs[1]
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
// two validators can't have the same owner address
msgCreateValidator2 := newTestMsgCreateValidator(addr1, pk2, 10)
got = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper)
require.False(t, got.IsOK(), "%v", got)
// two validators can't have the same pubkey
msgCreateValidator3 := newTestMsgCreateValidator(addr2, pk1, 10)
got = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper)
require.False(t, got.IsOK(), "%v", got)
// must have different pubkey and owner
msgCreateValidator4 := newTestMsgCreateValidator(addr2, pk2, 10)
got = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper)
require.True(t, got.IsOK(), "%v", got)
validator, found = keeper.GetValidator(ctx, addr2)
require.True(t, found)
assert.Equal(t, sdk.Bonded, validator.Status())
assert.Equal(t, addr2, validator.Owner)
assert.Equal(t, pk2, validator.PubKey)
assert.Equal(t, sdk.NewRat(10), validator.PoolShares.Bonded())
assert.Equal(t, sdk.NewRat(10), validator.DelegatorShares)
assert.Equal(t, Description{}, validator.Description)
}
func TestIncrementsMsgDelegate(t *testing.T) {

View File

@ -92,14 +92,15 @@ const (
)
var (
ErrNilValidatorAddr = types.ErrNilValidatorAddr
ErrNoValidatorFound = types.ErrNoValidatorFound
ErrValidatorAlreadyExists = types.ErrValidatorAlreadyExists
ErrValidatorRevoked = types.ErrValidatorRevoked
ErrBadRemoveValidator = types.ErrBadRemoveValidator
ErrDescriptionLength = types.ErrDescriptionLength
ErrCommissionNegative = types.ErrCommissionNegative
ErrCommissionHuge = types.ErrCommissionHuge
ErrNilValidatorAddr = types.ErrNilValidatorAddr
ErrNoValidatorFound = types.ErrNoValidatorFound
ErrValidatorOwnerExists = types.ErrValidatorOwnerExists
ErrValidatorPubKeyExists = types.ErrValidatorPubKeyExists
ErrValidatorRevoked = types.ErrValidatorRevoked
ErrBadRemoveValidator = types.ErrBadRemoveValidator
ErrDescriptionLength = types.ErrDescriptionLength
ErrCommissionNegative = types.ErrCommissionNegative
ErrCommissionHuge = types.ErrCommissionHuge
ErrNilDelegatorAddr = types.ErrNilDelegatorAddr
ErrBadDenom = types.ErrBadDenom

View File

@ -30,8 +30,12 @@ func ErrNoValidatorFound(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator does not exist for that address")
}
func ErrValidatorAlreadyExists(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist, cannot re-create validator")
func ErrValidatorOwnerExists(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist for this owner-address, must use new validator-owner address")
}
func ErrValidatorPubKeyExists(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist for this pubkey, must use new validator pubkey")
}
func ErrValidatorRevoked(codespace sdk.CodespaceType) sdk.Error {