Skip to content
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

fix: Inconsistent limit on InfiniteGasMeter and add GasLeft func to GasMeter #9651

Merged
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -75,6 +75,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

* [\#9651](https://github.com/cosmos/cosmos-sdk/pull/9651) Change inconsistent limit of `0` to `MaxUint64` on InfiniteGasMeter and add GasRemaining func to GasMeter.
* [\#9639](https://github.com/cosmos/cosmos-sdk/pull/9639) Check store keys length before accessing them by making sure that `key` is of length `m+1` (for `key[n:m]`)
* (types) [\#9627](https://github.com/cosmos/cosmos-sdk/pull/9627) Fix nil pointer panic on `NewBigIntFromInt`
* (x/genutil) [\#9574](https://github.com/cosmos/cosmos-sdk/pull/9575) Actually use the `gentx` client tx flags (like `--keyring-dir`)
Expand Down
14 changes: 13 additions & 1 deletion store/types/gas.go
Expand Up @@ -41,6 +41,7 @@ type ErrorGasOverflow struct {
type GasMeter interface {
GasConsumed() Gas
GasConsumedToLimit() Gas
GasRemaining() Gas
Limit() Gas
ConsumeGas(amount Gas, descriptor string)
RefundGas(amount Gas, descriptor string)
Expand All @@ -66,6 +67,13 @@ func (g *basicGasMeter) GasConsumed() Gas {
return g.consumed
}

func (g *basicGasMeter) GasRemaining() Gas {
if g.IsPastLimit() {
return 0
}
return g.limit - g.consumed
}

func (g *basicGasMeter) Limit() Gas {
return g.limit
}
Expand Down Expand Up @@ -145,8 +153,12 @@ func (g *infiniteGasMeter) GasConsumedToLimit() Gas {
return g.consumed
}

func (g *infiniteGasMeter) GasRemaining() Gas {
return math.MaxUint64
}

func (g *infiniteGasMeter) Limit() Gas {
return 0
return math.MaxUint64
}

func (g *infiniteGasMeter) ConsumeGas(amount Gas, descriptor string) {
Expand Down
15 changes: 13 additions & 2 deletions store/types/gas_test.go
Expand Up @@ -10,13 +10,16 @@ import (
func TestInfiniteGasMeter(t *testing.T) {
t.Parallel()
meter := NewInfiniteGasMeter()
require.Equal(t, uint64(0), meter.Limit())
require.Equal(t, uint64(math.MaxUint64), meter.Limit())
require.Equal(t, uint64(math.MaxUint64), meter.GasRemaining())
require.Equal(t, uint64(0), meter.GasConsumed())
require.Equal(t, uint64(0), meter.GasConsumedToLimit())
meter.ConsumeGas(10, "consume 10")
require.Equal(t, uint64(math.MaxUint64), meter.GasRemaining())
require.Equal(t, uint64(10), meter.GasConsumed())
require.Equal(t, uint64(10), meter.GasConsumedToLimit())
meter.RefundGas(1, "refund 1")
require.Equal(t, uint64(math.MaxUint64), meter.GasRemaining())
require.Equal(t, uint64(9), meter.GasConsumed())
require.False(t, meter.IsPastLimit())
require.False(t, meter.IsOutOfGas())
Expand Down Expand Up @@ -48,6 +51,7 @@ func TestGasMeter(t *testing.T) {
used += usage
require.NotPanics(t, func() { meter.ConsumeGas(usage, "") }, "Not exceeded limit but panicked. tc #%d, usage #%d", tcnum, unum)
require.Equal(t, used, meter.GasConsumed(), "Gas consumption not match. tc #%d, usage #%d", tcnum, unum)
require.Equal(t, tc.limit-used, meter.GasRemaining(), "Gas left not match. tc #%d, usage #%d", tcnum, unum)
require.Equal(t, used, meter.GasConsumedToLimit(), "Gas consumption (to limit) not match. tc #%d, usage #%d", tcnum, unum)
require.False(t, meter.IsPastLimit(), "Not exceeded limit but got IsPastLimit() true")
if unum < len(tc.usage)-1 {
Expand All @@ -60,13 +64,20 @@ func TestGasMeter(t *testing.T) {
require.Panics(t, func() { meter.ConsumeGas(1, "") }, "Exceeded but not panicked. tc #%d", tcnum)
require.Equal(t, meter.GasConsumedToLimit(), meter.Limit(), "Gas consumption (to limit) not match limit")
require.Equal(t, meter.GasConsumed(), meter.Limit()+1, "Gas consumption not match limit+1")
require.Equal(t, uint64(0), meter.GasRemaining())

require.NotPanics(t, func() { meter.RefundGas(1, "refund 1") })
require.Equal(t, meter.GasConsumed(), meter.Limit(), "Gas consumption not match limit+1")
require.Equal(t, meter.GasConsumed(), meter.Limit(), "Gas consumption not match with limit")
require.Equal(t, uint64(0), meter.GasRemaining())
require.Panics(t, func() { meter.RefundGas(meter.GasConsumed()+1, "refund greater than consumed") })

require.NotPanics(t, func() { meter.RefundGas(meter.GasConsumed(), "refund consumed gas") })
require.Equal(t, meter.Limit(), meter.GasRemaining())

meter2 := NewGasMeter(math.MaxUint64)
require.Equal(t, uint64(math.MaxUint64), meter2.GasRemaining())
meter2.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64")
require.Equal(t, Gas(math.MaxUint64-(math.MaxUint64/2)), meter2.GasRemaining())
require.Panics(t, func() { meter2.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") })
}
}
Expand Down
6 changes: 4 additions & 2 deletions x/auth/ante/setup_test.go
@@ -1,6 +1,8 @@
package ante_test

import (
"math"

cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -33,8 +35,8 @@ func (suite *AnteTestSuite) TestSetup() {
// Set height to non-zero value for GasMeter to be set
suite.ctx = suite.ctx.WithBlockHeight(1)

// Context GasMeter Limit not set
suite.Require().Equal(uint64(0), suite.ctx.GasMeter().Limit(), "GasMeter set with limit before setup")
// Context GasMeter Limit set to MaxUint64
suite.Require().Equal(uint64(math.MaxUint64), suite.ctx.GasMeter().Limit(), "GasMeter set with limit other than MaxUint64 before setup")

newCtx, err := antehandler(suite.ctx, tx, false)
suite.Require().Nil(err, "SetUpContextDecorator returned error")
Expand Down