types/rational: use encoding/json
minor fixes working on compiling
This commit is contained in:
parent
8e3f8319af
commit
af6c1a3f02
|
@ -109,6 +109,10 @@ func ErrInvalidCoins(msg string) Error {
|
|||
return newError(CodeInvalidCoins, msg)
|
||||
}
|
||||
|
||||
func ErrInvalidCoins(coins Coins) Error {
|
||||
return newError(CodeInvalidCoins, coins.String())
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Error & sdkError
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -13,12 +16,21 @@ import (
|
|||
// __| |_ |_
|
||||
|
||||
// Rat - extend big.Rat
|
||||
// NOTE: never use new(Rat) or else
|
||||
// we will panic unmarshalling into the
|
||||
// nil embedded big.Rat
|
||||
type Rat struct {
|
||||
*big.Rat `json:"rat"`
|
||||
}
|
||||
|
||||
// Rational - big Rat with additional functionality
|
||||
type Rational interface {
|
||||
type Rational = Rat
|
||||
|
||||
// RationalInterface - 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 Rational types that include
|
||||
// the units of the value in the type system.
|
||||
type RationalInterface interface {
|
||||
GetRat() *big.Rat
|
||||
Num() int64
|
||||
Denom() int64
|
||||
|
@ -200,6 +212,37 @@ func (r Rat) Round(precisionFactor int64) Rational {
|
|||
//return nil
|
||||
//}
|
||||
|
||||
//nolint
|
||||
func (r Rat) MarshalJSON() ([]byte, error) { return r.MarshalText() }
|
||||
func (r *Rat) UnmarshalJSON(data []byte) (err error) { return r.UnmarshalText(data) }
|
||||
var ratCdc JSONCodec // TODO wire.Codec
|
||||
|
||||
// Hack to just use json.Marshal for everything until
|
||||
// we update for amino
|
||||
type JSONCodec struct{}
|
||||
|
||||
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) MarshalJSON() ([]byte, error) {
|
||||
bz, err := r.MarshalText()
|
||||
if err != nil {
|
||||
return bz, err
|
||||
}
|
||||
return []byte(fmt.Sprintf(`"%s"`, bz)), nil
|
||||
}
|
||||
|
||||
// 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")
|
||||
}
|
||||
data = bytes.Trim(data, `"`)
|
||||
return r.UnmarshalText(data)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
|
@ -193,41 +192,44 @@ func TestRound(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestZeroSerializationJSON(t *testing.T) {
|
||||
var r Rat
|
||||
err := json.Unmarshal([]byte("{\"numerator\":0,\"denominator\":1}"), &r)
|
||||
r := NewRat(0, 1)
|
||||
err := r.UnmarshalJSON([]byte(`"0/1"`))
|
||||
assert.Nil(t, err)
|
||||
err = json.Unmarshal([]byte("{\"numerator\":0,\"denominator\":0}"), &r)
|
||||
err = r.UnmarshalJSON([]byte(`"0/0"`))
|
||||
assert.NotNil(t, err)
|
||||
err = json.Unmarshal([]byte("{\"numerator\":1,\"denominator\":0}"), &r)
|
||||
err = r.UnmarshalJSON([]byte(`"1/0"`))
|
||||
assert.NotNil(t, err)
|
||||
err = json.Unmarshal([]byte("{}"), &r)
|
||||
err = r.UnmarshalJSON([]byte(`"{}"`))
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestSerializationJSON(t *testing.T) {
|
||||
r := NewRat(1, 3)
|
||||
|
||||
rMarshal, err := json.Marshal(r)
|
||||
bz, err := r.MarshalText()
|
||||
require.Nil(t, err)
|
||||
|
||||
var rUnmarshal Rat
|
||||
err = json.Unmarshal(rMarshal, &rUnmarshal)
|
||||
r2 := NewRat(0, 1)
|
||||
err = r2.UnmarshalText(bz)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.True(t, r.Equal(rUnmarshal), "original: %v, unmarshalled: %v", r, rUnmarshal)
|
||||
assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2)
|
||||
}
|
||||
|
||||
func TestSerializationGoWire(t *testing.T) {
|
||||
r := NewRat(1, 3)
|
||||
|
||||
rMarshal, err := ratCdc.MarshalJSON(r)
|
||||
bz, err := ratCdc.MarshalJSON(r)
|
||||
require.Nil(t, err)
|
||||
|
||||
var rUnmarshal Rat
|
||||
err = ratCdc.UnmarshalJSON(rMarshal, &rUnmarshal)
|
||||
bz, err = r.MarshalJSON()
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.True(t, r.Equal(rUnmarshal), "original: %v, unmarshalled: %v", r, rUnmarshal)
|
||||
r2 := NewRat(0, 1)
|
||||
err = ratCdc.UnmarshalJSON(bz, &r2)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2)
|
||||
}
|
||||
|
||||
type testEmbedStruct struct {
|
||||
|
@ -237,38 +239,18 @@ type testEmbedStruct struct {
|
|||
}
|
||||
|
||||
func TestEmbeddedStructSerializationGoWire(t *testing.T) {
|
||||
r := testEmbedStruct{"foo", 10, NewRat(1, 3)}
|
||||
obj := testEmbedStruct{"foo", 10, NewRat(1, 3)}
|
||||
|
||||
rMarshal, err := ratCdc.MarshalJSON(r)
|
||||
bz, err := ratCdc.MarshalJSON(obj)
|
||||
require.Nil(t, err)
|
||||
|
||||
var rUnmarshal testEmbedStruct
|
||||
err = ratCdc.UnmarshalJSON(rMarshal, &rUnmarshal)
|
||||
var obj2 testEmbedStruct
|
||||
obj2.Field3 = NewRat(0, 1) // ... needs to be initialized
|
||||
err = ratCdc.UnmarshalJSON(bz, &obj2)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Equal(t, r.Field1, rUnmarshal.Field1)
|
||||
assert.Equal(t, r.Field2, rUnmarshal.Field2)
|
||||
assert.True(t, r.Field3.Equal(rUnmarshal.Field3), "original: %v, unmarshalled: %v", r, rUnmarshal)
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
type testEmbedInterface struct {
|
||||
Field1 string `json:"f1"`
|
||||
Field2 int `json:"f2"`
|
||||
Field3 Rational `json:"f3"`
|
||||
}
|
||||
|
||||
func TestEmbeddedInterfaceSerializationGoWire(t *testing.T) {
|
||||
r := testEmbedInterface{"foo", 10, NewRat(1, 3)}
|
||||
|
||||
rMarshal, err := ratCdc.MarshalJSON(r)
|
||||
require.Nil(t, err)
|
||||
|
||||
var rUnmarshal testEmbedInterface
|
||||
err = ratCdc.UnmarshalJSON(rMarshal, &rUnmarshal)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Equal(t, r.Field1, rUnmarshal.Field1)
|
||||
assert.Equal(t, r.Field2, rUnmarshal.Field2)
|
||||
assert.True(t, r.Field3.Equal(rUnmarshal.Field3), "original: %v, unmarshalled: %v", r, rUnmarshal)
|
||||
}
|
||||
|
|
|
@ -301,7 +301,7 @@ func (m Mapper) removeDelegatorBond(delegator sdk.Address, candidateAddr sdk.Add
|
|||
addrs = append(addrs[:i], addrs[i+1:]...)
|
||||
}
|
||||
}
|
||||
b, err := m.cdc.MarshalJSON(pks)
|
||||
b, err := m.cdc.MarshalJSON(addrs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
crypto "github.com/tendermint/go-crypto"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
|
@ -21,18 +22,18 @@ func subspace(prefix []byte) (start, end []byte) {
|
|||
return prefix, end
|
||||
}
|
||||
|
||||
func createTestInput(t *testing.T, isCheckTx bool) (store sdk.KVStore, ctx sdk.Context, key sdk.StoreKey) {
|
||||
func createTestInput(t *testing.T, isCheckTx bool) (sdk.KVStore, sdk.Context, sdk.StoreKey) {
|
||||
db := dbm.NewMemDB()
|
||||
key = sdk.NewKVStoreKey("stake")
|
||||
key := sdk.NewKVStoreKey("stake")
|
||||
|
||||
ms := store.NewCommitMultiStore(db)
|
||||
ms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
|
||||
err := ms.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
|
||||
ctx = sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil)
|
||||
store = ms.GetKVStore(key)
|
||||
return
|
||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil)
|
||||
store := ms.GetKVStore(key)
|
||||
return store, ctx, key
|
||||
}
|
||||
|
||||
func newAddrs(n int) (addrs []crypto.Address) {
|
||||
|
@ -50,7 +51,7 @@ func newPubKey(pk string) (res crypto.PubKey) {
|
|||
//res, err = crypto.PubKeyFromBytes(pkBytes)
|
||||
var pkEd crypto.PubKeyEd25519
|
||||
copy(pkEd[:], pkBytes[:])
|
||||
return pkEd
|
||||
return pkEd.Wrap()
|
||||
}
|
||||
|
||||
// dummy pubkeys used for testing
|
||||
|
@ -74,7 +75,7 @@ func candidatesFromActors(store sdk.KVStore, addrs []crypto.Address, amts []int6
|
|||
c := &Candidate{
|
||||
Status: Unbonded,
|
||||
PubKey: pks[i],
|
||||
Owner: addrs[i],
|
||||
Address: addrs[i],
|
||||
Assets: sdk.NewRat(amts[i]),
|
||||
Liabilities: sdk.NewRat(amts[i]),
|
||||
VotingPower: sdk.NewRat(amts[i]),
|
||||
|
@ -83,12 +84,14 @@ func candidatesFromActors(store sdk.KVStore, addrs []crypto.Address, amts []int6
|
|||
}
|
||||
}
|
||||
|
||||
func saveCandidate(store sdk.KVStore, c *Candidate) {} // TODO
|
||||
|
||||
func candidatesFromActorsEmpty(addrs []crypto.Address) (candidates Candidates) {
|
||||
for i := 0; i < len(addrs); i++ {
|
||||
c := &Candidate{
|
||||
Status: Unbonded,
|
||||
PubKey: pks[i],
|
||||
Owner: addrs[i],
|
||||
Address: addrs[i],
|
||||
Assets: sdk.ZeroRat,
|
||||
Liabilities: sdk.ZeroRat,
|
||||
VotingPower: sdk.ZeroRat,
|
||||
|
|
|
@ -22,6 +22,7 @@ func Tick(ctx sdk.Context, m Mapper) (change []*abci.Validator, err error) {
|
|||
|
||||
newVals := m.getValidators(params.MaxVals)
|
||||
// XXX determine change from old validators, set to change
|
||||
_ = newVals
|
||||
return change, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -167,10 +167,10 @@ type MsgUnbond struct {
|
|||
Shares string `json:"shares"`
|
||||
}
|
||||
|
||||
func NewMsgUnbond(shares string, address sdk.Address) MsgDelegate {
|
||||
func NewMsgUnbond(bond sdk.Coin, address sdk.Address) MsgDelegate {
|
||||
return MsgDelegate{
|
||||
MsgAddr: NewMsgAddr(address),
|
||||
Shares: shares,
|
||||
Bond: bond, // Shares: shares,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,10 +202,10 @@ func (msg MsgUnbond) ValidateBasic() sdk.Error {
|
|||
func validateCoin(coin sdk.Coin) sdk.Error {
|
||||
coins := sdk.Coins{coin}
|
||||
if !coins.IsValid() {
|
||||
return sdk.ErrInvalidCoins()
|
||||
return sdk.ErrInvalidCoins(coins)
|
||||
}
|
||||
if !coins.IsPositive() {
|
||||
return fmt.Errorf("Amount must be > 0")
|
||||
return sdk.ErrInvalidCoins(coins) // XXX: add "Amount must be > 0" ?
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package stake
|
|||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/abci/types"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
|
@ -167,7 +166,7 @@ type Description struct {
|
|||
func NewCandidate(pubKey crypto.PubKey, address sdk.Address, description Description) *Candidate {
|
||||
return &Candidate{
|
||||
Status: Unbonded,
|
||||
PubKey: pubKet,
|
||||
PubKey: pubKey,
|
||||
Address: address,
|
||||
Assets: sdk.ZeroRat,
|
||||
Liabilities: sdk.ZeroRat,
|
||||
|
@ -222,7 +221,7 @@ func (c *Candidate) removeShares(shares sdk.Rat, gs *GlobalState) (createdCoins
|
|||
// Should only be called when the Candidate qualifies as a validator.
|
||||
func (c *Candidate) validator() Validator {
|
||||
return Validator{
|
||||
PubKey: c.PubKey,
|
||||
Address: c.Address, // XXX !!!
|
||||
VotingPower: c.VotingPower,
|
||||
}
|
||||
}
|
||||
|
@ -234,8 +233,9 @@ type Validator struct {
|
|||
}
|
||||
|
||||
// ABCIValidator - Get the validator from a bond value
|
||||
/* TODO
|
||||
func (v Validator) ABCIValidator() (*abci.Validator, error) {
|
||||
pkBytes, err := cdc.MarshalBinary(v.PubKey)
|
||||
pkBytes, err := wire.MarshalBinary(v.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -244,6 +244,7 @@ func (v Validator) ABCIValidator() (*abci.Validator, error) {
|
|||
Power: v.VotingPower.Evaluate(),
|
||||
}, nil
|
||||
}
|
||||
*/
|
||||
|
||||
//_________________________________________________________________________
|
||||
|
||||
|
@ -263,11 +264,11 @@ type DelegatorBond struct {
|
|||
// Perform all the actions required to bond tokens to a delegator bond from their account
|
||||
func (bond *DelegatorBond) BondCoins(candidate *Candidate, tokens sdk.Coin, tr transact) sdk.Error {
|
||||
|
||||
_, err := tr.coinKeeper.SubtractCoins(tr.ctx, d.Address, sdk.Coins{tokens})
|
||||
_, err := tr.coinKeeper.SubtractCoins(tr.ctx, candidate.Address, sdk.Coins{tokens})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newShares = candidate.addTokens(tokens.Amount, tr.gs)
|
||||
newShares := candidate.addTokens(tokens.Amount, tr.gs)
|
||||
bond.Shares = bond.Shares.Add(newShares)
|
||||
return nil
|
||||
}
|
||||
|
@ -277,14 +278,14 @@ func (bond *DelegatorBond) UnbondCoins(candidate *Candidate, shares int64, tr tr
|
|||
|
||||
// subtract bond tokens from delegator bond
|
||||
if bond.Shares.LT(shares) {
|
||||
return ErrInsufficientFunds()
|
||||
return sdk.ErrInsufficientFunds("") // TODO
|
||||
}
|
||||
bond.Shares = bond.Shares.Sub(shares)
|
||||
|
||||
returnAmount := candidate.removeShares(shares, tr.gs)
|
||||
returnCoins := sdk.Coins{{tr.params.BondDenom, returnAmount}}
|
||||
|
||||
_, err := tr.coinKeeper.AddCoins(tr.ctx, d.Address, returnCoins)
|
||||
_, err := tr.coinKeeper.AddCoins(tr.ctx, candidate.Address, returnCoins)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue