Merge PR #3072: Catch overflows in gas wanted

* Check for overflow

* Only expect block gas meter on DeliverTx

* ErrGasOverflow in tx.ValidateBasic()

* Update unit test
This commit is contained in:
Christopher Goes 2018-12-10 21:39:29 +01:00 committed by GitHub
parent 2ce41760e2
commit 243576143e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 15 additions and 2 deletions

View File

@ -69,5 +69,6 @@ BUG FIXES
* SDK
* \#2967 Change ordering of `mint.BeginBlocker` and `distr.BeginBlocker`, recalculate inflation each block
* \#3071 Catch overflow on block gas meter
* Tendermint

View File

@ -701,6 +701,11 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
return
}
var startingGas uint64
if mode == runTxModeDeliver {
startingGas = ctx.BlockGasMeter().GasConsumed()
}
defer func() {
if r := recover(); r != nil {
switch rType := r.(type) {
@ -726,6 +731,9 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
if mode == runTxModeDeliver {
ctx.BlockGasMeter().ConsumeGas(
ctx.GasMeter().GasConsumedToLimit(), "block gas meter")
if ctx.BlockGasMeter().GasConsumed() < startingGas {
panic(sdk.ErrorGasOverflow{"tx gas summation"})
}
}
}()

View File

@ -43,6 +43,7 @@ const (
CodeMemoTooLarge CodeType = 13
CodeInsufficientFee CodeType = 14
CodeTooManySignatures CodeType = 15
CodeGasOverflow CodeType = 16
// CodespaceRoot is a codespace for error codes in this file only.
// Notice that 0 is an "unset" codespace, which can be overridden with
@ -143,6 +144,9 @@ func ErrInsufficientFee(msg string) Error {
func ErrTooManySignatures(msg string) Error {
return newErrorWithRootCodespace(CodeTooManySignatures, msg)
}
func ErrGasOverflow(msg string) Error {
return newErrorWithRootCodespace(CodeGasOverflow, msg)
}
//----------------------------------------
// Error & sdkError

View File

@ -43,7 +43,7 @@ func (tx StdTx) ValidateBasic() sdk.Error {
stdSigs := tx.GetSignatures()
if tx.Fee.Gas > maxGasWanted {
return sdk.ErrInternal(fmt.Sprintf("invalid gas supplied; %d > %d", tx.Fee.Gas, maxGasWanted))
return sdk.ErrGasOverflow(fmt.Sprintf("invalid gas supplied; %d > %d", tx.Fee.Gas, maxGasWanted))
}
if !tx.Fee.Amount.IsNotNegative() {
return sdk.ErrInsufficientFee(fmt.Sprintf("invalid fee %s amount provided", tx.Fee.Amount))

View File

@ -127,7 +127,7 @@ func TestTxValidateBasic(t *testing.T) {
err = tx.ValidateBasic()
require.Error(t, err)
require.Equal(t, sdk.CodeInternal, err.Result().Code)
require.Equal(t, sdk.CodeGasOverflow, err.Result().Code)
// require to pass when above criteria are matched
privs, accNums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}