Merge PR #2506: types: Dec.MarshalJSON now marshals as a normal decimal string
This commit is contained in:
commit
cca2f9db43
|
@ -81,6 +81,7 @@ BREAKING CHANGES
|
||||||
* [x/stake] \#2412 Added an unbonding validator queue to EndBlock to automatically update validator.Status when finished Unbonding
|
* [x/stake] \#2412 Added an unbonding validator queue to EndBlock to automatically update validator.Status when finished Unbonding
|
||||||
* [x/stake] \#2500 Block conflicting redelegations until we add an index
|
* [x/stake] \#2500 Block conflicting redelegations until we add an index
|
||||||
* [x/params] Global Paramstore refactored
|
* [x/params] Global Paramstore refactored
|
||||||
|
* [types] \#2506 sdk.Dec MarshalJSON now marshals as a normal Decimal, with 10 digits of decimal precision
|
||||||
* [x/stake] \#2508 Utilize Tendermint power for validator power key
|
* [x/stake] \#2508 Utilize Tendermint power for validator power key
|
||||||
* [x/stake] \#2531 Remove all inflation logic
|
* [x/stake] \#2531 Remove all inflation logic
|
||||||
* [x/mint] \#2531 Add minting module and inflation logic
|
* [x/mint] \#2531 Add minting module and inflation logic
|
||||||
|
|
|
@ -248,29 +248,33 @@ func (d Dec) QuoInt(i Int) Dec {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Dec) String() string {
|
func (d Dec) String() string {
|
||||||
str := d.ToLeftPaddedWithDecimals(Precision)
|
bz, err := d.Int.MarshalText()
|
||||||
placement := len(str) - Precision
|
if err != nil {
|
||||||
if placement < 0 {
|
return ""
|
||||||
panic("too few decimal digits")
|
|
||||||
}
|
}
|
||||||
return str[:placement] + "." + str[placement:]
|
var bzWDec []byte
|
||||||
}
|
inputSize := len(bz)
|
||||||
|
// TODO: Remove trailing zeros
|
||||||
// TODO panic if negative or if totalDigits < len(initStr)???
|
// case 1, purely decimal
|
||||||
// evaluate as an integer and return left padded string
|
if inputSize <= 10 {
|
||||||
func (d Dec) ToLeftPaddedWithDecimals(totalDigits int8) string {
|
bzWDec = make([]byte, 12)
|
||||||
intStr := d.Int.String()
|
// 0. prefix
|
||||||
fcode := `%0` + strconv.Itoa(int(totalDigits)) + `s`
|
bzWDec[0] = byte('0')
|
||||||
return fmt.Sprintf(fcode, intStr)
|
bzWDec[1] = byte('.')
|
||||||
}
|
// set relevant digits to 0
|
||||||
|
for i := 0; i < 10-inputSize; i++ {
|
||||||
// TODO panic if negative or if totalDigits < len(initStr)???
|
bzWDec[i+2] = byte('0')
|
||||||
// evaluate as an integer and return left padded string
|
}
|
||||||
func (d Dec) ToLeftPadded(totalDigits int8) string {
|
// set last few digits
|
||||||
chopped := chopPrecisionAndRoundNonMutative(d.Int)
|
copy(bzWDec[2+(10-inputSize):], bz)
|
||||||
intStr := chopped.String()
|
} else {
|
||||||
fcode := `%0` + strconv.Itoa(int(totalDigits)) + `s`
|
// inputSize + 1 to account for the decimal point that is being added
|
||||||
return fmt.Sprintf(fcode, intStr)
|
bzWDec = make([]byte, inputSize+1)
|
||||||
|
copy(bzWDec, bz[:inputSize-10])
|
||||||
|
bzWDec[inputSize-10] = byte('.')
|
||||||
|
copy(bzWDec[inputSize-9:], bz[inputSize-10:])
|
||||||
|
}
|
||||||
|
return string(bzWDec)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ____
|
// ____
|
||||||
|
@ -407,17 +411,13 @@ func (d *Dec) UnmarshalAmino(text string) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON defines custom encoding scheme
|
// MarshalJSON marshals the decimal
|
||||||
func (d Dec) MarshalJSON() ([]byte, error) {
|
func (d Dec) MarshalJSON() ([]byte, error) {
|
||||||
if d.Int == nil {
|
if d.Int == nil {
|
||||||
return nilJSON, nil
|
return nilJSON, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
bz, err := d.Int.MarshalText()
|
return json.Marshal(d.String())
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return json.Marshal(string(bz))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON defines custom decoding scheme
|
// UnmarshalJSON defines custom decoding scheme
|
||||||
|
@ -431,7 +431,13 @@ func (d *Dec) UnmarshalJSON(bz []byte) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return d.Int.UnmarshalText([]byte(text))
|
// TODO: Reuse dec allocation
|
||||||
|
newDec, err := NewDecFromStr(text)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d.Int = newDec.Int
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//___________________________________________________________________________________
|
//___________________________________________________________________________________
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -228,26 +230,46 @@ func TestTruncate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToLeftPadded(t *testing.T) {
|
var cdc = codec.New()
|
||||||
tests := []struct {
|
|
||||||
dec Dec
|
func TestDecMarshalJSON(t *testing.T) {
|
||||||
digits int8
|
decimal := func(i int64) Dec {
|
||||||
exp string
|
d := NewDec(0)
|
||||||
}{
|
d.Int = new(big.Int).SetInt64(i)
|
||||||
{mustNewDecFromStr(t, "33.3"), 8, "00000033"},
|
return d
|
||||||
{mustNewDecFromStr(t, "50"), 8, "00000050"},
|
|
||||||
{mustNewDecFromStr(t, "333"), 8, "00000333"},
|
|
||||||
{mustNewDecFromStr(t, "333"), 12, "000000000333"},
|
|
||||||
{mustNewDecFromStr(t, "0.3333"), 8, "00000000"},
|
|
||||||
}
|
}
|
||||||
for tcIndex, tc := range tests {
|
tests := []struct {
|
||||||
res := tc.dec.ToLeftPadded(tc.digits)
|
name string
|
||||||
require.Equal(t, tc.exp, res, "incorrect left padding, tc %d", tcIndex)
|
d Dec
|
||||||
|
want string
|
||||||
|
wantErr bool // if wantErr = false, will also attempt unmarshaling
|
||||||
|
}{
|
||||||
|
{"zero", decimal(0), "\"0.0000000000\"", false},
|
||||||
|
{"one", decimal(1), "\"0.0000000001\"", false},
|
||||||
|
{"ten", decimal(10), "\"0.0000000010\"", false},
|
||||||
|
{"12340", decimal(12340), "\"0.0000012340\"", false},
|
||||||
|
{"zeroInt", NewDec(0), "\"0.0000000000\"", false},
|
||||||
|
{"oneInt", NewDec(1), "\"1.0000000000\"", false},
|
||||||
|
{"tenInt", NewDec(10), "\"10.0000000000\"", false},
|
||||||
|
{"12340Int", NewDec(12340), "\"12340.0000000000\"", false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := tt.d.MarshalJSON()
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Dec.MarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !tt.wantErr {
|
||||||
|
assert.Equal(t, tt.want, string(got), "incorrect marshalled value")
|
||||||
|
unmarshalledDec := NewDec(0)
|
||||||
|
unmarshalledDec.UnmarshalJSON(got)
|
||||||
|
assert.Equal(t, tt.d, unmarshalledDec, "incorrect unmarshalled value")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cdc = codec.New()
|
|
||||||
|
|
||||||
func TestZeroDeserializationJSON(t *testing.T) {
|
func TestZeroDeserializationJSON(t *testing.T) {
|
||||||
d := Dec{new(big.Int)}
|
d := Dec{new(big.Int)}
|
||||||
err := cdc.UnmarshalJSON([]byte(`"0"`), &d)
|
err := cdc.UnmarshalJSON([]byte(`"0"`), &d)
|
||||||
|
|
Loading…
Reference in New Issue