Skip to content

Commit 9e576f7

Browse files
committed
count gas refund diff for manual correction in case opcode execution returns ErrWriteProtection
1 parent dcc10c7 commit 9e576f7

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

core/vm/evm.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ type BlockContext struct {
8282
// All fields can change between transactions.
8383
type TxContext struct {
8484
// Message information
85-
Origin common.Address // Provides information for ORIGIN
86-
GasPrice *big.Int // Provides information for GASPRICE
85+
Origin common.Address // Provides information for ORIGIN
86+
GasPrice *big.Int // Provides information for GASPRICE
87+
DeltaRefundByDynamicGas int64 // difference of refund due to dynamicGas
8788
}
8889

8990
// EVM is the Ethereum Virtual Machine base object and provides

core/vm/interpreter.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
147147
// For optimisation reason we're using uint64 as the program counter.
148148
// It's theoretically possible to go above 2^64. The YP defines the PC
149149
// to be uint256. Practically much less so feasible.
150-
pc = uint64(0) // program counter
151-
cost uint64
150+
pc = uint64(0) // program counter
151+
cost uint64
152+
refundBeforeDynamicGas int64
153+
refundDiff int64
152154
// copies used by tracer
153155
pcCopy uint64 // needed for the deferred EVMLogger
154156
gasCopy uint64 // for EVMLogger to log gas remaining before execution
@@ -218,7 +220,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
218220
// Consume the gas and return an error if not enough gas is available.
219221
// cost is explicitly set so that the capture state defer method can get the proper cost
220222
var dynamicCost uint64
223+
refundBeforeDynamicGas = int64(in.evm.StateDB.GetRefund())
221224
dynamicCost, err = operation.dynamicGas(in.evm, contract, stack, mem, memorySize)
225+
refundDiff = int64(in.evm.StateDB.GetRefund()) - refundBeforeDynamicGas
222226
cost += dynamicCost // for tracing
223227
if err != nil || !contract.UseGas(dynamicCost) {
224228
return nil, ErrOutOfGas
@@ -234,6 +238,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
234238
// execute the operation
235239
res, err = operation.execute(&pc, in, callContext)
236240
if err != nil {
241+
if err == ErrWriteProtection {
242+
in.evm.TxContext.DeltaRefundByDynamicGas += refundDiff
243+
}
237244
break
238245
}
239246
pc++

0 commit comments

Comments
 (0)