func UnmarshalRED(cdc *codec.Codec, value []byte) (red Redelegation, err error) {
	err = cdc.UnmarshalBinaryBare(value, &red)
	return red, err
}
UnmarshalRED unmarshals a redelegation from a store value
package types
import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
	"bytes"
	chainTypes "github.com/KuChainNetwork/kuchain/chain/types"
	"github.com/KuChainNetwork/kuchain/x/staking/exported"
	"github.com/cosmos/cosmos-sdk/codec"
	sdk "github.com/cosmos/cosmos-sdk/types"
	yaml "gopkg.in/yaml.v2"
)
var _ exported.DelegationI = Delegation{}
type DVPair struct {
	DelegatorAccount AccountID `json:"delegator_account" yaml:"delegator_account"`
	ValidatorAccount AccountID `json:"validator_account" yaml:"validator_account"`
}
type DVPairs struct {
	Pairs []DVPair `json:"pairs" yaml:"pairs"`
}
func (dv DVPair) String() string {
	out, _ := yaml.Marshal(dv)
	return string(out)
}
type DVVTriplet struct {
	DelegatorAccount    AccountID `json:"delegator_account" yaml:"delegator_account"`
	ValidatorSrcAccount AccountID `json:"validator_src_account" yaml:"validator_src_account"`
	ValidatorDstAccount AccountID `json:"validator_dst_account" yaml:"validator_dst_account"`
}
type DVVTriplets struct {
	Triplets []DVVTriplet `json:"triplets" yaml:"triplets"`
}
func (dvv DVVTriplet) String() string {
	out, _ := yaml.Marshal(dvv)
	return string(out)
}
type Delegation struct {
	DelegatorAccount AccountID `json:"delegator_account" yaml:"delegator_account"`
	ValidatorAccount AccountID `json:"validator_account" yaml:"validator_account"`
	Shares           Dec       `json:"shares" yaml:"shares"`
}
func NewDelegation(delegatorAddr chainTypes.AccountID, validatorAddr chainTypes.AccountID, shares sdk.Dec) Delegation {
	return Delegation{
		DelegatorAccount: delegatorAddr,
		ValidatorAccount: validatorAddr,
		Shares:           shares,
	}
}
func MustMarshalDelegation(cdc *codec.Codec, delegation Delegation) []byte {
	return cdc.MustMarshalBinaryBare(&delegation)
}
func MustUnmarshalDelegation(cdc *codec.Codec, value []byte) Delegation {
	delegation, err := UnmarshalDelegation(cdc, value)
	if err != nil {
		panic(err)
	}
	return delegation
}
func UnmarshalDelegation(cdc *codec.Codec, value []byte) (delegation Delegation, err error) {
	err = cdc.UnmarshalBinaryBare(value, &delegation)
	return delegation, err
}
func (d Delegation) Equal(d2 Delegation) bool {
	return bytes.Equal(d.DelegatorAccount.Bytes(), d2.DelegatorAccount.Bytes()) &&
		bytes.Equal(d.ValidatorAccount.Bytes(), d2.ValidatorAccount.Bytes()) &&
		d.Shares.Equal(d2.Shares)
}
func (d Delegation) GetDelegatorAccountID() chainTypes.AccountID { return d.DelegatorAccount }
func (d Delegation) GetValidatorAccountID() chainTypes.AccountID { return d.ValidatorAccount }
func (d Delegation) GetDelegatorAddr() sdk.AccAddress {
	delegatorAccAddr, _ := d.DelegatorAccount.ToAccAddress()
	return delegatorAccAddr
}
func (d Delegation) GetValidatorAddr() sdk.ValAddress {
	validatorAccaddr, _ := d.ValidatorAccount.ToAccAddress()
	return sdk.ValAddress(validatorAccaddr)
}
func (d Delegation) GetShares() sdk.Dec { return d.Shares }
func (d Delegation) String() string {
	out, _ := yaml.Marshal(d)
	return string(out)
}
type Delegations []Delegation
func (d Delegations) String() (out string) {
	for _, del := range d {
		out += del.String() + "\n"
	}
	return strings.TrimSpace(out)
}
func NewUnbondingDelegationEntry(creationHeight int64, completionTime time.Time, balance sdk.Int) UnbondingDelegationEntry {
	return UnbondingDelegationEntry{
		CreationHeight: creationHeight,
		CompletionTime: completionTime,
		InitialBalance: balance,
		Balance:        balance,
	}
}
func (e UnbondingDelegationEntry) String() string {
	out, _ := yaml.Marshal(e)
	return string(out)
}
func (e UnbondingDelegationEntry) IsMature(currentTime time.Time) bool {
	return !e.CompletionTime.After(currentTime)
}
func NewUnbondingDelegation(
	delegatorAddr chainTypes.AccountID, validatorAddr chainTypes.AccountID,
	creationHeight int64, minTime time.Time, balance sdk.Int,
) UnbondingDelegation {
	return UnbondingDelegation{
		DelegatorAccount: delegatorAddr,
		ValidatorAccount: validatorAddr,
		Entries: []UnbondingDelegationEntry{
			NewUnbondingDelegationEntry(creationHeight, minTime, balance),
		},
	}
}
func (ubd *UnbondingDelegation) AddEntry(creationHeight int64, minTime time.Time, balance sdk.Int) {
	entry := NewUnbondingDelegationEntry(creationHeight, minTime, balance)
	ubd.Entries = append(ubd.Entries, entry)
}
func (ubd *UnbondingDelegation) RemoveEntry(i int64) {
	ubd.Entries = append(ubd.Entries[:i], ubd.Entries[i+1:]...)
}
func MustMarshalUBD(cdc *codec.Codec, ubd UnbondingDelegation) []byte {
	return cdc.MustMarshalBinaryBare(&ubd)
}
func MustUnmarshalUBD(cdc *codec.Codec, value []byte) UnbondingDelegation {
	ubd, err := UnmarshalUBD(cdc, value)
	if err != nil {
		panic(err)
	}
	return ubd
}
func UnmarshalUBD(cdc *codec.Codec, value []byte) (ubd UnbondingDelegation, err error) {
	err = cdc.UnmarshalBinaryBare(value, &ubd)
	return ubd, err
}
type UnbondingDelegation struct {
	DelegatorAccount AccountID                  `json:"delegator_account" yaml:"delegator_account"`
	ValidatorAccount AccountID                  `json:"validator_account" yaml:"validator_account"`
	Entries          []UnbondingDelegationEntry `json:"entries" yaml:"entries"`
}
func (d UnbondingDelegation) Equal(d2 UnbondingDelegation) bool {
	bz1 := ModuleCdc.MustMarshalBinaryLengthPrefixed(&d)
	bz2 := ModuleCdc.MustMarshalBinaryLengthPrefixed(&d2)
	return bytes.Equal(bz1, bz2)
}
func (ubd UnbondingDelegation) String() string {
	out := fmt.Sprintf(`Unbonding Delegations between:
  Delegator:                 %s
  Validator:                 %s
	Entries:`, ubd.DelegatorAccount, ubd.ValidatorAccount)
	for i, entry := range ubd.Entries {
		out += fmt.Sprintf(`    Unbonding Delegation %d:
      Creation Height:           %v
      Min time to unbond (unix): %v
      Expected balance:          %s`, i, entry.CreationHeight,
			entry.CompletionTime, entry.Balance)
	}
	return out
}
type UnbondingDelegations []UnbondingDelegation
func (ubds UnbondingDelegations) String() (out string) {
	for _, u := range ubds {
		out += u.String() + "\n"
	}
	return strings.TrimSpace(out)
}
type UnbondingDelegationEntry struct {
	CreationHeight int64     `json:"creation_height,omitempty" yaml:"creation_height"`
	CompletionTime time.Time `json:"completion_time" yaml:"completion_time"`
	InitialBalance sdk.Int   `json:"initial_balance" yaml:"initial_balance"`
	Balance        sdk.Int   `json:"balance" yaml:"balance"`
}
type RedelegationEntry struct {
	CreationHeight int64     `json:"creation_height,omitempty" yaml:"creation_height"`
	CompletionTime time.Time `json:"completion_time" yaml:"completion_time"`
	InitialBalance sdk.Int   `json:"initial_balance" yaml:"initial_balance"`
	SharesDst      sdk.Dec   `json:"shares_dst" yaml:"shares_dst"`
}
func NewRedelegationEntry(creationHeight int64, completionTime time.Time, balance sdk.Int, sharesDst sdk.Dec) RedelegationEntry {
	return RedelegationEntry{
		CreationHeight: creationHeight,
		CompletionTime: completionTime,
		InitialBalance: balance,
		SharesDst:      sharesDst,
	}
}
func (e RedelegationEntry) String() string {
	out, _ := yaml.Marshal(e)
	return string(out)
}
func (e RedelegationEntry) IsMature(currentTime time.Time) bool {
	return !e.CompletionTime.After(currentTime)
}
type Redelegation struct {
	DelegatorAccount    AccountID           `json:"delegator_account" yaml:"delegator_account"`
	ValidatorSrcAccount AccountID           `json:"validator_src_account" yaml:"validator_src_account"`
	ValidatorDstAccount AccountID           `json:"validator_dst_account" yaml:"validator_dst_account"`
	Entries             []RedelegationEntry `json:"entries" yaml:"entries"`
}
func NewRedelegation(
	delegatorAddr chainTypes.AccountID, validatorSrcAddr, validatorDstAddr chainTypes.AccountID,
	creationHeight int64, minTime time.Time, balance sdk.Int, sharesDst sdk.Dec,
) Redelegation {
	return Redelegation{
		DelegatorAccount:    delegatorAddr,
		ValidatorSrcAccount: validatorSrcAddr,
		ValidatorDstAccount: validatorDstAddr,
		Entries: []RedelegationEntry{
			NewRedelegationEntry(creationHeight, minTime, balance, sharesDst),
		},
	}
}
func (red *Redelegation) AddEntry(creationHeight int64, minTime time.Time, balance sdk.Int, sharesDst sdk.Dec) {
	entry := NewRedelegationEntry(creationHeight, minTime, balance, sharesDst)
	red.Entries = append(red.Entries, entry)
}
func (red *Redelegation) RemoveEntry(i int64) {
	red.Entries = append(red.Entries[:i], red.Entries[i+1:]...)
}
func MustMarshalRED(cdc *codec.Codec, red Redelegation) []byte {
	return cdc.MustMarshalBinaryBare(&red)
}
func MustUnmarshalRED(cdc *codec.Codec, value []byte) Redelegation {
	red, err := UnmarshalRED(cdc, value)
	if err != nil {
		panic(err)
	}
	return red
}