github.com/ethereum/go-ethereum@v1.16.1/eth/tracers/dir.go (about) 1 // Copyright 2024 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 "github.com/ethereum/go-ethereum/params" 26 ) 27 28 // Context contains some contextual infos for a transaction execution that is not 29 // available from within the EVM object. 30 type Context struct { 31 BlockHash common.Hash // Hash of the block the tx is contained within (zero if dangling tx or call) 32 BlockNumber *big.Int // Number of the block the tx is contained within (zero if dangling tx or call) 33 TxIndex int // Index of the transaction within a block (zero if dangling tx or call) 34 TxHash common.Hash // Hash of the transaction being traced (zero if dangling call) 35 } 36 37 // Tracer represents the set of methods that must be exposed by a tracer 38 // for it to be available through the RPC interface. 39 // This involves a method to retrieve results and one to 40 // stop tracing. 41 type Tracer struct { 42 *tracing.Hooks 43 GetResult func() (json.RawMessage, error) 44 // Stop terminates execution of the tracer at the first opportune moment. 45 Stop func(err error) 46 } 47 48 type ctorFn func(*Context, json.RawMessage, *params.ChainConfig) (*Tracer, error) 49 type jsCtorFn func(string, *Context, json.RawMessage, *params.ChainConfig) (*Tracer, error) 50 51 type elem struct { 52 ctor ctorFn 53 isJS bool 54 } 55 56 // DefaultDirectory is the collection of tracers bundled by default. 57 var DefaultDirectory = directory{elems: make(map[string]elem)} 58 59 // directory provides functionality to lookup a tracer by name 60 // and a function to instantiate it. It falls back to a JS code evaluator 61 // if no tracer of the given name exists. 62 type directory struct { 63 elems map[string]elem 64 jsEval jsCtorFn 65 } 66 67 // Register registers a method as a lookup for tracers, meaning that 68 // users can invoke a named tracer through that lookup. 69 func (d *directory) Register(name string, f ctorFn, isJS bool) { 70 d.elems[name] = elem{ctor: f, isJS: isJS} 71 } 72 73 // RegisterJSEval registers a tracer that is able to parse 74 // dynamic user-provided JS code. 75 func (d *directory) RegisterJSEval(f jsCtorFn) { 76 d.jsEval = f 77 } 78 79 // New returns a new instance of a tracer, by iterating through the 80 // registered lookups. Name is either name of an existing tracer 81 // or an arbitrary JS code. 82 func (d *directory) New(name string, ctx *Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*Tracer, error) { 83 if len(cfg) == 0 { 84 cfg = json.RawMessage("{}") 85 } 86 if elem, ok := d.elems[name]; ok { 87 return elem.ctor(ctx, cfg, chainConfig) 88 } 89 // Assume JS code 90 return d.jsEval(name, ctx, cfg, chainConfig) 91 } 92 93 // IsJS will return true if the given tracer will evaluate 94 // JS code. Because code evaluation has high overhead, this 95 // info will be used in determining fast and slow code paths. 96 func (d *directory) IsJS(name string) bool { 97 if elem, ok := d.elems[name]; ok { 98 return elem.isJS 99 } 100 // JS eval will execute JS code 101 return true 102 }