Merge PR #4865: Add security contact to Validator description
This commit is contained in:
parent
a6e776c47e
commit
771f8a04f3
1
.pending/improvements/modules/_4814-Add-security-c
Normal file
1
.pending/improvements/modules/_4814-Add-security-c
Normal file
@ -0,0 +1 @@
|
||||
#4814 Add security contact to Validator description
|
||||
2
client/lcd/swagger-ui/swagger.yaml
vendored
2
client/lcd/swagger-ui/swagger.yaml
vendored
@ -2343,6 +2343,8 @@ definitions:
|
||||
type: string
|
||||
website:
|
||||
type: string
|
||||
security_contact:
|
||||
type: string
|
||||
details:
|
||||
type: string
|
||||
bond_height:
|
||||
|
||||
@ -85,10 +85,11 @@ CommissionRates struct {
|
||||
}
|
||||
|
||||
type Description struct {
|
||||
Moniker string // name
|
||||
Identity string // optional identity signature (ex. UPort or Keybase)
|
||||
Website string // optional website link
|
||||
Details string // optional details
|
||||
Moniker string // name
|
||||
Identity string // optional identity signature (ex. UPort or Keybase)
|
||||
Website string // optional website link
|
||||
SecurityContact string // optional email for security contact
|
||||
Details string // optional details
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -211,7 +211,7 @@ func TestDecodeStakingStore(t *testing.T) {
|
||||
|
||||
bondTime := time.Now().UTC()
|
||||
|
||||
val := staking.NewValidator(valAddr1, delPk1, staking.NewDescription("test", "test", "test", "test"))
|
||||
val := staking.NewValidator(valAddr1, delPk1, staking.NewDescription("test", "test", "test", "test", "test"))
|
||||
del := staking.NewDelegation(delAddr1, valAddr1, sdk.OneDec())
|
||||
ubd := staking.NewUnbondingDelegation(delAddr1, valAddr1, 15, bondTime, sdk.OneInt())
|
||||
red := staking.NewRedelegation(delAddr1, valAddr1, valAddr1, 12, bondTime, sdk.OneInt(), sdk.OneDec())
|
||||
|
||||
@ -12,7 +12,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
extypes "github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
v036 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v036"
|
||||
v036 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v0_36"
|
||||
)
|
||||
|
||||
var migrationMap = extypes.MigrationMap{
|
||||
|
||||
@ -18,7 +18,7 @@ var (
|
||||
|
||||
func TestValidateGenesisMultipleMessages(t *testing.T) {
|
||||
|
||||
desc := stakingtypes.NewDescription("testname", "", "", "")
|
||||
desc := stakingtypes.NewDescription("testname", "", "", "", "")
|
||||
comm := stakingtypes.CommissionRates{}
|
||||
|
||||
msg1 := stakingtypes.NewMsgCreateValidator(sdk.ValAddress(pk1.Address()), pk1,
|
||||
@ -35,7 +35,7 @@ func TestValidateGenesisMultipleMessages(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateGenesisBadMessage(t *testing.T) {
|
||||
desc := stakingtypes.NewDescription("testname", "", "", "")
|
||||
desc := stakingtypes.NewDescription("testname", "", "", "", "")
|
||||
|
||||
msg1 := stakingtypes.NewMsgEditValidator(sdk.ValAddress(pk1.Address()), desc, nil, nil)
|
||||
|
||||
|
||||
@ -14,9 +14,9 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
@ -61,7 +61,7 @@ var (
|
||||
// TODO: remove dependency with staking
|
||||
var (
|
||||
TestProposal = types.NewTextProposal("Test", "description")
|
||||
TestDescription = staking.NewDescription("T", "E", "S", "T")
|
||||
TestDescription = staking.NewDescription("T", "E", "S", "T", "Z")
|
||||
TestCommissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||
)
|
||||
|
||||
@ -153,7 +153,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context
|
||||
AddRoute(types.RouterKey, types.ProposalHandler)
|
||||
|
||||
keeper := NewKeeper(cdc, keyGov, pk.Subspace(types.DefaultParamspace).WithKeyTable(types.ParamKeyTable()),
|
||||
supplyKeeper, sk, types.DefaultCodespace, rtr)
|
||||
supplyKeeper, sk, types.DefaultCodespace, rtr)
|
||||
|
||||
keeper.SetProposalID(ctx, types.DefaultStartingProposalID)
|
||||
keeper.SetDepositParams(ctx, types.DefaultDepositParams())
|
||||
|
||||
@ -81,7 +81,7 @@ func getMockApp(t *testing.T, numGenAccs int, genState types.GenesisState, genAc
|
||||
sk := staking.NewKeeper(mApp.Cdc, keyStaking, tKeyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace), staking.DefaultCodespace)
|
||||
|
||||
keeper := keep.NewKeeper(mApp.Cdc, keyGov, pk.Subspace(DefaultParamspace).WithKeyTable(ParamKeyTable()),
|
||||
supplyKeeper, sk, types.DefaultCodespace, rtr)
|
||||
supplyKeeper, sk, types.DefaultCodespace, rtr)
|
||||
|
||||
mApp.Router().AddRoute(types.RouterKey, NewHandler(keeper))
|
||||
mApp.QueryRouter().AddRoute(types.QuerierRoute, keep.NewQuerier(keeper))
|
||||
|
||||
@ -127,7 +127,7 @@ func TestSlashingMsgs(t *testing.T) {
|
||||
accs := []auth.Account{acc1}
|
||||
mock.SetGenesis(mapp, accs)
|
||||
|
||||
description := staking.NewDescription("foo_moniker", "", "", "")
|
||||
description := staking.NewDescription("foo_moniker", "", "", "", "")
|
||||
commission := staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||
|
||||
createValidatorMsg := staking.NewMsgCreateValidator(
|
||||
|
||||
@ -136,7 +136,7 @@ func TestStakingMsgs(t *testing.T) {
|
||||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin})
|
||||
|
||||
// create validator
|
||||
description := NewDescription("foo_moniker", "", "", "")
|
||||
description := NewDescription("foo_moniker", "", "", "", "")
|
||||
createValidatorMsg := NewMsgCreateValidator(
|
||||
sdk.ValAddress(addr1), priv1.PubKey(), bondCoin, description, commissionRates, sdk.OneInt(),
|
||||
)
|
||||
@ -157,7 +157,7 @@ func TestStakingMsgs(t *testing.T) {
|
||||
mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
// edit the validator
|
||||
description = NewDescription("bar_moniker", "", "", "")
|
||||
description = NewDescription("bar_moniker", "", "", "", "")
|
||||
editValidatorMsg := NewMsgEditValidator(sdk.ValAddress(addr1), description, nil, nil)
|
||||
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
|
||||
@ -16,10 +16,11 @@ const (
|
||||
FlagSharesAmount = "shares-amount"
|
||||
FlagSharesFraction = "shares-fraction"
|
||||
|
||||
FlagMoniker = "moniker"
|
||||
FlagIdentity = "identity"
|
||||
FlagWebsite = "website"
|
||||
FlagDetails = "details"
|
||||
FlagMoniker = "moniker"
|
||||
FlagIdentity = "identity"
|
||||
FlagWebsite = "website"
|
||||
FlagSecurityContact = "security-contact"
|
||||
FlagDetails = "details"
|
||||
|
||||
FlagCommissionRate = "commission-rate"
|
||||
FlagCommissionMaxRate = "commission-max-rate"
|
||||
@ -54,6 +55,7 @@ func init() {
|
||||
fsDescriptionCreate.String(FlagMoniker, "", "The validator's name")
|
||||
fsDescriptionCreate.String(FlagIdentity, "", "The optional identity signature (ex. UPort or Keybase)")
|
||||
fsDescriptionCreate.String(FlagWebsite, "", "The validator's (optional) website")
|
||||
fsDescriptionCreate.String(FlagSecurityContact, "", "The validator's (optional) security contact email")
|
||||
fsDescriptionCreate.String(FlagDetails, "", "The validator's (optional) details")
|
||||
fsCommissionUpdate.String(FlagCommissionRate, "", "The new commission rate percentage")
|
||||
FsCommissionCreate.String(FlagCommissionRate, "", "The initial commission rate percentage")
|
||||
@ -63,6 +65,7 @@ func init() {
|
||||
fsDescriptionEdit.String(FlagMoniker, types.DoNotModifyDesc, "The validator's name")
|
||||
fsDescriptionEdit.String(FlagIdentity, types.DoNotModifyDesc, "The (optional) identity signature (ex. UPort or Keybase)")
|
||||
fsDescriptionEdit.String(FlagWebsite, types.DoNotModifyDesc, "The validator's (optional) website")
|
||||
fsDescriptionEdit.String(FlagSecurityContact, types.DoNotModifyDesc, "The validator's (optional) security contact email")
|
||||
fsDescriptionEdit.String(FlagDetails, types.DoNotModifyDesc, "The validator's (optional) details")
|
||||
fsValidator.String(FlagAddressValidator, "", "The Bech32 address of the validator")
|
||||
fsRedelegation.String(FlagAddressValidatorSrc, "", "The Bech32 address of the source validator")
|
||||
|
||||
@ -89,12 +89,13 @@ func GetCmdEditValidator(cdc *codec.Codec) *cobra.Command {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
valAddr := cliCtx.GetFromAddress()
|
||||
description := types.Description{
|
||||
Moniker: viper.GetString(FlagMoniker),
|
||||
Identity: viper.GetString(FlagIdentity),
|
||||
Website: viper.GetString(FlagWebsite),
|
||||
Details: viper.GetString(FlagDetails),
|
||||
}
|
||||
description := types.NewDescription(
|
||||
viper.GetString(FlagMoniker),
|
||||
viper.GetString(FlagIdentity),
|
||||
viper.GetString(FlagWebsite),
|
||||
viper.GetString(FlagSecurityContact),
|
||||
viper.GetString(FlagDetails),
|
||||
)
|
||||
|
||||
var newRate *sdk.Dec
|
||||
|
||||
@ -265,6 +266,7 @@ func CreateValidatorMsgHelpers(ipDefault string) (fs *flag.FlagSet, nodeIDFlag,
|
||||
fsCreateValidator.String(FlagIP, ipDefault, "The node's public IP")
|
||||
fsCreateValidator.String(FlagNodeID, "", "The node's NodeID")
|
||||
fsCreateValidator.String(FlagWebsite, "", "The validator's (optional) website")
|
||||
fsCreateValidator.String(FlagSecurityContact, "", "The validator's (optional) security contact email")
|
||||
fsCreateValidator.String(FlagDetails, "", "The validator's (optional) details")
|
||||
fsCreateValidator.String(FlagIdentity, "", "The (optional) identity signature (ex. UPort or Keybase)")
|
||||
fsCreateValidator.AddFlagSet(FsCommissionCreate)
|
||||
@ -297,6 +299,7 @@ func PrepareFlagsForTxCreateValidator(
|
||||
}
|
||||
|
||||
website := viper.GetString(FlagWebsite)
|
||||
securityContact := viper.GetString(FlagSecurityContact)
|
||||
details := viper.GetString(FlagDetails)
|
||||
identity := viper.GetString(FlagIdentity)
|
||||
|
||||
@ -307,6 +310,7 @@ func PrepareFlagsForTxCreateValidator(
|
||||
viper.Set(FlagPubKey, sdk.MustBech32ifyConsPub(valPubKey))
|
||||
viper.Set(FlagMoniker, config.Moniker)
|
||||
viper.Set(FlagWebsite, website)
|
||||
viper.Set(FlagSecurityContact, securityContact)
|
||||
viper.Set(FlagDetails, details)
|
||||
viper.Set(FlagIdentity, identity)
|
||||
|
||||
@ -350,6 +354,7 @@ func BuildCreateValidatorMsg(cliCtx context.CLIContext, txBldr auth.TxBuilder) (
|
||||
viper.GetString(FlagMoniker),
|
||||
viper.GetString(FlagIdentity),
|
||||
viper.GetString(FlagWebsite),
|
||||
viper.GetString(FlagSecurityContact),
|
||||
viper.GetString(FlagDetails),
|
||||
)
|
||||
|
||||
|
||||
@ -28,13 +28,13 @@ func TestInitGenesis(t *testing.T) {
|
||||
// initialize the validators
|
||||
validators[0].OperatorAddress = sdk.ValAddress(keep.Addrs[0])
|
||||
validators[0].ConsPubKey = keep.PKs[0]
|
||||
validators[0].Description = NewDescription("hoop", "", "", "")
|
||||
validators[0].Description = NewDescription("hoop", "", "", "", "")
|
||||
validators[0].Status = sdk.Bonded
|
||||
validators[0].Tokens = valTokens
|
||||
validators[0].DelegatorShares = valTokens.ToDec()
|
||||
validators[1].OperatorAddress = sdk.ValAddress(keep.Addrs[1])
|
||||
validators[1].ConsPubKey = keep.PKs[1]
|
||||
validators[1].Description = NewDescription("bloop", "", "", "")
|
||||
validators[1].Description = NewDescription("bloop", "", "", "", "")
|
||||
validators[1].Status = sdk.Bonded
|
||||
validators[1].Tokens = valTokens
|
||||
validators[1].DelegatorShares = valTokens.ToDec()
|
||||
@ -76,7 +76,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
|
||||
|
||||
for i := range validators {
|
||||
validators[i] = NewValidator(sdk.ValAddress(keep.Addrs[i]),
|
||||
keep.PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", ""))
|
||||
keep.PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""))
|
||||
|
||||
validators[i].Status = sdk.Bonded
|
||||
|
||||
@ -102,7 +102,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
|
||||
func TestValidateGenesis(t *testing.T) {
|
||||
genValidators1 := make([]types.Validator, 1, 5)
|
||||
pk := ed25519.GenPrivKey().PubKey()
|
||||
genValidators1[0] = types.NewValidator(sdk.ValAddress(pk.Address()), pk, types.NewDescription("", "", "", ""))
|
||||
genValidators1[0] = types.NewValidator(sdk.ValAddress(pk.Address()), pk, types.NewDescription("", "", "", "", ""))
|
||||
genValidators1[0].Tokens = sdk.OneInt()
|
||||
genValidators1[0].DelegatorShares = sdk.OneDec()
|
||||
|
||||
|
||||
51
x/staking/legacy/v0_37/migrate.go
Normal file
51
x/staking/legacy/v0_37/migrate.go
Normal file
@ -0,0 +1,51 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_37
|
||||
|
||||
import (
|
||||
v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_36"
|
||||
)
|
||||
|
||||
// Migrate accepts exported genesis state from v0.34 and migrates it to v0.36
|
||||
// genesis state. All entries are identical except for validator slashing events
|
||||
// which now include the period.
|
||||
func Migrate(oldGenState v036staking.GenesisState) GenesisState {
|
||||
return NewGenesisState(
|
||||
oldGenState.Params,
|
||||
oldGenState.LastTotalPower,
|
||||
oldGenState.LastValidatorPowers,
|
||||
migrateValidators(oldGenState.Validators),
|
||||
oldGenState.Delegations,
|
||||
oldGenState.UnbondingDelegations,
|
||||
oldGenState.Redelegations,
|
||||
oldGenState.Exported,
|
||||
)
|
||||
}
|
||||
|
||||
func migrateValidators(oldValidators v036staking.Validators) Validators {
|
||||
validators := make(Validators, len(oldValidators))
|
||||
|
||||
for i, val := range oldValidators {
|
||||
validators[i] = Validator{
|
||||
OperatorAddress: val.OperatorAddress,
|
||||
ConsPubKey: val.ConsPubKey,
|
||||
Jailed: val.Jailed,
|
||||
Status: val.Status,
|
||||
Tokens: val.Tokens,
|
||||
DelegatorShares: val.DelegatorShares,
|
||||
Description: NewDescription(
|
||||
val.Description.Moniker,
|
||||
val.Description.Identity,
|
||||
val.Description.Website,
|
||||
"", // security contact field
|
||||
val.Description.Details,
|
||||
),
|
||||
UnbondingHeight: val.UnbondingHeight,
|
||||
UnbondingCompletionTime: val.UnbondingCompletionTime,
|
||||
Commission: val.Commission,
|
||||
MinSelfDelegation: val.MinSelfDelegation,
|
||||
}
|
||||
}
|
||||
|
||||
return validators
|
||||
}
|
||||
86
x/staking/legacy/v0_37/types.go
Normal file
86
x/staking/legacy/v0_37/types.go
Normal file
@ -0,0 +1,86 @@
|
||||
// DONTCOVER
|
||||
// nolint
|
||||
package v0_37
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34"
|
||||
v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_36"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "staking"
|
||||
)
|
||||
|
||||
type (
|
||||
Description struct {
|
||||
Moniker string `json:"moniker" yaml:"moniker"`
|
||||
Identity string `json:"identity" yaml:"identity"`
|
||||
Website string `json:"website" yaml:"website"`
|
||||
SecurityContact string `json:"security_contact" yaml:"security_contact"`
|
||||
Details string `json:"details" yaml:"details"`
|
||||
}
|
||||
|
||||
Validator struct {
|
||||
OperatorAddress sdk.ValAddress `json:"operator_address" yaml:"operator_address"`
|
||||
ConsPubKey crypto.PubKey `json:"consensus_pubkey" yaml:"consensus_pubkey"`
|
||||
Jailed bool `json:"jailed" yaml:"jailed"`
|
||||
Status sdk.BondStatus `json:"status" yaml:"status"`
|
||||
Tokens sdk.Int `json:"tokens" yaml:"tokens"`
|
||||
DelegatorShares sdk.Dec `json:"delegator_shares" yaml:"delegator_shares"`
|
||||
Description Description `json:"description" yaml:"description"`
|
||||
UnbondingHeight int64 `json:"unbonding_height" yaml:"unbonding_height"`
|
||||
UnbondingCompletionTime time.Time `json:"unbonding_time" yaml:"unbonding_time"`
|
||||
Commission v036staking.Commission `json:"commission" yaml:"commission"`
|
||||
MinSelfDelegation sdk.Int `json:"min_self_delegation" yaml:"min_self_delegation"`
|
||||
}
|
||||
|
||||
Validators []Validator
|
||||
|
||||
GenesisState struct {
|
||||
Params v034staking.Params `json:"params"`
|
||||
LastTotalPower sdk.Int `json:"last_total_power"`
|
||||
LastValidatorPowers []v034staking.LastValidatorPower `json:"last_validator_powers"`
|
||||
Validators Validators `json:"validators"`
|
||||
Delegations v034staking.Delegations `json:"delegations"`
|
||||
UnbondingDelegations []v034staking.UnbondingDelegation `json:"unbonding_delegations"`
|
||||
Redelegations []v034staking.Redelegation `json:"redelegations"`
|
||||
Exported bool `json:"exported"`
|
||||
}
|
||||
)
|
||||
|
||||
// NewDescription creates a new Description object
|
||||
func NewDescription(moniker, identity, website,
|
||||
securityContact, details string) Description {
|
||||
|
||||
return Description{
|
||||
Moniker: moniker,
|
||||
Identity: identity,
|
||||
Website: website,
|
||||
SecurityContact: securityContact,
|
||||
Details: details,
|
||||
}
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new GenesisState object
|
||||
func NewGenesisState(
|
||||
params v034staking.Params, lastTotalPower sdk.Int, lastValPowers []v034staking.LastValidatorPower,
|
||||
validators Validators, delegations v034staking.Delegations,
|
||||
ubds []v034staking.UnbondingDelegation, reds []v034staking.Redelegation, exported bool,
|
||||
) GenesisState {
|
||||
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
LastTotalPower: lastTotalPower,
|
||||
LastValidatorPowers: lastValPowers,
|
||||
Validators: validators,
|
||||
Delegations: delegations,
|
||||
UnbondingDelegations: ubds,
|
||||
Redelegations: reds,
|
||||
Exported: exported,
|
||||
}
|
||||
}
|
||||
@ -20,9 +20,13 @@ func SimulateMsgCreateValidator(m auth.AccountKeeper, k staking.Keeper) simulati
|
||||
opMsg simulation.OperationMsg, fOps []simulation.FutureOperation, err error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
description := staking.Description{
|
||||
Moniker: simulation.RandStringOfLength(r, 10),
|
||||
}
|
||||
description := staking.NewDescription(
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
)
|
||||
|
||||
maxCommission := sdk.NewDecWithPrec(r.Int63n(1000), 3)
|
||||
commission := staking.NewCommissionRates(
|
||||
@ -67,12 +71,13 @@ func SimulateMsgEditValidator(k staking.Keeper) simulation.Operation {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
accs []simulation.Account) (opMsg simulation.OperationMsg, fOps []simulation.FutureOperation, err error) {
|
||||
|
||||
description := staking.Description{
|
||||
Moniker: simulation.RandStringOfLength(r, 10),
|
||||
Identity: simulation.RandStringOfLength(r, 10),
|
||||
Website: simulation.RandStringOfLength(r, 10),
|
||||
Details: simulation.RandStringOfLength(r, 10),
|
||||
}
|
||||
description := staking.NewDescription(
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
)
|
||||
|
||||
if len(k.GetAllValidators(ctx)) == 0 {
|
||||
return simulation.NoOpMsg(staking.ModuleName), nil, nil
|
||||
|
||||
@ -20,27 +20,27 @@ func TestMsgCreateValidator(t *testing.T) {
|
||||
commission2 := NewCommissionRates(sdk.NewDec(5), sdk.NewDec(5), sdk.NewDec(5))
|
||||
|
||||
tests := []struct {
|
||||
name, moniker, identity, website, details string
|
||||
CommissionRates CommissionRates
|
||||
minSelfDelegation sdk.Int
|
||||
validatorAddr sdk.ValAddress
|
||||
pubkey crypto.PubKey
|
||||
bond sdk.Coin
|
||||
expectPass bool
|
||||
name, moniker, identity, website, securityContact, details string
|
||||
CommissionRates CommissionRates
|
||||
minSelfDelegation sdk.Int
|
||||
validatorAddr sdk.ValAddress
|
||||
pubkey crypto.PubKey
|
||||
bond sdk.Coin
|
||||
expectPass bool
|
||||
}{
|
||||
{"basic good", "a", "b", "c", "d", commission1, sdk.OneInt(), valAddr1, pk1, coinPos, true},
|
||||
{"partial description", "", "", "c", "", commission1, sdk.OneInt(), valAddr1, pk1, coinPos, true},
|
||||
{"empty description", "", "", "", "", commission2, sdk.OneInt(), valAddr1, pk1, coinPos, false},
|
||||
{"empty address", "a", "b", "c", "d", commission2, sdk.OneInt(), emptyAddr, pk1, coinPos, false},
|
||||
{"empty pubkey", "a", "b", "c", "d", commission1, sdk.OneInt(), valAddr1, emptyPubkey, coinPos, true},
|
||||
{"empty bond", "a", "b", "c", "d", commission2, sdk.OneInt(), valAddr1, pk1, coinZero, false},
|
||||
{"zero min self delegation", "a", "b", "c", "d", commission1, sdk.ZeroInt(), valAddr1, pk1, coinPos, false},
|
||||
{"negative min self delegation", "a", "b", "c", "d", commission1, sdk.NewInt(-1), valAddr1, pk1, coinPos, false},
|
||||
{"delegation less than min self delegation", "a", "b", "c", "d", commission1, coinPos.Amount.Add(sdk.OneInt()), valAddr1, pk1, coinPos, false},
|
||||
{"basic good", "a", "b", "c", "d", "e", commission1, sdk.OneInt(), valAddr1, pk1, coinPos, true},
|
||||
{"partial description", "", "", "c", "", "", commission1, sdk.OneInt(), valAddr1, pk1, coinPos, true},
|
||||
{"empty description", "", "", "", "", "", commission2, sdk.OneInt(), valAddr1, pk1, coinPos, false},
|
||||
{"empty address", "a", "b", "c", "d", "e", commission2, sdk.OneInt(), emptyAddr, pk1, coinPos, false},
|
||||
{"empty pubkey", "a", "b", "c", "d", "e", commission1, sdk.OneInt(), valAddr1, emptyPubkey, coinPos, true},
|
||||
{"empty bond", "a", "b", "c", "d", "e", commission2, sdk.OneInt(), valAddr1, pk1, coinZero, false},
|
||||
{"zero min self delegation", "a", "b", "c", "d", "e", commission1, sdk.ZeroInt(), valAddr1, pk1, coinPos, false},
|
||||
{"negative min self delegation", "a", "b", "c", "d", "e", commission1, sdk.NewInt(-1), valAddr1, pk1, coinPos, false},
|
||||
{"delegation less than min self delegation", "a", "b", "c", "d", "e", commission1, coinPos.Amount.Add(sdk.OneInt()), valAddr1, pk1, coinPos, false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.details)
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.securityContact, tc.details)
|
||||
msg := NewMsgCreateValidator(tc.validatorAddr, tc.pubkey, tc.bond, description, tc.CommissionRates, tc.minSelfDelegation)
|
||||
if tc.expectPass {
|
||||
require.Nil(t, msg.ValidateBasic(), "test: %v", tc.name)
|
||||
@ -53,18 +53,18 @@ func TestMsgCreateValidator(t *testing.T) {
|
||||
// test ValidateBasic for MsgEditValidator
|
||||
func TestMsgEditValidator(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, moniker, identity, website, details string
|
||||
validatorAddr sdk.ValAddress
|
||||
expectPass bool
|
||||
name, moniker, identity, website, securityContact, details string
|
||||
validatorAddr sdk.ValAddress
|
||||
expectPass bool
|
||||
}{
|
||||
{"basic good", "a", "b", "c", "d", valAddr1, true},
|
||||
{"partial description", "", "", "c", "", valAddr1, true},
|
||||
{"empty description", "", "", "", "", valAddr1, false},
|
||||
{"empty address", "a", "b", "c", "d", emptyAddr, false},
|
||||
{"basic good", "a", "b", "c", "d", "e", valAddr1, true},
|
||||
{"partial description", "", "", "c", "", "", valAddr1, true},
|
||||
{"empty description", "", "", "", "", "", valAddr1, false},
|
||||
{"empty address", "a", "b", "c", "d", "e", emptyAddr, false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.details)
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.securityContact, tc.details)
|
||||
newRate := sdk.ZeroDec()
|
||||
newMinSelfDelegation := sdk.OneInt()
|
||||
|
||||
|
||||
@ -19,10 +19,11 @@ import (
|
||||
// nolint
|
||||
const (
|
||||
// TODO: Why can't we just have one string description which can be JSON by convention
|
||||
MaxMonikerLength = 70
|
||||
MaxIdentityLength = 3000
|
||||
MaxWebsiteLength = 140
|
||||
MaxDetailsLength = 280
|
||||
MaxMonikerLength = 70
|
||||
MaxIdentityLength = 3000
|
||||
MaxWebsiteLength = 140
|
||||
MaxSecurityContactLength = 140
|
||||
MaxDetailsLength = 280
|
||||
)
|
||||
|
||||
// Implements Validator interface
|
||||
@ -260,19 +261,21 @@ const DoNotModifyDesc = "[do-not-modify]"
|
||||
|
||||
// Description - description fields for a validator
|
||||
type Description struct {
|
||||
Moniker string `json:"moniker" yaml:"moniker"` // name
|
||||
Identity string `json:"identity" yaml:"identity"` // optional identity signature (ex. UPort or Keybase)
|
||||
Website string `json:"website" yaml:"website"` // optional website link
|
||||
Details string `json:"details" yaml:"details"` // optional details
|
||||
Moniker string `json:"moniker" yaml:"moniker"` // name
|
||||
Identity string `json:"identity" yaml:"identity"` // optional identity signature (ex. UPort or Keybase)
|
||||
Website string `json:"website" yaml:"website"` // optional website link
|
||||
SecurityContact string `json:"security_contact" yaml:"security_contact"` // optional security contact info
|
||||
Details string `json:"details" yaml:"details"` // optional details
|
||||
}
|
||||
|
||||
// NewDescription returns a new Description with the provided values.
|
||||
func NewDescription(moniker, identity, website, details string) Description {
|
||||
func NewDescription(moniker, identity, website, securityContact, details string) Description {
|
||||
return Description{
|
||||
Moniker: moniker,
|
||||
Identity: identity,
|
||||
Website: website,
|
||||
Details: details,
|
||||
Moniker: moniker,
|
||||
Identity: identity,
|
||||
Website: website,
|
||||
SecurityContact: securityContact,
|
||||
Details: details,
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,16 +291,20 @@ func (d Description) UpdateDescription(d2 Description) (Description, sdk.Error)
|
||||
if d2.Website == DoNotModifyDesc {
|
||||
d2.Website = d.Website
|
||||
}
|
||||
if d2.SecurityContact == DoNotModifyDesc {
|
||||
d2.SecurityContact = d.SecurityContact
|
||||
}
|
||||
if d2.Details == DoNotModifyDesc {
|
||||
d2.Details = d.Details
|
||||
}
|
||||
|
||||
return Description{
|
||||
Moniker: d2.Moniker,
|
||||
Identity: d2.Identity,
|
||||
Website: d2.Website,
|
||||
Details: d2.Details,
|
||||
}.EnsureLength()
|
||||
return NewDescription(
|
||||
d2.Moniker,
|
||||
d2.Identity,
|
||||
d2.Website,
|
||||
d2.SecurityContact,
|
||||
d2.Details,
|
||||
).EnsureLength()
|
||||
}
|
||||
|
||||
// EnsureLength ensures the length of a validator's description.
|
||||
@ -311,6 +318,9 @@ func (d Description) EnsureLength() (Description, sdk.Error) {
|
||||
if len(d.Website) > MaxWebsiteLength {
|
||||
return d, ErrDescriptionLength(DefaultCodespace, "website", len(d.Website), MaxWebsiteLength)
|
||||
}
|
||||
if len(d.SecurityContact) > MaxSecurityContactLength {
|
||||
return d, ErrDescriptionLength(DefaultCodespace, "security contact", len(d.SecurityContact), MaxSecurityContactLength)
|
||||
}
|
||||
if len(d.Details) > MaxDetailsLength {
|
||||
return d, ErrDescriptionLength(DefaultCodespace, "details", len(d.Details), MaxDetailsLength)
|
||||
}
|
||||
|
||||
@ -289,6 +289,7 @@ func TestValidatorMarshalYAML(t *testing.T) {
|
||||
moniker: ""
|
||||
identity: ""
|
||||
website: ""
|
||||
security_contact: ""
|
||||
details: ""
|
||||
unbondingheight: 0
|
||||
unbondingcompletiontime: 1970-01-01T00:00:00Z
|
||||
|
||||
Loading…
Reference in New Issue
Block a user