forked from evmos/ethermint
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: GasMeter reset in AnteHandler
EthGasConsumeDecorator
(evmos#964)
* Fix GasMeter reset in AnteHandler - EthGasConsumeDecorator Conforming to the spec: https://github.com/cosmos/cosmos-sdk/blob/e7066c4271ff3d33dc426dc6313c82a1201ae3c6/docs/basics/gas-fees.md > Set newCtx.GasMeter to 0, with a limit of GasWanted. > This step is extremely important, as it not only makes sure the transaction cannot consume infinite gas, > but also that ctx.GasMeter is reset in-between each DeliverTx > (ctx is set to newCtx after anteHandler is run, and the anteHandler is run each time DeliverTx is called). * Compute gasWanted in ante handler based on msg gas * Tests - check gas meter limit after EthGasConsumeDecorator ante handler runs * Update CHANGELOG.md * EthGasConsumeDecorator ante handler resets the gas meter only for CheckTx * Reset the gas meter in Keeper.EthereumTx to an infinite gas meter * Fix TestOutOfGasWhenDeployContract error check * Move gas meter reset to the innermost EthAnteHandle * add NewInfiniteGasMeterWithLimit for setting the user provided gas limit Fixes block's consumed gas calculation in the block creation phase. * Fix lint * Fix lint Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
- Loading branch information
Showing
5 changed files
with
118 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package types | ||
|
||
import ( | ||
fmt "fmt" | ||
math "math" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// ErrorNegativeGasConsumed defines an error thrown when the amount of gas refunded results in a | ||
// negative gas consumed amount. | ||
// Copied from cosmos-sdk | ||
type ErrorNegativeGasConsumed struct { | ||
Descriptor string | ||
} | ||
|
||
// ErrorGasOverflow defines an error thrown when an action results gas consumption | ||
// unsigned integer overflow. | ||
type ErrorGasOverflow struct { | ||
Descriptor string | ||
} | ||
|
||
type infiniteGasMeterWithLimit struct { | ||
consumed sdk.Gas | ||
limit sdk.Gas | ||
} | ||
|
||
// NewInfiniteGasMeterWithLimit returns a reference to a new infiniteGasMeter. | ||
func NewInfiniteGasMeterWithLimit(limit sdk.Gas) sdk.GasMeter { | ||
return &infiniteGasMeterWithLimit{ | ||
consumed: 0, | ||
limit: limit, | ||
} | ||
} | ||
|
||
func (g *infiniteGasMeterWithLimit) GasConsumed() sdk.Gas { | ||
return g.consumed | ||
} | ||
|
||
func (g *infiniteGasMeterWithLimit) GasConsumedToLimit() sdk.Gas { | ||
return g.consumed | ||
} | ||
|
||
func (g *infiniteGasMeterWithLimit) Limit() sdk.Gas { | ||
return g.limit | ||
} | ||
|
||
// addUint64Overflow performs the addition operation on two uint64 integers and | ||
// returns a boolean on whether or not the result overflows. | ||
func addUint64Overflow(a, b uint64) (uint64, bool) { | ||
if math.MaxUint64-a < b { | ||
return 0, true | ||
} | ||
|
||
return a + b, false | ||
} | ||
|
||
func (g *infiniteGasMeterWithLimit) ConsumeGas(amount sdk.Gas, descriptor string) { | ||
var overflow bool | ||
// TODO: Should we set the consumed field after overflow checking? | ||
g.consumed, overflow = addUint64Overflow(g.consumed, amount) | ||
if overflow { | ||
panic(ErrorGasOverflow{descriptor}) | ||
} | ||
} | ||
|
||
// RefundGas will deduct the given amount from the gas consumed. If the amount is greater than the | ||
// gas consumed, the function will panic. | ||
// | ||
// Use case: This functionality enables refunding gas to the trasaction or block gas pools so that | ||
// EVM-compatible chains can fully support the go-ethereum StateDb interface. | ||
// See https://github.com/cosmos/cosmos-sdk/pull/9403 for reference. | ||
func (g *infiniteGasMeterWithLimit) RefundGas(amount sdk.Gas, descriptor string) { | ||
if g.consumed < amount { | ||
panic(ErrorNegativeGasConsumed{Descriptor: descriptor}) | ||
} | ||
|
||
g.consumed -= amount | ||
} | ||
|
||
func (g *infiniteGasMeterWithLimit) IsPastLimit() bool { | ||
return false | ||
} | ||
|
||
func (g *infiniteGasMeterWithLimit) IsOutOfGas() bool { | ||
return false | ||
} | ||
|
||
func (g *infiniteGasMeterWithLimit) String() string { | ||
return fmt.Sprintf("InfiniteGasMeter:\n consumed: %d", g.consumed) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters