working refactoring

This commit is contained in:
rigelrozanski 2018-05-10 00:01:58 -04:00
parent aff7d28bb0
commit 6d0c788185
20 changed files with 740 additions and 737 deletions

View File

@ -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))
}

View File

@ -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")
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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())

View File

@ -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")

View File

@ -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

View File

@ -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 {

View File

@ -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
}

View File

@ -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)

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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())
}

View File

@ -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 }

View File

@ -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.

View File

@ -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

View File

@ -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}