From 51ff5d48a9b3319cecff89f99782a765c2c09be6 Mon Sep 17 00:00:00 2001 From: Austin Abell Date: Tue, 29 Oct 2019 11:52:26 -0400 Subject: [PATCH] Fixes gas limit for simulated transaction (#130) * Fixes call gas limit for stdTxs * reword comment --- app/ante.go | 4 ++-- x/evm/handler.go | 4 ++-- x/evm/types/state_transition.go | 21 ++++++++++++++++----- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/ante.go b/app/ante.go index fe4e00e8..8a110392 100644 --- a/app/ante.go +++ b/app/ante.go @@ -257,7 +257,7 @@ func ethAnteHandler( // Set gas meter after ante handler to ignore gaskv costs newCtx = auth.SetGasMeter(sim, ctx, ethTxMsg.Data.GasLimit) - gas, _ := ethcore.IntrinsicGas(ethTxMsg.Data.Payload, ethTxMsg.To() == nil, false) + gas, _ := ethcore.IntrinsicGas(ethTxMsg.Data.Payload, ethTxMsg.To() == nil, true) newCtx.GasMeter().ConsumeGas(gas, "eth intrinsic gas") return newCtx, sdk.Result{}, false @@ -313,7 +313,7 @@ func validateSignature(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) (sdk.A // constant value of 21000 plus any cost inccured by additional bytes of data // supplied with the transaction. func validateIntrinsicGas(ethTxMsg *evmtypes.EthereumTxMsg) sdk.Result { - gas, err := ethcore.IntrinsicGas(ethTxMsg.Data.Payload, ethTxMsg.To() == nil, false) + gas, err := ethcore.IntrinsicGas(ethTxMsg.Data.Payload, ethTxMsg.To() == nil, true) if err != nil { return sdk.ErrInternal(fmt.Sprintf("failed to compute intrinsic gas cost: %s", err)).Result() } diff --git a/x/evm/handler.go b/x/evm/handler.go index ebd641e4..4b121203 100644 --- a/x/evm/handler.go +++ b/x/evm/handler.go @@ -73,7 +73,7 @@ func handleETHTxMsg(ctx sdk.Context, keeper Keeper, msg types.EthereumTxMsg) sdk keeper.csdb.Prepare(ethHash, common.Hash{}, keeper.txCount.get()) keeper.txCount.increment() - res, bloom := st.TransitionCSDB(ctx) + bloom, res := st.TransitionCSDB(ctx) keeper.bloom.Or(keeper.bloom, bloom) return res } @@ -110,6 +110,6 @@ func handleEmintMsg(ctx sdk.Context, keeper Keeper, msg types.EmintMsg) sdk.Resu keeper.csdb.Prepare(common.Hash{}, common.Hash{}, keeper.txCount.get()) // Cannot provide tx hash keeper.txCount.increment() - res, _ := st.TransitionCSDB(ctx) + _, res := st.TransitionCSDB(ctx) return res } diff --git a/x/evm/types/state_transition.go b/x/evm/types/state_transition.go index 9c35ef96..0e1eff0e 100644 --- a/x/evm/types/state_transition.go +++ b/x/evm/types/state_transition.go @@ -29,15 +29,26 @@ type StateTransition struct { } // TransitionCSDB performs an evm state transition from a transaction -func (st StateTransition) TransitionCSDB(ctx sdk.Context) (sdk.Result, *big.Int) { +func (st StateTransition) TransitionCSDB(ctx sdk.Context) (*big.Int, sdk.Result) { contractCreation := st.Recipient == nil if res := st.checkNonce(); !res.IsOK() { - return res, nil + return nil, res + } + + cost, err := core.IntrinsicGas(st.Payload, st.Recipient == nil, true) + if err != nil { + return nil, sdk.ErrOutOfGas("invalid intrinsic gas for transaction").Result() } // This gas limit the the transaction gas limit with intrinsic gas subtracted - gasLimit := ctx.GasMeter().Limit() + gasLimit := st.GasLimit - ctx.GasMeter().GasConsumed() + + if st.Simulate { + // gasLimit is set here because stdTxs incur gaskv charges in the ante handler, but for eth_call + // the cost needs to be the same as an Ethereum transaction sent through the web3 API + gasLimit = st.GasLimit - cost + } // Create context for evm context := vm.Context{ @@ -92,7 +103,7 @@ func (st StateTransition) TransitionCSDB(ctx sdk.Context) (sdk.Result, *big.Int) if vmerr != nil { res := emint.ErrVMExecution(vmerr.Error()).Result() res.Data = returnData - return res, nil + return nil, res } // TODO: Refund unused gas here, if intended in future @@ -103,7 +114,7 @@ func (st StateTransition) TransitionCSDB(ctx sdk.Context) (sdk.Result, *big.Int) // Out of gas check does not need to be done here since it is done within the EVM execution ctx.GasMeter().ConsumeGas(gasLimit-leftOverGas, "EVM execution consumption") - return sdk.Result{Data: returnData, GasUsed: st.GasLimit - leftOverGas}, bloomInt + return bloomInt, sdk.Result{Data: returnData, GasUsed: st.GasLimit - leftOverGas} } func (st *StateTransition) checkNonce() sdk.Result {