-
Notifications
You must be signed in to change notification settings - Fork 49
Problem: prevent int overflow #431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem: prevent int overflow #431
Conversation
b0dc932
to
1ad94ec
Compare
overflows 256bits integer? |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #431 +/- ##
===========================================
- Coverage 62.53% 62.53% -0.01%
===========================================
Files 130 130
Lines 12495 12503 +8
===========================================
+ Hits 7814 7819 +5
- Misses 4135 4136 +1
- Partials 546 548 +2
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
diff --git a/types/int.go b/types/int.go
index c70d1b6a..9342b836 100644
--- a/types/int.go
+++ b/types/int.go
@@ -19,13 +19,23 @@ import (
fmt "fmt"
math "math"
"math/big"
+ "math/bits"
errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
)
-const maxBitLen = 256
+const (
+ maxWordLen = sdkmath.MaxBitLen / bits.UintSize
+)
+
+var MaxInt256 *big.Int
+
+func init() {
+ var tmp big.Int
+ MaxInt256 = tmp.Lsh(big.NewInt(1), sdkmath.MaxBitLen).Sub(&tmp, big.NewInt(1))
+}
// SafeInt64 checks for overflows while casting a uint64 to int64 value.
func SafeInt64(value uint64) (int64, error) {
@@ -52,7 +62,28 @@ func SafeNewIntFromBigInt(i *big.Int) (sdkmath.Int, error) {
return sdkmath.NewIntFromBigInt(i), nil
}
+// SaturatedNewInt constructs Int from big.Int, truncate if more than 256bits
+func SaturatedNewInt(i *big.Int) sdkmath.Int {
+ if !IsValidInt256(i) {
+ i = MaxInt256
+ }
+ return sdkmath.NewIntFromBigInt(i)
+}
+
// IsValidInt256 check the bound of 256 bit number
func IsValidInt256(i *big.Int) bool {
- return i == nil || i.BitLen() <= maxBitLen
+ return i == nil || !bigIntOverflows(i)
+}
+
+// check if the big int overflows,
+// NOTE: copied from cosmos-sdk.
+func bigIntOverflows(i *big.Int) bool {
+ // overflow is defined as i.BitLen() > MaxBitLen
+ // however this check can be expensive when doing many operations.
+ // So we first check if the word length is greater than maxWordLen.
+ // However the most significant word could be zero, hence we still do the bitlen check.
+ if len(i.Bits()) > maxWordLen {
+ return i.BitLen() > sdkmath.MaxBitLen
+ }
+ return false
}
diff --git a/types/int_test.go b/types/int_test.go
new file mode 100644
index 00000000..b751cacc
--- /dev/null
+++ b/types/int_test.go
@@ -0,0 +1,18 @@
+package types
+
+import (
+ "math/big"
+ "testing"
+
+ sdkmath "cosmossdk.io/math"
+ "github.com/stretchr/testify/require"
+)
+
+func TestMaxInt256(t *testing.T) {
+ maxInt256Plus1 := new(big.Int).Add(MaxInt256, big.NewInt(1))
+ require.Equal(t, sdkmath.MaxBitLen, MaxInt256.BitLen())
+ require.Equal(t, sdkmath.MaxBitLen+1, maxInt256Plus1.BitLen())
+
+ require.True(t, IsValidInt256(MaxInt256))
+ require.False(t, IsValidInt256(maxInt256Plus1))
+}
diff --git a/x/feemarket/keeper/params.go b/x/feemarket/keeper/params.go
index eab87a39..9a04a04e 100644
--- a/x/feemarket/keeper/params.go
+++ b/x/feemarket/keeper/params.go
@@ -18,7 +18,7 @@ package keeper
import (
"math/big"
- sdkmath "cosmossdk.io/math"
+ ethermint "github.com/evmos/ethermint/types"
"github.com/evmos/ethermint/x/feemarket/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -71,7 +71,7 @@ func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int {
// SetBaseFee set's the base fee in the store
func (k Keeper) SetBaseFee(ctx sdk.Context, baseFee *big.Int) {
params := k.GetParams(ctx)
- params.BaseFee = sdkmath.NewIntFromBigInt(baseFee)
+ params.BaseFee = ethermint.SaturatedNewInt(baseFee)
err := k.SetParams(ctx, params)
if err != nil {
return
I did a cleaner version of it, can you use this version if you likes it.
fixed in #433 |
Description
This PR implements a fix to prevent an int overflow when converting a
big.Int
tosdkmath.Int
.Upon heavy load testing, there is a possibility that the feemarket eip1559 base fee implementation can crash.
For contributor use:
docs/
) or specification (x/<module>/spec/
)godoc
comments.Unreleased
section inCHANGELOG.md
Files changed
in the Github PR explorerFor admin use:
WIP
,R4R
,docs
, etc)