Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support trace API similar to OpenEthereum/Parity's one #211

Merged
merged 75 commits into from
Nov 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
6be3792
tracer: Add call_tracer_open_ethereum with formatted output similar t…
ziogaschr Oct 2, 2020
0bcd35b
tracer: Expose trace_traceTransaction API (draft, might change)
ziogaschr Oct 2, 2020
5752398
tracer: Add `trace_traceBlock*` methods
ziogaschr Oct 2, 2020
c2b0717
Rename TraceBlockByNumber to TraceBlock for compatibility with OpenEt…
ziogaschr Oct 5, 2020
7a4afdb
Rename trace methods for compatibility with OpenEthereum names
ziogaschr Oct 6, 2020
9228a99
tracer: add dump trace_filter func
ziogaschr Oct 6, 2020
8efa8a4
tracer: include `blockHash`, `transactionHash` and `transactionPositi…
ziogaschr Oct 7, 2020
7770fc1
tracer: small change to accumulateRewards to make it available to the…
ziogaschr Oct 9, 2020
590fdf2
tracer: restructure PrivateTraceAPI to its own file
ziogaschr Oct 9, 2020
66362d8
tracer: add block/uncle rewards in trace_block
ziogaschr Oct 9, 2020
7b56e95
tracer: reorder tracer json fields
ziogaschr Oct 9, 2020
350afc9
Cleanup
ziogaschr Oct 12, 2020
548de0d
tracer: handle gas 2300 stipend
ziogaschr Oct 13, 2020
da1a1ec
tracer: Add mapping of core-geth errors to OpenEthereum ones
ziogaschr Oct 13, 2020
b5b4990
tracer: handle op=selfdestruct similar to OpenEthereum
ziogaschr Oct 13, 2020
f6996ac
tracer: cleanup reward structs
ziogaschr Oct 14, 2020
2ec697c
tracer: JS better handling of typeof undefined
ziogaschr Oct 14, 2020
9ac36bd
tracer: JS rename oeErrorMapping
ziogaschr Oct 14, 2020
f583aaa
tracer: JS cleanup 🧽
ziogaschr Oct 14, 2020
3c07e02
tracer: JS refactor/cleanup finalize()
ziogaschr Oct 14, 2020
8a2dd93
tracer: JS add additional error maps
ziogaschr Oct 14, 2020
5ddf481
js/tracers: make OpenEthereum calltracer report value in selfdestructs
ziogaschr Oct 14, 2020
860f014
tracer: JS better handling of gas and gasUsed (remove the stipend hack)
ziogaschr Oct 14, 2020
82c221d
tracer: JS OE compatibility fixes
ziogaschr Oct 14, 2020
8c5a412
tracer: JS handle out of gas errors
ziogaschr Oct 14, 2020
05bfa16
tracer: JS temp hack for compatibility (to be changed)
ziogaschr Oct 14, 2020
791c601
tracer: fix handling of op=delegatecall value
ziogaschr Oct 14, 2020
4e4f55b
tracer: better naming for isDynamicGas variable (still not sure if ac…
ziogaschr Oct 14, 2020
e3fcba6
tracer: add more error mappings
ziogaschr Oct 14, 2020
fa1a6b6
tracer: op=CREATE2 to return type=CREATE for OE compatibility
ziogaschr Oct 14, 2020
6099dbc
eth: clean ineffectual assigns re: OE tracer config setting
meowsbits Oct 15, 2020
d1b01a9
eth: (lint) remove unnecessary type conversion
meowsbits Oct 15, 2020
14a05d2
eth: (lint:gosimple) replace iterating assign with variadic append
meowsbits Oct 15, 2020
582c97a
main: add 'trace:1.0' to console test
meowsbits Oct 15, 2020
69d7e09
eth: add benchmarking test for slice append patterns
meowsbits Oct 15, 2020
c0a40fd
tracer: remove unused OpenEthereumTrace fields
ziogaschr Oct 19, 2020
0801f65
tracer: JS cleanup
ziogaschr Oct 19, 2020
da163f9
tracer: Set value=0x0 for op=STATICCALL
ziogaschr Oct 19, 2020
0119efd
tracer: JS handle output based on op=RETURN
ziogaschr Oct 19, 2020
64d05c9
tracer: JS remove the uneeded isDynamic check on gas
ziogaschr Oct 19, 2020
75a90fa
tracer: JS on “out of gas” Failure set gas=0x0
ziogaschr Oct 19, 2020
d604f32
tracer: JS fix
ziogaschr Oct 21, 2020
fc900c0
tracer: revert remove unused OpenEthereumTrace fields
ziogaschr Oct 21, 2020
0d757e0
tracer: JS OE handle “return data out of bounds”
ziogaschr Oct 21, 2020
06a14f6
tracer: JS OE on fault, try to get gas from inner calls
ziogaschr Oct 21, 2020
44208e2
Revert "eth: clean ineffectual assigns re: OE tracer config setting"
ziogaschr Oct 21, 2020
c32bcd6
core/vm: track 63/64 call gas off stack
ziogaschr Oct 29, 2020
d9de8f3
tracer: pass the true available gas for an opcode call in CaptureState
ziogaschr Oct 31, 2020
b78b08f
tracer/js: extend JS log tracer with getAvailableGas per call
ziogaschr Oct 31, 2020
87a885e
tracer/js: extend JS log tracer with getReturnData
ziogaschr Oct 31, 2020
d9eebfc
tracer/js: add "Out of stack” error mapping for OE tracer
ziogaschr Oct 31, 2020
becfd6d
tracer/js: handle edje cases where first time in callstack remains em…
ziogaschr Oct 31, 2020
a94bede
tracer/js: extend OE JS tracer to return compatible gas with OE using…
ziogaschr Nov 1, 2020
269474b
tracer/js: extend OE JS tracer to use getReturnData to decide if the …
ziogaschr Nov 1, 2020
dfa7777
tracer/js: bring back wrongly removed line
ziogaschr Nov 1, 2020
6fff135
cleanup
ziogaschr Nov 1, 2020
a50e971
tracer/js: handle precompiled contract failures on CALL opcodes
ziogaschr Nov 1, 2020
ecad577
tracer/js: expose system opcode errors in JS tracers
ziogaschr Nov 2, 2020
c956731
cleanup
ziogaschr Nov 2, 2020
72251c2
tracer/js: read system opcode error in OE JS tracer
ziogaschr Nov 2, 2020
955fa16
tracer/js: extend OE JS tracer to use only getReturnData for CALL rel…
ziogaschr Nov 2, 2020
0de90ff
tracers: generate assets.go
ziogaschr Nov 2, 2020
e4a3a5c
tracers/js: cleanup
ziogaschr Nov 2, 2020
88bbfb2
tracer: Rename call_tracer_open_ethereum to call_tracer_parity and re…
ziogaschr Nov 2, 2020
c89f77c
tracer: fix lint issues
ziogaschr Nov 3, 2020
39fcedf
tracer/js: add TODO comment
ziogaschr Nov 4, 2020
dbe01d4
core/vm: track 63/64 create gas off stack (fix)
ziogaschr Nov 4, 2020
05f0d9c
tracers: generate assets.go
ziogaschr Nov 4, 2020
c5b5386
core/vm: add createGasEip150 for CREATE/CREATE2 gas calc of 63/64 rul…
ziogaschr Nov 4, 2020
b66cd1c
core/vm: cleanup use of evm.callGasTemp in interpreter
ziogaschr Nov 4, 2020
0f710a4
Merge branch 'master' into feat/openethereum-trace-apis
ziogaschr Nov 4, 2020
ad4fdbe
consensus/ethash: better name for AccumulateRewards -> GetRewards
ziogaschr Nov 5, 2020
e1a3c01
ethash: remove unnecessarily defensive conditional
meowsbits Nov 5, 2020
45d5f66
core/vm, eth/tracers: make `evm.callGasTemp` public `evm.CallGasTemp`
ziogaschr Nov 5, 2020
e447981
eth/tracers: fix broken test `call_tracer_inner_create_oog_outer_thro…
ziogaschr Nov 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/geth/consolecmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
)

const (
ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0"
ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 trace:1.0 txpool:1.0 web3:1.0"
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
)

Expand Down
31 changes: 22 additions & 9 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,31 +584,44 @@ var (
big32 = big.NewInt(32)
)

// AccumulateRewards credits the coinbase of the given block with the mining
// reward. The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also rewarded.
func accumulateRewards(config ctypes.ChainConfigurator, state *state.StateDB, header *types.Header, uncles []*types.Header) {
// GetRewards calculates the mining reward.
// The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also calculated.
func GetRewards(config ctypes.ChainConfigurator, header *types.Header, uncles []*types.Header) (*big.Int, []*big.Int) {
if config.IsEnabled(config.GetEthashECIP1017Transition, header.Number) {
ecip1017BlockReward(config, state, header, uncles)
return
return ecip1017BlockReward(config, header, uncles)
}

blockReward := ctypes.EthashBlockReward(config, header.Number)

// Accumulate the rewards for the miner and any included uncles
uncleRewards := make([]*big.Int, len(uncles))
reward := new(big.Int).Set(blockReward)
r := new(big.Int)
for _, uncle := range uncles {
for i, uncle := range uncles {
r.Add(uncle.Number, big8)
r.Sub(r, header.Number)
r.Mul(r, blockReward)
r.Div(r, big8)
state.AddBalance(uncle.Coinbase, r)

ur := new(big.Int).Set(r)
uncleRewards[i] = ur

r.Div(blockReward, big32)
reward.Add(reward, r)
}
state.AddBalance(header.Coinbase, reward)

return reward, uncleRewards
}

// accumulateRewards credits the coinbase of the given block with the mining
// reward. The coinbase of each uncle block is also rewarded.
func accumulateRewards(config ctypes.ChainConfigurator, state *state.StateDB, header *types.Header, uncles []*types.Header) {
minerReward, uncleRewards := GetRewards(config, header, uncles)
for i, uncle := range uncles {
state.AddBalance(uncle.Coinbase, uncleRewards[i])
}
state.AddBalance(header.Coinbase, minerReward)
}

// As of "Era 2" (zero-index era 1), uncle miners and winners are rewarded equally for each included block.
Expand Down
11 changes: 6 additions & 5 deletions consensus/ethash/consensus_classic.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ package ethash
import (
"math/big"

"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params/types/ctypes"
"github.com/ethereum/go-ethereum/params/vars"
)

func ecip1017BlockReward(config ctypes.ChainConfigurator, state *state.StateDB, header *types.Header, uncles []*types.Header) {
func ecip1017BlockReward(config ctypes.ChainConfigurator, header *types.Header, uncles []*types.Header) (*big.Int, []*big.Int) {
blockReward := vars.FrontierBlockReward

// Ensure value 'era' is configured.
Expand All @@ -33,13 +32,15 @@ func ecip1017BlockReward(config ctypes.ChainConfigurator, state *state.StateDB,
wr := GetBlockWinnerRewardByEra(era, blockReward) // wr "winner reward". 5, 4, 3.2, 2.56, ...
wurs := GetBlockWinnerRewardForUnclesByEra(era, uncles, blockReward) // wurs "winner uncle rewards"
wr.Add(wr, wurs)
state.AddBalance(header.Coinbase, wr) // $$

// Reward uncle miners.
for _, uncle := range uncles {
uncleRewards := make([]*big.Int, len(uncles))
for i, uncle := range uncles {
ur := GetBlockUncleRewardByEra(era, header, uncle, blockReward)
state.AddBalance(uncle.Coinbase, ur) // $$
uncleRewards[i] = ur
}

return wr, uncleRewards
}

func ecip1010Explosion(config ctypes.ChainConfigurator, next *big.Int, exPeriodRef *big.Int) {
Expand Down
7 changes: 5 additions & 2 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,13 @@ type EVM struct {
// abort is used to abort the EVM calling operations
// NOTE: must be set atomically
abort int32
// callGasTemp holds the gas available for the current call. This is needed because the
// CallGasTemp holds the gas available for the current call. This is needed because the
// available gas is calculated in gasCall* according to the 63/64 rule and later
// applied in opCall*.
callGasTemp uint64
CallGasTemp uint64
// callErrorTemp holds any errors caused during the execution of system opcodes (0xf0)
// NOTE: it's being used only for tracers
CallErrorTemp error
}

// NewEVM returns a new EVM. The returned EVM is not thread safe and should
Expand Down
12 changes: 12 additions & 0 deletions core/vm/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ const (
GasExtStep uint64 = 20
)

// createGas returns the actual gas available for the call.
//
// The cost of gas was changed during the homestead price change HF.
// As part of EIP 150 (TangerineWhistle), the returned gas is gas - gas * 63 / 64.
func createGasEip150(isEip150 bool, availableGas uint64) (uint64, error) {
if isEip150 {
gas := availableGas - availableGas/64
return gas, nil
}
return availableGas, nil
}

// callGas returns the actual gas cost of the call.
//
// The cost of gas was changed during the homestead price change HF.
Expand Down
48 changes: 39 additions & 9 deletions core/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,28 @@ var (
gasMLoad = pureMemoryGascost
gasMStore8 = pureMemoryGascost
gasMStore = pureMemoryGascost
gasCreate = pureMemoryGascost
)

func gasCreate(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var overflow bool
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
remainingGasTemp, overflow := math.SafeSub(contract.Gas, gas)
if overflow {
return 0, ErrGasUintOverflow
}
evm.CallGasTemp, err = createGasEip150(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), remainingGasTemp)
if err != nil {
return 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, ErrGasUintOverflow
}
return gas, nil
}

func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
Expand All @@ -301,6 +320,17 @@ func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memoryS
if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
return 0, ErrGasUintOverflow
}
remainingGasTemp, overflow := math.SafeSub(contract.Gas, gas)
if overflow {
return 0, ErrGasUintOverflow
}
evm.CallGasTemp, err = createGasEip150(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), remainingGasTemp)
if err != nil {
return 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, ErrGasUintOverflow
}
return gas, nil
}

Expand Down Expand Up @@ -356,11 +386,11 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
return 0, ErrGasUintOverflow
}

evm.callGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
evm.CallGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, ErrGasUintOverflow
}
return gas, nil
Expand All @@ -381,11 +411,11 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory
if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
return 0, ErrGasUintOverflow
}
evm.callGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
evm.CallGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, ErrGasUintOverflow
}
return gas, nil
Expand All @@ -396,12 +426,12 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
if err != nil {
return 0, err
}
evm.callGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
evm.CallGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
var overflow bool
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, ErrGasUintOverflow
}
return gas, nil
Expand All @@ -412,12 +442,12 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
if err != nil {
return 0, err
}
evm.callGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
evm.CallGasTemp, err = callGas(evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP150Transition, evm.BlockNumber), contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
var overflow bool
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, ErrGasUintOverflow
}
return gas, nil
Expand Down
35 changes: 17 additions & 18 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,15 +599,11 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
value = callContext.stack.pop()
offset, size = callContext.stack.pop(), callContext.stack.pop()
input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
gas = callContext.contract.Gas
gas = interpreter.evm.CallGasTemp
)
if interpreter.evm.ChainConfig().IsEnabled(interpreter.evm.chainConfig.GetEIP150Transition, interpreter.evm.BlockNumber) {
gas -= gas / 64
}
// reuse size int for stackvalue
stackvalue := size

callContext.contract.UseGas(gas)
//TODO: use uint256.Int instead of converting with toBig()
var bigVal = big0
if !value.IsZero() {
Expand All @@ -621,8 +617,10 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
// ignore this error and pretend the operation was successful.
if interpreter.evm.ChainConfig().IsEnabled(interpreter.evm.chainConfig.GetEIP2Transition, interpreter.evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
stackvalue.Clear()
interpreter.evm.CallErrorTemp = suberr // temp storage, for debug tracing
} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
stackvalue.Clear()
interpreter.evm.CallErrorTemp = suberr // temp storage, for debug tracing
} else {
stackvalue.SetBytes(addr.Bytes())
}
Expand All @@ -641,12 +639,8 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([
offset, size = callContext.stack.pop(), callContext.stack.pop()
salt = callContext.stack.pop()
input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
gas = callContext.contract.Gas
gas = interpreter.evm.CallGasTemp
)

// Apply EIP150
gas -= gas / 64
callContext.contract.UseGas(gas)
// reuse size int for stackvalue
stackvalue := size
//TODO: use uint256.Int instead of converting with toBig()
Expand All @@ -659,6 +653,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([
// Push item on the stack based on the returned error.
if suberr != nil {
stackvalue.Clear()
interpreter.evm.CallErrorTemp = suberr // temp storage, for debug tracing
} else {
stackvalue.SetBytes(addr.Bytes())
}
Expand All @@ -673,10 +668,10 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([

func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
stack := callContext.stack
// Pop gas. The actual gas in interpreter.evm.callGasTemp.
// Pop gas. The actual gas in interpreter.evm.CallGasTemp.
// We can use this as a temporary value
temp := stack.pop()
gas := interpreter.evm.callGasTemp
gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20())
Expand All @@ -696,6 +691,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by

if err != nil {
temp.Clear()
interpreter.evm.CallErrorTemp = err // temp storage, for debug tracing
} else {
temp.SetOne()
}
Expand All @@ -709,11 +705,11 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by
}

func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
// Pop gas. The actual gas is in interpreter.evm.CallGasTemp.
stack := callContext.stack
// We use it as a temporary value
temp := stack.pop()
gas := interpreter.evm.callGasTemp
gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20())
Expand All @@ -730,6 +726,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
ret, returnGas, err := interpreter.evm.CallCode(callContext.contract, toAddr, args, gas, bigVal)
if err != nil {
temp.Clear()
interpreter.evm.CallErrorTemp = err // temp storage, for debug tracing
} else {
temp.SetOne()
}
Expand All @@ -744,10 +741,10 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (

func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
stack := callContext.stack
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
// Pop gas. The actual gas is in interpreter.evm.CallGasTemp.
// We use it as a temporary value
temp := stack.pop()
gas := interpreter.evm.callGasTemp
gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20())
Expand All @@ -757,6 +754,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCt
ret, returnGas, err := interpreter.evm.DelegateCall(callContext.contract, toAddr, args, gas)
if err != nil {
temp.Clear()
interpreter.evm.CallErrorTemp = err // temp storage, for debug tracing
} else {
temp.SetOne()
}
Expand All @@ -770,11 +768,11 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCt
}

func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
// Pop gas. The actual gas is in interpreter.evm.CallGasTemp.
stack := callContext.stack
// We use it as a temporary value
temp := stack.pop()
gas := interpreter.evm.callGasTemp
gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20())
Expand All @@ -784,6 +782,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx)
ret, returnGas, err := interpreter.evm.StaticCall(callContext.contract, toAddr, args, gas)
if err != nil {
temp.Clear()
interpreter.evm.CallErrorTemp = err // temp storage, for debug tracing
} else {
temp.SetOne()
}
Expand Down
4 changes: 4 additions & 0 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
logged, pcCopy, gasCopy = false, pc, contract.Gas
}

// Clean up the CallGasTemp on every iteration, as you never know how it might be used in the future, causing false positives
in.evm.CallGasTemp = 0

// Get the operation from the jump table and validate the stack to ensure there are
// enough stack items available to perform the operation.
op = contract.GetOp(pc)
Expand Down Expand Up @@ -246,6 +249,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
return nil, ErrGasUintOverflow
}
}

// Dynamic portion of gas
// 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
Expand Down
Loading