338 lines
11 KiB
Go
338 lines
11 KiB
Go
package types
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
)
|
|
|
|
// DVPair is struct that just has a delegator-validator pair with no other data.
|
|
// It is intended to be used as a marshalable pointer. For example, a DVPair can be used to construct the
|
|
// key to getting an UnbondingDelegation from state.
|
|
type DVPair struct {
|
|
DelegatorAddress sdk.AccAddress
|
|
ValidatorAddress sdk.ValAddress
|
|
}
|
|
|
|
// DVVTriplet is struct that just has a delegator-validator-validator triplet with no other data.
|
|
// It is intended to be used as a marshalable pointer. For example, a DVVTriplet can be used to construct the
|
|
// key to getting a Redelegation from state.
|
|
type DVVTriplet struct {
|
|
DelegatorAddress sdk.AccAddress
|
|
ValidatorSrcAddress sdk.ValAddress
|
|
ValidatorDstAddress sdk.ValAddress
|
|
}
|
|
|
|
// Delegation represents the bond with tokens held by an account. It is
|
|
// owned by one delegator, and is associated with the voting power of one
|
|
// validator.
|
|
type Delegation struct {
|
|
DelegatorAddress sdk.AccAddress `json:"delegator_address"`
|
|
ValidatorAddress sdk.ValAddress `json:"validator_address"`
|
|
Shares sdk.Dec `json:"shares"`
|
|
}
|
|
|
|
// NewDelegation creates a new delegation object
|
|
func NewDelegation(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
|
|
shares sdk.Dec) Delegation {
|
|
|
|
return Delegation{
|
|
DelegatorAddress: delegatorAddr,
|
|
ValidatorAddress: validatorAddr,
|
|
Shares: shares,
|
|
}
|
|
}
|
|
|
|
// return the delegation
|
|
func MustMarshalDelegation(cdc *codec.Codec, delegation Delegation) []byte {
|
|
return cdc.MustMarshalBinaryLengthPrefixed(delegation)
|
|
}
|
|
|
|
// return the delegation
|
|
func MustUnmarshalDelegation(cdc *codec.Codec, value []byte) Delegation {
|
|
delegation, err := UnmarshalDelegation(cdc, value)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return delegation
|
|
}
|
|
|
|
// return the delegation
|
|
func UnmarshalDelegation(cdc *codec.Codec, value []byte) (delegation Delegation, err error) {
|
|
err = cdc.UnmarshalBinaryLengthPrefixed(value, &delegation)
|
|
return delegation, err
|
|
}
|
|
|
|
// nolint
|
|
func (d Delegation) Equal(d2 Delegation) bool {
|
|
return bytes.Equal(d.DelegatorAddress, d2.DelegatorAddress) &&
|
|
bytes.Equal(d.ValidatorAddress, d2.ValidatorAddress) &&
|
|
d.Shares.Equal(d2.Shares)
|
|
}
|
|
|
|
// ensure fulfills the sdk validator types
|
|
var _ sdk.Delegation = Delegation{}
|
|
|
|
// nolint - for sdk.Delegation
|
|
func (d Delegation) GetDelegatorAddr() sdk.AccAddress { return d.DelegatorAddress }
|
|
func (d Delegation) GetValidatorAddr() sdk.ValAddress { return d.ValidatorAddress }
|
|
func (d Delegation) GetShares() sdk.Dec { return d.Shares }
|
|
|
|
// String returns a human readable string representation of a Delegation.
|
|
func (d Delegation) String() string {
|
|
return fmt.Sprintf(`Delegation:
|
|
Delegator: %s
|
|
Validator: %s
|
|
Shares: %s`, d.DelegatorAddress,
|
|
d.ValidatorAddress, d.Shares)
|
|
}
|
|
|
|
// Delegations is a collection of delegations
|
|
type Delegations []Delegation
|
|
|
|
func (d Delegations) String() (out string) {
|
|
for _, del := range d {
|
|
out += del.String() + "\n"
|
|
}
|
|
return strings.TrimSpace(out)
|
|
}
|
|
|
|
// UnbondingDelegation stores all of a single delegator's unbonding bonds
|
|
// for a single validator in an time-ordered list
|
|
type UnbondingDelegation struct {
|
|
DelegatorAddress sdk.AccAddress `json:"delegator_address"` // delegator
|
|
ValidatorAddress sdk.ValAddress `json:"validator_address"` // validator unbonding from operator addr
|
|
Entries []UnbondingDelegationEntry `json:"entries"` // unbonding delegation entries
|
|
}
|
|
|
|
// UnbondingDelegationEntry - entry to an UnbondingDelegation
|
|
type UnbondingDelegationEntry struct {
|
|
CreationHeight int64 `json:"creation_height"` // height which the unbonding took place
|
|
CompletionTime time.Time `json:"completion_time"` // time at which the unbonding delegation will complete
|
|
InitialBalance sdk.Int `json:"initial_balance"` // atoms initially scheduled to receive at completion
|
|
Balance sdk.Int `json:"balance"` // atoms to receive at completion
|
|
}
|
|
|
|
// IsMature - is the current entry mature
|
|
func (e UnbondingDelegationEntry) IsMature(currentTime time.Time) bool {
|
|
return !e.CompletionTime.After(currentTime)
|
|
}
|
|
|
|
// NewUnbondingDelegation - create a new unbonding delegation object
|
|
func NewUnbondingDelegation(delegatorAddr sdk.AccAddress,
|
|
validatorAddr sdk.ValAddress, creationHeight int64, minTime time.Time,
|
|
balance sdk.Int) UnbondingDelegation {
|
|
|
|
entry := NewUnbondingDelegationEntry(creationHeight, minTime, balance)
|
|
return UnbondingDelegation{
|
|
DelegatorAddress: delegatorAddr,
|
|
ValidatorAddress: validatorAddr,
|
|
Entries: []UnbondingDelegationEntry{entry},
|
|
}
|
|
}
|
|
|
|
// NewUnbondingDelegation - create a new unbonding delegation object
|
|
func NewUnbondingDelegationEntry(creationHeight int64, completionTime time.Time,
|
|
balance sdk.Int) UnbondingDelegationEntry {
|
|
|
|
return UnbondingDelegationEntry{
|
|
CreationHeight: creationHeight,
|
|
CompletionTime: completionTime,
|
|
InitialBalance: balance,
|
|
Balance: balance,
|
|
}
|
|
}
|
|
|
|
// AddEntry - append entry to the unbonding delegation
|
|
func (d *UnbondingDelegation) AddEntry(creationHeight int64,
|
|
minTime time.Time, balance sdk.Int) {
|
|
|
|
entry := NewUnbondingDelegationEntry(creationHeight, minTime, balance)
|
|
d.Entries = append(d.Entries, entry)
|
|
}
|
|
|
|
// RemoveEntry - remove entry at index i to the unbonding delegation
|
|
func (d *UnbondingDelegation) RemoveEntry(i int64) {
|
|
d.Entries = append(d.Entries[:i], d.Entries[i+1:]...)
|
|
}
|
|
|
|
// return the unbonding delegation
|
|
func MustMarshalUBD(cdc *codec.Codec, ubd UnbondingDelegation) []byte {
|
|
return cdc.MustMarshalBinaryLengthPrefixed(ubd)
|
|
}
|
|
|
|
// unmarshal a unbonding delegation from a store value
|
|
func MustUnmarshalUBD(cdc *codec.Codec, value []byte) UnbondingDelegation {
|
|
ubd, err := UnmarshalUBD(cdc, value)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return ubd
|
|
}
|
|
|
|
// unmarshal a unbonding delegation from a store value
|
|
func UnmarshalUBD(cdc *codec.Codec, value []byte) (ubd UnbondingDelegation, err error) {
|
|
err = cdc.UnmarshalBinaryLengthPrefixed(value, &ubd)
|
|
return ubd, err
|
|
}
|
|
|
|
// nolint
|
|
// inefficient but only used in testing
|
|
func (d UnbondingDelegation) Equal(d2 UnbondingDelegation) bool {
|
|
bz1 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d)
|
|
bz2 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d2)
|
|
return bytes.Equal(bz1, bz2)
|
|
}
|
|
|
|
// String returns a human readable string representation of an UnbondingDelegation.
|
|
func (d UnbondingDelegation) String() string {
|
|
out := fmt.Sprintf(`Unbonding Delegations between:
|
|
Delegator: %s
|
|
Validator: %s
|
|
Entries:`, d.DelegatorAddress, d.ValidatorAddress)
|
|
for i, entry := range d.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
|
|
}
|
|
|
|
// UnbondingDelegations is a collection of UnbondingDelegation
|
|
type UnbondingDelegations []UnbondingDelegation
|
|
|
|
func (ubds UnbondingDelegations) String() (out string) {
|
|
for _, u := range ubds {
|
|
out += u.String() + "\n"
|
|
}
|
|
return strings.TrimSpace(out)
|
|
}
|
|
|
|
// Redelegation contains the list of a particular delegator's
|
|
// redelegating bonds from a particular source validator to a
|
|
// particular destination validator
|
|
type Redelegation struct {
|
|
DelegatorAddress sdk.AccAddress `json:"delegator_address"` // delegator
|
|
ValidatorSrcAddress sdk.ValAddress `json:"validator_src_address"` // validator redelegation source operator addr
|
|
ValidatorDstAddress sdk.ValAddress `json:"validator_dst_address"` // validator redelegation destination operator addr
|
|
Entries []RedelegationEntry `json:"entries"` // redelegation entries
|
|
}
|
|
|
|
// RedelegationEntry - entry to a Redelegation
|
|
type RedelegationEntry struct {
|
|
CreationHeight int64 `json:"creation_height"` // height at which the redelegation took place
|
|
CompletionTime time.Time `json:"completion_time"` // time at which the redelegation will complete
|
|
InitialBalance sdk.Int `json:"initial_balance"` // initial balance when redelegation started
|
|
SharesDst sdk.Dec `json:"shares_dst"` // amount of destination-validator shares created by redelegation
|
|
}
|
|
|
|
// NewRedelegation - create a new redelegation object
|
|
func NewRedelegation(delegatorAddr sdk.AccAddress, validatorSrcAddr,
|
|
validatorDstAddr sdk.ValAddress, creationHeight int64,
|
|
minTime time.Time, balance sdk.Int,
|
|
sharesDst sdk.Dec) Redelegation {
|
|
|
|
entry := NewRedelegationEntry(creationHeight,
|
|
minTime, balance, sharesDst)
|
|
|
|
return Redelegation{
|
|
DelegatorAddress: delegatorAddr,
|
|
ValidatorSrcAddress: validatorSrcAddr,
|
|
ValidatorDstAddress: validatorDstAddr,
|
|
Entries: []RedelegationEntry{entry},
|
|
}
|
|
}
|
|
|
|
// NewRedelegation - create a new redelegation object
|
|
func NewRedelegationEntry(creationHeight int64,
|
|
completionTime time.Time, balance sdk.Int,
|
|
sharesDst sdk.Dec) RedelegationEntry {
|
|
|
|
return RedelegationEntry{
|
|
CreationHeight: creationHeight,
|
|
CompletionTime: completionTime,
|
|
InitialBalance: balance,
|
|
SharesDst: sharesDst,
|
|
}
|
|
}
|
|
|
|
// IsMature - is the current entry mature
|
|
func (e RedelegationEntry) IsMature(currentTime time.Time) bool {
|
|
return !e.CompletionTime.After(currentTime)
|
|
}
|
|
|
|
// AddEntry - append entry to the unbonding delegation
|
|
func (d *Redelegation) AddEntry(creationHeight int64,
|
|
minTime time.Time, balance sdk.Int,
|
|
sharesDst sdk.Dec) {
|
|
|
|
entry := NewRedelegationEntry(creationHeight, minTime, balance, sharesDst)
|
|
d.Entries = append(d.Entries, entry)
|
|
}
|
|
|
|
// RemoveEntry - remove entry at index i to the unbonding delegation
|
|
func (d *Redelegation) RemoveEntry(i int64) {
|
|
d.Entries = append(d.Entries[:i], d.Entries[i+1:]...)
|
|
}
|
|
|
|
// return the redelegation
|
|
func MustMarshalRED(cdc *codec.Codec, red Redelegation) []byte {
|
|
return cdc.MustMarshalBinaryLengthPrefixed(red)
|
|
}
|
|
|
|
// unmarshal a redelegation from a store value
|
|
func MustUnmarshalRED(cdc *codec.Codec, value []byte) Redelegation {
|
|
red, err := UnmarshalRED(cdc, value)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return red
|
|
}
|
|
|
|
// unmarshal a redelegation from a store value
|
|
func UnmarshalRED(cdc *codec.Codec, value []byte) (red Redelegation, err error) {
|
|
err = cdc.UnmarshalBinaryLengthPrefixed(value, &red)
|
|
return red, err
|
|
}
|
|
|
|
// nolint
|
|
// inefficient but only used in tests
|
|
func (d Redelegation) Equal(d2 Redelegation) bool {
|
|
bz1 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d)
|
|
bz2 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d2)
|
|
return bytes.Equal(bz1, bz2)
|
|
}
|
|
|
|
// String returns a human readable string representation of a Redelegation.
|
|
func (d Redelegation) String() string {
|
|
out := fmt.Sprintf(`Redelegations between:
|
|
Delegator: %s
|
|
Source Validator: %s
|
|
Destination Validator: %s
|
|
Entries:`, d.DelegatorAddress, d.ValidatorSrcAddress, d.ValidatorDstAddress)
|
|
for i, entry := range d.Entries {
|
|
out += fmt.Sprintf(` Redelegation %d:
|
|
Creation height: %v
|
|
Min time to unbond (unix): %v
|
|
Dest Shares: %s`, i, entry.CreationHeight,
|
|
entry.CompletionTime, entry.SharesDst)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Redelegations are a collection of Redelegation
|
|
type Redelegations []Redelegation
|
|
|
|
func (d Redelegations) String() (out string) {
|
|
for _, red := range d {
|
|
out += red.String() + "\n"
|
|
}
|
|
return strings.TrimSpace(out)
|
|
}
|