Skip to content

Commit

Permalink
fix: Handle MAX_INT_256 (#9511)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
mankenavenkatesh authored and zmanian committed Jun 22, 2021
1 parent 8cfa2c2 commit b7f7c45
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ if input key is empty, or input data contains empty key.
* (x/slashing) [\#8427](https://github.com/cosmos/cosmos-sdk/pull/8427) Fix query signing infos command
* (server) [\#8399](https://github.com/cosmos/cosmos-sdk/pull/8399) fix gRPC-web flag default value
* (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

Expand Down
20 changes: 11 additions & 9 deletions types/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down Expand Up @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand Down
6 changes: 3 additions & 3 deletions types/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
}
Expand Down
20 changes: 19 additions & 1 deletion types/int_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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

Expand Down
24 changes: 12 additions & 12 deletions types/int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

s.Require().Panics(func() { sdk.NewIntWithDecimal(6, 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(2, 77) })
s.Require().Panics(func() { sdk.NewIntWithDecimal(9, 80) })

// Overflow check
Expand All @@ -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) })
Expand All @@ -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()) })
Expand Down

0 comments on commit b7f7c45

Please sign in to comment.