diff --git a/CHANGELOG.md b/CHANGELOG.md index b2b6d7b003e0..b6a03be6098e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* (types) [#11788](https://github.com/cosmos/cosmos-sdk/pull/11788) The `Int` and `Uint` types have been moved to their own dedicated module, `math`. Aliases are kept in the SDK's root `types` package, however, it is encouraged to utilize the new `math` module. As a result, the `Int#ToDec` API has been removed. * (grpc) [\#11642](https://github.com/cosmos/cosmos-sdk/pull/11642) The `RegisterTendermintService` method in the `tmservice` package now requires a `abciQueryFn` query function parameter. * [\#11496](https://github.com/cosmos/cosmos-sdk/pull/11496) Refactor abstractions for snapshot and pruning; snapshot intervals eventually pruned; unit tests. * (types) [\#11689](https://github.com/cosmos/cosmos-sdk/pull/11689) Make `Coins#Sub` and `Coins#SafeSub` consistent with `Coins#Add`. diff --git a/contrib/images/simd-dlv/Dockerfile b/contrib/images/simd-dlv/Dockerfile index 30ed840fcb63..e88fc4da0d9e 100644 --- a/contrib/images/simd-dlv/Dockerfile +++ b/contrib/images/simd-dlv/Dockerfile @@ -2,9 +2,13 @@ FROM golang:1.18-alpine AS build RUN apk add build-base git linux-headers libc-dev RUN go install github.com/go-delve/delve/cmd/dlv@latest + WORKDIR /work COPY go.mod go.sum /work/ COPY db/go.mod db/go.sum /work/db/ +COPY errors/go.mod errors/go.sum /work/errors/ +COPY math/go.mod math/go.sum /work/math/ + RUN go mod download COPY ./ /work RUN LEDGER_ENABLED=false make COSMOS_BUILD_OPTIONS="debug,nostrip" clean build diff --git a/contrib/images/simd-env/Dockerfile b/contrib/images/simd-env/Dockerfile index d32fdfe82614..0d3565375837 100644 --- a/contrib/images/simd-env/Dockerfile +++ b/contrib/images/simd-env/Dockerfile @@ -1,9 +1,12 @@ FROM golang:1.18-alpine AS build + RUN apk add build-base git linux-headers + WORKDIR /work COPY go.mod go.sum /work/ COPY db/go.mod db/go.sum /work/db/ COPY errors/go.mod errors/go.sum /work/errors/ +COPY math/go.mod math/go.sum /work/math/ RUN go mod download COPY ./ /work diff --git a/errors/CHANGELOG.md b/errors/CHANGELOG.md index ec995cb13bdf..39b42c9457f6 100644 --- a/errors/CHANGELOG.md +++ b/errors/CHANGELOG.md @@ -15,10 +15,7 @@ Change log entries are to be added to the Unreleased section under the appropriate stanza (see below). Each entry should ideally include a tag and the Github issue reference in the following format: -* () \# message - -The issue numbers will later be link-ified during the release process so you do -not have to worry about including a link manually, but you can if you wish. +* () [#] Changelog message. Types of changes (Stanzas): @@ -26,8 +23,6 @@ Types of changes (Stanzas): "Improvements" for changes in existing functionality. "Deprecated" for soon-to-be removed features. "Bug Fixes" for any bug fixes. -"Client Breaking" for breaking Protobuf, gRPC and REST routes used by end-users. -"CLI Breaking" for breaking CLI commands. "API Breaking" for breaking exported APIs used by developers building on SDK. Ref: https://keepachangelog.com/en/1.0.0/ --> diff --git a/go.mod b/go.mod index 16ee5eb0363a..ef25702d3b29 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/cosmos/cosmos-sdk/api v0.1.0 github.com/cosmos/cosmos-sdk/db v1.0.0-beta.1 github.com/cosmos/cosmos-sdk/errors v1.0.0-beta.5 + github.com/cosmos/cosmos-sdk/math v0.0.0-00010101000000-000000000000 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/iavl v0.18.0 github.com/cosmos/ledger-cosmos-go v0.11.1 @@ -149,14 +150,16 @@ require ( nhooyr.io/websocket v1.8.6 // indirect ) -replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +replace ( + github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 -replace github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 + github.com/cosmos/cosmos-sdk/db => ./db + github.com/cosmos/cosmos-sdk/math => ./math -// Fix upstream GHSA-h395-qcrw-5vmq vulnerability. -// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 -replace github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0 - -replace github.com/cosmos/cosmos-sdk/db => ./db + // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. + // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 + github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0 + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +) retract v0.43.0 diff --git a/math/CHANGELOG.md b/math/CHANGELOG.md new file mode 100644 index 000000000000..16de809f2717 --- /dev/null +++ b/math/CHANGELOG.md @@ -0,0 +1,32 @@ + + +# Changelog + +## [Unreleased] diff --git a/math/doc.go b/math/doc.go new file mode 100644 index 000000000000..17664a9531e0 --- /dev/null +++ b/math/doc.go @@ -0,0 +1,6 @@ +/* +Package math implements custom Cosmos SDK math types used for arithmetic +operations. Signed and unsigned integer types utilize Golang's standard library +big integers types, having a maximum bit length of 256 bits. +*/ +package math diff --git a/math/go.mod b/math/go.mod new file mode 100644 index 000000000000..6f58ffc03bea --- /dev/null +++ b/math/go.mod @@ -0,0 +1,11 @@ +module github.com/cosmos/cosmos-sdk/math + +go 1.18 + +require github.com/stretchr/testify v1.7.0 + +require ( + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/math/go.sum b/math/go.sum new file mode 100644 index 000000000000..acb88a48f684 --- /dev/null +++ b/math/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/types/int.go b/math/int.go similarity index 94% rename from types/int.go rename to math/int.go index 04b808fbc69d..4c1e9ceb8491 100644 --- a/types/int.go +++ b/math/int.go @@ -1,15 +1,15 @@ -package types +package math import ( "encoding" "encoding/json" "fmt" - "testing" - "math/big" + "testing" ) -const maxBitLen = 256 +// MaxBitLen defines the maximum bit length supported bit Int and Uint types. +const MaxBitLen = 256 func newIntegerFromString(s string) (*big.Int, bool) { return new(big.Int).SetString(s, 0) @@ -60,14 +60,14 @@ func unmarshalText(i *big.Int, text string) error { return err } - if i.BitLen() > maxBitLen { + if i.BitLen() > MaxBitLen { return fmt.Errorf("integer out of range: %s", text) } return nil } -var _ CustomProtobufType = (*Int)(nil) +var _ customProtobufType = (*Int)(nil) // Int wraps big.Int with a 257 bit range bound // Checks overflow, underflow and division by zero @@ -108,7 +108,7 @@ func NewIntFromBigInt(i *big.Int) Int { return Int{} } - if i.BitLen() > maxBitLen { + if i.BitLen() > MaxBitLen { panic("NewIntFromBigInt() out of bound") } return Int{i} @@ -121,7 +121,7 @@ func NewIntFromString(s string) (res Int, ok bool) { return } // Check overflow - if i.BitLen() > maxBitLen { + if i.BitLen() > MaxBitLen { ok = false return } @@ -139,7 +139,7 @@ func NewIntWithDecimal(n int64, dec int) Int { i.Mul(big.NewInt(n), exp) // Check overflow - if i.BitLen() > maxBitLen { + if i.BitLen() > MaxBitLen { panic("NewIntWithDecimal() out of bound") } return Int{i} @@ -151,11 +151,6 @@ func ZeroInt() Int { return Int{big.NewInt(0)} } // OneInt returns Int value with one func OneInt() Int { return Int{big.NewInt(1)} } -// ToDec converts Int to Dec -func (i Int) ToDec() Dec { - return NewDecFromInt(i) -} - // Int64 converts Int to int64 // Panics if the value is out of range func (i Int) Int64() int64 { @@ -234,7 +229,7 @@ func (i Int) LTE(i2 Int) bool { func (i Int) Add(i2 Int) (res Int) { res = Int{add(i.i, i2.i)} // Check overflow - if res.i.BitLen() > maxBitLen { + if res.i.BitLen() > MaxBitLen { panic("Int overflow") } return @@ -249,7 +244,7 @@ func (i Int) AddRaw(i2 int64) Int { func (i Int) Sub(i2 Int) (res Int) { res = Int{sub(i.i, i2.i)} // Check overflow - if res.i.BitLen() > maxBitLen { + if res.i.BitLen() > MaxBitLen { panic("Int overflow") } return @@ -263,12 +258,12 @@ func (i Int) SubRaw(i2 int64) Int { // Mul multiples two Ints func (i Int) Mul(i2 Int) (res Int) { // Check overflow - if i.i.BitLen()+i2.i.BitLen()-1 > maxBitLen { + if i.i.BitLen()+i2.i.BitLen()-1 > MaxBitLen { panic("Int overflow") } res = Int{mul(i.i, i2.i)} // Check overflow if sign of both are same - if res.i.BitLen() > maxBitLen { + if res.i.BitLen() > MaxBitLen { panic("Int overflow") } return @@ -416,8 +411,8 @@ func (i *Int) Unmarshal(data []byte) error { return err } - if i.i.BitLen() > maxBitLen { - return fmt.Errorf("integer out of range; got: %d, max: %d", i.i.BitLen(), maxBitLen) + if i.i.BitLen() > MaxBitLen { + return fmt.Errorf("integer out of range; got: %d, max: %d", i.i.BitLen(), MaxBitLen) } return nil @@ -437,7 +432,3 @@ func (i *Int) UnmarshalAmino(bz []byte) error { return i.Unmarshal(bz) } func IntEq(t *testing.T, exp, got Int) (*testing.T, bool, string, string, string) { return t, exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String() } - -func (ip IntProto) String() string { - return ip.Int.String() -} diff --git a/types/int_internal_test.go b/math/int_internal_test.go similarity index 99% rename from types/int_internal_test.go rename to math/int_internal_test.go index 77d357bbf750..d2cb90240852 100644 --- a/types/int_internal_test.go +++ b/math/int_internal_test.go @@ -1,4 +1,4 @@ -package types +package math import ( "math/big" diff --git a/types/int_test.go b/math/int_test.go similarity index 69% rename from types/int_test.go rename to math/int_test.go index a6ec8c6d48bd..86bbe6d71a8f 100644 --- a/types/int_test.go +++ b/math/int_test.go @@ -1,4 +1,4 @@ -package types_test +package math_test import ( "fmt" @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/suite" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/math" ) type intTestSuite struct { @@ -27,30 +27,30 @@ func (s *intTestSuite) SetupSuite() { func (s *intTestSuite) TestFromInt64() { for n := 0; n < 20; n++ { r := rand.Int63() - s.Require().Equal(r, sdk.NewInt(r).Int64()) + s.Require().Equal(r, math.NewInt(r).Int64()) } } func (s *intTestSuite) TestFromUint64() { for n := 0; n < 20; n++ { r := rand.Uint64() - s.Require().True(sdk.NewIntFromUint64(r).IsUint64()) - s.Require().Equal(r, sdk.NewIntFromUint64(r).Uint64()) + s.Require().True(math.NewIntFromUint64(r).IsUint64()) + s.Require().Equal(r, math.NewIntFromUint64(r).Uint64()) } } func (s *intTestSuite) TestIntPanic() { // Max Int = 2^256-1 = 1.1579209e+77 // Min Int = -(2^256-1) = -1.1579209e+77 - s.Require().NotPanics(func() { sdk.NewIntWithDecimal(4, 76) }) - i1 := sdk.NewIntWithDecimal(4, 76) - s.Require().NotPanics(func() { sdk.NewIntWithDecimal(5, 76) }) - i2 := sdk.NewIntWithDecimal(5, 76) - s.Require().NotPanics(func() { sdk.NewIntWithDecimal(6, 76) }) - i3 := sdk.NewIntWithDecimal(6, 76) + s.Require().NotPanics(func() { math.NewIntWithDecimal(4, 76) }) + i1 := math.NewIntWithDecimal(4, 76) + s.Require().NotPanics(func() { math.NewIntWithDecimal(5, 76) }) + i2 := math.NewIntWithDecimal(5, 76) + s.Require().NotPanics(func() { math.NewIntWithDecimal(6, 76) }) + i3 := math.NewIntWithDecimal(6, 76) - s.Require().Panics(func() { sdk.NewIntWithDecimal(2, 77) }) - s.Require().Panics(func() { sdk.NewIntWithDecimal(9, 80) }) + s.Require().Panics(func() { math.NewIntWithDecimal(2, 77) }) + s.Require().Panics(func() { math.NewIntWithDecimal(9, 80) }) // Overflow check s.Require().NotPanics(func() { i1.Add(i1) }) @@ -84,20 +84,20 @@ func (s *intTestSuite) TestIntPanic() { s.Require().Panics(func() { i3.Mul(i3.Neg()) }) // Bound check - intmax := sdk.NewIntFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(1))) + intmax := math.NewIntFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(1))) intmin := intmax.Neg() - s.Require().NotPanics(func() { intmax.Add(sdk.ZeroInt()) }) - s.Require().NotPanics(func() { intmin.Sub(sdk.ZeroInt()) }) - s.Require().Panics(func() { intmax.Add(sdk.OneInt()) }) - s.Require().Panics(func() { intmin.Sub(sdk.OneInt()) }) + s.Require().NotPanics(func() { intmax.Add(math.ZeroInt()) }) + s.Require().NotPanics(func() { intmin.Sub(math.ZeroInt()) }) + s.Require().Panics(func() { intmax.Add(math.OneInt()) }) + s.Require().Panics(func() { intmin.Sub(math.OneInt()) }) - s.Require().NotPanics(func() { sdk.NewIntFromBigInt(nil) }) - s.Require().True(sdk.NewIntFromBigInt(nil).IsNil()) + s.Require().NotPanics(func() { math.NewIntFromBigInt(nil) }) + s.Require().True(math.NewIntFromBigInt(nil).IsNil()) // Division-by-zero check - s.Require().Panics(func() { i1.Quo(sdk.NewInt(0)) }) + s.Require().Panics(func() { i1.Quo(math.NewInt(0)) }) - s.Require().NotPanics(func() { sdk.Int{}.BigInt() }) + s.Require().NotPanics(func() { math.Int{}.BigInt() }) } // Tests below uses randomness @@ -107,17 +107,17 @@ func (s *intTestSuite) TestIntPanic() { func (s *intTestSuite) TestIdentInt() { for d := 0; d < 1000; d++ { n := rand.Int63() - i := sdk.NewInt(n) + i := math.NewInt(n) - ifromstr, ok := sdk.NewIntFromString(strconv.FormatInt(n, 10)) + ifromstr, ok := math.NewIntFromString(strconv.FormatInt(n, 10)) s.Require().True(ok) cases := []int64{ i.Int64(), i.BigInt().Int64(), ifromstr.Int64(), - sdk.NewIntFromBigInt(big.NewInt(n)).Int64(), - sdk.NewIntWithDecimal(n, 0).Int64(), + math.NewIntFromBigInt(big.NewInt(n)).Int64(), + math.NewIntWithDecimal(n, 0).Int64(), } for tcnum, tc := range cases { @@ -143,12 +143,12 @@ func maxint(i1, i2 int64) int64 { func (s *intTestSuite) TestArithInt() { for d := 0; d < 1000; d++ { n1 := int64(rand.Int31()) - i1 := sdk.NewInt(n1) + i1 := math.NewInt(n1) n2 := int64(rand.Int31()) - i2 := sdk.NewInt(n2) + i2 := math.NewInt(n2) cases := []struct { - ires sdk.Int + ires math.Int nres int64 }{ {i1.Add(i2), n1 + n2}, @@ -159,8 +159,8 @@ func (s *intTestSuite) TestArithInt() { {i1.SubRaw(n2), n1 - n2}, {i1.MulRaw(n2), n1 * n2}, {i1.QuoRaw(n2), n1 / n2}, - {sdk.MinInt(i1, i2), minint(n1, n2)}, - {sdk.MaxInt(i1, i2), maxint(n1, n2)}, + {math.MinInt(i1, i2), minint(n1, n2)}, + {math.MaxInt(i1, i2), maxint(n1, n2)}, {i1.Neg(), -n1}, {i1.Abs(), n1}, {i1.Neg().Abs(), n1}, @@ -176,9 +176,9 @@ func (s *intTestSuite) TestArithInt() { func (s *intTestSuite) TestCompInt() { for d := 0; d < 1000; d++ { n1 := int64(rand.Int31()) - i1 := sdk.NewInt(n1) + i1 := math.NewInt(n1) n2 := int64(rand.Int31()) - i2 := sdk.NewInt(n2) + i2 := math.NewInt(n2) cases := []struct { ires bool @@ -196,93 +196,93 @@ func (s *intTestSuite) TestCompInt() { } } -func randint() sdk.Int { - return sdk.NewInt(rand.Int63()) +func randint() math.Int { + return math.NewInt(rand.Int63()) } func (s *intTestSuite) TestImmutabilityAllInt() { - ops := []func(*sdk.Int){ - func(i *sdk.Int) { _ = i.Add(randint()) }, - func(i *sdk.Int) { _ = i.Sub(randint()) }, - func(i *sdk.Int) { _ = i.Mul(randint()) }, - func(i *sdk.Int) { _ = i.Quo(randint()) }, - func(i *sdk.Int) { _ = i.AddRaw(rand.Int63()) }, - func(i *sdk.Int) { _ = i.SubRaw(rand.Int63()) }, - func(i *sdk.Int) { _ = i.MulRaw(rand.Int63()) }, - func(i *sdk.Int) { _ = i.QuoRaw(rand.Int63()) }, - func(i *sdk.Int) { _ = i.Neg() }, - func(i *sdk.Int) { _ = i.Abs() }, - func(i *sdk.Int) { _ = i.IsZero() }, - func(i *sdk.Int) { _ = i.Sign() }, - func(i *sdk.Int) { _ = i.Equal(randint()) }, - func(i *sdk.Int) { _ = i.GT(randint()) }, - func(i *sdk.Int) { _ = i.LT(randint()) }, - func(i *sdk.Int) { _ = i.String() }, + ops := []func(*math.Int){ + func(i *math.Int) { _ = i.Add(randint()) }, + func(i *math.Int) { _ = i.Sub(randint()) }, + func(i *math.Int) { _ = i.Mul(randint()) }, + func(i *math.Int) { _ = i.Quo(randint()) }, + func(i *math.Int) { _ = i.AddRaw(rand.Int63()) }, + func(i *math.Int) { _ = i.SubRaw(rand.Int63()) }, + func(i *math.Int) { _ = i.MulRaw(rand.Int63()) }, + func(i *math.Int) { _ = i.QuoRaw(rand.Int63()) }, + func(i *math.Int) { _ = i.Neg() }, + func(i *math.Int) { _ = i.Abs() }, + func(i *math.Int) { _ = i.IsZero() }, + func(i *math.Int) { _ = i.Sign() }, + func(i *math.Int) { _ = i.Equal(randint()) }, + func(i *math.Int) { _ = i.GT(randint()) }, + func(i *math.Int) { _ = i.LT(randint()) }, + func(i *math.Int) { _ = i.String() }, } for i := 0; i < 1000; i++ { n := rand.Int63() - ni := sdk.NewInt(n) + ni := math.NewInt(n) for opnum, op := range ops { op(&ni) s.Require().Equal(n, ni.Int64(), "Int is modified by operation. tc #%d", opnum) - s.Require().Equal(sdk.NewInt(n), ni, "Int is modified by operation. tc #%d", opnum) + s.Require().Equal(math.NewInt(n), ni, "Int is modified by operation. tc #%d", opnum) } } } func (s *intTestSuite) TestEncodingTableInt() { - var i sdk.Int + var i math.Int cases := []struct { - i sdk.Int + i math.Int jsonBz []byte rawBz []byte }{ { - sdk.NewInt(0), + math.NewInt(0), []byte("\"0\""), []byte{0x30}, }, { - sdk.NewInt(100), + math.NewInt(100), []byte("\"100\""), []byte{0x31, 0x30, 0x30}, }, { - sdk.NewInt(-100), + math.NewInt(-100), []byte("\"-100\""), []byte{0x2d, 0x31, 0x30, 0x30}, }, { - sdk.NewInt(51842), + math.NewInt(51842), []byte("\"51842\""), []byte{0x35, 0x31, 0x38, 0x34, 0x32}, }, { - sdk.NewInt(-51842), + math.NewInt(-51842), []byte("\"-51842\""), []byte{0x2d, 0x35, 0x31, 0x38, 0x34, 0x32}, }, { - sdk.NewInt(19513368), + math.NewInt(19513368), []byte("\"19513368\""), []byte{0x31, 0x39, 0x35, 0x31, 0x33, 0x33, 0x36, 0x38}, }, { - sdk.NewInt(-19513368), + math.NewInt(-19513368), []byte("\"-19513368\""), []byte{0x2d, 0x31, 0x39, 0x35, 0x31, 0x33, 0x33, 0x36, 0x38}, }, { - sdk.NewInt(999999999999), + math.NewInt(999999999999), []byte("\"999999999999\""), []byte{0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39}, }, { - sdk.NewInt(-999999999999), + math.NewInt(-999999999999), []byte("\"-999999999999\""), []byte{0x2d, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39}, }, @@ -308,35 +308,35 @@ func (s *intTestSuite) TestEncodingTableInt() { } func (s *intTestSuite) TestEncodingTableUint() { - var i sdk.Uint + var i math.Uint cases := []struct { - i sdk.Uint + i math.Uint jsonBz []byte rawBz []byte }{ { - sdk.NewUint(0), + math.NewUint(0), []byte("\"0\""), []byte{0x30}, }, { - sdk.NewUint(100), + math.NewUint(100), []byte("\"100\""), []byte{0x31, 0x30, 0x30}, }, { - sdk.NewUint(51842), + math.NewUint(51842), []byte("\"51842\""), []byte{0x35, 0x31, 0x38, 0x34, 0x32}, }, { - sdk.NewUint(19513368), + math.NewUint(19513368), []byte("\"19513368\""), []byte{0x31, 0x39, 0x35, 0x31, 0x33, 0x33, 0x36, 0x38}, }, { - sdk.NewUint(999999999999), + math.NewUint(999999999999), []byte("\"999999999999\""), []byte{0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39}, }, @@ -377,19 +377,19 @@ func (s *intTestSuite) TestIntMod() { for _, tt := range tests { if tt.wantPanic { - s.Require().Panics(func() { sdk.NewInt(tt.x).Mod(sdk.NewInt(tt.y)) }) - s.Require().Panics(func() { sdk.NewInt(tt.x).ModRaw(tt.y) }) + s.Require().Panics(func() { math.NewInt(tt.x).Mod(math.NewInt(tt.y)) }) + s.Require().Panics(func() { math.NewInt(tt.x).ModRaw(tt.y) }) return } - s.Require().True(sdk.NewInt(tt.x).Mod(sdk.NewInt(tt.y)).Equal(sdk.NewInt(tt.ret))) - s.Require().True(sdk.NewInt(tt.x).ModRaw(tt.y).Equal(sdk.NewInt(tt.ret))) + s.Require().True(math.NewInt(tt.x).Mod(math.NewInt(tt.y)).Equal(math.NewInt(tt.ret))) + s.Require().True(math.NewInt(tt.x).ModRaw(tt.y).Equal(math.NewInt(tt.ret))) } } func (s *intTestSuite) TestIntEq() { - _, resp, _, _, _ := sdk.IntEq(s.T(), sdk.ZeroInt(), sdk.ZeroInt()) + _, resp, _, _, _ := math.IntEq(s.T(), math.ZeroInt(), math.ZeroInt()) s.Require().True(resp) - _, resp, _, _, _ = sdk.IntEq(s.T(), sdk.OneInt(), sdk.ZeroInt()) + _, resp, _, _, _ = math.IntEq(s.T(), math.OneInt(), math.ZeroInt()) s.Require().False(resp) } @@ -410,12 +410,12 @@ func TestRoundTripMarshalToInt(t *testing.T) { t.Parallel() var scratch [20]byte - iv := sdk.NewInt(value) + iv := math.NewInt(value) n, err := iv.MarshalTo(scratch[:]) if err != nil { t.Fatal(err) } - rt := new(sdk.Int) + rt := new(math.Int) if err := rt.Unmarshal(scratch[:n]); err != nil { t.Fatal(err) } diff --git a/math/proto.go b/math/proto.go new file mode 100644 index 000000000000..86e78bafa90d --- /dev/null +++ b/math/proto.go @@ -0,0 +1,15 @@ +package math + +// customProtobufType defines the interface custom gogo proto types must implement +// in order to be used as a "customtype" extension. +// +// ref: https://github.com/gogo/protobuf/blob/master/custom_types.md +type customProtobufType interface { + Marshal() ([]byte, error) + MarshalTo(data []byte) (n int, err error) + Unmarshal(data []byte) error + Size() int + + MarshalJSON() ([]byte, error) + UnmarshalJSON(data []byte) error +} diff --git a/types/uint.go b/math/uint.go similarity index 98% rename from types/uint.go rename to math/uint.go index dbdd17bd58a9..505984d19864 100644 --- a/types/uint.go +++ b/math/uint.go @@ -1,4 +1,4 @@ -package types +package math import ( "errors" @@ -49,7 +49,7 @@ func ZeroUint() Uint { return Uint{big.NewInt(0)} } // OneUint returns Uint value with one. func OneUint() Uint { return Uint{big.NewInt(1)} } -var _ CustomProtobufType = (*Uint)(nil) +var _ customProtobufType = (*Uint)(nil) // Uint64 converts Uint to uint64 // Panics if the value is out of range @@ -190,8 +190,8 @@ func (u *Uint) Unmarshal(data []byte) error { return err } - if u.i.BitLen() > maxBitLen { - return fmt.Errorf("integer out of range; got: %d, max: %d", u.i.BitLen(), maxBitLen) + if u.i.BitLen() > MaxBitLen { + return fmt.Errorf("integer out of range; got: %d, max: %d", u.i.BitLen(), MaxBitLen) } return nil diff --git a/types/uint_internal_test.go b/math/uint_internal_test.go similarity index 98% rename from types/uint_internal_test.go rename to math/uint_internal_test.go index a39869cac759..3f86c93604af 100644 --- a/types/uint_internal_test.go +++ b/math/uint_internal_test.go @@ -1,4 +1,4 @@ -package types +package math import ( "math/big" diff --git a/math/uint_test.go b/math/uint_test.go new file mode 100644 index 000000000000..b19d84a97a55 --- /dev/null +++ b/math/uint_test.go @@ -0,0 +1,325 @@ +package math_test + +import ( + "fmt" + "math" + "math/big" + "math/rand" + "testing" + + sdkmath "github.com/cosmos/cosmos-sdk/math" + "github.com/stretchr/testify/suite" +) + +type uintTestSuite struct { + suite.Suite +} + +func TestUnitTestSuite(t *testing.T) { + suite.Run(t, new(uintTestSuite)) +} + +func (s *uintTestSuite) SetupSuite() { + s.T().Parallel() +} + +func (s *uintTestSuite) TestUintPanics() { + // Max Uint = 1.15e+77 + // Min Uint = 0 + u1 := sdkmath.NewUint(0) + u2 := sdkmath.OneUint() + + s.Require().Equal(uint64(0), u1.Uint64()) + s.Require().Equal(uint64(1), u2.Uint64()) + + s.Require().Panics(func() { sdkmath.NewUintFromBigInt(big.NewInt(-5)) }) + s.Require().Panics(func() { sdkmath.NewUintFromString("-1") }) + s.Require().NotPanics(func() { + s.Require().True(sdkmath.NewUintFromString("0").Equal(sdkmath.ZeroUint())) + s.Require().True(sdkmath.NewUintFromString("5").Equal(sdkmath.NewUint(5))) + }) + + // Overflow check + s.Require().True(u1.Add(u1).Equal(sdkmath.ZeroUint())) + s.Require().True(u1.Add(sdkmath.OneUint()).Equal(sdkmath.OneUint())) + s.Require().Equal(uint64(0), u1.Uint64()) + s.Require().Equal(uint64(1), sdkmath.OneUint().Uint64()) + s.Require().Panics(func() { u1.SubUint64(2) }) + s.Require().True(u1.SubUint64(0).Equal(sdkmath.ZeroUint())) + s.Require().True(u2.Add(sdkmath.OneUint()).Sub(sdkmath.OneUint()).Equal(sdkmath.OneUint())) // i2 == 1 + s.Require().True(u2.Add(sdkmath.OneUint()).Mul(sdkmath.NewUint(5)).Equal(sdkmath.NewUint(10))) // i2 == 10 + s.Require().True(sdkmath.NewUint(7).Quo(sdkmath.NewUint(2)).Equal(sdkmath.NewUint(3))) + s.Require().True(sdkmath.NewUint(0).Quo(sdkmath.NewUint(2)).Equal(sdkmath.ZeroUint())) + s.Require().True(sdkmath.NewUint(5).MulUint64(4).Equal(sdkmath.NewUint(20))) + s.Require().True(sdkmath.NewUint(5).MulUint64(0).Equal(sdkmath.ZeroUint())) + + uintmax := sdkmath.NewUintFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(1))) + uintmin := sdkmath.ZeroUint() + + // divs by zero + s.Require().Panics(func() { sdkmath.OneUint().Mul(sdkmath.ZeroUint().SubUint64(uint64(1))) }) + s.Require().Panics(func() { sdkmath.OneUint().QuoUint64(0) }) + s.Require().Panics(func() { sdkmath.OneUint().Quo(sdkmath.ZeroUint()) }) + s.Require().Panics(func() { sdkmath.ZeroUint().QuoUint64(0) }) + s.Require().Panics(func() { sdkmath.OneUint().Quo(sdkmath.ZeroUint().Sub(sdkmath.OneUint())) }) + s.Require().Panics(func() { uintmax.Add(sdkmath.OneUint()) }) + s.Require().Panics(func() { uintmax.Incr() }) + s.Require().Panics(func() { uintmin.Sub(sdkmath.OneUint()) }) + s.Require().Panics(func() { uintmin.Decr() }) + + s.Require().Equal(uint64(0), sdkmath.MinUint(sdkmath.ZeroUint(), sdkmath.OneUint()).Uint64()) + s.Require().Equal(uint64(1), sdkmath.MaxUint(sdkmath.ZeroUint(), sdkmath.OneUint()).Uint64()) + + // comparison ops + s.Require().True( + sdkmath.OneUint().GT(sdkmath.ZeroUint()), + ) + s.Require().False( + sdkmath.OneUint().LT(sdkmath.ZeroUint()), + ) + s.Require().True( + sdkmath.OneUint().GTE(sdkmath.ZeroUint()), + ) + s.Require().False( + sdkmath.OneUint().LTE(sdkmath.ZeroUint()), + ) + + s.Require().False(sdkmath.ZeroUint().GT(sdkmath.OneUint())) + s.Require().True(sdkmath.ZeroUint().LT(sdkmath.OneUint())) + s.Require().False(sdkmath.ZeroUint().GTE(sdkmath.OneUint())) + s.Require().True(sdkmath.ZeroUint().LTE(sdkmath.OneUint())) +} + +func (s *uintTestSuite) TestArithUint() { + for d := 0; d < 1000; d++ { + n1 := uint64(rand.Uint32()) + u1 := sdkmath.NewUint(n1) + n2 := uint64(rand.Uint32()) + u2 := sdkmath.NewUint(n2) + + cases := []struct { + ures sdkmath.Uint + nres uint64 + }{ + {u1.Add(u2), n1 + n2}, + {u1.Mul(u2), n1 * n2}, + {u1.Quo(u2), n1 / n2}, + {u1.AddUint64(n2), n1 + n2}, + {u1.MulUint64(n2), n1 * n2}, + {u1.QuoUint64(n2), n1 / n2}, + {sdkmath.MinUint(u1, u2), minuint(n1, n2)}, + {sdkmath.MaxUint(u1, u2), maxuint(n1, n2)}, + {u1.Incr(), n1 + 1}, + } + + for tcnum, tc := range cases { + s.Require().Equal(tc.nres, tc.ures.Uint64(), "Uint arithmetic operation does not match with uint64 operation. tc #%d", tcnum) + } + + if n2 > n1 { + n1, n2 = n2, n1 + u1, u2 = sdkmath.NewUint(n1), sdkmath.NewUint(n2) + } + + subs := []struct { + ures sdkmath.Uint + nres uint64 + }{ + {u1.Sub(u2), n1 - n2}, + {u1.SubUint64(n2), n1 - n2}, + {u1.Decr(), n1 - 1}, + } + + for tcnum, tc := range subs { + s.Require().Equal(tc.nres, tc.ures.Uint64(), "Uint subtraction does not match with uint64 operation. tc #%d", tcnum) + } + } +} + +func (s *uintTestSuite) TestCompUint() { + for d := 0; d < 10000; d++ { + n1 := rand.Uint64() + i1 := sdkmath.NewUint(n1) + n2 := rand.Uint64() + i2 := sdkmath.NewUint(n2) + + cases := []struct { + ires bool + nres bool + }{ + {i1.Equal(i2), n1 == n2}, + {i1.GT(i2), n1 > n2}, + {i1.LT(i2), n1 < n2}, + {i1.GTE(i2), !i1.LT(i2)}, + {!i1.GTE(i2), i1.LT(i2)}, + {i1.LTE(i2), n1 <= n2}, + {i2.LTE(i1), n2 <= n1}, + } + + for tcnum, tc := range cases { + s.Require().Equal(tc.nres, tc.ires, "Uint comparison operation does not match with uint64 operation. tc #%d", tcnum) + } + } +} + +func (s *uintTestSuite) TestImmutabilityAllUint() { + ops := []func(*sdkmath.Uint){ + func(i *sdkmath.Uint) { _ = i.Add(sdkmath.NewUint(rand.Uint64())) }, + func(i *sdkmath.Uint) { _ = i.Sub(sdkmath.NewUint(rand.Uint64() % i.Uint64())) }, + func(i *sdkmath.Uint) { _ = i.Mul(randuint()) }, + func(i *sdkmath.Uint) { _ = i.Quo(randuint()) }, + func(i *sdkmath.Uint) { _ = i.AddUint64(rand.Uint64()) }, + func(i *sdkmath.Uint) { _ = i.SubUint64(rand.Uint64() % i.Uint64()) }, + func(i *sdkmath.Uint) { _ = i.MulUint64(rand.Uint64()) }, + func(i *sdkmath.Uint) { _ = i.QuoUint64(rand.Uint64()) }, + func(i *sdkmath.Uint) { _ = i.IsZero() }, + func(i *sdkmath.Uint) { _ = i.Equal(randuint()) }, + func(i *sdkmath.Uint) { _ = i.GT(randuint()) }, + func(i *sdkmath.Uint) { _ = i.GTE(randuint()) }, + func(i *sdkmath.Uint) { _ = i.LT(randuint()) }, + func(i *sdkmath.Uint) { _ = i.LTE(randuint()) }, + func(i *sdkmath.Uint) { _ = i.String() }, + func(i *sdkmath.Uint) { _ = i.Incr() }, + func(i *sdkmath.Uint) { + if i.IsZero() { + return + } + + _ = i.Decr() + }, + } + + for i := 0; i < 1000; i++ { + n := rand.Uint64() + ni := sdkmath.NewUint(n) + + for opnum, op := range ops { + op(&ni) + + s.Require().Equal(n, ni.Uint64(), "Uint is modified by operation. #%d", opnum) + s.Require().Equal(sdkmath.NewUint(n), ni, "Uint is modified by operation. #%d", opnum) + } + } +} + +func (s *uintTestSuite) TestSafeSub() { + testCases := []struct { + x, y sdkmath.Uint + expected uint64 + panic bool + }{ + {sdkmath.NewUint(0), sdkmath.NewUint(0), 0, false}, + {sdkmath.NewUint(10), sdkmath.NewUint(5), 5, false}, + {sdkmath.NewUint(5), sdkmath.NewUint(10), 5, true}, + {sdkmath.NewUint(math.MaxUint64), sdkmath.NewUint(0), math.MaxUint64, false}, + } + + for i, tc := range testCases { + tc := tc + if tc.panic { + s.Require().Panics(func() { tc.x.Sub(tc.y) }) + continue + } + s.Require().Equal( + tc.expected, tc.x.Sub(tc.y).Uint64(), + "invalid subtraction result; x: %s, y: %s, tc: #%d", tc.x, tc.y, i, + ) + } +} + +func (s *uintTestSuite) TestParseUint() { + type args struct { + s string + } + tests := []struct { + name string + args args + want sdkmath.Uint + wantErr bool + }{ + {"malformed", args{"malformed"}, sdkmath.Uint{}, true}, + {"empty", args{""}, sdkmath.Uint{}, true}, + {"positive", args{"50"}, sdkmath.NewUint(uint64(50)), false}, + {"negative", args{"-1"}, sdkmath.Uint{}, true}, + {"zero", args{"0"}, sdkmath.ZeroUint(), false}, + } + for _, tt := range tests { + got, err := sdkmath.ParseUint(tt.args.s) + if tt.wantErr { + s.Require().Error(err) + continue + } + s.Require().NoError(err) + s.Require().True(got.Equal(tt.want)) + } +} + +func randuint() sdkmath.Uint { + return sdkmath.NewUint(rand.Uint64()) +} + +func (s *uintTestSuite) TestRelativePow() { + tests := []struct { + args []sdkmath.Uint + want sdkmath.Uint + }{ + {[]sdkmath.Uint{sdkmath.ZeroUint(), sdkmath.ZeroUint(), sdkmath.OneUint()}, sdkmath.OneUint()}, + {[]sdkmath.Uint{sdkmath.ZeroUint(), sdkmath.ZeroUint(), sdkmath.NewUint(10)}, sdkmath.NewUint(10)}, + {[]sdkmath.Uint{sdkmath.ZeroUint(), sdkmath.OneUint(), sdkmath.NewUint(10)}, sdkmath.ZeroUint()}, + {[]sdkmath.Uint{sdkmath.NewUint(10), sdkmath.NewUint(2), sdkmath.OneUint()}, sdkmath.NewUint(100)}, + {[]sdkmath.Uint{sdkmath.NewUint(210), sdkmath.NewUint(2), sdkmath.NewUint(100)}, sdkmath.NewUint(441)}, + {[]sdkmath.Uint{sdkmath.NewUint(2100), sdkmath.NewUint(2), sdkmath.NewUint(1000)}, sdkmath.NewUint(4410)}, + {[]sdkmath.Uint{sdkmath.NewUint(1000000001547125958), sdkmath.NewUint(600), sdkmath.NewUint(1000000000000000000)}, sdkmath.NewUint(1000000928276004850)}, + } + for i, tc := range tests { + res := sdkmath.RelativePow(tc.args[0], tc.args[1], tc.args[2]) + s.Require().Equal(tc.want, res, "unexpected result for test case %d, input: %v, got: %v", i, tc.args, res) + } +} + +func minuint(i1, i2 uint64) uint64 { + if i1 < i2 { + return i1 + } + return i2 +} + +func maxuint(i1, i2 uint64) uint64 { + if i1 > i2 { + return i1 + } + return i2 +} + +func TestRoundTripMarshalToUint(t *testing.T) { + var values = []uint64{ + 0, + 1, + 1 << 10, + 1<<10 - 3, + 1<<63 - 1, + 1<<32 - 7, + 1<<22 - 8, + } + + for _, value := range values { + value := value + t.Run(fmt.Sprintf("%d", value), func(t *testing.T) { + t.Parallel() + + var scratch [20]byte + uv := sdkmath.NewUint(value) + n, err := uv.MarshalTo(scratch[:]) + if err != nil { + t.Fatal(err) + } + rt := new(sdkmath.Uint) + if err := rt.Unmarshal(scratch[:n]); err != nil { + t.Fatal(err) + } + if !rt.Equal(uv) { + t.Fatalf("roundtrip=%q != original=%q", rt, uv) + } + }) + } +} diff --git a/types/bench_test.go b/types/bench_test.go index e9ed9fa12bff..89fd9f19ea02 100644 --- a/types/bench_test.go +++ b/types/bench_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/cosmos/cosmos-sdk/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) var coinStrs = []string{ @@ -14,11 +14,11 @@ var coinStrs = []string{ } func BenchmarkParseCoin(b *testing.B) { - var blankCoin types.Coin + var blankCoin sdk.Coin b.ReportAllocs() for i := 0; i < b.N; i++ { for _, coinStr := range coinStrs { - coin, err := types.ParseCoinNormalized(coinStr) + coin, err := sdk.ParseCoinNormalized(coinStr) if err != nil { b.Fatal(err) } @@ -44,7 +44,7 @@ func BenchmarkUintMarshal(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { for _, value := range values { - u := types.NewUint(value) + u := sdk.NewUint(value) n, err := u.MarshalTo(scratch[:]) if err != nil { b.Fatal(err) @@ -69,7 +69,7 @@ func BenchmarkIntMarshal(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { for _, value := range values { - in := types.NewInt(value) + in := sdk.NewInt(value) n, err := in.MarshalTo(scratch[:]) if err != nil { b.Fatal(err) diff --git a/types/coin.go b/types/coin.go index 1b8e465c1d81..c0ad2ca0cfb5 100644 --- a/types/coin.go +++ b/types/coin.go @@ -166,7 +166,7 @@ func (coin Coin) IsNegative() bool { // IsNil returns true if the coin amount is nil and false otherwise. func (coin Coin) IsNil() bool { - return coin.Amount.i == nil + return coin.Amount.BigInt() == nil } //----------------------------------------------------------------------------- diff --git a/types/dec_coin.go b/types/dec_coin.go index aebfcc12192c..99c77a970668 100644 --- a/types/dec_coin.go +++ b/types/dec_coin.go @@ -17,7 +17,7 @@ func NewDecCoin(denom string, amount Int) DecCoin { return DecCoin{ Denom: coin.Denom, - Amount: coin.Amount.ToDec(), + Amount: NewDecFromInt(coin.Amount), } } @@ -43,7 +43,7 @@ func NewDecCoinFromCoin(coin Coin) DecCoin { return DecCoin{ Denom: coin.Denom, - Amount: coin.Amount.ToDec(), + Amount: NewDecFromInt(coin.Amount), } } @@ -111,7 +111,7 @@ func (coin DecCoin) Sub(coinB DecCoin) DecCoin { // change. Note, the change may be zero. func (coin DecCoin) TruncateDecimal() (Coin, DecCoin) { truncated := coin.Amount.TruncateInt() - change := coin.Amount.Sub(truncated.ToDec()) + change := coin.Amount.Sub(NewDecFromInt(truncated)) return NewCoin(coin.Denom, truncated), NewDecCoinFromDec(coin.Denom, change) } diff --git a/types/decimal.go b/types/decimal.go index 3be55863c068..02edd99d6aca 100644 --- a/types/decimal.go +++ b/types/decimal.go @@ -31,7 +31,7 @@ const ( // Floor[Log2[10^Precision - 1]]. decimalTruncateBits = DecimalPrecisionBits - 1 - maxDecBitLen = maxBitLen + decimalTruncateBits + maxDecBitLen = MaxBitLen + decimalTruncateBits // max number of iterations in ApproxRoot function maxApproxRootIterations = 100 @@ -318,7 +318,7 @@ func (d Dec) MulInt(i Int) Dec { } func (d Dec) MulIntMut(i Int) Dec { - d.i.Mul(d.i, i.i) + d.i.Mul(d.i, i.BigInt()) if d.i.BitLen() > maxDecBitLen { panic("Int overflow") } @@ -402,7 +402,7 @@ func (d Dec) QuoInt(i Int) Dec { } func (d Dec) QuoIntMut(i Int) Dec { - d.i.Quo(d.i, i.i) + d.i.Quo(d.i, i.BigInt()) return d } diff --git a/types/denom.go b/types/denom.go index 0e8d716a2670..df25dd4b55ed 100644 --- a/types/denom.go +++ b/types/denom.go @@ -75,7 +75,7 @@ func ConvertCoin(coin Coin, denom string) (Coin, error) { return NewCoin(denom, coin.Amount), nil } - return NewCoin(denom, coin.Amount.ToDec().Mul(srcUnit).Quo(dstUnit).TruncateInt()), nil + return NewCoin(denom, NewDecFromInt(coin.Amount).Mul(srcUnit).Quo(dstUnit).TruncateInt()), nil } // ConvertDecCoin attempts to convert a decimal coin to a given denomination. If the given diff --git a/types/math.go b/types/math.go new file mode 100644 index 000000000000..3cd650f4a111 --- /dev/null +++ b/types/math.go @@ -0,0 +1,37 @@ +package types + +import ( + sdkmath "github.com/cosmos/cosmos-sdk/math" +) + +// Type aliases to the SDK's math sub-module +// +// Deprecated: Functionality of this package has been moved to it's own module: +// github.com/cosmos/cosmos-sdk/math +// +// Please use the above module instead of this package. +type ( + Int = sdkmath.Int + Uint = sdkmath.Uint +) + +var ( + NewIntFromBigInt = sdkmath.NewIntFromBigInt + OneInt = sdkmath.OneInt + NewInt = sdkmath.NewInt + ZeroInt = sdkmath.ZeroInt + IntEq = sdkmath.IntEq + NewIntFromString = sdkmath.NewIntFromString + NewUint = sdkmath.NewUint + NewIntFromUint64 = sdkmath.NewIntFromUint64 + MaxInt = sdkmath.MaxInt + MinInt = sdkmath.MinInt +) + +const ( + MaxBitLen = sdkmath.MaxBitLen +) + +func (ip IntProto) String() string { + return ip.Int.String() +} diff --git a/types/uint_test.go b/types/uint_test.go deleted file mode 100644 index b91f9ab4a96a..000000000000 --- a/types/uint_test.go +++ /dev/null @@ -1,326 +0,0 @@ -package types_test - -import ( - "fmt" - "math" - "math/big" - "math/rand" - "testing" - - "github.com/stretchr/testify/suite" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type uintTestSuite struct { - suite.Suite -} - -func TestUnitTestSuite(t *testing.T) { - suite.Run(t, new(uintTestSuite)) -} - -func (s *uintTestSuite) SetupSuite() { - s.T().Parallel() -} - -func (s *uintTestSuite) TestUintPanics() { - // Max Uint = 1.15e+77 - // Min Uint = 0 - u1 := sdk.NewUint(0) - u2 := sdk.OneUint() - - s.Require().Equal(uint64(0), u1.Uint64()) - s.Require().Equal(uint64(1), u2.Uint64()) - - s.Require().Panics(func() { sdk.NewUintFromBigInt(big.NewInt(-5)) }) - s.Require().Panics(func() { sdk.NewUintFromString("-1") }) - s.Require().NotPanics(func() { - s.Require().True(sdk.NewUintFromString("0").Equal(sdk.ZeroUint())) - s.Require().True(sdk.NewUintFromString("5").Equal(sdk.NewUint(5))) - }) - - // Overflow check - s.Require().True(u1.Add(u1).Equal(sdk.ZeroUint())) - s.Require().True(u1.Add(sdk.OneUint()).Equal(sdk.OneUint())) - s.Require().Equal(uint64(0), u1.Uint64()) - s.Require().Equal(uint64(1), sdk.OneUint().Uint64()) - s.Require().Panics(func() { u1.SubUint64(2) }) - s.Require().True(u1.SubUint64(0).Equal(sdk.ZeroUint())) - s.Require().True(u2.Add(sdk.OneUint()).Sub(sdk.OneUint()).Equal(sdk.OneUint())) // i2 == 1 - s.Require().True(u2.Add(sdk.OneUint()).Mul(sdk.NewUint(5)).Equal(sdk.NewUint(10))) // i2 == 10 - s.Require().True(sdk.NewUint(7).Quo(sdk.NewUint(2)).Equal(sdk.NewUint(3))) - s.Require().True(sdk.NewUint(0).Quo(sdk.NewUint(2)).Equal(sdk.ZeroUint())) - s.Require().True(sdk.NewUint(5).MulUint64(4).Equal(sdk.NewUint(20))) - s.Require().True(sdk.NewUint(5).MulUint64(0).Equal(sdk.ZeroUint())) - - uintmax := sdk.NewUintFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(1))) - uintmin := sdk.ZeroUint() - - // divs by zero - s.Require().Panics(func() { sdk.OneUint().Mul(sdk.ZeroUint().SubUint64(uint64(1))) }) - s.Require().Panics(func() { sdk.OneUint().QuoUint64(0) }) - s.Require().Panics(func() { sdk.OneUint().Quo(sdk.ZeroUint()) }) - s.Require().Panics(func() { sdk.ZeroUint().QuoUint64(0) }) - s.Require().Panics(func() { sdk.OneUint().Quo(sdk.ZeroUint().Sub(sdk.OneUint())) }) - s.Require().Panics(func() { uintmax.Add(sdk.OneUint()) }) - s.Require().Panics(func() { uintmax.Incr() }) - s.Require().Panics(func() { uintmin.Sub(sdk.OneUint()) }) - s.Require().Panics(func() { uintmin.Decr() }) - - s.Require().Equal(uint64(0), sdk.MinUint(sdk.ZeroUint(), sdk.OneUint()).Uint64()) - s.Require().Equal(uint64(1), sdk.MaxUint(sdk.ZeroUint(), sdk.OneUint()).Uint64()) - - // comparison ops - s.Require().True( - sdk.OneUint().GT(sdk.ZeroUint()), - ) - s.Require().False( - sdk.OneUint().LT(sdk.ZeroUint()), - ) - s.Require().True( - sdk.OneUint().GTE(sdk.ZeroUint()), - ) - s.Require().False( - sdk.OneUint().LTE(sdk.ZeroUint()), - ) - - s.Require().False(sdk.ZeroUint().GT(sdk.OneUint())) - s.Require().True(sdk.ZeroUint().LT(sdk.OneUint())) - s.Require().False(sdk.ZeroUint().GTE(sdk.OneUint())) - s.Require().True(sdk.ZeroUint().LTE(sdk.OneUint())) -} - -func (s *uintTestSuite) TestArithUint() { - for d := 0; d < 1000; d++ { - n1 := uint64(rand.Uint32()) - u1 := sdk.NewUint(n1) - n2 := uint64(rand.Uint32()) - u2 := sdk.NewUint(n2) - - cases := []struct { - ures sdk.Uint - nres uint64 - }{ - {u1.Add(u2), n1 + n2}, - {u1.Mul(u2), n1 * n2}, - {u1.Quo(u2), n1 / n2}, - {u1.AddUint64(n2), n1 + n2}, - {u1.MulUint64(n2), n1 * n2}, - {u1.QuoUint64(n2), n1 / n2}, - {sdk.MinUint(u1, u2), minuint(n1, n2)}, - {sdk.MaxUint(u1, u2), maxuint(n1, n2)}, - {u1.Incr(), n1 + 1}, - } - - for tcnum, tc := range cases { - s.Require().Equal(tc.nres, tc.ures.Uint64(), "Uint arithmetic operation does not match with uint64 operation. tc #%d", tcnum) - } - - if n2 > n1 { - n1, n2 = n2, n1 - u1, u2 = sdk.NewUint(n1), sdk.NewUint(n2) - } - - subs := []struct { - ures sdk.Uint - nres uint64 - }{ - {u1.Sub(u2), n1 - n2}, - {u1.SubUint64(n2), n1 - n2}, - {u1.Decr(), n1 - 1}, - } - - for tcnum, tc := range subs { - s.Require().Equal(tc.nres, tc.ures.Uint64(), "Uint subtraction does not match with uint64 operation. tc #%d", tcnum) - } - } -} - -func (s *uintTestSuite) TestCompUint() { - for d := 0; d < 10000; d++ { - n1 := rand.Uint64() - i1 := sdk.NewUint(n1) - n2 := rand.Uint64() - i2 := sdk.NewUint(n2) - - cases := []struct { - ires bool - nres bool - }{ - {i1.Equal(i2), n1 == n2}, - {i1.GT(i2), n1 > n2}, - {i1.LT(i2), n1 < n2}, - {i1.GTE(i2), !i1.LT(i2)}, - {!i1.GTE(i2), i1.LT(i2)}, - {i1.LTE(i2), n1 <= n2}, - {i2.LTE(i1), n2 <= n1}, - } - - for tcnum, tc := range cases { - s.Require().Equal(tc.nres, tc.ires, "Uint comparison operation does not match with uint64 operation. tc #%d", tcnum) - } - } -} - -func (s *uintTestSuite) TestImmutabilityAllUint() { - ops := []func(*sdk.Uint){ - func(i *sdk.Uint) { _ = i.Add(sdk.NewUint(rand.Uint64())) }, - func(i *sdk.Uint) { _ = i.Sub(sdk.NewUint(rand.Uint64() % i.Uint64())) }, - func(i *sdk.Uint) { _ = i.Mul(randuint()) }, - func(i *sdk.Uint) { _ = i.Quo(randuint()) }, - func(i *sdk.Uint) { _ = i.AddUint64(rand.Uint64()) }, - func(i *sdk.Uint) { _ = i.SubUint64(rand.Uint64() % i.Uint64()) }, - func(i *sdk.Uint) { _ = i.MulUint64(rand.Uint64()) }, - func(i *sdk.Uint) { _ = i.QuoUint64(rand.Uint64()) }, - func(i *sdk.Uint) { _ = i.IsZero() }, - func(i *sdk.Uint) { _ = i.Equal(randuint()) }, - func(i *sdk.Uint) { _ = i.GT(randuint()) }, - func(i *sdk.Uint) { _ = i.GTE(randuint()) }, - func(i *sdk.Uint) { _ = i.LT(randuint()) }, - func(i *sdk.Uint) { _ = i.LTE(randuint()) }, - func(i *sdk.Uint) { _ = i.String() }, - func(i *sdk.Uint) { _ = i.Incr() }, - func(i *sdk.Uint) { - if i.IsZero() { - return - } - - _ = i.Decr() - }, - } - - for i := 0; i < 1000; i++ { - n := rand.Uint64() - ni := sdk.NewUint(n) - - for opnum, op := range ops { - op(&ni) - - s.Require().Equal(n, ni.Uint64(), "Uint is modified by operation. #%d", opnum) - s.Require().Equal(sdk.NewUint(n), ni, "Uint is modified by operation. #%d", opnum) - } - } -} - -func (s *uintTestSuite) TestSafeSub() { - testCases := []struct { - x, y sdk.Uint - expected uint64 - panic bool - }{ - {sdk.NewUint(0), sdk.NewUint(0), 0, false}, - {sdk.NewUint(10), sdk.NewUint(5), 5, false}, - {sdk.NewUint(5), sdk.NewUint(10), 5, true}, - {sdk.NewUint(math.MaxUint64), sdk.NewUint(0), math.MaxUint64, false}, - } - - for i, tc := range testCases { - tc := tc - if tc.panic { - s.Require().Panics(func() { tc.x.Sub(tc.y) }) - continue - } - s.Require().Equal( - tc.expected, tc.x.Sub(tc.y).Uint64(), - "invalid subtraction result; x: %s, y: %s, tc: #%d", tc.x, tc.y, i, - ) - } -} - -func (s *uintTestSuite) TestParseUint() { - type args struct { - s string - } - tests := []struct { - name string - args args - want sdk.Uint - wantErr bool - }{ - {"malformed", args{"malformed"}, sdk.Uint{}, true}, - {"empty", args{""}, sdk.Uint{}, true}, - {"positive", args{"50"}, sdk.NewUint(uint64(50)), false}, - {"negative", args{"-1"}, sdk.Uint{}, true}, - {"zero", args{"0"}, sdk.ZeroUint(), false}, - } - for _, tt := range tests { - got, err := sdk.ParseUint(tt.args.s) - if tt.wantErr { - s.Require().Error(err) - continue - } - s.Require().NoError(err) - s.Require().True(got.Equal(tt.want)) - } -} - -func randuint() sdk.Uint { - return sdk.NewUint(rand.Uint64()) -} - -func (s *uintTestSuite) TestRelativePow() { - tests := []struct { - args []sdk.Uint - want sdk.Uint - }{ - {[]sdk.Uint{sdk.ZeroUint(), sdk.ZeroUint(), sdk.OneUint()}, sdk.OneUint()}, - {[]sdk.Uint{sdk.ZeroUint(), sdk.ZeroUint(), sdk.NewUint(10)}, sdk.NewUint(10)}, - {[]sdk.Uint{sdk.ZeroUint(), sdk.OneUint(), sdk.NewUint(10)}, sdk.ZeroUint()}, - {[]sdk.Uint{sdk.NewUint(10), sdk.NewUint(2), sdk.OneUint()}, sdk.NewUint(100)}, - {[]sdk.Uint{sdk.NewUint(210), sdk.NewUint(2), sdk.NewUint(100)}, sdk.NewUint(441)}, - {[]sdk.Uint{sdk.NewUint(2100), sdk.NewUint(2), sdk.NewUint(1000)}, sdk.NewUint(4410)}, - {[]sdk.Uint{sdk.NewUint(1000000001547125958), sdk.NewUint(600), sdk.NewUint(1000000000000000000)}, sdk.NewUint(1000000928276004850)}, - } - for i, tc := range tests { - res := sdk.RelativePow(tc.args[0], tc.args[1], tc.args[2]) - s.Require().Equal(tc.want, res, "unexpected result for test case %d, input: %v, got: %v", i, tc.args, res) - } -} - -func minuint(i1, i2 uint64) uint64 { - if i1 < i2 { - return i1 - } - return i2 -} - -func maxuint(i1, i2 uint64) uint64 { - if i1 > i2 { - return i1 - } - return i2 -} - -func TestRoundTripMarshalToUint(t *testing.T) { - var values = []uint64{ - 0, - 1, - 1 << 10, - 1<<10 - 3, - 1<<63 - 1, - 1<<32 - 7, - 1<<22 - 8, - } - - for _, value := range values { - value := value - t.Run(fmt.Sprintf("%d", value), func(t *testing.T) { - t.Parallel() - - var scratch [20]byte - uv := sdk.NewUint(value) - n, err := uv.MarshalTo(scratch[:]) - if err != nil { - t.Fatal(err) - } - rt := new(sdk.Uint) - if err := rt.Unmarshal(scratch[:n]); err != nil { - t.Fatal(err) - } - if !rt.Equal(uv) { - t.Fatalf("roundtrip=%q != original=%q", rt, uv) - } - }) - } -} diff --git a/x/auth/vesting/types/vesting_account.go b/x/auth/vesting/types/vesting_account.go index 7316e6afd5b7..342ddce28b0d 100644 --- a/x/auth/vesting/types/vesting_account.go +++ b/x/auth/vesting/types/vesting_account.go @@ -238,7 +238,7 @@ func (cva ContinuousVestingAccount) GetVestedCoins(blockTime time.Time) sdk.Coin s := sdk.NewDec(x).Quo(sdk.NewDec(y)) for _, ovc := range cva.OriginalVesting { - vestedAmt := ovc.Amount.ToDec().Mul(s).RoundInt() + vestedAmt := sdk.NewDecFromInt(ovc.Amount).Mul(s).RoundInt() vestedCoins = append(vestedCoins, sdk.NewCoin(ovc.Denom, vestedAmt)) } diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index a1916913c424..7b18c0241f3b 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -117,7 +117,7 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { // allocate some rewards initial := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) - tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.ToDec()}} + tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}} app.DistrKeeper.AllocateTokensToValidator(ctx, val, tokens) // end period @@ -127,10 +127,10 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { rewards = app.DistrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) // rewards should be half the tokens - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.QuoRaw(2).ToDec()}}, rewards) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial.QuoRaw(2))}}, rewards) // commission should be the other half - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.QuoRaw(2).ToDec()}}, + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial.QuoRaw(2))}}, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission) } @@ -180,7 +180,7 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { // allocate some rewards initial := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) - tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.ToDec()}} + tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}} app.DistrKeeper.AllocateTokensToValidator(ctx, val, tokens) // slash the validator by 50% again @@ -202,10 +202,10 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { rewards = app.DistrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod) // rewards should be half the tokens - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.ToDec()}}, rewards) + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}}, rewards) // commission should be the other half - require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.ToDec()}}, + require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}}, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission) } @@ -381,7 +381,7 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3) // allocate some rewards - initial := app.StakingKeeper.TokensFromConsensusPower(ctx, 10).ToDec() + initial := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)) tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}} app.DistrKeeper.AllocateTokensToValidator(ctx, val, tokens) @@ -437,7 +437,7 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { del1 := app.StakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0]) // allocate some rewards - initial := app.StakingKeeper.TokensFromConsensusPower(ctx, 30).ToDec() + initial := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 30)) tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}} app.DistrKeeper.AllocateTokensToValidator(ctx, val, tokens) diff --git a/x/distribution/keeper/validator.go b/x/distribution/keeper/validator.go index 3d1953c3b5fa..38654e771a0b 100644 --- a/x/distribution/keeper/validator.go +++ b/x/distribution/keeper/validator.go @@ -45,7 +45,7 @@ func (k Keeper) IncrementValidatorPeriod(ctx sdk.Context, val stakingtypes.Valid current = sdk.DecCoins{} } else { // note: necessary to truncate so we don't allow withdrawing more rewards than owed - current = rewards.Rewards.QuoDecTruncate(val.GetTokens().ToDec()) + current = rewards.Rewards.QuoDecTruncate(sdk.NewDecFromInt(val.GetTokens())) } // fetch historical rewards for last period diff --git a/x/gov/keeper/tally.go b/x/gov/keeper/tally.go index 52d7138e8388..6b2b51f257e3 100644 --- a/x/gov/keeper/tally.go +++ b/x/gov/keeper/tally.go @@ -102,7 +102,7 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes bool, } // If there is not enough quorum of votes, the proposal fails - percentVoting := totalVotingPower.Quo(keeper.sk.TotalBondedTokens(ctx).ToDec()) + percentVoting := totalVotingPower.Quo(sdk.NewDecFromInt(keeper.sk.TotalBondedTokens(ctx))) quorum, _ := sdk.NewDecFromStr(tallyParams.Quorum) if percentVoting.LT(quorum) { return false, false, tallyResults diff --git a/x/staking/app_test.go b/x/staking/app_test.go index a97954254826..ce737e3b6218 100644 --- a/x/staking/app_test.go +++ b/x/staking/app_test.go @@ -107,7 +107,7 @@ func TestStakingMsgs(t *testing.T) { require.NoError(t, err) simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin.Sub(bondCoin)}) - checkDelegation(t, app, addr2, sdk.ValAddress(addr1), true, bondTokens.ToDec()) + checkDelegation(t, app, addr2, sdk.ValAddress(addr1), true, sdk.NewDecFromInt(bondTokens)) // begin unbonding beginUnbondingMsg := types.NewMsgUndelegate(addr2, sdk.ValAddress(addr1), bondCoin) diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index df6120b04361..24b794123a99 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -49,7 +49,7 @@ func TestInitGenesis(t *testing.T) { ConsensusPubkey: pk0, Status: types.Bonded, Tokens: valTokens, - DelegatorShares: valTokens.ToDec(), + DelegatorShares: sdk.NewDecFromInt(valTokens), Description: types.NewDescription("hoop", "", "", "", ""), } bondedVal2 := types.Validator{ @@ -57,7 +57,7 @@ func TestInitGenesis(t *testing.T) { ConsensusPubkey: pk1, Status: types.Bonded, Tokens: valTokens, - DelegatorShares: valTokens.ToDec(), + DelegatorShares: sdk.NewDecFromInt(valTokens), Description: types.NewDescription("bloop", "", "", "", ""), } @@ -126,7 +126,7 @@ func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) { ConsensusPubkey: consPub, Jailed: false, Tokens: sdk.NewInt(10), - DelegatorShares: sdk.NewInt(10).ToDec(), + DelegatorShares: sdk.NewDecFromInt(sdk.NewInt(10)), Description: types.NewDescription("bloop", "", "", "", ""), } // valid params @@ -182,7 +182,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 2) } validators[i].Tokens = tokens - validators[i].DelegatorShares = tokens.ToDec() + validators[i].DelegatorShares = sdk.NewDecFromInt(tokens) // add bonded coins bondedPoolAmt = bondedPoolAmt.Add(tokens) } diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 345121e4ed60..723caa693e1c 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -221,7 +221,7 @@ func TestUnbondDelegation(t *testing.T) { app.StakingKeeper.SetDelegation(ctx, delegation) bondTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) - amount, err := app.StakingKeeper.Unbond(ctx, delAddrs[0], valAddrs[0], bondTokens.ToDec()) + amount, err := app.StakingKeeper.Unbond(ctx, delAddrs[0], valAddrs[0], sdk.NewDecFromInt(bondTokens)) require.NoError(t, err) require.Equal(t, bondTokens, amount) // shares to be added to an unbonding delegation @@ -364,7 +364,7 @@ func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { app.StakingKeeper.SetDelegation(ctx, delegation) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], app.StakingKeeper.TokensFromConsensusPower(ctx, 6).ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 6))) require.NoError(t, err) // end block @@ -433,7 +433,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { // unbond the all self-delegation to put validator in unbonding state val0AccAddr := sdk.AccAddress(addrVals[0]) - _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens)) require.NoError(t, err) // end block @@ -508,7 +508,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { ctx = ctx.WithBlockTime(time.Unix(333, 0)) // unbond the all self-delegation to put validator in unbonding state - _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(valTokens)) require.NoError(t, err) // end block @@ -531,12 +531,12 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { // unbond some of the other delegation's shares unbondTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) - _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], unbondTokens.ToDec()) + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(unbondTokens)) require.NoError(t, err) // unbond rest of the other delegation's shares remainingTokens := delTokens.Sub(unbondTokens) - _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], remainingTokens.ToDec()) + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(remainingTokens)) require.NoError(t, err) // now validator should be deleted from state @@ -592,14 +592,14 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) { ctx = ctx.WithBlockTime(time.Unix(333, 0)) // unbond the all self-delegation to put validator in unbonding state - _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(valTokens)) require.NoError(t, err) // end block applyValidatorSetUpdates(t, ctx, app.StakingKeeper, 1) // unbond all the remaining delegation - _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], delTokens.ToDec()) + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(delTokens)) require.NoError(t, err) // validator should still be in state and still be in unbonding state @@ -836,7 +836,7 @@ func TestRedelegateSelfDelegation(t *testing.T) { delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) app.StakingKeeper.SetDelegation(ctx, delegation) - _, err := app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) + _, err := app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDecFromInt(delTokens)) require.NoError(t, err) // end block @@ -897,7 +897,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { ctx = ctx.WithBlockHeader(header) // unbond the all self-delegation to put validator in unbonding state - _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens)) require.NoError(t, err) // end block @@ -919,7 +919,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { // unbond some of the other delegation's shares redelegateTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) - _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegateTokens.ToDec()) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], sdk.NewDecFromInt(redelegateTokens)) require.NoError(t, err) // retrieve the unbonding delegation @@ -976,7 +976,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { ctx = ctx.WithBlockTime(time.Unix(333, 0)) // unbond the all self-delegation to put validator in unbonding state - _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens)) require.NoError(t, err) // end block @@ -993,7 +993,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { // redelegate some of the delegation's shares redelegationTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) - _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegationTokens.ToDec()) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], sdk.NewDecFromInt(redelegationTokens)) require.NoError(t, err) // no red should have been found diff --git a/x/staking/keeper/grpc_query_test.go b/x/staking/keeper/grpc_query_test.go index 8bb355571cd2..402e0dc0f2cd 100644 --- a/x/staking/keeper/grpc_query_test.go +++ b/x/staking/keeper/grpc_query_test.go @@ -422,7 +422,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryUnbondingDelegation() { unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2) valAddr, err1 := sdk.ValAddressFromBech32(addrVal2) suite.NoError(err1) - _, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, valAddr, unbondingTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, valAddr, sdk.NewDecFromInt(unbondingTokens)) suite.NoError(err) unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, valAddr) @@ -480,11 +480,11 @@ func (suite *KeeperTestSuite) TestGRPCQueryDelegatorUnbondingDelegations() { unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2) valAddr1, err1 := sdk.ValAddressFromBech32(addrVal) suite.NoError(err1) - _, err := app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr1, unbondingTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr1, sdk.NewDecFromInt(unbondingTokens)) suite.NoError(err) valAddr2, err1 := sdk.ValAddressFromBech32(addrVal2) suite.NoError(err1) - _, err = app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr2, unbondingTokens.ToDec()) + _, err = app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr2, sdk.NewDecFromInt(unbondingTokens)) suite.NoError(err) unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc, valAddr1) @@ -632,7 +632,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryRedelegations() { applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1) rdAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 1) - _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator(), sdk.NewDecFromInt(rdAmount)) suite.NoError(err) applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1) @@ -724,7 +724,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryValidatorUnbondingDelegations() { // undelegate undelAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 2) - _, err := app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), sdk.NewDecFromInt(undelAmount)) suite.NoError(err) applyValidatorSetUpdates(suite.T(), ctx, app.StakingKeeper, -1) diff --git a/x/staking/keeper/pool.go b/x/staking/keeper/pool.go index c24c87632358..b281b45784dc 100644 --- a/x/staking/keeper/pool.go +++ b/x/staking/keeper/pool.go @@ -71,7 +71,7 @@ func (k Keeper) StakingTokenSupply(ctx sdk.Context) sdk.Int { func (k Keeper) BondedRatio(ctx sdk.Context) sdk.Dec { stakeSupply := k.StakingTokenSupply(ctx) if stakeSupply.IsPositive() { - return k.TotalBondedTokens(ctx).ToDec().QuoInt(stakeSupply) + return sdk.NewDecFromInt(k.TotalBondedTokens(ctx)).QuoInt(stakeSupply) } return sdk.ZeroDec() diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index f50e95a1833e..ac5b1eed5a56 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -351,7 +351,7 @@ func TestQueryDelegation(t *testing.T) { // Query unbonding delegation unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) - _, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.GetOperator(), unbondingTokens.ToDec()) + _, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.GetOperator(), sdk.NewDecFromInt(unbondingTokens)) require.NoError(t, err) queryBondParams = types.QueryDelegatorValidatorRequest{DelegatorAddr: addrAcc2.String(), ValidatorAddr: addrVal1.String()} @@ -404,8 +404,7 @@ func TestQueryDelegation(t *testing.T) { // Query redelegation redelegationTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 10) - _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), - val2.GetOperator(), redelegationTokens.ToDec()) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), sdk.NewDecFromInt(redelegationTokens)) require.NoError(t, err) redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator()) require.True(t, found) @@ -509,7 +508,7 @@ func TestQueryValidatorDelegations_Pagination(t *testing.T) { // Undelegate for _, addr := range addrs { delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 20) - _, err := app.StakingKeeper.Undelegate(ctx, addr, val1.GetOperator(), delTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, addr, val1.GetOperator(), sdk.NewDecFromInt(delTokens)) require.NoError(t, err) } @@ -559,7 +558,7 @@ func TestQueryRedelegations(t *testing.T) { applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1) rdAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 20) - _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), sdk.NewDecFromInt(rdAmount)) require.NoError(t, err) applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1) @@ -631,7 +630,7 @@ func TestQueryUnbondingDelegation(t *testing.T) { // undelegate undelAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 20) - _, err = app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) + _, err = app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), sdk.NewDecFromInt(undelAmount)) require.NoError(t, err) applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1) diff --git a/x/staking/keeper/slash.go b/x/staking/keeper/slash.go index 279af3a85a35..734af19f6f44 100644 --- a/x/staking/keeper/slash.go +++ b/x/staking/keeper/slash.go @@ -30,7 +30,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // Amount of slashing = slash slashFactor * power at time of infraction amount := k.TokensFromConsensusPower(ctx, power) - slashAmountDec := amount.ToDec().Mul(slashFactor) + slashAmountDec := sdk.NewDecFromInt(amount).Mul(slashFactor) slashAmount := slashAmountDec.TruncateInt() // ref https://github.com/cosmos/cosmos-sdk/issues/1348 @@ -108,7 +108,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // we need to calculate the *effective* slash fraction for distribution if validator.Tokens.IsPositive() { - effectiveFraction := tokensToBurn.ToDec().QuoRoundUp(validator.Tokens.ToDec()) + effectiveFraction := sdk.NewDecFromInt(tokensToBurn).QuoRoundUp(sdk.NewDecFromInt(validator.Tokens)) // possible if power has changed if effectiveFraction.GT(sdk.OneDec()) { effectiveFraction = sdk.OneDec() diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 014173d9d075..ea83aab9dce2 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -390,12 +390,11 @@ func TestSlashWithRedelegation(t *testing.T) { // set a redelegation rdTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, - time.Unix(0, 0), rdTokens, rdTokens.ToDec()) + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdTokens, sdk.NewDecFromInt(rdTokens)) app.StakingKeeper.SetRedelegation(ctx, rd) // set the associated delegation - del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec()) + del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdTokens)) app.StakingKeeper.SetDelegation(ctx, del) // update bonded tokens @@ -416,7 +415,7 @@ func TestSlashWithRedelegation(t *testing.T) { require.True(t, found) require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction) }) - burnAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 10).ToDec().Mul(fraction).TruncateInt() + burnAmount := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(fraction).TruncateInt() bondedPool = app.StakingKeeper.GetBondedPool(ctx) notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) @@ -482,7 +481,7 @@ func TestSlashWithRedelegation(t *testing.T) { require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) - burnAmount = app.StakingKeeper.TokensFromConsensusPower(ctx, 10).ToDec().Mul(sdk.OneDec()).TruncateInt() + burnAmount = sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(sdk.OneDec()).TruncateInt() burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt()) // read updated pool @@ -543,13 +542,11 @@ func TestSlashBoth(t *testing.T) { // set a redelegation with expiration timestamp beyond which the // redelegation shouldn't be slashed rdATokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 6) - rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, - time.Unix(0, 0), rdATokens, - rdATokens.ToDec()) + rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, time.Unix(0, 0), rdATokens, sdk.NewDecFromInt(rdATokens)) app.StakingKeeper.SetRedelegation(ctx, rdA) // set the associated delegation - delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec()) + delA := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDecFromInt(rdATokens)) app.StakingKeeper.SetDelegation(ctx, delA) // set an unbonding delegation with expiration timestamp (beyond which the @@ -582,7 +579,7 @@ func TestSlashBoth(t *testing.T) { app.StakingKeeper.Slash(ctx, consAddr0, 10, 10, fraction) burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt() - burnedBondAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 10).ToDec().Mul(fraction).TruncateInt() + burnedBondAmount := sdk.NewDecFromInt(app.StakingKeeper.TokensFromConsensusPower(ctx, 10)).Mul(fraction).TruncateInt() burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount) // read updated pool diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index c4109a9f3ddf..585897ca7929 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -196,7 +196,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { // validator and next in line cliff validator app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal) shares := app.StakingKeeper.TokensFromConsensusPower(ctx, 21) - nextCliffVal, _ = nextCliffVal.RemoveDelShares(shares.ToDec()) + nextCliffVal, _ = nextCliffVal.RemoveDelShares(sdk.NewDecFromInt(shares)) nextCliffVal = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, nextCliffVal, true) expectedValStatus := map[int]types.BondStatus{ @@ -300,7 +300,7 @@ func TestValidatorBasics(t *testing.T) { // modify a records, save, and retrieve validators[0].Status = types.Bonded validators[0].Tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 10) - validators[0].DelegatorShares = validators[0].Tokens.ToDec() + validators[0].DelegatorShares = sdk.NewDecFromInt(validators[0].Tokens) validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) resVal, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) require.True(t, found) @@ -881,8 +881,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { // tendermintUpdate set: {c1, c3} -> {c1', c3'} delTokens1 := app.StakingKeeper.TokensFromConsensusPower(ctx, 20) delTokens2 := app.StakingKeeper.TokensFromConsensusPower(ctx, 30) - validators[0], _ = validators[0].RemoveDelShares(delTokens1.ToDec()) - validators[1], _ = validators[1].RemoveDelShares(delTokens2.ToDec()) + validators[0], _ = validators[0].RemoveDelShares(sdk.NewDecFromInt(delTokens1)) + validators[1], _ = validators[1].RemoveDelShares(sdk.NewDecFromInt(delTokens2)) validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) @@ -950,7 +950,7 @@ func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) { app.StakingKeeper.SetValidator(ctx, validator) - validator, _ = validator.RemoveDelShares(amt.ToDec()) + validator, _ = validator.RemoveDelShares(sdk.NewDecFromInt(amt)) app.StakingKeeper.SetValidator(ctx, validator) app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator) diff --git a/x/staking/types/validator.go b/x/staking/types/validator.go index 79bd2a4f55b1..88efb213f3ff 100644 --- a/x/staking/types/validator.go +++ b/x/staking/types/validator.go @@ -342,7 +342,7 @@ func (v Validator) SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, error) { return sdk.ZeroDec(), ErrInsufficientShares } - return v.GetDelegatorShares().MulInt(amt).QuoTruncate(v.GetTokens().ToDec()), nil + return v.GetDelegatorShares().MulInt(amt).QuoTruncate(sdk.NewDecFromInt(v.GetTokens())), nil } // get the bonded tokens which the validator holds @@ -382,7 +382,7 @@ func (v Validator) AddTokensFromDel(amount sdk.Int) (Validator, sdk.Dec) { var issuedShares sdk.Dec if v.DelegatorShares.IsZero() { // the first delegation to a validator sets the exchange rate to one - issuedShares = amount.ToDec() + issuedShares = sdk.NewDecFromInt(amount) } else { shares, err := v.SharesFromTokens(amount) if err != nil {