func (vp VotingParams) String() string {
	out, _ := yaml.Marshal(vp)
	return string(out)
}
String implements stringer interface
package types
import (
	"fmt"
	"time"
	"github.com/KuChainNetwork/kuchain/chain/types"
	"github.com/KuChainNetwork/kuchain/x/gov/external"
	paramtypes "github.com/KuChainNetwork/kuchain/x/params/types"
	stakingexport "github.com/KuChainNetwork/kuchain/x/staking/exported"
	sdk "github.com/cosmos/cosmos-sdk/types"
	"gopkg.in/yaml.v2"
)
const (
	DefaultPeriod       time.Duration = time.Hour * 24 * 14  
	DefaultPunishPeriod time.Duration = time.Hour * 24 * 7   
)
var (
	DefaultMinDepositTokens = external.TokensFromConsensusPower(500)
	DefaultQuorum           = sdk.NewDecWithPrec(334, 3)
	DefaultThreshold        = sdk.NewDecWithPrec(5, 1)
	DefaultVeto             = sdk.NewDecWithPrec(334, 3)
	DefaultEmergengcy       = sdk.NewDecWithPrec(667, 3)
	DefaultSlashFraction    = types.NewDec(1).Quo(types.NewDec(10000))
)
var (
	ParamStoreKeyDepositParams = []byte("depositparams")
	ParamStoreKeyVotingParams  = []byte("votingparams")
	ParamStoreKeyTallyParams   = []byte("tallyparams")
)
func ParamKeyTable() paramtypes.KeyTable {
	return paramtypes.NewKeyTable(
		paramtypes.NewParamSetPair(ParamStoreKeyDepositParams, DepositParams{}, validateDepositParams),
		paramtypes.NewParamSetPair(ParamStoreKeyVotingParams, VotingParams{}, validateVotingParams),
		paramtypes.NewParamSetPair(ParamStoreKeyTallyParams, TallyParams{}, validateTallyParams),
	)
}
type DepositParams struct {
	MinDeposit       Coins         `json:"min_deposit,omitempty" yaml:"min_deposit,omitempty"`                
	MaxDepositPeriod time.Duration `json:"max_deposit_period,omitempty" yaml:"max_deposit_period,omitempty"`  
}
func NewDepositParams(minDeposit Coins, maxDepositPeriod time.Duration) DepositParams {
	return DepositParams{
		MinDeposit:       minDeposit,
		MaxDepositPeriod: maxDepositPeriod,
	}
}
func DefaultDepositParams() DepositParams {
	return NewDepositParams(
		types.NewCoins(types.NewCoin(stakingexport.DefaultBondDenom, DefaultMinDepositTokens)),
		DefaultPeriod,
	)
}
func (dp DepositParams) String() string {
	out, _ := yaml.Marshal(dp)
	return string(out)
}
func (dp DepositParams) Equal(dp2 DepositParams) bool {
	return dp.MinDeposit.IsEqual(dp2.MinDeposit) && dp.MaxDepositPeriod == dp2.MaxDepositPeriod
}
func validateDepositParams(i interface{}) error {
	v, ok := i.(DepositParams)
	if !ok {
		return fmt.Errorf("invalid parameter type: %T", i)
	}
	if !v.MinDeposit.IsValid() {
		return fmt.Errorf("invalid minimum deposit: %s", v.MinDeposit)
	}
	if v.MaxDepositPeriod <= 0 {
		return fmt.Errorf("maximum deposit period must be positive: %d", v.MaxDepositPeriod)
	}
	return nil
}
type TallyParams struct {
	Quorum          sdk.Dec       `json:"quorum,omitempty" yaml:"quorum,omitempty"`                        
	Threshold       sdk.Dec       `json:"threshold,omitempty" yaml:"threshold,omitempty"`                  
	Veto            sdk.Dec       `json:"veto,omitempty" yaml:"veto,omitempty"`                            
	Emergency       sdk.Dec       `json:"emergency,omitempty" yaml:"emergency,omitempty"`                  
	MaxPunishPeriod time.Duration `json:"max_punish_period,omitempty" yaml:"max_punish_period,omitempty"`  
	SlashFraction   sdk.Dec       `json:"slash_fraction,omitempty" yaml:"slash_fraction,omitempty"`        
}
func NewTallyParams(quorum, threshold, veto sdk.Dec, emergency sdk.Dec, punishPeriod time.Duration, slashFraction sdk.Dec) TallyParams {
	return TallyParams{
		Quorum:          quorum,
		Threshold:       threshold,
		Veto:            veto,
		Emergency:       emergency,
		MaxPunishPeriod: punishPeriod,
		SlashFraction:   slashFraction,
	}
}
func DefaultTallyParams() TallyParams {
	return NewTallyParams(DefaultQuorum, DefaultThreshold, DefaultVeto, DefaultEmergengcy, DefaultPunishPeriod, DefaultSlashFraction)
}
func (tp TallyParams) Equal(other TallyParams) bool {
	return tp.Quorum.Equal(other.Quorum) && tp.Threshold.Equal(other.Threshold) && tp.Veto.Equal(other.Veto)
}
func (tp TallyParams) String() string {
	out, _ := yaml.Marshal(tp)
	return string(out)
}
func validateTallyParams(i interface{}) error {
	v, ok := i.(TallyParams)
	if !ok {
		return fmt.Errorf("invalid parameter type: %T", i)
	}
	if v.Quorum.IsNegative() {
		return fmt.Errorf("quorom cannot be negative: %s", v.Quorum)
	}
	if v.Quorum.GT(sdk.OneDec()) {
		return fmt.Errorf("quorom too large: %s", v)
	}
	if !v.Threshold.IsPositive() {
		return fmt.Errorf("vote threshold must be positive: %s", v.Threshold)
	}
	if v.Threshold.GT(sdk.OneDec()) {
		return fmt.Errorf("vote threshold too large: %s", v)
	}
	if !v.Veto.IsPositive() {
		return fmt.Errorf("veto threshold must be positive: %s", v.Threshold)
	}
	if v.Veto.GT(sdk.OneDec()) {
		return fmt.Errorf("veto threshold too large: %s", v)
	}
	return nil
}
type VotingParams struct {
	VotingPeriod time.Duration `json:"voting_period,omitempty" yaml:"voting_period,omitempty"`  
}
func NewVotingParams(votingPeriod time.Duration) VotingParams {
	return VotingParams{
		VotingPeriod: votingPeriod,
	}
}
func DefaultVotingParams() VotingParams {
	return NewVotingParams(DefaultPeriod)
}
func (vp VotingParams) Equal(other VotingParams) bool {
	return vp.VotingPeriod == other.VotingPeriod
}