From 9e576f7b3e4be79d4c43f0380823577f93b23fb3 Mon Sep 17 00:00:00 2001 From: Dustin Xie Date: Tue, 22 Nov 2022 20:17:18 -0600 Subject: [PATCH] count gas refund diff for manual correction in case opcode execution returns ErrWriteProtection --- core/vm/evm.go | 5 +++-- core/vm/interpreter.go | 11 +++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/vm/evm.go b/core/vm/evm.go index deac1c0279a6..b840d20c9ac1 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -82,8 +82,9 @@ type BlockContext struct { // All fields can change between transactions. type TxContext struct { // Message information - Origin common.Address // Provides information for ORIGIN - GasPrice *big.Int // Provides information for GASPRICE + Origin common.Address // Provides information for ORIGIN + GasPrice *big.Int // Provides information for GASPRICE + DeltaRefundByDynamicGas int64 // difference of refund due to dynamicGas } // EVM is the Ethereum Virtual Machine base object and provides diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 21e3c914e139..60774ba97619 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -147,8 +147,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // For optimisation reason we're using uint64 as the program counter. // It's theoretically possible to go above 2^64. The YP defines the PC // to be uint256. Practically much less so feasible. - pc = uint64(0) // program counter - cost uint64 + pc = uint64(0) // program counter + cost uint64 + refundBeforeDynamicGas int64 + refundDiff int64 // copies used by tracer pcCopy uint64 // needed for the deferred EVMLogger gasCopy uint64 // for EVMLogger to log gas remaining before execution @@ -218,7 +220,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // Consume the gas and return an error if not enough gas is available. // cost is explicitly set so that the capture state defer method can get the proper cost var dynamicCost uint64 + refundBeforeDynamicGas = int64(in.evm.StateDB.GetRefund()) dynamicCost, err = operation.dynamicGas(in.evm, contract, stack, mem, memorySize) + refundDiff = int64(in.evm.StateDB.GetRefund()) - refundBeforeDynamicGas cost += dynamicCost // for tracing if err != nil || !contract.UseGas(dynamicCost) { return nil, ErrOutOfGas @@ -234,6 +238,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // execute the operation res, err = operation.execute(&pc, in, callContext) if err != nil { + if err == ErrWriteProtection { + in.evm.TxContext.DeltaRefundByDynamicGas += refundDiff + } break } pc++