github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/eth/tracers/dir.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package tracers 18 19 import ( 20 "encoding/json" 21 "math/big" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/core/tracing" 25 ) 26 27 // Context contains some contextual infos for a transaction execution that is not 28 // available from within the EVM object. 29 type Context struct { 30 BlockHash common.Hash // Hash of the block the tx is contained within (zero if dangling tx or call) 31 BlockNumber *big.Int // Number of the block the tx is contained within (zero if dangling tx or call) 32 TxIndex int // Index of the transaction within a block (zero if dangling tx or call) 33 TxHash common.Hash // Hash of the transaction being traced (zero if dangling call) 34 } 35 36 // The set of methods that must be exposed by a tracer 37 // for it to be available through the RPC interface. 38 // This involves a method to retrieve results and one to 39 // stop tracing. 40 type Tracer struct { 41 *tracing.Hooks 42 GetResult func() (json.RawMessage, error) 43 // Stop terminates execution of the tracer at the first opportune moment. 44 Stop func(err error) 45 } 46 47 type ctorFn func(*Context, json.RawMessage) (*Tracer, error) 48 type jsCtorFn func(string, *Context, json.RawMessage) (*Tracer, error) 49 50 type elem struct { 51 ctor ctorFn 52 isJS bool 53 } 54 55 // DefaultDirectory is the collection of tracers bundled by default. 56 var DefaultDirectory = directory{elems: make(map[string]elem)} 57 58 // directory provides functionality to lookup a tracer by name 59 // and a function to instantiate it. It falls back to a JS code evaluator 60 // if no tracer of the given name exists. 61 type directory struct { 62 elems map[string]elem 63 jsEval jsCtorFn 64 } 65 66 // Register registers a method as a lookup for tracers, meaning that 67 // users can invoke a named tracer through that lookup. 68 func (d *directory) Register(name string, f ctorFn, isJS bool) { 69 d.elems[name] = elem{ctor: f, isJS: isJS} 70 } 71 72 // RegisterJSEval registers a tracer that is able to parse 73 // dynamic user-provided JS code. 74 func (d *directory) RegisterJSEval(f jsCtorFn) { 75 d.jsEval = f 76 } 77 78 // New returns a new instance of a tracer, by iterating through the 79 // registered lookups. Name is either name of an existing tracer 80 // or an arbitrary JS code. 81 func (d *directory) New(name string, ctx *Context, cfg json.RawMessage) (*Tracer, error) { 82 if elem, ok := d.elems[name]; ok { 83 return elem.ctor(ctx, cfg) 84 } 85 // Assume JS code 86 return d.jsEval(name, ctx, cfg) 87 } 88 89 // IsJS will return true if the given tracer will evaluate 90 // JS code. Because code evaluation has high overhead, this 91 // info will be used in determining fast and slow code paths. 92 func (d *directory) IsJS(name string) bool { 93 if elem, ok := d.elems[name]; ok { 94 return elem.isJS 95 } 96 // JS eval will execute JS code 97 return true 98 }