fix: Handle MAX_INT_256 (#9511)
Change maxBitLen of sdk.Int to handle max Erc20 value. <!-- The default pull request template is for types feat, fix, or refactor. For other templates, add one of the following parameters to the url: - template=docs.md - template=other.md --> ## Description Closes: #XXXX <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
This commit is contained in:
parent
38d670226f
commit
3841df6468
|
@ -153,6 +153,7 @@ if input key is empty, or input data contains empty key.
|
||||||
* (x/bank) [\#8434](https://github.com/cosmos/cosmos-sdk/pull/8434) Fix legacy REST API `GET /bank/total` and `GET /bank/total/{denom}` in swagger
|
* (x/bank) [\#8434](https://github.com/cosmos/cosmos-sdk/pull/8434) Fix legacy REST API `GET /bank/total` and `GET /bank/total/{denom}` in swagger
|
||||||
* (x/slashing) [\#8427](https://github.com/cosmos/cosmos-sdk/pull/8427) Fix query signing infos command
|
* (x/slashing) [\#8427](https://github.com/cosmos/cosmos-sdk/pull/8427) Fix query signing infos command
|
||||||
* (x/bank) [\#9229](https://github.com/cosmos/cosmos-sdk/pull/9229) Now zero coin balances cannot be added to balances & supply stores. If any denom becomes zero corresponding key gets deleted from store.
|
* (x/bank) [\#9229](https://github.com/cosmos/cosmos-sdk/pull/9229) Now zero coin balances cannot be added to balances & supply stores. If any denom becomes zero corresponding key gets deleted from store.
|
||||||
|
* (types) [\#9511](https://github.com/cosmos/cosmos-sdk/pull/9511) Change `maxBitLen` of `sdk.Int` and `sdk.Dec` to handle max ERC20 value.
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@ const (
|
||||||
// Ceiling[Log2[999 999 999 999 999 999]]
|
// Ceiling[Log2[999 999 999 999 999 999]]
|
||||||
DecimalPrecisionBits = 60
|
DecimalPrecisionBits = 60
|
||||||
|
|
||||||
|
maxDecBitLen = maxBitLen + DecimalPrecisionBits
|
||||||
|
|
||||||
// max number of iterations in ApproxRoot function
|
// max number of iterations in ApproxRoot function
|
||||||
maxApproxRootIterations = 100
|
maxApproxRootIterations = 100
|
||||||
)
|
)
|
||||||
|
@ -222,7 +224,7 @@ func (d Dec) BigInt() *big.Int {
|
||||||
func (d Dec) Add(d2 Dec) Dec {
|
func (d Dec) Add(d2 Dec) Dec {
|
||||||
res := new(big.Int).Add(d.i, d2.i)
|
res := new(big.Int).Add(d.i, d2.i)
|
||||||
|
|
||||||
if res.BitLen() > 255+DecimalPrecisionBits {
|
if res.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{res}
|
return Dec{res}
|
||||||
|
@ -232,7 +234,7 @@ func (d Dec) Add(d2 Dec) Dec {
|
||||||
func (d Dec) Sub(d2 Dec) Dec {
|
func (d Dec) Sub(d2 Dec) Dec {
|
||||||
res := new(big.Int).Sub(d.i, d2.i)
|
res := new(big.Int).Sub(d.i, d2.i)
|
||||||
|
|
||||||
if res.BitLen() > 255+DecimalPrecisionBits {
|
if res.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{res}
|
return Dec{res}
|
||||||
|
@ -243,7 +245,7 @@ func (d Dec) Mul(d2 Dec) Dec {
|
||||||
mul := new(big.Int).Mul(d.i, d2.i)
|
mul := new(big.Int).Mul(d.i, d2.i)
|
||||||
chopped := chopPrecisionAndRound(mul)
|
chopped := chopPrecisionAndRound(mul)
|
||||||
|
|
||||||
if chopped.BitLen() > 255+DecimalPrecisionBits {
|
if chopped.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{chopped}
|
return Dec{chopped}
|
||||||
|
@ -254,7 +256,7 @@ func (d Dec) MulTruncate(d2 Dec) Dec {
|
||||||
mul := new(big.Int).Mul(d.i, d2.i)
|
mul := new(big.Int).Mul(d.i, d2.i)
|
||||||
chopped := chopPrecisionAndTruncate(mul)
|
chopped := chopPrecisionAndTruncate(mul)
|
||||||
|
|
||||||
if chopped.BitLen() > 255+DecimalPrecisionBits {
|
if chopped.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{chopped}
|
return Dec{chopped}
|
||||||
|
@ -264,7 +266,7 @@ func (d Dec) MulTruncate(d2 Dec) Dec {
|
||||||
func (d Dec) MulInt(i Int) Dec {
|
func (d Dec) MulInt(i Int) Dec {
|
||||||
mul := new(big.Int).Mul(d.i, i.i)
|
mul := new(big.Int).Mul(d.i, i.i)
|
||||||
|
|
||||||
if mul.BitLen() > 255+DecimalPrecisionBits {
|
if mul.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{mul}
|
return Dec{mul}
|
||||||
|
@ -274,7 +276,7 @@ func (d Dec) MulInt(i Int) Dec {
|
||||||
func (d Dec) MulInt64(i int64) Dec {
|
func (d Dec) MulInt64(i int64) Dec {
|
||||||
mul := new(big.Int).Mul(d.i, big.NewInt(i))
|
mul := new(big.Int).Mul(d.i, big.NewInt(i))
|
||||||
|
|
||||||
if mul.BitLen() > 255+DecimalPrecisionBits {
|
if mul.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{mul}
|
return Dec{mul}
|
||||||
|
@ -289,7 +291,7 @@ func (d Dec) Quo(d2 Dec) Dec {
|
||||||
quo := new(big.Int).Quo(mul, d2.i)
|
quo := new(big.Int).Quo(mul, d2.i)
|
||||||
chopped := chopPrecisionAndRound(quo)
|
chopped := chopPrecisionAndRound(quo)
|
||||||
|
|
||||||
if chopped.BitLen() > 255+DecimalPrecisionBits {
|
if chopped.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{chopped}
|
return Dec{chopped}
|
||||||
|
@ -304,7 +306,7 @@ func (d Dec) QuoTruncate(d2 Dec) Dec {
|
||||||
quo := mul.Quo(mul, d2.i)
|
quo := mul.Quo(mul, d2.i)
|
||||||
chopped := chopPrecisionAndTruncate(quo)
|
chopped := chopPrecisionAndTruncate(quo)
|
||||||
|
|
||||||
if chopped.BitLen() > 255+DecimalPrecisionBits {
|
if chopped.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{chopped}
|
return Dec{chopped}
|
||||||
|
@ -319,7 +321,7 @@ func (d Dec) QuoRoundUp(d2 Dec) Dec {
|
||||||
quo := new(big.Int).Quo(mul, d2.i)
|
quo := new(big.Int).Quo(mul, d2.i)
|
||||||
chopped := chopPrecisionAndRoundUp(quo)
|
chopped := chopPrecisionAndRoundUp(quo)
|
||||||
|
|
||||||
if chopped.BitLen() > 255+DecimalPrecisionBits {
|
if chopped.BitLen() > maxDecBitLen {
|
||||||
panic("Int overflow")
|
panic("Int overflow")
|
||||||
}
|
}
|
||||||
return Dec{chopped}
|
return Dec{chopped}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxBitLen = 255
|
const maxBitLen = 256
|
||||||
|
|
||||||
func newIntegerFromString(s string) (*big.Int, bool) {
|
func newIntegerFromString(s string) (*big.Int, bool) {
|
||||||
return new(big.Int).SetString(s, 0)
|
return new(big.Int).SetString(s, 0)
|
||||||
|
@ -69,9 +69,9 @@ func unmarshalText(i *big.Int, text string) error {
|
||||||
|
|
||||||
var _ CustomProtobufType = (*Int)(nil)
|
var _ CustomProtobufType = (*Int)(nil)
|
||||||
|
|
||||||
// Int wraps big.Int with a 256 bit range bound
|
// Int wraps big.Int with a 257 bit range bound
|
||||||
// Checks overflow, underflow and division by zero
|
// Checks overflow, underflow and division by zero
|
||||||
// Exists in range from -(2^255 - 1) to 2^255 - 1
|
// Exists in range from -(2^256 - 1) to 2^256 - 1
|
||||||
type Int struct {
|
type Int struct {
|
||||||
i *big.Int
|
i *big.Int
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ func (s *internalIntTestSuite) TestEncodingRandom() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *internalIntTestSuite) TestSerializationOverflow() {
|
func (s *internalIntTestSuite) TestSerializationOverflow() {
|
||||||
bx, _ := new(big.Int).SetString("91888242871839275229946405745257275988696311157297823662689937894645226298583", 10)
|
bx, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007913129639936", 10)
|
||||||
x := Int{bx}
|
x := Int{bx}
|
||||||
y := new(Int)
|
y := new(Int)
|
||||||
|
|
||||||
|
@ -80,6 +80,24 @@ func (s *internalIntTestSuite) TestSerializationOverflow() {
|
||||||
s.Require().Error(y.UnmarshalJSON(bz))
|
s.Require().Error(y.UnmarshalJSON(bz))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *internalIntTestSuite) TestDeserializeMaxERC20() {
|
||||||
|
bx, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007913129639935", 10)
|
||||||
|
x := Int{bx}
|
||||||
|
y := new(Int)
|
||||||
|
|
||||||
|
bz, err := x.Marshal()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// require deserialization to be successful
|
||||||
|
s.Require().NoError(y.Unmarshal(bz))
|
||||||
|
|
||||||
|
// require JSON deserialization to succeed
|
||||||
|
bz, err = x.MarshalJSON()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(y.UnmarshalJSON(bz))
|
||||||
|
}
|
||||||
|
|
||||||
func (s *internalIntTestSuite) TestImmutabilityArithInt() {
|
func (s *internalIntTestSuite) TestImmutabilityArithInt() {
|
||||||
size := 500
|
size := 500
|
||||||
|
|
||||||
|
|
|
@ -40,16 +40,16 @@ func (s *intTestSuite) TestFromUint64() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *intTestSuite) TestIntPanic() {
|
func (s *intTestSuite) TestIntPanic() {
|
||||||
// Max Int = 2^255-1 = 5.789e+76
|
// Max Int = 2^256-1 = 1.1579209e+77
|
||||||
// Min Int = -(2^255-1) = -5.789e+76
|
// Min Int = -(2^256-1) = -1.1579209e+77
|
||||||
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(1, 76) })
|
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(4, 76) })
|
||||||
i1 := sdk.NewIntWithDecimal(1, 76)
|
i1 := sdk.NewIntWithDecimal(4, 76)
|
||||||
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(2, 76) })
|
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(5, 76) })
|
||||||
i2 := sdk.NewIntWithDecimal(2, 76)
|
i2 := sdk.NewIntWithDecimal(5, 76)
|
||||||
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(3, 76) })
|
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(6, 76) })
|
||||||
i3 := sdk.NewIntWithDecimal(3, 76)
|
i3 := sdk.NewIntWithDecimal(6, 76)
|
||||||
|
|
||||||
s.Require().Panics(func() { sdk.NewIntWithDecimal(6, 76) })
|
s.Require().Panics(func() { sdk.NewIntWithDecimal(2, 77) })
|
||||||
s.Require().Panics(func() { sdk.NewIntWithDecimal(9, 80) })
|
s.Require().Panics(func() { sdk.NewIntWithDecimal(9, 80) })
|
||||||
|
|
||||||
// Overflow check
|
// Overflow check
|
||||||
|
@ -69,7 +69,7 @@ func (s *intTestSuite) TestIntPanic() {
|
||||||
s.Require().Panics(func() { i2.Neg().Mul(i2.Neg()) })
|
s.Require().Panics(func() { i2.Neg().Mul(i2.Neg()) })
|
||||||
s.Require().Panics(func() { i3.Neg().Mul(i3.Neg()) })
|
s.Require().Panics(func() { i3.Neg().Mul(i3.Neg()) })
|
||||||
|
|
||||||
// Underflow check
|
// // Underflow check
|
||||||
i3n := i3.Neg()
|
i3n := i3.Neg()
|
||||||
s.Require().NotPanics(func() { i3n.Sub(i1) })
|
s.Require().NotPanics(func() { i3n.Sub(i1) })
|
||||||
s.Require().NotPanics(func() { i3n.Sub(i2) })
|
s.Require().NotPanics(func() { i3n.Sub(i2) })
|
||||||
|
@ -84,7 +84,7 @@ func (s *intTestSuite) TestIntPanic() {
|
||||||
s.Require().Panics(func() { i3.Mul(i3.Neg()) })
|
s.Require().Panics(func() { i3.Mul(i3.Neg()) })
|
||||||
|
|
||||||
// Bound check
|
// Bound check
|
||||||
intmax := sdk.NewIntFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(255), nil), big.NewInt(1)))
|
intmax := sdk.NewIntFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(1)))
|
||||||
intmin := intmax.Neg()
|
intmin := intmax.Neg()
|
||||||
s.Require().NotPanics(func() { intmax.Add(sdk.ZeroInt()) })
|
s.Require().NotPanics(func() { intmax.Add(sdk.ZeroInt()) })
|
||||||
s.Require().NotPanics(func() { intmin.Sub(sdk.ZeroInt()) })
|
s.Require().NotPanics(func() { intmin.Sub(sdk.ZeroInt()) })
|
||||||
|
|
Loading…
Reference in New Issue