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:
Venkatesh Mankena 2021-06-16 19:48:02 +05:30 committed by GitHub
parent 38d670226f
commit 3841df6468
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 24 deletions

View File

@ -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/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.
* (types) [\#9511](https://github.com/cosmos/cosmos-sdk/pull/9511) Change `maxBitLen` of `sdk.Int` and `sdk.Dec` to handle max ERC20 value.
### Deprecated

View File

@ -26,6 +26,8 @@ const (
// Ceiling[Log2[999 999 999 999 999 999]]
DecimalPrecisionBits = 60
maxDecBitLen = maxBitLen + DecimalPrecisionBits
// max number of iterations in ApproxRoot function
maxApproxRootIterations = 100
)
@ -222,7 +224,7 @@ func (d Dec) BigInt() *big.Int {
func (d Dec) Add(d2 Dec) Dec {
res := new(big.Int).Add(d.i, d2.i)
if res.BitLen() > 255+DecimalPrecisionBits {
if res.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{res}
@ -232,7 +234,7 @@ func (d Dec) Add(d2 Dec) Dec {
func (d Dec) Sub(d2 Dec) Dec {
res := new(big.Int).Sub(d.i, d2.i)
if res.BitLen() > 255+DecimalPrecisionBits {
if res.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{res}
@ -243,7 +245,7 @@ func (d Dec) Mul(d2 Dec) Dec {
mul := new(big.Int).Mul(d.i, d2.i)
chopped := chopPrecisionAndRound(mul)
if chopped.BitLen() > 255+DecimalPrecisionBits {
if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{chopped}
@ -254,7 +256,7 @@ func (d Dec) MulTruncate(d2 Dec) Dec {
mul := new(big.Int).Mul(d.i, d2.i)
chopped := chopPrecisionAndTruncate(mul)
if chopped.BitLen() > 255+DecimalPrecisionBits {
if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{chopped}
@ -264,7 +266,7 @@ func (d Dec) MulTruncate(d2 Dec) Dec {
func (d Dec) MulInt(i Int) Dec {
mul := new(big.Int).Mul(d.i, i.i)
if mul.BitLen() > 255+DecimalPrecisionBits {
if mul.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{mul}
@ -274,7 +276,7 @@ func (d Dec) MulInt(i Int) Dec {
func (d Dec) MulInt64(i int64) Dec {
mul := new(big.Int).Mul(d.i, big.NewInt(i))
if mul.BitLen() > 255+DecimalPrecisionBits {
if mul.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{mul}
@ -289,7 +291,7 @@ func (d Dec) Quo(d2 Dec) Dec {
quo := new(big.Int).Quo(mul, d2.i)
chopped := chopPrecisionAndRound(quo)
if chopped.BitLen() > 255+DecimalPrecisionBits {
if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{chopped}
@ -304,7 +306,7 @@ func (d Dec) QuoTruncate(d2 Dec) Dec {
quo := mul.Quo(mul, d2.i)
chopped := chopPrecisionAndTruncate(quo)
if chopped.BitLen() > 255+DecimalPrecisionBits {
if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{chopped}
@ -319,7 +321,7 @@ func (d Dec) QuoRoundUp(d2 Dec) Dec {
quo := new(big.Int).Quo(mul, d2.i)
chopped := chopPrecisionAndRoundUp(quo)
if chopped.BitLen() > 255+DecimalPrecisionBits {
if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
return Dec{chopped}

View File

@ -9,7 +9,7 @@ import (
"math/big"
)
const maxBitLen = 255
const maxBitLen = 256
func newIntegerFromString(s string) (*big.Int, bool) {
return new(big.Int).SetString(s, 0)
@ -69,9 +69,9 @@ func unmarshalText(i *big.Int, text string) error {
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
// 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 {
i *big.Int
}

View File

@ -63,7 +63,7 @@ func (s *internalIntTestSuite) TestEncodingRandom() {
}
func (s *internalIntTestSuite) TestSerializationOverflow() {
bx, _ := new(big.Int).SetString("91888242871839275229946405745257275988696311157297823662689937894645226298583", 10)
bx, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007913129639936", 10)
x := Int{bx}
y := new(Int)
@ -80,6 +80,24 @@ func (s *internalIntTestSuite) TestSerializationOverflow() {
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() {
size := 500

View File

@ -40,16 +40,16 @@ func (s *intTestSuite) TestFromUint64() {
}
func (s *intTestSuite) TestIntPanic() {
// Max Int = 2^255-1 = 5.789e+76
// Min Int = -(2^255-1) = -5.789e+76
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(1, 76) })
i1 := sdk.NewIntWithDecimal(1, 76)
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(2, 76) })
i2 := sdk.NewIntWithDecimal(2, 76)
s.Require().NotPanics(func() { sdk.NewIntWithDecimal(3, 76) })
i3 := sdk.NewIntWithDecimal(3, 76)
// 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().Panics(func() { sdk.NewIntWithDecimal(6, 76) })
s.Require().Panics(func() { sdk.NewIntWithDecimal(2, 77) })
s.Require().Panics(func() { sdk.NewIntWithDecimal(9, 80) })
// Overflow check
@ -69,7 +69,7 @@ func (s *intTestSuite) TestIntPanic() {
s.Require().Panics(func() { i2.Neg().Mul(i2.Neg()) })
s.Require().Panics(func() { i3.Neg().Mul(i3.Neg()) })
// Underflow check
// // Underflow check
i3n := i3.Neg()
s.Require().NotPanics(func() { i3n.Sub(i1) })
s.Require().NotPanics(func() { i3n.Sub(i2) })
@ -84,7 +84,7 @@ 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(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()
s.Require().NotPanics(func() { intmax.Add(sdk.ZeroInt()) })
s.Require().NotPanics(func() { intmin.Sub(sdk.ZeroInt()) })