ported over rational

This commit is contained in:
rigelrozanski 2018-02-23 13:13:55 +00:00
parent 514470b4d6
commit c8c85dfbc8
6 changed files with 194 additions and 218 deletions

View File

@ -10,8 +10,10 @@ import (
wire "github.com/tendermint/go-wire" wire "github.com/tendermint/go-wire"
) )
var ratCdc = RegisterWire(wire.NewCodec())
// add rational codec elements to provided codec // add rational codec elements to provided codec
func RationalCodec(cdc *wire.Codec) *wire.Codec { func RegisterWire(cdc *wire.Codec) *wire.Codec {
cdc.RegisterInterface((*Rational)(nil), nil) cdc.RegisterInterface((*Rational)(nil), nil)
cdc.RegisterConcrete(Rat{}, "rat", nil) cdc.RegisterConcrete(Rat{}, "rat", nil)
return cdc return cdc
@ -55,7 +57,7 @@ var (
) )
// New - create a new Rat from integers // New - create a new Rat from integers
func NewRational(Numerator int64, Denominator ...int64) Rat { func NewRat(Numerator int64, Denominator ...int64) Rat {
switch len(Denominator) { switch len(Denominator) {
case 0: case 0:
return Rat{big.NewRat(Numerator, 1)} return Rat{big.NewRat(Numerator, 1)}
@ -67,7 +69,7 @@ func NewRational(Numerator int64, Denominator ...int64) Rat {
} }
//NewFromDecimal - create a rational from decimal string or integer string //NewFromDecimal - create a rational from decimal string or integer string
func NewRationlFromDecimal(decimalStr string) (f Rat, err error) { func NewRatFromDecimal(decimalStr string) (f Rat, err error) {
// first extract any negative symbol // first extract any negative symbol
neg := false neg := false
@ -183,7 +185,7 @@ type RatMarshal struct {
// MarshalJSON - custom implementation of JSON Marshal // MarshalJSON - custom implementation of JSON Marshal
func (r Rat) MarshalJSON() ([]byte, error) { func (r Rat) MarshalJSON() ([]byte, error) {
return cdc.MarshalJSON(RatMarshal{r.Num(), r.Denom()}) return ratCdc.MarshalJSON(RatMarshal{r.Num(), r.Denom()})
} }
// UnmarshalJSON - custom implementation of JSON Unmarshal // UnmarshalJSON - custom implementation of JSON Unmarshal
@ -195,7 +197,7 @@ func (r *Rat) UnmarshalJSON(data []byte) (err error) {
}() }()
ratMar := new(RatMarshal) ratMar := new(RatMarshal)
if err := cdc.UnmarshalJSON(data, ratMar); err != nil { if err := ratCdc.UnmarshalJSON(data, ratMar); err != nil {
return err return err
} }
r.Rat = big.NewRat(ratMar.Numerator, ratMar.Denominator) r.Rat = big.NewRat(ratMar.Numerator, ratMar.Denominator)

View File

@ -5,37 +5,33 @@ import (
"math/big" "math/big"
"testing" "testing"
asrt "github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
rqr "github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestNew(t *testing.T) { func TestNew(t *testing.T) {
assert := asrt.New(t) assert.Equal(t, NewRat(1), NewRat(1, 1))
assert.Equal(t, NewRat(100), NewRat(100, 1))
assert.Equal(New(1), New(1, 1)) assert.Equal(t, NewRat(-1), NewRat(-1, 1))
assert.Equal(New(100), New(100, 1)) assert.Equal(t, NewRat(-100), NewRat(-100, 1))
assert.Equal(New(-1), New(-1, 1)) assert.Equal(t, NewRat(0), NewRat(0, 1))
assert.Equal(New(-100), New(-100, 1))
assert.Equal(New(0), New(0, 1))
// do not allow for more than 2 variables // do not allow for more than 2 variables
assert.Panics(func() { New(1, 1, 1) }) assert.Panics(t, func() { NewRat(1, 1, 1) })
} }
func TestNewFromDecimal(t *testing.T) { func TestNewFromDecimal(t *testing.T) {
assert := asrt.New(t)
tests := []struct { tests := []struct {
decimalStr string decimalStr string
expErr bool expErr bool
exp Rat exp Rat
}{ }{
{"0", false, New(0)}, {"0", false, NewRat(0)},
{"1", false, New(1)}, {"1", false, NewRat(1)},
{"1.1", false, New(11, 10)}, {"1.1", false, NewRat(11, 10)},
{"0.75", false, New(3, 4)}, {"0.75", false, NewRat(3, 4)},
{"0.8", false, New(4, 5)}, {"0.8", false, NewRat(4, 5)},
{"0.11111", false, New(11111, 100000)}, {"0.11111", false, NewRat(11111, 100000)},
{".", true, Rat{}}, {".", true, Rat{}},
{".0", true, Rat{}}, {".0", true, Rat{}},
{"1.", true, Rat{}}, {"1.", true, Rat{}},
@ -46,206 +42,192 @@ func TestNewFromDecimal(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
res, err := NewFromDecimal(tc.decimalStr) res, err := NewRatFromDecimal(tc.decimalStr)
if tc.expErr { if tc.expErr {
assert.NotNil(err, tc.decimalStr) assert.NotNil(t, err, tc.decimalStr)
} else { } else {
assert.Nil(err) assert.Nil(t, err)
assert.True(res.Equal(tc.exp)) assert.True(t, res.Equal(tc.exp))
} }
// negative tc // negative tc
res, err = NewFromDecimal("-" + tc.decimalStr) res, err = NewRatFromDecimal("-" + tc.decimalStr)
if tc.expErr { if tc.expErr {
assert.NotNil(err, tc.decimalStr) assert.NotNil(t, err, tc.decimalStr)
} else { } else {
assert.Nil(err) assert.Nil(t, err)
assert.True(res.Equal(tc.exp.Mul(New(-1)))) assert.True(t, res.Equal(tc.exp.Mul(NewRat(-1))))
} }
} }
} }
func TestEqualities(t *testing.T) { func TestEqualities(t *testing.T) {
assert := asrt.New(t)
tests := []struct { tests := []struct {
r1, r2 Rat r1, r2 Rat
gt, lt, eq bool gt, lt, eq bool
}{ }{
{New(0), New(0), false, false, true}, {NewRat(0), NewRat(0), false, false, true},
{New(0, 100), New(0, 10000), false, false, true}, {NewRat(0, 100), NewRat(0, 10000), false, false, true},
{New(100), New(100), false, false, true}, {NewRat(100), NewRat(100), false, false, true},
{New(-100), New(-100), false, false, true}, {NewRat(-100), NewRat(-100), false, false, true},
{New(-100, -1), New(100), false, false, true}, {NewRat(-100, -1), NewRat(100), false, false, true},
{New(-1, 1), New(1, -1), false, false, true}, {NewRat(-1, 1), NewRat(1, -1), false, false, true},
{New(1, -1), New(-1, 1), false, false, true}, {NewRat(1, -1), NewRat(-1, 1), false, false, true},
{New(3, 7), New(3, 7), false, false, true}, {NewRat(3, 7), NewRat(3, 7), false, false, true},
{New(0), New(3, 7), false, true, false}, {NewRat(0), NewRat(3, 7), false, true, false},
{New(0), New(100), false, true, false}, {NewRat(0), NewRat(100), false, true, false},
{New(-1), New(3, 7), false, true, false}, {NewRat(-1), NewRat(3, 7), false, true, false},
{New(-1), New(100), false, true, false}, {NewRat(-1), NewRat(100), false, true, false},
{New(1, 7), New(100), false, true, false}, {NewRat(1, 7), NewRat(100), false, true, false},
{New(1, 7), New(3, 7), false, true, false}, {NewRat(1, 7), NewRat(3, 7), false, true, false},
{New(-3, 7), New(-1, 7), false, true, false}, {NewRat(-3, 7), NewRat(-1, 7), false, true, false},
{New(3, 7), New(0), true, false, false}, {NewRat(3, 7), NewRat(0), true, false, false},
{New(100), New(0), true, false, false}, {NewRat(100), NewRat(0), true, false, false},
{New(3, 7), New(-1), true, false, false}, {NewRat(3, 7), NewRat(-1), true, false, false},
{New(100), New(-1), true, false, false}, {NewRat(100), NewRat(-1), true, false, false},
{New(100), New(1, 7), true, false, false}, {NewRat(100), NewRat(1, 7), true, false, false},
{New(3, 7), New(1, 7), true, false, false}, {NewRat(3, 7), NewRat(1, 7), true, false, false},
{New(-1, 7), New(-3, 7), true, false, false}, {NewRat(-1, 7), NewRat(-3, 7), true, false, false},
} }
for _, tc := range tests { for _, tc := range tests {
assert.Equal(tc.gt, tc.r1.GT(tc.r2)) assert.Equal(t, tc.gt, tc.r1.GT(tc.r2))
assert.Equal(tc.lt, tc.r1.LT(tc.r2)) assert.Equal(t, tc.lt, tc.r1.LT(tc.r2))
assert.Equal(tc.eq, tc.r1.Equal(tc.r2)) assert.Equal(t, tc.eq, tc.r1.Equal(tc.r2))
} }
} }
func TestArithmatic(t *testing.T) { func TestArithmatic(t *testing.T) {
assert := asrt.New(t)
tests := []struct { tests := []struct {
r1, r2 Rat r1, r2 Rat
resMul, resDiv, resAdd, resSub Rat resMul, resDiv, resAdd, resSub Rat
}{ }{
// r1 r2 MUL DIV ADD SUB // r1 r2 MUL DIV ADD SUB
{New(0), New(0), New(0), New(0), New(0), New(0)}, {NewRat(0), NewRat(0), NewRat(0), NewRat(0), NewRat(0), NewRat(0)},
{New(1), New(0), New(0), New(0), New(1), New(1)}, {NewRat(1), NewRat(0), NewRat(0), NewRat(0), NewRat(1), NewRat(1)},
{New(0), New(1), New(0), New(0), New(1), New(-1)}, {NewRat(0), NewRat(1), NewRat(0), NewRat(0), NewRat(1), NewRat(-1)},
{New(0), New(-1), New(0), New(0), New(-1), New(1)}, {NewRat(0), NewRat(-1), NewRat(0), NewRat(0), NewRat(-1), NewRat(1)},
{New(-1), New(0), New(0), New(0), New(-1), New(-1)}, {NewRat(-1), NewRat(0), NewRat(0), NewRat(0), NewRat(-1), NewRat(-1)},
{New(1), New(1), New(1), New(1), New(2), New(0)}, {NewRat(1), NewRat(1), NewRat(1), NewRat(1), NewRat(2), NewRat(0)},
{New(-1), New(-1), New(1), New(1), New(-2), New(0)}, {NewRat(-1), NewRat(-1), NewRat(1), NewRat(1), NewRat(-2), NewRat(0)},
{New(1), New(-1), New(-1), New(-1), New(0), New(2)}, {NewRat(1), NewRat(-1), NewRat(-1), NewRat(-1), NewRat(0), NewRat(2)},
{New(-1), New(1), New(-1), New(-1), New(0), New(-2)}, {NewRat(-1), NewRat(1), NewRat(-1), NewRat(-1), NewRat(0), NewRat(-2)},
{New(3), New(7), New(21), New(3, 7), New(10), New(-4)}, {NewRat(3), NewRat(7), NewRat(21), NewRat(3, 7), NewRat(10), NewRat(-4)},
{New(2), New(4), New(8), New(1, 2), New(6), New(-2)}, {NewRat(2), NewRat(4), NewRat(8), NewRat(1, 2), NewRat(6), NewRat(-2)},
{New(100), New(100), New(10000), New(1), New(200), New(0)}, {NewRat(100), NewRat(100), NewRat(10000), NewRat(1), NewRat(200), NewRat(0)},
{New(3, 2), New(3, 2), New(9, 4), New(1), New(3), New(0)}, {NewRat(3, 2), NewRat(3, 2), NewRat(9, 4), NewRat(1), NewRat(3), NewRat(0)},
{New(3, 7), New(7, 3), New(1), New(9, 49), New(58, 21), New(-40, 21)}, {NewRat(3, 7), NewRat(7, 3), NewRat(1), NewRat(9, 49), NewRat(58, 21), NewRat(-40, 21)},
{New(1, 21), New(11, 5), New(11, 105), New(5, 231), New(236, 105), New(-226, 105)}, {NewRat(1, 21), NewRat(11, 5), NewRat(11, 105), NewRat(5, 231), NewRat(236, 105), NewRat(-226, 105)},
{New(-21), New(3, 7), New(-9), New(-49), New(-144, 7), New(-150, 7)}, {NewRat(-21), NewRat(3, 7), NewRat(-9), NewRat(-49), NewRat(-144, 7), NewRat(-150, 7)},
{New(100), New(1, 7), New(100, 7), New(700), New(701, 7), New(699, 7)}, {NewRat(100), NewRat(1, 7), NewRat(100, 7), NewRat(700), NewRat(701, 7), NewRat(699, 7)},
} }
for _, tc := range tests { for _, tc := range tests {
assert.True(tc.resMul.Equal(tc.r1.Mul(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.GetRat(), tc.r2.GetRat())
assert.True(tc.resAdd.Equal(tc.r1.Add(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(tc.resSub.Equal(tc.r1.Sub(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())
if tc.r2.Num() == 0 { // panic for divide by zero if tc.r2.Num() == 0 { // panic for divide by zero
assert.Panics(func() { tc.r1.Quo(tc.r2) }) assert.Panics(t, func() { tc.r1.Quo(tc.r2) })
} else { } else {
assert.True(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.GetRat(), tc.r2.GetRat())
} }
} }
} }
func TestEvaluate(t *testing.T) { func TestEvaluate(t *testing.T) {
assert := asrt.New(t)
tests := []struct { tests := []struct {
r1 Rat r1 Rat
res int64 res int64
}{ }{
{New(0), 0}, {NewRat(0), 0},
{New(1), 1}, {NewRat(1), 1},
{New(1, 4), 0}, {NewRat(1, 4), 0},
{New(1, 2), 0}, {NewRat(1, 2), 0},
{New(3, 4), 1}, {NewRat(3, 4), 1},
{New(5, 6), 1}, {NewRat(5, 6), 1},
{New(3, 2), 2}, {NewRat(3, 2), 2},
{New(5, 2), 2}, {NewRat(5, 2), 2},
{New(6, 11), 1}, // 0.545-> 1 even though 5 is first decimal and 1 not even {NewRat(6, 11), 1}, // 0.545-> 1 even though 5 is first decimal and 1 not even
{New(17, 11), 2}, // 1.545 {NewRat(17, 11), 2}, // 1.545
{New(5, 11), 0}, {NewRat(5, 11), 0},
{New(16, 11), 1}, {NewRat(16, 11), 1},
{New(113, 12), 9}, {NewRat(113, 12), 9},
} }
for _, tc := range tests { for _, tc := range tests {
assert.Equal(tc.res, tc.r1.Evaluate(), "%v", tc.r1) assert.Equal(t, tc.res, tc.r1.Evaluate(), "%v", tc.r1)
assert.Equal(tc.res*-1, tc.r1.Mul(New(-1)).Evaluate(), "%v", tc.r1.Mul(New(-1))) assert.Equal(t, tc.res*-1, tc.r1.Mul(NewRat(-1)).Evaluate(), "%v", tc.r1.Mul(NewRat(-1)))
} }
} }
func TestRound(t *testing.T) { func TestRound(t *testing.T) {
assert, require := asrt.New(t), rqr.New(t)
many3 := "333333333333333333333333333333333333333333333" many3 := "333333333333333333333333333333333333333333333"
many7 := "777777777777777777777777777777777777777777777" many7 := "777777777777777777777777777777777777777777777"
big3, worked := new(big.Int).SetString(many3, 10) big3, worked := new(big.Int).SetString(many3, 10)
require.True(worked) require.True(t, worked)
big7, worked := new(big.Int).SetString(many7, 10) big7, worked := new(big.Int).SetString(many7, 10)
require.True(worked) require.True(t, worked)
tests := []struct { tests := []struct {
r1, res Rat r1, res Rat
precFactor int64 precFactor int64
}{ }{
{New(333, 777), New(429, 1000), 1000}, {NewRat(333, 777), NewRat(429, 1000), 1000},
{Rat{new(big.Rat).SetFrac(big3, big7)}, New(429, 1000), 1000}, {Rat{new(big.Rat).SetFrac(big3, big7)}, NewRat(429, 1000), 1000},
{Rat{new(big.Rat).SetFrac(big3, big7)}, New(4285714286, 10000000000), 10000000000}, {Rat{new(big.Rat).SetFrac(big3, big7)}, NewRat(4285714286, 10000000000), 10000000000},
{New(1, 2), New(1, 2), 1000}, {NewRat(1, 2), NewRat(1, 2), 1000},
} }
for _, tc := range tests { for _, tc := range tests {
assert.Equal(tc.res, tc.r1.Round(tc.precFactor), "%v", tc.r1) assert.Equal(t, tc.res, tc.r1.Round(tc.precFactor), "%v", tc.r1)
negR1, negRes := tc.r1.Mul(New(-1)), tc.res.Mul(New(-1)) negR1, negRes := tc.r1.Mul(NewRat(-1)), tc.res.Mul(NewRat(-1))
assert.Equal(negRes, negR1.Round(tc.precFactor), "%v", negR1) assert.Equal(t, negRes, negR1.Round(tc.precFactor), "%v", negR1)
} }
} }
func TestZeroSerializationJSON(t *testing.T) { func TestZeroSerializationJSON(t *testing.T) {
assert := asrt.New(t)
var r Rat var r Rat
err := json.Unmarshal([]byte("{\"numerator\":0,\"denominator\":1}"), &r) err := json.Unmarshal([]byte("{\"numerator\":0,\"denominator\":1}"), &r)
assert.Nil(err) assert.Nil(t, err)
err = json.Unmarshal([]byte("{\"numerator\":0,\"denominator\":0}"), &r) err = json.Unmarshal([]byte("{\"numerator\":0,\"denominator\":0}"), &r)
assert.NotNil(err) assert.NotNil(t, err)
err = json.Unmarshal([]byte("{\"numerator\":1,\"denominator\":0}"), &r) err = json.Unmarshal([]byte("{\"numerator\":1,\"denominator\":0}"), &r)
assert.NotNil(err) assert.NotNil(t, err)
err = json.Unmarshal([]byte("{}"), &r) err = json.Unmarshal([]byte("{}"), &r)
assert.NotNil(err) assert.NotNil(t, err)
} }
func TestSerializationJSON(t *testing.T) { func TestSerializationJSON(t *testing.T) {
assert, require := asrt.New(t), rqr.New(t) r := NewRat(1, 3)
r := New(1, 3)
rMarshal, err := json.Marshal(r) rMarshal, err := json.Marshal(r)
require.Nil(err) require.Nil(t, err)
var rUnmarshal Rat var rUnmarshal Rat
err = json.Unmarshal(rMarshal, &rUnmarshal) err = json.Unmarshal(rMarshal, &rUnmarshal)
require.Nil(err) require.Nil(t, err)
assert.True(r.Equal(rUnmarshal), "original: %v, unmarshalled: %v", r, rUnmarshal) assert.True(t, r.Equal(rUnmarshal), "original: %v, unmarshalled: %v", r, rUnmarshal)
} }
func TestSerializationGoWire(t *testing.T) { func TestSerializationGoWire(t *testing.T) {
assert, require := asrt.New(t), rqr.New(t) r := NewRat(1, 3)
r := New(1, 3) rMarshal, err := ratCdc.MarshalJSON(r)
require.Nil(t, err)
rMarshal, err := cdc.MarshalJSON(r)
require.Nil(err)
var rUnmarshal Rat var rUnmarshal Rat
err = cdc.UnmarshalJSON(rMarshal, &rUnmarshal) err = ratCdc.UnmarshalJSON(rMarshal, &rUnmarshal)
require.Nil(err) require.Nil(t, err)
assert.True(r.Equal(rUnmarshal), "original: %v, unmarshalled: %v", r, rUnmarshal) assert.True(t, r.Equal(rUnmarshal), "original: %v, unmarshalled: %v", r, rUnmarshal)
} }
type testEmbedStruct struct { type testEmbedStruct struct {
@ -255,20 +237,18 @@ type testEmbedStruct struct {
} }
func TestEmbeddedStructSerializationGoWire(t *testing.T) { func TestEmbeddedStructSerializationGoWire(t *testing.T) {
assert, require := asrt.New(t), rqr.New(t) r := testEmbedStruct{"foo", 10, NewRat(1, 3)}
r := testEmbedStruct{"foo", 10, New(1, 3)} rMarshal, err := ratCdc.MarshalJSON(r)
require.Nil(t, err)
rMarshal, err := cdc.MarshalJSON(r)
require.Nil(err)
var rUnmarshal testEmbedStruct var rUnmarshal testEmbedStruct
err = cdc.UnmarshalJSON(rMarshal, &rUnmarshal) err = ratCdc.UnmarshalJSON(rMarshal, &rUnmarshal)
require.Nil(err) require.Nil(t, err)
assert.Equal(r.Field1, rUnmarshal.Field1) assert.Equal(t, r.Field1, rUnmarshal.Field1)
assert.Equal(r.Field2, rUnmarshal.Field2) assert.Equal(t, r.Field2, rUnmarshal.Field2)
assert.True(r.Field3.Equal(rUnmarshal.Field3), "original: %v, unmarshalled: %v", r, rUnmarshal) assert.True(t, r.Field3.Equal(rUnmarshal.Field3), "original: %v, unmarshalled: %v", r, rUnmarshal)
} }
@ -279,18 +259,16 @@ type testEmbedInterface struct {
} }
func TestEmbeddedInterfaceSerializationGoWire(t *testing.T) { func TestEmbeddedInterfaceSerializationGoWire(t *testing.T) {
assert, require := asrt.New(t), rqr.New(t) r := testEmbedInterface{"foo", 10, NewRat(1, 3)}
r := testEmbedInterface{"foo", 10, New(1, 3)} rMarshal, err := ratCdc.MarshalJSON(r)
require.Nil(t, err)
rMarshal, err := cdc.MarshalJSON(r)
require.Nil(err)
var rUnmarshal testEmbedInterface var rUnmarshal testEmbedInterface
err = cdc.UnmarshalJSON(rMarshal, &rUnmarshal) err = ratCdc.UnmarshalJSON(rMarshal, &rUnmarshal)
require.Nil(err) require.Nil(t, err)
assert.Equal(r.Field1, rUnmarshal.Field1) assert.Equal(t, r.Field1, rUnmarshal.Field1)
assert.Equal(r.Field2, rUnmarshal.Field2) assert.Equal(t, r.Field2, rUnmarshal.Field2)
assert.True(r.Field3.Equal(rUnmarshal.Field3), "original: %v, unmarshalled: %v", r, rUnmarshal) assert.True(t, r.Field3.Equal(rUnmarshal.Field3), "original: %v, unmarshalled: %v", r, rUnmarshal)
} }

View File

@ -142,7 +142,7 @@ func updateValidator(store types.KVStore, validator *Validator) {
func removeValidator(store types.KVStore, pubKey crypto.PubKey) { func removeValidator(store types.KVStore, pubKey crypto.PubKey) {
//add validator with zero power to the validator updates //add validator with zero power to the validator updates
b, err := cdc.MarshalJSON(Validator{pubKey, types.Zero}) b, err := cdc.MarshalJSON(Validator{pubKey, types.ZeroRat})
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -26,12 +26,12 @@ import (
//candidates := candidatesFromActors(actors, []int64{400, 200, 100, 10, 1}) //candidates := candidatesFromActors(actors, []int64{400, 200, 100, 10, 1})
//// test a basic change in voting power //// test a basic change in voting power
//candidates[0].Assets = types.New(500) //candidates[0].Assets = types.NewRat(500)
//candidates.updateVotingPower(store, gs, params) //candidates.updateVotingPower(store, gs, params)
//assert.Equal(int64(500), candidates[0].VotingPower.Evaluate(), "%v", candidates[0]) //assert.Equal(int64(500), candidates[0].VotingPower.Evaluate(), "%v", candidates[0])
//// test a swap in voting power //// test a swap in voting power
//candidates[1].Assets = types.New(600) //candidates[1].Assets = types.NewRat(600)
//candidates.updateVotingPower(store, gs, params) //candidates.updateVotingPower(store, gs, params)
//assert.Equal(int64(600), candidates[0].VotingPower.Evaluate(), "%v", candidates[0]) //assert.Equal(int64(600), candidates[0].VotingPower.Evaluate(), "%v", candidates[0])
//assert.Equal(int64(500), candidates[1].VotingPower.Evaluate(), "%v", candidates[1]) //assert.Equal(int64(500), candidates[1].VotingPower.Evaluate(), "%v", candidates[1])
@ -46,11 +46,11 @@ import (
//func TestValidatorsChanged(t *testing.T) { //func TestValidatorsChanged(t *testing.T) {
//require := require.New(t) //require := require.New(t)
//v1 := (&Candidate{PubKey: pks[0], VotingPower: types.New(10)}).validator() //v1 := (&Candidate{PubKey: pks[0], VotingPower: types.NewRat(10)}).validator()
//v2 := (&Candidate{PubKey: pks[1], VotingPower: types.New(10)}).validator() //v2 := (&Candidate{PubKey: pks[1], VotingPower: types.NewRat(10)}).validator()
//v3 := (&Candidate{PubKey: pks[2], VotingPower: types.New(10)}).validator() //v3 := (&Candidate{PubKey: pks[2], VotingPower: types.NewRat(10)}).validator()
//v4 := (&Candidate{PubKey: pks[3], VotingPower: types.New(10)}).validator() //v4 := (&Candidate{PubKey: pks[3], VotingPower: types.NewRat(10)}).validator()
//v5 := (&Candidate{PubKey: pks[4], VotingPower: types.New(10)}).validator() //v5 := (&Candidate{PubKey: pks[4], VotingPower: types.NewRat(10)}).validator()
//// test from nothing to something //// test from nothing to something
//vs1 := []Validator{} //vs1 := []Validator{}
@ -72,17 +72,17 @@ import (
//vs1 = []Validator{v1, v2, v4} //vs1 = []Validator{v1, v2, v4}
//vs2 = []Validator{v1, v2, v4} //vs2 = []Validator{v1, v2, v4}
//changed = vs1.validatorsUpdated(vs2) //changed = vs1.validatorsUpdated(vs2)
//require.Zero(len(changed)) //require.ZeroRat(len(changed))
//// test single value change //// test single value change
//vs2[2].VotingPower = types.One //vs2[2].VotingPower = types.OneRat
//changed = vs1.validatorsUpdated(vs2) //changed = vs1.validatorsUpdated(vs2)
//require.Equal(1, len(changed)) //require.Equal(1, len(changed))
//testChange(t, vs2[2], changed[0]) //testChange(t, vs2[2], changed[0])
//// test multiple value change //// test multiple value change
//vs2[0].VotingPower = types.New(11) //vs2[0].VotingPower = types.NewRat(11)
//vs2[2].VotingPower = types.New(5) //vs2[2].VotingPower = types.NewRat(5)
//changed = vs1.validatorsUpdated(vs2) //changed = vs1.validatorsUpdated(vs2)
//require.Equal(2, len(changed)) //require.Equal(2, len(changed))
//testChange(t, vs2[0], changed[0]) //testChange(t, vs2[0], changed[0])
@ -118,7 +118,7 @@ import (
//testRemove(t, vs1[1], changed[0]) //testRemove(t, vs1[1], changed[0])
//testRemove(t, vs1[2], changed[1]) //testRemove(t, vs1[2], changed[1])
//// test many types of changes //vs2 = []Validator{v1, v3, v4, v5} //vs2[2].VotingPower = types.New(11) //changed = vs1.validatorsUpdated(vs2) //require.Equal(4, len(changed), "%v", changed) // change 1, remove 1, add 2 //testRemove(t, vs1[1], changed[0]) //testChange(t, vs2[1], changed[1]) //testChange(t, vs2[2], changed[2]) //testChange(t, vs2[3], changed[3]) //} //func TestUpdateValidatorSet(t *testing.T) { //assert, require := assert.New(t), require.New(t) //store := initTestStore(t) //params := loadParams(store) //gs := loadGlobalState(store) //N := 5 //// test many types of changes //vs2 = []Validator{v1, v3, v4, v5} //vs2[2].VotingPower = types.NewRat(11) //changed = vs1.validatorsUpdated(vs2) //require.Equal(4, len(changed), "%v", changed) // change 1, remove 1, add 2 //testRemove(t, vs1[1], changed[0]) //testChange(t, vs2[1], changed[1]) //testChange(t, vs2[2], changed[2]) //testChange(t, vs2[3], changed[3]) //} //func TestUpdateValidatorSet(t *testing.T) { //assert, require := assert.New(t), require.New(t) //store := initTestStore(t) //params := loadParams(store) //gs := loadGlobalState(store) //N := 5
//actors := newAddrs(N) //actors := newAddrs(N)
//candidates := candidatesFromActors(actors, []int64{400, 200, 100, 10, 1}) //candidates := candidatesFromActors(actors, []int64{400, 200, 100, 10, 1})
//for _, c := range candidates { //for _, c := range candidates {
@ -141,11 +141,11 @@ import (
//assert.Equal(int64(0), candidates[4].VotingPower.Evaluate()) //assert.Equal(int64(0), candidates[4].VotingPower.Evaluate())
//// mess with the power's of the candidates and test //// mess with the power's of the candidates and test
//candidates[0].Assets = types.New(10) //candidates[0].Assets = types.NewRat(10)
//candidates[1].Assets = types.New(600) //candidates[1].Assets = types.NewRat(600)
//candidates[2].Assets = types.New(1000) //candidates[2].Assets = types.NewRat(1000)
//candidates[3].Assets = types.One //candidates[3].Assets = types.OneRat
//candidates[4].Assets = types.New(10) //candidates[4].Assets = types.NewRat(10)
//for _, c := range candidates { //for _, c := range candidates {
//saveCandidate(store, c) //saveCandidate(store, c)
//} //}
@ -161,8 +161,6 @@ import (
//} //}
func TestState(t *testing.T) { func TestState(t *testing.T) {
assert, require := assert.New(t), require.New(t)
store := initTestStore(t) store := initTestStore(t)
//delegator := crypto.Address{[]byte("addressdelegator")} //delegator := crypto.Address{[]byte("addressdelegator")}
@ -179,9 +177,9 @@ func TestState(t *testing.T) {
candidate := &Candidate{ candidate := &Candidate{
Owner: validator, Owner: validator,
PubKey: pk, PubKey: pk,
Assets: types.New(9), Assets: types.NewRat(9),
Liabilities: types.New(9), Liabilities: types.NewRat(9),
VotingPower: types.Zero, VotingPower: types.ZeroRat,
} }
candidatesEqual := func(c1, c2 *Candidate) bool { candidatesEqual := func(c1, c2 *Candidate) bool {
@ -196,33 +194,33 @@ func TestState(t *testing.T) {
// check the empty store first // check the empty store first
resCand := loadCandidate(store, pk) resCand := loadCandidate(store, pk)
assert.Nil(resCand) assert.Nil(t, resCand)
resPks := loadCandidates(store) resPks := loadCandidates(store)
assert.Zero(len(resPks)) assert.Zero(t, len(resPks))
// set and retrieve a record // set and retrieve a record
saveCandidate(store, candidate) saveCandidate(store, candidate)
resCand = loadCandidate(store, pk) resCand = loadCandidate(store, pk)
//assert.Equal(candidate, resCand) //assert.Equal(candidate, resCand)
assert.True(candidatesEqual(candidate, resCand), "%#v \n %#v", resCand, candidate) assert.True(t, candidatesEqual(candidate, resCand), "%#v \n %#v", resCand, candidate)
// modify a records, save, and retrieve // modify a records, save, and retrieve
candidate.Liabilities = types.New(99) candidate.Liabilities = types.NewRat(99)
saveCandidate(store, candidate) saveCandidate(store, candidate)
resCand = loadCandidate(store, pk) resCand = loadCandidate(store, pk)
assert.True(candidatesEqual(candidate, resCand)) assert.True(t, candidatesEqual(candidate, resCand))
// also test that the pubkey has been added to pubkey list // also test that the pubkey has been added to pubkey list
resPks = loadCandidates(store) resPks = loadCandidates(store)
require.Equal(1, len(resPks)) require.Equal(t, 1, len(resPks))
assert.Equal(pk, resPks[0].PubKey) assert.Equal(t, pk, resPks[0].PubKey)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Bond checks // Bond checks
bond := &DelegatorBond{ bond := &DelegatorBond{
PubKey: pk, PubKey: pk,
Shares: types.New(9), Shares: types.NewRat(9),
} }
bondsEqual := func(b1, b2 *DelegatorBond) bool { bondsEqual := func(b1, b2 *DelegatorBond) bool {
@ -232,18 +230,18 @@ func TestState(t *testing.T) {
//check the empty store first //check the empty store first
resBond := loadDelegatorBond(store, delegator, pk) resBond := loadDelegatorBond(store, delegator, pk)
assert.Nil(resBond) assert.Nil(t, resBond)
//Set and retrieve a record //Set and retrieve a record
saveDelegatorBond(store, delegator, bond) saveDelegatorBond(store, delegator, bond)
resBond = loadDelegatorBond(store, delegator, pk) resBond = loadDelegatorBond(store, delegator, pk)
assert.True(bondsEqual(bond, resBond)) assert.True(t, bondsEqual(bond, resBond))
//modify a records, save, and retrieve //modify a records, save, and retrieve
bond.Shares = types.New(99) bond.Shares = types.NewRat(99)
saveDelegatorBond(store, delegator, bond) saveDelegatorBond(store, delegator, bond)
resBond = loadDelegatorBond(store, delegator, pk) resBond = loadDelegatorBond(store, delegator, pk)
assert.True(bondsEqual(bond, resBond)) assert.True(t, bondsEqual(bond, resBond))
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Param checks // Param checks
@ -252,25 +250,23 @@ func TestState(t *testing.T) {
//check that the empty store loads the default //check that the empty store loads the default
resParams := loadParams(store) resParams := loadParams(store)
assert.Equal(params, resParams) assert.Equal(t, params, resParams)
//modify a params, save, and retrieve //modify a params, save, and retrieve
params.MaxVals = 777 params.MaxVals = 777
saveParams(store, params) saveParams(store, params)
resParams = loadParams(store) resParams = loadParams(store)
assert.Equal(params, resParams) assert.Equal(t, params, resParams)
} }
func TestGetValidators(t *testing.T) { func TestGetValidators(t *testing.T) {
assert, require := assert.New(t), require.New(t)
store := initTestStore(t) store := initTestStore(t)
N := 5 N := 5
addrs := newAddrs(N) addrs := newAddrs(N)
candidatesFromActors(store, addrs, []int64{400, 200, 0, 0, 0}) candidatesFromActors(store, addrs, []int64{400, 200, 0, 0, 0})
validators := getValidators(store, 5) validators := getValidators(store, 5)
require.Equal(2, len(validators)) require.Equal(t, 2, len(validators))
assert.Equal(pks[0], validators[0].PubKey) assert.Equal(t, pks[0], validators[0].PubKey)
assert.Equal(pks[1], validators[1].PubKey) assert.Equal(t, pks[1], validators[1].PubKey)
} }

View File

@ -73,9 +73,9 @@ func candidatesFromActors(store sdk.KVStore, addrs []crypto.Address, amts []int6
Status: Unbonded, Status: Unbonded,
PubKey: pks[i], PubKey: pks[i],
Owner: addrs[i], Owner: addrs[i],
Assets: sdk.New(amts[i]), Assets: sdk.NewRat(amts[i]),
Liabilities: sdk.New(amts[i]), Liabilities: sdk.NewRat(amts[i]),
VotingPower: sdk.New(amts[i]), VotingPower: sdk.NewRat(amts[i]),
} }
saveCandidate(store, c) saveCandidate(store, c)
} }
@ -87,9 +87,9 @@ func candidatesFromActorsEmpty(addrs []crypto.Address) (candidates Candidates) {
Status: Unbonded, Status: Unbonded,
PubKey: pks[i], PubKey: pks[i],
Owner: addrs[i], Owner: addrs[i],
Assets: sdk.Zero, Assets: sdk.ZeroRat,
Liabilities: sdk.Zero, Liabilities: sdk.ZeroRat,
VotingPower: sdk.Zero, VotingPower: sdk.ZeroRat,
} }
candidates = append(candidates, c) candidates = append(candidates, c)
} }

View File

@ -30,10 +30,10 @@ func defaultParams() Params {
return Params{ return Params{
HoldBonded: []byte("77777777777777777777777777777777"), HoldBonded: []byte("77777777777777777777777777777777"),
HoldUnbonded: []byte("88888888888888888888888888888888"), HoldUnbonded: []byte("88888888888888888888888888888888"),
InflationRateChange: sdk.New(13, 100), InflationRateChange: sdk.NewRat(13, 100),
InflationMax: sdk.New(20, 100), InflationMax: sdk.NewRat(20, 100),
InflationMin: sdk.New(7, 100), InflationMin: sdk.NewRat(7, 100),
GoalBonded: sdk.New(67, 100), GoalBonded: sdk.NewRat(67, 100),
MaxVals: 100, MaxVals: 100,
AllowedBondDenom: "fermion", AllowedBondDenom: "fermion",
GasDeclareCandidacy: 20, GasDeclareCandidacy: 20,
@ -61,41 +61,41 @@ type GlobalState struct {
func initialGlobalState() *GlobalState { func initialGlobalState() *GlobalState {
return &GlobalState{ return &GlobalState{
TotalSupply: 0, TotalSupply: 0,
BondedShares: sdk.Zero, BondedShares: sdk.ZeroRat,
UnbondedShares: sdk.Zero, UnbondedShares: sdk.ZeroRat,
BondedPool: 0, BondedPool: 0,
UnbondedPool: 0, UnbondedPool: 0,
InflationLastTime: 0, InflationLastTime: 0,
Inflation: sdk.New(7, 100), Inflation: sdk.NewRat(7, 100),
} }
} }
// get the bond ratio of the global state // get the bond ratio of the global state
func (gs *GlobalState) bondedRatio() sdk.Rational { func (gs *GlobalState) bondedRatio() sdk.Rational {
if gs.TotalSupply > 0 { if gs.TotalSupply > 0 {
return sdk.New(gs.BondedPool, gs.TotalSupply) return sdk.NewRat(gs.BondedPool, gs.TotalSupply)
} }
return sdk.Zero return sdk.ZeroRat
} }
// get the exchange rate of bonded token per issued share // get the exchange rate of bonded token per issued share
func (gs *GlobalState) bondedShareExRate() sdk.Rational { func (gs *GlobalState) bondedShareExRate() sdk.Rational {
if gs.BondedShares.IsZero() { if gs.BondedShares.IsZero() {
return sdk.One return sdk.OneRat
} }
return gs.BondedShares.Inv().Mul(sdk.New(gs.BondedPool)) return gs.BondedShares.Inv().Mul(sdk.NewRat(gs.BondedPool))
} }
// get the exchange rate of unbonded tokens held in candidates per issued share // get the exchange rate of unbonded tokens held in candidates per issued share
func (gs *GlobalState) unbondedShareExRate() sdk.Rational { func (gs *GlobalState) unbondedShareExRate() sdk.Rational {
if gs.UnbondedShares.IsZero() { if gs.UnbondedShares.IsZero() {
return sdk.One return sdk.OneRat
} }
return gs.UnbondedShares.Inv().Mul(sdk.New(gs.UnbondedPool)) return gs.UnbondedShares.Inv().Mul(sdk.NewRat(gs.UnbondedPool))
} }
func (gs *GlobalState) addTokensBonded(amount int64) (issuedShares sdk.Rational) { func (gs *GlobalState) addTokensBonded(amount int64) (issuedShares sdk.Rational) {
issuedShares = gs.bondedShareExRate().Inv().Mul(sdk.New(amount)) // (tokens/shares)^-1 * tokens issuedShares = gs.bondedShareExRate().Inv().Mul(sdk.NewRat(amount)) // (tokens/shares)^-1 * tokens
gs.BondedPool += amount gs.BondedPool += amount
gs.BondedShares = gs.BondedShares.Add(issuedShares) gs.BondedShares = gs.BondedShares.Add(issuedShares)
return return
@ -109,7 +109,7 @@ func (gs *GlobalState) removeSharesBonded(shares sdk.Rational) (removedTokens in
} }
func (gs *GlobalState) addTokensUnbonded(amount int64) (issuedShares sdk.Rational) { func (gs *GlobalState) addTokensUnbonded(amount int64) (issuedShares sdk.Rational) {
issuedShares = gs.unbondedShareExRate().Inv().Mul(sdk.New(amount)) // (tokens/shares)^-1 * tokens issuedShares = gs.unbondedShareExRate().Inv().Mul(sdk.NewRat(amount)) // (tokens/shares)^-1 * tokens
gs.UnbondedShares = gs.UnbondedShares.Add(issuedShares) gs.UnbondedShares = gs.UnbondedShares.Add(issuedShares)
gs.UnbondedPool += amount gs.UnbondedPool += amount
return return
@ -165,9 +165,9 @@ func NewCandidate(pubKey crypto.PubKey, owner crypto.Address, description Descri
Status: Unbonded, Status: Unbonded,
PubKey: pubKey, PubKey: pubKey,
Owner: owner, Owner: owner,
Assets: sdk.Zero, Assets: sdk.ZeroRat,
Liabilities: sdk.Zero, Liabilities: sdk.ZeroRat,
VotingPower: sdk.Zero, VotingPower: sdk.ZeroRat,
Description: description, Description: description,
} }
} }
@ -177,7 +177,7 @@ func NewCandidate(pubKey crypto.PubKey, owner crypto.Address, description Descri
// get the exchange rate of global pool shares over delegator shares // get the exchange rate of global pool shares over delegator shares
func (c *Candidate) delegatorShareExRate() sdk.Rational { func (c *Candidate) delegatorShareExRate() sdk.Rational {
if c.Liabilities.IsZero() { if c.Liabilities.IsZero() {
return sdk.One return sdk.OneRat
} }
return c.Assets.Quo(c.Liabilities) return c.Assets.Quo(c.Liabilities)
} }