2021-01-25 16:36:39 +03:00
// Copyright 2021 The go-ethereum Authors
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
2021-01-25 16:36:39 +03:00
package tracers
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
import (
2018-10-15 13:28:44 +03:00
"bufio"
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
"bytes"
"context"
"errors"
"fmt"
"io/ioutil"
2018-10-15 13:28:44 +03:00
"os"
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
"runtime"
"sync"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
2021-01-25 16:36:39 +03:00
"github.com/ethereum/go-ethereum/consensus"
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
"github.com/ethereum/go-ethereum/core"
2018-05-07 14:35:06 +03:00
"github.com/ethereum/go-ethereum/core/rawdb"
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
2021-01-25 16:36:39 +03:00
"github.com/ethereum/go-ethereum/ethdb"
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/log"
2020-10-23 09:26:57 +03:00
"github.com/ethereum/go-ethereum/params"
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
)
const (
// defaultTraceTimeout is the amount of time a single transaction can execute
// by default before being forcefully aborted.
defaultTraceTimeout = 5 * time . Second
// defaultTraceReexec is the number of blocks the tracer is willing to go back
// and reexecute to produce missing historical state necessary to run a specific
// trace.
defaultTraceReexec = uint64 ( 128 )
)
2021-01-25 16:36:39 +03:00
// Backend interface provides the common API services (that are provided by
// both full and light clients) with access to necessary functions.
type Backend interface {
HeaderByHash ( ctx context . Context , hash common . Hash ) ( * types . Header , error )
HeaderByNumber ( ctx context . Context , number rpc . BlockNumber ) ( * types . Header , error )
BlockByHash ( ctx context . Context , hash common . Hash ) ( * types . Block , error )
BlockByNumber ( ctx context . Context , number rpc . BlockNumber ) ( * types . Block , error )
GetTransaction ( ctx context . Context , txHash common . Hash ) ( * types . Transaction , common . Hash , uint64 , uint64 , error )
RPCGasCap ( ) uint64
ChainConfig ( ) * params . ChainConfig
Engine ( ) consensus . Engine
ChainDb ( ) ethdb . Database
StateAtBlock ( ctx context . Context , block * types . Block , reexec uint64 ) ( * state . StateDB , func ( ) , error )
StateAtTransaction ( ctx context . Context , block * types . Block , txIndex int , reexec uint64 ) ( core . Message , vm . BlockContext , * state . StateDB , func ( ) , error )
StatesInRange ( ctx context . Context , fromBlock * types . Block , toBlock * types . Block , reexec uint64 ) ( [ ] * state . StateDB , func ( ) , error )
}
// API is the collection of tracing APIs exposed over the private debugging endpoint.
type API struct {
backend Backend
}
// NewAPI creates a new API definition for the tracing methods of the Ethereum service.
func NewAPI ( backend Backend ) * API {
return & API { backend : backend }
}
type chainContext struct {
api * API
ctx context . Context
}
func ( context * chainContext ) Engine ( ) consensus . Engine {
return context . api . backend . Engine ( )
}
func ( context * chainContext ) GetHeader ( hash common . Hash , number uint64 ) * types . Header {
header , err := context . api . backend . HeaderByNumber ( context . ctx , rpc . BlockNumber ( number ) )
if err != nil {
return nil
}
if header . Hash ( ) == hash {
return header
}
header , err = context . api . backend . HeaderByHash ( context . ctx , hash )
if err != nil {
return nil
}
return header
}
// chainContext construts the context reader which is used by the evm for reading
// the necessary chain context.
func ( api * API ) chainContext ( ctx context . Context ) core . ChainContext {
return & chainContext { api : api , ctx : ctx }
}
// blockByNumber is the wrapper of the chain access function offered by the backend.
// It will return an error if the block is not found.
func ( api * API ) blockByNumber ( ctx context . Context , number rpc . BlockNumber ) ( * types . Block , error ) {
block , err := api . backend . BlockByNumber ( ctx , number )
if err != nil {
return nil , err
}
if block == nil {
return nil , fmt . Errorf ( "block #%d not found" , number )
}
return block , nil
}
// blockByHash is the wrapper of the chain access function offered by the backend.
// It will return an error if the block is not found.
func ( api * API ) blockByHash ( ctx context . Context , hash common . Hash ) ( * types . Block , error ) {
block , err := api . backend . BlockByHash ( ctx , hash )
if err != nil {
return nil , err
}
if block == nil {
return nil , fmt . Errorf ( "block %s not found" , hash . Hex ( ) )
}
return block , nil
}
// blockByNumberAndHash is the wrapper of the chain access function offered by
// the backend. It will return an error if the block is not found.
//
// Note this function is friendly for the light client which can only retrieve the
// historical(before the CHT) header/block by number.
func ( api * API ) blockByNumberAndHash ( ctx context . Context , number rpc . BlockNumber , hash common . Hash ) ( * types . Block , error ) {
block , err := api . blockByNumber ( ctx , number )
if err != nil {
return nil , err
}
if block . Hash ( ) == hash {
return block , nil
}
return api . blockByHash ( ctx , hash )
}
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// TraceConfig holds extra parameters to trace functions.
type TraceConfig struct {
* vm . LogConfig
Tracer * string
Timeout * string
Reexec * uint64
}
2018-10-15 13:28:44 +03:00
// StdTraceConfig holds extra parameters to standard-json trace functions.
type StdTraceConfig struct {
2020-12-02 14:49:20 +03:00
vm . LogConfig
2018-10-15 13:28:44 +03:00
Reexec * uint64
2018-12-10 13:32:40 +03:00
TxHash common . Hash
2018-10-15 13:28:44 +03:00
}
2021-03-14 18:13:25 +03:00
// txTraceContext is the contextual infos about a transaction before it gets run.
type txTraceContext struct {
index int // Index of the transaction within the block
hash common . Hash // Hash of the transaction
block common . Hash // Hash of the block containing the transaction
}
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// txTraceResult is the result of a single transaction trace.
type txTraceResult struct {
Result interface { } ` json:"result,omitempty" ` // Trace results produced by the tracer
Error string ` json:"error,omitempty" ` // Trace failure produced by the tracer
}
// blockTraceTask represents a single block trace task when an entire chain is
// being traced.
type blockTraceTask struct {
statedb * state . StateDB // Intermediate state prepped for tracing
block * types . Block // Block to trace the transactions from
results [ ] * txTraceResult // Trace results procudes by the task
}
// blockTraceResult represets the results of tracing a single block when an entire
// chain is being traced.
type blockTraceResult struct {
Block hexutil . Uint64 ` json:"block" ` // Block number corresponding to this trace
Hash common . Hash ` json:"hash" ` // Block hash corresponding to this trace
Traces [ ] * txTraceResult ` json:"traces" ` // Trace results produced by the task
}
// txTraceTask represents a single transaction trace task when an entire block
// is being traced.
type txTraceTask struct {
statedb * state . StateDB // Intermediate state prepped for tracing
index int // Transaction offset in the block
}
// TraceChain returns the structured logs created during the execution of EVM
// between two blocks (excluding start) and returns them as a JSON object.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceChain ( ctx context . Context , start , end rpc . BlockNumber , config * TraceConfig ) ( * rpc . Subscription , error ) { // Fetch the block interval that we want to trace
from , err := api . blockByNumber ( ctx , start )
if err != nil {
return nil , err
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
2021-01-25 16:36:39 +03:00
to , err := api . blockByNumber ( ctx , end )
if err != nil {
return nil , err
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
2018-08-21 10:48:53 +03:00
if from . Number ( ) . Cmp ( to . Number ( ) ) >= 0 {
return nil , fmt . Errorf ( "end block (#%d) needs to come after start block (#%d)" , end , start )
}
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
return api . traceChain ( ctx , from , to , config )
}
// traceChain configures a new tracer according to the provided configuration, and
// executes all the transactions contained within. The return value will be one item
2018-09-19 19:10:40 +03:00
// per transaction, dependent on the requested tracer.
2021-01-25 16:36:39 +03:00
func ( api * API ) traceChain ( ctx context . Context , start , end * types . Block , config * TraceConfig ) ( * rpc . Subscription , error ) {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// Tracing a chain is a **long** operation, only do with subscriptions
notifier , supported := rpc . NotifierFromContext ( ctx )
if ! supported {
return & rpc . Subscription { } , rpc . ErrNotificationsUnsupported
}
sub := notifier . CreateSubscription ( )
2021-01-25 16:36:39 +03:00
// Shift the border to a block ahead in order to get the states
// before these blocks.
endBlock , err := api . blockByNumberAndHash ( ctx , rpc . BlockNumber ( end . NumberU64 ( ) - 1 ) , end . ParentHash ( ) )
if err != nil {
return nil , err
}
// Prepare all the states for tracing. Note this procedure can take very
// long time. Timeout mechanism is necessary.
reexec := defaultTraceReexec
if config != nil && config . Reexec != nil {
reexec = * config . Reexec
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
2021-01-25 16:36:39 +03:00
states , release , err := api . backend . StatesInRange ( ctx , start , endBlock , reexec )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
if err != nil {
2021-01-25 16:36:39 +03:00
return nil , err
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
2021-01-25 16:36:39 +03:00
defer release ( ) // Release all the resources in the last step.
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
2021-01-25 16:36:39 +03:00
blocks := int ( end . NumberU64 ( ) - start . NumberU64 ( ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
threads := runtime . NumCPU ( )
if threads > blocks {
threads = blocks
}
var (
pend = new ( sync . WaitGroup )
tasks = make ( chan * blockTraceTask , threads )
results = make ( chan * blockTraceTask , threads )
)
for th := 0 ; th < threads ; th ++ {
pend . Add ( 1 )
go func ( ) {
defer pend . Done ( )
// Fetch and execute the next block trace tasks
for task := range tasks {
2021-01-25 16:36:39 +03:00
signer := types . MakeSigner ( api . backend . ChainConfig ( ) , task . block . Number ( ) )
blockCtx := core . NewEVMBlockContext ( task . block . Header ( ) , api . chainContext ( ctx ) , nil )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// Trace all the transactions contained within
for i , tx := range task . block . Transactions ( ) {
msg , _ := tx . AsMessage ( signer )
2021-03-14 18:13:25 +03:00
txctx := & txTraceContext {
index : i ,
hash : tx . Hash ( ) ,
block : task . block . Hash ( ) ,
}
res , err := api . traceTx ( ctx , msg , txctx , blockCtx , task . statedb , config )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
if err != nil {
task . results [ i ] = & txTraceResult { Error : err . Error ( ) }
2018-02-05 19:40:32 +03:00
log . Warn ( "Tracing failed" , "hash" , tx . Hash ( ) , "block" , task . block . NumberU64 ( ) , "err" , err )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
break
}
2019-02-01 12:30:59 +03:00
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
2021-01-25 16:36:39 +03:00
task . statedb . Finalise ( api . backend . ChainConfig ( ) . IsEIP158 ( task . block . Number ( ) ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
task . results [ i ] = & txTraceResult { Result : res }
}
// Stream the result back to the user or abort on teardown
select {
case results <- task :
case <- notifier . Closed ( ) :
return
}
}
} ( )
}
// Start a goroutine to feed all the blocks into the tracers
begin := time . Now ( )
go func ( ) {
var (
logged time . Time
number uint64
traced uint64
failed error
)
// Ensure everything is properly cleaned up on any exit path
defer func ( ) {
close ( tasks )
pend . Wait ( )
switch {
case failed != nil :
log . Warn ( "Chain tracing failed" , "start" , start . NumberU64 ( ) , "end" , end . NumberU64 ( ) , "transactions" , traced , "elapsed" , time . Since ( begin ) , "err" , failed )
case number < end . NumberU64 ( ) :
log . Warn ( "Chain tracing aborted" , "start" , start . NumberU64 ( ) , "end" , end . NumberU64 ( ) , "abort" , number , "transactions" , traced , "elapsed" , time . Since ( begin ) )
default :
log . Info ( "Chain tracing finished" , "start" , start . NumberU64 ( ) , "end" , end . NumberU64 ( ) , "transactions" , traced , "elapsed" , time . Since ( begin ) )
}
close ( results )
} ( )
// Feed all the blocks both into the tracer, as well as fast process concurrently
for number = start . NumberU64 ( ) + 1 ; number <= end . NumberU64 ( ) ; number ++ {
// Stop tracing if interruption was requested
select {
case <- notifier . Closed ( ) :
return
default :
}
// Print progress logs if long enough time elapsed
if time . Since ( logged ) > 8 * time . Second {
logged = time . Now ( )
2021-01-25 16:36:39 +03:00
log . Info ( "Tracing chain segment" , "start" , start . NumberU64 ( ) , "end" , end . NumberU64 ( ) , "current" , number , "transactions" , traced , "elapsed" , time . Since ( begin ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
// Retrieve the next block to trace
2021-01-25 16:36:39 +03:00
block , err := api . blockByNumber ( ctx , rpc . BlockNumber ( number ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
if err != nil {
failed = err
break
}
2021-01-25 16:36:39 +03:00
// Send the block over to the concurrent tracers (if not in the fast-forward phase)
txs := block . Transactions ( )
select {
case tasks <- & blockTraceTask { statedb : states [ int ( number - start . NumberU64 ( ) - 1 ) ] , block : block , results : make ( [ ] * txTraceResult , len ( txs ) ) } :
case <- notifier . Closed ( ) :
return
2018-08-08 17:16:38 +03:00
}
2021-01-25 16:36:39 +03:00
traced += uint64 ( len ( txs ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
} ( )
// Keep reading the trace results and stream the to the user
go func ( ) {
var (
done = make ( map [ uint64 ] * blockTraceResult )
2021-01-25 16:36:39 +03:00
next = start . NumberU64 ( ) + 1
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
)
for res := range results {
// Queue up next received result
result := & blockTraceResult {
Block : hexutil . Uint64 ( res . block . NumberU64 ( ) ) ,
Hash : res . block . Hash ( ) ,
Traces : res . results ,
}
done [ uint64 ( result . Block ) ] = result
// Stream completed traces to the user, aborting on the first error
for result , ok := done [ next ] ; ok ; result , ok = done [ next ] {
if len ( result . Traces ) > 0 || next == end . NumberU64 ( ) {
notifier . Notify ( sub . ID , result )
}
delete ( done , next )
next ++
}
}
} ( )
return sub , nil
}
// TraceBlockByNumber returns the structured logs created during the execution of
// EVM and returns them as a JSON object.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceBlockByNumber ( ctx context . Context , number rpc . BlockNumber , config * TraceConfig ) ( [ ] * txTraceResult , error ) {
block , err := api . blockByNumber ( ctx , number )
if err != nil {
return nil , err
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
return api . traceBlock ( ctx , block , config )
}
// TraceBlockByHash returns the structured logs created during the execution of
// EVM and returns them as a JSON object.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceBlockByHash ( ctx context . Context , hash common . Hash , config * TraceConfig ) ( [ ] * txTraceResult , error ) {
block , err := api . blockByHash ( ctx , hash )
if err != nil {
return nil , err
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
return api . traceBlock ( ctx , block , config )
}
// TraceBlock returns the structured logs created during the execution of EVM
// and returns them as a JSON object.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceBlock ( ctx context . Context , blob [ ] byte , config * TraceConfig ) ( [ ] * txTraceResult , error ) {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
block := new ( types . Block )
if err := rlp . Decode ( bytes . NewReader ( blob ) , block ) ; err != nil {
return nil , fmt . Errorf ( "could not decode block: %v" , err )
}
return api . traceBlock ( ctx , block , config )
}
// TraceBlockFromFile returns the structured logs created during the execution of
// EVM and returns them as a JSON object.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceBlockFromFile ( ctx context . Context , file string , config * TraceConfig ) ( [ ] * txTraceResult , error ) {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
blob , err := ioutil . ReadFile ( file )
if err != nil {
return nil , fmt . Errorf ( "could not read file: %v" , err )
}
return api . TraceBlock ( ctx , blob , config )
}
2020-08-26 13:20:12 +03:00
// TraceBadBlock returns the structured logs created during the execution of
2018-12-10 13:32:40 +03:00
// EVM against a block pulled from the pool of bad ones and returns them as a JSON
// object.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceBadBlock ( ctx context . Context , hash common . Hash , config * TraceConfig ) ( [ ] * txTraceResult , error ) {
for _ , block := range rawdb . ReadAllBadBlocks ( api . backend . ChainDb ( ) ) {
2018-12-10 13:32:40 +03:00
if block . Hash ( ) == hash {
2018-10-15 13:28:44 +03:00
return api . traceBlock ( ctx , block , config )
}
}
2018-12-10 13:32:40 +03:00
return nil , fmt . Errorf ( "bad block %#x not found" , hash )
2018-10-15 13:28:44 +03:00
}
2018-12-10 13:32:40 +03:00
// StandardTraceBlockToFile dumps the structured logs created during the
// execution of EVM to the local file system and returns a list of files
// to the caller.
2021-01-25 16:36:39 +03:00
func ( api * API ) StandardTraceBlockToFile ( ctx context . Context , hash common . Hash , config * StdTraceConfig ) ( [ ] string , error ) {
block , err := api . blockByHash ( ctx , hash )
if err != nil {
return nil , err
2018-10-04 18:15:37 +03:00
}
2018-12-10 13:32:40 +03:00
return api . standardTraceBlockToFile ( ctx , block , config )
2018-10-15 13:28:44 +03:00
}
2018-12-10 13:32:40 +03:00
// StandardTraceBadBlockToFile dumps the structured logs created during the
// execution of EVM against a block pulled from the pool of bad ones to the
// local file system and returns a list of files to the caller.
2021-01-25 16:36:39 +03:00
func ( api * API ) StandardTraceBadBlockToFile ( ctx context . Context , hash common . Hash , config * StdTraceConfig ) ( [ ] string , error ) {
for _ , block := range rawdb . ReadAllBadBlocks ( api . backend . ChainDb ( ) ) {
2018-12-10 13:32:40 +03:00
if block . Hash ( ) == hash {
return api . standardTraceBlockToFile ( ctx , block , config )
}
2018-10-15 13:28:44 +03:00
}
2018-12-10 13:32:40 +03:00
return nil , fmt . Errorf ( "bad block %#x not found" , hash )
2018-10-04 18:15:37 +03:00
}
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// traceBlock configures a new tracer according to the provided configuration, and
// executes all the transactions contained within. The return value will be one item
// per transaction, dependent on the requestd tracer.
2021-01-25 16:36:39 +03:00
func ( api * API ) traceBlock ( ctx context . Context , block * types . Block , config * TraceConfig ) ( [ ] * txTraceResult , error ) {
if block . NumberU64 ( ) == 0 {
return nil , errors . New ( "genesis is not traceable" )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
2021-01-25 16:36:39 +03:00
parent , err := api . blockByNumberAndHash ( ctx , rpc . BlockNumber ( block . NumberU64 ( ) - 1 ) , block . ParentHash ( ) )
if err != nil {
return nil , err
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
reexec := defaultTraceReexec
2018-01-04 14:58:11 +03:00
if config != nil && config . Reexec != nil {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
reexec = * config . Reexec
}
2021-01-25 16:36:39 +03:00
statedb , release , err := api . backend . StateAtBlock ( ctx , parent , reexec )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
if err != nil {
return nil , err
}
2021-01-25 16:36:39 +03:00
defer release ( )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// Execute all the transaction contained within the block concurrently
var (
2021-01-25 16:36:39 +03:00
signer = types . MakeSigner ( api . backend . ChainConfig ( ) , block . Number ( ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
txs = block . Transactions ( )
results = make ( [ ] * txTraceResult , len ( txs ) )
pend = new ( sync . WaitGroup )
jobs = make ( chan * txTraceTask , len ( txs ) )
)
threads := runtime . NumCPU ( )
if threads > len ( txs ) {
threads = len ( txs )
}
2021-01-25 16:36:39 +03:00
blockCtx := core . NewEVMBlockContext ( block . Header ( ) , api . chainContext ( ctx ) , nil )
2021-03-14 18:13:25 +03:00
blockHash := block . Hash ( )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
for th := 0 ; th < threads ; th ++ {
pend . Add ( 1 )
go func ( ) {
defer pend . Done ( )
// Fetch and execute the next transaction trace tasks
for task := range jobs {
msg , _ := txs [ task . index ] . AsMessage ( signer )
2021-03-14 18:13:25 +03:00
txctx := & txTraceContext {
index : task . index ,
hash : txs [ task . index ] . Hash ( ) ,
block : blockHash ,
}
res , err := api . traceTx ( ctx , msg , txctx , blockCtx , task . statedb , config )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
if err != nil {
results [ task . index ] = & txTraceResult { Error : err . Error ( ) }
continue
}
results [ task . index ] = & txTraceResult { Result : res }
}
} ( )
}
// Feed the transactions into the tracers and return
var failed error
for i , tx := range txs {
// Send the trace task over for execution
jobs <- & txTraceTask { statedb : statedb . Copy ( ) , index : i }
// Generate the next state snapshot fast without tracing
msg , _ := tx . AsMessage ( signer )
2021-03-14 18:13:25 +03:00
statedb . Prepare ( tx . Hash ( ) , block . Hash ( ) , i )
vmenv := vm . NewEVM ( blockCtx , core . NewEVMTxContext ( msg ) , statedb , api . backend . ChainConfig ( ) , vm . Config { } )
2020-04-22 11:25:36 +03:00
if _ , err := core . ApplyMessage ( vmenv , msg , new ( core . GasPool ) . AddGas ( msg . Gas ( ) ) ) ; err != nil {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
failed = err
break
}
// Finalize the state so any modifications are written to the trie
2019-02-01 12:30:59 +03:00
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
statedb . Finalise ( vmenv . ChainConfig ( ) . IsEIP158 ( block . Number ( ) ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
close ( jobs )
pend . Wait ( )
// If execution failed in between, abort
if failed != nil {
return nil , failed
}
return results , nil
}
2018-12-10 13:32:40 +03:00
// standardTraceBlockToFile configures a new tracer which uses standard JSON output,
// and traces either a full block or an individual transaction. The return value will
// be one filename per transaction traced.
2021-01-25 16:36:39 +03:00
func ( api * API ) standardTraceBlockToFile ( ctx context . Context , block * types . Block , config * StdTraceConfig ) ( [ ] string , error ) {
2018-12-10 13:32:40 +03:00
// If we're tracing a single transaction, make sure it's present
if config != nil && config . TxHash != ( common . Hash { } ) {
2019-02-19 20:49:24 +03:00
if ! containsTx ( block , config . TxHash ) {
2018-12-10 13:32:40 +03:00
return nil , fmt . Errorf ( "transaction %#x not found in block" , config . TxHash )
}
}
2021-01-25 16:36:39 +03:00
if block . NumberU64 ( ) == 0 {
return nil , errors . New ( "genesis is not traceable" )
2018-10-15 13:28:44 +03:00
}
2021-01-25 16:36:39 +03:00
parent , err := api . blockByNumberAndHash ( ctx , rpc . BlockNumber ( block . NumberU64 ( ) - 1 ) , block . ParentHash ( ) )
if err != nil {
return nil , err
2018-10-15 13:28:44 +03:00
}
2018-12-10 13:32:40 +03:00
reexec := defaultTraceReexec
if config != nil && config . Reexec != nil {
reexec = * config . Reexec
2018-10-15 13:28:44 +03:00
}
2021-01-25 16:36:39 +03:00
statedb , release , err := api . backend . StateAtBlock ( ctx , parent , reexec )
2018-10-15 13:28:44 +03:00
if err != nil {
return nil , err
}
2021-01-25 16:36:39 +03:00
defer release ( )
2018-12-10 13:32:40 +03:00
// Retrieve the tracing configurations, or use default values
var (
logConfig vm . LogConfig
txHash common . Hash
)
if config != nil {
2020-12-02 14:49:20 +03:00
logConfig = config . LogConfig
2018-12-10 13:32:40 +03:00
txHash = config . TxHash
}
logConfig . Debug = true
2018-10-15 13:28:44 +03:00
2018-12-10 13:32:40 +03:00
// Execute transaction, either tracing all or just the requested one
var (
2020-10-23 09:26:57 +03:00
dumps [ ] string
2021-01-25 16:36:39 +03:00
signer = types . MakeSigner ( api . backend . ChainConfig ( ) , block . Number ( ) )
chainConfig = api . backend . ChainConfig ( )
vmctx = core . NewEVMBlockContext ( block . Header ( ) , api . chainContext ( ctx ) , nil )
2020-10-23 09:26:57 +03:00
canon = true
2018-12-10 13:32:40 +03:00
)
2020-10-23 09:26:57 +03:00
// Check if there are any overrides: the caller may wish to enable a future
// fork when executing this block. Note, such overrides are only applicable to the
// actual specified block, not any preceding blocks that we have to go through
// in order to obtain the state.
// Therefore, it's perfectly valid to specify `"futureForkBlock": 0`, to enable `futureFork`
if config != nil && config . Overrides != nil {
// Copy the config, to not screw up the main config
// Note: the Clique-part is _not_ deep copied
chainConfigCopy := new ( params . ChainConfig )
* chainConfigCopy = * chainConfig
chainConfig = chainConfigCopy
2021-02-25 10:10:30 +03:00
if berlin := config . LogConfig . Overrides . BerlinBlock ; berlin != nil {
chainConfig . BerlinBlock = berlin
2020-10-23 09:26:57 +03:00
canon = false
}
}
2018-10-15 13:28:44 +03:00
for i , tx := range block . Transactions ( ) {
2018-12-10 13:32:40 +03:00
// Prepare the trasaction for un-traced execution
2018-10-15 13:28:44 +03:00
var (
2020-11-13 15:42:19 +03:00
msg , _ = tx . AsMessage ( signer )
txContext = core . NewEVMTxContext ( msg )
vmConf vm . Config
dump * os . File
writer * bufio . Writer
err error
2018-10-15 13:28:44 +03:00
)
2018-12-10 13:32:40 +03:00
// If the transaction needs tracing, swap out the configs
if tx . Hash ( ) == txHash || txHash == ( common . Hash { } ) {
// Generate a unique temporary file to dump it into
prefix := fmt . Sprintf ( "block_%#x-%d-%#x-" , block . Hash ( ) . Bytes ( ) [ : 4 ] , i , tx . Hash ( ) . Bytes ( ) [ : 4 ] )
2020-10-23 09:26:57 +03:00
if ! canon {
prefix = fmt . Sprintf ( "%valt-" , prefix )
}
2018-12-10 13:32:40 +03:00
dump , err = ioutil . TempFile ( os . TempDir ( ) , prefix )
2018-10-15 13:28:44 +03:00
if err != nil {
return nil , err
}
2018-12-10 13:32:40 +03:00
dumps = append ( dumps , dump . Name ( ) )
// Swap out the noop logger to the standard tracer
2019-01-23 13:13:13 +03:00
writer = bufio . NewWriter ( dump )
2018-10-15 13:28:44 +03:00
vmConf = vm . Config {
Debug : true ,
2019-01-23 13:13:13 +03:00
Tracer : vm . NewJSONLogger ( & logConfig , writer ) ,
2018-10-15 13:28:44 +03:00
EnablePreimageRecording : true ,
}
}
2018-12-10 13:32:40 +03:00
// Execute the transaction and flush any traces to disk
2020-11-13 15:42:19 +03:00
vmenv := vm . NewEVM ( vmctx , txContext , statedb , chainConfig , vmConf )
2021-03-14 18:13:25 +03:00
statedb . Prepare ( tx . Hash ( ) , block . Hash ( ) , i )
2020-04-22 11:25:36 +03:00
_ , err = core . ApplyMessage ( vmenv , msg , new ( core . GasPool ) . AddGas ( msg . Gas ( ) ) )
2019-01-23 13:13:13 +03:00
if writer != nil {
writer . Flush ( )
}
2018-12-10 13:32:40 +03:00
if dump != nil {
dump . Close ( )
log . Info ( "Wrote standard trace" , "file" , dump . Name ( ) )
2018-10-15 13:28:44 +03:00
}
if err != nil {
2018-12-10 13:32:40 +03:00
return dumps , err
2018-10-15 13:28:44 +03:00
}
// Finalize the state so any modifications are written to the trie
2019-02-01 12:30:59 +03:00
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
statedb . Finalise ( vmenv . ChainConfig ( ) . IsEIP158 ( block . Number ( ) ) )
2018-10-15 13:28:44 +03:00
2018-12-10 13:32:40 +03:00
// If we've traced the transaction we were looking for, abort
if tx . Hash ( ) == txHash {
2018-10-15 13:28:44 +03:00
break
}
}
2018-12-10 13:32:40 +03:00
return dumps , nil
2018-10-15 13:28:44 +03:00
}
2019-02-19 20:49:24 +03:00
// containsTx reports whether the transaction with a certain hash
// is contained within the specified block.
func containsTx ( block * types . Block , hash common . Hash ) bool {
for _ , tx := range block . Transactions ( ) {
if tx . Hash ( ) == hash {
return true
}
}
return false
}
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// TraceTransaction returns the structured logs created during the execution of EVM
// and returns them as a JSON object.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceTransaction ( ctx context . Context , hash common . Hash , config * TraceConfig ) ( interface { } , error ) {
_ , blockHash , blockNumber , index , err := api . backend . GetTransaction ( ctx , hash )
if err != nil {
return nil , err
}
// It shouldn't happen in practice.
if blockNumber == 0 {
return nil , errors . New ( "genesis is not traceable" )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
reexec := defaultTraceReexec
2018-01-04 14:58:11 +03:00
if config != nil && config . Reexec != nil {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
reexec = * config . Reexec
}
2021-01-25 16:36:39 +03:00
block , err := api . blockByNumberAndHash ( ctx , rpc . BlockNumber ( blockNumber ) , blockHash )
if err != nil {
return nil , err
2020-09-07 11:52:01 +03:00
}
2021-01-25 16:36:39 +03:00
msg , vmctx , statedb , release , err := api . backend . StateAtTransaction ( ctx , block , int ( index ) , reexec )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
if err != nil {
return nil , err
}
2021-01-25 16:36:39 +03:00
defer release ( )
2021-03-14 18:13:25 +03:00
txctx := & txTraceContext {
index : int ( index ) ,
hash : hash ,
block : blockHash ,
}
return api . traceTx ( ctx , msg , txctx , vmctx , statedb , config )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
2021-01-25 16:36:39 +03:00
// TraceCall lets you trace a given eth_call. It collects the structured logs
// created during the execution of EVM if the given transaction was added on
// top of the provided block and returns them as a JSON object.
2020-09-07 11:52:01 +03:00
// You can provide -2 as a block number to trace on top of the pending block.
2021-01-25 16:36:39 +03:00
func ( api * API ) TraceCall ( ctx context . Context , args ethapi . CallArgs , blockNrOrHash rpc . BlockNumberOrHash , config * TraceConfig ) ( interface { } , error ) {
// Try to retrieve the specified block
var (
err error
block * types . Block
)
if hash , ok := blockNrOrHash . Hash ( ) ; ok {
block , err = api . blockByHash ( ctx , hash )
} else if number , ok := blockNrOrHash . Number ( ) ; ok {
block , err = api . blockByNumber ( ctx , number )
}
2020-09-07 11:52:01 +03:00
if err != nil {
2021-01-25 16:36:39 +03:00
return nil , err
}
// try to recompute the state
reexec := defaultTraceReexec
if config != nil && config . Reexec != nil {
reexec = * config . Reexec
2020-09-07 11:52:01 +03:00
}
2021-01-25 16:36:39 +03:00
statedb , release , err := api . backend . StateAtBlock ( ctx , block , reexec )
if err != nil {
return nil , err
}
defer release ( )
2020-09-07 11:52:01 +03:00
// Execute the trace
2021-01-25 16:36:39 +03:00
msg := args . ToMessage ( api . backend . RPCGasCap ( ) )
vmctx := core . NewEVMBlockContext ( block . Header ( ) , api . chainContext ( ctx ) , nil )
2021-03-14 18:13:25 +03:00
return api . traceTx ( ctx , msg , new ( txTraceContext ) , vmctx , statedb , config )
2020-09-07 11:52:01 +03:00
}
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// traceTx configures a new tracer according to the provided configuration, and
// executes the given message in the provided environment. The return value will
// be tracer dependent.
2021-03-14 18:13:25 +03:00
func ( api * API ) traceTx ( ctx context . Context , message core . Message , txctx * txTraceContext , vmctx vm . BlockContext , statedb * state . StateDB , config * TraceConfig ) ( interface { } , error ) {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
// Assemble the structured logger or the JavaScript tracer
var (
2020-11-13 15:42:19 +03:00
tracer vm . Tracer
err error
txContext = core . NewEVMTxContext ( message )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
)
switch {
case config != nil && config . Tracer != nil :
// Define a meaningful timeout of a single transaction trace
timeout := defaultTraceTimeout
if config . Timeout != nil {
if timeout , err = time . ParseDuration ( * config . Timeout ) ; err != nil {
return nil , err
}
}
// Constuct the JavaScript tracer to execute with
2021-01-25 16:36:39 +03:00
if tracer , err = New ( * config . Tracer , txContext ) ; err != nil {
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
return nil , err
}
// Handle timeouts and RPC cancellations
deadlineCtx , cancel := context . WithTimeout ( ctx , timeout )
go func ( ) {
<- deadlineCtx . Done ( )
2021-01-25 16:36:39 +03:00
tracer . ( * Tracer ) . Stop ( errors . New ( "execution timeout" ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
} ( )
defer cancel ( )
case config == nil :
tracer = vm . NewStructLogger ( nil )
default :
tracer = vm . NewStructLogger ( config . LogConfig )
}
// Run the transaction with tracing enabled.
2021-01-25 16:36:39 +03:00
vmenv := vm . NewEVM ( vmctx , txContext , statedb , api . backend . ChainConfig ( ) , vm . Config { Debug : true , Tracer : tracer } )
2021-03-14 18:13:25 +03:00
// Call Prepare to clear out the statedb access list
statedb . Prepare ( txctx . hash , txctx . block , txctx . index )
2020-04-22 11:25:36 +03:00
result , err := core . ApplyMessage ( vmenv , message , new ( core . GasPool ) . AddGas ( message . Gas ( ) ) )
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
if err != nil {
return nil , fmt . Errorf ( "tracing failed: %v" , err )
}
2021-02-25 17:26:57 +03:00
// Depending on the tracer type, format and return the output.
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
switch tracer := tracer . ( type ) {
case * vm . StructLogger :
2020-06-26 13:19:31 +03:00
// If the result contains a revert reason, return it.
returnVal := fmt . Sprintf ( "%x" , result . Return ( ) )
if len ( result . Revert ( ) ) > 0 {
returnVal = fmt . Sprintf ( "%x" , result . Revert ( ) )
}
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
return & ethapi . ExecutionResult {
2020-04-22 11:25:36 +03:00
Gas : result . UsedGas ,
Failed : result . Failed ( ) ,
2020-06-26 13:19:31 +03:00
ReturnValue : returnVal ,
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
StructLogs : ethapi . FormatLogs ( tracer . StructLogs ( ) ) ,
} , nil
2021-01-25 16:36:39 +03:00
case * Tracer :
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
return tracer . GetResult ( )
default :
panic ( fmt . Sprintf ( "bad tracer type %T" , tracer ) )
}
}
2021-01-25 16:36:39 +03:00
// APIs return the collection of RPC services the tracer package offers.
func APIs ( backend Backend ) [ ] rpc . API {
// Append all the local APIs and return
return [ ] rpc . API {
{
Namespace : "debug" ,
Version : "1.0" ,
Service : NewAPI ( backend ) ,
Public : false ,
} ,
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing
* eth, internal/web3ext: rework trace API, concurrency, chain tracing
* eth/tracers: add three more JavaScript tracers
* eth/tracers, vendor: swap ottovm to duktape for tracing
* core, eth, internal: finalize call tracer and needed extras
* eth, tests: prestate tracer, call test suite, rewinding
* vendor: fix windows builds for tracer js engine
* vendor: temporary duktape fix
* eth/tracers: fix up 4byte and evmdis tracer
* vendor: pull in latest duktape with my upstream fixes
* eth: fix some review comments
* eth: rename rewind to reexec to make it more obvious
* core/vm: terminate tracing using defers
2017-12-21 14:56:11 +03:00
}
}