mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 07:36:44 +00:00
Merge branch 'extended-tracer' into feature/firehose-extended-tracer
# Conflicts: # core/vm/evm.go
This commit is contained in:
commit
09df0e0c95
10 changed files with 125 additions and 53 deletions
|
|
@ -256,7 +256,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
|||
if vmConfig.Tracer != nil {
|
||||
l, ok := vmConfig.Tracer.(BlockchainLogger)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("only extended tracers are supported for live mode")
|
||||
return nil, errors.New("only extended tracers are supported for live mode")
|
||||
}
|
||||
logger = l
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -181,24 +179,24 @@ func (evm *EVM) SetBlockContext(blockCtx BlockContext) {
|
|||
// the necessary steps to create accounts and reverses the state in case of an
|
||||
// execution error or failed value transfer.
|
||||
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
// Capture the tracer start/end events in debug mode
|
||||
if evm.Config.Tracer != nil {
|
||||
if evm.depth == 0 {
|
||||
tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
|
||||
evm.Config.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
|
||||
defer func(startGas uint64) { // Lazy evaluation of the parameters
|
||||
tracer.CaptureEnd(ret, startGas-leftOverGas, err)
|
||||
evm.Config.Tracer.CaptureEnd(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
} else {
|
||||
// Handle tracer events for entering and exiting a call frame
|
||||
tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
|
||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
|
||||
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
|
||||
defer func(startGas uint64) {
|
||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
||||
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
}
|
||||
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
|
|
@ -212,6 +210,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
|
||||
if !evm.StateDB.Exist(addr) {
|
||||
if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
|
||||
// Calling a non-existing account, don't do anything.
|
||||
return nil, gas, nil
|
||||
}
|
||||
evm.StateDB.CreateAccount(addr)
|
||||
|
|
@ -237,7 +236,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
}
|
||||
}
|
||||
// When an error was returned by the EVM or when setting the creation code
|
||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||
// above we revert to the snapshot and consume any gas remaining. Additionally,
|
||||
// when we're in homestead this also counts for code storage gas errors.
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
|
|
@ -264,16 +263,15 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
// code with the caller as context.
|
||||
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
|
||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
if evm.Config.Tracer != nil {
|
||||
evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
|
||||
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
|
||||
defer func(startGas uint64) {
|
||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
||||
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
|
|
@ -319,20 +317,19 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
|||
// code with the caller as context and the caller is set to the caller of the caller.
|
||||
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
if evm.Config.Tracer != nil {
|
||||
// NOTE: caller must, at all times be a contract. It should never happen
|
||||
// that caller is something other than a Contract.
|
||||
parent := caller.(*Contract)
|
||||
// DELEGATECALL inherits value from parent call
|
||||
tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
|
||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
|
||||
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
|
||||
defer func(startGas uint64) {
|
||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
||||
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
|
|
@ -369,16 +366,15 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
|||
// instead of performing the modifications.
|
||||
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
|
||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
if evm.Config.Tracer != nil {
|
||||
evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
|
||||
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
|
||||
defer func(startGas uint64) {
|
||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
||||
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
|
|
@ -439,24 +435,23 @@ func (c *codeAndHash) Hash() common.Hash {
|
|||
}
|
||||
|
||||
// create creates a new contract using code as deployment code.
|
||||
func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) (ret []byte, created common.Address, leftOverGas uint64, err error) {
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftoverGas uint64, err error) {
|
||||
if evm.Config.Tracer != nil {
|
||||
if evm.depth == 0 {
|
||||
tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
|
||||
defer func(startGas uint64) {
|
||||
tracer.CaptureEnd(ret, startGas-leftOverGas, err)
|
||||
}(gas)
|
||||
evm.Config.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
|
||||
defer func() {
|
||||
evm.Config.Tracer.CaptureEnd(ret, gas-leftoverGas, err)
|
||||
}()
|
||||
} else {
|
||||
tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
|
||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
|
||||
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||
|
||||
defer func(startGas uint64) {
|
||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
||||
}(gas)
|
||||
defer func() {
|
||||
evm.Config.Tracer.OnGasConsumed(leftoverGas, leftoverGas, GasBuyBack)
|
||||
evm.Config.Tracer.CaptureExit(ret, gas-leftoverGas, err)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// Depth check execution. Fail if we're trying to execute above the
|
||||
// limit.
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
|
|
@ -523,7 +518,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
}
|
||||
|
||||
// When an error was returned by the EVM or when setting the creation code
|
||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||
// above we revert to the snapshot and consume any gas remaining. Additionally,
|
||||
// when we're in homestead this also counts for code storage gas errors.
|
||||
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
|
|
|
|||
|
|
@ -562,7 +562,6 @@ func TestTracingWithOverrides(t *testing.T) {
|
|||
From: &accounts[0].addr,
|
||||
// BLOCKNUMBER PUSH1 MSTORE
|
||||
Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")),
|
||||
//&hexutil.Bytes{0x43}, // blocknumber
|
||||
},
|
||||
config: &TraceCallConfig{
|
||||
BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
|||
return fmt.Errorf("failed to unmarshal trace result: %v", err)
|
||||
}
|
||||
if !jsonEqualFlat(ret, test.Result) {
|
||||
t.Logf("tracer name: %s", tracerName)
|
||||
t.Logf("test %s failed", filename)
|
||||
|
||||
// uncomment this for easier debugging
|
||||
// have, _ := json.MarshalIndent(ret, "", " ")
|
||||
|
|
|
|||
|
|
@ -56,6 +56,16 @@
|
|||
"value": "0x0",
|
||||
"gas": "0x1f97e",
|
||||
"gasUsed": "0x72de",
|
||||
"input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000"
|
||||
"input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000",
|
||||
"calls": [{
|
||||
"from":"0x6c06b16512b332e6cd8293a2974872674716ce18",
|
||||
"gas":"0x8fc",
|
||||
"gasUsed":"0x0",
|
||||
"to":"0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
|
||||
"input":"0x",
|
||||
"error":"insufficient balance for transfer",
|
||||
"value":"0x14d1120d7b160000",
|
||||
"type":"CALL"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,12 +63,27 @@
|
|||
"address": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224"
|
||||
},
|
||||
"traceAddress": [],
|
||||
"subtraces": 0,
|
||||
"subtraces": 1,
|
||||
"transactionPosition": 74,
|
||||
"transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4",
|
||||
"blockNumber": 1555279,
|
||||
"blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46",
|
||||
"time": "209.346µs"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"balance": "0x0",
|
||||
"callType": "callcode",
|
||||
"from": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224",
|
||||
"gas": "0xaf64",
|
||||
"to": "0x0000000000000000000000000000000000000004",
|
||||
"value": "0x13"
|
||||
},
|
||||
"error": "insufficient balance for transfer",
|
||||
"result": {},
|
||||
"subtraces": 0,
|
||||
"traceAddress": [0],
|
||||
"type": "call"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,9 +64,23 @@
|
|||
"gasUsed": "0x72de",
|
||||
"output": "0x"
|
||||
},
|
||||
"subtraces": 0,
|
||||
"subtraces": 1,
|
||||
"traceAddress": [],
|
||||
"type": "call"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"callType": "call",
|
||||
"from": "0x6c06b16512b332e6cd8293a2974872674716ce18",
|
||||
"gas": "0x8fc",
|
||||
"to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
|
||||
"value": "0x14d1120d7b160000"
|
||||
},
|
||||
"error": "insufficient balance for transfer",
|
||||
"result": {},
|
||||
"subtraces": 0,
|
||||
"traceAddress": [0],
|
||||
"type": "call"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,12 +70,25 @@
|
|||
"output": "0x"
|
||||
},
|
||||
"traceAddress": [],
|
||||
"subtraces": 0,
|
||||
"subtraces": 1,
|
||||
"transactionPosition": 26,
|
||||
"transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4",
|
||||
"blockNumber": 839247,
|
||||
"blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c",
|
||||
"time": "182.267µs"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"from": "0x76554b33410b6d90b7dc889bfed0451ad195f27e",
|
||||
"gas": "0x25a18",
|
||||
"init": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"value": "0xa"
|
||||
},
|
||||
"error": "insufficient balance for transfer",
|
||||
"result": {},
|
||||
"subtraces": 0,
|
||||
"traceAddress": [0],
|
||||
"type": "create"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -63,13 +63,26 @@
|
|||
"address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca"
|
||||
},
|
||||
"traceAddress": [],
|
||||
"subtraces": 1,
|
||||
"subtraces": 2,
|
||||
"transactionPosition": 14,
|
||||
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
|
||||
"blockNumber": 1555146,
|
||||
"blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e",
|
||||
"time": "187.145µs"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"from": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca",
|
||||
"gas": "0x50ac",
|
||||
"init": "0x5a",
|
||||
"value": "0x1"
|
||||
},
|
||||
"error": "insufficient balance for transfer",
|
||||
"result": {},
|
||||
"subtraces": 0,
|
||||
"traceAddress": [0],
|
||||
"type": "create"
|
||||
},
|
||||
{
|
||||
"type": "suicide",
|
||||
"action": {
|
||||
|
|
@ -79,7 +92,7 @@
|
|||
},
|
||||
"result": null,
|
||||
"traceAddress": [
|
||||
0
|
||||
1
|
||||
],
|
||||
"subtraces": 0,
|
||||
"transactionPosition": 14,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue