rational embedes bigRat

This commit is contained in:
rigelrozanski 2018-04-30 17:21:14 -04:00
parent b79ab072e7
commit ce32117399
16 changed files with 231 additions and 275 deletions

View File

@ -265,7 +265,6 @@ func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOp
// InitChain runs the initialization logic directly on the CommitMultiStore and commits it.
func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {
if app.initChainer == nil {
// TODO: should we have some default handling of validators?
return
}
@ -275,7 +274,6 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC
// NOTE: we don't commit, but BeginBlock for block 1
// starts from this deliverState
return
}

View File

@ -106,8 +106,8 @@ func MakeCodec() *wire.Codec {
func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.AppStateBytes
genesisState := new(GenesisState)
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)
var genesisState GenesisState
err := app.cdc.UnmarshalJSON(stateJSON, &genesisState)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")

View File

@ -1,6 +1,7 @@
package types
import (
"bytes"
"fmt"
"math/big"
"strconv"
@ -13,68 +14,24 @@ import (
// __ /___...._____ _\o
// __| |_ |_
// Rat - extend big.Rat
// NOTE: never use new(Rat) or else
// we will panic unmarshalling into the
// nil embedded big.Rat
type Rat struct {
Num int64 `json:"num"`
Denom int64 `json:"denom"`
//*big.Rat `json:"rat"`
big.Rat `json:"rat"`
}
// RatInterface - big Rat with additional functionality
// NOTE: we only have one implementation of this interface
// and don't use it anywhere, but it might come in handy
// if we want to provide Rat types that include
// the units of the value in the type system.
//type RatInterface interface {
//GetRat() *big.Rat
//Num() int64
//Denom() int64
//GT(Rat) bool
//LT(Rat) bool
//Equal(Rat) bool
//IsZero() bool
//Inv() Rat
//Mul(Rat) Rat
//Quo(Rat) Rat
//Add(Rat) Rat
//Sub(Rat) Rat
//Round(int64) Rat
//Evaluate() int64
//}
//var _ Rat = Rat{} // enforce at compile time
// nolint - common values
var (
ZeroRat = NewRat(0) // Rat{big.NewRat(0, 1)}
OneRat = NewRat(1) // Rat{big.NewRat(1, 1)}
)
func ZeroRat() Rat { return Rat{*big.NewRat(0, 1)} }
func OneRat() Rat { return Rat{*big.NewRat(1, 1)} }
// New - create a new Rat from integers
//func NewRat(Numerator int64, Denominator ...int64) Rat {
//switch len(Denominator) {
//case 0:
//return Rat{big.NewRat(Numerator, 1)}
//case 1:
//return Rat{big.NewRat(Numerator, Denominator[0])}
//default:
//panic("improper use of New, can only have one denominator")
//}
//}
func NewRat(num int64, denom ...int64) Rat {
switch len(denom) {
func NewRat(Numerator int64, Denominator ...int64) Rat {
switch len(Denominator) {
case 0:
return Rat{
Num: num,
Denom: 1,
}
return Rat{*big.NewRat(Numerator, 1)}
case 1:
return Rat{
Num: num,
Denom: denom[0],
}
return Rat{*big.NewRat(Numerator, Denominator[0])}
default:
panic("improper use of New, can only have one denominator")
}
@ -124,30 +81,17 @@ func NewRatFromDecimal(decimalStr string) (f Rat, err Error) {
}
//nolint
func ToRat(r *big.Rat) Rat { return NewRat(r.Num().Int64(), r.Denom().Int64()) } // GetRat - get big.Rat
func (r Rat) GetRat() *big.Rat { return big.NewRat(r.Num, r.Denom) } // GetRat - get big.Rat
func (r Rat) IsZero() bool { return r.Num == 0 } // IsZero - Is the Rat equal to zero
func (r Rat) Equal(r2 Rat) bool { return r.GetRat().Cmp(r2.GetRat()) == 0 } // Equal - rationals are equal
func (r Rat) GT(r2 Rat) bool { return r.GetRat().Cmp(r2.GetRat()) == 1 } // GT - greater than
func (r Rat) LT(r2 Rat) bool { return r.GetRat().Cmp(r2.GetRat()) == -1 } // LT - less than
func (r Rat) Inv() Rat { return ToRat(new(big.Rat).Inv(r.GetRat())) } // Inv - inverse
func (r Rat) Mul(r2 Rat) Rat { return ToRat(new(big.Rat).Mul(r.GetRat(), r2.GetRat())) } // Mul - multiplication
func (r Rat) Quo(r2 Rat) Rat { return ToRat(new(big.Rat).Quo(r.GetRat(), r2.GetRat())) } // Quo - quotient
func (r Rat) Add(r2 Rat) Rat { return ToRat(new(big.Rat).Add(r.GetRat(), r2.GetRat())) } // Add - addition
func (r Rat) Sub(r2 Rat) Rat { return ToRat(new(big.Rat).Sub(r.GetRat(), r2.GetRat())) } // Sub - subtraction
//func (r Rat) GetRat() *big.Rat { return r.Rat } // GetRat - get big.Rat
//func (r Rat) Num() int64 { return r.Rat.Num().Int64() } // Num - return the numerator
//func (r Rat) Denom() int64 { return r.Rat.Denom().Int64() } // Denom - return the denominator
//func (r Rat) IsZero() bool { return r.Num() == 0 } // IsZero - Is the Rat equal to zero
//func (r Rat) Equal(r2 Rat) bool { return r.Rat.Cmp(r2.GetRat()) == 0 } // Equal - rationals are equal
//func (r Rat) GT(r2 Rat) bool { return r.Rat.Cmp(r2.GetRat()) == 1 } // GT - greater than
//func (r Rat) LT(r2 Rat) bool { return r.Rat.Cmp(r2.GetRat()) == -1 } // LT - less than
//func (r Rat) Inv() Rat { return Rat{new(big.Rat).Inv(r.Rat)} } // Inv - inverse
//func (r Rat) Mul(r2 Rat) Rat { return Rat{new(big.Rat).Mul(r.Rat, r2.GetRat())} } // Mul - multiplication
//func (r Rat) Quo(r2 Rat) Rat { return Rat{new(big.Rat).Quo(r.Rat, r2.GetRat())} } // Quo - quotient
//func (r Rat) Add(r2 Rat) Rat { return Rat{new(big.Rat).Add(r.Rat, r2.GetRat())} } // Add - addition
//func (r Rat) Sub(r2 Rat) Rat { return Rat{new(big.Rat).Sub(r.Rat, r2.GetRat())} } // Sub - subtraction
//func (r Rat) String() string { return fmt.Sprintf("%v/%v", r.Num(), r.Denom()) } // Sub - subtraction
func (r Rat) Num() int64 { return r.Rat.Num().Int64() } // Num - return the numerator
func (r Rat) Denom() int64 { return r.Rat.Denom().Int64() } // Denom - return the denominator
func (r Rat) IsZero() bool { return r.Num() == 0 } // IsZero - Is the Rat equal to zero
func (r Rat) Equal(r2 Rat) bool { return (&(r.Rat)).Cmp(&(r2.Rat)) == 0 } // Equal - rationals are equal
func (r Rat) GT(r2 Rat) bool { return (&(r.Rat)).Cmp(&(r2.Rat)) == 1 } // Equal - rationals are equal
func (r Rat) LT(r2 Rat) bool { return (&(r.Rat)).Cmp(&(r2.Rat)) == -1 } // Equal - rationals are equal
func (r Rat) Mul(r2 Rat) Rat { return Rat{*new(big.Rat).Mul(&(r.Rat), &(r2.Rat))} } // Mul - multiplication
func (r Rat) Quo(r2 Rat) Rat { return Rat{*new(big.Rat).Quo(&(r.Rat), &(r2.Rat))} } // Quo - quotient
func (r Rat) Add(r2 Rat) Rat { return Rat{*new(big.Rat).Add(&(r.Rat), &(r2.Rat))} } // Add - addition
func (r Rat) Sub(r2 Rat) Rat { return Rat{*new(big.Rat).Sub(&(r.Rat), &(r2.Rat))} } // Sub - subtraction
func (r Rat) String() string { return fmt.Sprintf("%v/%v", r.Num(), r.Denom()) } // Sub - subtraction
var (
zero = big.NewInt(0)
@ -161,8 +105,8 @@ var (
// evaluate the rational using bankers rounding
func (r Rat) EvaluateBig() *big.Int {
num := r.GetRat().Num()
denom := r.GetRat().Denom()
num := r.Rat.Num()
denom := r.Rat.Denom()
d, rem := new(big.Int), new(big.Int)
d.QuoRem(num, denom, rem)
@ -195,8 +139,8 @@ func (r Rat) Evaluate() int64 {
// round Rat with the provided precisionFactor
func (r Rat) Round(precisionFactor int64) Rat {
rTen := ToRat(new(big.Rat).Mul(r.GetRat(), big.NewRat(precisionFactor, 1)))
return ToRat(big.NewRat(rTen.Evaluate(), precisionFactor))
rTen := Rat{*new(big.Rat).Mul(&(r.Rat), big.NewRat(precisionFactor, 1))}
return Rat{*big.NewRat(rTen.Evaluate(), precisionFactor)}
}
// TODO panic if negative or if totalDigits < len(initStr)???
@ -212,26 +156,33 @@ func (r Rat) ToLeftPadded(totalDigits int8) string {
// Hack to just use json.Marshal for everything until
// we update for amino
//type JSONCodec struct{}
//nolint
//func (jc JSONCodec) MarshalJSON(o interface{}) ([]byte, error) { return json.Marshal(o) }
//func (jc JSONCodec) UnmarshalJSON(bz []byte, o interface{}) error { return json.Unmarshal(bz, o) }
// Wraps r.MarshalText() in quotes to make it a valid JSON string.
//func (r Rat) MarshalAmino() (string, error) {
//bz, err := r.MarshalText()
//if err != nil {
//return "", err
//}
//return fmt.Sprintf(`%s`, bz), nil
//}
//Wraps r.MarshalText() in quotes to make it a valid JSON string.
func (r Rat) MarshalJSON() ([]byte, error) {
bz, err := (&(r.Rat)).MarshalText()
if err != nil {
return nil, err
}
return []byte(fmt.Sprintf("\"%s\"", bz)), nil
}
//// Requires a valid JSON string - strings quotes and calls UnmarshalText
//func (r *Rat) UnmarshalAmino(data string) (err error) {
////quote := []byte(`"`)
////if len(data) < 2 ||
////!bytes.HasPrefix(data, quote) ||
////!bytes.HasSuffix(data, quote) {
////return fmt.Errorf("JSON encoded Rat must be a quote-delimitted string")
////}
////data = bytes.Trim(data, `"`)
//return r.UnmarshalText([]byte(data))
//}
// Requires a valid JSON string - strings quotes and calls UnmarshalText
func (r *Rat) UnmarshalJSON(data []byte) (err error) {
quote := []byte(`"`)
if len(data) < 2 ||
!bytes.HasPrefix(data, quote) ||
!bytes.HasSuffix(data, quote) {
return fmt.Errorf("JSON encoded Rat must be a quote-delimitted string, have %v", string(data))
}
data = bytes.Trim(data, `"`)
tempRat := big.NewRat(0, 1)
err = tempRat.UnmarshalText(data)
if err != nil {
return err
}
r.Rat = *tempRat
return nil
}

View File

@ -129,14 +129,14 @@ func TestArithmatic(t *testing.T) {
}
for _, tc := range tests {
assert.True(t, tc.resMul.Equal(tc.r1.Mul(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat())
assert.True(t, tc.resAdd.Equal(tc.r1.Add(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat())
assert.True(t, tc.resSub.Equal(tc.r1.Sub(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat())
assert.True(t, tc.resMul.Equal(tc.r1.Mul(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat)
assert.True(t, tc.resAdd.Equal(tc.r1.Add(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat)
assert.True(t, tc.resSub.Equal(tc.r1.Sub(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat)
if tc.r2.Num == 0 { // panic for divide by zero
if tc.r2.Num() == 0 { // panic for divide by zero
assert.Panics(t, func() { tc.r1.Quo(tc.r2) })
} else {
assert.True(t, tc.resDiv.Equal(tc.r1.Quo(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat())
assert.True(t, tc.resDiv.Equal(tc.r1.Quo(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat)
}
}
}
@ -180,8 +180,8 @@ func TestRound(t *testing.T) {
precFactor int64
}{
{NewRat(333, 777), NewRat(429, 1000), 1000},
{ToRat(new(big.Rat).SetFrac(big3, big7)), NewRat(429, 1000), 1000},
{ToRat(new(big.Rat).SetFrac(big3, big7)), ToRat(big.NewRat(4285714286, 10000000000)), 10000000000},
{Rat{*new(big.Rat).SetFrac(big3, big7)}, NewRat(429, 1000), 1000},
{Rat{*new(big.Rat).SetFrac(big3, big7)}, Rat{*big.NewRat(4285714286, 10000000000)}, 10000000000},
{NewRat(1, 2), NewRat(1, 2), 1000},
}
@ -209,47 +209,40 @@ func TestToLeftPadded(t *testing.T) {
}
}
//func TestZeroSerializationJSON(t *testing.T) {
//r := NewRat(0, 1)
//err := r.UnmarshalJSON([]byte(`"0/1"`))
//assert.Nil(t, err)
//err = r.UnmarshalJSON([]byte(`"0/0"`))
//assert.NotNil(t, err)
//err = r.UnmarshalJSON([]byte(`"1/0"`))
//assert.NotNil(t, err)
//err = r.UnmarshalJSON([]byte(`"{}"`))
//assert.NotNil(t, err)
//}
func TestZeroSerializationJSON(t *testing.T) {
r := NewRat(0, 1)
err := r.UnmarshalJSON([]byte(`"0/1"`))
assert.Nil(t, err)
err = r.UnmarshalJSON([]byte(`"0/0"`))
assert.NotNil(t, err)
err = r.UnmarshalJSON([]byte(`"1/0"`))
assert.NotNil(t, err)
err = r.UnmarshalJSON([]byte(`"{}"`))
assert.NotNil(t, err)
}
//func TestSerializationJSON(t *testing.T) {
//r := NewRat(1, 3)
func TestSerializationText(t *testing.T) {
r := NewRat(1, 3)
//bz, err := r.MarshalText()
//require.Nil(t, err)
bz, err := r.MarshalText()
require.NoError(t, err)
//r2 := NewRat(0, 1)
//err = r2.UnmarshalText(bz)
//require.Nil(t, err)
//assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2)
//}
r2 := NewRat(0, 1)
err = r2.UnmarshalText(bz)
require.NoError(t, err)
assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2)
}
var cdc = wire.NewCodec() //var jsonCdc JSONCodec // TODO wire.Codec
func TestSerializationGoWire(t *testing.T) {
r := NewRat(1, 3)
bz, err := cdc.MarshalBinary(r)
require.Nil(t, err)
//str, err := r.MarshalJSON()
//require.Nil(t, err)
bz, err := cdc.MarshalJSON(r)
require.NoError(t, err)
r2 := NewRat(0, 1)
err = cdc.UnmarshalBinary([]byte(bz), &r2)
//panic(fmt.Sprintf("debug bz: %v\n", string(bz)))
require.Nil(t, err)
err = cdc.UnmarshalJSON(bz, &r2)
require.NoError(t, err)
assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2)
}
@ -261,17 +254,14 @@ type testEmbedStruct struct {
func TestEmbeddedStructSerializationGoWire(t *testing.T) {
obj := testEmbedStruct{"foo", 10, NewRat(1, 3)}
bz, err := cdc.MarshalBinary(obj)
bz, err := cdc.MarshalJSON(obj)
require.Nil(t, err)
var obj2 testEmbedStruct
obj2.Field3 = NewRat(0, 1) // ... needs to be initialized
err = cdc.UnmarshalBinary(bz, &obj2)
err = cdc.UnmarshalJSON(bz, &obj2)
require.Nil(t, err)
assert.Equal(t, obj.Field1, obj2.Field1)
assert.Equal(t, obj.Field2, obj2.Field2)
assert.True(t, obj.Field3.Equal(obj2.Field3), "original: %v, unmarshalled: %v", obj, obj2)
}

View File

@ -166,7 +166,7 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command {
if err != nil {
return err
}
if !shares.GT(sdk.ZeroRat) {
if !shares.GT(sdk.ZeroRat()) {
return fmt.Errorf("shares must be positive integer or decimal (ex. 123, 1.23456789)")
}
}

View File

@ -165,7 +165,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
bond = DelegatorBond{
DelegatorAddr: delegatorAddr,
CandidateAddr: candidate.Address,
Shares: sdk.ZeroRat,
Shares: sdk.ZeroRat(),
}
}
@ -194,7 +194,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
if !found {
return ErrNoDelegatorForAddress(k.codespace).Result()
}
if !bond.Shares.GT(sdk.ZeroRat) { // bond shares < msg shares
if !bond.Shares.GT(sdk.ZeroRat()) { // bond shares < msg shares
return ErrInsufficientFunds(k.codespace).Result()
}
@ -202,7 +202,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
// test that there are enough shares to unbond
if msg.Shares == "MAX" {
if !bond.Shares.GT(sdk.ZeroRat) {
if !bond.Shares.GT(sdk.ZeroRat()) {
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
}
} else {

View File

@ -16,7 +16,7 @@ type Keeper struct {
coinKeeper bank.Keeper
// caches
gs Pool
pool Pool
params Params
// codespace
@ -41,7 +41,7 @@ func (k Keeper) getCounter(ctx sdk.Context) int16 {
return 0
}
var counter int16
err := k.cdc.UnmarshalBinary(b, &counter)
err := k.cdc.UnmarshalJSON(b, &counter)
if err != nil {
panic(err)
}
@ -51,7 +51,7 @@ func (k Keeper) getCounter(ctx sdk.Context) int16 {
// set the current in-block validator operation counter
func (k Keeper) setCounter(ctx sdk.Context, counter int16) {
store := ctx.KVStore(k.storeKey)
bz, err := k.cdc.MarshalBinary(counter)
bz, err := k.cdc.MarshalJSON(counter)
if err != nil {
panic(err)
}
@ -67,7 +67,7 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi
if b == nil {
return candidate, false
}
err := k.cdc.UnmarshalBinary(b, &candidate)
err := k.cdc.UnmarshalJSON(b, &candidate)
if err != nil {
panic(err)
}
@ -88,7 +88,7 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca
}
bz := iterator.Value()
var candidate Candidate
err := k.cdc.UnmarshalBinary(bz, &candidate)
err := k.cdc.UnmarshalJSON(bz, &candidate)
if err != nil {
panic(err)
}
@ -112,7 +112,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
}
// marshal the candidate record and add to the state
bz, err := k.cdc.MarshalBinary(candidate)
bz, err := k.cdc.MarshalJSON(candidate)
if err != nil {
panic(err)
}
@ -145,7 +145,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
}
// update the candidate record
bz, err = k.cdc.MarshalBinary(candidate)
bz, err = k.cdc.MarshalJSON(candidate)
if err != nil {
panic(err)
}
@ -153,7 +153,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
// marshal the new validator record
validator := candidate.validator()
bz, err = k.cdc.MarshalBinary(validator)
bz, err = k.cdc.MarshalJSON(validator)
if err != nil {
panic(err)
}
@ -171,7 +171,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
setAcc = true
}
if setAcc {
bz, err = k.cdc.MarshalBinary(validator.abciValidator(k.cdc))
bz, err = k.cdc.MarshalJSON(validator.abciValidator(k.cdc))
if err != nil {
panic(err)
}
@ -200,7 +200,7 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) {
if store.Get(GetRecentValidatorKey(address)) == nil {
return
}
bz, err := k.cdc.MarshalBinary(candidate.validator().abciValidatorZero(k.cdc))
bz, err := k.cdc.MarshalJSON(candidate.validator().abciValidatorZero(k.cdc))
if err != nil {
panic(err)
}
@ -242,7 +242,7 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) {
}
bz := iterator.Value()
var validator Validator
err := k.cdc.UnmarshalBinary(bz, &validator)
err := k.cdc.UnmarshalJSON(bz, &validator)
if err != nil {
panic(err)
}
@ -266,11 +266,11 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) {
// get the zero abci validator from the ToKickOut iterator value
bz := iterator.Value()
var validator Validator
err := k.cdc.UnmarshalBinary(bz, &validator)
err := k.cdc.UnmarshalJSON(bz, &validator)
if err != nil {
panic(err)
}
bz, err = k.cdc.MarshalBinary(validator.abciValidatorZero(k.cdc))
bz, err = k.cdc.MarshalJSON(validator.abciValidatorZero(k.cdc))
if err != nil {
panic(err)
}
@ -297,7 +297,7 @@ func (k Keeper) isNewValidator(ctx sdk.Context, store sdk.KVStore, address sdk.A
}
bz := iterator.Value()
var val Validator
err := k.cdc.UnmarshalBinary(bz, &val)
err := k.cdc.UnmarshalJSON(bz, &val)
if err != nil {
panic(err)
}
@ -330,7 +330,7 @@ func (k Keeper) getAccUpdateValidators(ctx sdk.Context) (updates []abci.Validato
for ; iterator.Valid(); iterator.Next() {
valBytes := iterator.Value()
var val abci.Validator
err := k.cdc.UnmarshalBinary(valBytes, &val)
err := k.cdc.UnmarshalJSON(valBytes, &val)
if err != nil {
panic(err)
}
@ -364,7 +364,7 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context,
return bond, false
}
err := k.cdc.UnmarshalBinary(delegatorBytes, &bond)
err := k.cdc.UnmarshalJSON(delegatorBytes, &bond)
if err != nil {
panic(err)
}
@ -385,7 +385,7 @@ func (k Keeper) getBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorB
}
bondBytes := iterator.Value()
var bond DelegatorBond
err := k.cdc.UnmarshalBinary(bondBytes, &bond)
err := k.cdc.UnmarshalJSON(bondBytes, &bond)
if err != nil {
panic(err)
}
@ -410,7 +410,7 @@ func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet
}
bondBytes := iterator.Value()
var bond DelegatorBond
err := k.cdc.UnmarshalBinary(bondBytes, &bond)
err := k.cdc.UnmarshalJSON(bondBytes, &bond)
if err != nil {
panic(err)
}
@ -422,7 +422,7 @@ func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet
func (k Keeper) setDelegatorBond(ctx sdk.Context, bond DelegatorBond) {
store := ctx.KVStore(k.storeKey)
b, err := k.cdc.MarshalBinary(bond)
b, err := k.cdc.MarshalJSON(bond)
if err != nil {
panic(err)
}
@ -439,7 +439,7 @@ func (k Keeper) removeDelegatorBond(ctx sdk.Context, bond DelegatorBond) {
// load/save the global staking params
func (k Keeper) GetParams(ctx sdk.Context) (params Params) {
// check if cached before anything
if k.params != (Params{}) {
if !k.params.equal(Params{}) {
return k.params
}
store := ctx.KVStore(k.storeKey)
@ -448,7 +448,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params Params) {
panic("Stored params should not have been nil")
}
err := k.cdc.UnmarshalBinary(b, &params)
err := k.cdc.UnmarshalJSON(b, &params)
if err != nil {
panic(err)
}
@ -456,7 +456,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params Params) {
}
func (k Keeper) setParams(ctx sdk.Context, params Params) {
store := ctx.KVStore(k.storeKey)
b, err := k.cdc.MarshalBinary(params)
b, err := k.cdc.MarshalJSON(params)
if err != nil {
panic(err)
}
@ -467,17 +467,17 @@ func (k Keeper) setParams(ctx sdk.Context, params Params) {
//_______________________________________________________________________
// load/save the pool
func (k Keeper) GetPool(ctx sdk.Context) (gs Pool) {
func (k Keeper) GetPool(ctx sdk.Context) (pool Pool) {
// check if cached before anything
if k.gs != (Pool{}) {
return k.gs
if !k.pool.equal(Pool{}) {
return k.pool
}
store := ctx.KVStore(k.storeKey)
b := store.Get(PoolKey)
if b == nil {
panic("Stored pool should not have been nil")
}
err := k.cdc.UnmarshalBinary(b, &gs)
err := k.cdc.UnmarshalJSON(b, &pool)
if err != nil {
panic(err) // This error should never occur big problem if does
}
@ -486,10 +486,10 @@ func (k Keeper) GetPool(ctx sdk.Context) (gs Pool) {
func (k Keeper) setPool(ctx sdk.Context, p Pool) {
store := ctx.KVStore(k.storeKey)
b, err := k.cdc.MarshalBinary(p)
b, err := k.cdc.MarshalJSON(p)
if err != nil {
panic(err)
}
store.Set(PoolKey, b)
k.gs = Pool{} // clear the cache
k.pool = Pool{} //clear the cache
}

View File

@ -1,7 +1,6 @@
package stake
import (
"bytes"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -40,15 +39,6 @@ func TestCandidate(t *testing.T) {
}
}
candidatesEqual := func(c1, c2 Candidate) bool {
return c1.Status == c2.Status &&
c1.PubKey.Equals(c2.PubKey) &&
bytes.Equal(c1.Address, c2.Address) &&
c1.Assets.Equal(c2.Assets) &&
c1.Liabilities.Equal(c2.Liabilities) &&
c1.Description == c2.Description
}
// check the empty keeper first
_, found := keeper.GetCandidate(ctx, addrVals[0])
assert.False(t, found)
@ -119,13 +109,6 @@ func TestBond(t *testing.T) {
Shares: sdk.NewRat(9),
}
bondsEqual := func(b1, b2 DelegatorBond) bool {
return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) &&
bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) &&
b1.Height == b2.Height &&
b1.Shares == b2.Shares
}
// check the empty keeper first
_, found := keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0])
assert.False(t, found)
@ -460,8 +443,8 @@ func TestGetAccUpdateValidators(t *testing.T) {
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.Equal(t, candidates[0].validator(), vals[1])
assert.Equal(t, candidates[1].validator(), vals[0])
assert.True(t, validatorsEqual(candidates[0].validator(), vals[1]))
assert.True(t, validatorsEqual(candidates[1].validator(), vals[0]))
// test identical,
// candidate set: {c1, c3} -> {c1, c3}
@ -654,10 +637,10 @@ func TestIsRecentValidator(t *testing.T) {
keeper.setCandidate(ctx, candidatesIn[1])
validators = keeper.GetValidators(ctx)
require.Equal(t, 2, len(validators))
assert.Equal(t, candidatesIn[0].validator(), validators[0])
assert.True(t, validatorsEqual(candidatesIn[0].validator(), validators[0]))
c1ValWithCounter := candidatesIn[1].validator()
c1ValWithCounter.Counter = int16(1)
assert.Equal(t, c1ValWithCounter, validators[1])
assert.True(t, validatorsEqual(c1ValWithCounter, validators[1]))
// test a basic retrieve of something that should be a recent validator
assert.True(t, keeper.IsRecentValidator(ctx, candidatesIn[0].Address))

View File

@ -204,7 +204,7 @@ func (msg MsgUnbond) ValidateBasic() sdk.Error {
if err != nil {
return ErrBadShares(DefaultCodespace)
}
if rat.IsZero() || rat.LT(sdk.ZeroRat) {
if rat.IsZero() || rat.LT(sdk.ZeroRat()) {
return ErrBadShares(DefaultCodespace)
}
}

View File

@ -9,13 +9,13 @@ func (p Pool) bondedRatio() sdk.Rat {
if p.TotalSupply > 0 {
return sdk.NewRat(p.BondedPool, p.TotalSupply)
}
return sdk.ZeroRat
return sdk.ZeroRat()
}
// get the exchange rate of bonded token per issued share
func (p Pool) bondedShareExRate() sdk.Rat {
if p.BondedShares.IsZero() {
return sdk.OneRat
return sdk.OneRat()
}
return sdk.NewRat(p.BondedPool).Quo(p.BondedShares)
}
@ -23,7 +23,7 @@ func (p Pool) bondedShareExRate() sdk.Rat {
// get the exchange rate of unbonded tokens held in candidates per issued share
func (p Pool) unbondedShareExRate() sdk.Rat {
if p.UnbondedShares.IsZero() {
return sdk.OneRat
return sdk.OneRat()
}
return sdk.NewRat(p.UnbondedPool).Quo(p.UnbondedShares)
}
@ -51,7 +51,7 @@ func (p Pool) unbondedToBondedPool(candidate Candidate) (Pool, Candidate) {
//_______________________________________________________________________
func (p Pool) addTokensBonded(amount int64) (p2 Pool, issuedShares sdk.Rat) {
issuedShares = sdk.NewRat(amount).Quo(p.bondedShareExRate()) // (tokens/shares)^-1 * tokens
issuedShares = sdk.NewRat(amount).Quo(p.bondedShareExRate()) // tokens * (shares/tokens)
p.BondedPool += amount
p.BondedShares = p.BondedShares.Add(issuedShares)
return p, issuedShares
@ -65,7 +65,7 @@ func (p Pool) removeSharesBonded(shares sdk.Rat) (p2 Pool, removedTokens int64)
}
func (p Pool) addTokensUnbonded(amount int64) (p2 Pool, issuedShares sdk.Rat) {
issuedShares = p.unbondedShareExRate().Inv().Mul(sdk.NewRat(amount)) // (tokens/shares)^-1 * tokens
issuedShares = sdk.NewRat(amount).Quo(p.unbondedShareExRate()) // tokens * (shares/tokens)
p.UnbondedShares = p.UnbondedShares.Add(issuedShares)
p.UnbondedPool += amount
return p, issuedShares

View File

@ -22,7 +22,7 @@ func TestBondedRatio(t *testing.T) {
pool.TotalSupply = 0
// avoids divide-by-zero
require.Equal(t, pool.bondedRatio(), sdk.ZeroRat)
require.Equal(t, pool.bondedRatio(), sdk.ZeroRat())
}
func TestBondedShareExRate(t *testing.T) {
@ -33,10 +33,10 @@ func TestBondedShareExRate(t *testing.T) {
// bonded pool / bonded shares
require.Equal(t, pool.bondedShareExRate(), sdk.NewRat(3).Quo(sdk.NewRat(10)))
pool.BondedShares = sdk.ZeroRat
pool.BondedShares = sdk.ZeroRat()
// avoids divide-by-zero
require.Equal(t, pool.bondedShareExRate(), sdk.OneRat)
require.Equal(t, pool.bondedShareExRate(), sdk.OneRat())
}
func TestUnbondedShareExRate(t *testing.T) {
@ -47,24 +47,24 @@ func TestUnbondedShareExRate(t *testing.T) {
// unbonded pool / unbonded shares
require.Equal(t, pool.unbondedShareExRate(), sdk.NewRat(3).Quo(sdk.NewRat(10)))
pool.UnbondedShares = sdk.ZeroRat
pool.UnbondedShares = sdk.ZeroRat()
// avoids divide-by-zero
require.Equal(t, pool.unbondedShareExRate(), sdk.OneRat)
require.Equal(t, pool.unbondedShareExRate(), sdk.OneRat())
}
func TestBondedToUnbondedPool(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
poolA := keeper.GetPool(ctx)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
candA := Candidate{
Status: Bonded,
Address: addrs[0],
PubKey: pks[0],
Assets: sdk.OneRat,
Liabilities: sdk.OneRat,
Assets: sdk.OneRat(),
Liabilities: sdk.OneRat(),
}
poolB, candB := poolA.bondedToUnbondedPool(candA)
@ -84,14 +84,14 @@ func TestUnbonbedtoBondedPool(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
poolA := keeper.GetPool(ctx)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
candA := Candidate{
Status: Bonded,
Address: addrs[0],
PubKey: pks[0],
Assets: sdk.OneRat,
Liabilities: sdk.OneRat,
Assets: sdk.OneRat(),
Liabilities: sdk.OneRat(),
}
candA.Status = Unbonded
poolB, candB := poolA.unbondedToBondedPool(candA)
@ -112,65 +112,64 @@ func TestAddTokensBonded(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
poolA := keeper.GetPool(ctx)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
poolB, sharesB := poolA.addTokensBonded(10)
assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat())
// correct changes to bonded shares and bonded pool
assert.Equal(t, poolB.BondedShares, poolA.BondedShares.Add(sharesB))
assert.Equal(t, poolB.BondedPool, poolA.BondedPool+10)
// same number of bonded shares / tokens when exchange rate is one
assert.Equal(t, poolB.BondedShares, sdk.NewRat(poolB.BondedPool))
assert.True(t, poolB.BondedShares.Equal(sdk.NewRat(poolB.BondedPool)))
}
func TestRemoveSharesBonded(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
poolA := keeper.GetPool(ctx)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat())
poolB, tokensB := poolA.removeSharesBonded(sdk.NewRat(10))
assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat())
// correct changes to bonded shares and bonded pool
assert.Equal(t, poolB.BondedShares, poolA.BondedShares.Sub(sdk.NewRat(10)))
assert.Equal(t, poolB.BondedPool, poolA.BondedPool-tokensB)
// same number of bonded shares / tokens when exchange rate is one
assert.Equal(t, poolB.BondedShares, sdk.NewRat(poolB.BondedPool))
assert.True(t, poolB.BondedShares.Equal(sdk.NewRat(poolB.BondedPool)))
}
func TestAddTokensUnbonded(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
poolA := keeper.GetPool(ctx)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
poolB, sharesB := poolA.addTokensUnbonded(10)
assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat())
// correct changes to unbonded shares and unbonded pool
assert.Equal(t, poolB.UnbondedShares, poolA.UnbondedShares.Add(sharesB))
assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool+10)
// same number of unbonded shares / tokens when exchange rate is one
assert.Equal(t, poolB.UnbondedShares, sdk.NewRat(poolB.UnbondedPool))
assert.True(t, poolB.UnbondedShares.Equal(sdk.NewRat(poolB.UnbondedPool)))
}
func TestRemoveSharesUnbonded(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
poolA := keeper.GetPool(ctx)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat())
poolB, tokensB := poolA.removeSharesUnbonded(sdk.NewRat(10))
assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat())
// correct changes to unbonded shares and bonded pool
assert.Equal(t, poolB.UnbondedShares, poolA.UnbondedShares.Sub(sdk.NewRat(10)))
assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool-tokensB)
// same number of unbonded shares / tokens when exchange rate is one
assert.Equal(t, poolB.UnbondedShares, sdk.NewRat(poolB.UnbondedPool))
assert.True(t, poolB.UnbondedShares.Equal(sdk.NewRat(poolB.UnbondedPool)))
}
func TestCandidateAddTokens(t *testing.T) {
@ -186,9 +185,9 @@ func TestCandidateAddTokens(t *testing.T) {
}
poolA.BondedPool = candA.Assets.Evaluate()
poolA.BondedShares = candA.Assets
assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat)
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)
// shares were issued
@ -212,9 +211,9 @@ func TestCandidateRemoveShares(t *testing.T) {
}
poolA.BondedPool = candA.Assets.Evaluate()
poolA.BondedShares = candA.Assets
assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat)
assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat)
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))
// coins were created
@ -280,8 +279,8 @@ func randomCandidate(r *rand.Rand) Candidate {
func randomSetup(r *rand.Rand, numCandidates int) (Pool, Candidates) {
pool := Pool{
TotalSupply: 0,
BondedShares: sdk.ZeroRat,
UnbondedShares: sdk.ZeroRat,
BondedShares: sdk.ZeroRat(),
UnbondedShares: sdk.ZeroRat(),
BondedPool: 0,
UnbondedPool: 0,
InflationLastTime: 0,
@ -380,29 +379,29 @@ func assertInvariants(t *testing.T, msg string,
pMod.UnbondedPool, pMod.BondedPool, tokens)
// nonnegative bonded shares
require.False(t, pMod.BondedShares.LT(sdk.ZeroRat),
require.False(t, pMod.BondedShares.LT(sdk.ZeroRat()),
"Negative bonded shares - msg: %v\npOrig: %#v\npMod: %#v\ntokens: %v\n",
msg, pOrig, pMod, tokens)
// nonnegative unbonded shares
require.False(t, pMod.UnbondedShares.LT(sdk.ZeroRat),
require.False(t, pMod.UnbondedShares.LT(sdk.ZeroRat()),
"Negative unbonded shares - msg: %v\npOrig: %#v\npMod: %#v\ntokens: %v\n",
msg, pOrig, pMod, tokens)
// nonnegative bonded ex rate
require.False(t, pMod.bondedShareExRate().LT(sdk.ZeroRat),
require.False(t, pMod.bondedShareExRate().LT(sdk.ZeroRat()),
"Applying operation \"%s\" resulted in negative bondedShareExRate: %d",
msg, pMod.bondedShareExRate().Evaluate())
// nonnegative unbonded ex rate
require.False(t, pMod.unbondedShareExRate().LT(sdk.ZeroRat),
require.False(t, pMod.unbondedShareExRate().LT(sdk.ZeroRat()),
"Applying operation \"%s\" resulted in negative unbondedShareExRate: %d",
msg, pMod.unbondedShareExRate().Evaluate())
for _, cMod := range cMods {
// nonnegative ex rate
require.False(t, cMod.delegatorShareExRate().LT(sdk.ZeroRat),
require.False(t, cMod.delegatorShareExRate().LT(sdk.ZeroRat()),
"Applying operation \"%s\" resulted in negative candidate.delegatorShareExRate(): %v (candidate.Address: %s)",
msg,
cMod.delegatorShareExRate(),
@ -410,7 +409,7 @@ func assertInvariants(t *testing.T, msg string,
)
// nonnegative assets
require.False(t, cMod.Assets.LT(sdk.ZeroRat),
require.False(t, cMod.Assets.LT(sdk.ZeroRat()),
"Applying operation \"%s\" resulted in negative candidate.Assets: %v (candidate.Liabilities: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)",
msg,
cMod.Assets,
@ -420,7 +419,7 @@ func assertInvariants(t *testing.T, msg string,
)
// nonnegative liabilities
require.False(t, cMod.Liabilities.LT(sdk.ZeroRat),
require.False(t, cMod.Liabilities.LT(sdk.ZeroRat()),
"Applying operation \"%s\" resulted in negative candidate.Liabilities: %v (candidate.Assets: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)",
msg,
cMod.Liabilities,
@ -449,7 +448,7 @@ func TestPossibleOverflow(t *testing.T) {
pool := Pool{
TotalSupply: 0,
BondedShares: assets,
UnbondedShares: sdk.ZeroRat,
UnbondedShares: sdk.ZeroRat(),
BondedPool: assets.Evaluate(),
UnbondedPool: 0,
InflationLastTime: 0,
@ -461,7 +460,7 @@ func TestPossibleOverflow(t *testing.T) {
_, newCandidate, _ := pool.candidateAddTokens(cand, tokens)
msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg)
require.False(t, newCandidate.delegatorShareExRate().LT(sdk.ZeroRat),
require.False(t, newCandidate.delegatorShareExRate().LT(sdk.ZeroRat()),
"Applying operation \"%s\" resulted in negative delegatorShareExRate(): %v",
msg, newCandidate.delegatorShareExRate())
}

View File

@ -1,6 +1,7 @@
package stake
import (
"bytes"
"encoding/hex"
"testing"
@ -50,6 +51,30 @@ var (
emptyPubkey crypto.PubKey
)
func validatorsEqual(b1, b2 Validator) bool {
return bytes.Equal(b1.Address, b2.Address) &&
b1.PubKey.Equals(b2.PubKey) &&
b1.Power.Equal(b2.Power) &&
b1.Height == b2.Height &&
b1.Counter == b2.Counter
}
func candidatesEqual(c1, c2 Candidate) bool {
return c1.Status == c2.Status &&
c1.PubKey.Equals(c2.PubKey) &&
bytes.Equal(c1.Address, c2.Address) &&
c1.Assets.Equal(c2.Assets) &&
c1.Liabilities.Equal(c2.Liabilities) &&
c1.Description == c2.Description
}
func bondsEqual(b1, b2 DelegatorBond) bool {
return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) &&
bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) &&
b1.Height == b2.Height &&
b1.Shares.Equal(b2.Shares)
}
// default params for testing
func defaultParams() Params {
return Params{
@ -66,8 +91,8 @@ func defaultParams() Params {
func initialPool() Pool {
return Pool{
TotalSupply: 0,
BondedShares: sdk.ZeroRat,
UnbondedShares: sdk.ZeroRat,
BondedShares: sdk.ZeroRat(),
UnbondedShares: sdk.ZeroRat(),
BondedPool: 0,
UnbondedPool: 0,
InflationLastTime: 0,
@ -112,9 +137,9 @@ func makeTestCodec() *wire.Codec {
func paramsNoInflation() Params {
return Params{
InflationRateChange: sdk.ZeroRat,
InflationMax: sdk.ZeroRat,
InflationMin: sdk.ZeroRat,
InflationRateChange: sdk.ZeroRat(),
InflationMax: sdk.ZeroRat(),
InflationMin: sdk.ZeroRat(),
GoalBonded: sdk.NewRat(67, 100),
MaxValidators: 100,
BondDenom: "fermion",

View File

@ -62,7 +62,7 @@ func (k Keeper) nextInflation(ctx sdk.Context) (inflation sdk.Rat) {
// 7% and 20%.
// (1 - bondedRatio/GoalBonded) * InflationRateChange
inflationRateChangePerYear := sdk.OneRat.Sub(pool.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange)
inflationRateChangePerYear := sdk.OneRat().Sub(pool.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange)
inflationRateChange := inflationRateChangePerYear.Quo(hrsPerYrRat)
// increase the new annual inflation for this next cycle

View File

@ -29,22 +29,22 @@ func TestGetInflation(t *testing.T) {
// 100% bonded, starting at 20% inflation and being reduced
// (1 - (1/0.67))*(0.13/8667)
{"test 2", 1, 1, sdk.NewRat(20, 100),
sdk.OneRat.Sub(sdk.OneRat.Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
sdk.OneRat().Sub(sdk.OneRat().Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
// 50% bonded, starting at 10% inflation and being increased
{"test 3", 1, 2, sdk.NewRat(10, 100),
sdk.OneRat.Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
sdk.OneRat().Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
// test 7% minimum stop (testing with 100% bonded)
{"test 4", 1, 1, sdk.NewRat(7, 100), sdk.ZeroRat},
{"test 4", 1, 1, sdk.NewRat(7, 100), sdk.ZeroRat()},
{"test 5", 1, 1, sdk.NewRat(70001, 1000000), sdk.NewRat(-1, 1000000).Round(precision)},
// test 20% maximum stop (testing with 0% bonded)
{"test 6", 0, 0, sdk.NewRat(20, 100), sdk.ZeroRat},
{"test 6", 0, 0, sdk.NewRat(20, 100), sdk.ZeroRat()},
{"test 7", 0, 0, sdk.NewRat(199999, 1000000), sdk.NewRat(1, 1000000).Round(precision)},
// perfect balance shouldn't change inflation
{"test 8", 67, 100, sdk.NewRat(15, 100), sdk.ZeroRat},
{"test 8", 67, 100, sdk.NewRat(15, 100), sdk.ZeroRat()},
}
for _, tc := range tests {
pool.BondedPool, pool.TotalSupply = tc.setBondedPool, tc.setTotalSupply
@ -97,7 +97,7 @@ func TestProcessProvisions(t *testing.T) {
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, totalSupply)), "%v", pool.bondedRatio())
// test the value of candidate shares
assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat), "%v", pool.bondedShareExRate())
assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate())
initialSupply := pool.TotalSupply
initialUnbonded := pool.TotalSupply - pool.BondedPool
@ -121,14 +121,13 @@ func TestProcessProvisions(t *testing.T) {
//panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedPool, pool.TotalSupply-pool.BondedPool))
// initial bonded ratio ~ from 27% to 40% increase for bonded holders ownership of total supply
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(271734723, 671734723)), "%v", pool.bondedRatio())
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(211813022, 611813022)), "%v", pool.bondedRatio())
// global supply
assert.Equal(t, int64(671734723), pool.TotalSupply)
assert.Equal(t, int64(271734723), pool.BondedPool)
assert.Equal(t, int64(611813022), pool.TotalSupply)
assert.Equal(t, int64(211813022), pool.BondedPool)
assert.Equal(t, unbondedShares, pool.UnbondedPool)
// test the value of candidate shares
assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(271734723)), "%v", pool.bondedShareExRate())
assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(211813022)), "%v", pool.bondedShareExRate())
}

View File

@ -28,6 +28,15 @@ type Params struct {
BondDenom string `json:"bond_denom"` // bondable coin denomination
}
func (p Params) equal(p2 Params) bool {
return p.InflationRateChange.Equal(p2.InflationRateChange) &&
p.InflationMax.Equal(p2.InflationMax) &&
p.InflationMin.Equal(p2.InflationMin) &&
p.GoalBonded.Equal(p2.GoalBonded) &&
p.MaxValidators == p2.MaxValidators &&
p.BondDenom == p2.BondDenom
}
//_________________________________________________________________________
// Pool - dynamic parameters of the current state
@ -41,6 +50,16 @@ type Pool struct {
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
}
func (p Pool) equal(p2 Pool) bool {
return p.BondedShares.Equal(p2.BondedShares) &&
p.UnbondedShares.Equal(p2.UnbondedShares) &&
p.Inflation.Equal(p2.Inflation) &&
p.TotalSupply == p2.TotalSupply &&
p.BondedPool == p2.BondedPool &&
p.UnbondedPool == p2.UnbondedPool &&
p.InflationLastTime == p2.InflationLastTime
}
//_________________________________________________________________________
// CandidateStatus - status of a validator-candidate
@ -80,8 +99,8 @@ func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Descrip
Status: Unbonded,
Address: address,
PubKey: pubKey,
Assets: sdk.ZeroRat,
Liabilities: sdk.ZeroRat,
Assets: sdk.ZeroRat(),
Liabilities: sdk.ZeroRat(),
Description: description,
ValidatorBondHeight: int64(0),
ValidatorBondCounter: int16(0),
@ -108,7 +127,7 @@ 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.Liabilities.IsZero() {
return sdk.OneRat
return sdk.OneRat()
}
return c.Assets.Quo(c.Liabilities)
}

View File

@ -1,7 +1,6 @@
package stake
import (
"bytes"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -37,13 +36,6 @@ func TestViewSlashBond(t *testing.T) {
viewSlashKeeper := NewViewSlashKeeper(keeper)
bondsEqual := func(b1, b2 DelegatorBond) bool {
return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) &&
bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) &&
b1.Height == b2.Height &&
b1.Shares == b2.Shares
}
// check the empty keeper first
_, found := viewSlashKeeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0])
assert.False(t, found)