diff --git a/VERSION b/VERSION index 8b8043350..377707783 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.44.2 \ No newline at end of file +0.44.3 diff --git a/pkg/util/fixed8.go b/pkg/util/fixed8.go index b583aadf2..6a4783b18 100644 --- a/pkg/util/fixed8.go +++ b/pkg/util/fixed8.go @@ -2,6 +2,7 @@ package util import ( "bytes" + "encoding/json" "errors" "strconv" "strings" @@ -49,7 +50,8 @@ func NewFixed8(val int) Fixed8 { return Fixed8(decimals * val) } -// Fixed8DecodeString +// Fixed8DecodeString parses s which must be a fixed point number +// with precision up to 10^-8 func Fixed8DecodeString(s string) (Fixed8, error) { parts := strings.SplitN(s, ".", 2) ip, err := strconv.Atoi(parts[0]) @@ -68,3 +70,24 @@ func Fixed8DecodeString(s string) (Fixed8, error) { } return Fixed8(ip*decimals + fp), nil } + +// UnmarshalJSON implements the json unmarshaller interface. +func (f *Fixed8) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err == nil { + p, err := Fixed8DecodeString(s) + if err != nil { + return err + } + *f = p + return nil + } + + var fl float64 + if err := json.Unmarshal(data, &fl); err != nil { + return err + } + + *f = Fixed8(decimals * fl) + return nil +} diff --git a/pkg/util/fixed8_test.go b/pkg/util/fixed8_test.go index 6cf3a8392..e392eb6f6 100644 --- a/pkg/util/fixed8_test.go +++ b/pkg/util/fixed8_test.go @@ -1,6 +1,7 @@ package util import ( + "encoding/json" "testing" "github.com/stretchr/testify/assert" @@ -18,7 +19,7 @@ func TestNewFixed8(t *testing.T) { func TestFixed8DecodeString(t *testing.T) { // Fixed8DecodeString works correctly with integers ivalues := []string{"9000", "100000000", "5", "10945"} - for _, val:= range ivalues { + for _, val := range ivalues { n, err := Fixed8DecodeString(val) assert.Nil(t, err) assert.Equal(t, val, n.String()) @@ -36,3 +37,21 @@ func TestFixed8DecodeString(t *testing.T) { assert.Nil(t, err) assert.Equal(t, Fixed8(90123410000), n) } + +func TestFixed8UnmarshalJSON(t *testing.T) { + fl := float64(123.45) + str := "123.45" + expected, _ := Fixed8DecodeString(str) + + // UnmarshalJSON should decode floats + var u1 Fixed8 + s, _ := json.Marshal(fl) + assert.Nil(t, json.Unmarshal(s, &u1)) + assert.Equal(t, expected, u1) + + // UnmarshalJSON should decode strings + var u2 Fixed8 + s, _ = json.Marshal(str) + assert.Nil(t, json.Unmarshal(s, &u2)) + assert.Equal(t, expected, u2) +} diff --git a/pkg/util/test_util.go b/pkg/util/test_util.go index 984bc60dc..76c56a943 100644 --- a/pkg/util/test_util.go +++ b/pkg/util/test_util.go @@ -18,7 +18,7 @@ func RandomString(n int) string { return string(b) } -// RamdomInt returns a ramdom integer betweeen min and max. +// RandomInt returns a ramdom integer betweeen min and max. func RandomInt(min, max int) int { return min + rand.Intn(max-min) } diff --git a/pkg/util/uint160.go b/pkg/util/uint160.go index f3dfdd306..04e13ae99 100644 --- a/pkg/util/uint160.go +++ b/pkg/util/uint160.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "strings" "golang.org/x/crypto/ripemd160" ) @@ -77,6 +78,19 @@ func (u Uint160) Equals(other Uint160) bool { return true } +// UnmarshalJSON implements the json unmarshaller interface. +func (u *Uint160) UnmarshalJSON(data []byte) (err error) { + var js string + if err = json.Unmarshal(data, &js); err != nil { + return err + } + if strings.HasPrefix(js, "0x") { + js = js[2:] + } + *u, err = Uint160DecodeString(js) + return err +} + // MarshalJSON implements the json marshaller interface. func (u Uint160) MarshalJSON() ([]byte, error) { return json.Marshal( diff --git a/pkg/util/uint160_test.go b/pkg/util/uint160_test.go index 96416653c..4f6b9a149 100644 --- a/pkg/util/uint160_test.go +++ b/pkg/util/uint160_test.go @@ -2,11 +2,29 @@ package util import ( "encoding/hex" + "encoding/json" "testing" "github.com/stretchr/testify/assert" ) +func TestUint160UnmarshalJSON(t *testing.T) { + str := "2d3b96ae1bcc5a585e075e3b81920210dec16302" + expected, _ := Uint160DecodeString(str) + + // UnmarshalJSON should decode hex-strings + var u1 Uint160 + s, _ := json.Marshal(str) + assert.Nil(t, json.Unmarshal(s, &u1)) + assert.True(t, expected.Equals(u1)) + + // UnmarshalJSON should decode hex-strings prefixed by 0x + var u2 Uint160 + s, _ = json.Marshal("0x" + str) + assert.Nil(t, json.Unmarshal(s, &u2)) + assert.True(t, expected.Equals(u2)) +} + func TestUInt160DecodeString(t *testing.T) { hexStr := "2d3b96ae1bcc5a585e075e3b81920210dec16302" val, err := Uint160DecodeString(hexStr) diff --git a/pkg/util/uint256.go b/pkg/util/uint256.go index 46b1a4690..b234f8505 100644 --- a/pkg/util/uint256.go +++ b/pkg/util/uint256.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "strings" ) const uint256Size = 32 @@ -59,6 +60,19 @@ func (u Uint256) String() string { return hex.EncodeToString(ArrayReverse(u.Bytes())) } +// UnmarshalJSON implements the json unmarshaller interface. +func (u *Uint256) UnmarshalJSON(data []byte) (err error) { + var js string + if err = json.Unmarshal(data, &js); err != nil { + return err + } + if strings.HasPrefix(js, "0x") { + js = js[2:] + } + *u, err = Uint256DecodeString(js) + return err +} + // MarshalJSON implements the json marshaller interface. func (u Uint256) MarshalJSON() ([]byte, error) { return json.Marshal(fmt.Sprintf("0x%s", u.String())) diff --git a/pkg/util/uint256_test.go b/pkg/util/uint256_test.go index ae6b8a438..cd0eba218 100644 --- a/pkg/util/uint256_test.go +++ b/pkg/util/uint256_test.go @@ -2,11 +2,29 @@ package util import ( "encoding/hex" + "encoding/json" "testing" "github.com/stretchr/testify/assert" ) +func TestUint256UnmarshalJSON(t *testing.T) { + str := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" + expected, _ := Uint256DecodeString(str) + + // UnmarshalJSON should decode hex-strings + var u1 Uint256 + s, _ := json.Marshal(str) + assert.Nil(t, json.Unmarshal(s, &u1)) + assert.True(t, expected.Equals(u1)) + + // UnmarshalJSON should decode hex-strings prefixed by 0x + var u2 Uint256 + s, _ = json.Marshal("0x" + str) + assert.Nil(t, json.Unmarshal(s, &u2)) + assert.True(t, expected.Equals(u2)) +} + func TestUint256DecodeString(t *testing.T) { hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" val, err := Uint256DecodeString(hexStr)