working refactoring
This commit is contained in:
parent
aff7d28bb0
commit
6d0c788185
|
@ -35,9 +35,9 @@ func ABCIValidator(v Validator) abci.Validator {
|
|||
|
||||
// properties for the set of all validators
|
||||
type ValidatorSet interface {
|
||||
Iterate(func(index int64, validator Validator)) // execute arbitrary logic for each validator
|
||||
Validator(Context, Address) Validator // get a particular validator by owner address
|
||||
TotalPower(Context) Rat // total power of the validator set
|
||||
IterateValidatorsBonded(func(index int64, validator Validator)) // execute arbitrary logic for each validator
|
||||
Validator(Context, Address) Validator // get a particular validator by owner address
|
||||
TotalPower(Context) Rat // total power of the validator set
|
||||
}
|
||||
|
||||
//_______________________________________________________________________________
|
||||
|
@ -53,5 +53,5 @@ type Delegation interface {
|
|||
type DelegationSet interface {
|
||||
|
||||
// execute arbitrary logic for each validator which a delegator has a delegation for
|
||||
Iterate(delegator Address, fn func(index int64, delegation Delegation))
|
||||
IterateDelegators(delegator Address, fn func(index int64, delegation Delegation))
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
// nolint
|
||||
const (
|
||||
FlagAddressDelegator = "address-delegator"
|
||||
FlagAddressCandidate = "address-candidate"
|
||||
FlagAddressValidator = "address-validator"
|
||||
FlagPubKey = "pubkey"
|
||||
FlagAmount = "amount"
|
||||
FlagShares = "shares"
|
||||
|
@ -24,18 +24,18 @@ var (
|
|||
fsAmount = flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fsShares = flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fsDescription = flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fsCandidate = flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fsValidator = flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fsDelegator = flag.NewFlagSet("", flag.ContinueOnError)
|
||||
)
|
||||
|
||||
func init() {
|
||||
fsPk.String(FlagPubKey, "", "Go-Amino encoded hex PubKey of the validator-candidate. For Ed25519 the go-amino prepend hex is 1624de6220")
|
||||
fsPk.String(FlagPubKey, "", "Go-Amino encoded hex PubKey of the validator-validator. For Ed25519 the go-amino prepend hex is 1624de6220")
|
||||
fsAmount.String(FlagAmount, "1steak", "Amount of coins to bond")
|
||||
fsShares.String(FlagShares, "", "Amount of shares to unbond, either in decimal or keyword MAX (ex. 1.23456789, 99, MAX)")
|
||||
fsDescription.String(FlagMoniker, "", "validator-candidate name")
|
||||
fsDescription.String(FlagMoniker, "", "validator-validator name")
|
||||
fsDescription.String(FlagIdentity, "", "optional keybase signature")
|
||||
fsDescription.String(FlagWebsite, "", "optional website")
|
||||
fsDescription.String(FlagDetails, "", "optional details")
|
||||
fsCandidate.String(FlagAddressCandidate, "", "hex address of the validator/candidate")
|
||||
fsValidator.String(FlagAddressValidator, "", "hex address of the validator/validator")
|
||||
fsDelegator.String(FlagAddressDelegator, "", "hex address of the delegator")
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
)
|
||||
|
||||
// get the command to query a candidate
|
||||
func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
// get the command to query a validator
|
||||
func GetCmdQueryValidator(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "candidate [candidate-addr]",
|
||||
Short: "Query a validator-candidate account",
|
||||
Use: "validator [validator-addr]",
|
||||
Short: "Query a validator-validator account",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
|
@ -27,22 +27,22 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := stake.GetCandidateKey(addr)
|
||||
key := stake.GetValidatorKey(addr)
|
||||
ctx := context.NewCoreContextFromViper()
|
||||
res, err := ctx.Query(key, storeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// parse out the candidate
|
||||
candidate := new(stake.Candidate)
|
||||
cdc.MustUnmarshalBinary(res, candidate)
|
||||
output, err := wire.MarshalJSONIndent(cdc, candidate)
|
||||
// parse out the validator
|
||||
validator := new(stake.Validator)
|
||||
cdc.MustUnmarshalBinary(res, validator)
|
||||
err = cdc.UnmarshalBinary(res, validator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
output, err := wire.MarshalJSONIndent(cdc, validator)
|
||||
fmt.Println(string(output))
|
||||
return nil
|
||||
|
||||
// TODO output with proofs / machine parseable etc.
|
||||
},
|
||||
|
@ -86,14 +86,14 @@ func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
// get the command to query a single delegator bond
|
||||
// get the command to query a single delegation bond
|
||||
func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delegator-bond",
|
||||
Short: "Query a delegators bond based on address and candidate pubkey",
|
||||
Use: "delegation-bond",
|
||||
Short: "Query a delegations bond based on address and validator pubkey",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
addr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate))
|
||||
addr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -102,9 +102,9 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delegator := crypto.Address(bz)
|
||||
delegation := crypto.Address(bz)
|
||||
|
||||
key := stake.GetDelegationKey(delegator, addr, cdc)
|
||||
key := stake.GetDelegationKey(delegation, addr, cdc)
|
||||
ctx := context.NewCoreContextFromViper()
|
||||
res, err := ctx.Query(key, storeName)
|
||||
if err != nil {
|
||||
|
@ -125,16 +125,16 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
},
|
||||
}
|
||||
|
||||
cmd.Flags().AddFlagSet(fsCandidate)
|
||||
cmd.Flags().AddFlagSet(fsValidator)
|
||||
cmd.Flags().AddFlagSet(fsDelegator)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// get the command to query all the candidates bonded to a delegator
|
||||
func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
// get the command to query all the candidates bonded to a delegation
|
||||
func GetCmdQueryDelegations(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delegator-candidates",
|
||||
Short: "Query all delegators bonds based on delegator-address",
|
||||
Use: "delegation-candidates",
|
||||
Short: "Query all delegations bonds based on delegation-address",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator))
|
||||
|
@ -149,14 +149,14 @@ func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command
|
|||
}
|
||||
|
||||
// parse out the candidates
|
||||
var delegators []stake.DelegatorBond
|
||||
var delegations []stake.Delegation
|
||||
for _, KV := range resKVs {
|
||||
var delegator stake.DelegatorBond
|
||||
cdc.MustUnmarshalBinary(KV.Value, &delegator)
|
||||
delegators = append(delegators, delegator)
|
||||
var delegation stake.Delegation
|
||||
cdc.MustUnmarshalBinary(KV.Value, &delegation)
|
||||
delegations = append(delegations, delegation)
|
||||
}
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, delegators)
|
||||
output, err := wire.MarshalJSONIndent(cdc, delegations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "declare-candidacy",
|
||||
Short: "create new validator-candidate account and delegate some coins to it",
|
||||
Short: "create new validator-validator account and delegate some coins to it",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
||||
|
@ -28,7 +28,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
candidateAddr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate))
|
||||
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
}
|
||||
|
||||
if viper.GetString(FlagMoniker) == "" {
|
||||
return fmt.Errorf("please enter a moniker for the validator-candidate using --moniker")
|
||||
return fmt.Errorf("please enter a moniker for the validator-validator using --moniker")
|
||||
}
|
||||
description := stake.Description{
|
||||
Moniker: viper.GetString(FlagMoniker),
|
||||
|
@ -55,7 +55,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
Website: viper.GetString(FlagWebsite),
|
||||
Details: viper.GetString(FlagDetails),
|
||||
}
|
||||
msg := stake.NewMsgDeclareCandidacy(candidateAddr, pk, amount, description)
|
||||
msg := stake.NewMsgDeclareCandidacy(validatorAddr, pk, amount, description)
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc)
|
||||
|
@ -71,7 +71,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
cmd.Flags().AddFlagSet(fsPk)
|
||||
cmd.Flags().AddFlagSet(fsAmount)
|
||||
cmd.Flags().AddFlagSet(fsDescription)
|
||||
cmd.Flags().AddFlagSet(fsCandidate)
|
||||
cmd.Flags().AddFlagSet(fsValidator)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -79,10 +79,10 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "edit-candidacy",
|
||||
Short: "edit and existing validator-candidate account",
|
||||
Short: "edit and existing validator-validator account",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
candidateAddr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate))
|
||||
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
Website: viper.GetString(FlagWebsite),
|
||||
Details: viper.GetString(FlagDetails),
|
||||
}
|
||||
msg := stake.NewMsgEditCandidacy(candidateAddr, description)
|
||||
msg := stake.NewMsgEditCandidacy(validatorAddr, description)
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
@ -108,7 +108,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
}
|
||||
|
||||
cmd.Flags().AddFlagSet(fsDescription)
|
||||
cmd.Flags().AddFlagSet(fsCandidate)
|
||||
cmd.Flags().AddFlagSet(fsValidator)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
|||
func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delegate",
|
||||
Short: "delegate coins to an existing validator/candidate",
|
||||
Short: "delegate coins to an existing validator/validator",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
amount, err := sdk.ParseCoin(viper.GetString(FlagAmount))
|
||||
if err != nil {
|
||||
|
@ -124,12 +124,12 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
|||
}
|
||||
|
||||
delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator))
|
||||
candidateAddr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate))
|
||||
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := stake.NewMsgDelegate(delegatorAddr, candidateAddr, amount)
|
||||
msg := stake.NewMsgDelegate(delegatorAddr, validatorAddr, amount)
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
@ -146,7 +146,7 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
|||
|
||||
cmd.Flags().AddFlagSet(fsAmount)
|
||||
cmd.Flags().AddFlagSet(fsDelegator)
|
||||
cmd.Flags().AddFlagSet(fsCandidate)
|
||||
cmd.Flags().AddFlagSet(fsValidator)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
|||
func GetCmdUnbond(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "unbond",
|
||||
Short: "unbond coins from a validator/candidate",
|
||||
Short: "unbond coins from a validator/validator",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// check the shares before broadcasting
|
||||
|
@ -172,12 +172,12 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command {
|
|||
}
|
||||
|
||||
delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator))
|
||||
candidateAddr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate))
|
||||
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := stake.NewMsgUnbond(delegatorAddr, candidateAddr, sharesStr)
|
||||
msg := stake.NewMsgUnbond(delegatorAddr, validatorAddr, sharesStr)
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
@ -194,6 +194,6 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command {
|
|||
|
||||
cmd.Flags().AddFlagSet(fsShares)
|
||||
cmd.Flags().AddFlagSet(fsDelegator)
|
||||
cmd.Flags().AddFlagSet(fsCandidate)
|
||||
cmd.Flags().AddFlagSet(fsValidator)
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", BondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
|
||||
r.HandleFunc("/stake/{delegator}/bonding_status/{validator}", BondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
|
||||
}
|
||||
|
||||
// BondingStatusHandlerFn - http request handler to query delegator bonding status
|
||||
|
@ -41,9 +41,9 @@ func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase,
|
|||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
candidateAddr := sdk.Address(bz)
|
||||
validatorAddr := sdk.Address(bz)
|
||||
|
||||
key := stake.GetDelegationKey(delegatorAddr, candidateAddr, cdc)
|
||||
key := stake.GetDelegationKey(delegatorAddr, validatorAddr, cdc)
|
||||
|
||||
res, err := ctx.Query(key, storeName)
|
||||
if err != nil {
|
||||
|
|
|
@ -14,9 +14,8 @@ const (
|
|||
|
||||
// Gaia errors reserve 200 ~ 299.
|
||||
CodeInvalidValidator CodeType = 201
|
||||
CodeInvalidCandidate CodeType = 202
|
||||
CodeInvalidBond CodeType = 203
|
||||
CodeInvalidInput CodeType = 204
|
||||
CodeInvalidBond CodeType = 202
|
||||
CodeInvalidInput CodeType = 203
|
||||
CodeUnauthorized CodeType = sdk.CodeUnauthorized
|
||||
CodeInternal CodeType = sdk.CodeInternal
|
||||
CodeUnknownRequest CodeType = sdk.CodeUnknownRequest
|
||||
|
@ -27,8 +26,6 @@ func codeToDefaultMsg(code CodeType) string {
|
|||
switch code {
|
||||
case CodeInvalidValidator:
|
||||
return "Invalid Validator"
|
||||
case CodeInvalidCandidate:
|
||||
return "Invalid Candidate"
|
||||
case CodeInvalidBond:
|
||||
return "Invalid Bond"
|
||||
case CodeInvalidInput:
|
||||
|
@ -50,8 +47,8 @@ func codeToDefaultMsg(code CodeType) string {
|
|||
func ErrNotEnoughBondShares(codespace sdk.CodespaceType, shares string) sdk.Error {
|
||||
return newError(codespace, CodeInvalidBond, fmt.Sprintf("not enough shares only have %v", shares))
|
||||
}
|
||||
func ErrCandidateEmpty(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Cannot bond to an empty candidate")
|
||||
func ErrValidatorEmpty(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Cannot bond to an empty validator")
|
||||
}
|
||||
func ErrBadBondingDenom(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidBond, "Invalid coin denomination")
|
||||
|
@ -71,16 +68,13 @@ func ErrCommissionHuge(codespace sdk.CodespaceType) sdk.Error {
|
|||
func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address")
|
||||
}
|
||||
func ErrBadCandidateAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Candidate does not exist for that address")
|
||||
}
|
||||
func ErrBadDelegatorAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Delegator does not exist for that address")
|
||||
}
|
||||
func ErrCandidateExistsAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Candidate already exist, cannot re-declare candidacy")
|
||||
func ErrValidatorExistsAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Validator already exist, cannot re-declare candidacy")
|
||||
}
|
||||
func ErrCandidateRevoked(codespace sdk.CodespaceType) sdk.Error {
|
||||
func ErrValidatorRevoked(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Candidacy for this address is currently revoked")
|
||||
}
|
||||
func ErrMissingSignature(codespace sdk.CodespaceType) sdk.Error {
|
||||
|
@ -89,7 +83,7 @@ func ErrMissingSignature(codespace sdk.CodespaceType) sdk.Error {
|
|||
func ErrBondNotNominated(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Cannot bond to non-nominated account")
|
||||
}
|
||||
func ErrNoCandidateForAddress(codespace sdk.CodespaceType) sdk.Error {
|
||||
func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address")
|
||||
}
|
||||
func ErrNoDelegatorForAddress(codespace sdk.CodespaceType) sdk.Error {
|
||||
|
|
|
@ -52,8 +52,8 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker {
|
|||
func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
||||
k.setPool(ctx, data.Pool)
|
||||
k.setParams(ctx, data.Params)
|
||||
for _, candidate := range data.Candidates {
|
||||
k.setCandidate(ctx, candidate)
|
||||
for _, validator := range data.Validators {
|
||||
k.setValidator(ctx, validator)
|
||||
}
|
||||
for _, bond := range data.Bonds {
|
||||
k.setDelegation(ctx, bond)
|
||||
|
@ -64,12 +64,12 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
|||
func WriteGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
||||
pool := k.GetPool(ctx)
|
||||
params := k.GetParams(ctx)
|
||||
candidates := k.GetCandidates(ctx, 32767)
|
||||
validators := k.GetValidators(ctx, 32767)
|
||||
bonds := k.getBonds(ctx, 32767)
|
||||
return GenesisState{
|
||||
pool,
|
||||
params,
|
||||
candidates,
|
||||
validators,
|
||||
bonds,
|
||||
}
|
||||
}
|
||||
|
@ -82,9 +82,9 @@ func WriteGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
|||
func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keeper) sdk.Result {
|
||||
|
||||
// check to see if the pubkey or sender has been registered before
|
||||
_, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
_, found := k.GetValidator(ctx, msg.ValidatorAddr)
|
||||
if found {
|
||||
return ErrCandidateExistsAddr(k.codespace).Result()
|
||||
return ErrValidatorExistsAddr(k.codespace).Result()
|
||||
}
|
||||
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
|
||||
return ErrBadBondingDenom(k.codespace).Result()
|
||||
|
@ -95,12 +95,17 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe
|
|||
}
|
||||
}
|
||||
|
||||
candidate := NewCandidate(msg.CandidateAddr, msg.PubKey, msg.Description)
|
||||
k.setCandidate(ctx, candidate)
|
||||
tags := sdk.NewTags("action", []byte("declareCandidacy"), "candidate", msg.CandidateAddr.Bytes(), "moniker", []byte(msg.Description.Moniker), "identity", []byte(msg.Description.Identity))
|
||||
validator := NewValidator(msg.ValidatorAddr, msg.PubKey, msg.Description)
|
||||
k.setValidator(ctx, validator)
|
||||
tags := sdk.NewTags(
|
||||
"action", []byte("declareCandidacy"),
|
||||
"candidate", msg.CandidateAddr.Bytes(),
|
||||
"moniker", []byte(msg.Description.Moniker),
|
||||
"identity", []byte(msg.Description.Identity),
|
||||
)
|
||||
|
||||
// move coins from the msg.Address account to a (self-bond) delegator account
|
||||
// the candidate account and global shares are updated within here
|
||||
// the validator account and global shares are updated within here
|
||||
delegateTags, err := delegate(ctx, k, msg.CandidateAddr, msg.Bond, candidate)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
|
@ -113,10 +118,10 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe
|
|||
|
||||
func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk.Result {
|
||||
|
||||
// candidate must already be registered
|
||||
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
// validator must already be registered
|
||||
validator, found := k.GetValidator(ctx, msg.ValidatorAddr)
|
||||
if !found {
|
||||
return ErrBadCandidateAddr(k.codespace).Result()
|
||||
return ErrBadValidatorAddr(k.codespace).Result()
|
||||
}
|
||||
if ctx.IsCheckTx() {
|
||||
return sdk.Result{
|
||||
|
@ -126,13 +131,18 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk
|
|||
|
||||
// XXX move to types
|
||||
// replace all editable fields (clients should autofill existing values)
|
||||
candidate.Description.Moniker = msg.Description.Moniker
|
||||
candidate.Description.Identity = msg.Description.Identity
|
||||
candidate.Description.Website = msg.Description.Website
|
||||
candidate.Description.Details = msg.Description.Details
|
||||
validator.Description.Moniker = msg.Description.Moniker
|
||||
validator.Description.Identity = msg.Description.Identity
|
||||
validator.Description.Website = msg.Description.Website
|
||||
validator.Description.Details = msg.Description.Details
|
||||
|
||||
k.setCandidate(ctx, candidate)
|
||||
tags := sdk.NewTags("action", []byte("editCandidacy"), "candidate", msg.CandidateAddr.Bytes(), "moniker", []byte(msg.Description.Moniker), "identity", []byte(msg.Description.Identity))
|
||||
k.setValidator(ctx, validator)
|
||||
tags := sdk.NewTags(
|
||||
"action", []byte("editCandidacy"),
|
||||
"candidate", msg.CandidateAddr.Bytes(),
|
||||
"moniker", []byte(msg.Description.Moniker),
|
||||
"identity", []byte(msg.Description.Identity),
|
||||
)
|
||||
return sdk.Result{
|
||||
Tags: tags,
|
||||
}
|
||||
|
@ -140,22 +150,22 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk
|
|||
|
||||
func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result {
|
||||
|
||||
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
validator, found := k.GetValidator(ctx, msg.ValidatorAddr)
|
||||
if !found {
|
||||
return ErrBadCandidateAddr(k.codespace).Result()
|
||||
return ErrBadValidatorAddr(k.codespace).Result()
|
||||
}
|
||||
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
|
||||
return ErrBadBondingDenom(k.codespace).Result()
|
||||
}
|
||||
if candidate.Status == Revoked {
|
||||
return ErrCandidateRevoked(k.codespace).Result()
|
||||
if validator.Status == sdk.Revoked {
|
||||
return ErrValidatorRevoked(k.codespace).Result()
|
||||
}
|
||||
if ctx.IsCheckTx() {
|
||||
return sdk.Result{
|
||||
GasUsed: GasDelegate,
|
||||
}
|
||||
}
|
||||
tags, err := delegate(ctx, k, msg.DelegatorAddr, msg.Bond, candidate)
|
||||
tags, err := delegate(ctx, k, msg.DelegatorAddr, msg.Bond, validator)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
@ -166,14 +176,14 @@ func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result {
|
|||
|
||||
// common functionality between handlers
|
||||
func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
|
||||
bondAmt sdk.Coin, candidate Candidate) (sdk.Tags, sdk.Error) {
|
||||
bondAmt sdk.Coin, validator Validator) (sdk.Tags, sdk.Error) {
|
||||
|
||||
// Get or create the delegator bond
|
||||
bond, found := k.GetDelegation(ctx, delegatorAddr, candidate.Address)
|
||||
bond, found := k.GetDelegation(ctx, delegatorAddr, validator.Address)
|
||||
if !found {
|
||||
bond = Delegation{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
CandidateAddr: candidate.Address,
|
||||
ValidatorAddr: validator.Address,
|
||||
Shares: sdk.ZeroRat(),
|
||||
}
|
||||
}
|
||||
|
@ -184,14 +194,14 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool, candidate, newShares := pool.candidateAddTokens(candidate, bondAmt.Amount)
|
||||
pool, validator, newShares := pool.validatorAddTokens(validator, bondAmt.Amount)
|
||||
bond.Shares = bond.Shares.Add(newShares)
|
||||
|
||||
// Update bond height
|
||||
bond.Height = ctx.BlockHeight()
|
||||
|
||||
k.setDelegation(ctx, bond)
|
||||
k.setCandidate(ctx, candidate)
|
||||
k.setValidator(ctx, validator)
|
||||
k.setPool(ctx, pool)
|
||||
tags := sdk.NewTags("action", []byte("delegate"), "delegator", delegatorAddr.Bytes(), "candidate", candidate.Address.Bytes())
|
||||
return tags, nil
|
||||
|
@ -200,7 +210,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
|
|||
func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
||||
|
||||
// check if bond has any shares in it unbond
|
||||
bond, found := k.GetDelegation(ctx, msg.DelegatorAddr, msg.CandidateAddr)
|
||||
bond, found := k.GetDelegation(ctx, msg.DelegatorAddr, msg.ValidatorAddr)
|
||||
if !found {
|
||||
return ErrNoDelegatorForAddress(k.codespace).Result()
|
||||
}
|
||||
|
@ -226,10 +236,10 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
|||
}
|
||||
}
|
||||
|
||||
// get candidate
|
||||
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
// get validator
|
||||
validator, found := k.GetValidator(ctx, msg.ValidatorAddr)
|
||||
if !found {
|
||||
return ErrNoCandidateForAddress(k.codespace).Result()
|
||||
return ErrNoValidatorForAddress(k.codespace).Result()
|
||||
}
|
||||
|
||||
if ctx.IsCheckTx() {
|
||||
|
@ -250,10 +260,10 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
|||
revokeCandidacy := false
|
||||
if bond.Shares.IsZero() {
|
||||
|
||||
// if the bond is the owner of the candidate then
|
||||
// if the bond is the owner of the validator then
|
||||
// trigger a revoke candidacy
|
||||
if bytes.Equal(bond.DelegatorAddr, candidate.Address) &&
|
||||
candidate.Status != Revoked {
|
||||
if bytes.Equal(bond.DelegatorAddr, validator.Address) &&
|
||||
validator.Status != sdk.Revoked {
|
||||
revokeCandidacy = true
|
||||
}
|
||||
|
||||
|
@ -266,29 +276,29 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
|||
|
||||
// Add the coins
|
||||
p := k.GetPool(ctx)
|
||||
p, candidate, returnAmount := p.candidateRemoveShares(candidate, shares)
|
||||
p, validator, returnAmount := p.validatorRemoveShares(validator, shares)
|
||||
returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}}
|
||||
k.coinKeeper.AddCoins(ctx, bond.DelegatorAddr, returnCoins)
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
// revoke candidate if necessary
|
||||
// revoke validator if necessary
|
||||
if revokeCandidacy {
|
||||
|
||||
// change the share types to unbonded if they were not already
|
||||
if candidate.Status == Bonded {
|
||||
p, candidate = p.bondedToUnbondedPool(candidate)
|
||||
if validator.Status == sdk.Bonded {
|
||||
p, validator = p.bondedToUnbondedPool(validator)
|
||||
}
|
||||
|
||||
// lastly update the status
|
||||
candidate.Status = Revoked
|
||||
validator.Status = sdk.Revoked
|
||||
}
|
||||
|
||||
// deduct shares from the candidate
|
||||
if candidate.DelegatorShares.IsZero() {
|
||||
k.removeCandidate(ctx, candidate.Address)
|
||||
// deduct shares from the validator
|
||||
if validator.DelegatorShares.IsZero() {
|
||||
k.removeValidator(ctx, validator.Address)
|
||||
} else {
|
||||
k.setCandidate(ctx, candidate)
|
||||
k.setValidator(ctx, validator)
|
||||
}
|
||||
k.setPool(ctx, p)
|
||||
tags := sdk.NewTags("action", []byte("unbond"), "delegator", msg.DelegatorAddr.Bytes(), "candidate", msg.CandidateAddr.Bytes())
|
||||
|
|
|
@ -17,16 +17,16 @@ import (
|
|||
func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt int64) MsgDeclareCandidacy {
|
||||
return MsgDeclareCandidacy{
|
||||
Description: Description{},
|
||||
CandidateAddr: address,
|
||||
ValidatorAddr: address,
|
||||
PubKey: pubKey,
|
||||
Bond: sdk.Coin{"steak", amt},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestMsgDelegate(delegatorAddr, candidateAddr sdk.Address, amt int64) MsgDelegate {
|
||||
func newTestMsgDelegate(delegatorAddr, validatorAddr sdk.Address, amt int64) MsgDelegate {
|
||||
return MsgDelegate{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
CandidateAddr: candidateAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
Bond: sdk.Coin{"steak", amt},
|
||||
}
|
||||
}
|
||||
|
@ -36,21 +36,21 @@ func newTestMsgDelegate(delegatorAddr, candidateAddr sdk.Address, amt int64) Msg
|
|||
func TestDuplicatesMsgDeclareCandidacy(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 1000)
|
||||
|
||||
candidateAddr := addrs[0]
|
||||
validatorAddr := addrs[0]
|
||||
pk := pks[0]
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pk, 10)
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pk, 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
assert.True(t, got.IsOK(), "%v", got)
|
||||
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
assert.Equal(t, Unbonded, candidate.Status)
|
||||
assert.Equal(t, candidateAddr, candidate.Address)
|
||||
assert.Equal(t, pk, candidate.PubKey)
|
||||
assert.Equal(t, sdk.NewRat(10), candidate.BondedShares)
|
||||
assert.Equal(t, sdk.NewRat(10), candidate.DelegatorShares)
|
||||
assert.Equal(t, Description{}, candidate.Description)
|
||||
assert.Equal(t, Unbonded, validator.Status)
|
||||
assert.Equal(t, validatorAddr, validator.Address)
|
||||
assert.Equal(t, pk, validator.PubKey)
|
||||
assert.Equal(t, sdk.NewRat(10), validator.BondedShares)
|
||||
assert.Equal(t, sdk.NewRat(10), validator.DelegatorShares)
|
||||
assert.Equal(t, Description{}, validator.Description)
|
||||
|
||||
// one candidate cannot bond twice
|
||||
// one validator cannot bond twice
|
||||
msgDeclareCandidacy.PubKey = pks[1]
|
||||
got = handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
assert.False(t, got.IsOK(), "%v", got)
|
||||
|
@ -62,20 +62,20 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
|||
params := keeper.GetParams(ctx)
|
||||
|
||||
bondAmount := int64(10)
|
||||
candidateAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
validatorAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
|
||||
// first declare candidacy
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], bondAmount)
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], bondAmount)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
assert.True(t, got.IsOK(), "expected declare candidacy msg to be ok, got %v", got)
|
||||
|
||||
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
assert.Equal(t, bondAmount, candidate.DelegatorShares.Evaluate())
|
||||
assert.Equal(t, bondAmount, candidate.BondedShares.Evaluate())
|
||||
assert.Equal(t, bondAmount, validator.DelegatorShares.Evaluate())
|
||||
assert.Equal(t, bondAmount, validator.BondedShares.Evaluate())
|
||||
|
||||
// just send the same msgbond multiple times
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, bondAmount)
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount)
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
ctx = ctx.WithBlockHeight(int64(i))
|
||||
|
@ -84,9 +84,9 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
|||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
|
||||
//Check that the accounts and the bond account have the appropriate values
|
||||
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
bond, found := keeper.GetDelegation(ctx, delegatorAddr, candidateAddr)
|
||||
bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
require.True(t, found)
|
||||
|
||||
expBond := int64(i+1) * bondAmount
|
||||
|
@ -96,18 +96,18 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
|||
require.Equal(t, bond.Height, int64(i), "Incorrect bond height")
|
||||
|
||||
gotBond := bond.Shares.Evaluate()
|
||||
gotDelegatorShares := candidate.DelegatorShares.Evaluate()
|
||||
gotDelegatorShares := validator.DelegatorShares.Evaluate()
|
||||
gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
|
||||
|
||||
require.Equal(t, expBond, gotBond,
|
||||
"i: %v\nexpBond: %v\ngotBond: %v\ncandidate: %v\nbond: %v\n",
|
||||
i, expBond, gotBond, candidate, bond)
|
||||
"i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n",
|
||||
i, expBond, gotBond, validator, bond)
|
||||
require.Equal(t, expDelegatorShares, gotDelegatorShares,
|
||||
"i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\ncandidate: %v\nbond: %v\n",
|
||||
i, expDelegatorShares, gotDelegatorShares, candidate, bond)
|
||||
"i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n",
|
||||
i, expDelegatorShares, gotDelegatorShares, validator, bond)
|
||||
require.Equal(t, expDelegatorAcc, gotDelegatorAcc,
|
||||
"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\ncandidate: %v\nbond: %v\n",
|
||||
i, expDelegatorAcc, gotDelegatorAcc, candidate, bond)
|
||||
"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n",
|
||||
i, expDelegatorAcc, gotDelegatorAcc, validator, bond)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,34 +117,34 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
|||
params := keeper.GetParams(ctx)
|
||||
|
||||
// declare candidacy, delegate
|
||||
candidateAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
validatorAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], initBond)
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], initBond)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
assert.True(t, got.IsOK(), "expected declare-candidacy to be ok, got %v", got)
|
||||
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, initBond)
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, initBond)
|
||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||
assert.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
|
||||
|
||||
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
assert.Equal(t, initBond*2, candidate.DelegatorShares.Evaluate())
|
||||
assert.Equal(t, initBond*2, candidate.BondedShares.Evaluate())
|
||||
assert.Equal(t, initBond*2, validator.DelegatorShares.Evaluate())
|
||||
assert.Equal(t, initBond*2, validator.BondedShares.Evaluate())
|
||||
|
||||
// just send the same msgUnbond multiple times
|
||||
// TODO use decimals here
|
||||
unbondShares, unbondSharesStr := int64(10), "10"
|
||||
msgUnbond := NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr)
|
||||
msgUnbond := NewMsgUnbond(delegatorAddr, validatorAddr, unbondSharesStr)
|
||||
numUnbonds := 5
|
||||
for i := 0; i < numUnbonds; i++ {
|
||||
got := handleMsgUnbond(ctx, msgUnbond, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
|
||||
//Check that the accounts and the bond account have the appropriate values
|
||||
candidate, found = keeper.GetCandidate(ctx, candidateAddr)
|
||||
validator, found = keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
bond, found := keeper.GetDelegation(ctx, delegatorAddr, candidateAddr)
|
||||
bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
require.True(t, found)
|
||||
|
||||
expBond := initBond - int64(i+1)*unbondShares
|
||||
|
@ -152,18 +152,18 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
|||
expDelegatorAcc := initBond - expBond
|
||||
|
||||
gotBond := bond.Shares.Evaluate()
|
||||
gotDelegatorShares := candidate.DelegatorShares.Evaluate()
|
||||
gotDelegatorShares := validator.DelegatorShares.Evaluate()
|
||||
gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
|
||||
|
||||
require.Equal(t, expBond, gotBond,
|
||||
"i: %v\nexpBond: %v\ngotBond: %v\ncandidate: %v\nbond: %v\n",
|
||||
i, expBond, gotBond, candidate, bond)
|
||||
"i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n",
|
||||
i, expBond, gotBond, validator, bond)
|
||||
require.Equal(t, expDelegatorShares, gotDelegatorShares,
|
||||
"i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\ncandidate: %v\nbond: %v\n",
|
||||
i, expDelegatorShares, gotDelegatorShares, candidate, bond)
|
||||
"i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n",
|
||||
i, expDelegatorShares, gotDelegatorShares, validator, bond)
|
||||
require.Equal(t, expDelegatorAcc, gotDelegatorAcc,
|
||||
"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\ncandidate: %v\nbond: %v\n",
|
||||
i, expDelegatorAcc, gotDelegatorAcc, candidate, bond)
|
||||
"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n",
|
||||
i, expDelegatorAcc, gotDelegatorAcc, validator, bond)
|
||||
}
|
||||
|
||||
// these are more than we have bonded now
|
||||
|
@ -176,7 +176,7 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
|||
}
|
||||
for _, c := range errorCases {
|
||||
unbondShares := strconv.Itoa(int(c))
|
||||
msgUnbond := NewMsgUnbond(delegatorAddr, candidateAddr, unbondShares)
|
||||
msgUnbond := NewMsgUnbond(delegatorAddr, validatorAddr, unbondShares)
|
||||
got = handleMsgUnbond(ctx, msgUnbond, keeper)
|
||||
require.False(t, got.IsOK(), "expected unbond msg to fail")
|
||||
}
|
||||
|
@ -185,14 +185,14 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
|||
|
||||
// should be unable to unbond one more than we have
|
||||
unbondSharesStr = strconv.Itoa(int(leftBonded) + 1)
|
||||
msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr)
|
||||
msgUnbond = NewMsgUnbond(delegatorAddr, validatorAddr, unbondSharesStr)
|
||||
got = handleMsgUnbond(ctx, msgUnbond, keeper)
|
||||
assert.False(t, got.IsOK(),
|
||||
"got: %v\nmsgUnbond: %v\nshares: %v\nleftBonded: %v\n", got, msgUnbond, unbondSharesStr, leftBonded)
|
||||
|
||||
// should be able to unbond just what we have
|
||||
unbondSharesStr = strconv.Itoa(int(leftBonded))
|
||||
msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr)
|
||||
msgUnbond = NewMsgUnbond(delegatorAddr, validatorAddr, unbondSharesStr)
|
||||
got = handleMsgUnbond(ctx, msgUnbond, keeper)
|
||||
assert.True(t, got.IsOK(),
|
||||
"got: %v\nmsgUnbond: %v\nshares: %v\nleftBonded: %v\n", got, msgUnbond, unbondSharesStr, leftBonded)
|
||||
|
@ -202,108 +202,108 @@ func TestMultipleMsgDeclareCandidacy(t *testing.T) {
|
|||
initBond := int64(1000)
|
||||
ctx, accMapper, keeper := createTestInput(t, false, initBond)
|
||||
params := keeper.GetParams(ctx)
|
||||
candidateAddrs := []sdk.Address{addrs[0], addrs[1], addrs[2]}
|
||||
validatorAddrs := []sdk.Address{addrs[0], addrs[1], addrs[2]}
|
||||
|
||||
// bond them all
|
||||
for i, candidateAddr := range candidateAddrs {
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[i], 10)
|
||||
for i, validatorAddr := range validatorAddrs {
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[i], 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
|
||||
//Check that the account is bonded
|
||||
candidates := keeper.GetCandidates(ctx, 100)
|
||||
require.Equal(t, (i + 1), len(candidates))
|
||||
val := candidates[i]
|
||||
validators := keeper.GetValidators(ctx, 100)
|
||||
require.Equal(t, (i + 1), len(validators))
|
||||
val := validators[i]
|
||||
balanceExpd := initBond - 10
|
||||
balanceGot := accMapper.GetAccount(ctx, val.Address).GetCoins().AmountOf(params.BondDenom)
|
||||
require.Equal(t, i+1, len(candidates), "expected %d candidates got %d, candidates: %v", i+1, len(candidates), candidates)
|
||||
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.Evaluate()), "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
|
||||
for i, candidateAddr := range candidateAddrs {
|
||||
candidatePre, found := keeper.GetCandidate(ctx, candidateAddr)
|
||||
for i, validatorAddr := range validatorAddrs {
|
||||
validatorPre, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
msgUnbond := NewMsgUnbond(candidateAddr, candidateAddr, "10") // self-delegation
|
||||
msgUnbond := NewMsgUnbond(validatorAddr, validatorAddr, "10") // self-delegation
|
||||
got := handleMsgUnbond(ctx, msgUnbond, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
|
||||
//Check that the account is unbonded
|
||||
candidates := keeper.GetCandidates(ctx, 100)
|
||||
require.Equal(t, len(candidateAddrs)-(i+1), len(candidates),
|
||||
"expected %d candidates got %d", len(candidateAddrs)-(i+1), len(candidates))
|
||||
validators := keeper.GetValidators(ctx, 100)
|
||||
require.Equal(t, len(validatorAddrs)-(i+1), len(validators),
|
||||
"expected %d validators got %d", len(validatorAddrs)-(i+1), len(validators))
|
||||
|
||||
_, found = keeper.GetCandidate(ctx, candidateAddr)
|
||||
_, found = keeper.GetValidator(ctx, validatorAddr)
|
||||
require.False(t, found)
|
||||
|
||||
expBalance := initBond
|
||||
gotBalance := accMapper.GetAccount(ctx, candidatePre.Address).GetCoins().AmountOf(params.BondDenom)
|
||||
gotBalance := accMapper.GetAccount(ctx, validatorPre.Address).GetCoins().AmountOf(params.BondDenom)
|
||||
require.Equal(t, expBalance, gotBalance, "expected account to have %d, got %d", expBalance, gotBalance)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleMsgDelegate(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 1000)
|
||||
candidateAddr, delegatorAddrs := addrs[0], addrs[1:]
|
||||
validatorAddr, delegatorAddrs := addrs[0], addrs[1:]
|
||||
|
||||
//first make a candidate
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], 10)
|
||||
//first make a validator
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||
|
||||
// delegate multiple parties
|
||||
for i, delegatorAddr := range delegatorAddrs {
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, 10)
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
||||
got := handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
|
||||
//Check that the account is bonded
|
||||
bond, found := keeper.GetDelegation(ctx, delegatorAddr, candidateAddr)
|
||||
bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
require.True(t, found)
|
||||
require.NotNil(t, bond, "expected delegatee bond %d to exist", bond)
|
||||
}
|
||||
|
||||
// unbond them all
|
||||
for i, delegatorAddr := range delegatorAddrs {
|
||||
msgUnbond := NewMsgUnbond(delegatorAddr, candidateAddr, "10")
|
||||
msgUnbond := NewMsgUnbond(delegatorAddr, validatorAddr, "10")
|
||||
got := handleMsgUnbond(ctx, msgUnbond, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
|
||||
//Check that the account is unbonded
|
||||
_, found := keeper.GetDelegation(ctx, delegatorAddr, candidateAddr)
|
||||
_, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
require.False(t, found)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVoidCandidacy(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 1000)
|
||||
candidateAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
validatorAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
|
||||
// create the candidate
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], 10)
|
||||
// create the validator
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
|
||||
|
||||
// bond a delegator
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, 10)
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||
require.True(t, got.IsOK(), "expected ok, got %v", got)
|
||||
|
||||
// unbond the candidates bond portion
|
||||
msgUnbondCandidate := NewMsgUnbond(candidateAddr, candidateAddr, "10")
|
||||
got = handleMsgUnbond(ctx, msgUnbondCandidate, keeper)
|
||||
// unbond the validators bond portion
|
||||
msgUnbondValidator := NewMsgUnbond(validatorAddr, validatorAddr, "10")
|
||||
got = handleMsgUnbond(ctx, msgUnbondValidator, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
|
||||
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Revoked, candidate.Status)
|
||||
require.Equal(t, Revoked, validator.Status)
|
||||
|
||||
// test that this address cannot yet be bonded too because is revoked
|
||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||
assert.False(t, got.IsOK(), "expected error, got %v", got)
|
||||
|
||||
// test that the delegator can still withdraw their bonds
|
||||
msgUnbondDelegator := NewMsgUnbond(delegatorAddr, candidateAddr, "10")
|
||||
msgUnbondDelegator := NewMsgUnbond(delegatorAddr, validatorAddr, "10")
|
||||
got = handleMsgUnbond(ctx, msgUnbondDelegator, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
|
||||
|
||||
|
|
|
@ -36,23 +36,23 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.
|
|||
|
||||
//_________________________________________________________________________
|
||||
|
||||
// get a single candidate
|
||||
func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candidate, found bool) {
|
||||
// get a single validator
|
||||
func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.Address) (validator Validator, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
b := store.Get(GetCandidateKey(addr))
|
||||
b := store.Get(GetValidatorKey(addr))
|
||||
if b == nil {
|
||||
return candidate, false
|
||||
return validator, false
|
||||
}
|
||||
k.cdc.MustUnmarshalBinary(b, &candidate)
|
||||
return candidate, true
|
||||
k.cdc.MustUnmarshalBinary(b, &validator)
|
||||
return validator, true
|
||||
}
|
||||
|
||||
// Get the set of all candidates, retrieve a maxRetrieve number of records
|
||||
func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Candidates) {
|
||||
// Get the set of all validators, retrieve a maxRetrieve number of records
|
||||
func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve int16) (validators Validators) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
iterator := store.SubspaceIterator(CandidatesKey)
|
||||
iterator := store.SubspaceIterator(ValidatorsKey)
|
||||
|
||||
candidates = make([]Candidate, maxRetrieve)
|
||||
validators = make([]Validator, maxRetrieve)
|
||||
i := 0
|
||||
for ; ; i++ {
|
||||
if !iterator.Valid() || i > int(maxRetrieve-1) {
|
||||
|
@ -60,62 +60,61 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca
|
|||
break
|
||||
}
|
||||
bz := iterator.Value()
|
||||
var candidate Candidate
|
||||
k.cdc.MustUnmarshalBinary(bz, &candidate)
|
||||
candidates[i] = candidate
|
||||
var validator Validator
|
||||
k.cdc.MustUnmarshalBinary(bz, &validator)
|
||||
validators[i] = validator
|
||||
iterator.Next()
|
||||
}
|
||||
return candidates[:i] // trim
|
||||
return validators[:i] // trim
|
||||
}
|
||||
|
||||
func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
|
||||
func (k Keeper) setValidator(ctx sdk.Context, validator Validator) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
address := candidate.Address
|
||||
address := validator.Address
|
||||
|
||||
// retreive the old candidate record
|
||||
oldCandidate, oldFound := k.GetCandidate(ctx, address)
|
||||
// retreive the old validator record
|
||||
oldValidator, oldFound := k.GetValidator(ctx, address)
|
||||
|
||||
// if found, copy the old block height and counter
|
||||
if oldFound {
|
||||
candidate.ValidatorBondHeight = oldCandidate.ValidatorBondHeight
|
||||
candidate.ValidatorBondCounter = oldCandidate.ValidatorBondCounter
|
||||
validator.ValidatorBondHeight = oldValidator.ValidatorBondHeight
|
||||
validator.ValidatorBondCounter = oldValidator.ValidatorBondCounter
|
||||
}
|
||||
|
||||
// marshal the candidate record and add to the state
|
||||
bz := k.cdc.MustMarshalBinary(candidate)
|
||||
store.Set(GetCandidateKey(address), bz)
|
||||
// marshal the validator record and add to the state
|
||||
bz := k.cdc.MustMarshalBinary(validator)
|
||||
store.Set(GetValidatorKey(address), bz)
|
||||
|
||||
if oldFound {
|
||||
// if the voting power is the same no need to update any of the other indexes
|
||||
if oldCandidate.BondedShares.Equal(candidate.BondedShares) {
|
||||
if oldValidator.BondedShares.Equal(validator.BondedShares) {
|
||||
return
|
||||
}
|
||||
|
||||
// if this candidate wasn't just bonded then update the height and counter
|
||||
if oldCandidate.Status != Bonded {
|
||||
candidate.ValidatorBondHeight = ctx.BlockHeight()
|
||||
// if this validator wasn't just bonded then update the height and counter
|
||||
if oldValidator.Status != sdk.Bonded {
|
||||
validator.ValidatorBondHeight = ctx.BlockHeight()
|
||||
counter := k.getIntraTxCounter(ctx)
|
||||
candidate.ValidatorBondCounter = counter
|
||||
validator.ValidatorBondCounter = counter
|
||||
k.setIntraTxCounter(ctx, counter+1)
|
||||
}
|
||||
|
||||
// delete the old record in the power ordered list
|
||||
store.Delete(GetValidatorsBondedByPowerKey(oldCandidate.validator()))
|
||||
store.Delete(GetValidatorsBondedByPowerKey(oldValidator))
|
||||
}
|
||||
|
||||
// set the new candidate record
|
||||
bz = k.cdc.MustMarshalBinary(candidate)
|
||||
store.Set(GetCandidateKey(address), bz)
|
||||
// set the new validator record
|
||||
bz = k.cdc.MustMarshalBinary(validator)
|
||||
store.Set(GetValidatorKey(address), bz)
|
||||
|
||||
// update the list ordered by voting power
|
||||
validator := candidate.validator()
|
||||
bzVal := k.cdc.MustMarshalBinary(validator)
|
||||
store.Set(GetValidatorsBondedByPowerKey(validator), bzVal)
|
||||
|
||||
// add to the validators to update list if is already a validator
|
||||
if store.Get(GetValidatorsBondedBondedKey(candidate.PubKey)) != nil {
|
||||
if store.Get(GetValidatorsBondedBondedKey(validator.PubKey)) != nil {
|
||||
bzAbci := k.cdc.MustMarshalBinary(validator.abciValidator(k.cdc))
|
||||
store.Set(GetAccUpdateValidatorKey(address), bzAbci)
|
||||
store.Set(GetValidatorsTendermintUpdatesKey(address), bzAbci)
|
||||
|
||||
// also update the current validator store
|
||||
store.Set(GetValidatorsBondedBondedKey(validator.PubKey), bzVal)
|
||||
|
@ -123,31 +122,31 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
|
|||
}
|
||||
|
||||
// maybe add to the validator list and kick somebody off
|
||||
k.addNewValidatorOrNot(ctx, store, candidate.Address)
|
||||
k.addNewValidatorOrNot(ctx, store, validator.Address)
|
||||
return
|
||||
}
|
||||
|
||||
func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) {
|
||||
func (k Keeper) removeValidator(ctx sdk.Context, address sdk.Address) {
|
||||
|
||||
// first retreive the old candidate record
|
||||
candidate, found := k.GetCandidate(ctx, address)
|
||||
// first retreive the old validator record
|
||||
validator, found := k.GetValidator(ctx, address)
|
||||
if !found {
|
||||
return
|
||||
}
|
||||
|
||||
// delete the old candidate record
|
||||
// delete the old validator record
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(GetCandidateKey(address))
|
||||
store.Delete(GetValidatorsBondedByPowerKey(candidate.validator()))
|
||||
store.Delete(GetValidatorKey(address))
|
||||
store.Delete(GetValidatorsBondedByPowerKey(validator))
|
||||
|
||||
// delete from current and power weighted validator groups if the validator
|
||||
// exists and add validator with zero power to the validator updates
|
||||
if store.Get(GetValidatorsBondedBondedKey(candidate.PubKey)) == nil {
|
||||
if store.Get(GetValidatorsBondedBondedKey(validator.PubKey)) == nil {
|
||||
return
|
||||
}
|
||||
bz := k.cdc.MustMarshalBinary(candidate.validator().abciValidatorZero(k.cdc))
|
||||
store.Set(GetAccUpdateValidatorKey(address), bz)
|
||||
store.Delete(GetValidatorsBondedBondedKey(candidate.PubKey))
|
||||
bz := k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc))
|
||||
store.Set(GetValidatorsTendermintUpdatesKey(address), bz)
|
||||
store.Delete(GetValidatorsBondedBondedKey(validator.PubKey))
|
||||
}
|
||||
|
||||
//___________________________________________________________________________
|
||||
|
@ -175,9 +174,10 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []Validator) {
|
|||
|
||||
// get the group of bonded validators sorted by power-rank
|
||||
func (k Keeper) GetValidatorsBondedByPower(ctx sdk.Context) []Validator {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
maxValidators := k.GetParams(ctx).MaxValidators
|
||||
validators = make([]Validator, maxValidators)
|
||||
iterator = store.ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest
|
||||
validators := make([]Validator, maxValidators)
|
||||
iterator := store.ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest
|
||||
i := 0
|
||||
for ; ; i++ {
|
||||
if !iterator.Valid() || i > int(maxValidators-1) {
|
||||
|
@ -190,15 +190,16 @@ func (k Keeper) GetValidatorsBondedByPower(ctx sdk.Context) []Validator {
|
|||
validators[i] = validator
|
||||
iterator.Next()
|
||||
}
|
||||
return validators
|
||||
}
|
||||
|
||||
// This function add's (or doesn't add) a candidate record to the validator group
|
||||
// This function add's (or doesn't add) a validator record to the validator group
|
||||
// simultaniously it kicks any old validators out
|
||||
//
|
||||
// The correct subset is retrieved by iterating through an index of the
|
||||
// candidates sorted by power, stored using the ValidatorsByPowerKey. Simultaniously
|
||||
// validators sorted by power, stored using the ValidatorsByPowerKey. Simultaniously
|
||||
// the current validator records are updated in store with the
|
||||
// ValidatorsBondedKey. This store is used to determine if a candidate is a
|
||||
// ValidatorsBondedKey. This store is used to determine if a validator is a
|
||||
// validator without needing to iterate over the subspace as we do in
|
||||
// GetValidatorsBonded
|
||||
func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address sdk.Address) {
|
||||
|
@ -215,7 +216,7 @@ func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address
|
|||
addr := validator.Address
|
||||
|
||||
// iterator.Value is the validator object
|
||||
toKickOut[GetToKickOutValidatorKey(addr)] = iterator.Value()
|
||||
toKickOut[addr] = iterator.Value()
|
||||
store.Delete(iterator.Key())
|
||||
}
|
||||
iterator.Close()
|
||||
|
@ -234,15 +235,15 @@ func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address
|
|||
k.cdc.MustUnmarshalBinary(bz, &validator)
|
||||
|
||||
// remove from ToKickOut group
|
||||
toKickOut[GetToKickOutValidatorKey(validator.Address)] = nil
|
||||
toKickOut[validator.Address] = nil
|
||||
|
||||
// also add to the current validators group
|
||||
store.Set(GetValidatorsBondedBondedKey(validator.PubKey), bz)
|
||||
|
||||
// MOST IMPORTANTLY, add to the accumulated changes if this is the modified candidate
|
||||
// MOST IMPORTANTLY, add to the accumulated changes if this is the modified validator
|
||||
if bytes.Equal(address, validator.Address) {
|
||||
bz = k.cdc.MustMarshalBinary(validator.abciValidator(k.cdc))
|
||||
store.Set(GetAccUpdateValidatorKey(address), bz)
|
||||
store.Set(GetValidatorsTendermintUpdatesKey(address), bz)
|
||||
}
|
||||
|
||||
iterator.Next()
|
||||
|
@ -255,48 +256,48 @@ func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address
|
|||
var validator Validator
|
||||
k.cdc.MustUnmarshalBinary(value, &validator)
|
||||
bz := k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc))
|
||||
store.Set(GetAccUpdateValidatorKey(addr), bz)
|
||||
store.Set(GetValidatorsTendermintUpdatesKey(addr), bz)
|
||||
}
|
||||
}
|
||||
|
||||
// cummulative power of the non-absent prevotes
|
||||
func (k Keeper) GetTotalPrecommitVotingPower(ctx sdk.Context) sdk.Rat {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
//func (k Keeper) GetTotalPrecommitVotingPower(ctx sdk.Context) sdk.Rat {
|
||||
//store := ctx.KVStore(k.storeKey)
|
||||
|
||||
// get absent prevote indexes
|
||||
absents := ctx.AbsentValidators()
|
||||
//// get absent prevote indexes
|
||||
//absents := ctx.AbsentValidators()
|
||||
|
||||
TotalPower := sdk.ZeroRat()
|
||||
i := int32(0)
|
||||
iterator := store.SubspaceIterator(ValidatorsBondedKey)
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
//TotalPower := sdk.ZeroRat()
|
||||
//i := int32(0)
|
||||
//iterator := store.SubspaceIterator(ValidatorsBondedKey)
|
||||
//for ; iterator.Valid(); iterator.Next() {
|
||||
|
||||
skip := false
|
||||
for j, absentIndex := range absents {
|
||||
if absentIndex > i {
|
||||
break
|
||||
}
|
||||
//skip := false
|
||||
//for j, absentIndex := range absents {
|
||||
//if absentIndex > i {
|
||||
//break
|
||||
//}
|
||||
|
||||
// if non-voting validator found, skip adding its power
|
||||
if absentIndex == i {
|
||||
absents = append(absents[:j], absents[j+1:]...) // won't need again
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
//// if non-voting validator found, skip adding its power
|
||||
//if absentIndex == i {
|
||||
//absents = append(absents[:j], absents[j+1:]...) // won't need again
|
||||
//skip = true
|
||||
//break
|
||||
//}
|
||||
//}
|
||||
//if skip {
|
||||
//continue
|
||||
//}
|
||||
|
||||
bz := iterator.Value()
|
||||
var validator Validator
|
||||
k.cdc.MustUnmarshalBinary(bz, &validator)
|
||||
TotalPower = TotalPower.Add(validator.Power)
|
||||
i++
|
||||
}
|
||||
iterator.Close()
|
||||
return TotalPower
|
||||
}
|
||||
//bz := iterator.Value()
|
||||
//var validator Validator
|
||||
//k.cdc.MustUnmarshalBinary(bz, &validator)
|
||||
//TotalPower = TotalPower.Add(validator.Power)
|
||||
//i++
|
||||
//}
|
||||
//iterator.Close()
|
||||
//return TotalPower
|
||||
//}
|
||||
|
||||
//_________________________________________________________________________
|
||||
// Accumulated updates to the active/bonded validator set for tendermint
|
||||
|
@ -332,10 +333,10 @@ func (k Keeper) clearValidatorsTendermintUpdates(ctx sdk.Context) {
|
|||
|
||||
// load a delegator bond
|
||||
func (k Keeper) GetDelegation(ctx sdk.Context,
|
||||
delegatorAddr, candidateAddr sdk.Address) (bond Delegation, found bool) {
|
||||
delegatorAddr, validatorAddr sdk.Address) (bond Delegation, found bool) {
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
delegatorBytes := store.Get(GetDelegationKey(delegatorAddr, candidateAddr, k.cdc))
|
||||
delegatorBytes := store.Get(GetDelegationKey(delegatorAddr, validatorAddr, k.cdc))
|
||||
if delegatorBytes == nil {
|
||||
return bond, false
|
||||
}
|
||||
|
@ -390,12 +391,12 @@ func (k Keeper) GetDelegations(ctx sdk.Context, delegator sdk.Address, maxRetrie
|
|||
func (k Keeper) setDelegation(ctx sdk.Context, bond Delegation) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
b := k.cdc.MustMarshalBinary(bond)
|
||||
store.Set(GetDelegationKey(bond.DelegatorAddr, bond.CandidateAddr, k.cdc), b)
|
||||
store.Set(GetDelegationKey(bond.DelegatorAddr, bond.ValidatorAddr, k.cdc), b)
|
||||
}
|
||||
|
||||
func (k Keeper) removeDelegation(ctx sdk.Context, bond Delegation) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(GetDelegationKey(bond.DelegatorAddr, bond.CandidateAddr, k.cdc))
|
||||
store.Delete(GetDelegationKey(bond.DelegatorAddr, bond.ValidatorAddr, k.cdc))
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
@ -482,7 +483,8 @@ func (k Keeper) setPool(ctx sdk.Context, p Pool) {
|
|||
var _ sdk.ValidatorSet = Keeper{}
|
||||
|
||||
// iterate through the active validator set and perform the provided function
|
||||
func (k Keeper) Iterate(fn func(index int64, validator sdk.Validator)) {
|
||||
func (k Keeper) IterateValidatorsBonded(fn func(index int64, validator sdk.Validator)) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
iterator := store.SubspaceIterator(ValidatorsBondedKey)
|
||||
i := 0
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
|
@ -497,14 +499,11 @@ func (k Keeper) Iterate(fn func(index int64, validator sdk.Validator)) {
|
|||
|
||||
// get the sdk.validator for a particular address
|
||||
func (k Keeper) Validator(ctx sdk.Context, addr sdk.Address) sdk.Validator {
|
||||
can, ok := k.GetCandidate(ctx, addr)
|
||||
if !ok {
|
||||
val, found := k.GetValidator(ctx, addr)
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
if can.Status != Bonded {
|
||||
return nil
|
||||
}
|
||||
return can.validator()
|
||||
return val
|
||||
}
|
||||
|
||||
// total power from the bond
|
||||
|
@ -529,7 +528,7 @@ func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.Address, addrVal sdk.Add
|
|||
}
|
||||
|
||||
// iterate through the active validator set and perform the provided function
|
||||
func (k Keeper) Iterate(delAddr sdk.Address, fn func(index int64, delegator sdk.Delegator)) {
|
||||
func (k Keeper) IterateDelegators(delAddr sdk.Address, fn func(index int64, delegator sdk.Delegator)) {
|
||||
key := GetDelegationsKey(delAddr, k.cdc)
|
||||
iterator := store.SubspaceIterator(ValidatorsBondedKey)
|
||||
i := 0
|
||||
|
|
|
@ -15,7 +15,7 @@ var (
|
|||
// Keys for store prefixes
|
||||
ParamKey = []byte{0x00} // key for global parameters relating to staking
|
||||
PoolKey = []byte{0x01} // key for global parameters relating to staking
|
||||
CandidatesKey = []byte{0x02} // prefix for each key to a candidate
|
||||
ValidatorsKey = []byte{0x02} // prefix for each key to a validator
|
||||
ValidatorsByPowerKey = []byte{0x03} // prefix for each key to a validator
|
||||
ValidatorsTendermintUpdatesKey = []byte{0x04} // prefix for each key to a validator which is being updated
|
||||
ValidatorsBondedKey = []byte{0x05} // prefix for each key to bonded/actively validating validators
|
||||
|
@ -25,9 +25,9 @@ var (
|
|||
|
||||
const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch
|
||||
|
||||
// get the key for the candidate with address
|
||||
func GetCandidateKey(addr sdk.Address) []byte {
|
||||
return append(CandidatesKey, addr.Bytes()...)
|
||||
// get the key for the validator with address
|
||||
func GetValidatorKey(addr sdk.Address) []byte {
|
||||
return append(ValidatorsKey, addr.Bytes()...)
|
||||
}
|
||||
|
||||
// get the key for the validator used in the power-store
|
||||
|
@ -47,7 +47,7 @@ func GetValidatorsBondedByPowerKey(validator Validator) []byte {
|
|||
}
|
||||
|
||||
// get the key for the accumulated update validators
|
||||
func GetValidatorsBondedTendermintUpdatesKey(addr sdk.Address) []byte {
|
||||
func GetValidatorsTendermintUpdatesKey(addr sdk.Address) []byte {
|
||||
return append(ValidatorsTendermintUpdatesKey, addr.Bytes()...)
|
||||
}
|
||||
|
||||
|
@ -57,12 +57,12 @@ func GetValidatorsBondedBondedKey(pk crypto.PubKey) []byte {
|
|||
return append(ValidatorsBondedKey, addr.Bytes()...)
|
||||
}
|
||||
|
||||
// get the key for delegator bond with candidate
|
||||
func GetDelegationKey(delegatorAddr, candidateAddr sdk.Address, cdc *wire.Codec) []byte {
|
||||
return append(GetDelegationsKey(delegatorAddr, cdc), candidateAddr.Bytes()...)
|
||||
// get the key for delegator bond with validator
|
||||
func GetDelegationKey(delegatorAddr, validatorAddr sdk.Address, cdc *wire.Codec) []byte {
|
||||
return append(GetDelegationsKey(delegatorAddr, cdc), validatorAddr.Bytes()...)
|
||||
}
|
||||
|
||||
// get the prefix for a delegator for all candidates
|
||||
// get the prefix for a delegator for all validators
|
||||
func GetDelegationsKey(delegatorAddr sdk.Address, cdc *wire.Codec) []byte {
|
||||
res, err := cdc.MarshalBinary(&delegatorAddr)
|
||||
if err != nil {
|
||||
|
|
|
@ -23,61 +23,61 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
// This function tests GetCandidate, GetCandidates, setCandidate, removeCandidate
|
||||
func TestCandidate(t *testing.T) {
|
||||
// This function tests GetValidator, GetValidators, setValidator, removeValidator
|
||||
func TestValidator(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
//construct the candidates
|
||||
var candidates [3]Candidate
|
||||
//construct the validators
|
||||
var validators [3]Validator
|
||||
amts := []int64{9, 8, 7}
|
||||
for i, amt := range amts {
|
||||
candidates[i] = NewCandidate(addrVals[i], pks[i], Description{})
|
||||
candidates[i].BondedShares = sdk.NewRat(amt)
|
||||
candidates[i].DelegatorShares = sdk.NewRat(amt)
|
||||
validators[i] = NewValidator(addrVals[i], pks[i], Description{})
|
||||
validators[i].BondedShares = sdk.NewRat(amt)
|
||||
validators[i].DelegatorShares = sdk.NewRat(amt)
|
||||
}
|
||||
|
||||
// check the empty keeper first
|
||||
_, found := keeper.GetCandidate(ctx, addrVals[0])
|
||||
_, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
assert.False(t, found)
|
||||
resCands := keeper.GetCandidates(ctx, 100)
|
||||
resCands := keeper.GetValidators(ctx, 100)
|
||||
assert.Zero(t, len(resCands))
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
resCand, found := keeper.GetCandidate(ctx, addrVals[0])
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
resCand, found := keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(t, found)
|
||||
assert.True(t, candidates[0].equal(resCand), "%v \n %v", resCand, candidates[0])
|
||||
assert.True(t, validators[0].equal(resCand), "%v \n %v", resCand, validators[0])
|
||||
|
||||
// modify a records, save, and retrieve
|
||||
candidates[0].DelegatorShares = sdk.NewRat(99)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
resCand, found = keeper.GetCandidate(ctx, addrVals[0])
|
||||
validators[0].DelegatorShares = sdk.NewRat(99)
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
resCand, found = keeper.GetValidator(ctx, addrVals[0])
|
||||
require.True(t, found)
|
||||
assert.True(t, candidates[0].equal(resCand))
|
||||
assert.True(t, validators[0].equal(resCand))
|
||||
|
||||
// also test that the address has been added to address list
|
||||
resCands = keeper.GetCandidates(ctx, 100)
|
||||
resCands = keeper.GetValidators(ctx, 100)
|
||||
require.Equal(t, 1, len(resCands))
|
||||
assert.Equal(t, addrVals[0], resCands[0].Address)
|
||||
|
||||
// add other candidates
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
keeper.setCandidate(ctx, candidates[2])
|
||||
resCand, found = keeper.GetCandidate(ctx, addrVals[1])
|
||||
// add other validators
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
keeper.setValidator(ctx, validators[2])
|
||||
resCand, found = keeper.GetValidator(ctx, addrVals[1])
|
||||
require.True(t, found)
|
||||
assert.True(t, candidates[1].equal(resCand), "%v \n %v", resCand, candidates[1])
|
||||
resCand, found = keeper.GetCandidate(ctx, addrVals[2])
|
||||
assert.True(t, validators[1].equal(resCand), "%v \n %v", resCand, validators[1])
|
||||
resCand, found = keeper.GetValidator(ctx, addrVals[2])
|
||||
require.True(t, found)
|
||||
assert.True(t, candidates[2].equal(resCand), "%v \n %v", resCand, candidates[2])
|
||||
resCands = keeper.GetCandidates(ctx, 100)
|
||||
assert.True(t, validators[2].equal(resCand), "%v \n %v", resCand, validators[2])
|
||||
resCands = keeper.GetValidators(ctx, 100)
|
||||
require.Equal(t, 3, len(resCands))
|
||||
assert.True(t, candidates[0].equal(resCands[0]), "%v \n %v", resCands[0], candidates[0])
|
||||
assert.True(t, candidates[1].equal(resCands[1]), "%v \n %v", resCands[1], candidates[1])
|
||||
assert.True(t, candidates[2].equal(resCands[2]), "%v \n %v", resCands[2], candidates[2])
|
||||
assert.True(t, validators[0].equal(resCands[0]), "%v \n %v", resCands[0], validators[0])
|
||||
assert.True(t, validators[1].equal(resCands[1]), "%v \n %v", resCands[1], validators[1])
|
||||
assert.True(t, validators[2].equal(resCands[2]), "%v \n %v", resCands[2], validators[2])
|
||||
|
||||
// remove a record
|
||||
keeper.removeCandidate(ctx, candidates[1].Address)
|
||||
_, found = keeper.GetCandidate(ctx, addrVals[1])
|
||||
keeper.removeValidator(ctx, validators[1].Address)
|
||||
_, found = keeper.GetValidator(ctx, addrVals[1])
|
||||
assert.False(t, found)
|
||||
}
|
||||
|
||||
|
@ -85,21 +85,21 @@ func TestCandidate(t *testing.T) {
|
|||
func TestBond(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
//construct the candidates
|
||||
//construct the validators
|
||||
amts := []int64{9, 8, 7}
|
||||
var candidates [3]Candidate
|
||||
var validators [3]Validator
|
||||
for i, amt := range amts {
|
||||
candidates[i] = NewCandidate(addrVals[i], pks[i], Description{})
|
||||
candidates[i].BondedShares = sdk.NewRat(amt)
|
||||
candidates[i].DelegatorShares = sdk.NewRat(amt)
|
||||
validators[i] = NewValidator(addrVals[i], pks[i], Description{})
|
||||
validators[i].BondedShares = sdk.NewRat(amt)
|
||||
validators[i].DelegatorShares = sdk.NewRat(amt)
|
||||
}
|
||||
|
||||
// first add a candidates[0] to delegate too
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
// first add a validators[0] to delegate too
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
|
||||
bond1to1 := Delegation{
|
||||
DelegatorAddr: addrDels[0],
|
||||
CandidateAddr: addrVals[0],
|
||||
ValidatorAddr: addrVals[0],
|
||||
Shares: sdk.NewRat(9),
|
||||
}
|
||||
|
||||
|
@ -121,8 +121,8 @@ func TestBond(t *testing.T) {
|
|||
assert.True(t, bond1to1.equal(resBond))
|
||||
|
||||
// add some more records
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
keeper.setCandidate(ctx, candidates[2])
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
keeper.setValidator(ctx, validators[2])
|
||||
bond1to2 := Delegation{addrDels[0], addrVals[1], sdk.NewRat(9), 0}
|
||||
bond1to3 := Delegation{addrDels[0], addrVals[2], sdk.NewRat(9), 1}
|
||||
bond2to1 := Delegation{addrDels[1], addrVals[0], sdk.NewRat(9), 2}
|
||||
|
@ -182,15 +182,15 @@ func TestBond(t *testing.T) {
|
|||
func TestGetValidatorsBonded(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
// initialize some candidates into the state
|
||||
// initialize some validators into the state
|
||||
amts := []int64{0, 100, 1, 400, 200}
|
||||
n := len(amts)
|
||||
var candidates [5]Candidate
|
||||
var validators [5]Validator
|
||||
for i, amt := range amts {
|
||||
candidates[i] = NewCandidate(addrs[i], pks[i], Description{})
|
||||
candidates[i].BondedShares = sdk.NewRat(amt)
|
||||
candidates[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setCandidate(ctx, candidates[i])
|
||||
validators[i] = NewValidator(addrs[i], pks[i], Description{})
|
||||
validators[i].BondedShares = sdk.NewRat(amt)
|
||||
validators[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setValidator(ctx, validators[i])
|
||||
}
|
||||
|
||||
// first make sure everything made it in to the validator group
|
||||
|
@ -201,64 +201,64 @@ func TestGetValidatorsBonded(t *testing.T) {
|
|||
assert.Equal(t, sdk.NewRat(100), validators[2].Power, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(1), validators[3].Power, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(0), validators[4].Power, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[1].Address, validators[2].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[2].Address, validators[3].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[0].Address, validators[4].Address, "%v", validators)
|
||||
assert.Equal(t, validators[3].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, validators[4].Address, validators[1].Address, "%v", validators)
|
||||
assert.Equal(t, validators[1].Address, validators[2].Address, "%v", validators)
|
||||
assert.Equal(t, validators[2].Address, validators[3].Address, "%v", validators)
|
||||
assert.Equal(t, validators[0].Address, validators[4].Address, "%v", validators)
|
||||
|
||||
// test a basic increase in voting power
|
||||
candidates[3].BondedShares = sdk.NewRat(500)
|
||||
keeper.setCandidate(ctx, candidates[3])
|
||||
validators[3].BondedShares = sdk.NewRat(500)
|
||||
keeper.setValidator(ctx, validators[3])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(500), validators[0].Power, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, validators[3].Address, validators[0].Address, "%v", validators)
|
||||
|
||||
// test a decrease in voting power
|
||||
candidates[3].BondedShares = sdk.NewRat(300)
|
||||
keeper.setCandidate(ctx, candidates[3])
|
||||
validators[3].BondedShares = sdk.NewRat(300)
|
||||
keeper.setValidator(ctx, validators[3])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(300), validators[0].Power, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, validators[3].Address, validators[0].Address, "%v", validators)
|
||||
|
||||
// XXX FIX TEST
|
||||
// test equal voting power, different age
|
||||
candidates[3].BondedShares = sdk.NewRat(200)
|
||||
validators[3].BondedShares = sdk.NewRat(200)
|
||||
ctx = ctx.WithBlockHeight(10)
|
||||
keeper.setCandidate(ctx, candidates[3])
|
||||
keeper.setValidator(ctx, validators[3])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
//assert.Equal(t, sdk.NewRat(200), validators[0].Power, "%v", validators)
|
||||
//assert.Equal(t, sdk.NewRat(200), validators[1].Power, "%v", validators)
|
||||
//assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
//assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators)
|
||||
//assert.Equal(t, validators[3].Address, validators[0].Address, "%v", validators)
|
||||
//assert.Equal(t, validators[4].Address, validators[1].Address, "%v", validators)
|
||||
//assert.Equal(t, int64(0), validators[0].Height, "%v", validators)
|
||||
//assert.Equal(t, int64(0), validators[1].Height, "%v", validators)
|
||||
|
||||
// XXX FIX TEST
|
||||
// no change in voting power - no change in sort
|
||||
ctx = ctx.WithBlockHeight(20)
|
||||
keeper.setCandidate(ctx, candidates[4])
|
||||
keeper.setValidator(ctx, validators[4])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
//assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
//assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators)
|
||||
//assert.Equal(t, validators[3].Address, validators[0].Address, "%v", validators)
|
||||
//assert.Equal(t, validators[4].Address, validators[1].Address, "%v", validators)
|
||||
|
||||
// XXX FIX TEST
|
||||
// change in voting power of both candidates, both still in v-set, no age change
|
||||
candidates[3].BondedShares = sdk.NewRat(300)
|
||||
candidates[4].BondedShares = sdk.NewRat(300)
|
||||
keeper.setCandidate(ctx, candidates[3])
|
||||
// change in voting power of both validators, both still in v-set, no age change
|
||||
validators[3].BondedShares = sdk.NewRat(300)
|
||||
validators[4].BondedShares = sdk.NewRat(300)
|
||||
keeper.setValidator(ctx, validators[3])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
ctx = ctx.WithBlockHeight(30)
|
||||
keeper.setCandidate(ctx, candidates[4])
|
||||
keeper.setValidator(ctx, validators[4])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n, "%v", validators)
|
||||
//assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
//assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators)
|
||||
//assert.Equal(t, validators[3].Address, validators[0].Address, "%v", validators)
|
||||
//assert.Equal(t, validators[4].Address, validators[1].Address, "%v", validators)
|
||||
|
||||
}
|
||||
|
||||
|
@ -272,101 +272,101 @@ func TestGetValidatorsBondedEdgeCases(t *testing.T) {
|
|||
params.MaxValidators = 2
|
||||
keeper.setParams(ctx, params)
|
||||
|
||||
// initialize some candidates into the state
|
||||
// initialize some validators into the state
|
||||
amts := []int64{0, 100, 1, 400, 200}
|
||||
n := len(amts)
|
||||
var candidates [5]Candidate
|
||||
var validators [5]Validator
|
||||
for i, amt := range amts {
|
||||
candidates[i] = NewCandidate(addrs[i], pks[i], Description{})
|
||||
candidates[i].BondedShares = sdk.NewRat(amt)
|
||||
candidates[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setCandidate(ctx, candidates[i])
|
||||
validators[i] = NewValidator(addrs[i], pks[i], Description{})
|
||||
validators[i].BondedShares = sdk.NewRat(amt)
|
||||
validators[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setValidator(ctx, validators[i])
|
||||
}
|
||||
|
||||
candidates[0].BondedShares = sdk.NewRat(500)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
validators[0].BondedShares = sdk.NewRat(500)
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
validators := keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, uint16(len(validators)), params.MaxValidators)
|
||||
require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
// candidate 3 was set before candidate 4
|
||||
require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators)
|
||||
require.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
// validator 3 was set before validator 4
|
||||
require.Equal(t, validators[3].Address, validators[1].Address, "%v", validators)
|
||||
|
||||
//A candidate which leaves the validator set due to a decrease in voting power,
|
||||
//A validator which leaves the validator set due to a decrease in voting power,
|
||||
//then increases to the original voting power, does not get its spot back in the
|
||||
//case of a tie.
|
||||
|
||||
//ref https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-380757108
|
||||
candidates[4].BondedShares = sdk.NewRat(301)
|
||||
keeper.setCandidate(ctx, candidates[4])
|
||||
validators[4].BondedShares = sdk.NewRat(301)
|
||||
keeper.setValidator(ctx, validators[4])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, uint16(len(validators)), params.MaxValidators)
|
||||
require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators)
|
||||
require.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, validators[4].Address, validators[1].Address, "%v", validators)
|
||||
ctx = ctx.WithBlockHeight(40)
|
||||
// candidate 4 kicked out temporarily
|
||||
candidates[4].BondedShares = sdk.NewRat(200)
|
||||
keeper.setCandidate(ctx, candidates[4])
|
||||
// validator 4 kicked out temporarily
|
||||
validators[4].BondedShares = sdk.NewRat(200)
|
||||
keeper.setValidator(ctx, validators[4])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, uint16(len(validators)), params.MaxValidators)
|
||||
require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators)
|
||||
// candidate 4 does not get spot back
|
||||
candidates[4].BondedShares = sdk.NewRat(300)
|
||||
keeper.setCandidate(ctx, candidates[4])
|
||||
require.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, validators[3].Address, validators[1].Address, "%v", validators)
|
||||
// validator 4 does not get spot back
|
||||
validators[4].BondedShares = sdk.NewRat(300)
|
||||
keeper.setValidator(ctx, validators[4])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, uint16(len(validators)), params.MaxValidators)
|
||||
require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators)
|
||||
candidate, exists := keeper.GetCandidate(ctx, candidates[4].Address)
|
||||
require.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, validators[3].Address, validators[1].Address, "%v", validators)
|
||||
validator, exists := keeper.GetValidator(ctx, validators[4].Address)
|
||||
require.Equal(t, exists, true)
|
||||
require.Equal(t, candidate.ValidatorBondHeight, int64(40))
|
||||
require.Equal(t, validator.ValidatorBondHeight, int64(40))
|
||||
|
||||
//If two candidates both increase to the same voting power in the same block,
|
||||
//If two validators both increase to the same voting power in the same block,
|
||||
//the one with the first transaction should take precedence (become a validator).
|
||||
//ref https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-381250392
|
||||
candidates[0].BondedShares = sdk.NewRat(2000)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
candidates[1].BondedShares = sdk.NewRat(1000)
|
||||
candidates[2].BondedShares = sdk.NewRat(1000)
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
keeper.setCandidate(ctx, candidates[2])
|
||||
validators[0].BondedShares = sdk.NewRat(2000)
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
validators[1].BondedShares = sdk.NewRat(1000)
|
||||
validators[2].BondedShares = sdk.NewRat(1000)
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
keeper.setValidator(ctx, validators[2])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, uint16(len(validators)), params.MaxValidators)
|
||||
require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, candidates[1].Address, validators[1].Address, "%v", validators)
|
||||
candidates[1].BondedShares = sdk.NewRat(1100)
|
||||
candidates[2].BondedShares = sdk.NewRat(1100)
|
||||
keeper.setCandidate(ctx, candidates[2])
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
require.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, validators[1].Address, validators[1].Address, "%v", validators)
|
||||
validators[1].BondedShares = sdk.NewRat(1100)
|
||||
validators[2].BondedShares = sdk.NewRat(1100)
|
||||
keeper.setValidator(ctx, validators[2])
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, uint16(len(validators)), params.MaxValidators)
|
||||
require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, candidates[2].Address, validators[1].Address, "%v", validators)
|
||||
require.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
require.Equal(t, validators[2].Address, validators[1].Address, "%v", validators)
|
||||
|
||||
// reset assets / heights
|
||||
params.MaxValidators = 100
|
||||
keeper.setParams(ctx, params)
|
||||
candidates[0].BondedShares = sdk.NewRat(0)
|
||||
candidates[1].BondedShares = sdk.NewRat(100)
|
||||
candidates[2].BondedShares = sdk.NewRat(1)
|
||||
candidates[3].BondedShares = sdk.NewRat(300)
|
||||
candidates[4].BondedShares = sdk.NewRat(200)
|
||||
validators[0].BondedShares = sdk.NewRat(0)
|
||||
validators[1].BondedShares = sdk.NewRat(100)
|
||||
validators[2].BondedShares = sdk.NewRat(1)
|
||||
validators[3].BondedShares = sdk.NewRat(300)
|
||||
validators[4].BondedShares = sdk.NewRat(200)
|
||||
ctx = ctx.WithBlockHeight(0)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
keeper.setCandidate(ctx, candidates[2])
|
||||
keeper.setCandidate(ctx, candidates[3])
|
||||
keeper.setCandidate(ctx, candidates[4])
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
keeper.setValidator(ctx, validators[2])
|
||||
keeper.setValidator(ctx, validators[3])
|
||||
keeper.setValidator(ctx, validators[4])
|
||||
|
||||
// test a swap in voting power
|
||||
candidates[0].BondedShares = sdk.NewRat(600)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
validators[0].BondedShares = sdk.NewRat(600)
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(600), validators[0].Power, "%v", validators)
|
||||
assert.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(300), validators[1].Power, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators)
|
||||
assert.Equal(t, validators[3].Address, validators[1].Address, "%v", validators)
|
||||
|
||||
// test the max validators term
|
||||
params = keeper.GetParams(ctx)
|
||||
|
@ -376,9 +376,9 @@ func TestGetValidatorsBondedEdgeCases(t *testing.T) {
|
|||
validators = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(600), validators[0].Power, "%v", validators)
|
||||
assert.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, validators[0].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(300), validators[1].Power, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators)
|
||||
assert.Equal(t, validators[3].Address, validators[1].Address, "%v", validators)
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -387,12 +387,12 @@ func TestClearValidatorsTendermintUpdates(t *testing.T) {
|
|||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
amts := []int64{100, 400, 200}
|
||||
candidates := make([]Candidate, len(amts))
|
||||
validators := make([]Validator, len(amts))
|
||||
for i, amt := range amts {
|
||||
candidates[i] = NewCandidate(addrs[i], pks[i], Description{})
|
||||
candidates[i].BondedShares = sdk.NewRat(amt)
|
||||
candidates[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setCandidate(ctx, candidates[i])
|
||||
validators[i] = NewValidator(addrs[i], pks[i], Description{})
|
||||
validators[i].BondedShares = sdk.NewRat(amt)
|
||||
validators[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setValidator(ctx, validators[i])
|
||||
}
|
||||
|
||||
acc := keeper.getValidatorsTendermintUpdates(ctx)
|
||||
|
@ -409,202 +409,202 @@ func TestGetValidatorsTendermintUpdates(t *testing.T) {
|
|||
params.MaxValidators = 4
|
||||
keeper.setParams(ctx, params)
|
||||
|
||||
// TODO eliminate use of candidatesIn here
|
||||
// TODO eliminate use of validatorsIn here
|
||||
// tests could be clearer if they just
|
||||
// created the candidate at time of use
|
||||
// created the validator at time of use
|
||||
// and were labelled by power in the comments
|
||||
// outlining in each test
|
||||
amts := []int64{10, 11, 12, 13, 1}
|
||||
var candidatesIn [5]Candidate
|
||||
var validatorsIn [5]Validator
|
||||
for i, amt := range amts {
|
||||
candidatesIn[i] = NewCandidate(addrs[i], pks[i], Description{})
|
||||
candidatesIn[i].BondedShares = sdk.NewRat(amt)
|
||||
candidatesIn[i].DelegatorShares = sdk.NewRat(amt)
|
||||
validatorsIn[i] = NewValidator(addrs[i], pks[i], Description{})
|
||||
validatorsIn[i].BondedShares = sdk.NewRat(amt)
|
||||
validatorsIn[i].DelegatorShares = sdk.NewRat(amt)
|
||||
}
|
||||
|
||||
// test from nothing to something
|
||||
// candidate set: {} -> {c1, c3}
|
||||
// validator set: {} -> {c1, c3}
|
||||
// validator set: {} -> {c1, c3}
|
||||
// accUpdate set: {} -> {c1, c3}
|
||||
assert.Equal(t, 0, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.GetValidatorsBonded(ctx)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
keeper.setCandidate(ctx, candidatesIn[1])
|
||||
keeper.setCandidate(ctx, candidatesIn[3])
|
||||
keeper.setValidator(ctx, validatorsIn[1])
|
||||
keeper.setValidator(ctx, validatorsIn[3])
|
||||
|
||||
vals := keeper.GetValidatorsBondedByPower(ctx) // to init recent validator set
|
||||
require.Equal(t, 2, len(vals))
|
||||
acc := keeper.getValidatorsTendermintUpdates(ctx)
|
||||
require.Equal(t, 2, len(acc))
|
||||
candidates := keeper.GetCandidates(ctx, 5)
|
||||
require.Equal(t, 2, len(candidates))
|
||||
assert.Equal(t, candidates[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
assert.Equal(t, candidates[1].validator().abciValidator(keeper.cdc), acc[1])
|
||||
assert.True(t, candidates[0].validator().equal(vals[1]))
|
||||
assert.True(t, candidates[1].validator().equal(vals[0]))
|
||||
validators := keeper.GetValidators(ctx, 5)
|
||||
require.Equal(t, 2, len(validators))
|
||||
assert.Equal(t, validators[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
assert.Equal(t, validators[1].validator().abciValidator(keeper.cdc), acc[1])
|
||||
assert.True(t, validators[0].validator().equal(vals[1]))
|
||||
assert.True(t, validators[1].validator().equal(vals[0]))
|
||||
|
||||
// test identical,
|
||||
// candidate set: {c1, c3} -> {c1, c3}
|
||||
// validator set: {c1, c3} -> {c1, c3}
|
||||
// accUpdate set: {} -> {}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 2, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 2, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
|
||||
require.Equal(t, 2, len(keeper.GetCandidates(ctx, 5)))
|
||||
require.Equal(t, 2, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
// test single value change
|
||||
// candidate set: {c1, c3} -> {c1', c3}
|
||||
// validator set: {c1, c3} -> {c1', c3}
|
||||
// accUpdate set: {} -> {c1'}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 2, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 2, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
candidates[0].BondedShares = sdk.NewRat(600)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
validators[0].BondedShares = sdk.NewRat(600)
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
|
||||
candidates = keeper.GetCandidates(ctx, 5)
|
||||
require.Equal(t, 2, len(candidates))
|
||||
assert.True(t, candidates[0].BondedShares.Equal(sdk.NewRat(600)))
|
||||
validators = keeper.GetValidators(ctx, 5)
|
||||
require.Equal(t, 2, len(validators))
|
||||
assert.True(t, validators[0].BondedShares.Equal(sdk.NewRat(600)))
|
||||
acc = keeper.getValidatorsTendermintUpdates(ctx)
|
||||
require.Equal(t, 1, len(acc))
|
||||
assert.Equal(t, candidates[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
assert.Equal(t, validators[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
|
||||
// test multiple value change
|
||||
// candidate set: {c1, c3} -> {c1', c3'}
|
||||
// validator set: {c1, c3} -> {c1', c3'}
|
||||
// accUpdate set: {c1, c3} -> {c1', c3'}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 2, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 2, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
candidates[0].BondedShares = sdk.NewRat(200)
|
||||
candidates[1].BondedShares = sdk.NewRat(100)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
validators[0].BondedShares = sdk.NewRat(200)
|
||||
validators[1].BondedShares = sdk.NewRat(100)
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
|
||||
acc = keeper.getValidatorsTendermintUpdates(ctx)
|
||||
require.Equal(t, 2, len(acc))
|
||||
candidates = keeper.GetCandidates(ctx, 5)
|
||||
require.Equal(t, 2, len(candidates))
|
||||
require.Equal(t, candidates[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
require.Equal(t, candidates[1].validator().abciValidator(keeper.cdc), acc[1])
|
||||
validators = keeper.GetValidators(ctx, 5)
|
||||
require.Equal(t, 2, len(validators))
|
||||
require.Equal(t, validators[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
require.Equal(t, validators[1].validator().abciValidator(keeper.cdc), acc[1])
|
||||
|
||||
// test validtor added at the beginning
|
||||
// candidate set: {c1, c3} -> {c0, c1, c3}
|
||||
// validator set: {c1, c3} -> {c0, c1, c3}
|
||||
// accUpdate set: {} -> {c0}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 2, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 2, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
keeper.setCandidate(ctx, candidatesIn[0])
|
||||
keeper.setValidator(ctx, validatorsIn[0])
|
||||
acc = keeper.getValidatorsTendermintUpdates(ctx)
|
||||
require.Equal(t, 1, len(acc))
|
||||
candidates = keeper.GetCandidates(ctx, 5)
|
||||
require.Equal(t, 3, len(candidates))
|
||||
assert.Equal(t, candidates[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
validators = keeper.GetValidators(ctx, 5)
|
||||
require.Equal(t, 3, len(validators))
|
||||
assert.Equal(t, validators[0].validator().abciValidator(keeper.cdc), acc[0])
|
||||
|
||||
// test validator added at the middle
|
||||
// candidate set: {c0, c1, c3} -> {c0, c1, c2, c3]
|
||||
// validator set: {c0, c1, c3} -> {c0, c1, c2, c3}
|
||||
// accUpdate set: {} -> {c2}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 3, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 3, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
keeper.setCandidate(ctx, candidatesIn[2])
|
||||
keeper.setValidator(ctx, validatorsIn[2])
|
||||
acc = keeper.getValidatorsTendermintUpdates(ctx)
|
||||
require.Equal(t, 1, len(acc))
|
||||
candidates = keeper.GetCandidates(ctx, 5)
|
||||
require.Equal(t, 4, len(candidates))
|
||||
assert.Equal(t, candidates[2].validator().abciValidator(keeper.cdc), acc[0])
|
||||
validators = keeper.GetValidators(ctx, 5)
|
||||
require.Equal(t, 4, len(validators))
|
||||
assert.Equal(t, validators[2].validator().abciValidator(keeper.cdc), acc[0])
|
||||
|
||||
// test candidate added at the end but not inserted in the valset
|
||||
// candidate set: {c0, c1, c2, c3} -> {c0, c1, c2, c3, c4}
|
||||
// test validator added at the end but not inserted in the valset
|
||||
// validator set: {c0, c1, c2, c3} -> {c0, c1, c2, c3, c4}
|
||||
// validator set: {c0, c1, c2, c3} -> {c0, c1, c2, c3}
|
||||
// accUpdate set: {} -> {}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 4, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 4, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 4, len(keeper.GetValidatorsBonded(ctx)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
keeper.setCandidate(ctx, candidatesIn[4])
|
||||
keeper.setValidator(ctx, validatorsIn[4])
|
||||
|
||||
assert.Equal(t, 5, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 5, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 4, len(keeper.GetValidatorsBonded(ctx)))
|
||||
require.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx))) // max validator number is 4
|
||||
|
||||
// test candidate change its power but still not in the valset
|
||||
// candidate set: {c0, c1, c2, c3, c4} -> {c0, c1, c2, c3, c4}
|
||||
// test validator change its power but still not in the valset
|
||||
// validator set: {c0, c1, c2, c3, c4} -> {c0, c1, c2, c3, c4}
|
||||
// validator set: {c0, c1, c2, c3} -> {c0, c1, c2, c3}
|
||||
// accUpdate set: {} -> {}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 5, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 5, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 4, len(keeper.GetValidatorsBonded(ctx)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
candidatesIn[4].BondedShares = sdk.NewRat(1)
|
||||
keeper.setCandidate(ctx, candidatesIn[4])
|
||||
validatorsIn[4].BondedShares = sdk.NewRat(1)
|
||||
keeper.setValidator(ctx, validatorsIn[4])
|
||||
|
||||
assert.Equal(t, 5, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 5, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 4, len(keeper.GetValidatorsBonded(ctx)))
|
||||
require.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx))) // max validator number is 4
|
||||
|
||||
// test candidate change its power and become a validator (pushing out an existing)
|
||||
// candidate set: {c0, c1, c2, c3, c4} -> {c0, c1, c2, c3, c4}
|
||||
// test validator change its power and become a validator (pushing out an existing)
|
||||
// validator set: {c0, c1, c2, c3, c4} -> {c0, c1, c2, c3, c4}
|
||||
// validator set: {c0, c1, c2, c3} -> {c1, c2, c3, c4}
|
||||
// accUpdate set: {} -> {c0, c4}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 5, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 5, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 4, len(keeper.GetValidatorsBonded(ctx)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
candidatesIn[4].BondedShares = sdk.NewRat(1000)
|
||||
keeper.setCandidate(ctx, candidatesIn[4])
|
||||
validatorsIn[4].BondedShares = sdk.NewRat(1000)
|
||||
keeper.setValidator(ctx, validatorsIn[4])
|
||||
|
||||
candidates = keeper.GetCandidates(ctx, 5)
|
||||
require.Equal(t, 5, len(candidates))
|
||||
validators = keeper.GetValidators(ctx, 5)
|
||||
require.Equal(t, 5, len(validators))
|
||||
vals = keeper.GetValidatorsBondedByPower(ctx)
|
||||
require.Equal(t, 4, len(vals))
|
||||
assert.Equal(t, candidatesIn[1].Address, vals[1].Address)
|
||||
assert.Equal(t, candidatesIn[2].Address, vals[3].Address)
|
||||
assert.Equal(t, candidatesIn[3].Address, vals[2].Address)
|
||||
assert.Equal(t, candidatesIn[4].Address, vals[0].Address)
|
||||
assert.Equal(t, validatorsIn[1].Address, vals[1].Address)
|
||||
assert.Equal(t, validatorsIn[2].Address, vals[3].Address)
|
||||
assert.Equal(t, validatorsIn[3].Address, vals[2].Address)
|
||||
assert.Equal(t, validatorsIn[4].Address, vals[0].Address)
|
||||
|
||||
acc = keeper.getValidatorsTendermintUpdates(ctx)
|
||||
require.Equal(t, 2, len(acc), "%v", acc)
|
||||
|
||||
assert.Equal(t, candidatesIn[0].PubKey.Bytes(), acc[0].PubKey)
|
||||
assert.Equal(t, validatorsIn[0].PubKey.Bytes(), acc[0].PubKey)
|
||||
assert.Equal(t, int64(0), acc[0].Power)
|
||||
assert.Equal(t, vals[0].abciValidator(keeper.cdc), acc[1])
|
||||
|
||||
// test from something to nothing
|
||||
// candidate set: {c0, c1, c2, c3, c4} -> {}
|
||||
// validator set: {c0, c1, c2, c3, c4} -> {}
|
||||
// validator set: {c1, c2, c3, c4} -> {}
|
||||
// accUpdate set: {} -> {c1, c2, c3, c4}
|
||||
keeper.clearValidatorsTendermintUpdates(ctx)
|
||||
assert.Equal(t, 5, len(keeper.GetCandidates(ctx, 5)))
|
||||
assert.Equal(t, 5, len(keeper.GetValidators(ctx, 5)))
|
||||
assert.Equal(t, 4, len(keeper.GetValidatorsBonded(ctx)))
|
||||
assert.Equal(t, 0, len(keeper.getValidatorsTendermintUpdates(ctx)))
|
||||
|
||||
keeper.removeCandidate(ctx, candidatesIn[0].Address)
|
||||
keeper.removeCandidate(ctx, candidatesIn[1].Address)
|
||||
keeper.removeCandidate(ctx, candidatesIn[2].Address)
|
||||
keeper.removeCandidate(ctx, candidatesIn[3].Address)
|
||||
keeper.removeCandidate(ctx, candidatesIn[4].Address)
|
||||
keeper.removeValidator(ctx, validatorsIn[0].Address)
|
||||
keeper.removeValidator(ctx, validatorsIn[1].Address)
|
||||
keeper.removeValidator(ctx, validatorsIn[2].Address)
|
||||
keeper.removeValidator(ctx, validatorsIn[3].Address)
|
||||
keeper.removeValidator(ctx, validatorsIn[4].Address)
|
||||
|
||||
vals = keeper.GetValidatorsBondedByPower(ctx)
|
||||
assert.Equal(t, 0, len(vals), "%v", vals)
|
||||
candidates = keeper.GetCandidates(ctx, 5)
|
||||
require.Equal(t, 0, len(candidates))
|
||||
validators = keeper.GetValidators(ctx, 5)
|
||||
require.Equal(t, 0, len(validators))
|
||||
acc = keeper.getValidatorsTendermintUpdates(ctx)
|
||||
require.Equal(t, 4, len(acc))
|
||||
assert.Equal(t, candidatesIn[1].PubKey.Bytes(), acc[0].PubKey)
|
||||
assert.Equal(t, candidatesIn[2].PubKey.Bytes(), acc[1].PubKey)
|
||||
assert.Equal(t, candidatesIn[3].PubKey.Bytes(), acc[2].PubKey)
|
||||
assert.Equal(t, candidatesIn[4].PubKey.Bytes(), acc[3].PubKey)
|
||||
assert.Equal(t, validatorsIn[1].PubKey.Bytes(), acc[0].PubKey)
|
||||
assert.Equal(t, validatorsIn[2].PubKey.Bytes(), acc[1].PubKey)
|
||||
assert.Equal(t, validatorsIn[3].PubKey.Bytes(), acc[2].PubKey)
|
||||
assert.Equal(t, validatorsIn[4].PubKey.Bytes(), acc[3].PubKey)
|
||||
assert.Equal(t, int64(0), acc[0].Power)
|
||||
assert.Equal(t, int64(0), acc[1].Power)
|
||||
assert.Equal(t, int64(0), acc[2].Power)
|
||||
|
@ -616,12 +616,12 @@ func TestGetTotalPrecommitVotingPower(t *testing.T) {
|
|||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
amts := []int64{10000, 1000, 100, 10, 1}
|
||||
var candidatesIn [5]Candidate
|
||||
var validatorsIn [5]Validator
|
||||
for i, amt := range amts {
|
||||
candidatesIn[i] = NewCandidate(addrVals[i], pks[i], Description{})
|
||||
candidatesIn[i].BondedShares = sdk.NewRat(amt)
|
||||
candidatesIn[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setCandidate(ctx, candidatesIn[i])
|
||||
validatorsIn[i] = NewValidator(addrVals[i], pks[i], Description{})
|
||||
validatorsIn[i].BondedShares = sdk.NewRat(amt)
|
||||
validatorsIn[i].DelegatorShares = sdk.NewRat(amt)
|
||||
keeper.setValidator(ctx, validatorsIn[i])
|
||||
}
|
||||
|
||||
// test that an empty validator set doesn't have any validators
|
||||
|
@ -676,7 +676,7 @@ func TestValidatorsetKeeper(t *testing.T) {
|
|||
|
||||
total := int64(0)
|
||||
amts := []int64{9, 8, 7}
|
||||
var candidates [3]Candidate
|
||||
var validators [3]Validator
|
||||
for i, amt := range amts {
|
||||
candidates[i] = Candidate{
|
||||
Address: addrVals[i],
|
||||
|
@ -685,7 +685,7 @@ func TestValidatorsetKeeper(t *testing.T) {
|
|||
Liabilities: sdk.NewRat(amt),
|
||||
}
|
||||
|
||||
keeper.setCandidate(ctx, candidates[i])
|
||||
keeper.setValidator(ctx, validators[i])
|
||||
|
||||
total += amt
|
||||
}
|
||||
|
|
|
@ -31,16 +31,16 @@ func init() {
|
|||
// MsgDeclareCandidacy - struct for unbonding transactions
|
||||
type MsgDeclareCandidacy struct {
|
||||
Description
|
||||
CandidateAddr sdk.Address `json:"address"`
|
||||
ValidatorAddr sdk.Address `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pubkey"`
|
||||
Bond sdk.Coin `json:"bond"`
|
||||
}
|
||||
|
||||
func NewMsgDeclareCandidacy(candidateAddr sdk.Address, pubkey crypto.PubKey,
|
||||
func NewMsgDeclareCandidacy(validatorAddr sdk.Address, pubkey crypto.PubKey,
|
||||
bond sdk.Coin, description Description) MsgDeclareCandidacy {
|
||||
return MsgDeclareCandidacy{
|
||||
Description: description,
|
||||
CandidateAddr: candidateAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
PubKey: pubkey,
|
||||
Bond: bond,
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func NewMsgDeclareCandidacy(candidateAddr sdk.Address, pubkey crypto.PubKey,
|
|||
|
||||
//nolint
|
||||
func (msg MsgDeclareCandidacy) Type() string { return MsgType } //TODO update "stake/declarecandidacy"
|
||||
func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} }
|
||||
func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.ValidatorAddr} }
|
||||
|
||||
// get the bytes for the message signer to sign on
|
||||
func (msg MsgDeclareCandidacy) GetSignBytes() []byte {
|
||||
|
@ -57,8 +57,8 @@ func (msg MsgDeclareCandidacy) GetSignBytes() []byte {
|
|||
|
||||
// quick validity check
|
||||
func (msg MsgDeclareCandidacy) ValidateBasic() sdk.Error {
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrCandidateEmpty(DefaultCodespace)
|
||||
if msg.ValidatorAddr == nil {
|
||||
return ErrValidatorEmpty(DefaultCodespace)
|
||||
}
|
||||
if msg.Bond.Denom != StakingToken {
|
||||
return ErrBadBondingDenom(DefaultCodespace)
|
||||
|
@ -75,22 +75,22 @@ func (msg MsgDeclareCandidacy) ValidateBasic() sdk.Error {
|
|||
|
||||
//______________________________________________________________________
|
||||
|
||||
// MsgEditCandidacy - struct for editing a candidate
|
||||
// MsgEditCandidacy - struct for editing a validator
|
||||
type MsgEditCandidacy struct {
|
||||
Description
|
||||
CandidateAddr sdk.Address `json:"address"`
|
||||
ValidatorAddr sdk.Address `json:"address"`
|
||||
}
|
||||
|
||||
func NewMsgEditCandidacy(candidateAddr sdk.Address, description Description) MsgEditCandidacy {
|
||||
func NewMsgEditCandidacy(validatorAddr sdk.Address, description Description) MsgEditCandidacy {
|
||||
return MsgEditCandidacy{
|
||||
Description: description,
|
||||
CandidateAddr: candidateAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
}
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgEditCandidacy) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy"
|
||||
func (msg MsgEditCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} }
|
||||
func (msg MsgEditCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.ValidatorAddr} }
|
||||
|
||||
// get the bytes for the message signer to sign on
|
||||
func (msg MsgEditCandidacy) GetSignBytes() []byte {
|
||||
|
@ -103,8 +103,8 @@ func (msg MsgEditCandidacy) GetSignBytes() []byte {
|
|||
|
||||
// quick validity check
|
||||
func (msg MsgEditCandidacy) ValidateBasic() sdk.Error {
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrCandidateEmpty(DefaultCodespace)
|
||||
if msg.ValidatorAddr == nil {
|
||||
return ErrValidatorEmpty(DefaultCodespace)
|
||||
}
|
||||
empty := Description{}
|
||||
if msg.Description == empty {
|
||||
|
@ -118,14 +118,14 @@ func (msg MsgEditCandidacy) ValidateBasic() sdk.Error {
|
|||
// MsgDelegate - struct for bonding transactions
|
||||
type MsgDelegate struct {
|
||||
DelegatorAddr sdk.Address `json:"address"`
|
||||
CandidateAddr sdk.Address `json:"address"`
|
||||
ValidatorAddr sdk.Address `json:"address"`
|
||||
Bond sdk.Coin `json:"bond"`
|
||||
}
|
||||
|
||||
func NewMsgDelegate(delegatorAddr, candidateAddr sdk.Address, bond sdk.Coin) MsgDelegate {
|
||||
func NewMsgDelegate(delegatorAddr, validatorAddr sdk.Address, bond sdk.Coin) MsgDelegate {
|
||||
return MsgDelegate{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
CandidateAddr: candidateAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
Bond: bond,
|
||||
}
|
||||
}
|
||||
|
@ -148,8 +148,8 @@ func (msg MsgDelegate) ValidateBasic() sdk.Error {
|
|||
if msg.DelegatorAddr == nil {
|
||||
return ErrBadDelegatorAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrBadCandidateAddr(DefaultCodespace)
|
||||
if msg.ValidatorAddr == nil {
|
||||
return ErrBadValidatorAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.Bond.Denom != StakingToken {
|
||||
return ErrBadBondingDenom(DefaultCodespace)
|
||||
|
@ -165,14 +165,14 @@ func (msg MsgDelegate) ValidateBasic() sdk.Error {
|
|||
// MsgUnbond - struct for unbonding transactions
|
||||
type MsgUnbond struct {
|
||||
DelegatorAddr sdk.Address `json:"address"`
|
||||
CandidateAddr sdk.Address `json:"address"`
|
||||
ValidatorAddr sdk.Address `json:"address"`
|
||||
Shares string `json:"shares"`
|
||||
}
|
||||
|
||||
func NewMsgUnbond(delegatorAddr, candidateAddr sdk.Address, shares string) MsgUnbond {
|
||||
func NewMsgUnbond(delegatorAddr, validatorAddr sdk.Address, shares string) MsgUnbond {
|
||||
return MsgUnbond{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
CandidateAddr: candidateAddr,
|
||||
ValidatorAddr: validatorAddr,
|
||||
Shares: shares,
|
||||
}
|
||||
}
|
||||
|
@ -195,8 +195,8 @@ func (msg MsgUnbond) ValidateBasic() sdk.Error {
|
|||
if msg.DelegatorAddr == nil {
|
||||
return ErrBadDelegatorAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrBadCandidateAddr(DefaultCodespace)
|
||||
if msg.ValidatorAddr == nil {
|
||||
return ErrBadValidatorAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.Shares != "MAX" {
|
||||
rat, err := sdk.NewRatFromDecimal(msg.Shares)
|
||||
|
|
|
@ -22,7 +22,7 @@ var (
|
|||
func TestMsgDeclareCandidacy(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, moniker, identity, website, details string
|
||||
candidateAddr sdk.Address
|
||||
validatorAddr sdk.Address
|
||||
pubkey crypto.PubKey
|
||||
bond sdk.Coin
|
||||
expectPass bool
|
||||
|
@ -40,7 +40,7 @@ func TestMsgDeclareCandidacy(t *testing.T) {
|
|||
|
||||
for _, tc := range tests {
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.details)
|
||||
msg := NewMsgDeclareCandidacy(tc.candidateAddr, tc.pubkey, tc.bond, description)
|
||||
msg := NewMsgDeclareCandidacy(tc.validatorAddr, tc.pubkey, tc.bond, description)
|
||||
if tc.expectPass {
|
||||
assert.Nil(t, msg.ValidateBasic(), "test: %v", tc.name)
|
||||
} else {
|
||||
|
@ -53,7 +53,7 @@ func TestMsgDeclareCandidacy(t *testing.T) {
|
|||
func TestMsgEditCandidacy(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, moniker, identity, website, details string
|
||||
candidateAddr sdk.Address
|
||||
validatorAddr sdk.Address
|
||||
expectPass bool
|
||||
}{
|
||||
{"basic good", "a", "b", "c", "d", addrs[0], true},
|
||||
|
@ -64,7 +64,7 @@ func TestMsgEditCandidacy(t *testing.T) {
|
|||
|
||||
for _, tc := range tests {
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.details)
|
||||
msg := NewMsgEditCandidacy(tc.candidateAddr, description)
|
||||
msg := NewMsgEditCandidacy(tc.validatorAddr, description)
|
||||
if tc.expectPass {
|
||||
assert.Nil(t, msg.ValidateBasic(), "test: %v", tc.name)
|
||||
} else {
|
||||
|
@ -78,21 +78,21 @@ func TestMsgDelegate(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
delegatorAddr sdk.Address
|
||||
candidateAddr sdk.Address
|
||||
validatorAddr sdk.Address
|
||||
bond sdk.Coin
|
||||
expectPass bool
|
||||
}{
|
||||
{"basic good", addrs[0], addrs[1], coinPos, true},
|
||||
{"self bond", addrs[0], addrs[0], coinPos, true},
|
||||
{"empty delegator", emptyAddr, addrs[0], coinPos, false},
|
||||
{"empty candidate", addrs[0], emptyAddr, coinPos, false},
|
||||
{"empty validator", addrs[0], emptyAddr, coinPos, false},
|
||||
{"empty bond", addrs[0], addrs[1], coinZero, false},
|
||||
{"negative bond", addrs[0], addrs[1], coinNeg, false},
|
||||
{"wrong staking token", addrs[0], addrs[1], coinPosNotAtoms, false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
msg := NewMsgDelegate(tc.delegatorAddr, tc.candidateAddr, tc.bond)
|
||||
msg := NewMsgDelegate(tc.delegatorAddr, tc.validatorAddr, tc.bond)
|
||||
if tc.expectPass {
|
||||
assert.Nil(t, msg.ValidateBasic(), "test: %v", tc.name)
|
||||
} else {
|
||||
|
@ -106,7 +106,7 @@ func TestMsgUnbond(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
delegatorAddr sdk.Address
|
||||
candidateAddr sdk.Address
|
||||
validatorAddr sdk.Address
|
||||
shares string
|
||||
expectPass bool
|
||||
}{
|
||||
|
@ -116,11 +116,11 @@ func TestMsgUnbond(t *testing.T) {
|
|||
{"zero unbond", addrs[0], addrs[1], "0.0", false},
|
||||
{"invalid decimal", addrs[0], addrs[0], "sunny", false},
|
||||
{"empty delegator", emptyAddr, addrs[0], "0.1", false},
|
||||
{"empty candidate", addrs[0], emptyAddr, "0.1", false},
|
||||
{"empty validator", addrs[0], emptyAddr, "0.1", false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
msg := NewMsgUnbond(tc.delegatorAddr, tc.candidateAddr, tc.shares)
|
||||
msg := NewMsgUnbond(tc.delegatorAddr, tc.validatorAddr, tc.shares)
|
||||
if tc.expectPass {
|
||||
assert.Nil(t, msg.ValidateBasic(), "test: %v", tc.name)
|
||||
} else {
|
||||
|
|
|
@ -20,7 +20,7 @@ func (p Pool) bondedShareExRate() sdk.Rat {
|
|||
return sdk.NewRat(p.BondedPool).Quo(p.BondedShares)
|
||||
}
|
||||
|
||||
// get the exchange rate of unbonded tokens held in candidates per issued share
|
||||
// get the exchange rate of unbonded tokens held in validators per issued share
|
||||
func (p Pool) unbondedShareExRate() sdk.Rat {
|
||||
if p.UnbondedShares.IsZero() {
|
||||
return sdk.OneRat()
|
||||
|
@ -28,24 +28,24 @@ func (p Pool) unbondedShareExRate() sdk.Rat {
|
|||
return sdk.NewRat(p.UnbondedPool).Quo(p.UnbondedShares)
|
||||
}
|
||||
|
||||
// move a candidates asset pool from bonded to unbonded pool
|
||||
func (p Pool) bondedToUnbondedPool(candidate Candidate) (Pool, Candidate) {
|
||||
// move a validators asset pool from bonded to unbonded pool
|
||||
func (p Pool) bondedToUnbondedPool(validator Validator) (Pool, Validator) {
|
||||
|
||||
// replace bonded shares with unbonded shares
|
||||
p, tokens := p.removeSharesBonded(candidate.BondedShares)
|
||||
p, candidate.BondedShares = p.addTokensUnbonded(tokens)
|
||||
candidate.Status = Unbonded
|
||||
return p, candidate
|
||||
p, tokens := p.removeSharesBonded(validator.BondedShares)
|
||||
p, validator.BondedShares = p.addTokensUnbonded(tokens)
|
||||
validator.Status = Unbonded
|
||||
return p, validator
|
||||
}
|
||||
|
||||
// move a candidates asset pool from unbonded to bonded pool
|
||||
func (p Pool) unbondedToBondedPool(candidate Candidate) (Pool, Candidate) {
|
||||
// move a validators asset pool from unbonded to bonded pool
|
||||
func (p Pool) unbondedToBondedPool(validator Validator) (Pool, Validator) {
|
||||
|
||||
// replace unbonded shares with bonded shares
|
||||
p, tokens := p.removeSharesUnbonded(candidate.BondedShares)
|
||||
p, candidate.BondedShares = p.addTokensBonded(tokens)
|
||||
candidate.Status = Bonded
|
||||
return p, candidate
|
||||
p, tokens := p.removeSharesUnbonded(validator.BondedShares)
|
||||
p, validator.BondedShares = p.addTokensBonded(tokens)
|
||||
validator.Status = Bonded
|
||||
return p, validator
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
@ -80,39 +80,39 @@ func (p Pool) removeSharesUnbonded(shares sdk.Rat) (p2 Pool, removedTokens int64
|
|||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// add tokens to a candidate
|
||||
func (p Pool) candidateAddTokens(candidate Candidate,
|
||||
amount int64) (p2 Pool, candidate2 Candidate, issuedDelegatorShares sdk.Rat) {
|
||||
// add tokens to a validator
|
||||
func (p Pool) validatorAddTokens(validator Validator,
|
||||
amount int64) (p2 Pool, validator2 Validator, issuedDelegatorShares sdk.Rat) {
|
||||
|
||||
exRate := candidate.delegatorShareExRate()
|
||||
exRate := validator.delegatorShareExRate()
|
||||
|
||||
var receivedGlobalShares sdk.Rat
|
||||
if candidate.Status == Bonded {
|
||||
if validator.Status == Bonded {
|
||||
p, receivedGlobalShares = p.addTokensBonded(amount)
|
||||
} else {
|
||||
p, receivedGlobalShares = p.addTokensUnbonded(amount)
|
||||
}
|
||||
candidate.BondedShares = candidate.BondedShares.Add(receivedGlobalShares)
|
||||
validator.BondedShares = validator.BondedShares.Add(receivedGlobalShares)
|
||||
|
||||
issuedDelegatorShares = exRate.Mul(receivedGlobalShares)
|
||||
candidate.DelegatorShares = candidate.DelegatorShares.Add(issuedDelegatorShares)
|
||||
validator.DelegatorShares = validator.DelegatorShares.Add(issuedDelegatorShares)
|
||||
|
||||
return p, candidate, issuedDelegatorShares
|
||||
return p, validator, issuedDelegatorShares
|
||||
}
|
||||
|
||||
// remove shares from a candidate
|
||||
func (p Pool) candidateRemoveShares(candidate Candidate,
|
||||
shares sdk.Rat) (p2 Pool, candidate2 Candidate, createdCoins int64) {
|
||||
// remove shares from a validator
|
||||
func (p Pool) validatorRemoveShares(validator Validator,
|
||||
shares sdk.Rat) (p2 Pool, validator2 Validator, createdCoins int64) {
|
||||
|
||||
//exRate := candidate.delegatorShareExRate() //XXX make sure not used
|
||||
//exRate := validator.delegatorShareExRate() //XXX make sure not used
|
||||
|
||||
globalPoolSharesToRemove := candidate.delegatorShareExRate().Mul(shares)
|
||||
if candidate.Status == Bonded {
|
||||
globalPoolSharesToRemove := validator.delegatorShareExRate().Mul(shares)
|
||||
if validator.Status == Bonded {
|
||||
p, createdCoins = p.removeSharesBonded(globalPoolSharesToRemove)
|
||||
} else {
|
||||
p, createdCoins = p.removeSharesUnbonded(globalPoolSharesToRemove)
|
||||
}
|
||||
candidate.BondedShares = candidate.BondedShares.Sub(globalPoolSharesToRemove)
|
||||
candidate.DelegatorShares = candidate.DelegatorShares.Sub(shares)
|
||||
return p, candidate, createdCoins
|
||||
validator.BondedShares = validator.BondedShares.Sub(globalPoolSharesToRemove)
|
||||
validator.DelegatorShares = validator.DelegatorShares.Sub(shares)
|
||||
return p, validator, createdCoins
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ func TestBondedToUnbondedPool(t *testing.T) {
|
|||
poolA := keeper.GetPool(ctx)
|
||||
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
|
||||
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
|
||||
candA := Candidate{
|
||||
candA := Validator{
|
||||
Status: Bonded,
|
||||
Address: addrs[0],
|
||||
PubKey: pks[0],
|
||||
|
@ -86,7 +86,7 @@ func TestUnbonbedtoBondedPool(t *testing.T) {
|
|||
poolA := keeper.GetPool(ctx)
|
||||
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
|
||||
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
|
||||
candA := Candidate{
|
||||
candA := Validator{
|
||||
Status: Bonded,
|
||||
Address: addrs[0],
|
||||
PubKey: pks[0],
|
||||
|
@ -172,11 +172,11 @@ func TestRemoveSharesUnbonded(t *testing.T) {
|
|||
assert.True(t, poolB.UnbondedShares.Equal(sdk.NewRat(poolB.UnbondedPool)))
|
||||
}
|
||||
|
||||
func TestCandidateAddTokens(t *testing.T) {
|
||||
func TestValidatorAddTokens(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
poolA := keeper.GetPool(ctx)
|
||||
candA := Candidate{
|
||||
candA := Validator{
|
||||
Status: Bonded,
|
||||
Address: addrs[0],
|
||||
PubKey: pks[0],
|
||||
|
@ -188,7 +188,7 @@ func TestCandidateAddTokens(t *testing.T) {
|
|||
assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat())
|
||||
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
|
||||
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
|
||||
poolB, candB, sharesB := poolA.candidateAddTokens(candA, 10)
|
||||
poolB, candB, sharesB := poolA.validatorAddTokens(candA, 10)
|
||||
|
||||
// shares were issued
|
||||
assert.Equal(t, sdk.NewRat(10).Mul(candA.delegatorShareExRate()), sharesB)
|
||||
|
@ -198,11 +198,11 @@ func TestCandidateAddTokens(t *testing.T) {
|
|||
assert.Equal(t, poolB.BondedPool, 10+poolA.BondedPool)
|
||||
}
|
||||
|
||||
func TestCandidateRemoveShares(t *testing.T) {
|
||||
func TestValidatorRemoveShares(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
poolA := keeper.GetPool(ctx)
|
||||
candA := Candidate{
|
||||
candA := Validator{
|
||||
Status: Bonded,
|
||||
Address: addrs[0],
|
||||
PubKey: pks[0],
|
||||
|
@ -214,7 +214,7 @@ func TestCandidateRemoveShares(t *testing.T) {
|
|||
assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat())
|
||||
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
|
||||
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
|
||||
poolB, candB, coinsB := poolA.candidateRemoveShares(candA, sdk.NewRat(10))
|
||||
poolB, candB, coinsB := poolA.validatorRemoveShares(candA, sdk.NewRat(10))
|
||||
|
||||
// coins were created
|
||||
assert.Equal(t, coinsB, int64(10))
|
||||
|
@ -226,7 +226,7 @@ func TestCandidateRemoveShares(t *testing.T) {
|
|||
// specific case from random tests
|
||||
assets := sdk.NewRat(5102)
|
||||
liabilities := sdk.NewRat(115)
|
||||
cand := Candidate{
|
||||
cand := Validator{
|
||||
Status: Bonded,
|
||||
Address: addrs[0],
|
||||
PubKey: pks[0],
|
||||
|
@ -243,10 +243,10 @@ func TestCandidateRemoveShares(t *testing.T) {
|
|||
Inflation: sdk.NewRat(7, 100),
|
||||
}
|
||||
shares := sdk.NewRat(29)
|
||||
msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
msg := fmt.Sprintf("validator %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate())
|
||||
msg = fmt.Sprintf("Removed %v shares from %s", shares, msg)
|
||||
newPool, _, tokens := pool.candidateRemoveShares(cand, shares)
|
||||
newPool, _, tokens := pool.validatorRemoveShares(cand, shares)
|
||||
require.Equal(t,
|
||||
tokens+newPool.UnbondedPool+newPool.BondedPool,
|
||||
pool.BondedPool+pool.UnbondedPool,
|
||||
|
@ -256,9 +256,9 @@ func TestCandidateRemoveShares(t *testing.T) {
|
|||
/////////////////////////////////////
|
||||
// TODO Make all random tests less obfuscated!
|
||||
|
||||
// generate a random candidate
|
||||
func randomCandidate(r *rand.Rand) Candidate {
|
||||
var status CandidateStatus
|
||||
// generate a random validator
|
||||
func randomValidator(r *rand.Rand) Validator {
|
||||
var status ValidatorStatus
|
||||
if r.Float64() < float64(0.5) {
|
||||
status = Bonded
|
||||
} else {
|
||||
|
@ -266,7 +266,7 @@ func randomCandidate(r *rand.Rand) Candidate {
|
|||
}
|
||||
assets := sdk.NewRat(int64(r.Int31n(10000)))
|
||||
liabilities := sdk.NewRat(int64(r.Int31n(10000)))
|
||||
return Candidate{
|
||||
return Validator{
|
||||
Status: status,
|
||||
Address: addrs[0],
|
||||
PubKey: pks[0],
|
||||
|
@ -276,7 +276,7 @@ func randomCandidate(r *rand.Rand) Candidate {
|
|||
}
|
||||
|
||||
// generate a random staking state
|
||||
func randomSetup(r *rand.Rand, numCandidates int) (Pool, Candidates) {
|
||||
func randomSetup(r *rand.Rand, numValidators int) (Pool, Validators) {
|
||||
pool := Pool{
|
||||
TotalSupply: 0,
|
||||
BondedShares: sdk.ZeroRat(),
|
||||
|
@ -287,54 +287,54 @@ func randomSetup(r *rand.Rand, numCandidates int) (Pool, Candidates) {
|
|||
Inflation: sdk.NewRat(7, 100),
|
||||
}
|
||||
|
||||
candidates := make([]Candidate, numCandidates)
|
||||
for i := 0; i < numCandidates; i++ {
|
||||
candidate := randomCandidate(r)
|
||||
if candidate.Status == Bonded {
|
||||
pool.BondedShares = pool.BondedShares.Add(candidate.BondedShares)
|
||||
pool.BondedPool += candidate.BondedShares.Evaluate()
|
||||
} else if candidate.Status == Unbonded {
|
||||
pool.UnbondedShares = pool.UnbondedShares.Add(candidate.BondedShares)
|
||||
pool.UnbondedPool += candidate.BondedShares.Evaluate()
|
||||
validators := make([]Validator, numValidators)
|
||||
for i := 0; i < numValidators; i++ {
|
||||
validator := randomValidator(r)
|
||||
if validator.Status == Bonded {
|
||||
pool.BondedShares = pool.BondedShares.Add(validator.BondedShares)
|
||||
pool.BondedPool += validator.BondedShares.Evaluate()
|
||||
} else if validator.Status == Unbonded {
|
||||
pool.UnbondedShares = pool.UnbondedShares.Add(validator.BondedShares)
|
||||
pool.UnbondedPool += validator.BondedShares.Evaluate()
|
||||
}
|
||||
candidates[i] = candidate
|
||||
validators[i] = validator
|
||||
}
|
||||
return pool, candidates
|
||||
return pool, validators
|
||||
}
|
||||
|
||||
// any operation that transforms staking state
|
||||
// takes in RNG instance, pool, candidate
|
||||
// returns updated pool, updated candidate, delta tokens, descriptive message
|
||||
type Operation func(r *rand.Rand, p Pool, c Candidate) (Pool, Candidate, int64, string)
|
||||
// takes in RNG instance, pool, validator
|
||||
// returns updated pool, updated validator, delta tokens, descriptive message
|
||||
type Operation func(r *rand.Rand, p Pool, c Validator) (Pool, Validator, int64, string)
|
||||
|
||||
// operation: bond or unbond a candidate depending on current status
|
||||
func OpBondOrUnbond(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int64, string) {
|
||||
// operation: bond or unbond a validator depending on current status
|
||||
func OpBondOrUnbond(r *rand.Rand, p Pool, cand Validator) (Pool, Validator, int64, string) {
|
||||
var msg string
|
||||
if cand.Status == Bonded {
|
||||
msg = fmt.Sprintf("Unbonded previously bonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
msg = fmt.Sprintf("Unbonded previously bonded validator %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
cand.Address, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate())
|
||||
p, cand = p.bondedToUnbondedPool(cand)
|
||||
|
||||
} else if cand.Status == Unbonded {
|
||||
msg = fmt.Sprintf("Bonded previously unbonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
msg = fmt.Sprintf("Bonded previously unbonded validator %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
cand.Address, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate())
|
||||
p, cand = p.unbondedToBondedPool(cand)
|
||||
}
|
||||
return p, cand, 0, msg
|
||||
}
|
||||
|
||||
// operation: add a random number of tokens to a candidate
|
||||
func OpAddTokens(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int64, string) {
|
||||
// operation: add a random number of tokens to a validator
|
||||
func OpAddTokens(r *rand.Rand, p Pool, cand Validator) (Pool, Validator, int64, string) {
|
||||
tokens := int64(r.Int31n(1000))
|
||||
msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
msg := fmt.Sprintf("validator %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate())
|
||||
p, cand, _ = p.candidateAddTokens(cand, tokens)
|
||||
p, cand, _ = p.validatorAddTokens(cand, tokens)
|
||||
msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg)
|
||||
return p, cand, -1 * tokens, msg // tokens are removed so for accounting must be negative
|
||||
}
|
||||
|
||||
// operation: remove a random number of shares from a candidate
|
||||
func OpRemoveShares(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int64, string) {
|
||||
// operation: remove a random number of shares from a validator
|
||||
func OpRemoveShares(r *rand.Rand, p Pool, cand Validator) (Pool, Validator, int64, string) {
|
||||
var shares sdk.Rat
|
||||
for {
|
||||
shares = sdk.NewRat(int64(r.Int31n(1000)))
|
||||
|
@ -343,10 +343,10 @@ func OpRemoveShares(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int6
|
|||
}
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("Removed %v shares from candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
msg := fmt.Sprintf("Removed %v shares from validator %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
shares, cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate())
|
||||
|
||||
p, cand, tokens := p.candidateRemoveShares(cand, shares)
|
||||
p, cand, tokens := p.validatorRemoveShares(cand, shares)
|
||||
return p, cand, tokens, msg
|
||||
}
|
||||
|
||||
|
@ -365,7 +365,7 @@ func randomOperation(r *rand.Rand) Operation {
|
|||
|
||||
// ensure invariants that should always be true are true
|
||||
func assertInvariants(t *testing.T, msg string,
|
||||
pOrig Pool, cOrig Candidates, pMod Pool, cMods Candidates, tokens int64) {
|
||||
pOrig Pool, cOrig Validators, pMod Pool, cMods Validators, tokens int64) {
|
||||
|
||||
// total tokens conserved
|
||||
require.Equal(t,
|
||||
|
@ -402,7 +402,7 @@ func assertInvariants(t *testing.T, msg string,
|
|||
|
||||
// nonnegative ex rate
|
||||
require.False(t, cMod.delegatorShareExRate().LT(sdk.ZeroRat()),
|
||||
"Applying operation \"%s\" resulted in negative candidate.delegatorShareExRate(): %v (candidate.Address: %s)",
|
||||
"Applying operation \"%s\" resulted in negative validator.delegatorShareExRate(): %v (validator.Address: %s)",
|
||||
msg,
|
||||
cMod.delegatorShareExRate(),
|
||||
cMod.Address,
|
||||
|
@ -410,7 +410,7 @@ func assertInvariants(t *testing.T, msg string,
|
|||
|
||||
// nonnegative assets
|
||||
require.False(t, cMod.BondedShares.LT(sdk.ZeroRat()),
|
||||
"Applying operation \"%s\" resulted in negative candidate.BondedShares: %v (candidate.DelegatorShares: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)",
|
||||
"Applying operation \"%s\" resulted in negative validator.BondedShares: %v (validator.DelegatorShares: %v, validator.delegatorShareExRate: %v, validator.Address: %s)",
|
||||
msg,
|
||||
cMod.BondedShares,
|
||||
cMod.DelegatorShares,
|
||||
|
@ -420,7 +420,7 @@ func assertInvariants(t *testing.T, msg string,
|
|||
|
||||
// nonnegative liabilities
|
||||
require.False(t, cMod.DelegatorShares.LT(sdk.ZeroRat()),
|
||||
"Applying operation \"%s\" resulted in negative candidate.DelegatorShares: %v (candidate.BondedShares: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)",
|
||||
"Applying operation \"%s\" resulted in negative validator.DelegatorShares: %v (validator.BondedShares: %v, validator.delegatorShareExRate: %v, validator.Address: %s)",
|
||||
msg,
|
||||
cMod.DelegatorShares,
|
||||
cMod.BondedShares,
|
||||
|
@ -435,7 +435,7 @@ func assertInvariants(t *testing.T, msg string,
|
|||
func TestPossibleOverflow(t *testing.T) {
|
||||
assets := sdk.NewRat(2159)
|
||||
liabilities := sdk.NewRat(391432570689183511).Quo(sdk.NewRat(40113011844664))
|
||||
cand := Candidate{
|
||||
cand := Validator{
|
||||
Status: Bonded,
|
||||
Address: addrs[0],
|
||||
PubKey: pks[0],
|
||||
|
@ -452,72 +452,72 @@ func TestPossibleOverflow(t *testing.T) {
|
|||
Inflation: sdk.NewRat(7, 100),
|
||||
}
|
||||
tokens := int64(71)
|
||||
msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
msg := fmt.Sprintf("validator %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)",
|
||||
cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate())
|
||||
_, newCandidate, _ := pool.candidateAddTokens(cand, tokens)
|
||||
_, newValidator, _ := pool.validatorAddTokens(cand, tokens)
|
||||
|
||||
msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg)
|
||||
require.False(t, newCandidate.delegatorShareExRate().LT(sdk.ZeroRat()),
|
||||
require.False(t, newValidator.delegatorShareExRate().LT(sdk.ZeroRat()),
|
||||
"Applying operation \"%s\" resulted in negative delegatorShareExRate(): %v",
|
||||
msg, newCandidate.delegatorShareExRate())
|
||||
msg, newValidator.delegatorShareExRate())
|
||||
}
|
||||
|
||||
// run random operations in a random order on a random single-candidate state, assert invariants hold
|
||||
func TestSingleCandidateIntegrationInvariants(t *testing.T) {
|
||||
// run random operations in a random order on a random single-validator state, assert invariants hold
|
||||
func TestSingleValidatorIntegrationInvariants(t *testing.T) {
|
||||
r := rand.New(rand.NewSource(41))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
poolOrig, candidatesOrig := randomSetup(r, 1)
|
||||
require.Equal(t, 1, len(candidatesOrig))
|
||||
poolOrig, validatorsOrig := randomSetup(r, 1)
|
||||
require.Equal(t, 1, len(validatorsOrig))
|
||||
|
||||
// sanity check
|
||||
assertInvariants(t, "no operation",
|
||||
poolOrig, candidatesOrig,
|
||||
poolOrig, candidatesOrig, 0)
|
||||
poolOrig, validatorsOrig,
|
||||
poolOrig, validatorsOrig, 0)
|
||||
|
||||
for j := 0; j < 5; j++ {
|
||||
poolMod, candidateMod, tokens, msg := randomOperation(r)(r, poolOrig, candidatesOrig[0])
|
||||
poolMod, validatorMod, tokens, msg := randomOperation(r)(r, poolOrig, validatorsOrig[0])
|
||||
|
||||
candidatesMod := make([]Candidate, len(candidatesOrig))
|
||||
copy(candidatesMod[:], candidatesOrig[:])
|
||||
require.Equal(t, 1, len(candidatesOrig), "j %v", j)
|
||||
require.Equal(t, 1, len(candidatesMod), "j %v", j)
|
||||
candidatesMod[0] = candidateMod
|
||||
validatorsMod := make([]Validator, len(validatorsOrig))
|
||||
copy(validatorsMod[:], validatorsOrig[:])
|
||||
require.Equal(t, 1, len(validatorsOrig), "j %v", j)
|
||||
require.Equal(t, 1, len(validatorsMod), "j %v", j)
|
||||
validatorsMod[0] = validatorMod
|
||||
|
||||
assertInvariants(t, msg,
|
||||
poolOrig, candidatesOrig,
|
||||
poolMod, candidatesMod, tokens)
|
||||
poolOrig, validatorsOrig,
|
||||
poolMod, validatorsMod, tokens)
|
||||
|
||||
poolOrig = poolMod
|
||||
candidatesOrig = candidatesMod
|
||||
validatorsOrig = validatorsMod
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// run random operations in a random order on a random multi-candidate state, assert invariants hold
|
||||
func TestMultiCandidateIntegrationInvariants(t *testing.T) {
|
||||
// run random operations in a random order on a random multi-validator state, assert invariants hold
|
||||
func TestMultiValidatorIntegrationInvariants(t *testing.T) {
|
||||
r := rand.New(rand.NewSource(42))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
poolOrig, candidatesOrig := randomSetup(r, 100)
|
||||
poolOrig, validatorsOrig := randomSetup(r, 100)
|
||||
|
||||
assertInvariants(t, "no operation",
|
||||
poolOrig, candidatesOrig,
|
||||
poolOrig, candidatesOrig, 0)
|
||||
poolOrig, validatorsOrig,
|
||||
poolOrig, validatorsOrig, 0)
|
||||
|
||||
for j := 0; j < 5; j++ {
|
||||
index := int(r.Int31n(int32(len(candidatesOrig))))
|
||||
poolMod, candidateMod, tokens, msg := randomOperation(r)(r, poolOrig, candidatesOrig[index])
|
||||
candidatesMod := make([]Candidate, len(candidatesOrig))
|
||||
copy(candidatesMod[:], candidatesOrig[:])
|
||||
candidatesMod[index] = candidateMod
|
||||
index := int(r.Int31n(int32(len(validatorsOrig))))
|
||||
poolMod, validatorMod, tokens, msg := randomOperation(r)(r, poolOrig, validatorsOrig[index])
|
||||
validatorsMod := make([]Validator, len(validatorsOrig))
|
||||
copy(validatorsMod[:], validatorsOrig[:])
|
||||
validatorsMod[index] = validatorMod
|
||||
|
||||
assertInvariants(t, msg,
|
||||
poolOrig, candidatesOrig,
|
||||
poolMod, candidatesMod, tokens)
|
||||
poolOrig, validatorsOrig,
|
||||
poolMod, validatorsMod, tokens)
|
||||
|
||||
poolOrig = poolMod
|
||||
candidatesOrig = candidatesMod
|
||||
validatorsOrig = validatorsMod
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,10 +65,10 @@ func TestProcessProvisions(t *testing.T) {
|
|||
keeper.setParams(ctx, params)
|
||||
pool := keeper.GetPool(ctx)
|
||||
|
||||
// create some candidates some bonded, some unbonded
|
||||
candidates := make([]Candidate, 10)
|
||||
// create some validators some bonded, some unbonded
|
||||
validators := make([]Validator, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
c := Candidate{
|
||||
c := Validator{
|
||||
Status: Unbonded,
|
||||
PubKey: pks[i],
|
||||
Address: addrs[i],
|
||||
|
@ -80,10 +80,10 @@ func TestProcessProvisions(t *testing.T) {
|
|||
}
|
||||
mintedTokens := int64((i + 1) * 10000000)
|
||||
pool.TotalSupply += mintedTokens
|
||||
pool, c, _ = pool.candidateAddTokens(c, mintedTokens)
|
||||
pool, c, _ = pool.validatorAddTokens(c, mintedTokens)
|
||||
|
||||
keeper.setCandidate(ctx, c)
|
||||
candidates[i] = c
|
||||
keeper.setValidator(ctx, c)
|
||||
validators[i] = c
|
||||
}
|
||||
keeper.setPool(ctx, pool)
|
||||
var totalSupply int64 = 550000000
|
||||
|
@ -96,7 +96,7 @@ func TestProcessProvisions(t *testing.T) {
|
|||
// initial bonded ratio ~ 27%
|
||||
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, totalSupply)), "%v", pool.bondedRatio())
|
||||
|
||||
// test the value of candidate shares
|
||||
// test the value of validator shares
|
||||
assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate())
|
||||
|
||||
initialSupply := pool.TotalSupply
|
||||
|
@ -128,6 +128,6 @@ func TestProcessProvisions(t *testing.T) {
|
|||
assert.Equal(t, int64(211813022), pool.BondedPool)
|
||||
assert.Equal(t, unbondedShares, pool.UnbondedPool)
|
||||
|
||||
// test the value of candidate shares
|
||||
// test the value of validator shares
|
||||
assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(211813022)), "%v", pool.bondedShareExRate())
|
||||
}
|
||||
|
|
|
@ -13,15 +13,15 @@ import (
|
|||
type GenesisState struct {
|
||||
Pool Pool `json:"pool"`
|
||||
Params Params `json:"params"`
|
||||
Candidates []Candidate `json:"candidates"`
|
||||
Validators []Validator `json:"validators"`
|
||||
Bonds []Delegation `json:"bonds"`
|
||||
}
|
||||
|
||||
func NewGenesisState(pool Pool, params Params, candidates []Candidate, bonds []Delegation) GenesisState {
|
||||
func NewGenesisState(pool Pool, params Params, validators []Validator, bonds []Delegation) GenesisState {
|
||||
return GenesisState{
|
||||
Pool: pool,
|
||||
Params: params,
|
||||
Candidates: candidates,
|
||||
Validators: validators,
|
||||
Bonds: bonds,
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ type Pool struct {
|
|||
UnbondedShares sdk.Rat `json:"unbonded_shares"` // sum of all shares distributed for the Unbonded Pool
|
||||
BondedPool int64 `json:"bonded_pool"` // reserve of bonded tokens
|
||||
UnbondingPool int64 `json:"unbonding_pool"` // tokens moving from bonded to unbonded pool
|
||||
UnbondedPool int64 `json:"unbonded_pool"` // reserve of unbonded tokens held with candidates
|
||||
UnbondedPool int64 `json:"unbonded_pool"` // reserve of unbonded tokens held with validators
|
||||
InflationLastTime int64 `json:"inflation_last_time"` // block which the last inflation was processed // TODO make time
|
||||
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
|
||||
|
||||
|
@ -118,42 +118,42 @@ func initialPool() Pool {
|
|||
|
||||
//_________________________________________________________________________
|
||||
|
||||
// Candidate defines the total amount of bond shares and their exchange rate to
|
||||
// Validator defines the total amount of bond shares and their exchange rate to
|
||||
// coins. Accumulation of interest is modelled as an in increase in the
|
||||
// exchange rate, and slashing as a decrease. When coins are delegated to this
|
||||
// candidate, the candidate is credited with a Delegation whose number of
|
||||
// validator, the validator is credited with a Delegation whose number of
|
||||
// bond shares is based on the amount of coins delegated divided by the current
|
||||
// exchange rate. Voting power can be calculated as total bonds multiplied by
|
||||
// exchange rate.
|
||||
type Candidate struct {
|
||||
Status CandidateStatus `json:"status"` // Bonded status
|
||||
Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here
|
||||
PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate
|
||||
BondedShares sdk.Rat `json:"bonded_shares"` // total shares of a global hold pools
|
||||
UnbondingShares sdk.Rat `json:"unbonding_shares"` // total shares of a global hold pools
|
||||
UnbondedShares sdk.Rat `json:"unbonded_shares"` // total shares of a global hold pools
|
||||
DelegatorShares sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators
|
||||
type Validator struct {
|
||||
Status sdk.ValidatorStatus `json:"status"` // Bonded status
|
||||
Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here
|
||||
PubKey crypto.PubKey `json:"pub_key"` // Pubkey of validator
|
||||
BondedShares sdk.Rat `json:"bonded_shares"` // total shares of a global hold pools
|
||||
UnbondingShares sdk.Rat `json:"unbonding_shares"` // total shares of a global hold pools
|
||||
UnbondedShares sdk.Rat `json:"unbonded_shares"` // total shares of a global hold pools
|
||||
DelegatorShares sdk.Rat `json:"liabilities"` // total shares issued to a validator's delegators
|
||||
|
||||
Description Description `json:"description"` // Description terms for the candidate
|
||||
Description Description `json:"description"` // Description terms for the validator
|
||||
ValidatorBondHeight int64 `json:"validator_bond_height"` // Earliest height as a bonded validator
|
||||
ValidatorBondCounter int16 `json:"validator_bond_counter"` // Block-local tx index of validator change
|
||||
ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer
|
||||
|
||||
Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators
|
||||
CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this candidate can ever charge
|
||||
CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the candidate commission
|
||||
CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this validator can ever charge
|
||||
CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the validator commission
|
||||
CommissionChangeToday sdk.Rat `json:"commission_change_today"` // XXX commission rate change today, reset each day (UTC time)
|
||||
|
||||
// fee related
|
||||
PrevBondedShares sdk.Rat `json:"prev_bonded_shares"` // total shares of a global hold pools
|
||||
}
|
||||
|
||||
// Candidates - list of Candidates
|
||||
type Candidates []Candidate
|
||||
// Validators - list of Validators
|
||||
type Validators []Validator
|
||||
|
||||
// NewCandidate - initialize a new candidate
|
||||
func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Description) Candidate {
|
||||
return Candidate{
|
||||
// NewValidator - initialize a new validator
|
||||
func NewValidator(address sdk.Address, pubKey crypto.PubKey, description Description) Validator {
|
||||
return Validator{
|
||||
Status: Unbonded,
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
|
@ -172,25 +172,25 @@ func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Descrip
|
|||
}
|
||||
}
|
||||
|
||||
func (c Candidate) equal(c2 Candidate) bool {
|
||||
return c.Status == c2.Status &&
|
||||
c.PubKey.Equals(c2.PubKey) &&
|
||||
bytes.Equal(c.Address, c2.Address) &&
|
||||
c.BondedShares.Equal(c2.BondedShares) &&
|
||||
c.DelegatorShares.Equal(c2.DelegatorShares) &&
|
||||
c.Description == c2.Description &&
|
||||
c.ValidatorBondHeight == c2.ValidatorBondHeight &&
|
||||
//c.ValidatorBondCounter == c2.ValidatorBondCounter && // counter is always changing
|
||||
c.ProposerRewardPool.IsEqual(c2.ProposerRewardPool) &&
|
||||
c.Commission.Equal(c2.Commission) &&
|
||||
c.CommissionMax.Equal(c2.CommissionMax) &&
|
||||
c.CommissionChangeRate.Equal(c2.CommissionChangeRate) &&
|
||||
c.CommissionChangeToday.Equal(c2.CommissionChangeToday) &&
|
||||
sdk.RatsEqual(c.FeeAdjustments, c2.FeeAdjustments) &&
|
||||
c.PrevBondedShares.Equal(c2.PrevBondedShares)
|
||||
func (v Validator) equal(c2 Validator) bool {
|
||||
return v.Status == c2.Status &&
|
||||
v.PubKey.Equals(c2.PubKey) &&
|
||||
bytes.Equal(v.Address, c2.Address) &&
|
||||
v.BondedShares.Equal(c2.BondedShares) &&
|
||||
v.DelegatorShares.Equal(c2.DelegatorShares) &&
|
||||
v.Description == c2.Description &&
|
||||
v.ValidatorBondHeight == c2.ValidatorBondHeight &&
|
||||
//v.ValidatorBondCounter == c2.ValidatorBondCounter && // counter is always changing
|
||||
v.ProposerRewardPool.IsEqual(c2.ProposerRewardPool) &&
|
||||
v.Commission.Equal(c2.Commission) &&
|
||||
v.CommissionMax.Equal(c2.CommissionMax) &&
|
||||
v.CommissionChangeRate.Equal(c2.CommissionChangeRate) &&
|
||||
v.CommissionChangeToday.Equal(c2.CommissionChangeToday) &&
|
||||
sdk.RatsEqual(v.FeeAdjustments, c2.FeeAdjustments) &&
|
||||
v.PrevBondedShares.Equal(c2.PrevBondedShares)
|
||||
}
|
||||
|
||||
// Description - description fields for a candidate
|
||||
// Description - description fields for a validator
|
||||
type Description struct {
|
||||
Moniker string `json:"moniker"`
|
||||
Identity string `json:"identity"`
|
||||
|
@ -208,11 +208,11 @@ func NewDescription(moniker, identity, website, details string) Description {
|
|||
}
|
||||
|
||||
// get the exchange rate of global pool shares over delegator shares
|
||||
func (c Candidate) delegatorShareExRate() sdk.Rat {
|
||||
if c.DelegatorShares.IsZero() {
|
||||
func (v Validator) delegatorShareExRate() sdk.Rat {
|
||||
if v.DelegatorShares.IsZero() {
|
||||
return sdk.OneRat()
|
||||
}
|
||||
return c.BondedShares.Quo(c.DelegatorShares)
|
||||
return v.BondedShares.Quo(v.DelegatorShares)
|
||||
}
|
||||
|
||||
// abci validator from stake validator type
|
||||
|
@ -253,14 +253,14 @@ func (v Validator) GetPower() sdk.Rat { return v.Power }
|
|||
// TODO better way of managing space
|
||||
type Delegation struct {
|
||||
DelegatorAddr sdk.Address `json:"delegator_addr"`
|
||||
CandidateAddr sdk.Address `json:"candidate_addr"`
|
||||
ValidatorAddr sdk.Address `json:"validator_addr"`
|
||||
Shares sdk.Rat `json:"shares"`
|
||||
Height int64 `json:"height"` // Last height bond updated
|
||||
}
|
||||
|
||||
func (b Delegation) equal(b2 Delegation) bool {
|
||||
return bytes.Equal(b.DelegatorAddr, b2.DelegatorAddr) &&
|
||||
bytes.Equal(b.CandidateAddr, b2.CandidateAddr) &&
|
||||
bytes.Equal(b.ValidatorAddr, b2.ValidatorAddr) &&
|
||||
b.Height == b2.Height &&
|
||||
b.Shares.Equal(b2.Shares)
|
||||
}
|
||||
|
@ -270,5 +270,5 @@ var _ sdk.Delegation = Delegation{}
|
|||
|
||||
// nolint - for sdk.Delegation
|
||||
func (b Delegation) GetDelegator() sdk.Address { return b.DelegatorAddr }
|
||||
func (b Delegation) GetValidator() sdk.Address { return b.CandidateAddr }
|
||||
func (b Delegation) GetValidator() sdk.Address { return b.ValidatorAddr }
|
||||
func (b Delegation) GetBondAmount() sdk.Rat { return b.Shares }
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
package stake
|
||||
|
||||
// XXX test global state functions, candidate exchange rate functions etc.
|
||||
// XXX test global state functions, validator exchange rate functions etc.
|
||||
|
|
|
@ -18,8 +18,8 @@ func NewViewSlashKeeper(k Keeper) ViewSlashKeeper {
|
|||
|
||||
// load a delegator bond
|
||||
func (v ViewSlashKeeper) GetDelegation(ctx sdk.Context,
|
||||
delegatorAddr, candidateAddr sdk.Address) (bond Delegation, found bool) {
|
||||
return v.keeper.GetDelegation(ctx, delegatorAddr, candidateAddr)
|
||||
delegatorAddr, validatorAddr sdk.Address) (bond Delegation, found bool) {
|
||||
return v.keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
}
|
||||
|
||||
// load n delegator bonds
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
func TestViewSlashBond(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 0)
|
||||
|
||||
//construct the candidates
|
||||
//construct the validators
|
||||
amts := []int64{9, 8, 7}
|
||||
var candidates [3]Candidate
|
||||
var validators [3]Validator
|
||||
for i, amt := range amts {
|
||||
candidates[i] = Candidate{
|
||||
validators[i] = Validator{
|
||||
Address: addrVals[i],
|
||||
PubKey: pks[i],
|
||||
BondedShares: sdk.NewRat(amt),
|
||||
|
@ -25,12 +25,12 @@ func TestViewSlashBond(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// first add a candidates[0] to delegate too
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
// first add a validators[0] to delegate too
|
||||
keeper.setValidator(ctx, validators[0])
|
||||
|
||||
bond1to1 := Delegation{
|
||||
DelegatorAddr: addrDels[0],
|
||||
CandidateAddr: addrVals[0],
|
||||
ValidatorAddr: addrVals[0],
|
||||
Shares: sdk.NewRat(9),
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,8 @@ func TestViewSlashBond(t *testing.T) {
|
|||
assert.True(t, bond1to1.equal(resBond))
|
||||
|
||||
// add some more records
|
||||
keeper.setCandidate(ctx, candidates[1])
|
||||
keeper.setCandidate(ctx, candidates[2])
|
||||
keeper.setValidator(ctx, validators[1])
|
||||
keeper.setValidator(ctx, validators[2])
|
||||
bond1to2 := Delegation{addrDels[0], addrVals[1], sdk.NewRat(9), 0}
|
||||
bond1to3 := Delegation{addrDels[0], addrVals[2], sdk.NewRat(9), 1}
|
||||
bond2to1 := Delegation{addrDels[1], addrVals[0], sdk.NewRat(9), 2}
|
||||
|
|
Loading…
Reference in New Issue